diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 00000000..3ba13e0c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1 @@ +blank_issues_enabled: false diff --git a/.github/ISSUE_TEMPLATE/issue_template.yml b/.github/ISSUE_TEMPLATE/issue_template.yml new file mode 100644 index 00000000..222e60ad --- /dev/null +++ b/.github/ISSUE_TEMPLATE/issue_template.yml @@ -0,0 +1,93 @@ +name: Issue Report +description: File an issue report +title: "[issue]: " +assignees: + - octocat +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this issue report! + - type: checkboxes + id: faq + attributes: + label: Official FAQ + description: Have you checked the official FAQ at [https://www.ventoy.net/en/faq.html](https://www.ventoy.net/en/faq.html) ? + options: + - label: I have checked the official FAQ. + required: true + - type: input + id: version + attributes: + label: Ventoy Version + description: What version of ventoy are you running? + placeholder: 1.0.49 + validations: + required: true + - type: dropdown + id: latestrelease + attributes: + label: What about latest release + description: Have you tried with the latest release of Ventoy? + options: + - Yes. I have tried the latest release, but the bug still exist. + - No. I didn't try the latest release. + validations: + required: true + - type: dropdown + id: bios + attributes: + label: BIOS Mode + description: In which BIOS mode did you find the bug? + options: + - Legacy BIOS Mode + - UEFI Mode + - Both + validations: + required: true + - type: dropdown + id: partstyle + attributes: + label: Partition Style + description: Which partition style did you select when you install Ventoy? + options: + - MBR + - GPT + validations: + required: true + - type: input + id: capacity + attributes: + label: Disk Capacity + description: What is the capacity of the disk installed with Ventoy? + placeholder: 32GB + validations: + required: true + - type: dropdown + id: checksum + attributes: + label: Image file checksum (if applicable) + description: Have you checked the image file in Ventoy's menu as [https://www.ventoy.net/en/faq.html#faq_boot_checksum](https://www.ventoy.net/en/faq.html#faq_boot_checksum) ? + options: + - Yes. + - No. + validations: + required: false + - type: input + id: link + attributes: + label: Image file download link (if applicable) + description: What is the image file download link? + placeholder: https://xxx + validations: + required: false + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Tell me what happened. It's highly recommended to include some photo or video about the bug. + placeholder: Tell us what you see! + value: "A bug happened!" + validations: + required: true + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..670cea29 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,33 @@ +name: Ventoy CI + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run docker-compose up + run: docker-compose up + - uses: actions/upload-artifact@v2 + with: + name: ventoy-windows + path: INSTALL/ventoy-*windows* + - uses: actions/upload-artifact@v2 + with: + name: ventoy-linux + path: INSTALL/ventoy-*linux* + - uses: actions/upload-artifact@v2 + with: + name: ventoy-livecd + path: INSTALL/ventoy-*livecd* + - uses: actions/upload-artifact@v2 + with: + name: xxx-build-log + path: DOC/build.log diff --git a/.github/workflows/sync2gitee.yml b/.github/workflows/sync2gitee.yml new file mode 100644 index 00000000..2fd7e871 --- /dev/null +++ b/.github/workflows/sync2gitee.yml @@ -0,0 +1,25 @@ +name: Mirror GitHub to Gitee + +on: + # Triggers the workflow on push or pull request events but only for the main branch + push: + branches: [ master ] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +jobs: + run: + name: Sync-GitHub-to-Gitee + if: ${{ github.repository_owner == 'ventoy' }} + runs-on: ubuntu-latest + steps: + - name: Mirror the Github repos to Gitee. + uses: Yikun/hub-mirror-action@master + with: + src: github/ventoy + dst: gitee/LongPanda + dst_key: ${{ secrets.GITEE_PRIVATE_KEY }} + dst_token: ${{ secrets.GITEE_TOKEN }} + static_list: "Ventoy" + force_update: true diff --git a/BUSYBOX/aarch64_ash.config b/BUSYBOX/aarch64_ash.config new file mode 100644 index 00000000..32854774 --- /dev/null +++ b/BUSYBOX/aarch64_ash.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Fri Aug 7 05:44:56 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +CONFIG_FEATURE_FANCY_ECHO=y +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +CONFIG_FEATURE_TEST_64=y +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y +CONFIG_ASH_BASH_COMPAT=y +CONFIG_ASH_BASH_SOURCE_CURDIR=y +CONFIG_ASH_BASH_NOT_FOUND_HOOK=y +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_ASH_IDLE_TIMEOUT=y +CONFIG_ASH_MAIL=y +CONFIG_ASH_ECHO=y +CONFIG_ASH_PRINTF=y +CONFIG_ASH_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y +CONFIG_CTTYHACK=y +CONFIG_HUSH=y +CONFIG_SHELL_HUSH=y +CONFIG_HUSH_BASH_COMPAT=y +CONFIG_HUSH_BRACE_EXPANSION=y +CONFIG_HUSH_LINENO_VAR=y +CONFIG_HUSH_BASH_SOURCE_CURDIR=y +CONFIG_HUSH_INTERACTIVE=y +# CONFIG_HUSH_SAVEHISTORY is not set +CONFIG_HUSH_JOB=y +CONFIG_HUSH_TICK=y +CONFIG_HUSH_IF=y +CONFIG_HUSH_LOOPS=y +CONFIG_HUSH_CASE=y +CONFIG_HUSH_FUNCTIONS=y +CONFIG_HUSH_LOCAL=y +CONFIG_HUSH_RANDOM_SUPPORT=y +CONFIG_HUSH_MODE_X=y +CONFIG_HUSH_ECHO=y +CONFIG_HUSH_PRINTF=y +CONFIG_HUSH_TEST=y +CONFIG_HUSH_HELP=y +CONFIG_HUSH_EXPORT=y +CONFIG_HUSH_EXPORT_N=y +CONFIG_HUSH_READONLY=y +CONFIG_HUSH_KILL=y +CONFIG_HUSH_WAIT=y +CONFIG_HUSH_COMMAND=y +CONFIG_HUSH_TRAP=y +CONFIG_HUSH_TYPE=y +CONFIG_HUSH_TIMES=y +CONFIG_HUSH_READ=y +CONFIG_HUSH_SET=y +CONFIG_HUSH_UNSET=y +CONFIG_HUSH_ULIMIT=y +CONFIG_HUSH_UMASK=y +CONFIG_HUSH_GETOPTS=y +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y +CONFIG_FEATURE_SH_MATH_BASE=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +CONFIG_FEATURE_SH_STANDALONE=y +CONFIG_FEATURE_SH_NOFORK=y +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/aarch64_hexdump.config b/BUSYBOX/aarch64_hexdump.config new file mode 100644 index 00000000..d13aa42b --- /dev/null +++ b/BUSYBOX/aarch64_hexdump.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 03:03:31 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_WHOAMI is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_FLASHCP is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_UBIRENAME is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/aarch64_xzcat.config b/BUSYBOX/aarch64_xzcat.config new file mode 100644 index 00000000..cd4361d6 --- /dev/null +++ b/BUSYBOX/aarch64_xzcat.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 11:07:46 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +CONFIG_XZCAT=y +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/build.txt b/BUSYBOX/build.txt new file mode 100644 index 00000000..7a68be81 --- /dev/null +++ b/BUSYBOX/build.txt @@ -0,0 +1,55 @@ +======== How to build ash/hexdump/xzcat for aarch64 ======== +#How to get ash.config/hexdump.cofig/xzcat.config +#ARCH=arm64 CROSS_COMPILE=aarch64-linux- make allnoconfig +#ARCH=arm64 CROSS_COMPILE=aarch64-linux- make menuconfig +#----> enable static build +#----> enable xzcat +#get aarch64_xzcat.config + +tar xf busybox-1.32.0.tar.bz2 +cd busybox-1.32.0 +copy aarch64_xzcat.config as .config +ARCH=arm64 CROSS_COMPILE=aarch64-linux- make +rename ./busybox to xzcat + + +======== How to build ash/hexdump/xzcat for mips64el ======== +#download mips64el-musl cross toolchain from https://github.com/ventoy/musl-cross-make/releases/download/latest/ +#How to get ash.config/hexdump.cofig/xzcat.config +#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make allnoconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os" +#ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make menuconfig "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os" +#----> enable static build +#----> enable xzcat +#get mips64el_xzcat.config + +tar xf busybox-1.32.0.tar.bz2 +cd busybox-1.32.0 +copy mips64el_xzcat.config as .config +ARCH=mips CROSS_COMPILE=mips64el-linux-musl- make "CFLAGS+=-mips64r2 -mabi=64 -Os" "LDFLAGS+=-mips64r2 -mabi=64 -Os" +rename ./busybox to xzcat + + +======== How to build full busybox ========= +#make defconfig +#make menuconfig select static build + +======== How to build ash/hexdump/xzcat for x86_64 ========== +#How to get ash.config/hexdump.cofig/xzcat.config +#make allnoconfig +#make menuconfig +#----> enable static build +#----> enable xzcat +#get x86_64_xzcat.config + + +tar xf busybox-1.32.0.tar.bz2 +cd busybox-1.32.0 +copy x86_64_xzcat.config as .config +modify Makefile +CC = gcc -specs "/usr/local/musl/lib/musl-gcc.specs" +MODFLAGS = -DMODULE -specs "/usr/local/musl/lib/musl-gcc.specs" +make +rename ./busybox to xzcat + + + diff --git a/BUSYBOX/chmod/build.sh b/BUSYBOX/chmod/build.sh new file mode 100644 index 00000000..5db2ae74 --- /dev/null +++ b/BUSYBOX/chmod/build.sh @@ -0,0 +1,31 @@ +#!/bin/sh + +DSTDIR=../../IMG/cpio/ventoy/busybox + +rm -f vtchmod32 vtchmod64 vtchmod64_musl vtchmodaa64 +rm -f $DSTDIR/vtchmod32 $DSTDIR/vtchmod64 $DSTDIR/vtchmodaa64 $DSTDIR/vtchmodm64e + +/opt/diet32/bin/diet gcc -Os -m32 vtchmod.c -o vtchmod32 +/opt/diet64/bin/diet gcc -Os vtchmod.c -o vtchmod64 +aarch64-linux-gcc -Os -static vtchmod.c -o vtchmodaa64 +aarch64-linux-strip --strip-all vtchmodaa64 + +mips64el-linux-musl-gcc -mips64r2 -mabi=64 -Os -static vtchmod.c -o vtchmodm64e +mips64el-linux-musl-strip --strip-all vtchmodm64e + + +gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -Os -static vtchmod.c -o vtchmod64_musl +strip --strip-all vtchmod64_musl + +chmod 777 vtchmod32 +chmod 777 vtchmod64 +chmod 777 vtchmodaa64 +chmod 777 vtchmod64_musl +chmod 777 vtchmodm64e + +cp -a vtchmod32 $DSTDIR/ +cp -a vtchmod64 $DSTDIR/ +cp -a vtchmodaa64 $DSTDIR/ +cp -a vtchmod64_musl $DSTDIR/ +cp -a vtchmodm64e $DSTDIR/ + diff --git a/BUSYBOX/chmod/vtchmod.c b/BUSYBOX/chmod/vtchmod.c new file mode 100644 index 00000000..5a9d833f --- /dev/null +++ b/BUSYBOX/chmod/vtchmod.c @@ -0,0 +1,13 @@ +#include +#include + +int main(int argc, char **argv) +{ + if (argc != 2) + { + return 1; + } + + return chmod(argv[1], 0777); +} + diff --git a/BUSYBOX/chmod/vtchmod32 b/BUSYBOX/chmod/vtchmod32 new file mode 100644 index 00000000..4b66db3c Binary files /dev/null and b/BUSYBOX/chmod/vtchmod32 differ diff --git a/BUSYBOX/chmod/vtchmod64 b/BUSYBOX/chmod/vtchmod64 new file mode 100644 index 00000000..9c799581 Binary files /dev/null and b/BUSYBOX/chmod/vtchmod64 differ diff --git a/BUSYBOX/chmod/vtchmod64_musl b/BUSYBOX/chmod/vtchmod64_musl new file mode 100644 index 00000000..d4cd5c6b Binary files /dev/null and b/BUSYBOX/chmod/vtchmod64_musl differ diff --git a/BUSYBOX/chmod/vtchmodaa64 b/BUSYBOX/chmod/vtchmodaa64 new file mode 100644 index 00000000..593c021f Binary files /dev/null and b/BUSYBOX/chmod/vtchmodaa64 differ diff --git a/BUSYBOX/chmod/vtchmodm64e b/BUSYBOX/chmod/vtchmodm64e new file mode 100644 index 00000000..47e84be6 Binary files /dev/null and b/BUSYBOX/chmod/vtchmodm64e differ diff --git a/BUSYBOX/config b/BUSYBOX/config new file mode 100644 index 00000000..d650073e --- /dev/null +++ b/BUSYBOX/config @@ -0,0 +1,1181 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.30.0 +# Sun Dec 30 19:34:09 2018 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +CONFIG_DESKTOP=y +CONFIG_EXTRA_COMPAT=y +# CONFIG_FEDORA_COMPAT is not set +CONFIG_INCLUDE_SUSv2=y +CONFIG_LONG_OPTS=y +CONFIG_SHOW_USAGE=y +CONFIG_FEATURE_VERBOSE_USAGE=y +CONFIG_FEATURE_COMPRESS_USAGE=y +CONFIG_LFS=y +# CONFIG_PAM is not set +CONFIG_FEATURE_DEVPTS=y +CONFIG_FEATURE_UTMP=y +CONFIG_FEATURE_WTMP=y +CONFIG_FEATURE_PIDFILE=y +CONFIG_PID_FILE_PATH="/var/run" +CONFIG_BUSYBOX=y +CONFIG_FEATURE_SHOW_SCRIPT=y +CONFIG_FEATURE_INSTALLER=y +# CONFIG_INSTALL_NO_USR is not set +CONFIG_FEATURE_SUID=y +CONFIG_FEATURE_SUID_CONFIG=y +CONFIG_FEATURE_SUID_CONFIG_QUIET=y +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +CONFIG_FEATURE_SYSLOG=y +CONFIG_PLATFORM_LINUX=y + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="i486-linux-uclibc-" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +CONFIG_STACK_OPTIMIZATION_386=y + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +CONFIG_WERROR=y +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +CONFIG_FEATURE_USE_BSS_TAIL=y +CONFIG_FLOAT_DURATION=y +CONFIG_FEATURE_RTMINMAX=y +CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS=y +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +CONFIG_FEATURE_FAST_TOP=y +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +CONFIG_FEATURE_EDITING=y +CONFIG_FEATURE_EDITING_MAX_LEN=1024 +CONFIG_FEATURE_EDITING_VI=y +CONFIG_FEATURE_EDITING_HISTORY=15 +CONFIG_FEATURE_EDITING_SAVEHISTORY=y +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +CONFIG_FEATURE_REVERSE_SEARCH=y +CONFIG_FEATURE_TAB_COMPLETION=y +CONFIG_FEATURE_USERNAME_COMPLETION=y +CONFIG_FEATURE_EDITING_FANCY_PROMPT=y +CONFIG_FEATURE_EDITING_WINCH=y +CONFIG_FEATURE_EDITING_ASK_TERMINAL=y +# CONFIG_LOCALE_SUPPORT is not set +CONFIG_UNICODE_SUPPORT=y +# CONFIG_UNICODE_USING_LOCALE is not set +CONFIG_FEATURE_CHECK_UNICODE_IN_ENV=y +CONFIG_SUBST_WCHAR=63 +CONFIG_LAST_SUPPORTED_WCHAR=4351 +CONFIG_UNICODE_COMBINING_WCHARS=y +# CONFIG_UNICODE_WIDE_WCHARS is not set +CONFIG_UNICODE_BIDI_SUPPORT=y +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +CONFIG_UNICODE_PRESERVE_BROKEN=y +CONFIG_FEATURE_NON_POSIX_CP=y +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +CONFIG_FEATURE_USE_SENDFILE=y +CONFIG_FEATURE_COPYBUF_KB=64 +CONFIG_FEATURE_SKIP_ROOTFS=y +CONFIG_MONOTONIC_SYSCALL=y +# CONFIG_IOCTL_HEX2STR_ERROR is not set +CONFIG_FEATURE_HWIB=y + +# +# Applets +# + +# +# Archival Utilities +# +CONFIG_FEATURE_SEAMLESS_XZ=y +CONFIG_FEATURE_SEAMLESS_LZMA=y +CONFIG_FEATURE_SEAMLESS_BZ2=y +CONFIG_FEATURE_SEAMLESS_GZ=y +CONFIG_FEATURE_SEAMLESS_Z=y +CONFIG_AR=y +CONFIG_FEATURE_AR_LONG_FILENAMES=y +CONFIG_FEATURE_AR_CREATE=y +CONFIG_UNCOMPRESS=y +CONFIG_GUNZIP=y +CONFIG_ZCAT=y +CONFIG_FEATURE_GUNZIP_LONG_OPTIONS=y +CONFIG_BUNZIP2=y +CONFIG_BZCAT=y +CONFIG_UNLZMA=y +CONFIG_LZCAT=y +CONFIG_LZMA=y +CONFIG_UNXZ=y +CONFIG_XZCAT=y +CONFIG_XZ=y +CONFIG_BZIP2=y +CONFIG_BZIP2_SMALL=8 +CONFIG_FEATURE_BZIP2_DECOMPRESS=y +CONFIG_CPIO=y +CONFIG_FEATURE_CPIO_O=y +CONFIG_FEATURE_CPIO_P=y +CONFIG_DPKG=y +CONFIG_DPKG_DEB=y +CONFIG_GZIP=y +CONFIG_FEATURE_GZIP_LONG_OPTIONS=y +CONFIG_GZIP_FAST=2 +# CONFIG_FEATURE_GZIP_LEVELS is not set +CONFIG_FEATURE_GZIP_DECOMPRESS=y +CONFIG_LZOP=y +CONFIG_UNLZOP=y +CONFIG_LZOPCAT=y +# CONFIG_LZOP_COMPR_HIGH is not set +CONFIG_RPM=y +CONFIG_RPM2CPIO=y +CONFIG_TAR=y +CONFIG_FEATURE_TAR_LONG_OPTIONS=y +CONFIG_FEATURE_TAR_CREATE=y +CONFIG_FEATURE_TAR_AUTODETECT=y +CONFIG_FEATURE_TAR_FROM=y +CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y +CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y +CONFIG_FEATURE_TAR_TO_COMMAND=y +CONFIG_FEATURE_TAR_UNAME_GNAME=y +CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y +# CONFIG_FEATURE_TAR_SELINUX is not set +CONFIG_UNZIP=y +CONFIG_FEATURE_UNZIP_CDF=y +CONFIG_FEATURE_UNZIP_BZIP2=y +CONFIG_FEATURE_UNZIP_LZMA=y +CONFIG_FEATURE_UNZIP_XZ=y +CONFIG_FEATURE_LZMA_FAST=y + +# +# Coreutils +# +CONFIG_BASENAME=y +CONFIG_CAT=y +CONFIG_FEATURE_CATN=y +CONFIG_FEATURE_CATV=y +CONFIG_CHGRP=y +CONFIG_CHMOD=y +CONFIG_CHOWN=y +CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y +CONFIG_CHROOT=y +CONFIG_CKSUM=y +CONFIG_COMM=y +CONFIG_CP=y +CONFIG_FEATURE_CP_LONG_OPTIONS=y +CONFIG_FEATURE_CP_REFLINK=y +CONFIG_CUT=y +CONFIG_DATE=y +CONFIG_FEATURE_DATE_ISOFMT=y +CONFIG_FEATURE_DATE_NANO=y +# CONFIG_FEATURE_DATE_COMPAT is not set +CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y +CONFIG_FEATURE_DD_IBS_OBS=y +CONFIG_FEATURE_DD_STATUS=y +CONFIG_DF=y +CONFIG_FEATURE_DF_FANCY=y +CONFIG_DIRNAME=y +CONFIG_DOS2UNIX=y +CONFIG_UNIX2DOS=y +CONFIG_DU=y +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y +CONFIG_ECHO=y +CONFIG_FEATURE_FANCY_ECHO=y +CONFIG_ENV=y +CONFIG_EXPAND=y +CONFIG_UNEXPAND=y +CONFIG_EXPR=y +CONFIG_EXPR_MATH_SUPPORT_64=y +CONFIG_FACTOR=y +CONFIG_FALSE=y +CONFIG_FOLD=y +CONFIG_FSYNC=y +CONFIG_HEAD=y +CONFIG_FEATURE_FANCY_HEAD=y +CONFIG_HOSTID=y +CONFIG_ID=y +CONFIG_GROUPS=y +CONFIG_INSTALL=y +CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y +CONFIG_LINK=y +CONFIG_LN=y +CONFIG_LOGNAME=y +CONFIG_LS=y +CONFIG_FEATURE_LS_FILETYPES=y +CONFIG_FEATURE_LS_FOLLOWLINKS=y +CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_WIDTH=y +CONFIG_FEATURE_LS_SORTFILES=y +CONFIG_FEATURE_LS_TIMESTAMPS=y +CONFIG_FEATURE_LS_USERNAME=y +CONFIG_FEATURE_LS_COLOR=y +CONFIG_FEATURE_LS_COLOR_IS_DEFAULT=y +CONFIG_MD5SUM=y +CONFIG_SHA1SUM=y +CONFIG_SHA256SUM=y +CONFIG_SHA512SUM=y +CONFIG_SHA3SUM=y + +# +# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y +CONFIG_MKDIR=y +CONFIG_MKFIFO=y +CONFIG_MKNOD=y +CONFIG_MKTEMP=y +CONFIG_MV=y +CONFIG_NICE=y +CONFIG_NL=y +CONFIG_NOHUP=y +CONFIG_NPROC=y +CONFIG_OD=y +CONFIG_PASTE=y +CONFIG_PRINTENV=y +CONFIG_PRINTF=y +CONFIG_PWD=y +CONFIG_READLINK=y +CONFIG_FEATURE_READLINK_FOLLOW=y +CONFIG_REALPATH=y +CONFIG_RM=y +CONFIG_RMDIR=y +CONFIG_SEQ=y +CONFIG_SHRED=y +CONFIG_SHUF=y +CONFIG_SLEEP=y +CONFIG_FEATURE_FANCY_SLEEP=y +CONFIG_SORT=y +CONFIG_FEATURE_SORT_BIG=y +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +CONFIG_SPLIT=y +CONFIG_FEATURE_SPLIT_FANCY=y +CONFIG_STAT=y +CONFIG_FEATURE_STAT_FORMAT=y +CONFIG_FEATURE_STAT_FILESYSTEM=y +CONFIG_STTY=y +CONFIG_SUM=y +CONFIG_SYNC=y +# CONFIG_FEATURE_SYNC_FANCY is not set +CONFIG_TAC=y +CONFIG_TAIL=y +CONFIG_FEATURE_FANCY_TAIL=y +CONFIG_TEE=y +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TEST=y +CONFIG_TEST1=y +CONFIG_TEST2=y +CONFIG_FEATURE_TEST_64=y +CONFIG_TIMEOUT=y +CONFIG_TOUCH=y +CONFIG_FEATURE_TOUCH_NODEREF=y +CONFIG_FEATURE_TOUCH_SUSV3=y +CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +CONFIG_FEATURE_TR_EQUIV=y +CONFIG_TRUE=y +CONFIG_TRUNCATE=y +CONFIG_TTY=y +CONFIG_UNAME=y +CONFIG_UNAME_OSNAME="GNU/Linux" +CONFIG_BB_ARCH=y +CONFIG_UNIQ=y +CONFIG_UNLINK=y +CONFIG_USLEEP=y +CONFIG_UUDECODE=y +CONFIG_BASE64=y +CONFIG_UUENCODE=y +CONFIG_WC=y +CONFIG_FEATURE_WC_LARGE=y +CONFIG_WHOAMI=y +CONFIG_WHO=y +CONFIG_W=y +CONFIG_USERS=y +CONFIG_YES=y + +# +# Common options +# +CONFIG_FEATURE_VERBOSE=y + +# +# Common options for cp and mv +# +CONFIG_FEATURE_PRESERVE_HARDLINKS=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y + +# +# Console Utilities +# +CONFIG_CHVT=y +CONFIG_CLEAR=y +CONFIG_DEALLOCVT=y +CONFIG_DUMPKMAP=y +CONFIG_FGCONSOLE=y +CONFIG_KBD_MODE=y +CONFIG_LOADFONT=y +CONFIG_SETFONT=y +CONFIG_FEATURE_SETFONT_TEXTUAL_MAP=y +CONFIG_DEFAULT_SETFONT_DIR="" + +# +# Common options for loadfont and setfont +# +CONFIG_FEATURE_LOADFONT_PSF2=y +CONFIG_FEATURE_LOADFONT_RAW=y +CONFIG_LOADKMAP=y +CONFIG_OPENVT=y +CONFIG_RESET=y +CONFIG_RESIZE=y +CONFIG_FEATURE_RESIZE_PRINT=y +CONFIG_SETCONSOLE=y +CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y +CONFIG_SETKEYCODES=y +CONFIG_SETLOGCONS=y +CONFIG_SHOWKEY=y + +# +# Debian Utilities +# +CONFIG_PIPE_PROGRESS=y +CONFIG_RUN_PARTS=y +CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS=y +CONFIG_FEATURE_RUN_PARTS_FANCY=y +CONFIG_START_STOP_DAEMON=y +CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y +CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y +CONFIG_WHICH=y + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +CONFIG_NUKE=y +CONFIG_RESUME=y +CONFIG_RUN_INIT=y + +# +# Editors +# +CONFIG_AWK=y +# CONFIG_FEATURE_AWK_LIBM is not set +CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y +CONFIG_CMP=y +CONFIG_DIFF=y +CONFIG_FEATURE_DIFF_LONG_OPTIONS=y +CONFIG_FEATURE_DIFF_DIR=y +CONFIG_ED=y +CONFIG_PATCH=y +CONFIG_SED=y +CONFIG_VI=y +CONFIG_FEATURE_VI_MAX_LEN=1024 +# CONFIG_FEATURE_VI_8BIT is not set +CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_YANKMARK=y +CONFIG_FEATURE_VI_SEARCH=y +CONFIG_FEATURE_VI_REGEX_SEARCH=y +CONFIG_FEATURE_VI_USE_SIGNALS=y +CONFIG_FEATURE_VI_DOT_CMD=y +CONFIG_FEATURE_VI_READONLY=y +CONFIG_FEATURE_VI_SETOPTS=y +CONFIG_FEATURE_VI_SET=y +CONFIG_FEATURE_VI_WIN_RESIZE=y +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +CONFIG_FEATURE_VI_UNDO=y +CONFIG_FEATURE_VI_UNDO_QUEUE=y +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 +CONFIG_FEATURE_ALLOW_EXEC=y + +# +# Finding Utilities +# +CONFIG_FIND=y +CONFIG_FEATURE_FIND_PRINT0=y +CONFIG_FEATURE_FIND_MTIME=y +CONFIG_FEATURE_FIND_MMIN=y +CONFIG_FEATURE_FIND_PERM=y +CONFIG_FEATURE_FIND_TYPE=y +CONFIG_FEATURE_FIND_EXECUTABLE=y +CONFIG_FEATURE_FIND_XDEV=y +CONFIG_FEATURE_FIND_MAXDEPTH=y +CONFIG_FEATURE_FIND_NEWER=y +CONFIG_FEATURE_FIND_INUM=y +CONFIG_FEATURE_FIND_EXEC=y +CONFIG_FEATURE_FIND_EXEC_PLUS=y +CONFIG_FEATURE_FIND_USER=y +CONFIG_FEATURE_FIND_GROUP=y +CONFIG_FEATURE_FIND_NOT=y +CONFIG_FEATURE_FIND_DEPTH=y +CONFIG_FEATURE_FIND_PAREN=y +CONFIG_FEATURE_FIND_SIZE=y +CONFIG_FEATURE_FIND_PRUNE=y +CONFIG_FEATURE_FIND_QUIT=y +CONFIG_FEATURE_FIND_DELETE=y +CONFIG_FEATURE_FIND_PATH=y +CONFIG_FEATURE_FIND_REGEX=y +# CONFIG_FEATURE_FIND_CONTEXT is not set +CONFIG_FEATURE_FIND_LINKS=y +CONFIG_GREP=y +CONFIG_EGREP=y +CONFIG_FGREP=y +CONFIG_FEATURE_GREP_CONTEXT=y +CONFIG_XARGS=y +CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y +CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y +CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL=y +CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE=y + +# +# Init Utilities +# +CONFIG_BOOTCHARTD=y +CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y +CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y +CONFIG_HALT=y +CONFIG_POWEROFF=y +CONFIG_REBOOT=y +CONFIG_FEATURE_WAIT_FOR_INIT=y +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +CONFIG_INIT=y +CONFIG_LINUXRC=y +CONFIG_FEATURE_USE_INITTAB=y +CONFIG_FEATURE_KILL_REMOVED=y +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +CONFIG_FEATURE_INIT_SYSLOG=y +CONFIG_FEATURE_INIT_QUIET=y +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="linux" +CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y + +# +# Login/Password Management Utilities +# +CONFIG_FEATURE_SHADOWPASSWDS=y +CONFIG_USE_BB_PWD_GRP=y +CONFIG_USE_BB_SHADOW=y +CONFIG_USE_BB_CRYPT=y +CONFIG_USE_BB_CRYPT_SHA=y +CONFIG_ADDGROUP=y +CONFIG_FEATURE_ADDUSER_TO_GROUP=y +CONFIG_ADD_SHELL=y +CONFIG_REMOVE_SHELL=y +CONFIG_ADDUSER=y +CONFIG_FEATURE_CHECK_NAMES=y +CONFIG_LAST_ID=60000 +CONFIG_FIRST_SYSTEM_ID=100 +CONFIG_LAST_SYSTEM_ID=999 +CONFIG_CHPASSWD=y +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="des" +CONFIG_CRYPTPW=y +CONFIG_MKPASSWD=y +CONFIG_DELUSER=y +CONFIG_DELGROUP=y +CONFIG_FEATURE_DEL_USER_FROM_GROUP=y +CONFIG_GETTY=y +CONFIG_LOGIN=y +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +CONFIG_LOGIN_SCRIPTS=y +# CONFIG_FEATURE_NOLOGIN is not set +CONFIG_FEATURE_SECURETTY=y +CONFIG_PASSWD=y +CONFIG_FEATURE_PASSWD_WEAK_CHECK=y +CONFIG_SU=y +CONFIG_FEATURE_SU_SYSLOG=y +CONFIG_FEATURE_SU_CHECKS_SHELLS=y +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +CONFIG_SULOGIN=y +CONFIG_VLOCK=y + +# +# Linux Ext2 FS Progs +# +CONFIG_CHATTR=y +CONFIG_FSCK=y +CONFIG_LSATTR=y +CONFIG_TUNE2FS=y + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +CONFIG_DEPMOD=y +CONFIG_INSMOD=y +CONFIG_LSMOD=y +CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y +CONFIG_MODINFO=y +CONFIG_MODPROBE=y +CONFIG_FEATURE_MODPROBE_BLACKLIST=y +CONFIG_RMMOD=y + +# +# Options common to multiple modutils +# +CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS=y +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +CONFIG_FEATURE_CHECK_TAINTED_MODULE=y +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +CONFIG_FEATURE_MODUTILS_ALIAS=y +CONFIG_FEATURE_MODUTILS_SYMBOLS=y +CONFIG_DEFAULT_MODULES_DIR="/lib/modules" +CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" + +# +# Linux System Utilities +# +CONFIG_ACPID=y +CONFIG_FEATURE_ACPID_COMPAT=y +CONFIG_BLKDISCARD=y +CONFIG_BLKID=y +CONFIG_FEATURE_BLKID_TYPE=y +CONFIG_BLOCKDEV=y +CONFIG_CAL=y +CONFIG_CHRT=y +CONFIG_DMESG=y +CONFIG_FEATURE_DMESG_PRETTY=y +CONFIG_EJECT=y +CONFIG_FEATURE_EJECT_SCSI=y +# CONFIG_FALLOCATE is not set +CONFIG_FATATTR=y +CONFIG_FBSET=y +CONFIG_FEATURE_FBSET_FANCY=y +CONFIG_FEATURE_FBSET_READMODE=y +CONFIG_FDFORMAT=y +CONFIG_FDISK=y +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +CONFIG_FEATURE_FDISK_WRITABLE=y +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +CONFIG_FEATURE_FDISK_ADVANCED=y +CONFIG_FINDFS=y +CONFIG_FLOCK=y +CONFIG_FDFLUSH=y +CONFIG_FREERAMDISK=y +CONFIG_FSCK_MINIX=y +CONFIG_FSFREEZE=y +CONFIG_FSTRIM=y +CONFIG_GETOPT=y +CONFIG_FEATURE_GETOPT_LONG=y +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +CONFIG_HD=y +CONFIG_XXD=y +CONFIG_HWCLOCK=y +CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS=y +CONFIG_IONICE=y +CONFIG_IPCRM=y +CONFIG_IPCS=y +CONFIG_LAST=y +CONFIG_FEATURE_LAST_FANCY=y +CONFIG_LOSETUP=y +CONFIG_LSPCI=y +CONFIG_LSUSB=y +CONFIG_MDEV=y +CONFIG_FEATURE_MDEV_CONF=y +CONFIG_FEATURE_MDEV_RENAME=y +CONFIG_FEATURE_MDEV_RENAME_REGEXP=y +CONFIG_FEATURE_MDEV_EXEC=y +CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y +CONFIG_MESG=y +CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y +CONFIG_MKE2FS=y +CONFIG_MKFS_EXT2=y +CONFIG_MKFS_MINIX=y +CONFIG_FEATURE_MINIX2=y +# CONFIG_MKFS_REISER is not set +CONFIG_MKDOSFS=y +CONFIG_MKFS_VFAT=y +CONFIG_MKSWAP=y +CONFIG_FEATURE_MKSWAP_UUID=y +CONFIG_MORE=y +CONFIG_MOUNT=y +CONFIG_FEATURE_MOUNT_FAKE=y +CONFIG_FEATURE_MOUNT_VERBOSE=y +CONFIG_FEATURE_MOUNT_HELPERS=y +CONFIG_FEATURE_MOUNT_LABEL=y +CONFIG_FEATURE_MOUNT_NFS=y +CONFIG_FEATURE_MOUNT_CIFS=y +CONFIG_FEATURE_MOUNT_FLAGS=y +CONFIG_FEATURE_MOUNT_FSTAB=y +CONFIG_FEATURE_MOUNT_OTHERTAB=y +CONFIG_MOUNTPOINT=y +CONFIG_NOLOGIN=y +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +CONFIG_PIVOT_ROOT=y +CONFIG_RDATE=y +CONFIG_RDEV=y +CONFIG_READPROFILE=y +CONFIG_RENICE=y +CONFIG_REV=y +CONFIG_RTCWAKE=y +CONFIG_SCRIPT=y +CONFIG_SCRIPTREPLAY=y +CONFIG_SETARCH=y +CONFIG_LINUX32=y +CONFIG_LINUX64=y +CONFIG_SETPRIV=y +CONFIG_FEATURE_SETPRIV_DUMP=y +CONFIG_FEATURE_SETPRIV_CAPABILITIES=y +CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES=y +CONFIG_SETSID=y +CONFIG_SWAPON=y +CONFIG_FEATURE_SWAPON_DISCARD=y +CONFIG_FEATURE_SWAPON_PRI=y +CONFIG_SWAPOFF=y +CONFIG_FEATURE_SWAPONOFF_LABEL=y +CONFIG_SWITCH_ROOT=y +CONFIG_TASKSET=y +CONFIG_FEATURE_TASKSET_FANCY=y +CONFIG_UEVENT=y +CONFIG_UMOUNT=y +CONFIG_FEATURE_UMOUNT_ALL=y +# CONFIG_UNSHARE is not set +CONFIG_WALL=y + +# +# Common options for mount/umount +# +CONFIG_FEATURE_MOUNT_LOOP=y +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +CONFIG_VOLUMEID=y + +# +# Filesystem/Volume identification +# +CONFIG_FEATURE_VOLUMEID_BCACHE=y +CONFIG_FEATURE_VOLUMEID_BTRFS=y +CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_EXFAT=y +CONFIG_FEATURE_VOLUMEID_EXT=y +CONFIG_FEATURE_VOLUMEID_F2FS=y +CONFIG_FEATURE_VOLUMEID_FAT=y +CONFIG_FEATURE_VOLUMEID_HFS=y +CONFIG_FEATURE_VOLUMEID_ISO9660=y +CONFIG_FEATURE_VOLUMEID_JFS=y +CONFIG_FEATURE_VOLUMEID_LFS=y +CONFIG_FEATURE_VOLUMEID_LINUXRAID=y +CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y +CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_MINIX=y +CONFIG_FEATURE_VOLUMEID_NILFS=y +CONFIG_FEATURE_VOLUMEID_NTFS=y +CONFIG_FEATURE_VOLUMEID_OCFS2=y +CONFIG_FEATURE_VOLUMEID_REISERFS=y +CONFIG_FEATURE_VOLUMEID_ROMFS=y +CONFIG_FEATURE_VOLUMEID_SQUASHFS=y +CONFIG_FEATURE_VOLUMEID_SYSV=y +CONFIG_FEATURE_VOLUMEID_UBIFS=y +CONFIG_FEATURE_VOLUMEID_UDF=y +CONFIG_FEATURE_VOLUMEID_XFS=y + +# +# Miscellaneous Utilities +# +CONFIG_ADJTIMEX=y +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +CONFIG_BC=y +CONFIG_DC=y +CONFIG_FEATURE_DC_BIG=y +# CONFIG_FEATURE_DC_LIBM is not set +CONFIG_FEATURE_BC_INTERACTIVE=y +CONFIG_FEATURE_BC_LONG_OPTIONS=y +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +CONFIG_CHAT=y +CONFIG_FEATURE_CHAT_NOFAIL=y +CONFIG_FEATURE_CHAT_TTY_HIFI=y +CONFIG_FEATURE_CHAT_IMPLICIT_CR=y +CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y +CONFIG_FEATURE_CHAT_SEND_ESCAPES=y +CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y +CONFIG_FEATURE_CHAT_CLR_ABORT=y +CONFIG_CONSPY=y +CONFIG_CROND=y +CONFIG_FEATURE_CROND_D=y +CONFIG_FEATURE_CROND_CALL_SENDMAIL=y +CONFIG_FEATURE_CROND_SPECIAL_TIMES=y +CONFIG_FEATURE_CROND_DIR="/var/spool/cron" +CONFIG_CRONTAB=y +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +CONFIG_DEVMEM=y +CONFIG_FBSPLASH=y +CONFIG_FLASHCP=y +CONFIG_FLASH_ERASEALL=y +CONFIG_FLASH_LOCK=y +CONFIG_FLASH_UNLOCK=y +CONFIG_HDPARM=y +CONFIG_FEATURE_HDPARM_GET_IDENTITY=y +CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y +CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y +CONFIG_HEXEDIT=y +CONFIG_I2CGET=y +CONFIG_I2CSET=y +CONFIG_I2CDUMP=y +CONFIG_I2CDETECT=y +CONFIG_INOTIFYD=y +CONFIG_LESS=y +CONFIG_FEATURE_LESS_MAXLINES=9999999 +CONFIG_FEATURE_LESS_BRACKETS=y +CONFIG_FEATURE_LESS_FLAGS=y +CONFIG_FEATURE_LESS_TRUNCATE=y +CONFIG_FEATURE_LESS_MARKS=y +CONFIG_FEATURE_LESS_REGEXP=y +CONFIG_FEATURE_LESS_WINCH=y +CONFIG_FEATURE_LESS_ASK_TERMINAL=y +CONFIG_FEATURE_LESS_DASHCMD=y +CONFIG_FEATURE_LESS_LINENUMS=y +CONFIG_FEATURE_LESS_RAW=y +CONFIG_FEATURE_LESS_ENV=y +CONFIG_LSSCSI=y +CONFIG_MAKEDEVS=y +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +CONFIG_FEATURE_MAKEDEVS_TABLE=y +CONFIG_MAN=y +CONFIG_MICROCOM=y +CONFIG_MT=y +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +CONFIG_PARTPROBE=y +CONFIG_RAIDAUTORUN=y +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +CONFIG_RUNLEVEL=y +CONFIG_RX=y +CONFIG_SETFATTR=y +CONFIG_SETSERIAL=y +CONFIG_STRINGS=y +CONFIG_TIME=y +CONFIG_TTYSIZE=y +CONFIG_UBIRENAME=y +CONFIG_UBIATTACH=y +CONFIG_UBIDETACH=y +CONFIG_UBIMKVOL=y +CONFIG_UBIRMVOL=y +CONFIG_UBIRSVOL=y +CONFIG_UBIUPDATEVOL=y +CONFIG_VOLNAME=y +CONFIG_WATCHDOG=y + +# +# Networking Utilities +# +CONFIG_FEATURE_IPV6=y +# CONFIG_FEATURE_UNIX_LOCAL is not set +CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y +CONFIG_VERBOSE_RESOLUTION_ERRORS=y +CONFIG_FEATURE_TLS_SHA1=y +CONFIG_ARP=y +CONFIG_ARPING=y +CONFIG_BRCTL=y +CONFIG_FEATURE_BRCTL_FANCY=y +CONFIG_FEATURE_BRCTL_SHOW=y +CONFIG_DNSD=y +# CONFIG_ETHER_WAKE is not set +CONFIG_FTPD=y +CONFIG_FEATURE_FTPD_WRITE=y +CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y +CONFIG_FEATURE_FTPD_AUTHENTICATION=y +CONFIG_FTPGET=y +CONFIG_FTPPUT=y +CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS=y +CONFIG_HOSTNAME=y +CONFIG_DNSDOMAINNAME=y +CONFIG_HTTPD=y +CONFIG_FEATURE_HTTPD_RANGES=y +CONFIG_FEATURE_HTTPD_SETUID=y +CONFIG_FEATURE_HTTPD_BASIC_AUTH=y +CONFIG_FEATURE_HTTPD_AUTH_MD5=y +CONFIG_FEATURE_HTTPD_CGI=y +CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y +CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y +CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y +CONFIG_FEATURE_HTTPD_ERROR_PAGES=y +CONFIG_FEATURE_HTTPD_PROXY=y +CONFIG_FEATURE_HTTPD_GZIP=y +CONFIG_IFCONFIG=y +CONFIG_FEATURE_IFCONFIG_STATUS=y +CONFIG_FEATURE_IFCONFIG_SLIP=y +CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ=y +CONFIG_FEATURE_IFCONFIG_HW=y +CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y +CONFIG_IFENSLAVE=y +CONFIG_IFPLUGD=y +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +CONFIG_INETD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN=y +CONFIG_FEATURE_INETD_RPC=y +CONFIG_IP=y +CONFIG_IPADDR=y +CONFIG_IPLINK=y +CONFIG_IPROUTE=y +CONFIG_IPTUNNEL=y +CONFIG_IPRULE=y +CONFIG_IPNEIGH=y +CONFIG_FEATURE_IP_ADDRESS=y +CONFIG_FEATURE_IP_LINK=y +CONFIG_FEATURE_IP_ROUTE=y +CONFIG_FEATURE_IP_ROUTE_DIR="/etc/iproute2" +CONFIG_FEATURE_IP_TUNNEL=y +CONFIG_FEATURE_IP_RULE=y +CONFIG_FEATURE_IP_NEIGH=y +CONFIG_FEATURE_IP_RARE_PROTOCOLS=y +CONFIG_IPCALC=y +CONFIG_FEATURE_IPCALC_LONG_OPTIONS=y +CONFIG_FEATURE_IPCALC_FANCY=y +CONFIG_FAKEIDENTD=y +CONFIG_NAMEIF=y +CONFIG_FEATURE_NAMEIF_EXTENDED=y +CONFIG_NBDCLIENT=y +CONFIG_NC=y +# CONFIG_NETCAT is not set +CONFIG_NC_SERVER=y +CONFIG_NC_EXTRA=y +CONFIG_NC_110_COMPAT=y +CONFIG_NETSTAT=y +CONFIG_FEATURE_NETSTAT_WIDE=y +CONFIG_FEATURE_NETSTAT_PRG=y +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +CONFIG_NTPD=y +CONFIG_FEATURE_NTPD_SERVER=y +# CONFIG_FEATURE_NTPD_CONF is not set +CONFIG_FEATURE_NTP_AUTH=y +CONFIG_PING=y +CONFIG_PING6=y +CONFIG_FEATURE_FANCY_PING=y +CONFIG_PSCAN=y +CONFIG_ROUTE=y +CONFIG_SLATTACH=y +CONFIG_SSL_CLIENT=y +CONFIG_TC=y +CONFIG_FEATURE_TC_INGRESS=y +CONFIG_TCPSVD=y +CONFIG_UDPSVD=y +CONFIG_TELNET=y +CONFIG_FEATURE_TELNET_TTYPE=y +CONFIG_FEATURE_TELNET_AUTOLOGIN=y +CONFIG_FEATURE_TELNET_WIDTH=y +CONFIG_TELNETD=y +CONFIG_FEATURE_TELNETD_STANDALONE=y +CONFIG_FEATURE_TELNETD_INETD_WAIT=y +CONFIG_TFTP=y +CONFIG_FEATURE_TFTP_PROGRESS_BAR=y +CONFIG_TFTPD=y +CONFIG_FEATURE_TFTP_GET=y +CONFIG_FEATURE_TFTP_PUT=y +CONFIG_FEATURE_TFTP_BLOCKSIZE=y +# CONFIG_TFTP_DEBUG is not set +CONFIG_TLS=y +CONFIG_TRACEROUTE=y +CONFIG_TRACEROUTE6=y +CONFIG_FEATURE_TRACEROUTE_VERBOSE=y +CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y +CONFIG_TUNCTL=y +CONFIG_FEATURE_TUNCTL_UG=y +CONFIG_VCONFIG=y +CONFIG_WGET=y +CONFIG_FEATURE_WGET_LONG_OPTIONS=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_TIMEOUT=y +CONFIG_FEATURE_WGET_HTTPS=y +CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_WHOIS=y +CONFIG_ZCIP=y +CONFIG_UDHCPD=y +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY=y +CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases" +CONFIG_DUMPLEASES=y +CONFIG_DHCPRELAY=y +CONFIG_UDHCPC=y +CONFIG_FEATURE_UDHCPC_ARPING=y +CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y +CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set + +# +# Common options for DHCP applets +# +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=9 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 +CONFIG_FEATURE_UDHCP_RFC3397=y +CONFIG_FEATURE_UDHCP_8021Q=y +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +CONFIG_LPD=y +CONFIG_LPR=y +CONFIG_LPQ=y + +# +# Mail Utilities +# +CONFIG_MAKEMIME=y +CONFIG_POPMAILDIR=y +CONFIG_FEATURE_POPMAILDIR_DELIVERY=y +CONFIG_REFORMIME=y +CONFIG_FEATURE_REFORMIME_COMPAT=y +CONFIG_SENDMAIL=y +CONFIG_FEATURE_MIME_CHARSET="us-ascii" + +# +# Process Utilities +# +CONFIG_FREE=y +CONFIG_FUSER=y +CONFIG_IOSTAT=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_KILLALL5=y +CONFIG_LSOF=y +CONFIG_MPSTAT=y +CONFIG_NMETER=y +CONFIG_PGREP=y +CONFIG_PKILL=y +CONFIG_PIDOF=y +CONFIG_FEATURE_PIDOF_SINGLE=y +CONFIG_FEATURE_PIDOF_OMIT=y +CONFIG_PMAP=y +CONFIG_POWERTOP=y +CONFIG_FEATURE_POWERTOP_INTERACTIVE=y +CONFIG_PS=y +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +CONFIG_FEATURE_PS_TIME=y +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y +CONFIG_PSTREE=y +CONFIG_PWDX=y +CONFIG_SMEMCAP=y +CONFIG_BB_SYSCTL=y +CONFIG_TOP=y +CONFIG_FEATURE_TOP_INTERACTIVE=y +CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y +CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y +CONFIG_FEATURE_TOP_SMP_CPU=y +# CONFIG_FEATURE_TOP_DECIMALS is not set +CONFIG_FEATURE_TOP_SMP_PROCESS=y +CONFIG_FEATURE_TOPMEM=y +CONFIG_UPTIME=y +CONFIG_FEATURE_UPTIME_UTMP_SUPPORT=y +CONFIG_WATCH=y +CONFIG_FEATURE_SHOW_THREADS=y + +# +# Runit Utilities +# +CONFIG_CHPST=y +CONFIG_SETUIDGID=y +CONFIG_ENVUIDGID=y +CONFIG_ENVDIR=y +CONFIG_SOFTLIMIT=y +CONFIG_RUNSV=y +CONFIG_RUNSVDIR=y +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +CONFIG_SV=y +CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" +CONFIG_SVC=y +CONFIG_SVOK=y +CONFIG_SVLOGD=y +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y +CONFIG_ASH_BASH_COMPAT=y +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +CONFIG_ASH_BASH_NOT_FOUND_HOOK=y +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_ASH_IDLE_TIMEOUT=y +CONFIG_ASH_MAIL=y +CONFIG_ASH_ECHO=y +CONFIG_ASH_PRINTF=y +CONFIG_ASH_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y +CONFIG_CTTYHACK=y +CONFIG_HUSH=y +CONFIG_HUSH_BASH_COMPAT=y +CONFIG_HUSH_BRACE_EXPANSION=y +CONFIG_HUSH_LINENO_VAR=y +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +CONFIG_HUSH_INTERACTIVE=y +CONFIG_HUSH_SAVEHISTORY=y +CONFIG_HUSH_JOB=y +CONFIG_HUSH_TICK=y +CONFIG_HUSH_IF=y +CONFIG_HUSH_LOOPS=y +CONFIG_HUSH_CASE=y +CONFIG_HUSH_FUNCTIONS=y +CONFIG_HUSH_LOCAL=y +CONFIG_HUSH_RANDOM_SUPPORT=y +CONFIG_HUSH_MODE_X=y +CONFIG_HUSH_ECHO=y +CONFIG_HUSH_PRINTF=y +CONFIG_HUSH_TEST=y +CONFIG_HUSH_HELP=y +CONFIG_HUSH_EXPORT=y +CONFIG_HUSH_EXPORT_N=y +CONFIG_HUSH_READONLY=y +CONFIG_HUSH_KILL=y +CONFIG_HUSH_WAIT=y +CONFIG_HUSH_COMMAND=y +CONFIG_HUSH_TRAP=y +CONFIG_HUSH_TYPE=y +CONFIG_HUSH_TIMES=y +CONFIG_HUSH_READ=y +CONFIG_HUSH_SET=y +CONFIG_HUSH_UNSET=y +CONFIG_HUSH_ULIMIT=y +CONFIG_HUSH_UMASK=y +CONFIG_HUSH_GETOPTS=y +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +CONFIG_FEATURE_SH_READ_FRAC=y +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS=y + +# +# System Logging Utilities +# +CONFIG_KLOGD=y +CONFIG_FEATURE_KLOGD_KLOGCTL=y +CONFIG_LOGGER=y +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +CONFIG_SYSLOGD=y +CONFIG_FEATURE_ROTATE_LOGFILE=y +CONFIG_FEATURE_REMOTE_LOG=y +CONFIG_FEATURE_SYSLOGD_DUP=y +CONFIG_FEATURE_SYSLOGD_CFG=y +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/mips64el_ash.config b/BUSYBOX/mips64el_ash.config new file mode 100644 index 00000000..8354db85 --- /dev/null +++ b/BUSYBOX/mips64el_ash.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Thu Mar 4 12:59:59 2021 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +CONFIG_ASH=y +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/mips64el_hexdump.config b/BUSYBOX/mips64el_hexdump.config new file mode 100644 index 00000000..70cfa69d --- /dev/null +++ b/BUSYBOX/mips64el_hexdump.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Thu Mar 4 13:08:09 2021 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/mips64el_xzcat.config b/BUSYBOX/mips64el_xzcat.config new file mode 100644 index 00000000..8a192d33 --- /dev/null +++ b/BUSYBOX/mips64el_xzcat.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Thu Mar 4 13:03:19 2021 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +CONFIG_XZCAT=y +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/x86_64_ash.config b/BUSYBOX/x86_64_ash.config new file mode 100644 index 00000000..32854774 --- /dev/null +++ b/BUSYBOX/x86_64_ash.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Fri Aug 7 05:44:56 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +CONFIG_FEATURE_FANCY_ECHO=y +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +CONFIG_FEATURE_TEST_64=y +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +CONFIG_SHELL_ASH=y +CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y +CONFIG_ASH_BASH_COMPAT=y +CONFIG_ASH_BASH_SOURCE_CURDIR=y +CONFIG_ASH_BASH_NOT_FOUND_HOOK=y +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_ASH_IDLE_TIMEOUT=y +CONFIG_ASH_MAIL=y +CONFIG_ASH_ECHO=y +CONFIG_ASH_PRINTF=y +CONFIG_ASH_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y +CONFIG_CTTYHACK=y +CONFIG_HUSH=y +CONFIG_SHELL_HUSH=y +CONFIG_HUSH_BASH_COMPAT=y +CONFIG_HUSH_BRACE_EXPANSION=y +CONFIG_HUSH_LINENO_VAR=y +CONFIG_HUSH_BASH_SOURCE_CURDIR=y +CONFIG_HUSH_INTERACTIVE=y +# CONFIG_HUSH_SAVEHISTORY is not set +CONFIG_HUSH_JOB=y +CONFIG_HUSH_TICK=y +CONFIG_HUSH_IF=y +CONFIG_HUSH_LOOPS=y +CONFIG_HUSH_CASE=y +CONFIG_HUSH_FUNCTIONS=y +CONFIG_HUSH_LOCAL=y +CONFIG_HUSH_RANDOM_SUPPORT=y +CONFIG_HUSH_MODE_X=y +CONFIG_HUSH_ECHO=y +CONFIG_HUSH_PRINTF=y +CONFIG_HUSH_TEST=y +CONFIG_HUSH_HELP=y +CONFIG_HUSH_EXPORT=y +CONFIG_HUSH_EXPORT_N=y +CONFIG_HUSH_READONLY=y +CONFIG_HUSH_KILL=y +CONFIG_HUSH_WAIT=y +CONFIG_HUSH_COMMAND=y +CONFIG_HUSH_TRAP=y +CONFIG_HUSH_TYPE=y +CONFIG_HUSH_TIMES=y +CONFIG_HUSH_READ=y +CONFIG_HUSH_SET=y +CONFIG_HUSH_UNSET=y +CONFIG_HUSH_ULIMIT=y +CONFIG_HUSH_UMASK=y +CONFIG_HUSH_GETOPTS=y +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y +CONFIG_FEATURE_SH_MATH_BASE=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +CONFIG_FEATURE_SH_STANDALONE=y +CONFIG_FEATURE_SH_NOFORK=y +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/x86_64_hexdump.config b/BUSYBOX/x86_64_hexdump.config new file mode 100644 index 00000000..d13aa42b --- /dev/null +++ b/BUSYBOX/x86_64_hexdump.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 03:03:31 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +# CONFIG_XZCAT is not set +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_WHOAMI is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_FLASHCP is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_UBIRENAME is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/BUSYBOX/x86_64_xzcat.config b/BUSYBOX/x86_64_xzcat.config new file mode 100644 index 00000000..cd4361d6 --- /dev/null +++ b/BUSYBOX/x86_64_xzcat.config @@ -0,0 +1,1166 @@ +# +# Automatically generated make config: don't edit +# Busybox version: 1.32.0 +# Tue Dec 8 11:07:46 2020 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Settings +# +# CONFIG_DESKTOP is not set +# CONFIG_EXTRA_COMPAT is not set +# CONFIG_FEDORA_COMPAT is not set +# CONFIG_INCLUDE_SUSv2 is not set +# CONFIG_LONG_OPTS is not set +# CONFIG_SHOW_USAGE is not set +# CONFIG_FEATURE_VERBOSE_USAGE is not set +# CONFIG_FEATURE_COMPRESS_USAGE is not set +# CONFIG_LFS is not set +# CONFIG_PAM is not set +# CONFIG_FEATURE_DEVPTS is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +# CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" +# CONFIG_BUSYBOX is not set +# CONFIG_FEATURE_SHOW_SCRIPT is not set +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_FEATURE_SUID_CONFIG is not set +# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SYSLOG_INFO is not set +# CONFIG_FEATURE_SYSLOG is not set +# CONFIG_PLATFORM_LINUX is not set + +# +# Build Options +# +CONFIG_STATIC=y +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_LIBBUSYBOX_STATIC is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="" +# CONFIG_USE_PORTABLE_CODE is not set +# CONFIG_STACK_OPTIMIZATION_386 is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +# CONFIG_WARN_SIMPLE_MSG is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Library Tuning +# +# CONFIG_FEATURE_USE_BSS_TAIL is not set +# CONFIG_FLOAT_DURATION is not set +# CONFIG_FEATURE_RTMINMAX is not set +# CONFIG_FEATURE_RTMINMAX_USE_LIBC_DEFINITIONS is not set +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +# CONFIG_FEATURE_ETC_SERVICES is not set +# CONFIG_FEATURE_EDITING is not set +CONFIG_FEATURE_EDITING_MAX_LEN=0 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=0 +# CONFIG_FEATURE_EDITING_SAVEHISTORY is not set +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +# CONFIG_FEATURE_REVERSE_SEARCH is not set +# CONFIG_FEATURE_TAB_COMPLETION is not set +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +# CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set +# CONFIG_FEATURE_EDITING_WINCH is not set +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +# CONFIG_UNICODE_SUPPORT is not set +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=0 +CONFIG_LAST_SUPPORTED_WCHAR=0 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_FEATURE_NON_POSIX_CP is not set +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +# CONFIG_FEATURE_USE_SENDFILE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +# CONFIG_FEATURE_SKIP_ROOTFS is not set +# CONFIG_MONOTONIC_SYSCALL is not set +# CONFIG_IOCTL_HEX2STR_ERROR is not set +# CONFIG_FEATURE_HWIB is not set + +# +# Applets +# + +# +# Archival Utilities +# +# CONFIG_FEATURE_SEAMLESS_XZ is not set +# CONFIG_FEATURE_SEAMLESS_LZMA is not set +# CONFIG_FEATURE_SEAMLESS_BZ2 is not set +# CONFIG_FEATURE_SEAMLESS_GZ is not set +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_GUNZIP is not set +# CONFIG_ZCAT is not set +# CONFIG_FEATURE_GUNZIP_LONG_OPTIONS is not set +# CONFIG_BUNZIP2 is not set +# CONFIG_BZCAT is not set +# CONFIG_UNLZMA is not set +# CONFIG_LZCAT is not set +# CONFIG_LZMA is not set +# CONFIG_UNXZ is not set +CONFIG_XZCAT=y +# CONFIG_XZ is not set +# CONFIG_BZIP2 is not set +CONFIG_BZIP2_SMALL=0 +# CONFIG_FEATURE_BZIP2_DECOMPRESS is not set +# CONFIG_CPIO is not set +# CONFIG_FEATURE_CPIO_O is not set +# CONFIG_FEATURE_CPIO_P is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +# CONFIG_GZIP is not set +# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +# CONFIG_FEATURE_GZIP_DECOMPRESS is not set +# CONFIG_LZOP is not set +# CONFIG_UNLZOP is not set +# CONFIG_LZOPCAT is not set +# CONFIG_LZOP_COMPR_HIGH is not set +# CONFIG_RPM is not set +# CONFIG_RPM2CPIO is not set +# CONFIG_TAR is not set +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_FEATURE_TAR_CREATE is not set +# CONFIG_FEATURE_TAR_AUTODETECT is not set +# CONFIG_FEATURE_TAR_FROM is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set +# CONFIG_FEATURE_TAR_GNU_EXTENSIONS is not set +# CONFIG_FEATURE_TAR_TO_COMMAND is not set +# CONFIG_FEATURE_TAR_UNAME_GNAME is not set +# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set +# CONFIG_FEATURE_TAR_SELINUX is not set +# CONFIG_UNZIP is not set +# CONFIG_FEATURE_UNZIP_CDF is not set +# CONFIG_FEATURE_UNZIP_BZIP2 is not set +# CONFIG_FEATURE_UNZIP_LZMA is not set +# CONFIG_FEATURE_UNZIP_XZ is not set +# CONFIG_FEATURE_LZMA_FAST is not set + +# +# Coreutils +# +# CONFIG_BASENAME is not set +# CONFIG_CAT is not set +# CONFIG_FEATURE_CATN is not set +# CONFIG_FEATURE_CATV is not set +# CONFIG_CHGRP is not set +# CONFIG_CHMOD is not set +# CONFIG_CHOWN is not set +# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set +# CONFIG_CHROOT is not set +# CONFIG_CKSUM is not set +# CONFIG_COMM is not set +# CONFIG_CP is not set +# CONFIG_FEATURE_CP_LONG_OPTIONS is not set +# CONFIG_FEATURE_CP_REFLINK is not set +# CONFIG_CUT is not set +# CONFIG_DATE is not set +# CONFIG_FEATURE_DATE_ISOFMT is not set +# CONFIG_FEATURE_DATE_NANO is not set +# CONFIG_FEATURE_DATE_COMPAT is not set +# CONFIG_DD is not set +# CONFIG_FEATURE_DD_SIGNAL_HANDLING is not set +# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set +# CONFIG_FEATURE_DD_IBS_OBS is not set +# CONFIG_FEATURE_DD_STATUS is not set +# CONFIG_DF is not set +# CONFIG_FEATURE_DF_FANCY is not set +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_UNIX2DOS is not set +# CONFIG_DU is not set +# CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K is not set +# CONFIG_ECHO is not set +# CONFIG_FEATURE_FANCY_ECHO is not set +# CONFIG_ENV is not set +# CONFIG_EXPAND is not set +# CONFIG_UNEXPAND is not set +# CONFIG_EXPR is not set +# CONFIG_EXPR_MATH_SUPPORT_64 is not set +# CONFIG_FACTOR is not set +# CONFIG_FALSE is not set +# CONFIG_FOLD is not set +# CONFIG_HEAD is not set +# CONFIG_FEATURE_FANCY_HEAD is not set +# CONFIG_HOSTID is not set +# CONFIG_ID is not set +# CONFIG_GROUPS is not set +# CONFIG_INSTALL is not set +# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set +# CONFIG_LINK is not set +# CONFIG_LN is not set +# CONFIG_LOGNAME is not set +# CONFIG_LS is not set +# CONFIG_FEATURE_LS_FILETYPES is not set +# CONFIG_FEATURE_LS_FOLLOWLINKS is not set +# CONFIG_FEATURE_LS_RECURSIVE is not set +# CONFIG_FEATURE_LS_WIDTH is not set +# CONFIG_FEATURE_LS_SORTFILES is not set +# CONFIG_FEATURE_LS_TIMESTAMPS is not set +# CONFIG_FEATURE_LS_USERNAME is not set +# CONFIG_FEATURE_LS_COLOR is not set +# CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set +# CONFIG_MD5SUM is not set +# CONFIG_SHA1SUM is not set +# CONFIG_SHA256SUM is not set +# CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set +# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set +# CONFIG_MKDIR is not set +# CONFIG_MKFIFO is not set +# CONFIG_MKNOD is not set +# CONFIG_MKTEMP is not set +# CONFIG_MV is not set +# CONFIG_NICE is not set +# CONFIG_NL is not set +# CONFIG_NOHUP is not set +# CONFIG_NPROC is not set +# CONFIG_OD is not set +# CONFIG_PASTE is not set +# CONFIG_PRINTENV is not set +# CONFIG_PRINTF is not set +# CONFIG_PWD is not set +# CONFIG_READLINK is not set +# CONFIG_FEATURE_READLINK_FOLLOW is not set +# CONFIG_REALPATH is not set +# CONFIG_RM is not set +# CONFIG_RMDIR is not set +# CONFIG_SEQ is not set +# CONFIG_SHRED is not set +# CONFIG_SHUF is not set +# CONFIG_SLEEP is not set +# CONFIG_FEATURE_FANCY_SLEEP is not set +# CONFIG_SORT is not set +# CONFIG_FEATURE_SORT_BIG is not set +# CONFIG_FEATURE_SORT_OPTIMIZE_MEMORY is not set +# CONFIG_SPLIT is not set +# CONFIG_FEATURE_SPLIT_FANCY is not set +# CONFIG_STAT is not set +# CONFIG_FEATURE_STAT_FORMAT is not set +# CONFIG_FEATURE_STAT_FILESYSTEM is not set +# CONFIG_STTY is not set +# CONFIG_SUM is not set +# CONFIG_SYNC is not set +# CONFIG_FEATURE_SYNC_FANCY is not set +# CONFIG_FSYNC is not set +# CONFIG_TAC is not set +# CONFIG_TAIL is not set +# CONFIG_FEATURE_FANCY_TAIL is not set +# CONFIG_TEE is not set +# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set +# CONFIG_TEST is not set +# CONFIG_TEST1 is not set +# CONFIG_TEST2 is not set +# CONFIG_FEATURE_TEST_64 is not set +# CONFIG_TIMEOUT is not set +# CONFIG_TOUCH is not set +# CONFIG_FEATURE_TOUCH_NODEREF is not set +# CONFIG_FEATURE_TOUCH_SUSV3 is not set +# CONFIG_TR is not set +# CONFIG_FEATURE_TR_CLASSES is not set +# CONFIG_FEATURE_TR_EQUIV is not set +# CONFIG_TRUE is not set +# CONFIG_TRUNCATE is not set +# CONFIG_TTY is not set +# CONFIG_UNAME is not set +CONFIG_UNAME_OSNAME="" +# CONFIG_BB_ARCH is not set +# CONFIG_UNIQ is not set +# CONFIG_UNLINK is not set +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_BASE64 is not set +# CONFIG_UUENCODE is not set +# CONFIG_WC is not set +# CONFIG_FEATURE_WC_LARGE is not set +# CONFIG_WHOAMI is not set +# CONFIG_WHO is not set +# CONFIG_W is not set +# CONFIG_USERS is not set +# CONFIG_YES is not set + +# +# Common options +# +# CONFIG_FEATURE_VERBOSE is not set +# CONFIG_FEATURE_PRESERVE_HARDLINKS is not set +# CONFIG_FEATURE_HUMAN_READABLE is not set + +# +# Console Utilities +# +# CONFIG_CHVT is not set +# CONFIG_CLEAR is not set +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_FGCONSOLE is not set +# CONFIG_KBD_MODE is not set +# CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +# CONFIG_RESET is not set +# CONFIG_RESIZE is not set +# CONFIG_FEATURE_RESIZE_PRINT is not set +# CONFIG_SETCONSOLE is not set +# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set +# CONFIG_SETKEYCODES is not set +# CONFIG_SETLOGCONS is not set +# CONFIG_SHOWKEY is not set + +# +# Debian Utilities +# +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_RUN_PARTS is not set +# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set +# CONFIG_FEATURE_RUN_PARTS_FANCY is not set +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set +# CONFIG_WHICH is not set + +# +# klibc-utils +# +# CONFIG_MINIPS is not set +# CONFIG_NUKE is not set +# CONFIG_RESUME is not set +# CONFIG_RUN_INIT is not set + +# +# Editors +# +# CONFIG_AWK is not set +# CONFIG_FEATURE_AWK_LIBM is not set +# CONFIG_FEATURE_AWK_GNU_EXTENSIONS is not set +# CONFIG_CMP is not set +# CONFIG_DIFF is not set +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +# CONFIG_FEATURE_DIFF_DIR is not set +# CONFIG_ED is not set +# CONFIG_PATCH is not set +# CONFIG_SED is not set +# CONFIG_VI is not set +CONFIG_FEATURE_VI_MAX_LEN=0 +# CONFIG_FEATURE_VI_8BIT is not set +# CONFIG_FEATURE_VI_COLON is not set +# CONFIG_FEATURE_VI_YANKMARK is not set +# CONFIG_FEATURE_VI_SEARCH is not set +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +# CONFIG_FEATURE_VI_USE_SIGNALS is not set +# CONFIG_FEATURE_VI_DOT_CMD is not set +# CONFIG_FEATURE_VI_READONLY is not set +# CONFIG_FEATURE_VI_SETOPTS is not set +# CONFIG_FEATURE_VI_SET is not set +# CONFIG_FEATURE_VI_WIN_RESIZE is not set +# CONFIG_FEATURE_VI_ASK_TERMINAL is not set +# CONFIG_FEATURE_VI_UNDO is not set +# CONFIG_FEATURE_VI_UNDO_QUEUE is not set +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=0 +# CONFIG_FEATURE_ALLOW_EXEC is not set + +# +# Finding Utilities +# +# CONFIG_FIND is not set +# CONFIG_FEATURE_FIND_PRINT0 is not set +# CONFIG_FEATURE_FIND_MTIME is not set +# CONFIG_FEATURE_FIND_MMIN is not set +# CONFIG_FEATURE_FIND_PERM is not set +# CONFIG_FEATURE_FIND_TYPE is not set +# CONFIG_FEATURE_FIND_EXECUTABLE is not set +# CONFIG_FEATURE_FIND_XDEV is not set +# CONFIG_FEATURE_FIND_MAXDEPTH is not set +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +# CONFIG_FEATURE_FIND_EXEC is not set +# CONFIG_FEATURE_FIND_EXEC_PLUS is not set +# CONFIG_FEATURE_FIND_USER is not set +# CONFIG_FEATURE_FIND_GROUP is not set +# CONFIG_FEATURE_FIND_NOT is not set +# CONFIG_FEATURE_FIND_DEPTH is not set +# CONFIG_FEATURE_FIND_PAREN is not set +# CONFIG_FEATURE_FIND_SIZE is not set +# CONFIG_FEATURE_FIND_PRUNE is not set +# CONFIG_FEATURE_FIND_QUIT is not set +# CONFIG_FEATURE_FIND_DELETE is not set +# CONFIG_FEATURE_FIND_EMPTY is not set +# CONFIG_FEATURE_FIND_PATH is not set +# CONFIG_FEATURE_FIND_REGEX is not set +# CONFIG_FEATURE_FIND_CONTEXT is not set +# CONFIG_FEATURE_FIND_LINKS is not set +# CONFIG_GREP is not set +# CONFIG_EGREP is not set +# CONFIG_FGREP is not set +# CONFIG_FEATURE_GREP_CONTEXT is not set +# CONFIG_XARGS is not set +# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set +# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set +# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set +# CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR is not set +# CONFIG_FEATURE_XARGS_SUPPORT_PARALLEL is not set +# CONFIG_FEATURE_XARGS_SUPPORT_ARGS_FILE is not set + +# +# Init Utilities +# +# CONFIG_BOOTCHARTD is not set +# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set +# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +# CONFIG_REBOOT is not set +# CONFIG_FEATURE_WAIT_FOR_INIT is not set +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +# CONFIG_INIT is not set +# CONFIG_LINUXRC is not set +# CONFIG_FEATURE_USE_INITTAB is not set +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +# CONFIG_FEATURE_INIT_SCTTY is not set +# CONFIG_FEATURE_INIT_SYSLOG is not set +# CONFIG_FEATURE_INIT_QUIET is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +CONFIG_INIT_TERMINAL_TYPE="" +# CONFIG_FEATURE_INIT_MODIFY_CMDLINE is not set + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +# CONFIG_USE_BB_CRYPT is not set +# CONFIG_USE_BB_CRYPT_SHA is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +# CONFIG_MKPASSWD is not set +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +# CONFIG_LOGIN_SCRIPTS is not set +# CONFIG_FEATURE_NOLOGIN is not set +# CONFIG_FEATURE_SECURETTY is not set +# CONFIG_PASSWD is not set +# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set +# CONFIG_SU is not set +# CONFIG_FEATURE_SU_SYSLOG is not set +# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set +# CONFIG_FEATURE_SU_BLANK_PW_NEEDS_SECURE_TTY is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Linux Ext2 FS Progs +# +# CONFIG_CHATTR is not set +# CONFIG_FSCK is not set +# CONFIG_LSATTR is not set +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +# CONFIG_MODPROBE_SMALL is not set +# CONFIG_DEPMOD is not set +# CONFIG_INSMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODINFO is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_RMMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_CMDLINE_MODULE_OPTIONS is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="" +CONFIG_DEFAULT_DEPMOD_FILE="" + +# +# Linux System Utilities +# +# CONFIG_ACPID is not set +# CONFIG_FEATURE_ACPID_COMPAT is not set +# CONFIG_BLKDISCARD is not set +# CONFIG_BLKID is not set +# CONFIG_FEATURE_BLKID_TYPE is not set +# CONFIG_BLOCKDEV is not set +# CONFIG_CAL is not set +# CONFIG_CHRT is not set +# CONFIG_DMESG is not set +# CONFIG_FEATURE_DMESG_PRETTY is not set +# CONFIG_EJECT is not set +# CONFIG_FEATURE_EJECT_SCSI is not set +# CONFIG_FALLOCATE is not set +# CONFIG_FATATTR is not set +# CONFIG_FBSET is not set +# CONFIG_FEATURE_FBSET_FANCY is not set +# CONFIG_FEATURE_FBSET_READMODE is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +# CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set +# CONFIG_FEATURE_FDISK_WRITABLE is not set +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +# CONFIG_FEATURE_FDISK_ADVANCED is not set +# CONFIG_FINDFS is not set +# CONFIG_FLOCK is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_FSFREEZE is not set +# CONFIG_FSTRIM is not set +# CONFIG_GETOPT is not set +# CONFIG_FEATURE_GETOPT_LONG is not set +# CONFIG_HEXDUMP is not set +# CONFIG_FEATURE_HEXDUMP_REVERSE is not set +# CONFIG_HD is not set +# CONFIG_XXD is not set +# CONFIG_HWCLOCK is not set +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IONICE is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +# CONFIG_LOSETUP is not set +# CONFIG_LSPCI is not set +# CONFIG_LSUSB is not set +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_FEATURE_MDEV_DAEMON is not set +# CONFIG_MESG is not set +# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set +# CONFIG_MKE2FS is not set +# CONFIG_MKFS_EXT2 is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +# CONFIG_MKDOSFS is not set +# CONFIG_MKFS_VFAT is not set +# CONFIG_MKSWAP is not set +# CONFIG_FEATURE_MKSWAP_UUID is not set +# CONFIG_MORE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set +# CONFIG_MOUNTPOINT is not set +# CONFIG_NOLOGIN is not set +# CONFIG_NOLOGIN_DEPENDENCIES is not set +# CONFIG_NSENTER is not set +# CONFIG_PIVOT_ROOT is not set +# CONFIG_RDATE is not set +# CONFIG_RDEV is not set +# CONFIG_READPROFILE is not set +# CONFIG_RENICE is not set +# CONFIG_REV is not set +# CONFIG_RTCWAKE is not set +# CONFIG_SCRIPT is not set +# CONFIG_SCRIPTREPLAY is not set +# CONFIG_SETARCH is not set +# CONFIG_LINUX32 is not set +# CONFIG_LINUX64 is not set +# CONFIG_SETPRIV is not set +# CONFIG_FEATURE_SETPRIV_DUMP is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITIES is not set +# CONFIG_FEATURE_SETPRIV_CAPABILITY_NAMES is not set +# CONFIG_SETSID is not set +# CONFIG_SWAPON is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +# CONFIG_SWAPOFF is not set +# CONFIG_FEATURE_SWAPONOFF_LABEL is not set +# CONFIG_SWITCH_ROOT is not set +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set +# CONFIG_FEATURE_TASKSET_CPULIST is not set +# CONFIG_UEVENT is not set +# CONFIG_UMOUNT is not set +# CONFIG_FEATURE_UMOUNT_ALL is not set +# CONFIG_UNSHARE is not set +# CONFIG_WALL is not set +# CONFIG_FEATURE_MOUNT_LOOP is not set +# CONFIG_FEATURE_MOUNT_LOOP_CREATE is not set +# CONFIG_FEATURE_MTAB_SUPPORT is not set +# CONFIG_VOLUMEID is not set +# CONFIG_FEATURE_VOLUMEID_BCACHE is not set +# CONFIG_FEATURE_VOLUMEID_BTRFS is not set +# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set +# CONFIG_FEATURE_VOLUMEID_EXFAT is not set +# CONFIG_FEATURE_VOLUMEID_EXT is not set +# CONFIG_FEATURE_VOLUMEID_F2FS is not set +# CONFIG_FEATURE_VOLUMEID_FAT is not set +# CONFIG_FEATURE_VOLUMEID_HFS is not set +# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set +# CONFIG_FEATURE_VOLUMEID_JFS is not set +# CONFIG_FEATURE_VOLUMEID_LFS is not set +# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set +# CONFIG_FEATURE_VOLUMEID_LINUXSWAP is not set +# CONFIG_FEATURE_VOLUMEID_LUKS is not set +# CONFIG_FEATURE_VOLUMEID_MINIX is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set +# CONFIG_FEATURE_VOLUMEID_NTFS is not set +# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set +# CONFIG_FEATURE_VOLUMEID_REISERFS is not set +# CONFIG_FEATURE_VOLUMEID_ROMFS is not set +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +# CONFIG_FEATURE_VOLUMEID_SYSV is not set +# CONFIG_FEATURE_VOLUMEID_UBIFS is not set +# CONFIG_FEATURE_VOLUMEID_UDF is not set +# CONFIG_FEATURE_VOLUMEID_XFS is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +# CONFIG_BC is not set +# CONFIG_DC is not set +# CONFIG_FEATURE_DC_BIG is not set +# CONFIG_FEATURE_DC_LIBM is not set +# CONFIG_FEATURE_BC_INTERACTIVE is not set +# CONFIG_FEATURE_BC_LONG_OPTIONS is not set +# CONFIG_BEEP is not set +CONFIG_FEATURE_BEEP_FREQ=0 +CONFIG_FEATURE_BEEP_LENGTH_MS=0 +# CONFIG_CHAT is not set +# CONFIG_FEATURE_CHAT_NOFAIL is not set +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set +# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set +# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set +# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set +# CONFIG_FEATURE_CHAT_CLR_ABORT is not set +# CONFIG_CONSPY is not set +# CONFIG_CROND is not set +# CONFIG_FEATURE_CROND_D is not set +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +# CONFIG_FEATURE_CROND_SPECIAL_TIMES is not set +CONFIG_FEATURE_CROND_DIR="" +# CONFIG_CRONTAB is not set +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +# CONFIG_DEVMEM is not set +# CONFIG_FBSPLASH is not set +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_ERASEALL is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_HDPARM is not set +# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set +# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set +# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set +# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +# CONFIG_HEXEDIT is not set +# CONFIG_I2CGET is not set +# CONFIG_I2CSET is not set +# CONFIG_I2CDUMP is not set +# CONFIG_I2CDETECT is not set +# CONFIG_I2CTRANSFER is not set +# CONFIG_INOTIFYD is not set +# CONFIG_LESS is not set +CONFIG_FEATURE_LESS_MAXLINES=0 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +# CONFIG_FEATURE_LESS_TRUNCATE is not set +# CONFIG_FEATURE_LESS_MARKS is not set +# CONFIG_FEATURE_LESS_REGEXP is not set +# CONFIG_FEATURE_LESS_WINCH is not set +# CONFIG_FEATURE_LESS_ASK_TERMINAL is not set +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set +# CONFIG_FEATURE_LESS_RAW is not set +# CONFIG_FEATURE_LESS_ENV is not set +# CONFIG_LSSCSI is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +# CONFIG_FEATURE_MAKEDEVS_TABLE is not set +# CONFIG_MAN is not set +# CONFIG_MICROCOM is not set +# CONFIG_MIM is not set +# CONFIG_MT is not set +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_PARTPROBE is not set +# CONFIG_RAIDAUTORUN is not set +# CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set +# CONFIG_RUNLEVEL is not set +# CONFIG_RX is not set +# CONFIG_SETFATTR is not set +# CONFIG_SETSERIAL is not set +# CONFIG_STRINGS is not set +# CONFIG_TIME is not set +# CONFIG_TS is not set +# CONFIG_TTYSIZE is not set +# CONFIG_UBIRENAME is not set +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_VOLNAME is not set +# CONFIG_WATCHDOG is not set + +# +# Networking Utilities +# +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_FEATURE_TLS_SHA1 is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +# CONFIG_BRCTL is not set +# CONFIG_FEATURE_BRCTL_FANCY is not set +# CONFIG_FEATURE_BRCTL_SHOW is not set +# CONFIG_DNSD is not set +# CONFIG_ETHER_WAKE is not set +# CONFIG_FTPD is not set +# CONFIG_FEATURE_FTPD_WRITE is not set +# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set +# CONFIG_HOSTNAME is not set +# CONFIG_DNSDOMAINNAME is not set +# CONFIG_HTTPD is not set +# CONFIG_FEATURE_HTTPD_RANGES is not set +# CONFIG_FEATURE_HTTPD_SETUID is not set +# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set +# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set +# CONFIG_FEATURE_HTTPD_CGI is not set +# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set +# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set +# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set +# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set +# CONFIG_FEATURE_HTTPD_PROXY is not set +# CONFIG_FEATURE_HTTPD_GZIP is not set +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +# CONFIG_IFPLUGD is not set +# CONFIG_IFUP is not set +# CONFIG_IFDOWN is not set +CONFIG_IFUPDOWN_IFSTATE_PATH="" +# CONFIG_FEATURE_IFUPDOWN_IP is not set +# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set +# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set +# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +# CONFIG_INETD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set +# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set +# CONFIG_FEATURE_INETD_RPC is not set +# CONFIG_IP is not set +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +# CONFIG_IPNEIGH is not set +# CONFIG_FEATURE_IP_ADDRESS is not set +# CONFIG_FEATURE_IP_LINK is not set +# CONFIG_FEATURE_IP_ROUTE is not set +CONFIG_FEATURE_IP_ROUTE_DIR="" +# CONFIG_FEATURE_IP_TUNNEL is not set +# CONFIG_FEATURE_IP_RULE is not set +# CONFIG_FEATURE_IP_NEIGH is not set +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +# CONFIG_IPCALC is not set +# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FEATURE_IPCALC_FANCY is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +# CONFIG_NBDCLIENT is not set +# CONFIG_NC is not set +# CONFIG_NETCAT is not set +# CONFIG_NC_SERVER is not set +# CONFIG_NC_EXTRA is not set +# CONFIG_NC_110_COMPAT is not set +# CONFIG_NETSTAT is not set +# CONFIG_FEATURE_NETSTAT_WIDE is not set +# CONFIG_FEATURE_NETSTAT_PRG is not set +# CONFIG_NSLOOKUP is not set +# CONFIG_FEATURE_NSLOOKUP_BIG is not set +# CONFIG_FEATURE_NSLOOKUP_LONG_OPTIONS is not set +# CONFIG_NTPD is not set +# CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set +# CONFIG_FEATURE_NTP_AUTH is not set +# CONFIG_PING is not set +# CONFIG_PING6 is not set +# CONFIG_FEATURE_FANCY_PING is not set +# CONFIG_PSCAN is not set +# CONFIG_ROUTE is not set +# CONFIG_SLATTACH is not set +# CONFIG_SSL_CLIENT is not set +# CONFIG_TC is not set +# CONFIG_FEATURE_TC_INGRESS is not set +# CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set +# CONFIG_TELNET is not set +# CONFIG_FEATURE_TELNET_TTYPE is not set +# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set +# CONFIG_FEATURE_TELNET_WIDTH is not set +# CONFIG_TELNETD is not set +# CONFIG_FEATURE_TELNETD_STANDALONE is not set +# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set +# CONFIG_TFTP is not set +# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set +# CONFIG_FEATURE_TFTP_HPA_COMPAT is not set +# CONFIG_TFTPD is not set +# CONFIG_FEATURE_TFTP_GET is not set +# CONFIG_FEATURE_TFTP_PUT is not set +# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set +# CONFIG_TFTP_DEBUG is not set +# CONFIG_TLS is not set +# CONFIG_TRACEROUTE is not set +# CONFIG_TRACEROUTE6 is not set +# CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +# CONFIG_TUNCTL is not set +# CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +# CONFIG_WGET is not set +# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set +# CONFIG_FEATURE_WGET_STATUSBAR is not set +# CONFIG_FEATURE_WGET_AUTHENTICATION is not set +# CONFIG_FEATURE_WGET_TIMEOUT is not set +# CONFIG_FEATURE_WGET_HTTPS is not set +# CONFIG_FEATURE_WGET_OPENSSL is not set +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set +# CONFIG_UDHCPD is not set +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set +CONFIG_DHCPD_LEASES_FILE="" +# CONFIG_DUMPLEASES is not set +# CONFIG_DHCPRELAY is not set +# CONFIG_UDHCPC is not set +# CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set +CONFIG_UDHCPC_DEFAULT_SCRIPT="" +# CONFIG_UDHCPC6 is not set +# CONFIG_FEATURE_UDHCPC6_RFC3646 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4704 is not set +# CONFIG_FEATURE_UDHCPC6_RFC4833 is not set +# CONFIG_FEATURE_UDHCPC6_RFC5970 is not set +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 +# CONFIG_FEATURE_UDHCP_RFC3397 is not set +# CONFIG_FEATURE_UDHCP_8021Q is not set +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" + +# +# Print Utilities +# +# CONFIG_LPD is not set +# CONFIG_LPR is not set +# CONFIG_LPQ is not set + +# +# Mail Utilities +# +# CONFIG_MAKEMIME is not set +# CONFIG_POPMAILDIR is not set +# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set +# CONFIG_REFORMIME is not set +# CONFIG_FEATURE_REFORMIME_COMPAT is not set +# CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" + +# +# Process Utilities +# +# CONFIG_FREE is not set +# CONFIG_FUSER is not set +# CONFIG_IOSTAT is not set +# CONFIG_KILL is not set +# CONFIG_KILLALL is not set +# CONFIG_KILLALL5 is not set +# CONFIG_LSOF is not set +# CONFIG_MPSTAT is not set +# CONFIG_NMETER is not set +# CONFIG_PGREP is not set +# CONFIG_PKILL is not set +# CONFIG_PIDOF is not set +# CONFIG_FEATURE_PIDOF_SINGLE is not set +# CONFIG_FEATURE_PIDOF_OMIT is not set +# CONFIG_PMAP is not set +# CONFIG_POWERTOP is not set +# CONFIG_FEATURE_POWERTOP_INTERACTIVE is not set +# CONFIG_PS is not set +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +# CONFIG_FEATURE_PS_TIME is not set +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set +# CONFIG_PSTREE is not set +# CONFIG_PWDX is not set +# CONFIG_SMEMCAP is not set +# CONFIG_BB_SYSCTL is not set +# CONFIG_TOP is not set +# CONFIG_FEATURE_TOP_INTERACTIVE is not set +# CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE is not set +# CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS is not set +# CONFIG_FEATURE_TOP_SMP_CPU is not set +# CONFIG_FEATURE_TOP_DECIMALS is not set +# CONFIG_FEATURE_TOP_SMP_PROCESS is not set +# CONFIG_FEATURE_TOPMEM is not set +# CONFIG_UPTIME is not set +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +# CONFIG_WATCH is not set +# CONFIG_FEATURE_SHOW_THREADS is not set + +# +# Runit Utilities +# +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set +# CONFIG_RUNSV is not set +# CONFIG_RUNSVDIR is not set +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +# CONFIG_SV is not set +CONFIG_SV_DEFAULT_SERVICE_DIR="" +# CONFIG_SVC is not set +# CONFIG_SVOK is not set +# CONFIG_SVLOGD is not set +# CONFIG_CHCON is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RUNCON is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SESTATUS is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_RESTORECON is not set +# CONFIG_SETSEBOOL is not set + +# +# Shells +# +# CONFIG_SH_IS_ASH is not set +# CONFIG_SH_IS_HUSH is not set +CONFIG_SH_IS_NONE=y +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y +# CONFIG_SHELL_ASH is not set +# CONFIG_ASH is not set +# CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set +# CONFIG_ASH_INTERNAL_GLOB is not set +# CONFIG_ASH_BASH_COMPAT is not set +# CONFIG_ASH_BASH_SOURCE_CURDIR is not set +# CONFIG_ASH_BASH_NOT_FOUND_HOOK is not set +# CONFIG_ASH_JOB_CONTROL is not set +# CONFIG_ASH_ALIAS is not set +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_ASH_EXPAND_PRMT is not set +# CONFIG_ASH_IDLE_TIMEOUT is not set +# CONFIG_ASH_MAIL is not set +# CONFIG_ASH_ECHO is not set +# CONFIG_ASH_PRINTF is not set +# CONFIG_ASH_TEST is not set +# CONFIG_ASH_HELP is not set +# CONFIG_ASH_GETOPTS is not set +# CONFIG_ASH_CMDCMD is not set +# CONFIG_CTTYHACK is not set +# CONFIG_HUSH is not set +# CONFIG_SHELL_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_LINENO_VAR is not set +# CONFIG_HUSH_BASH_SOURCE_CURDIR is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_HUSH_ECHO is not set +# CONFIG_HUSH_PRINTF is not set +# CONFIG_HUSH_TEST is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_EXPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_READONLY is not set +# CONFIG_HUSH_KILL is not set +# CONFIG_HUSH_WAIT is not set +# CONFIG_HUSH_COMMAND is not set +# CONFIG_HUSH_TRAP is not set +# CONFIG_HUSH_TYPE is not set +# CONFIG_HUSH_TIMES is not set +# CONFIG_HUSH_READ is not set +# CONFIG_HUSH_SET is not set +# CONFIG_HUSH_UNSET is not set +# CONFIG_HUSH_ULIMIT is not set +# CONFIG_HUSH_UMASK is not set +# CONFIG_HUSH_GETOPTS is not set +# CONFIG_HUSH_MEMLEAK is not set + +# +# Options common to all shells +# +# CONFIG_FEATURE_SH_MATH is not set +# CONFIG_FEATURE_SH_MATH_64 is not set +# CONFIG_FEATURE_SH_MATH_BASE is not set +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +# CONFIG_FEATURE_SH_READ_FRAC is not set +# CONFIG_FEATURE_SH_HISTFILESIZE is not set +# CONFIG_FEATURE_SH_EMBEDDED_SCRIPTS is not set + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +# CONFIG_FEATURE_SYSLOGD_PRECISE_TIMESTAMPS is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/DMSETUP/build.txt b/DMSETUP/build.txt index 5e2a8db0..b9601cbd 100644 --- a/DMSETUP/build.txt +++ b/DMSETUP/build.txt @@ -1,31 +1,70 @@ -Build a static linked, small dmsetup tool - -======== Source Code ======== -use an old version of dmsetup -http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm -https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz - -======== Build Envrioment ======== -build for 32bit, static linked with dietlibc -1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso -2. yum install gcc kernel-devel package -3. install dietc libc (just make && make install) -4. export PATH=$PATH:/opt/diet/bin - -======== Build Step ======== -1. extract device mapper source code -2. CC="diet gcc" ./configure --disable-nls --disable-selinux --disable-shared -3. modify include/configure.h file - --- delete the line with "#define malloc rpl_malloc" - --- add 2 defines as follow: - #ifndef UINT32_MAX - #define UINT32_MAX (4294967295U) - #endif - - #ifndef UINT64_C - #define UINT64_C(c) c ## ULL - #endif - -4. make -5. strip dmsetup/dmsetup -5. get dmsetup/dmsetup as the binary file +Build a static linked, small dmsetup tool + +======== Source Code ======== +use an old version of dmsetup +http://vault.centos.org/5.3/os/SRPMS/device-mapper-1.02.28-2.el5.src.rpm +https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz + +======== Build Envrioment ======== +build for 32bit, static linked with dietlibc +1. install centos 6.10 i386 with CentOS-6.10-i386-bin-DVD1.iso +2. yum install gcc kernel-devel package +3. install dietc libc (just make && make install) +4. export PATH=$PATH:/opt/diet/bin + +======== Build Step ======== +1. extract device mapper source code +2. CC="diet gcc" ./configure --disable-nls --disable-selinux --disable-shared +3. modify include/configure.h file + --- delete the line with "#define malloc rpl_malloc" + --- add 2 defines as follow: + #ifndef UINT32_MAX + #define UINT32_MAX (4294967295U) + #endif + + #ifndef UINT64_C + #define UINT64_C(c) c ## ULL + #endif + +4. make +5. strip dmsetup/dmsetup +6. get dmsetup/dmsetup as the dmsetup32 binary file + + + + + + +======================== Build for 64bit dmsetup ========================= +1. extract device mapper source code +2. ./configure --disable-nls --disable-selinux --disable-shared --enable-static_link CC='gcc -specs /usr/local/musl/lib/musl-gcc.specs' +3. touch include/linux/limits.h include/linux/types.h + echo '#include ' > include/linux/fs.h +4. make +5. strip --strip-all dmsetup/dmsetup.static +6. get dmsetup/dmsetup.static as the dmsetup64 binary file + + +======================== Build for arm64 dmsetup ========================= +1. extract device mapper source code +2. ./configure CC=aarch64-linux-gcc --target=arm --host=x86_64-linux-gnu --disable-nls --disable-selinux --disable-shared --enable-static_link +3. modify include/configure.h file + --- delete the line with "#define malloc rpl_malloc" +4. make +5. aarch64-linux-strip dmsetup/dmsetup.static +6. get dmsetup/dmsetup.static as the dmsetupaa64 binary file + + +======================== Build for mips64 dmsetup ========================= +1. extract device mapper source code +2. ./configure CC="mips64el-linux-musl-gcc -mips64r2 -mabi=64" --target=mips --host=x86_64-linux-gnu --disable-nls --disable-selinux --disable-shared --enable-static_link +3. modify include/configure.h file + --- delete the line with "#define malloc rpl_malloc" +4. make +5. mips64el-linux-musl-strip dmsetup/dmsetup.static +6. get dmsetup/dmsetup.static as the dmsetupm64e binary file + + + + + diff --git a/DMSETUP/dmsetup b/DMSETUP/dmsetup32 similarity index 100% rename from DMSETUP/dmsetup rename to DMSETUP/dmsetup32 diff --git a/DMSETUP/dmsetup64 b/DMSETUP/dmsetup64 new file mode 100644 index 00000000..4d390745 Binary files /dev/null and b/DMSETUP/dmsetup64 differ diff --git a/DMSETUP/dmsetupaa64 b/DMSETUP/dmsetupaa64 new file mode 100644 index 00000000..3b6b395f Binary files /dev/null and b/DMSETUP/dmsetupaa64 differ diff --git a/DMSETUP/dmsetupm64e b/DMSETUP/dmsetupm64e new file mode 100644 index 00000000..26d522ea Binary files /dev/null and b/DMSETUP/dmsetupm64e differ diff --git a/DOC/BuildVentoyFromSource.txt b/DOC/BuildVentoyFromSource.txt index 0a3e8fe1..8aae2823 100644 --- a/DOC/BuildVentoyFromSource.txt +++ b/DOC/BuildVentoyFromSource.txt @@ -1,204 +1,260 @@ - -========================================== -1. Compile Enviroment -========================================== - My build envrioment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch. - Because Ventoy is based on many open source projects, so the envrioment is important. I suggest you test it on a virtual machine first. - -1.1 Install CentOS 7.8 - I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install - -1.2 Install Packages - yum install \ - libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \ - mpfr.i686 mpfr-devel.i686 zlib.i686 rsync autogen autoconf automake libtool gettext* bison binutils \ - flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \ - libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \ - iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static - - - -========================================== -2. Download Source Code -========================================== -2.1 Download Ventoy source code from github and decompress it. - Next I assume that you have unzipped the code into the /home directory (check /home/Ventoy-master/README.md file for the directory level). - -2.2 Download third-part source code - - https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz - https://ftp.gnu.org/gnu/grub/grub-2.04.tar.xz ===> /home/Ventoy-master/GRUB2/grub-2.04.tar.xz - https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 ===> /home/Ventoy-master/EDK2/edk2-edk2-stable201911.zip - https://codeload.github.com/relan/exfat/zip/v1.3.0 ===> /home/Ventoy-master/ExFAT/exfat-1.3.0.zip - https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip - - - -========================================== -3. All in one script -========================================== - I have made the whole build process in all_in_one.sh, you can run this script to build and pack ventoy. - If you want to compile a certain part separately, you can continue to refer to the later chapters of this text. - - cd /home/Ventoy-master/INSTALL - sh all_in_one.sh - - It should be noted that, some part of Ventoy has 32bit&64bit version (like 4.9 4.10 4.11 follows) - all_in_one.sh only build 64bit version of them, if you want to rebuild the 32bit verison. You should create a 32bit CentOS environment and build them. - Fortunately these parts are few modified, you only need to build once or you can directly use the binary I have built. - - Besides, after a fully compile and pack, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package. - - - -========================================== -4. Build every part of Ventoy -========================================== -4.1 == Build grub2 == - cd /home/Ventoy-master/GRUB2 - sh buildgrub.sh - -4.2 == Build ipxe.krn == - cd /home/Ventoy-master/IPXE - sh buildipxe.sh - -4.3 == Build Ventoy2Disk.exe == - Ventoy2Disk.exe is the installer in Windows platform. And it must be built in Windows with Microsoft Visual Studio (2013+). - Open /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk.sln with Visual Studio and build it. - -4.4 == Build vtoyjump64.exe/vtoyjump32.exe == - vtoyjump64.exe/vtoyjump32.exe is used to mount iso file in windows PE. You should install Microsoft Visual Studio (2013+) to build it. - Open /home/Ventoy-master/vtoyjump/vtoyjump.sln with Visual Studio and build it (64&32). - -4.5 == Build dmsetup == - Please refer to DMSETUP/build.txt - -4.6 == Build ventoy_x64.efi == - cd /home/Ventoy-master/EDK2 - sh buildedk.sh - -4.7 == Build VtoyTool == - cd /home/Ventoy-master/VtoyTool - sh build.sh - -4.8 == Build vtoyfat == - cd /home/Ventoy-master/vtoyfat/fat_io_lib - sh buildlib.sh - cd /home/Ventoy-master/vtoyfat - sh build.sh - -4.9 == Build exfat-util == - cd /home/Ventoy-master/ExFAT - sh buidlibfuse.sh - sh buidexfat.sh - - After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64 - After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64 - - Use the same build step to build exfat-util 32bit in a 32bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32 - -4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 == - cd /home/Ventoy-master/FUSEISO - sh build_libfuse.sh - sh build.sh - - Use the same build step to build in a 32bit CentOS system and get vtoy_fuse_iso_32 - -4.11 == Build unsquashfs_64/unsquashfs_32 == - cd /home/Ventoy-master/SQUASHFS/SRC - sh build_lz4.sh - sh build_lzma.sh - sh build_lzo.sh - sh build_zstd.sh - - cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools - sh build.sh - - Use the same build step to build in a 32bit CentOS system and get unsquashfs_32 - -4.12 == Build vblade_64/vblade_32 == - cd /home/Ventoy-master/VBLADE/vblade-master - sh build.sh - -4.13 == Build zstdcat == - Please refer to ZSTD/build.txt - -4.14 == Build vtoy_gen_uuid == - cd /home/Ventoy-master/GenUUID - sh build.sh - -4.15 == Build xzminidec == - cd /home/Ventoy-master/xz-embedded-20130513/userspace - make -f ventoy_makefile - strip --strip-all xzminidec - -4.16 == Build iso9660_x64.efi == - This efi driver is from https://github.com/pbatard/efifs - Follow all the build instructions in this project. I modified 3 files (the original and modified source are at /home/Ventoy-master/EDK2/efiffs) - - - -========================================== -5. Binaries -========================================== - There some binaries in Ventoy install package. These files are downloaded from other open source project's website, such as busybox. - Here is the list of the binaries, their SHA-256 and the download urls: - -5.1 IMG/cpio/ventoy/tool/lz4cat - https://create.stephan-brumme.com/smallz4 smallz4cat-x32-v1.4 - SHA-256: 13d293ddeedb469f51da41167f79b2cbdb904e681716f6e6191b233dbb162438 - -5.2 IMG/cpio/ventoy/tool/ar - https://busybox.net/downloads/binaries/1.30.0-i686 busybox_AR - SHA-256: f29b7d81a983c0c85d22496f4a833c18f2528a1b666eb7d47c93084c1ed66ae0 - -5.3 IMG/cpio/ventoy/tool/inotifyd - https://busybox.net/downloads/binaries/1.30.0-i686 busybox_INOTIFYD - SHA-256: 3532162a8695e91a1ed9ddea28b2cb22259a90e93d5d9c4a517b6c36842c686f - -5.4 IMG/cpio/ventoy/busybox/tmpsh - https://busybox.net/downloads/binaries/1.27.1-i686 busybox_ASH - SHA-256: 44a6274bca580c2758ffc173fc76d18bb855b1fe8dcf70efd9ee75cbd57dee97 - -5.5 IMG/cpio/ventoy/busybox/tmpxz - https://busybox.net/downloads/binaries/1.27.1-i686 busybox_XZ - SHA-256: f6cdb6293680424c29b89bde0685ca27f455166c9b302cd6082ef90681456291 - -5.6 INSTALL/tool/xzcat - https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_XZCAT - SHA-256: 7399db642c2beaf52a16ab5264ffc55cfd1ff5699a524f63e5d48edf84e20f44 - -5.7 INSTALL/tool/hexdump - https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_HEXDUMP - SHA-256: cde08b6a2cf5ad914f05203e18e3f7c2ed6060a63604e3d75536f19b55e8e0af - -5.8 imdisk - download http://www.ltr-data.se/files/imdiskinst.exe and extract it by 7zip. - - INSTALL/ventoy/imdisk/64/imdisk.sys --> sys/amd64/imdisk.sys SHA-256: 6702202220268787e361f5a82dae53362c8e6c6dcd240bb01b44dd77ae0788da - INSTALL/ventoy/imdisk/64/imdisk.exe --> cli/amd64/imdisk.exe SHA-256: 9759175380af836869443e5f21ce2e33022125d154bc6b3d1c04dc36b190de04 - INSTALL/ventoy/imdisk/64/imdisk.cpl --> cpl/amd64/imdisk.cpl SHA-256: aea2ebbea2b073c947263744962af8a3eab025ff4c9d825c543e380e738a4c99 - - INSTALL/ventoy/imdisk/32/imdisk.sys --> sys/i386/imdisk.sys SHA-256: a94caec2f71a924d6a914c093ad4b905d7cfdea3f515ed48aaa8c3950b2dc191 - INSTALL/ventoy/imdisk/32/imdisk.exe --> cli/i386/imdisk.exe SHA-256: 33b53858e2139704cf603b115a3e5e1dfd4daeaaed4d3e03c633f2df3b55dbaa - INSTALL/ventoy/imdisk/32/imdisk.cpl --> cpl/i386/imdisk.cpl SHA-256: b781d3e2d286ac8bf548f44e50cbbb3fe78203296e41e4d2e73b407668f88f2d - -5.9 INSTALL/ventoy/memdisk - https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz - decompress it and memdisk is at syslinux-6.03/bios/memdisk/memdisk - SHA-256: 3f6cd656b8a14109cd3f906fee2dd2e75418f983a5e1bfdb64f44f7765588cbb - - -5.10 UEFIinSecureBoot - https://github.com/ValdikSS/Super-UEFIinSecureBoot-Disk/releases Super-UEFIinSecureBoot-Disk_minimal_v3.zip - unzip it and get Super-UEFIinSecureBoot-Disk_minimal.img, extract the img by 7zip. - - INSTALL/EFI/BOOT/BOOTX64.EFI --> EFI/BOOT/BOOTX64.EFI SHA-256: 475552c7476ad45e42344eee8b30d44c264d200ac2468428aa86fc8795fb6e34 - INSTALL/EFI/BOOT/grubx64.efi --> EFI/BOOT/grubx64.efi SHA-256: 25d858157349dc52fa70f3cdf5c62fe1e0bae37ddfc3a6b6528af9a3c745775f - INSTALL/EFI/BOOT/MokManager.efi --> EFI/BOOT/MokManager.efi SHA-256: 3bf1f46cee0832355c7dd1dba880dea9bcaa78cc44375a1559d43bc9db18933b - - -5.11 INSTALL/tool/ash - https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH - SHA-256: 2943f02f85fee0c9551aec47110a558a73f919c032b3c51e56d6f197b5ec4d7b - + +========================================== +1. Compile Enviroment +========================================== + My build envrioment is CentOS 7.8 x86_64. So here I first explain how to create the build environment from scratch. + Because Ventoy is based on many open source projects, so the environment is important. I suggest you test it on a virtual machine firstly. + +1.1 Install CentOS 7.8 + I use CentOS-7-x86_64-Everything-2003.iso and select Minimal install + +1.2 Install Packages + yum install \ + libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \ + mpfr.i686 mpfr-devel.i686 zlib.i686 rsync autogen autoconf automake libtool gettext* bison binutils \ + flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \ + libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \ + iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso + + + +========================================== +2. Download Source Code +========================================== +2.1 Download Ventoy source code from github and decompress it. + Next I assume that you have unzipped the code into the /home directory (check /home/Ventoy-master/README.md file for the directory layout). + +2.2 Download third-part source code and tool + + https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz ===> /home/Ventoy-master/DOC/dietlibc-0.34.tar.xz + https://musl.libc.org/releases/musl-1.2.1.tar.gz ===> /home/Ventoy-master/DOC/musl-1.2.1.tar.gz + https://ftp.gnu.org/gnu/grub/grub-2.04.tar.xz ===> /home/Ventoy-master/GRUB2/grub-2.04.tar.xz + https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 ===> /home/Ventoy-master/EDK2/edk2-edk2-stable201911.zip + https://codeload.github.com/relan/exfat/zip/v1.3.0 ===> /home/Ventoy-master/ExFAT/exfat-1.3.0.zip + https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 ===> /home/Ventoy-master/ExFAT/libfuse-fuse-2.9.9.zip + https://releases.linaro.org/components/toolchain/binaries/7.4-2019.02/aarch64-linux-gnu/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz ===> /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz + https://toolchains.bootlin.com/downloads/releases/toolchains/aarch64/tarballs/aarch64--uclibc--stable-2020.08-1.tar.bz2 ===> /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 + http://ftp.loongnix.org/toolchain/gcc/release/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz ===> /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz + https://github.com/ventoy/musl-cross-make/releases/download/latest/output.tar.bz2 ===> /opt/output.tar.bz2 + + + http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/vmlinuz64 ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/vmlinuz64 + http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/corepure64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/corepure64.gz + http://www.tinycorelinux.net/11.x/x86_64/release/distribution_files/modules64.gz ===> /home/Ventoy-master/LiveCD/ISO/EFI/boot/modules64.gz + +2.3 Prepare third-part tools + cd /home/Ventoy-master/DOC/ + tar xf musl-1.2.1.tar.gz + cd musl-1.2.1 + ./configure && make install + + tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt + tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt + tar xf /opt/output.tar.bz2 -C /opt + mv /opt/output /opt/mips64el-linux-musl-gcc730 + + +2.4 Set PATH envrioment + export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips64el-linux-musl-gcc730/bin + better to add this line to /root/.bashrc and relogin as root + + +========================================== +3. All in one script +========================================== + I have made a all_in_one.sh, you can run this script to build and pack ventoy. + If you want to compile a certain part separately, you can continue to refer to the later chapters of this text. + + cd /home/Ventoy-master/INSTALL + sh all_in_one.sh + + It should be noted that: + 1. Only grub2/EDK2/IPXE will be recompiled in all_in_one.sh. Other part contains the binaries and are few modified, so will no be recompiled everytime. + You can rebuild these parts separately if you want. + + 2. some part of Ventoy has 32bit&64bit version (like 4.9 4.10 4.11 follows) + all_in_one.sh only build 64bit version of them, if you want to rebuild the 32bit verison. You should create a 32bit CentOS environment and build them. + Fortunately these parts are few modified, you only need to build once or you can directly use the binary I have built. + + Besides, after a fully compile and pack, you can only build the part you modified (for example grub2) and run ventoy_pack.sh to generate the package. + +========================================== +4. Build every part of Ventoy +========================================== +4.1 == Build grub2 == + cd /home/Ventoy-master/GRUB2 + sh buildgrub.sh + +4.2 == Build ipxe.krn == + cd /home/Ventoy-master/IPXE + sh buildipxe.sh + +4.3 == Build Ventoy2Disk.exe == + Ventoy2Disk.exe is the installer in Windows platform. And it must be built in Windows with Microsoft Visual Studio (2013+). + Open /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk.sln with Visual Studio and build it. + +4.4 == Build vtoyjump64.exe/vtoyjump32.exe == + vtoyjump64.exe/vtoyjump32.exe is used to mount iso file in windows PE. You should install Microsoft Visual Studio (2013+) to build it. + Open /home/Ventoy-master/vtoyjump/vtoyjump.sln with Visual Studio and build it (64&32). + +4.5 == Build dmsetup == + Please refer to DMSETUP/build.txt + +4.6 == Build ventoy_x64.efi == + cd /home/Ventoy-master/EDK2 + sh buildedk.sh + +4.7 == Build VtoyTool == + cd /home/Ventoy-master/VtoyTool + sh build.sh + +4.8 == Build vtoyfat == + cd /home/Ventoy-master/vtoyfat/fat_io_lib + sh buildlib.sh + cd /home/Ventoy-master/vtoyfat + sh build.sh + +4.9 == Build exfat-util == + cd /home/Ventoy-master/ExFAT + sh buidlibfuse.sh + sh buidexfat.sh + + After that, copy EXFAT/shared/mkexfatfs ===> /home/Ventoy-master/INSTALL/tool/mkexfatfs_64 + After that, copy EXFAT/shared/mount.exfat-fuse ===> /home/Ventoy-master/INSTALL/tool/mount.exfat-fuse_64 + + Use the same build step to build exfat-util 32bit in a 32bit CentOS system and get mkexfatfs_32 and mount.exfat-fuse_32 + +4.10 == Build vtoy_fuse_iso_64/vtoy_fuse_iso_32 == + cd /home/Ventoy-master/FUSEISO + sh build_libfuse.sh + sh build.sh + + Use the same build step to build in a 32bit CentOS system and get vtoy_fuse_iso_32 + +4.11 == Build unsquashfs_64/unsquashfs_32 == + cd /home/Ventoy-master/SQUASHFS/SRC + sh build_lz4.sh + sh build_lzma.sh + sh build_lzo.sh + sh build_zstd.sh + + cd /home/Ventoy-master/SQUASHFS/squashfs-tools-4.4/squashfs-tools + sh build.sh + + Use the same build step to build in a 32bit CentOS system and get unsquashfs_32 + +4.12 == Build vblade_64/vblade_32 == + cd /home/Ventoy-master/VBLADE/vblade-master + sh build.sh + +4.13 == Build zstdcat == + Please refer to ZSTD/build.txt + +4.14 == Build vtoy_gen_uuid == + cd /home/Ventoy-master/GenUUID + sh build.sh + +4.15 == Build xzminidec32 == + cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace + make -f ventoy_makefile + strip --strip-all xzminidec + +4.16 == Build xzminidec64 == + cd /home/Ventoy-master/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace + make -f ventoy_makefile64 + strip --strip-all xzminidec + +4.17 == Build iso9660_x64.efi == + This efi driver is from https://github.com/pbatard/efifs + Follow all the build instructions in this project. I modified 3 files (the original and modified source are at /home/Ventoy-master/EDK2/efiffs) + +4.18 IMG/cpio/ventoy/busybox/64h + https://www.uclibc.org/downloads/binaries/0.9.30.1/mini-native-x86_64.tar.bz2 + https://busybox.net/downloads/busybox-1.32.0.tar.bz2 + use BUSYBOX/x86_64_ash.config and uclibc to build busybox-1.32 + +4.19 == Build lunzip32/lunzip64 == + http://mirror.yongbok.net/nongnu/lzip/lunzip/lunzip-1.11.tar.gz + PATH=$PATH:/opt/diet/bin + ./configure --disable-nls CC='diet gcc -nostdinc' + make + strip --strip-all lunzip + + #aarch64 + ./configure --disable-nls CC='aarch64-buildroot-linux-uclibc-gcc -static' + make + aarch64-buildroot-linux-uclibc-strip --strip-all lunzip + + + +========================================== +5. Binaries +========================================== + There some binaries in Ventoy install package. These files are downloaded from other open source project's website, such as busybox. + Here is the list of the binaries, their SHA-256 and the download urls: + +5.1 IMG/cpio/ventoy/tool/lz4cat + https://create.stephan-brumme.com/smallz4 smallz4cat-x32-v1.4 + SHA-256: 13d293ddeedb469f51da41167f79b2cbdb904e681716f6e6191b233dbb162438 + +5.2 IMG/cpio/ventoy/tool/ar + https://busybox.net/downloads/binaries/1.30.0-i686 busybox_AR + SHA-256: f29b7d81a983c0c85d22496f4a833c18f2528a1b666eb7d47c93084c1ed66ae0 + +5.3 IMG/cpio/ventoy/tool/inotifyd + https://busybox.net/downloads/binaries/1.30.0-i686 busybox_INOTIFYD + SHA-256: 3532162a8695e91a1ed9ddea28b2cb22259a90e93d5d9c4a517b6c36842c686f + +5.4 IMG/cpio/ventoy/busybox/ash + https://busybox.net/downloads/binaries/1.27.1-i686 busybox_ASH + SHA-256: 44a6274bca580c2758ffc173fc76d18bb855b1fe8dcf70efd9ee75cbd57dee97 + +5.5 IMG/cpio/ventoy/busybox/tmpxz + https://busybox.net/downloads/binaries/1.27.1-i686 busybox_XZ + SHA-256: f6cdb6293680424c29b89bde0685ca27f455166c9b302cd6082ef90681456291 + +5.6 INSTALL/tool/i386/xzcat + https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_XZCAT + SHA-256: 7399db642c2beaf52a16ab5264ffc55cfd1ff5699a524f63e5d48edf84e20f44 + +5.7 INSTALL/tool/i386/hexdump + https://busybox.net/downloads/binaries/1.30.0-i686/ busybox_HEXDUMP + SHA-256: cde08b6a2cf5ad914f05203e18e3f7c2ed6060a63604e3d75536f19b55e8e0af + +5.8 imdisk + download http://www.ltr-data.se/files/imdiskinst.exe and extract it by 7zip. + + INSTALL/ventoy/imdisk/64/imdisk.sys --> sys/amd64/imdisk.sys SHA-256: 6702202220268787e361f5a82dae53362c8e6c6dcd240bb01b44dd77ae0788da + INSTALL/ventoy/imdisk/64/imdisk.exe --> cli/amd64/imdisk.exe SHA-256: 9759175380af836869443e5f21ce2e33022125d154bc6b3d1c04dc36b190de04 + INSTALL/ventoy/imdisk/64/imdisk.cpl --> cpl/amd64/imdisk.cpl SHA-256: aea2ebbea2b073c947263744962af8a3eab025ff4c9d825c543e380e738a4c99 + + INSTALL/ventoy/imdisk/32/imdisk.sys --> sys/i386/imdisk.sys SHA-256: a94caec2f71a924d6a914c093ad4b905d7cfdea3f515ed48aaa8c3950b2dc191 + INSTALL/ventoy/imdisk/32/imdisk.exe --> cli/i386/imdisk.exe SHA-256: 33b53858e2139704cf603b115a3e5e1dfd4daeaaed4d3e03c633f2df3b55dbaa + INSTALL/ventoy/imdisk/32/imdisk.cpl --> cpl/i386/imdisk.cpl SHA-256: b781d3e2d286ac8bf548f44e50cbbb3fe78203296e41e4d2e73b407668f88f2d + +5.9 INSTALL/ventoy/memdisk + https://mirrors.edge.kernel.org/pub/linux/utils/boot/syslinux/syslinux-6.03.tar.gz + decompress it and memdisk is at syslinux-6.03/bios/memdisk/memdisk + SHA-256: 3f6cd656b8a14109cd3f906fee2dd2e75418f983a5e1bfdb64f44f7765588cbb + + +5.10 UEFIinSecureBoot + https://github.com/ValdikSS/Super-UEFIinSecureBoot-Disk/releases Super-UEFIinSecureBoot-Disk_minimal_v3.zip + unzip it and get Super-UEFIinSecureBoot-Disk_minimal.img, extract the img by 7zip. + + INSTALL/EFI/BOOT/BOOTX64.EFI --> EFI/BOOT/BOOTX64.EFI SHA-256: 475552c7476ad45e42344eee8b30d44c264d200ac2468428aa86fc8795fb6e34 + INSTALL/EFI/BOOT/grubx64.efi --> EFI/BOOT/grubx64.efi SHA-256: 25d858157349dc52fa70f3cdf5c62fe1e0bae37ddfc3a6b6528af9a3c745775f + INSTALL/EFI/BOOT/MokManager.efi --> EFI/BOOT/MokManager.efi SHA-256: 3bf1f46cee0832355c7dd1dba880dea9bcaa78cc44375a1559d43bc9db18933b + + +5.11 INSTALL/tool/ash + https://busybox.net/downloads/binaries/1.31.0-i686-uclibc/ busybox_ASH + SHA-256: 2943f02f85fee0c9551aec47110a558a73f919c032b3c51e56d6f197b5ec4d7b + +5.12 7za.exe + download from https://www.7-zip.org/a/7z1900-extra.7z + ISNTALL/ventoy/7z/64/7za.exe SHA-256: 8117e40ee7f824f63373a4f5625bb62749f69159d0c449b3ce2f35aad3b83549 + ISNTALL/ventoy/7z/32/7za.exe SHA-256: ea308c76a2f927b160a143d94072b0dce232e04b751f0c6432a94e05164e716d + + + diff --git a/DOC/LoopExBuild.txt b/DOC/LoopExBuild.txt new file mode 100644 index 00000000..2f5a39e7 --- /dev/null +++ b/DOC/LoopExBuild.txt @@ -0,0 +1,29 @@ + +1. LAKKA dm-mod.ko + LaKKa config + https://github.com/libretro/Lakka-LibreELEC/releases download source code + \projects\Generic\linux\linux.x86_64.conf + + Linux Kernel + linux-4.11.12.tar.xz & patch-4.11.12-rt14.patch.xz + patch -p1 < ../patch-4.11.12-rt14 + + make menuconfig + select device mapper as module + make -j 16 + get drivers\md\dm-mod.ko + +2. LibreELEC dm-mod.ko + LibreELEC config + https://github.com/LibreELEC/LibreELEC.tv/releases download source code + \projects\Generic\linux\linux.x86_64.conf + + Linux Kernel + linux-5.1.6.tar.xz + make menuconfig + select device mapper as module + make -j 16 + get drivers\md\dm-mod.ko + + + \ No newline at end of file diff --git a/DOC/prepare_env.sh b/DOC/prepare_env.sh new file mode 100644 index 00000000..4754db3e --- /dev/null +++ b/DOC/prepare_env.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +#[ -d /opt/diet64 ] || sh ./installdietlibc.sh + +[ -d /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu ] || tar xf /opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz -C /opt + +[ -d /opt/aarch64--uclibc--stable-2020.08-1 ] || tar xf /opt/aarch64--uclibc--stable-2020.08-1.tar.bz2 -C /opt + +[ -d /opt/mips-loongson-gcc7.3-linux-gnu ] || tar xf /opt/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz -C /opt diff --git a/Dockerfile b/Dockerfile index 06221bc0..4a6bf569 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,10 @@ FROM centos:7 -RUN yum -y install \ +RUN yum -y -q install \ libXpm net-tools bzip2 wget vim gcc gcc-c++ samba dos2unix glibc-devel glibc.i686 glibc-devel.i686 \ - mpfr.i686 mpfr-devel.i686 zlib.i686 rsync autogen autoconf automake libtool gettext* bison binutils \ + mpfr.i686 mpfr-devel.i686 rsync autogen autoconf automake libtool gettext* bison binutils \ flex device-mapper-devel SDL libpciaccess libusb freetype freetype-devel gnu-free-* qemu-* virt-* \ libvirt* vte* NetworkManager-bluetooth brlapi fuse-devel dejavu* gnu-efi* pesign shim \ - iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static - -CMD cd /ventoy \ - && wget -P DOC/ https://www.fefe.de/dietlibc/dietlibc-0.34.tar.xz \ - && wget -P GRUB2/ https://ftp.gnu.org/gnu/grub/grub-2.04.tar.xz \ - && wget -O EDK2/edk2-edk2-stable201911.zip https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 \ - && wget -O ExFAT/exfat-1.3.0.zip https://codeload.github.com/relan/exfat/zip/v1.3.0 \ - && wget -O ExFAT/libfuse-fuse-2.9.9.zip https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 \ - && cd INSTALL && ls -la && sh all_in_one.sh + iscsi-initiator-utils grub2-tools zip nasm acpica-tools glibc-static zlib-static xorriso +CMD cd /ventoy/INSTALL && ls -la && sh docker_ci_build.sh diff --git a/EDK2/build.sh b/EDK2/build.sh new file mode 100644 index 00000000..92244db3 --- /dev/null +++ b/EDK2/build.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +if [ -z "$1" ]; then + EDKARCH=X64 + postfix=x64 +elif [ "$1" = "ia32" ]; then + EDKARCH=IA32 + postfix=ia32 + shift +elif [ "$1" = "aa64" ]; then + EDKARCH=AARCH64 + postfix=aa64 + shift +fi + +cd edk2-edk2-stable201911 + +rm -rf ./Conf/.cache +rm -f ./Conf/.AutoGenIdFile.txt + +VTEFI_PATH=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/Ventoy/Ventoy/OUTPUT/Ventoy.efi +DST_PATH=../../INSTALL/ventoy/ventoy_${postfix}.efi + +VTEFI_PATH2=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VtoyUtil/VtoyUtil/OUTPUT/VtoyUtil.efi +DST_PATH2=../../INSTALL/ventoy/vtoyutil_${postfix}.efi + +VTEFI_PATH3=Build/MdeModule/RELEASE_GCC48/$EDKARCH/MdeModulePkg/Application/VDiskChain/VDiskChain/OUTPUT/VDiskChain.efi +DST_PATH3=../../VDiskChain/Tool/vdiskchain_${postfix}.efi + + +rm -f $VTEFI_PATH +rm -f $DST_PATH +rm -f $VTEFI_PATH2 +rm -f $DST_PATH2 +rm -f $VTEFI_PATH3 +[ -d ../../VDiskChain ] && rm -f $DST_PATH3 + +unset WORKSPACE +source ./edksetup.sh + +if [ "$EDKARCH" = "AARCH64" ]; then + GCC48_AARCH64_PREFIX=aarch64-linux-gnu- \ + build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 +else + build -p MdeModulePkg/MdeModulePkg.dsc -a $EDKARCH -b RELEASE -t GCC48 +fi + +if [ -e $VTEFI_PATH ] && [ -e $VTEFI_PATH2 ] && [ -e $VTEFI_PATH3 ]; then + echo -e '\n\n====================== SUCCESS ========================\n\n' + cp -a $VTEFI_PATH $DST_PATH + cp -a $VTEFI_PATH2 $DST_PATH2 + [ -d ../../VDiskChain ] && cp -a $VTEFI_PATH3 $DST_PATH3 + cd .. +else + echo -e '\n\n====================== FAILED ========================\n\n' + cd .. + exit 1 +fi + diff --git a/EDK2/buildedk.sh b/EDK2/buildedk.sh index bc99afc8..e001303b 100644 --- a/EDK2/buildedk.sh +++ b/EDK2/buildedk.sh @@ -2,32 +2,20 @@ rm -rf edk2-edk2-stable201911 -unzip edk2-edk2-stable201911.zip +unzip edk2-edk2-stable201911.zip > /dev/null /bin/cp -a ./edk2_mod/edk2-edk2-stable201911 ./ cd edk2-edk2-stable201911 - -VTEFI_PATH=Build/MdeModule/RELEASE_GCC48/X64/MdeModulePkg/Application/Ventoy/Ventoy/OUTPUT/Ventoy.efi -DST_PATH=../../INSTALL/ventoy/ventoy_x64.efi - -rm -f $VTEFI_PATH -rm -f $DST_PATH - make -j 4 -C BaseTools/ +cd .. -source ./edksetup.sh -build -p MdeModulePkg/MdeModulePkg.dsc -a X64 -b RELEASE -t GCC48 - -if [ -e $VTEFI_PATH ]; then - echo -e '\n\n====================== SUCCESS ========================\n\n' - cp -a $VTEFI_PATH $DST_PATH - cd .. -else - echo -e '\n\n====================== FAILED ========================\n\n' - cd .. - exit 1 -fi +echo '======== build EDK2 for i386-efi ===============' +sh ./build.sh ia32 || exit 1 +echo '======== build EDK2 for arm64-efi ===============' +sh ./build.sh aa64 || exit 1 +echo '======== build EDK2 for x86_64-efi ===============' +sh ./build.sh || exit 1 diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.c new file mode 100644 index 00000000..f3d8d458 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.c @@ -0,0 +1,466 @@ +/****************************************************************************** + * VDiskChain.c + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN gVDiskDebugPrint = FALSE; +vdisk_block_data gVDiskBlockData; + +/* Boot filename */ +CONST CHAR16 *gEfiBootFileName[] = +{ + L"@", + EFI_REMOVABLE_MEDIA_FILE_NAME, +#if defined (MDE_CPU_IA32) + L"\\EFI\\BOOT\\GRUBIA32.EFI", + L"\\EFI\\BOOT\\BOOTia32.EFI", + L"\\EFI\\BOOT\\bootia32.efi", + L"\\efi\\boot\\bootia32.efi", +#elif defined (MDE_CPU_X64) + L"\\EFI\\BOOT\\GRUBX64.EFI", + L"\\EFI\\BOOT\\BOOTx64.EFI", + L"\\EFI\\BOOT\\bootx64.efi", + L"\\efi\\boot\\bootx64.efi", +#elif defined (MDE_CPU_ARM) + L"\\EFI\\BOOT\\GRUBARM.EFI", + L"\\EFI\\BOOT\\BOOTarm.EFI", + L"\\EFI\\BOOT\\bootarm.efi", + L"\\efi\\boot\\bootarm.efi", +#elif defined (MDE_CPU_AARCH64) + L"\\EFI\\BOOT\\GRUBAA64.EFI", + L"\\EFI\\BOOT\\BOOTaa64.EFI", + L"\\EFI\\BOOT\\bootaa64.efi", + L"\\efi\\boot\\bootaa64.efi", +#endif + +}; + +UINT8 *g_disk_buf_addr = NULL; +UINT64 g_disk_buf_size = 0; + +STATIC EFI_GET_VARIABLE g_org_get_variable = NULL; +STATIC EFI_EXIT_BOOT_SERVICES g_org_exit_boot_service = NULL; + +VOID EFIAPI VDiskDebug(IN CONST CHAR8 *Format, ...) +{ + VA_LIST Marker; + CHAR16 Buffer[512]; + + VA_START (Marker, Format); + UnicodeVSPrintAsciiFormat(Buffer, sizeof(Buffer), Format, Marker); + VA_END (Marker); + + gST->ConOut->OutputString(gST->ConOut, Buffer); +} + +VOID EFIAPI vdisk_clear_input(VOID) +{ + EFI_INPUT_KEY Key; + + gST->ConIn->Reset(gST->ConIn, FALSE); + while (EFI_SUCCESS == gST->ConIn->ReadKeyStroke(gST->ConIn, &Key)) + { + ; + } + gST->ConIn->Reset(gST->ConIn, FALSE); +} + +STATIC EFI_STATUS EFIAPI vdisk_load_image +( + IN EFI_HANDLE ImageHandle, + IN EFI_DEVICE_PATH_PROTOCOL *pDevicePath, + IN CONST CHAR16 *FileName, + IN UINTN FileNameLen, + OUT EFI_HANDLE *Image +) +{ + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 TmpBuf[256] = {0}; + FILEPATH_DEVICE_PATH *pFilePath = NULL; + EFI_DEVICE_PATH_PROTOCOL *pImgPath = NULL; + + pFilePath = (FILEPATH_DEVICE_PATH *)TmpBuf; + pFilePath->Header.Type = MEDIA_DEVICE_PATH; + pFilePath->Header.SubType = MEDIA_FILEPATH_DP; + pFilePath->Header.Length[0] = FileNameLen + sizeof(EFI_DEVICE_PATH_PROTOCOL); + pFilePath->Header.Length[1] = 0; + CopyMem(pFilePath->PathName, FileName, FileNameLen); + + pImgPath = AppendDevicePathNode(pDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)pFilePath); + if (!pImgPath) + { + return EFI_NOT_FOUND; + } + + Status = gBS->LoadImage(FALSE, ImageHandle, pImgPath, NULL, 0, Image); + + debug("Load Image File %r DP: <%s>", Status, ConvertDevicePathToText(pImgPath, FALSE, FALSE)); + + FreePool(pImgPath); + + return Status; +} + +STATIC EFI_STATUS EFIAPI vdisk_decompress_vdisk(IN EFI_LOADED_IMAGE_PROTOCOL *pImageInfo) +{ + UINT32 Size; + UINT32 DestinationSize; + UINT32 ScratchSize; + UINT8 *buf; + VOID *ScratchBuf; + EFI_STATUS Status = EFI_SUCCESS; + + (VOID)pImageInfo; + + vdisk_get_vdisk_raw(&buf, &Size); + UefiDecompressGetInfo(buf + VDISK_MAGIC_LEN, Size - VDISK_MAGIC_LEN, &DestinationSize, &ScratchSize); + debug("vdisk: size:%u realsize:%u", Size, DestinationSize); + + g_disk_buf_size = DestinationSize; + g_disk_buf_addr = AllocatePool(DestinationSize); + ScratchBuf = AllocatePool(ScratchSize); + + Status = UefiDecompress(buf + VDISK_MAGIC_LEN, g_disk_buf_addr, ScratchBuf); + FreePool(ScratchBuf); + + debug("Status:%r %p %u", Status, g_disk_buf_addr, (UINT32)g_disk_buf_size); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS vdisk_patch_vdisk_path(CHAR16 *pos) +{ + UINTN i; + UINTN j; + CHAR16 *end; + CHAR8 *buf = (char *)g_disk_buf_addr; + + if (*pos == L'\"') + { + pos++; + } + + end = StrStr(pos, L".vtoy"); + end += 5;//string length + + for (i = 0; i < g_disk_buf_size; i++) + { + if (*(UINT32 *)(buf + i) == 0x59595959) + { + for (j = 0; j < 300; j++) + { + if (buf[i + j] != 'Y') + { + break; + } + } + + if (j >= 300) + { + break; + } + } + } + + if (i >= g_disk_buf_size) + { + debug("No need to fill vdisk path"); + return 0; + } + + debug("Fill vdisk path at %d", i); + + while (pos != end) + { + buf[i++] = (CHAR8)(*pos++); + } + + buf[i++] = '\"'; + + while (buf[i] == 'Y' || buf[i] == '\"') + { + buf[i] = ' '; + i++; + } + + return 0; +} + +EFI_STATUS EFIAPI vdisk_get_variable_wrapper +( + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + OUT UINT32 *Attributes, OPTIONAL + IN OUT UINTN *DataSize, + OUT VOID *Data OPTIONAL +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_org_get_variable(VariableName, VendorGuid, Attributes, DataSize, Data); + if (StrCmp(VariableName, L"SecureBoot") == 0) + { + if ((*DataSize == 1) && Data) + { + *(UINT8 *)Data = 0; + } + } + + return Status; +} + +EFI_STATUS EFIAPI vdisk_exit_boot_service_wrapper +( + IN EFI_HANDLE ImageHandle, + IN UINTN MapKey +) +{ + return g_org_exit_boot_service(ImageHandle, MapKey); +} + +STATIC EFI_STATUS EFIAPI vdisk_disable_secure_boot(IN EFI_HANDLE ImageHandle) +{ + /* step1: wrapper security protocol. */ + /* Do we still need it since we have been loaded ? */ + + + /* step2: fake SecureBoot variable */ + g_org_exit_boot_service = gBS->ExitBootServices; + gBS->ExitBootServices = vdisk_exit_boot_service_wrapper; + + g_org_get_variable = gRT->GetVariable; + gRT->GetVariable = vdisk_get_variable_wrapper; + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI vdisk_parse_cmdline(IN EFI_HANDLE ImageHandle) +{ + CHAR16 *Pos = NULL; + CHAR16 *pCmdLine = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); + if (EFI_ERROR(Status)) + { + VDiskDebug("Failed to handle load image protocol %r\n", Status); + return Status; + } + + pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4); + SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0); + CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize); + + if (StrStr(pCmdLine, L"debug")) + { + gVDiskDebugPrint = TRUE; + } + + debug("cmdline:<%s>", pCmdLine); + vdisk_debug_pause(); + + Pos = StrStr(pCmdLine, L"vdisk="); + if (NULL == Pos || NULL == StrStr(pCmdLine, L".vtoy")) + { + VDiskDebug("vdisk parameter not found!\n"); + return EFI_NOT_FOUND; + } + + vdisk_decompress_vdisk(pImageInfo); + + vdisk_patch_vdisk_path(Pos + 6); + + if (StrStr(pCmdLine, L"secureboot=off")) + { + vdisk_disable_secure_boot(ImageHandle); + } + + FreePool(pCmdLine); + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_boot(IN EFI_HANDLE ImageHandle) +{ + UINTN t = 0; + UINTN i = 0; + UINTN j = 0; + UINTN Find = 0; + UINTN Count = 0; + EFI_HANDLE Image = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL; + EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL; + + for (t = 0; t < 3; t++) + { + Count = 0; + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + debug("vdisk_boot fs count:%u", Count); + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile); + if (EFI_ERROR(Status)) + { + continue; + } + + debug("FS:%u Protocol:%p OpenVolume:%p", i, pFile, pFile->OpenVolume); + + Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, + (VOID **)&pDevPath, + ImageHandle, + Handles[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) + { + debug("Failed to open device path protocol %r", Status); + continue; + } + + debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE)); + if (CompareMem(gVDiskBlockData.Path, pDevPath, gVDiskBlockData.DevicePathCompareLen)) + { + debug("Not ventoy disk file system"); + continue; + } + + for (j = 1; j < ARRAY_SIZE(gEfiBootFileName); j++) + { + Status = vdisk_load_image(ImageHandle, pDevPath, gEfiBootFileName[j], + StrSize(gEfiBootFileName[j]), &Image); + if (EFI_SUCCESS == Status) + { + break; + } + debug("Failed to load image %r <%s>", Status, gEfiBootFileName[j]); + } + + if (j >= ARRAY_SIZE(gEfiBootFileName)) + { + continue; + } + + Find++; + debug("Find boot file, now try to boot ....."); + vdisk_debug_pause(); + + if (gVDiskDebugPrint) + { + gST->ConIn->Reset(gST->ConIn, FALSE); + } + + /* can't add debug print here */ + //ventoy_wrapper_system(); + Status = gBS->StartImage(Image, NULL, NULL); + if (EFI_ERROR(Status)) + { + debug("Failed to start image %r", Status); + sleep(3); + gBS->UnloadImage(Image); + break; + } + } + + FreePool(Handles); + + if (Find == 0) + { + debug("Fs not found, now wait and retry..."); + sleep(2); + } + } + + if (Find == 0) + { + return EFI_NOT_FOUND; + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI VDiskChainEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + EFI_STATUS Status = EFI_SUCCESS; + + gST->ConOut->ClearScreen(gST->ConOut); + vdisk_clear_input(); + + Status = vdisk_parse_cmdline(ImageHandle); + if (EFI_ERROR(Status)) + { + return Status; + } + + vdisk_install_blockio(ImageHandle, g_disk_buf_size); + vdisk_debug_pause(); + + Status = vdisk_boot(ImageHandle); + + gBS->DisconnectController(gVDiskBlockData.Handle, NULL, NULL); + gBS->UninstallMultipleProtocolInterfaces(gVDiskBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gVDiskBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gVDiskBlockData.Path, + NULL); + + if (EFI_NOT_FOUND == Status) + { + gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); + sleep(30); + } + + vdisk_clear_input(); + gST->ConOut->ClearScreen(gST->ConOut); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.h new file mode 100644 index 00000000..d4d21d00 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.h @@ -0,0 +1,97 @@ +/****************************************************************************** + * VDiskChain.h + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ + +#ifndef __VENTOY_H__ +#define __VENTOY_H__ + +#define VDISK_MAGIC_LEN 32 + +#define VDISK_BLOCK_DEVICE_PATH_GUID \ + { 0x6ed2134e, 0xc2ea, 0x4943, { 0x99, 0x54, 0xa7, 0x76, 0xe5, 0x9c, 0x12, 0xc3 }} + +#define VDISK_BLOCK_DEVICE_PATH_NAME L"vdisk" + +#if defined (MDE_CPU_IA32) + #define VENTOY_UEFI_DESC L"IA32 UEFI" +#elif defined (MDE_CPU_X64) + #define VENTOY_UEFI_DESC L"X64 UEFI" +#elif defined (MDE_CPU_EBC) +#elif defined (MDE_CPU_ARM) + #define VENTOY_UEFI_DESC L"ARM UEFI" +#elif defined (MDE_CPU_AARCH64) + #define VENTOY_UEFI_DESC L"ARM64 UEFI" +#else + #error Unknown Processor Type +#endif + +typedef struct vdisk_block_data +{ + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; /* Media descriptor */ + EFI_BLOCK_IO_PROTOCOL BlockIo; /* Block I/O protocol */ + + UINTN DevicePathCompareLen; + EFI_DEVICE_PATH_PROTOCOL *Path; /* Device path protocol */ + + EFI_HANDLE RawBlockIoHandle; + EFI_BLOCK_IO_PROTOCOL *pRawBlockIo; + EFI_DEVICE_PATH_PROTOCOL *pDiskDevPath; + + /* ventoy disk part2 ESP */ + EFI_HANDLE DiskFsHandle; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs; + EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath; + + EFI_HANDLE IsoDriverImage; +}vdisk_block_data; + + +#define debug(expr, ...) if (gVDiskDebugPrint) VDiskDebug("[VDISK] "expr"\r\n", ##__VA_ARGS__) +#define trace(expr, ...) VDiskDebug("[VDISK] "expr"\r\n", ##__VA_ARGS__) +#define sleep(sec) gBS->Stall(1000000 * (sec)) + +#define vdisk_debug_pause() \ +if (gVDiskDebugPrint) \ +{ \ + UINTN __Index = 0; \ + gST->ConOut->OutputString(gST->ConOut, L"[VDISK] ###### Press Enter to continue... ######\r\n");\ + gST->ConIn->Reset(gST->ConIn, FALSE); \ + gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\ +} + +extern BOOLEAN gVDiskDebugPrint; +VOID EFIAPI VDiskDebug(IN CONST CHAR8 *Format, ...); +EFI_STATUS EFIAPI vdisk_block_io_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +); + +extern UINT8 *g_disk_buf_addr; +extern UINT64 g_disk_buf_size; +extern vdisk_block_data gVDiskBlockData; +EFI_STATUS EFIAPI vdisk_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize); +int vdisk_get_vdisk_raw(UINT8 **buf, UINT32 *size); + +#endif + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.inf new file mode 100644 index 00000000..2f8cfefe --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChain.inf @@ -0,0 +1,82 @@ +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VDiskChain + FILE_GUID = 5bce96e3-ba11-4440-833b-299cf5849193 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VDiskChainEfiMain + + +[Sources] + VDiskChain.h + VDiskChain.c + VDiskRawData.c + VDiskChainProtocol.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DebugLib + UefiDecompressLib + +[Guids] + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + + + + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChainProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChainProtocol.c new file mode 100644 index 00000000..a6a6ad0b --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskChainProtocol.c @@ -0,0 +1,264 @@ +/****************************************************************************** + * VDiskChainProtocol.c + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* EFI block device vendor device path GUID */ +EFI_GUID gVDiskBlockDevicePathGuid = VDISK_BLOCK_DEVICE_PATH_GUID; + +EFI_STATUS EFIAPI vdisk_block_io_reset +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification +) +{ + (VOID)This; + (VOID)ExtendedVerification; + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) +{ + (VOID)This; + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_block_io_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + (VOID)This; + (VOID)MediaId; + + debug("vdisk_block_io_read %lu %lu\n", Lba, BufferSize / 512); + CopyMem(Buffer, g_disk_buf_addr + (Lba * 512), BufferSize); + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_block_io_write +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + (VOID)This; + (VOID)MediaId; + (VOID)Buffer; + + debug("vdisk_block_io_read %lu %lu\n", Lba, BufferSize / 512); + return EFI_WRITE_PROTECTED; +} + +EFI_STATUS EFIAPI vdisk_fill_device_path(VOID) +{ + UINTN NameLen = 0; + UINT8 TmpBuf[128] = {0}; + VENDOR_DEVICE_PATH *venPath = NULL; + + venPath = (VENDOR_DEVICE_PATH *)TmpBuf; + NameLen = StrSize(VDISK_BLOCK_DEVICE_PATH_NAME); + venPath->Header.Type = HARDWARE_DEVICE_PATH; + venPath->Header.SubType = HW_VENDOR_DP; + venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen; + venPath->Header.Length[1] = 0; + CopyMem(&venPath->Guid, &gVDiskBlockDevicePathGuid, sizeof(EFI_GUID)); + CopyMem(venPath + 1, VDISK_BLOCK_DEVICE_PATH_NAME, NameLen); + + gVDiskBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf); + gVDiskBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen; + + debug("gVDiskBlockData.Path=<%s>\n", ConvertDevicePathToText(gVDiskBlockData.Path, FALSE, FALSE)); + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI vdisk_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST CHAR16 *DrvName) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_HANDLE DrvHandles[2] = { NULL }; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + + debug("vdisk_connect_driver <%s>...", DrvName); + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName); + if (EFI_ERROR(Status) || NULL == DriverName) + { + continue; + } + + if (StrStr(DriverName, DrvName)) + { + debug("Find driver name2:<%s>: <%s>", DriverName, DrvName); + DrvHandles[0] = Handles[i]; + break; + } + } + + if (i < Count) + { + Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); + debug("vdisk_connect_driver:<%s> <%r>", DrvName, Status); + goto end; + } + + debug("%s NOT found, now try COMPONENT_NAME", DrvName); + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName); + if (EFI_ERROR(Status)) + { + continue; + } + + if (StrStr(DriverName, DrvName)) + { + debug("Find driver name:<%s>: <%s>", DriverName, DrvName); + DrvHandles[0] = Handles[i]; + break; + } + } + + if (i < Count) + { + Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); + debug("vdisk_connect_driver:<%s> <%r>", DrvName, Status); + goto end; + } + + Status = EFI_NOT_FOUND; + +end: + FreePool(Handles); + + return Status; +} + +EFI_STATUS EFIAPI vdisk_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gVDiskBlockData.BlockIo); + + vdisk_fill_device_path(); + + debug("install block io protocol %p", ImageHandle); + vdisk_debug_pause(); + + gVDiskBlockData.Media.BlockSize = 512; + gVDiskBlockData.Media.LastBlock = ImgSize / 512 - 1; + gVDiskBlockData.Media.ReadOnly = TRUE; + gVDiskBlockData.Media.MediaPresent = 1; + gVDiskBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; + + pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; + pBlockIo->Media = &(gVDiskBlockData.Media); + pBlockIo->Reset = vdisk_block_io_reset; + pBlockIo->ReadBlocks = vdisk_block_io_read; + pBlockIo->WriteBlocks = vdisk_block_io_write; + pBlockIo->FlushBlocks = vdisk_block_io_flush; + + Status = gBS->InstallMultipleProtocolInterfaces(&gVDiskBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gVDiskBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gVDiskBlockData.Path, + NULL); + debug("Install protocol %r %p", Status, gVDiskBlockData.Handle); + if (EFI_ERROR(Status)) + { + return Status; + } + + Status = vdisk_connect_driver(gVDiskBlockData.Handle, L"Disk I/O Driver"); + debug("Connect disk IO driver %r", Status); + + Status = vdisk_connect_driver(gVDiskBlockData.Handle, L"Partition Driver"); + debug("Connect partition driver %r", Status); + if (EFI_ERROR(Status)) + { + Status = gBS->ConnectController(gVDiskBlockData.Handle, NULL, NULL, TRUE); + debug("Connect all controller %r", Status); + } + + vdisk_debug_pause(); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskRawData.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskRawData.c new file mode 100644 index 00000000..a0aaaa1b --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VDiskChain/VDiskRawData.c @@ -0,0 +1,2 @@ +#include +int vdisk_get_vdisk_raw(UINT8 **buf, UINT32 *size) { *buf = NULL; *size = 0; return 0; } \ No newline at end of file diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c index 7c2267f5..3b7cf244 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.c @@ -34,11 +34,17 @@ #include #include #include +#include #include BOOLEAN gDebugPrint = FALSE; +BOOLEAN gBootFallBack = FALSE; +BOOLEAN gDotEfiBoot = FALSE; +BOOLEAN gLoadIsoEfi = FALSE; +BOOLEAN gIsoUdf = FALSE; ventoy_ram_disk g_ramdisk_param; ventoy_chain_head *g_chain; +void *g_vtoy_img_location_buf; ventoy_img_chunk *g_chunk; UINT8 *g_os_param_reserved; UINT32 g_img_chunk_num; @@ -48,10 +54,16 @@ ventoy_virt_chunk *g_virt_chunk; UINT32 g_virt_chunk_num; vtoy_block_data gBlockData; static grub_env_get_pf grub_env_get = NULL; +static grub_env_set_pf grub_env_set = NULL; ventoy_grub_param_file_replace *g_file_replace_list = NULL; ventoy_efi_file_replace g_efi_file_replace; +CONST CHAR16 gIso9660EfiDriverPath[] = ISO9660_EFI_DRIVER_PATH; +CONST CHAR16 gUdfEfiDriverPath[] = UDF_EFI_DRIVER_PATH; + +BOOLEAN g_fix_windows_1st_cdrom_issue = FALSE; + STATIC BOOLEAN g_hook_keyboard = FALSE; CHAR16 gFirstTryBootFile[256] = {0}; @@ -62,10 +74,28 @@ CONST CHAR16 *gEfiBootFileName[] = { L"@", EFI_REMOVABLE_MEDIA_FILE_NAME, +#if defined (MDE_CPU_IA32) + L"\\EFI\\BOOT\\GRUBIA32.EFI", + L"\\EFI\\BOOT\\BOOTia32.EFI", + L"\\EFI\\BOOT\\bootia32.efi", + L"\\efi\\boot\\bootia32.efi", +#elif defined (MDE_CPU_X64) L"\\EFI\\BOOT\\GRUBX64.EFI", L"\\EFI\\BOOT\\BOOTx64.EFI", L"\\EFI\\BOOT\\bootx64.efi", L"\\efi\\boot\\bootx64.efi", +#elif defined (MDE_CPU_ARM) + L"\\EFI\\BOOT\\GRUBARM.EFI", + L"\\EFI\\BOOT\\BOOTarm.EFI", + L"\\EFI\\BOOT\\bootarm.efi", + L"\\efi\\boot\\bootarm.efi", +#elif defined (MDE_CPU_AARCH64) + L"\\EFI\\BOOT\\GRUBAA64.EFI", + L"\\EFI\\BOOT\\BOOTaa64.EFI", + L"\\EFI\\BOOT\\bootaa64.efi", + L"\\efi\\boot\\bootaa64.efi", +#endif + }; VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...) @@ -242,6 +272,7 @@ static int ventoy_update_image_location(ventoy_os_param *param) } address = (UINTN)buffer; + g_vtoy_img_location_buf = buffer; if (address % 4096) { @@ -266,19 +297,33 @@ static int ventoy_update_image_location(ventoy_os_param *param) } CopyMem(&location->guid, ¶m->guid, sizeof(ventoy_guid)); - location->image_sector_size = 2048; + location->image_sector_size = gSector512Mode ? 512 : 2048; location->disk_sector_size = g_chain->disk_sector_size; location->region_count = g_img_chunk_num; region = location->regions; - for (i = 0; i < g_img_chunk_num; i++) + if (gSector512Mode) { - region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; - region->image_start_sector = chunk->img_start_sector; - region->disk_start_sector = chunk->disk_start_sector; - region++; - chunk++; + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; + region->image_start_sector = chunk->img_start_sector * 4; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + else + { + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; + region->image_start_sector = chunk->img_start_sector; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } } return 0; @@ -318,15 +363,27 @@ EFI_HANDLE EFIAPI ventoy_get_parent_handle(IN EFI_DEVICE_PATH_PROTOCOL *pDevPath return Handle; } +STATIC ventoy_ram_disk g_backup_ramdisk_param; +STATIC ventoy_os_param g_backup_os_param_var; + + EFI_STATUS EFIAPI ventoy_save_ramdisk_param(VOID) { + UINTN DataSize; EFI_STATUS Status = EFI_SUCCESS; EFI_GUID VarGuid = VENTOY_GUID; + + DataSize = sizeof(g_backup_ramdisk_param); + Status = gRT->GetVariable(L"VentoyRamDisk", &VarGuid, NULL, &DataSize, &g_backup_ramdisk_param); + if (!EFI_ERROR(Status)) + { + debug("find previous ramdisk variable <%llu>", g_backup_ramdisk_param.DiskSize); + } Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(g_ramdisk_param), &(g_ramdisk_param)); - debug("set efi variable %r", Status); + debug("set ramdisk variable %r", Status); return Status; } @@ -335,21 +392,38 @@ EFI_STATUS EFIAPI ventoy_delete_ramdisk_param(VOID) { EFI_STATUS Status = EFI_SUCCESS; EFI_GUID VarGuid = VENTOY_GUID; - - Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, + + if (g_backup_ramdisk_param.DiskSize > 0 && g_backup_ramdisk_param.PhyAddr > 0) + { + Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(g_backup_ramdisk_param), &g_backup_ramdisk_param); + debug("resotre ramdisk variable %r", Status); + } + else + { + Status = gRT->SetVariable(L"VentoyRamDisk", &VarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); - debug("delete efi variable %r", Status); + debug("delete ramdisk variable %r", Status); + } return Status; } - EFI_STATUS EFIAPI ventoy_save_variable(VOID) { + UINTN DataSize; EFI_STATUS Status = EFI_SUCCESS; EFI_GUID VarGuid = VENTOY_GUID; - + + DataSize = sizeof(g_backup_os_param_var); + Status = gRT->GetVariable(L"VentoyOsParam", &VarGuid, NULL, &DataSize, &g_backup_os_param_var); + if (!EFI_ERROR(Status)) + { + debug("find previous efi variable <%a>", g_backup_os_param_var.vtoy_img_path); + } + Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(g_chain->os_param), &(g_chain->os_param)); @@ -362,15 +436,55 @@ EFI_STATUS EFIAPI ventoy_delete_variable(VOID) { EFI_STATUS Status = EFI_SUCCESS; EFI_GUID VarGuid = VENTOY_GUID; - - Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid, + + if (0 == CompareMem(&(g_backup_os_param_var.guid), &VarGuid, sizeof(EFI_GUID))) + { + Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(g_backup_os_param_var), &(g_backup_os_param_var)); + debug("restore efi variable %r", Status); + } + else + { + Status = gRT->SetVariable(L"VentoyOsParam", &VarGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL); - debug("delete efi variable %r", Status); + debug("delete efi variable %r", Status); + } return Status; } +#if (VENTOY_DEVICE_WARN != 0) +STATIC VOID ventoy_warn_invalid_device(VOID) +{ + STATIC BOOLEAN flag = FALSE; + + if (flag) + { + return; + } + + flag = TRUE; + gST->ConOut->ClearScreen(gST->ConOut); + gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n"); + gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n"); + gST->ConOut->OutputString(gST->ConOut, VTOY_WARNING L"\r\n\r\n\r\n"); + + gST->ConOut->OutputString(gST->ConOut, L"This is NOT a standard Ventoy device and is NOT supported.\r\n\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"You should follow the official instructions in https://www.ventoy.net\r\n"); + + gST->ConOut->OutputString(gST->ConOut, L"\r\n\r\nWill exit after 10 seconds ...... "); + + sleep(10); +} +#else +STATIC VOID ventoy_warn_invalid_device(VOID) +{ + +} +#endif + STATIC EFI_STATUS EFIAPI ventoy_load_image ( IN EFI_HANDLE ImageHandle, @@ -413,6 +527,7 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle) UINTN i = 0; UINTN Count = 0; UINT64 DiskSize = 0; + MBR_HEAD *pMBR = NULL; UINT8 *pBuffer = NULL; EFI_HANDLE *Handles; EFI_STATUS Status = EFI_SUCCESS; @@ -456,6 +571,18 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle) if (CompareMem(g_chain->os_param.vtoy_disk_guid, pBuffer + 0x180, 16) == 0) { + pMBR = (MBR_HEAD *)pBuffer; + if (pMBR->PartTbl[0].FsFlag != 0xEE) + { + if (pMBR->PartTbl[0].StartSectorId != 2048 || + pMBR->PartTbl[1].SectorCount != 65536 || + pMBR->PartTbl[1].StartSectorId != pMBR->PartTbl[0].StartSectorId + pMBR->PartTbl[0].SectorCount) + { + debug("Failed to check disk part table"); + ventoy_warn_invalid_device(); + } + } + gBlockData.RawBlockIoHandle = Handles[i]; gBlockData.pRawBlockIo = pBlockIo; gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, @@ -482,17 +609,117 @@ STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk(IN EFI_HANDLE ImageHandle) } } + +STATIC EFI_STATUS EFIAPI ventoy_find_iso_disk_fs(IN EFI_HANDLE ImageHandle) +{ + UINTN i = 0; + UINTN Count = 0; + EFI_HANDLE Parent = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pFile = NULL; + EFI_DEVICE_PATH_PROTOCOL *pDevPath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiSimpleFileSystemProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + debug("ventoy_find_iso_disk_fs fs count:%u", Count); + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiSimpleFileSystemProtocolGuid, (VOID **)&pFile); + if (EFI_ERROR(Status)) + { + continue; + } + + Status = gBS->OpenProtocol(Handles[i], &gEfiDevicePathProtocolGuid, + (VOID **)&pDevPath, + ImageHandle, + Handles[i], + EFI_OPEN_PROTOCOL_GET_PROTOCOL); + if (EFI_ERROR(Status)) + { + debug("Failed to open device path protocol %r", Status); + continue; + } + + debug("Handle:%p FS DP: <%s>", Handles[i], ConvertDevicePathToText(pDevPath, FALSE, FALSE)); + Parent = ventoy_get_parent_handle(pDevPath); + + if (Parent == gBlockData.RawBlockIoHandle) + { + debug("Find ventoy disk fs"); + gBlockData.DiskFsHandle = Handles[i]; + gBlockData.pDiskFs = pFile; + gBlockData.pDiskFsDevPath = pDevPath; + break; + } + } + + FreePool(Handles); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_load_isoefi_driver(IN EFI_HANDLE ImageHandle) +{ + EFI_HANDLE Image = NULL; + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 LogVar[4] = L"5"; + + if (gIsoUdf) + { + Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath, + gUdfEfiDriverPath, + sizeof(gUdfEfiDriverPath), + &Image); + debug("load iso UDF efi driver status:%r", Status); + } + else + { + Status = ventoy_load_image(ImageHandle, gBlockData.pDiskFsDevPath, + gIso9660EfiDriverPath, + sizeof(gIso9660EfiDriverPath), + &Image); + debug("load iso 9660 efi driver status:%r", Status); + } + + if (gDebugPrint) + { + gRT->SetVariable(L"FS_LOGGING", &gShellVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(LogVar), LogVar); + } + + gRT->SetVariable(L"FS_NAME_NOCASE", &gShellVariableGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(LogVar), LogVar); + + gBlockData.IsoDriverImage = Image; + Status = gBS->StartImage(Image, NULL, NULL); + debug("Start iso efi driver status:%r", Status); + + return EFI_SUCCESS; +} + STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) { UINT32 i = 0; UINT32 old_cnt = 0; UINTN size = 0; UINT8 chksum = 0; + const char *pEnv = NULL; CHAR16 *pPos = NULL; CHAR16 *pCmdLine = NULL; EFI_STATUS Status = EFI_SUCCESS; ventoy_grub_param *pGrubParam = NULL; EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + ventoy_chain_head *chain = NULL; Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); if (EFI_ERROR(Status)) @@ -509,6 +736,26 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) { gDebugPrint = TRUE; } + + if (StrStr(pCmdLine, L"fallback")) + { + gBootFallBack = TRUE; + } + + if (StrStr(pCmdLine, L"dotefi")) + { + gDotEfiBoot = TRUE; + } + + if (StrStr(pCmdLine, L"isoefi=on")) + { + gLoadIsoEfi = TRUE; + } + + if (StrStr(pCmdLine, L"iso_udf")) + { + gIsoUdf = TRUE; + } pPos = StrStr(pCmdLine, L"FirstTry=@"); if (pPos) @@ -544,8 +791,20 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) } pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param=")); + grub_env_set = pGrubParam->grub_env_set; grub_env_get = pGrubParam->grub_env_get; + pEnv = grub_env_get("VTOY_CHKDEV_RESULT_STRING"); + if (!pEnv) + { + return EFI_INVALID_PARAMETER; + } + if (pEnv[0] != '0' || pEnv[1] != 0) + { + ventoy_warn_invalid_device(); + return EFI_INVALID_PARAMETER; + } + g_file_replace_list = &pGrubParam->file_replace; old_cnt = g_file_replace_list->old_file_cnt; debug("file replace: magic:0x%x virtid:%u name count:%u <%a> <%a> <%a> <%a>", @@ -559,20 +818,33 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) ); pPos = StrStr(pCmdLine, L"mem:"); - g_chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4); + chain = (ventoy_chain_head *)StrHexToUintn(pPos + 4); pPos = StrStr(pPos, L"size:"); size = StrDecimalToUintn(pPos + 5); - debug("memory addr:%p size:%lu", g_chain, size); + debug("memory addr:%p size:%lu", chain, size); + + if (StrStr(pCmdLine, L"sector512")) + { + gSector512Mode = TRUE; + } if (StrStr(pCmdLine, L"memdisk")) { - g_iso_buf_size = size; + g_iso_data_buf = (UINT8 *)chain + sizeof(ventoy_chain_head); + g_iso_buf_size = size - sizeof(ventoy_chain_head); + debug("memdisk mode iso_buf_size:%u", g_iso_buf_size); + + g_chain = chain; gMemdiskMode = TRUE; } else { + debug("This is normal mode"); + g_chain = AllocatePool(size); + CopyMem(g_chain, chain, size); + g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset); g_img_chunk_num = g_chain->img_chunk_num; g_override_chunk = (ventoy_override_chunk *)((char *)g_chain + g_chain->override_chunk_offset); @@ -583,12 +855,12 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) g_os_param_reserved = (UINT8 *)(g_chain->os_param.vtoy_reserved); /* Workaround for Windows & ISO9660 */ - if (g_os_param_reserved[2] == 1 && g_os_param_reserved[3] == 0) + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0) { g_fixup_iso9660_secover_enable = TRUE; } - if (g_os_param_reserved[2] == 1 && g_os_param_reserved[4] != 1) + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[4] != 1) { g_hook_keyboard = TRUE; } @@ -613,6 +885,19 @@ STATIC EFI_STATUS EFIAPI ventoy_parse_cmdline(IN EFI_HANDLE ImageHandle) } } + g_fix_windows_1st_cdrom_issue = FALSE; + if (ventoy_chain_windows == g_os_param_reserved[2] || + ventoy_chain_wim == g_os_param_reserved[2]) + { + if (ventoy_is_cdrom_dp_exist()) + { + debug("fixup the 1st cdrom influences when boot windows ..."); + g_fix_windows_1st_cdrom_issue = TRUE; + } + } + + ventoy_debug_pause(); + FreePool(pCmdLine); return EFI_SUCCESS; } @@ -622,6 +907,11 @@ EFI_STATUS EFIAPI ventoy_clean_env(VOID) FreePool(g_sector_flag); g_sector_flag_num = 0; + if (gLoadIsoEfi && gBlockData.IsoDriverImage) + { + gBS->UnloadImage(gBlockData.IsoDriverImage); + } + gBS->DisconnectController(gBlockData.Handle, NULL, NULL); gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle, @@ -631,9 +921,50 @@ EFI_STATUS EFIAPI ventoy_clean_env(VOID) ventoy_delete_variable(); - if (g_chain->os_param.vtoy_img_location_addr) + if (g_vtoy_img_location_buf) { - FreePool((VOID *)(UINTN)g_chain->os_param.vtoy_img_location_addr); + FreePool(g_vtoy_img_location_buf); + } + + if (!gMemdiskMode) + { + FreePool(g_chain); + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS ventoy_hook_start(VOID) +{ + /* don't add debug print in this function */ + + if (g_fix_windows_1st_cdrom_issue) + { + ventoy_hook_1st_cdrom_start(); + } + + /* let this the last */ + if (g_hook_keyboard) + { + ventoy_hook_keyboard_start(); + } + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS ventoy_hook_stop(VOID) +{ + /* don't add debug print in this function */ + + if (g_fix_windows_1st_cdrom_issue) + { + ventoy_hook_1st_cdrom_stop(); + } + + /* let this the last */ + if (g_hook_keyboard) + { + ventoy_hook_keyboard_stop(); } return EFI_SUCCESS; @@ -725,17 +1056,11 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) pFile->OpenVolume = ventoy_wrapper_open_volume; } - if (g_hook_keyboard) - { - ventoy_hook_keyboard_start(); - } + ventoy_hook_start(); /* can't add debug print here */ //ventoy_wrapper_system(); Status = gBS->StartImage(Image, NULL, NULL); - if (g_hook_keyboard) - { - ventoy_hook_keyboard_stop(); - } + ventoy_hook_stop(); if (EFI_ERROR(Status)) { @@ -750,8 +1075,13 @@ EFI_STATUS EFIAPI ventoy_boot(IN EFI_HANDLE ImageHandle) if (Find == 0) { + if (gDotEfiBoot) + { + break; + } + debug("Fs not found, now wait and retry..."); - sleep(2); + sleep(1); } } @@ -789,46 +1119,90 @@ EFI_STATUS EFIAPI VentoyEfiMain gST->ConOut->ClearScreen(gST->ConOut); ventoy_clear_input(); - ventoy_parse_cmdline(ImageHandle); + Status = ventoy_parse_cmdline(ImageHandle); + if (EFI_ERROR(Status)) + { + return Status; + } + + ventoy_disable_ex_filesystem(); if (gMemdiskMode) { - g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_chain; + g_ramdisk_param.PhyAddr = (UINT64)(UINTN)g_iso_data_buf; g_ramdisk_param.DiskSize = (UINT64)g_iso_buf_size; ventoy_save_ramdisk_param(); + + if (gLoadIsoEfi) + { + ventoy_find_iso_disk(ImageHandle); + ventoy_find_iso_disk_fs(ImageHandle); + ventoy_load_isoefi_driver(ImageHandle); + } ventoy_install_blockio(ImageHandle, g_iso_buf_size); + ventoy_debug_pause(); + Status = ventoy_boot(ImageHandle); ventoy_delete_ramdisk_param(); + + if (gLoadIsoEfi && gBlockData.IsoDriverImage) + { + gBS->UnloadImage(gBlockData.IsoDriverImage); + } + + gBS->DisconnectController(gBlockData.Handle, NULL, NULL); + gBS->UninstallMultipleProtocolInterfaces(gBlockData.Handle, + &gEfiBlockIoProtocolGuid, &gBlockData.BlockIo, + &gEfiDevicePathProtocolGuid, gBlockData.Path, + NULL); } else { ventoy_save_variable(); - ventoy_find_iso_disk(ImageHandle); + Status = ventoy_find_iso_disk(ImageHandle); + if (!EFI_ERROR(Status)) + { + if (gLoadIsoEfi) + { + ventoy_find_iso_disk_fs(ImageHandle); + ventoy_load_isoefi_driver(ImageHandle); + } - ventoy_debug_pause(); + ventoy_debug_pause(); + + ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes); + + ventoy_debug_pause(); + + Status = ventoy_boot(ImageHandle); + } - ventoy_install_blockio(ImageHandle, g_chain->virt_img_size_in_bytes); - - ventoy_debug_pause(); - - Status = ventoy_boot(ImageHandle); - ventoy_clean_env(); } - if (EFI_NOT_FOUND == Status) + if (FALSE == gDotEfiBoot && FALSE == gBootFallBack) { - gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); - gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); - sleep(30); + if (EFI_NOT_FOUND == Status) + { + gST->ConOut->OutputString(gST->ConOut, L"No bootfile found for UEFI!\r\n"); + gST->ConOut->OutputString(gST->ConOut, L"Maybe the image does not support " VENTOY_UEFI_DESC L"!\r\n"); + sleep(30); + } } - + ventoy_clear_input(); gST->ConOut->ClearScreen(gST->ConOut); + if (gDotEfiBoot && (EFI_NOT_FOUND == Status)) + { + grub_env_set("vtoy_dotefi_retry", "YES"); + } + + ventoy_enable_ex_filesystem(); + return EFI_SUCCESS; } diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h index 354496e7..04b67e79 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.h @@ -25,6 +25,15 @@ #define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + #pragma pack(1) typedef struct ventoy_guid @@ -159,21 +168,32 @@ typedef struct ventoy_virt_chunk #define VTOY_BLOCK_DEVICE_PATH_GUID \ { 0x37b87ac6, 0xc180, 0x4583, { 0xa7, 0x05, 0x41, 0x4d, 0xa8, 0xf7, 0x7e, 0xd2 }} -#define VTOY_BLOCK_DEVICE_PATH_NAME L"ventoy" + #if defined (MDE_CPU_IA32) #define VENTOY_UEFI_DESC L"IA32 UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_ia32.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_ia32.efi" #elif defined (MDE_CPU_X64) #define VENTOY_UEFI_DESC L"X64 UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_x64.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_x64.efi" #elif defined (MDE_CPU_EBC) #elif defined (MDE_CPU_ARM) #define VENTOY_UEFI_DESC L"ARM UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_arm.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_arm.efi" #elif defined (MDE_CPU_AARCH64) #define VENTOY_UEFI_DESC L"ARM64 UEFI" + #define ISO9660_EFI_DRIVER_PATH L"\\ventoy\\iso9660_aa64.efi" + #define UDF_EFI_DRIVER_PATH L"\\ventoy\\udf_aa64.efi" #else #error Unknown Processor Type #endif +#define VENTOY_DEVICE_WARN 1 +#define VTOY_WARNING L"!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!" + typedef struct ventoy_sector_flag { UINT8 flag; // 0:init 1:mem 2:remap @@ -199,6 +219,7 @@ typedef struct vtoy_block_data EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pDiskFs; EFI_DEVICE_PATH_PROTOCOL *pDiskFsDevPath; + EFI_HANDLE IsoDriverImage; }vtoy_block_data; @@ -215,7 +236,9 @@ if (gDebugPrint) \ gBS->WaitForEvent(1, &gST->ConIn->WaitForKey, &__Index);\ } +typedef int (*grub_env_set_pf)(const char *name, const char *val); typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); #pragma pack(1) @@ -242,8 +265,9 @@ typedef struct ventoy_grub_param_file_replace typedef struct ventoy_grub_param { grub_env_get_pf grub_env_get; - + grub_env_set_pf grub_env_set; ventoy_grub_param_file_replace file_replace; + grub_env_printf_pf grub_env_printf; }ventoy_grub_param; typedef struct ventoy_ram_disk @@ -260,6 +284,32 @@ typedef struct ventoy_iso9660_override UINT32 size_be; }ventoy_iso9660_override; +typedef struct PART_TABLE +{ + UINT8 Active; // 0x00 0x80 + + UINT8 StartHead; + UINT16 StartSector : 6; + UINT16 StartCylinder : 10; + + UINT8 FsFlag; + + UINT8 EndHead; + UINT16 EndSector : 6; + UINT16 EndCylinder : 10; + + UINT32 StartSectorId; + UINT32 SectorCount; +}PART_TABLE; + +typedef struct MBR_HEAD +{ + UINT8 BootCode[446]; + PART_TABLE PartTbl[4]; + UINT8 Byte55; + UINT8 ByteAA; +}MBR_HEAD; + #pragma pack() @@ -279,8 +329,28 @@ typedef struct ventoy_system_wrapper EFI_OPEN_PROTOCOL NewOpenProtocol; EFI_OPEN_PROTOCOL OriOpenProtocol; + + EFI_LOCATE_HANDLE_BUFFER NewLocateHandleBuffer; + EFI_LOCATE_HANDLE_BUFFER OriLocateHandleBuffer; + + EFI_PROTOCOLS_PER_HANDLE NewProtocolsPerHandle; + EFI_PROTOCOLS_PER_HANDLE OriProtocolsPerHandle; + + EFI_LOCATE_HANDLE NewLocateHandle; + EFI_LOCATE_HANDLE OriLocateHandle; + + EFI_LOCATE_DEVICE_PATH NewLocateDevicePath; + EFI_LOCATE_DEVICE_PATH OriLocateDevicePath; } ventoy_system_wrapper; + +#define MAX_DRIVER_BIND_WRAPPER 64 +typedef struct DriverBindWrapper +{ + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + EFI_DRIVER_BINDING_SUPPORTED pfOldSupport; +}DRIVER_BIND_WRAPPER; + #define ventoy_wrapper(bs, wrapper, func, newfunc) \ {\ wrapper.Ori##func = bs->func;\ @@ -288,6 +358,22 @@ typedef struct ventoy_system_wrapper bs->func = wrapper.New##func;\ } + +#define VENTOY_GET_COMPONENT_NAME(Protocol, DriverName) \ +{\ + DriverName = NULL;\ + Status = Protocol->GetDriverName(Protocol, "en", &DriverName);\ + if (EFI_ERROR(Status) || NULL == DriverName) \ + {\ + DriverName = NULL;\ + Status = Protocol->GetDriverName(Protocol, "eng", &DriverName);\ + if (EFI_ERROR(Status) || NULL == DriverName) \ + {\ + continue;\ + }\ + }\ +} + extern BOOLEAN gDebugPrint; VOID EFIAPI VtoyDebug(IN CONST CHAR8 *Format, ...); EFI_STATUS EFIAPI ventoy_wrapper_system(VOID); @@ -313,10 +399,13 @@ extern ventoy_efi_file_replace g_efi_file_replace; extern ventoy_sector_flag *g_sector_flag; extern UINT32 g_sector_flag_num; extern BOOLEAN gMemdiskMode; +extern BOOLEAN gSector512Mode; extern UINTN g_iso_buf_size; +extern UINT8 *g_iso_data_buf; extern ventoy_grub_param_file_replace *g_file_replace_list; extern BOOLEAN g_fixup_iso9660_secover_enable; extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex; +extern BOOLEAN g_fix_windows_1st_cdrom_issue; EFI_STATUS EFIAPI ventoy_wrapper_open_volume ( @@ -327,6 +416,11 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im EFI_STATUS EFIAPI ventoy_wrapper_push_openvolume(IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_OPEN_VOLUME OpenVolume); EFI_STATUS ventoy_hook_keyboard_start(VOID); EFI_STATUS ventoy_hook_keyboard_stop(VOID); +BOOLEAN ventoy_is_cdrom_dp_exist(VOID); +EFI_STATUS ventoy_hook_1st_cdrom_start(VOID); +EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID); +EFI_STATUS ventoy_disable_ex_filesystem(VOID); +EFI_STATUS ventoy_enable_ex_filesystem(VOID); #endif diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf index 00a5e548..892d8c77 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/Ventoy.inf @@ -1,81 +1,81 @@ -#************************************************************************************ -# Copyright (c) 2020, longpanda -# -# 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 . -# -#************************************************************************************ - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = Ventoy - FILE_GUID = 1c3a0915-09dc-49c2-873d-0aaaa7733299 - MODULE_TYPE = UEFI_APPLICATION - VERSION_STRING = 1.0 - ENTRY_POINT = VentoyEfiMain - - -[Sources] - Ventoy.h - Ventoy.c - VentoyDebug.c - VentoyProtocol.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - ShellPkg/ShellPkg.dec - -[LibraryClasses] - UefiApplicationEntryPoint - UefiLib - DebugLib - -[Guids] - gShellVariableGuid - gEfiVirtualCdGuid - gEfiFileInfoGuid - -[Protocols] - gEfiLoadedImageProtocolGuid - gEfiBlockIoProtocolGuid - gEfiDevicePathProtocolGuid - gEfiSimpleFileSystemProtocolGuid - gEfiRamDiskProtocolGuid - gEfiAbsolutePointerProtocolGuid - gEfiAcpiTableProtocolGuid - gEfiBlockIo2ProtocolGuid - gEfiBusSpecificDriverOverrideProtocolGuid - gEfiComponentNameProtocolGuid - gEfiComponentName2ProtocolGuid - gEfiDriverBindingProtocolGuid - gEfiDiskIoProtocolGuid - gEfiDiskIo2ProtocolGuid - gEfiGraphicsOutputProtocolGuid - gEfiHiiConfigAccessProtocolGuid - gEfiHiiFontProtocolGuid - gEfiLoadFileProtocolGuid - gEfiLoadFile2ProtocolGuid - gEfiLoadedImageProtocolGuid - gEfiLoadedImageDevicePathProtocolGuid - gEfiPciIoProtocolGuid - gEfiSerialIoProtocolGuid - gEfiSimpleTextInProtocolGuid - gEfiSimpleTextInputExProtocolGuid - gEfiSimpleTextOutProtocolGuid - - - - - - +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = Ventoy + FILE_GUID = 1c3a0915-09dc-49c2-873d-0aaaa7733299 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VentoyEfiMain + + +[Sources] + Ventoy.h + Ventoy.c + VentoyDebug.c + VentoyProtocol.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DebugLib + +[Guids] + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + + + + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c index d96c6b2e..9bdfaaa9 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyDebug.c @@ -34,11 +34,12 @@ #include #include #include +#include #include -#define PROCOTOL_SLEEP_SECONDS 0 +#define PROCOTOL_SLEEP_MSECONDS 0 -#define debug_sleep() if (PROCOTOL_SLEEP_SECONDS) sleep(PROCOTOL_SLEEP_SECONDS) +#define debug_sleep() if (PROCOTOL_SLEEP_MSECONDS) gBS->Stall(1000 * PROCOTOL_SLEEP_MSECONDS) STATIC ventoy_system_wrapper g_system_wrapper; @@ -126,7 +127,7 @@ STATIC EFI_STATUS EFIAPI ventoy_open_protocol IN UINT32 Attributes ) { - debug("ventoy_open_protocol:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + debug("ventoy_open_protocol:<%p> %a", Handle, ventoy_get_guid_name(Protocol)); debug_sleep(); return g_system_wrapper.OriOpenProtocol(Handle, Protocol, Interface, AgentHandle, ControllerHandle, Attributes); } @@ -141,11 +142,87 @@ STATIC EFI_STATUS EFIAPI ventoy_locate_protocol return g_system_wrapper.OriLocateProtocol(Protocol, Registration, Interface); } +STATIC EFI_STATUS EFIAPI ventoy_locate_handle_buffer +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *NoHandles, + OUT EFI_HANDLE **Buffer +) +{ + debug("ventoy_locate_handle_buffer:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriLocateHandleBuffer(SearchType, Protocol, SearchKey, NoHandles, Buffer); +} + +STATIC EFI_STATUS EFIAPI ventoy_protocol_per_handle +( + IN EFI_HANDLE Handle, + OUT EFI_GUID ***ProtocolBuffer, + OUT UINTN *ProtocolBufferCount +) +{ + debug("ventoy_protocol_per_handle:%p", Handle); debug_sleep(); + return g_system_wrapper.OriProtocolsPerHandle(Handle, ProtocolBuffer, ProtocolBufferCount); +} + +EFI_STATUS EFIAPI ventoy_locate_handle +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer +) +{ + UINTN i; + EFI_HANDLE Handle; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_locate_handle: %d %a %p", SearchType, ventoy_get_guid_name(Protocol), SearchKey); + Status = g_system_wrapper.OriLocateHandle(SearchType, Protocol, SearchKey, BufferSize, Buffer); + debug("ventoy_locate_handle: %r Handle Count:%u", Status, *BufferSize/sizeof(EFI_HANDLE)); + + if (EFI_SUCCESS == Status) + { + for (i = 0; i < *BufferSize / sizeof(EFI_HANDLE); i++) + { + if (Buffer[i] == gBlockData.Handle) + { + Handle = Buffer[0]; + Buffer[0] = Buffer[i]; + Buffer[i] = Handle; + debug("####### Handle at %u", i); + break; + } + } + } + + debug_sleep(); + + return Status; +} + +STATIC EFI_STATUS EFIAPI ventoy_locate_device_path +( + IN EFI_GUID *Protocol, + IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath, + OUT EFI_HANDLE *Device +) +{ + debug("ventoy_locate_device_path:%a", ventoy_get_guid_name(Protocol)); debug_sleep(); + return g_system_wrapper.OriLocateDevicePath(Protocol, DevicePath, Device); +} + EFI_STATUS EFIAPI ventoy_wrapper_system(VOID) { - ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol); - ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol); - ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol); + ventoy_wrapper(gBS, g_system_wrapper, LocateProtocol, ventoy_locate_protocol); + ventoy_wrapper(gBS, g_system_wrapper, HandleProtocol, ventoy_handle_protocol); + ventoy_wrapper(gBS, g_system_wrapper, OpenProtocol, ventoy_open_protocol); + ventoy_wrapper(gBS, g_system_wrapper, LocateHandleBuffer, ventoy_locate_handle_buffer); + ventoy_wrapper(gBS, g_system_wrapper, ProtocolsPerHandle, ventoy_protocol_per_handle); + ventoy_wrapper(gBS, g_system_wrapper, LocateHandle, ventoy_locate_handle); + ventoy_wrapper(gBS, g_system_wrapper, LocateDevicePath, ventoy_locate_device_path); return EFI_SUCCESS; } diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c index 0e19153c..9c8fc0e7 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/Ventoy/VentoyProtocol.c @@ -34,10 +34,13 @@ #include #include #include +#include #include +UINT8 *g_iso_data_buf = NULL; UINTN g_iso_buf_size = 0; BOOLEAN gMemdiskMode = FALSE; +BOOLEAN gSector512Mode = FALSE; ventoy_sector_flag *g_sector_flag = NULL; UINT32 g_sector_flag_num = 0; @@ -65,6 +68,54 @@ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *g_con_simple_input_ex = NULL; STATIC EFI_INPUT_READ_KEY_EX g_org_read_key_ex = NULL; STATIC EFI_INPUT_READ_KEY g_org_read_key = NULL; +STATIC EFI_LOCATE_HANDLE g_org_locate_handle = NULL; + +STATIC UINT8 g_sector_buf[2048]; +STATIC EFI_BLOCK_READ g_sector_2048_read = NULL; +STATIC EFI_BLOCK_WRITE g_sector_2048_write = NULL; + +STATIC UINTN g_DriverBindWrapperCnt = 0; +STATIC DRIVER_BIND_WRAPPER g_DriverBindWrapperList[MAX_DRIVER_BIND_WRAPPER]; + +BOOLEAN ventoy_is_cdrom_dp_exist(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return FALSE; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + continue; + } + + while (!IsDevicePathEnd(DevicePath)) + { + if (MEDIA_DEVICE_PATH == DevicePath->Type && MEDIA_CDROM_DP == DevicePath->SubType) + { + FreePool(Handles); + return TRUE; + } + + DevicePath = NextDevicePathNode(DevicePath); + } + } + + FreePool(Handles); + return FALSE; +} + #if 0 /* Block IO procotol */ #endif @@ -101,7 +152,7 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector ventoy_override_chunk *pOverride = g_override_chunk; EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; - debug("read iso sector %lu count %u", Sector, Count); + debug("read iso sector %lu count %u Buffer:%p Align:%u", Sector, Count, Buffer, pRawBlockIo->Media->IoAlign); ReadStart = Sector * 2048; ReadEnd = (Sector + Count) * 2048; @@ -114,9 +165,17 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector { MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector; } - else + else if (g_chain->disk_sector_size == 1024) { - MapLba = (Sector - pchunk->img_start_sector) * 2048 / g_chain->disk_sector_size + pchunk->disk_start_sector; + MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 2048) + { + MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 4096) + { + MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector; } secLeft = pchunk->img_end_sector + 1 - Sector; @@ -126,7 +185,7 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector MapLba, secRead * 2048, pCurBuf); if (EFI_ERROR(Status)) { - debug("Raw disk read block failed %r", Status); + debug("Raw disk read block failed %r LBA:%lu Count:%u %p", Status, MapLba, secRead, pCurBuf); return Status; } @@ -199,6 +258,96 @@ STATIC EFI_STATUS EFIAPI ventoy_read_iso_sector return EFI_SUCCESS; } +STATIC EFI_STATUS EFIAPI ventoy_write_iso_sector +( + IN UINT64 Sector, + IN UINTN Count, + IN VOID *Buffer +) +{ + EFI_STATUS Status = EFI_SUCCESS; + EFI_LBA MapLba = 0; + UINT32 i = 0; + UINTN secLeft = 0; + UINTN secRead = 0; + UINT64 ReadStart = 0; + UINT64 ReadEnd = 0; + UINT8 *pCurBuf = (UINT8 *)Buffer; + ventoy_img_chunk *pchunk = g_chunk; + EFI_BLOCK_IO_PROTOCOL *pRawBlockIo = gBlockData.pRawBlockIo; + + debug("write iso sector %lu count %u", Sector, Count); + + ReadStart = Sector * 2048; + ReadEnd = (Sector + Count) * 2048; + + for (i = 0; Count > 0 && i < g_img_chunk_num; i++, pchunk++) + { + if (Sector >= pchunk->img_start_sector && Sector <= pchunk->img_end_sector) + { + if (g_chain->disk_sector_size == 512) + { + MapLba = (Sector - pchunk->img_start_sector) * 4 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 1024) + { + MapLba = (Sector - pchunk->img_start_sector) * 2 + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 2048) + { + MapLba = (Sector - pchunk->img_start_sector) + pchunk->disk_start_sector; + } + else if (g_chain->disk_sector_size == 4096) + { + MapLba = ((Sector - pchunk->img_start_sector) >> 1) + pchunk->disk_start_sector; + } + + + secLeft = pchunk->img_end_sector + 1 - Sector; + secRead = (Count < secLeft) ? Count : secLeft; + + Status = pRawBlockIo->WriteBlocks(pRawBlockIo, pRawBlockIo->Media->MediaId, + MapLba, secRead * 2048, pCurBuf); + if (EFI_ERROR(Status)) + { + debug("Raw disk write block failed %r LBA:%lu Count:%u", Status, MapLba, secRead); + return Status; + } + + Count -= secRead; + Sector += secRead; + pCurBuf += secRead * 2048; + } + } + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_block_io_ramdisk_write +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + (VOID)This; + (VOID)MediaId; + (VOID)Lba; + (VOID)BufferSize; + (VOID)Buffer; + + if (!gSector512Mode) + { + return EFI_WRITE_PROTECTED; + } + + CopyMem(g_iso_data_buf + (Lba * 2048), Buffer, BufferSize); + + return EFI_SUCCESS; +} + EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read ( IN EFI_BLOCK_IO_PROTOCOL *This, @@ -213,7 +362,7 @@ EFI_STATUS EFIAPI ventoy_block_io_ramdisk_read (VOID)This; (VOID)MediaId; - CopyMem(Buffer, (char *)g_chain + (Lba * 2048), BufferSize); + CopyMem(Buffer, g_iso_data_buf + (Lba * 2048), BufferSize); if (g_blockio_start_record_bcd && FALSE == g_blockio_bcd_read_done) { @@ -279,7 +428,7 @@ end: return Lba; } -EFI_STATUS EFIAPI ventoy_block_io_read +EFI_STATUS EFIAPI ventoy_block_io_read_real ( IN EFI_BLOCK_IO_PROTOCOL *This, IN UINT32 MediaId, @@ -292,6 +441,8 @@ EFI_STATUS EFIAPI ventoy_block_io_read UINT32 j = 0; UINT32 lbacount = 0; UINT32 secNum = 0; + UINT32 TmpNum = 0; + UINT64 VirtSec = 0; UINT64 offset = 0; EFI_LBA curlba = 0; EFI_LBA lastlba = 0; @@ -299,7 +450,7 @@ EFI_STATUS EFIAPI ventoy_block_io_read ventoy_sector_flag *cur_flag; ventoy_virt_chunk *node; - //debug("### ventoy_block_io_read sector:%u count:%u", (UINT32)Lba, (UINT32)BufferSize / 2048); + debug("### block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer); secNum = BufferSize / 2048; @@ -315,6 +466,28 @@ EFI_STATUS EFIAPI ventoy_block_io_read { return ventoy_read_iso_sector(Lba, secNum, Buffer); } + else if (offset < g_chain->real_img_size_in_bytes) + { + TmpNum = (g_chain->real_img_size_in_bytes - offset) / 2048; + ventoy_read_iso_sector(Lba, TmpNum, Buffer); + + Lba += TmpNum; + secNum -= TmpNum; + Buffer = (UINT8 *)Buffer + (g_chain->real_img_size_in_bytes - offset); + offset = Lba * 2048; + } + + VirtSec = g_chain->virt_img_size_in_bytes / 2048; + if (Lba >= VirtSec) + { + return EFI_SUCCESS; + } + else if (Lba + secNum > VirtSec) + { + secNum = VirtSec - Lba; + } + + debug("XXX block_io_read_real sector:%u count:%u Buffer:%p", (UINT32)Lba, (UINT32)BufferSize / 2048, Buffer); if (secNum > g_sector_flag_num) { @@ -383,6 +556,42 @@ EFI_STATUS EFIAPI ventoy_block_io_read return EFI_SUCCESS; } +EFI_STATUS EFIAPI ventoy_block_io_read +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + UINT32 IoAlign = 0; + VOID *NewBuf = NULL; + EFI_STATUS Status = EFI_OUT_OF_RESOURCES; + + if (gBlockData.pRawBlockIo && gBlockData.pRawBlockIo->Media) + { + IoAlign = gBlockData.pRawBlockIo->Media->IoAlign; + } + + if ((IoAlign == 0) || (((UINTN) Buffer & (IoAlign - 1)) == 0)) + { + Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, Buffer); + } + else + { + NewBuf = AllocatePages(EFI_SIZE_TO_PAGES(BufferSize + IoAlign)); + if (NewBuf) + { + Status = ventoy_block_io_read_real(This, MediaId, Lba, BufferSize, NewBuf); + CopyMem(Buffer, NewBuf, BufferSize); + FreePages(NewBuf, EFI_SIZE_TO_PAGES(BufferSize + IoAlign)); + } + } + + return Status; +} + EFI_STATUS EFIAPI ventoy_block_io_write ( IN EFI_BLOCK_IO_PROTOCOL *This, @@ -392,12 +601,21 @@ EFI_STATUS EFIAPI ventoy_block_io_write IN VOID *Buffer ) { + UINT32 secNum = 0; + UINT64 offset = 0; + (VOID)This; (VOID)MediaId; - (VOID)Lba; - (VOID)BufferSize; - (VOID)Buffer; - return EFI_WRITE_PROTECTED; + + if (!gSector512Mode) + { + return EFI_WRITE_PROTECTED; + } + + secNum = BufferSize / 2048; + offset = Lba * 2048; + + return ventoy_write_iso_sector(Lba, secNum, Buffer); } EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) @@ -406,26 +624,74 @@ EFI_STATUS EFIAPI ventoy_block_io_flush(IN EFI_BLOCK_IO_PROTOCOL *This) return EFI_SUCCESS; } +STATIC UINTN ventoy_get_current_device_path_id(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + UINTN MaxId = 0; + UINTN CurId = 0; + BOOLEAN Find = FALSE; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + VENDOR_DEVICE_PATH *venPath = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiDevicePathProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return 0; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + continue; + } + + if (DevicePath->Type == HARDWARE_DEVICE_PATH && DevicePath->SubType == HW_VENDOR_DP) + { + venPath = (VENDOR_DEVICE_PATH *)DevicePath; + if (CompareGuid(&venPath->Guid, &gVtoyBlockDevicePathGuid)) + { + CurId = StrDecimalToUintn((CHAR16 *)(venPath + 1) + StrLen(L"ventoy_")); + MaxId = MAX(MaxId, CurId); + Find = TRUE; + } + } + } + + FreePool(Handles); + + return Find ? (MaxId + 1) : 0; +} EFI_STATUS EFIAPI ventoy_fill_device_path(VOID) { + UINTN CurVtoyDpId = 0; UINTN NameLen = 0; UINT8 TmpBuf[128] = {0}; VENDOR_DEVICE_PATH *venPath = NULL; + CHAR16 VtoyDpName[32]; + + CurVtoyDpId = ventoy_get_current_device_path_id(); + UnicodeSPrintAsciiFormat(VtoyDpName, sizeof(VtoyDpName), "ventoy_%03lu", CurVtoyDpId); venPath = (VENDOR_DEVICE_PATH *)TmpBuf; - NameLen = StrSize(VTOY_BLOCK_DEVICE_PATH_NAME); + NameLen = StrSize(VtoyDpName); venPath->Header.Type = HARDWARE_DEVICE_PATH; venPath->Header.SubType = HW_VENDOR_DP; venPath->Header.Length[0] = sizeof(VENDOR_DEVICE_PATH) + NameLen; venPath->Header.Length[1] = 0; CopyMem(&venPath->Guid, &gVtoyBlockDevicePathGuid, sizeof(EFI_GUID)); - CopyMem(venPath + 1, VTOY_BLOCK_DEVICE_PATH_NAME, NameLen); + CopyMem(venPath + 1, VtoyDpName, NameLen); gBlockData.Path = AppendDevicePathNode(NULL, (EFI_DEVICE_PATH_PROTOCOL *)TmpBuf); gBlockData.DevicePathCompareLen = sizeof(VENDOR_DEVICE_PATH) + NameLen; - debug("gBlockData.Path=<%s>\n", ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE)); + debug("gBlockData.Path=<%lu><%s>\n", CurVtoyDpId, ConvertDevicePathToText(gBlockData.Path, FALSE, FALSE)); return EFI_SUCCESS; } @@ -458,11 +724,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST continue; } - Status = Name2Protocol->GetDriverName(Name2Protocol, "en", &DriverName); - if (EFI_ERROR(Status) || NULL == DriverName) - { - continue; - } + VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName); if (StrStr(DriverName, DrvName)) { @@ -475,7 +737,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST if (i < Count) { Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); - debug("Connect partition driver:<%r>", Status); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); goto end; } @@ -500,11 +762,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST continue; } - Status = NameProtocol->GetDriverName(NameProtocol, "en", &DriverName); - if (EFI_ERROR(Status)) - { - continue; - } + VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName); if (StrStr(DriverName, DrvName)) { @@ -517,7 +775,7 @@ EFI_STATUS EFIAPI ventoy_connect_driver(IN EFI_HANDLE ControllerHandle, IN CONST if (i < Count) { Status = gBS->ConnectController(ControllerHandle, DrvHandles, NULL, TRUE); - debug("Connect partition driver:<%r>", Status); + debug("ventoy_connect_driver:<%s> <%r>", DrvName, Status); goto end; } @@ -529,24 +787,386 @@ end: return Status; } + +STATIC BOOLEAN ventoy_filesystem_need_wrapper(IN CONST CHAR16 *DrvName) +{ + UINTN i; + CHAR16 UpperDrvName[256]; + + StrCpyS(UpperDrvName, 256, DrvName); + + for (i = 0; i < 256 && UpperDrvName[i]; i++) + { + if (UpperDrvName[i] >= 'a' && UpperDrvName[i] <= 'z') + { + UpperDrvName[i] = 'A' + (UpperDrvName[i] - 'a'); + } + } + + /* + * suppress some file system drivers + * 1. rEFInd File System Driver + * + */ + + if (StrStr(UpperDrvName, L"REFIND") && StrStr(UpperDrvName, L"FILE SYSTEM")) + { + return TRUE; + } + + return FALSE; +} + +STATIC VOID ventoy_add_filesystem_wrapper +( + IN EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol, + IN CONST CHAR16 *DriverName +) +{ + UINTN j; + + if (g_DriverBindWrapperCnt >= MAX_DRIVER_BIND_WRAPPER) + { + debug("driver binding wrapper overflow %lu", g_DriverBindWrapperCnt); + return; + } + + if (!ventoy_filesystem_need_wrapper(DriverName)) + { + return; + } + + for (j = 0; j < g_DriverBindWrapperCnt; j++) + { + if (g_DriverBindWrapperList[j].DriverBinding == DriverBindProtocol) + { + debug("Duplicate driverbinding <%s> %p %lu %lu", DriverName, DriverBindProtocol, j, g_DriverBindWrapperCnt); + break; + } + } + + if (j >= g_DriverBindWrapperCnt) + { + g_DriverBindWrapperList[g_DriverBindWrapperCnt].DriverBinding = DriverBindProtocol; + g_DriverBindWrapperList[g_DriverBindWrapperCnt].pfOldSupport = DriverBindProtocol->Supported; + g_DriverBindWrapperCnt++; + debug("Add driverbinding <%s> %p %lu", DriverName, DriverBindProtocol, g_DriverBindWrapperCnt); + } +} + +STATIC EFI_STATUS ventoy_find_filesystem_driverbind(VOID) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + EFI_DRIVER_BINDING_PROTOCOL *DriverBindProtocol = NULL; + + debug("ventoy_find_filesystem_driverbind..."); + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(Name2Protocol, DriverName); + + Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol); + if (EFI_ERROR(Status)) + { + debug("### 2 No DriverBind <%s> <%r>", DriverName, Status); + continue; + } + + ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName); + } + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + VENTOY_GET_COMPONENT_NAME(NameProtocol, DriverName); + + Status = gBS->HandleProtocol(Handles[i], &gEfiDriverBindingProtocolGuid, (VOID **)&DriverBindProtocol); + if (EFI_ERROR(Status)) + { + debug("### 1 No DriverBind <%s> <%r>", DriverName, Status); + continue; + } + + ventoy_add_filesystem_wrapper(DriverBindProtocol, DriverName); + } + + FreePool(Handles); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_driver_bind_support +( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL +) +{ + UINTN i; + EFI_STATUS Status = EFI_SUCCESS; + EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL; + EFI_DRIVER_BINDING_SUPPORTED pfOldSupport = NULL; + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + if (g_DriverBindWrapperList[i].DriverBinding == This) + { + pfOldSupport = g_DriverBindWrapperList[i].pfOldSupport; + break; + } + } + + debug("ventoy_wrapper_driver_bind_support %lu %p", i, pfOldSupport); + + if (!pfOldSupport) + { + return EFI_UNSUPPORTED; + } + + Status = gBS->HandleProtocol(ControllerHandle, &gEfiDevicePathProtocolGuid, (VOID **)&DevicePath); + if (EFI_ERROR(Status)) + { + goto out; + } + + if (0 == CompareMem(gBlockData.Path, DevicePath, gBlockData.DevicePathCompareLen)) + { + debug("return EFI_UNSUPPORTED for ventoy"); + return EFI_UNSUPPORTED; + } + +out: + return pfOldSupport(This, ControllerHandle, RemainingDevicePath); +} + +EFI_STATUS ventoy_disable_ex_filesystem(VOID) +{ + UINTN i; + + ventoy_find_filesystem_driverbind(); + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + g_DriverBindWrapperList[i].DriverBinding->Supported = ventoy_wrapper_driver_bind_support; + } + + debug("Wrapper Ex Driver Binding %lu", g_DriverBindWrapperCnt); + ventoy_debug_pause(); + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_enable_ex_filesystem(VOID) +{ + UINTN i; + + for (i = 0; i < g_DriverBindWrapperCnt; i++) + { + g_DriverBindWrapperList[i].DriverBinding->Supported = g_DriverBindWrapperList[i].pfOldSupport; + } + g_DriverBindWrapperCnt = 0; + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI ventoy_block_io_read_512 +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + OUT VOID *Buffer +) +{ + EFI_LBA Mod; + UINTN ReadSize; + UINT8 *CurBuf = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_block_io_read_512 %lu %lu Buffer:%p\n", Lba, BufferSize / 512, Buffer); + + CurBuf = (UINT8 *)Buffer; + + Mod = Lba % 4; + if (Mod > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + if (BufferSize <= (4 - Mod) * 512) + { + CopyMem(CurBuf, g_sector_buf + Mod * 512, BufferSize); + return EFI_SUCCESS; + } + else + { + ReadSize = (4 - Mod) * 512; + CopyMem(CurBuf, g_sector_buf + Mod * 512, ReadSize); + CurBuf += ReadSize; + Lba += (4 - Mod); + BufferSize -= ReadSize; + } + } + + if (BufferSize >= 2048) + { + ReadSize = BufferSize / 2048 * 2048; + + Status |= g_sector_2048_read(This, MediaId, Lba / 4, ReadSize, CurBuf); + CurBuf += ReadSize; + + Lba += ReadSize / 512; + BufferSize -= ReadSize; + } + + if (BufferSize > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + CopyMem(CurBuf, g_sector_buf, BufferSize); + } + + return Status; +} + +EFI_STATUS EFIAPI ventoy_block_io_write_512 +( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA Lba, + IN UINTN BufferSize, + IN VOID *Buffer +) +{ + EFI_LBA Mod; + UINTN ReadSize; + UINT8 *CurBuf = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + debug("ventoy_block_io_write_512 %lu %lu\n", Lba, BufferSize / 512); + + CurBuf = (UINT8 *)Buffer; + + Mod = Lba % 4; + if (Mod > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + if (BufferSize <= (4 - Mod) * 512) + { + CopyMem(g_sector_buf + Mod * 512, CurBuf, BufferSize); + return g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + } + else + { + ReadSize = (4 - Mod) * 512; + CopyMem(g_sector_buf + Mod * 512, CurBuf, ReadSize); + g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + + CurBuf += ReadSize; + Lba += (4 - Mod); + BufferSize -= ReadSize; + } + } + + if (BufferSize >= 2048) + { + ReadSize = BufferSize / 2048 * 2048; + + Status |= g_sector_2048_write(This, MediaId, Lba / 4, ReadSize, CurBuf); + CurBuf += ReadSize; + + Lba += ReadSize / 512; + BufferSize -= ReadSize; + } + + if (BufferSize > 0) + { + Status |= g_sector_2048_read(This, MediaId, Lba / 4, 2048, g_sector_buf); + + CopyMem(g_sector_buf, CurBuf, BufferSize); + g_sector_2048_write(This, MediaId, Lba / 4, 2048, g_sector_buf); + } + + return Status; +} + EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 ImgSize) { EFI_STATUS Status = EFI_SUCCESS; EFI_BLOCK_IO_PROTOCOL *pBlockIo = &(gBlockData.BlockIo); ventoy_fill_device_path(); + + debug("install block io protocol %p", ImageHandle); + ventoy_debug_pause(); + + if (gSector512Mode) + { + gBlockData.Media.BlockSize = 512; + gBlockData.Media.LastBlock = ImgSize / 512 - 1; + gBlockData.Media.ReadOnly = FALSE; + } + else + { + gBlockData.Media.BlockSize = 2048; + gBlockData.Media.LastBlock = ImgSize / 2048 - 1; + gBlockData.Media.ReadOnly = TRUE; + } - gBlockData.Media.BlockSize = 2048; - gBlockData.Media.LastBlock = ImgSize / 2048 - 1; - gBlockData.Media.ReadOnly = TRUE; gBlockData.Media.MediaPresent = 1; gBlockData.Media.LogicalBlocksPerPhysicalBlock = 1; pBlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3; pBlockIo->Media = &(gBlockData.Media); pBlockIo->Reset = ventoy_block_io_reset; - pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read; - pBlockIo->WriteBlocks = ventoy_block_io_write; + + if (gSector512Mode) + { + g_sector_2048_read = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read; + g_sector_2048_write = gMemdiskMode ? ventoy_block_io_ramdisk_write : ventoy_block_io_write; + pBlockIo->ReadBlocks = ventoy_block_io_read_512; + pBlockIo->WriteBlocks = ventoy_block_io_write_512; + } + else + { + pBlockIo->ReadBlocks = gMemdiskMode ? ventoy_block_io_ramdisk_read : ventoy_block_io_read; + pBlockIo->WriteBlocks = ventoy_block_io_write; + } + pBlockIo->FlushBlocks = ventoy_block_io_flush; Status = gBS->InstallMultipleProtocolInterfaces(&gBlockData.Handle, @@ -558,11 +1178,10 @@ EFI_STATUS EFIAPI ventoy_install_blockio(IN EFI_HANDLE ImageHandle, IN UINT64 Im { return Status; } - + Status = ventoy_connect_driver(gBlockData.Handle, L"Disk I/O Driver"); debug("Connect disk IO driver %r", Status); - ventoy_debug_pause(); - + Status = ventoy_connect_driver(gBlockData.Handle, L"Partition Driver"); debug("Connect partition driver %r", Status); if (EFI_ERROR(Status)) @@ -656,8 +1275,16 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_set_pos(EFI_FILE_HANDLE This, UINT64 Position) { (VOID)This; + + if (Position <= g_efi_file_replace.FileSizeBytes) + { + g_efi_file_replace.CurPos = Position; + } + else + { + g_efi_file_replace.CurPos = g_efi_file_replace.FileSizeBytes; + } - g_efi_file_replace.CurPos = Position; return EFI_SUCCESS; } @@ -772,6 +1399,18 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open CHAR8 TmpName[256]; ventoy_virt_chunk *virt = NULL; + debug("## ventoy_wrapper_file_open <%s> ", Name); + + if ((Mode & EFI_FILE_MODE_WRITE) > 0 && StrCmp(Name, L"\\loader\\random-seed") == 0) + { + if (gDebugPrint) + { + debug("## ventoy_wrapper_file_open return NOT_FOUND for random-seed %lx", Mode); + sleep(3); + } + return EFI_NOT_FOUND; + } + Status = g_original_fopen(This, New, Name, Mode, Attributes); if (EFI_ERROR(Status)) { @@ -807,6 +1446,11 @@ STATIC EFI_STATUS EFIAPI ventoy_wrapper_file_open return Status; } } + + if (StrCmp(Name, L"\\EFI\\BOOT") == 0) + { + (*New)->Open = ventoy_wrapper_file_open; + } } return Status; @@ -916,3 +1560,55 @@ EFI_STATUS ventoy_hook_keyboard_stop(VOID) return EFI_SUCCESS; } +#if 0 +/* Fixup the 1st cdrom influnce for Windows boot */ +#endif + +STATIC EFI_STATUS EFIAPI ventoy_wrapper_locate_handle +( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol, OPTIONAL + IN VOID *SearchKey, OPTIONAL + IN OUT UINTN *BufferSize, + OUT EFI_HANDLE *Buffer +) +{ + UINTN i; + EFI_HANDLE Handle = NULL; + EFI_STATUS Status = EFI_SUCCESS; + + Status = g_org_locate_handle(SearchType, Protocol, SearchKey, BufferSize, Buffer); + + if (EFI_SUCCESS == Status && Protocol && CompareGuid(&gEfiBlockIoProtocolGuid, Protocol)) + { + for (i = 0; i < (*BufferSize) / sizeof(EFI_HANDLE); i++) + { + if (Buffer[i] == gBlockData.Handle) + { + Handle = Buffer[0]; + Buffer[0] = Buffer[i]; + Buffer[i] = Handle; + break; + } + } + } + + return Status; +} + +EFI_STATUS ventoy_hook_1st_cdrom_start(VOID) +{ + g_org_locate_handle = gBS->LocateHandle; + gBS->LocateHandle = ventoy_wrapper_locate_handle; + + return EFI_SUCCESS; +} + +EFI_STATUS ventoy_hook_1st_cdrom_stop(VOID) +{ + gBS->LocateHandle = g_org_locate_handle; + g_org_locate_handle = NULL; + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c new file mode 100644 index 00000000..715d7bce --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/Memhole.c @@ -0,0 +1,179 @@ +/****************************************************************************** + * Memhole.c + * + * Copyright (c) 2020, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC BOOLEAN IsMemContiguous +( + IN CONST EFI_MEMORY_DESCRIPTOR *Prev, + IN CONST EFI_MEMORY_DESCRIPTOR *Curr, + IN CONST EFI_MEMORY_DESCRIPTOR *Next +) +{ + UINTN Addr1 = 0; + UINTN Addr2 = 0; + + if (Prev == NULL || Curr == NULL || Next == NULL) + { + return FALSE; + } + + if (Prev->Type == EfiBootServicesData && + Curr->Type == EfiConventionalMemory && + Next->Type == EfiBootServicesData) + { + Addr1 = Prev->PhysicalStart + MultU64x64(SIZE_4KB, Prev->NumberOfPages); + Addr2 = Curr->PhysicalStart + MultU64x64(SIZE_4KB, Curr->NumberOfPages); + + if (Addr1 == Curr->PhysicalStart && Addr2 == Next->PhysicalStart) + { + return TRUE; + } + } + + return FALSE; +} + +STATIC EFI_MEMORY_DESCRIPTOR* GetMemDesc +( + OUT UINTN *pSize, + OUT UINTN *pItemSize, + OUT UINTN *pDescCount +) +{ + UINTN Size = 0; + UINTN MapKey = 0; + UINTN ItemSize = 0; + UINTN DescCount = 0; + UINT32 Version = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_MEMORY_DESCRIPTOR *pDesc = NULL; + EFI_MEMORY_DESCRIPTOR *Curr = NULL; + + Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version); + if (EFI_BUFFER_TOO_SMALL != Status) + { + debug("GetMemoryMap: %r", Status); + return NULL; + } + + Size += SIZE_1KB; + pDesc = AllocatePool(Size); + if (!pDesc) + { + debug("AllocatePool: %lu failed", Size); + return NULL; + } + + ZeroMem(pDesc, Size); + + Status = gBS->GetMemoryMap(&Size, pDesc, &MapKey, &ItemSize, &Version); + if (EFI_ERROR(Status)) + { + debug("GetMemoryMap: %r", Status); + FreePool(pDesc); + return NULL; + } + + Curr = pDesc; + while (Curr && Curr < (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)pDesc + Size)) + { + DescCount++; + Curr = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize); + } + + *pSize = Size; + *pItemSize = ItemSize; + *pDescCount = DescCount; + + debug("GetMemoryMap: ItemSize:%lu Count:%lu", ItemSize, DescCount); + + return pDesc; +} + +EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine) +{ + UINTN Size = 0; + UINTN ItemSize = 0; + UINTN DescCount = 0; + UINTN TotalMem = 0; + EFI_STATUS Status = EFI_SUCCESS; + EFI_PHYSICAL_ADDRESS AllocAddr = 0; + EFI_MEMORY_DESCRIPTOR *pDescs = NULL; + EFI_MEMORY_DESCRIPTOR *Prev = NULL; + EFI_MEMORY_DESCRIPTOR *Next = NULL; + EFI_MEMORY_DESCRIPTOR *Curr = NULL; + + (VOID)ImageHandle; + (VOID)CmdLine; + + pDescs = GetMemDesc(&Size, &ItemSize, &DescCount); + if (!pDescs) + { + return EFI_NOT_FOUND; + } + + if (DescCount < 500) + { + FreePool(pDescs); + Printf("There is no need to fixup (%lu)\n", DescCount); + return EFI_SUCCESS; + } + + Curr = pDescs; + while ((UINT8 *)Curr < (UINT8 *)pDescs + Size) + { + Next = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Curr + ItemSize); + + if (IsMemContiguous(Prev, Curr, Next)) + { + AllocAddr = Curr->PhysicalStart; + Status = gBS->AllocatePages(AllocateAddress, EfiBootServicesData, Curr->NumberOfPages, &AllocAddr); + if (EFI_SUCCESS == Status) + { + TotalMem += MultU64x64(SIZE_4KB, Curr->NumberOfPages); + } + } + + Prev = Curr; + Curr = Next; + } + + Printf("Fixup Windows mmap issue OK (%lu)\n", TotalMem); + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyDrv.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyDrv.c new file mode 100644 index 00000000..7886d66f --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyDrv.c @@ -0,0 +1,140 @@ +/****************************************************************************** + * VtoyDrv.c + * + * Copyright (c) 2020, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +STATIC UINTN g_EfiDriverNameCnt = 0; +STATIC CHAR16 *g_EfiDriverNameList[1024] = { NULL }; + +STATIC EFI_STATUS AddEfiDriverName(IN CHAR16 *DriverName) +{ + UINTN i = 0; + + if (g_EfiDriverNameCnt >= 1024) + { + return EFI_OUT_OF_RESOURCES; + } + + for (i = 0; i < g_EfiDriverNameCnt; i++) + { + if (g_EfiDriverNameList[i] && StrCmp(g_EfiDriverNameList[i], DriverName) == 0) + { + break; + } + } + + if (i >= g_EfiDriverNameCnt) + { + g_EfiDriverNameList[g_EfiDriverNameCnt] = DriverName; + g_EfiDriverNameCnt++; + } + + return EFI_SUCCESS; +} + +EFI_STATUS ShowEfiDrivers(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine) +{ + UINTN i = 0; + UINTN Count = 0; + CHAR16 *DriverName = NULL; + EFI_HANDLE *Handles = NULL; + EFI_STATUS Status = EFI_SUCCESS; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + + (VOID)ImageHandle; + (VOID)CmdLine; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentName2ProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentName2ProtocolGuid, (VOID **)&Name2Protocol); + if (EFI_ERROR(Status)) + { + continue; + } + + DriverName = NULL; + Status = VtoyGetComponentName(2, Name2Protocol, &DriverName); + if ((!EFI_ERROR(Status)) && (DriverName)) + { + AddEfiDriverName(DriverName); + } + } + + Count = 0; + FreePool(Handles); + Handles = NULL; + + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiComponentNameProtocolGuid, + NULL, &Count, &Handles); + if (EFI_ERROR(Status)) + { + return Status; + } + + for (i = 0; i < Count; i++) + { + Status = gBS->HandleProtocol(Handles[i], &gEfiComponentNameProtocolGuid, (VOID **)&NameProtocol); + if (EFI_ERROR(Status)) + { + continue; + } + + DriverName = NULL; + Status = VtoyGetComponentName(1, Name2Protocol, &DriverName); + if ((!EFI_ERROR(Status)) && (DriverName)) + { + AddEfiDriverName(DriverName); + } + } + + FreePool(Handles); + + for (i = 0; i < g_EfiDriverNameCnt; i++) + { + Printf("%2d %s\n", i, g_EfiDriverNameList[i]); + } + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c new file mode 100644 index 00000000..65212c23 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.c @@ -0,0 +1,178 @@ +/****************************************************************************** + * VtoyUtil.c + * + * Copyright (c) 2020, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +BOOLEAN gVtoyDebugPrint = FALSE; +STATIC CONST CHAR16 *gCurFeature= NULL; +STATIC CHAR16 *gCmdLine = NULL; +STATIC grub_env_printf_pf g_env_printf = NULL; + +STATIC VtoyUtilFeature gFeatureList[] = +{ + { L"fix_windows_mmap", FixWindowsMemhole }, + { L"show_efi_drivers", ShowEfiDrivers }, +}; + +EFI_STATUS VtoyGetComponentName(IN UINTN Ver, IN VOID *Protocol, OUT CHAR16 **DriverName) +{ + EFI_STATUS Status = EFI_SUCCESS; + CHAR16 *DrvName = NULL; + EFI_COMPONENT_NAME_PROTOCOL *NameProtocol = NULL; + EFI_COMPONENT_NAME2_PROTOCOL *Name2Protocol = NULL; + + if (1 == Ver) + { + NameProtocol = (EFI_COMPONENT_NAME_PROTOCOL *)Protocol; + Status = NameProtocol->GetDriverName(Protocol, "en", &DrvName); + if (EFI_ERROR(Status) || NULL == DrvName) + { + Status = NameProtocol->GetDriverName(Protocol, "eng", &DrvName); + } + } + else + { + Name2Protocol = (EFI_COMPONENT_NAME2_PROTOCOL *)Protocol; + Status = Name2Protocol->GetDriverName(Protocol, "en", &DrvName); + if (EFI_ERROR(Status) || NULL == DrvName) + { + Status = Name2Protocol->GetDriverName(Protocol, "eng", &DrvName); + } + } + + *DriverName = DrvName; + return Status; +} + +VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...) +{ + VA_LIST Marker; + CHAR8 Buffer[512]; + + VA_START (Marker, Format); + AsciiVSPrint(Buffer, sizeof(Buffer), Format, Marker); + VA_END (Marker); + + if (g_env_printf) + { + g_env_printf("%s", Buffer); + } +} + +STATIC EFI_STATUS ParseCmdline(IN EFI_HANDLE ImageHandle) +{ + CHAR16 *pPos = NULL; + CHAR16 *pCmdLine = NULL; + EFI_STATUS Status = EFI_SUCCESS; + ventoy_grub_param *pGrubParam = NULL; + EFI_LOADED_IMAGE_PROTOCOL *pImageInfo = NULL; + + Status = gBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, (VOID **)&pImageInfo); + if (EFI_ERROR(Status)) + { + return Status; + } + + pCmdLine = (CHAR16 *)AllocatePool(pImageInfo->LoadOptionsSize + 4); + SetMem(pCmdLine, pImageInfo->LoadOptionsSize + 4, 0); + CopyMem(pCmdLine, pImageInfo->LoadOptions, pImageInfo->LoadOptionsSize); + + if (StrStr(pCmdLine, L"vtoyefitest")) + { + gST->ConOut->OutputString(gST->ConOut, L"\r\n##########################"); + gST->ConOut->OutputString(gST->ConOut, L"\r\n######### VTOY #########"); + gST->ConOut->OutputString(gST->ConOut, L"\r\n##########################"); + return EFI_SUCCESS; + } + + if (StrStr(pCmdLine, L"debug")) + { + gVtoyDebugPrint = TRUE; + } + + pPos = StrStr(pCmdLine, L"env_param="); + if (!pPos) + { + return EFI_INVALID_PARAMETER; + } + + pGrubParam = (ventoy_grub_param *)StrHexToUintn(pPos + StrLen(L"env_param=")); + g_env_printf = pGrubParam->grub_env_printf; + + pPos = StrStr(pCmdLine, L"feature="); + if (!pPos) + { + return EFI_INVALID_PARAMETER; + } + + gCurFeature = pPos + StrLen(L"feature="); + + gCmdLine = pCmdLine; + + return EFI_SUCCESS; +} + +EFI_STATUS EFIAPI VtoyUtilEfiMain +( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable +) +{ + UINTN i; + UINTN Len; + + ParseCmdline(ImageHandle); + + for (i = 0; gCurFeature && i < ARRAY_SIZE(gFeatureList); i++) + { + Len = StrLen(gFeatureList[i].Cmd); + if (StrnCmp(gFeatureList[i].Cmd, gCurFeature, Len) == 0) + { + debug("Find main proc <%s>", gFeatureList[i].Cmd); + gFeatureList[i].MainProc(ImageHandle, gCurFeature + Len); + break; + } + } + + if (gCmdLine) + { + FreePool(gCmdLine); + gCmdLine = NULL; + } + + return EFI_SUCCESS; +} + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h new file mode 100644 index 00000000..5f3ae6d0 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * VtoyUtil.h + * + * Copyright (c) 2020, longpanda + * + * 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 . + * + */ + +#ifndef __VTOYUTIL_H__ +#define __VTOYUTIL_H__ + +#pragma pack(1) + +typedef EFI_STATUS (*VTOY_UTIL_PROC_PF)(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); +typedef int (*grub_env_set_pf)(const char *name, const char *val); +typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); + +typedef struct ventoy_grub_param_file_replace +{ + UINT32 magic; + char old_file_name[4][256]; + UINT32 old_file_cnt; + UINT32 new_file_virtual_id; +}ventoy_grub_param_file_replace; + +typedef struct ventoy_grub_param +{ + grub_env_get_pf grub_env_get; + grub_env_set_pf grub_env_set; + ventoy_grub_param_file_replace file_replace; + grub_env_printf_pf grub_env_printf; +}ventoy_grub_param; +#pragma pack() + + +typedef struct VtoyUtilFeature +{ + CONST CHAR16 *Cmd; + VTOY_UTIL_PROC_PF MainProc; +}VtoyUtilFeature; + +extern BOOLEAN gVtoyDebugPrint; +VOID EFIAPI VtoyUtilDebug(IN CONST CHAR8 *Format, ...); +#define debug(expr, ...) if (gVtoyDebugPrint) VtoyUtilDebug("[VTOY] "expr"\n", ##__VA_ARGS__) +#define Printf VtoyUtilDebug + +EFI_STATUS VtoyGetComponentName(IN UINTN Ver, IN VOID *Protocol, OUT CHAR16 **DriverName); +EFI_STATUS FixWindowsMemhole(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); +EFI_STATUS ShowEfiDrivers(IN EFI_HANDLE ImageHandle, IN CONST CHAR16 *CmdLine); + +#endif + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf new file mode 100644 index 00000000..c422b7d1 --- /dev/null +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf @@ -0,0 +1,81 @@ +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = VtoyUtil + FILE_GUID = a43466a0-68c6-469d-ba4b-678bbe90bc47 + MODULE_TYPE = UEFI_APPLICATION + VERSION_STRING = 1.0 + ENTRY_POINT = VtoyUtilEfiMain + + +[Sources] + VtoyUtil.h + VtoyUtil.c + VtoyDrv.c + Memhole.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + ShellPkg/ShellPkg.dec + +[LibraryClasses] + UefiApplicationEntryPoint + UefiLib + DebugLib + +[Guids] + gShellVariableGuid + gEfiVirtualCdGuid + gEfiFileInfoGuid + +[Protocols] + gEfiLoadedImageProtocolGuid + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiSimpleFileSystemProtocolGuid + gEfiRamDiskProtocolGuid + gEfiAbsolutePointerProtocolGuid + gEfiAcpiTableProtocolGuid + gEfiBlockIo2ProtocolGuid + gEfiBusSpecificDriverOverrideProtocolGuid + gEfiComponentNameProtocolGuid + gEfiComponentName2ProtocolGuid + gEfiDriverBindingProtocolGuid + gEfiDiskIoProtocolGuid + gEfiDiskIo2ProtocolGuid + gEfiGraphicsOutputProtocolGuid + gEfiHiiConfigAccessProtocolGuid + gEfiHiiFontProtocolGuid + gEfiLoadFileProtocolGuid + gEfiLoadFile2ProtocolGuid + gEfiLoadedImageProtocolGuid + gEfiLoadedImageDevicePathProtocolGuid + gEfiPciIoProtocolGuid + gEfiSerialIoProtocolGuid + gEfiSimpleTextInProtocolGuid + gEfiSimpleTextInputExProtocolGuid + gEfiSimpleTextOutProtocolGuid + + + + + + diff --git a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc index 2bdadd28..c27b6d17 100644 --- a/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc +++ b/EDK2/edk2_mod/edk2-edk2-stable201911/MdeModulePkg/MdeModulePkg.dsc @@ -204,6 +204,8 @@ [Components] MdeModulePkg/Application/Ventoy/Ventoy.inf + MdeModulePkg/Application/VtoyUtil/VtoyUtil.inf + MdeModulePkg/Application/VDiskChain/VDiskChain.inf MdeModulePkg/Application/HelloWorld/HelloWorld.inf MdeModulePkg/Application/DumpDynPcd/DumpDynPcd.inf MdeModulePkg/Application/MemoryProfileInfo/MemoryProfileInfo.inf diff --git a/EDK2/efiffs/mod/grub/grub-core/fs/iso9660.c b/EDK2/efiffs/mod/grub/grub-core/fs/iso9660.c index b691cd6d..bae3f621 100644 --- a/EDK2/efiffs/mod/grub/grub-core/fs/iso9660.c +++ b/EDK2/efiffs/mod/grub/grub-core/fs/iso9660.c @@ -743,8 +743,8 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, if (!ctx.filename && dirent.namelen == 1 && name[0] == 1) ctx.filename = (char *) ".."; - if (g_fs_name_nocase) - ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; + if (g_fs_name_nocase) + ctx.type |= GRUB_FSHELP_CASE_INSENSITIVE; /* The filename was not stored in a rock ridge entry. Read it from the iso9660 filesystem. */ diff --git a/EDK2/efiffs/mod/src/logging.c b/EDK2/efiffs/mod/src/logging.c index 64d30f7d..83661349 100644 --- a/EDK2/efiffs/mod/src/logging.c +++ b/EDK2/efiffs/mod/src/logging.c @@ -70,10 +70,10 @@ SetLogging(VOID) CHAR16 LogVar[4]; UINTN i, LogVarSize = sizeof(LogVar); - i = LogVarSize; + i = LogVarSize; Status = RT->GetVariable(L"FS_NAME_NOCASE", &ShellVariable, NULL, &i, LogVar); - if (Status == EFI_SUCCESS) - g_fs_name_nocase = 1; + if (Status == EFI_SUCCESS) + g_fs_name_nocase = 1; Status = RT->GetVariable(L"FS_LOGGING", &ShellVariable, NULL, &LogVarSize, LogVar); if (Status == EFI_SUCCESS) diff --git a/EfiISO/ISO/EFI/BOOT/BOOTX64.EFI b/EfiISO/ISO/EFI/BOOT/BOOTX64.EFI new file mode 100644 index 00000000..d00491fd --- /dev/null +++ b/EfiISO/ISO/EFI/BOOT/BOOTX64.EFI @@ -0,0 +1 @@ +1 diff --git a/EfiISO/mkefiiso.sh b/EfiISO/mkefiiso.sh new file mode 100644 index 00000000..b5abaa60 --- /dev/null +++ b/EfiISO/mkefiiso.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +rm -f ventoy_efiboot.img.* + +cd ISO +mkisofs -R -D -sysid VENTOY -V VENTOY -P "longpanda admin@ventoy.net" -p 'https://www.ventoy.net' -o ../ventoy_efiboot.img ./ +cd .. + +xz --check=crc32 ventoy_efiboot.img + +rm -f ../INSTALL/ventoy/ventoy_efiboot.img.xz +cp -a ventoy_efiboot.img.xz ../INSTALL/ventoy/ + diff --git a/ExFAT/buidexfat_aarch64.sh b/ExFAT/buidexfat_aarch64.sh new file mode 100644 index 00000000..9de43595 --- /dev/null +++ b/ExFAT/buidexfat_aarch64.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +CUR="$PWD" + +if ! [ -e LIBFUSE ]; then + ./buidlibfuse.sh +fi + +rm -f EXFAT/shared/* + + +rm -rf exfat-1.3.0 +unzip exfat-1.3.0.zip +sed "/printf.*VERSION/a\ if (access(\"/etc/initrd-release\", F_OK) >= 0) argv[0][0] = '@';" -i exfat-1.3.0/fuse/main.c + +cd exfat-1.3.0 +autoreconf --install +./configure --prefix="$CUR" CFLAGS='-O2 -D_FILE_OFFSET_BITS=64' FUSE_CFLAGS="-I$CUR/LIBFUSE/include/" FUSE_LIBS="$CUR/LIBFUSE/lib/libfuse.a -lpthread -ldl" +make + +strip --strip-all fuse/mount.exfat-fuse +strip --strip-all mkfs/mkexfatfs + +cp fuse/mount.exfat-fuse ../EXFAT/shared/mount.exfat-fuse +cp mkfs/mkexfatfs ../EXFAT/shared/mkexfatfs + +cd .. +rm -rf exfat-1.3.0 + + + + diff --git a/ExFAT/buidlibfuse_aarch64.sh b/ExFAT/buidlibfuse_aarch64.sh new file mode 100644 index 00000000..da1bdd21 --- /dev/null +++ b/ExFAT/buidlibfuse_aarch64.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CUR="$PWD" + +rm -rf libfuse +rm -rf LIBFUSE + +if [ -e mirrors-libfuse-fuse-2.9.9.zip ]; then + unzip mirrors-libfuse-fuse-2.9.9.zip + cd libfuse +else + unzip libfuse-fuse-2.9.9.zip + cd libfuse-fuse-2.9.9 +fi + +./makeconf.sh + +./configure --prefix="$CUR/LIBFUSE" + +sed '/#define *__u64/d' -i include/fuse_kernel.h +sed '/#define *__s64/d' -i include/fuse_kernel.h + +sed 's/__u64/uint64_t/g' -i include/fuse_kernel.h +sed 's/__s64/int64_t/g' -i include/fuse_kernel.h + +make -j 16 +make install +cd .. +rm -rf libfuse diff --git a/FUSEISO/build.sh b/FUSEISO/build.sh index af510d02..45617c2d 100644 --- a/FUSEISO/build.sh +++ b/FUSEISO/build.sh @@ -11,10 +11,16 @@ else opt=-lrt fi +# +# use musl-c to build for x86_64 +# + export C_INCLUDE_PATH=$LIBFUSE_DIR/include rm -f $name -gcc -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c -o $name $LIBFUSE_DIR/lib/libfuse.a -lpthread -ldl $opt +gcc -specs "/usr/local/musl/lib/musl-gcc.specs" -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c $LIBFUSE_DIR/lib/libfuse.a -o $name + +strip --strip-all $name if [ -e $name ]; then echo -e "\n############### SUCCESS $name ##################\n" diff --git a/FUSEISO/build_aarch64.sh b/FUSEISO/build_aarch64.sh new file mode 100644 index 00000000..59e995e9 --- /dev/null +++ b/FUSEISO/build_aarch64.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +CUR="$PWD" + +LIBFUSE_DIR=$CUR/LIBFUSE + +name=vtoy_fuse_iso_aa64 + +export C_INCLUDE_PATH=$LIBFUSE_DIR/include + +rm -f $name +aarch64-buildroot-linux-uclibc-gcc -static -O2 -D_FILE_OFFSET_BITS=64 vtoy_fuse_iso.c -o $name $LIBFUSE_DIR/lib/libfuse.a + +if [ -e $name ]; then + echo -e "\n############### SUCCESS $name ##################\n" +else + echo -e "\n############### FAILED $name ##################\n" +fi + +aarch64-buildroot-linux-uclibc-strip --strip-all $name + diff --git a/FUSEISO/build_libfuse.sh b/FUSEISO/build_libfuse.sh index 79086f6a..96086aab 100644 --- a/FUSEISO/build_libfuse.sh +++ b/FUSEISO/build_libfuse.sh @@ -7,6 +7,8 @@ # # +# use mini-native-x86_64 UCLIBC to build for x86_64 + CUR="$PWD" LIBFUSE_DIR=$CUR/LIBFUSE @@ -31,7 +33,7 @@ fi ./makeconf.sh -./configure --prefix="$LIBFUSE_DIR" +./configure --prefix="$LIBFUSE_DIR" CFLAGS='-specs /usr/local/musl/lib/musl-gcc.specs' make -j 16 make install cd .. diff --git a/FUSEISO/build_libfuse_aarch64.sh b/FUSEISO/build_libfuse_aarch64.sh new file mode 100644 index 00000000..691829ef --- /dev/null +++ b/FUSEISO/build_libfuse_aarch64.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# +# +# Package Dependency: +# gcc automake autoconf gettext gettext-devel libtool unzip +# +# + + +CUR="$PWD" +LIBFUSE_DIR=$CUR/LIBFUSE + +rm -rf libfuse +rm -rf $LIBFUSE_DIR + +# please download https://codeload.github.com/libfuse/libfuse/zip/fuse-2.9.9 +if [ -e ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip ]; then + rm -rf libfuse + unzip ../ExFAT/mirrors-libfuse-fuse-2.9.9.zip + cd libfuse +elif [ -e ../ExFAT/libfuse-fuse-2.9.9.zip ]; then + rm -rf libfuse-fuse-2.9.9 + unzip ../ExFAT/libfuse-fuse-2.9.9.zip + cd libfuse-fuse-2.9.9 +else + echo "Please download mirrors-libfuse-fuse-2.9.9.zip first" + exit 1 +fi + + +./makeconf.sh + +sed '/#define *__u64/d' -i include/fuse_kernel.h +sed '/#define *__s64/d' -i include/fuse_kernel.h + +sed 's/__u64/uint64_t/g' -i include/fuse_kernel.h +sed 's/__s64/int64_t/g' -i include/fuse_kernel.h + +./configure --prefix="$LIBFUSE_DIR" --host=aarch64 CC=aarch64-buildroot-linux-uclibc-gcc + + +make -j 16 +make install +cd .. +rm -rf libfuse diff --git a/FUSEISO/vtoy_fuse_iso.c b/FUSEISO/vtoy_fuse_iso.c index 0350ea0c..0178c8d9 100644 --- a/FUSEISO/vtoy_fuse_iso.c +++ b/FUSEISO/vtoy_fuse_iso.c @@ -114,11 +114,12 @@ static int ventoy_iso_open(const char *path, struct fuse_file_info *file) return 0; } -static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, void *buf) +static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, char *buf) { uint32_t i = 0; uint32_t leftSec = 0; uint32_t readSec = 0; + off_t offset = 0; dmtable_entry *entry = NULL; for (i = 0; i < g_disk_entry_num && num > 0; i++) @@ -127,14 +128,15 @@ static int ventoy_read_iso_sector(uint32_t sector, uint32_t num, void *buf) if (sector >= entry->isoSector && sector < entry->isoSector + entry->sectorNum) { - lseek(g_disk_fd, (entry->diskSector + (sector - entry->isoSector)) * 512, SEEK_SET); + offset = (entry->diskSector + (sector - entry->isoSector)) * 512; leftSec = entry->sectorNum - (sector - entry->isoSector); readSec = (leftSec > num) ? num : leftSec; - read(g_disk_fd, buf, readSec * 512); + pread(g_disk_fd, buf, readSec * 512, offset); sector += readSec; + buf += readSec * 512; num -= readSec; } } diff --git a/FUSEISO/vtoy_fuse_iso_32 b/FUSEISO/vtoy_fuse_iso_32 index 607ce42a..ab219292 100644 Binary files a/FUSEISO/vtoy_fuse_iso_32 and b/FUSEISO/vtoy_fuse_iso_32 differ diff --git a/FUSEISO/vtoy_fuse_iso_64 b/FUSEISO/vtoy_fuse_iso_64 index ad4ff340..c5e4b8d6 100644 Binary files a/FUSEISO/vtoy_fuse_iso_64 and b/FUSEISO/vtoy_fuse_iso_64 differ diff --git a/FUSEISO/vtoy_fuse_iso_aa64 b/FUSEISO/vtoy_fuse_iso_aa64 new file mode 100644 index 00000000..e10dff9e Binary files /dev/null and b/FUSEISO/vtoy_fuse_iso_aa64 differ diff --git a/GRUB2/MOD_SRC/grub-2.04/configure.ac b/GRUB2/MOD_SRC/grub-2.04/configure.ac new file mode 100644 index 00000000..9ad929e0 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/configure.ac @@ -0,0 +1,2123 @@ +# -*- autoconf -*- + +# Process this file with autoconf to produce a configure script. + +# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. +# +# This configure.ac is free software; the author +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +dnl This configure script is complicated, because GRUB needs to deal +dnl with three potentially different types: +dnl +dnl build -- the environment for building GRUB +dnl host -- the environment for running utilities +dnl target -- the environment for running GRUB +dnl +dnl In addition, GRUB needs to deal with a platform specification +dnl which specifies the system running GRUB, such as firmware. +dnl This is necessary because the target type in autoconf does not +dnl describe such a system very well. +dnl +dnl The current strategy is to use variables with no prefix (such as +dnl CC, CFLAGS, etc.) for the host type, variables with prefix "BUILD_" +dnl (such as BUILD_CC, BUILD_CFLAGS, etc.) for the build type and variables +dnl with the prefix "TARGET_" (such as TARGET_CC, TARGET_CFLAGS, etc.) are +dnl used for the target type. See INSTALL for full list of variables. + +AC_INIT([GRUB],[2.04],[bug-grub@gnu.org]) + +AC_CONFIG_AUX_DIR([build-aux]) + +# We don't want -g -O2 by default in CFLAGS +: ${CFLAGS=""} + +# Checks for build, host and target systems. +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +save_program_prefix="${program_prefix}" +AC_CANONICAL_TARGET +program_prefix="${save_program_prefix}" + +AM_INIT_AUTOMAKE([1.11]) +AC_PREREQ(2.63) +AC_CONFIG_SRCDIR([include/grub/dl.h]) +AC_CONFIG_HEADER([config-util.h]) + +# Explicitly check for pkg-config early on, since otherwise conditional +# calls are problematic. +PKG_PROG_PKG_CONFIG + +# Program name transformations +AC_ARG_PROGRAM +grub_TRANSFORM([grub-bios-setup]) +grub_TRANSFORM([grub-editenv]) +grub_TRANSFORM([grub-install]) +grub_TRANSFORM([grub-mkconfig]) +grub_TRANSFORM([grub-mkfont]) +grub_TRANSFORM([grub-mkimage]) +grub_TRANSFORM([grub-glue-efi]) +grub_TRANSFORM([grub-mklayout]) +grub_TRANSFORM([grub-mkpasswd-pbkdf2]) +grub_TRANSFORM([grub-mkrelpath]) +grub_TRANSFORM([grub-mkrescue]) +grub_TRANSFORM([grub-probe]) +grub_TRANSFORM([grub-reboot]) +grub_TRANSFORM([grub-script-check]) +grub_TRANSFORM([grub-set-default]) +grub_TRANSFORM([grub-sparc64-setup]) +grub_TRANSFORM([grub-render-label]) +grub_TRANSFORM([grub-file]) + +# Optimization flag. Allow user to override. +if test "x$TARGET_CFLAGS" = x; then + TARGET_CFLAGS="$TARGET_CFLAGS -Os" +fi + +# Default HOST_CPPFLAGS +HOST_CPPFLAGS="$HOST_CPPFLAGS -Wall -W" +HOST_CPPFLAGS="$HOST_CPPFLAGS -DGRUB_UTIL=1" + +TARGET_CPPFLAGS="$TARGET_CPPFLAGS -Wall -W" + +case "$target_cpu" in + i[[3456]]86) target_cpu=i386 ;; + amd64) target_cpu=x86_64 ;; + sparc) target_cpu=sparc64 ;; + mips64el) + target_cpu=mips64el + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS64EL=1" + ;; + mipsel) + target_cpu=mipsel + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPSEL=1" + ;; + mips|mips64) + target_cpu=mips + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS=1" + ;; + arm*) + target_cpu=arm + ;; + aarch64*) + target_cpu=arm64 + ;; + riscv32*) + target_cpu=riscv32 + ;; + riscv64*) + target_cpu=riscv64 + ;; +esac + +# Specify the platform (such as firmware). +AC_ARG_WITH([platform], + AS_HELP_STRING([--with-platform=PLATFORM], + [select the host platform [[guessed]]])) + +# Guess the platform if not specified. +if test "x$with_platform" = x; then + case "$target_cpu"-"$target_vendor" in + i386-apple) platform=efi ;; + i386-*) platform=pc ;; + x86_64-apple) platform=efi ;; + x86_64-*) platform=pc ;; + powerpc-*) platform=ieee1275 ;; + powerpc64-*) platform=ieee1275 ;; + powerpc64le-*) platform=ieee1275 ;; + sparc64-*) platform=ieee1275 ;; + mips64el-*) platform=efi;; + mipsel-*) platform=loongson ;; + mips-*) platform=arc ;; + ia64-*) platform=efi ;; + arm-*) platform=uboot ;; + arm64-*) platform=efi ;; + riscv32-*) platform=efi ;; + riscv64-*) platform=efi ;; + *) + AC_MSG_WARN([unsupported CPU: "$target_cpu" - only building utilities]) + platform=none + ;; + esac +else + platform="$with_platform" +fi + +case "$target_cpu"-"$platform" in + x86_64-efi) ;; + x86_64-emu) ;; + x86_64-xen) ;; + x86_64-none) ;; + x86_64-*) target_cpu=i386 ;; + powerpc64-ieee1275) target_cpu=powerpc ;; + powerpc64le-ieee1275) target_cpu=powerpc ;; +esac + +# Check if the platform is supported, make final adjustments. +case "$target_cpu"-"$platform" in + i386-efi) ;; + x86_64-efi) ;; + i386-xen) ;; + i386-xen_pvh) ;; + x86_64-xen) ;; + i386-pc) ;; + i386-multiboot) ;; + i386-coreboot) ;; + i386-linuxbios) platform=coreboot ;; + i386-ieee1275) ;; + i386-qemu) ;; + powerpc-ieee1275) ;; + sparc64-ieee1275) ;; + ia64-efi) ;; + mips-qemu_mips) ;; + mips-qemu-mips) platform=qemu_mips;; + mips-arc) ;; + mipsel-arc) ;; + mipsel-qemu_mips) ;; + mipsel-qemu-mips) platform=qemu_mips;; + mipsel-yeeloong) platform=loongson ;; + mipsel-fuloong) platform=loongson ;; + mipsel-loongson) ;; + mips64el-efi) ;; + arm-uboot) ;; + arm-coreboot) ;; + arm-efi) ;; + arm64-efi) ;; + riscv32-efi) ;; + riscv64-efi) ;; + *-emu) ;; + *-none) ;; + *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;; +esac + +if test x$platform != xemu ; then + case "$target_cpu" in + i386 | powerpc) target_m32=1 ;; + x86_64 | sparc64) target_m64=1 ;; + esac +fi + +if test x"$target_cpu-$platform" = xsparc64-emu ; then + target_m64=1 +fi + +case "$target_os" in + windows* | mingw32*) target_os=cygwin ;; +esac + +# This normalizes the names, and creates a new variable ("host_kernel") +# while at it, since the mapping is not always 1:1 (e.g. different OSes +# using the same kernel type). +case "$host_os" in + gnu*) host_kernel=hurd ;; + linux*) host_kernel=linux ;; + freebsd* | kfreebsd*-gnu) host_kernel=kfreebsd ;; + netbsd*) host_kernel=netbsd ;; + solaris*) host_kernel=illumos ;; + darwin*) host_kernel=xnu ;; + cygwin | windows* | mingw32*) host_kernel=windows ;; +esac + +case "$host_os" in + cygwin) have_exec=y ;; + windows* | mingw32*) have_exec=n ;; + aros*) have_exec=n ;; + *) have_exec=y;; +esac + +case "$platform" in + coreboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_COREBOOT=1" ;; + multiboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;; + efi) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;; + xen) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN=1" ;; + xen_pvh) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_XEN_PVH=1" ;; + ieee1275) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;; + uboot) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;; + qemu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;; + pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; + emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; + loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;; + qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; + arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; +esac +if test x${target_cpu} = xmipsel ; then + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo mips_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +else + machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE=`echo ${target_cpu}_$platform | sed y,abcdefghijklmnopqrstuvwxyz,ABCDEFGHIJKLMNOPQRSTUVWXYZ,`" +fi + +case "${target_cpu}-$platform" in + mips-arc) + TARGET_LINK_ADDR=0x88200000 + TARGET_DECOMPRESSOR_LINK_ADDR=0x88100000 + ;; + mipsel-arc) + TARGET_LINK_ADDR=0x80700000 + TARGET_DECOMPRESSOR_LINK_ADDR=0x80600000 + ;; + mips*-qemu_mips | mips*-loongson) + TARGET_DECOMPRESSOR_LINK_ADDR=0x80100000 + ;; +esac + +AC_SUBST(TARGET_LINK_ADDR) +AC_SUBST(TARGET_DECOMPRESSOR_LINK_ADDR) + +TARGET_CPPFLAGS="$TARGET_CPPFLAGS $machine_CPPFLAGS" + +AC_SUBST(host_cpu) +AC_SUBST(host_os) +AC_SUBST(host_kernel) + +AC_SUBST(target_cpu) +AC_SUBST(platform) + +# Define default variables + +have_with_bootdir=n +AC_ARG_WITH([bootdir], + AS_HELP_STRING([--with-bootdir=DIR], + [set the name of /boot directory [[guessed]]]), + [have_with_bootdir=y], + [have_with_bootdir=n]) +if test x$have_with_bootdir = xy; then + bootdirname="$with_bootdir" +else + case "$host_os" in + netbsd* | openbsd*) + # Because /boot is used for the boot block in NetBSD and OpenBSD, + bootdirname='' ;; + *) bootdirname='boot' ;; + esac +fi + +AC_SUBST(bootdirname) +AC_DEFINE_UNQUOTED(GRUB_BOOT_DIR_NAME, "$bootdirname", + [Default boot directory name]) + +AC_ARG_WITH([grubdir], + AS_HELP_STRING([--with-grubdir=DIR], + [set the name of grub directory [[guessed]]]), + [grubdirname="$with_grubdir"], + [grubdirname="$PACKAGE"]) + +AC_SUBST(grubdirname) +AC_DEFINE_UNQUOTED(GRUB_DIR_NAME, "$grubdirname", + [Default grub directory name]) + +# +# Checks for build programs. +# + +# Although cmp is listed in the GNU Coding Standards as a command which +# can used directly, OpenBSD lacks cmp in the default installation. +AC_CHECK_PROGS([CMP], [cmp]) +if test "x$CMP" = x; then + AC_MSG_ERROR([cmp is not found]) +fi + +AC_CHECK_PROGS([YACC], [bison]) +if test "x$YACC" = x; then + AC_MSG_ERROR([bison is not found]) +fi + +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_PROG_AWK +AC_PROG_LEX +AC_PROG_YACC +AC_PROG_MAKE_SET +AC_PROG_MKDIR_P +AC_PROG_LN_S + +if test "x$LEX" = "x:"; then + AC_MSG_ERROR([flex is not found]) +else + version=`$LEX --version | $AWK '{ split($2,x,"."); print x[[1]]*10000+x[[2]]*100+x[[3]]; }'` + if test -n "$version" -a "$version" -ge 20535; then + : + else + AC_MSG_ERROR([flex is too old. GRUB requires 2.5.35 or above]) + fi +fi + +# These are not a "must". +AC_PATH_PROGS(MAKEINFO, makeinfo true) + +# +# Checks for host programs. +# + +AC_PROG_CC +gl_EARLY +AC_PROG_CXX +AM_PROG_CC_C_O +AM_PROG_AS +AM_PATH_PYTHON([2.6]) + +# Must be GCC. +test "x$GCC" = xyes || AC_MSG_ERROR([GCC is required]) + +AC_CHECK_PROG(HAVE_CXX, $CXX, yes, no) + +AC_GNU_SOURCE +AM_GNU_GETTEXT([external]) +AM_GNU_GETTEXT_VERSION([0.18.3]) +AC_SYS_LARGEFILE + +# Identify characteristics of the host architecture. +unset ac_cv_c_bigendian + +if test x"$target_cpu-$platform" = xsparc64-emu ; then + CFLAGS="$CFLAGS -m64" + HOST_CFLAGS="$HOST_CFLAGS -m64" +fi + +CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=64" +HOST_CPPFLAGS="$HOST_CPPFLAGS -D_FILE_OFFSET_BITS=64" + +AC_C_BIGENDIAN +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long) + +case "$host_os" in + cygwin | windows* | mingw32*) + HOST_CPPFLAGS="$HOST_CPPFLAGS -DUNICODE=1 -D_WIN32_WINNT=0x0500" + CPPFLAGS="$CPPFLAGS -DUNICODE=1 -D_WIN32_WINNT=0x0500" + AC_CHECK_SIZEOF(TCHAR,,[#include ]) + ;; +esac + +case "$host_os" in + cygwin | windows* | mingw32* | aros*) + ;; + *) + AC_CHECK_SIZEOF(off_t) + if test x"$ac_cv_sizeof_off_t" != x8 ; then + AC_CHECK_SIZEOF(off64_t) + test x"$ac_cv_sizeof_off64_t" = x8 || AC_MSG_ERROR([Large file support is required]) + fi;; +esac + +if test x$USE_NLS = xno; then + HOST_CFLAGS="$HOST_CFLAGS -fno-builtin-gettext" +fi + +if test "x$cross_compiling" = xyes; then + AC_MSG_WARN([cannot generate manual pages while cross compiling]) +else + AC_PATH_PROG(HELP2MAN, help2man) +fi + +# Check for functions and headers. +AC_CHECK_FUNCS(posix_memalign memalign getextmntent) +AC_CHECK_HEADERS(sys/param.h sys/mount.h sys/mnttab.h limits.h) + +# glibc 2.25 still includes sys/sysmacros.h in sys/types.h but emits deprecation +# warning which causes compilation failure later with -Werror. So use -Werror here +# as well to force proper sys/sysmacros.h detection. +SAVED_CFLAGS="$CFLAGS" +CFLAGS="$HOST_CFLAGS -Werror" +AC_HEADER_MAJOR +CFLAGS="$SAVED_CFLAGS" + +AC_CHECK_MEMBERS([struct statfs.f_fstypename],,,[$ac_includes_default +#include +#include ]) + +AC_CHECK_MEMBERS([struct statfs.f_mntfromname],,,[$ac_includes_default +#include +#include ]) + +# For opendisk() and getrawpartition() on NetBSD. +# Used in util/deviceiter.c and in util/hostdisk.c. +AC_CHECK_HEADER([util.h], [ + AC_CHECK_LIB([util], [opendisk], [ + LIBUTIL="-lutil" + AC_DEFINE(HAVE_OPENDISK, 1, [Define if opendisk() in -lutil can be used]) + ]) + AC_CHECK_LIB([util], [getrawpartition], [ + LIBUTIL="-lutil" + AC_DEFINE(HAVE_GETRAWPARTITION, 1, [Define if getrawpartition() in -lutil can be used]) + ]) +]) +AC_SUBST([LIBUTIL]) + +AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_host_cc_wtrampolines], [ + SAVED_CFLAGS="$CFLAGS" + CFLAGS="$HOST_CFLAGS -Wtrampolines -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_host_cc_wtrampolines=yes], + [grub_cv_host_cc_wtrampolines=no]) + CFLAGS="$SAVED_CFLAGS" +]) + +if test x"$grub_host_cv_cc_wtrampolines" = xyes ; then + HOST_CFLAGS="$HOST_CFLAGS -Wtrampolines" +fi + +# +# Check for host and build compilers. +# +HOST_CC=$CC +AC_CHECK_PROGS(BUILD_CC, [gcc egcs cc]) +test -z "$BUILD_CC" && AC_MSG_ERROR([none of gcc, egcs and cc is found. set BUILD_CC manually.]) +BUILD_CPP="$BUILD_CC -E" + +case "$build_os" in + haiku*) BUILD_LIBM= ;; + *) BUILD_LIBM=-lm ;; +esac + +dnl FIXME proper test seems to require too deep dive into Autoconf internals. +dnl For now just list known platforms that we support. + +case "$build_os" in + cygwin*|mingw32*|mingw64*) BUILD_EXEEXT=.exe ;; + *) BUILD_EXEEXT= ;; +esac +AC_SUBST(BUILD_EXEEXT) + +# In some build environments like termux /bin/sh is not a valid +# shebang. Use $SHELL instead if it's executable and /bin/sh isn't +BUILD_SHEBANG=/bin/sh +for she in /bin/sh "$SHELL"; do + if test -x "$she" ; then + BUILD_SHEBANG="$she" + fi +done +AC_SUBST(BUILD_SHEBANG) + +# For gnulib. +gl_INIT + +WARN_FLAGS="-Wall -W -Wshadow -Wpointer-arith -Wundef -Wchar-subscripts -Wcomment -Wdeprecated-declarations -Wdisabled-optimization -Wdiv-by-zero -Wfloat-equal -Wformat-extra-args -Wformat-security -Wformat-y2k -Wimplicit -Wimplicit-function-declaration -Wimplicit-int -Wmain -Wmissing-braces -Wmissing-format-attribute -Wmultichar -Wparentheses -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wswitch -Wtrigraphs -Wunknown-pragmas -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wwrite-strings -Wnested-externs -Wstrict-prototypes" +EXTRA_WARN_FLAGS="-Wextra -Wattributes -Wendif-labels -Winit-self -Wint-to-pointer-cast -Winvalid-pch -Wmissing-field-initializers -Wnonnull -Woverflow -Wvla -Wpointer-to-int-cast -Wstrict-aliasing -Wvariadic-macros -Wvolatile-register-var -Wpointer-sign -Wmissing-include-dirs -Wmissing-prototypes -Wmissing-declarations -Wformat=2" + +HOST_CFLAGS="$HOST_CFLAGS $WARN_FLAGS -Wcast-align" + +AC_CACHE_CHECK([which extra warnings work], [grub_cv_cc_w_extra_flags], [ + SAVED_CFLAGS="$CFLAGS" + grub_cv_cc_w_extra_flags= + for x in $EXTRA_WARN_FLAGS; do + CFLAGS="$HOST_CFLAGS $x -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) + if test x$flag = x1 ; then + grub_cv_cc_w_extra_flags="$grub_cv_cc_w_extra_flags $x" + fi + done + CFLAGS="$SAVED_CFLAGS" +]) + +HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags" + +# +# Check for target programs. +# + +# Find tools for the target. +if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then + tmp_ac_tool_prefix="$ac_tool_prefix" + ac_tool_prefix=$target_alias- + + AC_CHECK_TOOLS(TARGET_CC, [gcc egcs cc], + [AC_MSG_ERROR([none of gcc, egcs and cc is found. set TARGET_CC manually.])]) + AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy) + AC_CHECK_TOOL(TARGET_STRIP, strip) + AC_CHECK_TOOL(TARGET_NM, nm) + AC_CHECK_TOOL(TARGET_RANLIB, ranlib) + + ac_tool_prefix="$tmp_ac_tool_prefix" +else + if test "x$TARGET_CC" = x; then + TARGET_CC=$CC + fi + AC_CHECK_TOOL(TARGET_OBJCOPY, objcopy) + AC_CHECK_TOOL(TARGET_STRIP, strip) + AC_CHECK_TOOL(TARGET_NM, nm) + AC_CHECK_TOOL(TARGET_RANLIB, ranlib) +fi + +AC_SUBST(HOST_CC) +AC_SUBST(BUILD_CC) +AC_SUBST(BUILD_CFLAGS) +AC_SUBST(BUILD_CPPFLAGS) +AC_SUBST(BUILD_LDFLAGS) +AC_SUBST(TARGET_CC) +AC_SUBST(TARGET_NM) +AC_SUBST(TARGET_RANLIB) +AC_SUBST(TARGET_STRIP) +AC_SUBST(TARGET_OBJCOPY) + +# Test the C compiler for the target environment. +tmp_CC="$CC" +tmp_CFLAGS="$CFLAGS" +tmp_LDFLAGS="$LDFLAGS" +tmp_CPPFLAGS="$CPPFLAGS" +tmp_LIBS="$LIBS" +CC="$TARGET_CC" +CFLAGS="$TARGET_CFLAGS" +CPPFLAGS="$TARGET_CPPFLAGS" +LDFLAGS="$TARGET_LDFLAGS" +LIBS="" + +# debug flags. +TARGET_CFLAGS="$TARGET_CFLAGS $WARN_FLAGS -g -Wredundant-decls -Wmissing-prototypes -Wmissing-declarations" +TARGET_CCASFLAGS="$TARGET_CCASFLAGS -g" + +if test "x$target_cpu" != xi386 && test "x$target_cpu" != xx86_64; then +TARGET_CFLAGS="$TARGET_CFLAGS -Wcast-align" +fi + +TARGET_CC_VERSION="$(LC_ALL=C $TARGET_CC --version | head -n1)" + +AC_CACHE_CHECK([which extra warnings work], [grub_cv_target_cc_w_extra_flags], [ + LDFLAGS="$TARGET_LDFLAGS -nostdlib -static" + + grub_cv_target_cc_w_extra_flags= + for x in $EXTRA_WARN_FLAGS; do + CFLAGS="$TARGET_CFLAGS $x -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +asm (".globl start; start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], [flag=1], [flag=0]) + if test x$flag = x1 ; then + grub_cv_target_cc_w_extra_flags="$grub_cv_target_cc_w_extra_flags $x" + fi + done +]) + +TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_w_extra_flags" + +AC_CACHE_CHECK([if compiling with clang], [grub_cv_cc_target_clang], +[ +CFLAGS="$TARGET_CFLAGS" +AC_COMPILE_IFELSE( +[AC_LANG_PROGRAM([], [[ +#ifdef __clang__ +#error "is clang" +#endif +]])], +[grub_cv_cc_target_clang=no], [grub_cv_cc_target_clang=yes])]) + +if test x$target_cpu = xpowerpc -o x$target_cpu = xmips; then + AC_CACHE_CHECK([for options to get big-endian compilation], grub_cv_target_cc_big_endian, [ + grub_cv_target_cc_big_endian=no + for cand in "-target $target_cpu -Wl,-EB" "-target $target_cpu" \ + "-target $target_cpu-linux-gnu -Wl,-EB" "-target $target_cpu-linux-gnu" \ + "-EB" "-mbig-endian"; do + if test x"$grub_cv_target_cc_big_endian" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ != __BYTE_ORDER__) +#error still little endian +#endif +asm (".globl start; start:"); +asm (".globl _start; _start:"); +asm (".globl __start; __start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], + [grub_cv_target_cc_big_endian="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_big_endian" = xno ; then + AC_MSG_ERROR([could not force big-endian]) + fi + + skip_linkflags="$(echo "$grub_cv_target_cc_big_endian"|sed 's@-Wl,-EB@@')" + + TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags" + TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_big_endian" +elif test x$target_cpu = xmipsel; then + AC_CACHE_CHECK([for options to get little-endian compilation], grub_cv_target_cc_little_endian, [ + grub_cv_target_cc_little_endian=no + for cand in "-target $target_cpu -Wl,-EL" "-target $target_cpu" \ + "-target $target_cpu-linux-gnu -Wl,-EL" "-target $target_cpu-linux-gnu" \ + "-EL"; do + if test x"$grub_cv_target_cc_little_endian" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && (__ORDER_BIG_ENDIAN__ == __BYTE_ORDER__) +#error still big endian +#endif +asm (".globl start; start:"); +asm (".globl _start; _start:"); +asm (".globl __start; __start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], + [grub_cv_target_cc_little_endian="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_little_endian" = xno ; then + AC_MSG_ERROR([could not force little-endian]) + fi + + skip_linkflags="$(echo "$grub_cv_target_cc_little_endian"|sed 's@-Wl,-EL@@')" + + TARGET_CFLAGS="$TARGET_CFLAGS $skip_linkflags" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $skip_linkflags" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $skip_linkflags" + TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_little_endian" +fi + +# GRUB code is N32-compliant but it's experimental and we would prefer to +# avoid having too much variety when it doesn't result in any real improvement. +# Moreover N64 isn't supported. +if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then + AC_CACHE_CHECK([for options to force MIPS o32 ABI], grub_cv_target_cc_mips_o32_abi, [ + grub_cv_target_cc_mips_o32_abi=no + for arg in "" "-mabi=32" "-target $target_cpu -mabi=32" ; do + if test x"$grub_cv_target_cc_mips_o32_abi" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $arg -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#if !defined(_ABIO32) || !defined(_MIPS_SIM) || (_MIPS_SIM != _ABIO32) +#error not o32 ABI +#endif +asm (".globl start; start:"); +asm (".globl _start; _start:"); +asm (".globl __start; __start:"); +void __main (void); +void __main (void) {} +int main (void); +]], [[]])], + [grub_cv_target_cc_mips_o32_abi="$arg"], []) + done + ]) + + if test x"$grub_cv_target_cc_mips_o32_abi" = xno ; then + AC_MSG_ERROR([could not force MIPS o32 ABI]) + fi + + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mips_o32_abi" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mips_o32_abi" +fi + +AC_CACHE_CHECK([for options to compile assembly], [grub_cv_cc_target_asm_compile], [ +test_program= +case "x$target_cpu-$platform" in + xmips-* | xmipsel-*) + test_program=mips + ;; + xi386-pc) + test_program=i386-pc + ;; + xi386-* | xx86_64-*) + test_program=i386 + ;; + xpowerpc-* | xsparc64-* | xarm-*) + test_program=$target_cpu + ;; +esac +if test x"$test_program" = x ; then + grub_cv_cc_target_asm_compile= +else + found=no + for arg in "" "-no-integrated-as"; do + cmdline="$TARGET_CC -c -o /dev/null $TARGET_CCASFLAGS $arg $TARGET_CPPFLAGS $srcdir/asm-tests/$test_program.S" + echo "Running $cmdline" >&AS_MESSAGE_LOG_FD + if $cmdline >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD; then + grub_cv_cc_target_asm_compile="$arg" + found=yes + break + fi + done + if test x"$found" = xno ; then + AC_MSG_ERROR([could not compile assembly]) + fi +fi +]) + +TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_cc_target_asm_compile" + +if test "x$target_cpu" = xi386 && test "x$platform" != xemu; then + TARGET_CFLAGS="$TARGET_CFLAGS -march=i386" +fi + +if test "x$target_m32" = x1; then + # Force 32-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m32" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m32" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m32" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m32" + TARGET_MODULE_FORMAT="elf32" +fi + +if test "x$target_m64" = x1; then + # Force 64-bit mode. + TARGET_CFLAGS="$TARGET_CFLAGS -m64" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -m64" + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -m64" + TARGET_LDFLAGS="$TARGET_LDFLAGS -m64" + TARGET_MODULE_FORMAT="elf64" +fi + +if test "x$grub_cv_cc_target_clang" = xno && test "x$target_cpu" = xi386 && test "x$platform" != xemu && test "x$platform" != xefi; then + TARGET_CFLAGS="$TARGET_CFLAGS -mrtd -mregparm=3" +fi + +# on mips redirect cache flushing function to non-existant one. +if test "x$target_cpu" = xmips || test "x$target_cpu" = xmipsel ; then + AC_CACHE_CHECK([whether -mflush-func=grub_red_herring works], [grub_cv_cc_mflush_func], [ + CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mflush_func=yes], + [grub_cv_cc_mflush_func=no]) + ]) + + if test "x$grub_cv_cc_mflush_func" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mflush-func=grub_red_herring" + fi +fi + + +# Force no alignment to save space on i386. +if test "x$target_cpu" = xi386; then + AC_CACHE_CHECK([whether -falign-loops works], [grub_cv_cc_falign_loop], [ + CFLAGS="$TARGET_CFLAGS -falign-loops=1 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_falign_loop=yes], + [grub_cv_cc_falign_loop=no]) + ]) + + AC_CACHE_CHECK([whether -malign-loops works], [grub_cv_cc_malign_loop], [ + CFLAGS="$TARGET_CFLAGS -malign-loops=1 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_malign_loop=yes], + [grub_cv_cc_malign_loop=no]) + ]) + + if test "x$grub_cv_cc_falign_loop" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -falign-jumps=1 -falign-loops=1 -falign-functions=1" + elif test "x$grub_cv_cc_malign_loop" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -malign-jumps=1 -malign-loops=1 -malign-functions=1" + fi +fi + +AC_CACHE_CHECK([whether -freg-struct-return works], [grub_cv_cc_freg_struct_return], [ + CFLAGS="$TARGET_CFLAGS -freg-struct-return -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_freg_struct_return=yes], + [grub_cv_cc_freg_struct_return=no]) +]) + +if test "x$grub_cv_cc_freg_struct_return" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -freg-struct-return" +fi + +if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$platform" != xemu; then + # Some toolchains enable these features by default, but they need + # registers that aren't set up properly in GRUB. + TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow" +fi + +# GRUB doesn't use float or doubles at all. Yet some toolchains may decide +# that floats are a good fit to run instead of what's written in the code. +# Given that floating point unit is disabled (if present to begin with) +# when GRUB is running which may result in various hard crashes. +#if test x"$platform" != xemu ; then +if ( test x"$platform" != xemu && x"$platform" != mips64el-efi ) ; then + AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [ + grub_cv_target_cc_soft_float=no + if test "x$target_cpu" = xarm64; then + CFLAGS="$TARGET_CFLAGS -mgeneral-regs-only -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-mgeneral-regs-only"], []) + fi + if test "x$target_cpu" = xriscv32; then + CFLAGS="$TARGET_CFLAGS -march=rv32imac -mabi=ilp32 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv32imac -mabi=ilp32"], []) + fi + if test "x$target_cpu" = xriscv64; then + CFLAGS="$TARGET_CFLAGS -march=rv64imac -mabi=lp64 -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-march=rv64imac -mabi=lp64"], []) + fi + if test "x$target_cpu" = xia64; then + CFLAGS="$TARGET_CFLAGS -mno-inline-float-divide -mno-inline-sqrt -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="-mno-inline-float-divide -mno-inline-sqrt"], []) + fi + for cand in "-msoft-float -Xclang -msoft-float -Xclang -no-implicit-float" \ + "-Xclang -msoft-float -Xclang -no-implicit-float" \ + "-Xclang -msoft-float" "-msoft-float"; do + if test x"$grub_cv_target_cc_soft_float" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_soft_float="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_soft_float" = xno ; then + AC_MSG_ERROR([could not force soft-float]) + fi + + case x"$grub_cv_target_cc_soft_float" in + x*"-Xclang"*) + # A trick so that clang doesn't see it on link stаge + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_soft_float" + ;; + *) + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_soft_float" + ;; + esac + TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_soft_float" + +fi + +if test x"$target_cpu" = xsparc64 ; then + AC_CACHE_CHECK([for options to reserve application registers], grub_cv_target_cc_mno_app_regs, [ + grub_cv_target_cc_mno_app_regs=no + for cand in "-mllvm -sparc-reserve-app-registers" \ + "-mno-app-regs"; do + if test x"$grub_cv_target_cc_mno_app_regs" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + CPPFLAGS="$TARGET_CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_mno_app_regs="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_mno_app_regs" = xno ; then + AC_MSG_ERROR([could not reserve application registers]) + fi + if test x"$grub_cv_target_cc_mno_app_regs" = x"-mllvm -sparc-reserve-app-registers" ; then + # A trick so that clang doesn't see it on link stаge + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_app_regs" + else + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_app_regs" + fi + + AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [ + grub_cv_target_cc_mno_relax=no + for cand in "-mno-relax" "-Wl,--no-relax"; do + if test x"$grub_cv_target_cc_mno_relax" != xno ; then + break + fi + LDFLAGS="$TARGET_LDFLAGS $cand -nostdlib -static" + CFLAGS="$TARGET_CFLAGS -Werror" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + asm (".globl start; start:"); + void __main (void); + void __main (void) {} + int main (void); + ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], []) + done + ]) + LDFLAGS="$TARGET_LDFLAGS" + CFLAGS="$TARGET_CFLAGS" + + if test x"$grub_cv_target_cc_mno_relax" = xno ; then + AC_MSG_ERROR([could not find no-relax options]) + fi + TARGET_LDFLAGS="$TARGET_LDFLAGS $grub_cv_target_cc_mno_relax" +fi + +# By default, GCC 4.4 generates .eh_frame sections containing unwind +# information in some cases where it previously did not. GRUB doesn't need +# these and they just use up vital space. Restore the old compiler +# behaviour. +AC_CACHE_CHECK([whether -fno-dwarf2-cfi-asm works], [grub_cv_cc_fno_dwarf2_cfi_asm], [ + CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_dwarf2_cfi_asm=yes], + [grub_cv_cc_fno_dwarf2_cfi_asm=no]) +]) + +if test "x$grub_cv_cc_fno_dwarf2_cfi_asm" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-dwarf2-cfi-asm" +fi + +if test x"$target_os" = xcygwin; then + AC_CACHE_CHECK([whether option -fno-reorder-functions works], grub_cv_cc_no_reorder_functions, [ + CFLAGS="$TARGET_CFLAGS -fno-reorder-functions" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_no_reorder_functions=yes], + [grub_cv_cc_no_reorder_functions=no]) + ]) +fi + +if test x"$target_os" = xcygwin && test "x$grub_cv_cc_no_reorder_functions" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-reorder-functions" +fi + +AC_CACHE_CHECK([whether -mno-stack-arg-probe works], [grub_cv_cc_mno_stack_arg_probe], [ + CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mno_stack_arg_probe=yes], + [grub_cv_cc_mno_stack_arg_probe=no]) +]) + +if test "x$grub_cv_cc_mno_stack_arg_probe" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" +fi + + +# By default, GCC 4.6 generates .eh_frame sections containing unwind +# information in some cases where it previously did not. GRUB doesn't need +# these and they just use up vital space. Restore the old compiler +# behaviour. +AC_CACHE_CHECK([whether -fno-asynchronous-unwind-tables works], [grub_cv_cc_fno_asynchronous_unwind_tables], [ + CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_asynchronous_unwind_tables=yes], + [grub_cv_cc_fno_asynchronous_unwind_tables=no]) +]) + +if test "x$grub_cv_cc_fno_asynchronous_unwind_tables" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-asynchronous-unwind-tables" +fi + +AC_CACHE_CHECK([whether -fno-unwind-tables works], [grub_cv_cc_fno_unwind_tables], [ + CFLAGS="$TARGET_CFLAGS -fno-unwind-tables" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_fno_unwind_tables=yes], + [grub_cv_cc_fno_unwind_tables=no]) +]) + +if test "x$grub_cv_cc_fno_unwind_tables" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-unwind-tables" +fi + + +CFLAGS="$TARGET_CFLAGS" + + +if test x"$platform" = xemu ; then + TARGET_OBJ2ELF= + grub_cv_target_cc_link_format= + case "$host_os" in + *darwin* | *mac*) + grub_cv_target_cc_link_format="-arch,${target_cpu}" + TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" + ;; + *windows* | *cygwin* | *mingw*) + if test x${target_cpu} = xi386 ; then + grub_cv_target_cc_link_format=-mi386pe + TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)' + fi + if test x${target_cpu} = xx86_64 ; then + grub_cv_target_cc_link_format=-mi386pep + TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)' + fi + TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" + ;; + esac +elif test x"$target_cpu" = xi386 || test x"$target_cpu" = xx86_64; then + AC_CACHE_CHECK([for target linking format], [grub_cv_target_cc_link_format], [ + grub_cv_target_cc_link_format=unknown + for format in -melf_${target_cpu} -melf_${target_cpu}_fbsd -melf_${target_cpu}_obsd -melf_${target_cpu}_haiku -mi386pe -mi386pep -arch,${target_cpu}; do + if test x${target_cpu} != xi386 && test x$format = x-mi386pe; then + continue + fi + if test x${target_cpu} != xx86_64 && test x$format = x-mi386pep; then + continue + fi + CFLAGS="$TARGET_CFLAGS" + LDFLAGS="$TARGET_LDFLAGS -Wl,$format -nostdlib -static" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + asm (".globl start; start:"); + asm (".globl _start; _start:"); + asm (".globl __start; __start:"); + void __main (void); + void __main (void) {} + ]], [[]])], [flag=1], [flag=0]) + if test x"$flag" = x1; then + grub_cv_target_cc_link_format="$format" + break + fi + done]) + if test x"$grub_cv_target_cc_link_format" = xunknown; then + AC_MSG_ERROR([no suitable link format found]) + fi + TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,$grub_cv_target_cc_link_format" + if test x"$grub_cv_target_cc_link_format" = x-mi386pe ; then + TARGET_OBJ2ELF='./build-grub-pe2elf$(BUILD_EXEEXT)' + fi + if test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then + TARGET_OBJ2ELF='./build-grub-pep2elf$(BUILD_EXEEXT)' + fi +fi + +if test x$grub_cv_target_cc_link_format = x-arch,i386 || test x$grub_cv_target_cc_link_format = x-arch,x86_64; then + TARGET_APPLE_LINKER=1 + AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [objconv], []) + if test "x$TARGET_OBJCONV" = x ; then + AC_CHECK_PROG([TARGET_OBJCONV], [objconv], [./objconv], [], [.]) + fi + if test "x$TARGET_OBJCONV" = x ; then + AC_MSG_ERROR([objconv not found which is required when building with apple compiler]) + fi + TARGET_IMG_LDSCRIPT= + TARGET_IMG_CFLAGS="-static" + TARGET_IMG_LDFLAGS='-nostdlib -static -Wl,-preload -Wl,-segalign,20' + TARGET_IMG_LDFLAGS_AC='-nostdlib -static -Wl,-preload -Wl,-segalign,20' + TARGET_IMG_BASE_LDOPT="-Wl,-image_base" + TARGET_LDFLAGS_OLDMAGIC="" +elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_cc_link_format = x-mi386pep ; then + TARGET_APPLE_LINKER=0 + TARGET_LDFLAGS_OLDMAGIC="-Wl,-N" + TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/${grub_coredir}/conf/i386-cygwin-img-ld.sc" + TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}" + TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/${grub_coredir}/conf/i386-cygwin-img-ld.sc" + TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" + TARGET_IMG_CFLAGS= +else + TARGET_APPLE_LINKER=0 + TARGET_LDFLAGS_OLDMAGIC="-Wl,-N" + TARGET_IMG_LDSCRIPT= + TARGET_IMG_LDFLAGS='-Wl,-N' + TARGET_IMG_LDFLAGS_AC='-Wl,-N' + TARGET_IMG_BASE_LDOPT="-Wl,-Ttext" + TARGET_IMG_CFLAGS= +fi + +CFLAGS="$TARGET_CFLAGS" + +AC_ARG_ENABLE([efiemu], + [AS_HELP_STRING([--enable-efiemu], + [build and install the efiemu runtimes (default=guessed)])]) +if test x"$enable_efiemu" = xno ; then + efiemu_excuse="explicitly disabled" +fi + +if test x"$grub_cv_target_cc_link_format" = x-mi386pe || test x"$grub_cv_target_cc_link_format" = x-mi386pep ; then + efiemu_excuse="not available on cygwin" +fi +if test x"$target_cpu" != xi386 ; then + efiemu_excuse="only available on i386" +fi +if test x"$platform" = xefi ; then + efiemu_excuse="not available on efi" +fi + +if test x"$efiemu_excuse" = x ; then + AC_CACHE_CHECK([whether options required for efiemu work], grub_cv_cc_efiemu, [ + CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_efiemu=yes], + [grub_cv_cc_efiemu=no]) + ]) + if test x$grub_cv_cc_efiemu = xno; then + efiemu_excuse="cannot compile with -m64 -mcmodel=large -mno-red-zone -nostdlib" + fi +fi +if test x"$efiemu_excuse" = x ; then + AC_CACHE_CHECK([for efiemu64 linking format], [grub_cv_target_cc_efiemu64_link_format], [ + grub_cv_target_cc_efiemu64_link_format=unknown + for format in -melf_x86_64 -melf_x86_64_fbsd -melf_x86_64_obsd -melf_x86_64_haiku -arch,x86_64; do + CFLAGS="-m64 -nostdlib -O2 -mcmodel=large -mno-red-zone" + LDFLAGS="-m64 -Wl,$format -nostdlib -static" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ + asm (".globl start; start:"); + asm (".globl _start; _start:"); + asm (".globl __start; __start:"); + void __main (void); + void __main (void) {} + ]], [[]])], [flag=1], [flag=0]) + if test x"$flag" = x1; then + grub_cv_target_cc_efiemu64_link_format="$format" + break + fi + done]) + if test x"$grub_cv_target_cc_efiemu64_link_format" = xunknown; then + efiemu_excuse="no suitable link format for efiemu64 found" + else + EFIEMU64_LINK_FORMAT="-Wl,$grub_cv_target_cc_efiemu64_link_format" + fi +fi +if test x"$enable_efiemu" = xyes && test x"$efiemu_excuse" != x ; then + AC_MSG_ERROR([efiemu runtime was explicitly requested but can't be compiled ($efiemu_excuse)]) +fi +if test x"$efiemu_excuse" = x ; then +enable_efiemu=yes +else +enable_efiemu=no +fi +AC_SUBST([enable_efiemu]) +AC_SUBST([EFIEMU64_LINK_FORMAT]) + +CFLAGS="$TARGET_CFLAGS" + +AC_SUBST(TARGET_LDFLAGS_OLDMAGIC) + + +LDFLAGS="$TARGET_LDFLAGS" + +if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then + # Use large model to support 4G memory + AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [ + CFLAGS="$TARGET_CFLAGS -mcmodel=large" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mcmodel=yes], + [grub_cv_cc_mcmodel=no]) + ]) + if test "x$grub_cv_cc_mcmodel" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large" + elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then + TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany" + fi +fi + +if test "$target_cpu"-"$platform" = x86_64-efi; then + # EFI writes to stack below %rsp, we must not use the red zone + AC_CACHE_CHECK([whether option -mno-red-zone works], grub_cv_cc_no_red_zone, [ + CFLAGS="$TARGET_CFLAGS -mno-red-zone" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_no_red_zone=yes], + [grub_cv_cc_no_red_zone=no]) + ]) + if test "x$grub_cv_cc_no_red_zone" = xno; then + AC_MSG_ERROR([-mno-red-zone not supported, upgrade your gcc]) + fi + + TARGET_CFLAGS="$TARGET_CFLAGS -mno-red-zone" +fi + +if test "x$target_cpu" = xarm; then + AC_CACHE_CHECK([for options to disable movt and movw], grub_cv_target_cc_mno_movt, [ + grub_cv_target_cc_mno_movt=no + for cand in "-mno-movt" \ + "-mllvm -arm-use-movt=0"; do + if test x"$grub_cv_target_cc_mno_movt" != xno ; then + break + fi + CFLAGS="$TARGET_CFLAGS $cand -Werror" + CPPFLAGS="$TARGET_CPPFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_mno_movt="$cand"], []) + done + ]) + + if test x"$grub_cv_target_cc_mno_movt" != xno ; then + # A trick so that clang doesn't see it on link stage + TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt" + fi + AC_CACHE_CHECK([whether option -mthumb-interwork works], grub_cv_cc_mthumb_interwork, [ + CFLAGS="$TARGET_CFLAGS -mthumb-interwork -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_cc_mthumb_interwork=yes], + [grub_cv_cc_mthumb_interwork=no]) + ]) + if test "x$grub_cv_cc_mthumb_interwork" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mthumb-interwork" + # Clang defaults to thumb interworking + elif test "x$grub_cv_cc_target_clang" = xno ; then + AC_MSG_ERROR([your compiler doesn't support -mthumb-interwork]) + fi +fi + +AC_CACHE_CHECK([whether option -Qn works], grub_cv_target_cc_qn, [ + CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], + [grub_cv_target_cc_qn=yes], + [grub_cv_target_cc_qn=no])]) +if test "x$grub_cv_target_cc_qn" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -Qn -Qunused-arguments" +fi + +# +# Compiler features. +# + +CFLAGS="$TARGET_CFLAGS" + +# Position independent executable. +grub_CHECK_PIE +grub_CHECK_NO_PIE +grub_CHECK_NO_PIE_ONEWORD +grub_CHECK_LINK_PIE +[# Need that, because some distributions ship compilers that include +# `-fPIE' or '-fpie' and '-pie' in the default specs. +if [ x"$pie_possible" = xyes ]; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIE -fno-pie" +fi + +if [ x"$link_nopie_needed" = xyes ] || [ x"$pie_possible" = xyes ]; then + if [ x"$nopie_possible" = xyes ]; then + TARGET_LDFLAGS="$TARGET_LDFLAGS -no-pie" + fi + if [ x"$nopie_oneword_possible" = xyes ]; then + TARGET_LDFLAGS="$TARGET_LDFLAGS -nopie" + fi +fi] + +CFLAGS="$TARGET_CFLAGS" +LDFLAGS="$TARGET_LDFLAGS" + +# Position independent executable. +grub_CHECK_PIC +[# On most platforms we don't want PIC as it only makes relocations harder +# and code less efficient. On mips we want to have one got table per module +# and reload $gp in every function. +# GCC implements it using symbol __gnu_local_gp in non-PIC as well. +# However with clang we need PIC for this reloading to happen. +# With arm64 we need relocations that are in some way representable in +# PE as we need to support arm64-efi. Without -fPIC clang generates +# movk's which aren't representable. +# Since default varies across dictributions use either -fPIC or -fno-PIC +# explicitly. +if ( test x$target_cpu = xmips || test x$target_cpu = xmipsel || test x$target_cpu = xarm64 || test x$target_cpu = xmips64el ) && test "x$grub_cv_cc_target_clang" = xyes ; then + TARGET_CFLAGS="$TARGET_CFLAGS -fPIC" +elif [ x"$pic_possible" = xyes ]; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-PIC" +fi +# Don't generate SVR4-style position-independent code for MIPS64. +if test x$target_cpu = xmips64el ; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-abicalls" + TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-abicalls" +fi] + +CFLAGS="$TARGET_CFLAGS" + +# Smashing stack protector. +grub_CHECK_STACK_PROTECTOR +# Need that, because some distributions ship compilers that include +# `-fstack-protector' in the default specs. +if test "x$ssp_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector" +fi + +CFLAGS="$TARGET_CFLAGS" + +grub_CHECK_STACK_ARG_PROBE +# Cygwin's GCC uses alloca() to probe the stackframe on static +# stack allocations above some threshold. +if test x"$sap_possible" = xyes; then + TARGET_CFLAGS="$TARGET_CFLAGS -mno-stack-arg-probe" +fi + +CFLAGS="$TARGET_CFLAGS" + +# -mno-unaligned-access -mstrict-align +if test "$target_cpu" = arm; then + AC_CACHE_CHECK([for compile options to get strict alignment], [grub_cv_target_cc_strict_align], [ + grub_cv_target_cc_strict_align= + for arg in -mno-unaligned-access "-Xclang -mstrict-align" -mstrict-align; do + CFLAGS="$TARGET_CFLAGS $arg -Werror" + LDFLAGS="$TARGET_LDFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [flag=1], [flag=0]) + if test x"$flag" = x1; then + grub_cv_target_cc_strict_align="$arg" + break + fi + done]) + + TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_strict_align" + if test x"$grub_cv_target_cc_strict_align" = x"-Xclang -mstrict-align"; then + TARGET_LDFLAGS="$TARGET_LDFLAGS -Qunused-arguments" + fi + AC_CACHE_CHECK([if compiler generates unaligned accesses], [grub_cv_cc_target_emits_unaligned], + [CFLAGS="$TARGET_CFLAGS" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [[ +#ifdef __ARM_FEATURE_UNALIGNED +#error "unaligned" +#endif + ]])], + [grub_cv_cc_target_emits_unaligned=no], [grub_cv_cc_target_emits_unaligned=yes])]) + if test x$grub_cv_cc_target_emits_unaligned = xyes; then + AC_MSG_ERROR([compiler generates unaligned accesses]) + fi +fi + +# Set them to their new values for the tests below. +CC="$TARGET_CC" +if test x"$platform" = xemu ; then +CFLAGS="$TARGET_CFLAGS -Wno-error" +elif test "x$TARGET_APPLE_LINKER" = x1 ; then +CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" +else +CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" +fi +CPPFLAGS="$TARGET_CPPFLAGS" + +grub_ASM_USCORE +if test "x$TARGET_APPLE_LINKER" = x0 && test x"$platform" != xemu; then +if test x$grub_cv_asm_uscore = xyes; then +DEFSYM="-Wl,--defsym,_abort=_main -Wl,--defsym,__main=_main" +else +DEFSYM="-Wl,--defsym,abort=main -Wl,--defsym,_main=main -Wl,--defsym,__main=main" +fi +CFLAGS="$TARGET_CFLAGS -nostdlib $DEFSYM" +fi + +# Check for libgcc symbols +if test x"$platform" = xemu; then +AC_CHECK_FUNCS(__udivsi3 __umodsi3 __divsi3 __modsi3 __divdi3 __moddi3 __udivdi3 __umoddi3 __ctzdi2 __ctzsi2 __aeabi_uidiv __aeabi_uidivmod __aeabi_idiv __aeabi_idivmod __aeabi_ulcmp __muldi3 __aeabi_lmul __aeabi_memcpy __aeabi_memcpy4 __aeabi_memcpy8 __aeabi_memclr __aeabi_memclr4 __aeabi_memclr8 __aeabi_memset __aeabi_lasr __aeabi_llsl __aeabi_llsr _restgpr_14_x __ucmpdi2 __ashldi3 __ashrdi3 __lshrdi3 __bswapsi2 __bswapdi2 __bzero __register_frame_info __deregister_frame_info ___chkstk_ms __chkstk_ms) +fi + +if test "x$TARGET_APPLE_LINKER" = x1 ; then +CFLAGS="$TARGET_CFLAGS -nostdlib -static" +else +CFLAGS="$TARGET_CFLAGS -nostdlib" +fi +LIBS="" + +# Defined in aclocal.m4. +grub_PROG_TARGET_CC +if test "x$TARGET_APPLE_LINKER" != x1 ; then +grub_PROG_OBJCOPY_ABSOLUTE +fi +grub_PROG_LD_BUILD_ID_NONE +if test "x$target_cpu" = xi386; then + if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then + if test ! -z "$TARGET_IMG_LDSCRIPT"; then + # Check symbols provided by linker script. + CFLAGS="$TARGET_CFLAGS -nostdlib ${TARGET_IMG_LDFLAGS_AC} ${TARGET_IMG_BASE_LDOPT},0x8000" + fi + grub_CHECK_BSS_START_SYMBOL + grub_CHECK_END_SYMBOL + fi + CFLAGS="$TARGET_CFLAGS" +fi + +grub_PROG_NM_WORKS +grub_PROG_NM_MINUS_P +grub_PROG_NM_DEFINED_ONLY +AC_SUBST(TARGET_NMFLAGS_MINUS_P) +AC_SUBST(TARGET_NMFLAGS_DEFINED_ONLY) + +if test "$platform" != emu; then +AC_CACHE_CHECK([whether -nostdinc -isystem works], [grub_cv_cc_isystem], [ + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$TARGET_CPPFLAGS -nostdlib -nostdinc -isystem `$TARGET_CC -print-file-name=include`" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_cc_isystem=yes], + [grub_cv_cc_isystem=no]) + CPPFLAGS="$SAVED_CPPFLAGS" +]) + +if test x"$grub_cv_cc_isystem" = xyes ; then + TARGET_CPPFLAGS="$TARGET_CPPFLAGS -nostdinc -isystem `$TARGET_CC -print-file-name=include`" +fi +fi + +AC_CACHE_CHECK([whether -Wtrampolines work], [grub_cv_cc_wtrampolines], [ + CFLAGS="$TARGET_CFLAGS -Wtrampolines -Werror" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +int va_arg_func (int fixed, va_list args);]], [[]])], + [grub_cv_cc_wtrampolines=yes], + [grub_cv_cc_wtrampolines=no]) +]) + +if test x"$grub_cv_cc_wtrampolines" = xyes ; then + TARGET_CFLAGS="$TARGET_CFLAGS -Wtrampolines" +fi + +# Restore the flags. +CC="$tmp_CC" +CFLAGS="$tmp_CFLAGS" +CPPFLAGS="$tmp_CPPFLAGS" +LDFLAGS="$tmp_LDFLAGS" +LIBS="$tmp_LIBS" + +# +# Check for options. +# + +# Memory manager debugging. +AC_ARG_ENABLE([mm-debug], + AS_HELP_STRING([--enable-mm-debug], + [include memory manager debugging]), + [AC_DEFINE([MM_DEBUG], [1], + [Define to 1 if you enable memory manager debugging.])]) + +AC_ARG_ENABLE([cache-stats], + AS_HELP_STRING([--enable-cache-stats], + [enable disk cache statistics collection])) + +if test x$enable_cache_stats = xyes; then + DISK_CACHE_STATS=1 +else + DISK_CACHE_STATS=0 +fi +AC_SUBST([DISK_CACHE_STATS]) + +AC_ARG_ENABLE([boot-time], + AS_HELP_STRING([--enable-boot-time], + [enable boot time statistics collection])) + +if test x$enable_boot_time = xyes; then + BOOT_TIME_STATS=1 +else + BOOT_TIME_STATS=0 +fi +AC_SUBST([BOOT_TIME_STATS]) + +AC_ARG_ENABLE([grub-emu-sdl], + [AS_HELP_STRING([--enable-grub-emu-sdl], + [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) + +AC_ARG_ENABLE([grub-emu-pci], + [AS_HELP_STRING([--enable-grub-emu-pci], + [build and install the `grub-emu' debugging utility with PCI support (potentially dangerous) (default=no)])]) + +if test "$platform" = emu; then + +if test x"$enable_grub_emu_sdl" = xno ; then + grub_emu_sdl_excuse="explicitly disabled" +fi +[if [ x"$grub_emu_sdl_excuse" = x ]; then + # Check for libSDL libraries.] +AC_CHECK_LIB([SDL], [SDL_Init], [LIBSDL="-lSDL"], + [grub_emu_sdl_excuse=["libSDL libraries are required to build \`grub-emu' with SDL support"]]) + AC_SUBST([LIBSDL]) +[fi] + +[if [ x"$grub_emu_sdl_excuse" = x ]; then + # Check for headers.] + AC_CHECK_HEADERS([SDL/SDL.h], [], + [grub_emu_sdl_excuse=["libSDL header file is required to build \`grub-emu' with SDL support"]]) +[fi] + +if test x"enable_grub_emu_sdl" = xyes && test x"$grub_emu_sdl_excuse" != x ; then + AC_MSG_ERROR([SDL support for grub-emu was explicitly requested but can't be compiled ($grub_emu_sdl_excuse)]) +fi +if test x"$grub_emu_sdl_excuse" = x ; then +enable_grub_emu_sdl=yes +else +enable_grub_emu_sdl=no +fi + +if test x"$enable_grub_emu_pci" != xyes ; then + grub_emu_pci_excuse="not enabled" +fi + +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for libpci libraries.] + AC_CHECK_LIB([pciaccess], [pci_system_init], [LIBPCIACCESS="-lpciaccess"], + [grub_emu_pci_excuse=["need libpciaccess library"]]) + AC_SUBST([LIBPCIACCESS]) +[fi] +[if [ x"$grub_emu_pci_excuse" = x ]; then + # Check for headers.] + AC_CHECK_HEADERS([pciaccess.h], [], + [grub_emu_pci_excuse=["need libpciaccess headers"]]) +[fi] + +if test x"$grub_emu_pci_excuse" = x ; then +enable_grub_emu_pci=yes +else + +enable_grub_emu_pci=no +fi + +AC_SUBST([enable_grub_emu_sdl]) +AC_SUBST([enable_grub_emu_pci]) + +else + +# Ignore --enable-emu-* if platform is not emu +enable_grub_emu_sdl=no +enable_grub_emu_pci=no +fi + +AC_ARG_ENABLE([grub-mkfont], + [AS_HELP_STRING([--enable-grub-mkfont], + [build and install the `grub-mkfont' utility (default=guessed)])]) +if test x"$enable_grub_mkfont" = xno ; then + grub_mkfont_excuse="explicitly disabled" +fi + +unset ac_cv_header_ft2build_h + +if test x"$grub_mkfont_excuse" = x ; then + # Check for freetype libraries. + PKG_CHECK_MODULES([FREETYPE], [freetype2], [ + SAVED_CPPFLAGS="$CPPFLAGS" + SAVED_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $FREETYPE_CFLAGS" + LIBS="$LIBS $FREETYPE_LIBS" + AC_CHECK_HEADERS([ft2build.h], [], + [grub_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], + [grub_mkfont_excuse=["freetype2 library unusable"]]) + CPPFLAGS="$SAVED_CPPFLAGS" + LIBS="$SAVED_LIBS" + ], [grub_mkfont_excuse=["need freetype2 library"]]) +fi + +if test x"$enable_grub_mkfont" = xyes && test x"$grub_mkfont_excuse" != x ; then + AC_MSG_ERROR([grub-mkfont was explicitly requested but can't be compiled ($grub_mkfont_excuse)]) +fi +if test x"$grub_mkfont_excuse" = x ; then +enable_grub_mkfont=yes +else +enable_grub_mkfont=no +fi +AC_SUBST([enable_grub_mkfont]) + +SAVED_CC="$CC" +SAVED_CPP="$CPP" +SAVED_CFLAGS="$CFLAGS" +SAVED_CPPFLAGS="$CPPFLAGS" +SAVED_LDFLAGS="$LDFLAGS" +CC="$BUILD_CC" +CPP="$BUILD_CPP" +CFLAGS="$BUILD_CFLAGS" +CPPFLAGS="$BUILD_CPPFLAGS" +LDFLAGS="$BUILD_LDFAGS" + +unset ac_cv_c_bigendian +unset ac_cv_header_ft2build_h + +AC_COMPUTE_INT([BUILD_SIZEOF_VOID_P], [sizeof (void *)]) +AC_COMPUTE_INT([BUILD_SIZEOF_LONG], [sizeof (long)]) +AC_C_BIGENDIAN([BUILD_WORDS_BIGENDIAN=1], [BUILD_WORDS_BIGENDIAN=0], [BUILD_WORDS_BIGENDIAN=err], [BUILD_WORDS_BIGENDIAN=err]) + +if test x$BUILD_WORDS_BIGENDIAN = xerr ; then + AC_MSG_ERROR([couldnt determine build endianness]) +fi + +AC_SUBST([BUILD_SIZEOF_LONG]) +AC_SUBST([BUILD_SIZEOF_VOID_P]) +AC_SUBST([BUILD_WORDS_BIGENDIAN]) + +if test x"$grub_build_mkfont_excuse" = x ; then + # Check for freetype libraries. + SAVED_PKG_CONFIG="$PKG_CONFIG" + test -z "$BUILD_PKG_CONFIG" || PKG_CONFIG="$BUILD_PKG_CONFIG" + PKG_CHECK_MODULES([BUILD_FREETYPE], [freetype2], [ + SAVED_CPPFLAGS_2="$CPPFLAGS" + SAVED_LIBS="$LIBS" + CPPFLAGS="$CPPFLAGS $BUILD_FREETYPE_CFLAGS" + LIBS="$LIBS $BUILD_FREETYPE_LIBS" + AC_CHECK_HEADERS([ft2build.h], [], + [grub_build_mkfont_excuse=["need freetype2 headers"]]) + AC_LINK_IFELSE([AC_LANG_CALL([], [FT_Load_Glyph])], [], + [grub_build_mkfont_excuse=["freetype2 library unusable"]]) + LIBS="$SAVED_LIBS" + CPPFLAGS="$SAVED_CPPFLAGS_2" + ], [grub_build_mkfont_excuse=["need freetype2 library"]]) + PKG_CONFIG="$SAVED_PKG_CONFIG" +fi + +if test x"$enable_build_grub_mkfont" = xyes && test x"$grub_build_mkfont_excuse" != x ; then + AC_MSG_ERROR([build-grub-mkfont was explicitly requested but can't be compiled ($grub_build_mkfont_excuse)]) +fi +if test x"$grub_build_mkfont_excuse" = x ; then + enable_build_grub_mkfont=yes +else + enable_build_grub_mkfont=no +fi +if test x"$enable_build_grub_mkfont" = xno && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then + if test x"$grub_build_mkfont_excuse" = x ; then + AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont]) + else + AC_MSG_ERROR([qemu, coreboot and loongson ports need build-time grub-mkfont ($grub_build_mkfont_excuse)]) + fi +fi + +CC="$SAVED_CC" +CPP="$SAVED_CPP" +CFLAGS="$SAVED_CFLAGS" +CPPFLAGS="$SAVED_CPPFLAGS" +LDFLAGS="$SAVED_LDFLAGS" + + +DJVU_FONT_SOURCE= + +starfield_excuse= + +AC_ARG_ENABLE([grub-themes], + [AS_HELP_STRING([--enable-grub-themes], + [build and install GRUB themes (default=guessed)])]) +if test x"$enable_grub_themes" = xno ; then + starfield_excuse="explicitly disabled" +fi + +if test x"$starfield_excuse" = x && test x"$enable_build_grub_mkfont" = xno ; then + starfield_excuse="No build-time grub-mkfont" +fi + +if test x"$starfield_excuse" = x; then + for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do + for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype; do + if test -f "$dir/DejaVuSans.$ext"; then + DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext" + break 2 + fi + done + done + + if test "x$DJVU_FONT_SOURCE" = x; then + starfield_excuse="No DejaVu found" + fi +fi + +if test x"$enable_grub_themes" = xyes && test x"$starfield_excuse" != x; then + AC_MSG_ERROR([themes were explicitly requested but requirements are not satisfied ($starfield_excuse)]) +fi + +AC_SUBST([DJVU_FONT_SOURCE]) + +FONT_SOURCE= + +for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do + for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/unifont /usr/share/fonts/uni /usr/share/fonts/truetype/unifont /usr/share/fonts/misc; do + if test -f "$dir/unifont.$ext"; then + md5="$(md5sum "$dir/unifont.$ext"|awk '{ print $1; }')" + # PCF and BDF from version 6.3 isn't hanled properly by libfreetype. + if test "$md5" = 0a54834d2788c83886a3e1785a6a1e61 || test "$md5" = 28f2565c7a41d8d407e2551159385edb || test "$md5" = dae5e588461b3b92b87b6ffee734f936 || test "$md5" = 4a3d687aa5bb329ed05f4263a1016791 ; then + continue + fi + FONT_SOURCE="$dir/unifont.$ext" + break 2 + fi + done +done + +if test x"$enable_build_grub_mkfont" = xno ; then + FONT_SOURCE= +fi + +if test "x$FONT_SOURCE" = x && ( test "x$platform" = xqemu || test "x$platform" = xloongson || test "x$platform" = xqemu_mips || test "x$platform" = xcoreboot ); then + if test x"$grub_build_mkfont_excuse" = x ; then + AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont]) + else + AC_MSG_ERROR([qemu, coreboot and loongson ports need unifont ($grub_build_mkfont_excuse)]) + fi +fi + +AC_SUBST([FONT_SOURCE]) + +if test x"$FONT_SOURCE" = x && test x"$DJVU_FONT_SOURCE" = x && test x"$grub_build_mkfont_excuse" = x; then + grub_build_mkfont_excuse="no fonts" +fi + + +AC_ARG_ENABLE([grub-mount], + [AS_HELP_STRING([--enable-grub-mount], + [build and install the `grub-mount' utility (default=guessed)])]) +if test x"$enable_grub_mount" = xno ; then + grub_mount_excuse="explicitly disabled" +fi + +if test x"$grub_mount_excuse" = x ; then + AC_CHECK_LIB([fuse], [fuse_main_real], [], + [grub_mount_excuse="need FUSE library"]) +fi + +if test x"$grub_mount_excuse" = x ; then + # Check for fuse headers. + SAVED_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS -DFUSE_USE_VERSION=26" + AC_CHECK_HEADERS([fuse/fuse.h], [], + [grub_mount_excuse=["need FUSE headers"]]) + CPPFLAGS="$SAVED_CPPFLAGS" +fi + +if test x"$enable_grub_mount" = xyes && test x"$grub_mount_excuse" != x ; then + AC_MSG_ERROR([grub-mount was explicitly requested but can't be compiled ($grub_mount_excuse)]) +fi +if test x"$grub_mount_excuse" = x ; then +enable_grub_mount=yes +else +enable_grub_mount=no +fi +AC_SUBST([enable_grub_mount]) + +AC_ARG_ENABLE([device-mapper], + [AS_HELP_STRING([--enable-device-mapper], + [enable Linux device-mapper support (default=guessed)])]) +if test x"$enable_device_mapper" = xno ; then + device_mapper_excuse="explicitly disabled" +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper header. + AC_CHECK_HEADER([libdevmapper.h], [], + [device_mapper_excuse="need libdevmapper header"]) +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_task_create], [], + [device_mapper_excuse="need devmapper library"]) +fi + +if test x"$device_mapper_excuse" = x ; then + # Check for device-mapper library. + AC_CHECK_LIB([devmapper], [dm_log_with_errno_init], + [], + [device_mapper_excuse="need devmapper library"]) +fi + +if test x"$device_mapper_excuse" = x ; then + LIBDEVMAPPER="-ldevmapper" + AC_DEFINE([HAVE_DEVICE_MAPPER], [1], + [Define to 1 if you have the devmapper library.]) +fi + +AC_SUBST([LIBDEVMAPPER]) + +LIBGEOM= +if test x$host_kernel = xkfreebsd; then + AC_CHECK_LIB([geom], [geom_gettree], [], + [AC_MSG_ERROR([Your platform requires libgeom])]) + LIBGEOM="-lgeom" +fi + +AC_SUBST([LIBGEOM]) + +AC_ARG_ENABLE([liblzma], + [AS_HELP_STRING([--enable-liblzma], + [enable liblzma integration (default=guessed)])]) +if test x"$enable_liblzma" = xno ; then + liblzma_excuse="explicitly disabled" +fi + +if test x"$liblzma_excuse" = x ; then +AC_CHECK_LIB([lzma], [lzma_code], + [],[liblzma_excuse="need lzma library"]) +fi +if test x"$liblzma_excuse" = x ; then +AC_CHECK_HEADER([lzma.h], [], [liblzma_excuse="need lzma header"]) +fi + +if test x"$enable_liblzma" = xyes && test x"$liblzma_excuse" != x ; then + AC_MSG_ERROR([liblzma support was explicitly requested but requirements are not satisfied ($liblzma_excuse)]) +fi + + +if test x"$liblzma_excuse" = x ; then + LIBLZMA="-llzma" + AC_DEFINE([USE_LIBLZMA], [1], + [Define to 1 if you have the LZMA library.]) +fi + +AC_SUBST([LIBLZMA]) + +AC_ARG_ENABLE([libzfs], + [AS_HELP_STRING([--enable-libzfs], + [enable libzfs integration (default=guessed)])]) +if test x"$enable_libzfs" = xno ; then + libzfs_excuse="explicitly disabled" +fi + +if test x"$libzfs_excuse" = x ; then + # Only check for system headers if libzfs support has not been disabled. + AC_CHECK_HEADERS(libzfs.h libnvpair.h) +fi + +if test x"$libzfs_excuse" = x ; then + AC_CHECK_LIB([zfs], [libzfs_init], + [], + [libzfs_excuse="need zfs library"]) +fi + +if test x"$libzfs_excuse" = x ; then + AC_CHECK_LIB([nvpair], [nvlist_lookup_string], + [], + [libzfs_excuse="need nvpair library"]) +fi + +if test x"$enable_libzfs" = xyes && test x"$libzfs_excuse" != x ; then + AC_MSG_ERROR([libzfs support was explicitly requested but requirements are not satisfied ($libzfs_excuse)]) +fi + +if test x"$libzfs_excuse" = x ; then + # We need both libzfs and libnvpair for a successful build. + LIBZFS="-lzfs" + AC_DEFINE([HAVE_LIBZFS], [1], + [Define to 1 if you have the ZFS library.]) + LIBNVPAIR="-lnvpair" + AC_DEFINE([HAVE_LIBNVPAIR], [1], + [Define to 1 if you have the NVPAIR library.]) +fi + +AC_SUBST([LIBZFS]) +AC_SUBST([LIBNVPAIR]) + +LIBS="" + +AC_SUBST([FONT_SOURCE]) +AS_IF([test x$target_cpu = xi386 -a x$platform = xqemu], + [AC_SUBST([GRUB_BOOT_MACHINE_LINK_ADDR], 0xffe00)]) + +AC_SUBST(HAVE_ASM_USCORE) +AC_SUBST(BSS_START_SYMBOL) +AC_SUBST(END_SYMBOL) +AC_SUBST(PACKAGE) +AC_SUBST(VERSION) + +AC_ARG_ENABLE([werror], + [AS_HELP_STRING([--disable-werror], + [do not use -Werror when building GRUB])]) +if test x"$enable_werror" != xno ; then + TARGET_CFLAGS="$TARGET_CFLAGS -Werror" + HOST_CFLAGS="$HOST_CFLAGS -Werror" +fi + +TARGET_CPP="$TARGET_CC -E" +TARGET_CCAS=$TARGET_CC + +# Includes which include make-time substitutions. They must come last +# as to avoid executing top_builddir in shell. +HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" +TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" +TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include" + +GRUB_TARGET_CPU="${target_cpu}" +GRUB_PLATFORM="${platform}" + +AC_SUBST(GRUB_TARGET_CPU) +AC_SUBST(GRUB_PLATFORM) + +AC_SUBST(TARGET_OBJCONV) +AC_SUBST(TARGET_CPP) +AC_SUBST(TARGET_CCAS) +AC_SUBST(TARGET_OBJ2ELF) +AC_SUBST(TARGET_MODULE_FORMAT) +AC_SUBST(TARGET_CC_VERSION) + +AC_SUBST(TARGET_CFLAGS) +AC_SUBST(TARGET_LDFLAGS) +AC_SUBST(TARGET_CPPFLAGS) +AC_SUBST(TARGET_CCASFLAGS) + +AC_SUBST(TARGET_IMG_LDFLAGS) +AC_SUBST(TARGET_IMG_CFLAGS) +AC_SUBST(TARGET_IMG_BASE_LDOPT) +AC_SUBST(TARGET_APPLE_LINKER) + +AC_SUBST(HOST_CFLAGS) +AC_SUBST(HOST_LDFLAGS) +AC_SUBST(HOST_CPPFLAGS) +AC_SUBST(HOST_CCASFLAGS) + +AC_SUBST(BUILD_LIBM) + +# +# Automake conditionals +# + +AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone]) +AM_CONDITIONAL([COND_emu], [test x$platform = xemu]) +AM_CONDITIONAL([COND_i386_pc], [test x$target_cpu = xi386 -a x$platform = xpc]) +AM_CONDITIONAL([COND_i386_efi], [test x$target_cpu = xi386 -a x$platform = xefi]) +AM_CONDITIONAL([COND_ia64_efi], [test x$target_cpu = xia64 -a x$platform = xefi]) +AM_CONDITIONAL([COND_i386_qemu], [test x$target_cpu = xi386 -a x$platform = xqemu]) +AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275]) +AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot]) +AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot]) +AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) +AM_CONDITIONAL([COND_i386_xen], [test x$target_cpu = xi386 -a x$platform = xxen]) +AM_CONDITIONAL([COND_i386_xen_pvh], [test x$target_cpu = xi386 -a x$platform = xxen_pvh]) +AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen]) +AM_CONDITIONAL([COND_mips64_efi], [test x$target_cpu = xmips64el -a x$platform = xefi]) +AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson]) +AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xqemu_mips]) +AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")" -a x$platform = xarc]) +AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) +AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu]) +AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) +AM_CONDITIONAL([COND_mips64el], [test x$target_cpu = xmips64el]) +AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) +AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) +AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) +AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ]) +AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot]) +AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xcoreboot]) +AM_CONDITIONAL([COND_arm_efi], [test x$target_cpu = xarm -a x$platform = xefi]) +AM_CONDITIONAL([COND_arm64], [test x$target_cpu = xarm64 ]) +AM_CONDITIONAL([COND_arm64_efi], [test x$target_cpu = xarm64 -a x$platform = xefi]) +AM_CONDITIONAL([COND_riscv32], [test x$target_cpu = xriscv32 ]) +AM_CONDITIONAL([COND_riscv64], [test x$target_cpu = xriscv64 ]) +AM_CONDITIONAL([COND_riscv32_efi], [test x$target_cpu = xriscv32 -a x$platform = xefi]) +AM_CONDITIONAL([COND_riscv64_efi], [test x$target_cpu = xriscv64 -a x$platform = xefi]) + +AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) +AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) +AM_CONDITIONAL([COND_HOST_NETBSD], [test x$host_kernel = xnetbsd]) +AM_CONDITIONAL([COND_HOST_WINDOWS], [test x$host_kernel = xwindows]) +AM_CONDITIONAL([COND_HOST_KFREEBSD], [test x$host_kernel = xkfreebsd]) +AM_CONDITIONAL([COND_HOST_XNU], [test x$host_kernel = xxnu]) +AM_CONDITIONAL([COND_HOST_ILLUMOS], [test x$host_kernel = xillumos]) + +AM_CONDITIONAL([COND_MAN_PAGES], [test x$cross_compiling = xno -a x$HELP2MAN != x]) +AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) +AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) +AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) +AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) +AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) +if test x$FONT_SOURCE != x ; then + HAVE_FONT_SOURCE=1 +else + HAVE_FONT_SOURCE=0 +fi +AC_SUBST(HAVE_FONT_SOURCE) +AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1]) +AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) +AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) +AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1]) + +AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes]) + +AM_CONDITIONAL([COND_HAVE_ASM_USCORE], [test x$HAVE_ASM_USCORE = x1]) +AM_CONDITIONAL([COND_STARFIELD], [test "x$starfield_excuse" = x]) +AM_CONDITIONAL([COND_HAVE_EXEC], [test "x$have_exec" = xy]) + +test "x$prefix" = xNONE && prefix="$ac_default_prefix" +test "x$exec_prefix" = xNONE && exec_prefix="${prefix}" +datarootdir="$(eval echo "$datarootdir")" +grub_libdir="$(eval echo "$libdir")" +grub_localedir="$(eval echo "$localedir")" +grub_datadir="$(eval echo "$datadir")" +grub_sysconfdir="$(eval echo "$sysconfdir")" +AC_DEFINE_UNQUOTED(LOCALEDIR, "$grub_localedir", [Locale dir]) +AC_DEFINE_UNQUOTED(GRUB_LIBDIR, "$grub_libdir", [Library dir]) +AC_DEFINE_UNQUOTED(GRUB_DATADIR, "$grub_datadir", [Data dir]) +AC_DEFINE_UNQUOTED(GRUB_SYSCONFDIR, "$grub_sysconfdir", [Configuration dir]) + + +# Output files. +if test "$platform" != none; then + cpudir="${target_cpu}" + if test x${cpudir} = xmips64el; then + cpudir=mips64; + elif test x${cpudir} = xmipsel; then + cpudir=mips; + fi + grub_CHECK_LINK_DIR + if test x"$link_dir" = xyes ; then + AC_CONFIG_LINKS([include/grub/cpu:include/grub/$cpudir]) + if test "$platform" != emu ; then + AC_CONFIG_LINKS([include/grub/machine:include/grub/$cpudir/$platform]) + fi + else + mkdir -p include/grub 2>/dev/null + rm -rf include/grub/cpu + cp -rp $srcdir/include/grub/$cpudir include/grub/cpu 2>/dev/null + if test "$platform" != emu ; then + rm -rf include/grub/machine + cp -rp $srcdir/include/grub/$cpudir/$platform include/grub/machine 2>/dev/null + fi + fi +else + # Just enough to stop the compiler failing with -I$(srcdir)/include. + mkdir -p include 2>/dev/null + rm -rf include/grub/cpu include/grub/machine +fi + +AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([grub-core/Makefile]) +AC_CONFIG_FILES([grub-core/lib/gnulib/Makefile]) +AC_CONFIG_FILES([po/Makefile.in]) +AC_CONFIG_FILES([docs/Makefile]) +AC_CONFIG_FILES([util/bash-completion.d/Makefile]) +AC_CONFIG_FILES([stamp-h], [echo timestamp > stamp-h]) +AC_CONFIG_FILES([config.h]) + +AC_OUTPUT +[ +echo "*******************************************************" +echo GRUB2 will be compiled with following components: +echo Platform: "$target_cpu"-"$platform" +if [ x"$platform" = xemu ]; then +if [ x"$grub_emu_sdl_excuse" = x ]; then +echo SDL support for grub-emu: Yes +else +echo SDL support for grub-emu: No "($grub_emu_sdl_excuse)" +fi +if [ x"$grub_emu_pci_excuse" = x ]; then +echo PCI support for grub-emu: Yes +else +echo PCI support for grub-emu: No "($grub_emu_pci_excuse)" +fi +fi +if test x"$device_mapper_excuse" = x ; then +echo With devmapper support: Yes +else +echo With devmapper support: No "($device_mapper_excuse)" +fi +if [ x"$enable_mm_debug" = xyes ]; then +echo With memory debugging: Yes +else +echo With memory debugging: No +fi +if [ x"$enable_cache_stats" = xyes ]; then +echo With disk cache statistics: Yes +else +echo With disk cache statistics: No +fi + +if [ x"$enable_boot_time" = xyes ]; then +echo With boot time statistics: Yes +else +echo With boot time statistics: No +fi + +if [ x"$efiemu_excuse" = x ]; then +echo efiemu runtime: Yes +else +echo efiemu runtime: No "($efiemu_excuse)" +fi +if [ x"$grub_mkfont_excuse" = x ]; then +echo grub-mkfont: Yes +else +echo grub-mkfont: No "($grub_mkfont_excuse)" +fi +if [ x"$grub_mount_excuse" = x ]; then +echo grub-mount: Yes +else +echo grub-mount: No "($grub_mount_excuse)" +fi +if [ x"$starfield_excuse" = x ]; then +echo starfield theme: Yes +echo With DejaVuSans font from $DJVU_FONT_SOURCE +else +echo starfield theme: No "($starfield_excuse)" +fi +if [ x"$libzfs_excuse" = x ]; then +echo With libzfs support: Yes +else +echo With libzfs support: No "($libzfs_excuse)" +fi +if [ x"$grub_build_mkfont_excuse" = x ]; then + echo Build-time grub-mkfont: Yes + if test "x$FONT_SOURCE" = x ; then + echo "Without unifont" + else + echo "With unifont from $FONT_SOURCE" + fi +else + echo Build-time grub-mkfont: No "($grub_build_mkfont_excuse)" + echo "Without unifont (no build-time grub-mkfont)" +fi +if test x"$liblzma_excuse" != x ; then +echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excuse)" +else +echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)" +fi +echo "*******************************************************" +] diff --git a/GRUB2/MOD_SRC/grub-2.04/gentpl.py b/GRUB2/MOD_SRC/grub-2.04/gentpl.py new file mode 100644 index 00000000..fcdb8adc --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/gentpl.py @@ -0,0 +1,909 @@ +#! /usr/bin/python +# GRUB -- GRand Unified Bootloader +# Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. +# +# GRUB 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. +# +# GRUB 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 GRUB. If not, see . + +from __future__ import print_function + +__metaclass__ = type + +from optparse import OptionParser +import re + +# +# This is the python script used to generate Makefile.*.am +# + +GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", + "i386_multiboot", "i386_ieee1275", "x86_64_efi", + "i386_xen", "x86_64_xen", "i386_xen_pvh", + "mips_loongson", "mips64_efi", "sparc64_ieee1275", + "powerpc_ieee1275", "mips_arc", "ia64_efi", + "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", + "arm_coreboot", "riscv32_efi", "riscv64_efi" ] + +GROUPS = {} + +GROUPS["common"] = GRUB_PLATFORMS[:] + +# Groups based on CPU +GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] +GROUPS["x86_64"] = [ "x86_64_efi" ] +GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] +GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] +GROUPS["mips64"] = [ "mips64_efi" ] +GROUPS["sparc64"] = [ "sparc64_ieee1275" ] +GROUPS["powerpc"] = [ "powerpc_ieee1275" ] +GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] +GROUPS["arm64"] = [ "arm64_efi" ] +GROUPS["riscv32"] = [ "riscv32_efi" ] +GROUPS["riscv64"] = [ "riscv64_efi" ] + +# Groups based on firmware +GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", "mips64_efi", + "riscv32_efi", "riscv64_efi" ] +GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] +GROUPS["uboot"] = [ "arm_uboot" ] +GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] +GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ] + +# emu is a special case so many core functionality isn't needed on this platform +GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") + +# Groups based on hardware features +GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips", + "sparc64_ieee1275", "powerpc_ieee1275"] +GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi"); +GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] +GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"] + +# If gfxterm is main output console integrate it into kernel +GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ] +GROUPS["videomodules"] = GRUB_PLATFORMS[:]; +for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) + +# Similar for terminfo +GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"]; +GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; +for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) + +# Flattened Device Trees (FDT) +GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ] + +# Needs software helpers for division +# Must match GRUB_DIVISION_IN_SOFTWARE in misc.h +GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"] +GROUPS["no_softdiv"] = GRUB_PLATFORMS[:] +for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i) + +# Miscellaneous groups scheduled to disappear in future +GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] +GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc") + +# +# Create platform => groups reverse map, where groups covering that +# platform are ordered by their sizes +# +RMAP = {} +for platform in GRUB_PLATFORMS: + # initialize with platform itself as a group + RMAP[platform] = [ platform ] + + for k in GROUPS.keys(): + v = GROUPS[k] + # skip groups that don't cover this platform + if platform not in v: continue + + bigger = [] + smaller = [] + # partition currently known groups based on their size + for group in RMAP[platform]: + if group in GRUB_PLATFORMS: smaller.append(group) + elif len(GROUPS[group]) < len(v): smaller.append(group) + else: bigger.append(group) + # insert in the middle + RMAP[platform] = smaller + [ k ] + bigger + +# +# Input +# + +# We support a subset of the AutoGen definitions file syntax. Specifically, +# compound names are disallowed; some preprocessing directives are +# disallowed (though #if/#endif are allowed; note that, like AutoGen, #if +# skips everything to the next #endif regardless of the value of the +# conditional); and shell-generated strings, Scheme-generated strings, and +# here strings are disallowed. + +class AutogenToken: + (autogen, definitions, eof, var_name, other_name, string, number, + semicolon, equals, comma, lbrace, rbrace, lbracket, rbracket) = range(14) + +class AutogenState: + (init, need_def, need_tpl, need_semi, need_name, have_name, need_value, + need_idx, need_rbracket, indx_name, have_value, done) = range(12) + +class AutogenParseError(Exception): + def __init__(self, message, path, line): + super(AutogenParseError, self).__init__(message) + self.path = path + self.line = line + + def __str__(self): + return ( + super(AutogenParseError, self).__str__() + + " at file %s line %d" % (self.path, self.line)) + +class AutogenDefinition(list): + def __getitem__(self, key): + try: + return super(AutogenDefinition, self).__getitem__(key) + except TypeError: + for name, value in self: + if name == key: + return value + + def __contains__(self, key): + for name, value in self: + if name == key: + return True + return False + + def get(self, key, default): + for name, value in self: + if name == key: + return value + else: + return default + + def find_all(self, key): + for name, value in self: + if name == key: + yield value + +class AutogenParser: + def __init__(self): + self.definitions = AutogenDefinition() + self.def_stack = [("", self.definitions)] + self.curdef = None + self.new_name = None + self.cur_path = None + self.cur_line = 0 + + @staticmethod + def is_unquotable_char(c): + return (ord(c) in range(ord("!"), ord("~") + 1) and + c not in "#,;<=>[\\]`{}?*'\"()") + + @staticmethod + def is_value_name_char(c): + return c in ":^-_" or c.isalnum() + + def error(self, message): + raise AutogenParseError(message, self.cur_file, self.cur_line) + + def read_tokens(self, f): + data = f.read() + end = len(data) + offset = 0 + while offset < end: + while offset < end and data[offset].isspace(): + if data[offset] == "\n": + self.cur_line += 1 + offset += 1 + if offset >= end: + break + c = data[offset] + if c == "#": + offset += 1 + try: + end_directive = data.index("\n", offset) + directive = data[offset:end_directive] + offset = end_directive + except ValueError: + directive = data[offset:] + offset = end + name, value = directive.split(None, 1) + if name == "if": + try: + end_if = data.index("\n#endif", offset) + new_offset = end_if + len("\n#endif") + self.cur_line += data[offset:new_offset].count("\n") + offset = new_offset + except ValueError: + self.error("#if without matching #endif") + else: + self.error("Unhandled directive '#%s'" % name) + elif c == "{": + yield AutogenToken.lbrace, c + offset += 1 + elif c == "=": + yield AutogenToken.equals, c + offset += 1 + elif c == "}": + yield AutogenToken.rbrace, c + offset += 1 + elif c == "[": + yield AutogenToken.lbracket, c + offset += 1 + elif c == "]": + yield AutogenToken.rbracket, c + offset += 1 + elif c == ";": + yield AutogenToken.semicolon, c + offset += 1 + elif c == ",": + yield AutogenToken.comma, c + offset += 1 + elif c in ("'", '"'): + s = [] + while True: + offset += 1 + if offset >= end: + self.error("EOF in quoted string") + if data[offset] == "\n": + self.cur_line += 1 + if data[offset] == "\\": + offset += 1 + if offset >= end: + self.error("EOF in quoted string") + if data[offset] == "\n": + self.cur_line += 1 + # Proper escaping unimplemented; this can be filled + # out if needed. + s.append("\\") + s.append(data[offset]) + elif data[offset] == c: + offset += 1 + break + else: + s.append(data[offset]) + yield AutogenToken.string, "".join(s) + elif c == "/": + offset += 1 + if data[offset] == "*": + offset += 1 + try: + end_comment = data.index("*/", offset) + new_offset = end_comment + len("*/") + self.cur_line += data[offset:new_offset].count("\n") + offset = new_offset + except ValueError: + self.error("/* without matching */") + elif data[offset] == "/": + try: + offset = data.index("\n", offset) + except ValueError: + pass + elif (c.isdigit() or + (c == "-" and offset < end - 1 and + data[offset + 1].isdigit())): + end_number = offset + 1 + while end_number < end and data[end_number].isdigit(): + end_number += 1 + yield AutogenToken.number, data[offset:end_number] + offset = end_number + elif self.is_unquotable_char(c): + end_name = offset + while (end_name < end and + self.is_value_name_char(data[end_name])): + end_name += 1 + if end_name < end and self.is_unquotable_char(data[end_name]): + while (end_name < end and + self.is_unquotable_char(data[end_name])): + end_name += 1 + yield AutogenToken.other_name, data[offset:end_name] + offset = end_name + else: + s = data[offset:end_name] + if s.lower() == "autogen": + yield AutogenToken.autogen, s + elif s.lower() == "definitions": + yield AutogenToken.definitions, s + else: + yield AutogenToken.var_name, s + offset = end_name + else: + self.error("Invalid input character '%s'" % c) + yield AutogenToken.eof, None + + def do_need_name_end(self, token): + if len(self.def_stack) > 1: + self.error("Definition blocks were left open") + + def do_need_name_var_name(self, token): + self.new_name = token + + def do_end_block(self, token): + if len(self.def_stack) <= 1: + self.error("Too many close braces") + new_name, parent_def = self.def_stack.pop() + parent_def.append((new_name, self.curdef)) + self.curdef = parent_def + + def do_empty_val(self, token): + self.curdef.append((self.new_name, "")) + + def do_str_value(self, token): + self.curdef.append((self.new_name, token)) + + def do_start_block(self, token): + self.def_stack.append((self.new_name, self.curdef)) + self.curdef = AutogenDefinition() + + def do_indexed_name(self, token): + self.new_name = token + + def read_definitions_file(self, f): + self.curdef = self.definitions + self.cur_line = 0 + state = AutogenState.init + + # The following transition table was reduced from the Autogen + # documentation: + # info -f autogen -n 'Full Syntax' + transitions = { + AutogenState.init: { + AutogenToken.autogen: (AutogenState.need_def, None), + }, + AutogenState.need_def: { + AutogenToken.definitions: (AutogenState.need_tpl, None), + }, + AutogenState.need_tpl: { + AutogenToken.var_name: (AutogenState.need_semi, None), + AutogenToken.other_name: (AutogenState.need_semi, None), + AutogenToken.string: (AutogenState.need_semi, None), + }, + AutogenState.need_semi: { + AutogenToken.semicolon: (AutogenState.need_name, None), + }, + AutogenState.need_name: { + AutogenToken.autogen: (AutogenState.need_def, None), + AutogenToken.eof: (AutogenState.done, self.do_need_name_end), + AutogenToken.var_name: ( + AutogenState.have_name, self.do_need_name_var_name), + AutogenToken.rbrace: ( + AutogenState.have_value, self.do_end_block), + }, + AutogenState.have_name: { + AutogenToken.semicolon: ( + AutogenState.need_name, self.do_empty_val), + AutogenToken.equals: (AutogenState.need_value, None), + AutogenToken.lbracket: (AutogenState.need_idx, None), + }, + AutogenState.need_value: { + AutogenToken.var_name: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.other_name: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.string: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.number: ( + AutogenState.have_value, self.do_str_value), + AutogenToken.lbrace: ( + AutogenState.need_name, self.do_start_block), + }, + AutogenState.need_idx: { + AutogenToken.var_name: ( + AutogenState.need_rbracket, self.do_indexed_name), + AutogenToken.number: ( + AutogenState.need_rbracket, self.do_indexed_name), + }, + AutogenState.need_rbracket: { + AutogenToken.rbracket: (AutogenState.indx_name, None), + }, + AutogenState.indx_name: { + AutogenToken.semicolon: ( + AutogenState.need_name, self.do_empty_val), + AutogenToken.equals: (AutogenState.need_value, None), + }, + AutogenState.have_value: { + AutogenToken.semicolon: (AutogenState.need_name, None), + AutogenToken.comma: (AutogenState.need_value, None), + }, + } + + for code, token in self.read_tokens(f): + if code in transitions[state]: + state, handler = transitions[state][code] + if handler is not None: + handler(token) + else: + self.error( + "Parse error in state %s: unexpected token '%s'" % ( + state, token)) + if state == AutogenState.done: + break + + def read_definitions(self, path): + self.cur_file = path + with open(path) as f: + self.read_definitions_file(f) + +defparser = AutogenParser() + +# +# Output +# + +outputs = {} + +def output(s, section=''): + if s == "": + return + outputs.setdefault(section, []) + outputs[section].append(s) + +def write_output(section=''): + for s in outputs.get(section, []): + print(s, end='') + +# +# Global variables +# + +def gvar_add(var, value): + output(var + " += " + value + "\n") + +# +# Per PROGRAM/SCRIPT variables +# + +seen_vars = set() + +def vars_init(defn, *var_list): + name = defn['name'] + + if name not in seen_target and name not in seen_vars: + for var in var_list: + output(var + " = \n", section='decl') + seen_vars.add(name) + +def var_set(var, value): + output(var + " = " + value + "\n") + +def var_add(var, value): + output(var + " += " + value + "\n") + +# +# Variable names and rules +# + +canonical_name_re = re.compile(r'[^0-9A-Za-z@_]') +canonical_name_suffix = "" + +def set_canonical_name_suffix(suffix): + global canonical_name_suffix + canonical_name_suffix = suffix + +def cname(defn): + return canonical_name_re.sub('_', defn['name'] + canonical_name_suffix) + +def rule(target, source, cmd): + if cmd[0] == "\n": + output("\n" + target + ": " + source + cmd.replace("\n", "\n\t") + "\n") + else: + output("\n" + target + ": " + source + "\n\t" + cmd.replace("\n", "\n\t") + "\n") + +# +# Handle keys with platform names as values, for example: +# +# kernel = { +# nostrip = emu; +# ... +# } +# +def platform_tagged(defn, platform, tag): + for value in defn.find_all(tag): + for group in RMAP[platform]: + if value == group: + return True + return False + +def if_platform_tagged(defn, platform, tag, snippet_if, snippet_else=None): + if platform_tagged(defn, platform, tag): + return snippet_if + elif snippet_else is not None: + return snippet_else + +# +# Handle tagged values +# +# module = { +# extra_dist = ... +# extra_dist = ... +# ... +# }; +# +def foreach_value(defn, tag, closure): + r = [] + for value in defn.find_all(tag): + r.append(closure(value)) + return ''.join(r) + +# +# Handle best matched values for a platform, for example: +# +# module = { +# cflags = '-Wall'; +# emu_cflags = '-Wall -DGRUB_EMU=1'; +# ... +# } +# +def foreach_platform_specific_value(defn, platform, suffix, nonetag, closure): + r = [] + for group in RMAP[platform]: + values = list(defn.find_all(group + suffix)) + if values: + for value in values: + r.append(closure(value)) + break + else: + for value in defn.find_all(nonetag): + r.append(closure(value)) + return ''.join(r) + +# +# Handle values from sum of all groups for a platform, for example: +# +# module = { +# common = kern/misc.c; +# emu = kern/emu/misc.c; +# ... +# } +# +def foreach_platform_value(defn, platform, suffix, closure): + r = [] + for group in RMAP[platform]: + for value in defn.find_all(group + suffix): + r.append(closure(value)) + return ''.join(r) + +def platform_conditional(platform, closure): + output("\nif COND_" + platform + "\n") + closure(platform) + output("endif\n") + +# +# Handle guarding with platform-specific "enable" keys, for example: +# +# module = { +# name = pci; +# noemu = bus/pci.c; +# emu = bus/emu/pci.c; +# emu = commands/lspci.c; +# +# enable = emu; +# enable = i386_pc; +# enable = x86_efi; +# enable = i386_ieee1275; +# enable = i386_coreboot; +# }; +# +def foreach_enabled_platform(defn, closure): + if 'enable' in defn: + for platform in GRUB_PLATFORMS: + if platform_tagged(defn, platform, "enable"): + platform_conditional(platform, closure) + else: + for platform in GRUB_PLATFORMS: + platform_conditional(platform, closure) + +# +# Handle guarding with platform-specific automake conditionals, for example: +# +# module = { +# name = usb; +# common = bus/usb/usb.c; +# noemu = bus/usb/usbtrans.c; +# noemu = bus/usb/usbhub.c; +# enable = emu; +# enable = i386; +# enable = mips_loongson; +# emu_condition = COND_GRUB_EMU_SDL; +# }; +# +def under_platform_specific_conditionals(defn, platform, closure): + output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "if " + cond + "\n")) + closure(defn, platform) + output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "endif " + cond + "\n")) + +def platform_specific_values(defn, platform, suffix, nonetag): + return foreach_platform_specific_value(defn, platform, suffix, nonetag, + lambda value: value + " ") + +def platform_values(defn, platform, suffix): + return foreach_platform_value(defn, platform, suffix, lambda value: value + " ") + +def extra_dist(defn): + return foreach_value(defn, "extra_dist", lambda value: value + " ") + +def platform_sources(defn, p): return platform_values(defn, p, "") +def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist") + +def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup") +def platform_ldadd(defn, p): return platform_specific_values(defn, p, "_ldadd", "ldadd") +def platform_dependencies(defn, p): return platform_specific_values(defn, p, "_dependencies", "dependencies") +def platform_cflags(defn, p): return platform_specific_values(defn, p, "_cflags", "cflags") +def platform_ldflags(defn, p): return platform_specific_values(defn, p, "_ldflags", "ldflags") +def platform_cppflags(defn, p): return platform_specific_values(defn, p, "_cppflags", "cppflags") +def platform_ccasflags(defn, p): return platform_specific_values(defn, p, "_ccasflags", "ccasflags") +def platform_stripflags(defn, p): return platform_specific_values(defn, p, "_stripflags", "stripflags") +def platform_objcopyflags(defn, p): return platform_specific_values(defn, p, "_objcopyflags", "objcopyflags") + +# +# Emit snippet only the first time through for the current name. +# +seen_target = set() + +def first_time(defn, snippet): + if defn['name'] not in seen_target: + return snippet + return '' + +def is_platform_independent(defn): + if 'enable' in defn: + return False + for suffix in [ "", "_nodist" ]: + template = platform_values(defn, GRUB_PLATFORMS[0], suffix) + for platform in GRUB_PLATFORMS[1:]: + if template != platform_values(defn, platform, suffix): + return False + + for suffix in [ "startup", "ldadd", "dependencies", "cflags", "ldflags", "cppflags", "ccasflags", "stripflags", "objcopyflags", "condition" ]: + template = platform_specific_values(defn, GRUB_PLATFORMS[0], "_" + suffix, suffix) + for platform in GRUB_PLATFORMS[1:]: + if template != platform_specific_values(defn, platform, "_" + suffix, suffix): + return False + for tag in [ "nostrip" ]: + template = platform_tagged(defn, GRUB_PLATFORMS[0], tag) + for platform in GRUB_PLATFORMS[1:]: + if template != platform_tagged(defn, platform, tag): + return False + + return True + +def module(defn, platform): + name = defn['name'] + set_canonical_name_suffix(".module") + + gvar_add("platform_PROGRAMS", name + ".module") + gvar_add("MODULE_FILES", name + ".module$(EXEEXT)") + + var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources") + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) + var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + + gvar_add("MOD_FILES", name + ".mod") + gvar_add("MARKER_FILES", name + ".marker") + gvar_add("CLEANFILES", name + ".marker") + output(""" +""" + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES) + $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) + grep 'MARKER' $@.new > $@; rm -f $@.new +""") + +def kernel(defn, platform): + name = defn['name'] + set_canonical_name_suffix(".exec") + gvar_add("platform_PROGRAMS", name + ".exec") + var_set(cname(defn) + "_SOURCES", platform_startup(defn, platform)) + var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(defn, platform)) + var_set(cname(defn) + "_STRIPFLAGS", "$(AM_STRIPFLAGS) $(STRIPFLAGS_KERNEL) " + platform_stripflags(defn, platform)) + var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF)") + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + + gvar_add("platform_DATA", name + ".img") + gvar_add("CLEANFILES", name + ".img") + rule(name + ".img", name + ".exec$(EXEEXT)", + if_platform_tagged(defn, platform, "nostrip", +"""if test x$(TARGET_APPLE_LINKER) = x1; then \ + $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \ + elif test ! -z '$(TARGET_OBJ2ELF)'; then \ + $(TARGET_OBJ2ELF) $< $@ || (rm -f $@; exit 1); \ + else cp $< $@; fi""", +"""if test x$(TARGET_APPLE_LINKER) = x1; then \ + $(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \ + $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \ + rm -f $@.bin; \ + elif test ! -z '$(TARGET_OBJ2ELF)'; then \ + """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \ + $(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \ + rm -f $@.bin; \ +else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \ +fi""")) + +def image(defn, platform): + name = defn['name'] + set_canonical_name_suffix(".image") + gvar_add("platform_PROGRAMS", name + ".image") + var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + "## platform nodist sources") + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(defn, platform)) + var_set(cname(defn) + "_OBJCOPYFLAGS", "$(OBJCOPYFLAGS_IMAGE) " + platform_objcopyflags(defn, platform)) + # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + + gvar_add("platform_DATA", name + ".img") + gvar_add("CLEANFILES", name + ".img") + rule(name + ".img", name + ".image$(EXEEXT)", """ +if test x$(TARGET_APPLE_LINKER) = x1; then \ + $(MACHO2IMG) $< $@; \ +else \ + $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .ARM.exidx $< $@; \ +fi +""") + +def library(defn, platform): + name = defn['name'] + set_canonical_name_suffix("") + + vars_init(defn, + cname(defn) + "_SOURCES", + "nodist_" + cname(defn) + "_SOURCES", + cname(defn) + "_CFLAGS", + cname(defn) + "_CPPFLAGS", + cname(defn) + "_CCASFLAGS") + # cname(defn) + "_DEPENDENCIES") + + if name not in seen_target: + gvar_add("noinst_LIBRARIES", name) + var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_add("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) + var_add(cname(defn) + "_CFLAGS", first_time(defn, "$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(defn, platform)) + var_add(cname(defn) + "_CPPFLAGS", first_time(defn, "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(defn, platform)) + var_add(cname(defn) + "_CCASFLAGS", first_time(defn, "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(defn, platform)) + # var_add(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + if name not in seen_target: + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + +def installdir(defn, default="bin"): + return defn.get('installdir', default) + +def manpage(defn, adddeps): + name = defn['name'] + mansection = defn['mansection'] + + output("if COND_MAN_PAGES\n") + gvar_add("man_MANS", name + "." + mansection) + rule(name + "." + mansection, name + " " + adddeps, """ +chmod a+x """ + name + """ +PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """ +""") + gvar_add("CLEANFILES", name + "." + mansection) + output("endif\n") + +def program(defn, platform, test=False): + name = defn['name'] + set_canonical_name_suffix("") + + if 'testcase' in defn: + gvar_add("check_PROGRAMS", name) + gvar_add("TESTS", name) + else: + var_add(installdir(defn) + "_PROGRAMS", name) + if 'mansection' in defn: + manpage(defn, "") + + var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) + var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) + var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) + var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(defn, platform)) + var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(defn, platform)) + var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(defn, platform)) + var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(defn, platform)) + # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) + + gvar_add("dist_noinst_DATA", extra_dist(defn)) + gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") + gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") + +def data(defn, platform): + var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform)) + gvar_add("dist_noinst_DATA", extra_dist(defn)) + +def transform_data(defn, platform): + name = defn['name'] + + var_add(installdir(defn) + "_DATA", name) + + rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ +(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- +chmod a+x """ + name + """ +""") + + gvar_add("CLEANFILES", name) + gvar_add("EXTRA_DIST", extra_dist(defn)) + gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) + +def script(defn, platform): + name = defn['name'] + + if 'testcase' in defn: + gvar_add("check_SCRIPTS", name) + gvar_add ("TESTS", name) + else: + var_add(installdir(defn) + "_SCRIPTS", name) + if 'mansection' in defn: + manpage(defn, "grub-mkconfig_lib") + + rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ +(for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- +chmod a+x """ + name + """ +""") + + gvar_add("CLEANFILES", name) + gvar_add("EXTRA_DIST", extra_dist(defn)) + gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) + +def rules(target, closure): + seen_target.clear() + seen_vars.clear() + + for defn in defparser.definitions.find_all(target): + if is_platform_independent(defn): + under_platform_specific_conditionals(defn, GRUB_PLATFORMS[0], closure) + else: + foreach_enabled_platform( + defn, + lambda p: under_platform_specific_conditionals(defn, p, closure)) + # Remember that we've seen this target. + seen_target.add(defn['name']) + +parser = OptionParser(usage="%prog DEFINITION-FILES") +_, args = parser.parse_args() + +for arg in args: + defparser.read_definitions(arg) + +rules("module", module) +rules("kernel", kernel) +rules("image", image) +rules("library", library) +rules("program", program) +rules("script", script) +rules("data", data) +rules("transform_data", transform_data) + +write_output(section='decl') +write_output() diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am new file mode 100644 index 00000000..d84c2ef6 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.am @@ -0,0 +1,507 @@ +AUTOMAKE_OPTIONS = subdir-objects -Wno-portability + +DEPDIR=.deps-core + +include $(top_srcdir)/conf/Makefile.common + +CC=$(TARGET_CC) +CPP=$(TARGET_CC) +CCAS=$(TARGET_CC) +RANLIB=$(TARGET_RANLIB) +STRIP=$(TARGET_STRIP) + +MACHO2IMG=$(top_builddir)/grub-macho2img + +AM_CFLAGS = $(TARGET_CFLAGS) +AM_LDFLAGS = $(TARGET_LDFLAGS) +AM_CPPFLAGS = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT) +AM_CCASFLAGS = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT) + +CFLAGS_PROGRAM += $(CFLAGS_PLATFORM) +LDFLAGS_PROGRAM += $(LDFLAGS_PLATFORM) +CPPFLAGS_PROGRAM += $(CPPFLAGS_PLATFORM) +CCASFLAGS_PROGRAM += $(CCASFLAGS_PLATFORM) + +CFLAGS_LIBRARY += $(CFLAGS_PLATFORM) -fno-builtin +CPPFLAGS_LIBRARY += $(CPPFLAGS_PLATFORM) +CCASFLAGS_LIBRARY += $(CCASFLAGS_PLATFORM) + +build-grub-pep2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=64 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pep2elf\" $^ +CLEANFILES += build-grub-pep2elf$(BUILD_EXEEXT) + +build-grub-pe2elf$(BUILD_EXEEXT): $(top_srcdir)/util/grub-pe2elf.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_TARGET_WORDSIZE=32 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-pe2elf\" $^ +CLEANFILES += build-grub-pe2elf$(BUILD_EXEEXT) + +# gentrigtables +gentrigtables$(BUILD_EXEEXT): gentrigtables.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) $< $(BUILD_LIBM) +CLEANFILES += gentrigtables$(BUILD_EXEEXT) + +build-grub-module-verifier$(BUILD_EXEEXT): $(top_srcdir)/util/grub-module-verifier.c $(top_srcdir)/util/grub-module-verifier32.c $(top_srcdir)/util/grub-module-verifier64.c $(top_srcdir)/grub-core/kern/emu/misc.c $(top_srcdir)/util/misc.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(BUILD_LDFLAGS) -DGRUB_BUILD=1 -DGRUB_UTIL=1 -DGRUB_BUILD_PROGRAM_NAME=\"build-grub-module-verifier\" $^ +CLEANFILES += build-grub-module-verifier$(BUILD_EXEEXT) + +# trigtables.c +trigtables.c: gentrigtables$(BUILD_EXEEXT) gentrigtables.c $(top_srcdir)/configure.ac + ./gentrigtables$(BUILD_EXEEXT) > $@ +CLEANFILES += trigtables.c + +# XXX Use Automake's LEX & YACC support +grub_script.tab.h: script/parser.y + $(YACC) -d -p grub_script_yy -b grub_script $< +grub_script.tab.c: grub_script.tab.h +CLEANFILES += grub_script.tab.c grub_script.tab.h + +# For the lexer. +grub_script.yy.h: script/yylex.l + $(LEX) -o grub_script.yy.c --header-file=grub_script.yy.h $< +grub_script.yy.c: grub_script.yy.h + +rs_decoder.h: $(srcdir)/lib/reed_solomon.c + $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) -Os -I$(top_builddir) -S -DSTANDALONE -o $@ $< -g0 -mregparm=3 -ffreestanding + +CLEANFILES += grub_script.yy.c grub_script.yy.h + +include $(srcdir)/Makefile.core.am + +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dl.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/list.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/misc.h +if COND_emu +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt-emu.h +else +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/compiler-rt.h +endif +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm_private.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/net.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/memory.h + +if COND_i386_pc +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pxe.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +endif + +if COND_i386_xen_pvh +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/int.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h +endif + +if COND_i386_efi +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h +endif + +if COND_i386_coreboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/coreboot/lbio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_i386_multiboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_i386_qemu +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +endif + +if COND_i386_ieee1275 +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +endif + +if COND_i386_xen +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/xen/hypercall.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +endif + +if COND_x86_64_xen +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/xen.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/x86_64/xen/hypercall.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +endif + +if COND_x86_64_efi +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/pmtimer.h +endif + +if COND_ia64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/cpu/kernel.h +endif + +if COND_mips_arc +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arc/arc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +endif + +if COND_mips_qemu_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_mips_loongson +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/time.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cs5536.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/pci.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/serial.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/loader.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_mips_qemu_mips +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h +endif + +if COND_mips64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/loongson.h +endif + +if COND_powerpc_ieee1275 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_sparc64_ieee1275 +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sparc64/ieee1275/ieee1275.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +endif + +if COND_arm_uboot +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +endif + +if COND_arm_coreboot +KERNEL_HEADER_FILES += $(top_builddir)/include/grub/keyboard_layouts.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/video_fb.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/gfxterm.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/font.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/dma.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/coreboot/kernel.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdtbus.h +endif + +if COND_arm_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_arm64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_riscv32_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_riscv64_efi +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +endif + +if COND_emu +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h +if COND_GRUB_EMU_SDL +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h +endif +if COND_GRUB_EMU_PCI +KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/libpciaccess.h +endif +endif + +symlist.h: $(top_builddir)/config.h $(KERNEL_HEADER_FILES) + @list='$^'; \ + for p in $$list; do \ + echo "#include <$$p>" >> $@ || (rm -f $@; exit 1); \ + done +CLEANFILES += symlist.h +BUILT_SOURCES += symlist.h + +symlist.c: symlist.h gensymlist.sh + $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) -DGRUB_SYMBOL_GENERATOR=1 symlist.h > symlist.p || (rm -f symlist.p; exit 1) + cat symlist.p | $(SHELL) $(srcdir)/gensymlist.sh $(top_builddir)/config.h $(KERNEL_HEADER_FILES) >$@ || (rm -f $@; exit 1) + rm -f symlist.p +CLEANFILES += symlist.c +BUILT_SOURCES += symlist.c + +if COND_HAVE_ASM_USCORE +ASM_PREFIX=_ +else +ASM_PREFIX= +endif + +noinst_DATA += kernel_syms.lst + +kernel_syms.lst: $(KERNEL_HEADER_FILES) $(top_builddir)/config.h + $(TARGET_CPP) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) $(CPPFLAGS) $(CFLAGS) -DGRUB_SYMBOL_GENERATOR=1 $^ >kernel_syms.input + cat kernel_syms.input | grep -v '^#' | sed -n \ + -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '"$(ASM_PREFIX)"'\1/;p;}' \ + | sort -u >$@ + rm -f kernel_syms.input +CLEANFILES += kernel_syms.lst + +if COND_emu +kern/emu/grub_emu-main.$(OBJEXT):grub_emu_init.h +grub_emu-grub_emu_init.$(OBJEXT):grub_emu_init.h +kern/emu/grub_emu_dyn-main.$(OBJEXT):grub_emu_init.h +grub_emu_dyn-grub_emu_init.$(OBJEXT):grub_emu_init.h + +grub_emu_init.h: genemuinitheader.sh $(MODULE_FILES) + rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinitheader.sh $(TARGET_NM) > $@ +CLEANFILES += grub_emu_init.h + +grub_emu_init.c: grub_emu_init.h genemuinit.sh $(MODULE_FILES) + rm -f $@; echo $(MODULE_FILES) | sh $(srcdir)/genemuinit.sh $(TARGET_NM) > $@ +CLEANFILES += grub_emu_init.c +endif + +# List files + +fs.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += fs.lst +CLEANFILES += fs.lst + +command.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/EXTCOMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/P1COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/*\1: $$b/;p;}" \ + -e "/COMMAND_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += command.lst +CLEANFILES += command.lst + +partmap.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + if grep 'PARTMAP_LIST_MARKER' $$pp >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += partmap.lst +CLEANFILES += partmap.lst + +terminal.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/INPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ + -e "/OUTPUT_TERMINAL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += terminal.lst +CLEANFILES += terminal.lst + +fdt.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/i\1: $$b/;p;}" \ + -e "/FDT_DRIVER_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/o\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += fdt.lst +CLEANFILES += fdt.lst + +parttool.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + sed -n \ + -e "/PARTTOOL_LIST_MARKER *( *\"/{s/.*( *\"\([^\"]*\)\".*/\1: $$b/;p;}" $$pp; \ + done) | sort -u > $@ +platform_DATA += parttool.lst +CLEANFILES += parttool.lst + +video.lst: $(MARKER_FILES) + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + if grep 'VIDEO_LIST_MARKER' $$pp >/dev/null 2>&1; then \ + echo $$b; \ + fi; \ + done) | sort -u > $@ +platform_DATA += video.lst +CLEANFILES += video.lst + +# but, crypto.lst is simply copied +crypto.lst: $(srcdir)/lib/libgcrypt-grub/cipher/crypto.lst + cp $^ $@ +platform_DATA += crypto.lst +CLEANFILES += crypto.lst + +syminfo.lst: gensyminfo.sh kernel_syms.lst $(MODULE_FILES) + cat kernel_syms.lst > $@.new + for m in $(MODULE_FILES); do \ + sh $< $$m >> $@.new || exit 1; \ + done + mv $@.new $@ + +# generate global module dependencies list +moddep.lst: syminfo.lst genmoddep.awk video.lst + cat $< | sort | $(AWK) -f $(srcdir)/genmoddep.awk > $@ || (rm -f $@; exit 1) +platform_DATA += moddep.lst +CLEANFILES += config.log syminfo.lst moddep.lst + +$(MOD_FILES): %.mod : genmod.sh moddep.lst %.module$(EXEEXT) build-grub-module-verifier$(BUILD_EXEEXT) + TARGET_OBJ2ELF=@TARGET_OBJ2ELF@ sh $^ $@ +platform_DATA += $(MOD_FILES) +platform_DATA += modinfo.sh +CLEANFILES += $(MOD_FILES) + +if COND_ENABLE_EFIEMU +efiemu32.o: efiemu/runtime/efiemu.c $(TARGET_OBJ2ELF) + -rm -f $@ + -rm -f $@.bin + $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m32 -Wall -Werror -nostdlib -static -O2 -c -o $@.bin $< + if test "x$(TARGET_APPLE_LINKER)" = x1; then \ + $(TARGET_OBJCONV) -felf32 -nu -nd $@.bin $@ || exit 1; \ + rm -f $@.bin ; \ + elif test ! -z "$(TARGET_OBJ2ELF)"; then \ + $(TARGET_OBJ2ELF) $@.bin || (rm -f $@.bin; exit 1); \ + mv $@.bin $@ ; \ + else \ + mv $@.bin $@ ; \ + fi + +# Link format -arch,x86_64 means Apple linker +efiemu64_c.o: efiemu/runtime/efiemu.c + $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -nostdlib -Wall -Werror -O2 -mcmodel=large -mno-red-zone -c -o $@ $< + +efiemu64_s.o: efiemu/runtime/efiemu.S + $(TARGET_CC) $(DEFS) $(INCLUDES) $(CPPFLAGS_EFIEMU) $(CPPFLAGS_DEFAULT) -m64 -Wall -Werror -nostdlib -O2 -mcmodel=large -mno-red-zone -c -o $@ $< + +efiemu64.o: efiemu64_c.o efiemu64_s.o $(TARGET_OBJ2ELEF) + -rm -f $@ + -rm -f $@.bin + $(TARGET_CC) -m64 $(EFIEMU64_LINK_FORMAT) -nostdlib -static -Wl,-r -o $@.bin $^ + if test "x$(EFIEMU64_LINK_FORMAT)" = x-arch,x86_64; then \ + $(TARGET_OBJCONV) -felf64 -nu -nd $@.bin $@ || exit 1; \ + rm -f $@.bin; \ + else \ + mv $@.bin $@ ; \ + fi + +platform_DATA += efiemu32.o efiemu64.o +CLEANFILES += efiemu32.o efiemu64.o efiemu64_c.o efiemu64_s.o +endif + +windowsdir=$(top_builddir)/$(PACKAGE)-$(VERSION)-for-windows +windowsdir: $(PROGRAMS) $(starfield_DATA) $(platform_DATA) + test -d $(windowsdir)/$(target_cpu)-$(platform) || mkdir $(windowsdir)/$(target_cpu)-$(platform) + for x in $(platform_DATA); do \ + cp -fp $$x $(windowsdir)/$(target_cpu)-$(platform)/$$x; \ + done diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def index d0455f9f..f7351891 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/Makefile.core.def @@ -100,6 +100,10 @@ kernel = { emu_cppflags = '$(CPPFLAGS_GNULIB)'; arm_uboot_ldflags = '-Wl,-r,-d'; arm_uboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; + + mips64_efi_ldflags = '-Wl,-r,-d'; + mips64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame -R .MIPS.abiflags'; + arm_coreboot_ldflags = '-Wl,-r,-d'; arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; @@ -114,6 +118,7 @@ kernel = { i386_coreboot_startup = kern/i386/coreboot/startup.S; i386_multiboot_startup = kern/i386/coreboot/startup.S; mips_startup = kern/mips/startup.S; + mips64_efi_startup = kern/mips64/efi/startup.S; sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S; powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S; arm_uboot_startup = kern/arm/startup.S; @@ -310,6 +315,15 @@ kernel = { extra_dist = video/sis315_init.c; mips_loongson = commands/keylayouts.c; + mips64 = kern/mips64/init.c; + mips64 = kern/mips64/dl.c; + mips64 = kern/mips64/cache.S; + mips64 = kern/generic/rtc_get_time_ms.c; + mips64_efi = kern/mips64/efi/init.c; + mips64_efi = kern/mips64/efi/loongson.c; + mips64_efi = lib/mips64/efi/loongson.c; + mips64_efi = lib/mips64/efi/loongson_asm.S; + powerpc_ieee1275 = kern/powerpc/cache.S; powerpc_ieee1275 = kern/powerpc/dl.c; powerpc_ieee1275 = kern/powerpc/compiler-rt.S; @@ -809,6 +823,16 @@ module = { common = commands/blocklist.c; }; +module = { + name = blscfg; + common = commands/blscfg.c; + common = commands/loadenv.h; + enable = powerpc_ieee1275; + enable = efi; + enable = i386_pc; + enable = emu; +}; + module = { name = boot; common = commands/boot.c; @@ -818,6 +842,7 @@ module = { enable = sparc64_ieee1275; enable = powerpc_ieee1275; enable = mips_arc; + enable = mips64_efi; enable = ia64_efi; enable = arm_efi; enable = arm64_efi; @@ -986,6 +1011,7 @@ module = { module = { name = loadenv; common = commands/loadenv.c; + common = commands/loadenv.h; common = lib/envblk.c; }; @@ -1577,12 +1603,22 @@ module = { module = { name = ventoy; common = ventoy/ventoy.c; + common = ventoy/ventoy_cmd.c; common = ventoy/ventoy_linux.c; + common = ventoy/ventoy_unix.c; common = ventoy/ventoy_windows.c; + common = ventoy/ventoy_vhd.c; common = ventoy/ventoy_plugin.c; common = ventoy/ventoy_json.c; common = ventoy/lzx.c; + common = ventoy/xpress.c; common = ventoy/huffman.c; + common = ventoy/miniz.c; +}; + +module = { + name = setkey; + common = term/setkey.c; }; module = { @@ -1647,6 +1683,8 @@ module = { efi = lib/efi/relocator.c; mips = lib/mips/relocator_asm.S; mips = lib/mips/relocator.c; + mips64 = lib/mips64/relocator_asm.S; + mips64 = lib/mips64/relocator.c; powerpc = lib/powerpc/relocator_asm.S; powerpc = lib/powerpc/relocator.c; xen = lib/xen/relocator.c; @@ -1659,6 +1697,7 @@ module = { extra_dist = kern/powerpc/cache_flush.S; enable = mips; + enable = mips64; enable = powerpc; enable = x86; enable = i386_xen_pvh; @@ -1789,6 +1828,7 @@ module = { i386_pc = lib/i386/pc/vesa_modes_table.c; i386_xen_pvh = lib/i386/pc/vesa_modes_table.c; mips = loader/mips/linux.c; + mips64 = loader/mips64/linux.c; powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c; sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c; ia64_efi = loader/ia64/efi/linux.c; @@ -1895,6 +1935,7 @@ module = { enable = riscv32_efi; enable = riscv64_efi; enable = mips; + enable = mips64_efi; }; module = { diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/boot/i386/pc/boot.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/boot/i386/pc/boot.S index 18c99b37..bc544f78 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/boot/i386/pc/boot.S +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/boot/i386/pc/boot.S @@ -479,7 +479,7 @@ LOCAL(stop): jmp LOCAL(stop) ventoy_uuid: .ascii "XXXXXXXXXXXXXXXX" -notification_string: .asciz "GR" +notification_string: .asciz "VT" geometry_error_string: .asciz "Ge" hd_probe_error_string: .asciz "HD" read_error_string: .asciz "Rd" diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c new file mode 100644 index 00000000..55ee2be0 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/blscfg.c @@ -0,0 +1,1111 @@ +/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ + +/* bls.c - implementation of the boot loader spec */ + +/* + * GRUB -- GRand Unified Bootloader + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#include "loadenv.h" + +#define GRUB_BLS_CONFIG_PATH "/loader/entries/" +#ifdef GRUB_MACHINE_EMU +#define GRUB_BOOT_DEVICE "/boot" +#else +#define GRUB_BOOT_DEVICE "($root)" +#endif + +struct keyval +{ + const char *key; + char *val; +}; + +static struct bls_entry *entries = NULL; + +#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries) + +static int bls_add_keyval(struct bls_entry *entry, char *key, char *val) +{ + char *k, *v; + struct keyval **kvs, *kv; + int new_n = entry->nkeyvals + 1; + + kvs = grub_realloc (entry->keyvals, new_n * sizeof (struct keyval *)); + if (!kvs) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + entry->keyvals = kvs; + + kv = grub_malloc (sizeof (struct keyval)); + if (!kv) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + + k = grub_strdup (key); + if (!k) + { + grub_free (kv); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + } + + v = grub_strdup (val); + if (!v) + { + grub_free (k); + grub_free (kv); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "couldn't find space for BLS entry"); + } + + kv->key = k; + kv->val = v; + + entry->keyvals[entry->nkeyvals] = kv; + grub_dprintf("blscfg", "new keyval at %p:%s:%s\n", entry->keyvals[entry->nkeyvals], k, v); + entry->nkeyvals = new_n; + + return 0; +} + +/* Find they value of the key named by keyname. If there are allowed to be + * more than one, pass a pointer to an int set to -1 the first time, and pass + * the same pointer through each time after, and it'll return them in sorted + * order as defined in the BLS fragment file */ +static char *bls_get_val(struct bls_entry *entry, const char *keyname, int *last) +{ + int idx, start = 0; + struct keyval *kv = NULL; + + if (last) + start = *last + 1; + + for (idx = start; idx < entry->nkeyvals; idx++) { + kv = entry->keyvals[idx]; + + if (!grub_strcmp (keyname, kv->key)) + break; + } + + if (idx == entry->nkeyvals) { + if (last) + *last = -1; + return NULL; + } + + if (last) + *last = idx; + + return kv->val; +} + +#define goto_return(x) ({ ret = (x); goto finish; }) + +/* compare alpha and numeric segments of two versions */ +/* return 1: a is newer than b */ +/* 0: a and b are the same version */ +/* -1: b is newer than a */ +static int vercmp(const char * a, const char * b) +{ + char oldch1, oldch2; + char *abuf, *bbuf; + char *str1, *str2; + char * one, * two; + int rc; + int isnum; + int ret = 0; + + grub_dprintf("blscfg", "%s comparing %s and %s\n", __func__, a, b); + if (!grub_strcmp(a, b)) + return 0; + + abuf = grub_malloc(grub_strlen(a) + 1); + bbuf = grub_malloc(grub_strlen(b) + 1); + str1 = abuf; + str2 = bbuf; + grub_strcpy(str1, a); + grub_strcpy(str2, b); + + one = str1; + two = str2; + + /* loop through each version segment of str1 and str2 and compare them */ + while (*one || *two) { + while (*one && !grub_isalnum(*one) && *one != '~') one++; + while (*two && !grub_isalnum(*two) && *two != '~') two++; + + /* handle the tilde separator, it sorts before everything else */ + if (*one == '~' || *two == '~') { + if (*one != '~') goto_return (1); + if (*two != '~') goto_return (-1); + one++; + two++; + continue; + } + + /* If we ran to the end of either, we are finished with the loop */ + if (!(*one && *two)) break; + + str1 = one; + str2 = two; + + /* grab first completely alpha or completely numeric segment */ + /* leave one and two pointing to the start of the alpha or numeric */ + /* segment and walk str1 and str2 to end of segment */ + if (grub_isdigit(*str1)) { + while (*str1 && grub_isdigit(*str1)) str1++; + while (*str2 && grub_isdigit(*str2)) str2++; + isnum = 1; + } else { + while (*str1 && grub_isalpha(*str1)) str1++; + while (*str2 && grub_isalpha(*str2)) str2++; + isnum = 0; + } + + /* save character at the end of the alpha or numeric segment */ + /* so that they can be restored after the comparison */ + oldch1 = *str1; + *str1 = '\0'; + oldch2 = *str2; + *str2 = '\0'; + + /* this cannot happen, as we previously tested to make sure that */ + /* the first string has a non-null segment */ + if (one == str1) goto_return(-1); /* arbitrary */ + + /* take care of the case where the two version segments are */ + /* different types: one numeric, the other alpha (i.e. empty) */ + /* numeric segments are always newer than alpha segments */ + /* XXX See patch #60884 (and details) from bugzilla #50977. */ + if (two == str2) goto_return (isnum ? 1 : -1); + + if (isnum) { + grub_size_t onelen, twolen; + /* this used to be done by converting the digit segments */ + /* to ints using atoi() - it's changed because long */ + /* digit segments can overflow an int - this should fix that. */ + + /* throw away any leading zeros - it's a number, right? */ + while (*one == '0') one++; + while (*two == '0') two++; + + /* whichever number has more digits wins */ + onelen = grub_strlen(one); + twolen = grub_strlen(two); + if (onelen > twolen) goto_return (1); + if (twolen > onelen) goto_return (-1); + } + + /* grub_strcmp will return which one is greater - even if the two */ + /* segments are alpha or if they are numeric. don't return */ + /* if they are equal because there might be more segments to */ + /* compare */ + rc = grub_strcmp(one, two); + if (rc) goto_return (rc < 1 ? -1 : 1); + + /* restore character that was replaced by null above */ + *str1 = oldch1; + one = str1; + *str2 = oldch2; + two = str2; + } + + /* this catches the case where all numeric and alpha segments have */ + /* compared identically but the segment sepparating characters were */ + /* different */ + if ((!*one) && (!*two)) goto_return (0); + + /* whichever version still has characters left over wins */ + if (!*one) goto_return (-1); else goto_return (1); + +finish: + grub_free (abuf); + grub_free (bbuf); + return ret; +} + +/* returns name/version/release */ +/* NULL string pointer returned if nothing found */ +static void +split_package_string (char *package_string, char **name, + char **version, char **release) +{ + char *package_version, *package_release; + + /* Release */ + package_release = grub_strrchr (package_string, '-'); + + if (package_release != NULL) + *package_release++ = '\0'; + + *release = package_release; + + if (name == NULL) + { + *version = package_string; + } + else + { + /* Version */ + package_version = grub_strrchr(package_string, '-'); + + if (package_version != NULL) + *package_version++ = '\0'; + + *version = package_version; + /* Name */ + *name = package_string; + } + + /* Bubble up non-null values from release to name */ + if (name != NULL && *name == NULL) + { + *name = (*version == NULL ? *release : *version); + *version = *release; + *release = NULL; + } + if (*version == NULL) + { + *version = *release; + *release = NULL; + } +} + +static int +split_cmp(char *nvr0, char *nvr1, int has_name) +{ + int ret = 0; + char *name0, *version0, *release0; + char *name1, *version1, *release1; + + split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0); + split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1); + + if (has_name) + { + ret = vercmp(name0 == NULL ? "" : name0, + name1 == NULL ? "" : name1); + if (ret != 0) + return ret; + } + + ret = vercmp(version0 == NULL ? "" : version0, + version1 == NULL ? "" : version1); + if (ret != 0) + return ret; + + ret = vercmp(release0 == NULL ? "" : release0, + release1 == NULL ? "" : release1); + return ret; +} + +/* return 1: e0 is newer than e1 */ +/* 0: e0 and e1 are the same version */ +/* -1: e1 is newer than e0 */ +static int bls_cmp(const struct bls_entry *e0, const struct bls_entry *e1) +{ + char *id0, *id1; + int r; + + id0 = grub_strdup(e0->filename); + id1 = grub_strdup(e1->filename); + + r = split_cmp(id0, id1, 1); + + grub_free(id0); + grub_free(id1); + + return r; +} + +static void list_add_tail(struct bls_entry *head, struct bls_entry *item) +{ + item->next = head; + if (head->prev) + head->prev->next = item; + item->prev = head->prev; + head->prev = item; +} + +static int bls_add_entry(struct bls_entry *entry) +{ + struct bls_entry *e, *last = NULL; + int rc; + + if (!entries) { + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); + entries = entry; + return 0; + } + + FOR_BLS_ENTRIES(e) { + rc = bls_cmp(entry, e); + + if (!rc) + return GRUB_ERR_BAD_ARGUMENT; + + if (rc == 1) { + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); + list_add_tail (e, entry); + if (e == entries) { + entries = entry; + entry->prev = NULL; + } + return 0; + } + last = e; + } + + if (last) { + grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); + last->next = entry; + entry->prev = last; + } + + return 0; +} + +struct read_entry_info { + const char *devid; + const char *dirname; + grub_file_t file; +}; + +static int read_entry ( + const char *filename, + const struct grub_dirhook_info *dirhook_info UNUSED, + void *data) +{ + grub_size_t m = 0, n, clip = 0; + int rc = 0; + char *p = NULL; + grub_file_t f = NULL; + struct bls_entry *entry; + struct read_entry_info *info = (struct read_entry_info *)data; + + grub_dprintf ("blscfg", "filename: \"%s\"\n", filename); + + n = grub_strlen (filename); + + if (info->file) + { + f = info->file; + } + else + { + if (filename[0] == '.') + return 0; + + if (n <= 5) + return 0; + + if (grub_strcmp (filename + n - 5, ".conf") != 0) + return 0; + + p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename); + + f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG); + if (!f) + goto finish; + } + + entry = grub_zalloc (sizeof (*entry)); + if (!entry) + goto finish; + + if (info->file) + { + char *slash; + + if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0) + clip = 5; + + slash = grub_strrchr (filename, '/'); + if (!slash) + slash = grub_strrchr (filename, '\\'); + + while (*slash == '/' || *slash == '\\') + slash++; + + m = slash ? slash - filename : 0; + } + else + { + m = 0; + clip = 5; + } + n -= m; + + entry->filename = grub_strndup(filename + m, n - clip); + if (!entry->filename) + goto finish; + + entry->filename[n - 5] = '\0'; + + for (;;) + { + char *buf; + char *separator; + + buf = grub_file_getline (f); + if (!buf) + break; + + while (buf && buf[0] && (buf[0] == ' ' || buf[0] == '\t')) + buf++; + if (buf[0] == '#') + continue; + + separator = grub_strchr (buf, ' '); + + if (!separator) + separator = grub_strchr (buf, '\t'); + + if (!separator || separator[1] == '\0') + { + grub_free (buf); + break; + } + + separator[0] = '\0'; + + do { + separator++; + } while (*separator == ' ' || *separator == '\t'); + + rc = bls_add_keyval (entry, buf, separator); + grub_free (buf); + if (rc < 0) + break; + } + + if (!rc) + bls_add_entry(entry); + +finish: + if (p) + grub_free (p); + + if (f) + grub_file_close (f); + + return 0; +} + +static grub_envblk_t saved_env = NULL; + +static int UNUSED +save_var (const char *name, const char *value, void *whitelist UNUSED) +{ + const char *val = grub_env_get (name); + grub_dprintf("blscfg", "saving \"%s\"\n", name); + + if (val) + grub_envblk_set (saved_env, name, value); + + return 0; +} + +static int UNUSED +unset_var (const char *name, const char *value UNUSED, void *whitelist) +{ + grub_dprintf("blscfg", "restoring \"%s\"\n", name); + if (! whitelist) + { + grub_env_unset (name); + return 0; + } + + if (test_whitelist_membership (name, + (const grub_env_whitelist_t *) whitelist)) + grub_env_unset (name); + + return 0; +} + +static char **bls_make_list (struct bls_entry *entry, const char *key, int *num) +{ + int last = -1; + char *val; + + int nlist = 0; + char **list = NULL; + + list = grub_malloc (sizeof (char *)); + if (!list) + return NULL; + list[0] = NULL; + + while (1) + { + char **new; + + val = bls_get_val (entry, key, &last); + if (!val) + break; + + new = grub_realloc (list, (nlist + 2) * sizeof (char *)); + if (!new) + break; + + list = new; + list[nlist++] = val; + list[nlist] = NULL; + } + + if (num) + *num = nlist; + + return list; +} + +static char *field_append(bool is_var, char *buffer, char *start, char *end) +{ + char *temp = grub_strndup(start, end - start + 1); + const char *field = temp; + + if (is_var) { + field = grub_env_get (temp); + if (!field) + return buffer; + } + + if (!buffer) { + buffer = grub_strdup(field); + if (!buffer) + return NULL; + } else { + buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field)); + if (!buffer) + return NULL; + + grub_stpcpy (buffer + grub_strlen(buffer), field); + } + + return buffer; +} + +static char *expand_val(char *value) +{ + char *buffer = NULL; + char *start = value; + char *end = value; + bool is_var = false; + + if (!value) + return NULL; + + while (*value) { + if (*value == '$') { + if (start != end) { + buffer = field_append(is_var, buffer, start, end); + if (!buffer) + return NULL; + } + + is_var = true; + start = value + 1; + } else if (is_var) { + if (!grub_isalnum(*value) && *value != '_') { + buffer = field_append(is_var, buffer, start, end); + is_var = false; + start = value; + } + } + + end = value; + value++; + } + + if (start != end) { + buffer = field_append(is_var, buffer, start, end); + if (!buffer) + return NULL; + } + + return buffer; +} + +static char **early_initrd_list (const char *initrd) +{ + int nlist = 0; + char **list = NULL; + char *separator; + + while ((separator = grub_strchr (initrd, ' '))) + { + list = grub_realloc (list, (nlist + 2) * sizeof (char *)); + if (!list) + return NULL; + + list[nlist++] = grub_strndup(initrd, separator - initrd); + list[nlist] = NULL; + initrd = separator + 1; + } + + list = grub_realloc (list, (nlist + 2) * sizeof (char *)); + if (!list) + return NULL; + + list[nlist++] = grub_strndup(initrd, grub_strlen(initrd)); + list[nlist] = NULL; + + return list; +} + +static void create_entry (struct bls_entry *entry) +{ + int argc = 0; + const char **argv = NULL; + + char *title = NULL; + char *clinux = NULL; + char *options = NULL; + char **initrds = NULL; + char *initrd = NULL; + const char *early_initrd = NULL; + char **early_initrds = NULL; + char *initrd_prefix = NULL; + char *id = entry->filename; + char *dotconf = id; + char *hotkey = NULL; + + char *users = NULL; + char **classes = NULL; + + char **args = NULL; + + char *src = NULL; + int bootlen; + const char *bootdev; + int i, index; + + grub_dprintf("blscfg", "%s got here\n", __func__); + clinux = bls_get_val (entry, "linux", NULL); + if (!clinux) + { + grub_dprintf ("blscfg", "Skipping file %s with no 'linux' key.\n", entry->filename); + goto finish; + } + + bootdev = grub_env_get("ventoy_bls_bootdev"); + if (!bootdev) + { + bootdev = GRUB_BOOT_DEVICE; + } + bootlen = grub_strlen(bootdev) + 2;//space and \0 + + /* + * strip the ".conf" off the end before we make it our "id" field. + */ + do + { + dotconf = grub_strstr(dotconf, ".conf"); + } while (dotconf != NULL && dotconf[5] != '\0'); + if (dotconf) + dotconf[0] = '\0'; + + title = bls_get_val (entry, "title", NULL); + options = expand_val (bls_get_val (entry, "options", NULL)); + + if (!options) + options = expand_val ((char *)grub_env_get("default_kernelopts")); + + initrds = bls_make_list (entry, "initrd", NULL); + + hotkey = bls_get_val (entry, "grub_hotkey", NULL); + users = expand_val (bls_get_val (entry, "grub_users", NULL)); + classes = bls_make_list (entry, "grub_class", NULL); + args = bls_make_list (entry, "grub_arg", &argc); + + argc += 1; + argv = grub_malloc ((argc + 1) * sizeof (char *)); + argv[0] = title ? title : clinux; + for (i = 1; i < argc; i++) + argv[i] = args[i-1]; + argv[argc] = NULL; + + early_initrd = grub_env_get("early_initrd"); + + grub_dprintf ("blscfg", "adding menu entry for \"%s\" with id \"%s\"\n", + title, id); + if (early_initrd) + { + early_initrds = early_initrd_list(early_initrd); + if (!early_initrds) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + + if (initrds != NULL && initrds[0] != NULL) + { + initrd_prefix = grub_strrchr (initrds[0], '/'); + initrd_prefix = grub_strndup(initrds[0], initrd_prefix - initrds[0] + 1); + } + else + { + initrd_prefix = grub_strrchr (clinux, '/'); + initrd_prefix = grub_strndup(clinux, initrd_prefix - clinux + 1); + } + + if (!initrd_prefix) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + } + + if (early_initrds || initrds) + { + int initrd_size = sizeof ("initrd"); + char *tmp; + + for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) + initrd_size += bootlen \ + + grub_strlen(initrd_prefix) \ + + grub_strlen (early_initrds[i]) + 1; + + for (i = 0; initrds != NULL && initrds[i] != NULL; i++) + initrd_size += bootlen \ + + grub_strlen (initrds[i]) + 1; + initrd_size += 1; + + initrd = grub_malloc (initrd_size); + if (!initrd) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto finish; + } + + + tmp = grub_stpcpy(initrd, "initrd"); + for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) + { + grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]); + tmp = grub_stpcpy (tmp, " "); + tmp = grub_stpcpy (tmp, bootdev); + tmp = grub_stpcpy (tmp, initrd_prefix); + tmp = grub_stpcpy (tmp, early_initrds[i]); + grub_free(early_initrds[i]); + } + + for (i = 0; initrds != NULL && initrds[i] != NULL; i++) + { + grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]); + tmp = grub_stpcpy (tmp, " "); + tmp = grub_stpcpy (tmp, bootdev); + tmp = grub_stpcpy (tmp, initrds[i]); + } + tmp = grub_stpcpy (tmp, "\n"); + } + + src = grub_xasprintf ("load_video\n" + "set gfxpayload=keep\n" + "insmod gzio\n" + "linux %s%s%s%s\n" + "%s", + bootdev, clinux, options ? " " : "", options ? options : "", + initrd ? initrd : ""); + + grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry); + grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id); + +finish: + grub_free (initrd); + grub_free (initrd_prefix); + grub_free (early_initrds); + grub_free (initrds); + grub_free (options); + grub_free (classes); + grub_free (args); + grub_free (argv); + grub_free (src); +} + +struct find_entry_info { + const char *dirname; + const char *devid; + grub_device_t dev; + grub_fs_t fs; +}; + +/* + * info: the filesystem object the file is on. + */ +static int find_entry (struct find_entry_info *info) +{ + struct read_entry_info read_entry_info; + grub_fs_t blsdir_fs = NULL; + grub_device_t blsdir_dev = NULL; + const char *blsdir = info->dirname; + int fallback = 0; + int r = 0; + + if (!blsdir) { + blsdir = grub_env_get ("blsdir"); + if (!blsdir) + blsdir = GRUB_BLS_CONFIG_PATH; + } + + read_entry_info.file = NULL; + read_entry_info.dirname = blsdir; + + grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir); + + blsdir_dev = info->dev; + blsdir_fs = info->fs; + read_entry_info.devid = info->devid; + +read_fallback: + r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, read_entry, + &read_entry_info); + if (r != 0) { + grub_dprintf ("blscfg", "read_entry returned error\n"); + grub_err_t e; + do + { + e = grub_error_pop(); + } while (e); + } + + if (r && !info->dirname && !fallback) { + read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH; + grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n", + blsdir, read_entry_info.dirname); + fallback = 1; + goto read_fallback; + } + + return 0; +} + +static grub_err_t +bls_load_entries (const char *path) +{ + grub_size_t len; + grub_fs_t fs; + grub_device_t dev; + static grub_err_t r; + const char *devid = NULL; + char *blsdir = NULL; + struct find_entry_info info = { + .dev = NULL, + .fs = NULL, + .dirname = NULL, + }; + struct read_entry_info rei = { + .devid = NULL, + .dirname = NULL, + }; + + if (path) { + len = grub_strlen (path); + if (grub_strcmp (path + len - 5, ".conf") == 0) { + rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG); + if (!rei.file) + return grub_errno; + /* + * read_entry() closes the file + */ + return read_entry(path, NULL, &rei); + } else if (path[0] == '(') { + devid = path + 1; + + blsdir = grub_strchr (path, ')'); + if (!blsdir) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct")); + + *blsdir = '\0'; + blsdir = blsdir + 1; + } + } + + if (!devid) { +#ifdef GRUB_MACHINE_EMU + devid = "host"; +#elif defined(GRUB_MACHINE_EFI) + devid = grub_env_get ("root"); +#else + devid = grub_env_get ("boot"); + if (!devid) + { + devid = grub_env_get ("root"); + } +#endif + if (!devid) + return grub_error (GRUB_ERR_FILE_NOT_FOUND, + N_("variable `%s' isn't set"), "boot"); + } + + grub_dprintf ("blscfg", "opening %s\n", devid); + dev = grub_device_open (devid); + if (!dev) + return grub_errno; + + grub_dprintf ("blscfg", "probing fs\n"); + fs = grub_fs_probe (dev); + if (!fs) + { + r = grub_errno; + goto finish; + } + + info.dirname = blsdir; + info.devid = devid; + info.dev = dev; + info.fs = fs; + find_entry(&info); + +finish: + if (dev) + grub_device_close (dev); + + return r; +} + +static bool +is_default_entry(const char *def_entry, struct bls_entry *entry, int idx) +{ + const char *title; + int def_idx; + + if (!def_entry) + return false; + + if (grub_strcmp(def_entry, entry->filename) == 0) + return true; + + title = bls_get_val(entry, "title", NULL); + + if (title && grub_strcmp(def_entry, title) == 0) + return true; + + def_idx = (int)grub_strtol(def_entry, NULL, 0); + if (grub_errno == GRUB_ERR_BAD_NUMBER) { + grub_errno = GRUB_ERR_NONE; + return false; + } + + if (def_idx == idx) + return true; + + return false; +} + +static grub_err_t +bls_create_entries (bool show_default, bool show_non_default, char *entry_id) +{ + const char *def_entry = NULL; + struct bls_entry *entry = NULL; + int idx = 0; + + def_entry = grub_env_get("default"); + + grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); + FOR_BLS_ENTRIES(entry) { + if (entry->visible) { + idx++; + continue; + } + + if ((show_default && is_default_entry(def_entry, entry, idx)) || + (show_non_default && !is_default_entry(def_entry, entry, idx)) || + (entry_id && grub_strcmp(entry_id, entry->filename) == 0)) { + create_entry(entry); + entry->visible = 1; + } + idx++; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, + int argc, char **args) +{ + grub_err_t r; + char *path = NULL; + char *entry_id = NULL; + bool show_default = true; + bool show_non_default = true; + + if (argc == 1) { + if (grub_strcmp (args[0], "default") == 0) { + show_non_default = false; + } else if (grub_strcmp (args[0], "non-default") == 0) { + show_default = false; + } else if (args[0][0] == '(') { + path = args[0]; + } else { + entry_id = args[0]; + show_default = false; + show_non_default = false; + } + } + + r = bls_load_entries(path); + if (r) + return r; + + return bls_create_entries(show_default, show_non_default, entry_id); +} + +static grub_extcmd_t cmd; +static grub_extcmd_t oldcmd; + +GRUB_MOD_INIT(blscfg) +{ + grub_dprintf("blscfg", "%s got here\n", __func__); + cmd = grub_register_extcmd ("blscfg", + grub_cmd_blscfg, + 0, + NULL, + N_("Import Boot Loader Specification snippets."), + NULL); + oldcmd = grub_register_extcmd ("bls_import", + grub_cmd_blscfg, + 0, + NULL, + N_("Import Boot Loader Specification snippets."), + NULL); +} + +GRUB_MOD_FINI(blscfg) +{ + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (oldcmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c new file mode 100644 index 00000000..7bca70e4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/hashsum.c @@ -0,0 +1,343 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options[] = { + {"hash", 'h', 0, N_("Specify hash to use."), N_("HASH"), ARG_TYPE_STRING}, + {"check", 'c', 0, N_("Check hashes of files with hash list FILE."), + N_("FILE"), ARG_TYPE_STRING}, + {"prefix", 'p', 0, N_("Base directory for hash list."), N_("DIR"), + ARG_TYPE_STRING}, + {"keep-going", 'k', 0, N_("Don't stop after first error."), 0, 0}, + {"uncompress", 'u', 0, N_("Uncompress file before checksumming."), 0, 0}, + {0, 0, 0, 0, 0, 0} +}; + +static struct { const char *name; const char *hashname; } aliases[] = + { + {"sha256sum", "sha256"}, + {"sha512sum", "sha512"}, + {"sha1sum", "sha1"}, + {"md5sum", "md5"}, + {"crc", "crc32"}, + }; + +static inline int +hextoval (char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static grub_err_t +hash_file (grub_file_t file, const gcry_md_spec_t *hash, void *result) +{ + int progress = 0; + grub_uint64_t ro = 0; + grub_uint64_t div = 0; + grub_uint64_t total = 0; + void *context; + grub_uint8_t *readbuf; +#define BUF_SIZE 1024 * 1024 + readbuf = grub_malloc (BUF_SIZE); + if (!readbuf) + return grub_errno; + context = grub_zalloc (hash->contextsize); + if (!readbuf || !context) + goto fail; + + if (file->size > 16 * 1024 * 1024) + progress = 1; + + hash->init (context); + while (1) + { + grub_ssize_t r; + r = grub_file_read (file, readbuf, BUF_SIZE); + if (r < 0) + goto fail; + if (r == 0) + break; + hash->write (context, readbuf, r); + if (progress) + { + total += r; + div = grub_divmod64(total * 100, (grub_uint64_t)file->size, &ro); + grub_printf("\rCalculating %d%% ", (int)div); + grub_refresh(); + } + } + hash->final (context); + grub_memcpy (result, hash->read (context), hash->mdlen); + + grub_free (readbuf); + grub_free (context); + if (progress) + { + grub_printf("\rCalculating 100%% \n\r\n"); + grub_refresh(); + } + return GRUB_ERR_NONE; + + fail: + grub_free (readbuf); + grub_free (context); + return grub_errno; +} + +static grub_err_t +check_list (const gcry_md_spec_t *hash, const char *hashfilename, + const char *prefix, int keep, int uncompress) +{ + grub_file_t hashlist, file; + char *buf = NULL; + grub_uint8_t expected[GRUB_CRYPTO_MAX_MDLEN]; + grub_uint8_t actual[GRUB_CRYPTO_MAX_MDLEN]; + grub_err_t err; + unsigned i; + unsigned unread = 0, mismatch = 0; + + if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) + return grub_error (GRUB_ERR_BUG, "mdlen is too long"); + + hashlist = grub_file_open (hashfilename, GRUB_FILE_TYPE_HASHLIST); + if (!hashlist) + return grub_errno; + + while (grub_free (buf), (buf = grub_file_getline (hashlist))) + { + const char *p = buf; + while (grub_isspace (p[0])) + p++; + for (i = 0; i < hash->mdlen; i++) + { + int high, low; + high = hextoval (*p++); + low = hextoval (*p++); + if (high < 0 || low < 0) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + expected[i] = (high << 4) | low; + } + if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t')) + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + p += 2; + if (prefix) + { + char *filename; + + filename = grub_xasprintf ("%s/%s", prefix, p); + if (!filename) + return grub_errno; + file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); + grub_free (filename); + } + else + file = grub_file_open (p, GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); + if (!file) + { + grub_file_close (hashlist); + grub_free (buf); + return grub_errno; + } + err = hash_file (file, hash, actual); + grub_file_close (file); + if (err) + { + grub_printf_ (N_("%s: READ ERROR\n"), p); + if (!keep) + { + grub_file_close (hashlist); + grub_free (buf); + return err; + } + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + unread++; + continue; + } + if (grub_crypto_memcmp (expected, actual, hash->mdlen) != 0) + { + grub_printf_ (N_("%s: HASH MISMATCH\n"), p); + if (!keep) + { + grub_file_close (hashlist); + grub_free (buf); + return grub_error (GRUB_ERR_TEST_FAILURE, + "hash of '%s' mismatches", p); + } + mismatch++; + continue; + } + grub_printf_ (N_("%s: OK\n"), p); + } + if (mismatch || unread) + return grub_error (GRUB_ERR_TEST_FAILURE, + "%d files couldn't be read and hash " + "of %d files mismatches", unread, mismatch); + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_hashsum (struct grub_extcmd_context *ctxt, + int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + const char *hashname = NULL; + const char *prefix = NULL; + const gcry_md_spec_t *hash; + unsigned i; + int keep = state[3].set; + int uncompress = state[4].set; + unsigned unread = 0; + + for (i = 0; i < ARRAY_SIZE (aliases); i++) + if (grub_strcmp (ctxt->extcmd->cmd->name, aliases[i].name) == 0) + hashname = aliases[i].hashname; + if (state[0].set) + hashname = state[0].arg; + + if (!hashname) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no hash specified"); + + hash = grub_crypto_lookup_md_by_name (hashname); + if (!hash) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown hash"); + + if (hash->mdlen > GRUB_CRYPTO_MAX_MDLEN) + return grub_error (GRUB_ERR_BUG, "mdlen is too long"); + + if (state[2].set) + prefix = state[2].arg; + + if (state[1].set) + { + if (argc != 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "--check is incompatible with file list"); + return check_list (hash, state[1].arg, prefix, keep, uncompress); + } + + for (i = 0; i < (unsigned) argc; i++) + { + GRUB_PROPERLY_ALIGNED_ARRAY (result, GRUB_CRYPTO_MAX_MDLEN); + grub_file_t file; + grub_err_t err; + unsigned j; + file = grub_file_open (args[i], GRUB_FILE_TYPE_TO_HASH + | (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS + : GRUB_FILE_TYPE_NONE)); + if (!file) + { + if (!keep) + return grub_errno; + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + unread++; + continue; + } + err = hash_file (file, hash, result); + grub_file_close (file); + if (err) + { + if (!keep) + return err; + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + unread++; + continue; + } + for (j = 0; j < hash->mdlen; j++) + grub_printf ("%02x", ((grub_uint8_t *) result)[j]); + grub_printf (" %s\n", args[i]); + } + + if (unread) + return grub_error (GRUB_ERR_TEST_FAILURE, "%d files couldn't be read", + unread); + return GRUB_ERR_NONE; +} + +static grub_extcmd_t cmd, cmd_md5, cmd_sha1, cmd_sha256, cmd_sha512, cmd_crc; + +GRUB_MOD_INIT(hashsum) +{ + cmd = grub_register_extcmd ("hashsum", grub_cmd_hashsum, 0, + N_("-h HASH [-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + /* TRANSLATORS: "hash checksum" is just to + be a bit more precise, you can treat it as + just "hash". */ + N_("Compute or check hash checksum."), + options); + cmd_md5 = grub_register_extcmd ("md5sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + cmd_sha1 = grub_register_extcmd ("sha1sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + cmd_sha256 = grub_register_extcmd ("sha256sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + cmd_sha512 = grub_register_extcmd ("sha512sum", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); + + cmd_crc = grub_register_extcmd ("crc", grub_cmd_hashsum, 0, + N_("[-c FILE [-p PREFIX]] " + "[FILE1 [FILE2 ...]]"), + N_("Compute or check hash checksum."), + options); +} + +GRUB_MOD_FINI(hashsum) +{ + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (cmd_md5); + grub_unregister_extcmd (cmd_sha1); + grub_unregister_extcmd (cmd_sha256); + grub_unregister_extcmd (cmd_sha512); + grub_unregister_extcmd (cmd_crc); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c new file mode 100644 index 00000000..891eac5a --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/legacycfg.c @@ -0,0 +1,894 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000, 2001, 2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +/* Helper for legacy_file. */ +static grub_err_t +legacy_file_getline (char **line, int cont __attribute__ ((unused)), + void *data __attribute__ ((unused))) +{ + *line = 0; + return GRUB_ERR_NONE; +} + +static grub_err_t +legacy_file (const char *filename) +{ + grub_file_t file; + char *entryname = NULL, *entrysrc = NULL; + grub_menu_t menu; + char *suffix = grub_strdup (""); + + if (!suffix) + return grub_errno; + + file = grub_file_open (filename, GRUB_FILE_TYPE_CONFIG); + if (! file) + { + grub_free (suffix); + return grub_errno; + } + + menu = grub_env_get_menu (); + if (! menu) + { + menu = grub_zalloc (sizeof (*menu)); + if (! menu) + { + grub_free (suffix); + return grub_errno; + } + + grub_env_set_menu (menu); + } + + while (1) + { + char *buf = grub_file_getline (file); + char *parsed = NULL; + + if (!buf && grub_errno) + { + grub_file_close (file); + grub_free (suffix); + return grub_errno; + } + + if (!buf) + break; + + { + char *oldname = NULL; + char *newsuffix; + char *ptr; + + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); + + oldname = entryname; + parsed = grub_legacy_parse (ptr, &entryname, &newsuffix); + grub_free (buf); + buf = NULL; + if (newsuffix) + { + char *t; + + t = suffix; + suffix = grub_realloc (suffix, grub_strlen (suffix) + + grub_strlen (newsuffix) + 1); + if (!suffix) + { + grub_free (t); + grub_free (entrysrc); + grub_free (parsed); + grub_free (newsuffix); + grub_free (suffix); + return grub_errno; + } + grub_memcpy (suffix + grub_strlen (suffix), newsuffix, + grub_strlen (newsuffix) + 1); + grub_free (newsuffix); + newsuffix = NULL; + } + if (oldname != entryname && oldname) + { + const char **args = grub_malloc (sizeof (args[0])); + if (!args) + { + grub_file_close (file); + return grub_errno; + } + args[0] = oldname; + grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", + NULL, NULL, + entrysrc, 0, NULL, NULL); + grub_free (args); + entrysrc[0] = 0; + grub_free (oldname); + } + } + + if (parsed && !entryname) + { + grub_normal_parse_line (parsed, legacy_file_getline, NULL); + grub_print_error (); + grub_free (parsed); + parsed = NULL; + } + else if (parsed) + { + if (!entrysrc) + entrysrc = parsed; + else + { + char *t; + + t = entrysrc; + entrysrc = grub_realloc (entrysrc, grub_strlen (entrysrc) + + grub_strlen (parsed) + 1); + if (!entrysrc) + { + grub_free (t); + grub_free (parsed); + grub_free (suffix); + return grub_errno; + } + grub_memcpy (entrysrc + grub_strlen (entrysrc), parsed, + grub_strlen (parsed) + 1); + grub_free (parsed); + parsed = NULL; + } + } + } + grub_file_close (file); + + if (entryname) + { + const char **args = grub_malloc (sizeof (args[0])); + if (!args) + { + grub_file_close (file); + grub_free (suffix); + grub_free (entrysrc); + return grub_errno; + } + args[0] = entryname; + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, + NULL, NULL, entrysrc, 0, NULL, + NULL); + grub_free (args); + } + + grub_normal_parse_line (suffix, legacy_file_getline, NULL); + grub_print_error (); + grub_free (suffix); + grub_free (entrysrc); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_legacy_source (struct grub_command *cmd, + int argc, char **args) +{ + int new_env, extractor; + grub_err_t ret; + + if (argc != 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + extractor = (cmd->name[0] == 'e'); + new_env = (cmd->name[extractor ? (sizeof ("extract_legacy_entries_") - 1) + : (sizeof ("legacy_") - 1)] == 'c'); + + if (new_env) + grub_cls (); + + if (new_env && !extractor) + grub_env_context_open (); + if (extractor) + grub_env_extractor_open (!new_env); + + ret = legacy_file (args[0]); + + if (new_env) + { + grub_menu_t menu; + menu = grub_env_get_menu (); + if (menu && menu->size) + grub_show_menu (menu, 1, 0); + if (!extractor) + grub_env_context_close (); + } + if (extractor) + grub_env_extractor_close (!new_env); + + return ret; +} + +static enum + { + GUESS_IT, LINUX, MULTIBOOT, KFREEBSD, KNETBSD, KOPENBSD + } kernel_type; + +static grub_err_t +grub_cmd_legacy_kernel (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + int i; +#ifdef TODO + int no_mem_option = 0; +#endif + struct grub_command *cmd; + char **cutargs; + int cutargc; + grub_err_t err = GRUB_ERR_NONE; + + for (i = 0; i < 2; i++) + { + /* FIXME: really support this. */ + if (argc >= 1 && grub_strcmp (args[0], "--no-mem-option") == 0) + { +#ifdef TODO + no_mem_option = 1; +#endif + argc--; + args++; + continue; + } + + /* linux16 handles both zImages and bzImages. */ + if (argc >= 1 && (grub_strcmp (args[0], "--type=linux") == 0 + || grub_strcmp (args[0], "--type=biglinux") == 0)) + { + kernel_type = LINUX; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=multiboot") == 0) + { + kernel_type = MULTIBOOT; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=freebsd") == 0) + { + kernel_type = KFREEBSD; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=openbsd") == 0) + { + kernel_type = KOPENBSD; + argc--; + args++; + continue; + } + + if (argc >= 1 && grub_strcmp (args[0], "--type=netbsd") == 0) + { + kernel_type = KNETBSD; + argc--; + args++; + continue; + } + } + + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + cutargs = grub_malloc (sizeof (cutargs[0]) * (argc - 1)); + if (!cutargs) + return grub_errno; + cutargc = argc - 1; + grub_memcpy (cutargs + 1, args + 2, sizeof (cutargs[0]) * (argc - 2)); + cutargs[0] = args[0]; + + do + { + /* First try Linux. */ + if (kernel_type == GUESS_IT || kernel_type == LINUX) + { +#ifdef GRUB_MACHINE_PCBIOS + cmd = grub_command_find ("linux16"); +#else + cmd = grub_command_find ("linux"); +#endif + if (cmd) + { + if (!(cmd->func) (cmd, cutargc, cutargs)) + { + kernel_type = LINUX; + goto out; + } + } + grub_errno = GRUB_ERR_NONE; + } + + /* Then multiboot. */ + if (kernel_type == GUESS_IT || kernel_type == MULTIBOOT) + { + cmd = grub_command_find ("multiboot"); + if (cmd) + { + if (!(cmd->func) (cmd, argc, args)) + { + kernel_type = MULTIBOOT; + goto out; + } + } + grub_errno = GRUB_ERR_NONE; + } + + { + int bsd_device = -1; + int bsd_slice = -1; + int bsd_part = -1; + { + grub_device_t dev; + const char *hdbiasstr; + int hdbias = 0; + hdbiasstr = grub_env_get ("legacy_hdbias"); + if (hdbiasstr) + { + hdbias = grub_strtoul (hdbiasstr, 0, 0); + grub_errno = GRUB_ERR_NONE; + } + dev = grub_device_open (0); + if (dev && dev->disk + && dev->disk->dev->id == GRUB_DISK_DEVICE_BIOSDISK_ID + && dev->disk->id >= 0x80 && dev->disk->id <= 0x90) + { + struct grub_partition *part = dev->disk->partition; + bsd_device = dev->disk->id - 0x80 - hdbias; + if (part && (grub_strcmp (part->partmap->name, "netbsd") == 0 + || grub_strcmp (part->partmap->name, "openbsd") == 0 + || grub_strcmp (part->partmap->name, "bsd") == 0)) + { + bsd_part = part->number; + part = part->parent; + } + if (part && grub_strcmp (part->partmap->name, "msdos") == 0) + bsd_slice = part->number; + } + if (dev) + grub_device_close (dev); + } + + /* k*BSD didn't really work well with grub-legacy. */ + if (kernel_type == GUESS_IT || kernel_type == KFREEBSD) + { + char buf[sizeof("adXXXXXXXXXXXXsXXXXXXXXXXXXYYY")]; + if (bsd_device != -1) + { + if (bsd_slice != -1 && bsd_part != -1) + grub_snprintf(buf, sizeof(buf), "ad%ds%d%c", bsd_device, + bsd_slice, 'a' + bsd_part); + else if (bsd_slice != -1) + grub_snprintf(buf, sizeof(buf), "ad%ds%d", bsd_device, + bsd_slice); + else + grub_snprintf(buf, sizeof(buf), "ad%d", bsd_device); + grub_env_set ("kFreeBSD.vfs.root.mountfrom", buf); + } + else + grub_env_unset ("kFreeBSD.vfs.root.mountfrom"); + cmd = grub_command_find ("kfreebsd"); + if (cmd) + { + if (!(cmd->func) (cmd, cutargc, cutargs)) + { + kernel_type = KFREEBSD; + goto out; + } + } + grub_errno = GRUB_ERR_NONE; + } + { + char **bsdargs; + int bsdargc; + char bsddevname[sizeof ("wdXXXXXXXXXXXXY")]; + int found = 0; + + if (bsd_device == -1) + { + bsdargs = cutargs; + bsdargc = cutargc; + } + else + { + char rbuf[3] = "-r"; + bsdargc = cutargc + 2; + bsdargs = grub_malloc (sizeof (bsdargs[0]) * bsdargc); + if (!bsdargs) + { + err = grub_errno; + goto out; + } + grub_memcpy (bsdargs, args, argc * sizeof (bsdargs[0])); + bsdargs[argc] = rbuf; + bsdargs[argc + 1] = bsddevname; + grub_snprintf (bsddevname, sizeof (bsddevname), + "wd%d%c", bsd_device, + bsd_part != -1 ? bsd_part + 'a' : 'c'); + } + if (kernel_type == GUESS_IT || kernel_type == KNETBSD) + { + cmd = grub_command_find ("knetbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, bsdargc, bsdargs)) + { + kernel_type = KNETBSD; + found = 1; + goto free_bsdargs; + } + } + grub_errno = GRUB_ERR_NONE; + } + if (kernel_type == GUESS_IT || kernel_type == KOPENBSD) + { + cmd = grub_command_find ("kopenbsd"); + if (cmd) + { + if (!(cmd->func) (cmd, bsdargc, bsdargs)) + { + kernel_type = KOPENBSD; + found = 1; + goto free_bsdargs; + } + } + grub_errno = GRUB_ERR_NONE; + } + +free_bsdargs: + if (bsdargs != cutargs) + grub_free (bsdargs); + if (found) + goto out; + } + } + } + while (0); + + err = grub_error (GRUB_ERR_BAD_OS, "couldn't load file %s", + args[0]); +out: + grub_free (cutargs); + return err; +} + +static grub_err_t +grub_cmd_legacy_initrd (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_command *cmd; + + if (kernel_type == LINUX) + { +#ifdef GRUB_MACHINE_PCBIOS + cmd = grub_command_find ("initrd16"); +#else + cmd = grub_command_find ("initrd"); +#endif + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), +#ifdef GRUB_MACHINE_PCBIOS + "initrd16" +#else + "initrd" +#endif + ); + + return cmd->func (cmd, argc ? 1 : 0, args); + } + if (kernel_type == MULTIBOOT) + { + cmd = grub_command_find ("module"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), + "module"); + + return cmd->func (cmd, argc, args); + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); +} + +static grub_err_t +grub_cmd_legacy_initrdnounzip (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct grub_command *cmd; + + if (kernel_type == LINUX) + { + cmd = grub_command_find ("initrd16"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), + "initrd16"); + + return cmd->func (cmd, argc, args); + } + if (kernel_type == MULTIBOOT) + { + char **newargs; + grub_err_t err; + char nounzipbuf[10] = "--nounzip"; + + cmd = grub_command_find ("module"); + if (!cmd) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("can't find command `%s'"), + "module"); + + newargs = grub_malloc ((argc + 1) * sizeof (newargs[0])); + if (!newargs) + return grub_errno; + grub_memcpy (newargs + 1, args, argc * sizeof (newargs[0])); + newargs[0] = nounzipbuf; + + err = cmd->func (cmd, argc + 1, newargs); + grub_free (newargs); + return err; + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); +} + +static grub_err_t +check_password_deny (const char *user __attribute__ ((unused)), + const char *entered __attribute__ ((unused)), + void *password __attribute__ ((unused))) +{ + return GRUB_ACCESS_DENIED; +} + +#define MD5_HASHLEN 16 + +struct legacy_md5_password +{ + grub_uint8_t *salt; + int saltlen; + grub_uint8_t hash[MD5_HASHLEN]; +}; + +static int +check_password_md5_real (const char *entered, + struct legacy_md5_password *pw) +{ + grub_size_t enteredlen = grub_strlen (entered); + unsigned char alt_result[MD5_HASHLEN]; + unsigned char *digest; + grub_uint8_t *ctx; + grub_size_t i; + int ret; + + ctx = grub_zalloc (GRUB_MD_MD5->contextsize); + if (!ctx) + return 0; + + GRUB_MD_MD5->init (ctx); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + grub_memcpy (alt_result, digest, MD5_HASHLEN); + + GRUB_MD_MD5->init (ctx); + GRUB_MD_MD5->write (ctx, entered, enteredlen); + GRUB_MD_MD5->write (ctx, pw->salt, pw->saltlen); /* include the $1$ header */ + for (i = enteredlen; i > 16; i -= 16) + GRUB_MD_MD5->write (ctx, alt_result, 16); + GRUB_MD_MD5->write (ctx, alt_result, i); + + for (i = enteredlen; i > 0; i >>= 1) + GRUB_MD_MD5->write (ctx, entered + ((i & 1) ? enteredlen : 0), 1); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + + for (i = 0; i < 1000; i++) + { + grub_memcpy (alt_result, digest, 16); + + GRUB_MD_MD5->init (ctx); + if ((i & 1) != 0) + GRUB_MD_MD5->write (ctx, entered, enteredlen); + else + GRUB_MD_MD5->write (ctx, alt_result, 16); + + if (i % 3 != 0) + GRUB_MD_MD5->write (ctx, pw->salt + 3, pw->saltlen - 3); + + if (i % 7 != 0) + GRUB_MD_MD5->write (ctx, entered, enteredlen); + + if ((i & 1) != 0) + GRUB_MD_MD5->write (ctx, alt_result, 16); + else + GRUB_MD_MD5->write (ctx, entered, enteredlen); + digest = GRUB_MD_MD5->read (ctx); + GRUB_MD_MD5->final (ctx); + } + + ret = (grub_crypto_memcmp (digest, pw->hash, MD5_HASHLEN) == 0); + grub_free (ctx); + return ret; +} + +static grub_err_t +check_password_md5 (const char *user, + const char *entered, + void *password) +{ + if (!check_password_md5_real (entered, password)) + return GRUB_ACCESS_DENIED; + + grub_auth_authenticate (user); + + return GRUB_ERR_NONE; +} + +static inline int +ib64t (char c) +{ + if (c == '.') + return 0; + if (c == '/') + return 1; + if (c >= '0' && c <= '9') + return c - '0' + 2; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 12; + if (c >= 'a' && c <= 'z') + return c - 'a' + 38; + return -1; +} + +static struct legacy_md5_password * +parse_legacy_md5 (int argc, char **args) +{ + const char *salt, *saltend; + struct legacy_md5_password *pw = NULL; + int i; + const char *p; + + if (grub_memcmp (args[0], "--md5", sizeof ("--md5")) != 0) + goto fail; + if (argc == 1) + goto fail; + if (grub_strlen(args[1]) <= 3) + goto fail; + salt = args[1]; + saltend = grub_strchr (salt + 3, '$'); + if (!saltend) + goto fail; + pw = grub_malloc (sizeof (*pw)); + if (!pw) + goto fail; + + p = saltend + 1; + for (i = 0; i < 5; i++) + { + int n; + grub_uint32_t w = 0; + + for (n = 0; n < 4; n++) + { + int ww = ib64t(*p++); + if (ww == -1) + goto fail; + w |= ww << (n * 6); + } + pw->hash[i == 4 ? 5 : 12+i] = w & 0xff; + pw->hash[6+i] = (w >> 8) & 0xff; + pw->hash[i] = (w >> 16) & 0xff; + } + { + int n; + grub_uint32_t w = 0; + for (n = 0; n < 2; n++) + { + int ww = ib64t(*p++); + if (ww == -1) + goto fail; + w |= ww << (6 * n); + } + if (w >= 0x100) + goto fail; + pw->hash[11] = w; + } + + pw->saltlen = saltend - salt; + pw->salt = (grub_uint8_t *) grub_strndup (salt, pw->saltlen); + if (!pw->salt) + goto fail; + + return pw; + + fail: + grub_free (pw); + return NULL; +} + +static grub_err_t +grub_cmd_legacy_password (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + struct legacy_md5_password *pw = NULL; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + if (args[0][0] != '-' || args[0][1] != '-') + return grub_normal_set_password ("legacy", args[0]); + + pw = parse_legacy_md5 (argc, args); + + if (pw) + return grub_auth_register_authentication ("legacy", check_password_md5, pw); + else + /* This is to imitate minor difference between grub-legacy in GRUB2. + If 2 password commands are executed in a row and second one fails + on GRUB2 the password of first one is used, whereas in grub-legacy + authenthication is denied. In case of no password command was executed + early both versions deny any access. */ + return grub_auth_register_authentication ("legacy", check_password_deny, + NULL); +} + +int +grub_legacy_check_md5_password (int argc, char **args, + char *entered) +{ + struct legacy_md5_password *pw = NULL; + int ret; + + if (args[0][0] != '-' || args[0][1] != '-') + { + char correct[GRUB_AUTH_MAX_PASSLEN]; + + grub_memset (correct, 0, sizeof (correct)); + grub_strncpy (correct, args[0], sizeof (correct)); + + return grub_crypto_memcmp (entered, correct, GRUB_AUTH_MAX_PASSLEN) == 0; + } + + pw = parse_legacy_md5 (argc, args); + + if (!pw) + return 0; + + ret = check_password_md5_real (entered, pw); + grub_free (pw); + return ret; +} + +static grub_err_t +grub_cmd_legacy_check_password (struct grub_command *mycmd __attribute__ ((unused)), + int argc, char **args) +{ + char entered[GRUB_AUTH_MAX_PASSLEN]; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + grub_puts_ (N_("Enter password: ")); + if (!grub_password_get (entered, GRUB_AUTH_MAX_PASSLEN)) + return GRUB_ACCESS_DENIED; + + if (!grub_legacy_check_md5_password (argc, args, + entered)) + return GRUB_ACCESS_DENIED; + + return GRUB_ERR_NONE; +} + +static grub_command_t cmd_source, cmd_configfile; +static grub_command_t cmd_source_extract, cmd_configfile_extract; +static grub_command_t cmd_kernel, cmd_initrd, cmd_initrdnounzip; +static grub_command_t cmd_password, cmd_check_password; + +GRUB_MOD_INIT(legacycfg) +{ + cmd_source + = grub_register_command ("legacy_source", + grub_cmd_legacy_source, + N_("FILE"), + /* TRANSLATORS: "legacy config" means + "config as used by grub-legacy". */ + N_("Parse legacy config in same context")); + cmd_configfile + = grub_register_command ("legacy_configfile", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in new context")); + cmd_source_extract + = grub_register_command ("extract_legacy_entries_source", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in same context taking only menu entries")); + cmd_configfile_extract + = grub_register_command ("extract_legacy_entries_configfile", + grub_cmd_legacy_source, + N_("FILE"), + N_("Parse legacy config in new context taking only menu entries")); + + cmd_kernel = grub_register_command ("legacy_kernel", + grub_cmd_legacy_kernel, + N_("[--no-mem-option] [--type=TYPE] FILE [ARG ...]"), + N_("Simulate grub-legacy `kernel' command")); + + cmd_initrd = grub_register_command ("legacy_initrd", + grub_cmd_legacy_initrd, + N_("FILE [ARG ...]"), + N_("Simulate grub-legacy `initrd' command")); + cmd_initrdnounzip = grub_register_command ("legacy_initrd_nounzip", + grub_cmd_legacy_initrdnounzip, + N_("FILE [ARG ...]"), + N_("Simulate grub-legacy `modulenounzip' command")); + + cmd_password = grub_register_command ("legacy_password", + grub_cmd_legacy_password, + N_("[--md5] PASSWD [FILE]"), + N_("Simulate grub-legacy `password' command")); + + cmd_check_password = grub_register_command ("legacy_check_password", + grub_cmd_legacy_check_password, + N_("[--md5] PASSWD [FILE]"), + N_("Simulate grub-legacy `password' command in menu entry mode")); + +} + +GRUB_MOD_FINI(legacycfg) +{ + grub_unregister_command (cmd_source); + grub_unregister_command (cmd_configfile); + grub_unregister_command (cmd_source_extract); + grub_unregister_command (cmd_configfile_extract); + + grub_unregister_command (cmd_kernel); + grub_unregister_command (cmd_initrd); + grub_unregister_command (cmd_initrdnounzip); + + grub_unregister_command (cmd_password); + grub_unregister_command (cmd_check_password); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c new file mode 100644 index 00000000..163b9a09 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.c @@ -0,0 +1,397 @@ +/* loadenv.c - command to load/save environment variable. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "loadenv.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +static const struct grub_arg_option options[] = + { + /* TRANSLATORS: This option is used to override default filename + for loading and storing environment. */ + {"file", 'f', 0, N_("Specify filename."), 0, ARG_TYPE_PATHNAME}, + {"skip-sig", 's', 0, + N_("Skip signature-checking of the environment file."), 0, ARG_TYPE_NONE}, + {0, 0, 0, 0, 0, 0} + }; + +/* Opens 'filename' with compression filters disabled. Optionally disables the + PUBKEY filter (that insists upon properly signed files) as well. PUBKEY + filter is restored before the function returns. */ +static grub_file_t +open_envblk_file (char *filename, + enum grub_file_type type) +{ + grub_file_t file; + char *buf = 0; + + if (! filename) + { + const char *prefix; + int len; + + prefix = grub_env_get ("prefix"); + if (! prefix) + { + grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix"); + return 0; + } + + len = grub_strlen (prefix); + buf = grub_malloc (len + 1 + sizeof (GRUB_ENVBLK_DEFCFG)); + if (! buf) + return 0; + filename = buf; + + grub_strcpy (filename, prefix); + filename[len] = '/'; + grub_strcpy (filename + len + 1, GRUB_ENVBLK_DEFCFG); + } + + file = grub_file_open (filename, type); + + grub_free (buf); + return file; +} + +static grub_err_t +grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + grub_envblk_t envblk; + grub_env_whitelist_t whitelist; + + whitelist.len = argc; + whitelist.list = args; + + /* state[0] is the -f flag; state[1] is the --skip-sig flag */ + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_LOADENV + | (state[1].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); + if (! file) + return grub_errno; + + envblk = read_envblk_file (file); + if (! envblk) + goto fail; + + /* argc > 0 indicates caller provided a whitelist of variables to read. */ + grub_envblk_iterate (envblk, argc > 0 ? &whitelist : 0, set_var); + grub_envblk_close (envblk); + + fail: + grub_file_close (file); + return grub_errno; +} + +/* Print all variables in current context. */ +static int +print_var (const char *name, const char *value, + void *hook_data __attribute__ ((unused))) +{ + grub_printf ("%s=%s\n", name, value); + return 0; +} + +static grub_err_t +grub_cmd_list_env (grub_extcmd_context_t ctxt, + int argc __attribute__ ((unused)), + char **args __attribute__ ((unused))) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + grub_envblk_t envblk; + + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_LOADENV + | (state[1].set + ? GRUB_FILE_TYPE_SKIP_SIGNATURE : GRUB_FILE_TYPE_NONE)); + if (! file) + return grub_errno; + + envblk = read_envblk_file (file); + if (! envblk) + goto fail; + + grub_envblk_iterate (envblk, NULL, print_var); + grub_envblk_close (envblk); + + fail: + grub_file_close (file); + return grub_errno; +} + +/* Used to maintain a variable length of blocklists internally. */ +struct blocklist +{ + grub_disk_addr_t sector; + unsigned offset; + unsigned length; + struct blocklist *next; +}; + +static void +free_blocklists (struct blocklist *p) +{ + struct blocklist *q; + + for (; p; p = q) + { + q = p->next; + grub_free (p); + } +} + +static grub_err_t +check_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, + grub_file_t file) +{ + grub_size_t total_length; + grub_size_t index; + grub_disk_t disk; + grub_disk_addr_t part_start; + struct blocklist *p; + char *buf; + + /* Sanity checks. */ + total_length = 0; + for (p = blocklists; p; p = p->next) + { + struct blocklist *q; + /* Check if any pair of blocks overlap. */ + for (q = p->next; q; q = q->next) + { + grub_disk_addr_t s1, s2; + grub_disk_addr_t e1, e2; + + s1 = p->sector; + e1 = s1 + ((p->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + + s2 = q->sector; + e2 = s2 + ((q->length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + + if (s1 < e2 && s2 < e1) + { + /* This might be actually valid, but it is unbelievable that + any filesystem makes such a silly allocation. */ + return grub_error (GRUB_ERR_BAD_FS, "malformed file"); + } + } + + total_length += p->length; + } + + if (total_length != grub_file_size (file)) + { + /* Maybe sparse, unallocated sectors. No way in GRUB. */ + return grub_error (GRUB_ERR_BAD_FILE_TYPE, "sparse file not allowed"); + } + + /* One more sanity check. Re-read all sectors by blocklists, and compare + those with the data read via a file. */ + disk = file->device->disk; + + part_start = grub_partition_get_start (disk->partition); + + buf = grub_envblk_buffer (envblk); + char *blockbuf = NULL; + grub_size_t blockbuf_len = 0; + for (p = blocklists, index = 0; p; index += p->length, p = p->next) + { + if (p->length > blockbuf_len) + { + grub_free (blockbuf); + blockbuf_len = 2 * p->length; + blockbuf = grub_malloc (blockbuf_len); + if (!blockbuf) + return grub_errno; + } + + if (grub_disk_read (disk, p->sector - part_start, + p->offset, p->length, blockbuf)) + return grub_errno; + + if (grub_memcmp (buf + index, blockbuf, p->length) != 0) + return grub_error (GRUB_ERR_FILE_READ_ERROR, "invalid blocklist"); + } + + return GRUB_ERR_NONE; +} + +static int +write_blocklists (grub_envblk_t envblk, struct blocklist *blocklists, + grub_file_t file) +{ + char *buf; + grub_disk_t disk; + grub_disk_addr_t part_start; + struct blocklist *p; + grub_size_t index; + + buf = grub_envblk_buffer (envblk); + disk = file->device->disk; + part_start = grub_partition_get_start (disk->partition); + + index = 0; + for (p = blocklists; p; index += p->length, p = p->next) + { + if (grub_disk_write (disk, p->sector - part_start, + p->offset, p->length, buf + index)) + return 0; + } + + return 1; +} + +/* Context for grub_cmd_save_env. */ +struct grub_cmd_save_env_ctx +{ + struct blocklist *head, *tail; +}; + +/* Store blocklists in a linked list. */ +static void +save_env_read_hook (grub_disk_addr_t sector, unsigned offset, unsigned length, + void *data) +{ + struct grub_cmd_save_env_ctx *ctx = data; + struct blocklist *block; + + block = grub_malloc (sizeof (*block)); + if (! block) + return; + + block->sector = sector; + block->offset = offset; + block->length = length; + + /* Slightly complicated, because the list should be FIFO. */ + block->next = 0; + if (ctx->tail) + ctx->tail->next = block; + ctx->tail = block; + if (! ctx->head) + ctx->head = block; +} + +static grub_err_t +grub_cmd_save_env (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + grub_envblk_t envblk; + struct grub_cmd_save_env_ctx ctx = { + .head = 0, + .tail = 0 + }; + + if (! argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no variable is specified"); + + file = open_envblk_file ((state[0].set) ? state[0].arg : 0, + GRUB_FILE_TYPE_SAVEENV + | GRUB_FILE_TYPE_SKIP_SIGNATURE); + if (! file) + return grub_errno; + + if (! file->device->disk) + { + grub_file_close (file); + return grub_error (GRUB_ERR_BAD_DEVICE, "disk device required"); + } + + file->read_hook = save_env_read_hook; + file->read_hook_data = &ctx; + envblk = read_envblk_file (file); + file->read_hook = 0; + if (! envblk) + goto fail; + + if (check_blocklists (envblk, ctx.head, file)) + goto fail; + + while (argc) + { + const char *value; + + value = grub_env_get (args[0]); + if (value) + { + if (! grub_envblk_set (envblk, args[0], value)) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, "environment block too small"); + goto fail; + } + } + else + grub_envblk_delete (envblk, args[0]); + + argc--; + args++; + } + + write_blocklists (envblk, ctx.head, file); + + fail: + if (envblk) + grub_envblk_close (envblk); + free_blocklists (ctx.head); + grub_file_close (file); + return grub_errno; +} + +static grub_extcmd_t cmd_load, cmd_list, cmd_save; + +GRUB_MOD_INIT(loadenv) +{ + cmd_load = + grub_register_extcmd ("load_env", grub_cmd_load_env, 0, + N_("[-f FILE] [-s|--skip-sig] [variable_name_to_whitelist] [...]"), + N_("Load variables from environment block file."), + options); + cmd_list = + grub_register_extcmd ("list_env", grub_cmd_list_env, 0, N_("[-f FILE]"), + N_("List variables from environment block file."), + options); + cmd_save = + grub_register_extcmd ("save_env", grub_cmd_save_env, 0, + N_("[-f FILE] variable_name [...]"), + N_("Save variables to environment block file."), + options); +} + +GRUB_MOD_FINI(loadenv) +{ + grub_unregister_extcmd (cmd_load); + grub_unregister_extcmd (cmd_list); + grub_unregister_extcmd (cmd_save); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h new file mode 100644 index 00000000..952f4612 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/loadenv.h @@ -0,0 +1,93 @@ +/* loadenv.c - command to load/save environment variable. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +static grub_envblk_t UNUSED +read_envblk_file (grub_file_t file) +{ + grub_off_t offset = 0; + char *buf; + grub_size_t size = grub_file_size (file); + grub_envblk_t envblk; + + buf = grub_malloc (size); + if (! buf) + return 0; + + while (size > 0) + { + grub_ssize_t ret; + + ret = grub_file_read (file, buf + offset, size); + if (ret <= 0) + { + grub_free (buf); + return 0; + } + + size -= ret; + offset += ret; + } + + envblk = grub_envblk_open (buf, offset); + if (! envblk) + { + grub_free (buf); + grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); + return 0; + } + + return envblk; +} + +struct grub_env_whitelist +{ + grub_size_t len; + char **list; +}; +typedef struct grub_env_whitelist grub_env_whitelist_t; + +static int UNUSED +test_whitelist_membership (const char* name, + const grub_env_whitelist_t* whitelist) +{ + grub_size_t i; + + for (i = 0; i < whitelist->len; i++) + if (grub_strcmp (name, whitelist->list[i]) == 0) + return 1; /* found it */ + + return 0; /* not found */ +} + +/* Helper for grub_cmd_load_env. */ +static int UNUSED +set_var (const char *name, const char *value, void *whitelist) +{ + if (! whitelist) + { + grub_env_set (name, value); + return 0; + } + + if (test_whitelist_membership (name, + (const grub_env_whitelist_t *) whitelist)) + grub_env_set (name, value); + + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c new file mode 100644 index 00000000..9faf2be0 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/menuentry.c @@ -0,0 +1,349 @@ +/* menuentry.c - menuentry command */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +static const struct grub_arg_option options[] = + { + {"class", 1, GRUB_ARG_OPTION_REPEATABLE, + N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, + {"users", 2, 0, + N_("List of users allowed to boot this entry."), N_("USERNAME[,USERNAME]"), + ARG_TYPE_STRING}, + {"hotkey", 3, 0, + N_("Keyboard key to quickly boot this entry."), N_("KEYBOARD_KEY"), ARG_TYPE_STRING}, + {"source", 4, 0, + N_("Use STRING as menu entry body."), N_("STRING"), ARG_TYPE_STRING}, + {"id", 0, 0, N_("Menu entry identifier."), N_("STRING"), ARG_TYPE_STRING}, + /* TRANSLATORS: menu entry can either be bootable by anyone or only by + handful of users. By default when security is active only superusers can + boot a given menu entry. With --unrestricted (this option) + anyone can boot it. */ + {"unrestricted", 0, 0, N_("This entry can be booted by any user."), + 0, ARG_TYPE_NONE}, + {0, 0, 0, 0, 0, 0} + }; + +static struct +{ + const char *name; + int key; +} hotkey_aliases[] = + { + {"backspace", GRUB_TERM_BACKSPACE}, + {"tab", GRUB_TERM_TAB}, + {"delete", GRUB_TERM_KEY_DC}, + {"insert", GRUB_TERM_KEY_INSERT}, + {"f1", GRUB_TERM_KEY_F1}, + {"f2", GRUB_TERM_KEY_F2}, + {"f3", GRUB_TERM_KEY_F3}, + {"f4", GRUB_TERM_KEY_F4}, + {"f5", GRUB_TERM_KEY_F5}, + {"f6", GRUB_TERM_KEY_F6}, + {"f7", GRUB_TERM_KEY_F7}, + {"f8", GRUB_TERM_KEY_F8}, + {"f9", GRUB_TERM_KEY_F9}, + {"f10", GRUB_TERM_KEY_F10}, + {"f11", GRUB_TERM_KEY_F11}, + {"f12", GRUB_TERM_KEY_F12}, + }; + +/* Add a menu entry to the current menu context (as given by the environment + variable data slot `menu'). As the configuration file is read, the script + parser calls this when a menu entry is to be created. */ +grub_err_t +grub_normal_add_menu_entry (int argc, const char **args, + char **classes, const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, + int submenu, int *index, struct bls_entry *bls) +{ + int menu_hotkey = 0; + char **menu_args = NULL; + char *menu_users = NULL; + char *menu_title = NULL; + char *menu_sourcecode = NULL; + char *menu_id = NULL; + struct grub_menu_entry_class *menu_classes = NULL; + + grub_menu_t menu; + grub_menu_entry_t *last; + + menu = grub_env_get_menu (); + if (! menu) + return grub_error (GRUB_ERR_MENU, "no menu context"); + + last = &menu->entry_list; + + menu_sourcecode = grub_xasprintf ("%s%s", prefix ?: "", sourcecode); + if (! menu_sourcecode) + return grub_errno; + + if (classes && classes[0]) + { + int i; + for (i = 0; classes[i]; i++); /* count # of menuentry classes */ + menu_classes = grub_zalloc (sizeof (struct grub_menu_entry_class) + * (i + 1)); + if (! menu_classes) + goto fail; + + for (i = 0; classes[i]; i++) + { + menu_classes[i].name = grub_strdup (classes[i]); + if (! menu_classes[i].name) + goto fail; + menu_classes[i].next = classes[i + 1] ? &menu_classes[i + 1] : NULL; + } + } + + if (users) + { + menu_users = grub_strdup (users); + if (! menu_users) + goto fail; + } + + if (hotkey) + { + unsigned i; + for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++) + if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0) + { + menu_hotkey = hotkey_aliases[i].key; + break; + } + if (i == ARRAY_SIZE (hotkey_aliases)) + menu_hotkey = hotkey[0]; + } + + if (! argc) + { + grub_error (GRUB_ERR_MENU, "menuentry is missing title"); + goto fail; + } + + menu_title = grub_strdup (args[0]); + if (! menu_title) + goto fail; + + grub_dprintf ("menu", "id:\"%s\"\n", id); + grub_dprintf ("menu", "title:\"%s\"\n", menu_title); + menu_id = grub_strdup (id ? : menu_title); + if (! menu_id) + goto fail; + grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id); + + /* Save argc, args to pass as parameters to block arg later. */ + menu_args = grub_malloc (sizeof (char*) * (argc + 1)); + if (! menu_args) + goto fail; + + { + int i; + for (i = 0; i < argc; i++) + { + menu_args[i] = grub_strdup (args[i]); + if (! menu_args[i]) + goto fail; + } + menu_args[argc] = NULL; + } + + /* Add the menu entry at the end of the list. */ + int ind=0; + while (*last) + { + ind++; + last = &(*last)->next; + } + + *last = grub_zalloc (sizeof (**last)); + if (! *last) + goto fail; + + (*last)->title = menu_title; + (*last)->id = menu_id; + (*last)->hotkey = menu_hotkey; + (*last)->classes = menu_classes; + if (menu_users) + (*last)->restricted = 1; + (*last)->users = menu_users; + (*last)->argc = argc; + (*last)->args = menu_args; + (*last)->sourcecode = menu_sourcecode; + (*last)->submenu = submenu; + (*last)->bls = bls; + + menu->size++; + if (index) + *index = ind; + return GRUB_ERR_NONE; + + fail: + + grub_free (menu_sourcecode); + { + int i; + for (i = 0; menu_classes && menu_classes[i].name; i++) + grub_free (menu_classes[i].name); + grub_free (menu_classes); + } + + { + int i; + for (i = 0; menu_args && menu_args[i]; i++) + grub_free (menu_args[i]); + grub_free (menu_args); + } + + grub_free (menu_users); + grub_free (menu_title); + grub_free (menu_id); + return grub_errno; +} + +static char * +setparams_prefix (int argc, char **args) +{ + int i; + int j; + char *p; + char *result; + grub_size_t len = 10; + + /* Count resulting string length */ + for (i = 0; i < argc; i++) + { + len += 3; /* 3 = 1 space + 2 quotes */ + p = args[i]; + while (*p) + len += (*p++ == '\'' ? 3 : 1); + } + + result = grub_malloc (len + 2); + if (! result) + return 0; + + grub_strcpy (result, "setparams"); + p = result + 9; + + for (j = 0; j < argc; j++) + { + *p++ = ' '; + *p++ = '\''; + p = grub_strchrsub (p, args[j], '\'', "'\\''"); + *p++ = '\''; + } + *p++ = '\n'; + *p = '\0'; + return result; +} + +static grub_err_t +grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) +{ + char ch; + char *src; + char *prefix; + unsigned len; + grub_err_t r; + const char *users; + + if (! argc) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "missing arguments"); + + if (ctxt->state[3].set && ctxt->script) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "multiple menuentry definitions"); + + if (! ctxt->state[3].set && ! ctxt->script) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition"); + + if (ctxt->state[1].set) + users = ctxt->state[1].arg; + else if (ctxt->state[5].set) + users = NULL; + else + users = ""; + + if (! ctxt->script) + return grub_normal_add_menu_entry (argc, (const char **) args, + (ctxt->state[0].set ? ctxt->state[0].args + : NULL), + ctxt->state[4].arg, + users, + ctxt->state[2].arg, 0, + ctxt->state[3].arg, + ctxt->extcmd->cmd->name[0] == 's', + NULL, NULL); + + src = args[argc - 1]; + args[argc - 1] = NULL; + + len = grub_strlen(src); + ch = src[len - 1]; + src[len - 1] = '\0'; + + prefix = setparams_prefix (argc - 1, args); + if (! prefix) + return grub_errno; + + r = grub_normal_add_menu_entry (argc - 1, (const char **) args, + ctxt->state[0].args, ctxt->state[4].arg, + users, + ctxt->state[2].arg, prefix, src + 1, + ctxt->extcmd->cmd->name[0] == 's', NULL, + NULL); + + src[len - 1] = ch; + args[argc - 1] = src; + grub_free (prefix); + return r; +} + +static grub_extcmd_t cmd, cmd_sub; + +void +grub_menu_init (void) +{ + cmd = grub_register_extcmd ("menuentry", grub_cmd_menuentry, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_ACCEPT_DASH + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), N_("Define a menu entry."), options); + cmd_sub = grub_register_extcmd ("submenu", grub_cmd_menuentry, + GRUB_COMMAND_FLAG_BLOCKS + | GRUB_COMMAND_ACCEPT_DASH + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), N_("Define a submenu."), + options); +} + +void +grub_menu_fini (void) +{ + grub_unregister_extcmd (cmd); + grub_unregister_extcmd (cmd_sub); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c new file mode 100644 index 00000000..3852c0c7 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/commands/search.c @@ -0,0 +1,353 @@ +/* search.c - search devices based on a file or a filesystem label */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_no_vtoyefi_part = 0; +static char g_vtoyefi_dosname[64]; +static char g_vtoyefi_gptname[64]; + +struct cache_entry +{ + struct cache_entry *next; + char *key; + char *value; +}; + +static struct cache_entry *cache; + +/* Context for FUNC_NAME. */ +struct search_ctx +{ + const char *key; + const char *var; + int no_floppy; + char **hints; + unsigned nhints; + int count; + int is_cache; +}; + +/* Helper for FUNC_NAME. */ +static int +iterate_device (const char *name, void *data) +{ + struct search_ctx *ctx = data; + int found = 0; + + /* Skip floppy drives when requested. */ + if (ctx->no_floppy && + name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') + return 1; + + if (g_no_vtoyefi_part && (grub_strcmp(name, g_vtoyefi_dosname) == 0 || grub_strcmp(name, g_vtoyefi_gptname) == 0)) { + return 0; + } + +#ifdef DO_SEARCH_FS_UUID +#define compare_fn grub_strcasecmp +#else +#define compare_fn grub_strcmp +#endif + +#ifdef DO_SEARCH_FILE + { + char *buf; + grub_file_t file; + + buf = grub_xasprintf ("(%s)%s", name, ctx->key); + if (! buf) + return 1; + + file = grub_file_open (buf, GRUB_FILE_TYPE_FS_SEARCH + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (file) + { + found = 1; + grub_file_close (file); + } + grub_free (buf); + } +#else + { + /* SEARCH_FS_UUID or SEARCH_LABEL */ + grub_device_t dev; + grub_fs_t fs; + char *quid; + + dev = grub_device_open (name); + if (dev) + { + fs = grub_fs_probe (dev); + +#ifdef DO_SEARCH_FS_UUID +#define read_fn fs_uuid +#else +#define read_fn fs_label +#endif + + if (fs && fs->read_fn) + { + fs->read_fn (dev, &quid); + + if (grub_errno == GRUB_ERR_NONE && quid) + { + if (compare_fn (quid, ctx->key) == 0) + found = 1; + + grub_free (quid); + } + } + + grub_device_close (dev); + } + } +#endif + + if (!ctx->is_cache && found && ctx->count == 0) + { + struct cache_entry *cache_ent; + cache_ent = grub_malloc (sizeof (*cache_ent)); + if (cache_ent) + { + cache_ent->key = grub_strdup (ctx->key); + cache_ent->value = grub_strdup (name); + if (cache_ent->value && cache_ent->key) + { + cache_ent->next = cache; + cache = cache_ent; + } + else + { + grub_free (cache_ent->value); + grub_free (cache_ent->key); + grub_free (cache_ent); + grub_errno = GRUB_ERR_NONE; + } + } + else + grub_errno = GRUB_ERR_NONE; + } + + if (found) + { + ctx->count++; + if (ctx->var) + grub_env_set (ctx->var, name); + else + grub_printf (" %s", name); + } + + grub_errno = GRUB_ERR_NONE; + return (found && ctx->var); +} + +/* Helper for FUNC_NAME. */ +static int +part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) +{ + struct search_ctx *ctx = data; + char *partition_name, *devname; + int ret; + + partition_name = grub_partition_get_name (partition); + if (! partition_name) + return 1; + + devname = grub_xasprintf ("%s,%s", disk->name, partition_name); + grub_free (partition_name); + if (!devname) + return 1; + ret = iterate_device (devname, ctx); + grub_free (devname); + + return ret; +} + +/* Helper for FUNC_NAME. */ +static void +try (struct search_ctx *ctx) +{ + unsigned i; + struct cache_entry **prev; + struct cache_entry *cache_ent; + + for (prev = &cache, cache_ent = *prev; cache_ent; + prev = &cache_ent->next, cache_ent = *prev) + if (compare_fn (cache_ent->key, ctx->key) == 0) + break; + if (cache_ent) + { + ctx->is_cache = 1; + if (iterate_device (cache_ent->value, ctx)) + { + ctx->is_cache = 0; + return; + } + ctx->is_cache = 0; + /* Cache entry was outdated. Remove it. */ + if (!ctx->count) + { + *prev = cache_ent->next; + grub_free (cache_ent->key); + grub_free (cache_ent->value); + grub_free (cache_ent); + } + } + + for (i = 0; i < ctx->nhints; i++) + { + char *end; + if (!ctx->hints[i][0]) + continue; + end = ctx->hints[i] + grub_strlen (ctx->hints[i]) - 1; + if (*end == ',') + *end = 0; + if (iterate_device (ctx->hints[i], ctx)) + { + if (!*end) + *end = ','; + return; + } + if (!*end) + { + grub_device_t dev; + int ret; + dev = grub_device_open (ctx->hints[i]); + if (!dev) + { + if (!*end) + *end = ','; + continue; + } + if (!dev->disk) + { + grub_device_close (dev); + if (!*end) + *end = ','; + continue; + } + ret = grub_partition_iterate (dev->disk, part_hook, ctx); + if (!*end) + *end = ','; + grub_device_close (dev); + if (ret) + return; + } + } + grub_device_iterate (iterate_device, ctx); +} + +void +FUNC_NAME (const char *key, const char *var, int no_floppy, + char **hints, unsigned nhints) +{ + struct search_ctx ctx = { + .key = key, + .var = var, + .no_floppy = no_floppy, + .hints = hints, + .nhints = nhints, + .count = 0, + .is_cache = 0 + }; + grub_fs_autoload_hook_t saved_autoload; + + g_no_vtoyefi_part = 0; + if (grub_env_get("VTOY_SEARCH_NO_VTOYEFI")) + { + grub_snprintf(g_vtoyefi_dosname, sizeof(g_vtoyefi_dosname), "%s,msdos2", grub_env_get("vtoydev")); + grub_snprintf(g_vtoyefi_gptname, sizeof(g_vtoyefi_gptname), "%s,gpt2", grub_env_get("vtoydev")); + g_no_vtoyefi_part = 1; + } + + /* First try without autoloading if we're setting variable. */ + if (var) + { + saved_autoload = grub_fs_autoload_hook; + grub_fs_autoload_hook = 0; + try (&ctx); + + /* Restore autoload hook. */ + grub_fs_autoload_hook = saved_autoload; + + /* Retry with autoload if nothing found. */ + if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) + try (&ctx); + } + else + try (&ctx); + + if (grub_errno == GRUB_ERR_NONE && ctx.count == 0) + grub_error (GRUB_ERR_FILE_NOT_FOUND, "no such device: %s", key); +} + +static grub_err_t +grub_cmd_do_search (grub_command_t cmd __attribute__ ((unused)), int argc, + char **args) +{ + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); + + FUNC_NAME (args[0], argc == 1 ? 0 : args[1], 0, (args + 2), + argc > 2 ? argc - 2 : 0); + + return grub_errno; +} + +static grub_command_t cmd; + +#ifdef DO_SEARCH_FILE +GRUB_MOD_INIT(search_fs_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_INIT(search_fs_uuid) +#else +GRUB_MOD_INIT(search_label) +#endif +{ + cmd = + grub_register_command (COMMAND_NAME, grub_cmd_do_search, + N_("NAME [VARIABLE] [HINTS]"), + HELP_MESSAGE); +} + +#ifdef DO_SEARCH_FILE +GRUB_MOD_FINI(search_fs_file) +#elif defined (DO_SEARCH_FS_UUID) +GRUB_MOD_FINI(search_fs_uuid) +#else +GRUB_MOD_FINI(search_label) +#endif +{ + grub_unregister_command (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c new file mode 100644 index 00000000..ef946a49 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/disk/loopback.c @@ -0,0 +1,257 @@ +/* loopback.c - command to add loopback devices. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +struct grub_loopback +{ + char *devname; + grub_file_t file; + struct grub_loopback *next; + unsigned long id; + grub_off_t skip; +}; + +static struct grub_loopback *loopback_list; +static unsigned long last_id = 0; + +static const struct grub_arg_option options[] = + { + /* TRANSLATORS: The disk is simply removed from the list of available ones, + not wiped, avoid to scare user. */ + {"delete", 'd', 0, N_("Delete the specified loopback drive."), 0, 0}, + {"skip", 's', 0, "skip sectors of the file.", "SECTORS", ARG_TYPE_INT }, + {0, 0, 0, 0, 0, 0} + }; + +/* Delete the loopback device NAME. */ +static grub_err_t +delete_loopback (const char *name) +{ + struct grub_loopback *dev; + struct grub_loopback **prev; + + /* Search for the device. */ + for (dev = loopback_list, prev = &loopback_list; + dev; + prev = &dev->next, dev = dev->next) + if (grub_strcmp (dev->devname, name) == 0) + break; + + if (! dev) + return grub_error (GRUB_ERR_BAD_DEVICE, "device not found"); + + /* Remove the device from the list. */ + *prev = dev->next; + + grub_free (dev->devname); + grub_file_close (dev->file); + grub_free (dev); + + return 0; +} + +/* The command to add and remove loopback devices. */ +static grub_err_t +grub_cmd_loopback (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + grub_file_t file; + struct grub_loopback *newdev; + grub_err_t ret; + grub_off_t skip = 0; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); + + /* Check if `-d' was used. */ + if (state[0].set) + return delete_loopback (args[0]); + + if (state[1].set) + skip = (grub_off_t)grub_strtoull(state[1].arg, NULL, 10); + + if (argc < 2) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + file = grub_file_open (args[1], GRUB_FILE_TYPE_LOOPBACK + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (! file) + return grub_errno; + + /* First try to replace the old device. */ + for (newdev = loopback_list; newdev; newdev = newdev->next) + if (grub_strcmp (newdev->devname, args[0]) == 0) + break; + + if (newdev) + { + grub_file_close (newdev->file); + newdev->file = file; + newdev->skip = skip; + + return 0; + } + + /* Unable to replace it, make a new entry. */ + newdev = grub_malloc (sizeof (struct grub_loopback)); + if (! newdev) + goto fail; + + newdev->devname = grub_strdup (args[0]); + if (! newdev->devname) + { + grub_free (newdev); + goto fail; + } + + newdev->file = file; + newdev->skip = skip; + newdev->id = last_id++; + + /* Add the new entry to the list. */ + newdev->next = loopback_list; + loopback_list = newdev; + + return 0; + +fail: + ret = grub_errno; + grub_file_close (file); + return ret; +} + + +static int +grub_loopback_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, + grub_disk_pull_t pull) +{ + struct grub_loopback *d; + if (pull != GRUB_DISK_PULL_NONE) + return 0; + for (d = loopback_list; d; d = d->next) + { + if (hook (d->devname, hook_data)) + return 1; + } + return 0; +} + +static grub_err_t +grub_loopback_open (const char *name, grub_disk_t disk) +{ + struct grub_loopback *dev; + + for (dev = loopback_list; dev; dev = dev->next) + if (grub_strcmp (dev->devname, name) == 0) + break; + + if (! dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); + + /* Use the filesize for the disk size, round up to a complete sector. */ + if (dev->file->size != GRUB_FILE_SIZE_UNKNOWN) + disk->total_sectors = ((dev->file->size + GRUB_DISK_SECTOR_SIZE - 1) + / GRUB_DISK_SECTOR_SIZE); + else + disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN; + /* Avoid reading more than 512M. */ + disk->max_agglomerate = 1 << (29 - GRUB_DISK_SECTOR_BITS + - GRUB_DISK_CACHE_BITS); + + disk->id = dev->id; + + disk->data = dev; + + return 0; +} + +static grub_err_t +grub_loopback_read (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) +{ + grub_file_t file = ((struct grub_loopback *) disk->data)->file; + grub_off_t skip = ((struct grub_loopback *) disk->data)->skip; + grub_off_t pos; + + grub_file_seek (file, (sector + skip) << GRUB_DISK_SECTOR_BITS); + + grub_file_read (file, buf, size << GRUB_DISK_SECTOR_BITS); + if (grub_errno) + return grub_errno; + + /* In case there is more data read than there is available, in case + of files that are not a multiple of GRUB_DISK_SECTOR_SIZE, fill + the rest with zeros. */ + pos = (sector + skip + size) << GRUB_DISK_SECTOR_BITS; + if (pos > file->size) + { + grub_size_t amount = pos - file->size; + grub_memset (buf + (size << GRUB_DISK_SECTOR_BITS) - amount, 0, amount); + } + + return 0; +} + +static grub_err_t +grub_loopback_write (grub_disk_t disk __attribute ((unused)), + grub_disk_addr_t sector __attribute ((unused)), + grub_size_t size __attribute ((unused)), + const char *buf __attribute ((unused))) +{ + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + "loopback write is not supported"); +} + +static struct grub_disk_dev grub_loopback_dev = + { + .name = "loopback", + .id = GRUB_DISK_DEVICE_LOOPBACK_ID, + .disk_iterate = grub_loopback_iterate, + .disk_open = grub_loopback_open, + .disk_read = grub_loopback_read, + .disk_write = grub_loopback_write, + .next = 0 + }; + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(loopback) +{ + cmd = grub_register_extcmd ("loopback", grub_cmd_loopback, 0, + N_("[-d] DEVICENAME FILE."), + /* TRANSLATORS: The file itself is not destroyed + or transformed into drive. */ + N_("Make a virtual drive from a file."), options); + grub_disk_dev_register (&grub_loopback_dev); +} + +GRUB_MOD_FINI(loopback) +{ + grub_unregister_extcmd (cmd); + grub_disk_dev_unregister (&grub_loopback_dev); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c index 5785c6f3..9a26bb21 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/fs/iso9660.c @@ -33,6 +33,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); static int g_ventoy_no_joliet = 0; +static int g_ventoy_cur_joliet = 0; static grub_uint64_t g_ventoy_last_read_pos = 0; static grub_uint64_t g_ventoy_last_read_offset = 0; static grub_uint64_t g_ventoy_last_read_dirent_pos = 0; @@ -451,6 +452,7 @@ grub_iso9660_mount (grub_disk_t disk) data->disk = disk; + g_ventoy_cur_joliet = 0; block = 16; do { @@ -484,6 +486,7 @@ grub_iso9660_mount (grub_disk_t disk) if (0 == g_ventoy_no_joliet) { copy_voldesc = 1; data->joliet = 1; + g_ventoy_cur_joliet = 1; } } @@ -735,6 +738,8 @@ grub_iso9660_iterate_dir (grub_fshelp_node_t dir, { if ((dirent.flags & FLAG_TYPE) == FLAG_TYPE_DIR) ctx.type = GRUB_FSHELP_DIR; + else if ((dirent.flags & FLAG_TYPE) == 3) + ctx.type = GRUB_FSHELP_DIR; else ctx.type = GRUB_FSHELP_REG; } @@ -1116,6 +1121,11 @@ void grub_iso9660_set_nojoliet(int nojoliet) g_ventoy_no_joliet = nojoliet; } +int grub_iso9660_is_joliet(void) +{ + return g_ventoy_cur_joliet; +} + grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file) { (void)file; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c index e1c1d478..5e448d27 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/gui_label.c @@ -28,6 +28,8 @@ extern int g_ventoy_memdisk_mode; extern int g_ventoy_iso_raw; +extern int g_ventoy_grub2_mode; +extern int g_ventoy_wimboot_mode; extern int g_ventoy_iso_uefi_drv; static const char *align_options[] = @@ -205,6 +207,12 @@ label_set_property (void *vself, const char *name, const char *value) else if (grub_strcmp (value, "@VTOY_ISO_RAW@") == 0) { value = g_ventoy_iso_raw ? grub_env_get("VTOY_ISO_RAW_STR") : " "; } + else if (grub_strcmp (value, "@VTOY_GRUB2_MODE@") == 0) { + value = g_ventoy_grub2_mode ? grub_env_get("VTOY_GRUB2_MODE_STR") : " "; + } + else if (grub_strcmp (value, "@VTOY_WIMBOOT_MODE@") == 0) { + value = g_ventoy_wimboot_mode ? grub_env_get("VTOY_WIMBOOT_MODE_STR") : " "; + } else if (grub_strcmp (value, "@VTOY_ISO_UEFI_DRV@") == 0) { value = g_ventoy_iso_uefi_drv ? grub_env_get("VTOY_ISO_UEFI_DRV_STR") : " "; } diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c new file mode 100644 index 00000000..cc905ced --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/theme_loader.c @@ -0,0 +1,839 @@ +/* theme_loader.c - Theme file loader for gfxmenu. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_err_t +parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop); + +/* Construct a new box widget using ABSPATTERN to find the pixmap files for + it, storing the new box instance at *BOXPTR. + PATTERN should be of the form: "(hd0,0)/somewhere/style*.png". + The '*' then gets substituted with the various pixmap names that the + box uses. */ +static grub_err_t +recreate_box_absolute (grub_gfxmenu_box_t *boxptr, const char *abspattern) +{ + char *prefix; + char *suffix; + char *star; + grub_gfxmenu_box_t box; + + star = grub_strchr (abspattern, '*'); + if (! star) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "missing `*' in box pixmap pattern `%s'", abspattern); + + /* Prefix: Get the part before the '*'. */ + prefix = grub_malloc (star - abspattern + 1); + if (! prefix) + return grub_errno; + + grub_memcpy (prefix, abspattern, star - abspattern); + prefix[star - abspattern] = '\0'; + + /* Suffix: Everything after the '*' is the suffix. */ + suffix = star + 1; + + box = grub_gfxmenu_create_box (prefix, suffix); + grub_free (prefix); + if (! box) + return grub_errno; + + if (*boxptr) + (*boxptr)->destroy (*boxptr); + *boxptr = box; + return grub_errno; +} + + +/* Construct a new box widget using PATTERN to find the pixmap files for it, + storing the new widget at *BOXPTR. PATTERN should be of the form: + "somewhere/style*.png". The '*' then gets substituted with the various + pixmap names that the widget uses. + + Important! The value of *BOXPTR must be initialized! It must either + (1) Be 0 (a NULL pointer), or + (2) Be a pointer to a valid 'grub_gfxmenu_box_t' instance. + In this case, the previous instance is destroyed. */ +grub_err_t +grub_gui_recreate_box (grub_gfxmenu_box_t *boxptr, + const char *pattern, const char *theme_dir) +{ + char *abspattern; + + /* Check arguments. */ + if (! pattern) + { + /* If no pixmap pattern is given, then just create an empty box. */ + if (*boxptr) + (*boxptr)->destroy (*boxptr); + *boxptr = grub_gfxmenu_create_box (0, 0); + return grub_errno; + } + + if (! theme_dir) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "styled box missing theme directory"); + + /* Resolve to an absolute path. */ + abspattern = grub_resolve_relative_path (theme_dir, pattern); + if (! abspattern) + return grub_errno; + + /* Create the box. */ + recreate_box_absolute (boxptr, abspattern); + grub_free (abspattern); + return grub_errno; +} + +static grub_err_t +theme_get_unsigned_int_from_proportional (const char *value, + unsigned absolute_value, + unsigned int *parsed_value) +{ + grub_err_t err; + grub_fixed_signed_t frac; + signed pixels; + err = parse_proportional_spec (value, &pixels, &frac); + if (err != GRUB_ERR_NONE) + return err; + int result = grub_fixed_sfs_multiply (absolute_value, frac) + pixels; + if (result < 0) + result = 0; + *parsed_value = result; + return GRUB_ERR_NONE; +} + +/* Set the specified property NAME on the view to the given string VALUE. + The caller is responsible for the lifetimes of NAME and VALUE. */ +static grub_err_t +theme_set_string (grub_gfxmenu_view_t view, + const char *name, + const char *value, + const char *theme_dir, + const char *filename, + int line_num, + int col_num) +{ + if (! grub_strcmp ("title-font", name)) + view->title_font = grub_font_get (value); + else if (! grub_strcmp ("message-font", name)) + view->message_font = grub_font_get (value); + else if (! grub_strcmp ("terminal-font", name)) + { + grub_free (view->terminal_font_name); + view->terminal_font_name = grub_strdup (value); + if (! view->terminal_font_name) + return grub_errno; + } + else if (! grub_strcmp ("title-color", name)) + grub_video_parse_color (value, &view->title_color); + else if (! grub_strcmp ("message-color", name)) + grub_video_parse_color (value, &view->message_color); + else if (! grub_strcmp ("message-bg-color", name)) + grub_video_parse_color (value, &view->message_bg_color); + else if (! grub_strcmp ("desktop-image", name)) + { + struct grub_video_bitmap *raw_bitmap; + char *path; + path = grub_resolve_relative_path (theme_dir, value); + if (! path) + return grub_errno; + if (grub_video_bitmap_load (&raw_bitmap, path) != GRUB_ERR_NONE) + { + grub_free (path); + return grub_errno; + } + grub_free(path); + grub_video_bitmap_destroy (view->raw_desktop_image); + view->raw_desktop_image = raw_bitmap; + } + else if (! grub_strcmp ("desktop-image-scale-method", name)) + { + if (! value || ! grub_strcmp ("stretch", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH; + else if (! grub_strcmp ("crop", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_CROP; + else if (! grub_strcmp ("padding", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_PADDING; + else if (! grub_strcmp ("fitwidth", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITWIDTH; + else if (! grub_strcmp ("fitheight", value)) + view->desktop_image_scale_method = + GRUB_VIDEO_BITMAP_SELECTION_METHOD_FITHEIGHT; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unsupported scale method: %s", + value); + } + else if (! grub_strcmp ("desktop-image-h-align", name)) + { + if (! grub_strcmp ("left", value)) + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_LEFT; + else if (! grub_strcmp ("center", value)) + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER; + else if (! grub_strcmp ("right", value)) + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_RIGHT; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unsupported horizontal align method: %s", + value); + } + else if (! grub_strcmp ("desktop-image-v-align", name)) + { + if (! grub_strcmp ("top", value)) + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_TOP; + else if (! grub_strcmp ("center", value)) + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER; + else if (! grub_strcmp ("bottom", value)) + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_BOTTOM; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "Unsupported vertical align method: %s", + value); + } + else if (! grub_strcmp ("desktop-color", name)) + grub_video_parse_color (value, &view->desktop_color); + else if (! grub_strcmp ("terminal-box", name)) + { + grub_err_t err; + err = grub_gui_recreate_box (&view->terminal_box, value, theme_dir); + if (err != GRUB_ERR_NONE) + return err; + } + else if (! grub_strcmp ("terminal-border", name)) + { + view->terminal_border = grub_strtoul (value, 0, 10); + if (grub_errno) + return grub_errno; + } + else if (! grub_strcmp ("terminal-left", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.width, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.x = tmp; + } + else if (! grub_strcmp ("terminal-top", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.height, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.y = tmp; + } + else if (! grub_strcmp ("terminal-width", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.width, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.width = tmp; + } + else if (! grub_strcmp ("terminal-height", name)) + { + unsigned int tmp; + int err = theme_get_unsigned_int_from_proportional (value, + view->screen.height, + &tmp); + if (err != GRUB_ERR_NONE) + return err; + view->terminal_rect.height = tmp; + } + else if (! grub_strcmp ("title-text", name)) + { + grub_free (view->title_text); + view->title_text = grub_strdup (value); + if (! view->title_text) + return grub_errno; + } + else + { + return grub_error (GRUB_ERR_BAD_ARGUMENT, + "%s:%d:%d unknown property `%s'", + filename, line_num, col_num, name); + } + return grub_errno; +} + +struct parsebuf +{ + char *buf; + int pos; + int len; + int line_num; + int col_num; + const char *filename; + char *theme_dir; + grub_gfxmenu_view_t view; +}; + +static int +has_more (struct parsebuf *p) +{ + return p->pos < p->len; +} + +static int +read_char (struct parsebuf *p) +{ + if (has_more (p)) + { + char c; + c = p->buf[p->pos++]; + if (c == '\n') + { + p->line_num++; + p->col_num = 1; + } + else + { + p->col_num++; + } + return c; + } + else + return -1; +} + +static int +peek_char (struct parsebuf *p) +{ + if (has_more (p)) + return p->buf[p->pos]; + else + return -1; +} + +static int +is_whitespace (char c) +{ + return (c == ' ' + || c == '\t' + || c == '\r' + || c == '\n' + || c == '\f'); +} + +static void +skip_whitespace (struct parsebuf *p) +{ + while (has_more (p) && is_whitespace(peek_char (p))) + read_char (p); +} + +static void +advance_to_next_line (struct parsebuf *p) +{ + int c; + + /* Eat characters up to the newline. */ + do + { + c = read_char (p); + } + while (c != -1 && c != '\n'); +} + +static int +is_identifier_char (int c) +{ + return (c != -1 + && (grub_isalpha(c) + || grub_isdigit(c) + || c == '_' + || c == '-')); +} + +static char * +read_identifier (struct parsebuf *p) +{ + /* Index of the first character of the identifier in p->buf. */ + int start; + /* Next index after the last character of the identifer in p->buf. */ + int end; + + skip_whitespace (p); + + /* Capture the start of the identifier. */ + start = p->pos; + + /* Scan for the end. */ + while (is_identifier_char (peek_char (p))) + read_char (p); + end = p->pos; + + if (end - start < 1) + return 0; + + return grub_new_substring (p->buf, start, end); +} + +static char * +read_expression (struct parsebuf *p) +{ + int start; + int end; + + skip_whitespace (p); + if (peek_char (p) == '"') + { + /* Read as a quoted string. + The quotation marks are not included in the expression value. */ + /* Skip opening quotation mark. */ + read_char (p); + start = p->pos; + while (has_more (p) && peek_char (p) != '"') + read_char (p); + end = p->pos; + /* Skip the terminating quotation mark. */ + read_char (p); + } + else if (peek_char (p) == '(') + { + /* Read as a parenthesized string -- for tuples/coordinates. */ + /* The parentheses are included in the expression value. */ + int c; + + start = p->pos; + do + { + c = read_char (p); + } + while (c != -1 && c != ')'); + end = p->pos; + } + else if (has_more (p)) + { + /* Read as a single word -- for numeric values or words without + whitespace. */ + start = p->pos; + while (has_more (p) && ! is_whitespace (peek_char (p))) + read_char (p); + end = p->pos; + } + else + { + /* The end of the theme file has been reached. */ + grub_error (GRUB_ERR_IO, "%s:%d:%d expression expected in theme file", + p->filename, p->line_num, p->col_num); + return 0; + } + + return grub_new_substring (p->buf, start, end); +} + +static grub_err_t +parse_proportional_spec (const char *value, signed *abs, grub_fixed_signed_t *prop) +{ + signed num; + const char *ptr; + int sig = 0; + *abs = 0; + *prop = 0; + ptr = value; + while (*ptr) + { + sig = 0; + + while (*ptr == '-' || *ptr == '+') + { + if (*ptr == '-') + sig = !sig; + ptr++; + } + + num = grub_strtoul (ptr, (char **) &ptr, 0); + if (grub_errno) + return grub_errno; + if (sig) + num = -num; + if (*ptr == '%') + { + *prop += grub_fixed_fsf_divide (grub_signed_to_fixed (num), 100); + ptr++; + } + else + *abs += num; + } + return GRUB_ERR_NONE; +} + + +/* Read a GUI object specification from the theme file. + Any components created will be added to the GUI container PARENT. */ +static grub_err_t +read_object (struct parsebuf *p, grub_gui_container_t parent) +{ + grub_video_rect_t bounds; + + char *name; + name = read_identifier (p); + if (! name) + goto cleanup; + + grub_gui_component_t component = 0; + if (grub_strcmp (name, "label") == 0) + { + component = grub_gui_label_new (); + } + else if (grub_strcmp (name, "image") == 0) + { + component = grub_gui_image_new (); + } + else if (grub_strcmp (name, "vbox") == 0) + { + component = (grub_gui_component_t) grub_gui_vbox_new (); + } + else if (grub_strcmp (name, "hbox") == 0) + { + component = (grub_gui_component_t) grub_gui_hbox_new (); + } + else if (grub_strcmp (name, "canvas") == 0) + { + component = (grub_gui_component_t) grub_gui_canvas_new (); + } + else if (grub_strcmp (name, "progress_bar") == 0) + { + component = grub_gui_progress_bar_new (); + } + else if (grub_strcmp (name, "circular_progress") == 0) + { + component = grub_gui_circular_progress_new (); + } + else if (grub_strcmp (name, "boot_menu") == 0) + { + component = grub_gui_list_new (); + } + else + { + /* Unknown type. */ + grub_error (GRUB_ERR_IO, "%s:%d:%d unknown object type `%s'", + p->filename, p->line_num, p->col_num, name); + goto cleanup; + } + + if (! component) + goto cleanup; + + /* Inform the component about the theme so it can find its resources. */ + component->ops->set_property (component, "theme_dir", p->theme_dir); + component->ops->set_property (component, "theme_path", p->filename); + + /* Add the component as a child of PARENT. */ + bounds.x = 0; + bounds.y = 0; + bounds.width = -1; + bounds.height = -1; + component->ops->set_bounds (component, &bounds); + parent->ops->add (parent, component); + + skip_whitespace (p); + if (read_char (p) != '{') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d expected `{' after object type name `%s'", + p->filename, p->line_num, p->col_num, name); + goto cleanup; + } + + while (has_more (p)) + { + skip_whitespace (p); + + /* Check whether the end has been encountered. */ + if (peek_char (p) == '}') + { + /* Skip the closing brace. */ + read_char (p); + break; + } + + if (peek_char (p) == '#') + { + /* Skip comments. */ + advance_to_next_line (p); + continue; + } + + if (peek_char (p) == '+') + { + /* Skip the '+'. */ + read_char (p); + + /* Check whether this component is a container. */ + if (component->ops->is_instance (component, "container")) + { + /* Read the sub-object recursively and add it as a child. */ + if (read_object (p, (grub_gui_container_t) component) != 0) + goto cleanup; + /* After reading the sub-object, resume parsing, expecting + another property assignment or sub-object definition. */ + continue; + } + else + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d attempted to add object to non-container", + p->filename, p->line_num, p->col_num); + goto cleanup; + } + } + + char *property; + property = read_identifier (p); + if (! property) + { + grub_error (GRUB_ERR_IO, "%s:%d:%d identifier expected in theme file", + p->filename, p->line_num, p->col_num); + goto cleanup; + } + + skip_whitespace (p); + if (read_char (p) != '=') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d expected `=' after property name `%s'", + p->filename, p->line_num, p->col_num, property); + grub_free (property); + goto cleanup; + } + skip_whitespace (p); + + char *value; + value = read_expression (p); + if (! value) + { + grub_free (property); + goto cleanup; + } + + /* Handle the property value. */ + if (grub_strcmp (property, "left") == 0) + parse_proportional_spec (value, &component->x, &component->xfrac); + else if (grub_strcmp (property, "top") == 0) + parse_proportional_spec (value, &component->y, &component->yfrac); + else if (grub_strcmp (property, "width") == 0) + parse_proportional_spec (value, &component->w, &component->wfrac); + else if (grub_strcmp (property, "height") == 0) + parse_proportional_spec (value, &component->h, &component->hfrac); + else + /* General property handling. */ + component->ops->set_property (component, property, value); + + grub_free (value); + grub_free (property); + if (grub_errno != GRUB_ERR_NONE) + goto cleanup; + } + +cleanup: + grub_free (name); + return grub_errno; +} + +static grub_err_t +read_property (struct parsebuf *p) +{ + char *name; + + /* Read the property name. */ + name = read_identifier (p); + if (! name) + { + advance_to_next_line (p); + return grub_errno; + } + + /* Skip whitespace before separator. */ + skip_whitespace (p); + + /* Read separator. */ + if (read_char (p) != ':') + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d missing separator after property name `%s'", + p->filename, p->line_num, p->col_num, name); + goto done; + } + + /* Skip whitespace after separator. */ + skip_whitespace (p); + + /* Get the value based on its type. */ + if (peek_char (p) == '"') + { + /* String value (e.g., '"My string"'). */ + char *value = read_expression (p); + if (! value) + { + grub_error (GRUB_ERR_IO, "%s:%d:%d missing property value", + p->filename, p->line_num, p->col_num); + goto done; + } + /* If theme_set_string results in an error, grub_errno will be returned + below. */ + theme_set_string (p->view, name, value, p->theme_dir, + p->filename, p->line_num, p->col_num); + grub_free (value); + } + else + { + grub_error (GRUB_ERR_IO, + "%s:%d:%d property value invalid; " + "enclose literal values in quotes (\")", + p->filename, p->line_num, p->col_num); + goto done; + } + +done: + grub_free (name); + return grub_errno; +} + +/* Set properties on the view based on settings from the specified + theme file. */ +grub_err_t +grub_gfxmenu_view_load_theme (grub_gfxmenu_view_t view, const char *theme_path) +{ + grub_file_t file; + struct parsebuf p; + + p.view = view; + p.theme_dir = grub_get_dirname (theme_path); + + file = grub_file_open (theme_path, GRUB_FILE_TYPE_THEME); + if (! file) + { + grub_free (p.theme_dir); + return grub_errno; + } + + p.len = grub_file_size (file); + p.buf = grub_malloc (p.len + 4096); + p.pos = 0; + p.line_num = 1; + p.col_num = 1; + p.filename = theme_path; + if (! p.buf) + { + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; + } + if (grub_file_read (file, p.buf, p.len) != p.len) + { + grub_free (p.buf); + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; + } + +{ + const char *checkret = grub_env_get("VTOY_CHKDEV_RESULT_STRING"); + if (checkret == NULL || checkret[0] != '0') + { + p.len += grub_snprintf(p.buf + p.len, 4096, "\n+ hbox{\n left = 1%%\n top = 90%%\n" + " + label {text = \"[Unofficial Ventoy]\" color = \"red\" align = \"left\"}\n" + "}\n"); + } +} + + if (view->canvas) + view->canvas->component.ops->destroy (view->canvas); + + view->canvas = grub_gui_canvas_new (); + if (!view->canvas) + goto fail; + ((grub_gui_component_t) view->canvas) + ->ops->set_bounds ((grub_gui_component_t) view->canvas, + &view->screen); + + while (has_more (&p)) + { + /* Skip comments (lines beginning with #). */ + if (peek_char (&p) == '#') + { + advance_to_next_line (&p); + continue; + } + + /* Find the first non-whitespace character. */ + skip_whitespace (&p); + + /* Handle the content. */ + if (peek_char (&p) == '+') + { + /* Skip the '+'. */ + read_char (&p); + read_object (&p, view->canvas); + } + else + { + read_property (&p); + } + + if (grub_errno != GRUB_ERR_NONE) + goto fail; + } + + /* Set the new theme path. */ + grub_free (view->theme_path); + view->theme_path = grub_strdup (theme_path); + goto cleanup; + +fail: + if (view->canvas) + { + view->canvas->component.ops->destroy (view->canvas); + view->canvas = 0; + } + +cleanup: + grub_free (p.buf); + grub_file_close (file); + grub_free (p.theme_dir); + return grub_errno; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c new file mode 100644 index 00000000..bfac3756 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/gfxmenu/view.c @@ -0,0 +1,647 @@ +/* view.c - Graphical menu interface MVC view. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +init_terminal (grub_gfxmenu_view_t view); +static void +init_background (grub_gfxmenu_view_t view); +static grub_gfxmenu_view_t term_view; + +/* Create a new view object, loading the theme specified by THEME_PATH and + associating MODEL with the view. */ +grub_gfxmenu_view_t +grub_gfxmenu_view_new (const char *theme_path, + int width, int height) +{ + grub_gfxmenu_view_t view; + grub_font_t default_font; + grub_video_rgba_color_t default_fg_color; + grub_video_rgba_color_t default_bg_color; + + view = grub_malloc (sizeof (*view)); + if (! view) + return 0; + + while (grub_gfxmenu_timeout_notifications) + { + struct grub_gfxmenu_timeout_notify *p; + p = grub_gfxmenu_timeout_notifications; + grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next; + grub_free (p); + } + + view->screen.x = 0; + view->screen.y = 0; + view->screen.width = width; + view->screen.height = height; + + view->need_to_check_sanity = 1; + view->terminal_border = 3; + view->terminal_rect.width = view->screen.width * 7 / 10; + view->terminal_rect.height = view->screen.height * 7 / 10; + view->terminal_rect.x = view->screen.x + (view->screen.width + - view->terminal_rect.width) / 2; + view->terminal_rect.y = view->screen.y + (view->screen.height + - view->terminal_rect.height) / 2; + + default_font = grub_font_get ("Unknown Regular 16"); + default_fg_color = grub_video_rgba_color_rgb (0, 0, 0); + default_bg_color = grub_video_rgba_color_rgb (255, 255, 255); + + view->canvas = 0; + + view->title_font = default_font; + view->message_font = default_font; + view->terminal_font_name = grub_strdup ("Fixed 10"); + view->title_color = default_fg_color; + view->message_color = default_bg_color; + view->message_bg_color = default_fg_color; + view->raw_desktop_image = 0; + view->scaled_desktop_image = 0; + view->desktop_image_scale_method = GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH; + view->desktop_image_h_align = GRUB_VIDEO_BITMAP_H_ALIGN_CENTER; + view->desktop_image_v_align = GRUB_VIDEO_BITMAP_V_ALIGN_CENTER; + view->desktop_color = default_bg_color; + view->terminal_box = grub_gfxmenu_create_box (0, 0); + view->title_text = grub_strdup (_("GRUB Boot Menu")); + view->progress_message_text = 0; + view->theme_path = 0; + + /* Set the timeout bar's frame. */ + view->progress_message_frame.width = view->screen.width * 4 / 5; + view->progress_message_frame.height = 50; + view->progress_message_frame.x = view->screen.x + + (view->screen.width - view->progress_message_frame.width) / 2; + view->progress_message_frame.y = view->screen.y + + view->screen.height - 90 - 20 - view->progress_message_frame.height; + + if (grub_gfxmenu_view_load_theme (view, theme_path) != 0) + { + grub_gfxmenu_view_destroy (view); + return 0; + } + + return view; +} + +/* Destroy the view object. All used memory is freed. */ +void +grub_gfxmenu_view_destroy (grub_gfxmenu_view_t view) +{ + if (!view) + return; + while (grub_gfxmenu_timeout_notifications) + { + struct grub_gfxmenu_timeout_notify *p; + p = grub_gfxmenu_timeout_notifications; + grub_gfxmenu_timeout_notifications = grub_gfxmenu_timeout_notifications->next; + grub_free (p); + } + grub_video_bitmap_destroy (view->raw_desktop_image); + grub_video_bitmap_destroy (view->scaled_desktop_image); + if (view->terminal_box) + view->terminal_box->destroy (view->terminal_box); + grub_free (view->terminal_font_name); + grub_free (view->title_text); + grub_free (view->progress_message_text); + grub_free (view->theme_path); + if (view->canvas) + view->canvas->component.ops->destroy (view->canvas); + grub_free (view); +} + +static void +redraw_background (grub_gfxmenu_view_t view, + const grub_video_rect_t *bounds) +{ + if (view->scaled_desktop_image) + { + struct grub_video_bitmap *img = view->scaled_desktop_image; + grub_video_blit_bitmap (img, GRUB_VIDEO_BLIT_REPLACE, + bounds->x, bounds->y, + bounds->x - view->screen.x, + bounds->y - view->screen.y, + bounds->width, bounds->height); + } + else + { + grub_video_fill_rect (grub_video_map_rgba_color (view->desktop_color), + bounds->x, bounds->y, + bounds->width, bounds->height); + } +} + +static void +draw_title (grub_gfxmenu_view_t view) +{ + if (! view->title_text) + return; + + /* Center the title. */ + int title_width = grub_font_get_string_width (view->title_font, + view->title_text); + int x = (view->screen.width - title_width) / 2; + int y = 40 + grub_font_get_ascent (view->title_font); + grub_font_draw_string (view->title_text, + view->title_font, + grub_video_map_rgba_color (view->title_color), + x, y); +} + +struct progress_value_data +{ + int visible; + int start; + int end; + int value; +}; + +struct grub_gfxmenu_timeout_notify *grub_gfxmenu_timeout_notifications; + +static void +update_timeouts (int visible, int start, int value, int end) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + cur->set_state (cur->self, visible, start, value, end); +} + +static void +redraw_timeouts (struct grub_gfxmenu_view *view) +{ + struct grub_gfxmenu_timeout_notify *cur; + + for (cur = grub_gfxmenu_timeout_notifications; cur; cur = cur->next) + { + grub_video_rect_t bounds; + cur->self->ops->get_bounds (cur->self, &bounds); + grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); + grub_gfxmenu_view_redraw (view, &bounds); + } +} + +void +grub_gfxmenu_print_timeout (int timeout, void *data) +{ + struct grub_gfxmenu_view *view = data; + + if (view->first_timeout == -1) + view->first_timeout = timeout; + + update_timeouts (1, -view->first_timeout, -timeout, 0); + redraw_timeouts (view); + grub_video_swap_buffers (); + if (view->double_repaint) + redraw_timeouts (view); +} + +void +grub_gfxmenu_clear_timeout (void *data) +{ + struct grub_gfxmenu_view *view = data; + + update_timeouts (0, 1, 0, 0); + redraw_timeouts (view); + grub_video_swap_buffers (); + if (view->double_repaint) + redraw_timeouts (view); +} + +static void +update_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_gui_list_t list = (grub_gui_list_t) component; + list->ops->set_view_info (list, view); + } +} + +/* Update any boot menu components with the current menu model and + theme path. */ +static void +update_menu_components (grub_gfxmenu_view_t view) +{ + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + update_menu_visit, view); +} + +static void +refresh_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_gui_list_t list = (grub_gui_list_t) component; + list->ops->refresh_list (list, view); + } +} + +/* Refresh list information (useful for submenus) */ +static void +refresh_menu_components (grub_gfxmenu_view_t view) +{ + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + refresh_menu_visit, view); +} + +static void +draw_message (grub_gfxmenu_view_t view) +{ + char *text = view->progress_message_text; + grub_video_rect_t f = view->progress_message_frame; + if (! text) + return; + + grub_font_t font = view->message_font; + grub_video_color_t color = grub_video_map_rgba_color (view->message_color); + + /* Border. */ + grub_video_fill_rect (color, + f.x-1, f.y-1, f.width+2, f.height+2); + /* Fill. */ + grub_video_fill_rect (grub_video_map_rgba_color (view->message_bg_color), + f.x, f.y, f.width, f.height); + + /* Center the text. */ + int text_width = grub_font_get_string_width (font, text); + int x = f.x + (f.width - text_width) / 2; + int y = (f.y + (f.height - grub_font_get_descent (font)) / 2 + + grub_font_get_ascent (font) / 2); + grub_font_draw_string (text, font, color, x, y); +} + +void +grub_gfxmenu_view_redraw (grub_gfxmenu_view_t view, + const grub_video_rect_t *region) +{ + if (grub_video_have_common_points (&view->terminal_rect, region)) + grub_gfxterm_schedule_repaint (); + + grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY); + grub_video_area_status_t area_status; + grub_video_get_area_status (&area_status); + if (area_status == GRUB_VIDEO_AREA_ENABLED) + grub_video_set_region (region->x, region->y, + region->width, region->height); + + redraw_background (view, region); + if (view->canvas) + view->canvas->component.ops->paint (view->canvas, region); + draw_title (view); + if (grub_video_have_common_points (&view->progress_message_frame, region)) + draw_message (view); + + if (area_status == GRUB_VIDEO_AREA_ENABLED) + grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); +} + +void +grub_gfxmenu_view_draw (grub_gfxmenu_view_t view) +{ + init_terminal (view); + + init_background (view); + + /* Clear the screen; there may be garbage left over in video memory. */ + grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_video_fill_rect (grub_video_map_rgb (0, 0, 0), + view->screen.x, view->screen.y, + view->screen.width, view->screen.height); + + refresh_menu_components (view); + update_menu_components (view); + + grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); + grub_gfxmenu_view_redraw (view, &view->screen); + grub_video_swap_buffers (); + if (view->double_repaint) + { + grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); + grub_gfxmenu_view_redraw (view, &view->screen); + } + +} + +static void +redraw_menu_visit (grub_gui_component_t component, + void *userdata) +{ + grub_gfxmenu_view_t view; + view = userdata; + if (component->ops->is_instance (component, "list")) + { + grub_video_rect_t bounds; + + component->ops->get_bounds (component, &bounds); + grub_video_set_area_status (GRUB_VIDEO_AREA_ENABLED); + grub_gfxmenu_view_redraw (view, &bounds); + } +} + +void +grub_gfxmenu_redraw_menu (grub_gfxmenu_view_t view) +{ + update_menu_components (view); + + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + redraw_menu_visit, view); + grub_video_swap_buffers (); + if (view->double_repaint) + { + grub_gui_iterate_recursively ((grub_gui_component_t) view->canvas, + redraw_menu_visit, view); + } +} + +void +grub_gfxmenu_set_chosen_entry (int entry, void *data) +{ + grub_gfxmenu_view_t view = data; + + view->selected = entry; + grub_gfxmenu_redraw_menu (view); +} + +static void +grub_gfxmenu_draw_terminal_box (void) +{ + grub_gfxmenu_box_t term_box; + + term_box = term_view->terminal_box; + if (!term_box) + return; + + grub_video_set_area_status (GRUB_VIDEO_AREA_DISABLED); + + term_box->set_content_size (term_box, term_view->terminal_rect.width, + term_view->terminal_rect.height); + + term_box->draw (term_box, + term_view->terminal_rect.x - term_box->get_left_pad (term_box), + term_view->terminal_rect.y - term_box->get_top_pad (term_box)); +} + +static void +get_min_terminal (grub_font_t terminal_font, + unsigned int border_width, + unsigned int *min_terminal_width, + unsigned int *min_terminal_height) +{ + struct grub_font_glyph *glyph; + glyph = grub_font_get_glyph (terminal_font, 'M'); + *min_terminal_width = (glyph? glyph->device_width : 8) * 80 + + 2 * border_width; + *min_terminal_height = grub_font_get_max_char_height (terminal_font) * 24 + + 2 * border_width; +} + +static void +terminal_sanity_check (grub_gfxmenu_view_t view) +{ + if (!view->need_to_check_sanity) + return; + + /* terminal_font was checked before in the init_terminal function. */ + grub_font_t terminal_font = grub_font_get (view->terminal_font_name); + + /* Non-negative numbers below. */ + int scr_x = view->screen.x; + int scr_y = view->screen.y; + int scr_width = view->screen.width; + int scr_height = view->screen.height; + int term_x = view->terminal_rect.x; + int term_y = view->terminal_rect.y; + int term_width = view->terminal_rect.width; + int term_height = view->terminal_rect.height; + + /* Check that border_width isn't too big. */ + unsigned int border_width = view->terminal_border; + unsigned int min_terminal_width; + unsigned int min_terminal_height; + get_min_terminal (terminal_font, border_width, + &min_terminal_width, &min_terminal_height); + if (border_width > 3 && ((int) min_terminal_width >= scr_width + || (int) min_terminal_height >= scr_height)) + { + border_width = 3; + get_min_terminal (terminal_font, border_width, + &min_terminal_width, &min_terminal_height); + } + + /* Sanity checks. */ + if (term_width > scr_width) + term_width = scr_width; + if (term_height > scr_height) + term_height = scr_height; + + if (scr_width <= (int) min_terminal_width + || scr_height <= (int) min_terminal_height) + { + /* The screen resulution is too low. Use all space, except a small border + to show the user, that it is a window. Then center the window. */ + term_width = scr_width - 6 * border_width; + term_height = scr_height - 6 * border_width; + term_x = scr_x + (scr_width - term_width) / 2; + term_y = scr_y + (scr_height - term_height) / 2; + } + else if (term_width < (int) min_terminal_width + || term_height < (int) min_terminal_height) + { + /* The screen resolution is big enough. Make sure, that terminal screen + dimensions aren't less than minimal values. Then center the window. */ + term_width = (int) min_terminal_width; + term_height = (int) min_terminal_height; + term_x = scr_x + (scr_width - term_width) / 2; + term_y = scr_y + (scr_height - term_height) / 2; + } + + /* At this point w and h are satisfying. */ + if (term_x + term_width > scr_width) + term_x = scr_width - term_width; + if (term_y + term_height > scr_height) + term_y = scr_height - term_height; + + /* Write down corrected data. */ + view->terminal_rect.x = (unsigned int) term_x; + view->terminal_rect.y = (unsigned int) term_y; + view->terminal_rect.width = (unsigned int) term_width; + view->terminal_rect.height = (unsigned int) term_height; + view->terminal_border = border_width; + + view->need_to_check_sanity = 0; +} + +static void +init_terminal (grub_gfxmenu_view_t view) +{ + grub_font_t terminal_font; + + terminal_font = grub_font_get (view->terminal_font_name); + if (!terminal_font) + { + grub_error (GRUB_ERR_BAD_FONT, "no font loaded"); + return; + } + + /* Check that terminal window size and position are sane. */ + terminal_sanity_check (view); + + term_view = view; + + /* Note: currently there is no API for changing the gfxterm font + on the fly, so whatever font the initially loaded theme specifies + will be permanent. */ + grub_gfxterm_set_window (GRUB_VIDEO_RENDER_TARGET_DISPLAY, + view->terminal_rect.x, + view->terminal_rect.y, + view->terminal_rect.width, + view->terminal_rect.height, + view->double_repaint, + terminal_font, + view->terminal_border); + grub_gfxterm_decorator_hook = grub_gfxmenu_draw_terminal_box; +} + +static void +init_background (grub_gfxmenu_view_t view) +{ + if (view->scaled_desktop_image || (!view->raw_desktop_image)) + return; + + struct grub_video_bitmap *scaled_bitmap; + if (view->desktop_image_scale_method == + GRUB_VIDEO_BITMAP_SELECTION_METHOD_STRETCH) + grub_video_bitmap_create_scaled (&scaled_bitmap, + view->screen.width, + view->screen.height, + view->raw_desktop_image, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST); + else + grub_video_bitmap_scale_proportional (&scaled_bitmap, + view->screen.width, + view->screen.height, + view->raw_desktop_image, + GRUB_VIDEO_BITMAP_SCALE_METHOD_BEST, + view->desktop_image_scale_method, + view->desktop_image_v_align, + view->desktop_image_h_align); + if (! scaled_bitmap) + return; + view->scaled_desktop_image = scaled_bitmap; + +} + +/* FIXME: previously notifications were displayed in special case. + Is it necessary? + */ +#if 0 +/* Sets MESSAGE as the progress message for the view. + MESSAGE can be 0, in which case no message is displayed. */ +static void +set_progress_message (grub_gfxmenu_view_t view, const char *message) +{ + grub_free (view->progress_message_text); + if (message) + view->progress_message_text = grub_strdup (message); + else + view->progress_message_text = 0; +} + +static void +notify_booting (grub_menu_entry_t entry, void *userdata) +{ + grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata; + + char *s = grub_malloc (100 + grub_strlen (entry->title)); + if (!s) + return; + + grub_sprintf (s, "Booting '%s'", entry->title); + set_progress_message (view, s); + grub_free (s); + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); +} + +static void +notify_fallback (grub_menu_entry_t entry, void *userdata) +{ + grub_gfxmenu_view_t view = (grub_gfxmenu_view_t) userdata; + + char *s = grub_malloc (100 + grub_strlen (entry->title)); + if (!s) + return; + + grub_sprintf (s, "Falling back to '%s'", entry->title); + set_progress_message (view, s); + grub_free (s); + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); + grub_video_swap_buffers (); + if (view->double_repaint) + grub_gfxmenu_view_redraw (view, &view->progress_message_frame); +} + +static void +notify_execution_failure (void *userdata __attribute__ ((unused))) +{ +} + + +static struct grub_menu_execute_callback execute_callback = +{ + .notify_booting = notify_booting, + .notify_fallback = notify_fallback, + .notify_failure = notify_execution_failure +}; + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c index dc811577..a93da199 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/efi.c @@ -964,3 +964,20 @@ void * grub_efi_allocate_iso_buf(grub_uint64_t size) return (void *)(unsigned long)address; } + +void * grub_efi_allocate_chain_buf(grub_uint64_t size) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_physical_address_t address = 0; + grub_efi_uintn_t pages = GRUB_EFI_BYTES_TO_PAGES(size); + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, GRUB_EFI_LOADER_DATA, pages, &address); + if (status != GRUB_EFI_SUCCESS) + { + return NULL; + } + + return (void *)(unsigned long)address; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c new file mode 100644 index 00000000..6676d6d6 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/efi/mm.c @@ -0,0 +1,672 @@ +/* mm.c - generic EFI memory management */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include + +#if defined (__i386__) || defined (__x86_64__) +#include +#endif + +#define NEXT_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) +#define BYTES_TO_PAGES_DOWN(bytes) ((bytes) >> 12) +#define PAGES_TO_BYTES(pages) ((pages) << 12) + +/* The size of a memory map obtained from the firmware. This must be + a multiplier of 4KB. */ +#define MEMORY_MAP_SIZE 0x3000 + +/* The minimum and maximum heap size for GRUB itself. */ +#define MIN_HEAP_SIZE 0x100000 +#define MAX_HEAP_SIZE (1600 * 0x100000) + +static void *finish_mmap_buf = 0; +static grub_efi_uintn_t finish_mmap_size = 0; +static grub_efi_uintn_t finish_key = 0; +static grub_efi_uintn_t finish_desc_size; +static grub_efi_uint32_t finish_desc_version; +int grub_efi_is_finished = 0; + +/* + * We need to roll back EFI allocations on exit. Remember allocations that + * we'll free on exit. + */ +struct efi_allocation; +struct efi_allocation { + grub_efi_physical_address_t address; + grub_efi_uint64_t pages; + struct efi_allocation *next; +}; +static struct efi_allocation *efi_allocated_memory; + +static void +grub_efi_store_alloc (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + grub_efi_boot_services_t *b; + struct efi_allocation *alloc; + grub_efi_status_t status; + + b = grub_efi_system_table->boot_services; + status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, + sizeof(*alloc), (void**)&alloc); + + if (status == GRUB_EFI_SUCCESS) + { + alloc->next = efi_allocated_memory; + alloc->address = address; + alloc->pages = pages; + efi_allocated_memory = alloc; + } + else + grub_printf ("Could not malloc memory to remember EFI allocation. " + "Exiting GRUB won't free all memory.\n"); +} + +static void +grub_efi_drop_alloc (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + struct efi_allocation *ea, *eap; + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + + for (eap = NULL, ea = efi_allocated_memory; ea; eap = ea, ea = ea->next) + { + if (ea->address != address || ea->pages != pages) + continue; + + /* Remove the current entry from the list. */ + if (eap) + eap->next = ea->next; + else + efi_allocated_memory = ea->next; + + /* Then free the memory backing it. */ + efi_call_1 (b->free_pool, ea); + + /* And leave, we're done. */ + break; + } +} + +/* Allocate pages. Return the pointer to the first of allocated pages. */ +void * +grub_efi_allocate_pages_real (grub_efi_physical_address_t address, + grub_efi_uintn_t pages, + grub_efi_allocate_type_t alloctype, + grub_efi_memory_type_t memtype) +{ + grub_efi_status_t status; + grub_efi_boot_services_t *b; + + /* Limit the memory access to less than 4GB for 32-bit platforms. */ + if (address > GRUB_EFI_MAX_USABLE_ADDRESS) + return 0; + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); + if (status != GRUB_EFI_SUCCESS) + return 0; + + if (address == 0) + { + /* Uggh, the address 0 was allocated... This is too annoying, + so reallocate another one. */ + address = GRUB_EFI_MAX_USABLE_ADDRESS; + status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address); + grub_efi_free_pages (0, pages); + if (status != GRUB_EFI_SUCCESS) + return 0; + } + + grub_efi_store_alloc (address, pages); + + return (void *) ((grub_addr_t) address); +} + +void * +grub_efi_allocate_any_pages (grub_efi_uintn_t pages) +{ + return grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, + pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + +void * +grub_efi_allocate_fixed (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + return grub_efi_allocate_pages_real (address, pages, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + +/* Free pages starting from ADDRESS. */ +void +grub_efi_free_pages (grub_efi_physical_address_t address, + grub_efi_uintn_t pages) +{ + grub_efi_boot_services_t *b; + + b = grub_efi_system_table->boot_services; + efi_call_2 (b->free_pages, address, pages); + + grub_efi_drop_alloc (address, pages); +} + +#if defined (__i386__) || defined (__x86_64__) + +/* Helper for stop_broadcom. */ +static int +find_card (grub_pci_device_t dev, grub_pci_id_t pciid, + void *data __attribute__ ((unused))) +{ + grub_pci_address_t addr; + grub_uint8_t cap; + grub_uint16_t pm_state; + + if ((pciid & 0xffff) != GRUB_PCI_VENDOR_BROADCOM) + return 0; + + addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS); + if (grub_pci_read (addr) >> 24 != GRUB_PCI_CLASS_NETWORK) + return 0; + cap = grub_pci_find_capability (dev, GRUB_PCI_CAP_POWER_MANAGEMENT); + if (!cap) + return 0; + addr = grub_pci_make_address (dev, cap + 4); + pm_state = grub_pci_read_word (addr); + pm_state = pm_state | 0x03; + grub_pci_write_word (addr, pm_state); + grub_pci_read_word (addr); + return 0; +} + +static void +stop_broadcom (void) +{ + grub_pci_iterate (find_card, NULL); +} + +#endif + +grub_err_t +grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *efi_desc_size, + grub_efi_uint32_t *efi_desc_version) +{ + grub_efi_boot_services_t *b; + grub_efi_status_t status; + +#if defined (__i386__) || defined (__x86_64__) + const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' }; + int is_apple; + + is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor, + apple, sizeof (apple)) == 0); +#endif + + while (1) + { + if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, + &finish_desc_size, &finish_desc_version) < 0) + return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); + + if (outbuf && *outbuf_size < finish_mmap_size) + return grub_error (GRUB_ERR_IO, "memory map buffer is too small"); + + finish_mmap_buf = grub_malloc (finish_mmap_size); + if (!finish_mmap_buf) + return grub_errno; + + if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf, &finish_key, + &finish_desc_size, &finish_desc_version) <= 0) + { + grub_free (finish_mmap_buf); + return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map"); + } + + b = grub_efi_system_table->boot_services; + status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle, + finish_key); + if (status == GRUB_EFI_SUCCESS) + break; + + if (status != GRUB_EFI_INVALID_PARAMETER) + { + grub_free (finish_mmap_buf); + return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services"); + } + + grub_free (finish_mmap_buf); + grub_printf ("Trying to terminate EFI services again\n"); + } + grub_efi_is_finished = 1; + if (outbuf_size) + *outbuf_size = finish_mmap_size; + if (outbuf) + grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size); + if (map_key) + *map_key = finish_key; + if (efi_desc_size) + *efi_desc_size = finish_desc_size; + if (efi_desc_version) + *efi_desc_version = finish_desc_version; + +#if defined (__i386__) || defined (__x86_64__) + if (is_apple) + stop_broadcom (); +#endif + + return GRUB_ERR_NONE; +} + +/* + * To obtain the UEFI memory map, we must pass a buffer of sufficient size + * to hold the entire map. This function returns a sane start value for + * buffer size. + */ +grub_efi_uintn_t +grub_efi_find_mmap_size (void) +{ + grub_efi_uintn_t mmap_size = 0; + grub_efi_uintn_t desc_size; + + if (grub_efi_get_memory_map (&mmap_size, NULL, NULL, &desc_size, 0) < 0) + { + grub_error (GRUB_ERR_IO, "cannot get EFI memory map size"); + return 0; + } + + /* + * Add an extra page, since UEFI can alter the memory map itself on + * callbacks or explicit calls, including console output. + */ + return ALIGN_UP (mmap_size + GRUB_EFI_PAGE_SIZE, GRUB_EFI_PAGE_SIZE); +} + +/* Get the memory map as defined in the EFI spec. Return 1 if successful, + return 0 if partial, or return -1 if an error occurs. */ +int +grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version) +{ + grub_efi_status_t status; + grub_efi_boot_services_t *b; + grub_efi_uintn_t key; + grub_efi_uint32_t version; + grub_efi_uintn_t size; + + if (grub_efi_is_finished) + { + int ret = 1; + if (*memory_map_size < finish_mmap_size) + { + grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size); + ret = 0; + } + else + { + grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size); + ret = 1; + } + *memory_map_size = finish_mmap_size; + if (map_key) + *map_key = finish_key; + if (descriptor_size) + *descriptor_size = finish_desc_size; + if (descriptor_version) + *descriptor_version = finish_desc_version; + return ret; + } + + /* Allow some parameters to be missing. */ + if (! map_key) + map_key = &key; + if (! descriptor_version) + descriptor_version = &version; + if (! descriptor_size) + descriptor_size = &size; + + b = grub_efi_system_table->boot_services; + status = efi_call_5 (b->get_memory_map, memory_map_size, memory_map, map_key, + descriptor_size, descriptor_version); + if (*descriptor_size == 0) + *descriptor_size = sizeof (grub_efi_memory_descriptor_t); + if (status == GRUB_EFI_SUCCESS) + return 1; + else if (status == GRUB_EFI_BUFFER_TOO_SMALL) + return 0; + else + return -1; +} + +/* Sort the memory map in place. */ +static void +sort_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *d1; + grub_efi_memory_descriptor_t *d2; + + for (d1 = memory_map; + d1 < memory_map_end; + d1 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size)) + { + grub_efi_memory_descriptor_t *max_desc = d1; + + for (d2 = NEXT_MEMORY_DESCRIPTOR (d1, desc_size); + d2 < memory_map_end; + d2 = NEXT_MEMORY_DESCRIPTOR (d2, desc_size)) + { + if (max_desc->num_pages < d2->num_pages) + max_desc = d2; + } + + if (max_desc != d1) + { + grub_efi_memory_descriptor_t tmp; + + tmp = *d1; + *d1 = *max_desc; + *max_desc = tmp; + } + } +} + +/* Filter the descriptors. GRUB needs only available memory. */ +static grub_efi_memory_descriptor_t * +filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_memory_descriptor_t *filtered_memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + grub_efi_memory_descriptor_t *filtered_desc; + + for (desc = memory_map, filtered_desc = filtered_memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY +#if 1 + && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS +#endif + && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 + && desc->num_pages != 0) + { + grub_memcpy (filtered_desc, desc, desc_size); + + /* Avoid less than 1MB, because some loaders seem to be confused. */ + if (desc->physical_start < 0x100000) + { + desc->num_pages -= BYTES_TO_PAGES (0x100000 + - desc->physical_start); + desc->physical_start = 0x100000; + } + +#if 1 + if (BYTES_TO_PAGES (filtered_desc->physical_start) + + filtered_desc->num_pages + > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)) + filtered_desc->num_pages + = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS) + - BYTES_TO_PAGES (filtered_desc->physical_start)); +#endif + + if (filtered_desc->num_pages == 0) + continue; + + filtered_desc = NEXT_MEMORY_DESCRIPTOR (filtered_desc, desc_size); + } + } + + return filtered_desc; +} + +/* Return the total number of pages. */ +static grub_efi_uint64_t +get_total_pages (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + grub_efi_uint64_t total = 0; + + for (desc = memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + total += desc->num_pages; + + return total; +} + +/* Add memory regions. */ +static void +add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end, + grub_efi_uint64_t required_pages) +{ + grub_efi_memory_descriptor_t *desc; + + for (desc = memory_map; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_uint64_t pages; + grub_efi_physical_address_t start; + void *addr; + + start = desc->physical_start; + pages = desc->num_pages; + if (pages > required_pages) + { + start += PAGES_TO_BYTES (pages - required_pages); + pages = required_pages; + } + + addr = grub_efi_allocate_pages_real (start, pages, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_CODE); + if (! addr) + grub_fatal ("cannot allocate conventional memory %p with %u pages", + (void *) ((grub_addr_t) start), + (unsigned) pages); + + grub_mm_init_region (addr, PAGES_TO_BYTES (pages)); + + required_pages -= pages; + if (required_pages == 0) + break; + } + + if (required_pages > 0) + grub_fatal ("too little memory"); +} + +void +grub_efi_memory_fini (void) +{ + /* + * Free all stale allocations. grub_efi_free_pages() will remove + * the found entry from the list and it will always find the first + * list entry (efi_allocated_memory is the list start). Hence we + * remove all entries from the list until none is left altogether. + */ + while (efi_allocated_memory) + grub_efi_free_pages (efi_allocated_memory->address, + efi_allocated_memory->pages); +} + +#if 0 +/* Print the memory map. */ +static void +print_memory_map (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end) +{ + grub_efi_memory_descriptor_t *desc; + int i; + + for (desc = memory_map, i = 0; + desc < memory_map_end; + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size), i++) + { + grub_printf ("MD: t=%x, p=%llx, v=%llx, n=%llx, a=%llx\n", + desc->type, desc->physical_start, desc->virtual_start, + desc->num_pages, desc->attribute); + } +} +#endif + +void +grub_efi_mm_init (void) +{ + grub_efi_memory_descriptor_t *memory_map; + grub_efi_memory_descriptor_t *memory_map_end; + grub_efi_memory_descriptor_t *filtered_memory_map; + grub_efi_memory_descriptor_t *filtered_memory_map_end; + grub_efi_uintn_t map_size; + grub_efi_uintn_t desc_size; + grub_efi_uint64_t total_pages; + grub_efi_uint64_t required_pages; + int mm_status; + + /* Prepare a memory region to store two memory maps. */ + memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + if (! memory_map) + grub_fatal ("cannot allocate memory"); + + /* Obtain descriptors for available memory. */ + map_size = MEMORY_MAP_SIZE; + + mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0); + + if (mm_status == 0) + { + grub_efi_free_pages + ((grub_efi_physical_address_t) ((grub_addr_t) memory_map), + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + + /* Freeing/allocating operations may increase memory map size. */ + map_size += desc_size * 32; + + memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (map_size)); + if (! memory_map) + grub_fatal ("cannot allocate memory"); + + mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, + &desc_size, 0); + } + + if (mm_status < 0) + grub_fatal ("cannot get memory map"); + + memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); + + filtered_memory_map = memory_map_end; + + filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map, + desc_size, memory_map_end); + + /* By default, request a quarter of the available memory. */ + total_pages = get_total_pages (filtered_memory_map, desc_size, + filtered_memory_map_end); + + #if defined (__mips__) && (_MIPS_SIM == _ABI64) + required_pages = (total_pages > 4096) ? (total_pages - 4096) : (total_pages >> 1); + #else + required_pages = (total_pages >> 2); + #endif + + if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE)) + required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE); + else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE)) + required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE); + + /* Sort the filtered descriptors, so that GRUB can allocate pages + from smaller regions. */ + sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end); + + /* Allocate memory regions for GRUB's memory management. */ + add_memory_regions (filtered_memory_map, desc_size, + filtered_memory_map_end, required_pages); + +#if 0 + /* For debug. */ + map_size = MEMORY_MAP_SIZE; + + if (grub_efi_get_memory_map (&map_size, memory_map, 0, &desc_size, 0) < 0) + grub_fatal ("cannot get memory map"); + + grub_printf ("printing memory map\n"); + print_memory_map (memory_map, desc_size, + NEXT_MEMORY_DESCRIPTOR (memory_map, map_size)); + grub_fatal ("Debug. "); +#endif + + /* Release the memory maps. */ + grub_efi_free_pages ((grub_addr_t) memory_map, + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); +} + +#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) +grub_err_t +grub_efi_get_ram_base(grub_addr_t *base_addr) +{ + grub_efi_memory_descriptor_t *memory_map, *desc; + grub_efi_uintn_t memory_map_size, desc_size; + int ret; + + memory_map_size = grub_efi_find_mmap_size(); + + memory_map = grub_malloc (memory_map_size); + if (! memory_map) + return GRUB_ERR_OUT_OF_MEMORY; + ret = grub_efi_get_memory_map (&memory_map_size, memory_map, NULL, + &desc_size, NULL); + + if (ret < 1) + return GRUB_ERR_BUG; + + for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS; + (grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size); + desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) + if (desc->attribute & GRUB_EFI_MEMORY_WB) + *base_addr = grub_min (*base_addr, desc->physical_start); + + grub_free(memory_map); + + return GRUB_ERR_NONE; +} +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c index 2f22ecb5..42bc22f7 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/main.c @@ -109,6 +109,52 @@ grub_env_write_root (struct grub_env_var *var __attribute__ ((unused)), return grub_strdup (val); } +static int g_ventoy_hook_root = 0; +void ventoy_env_hook_root(int hook) +{ + g_ventoy_hook_root = hook; +} + +static char * +ventoy_env_write_root (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + const char *pos = val; + char buf[256]; + + if (g_ventoy_hook_root == 0) + { + return grub_env_write_root(var, val); + } + + if (pos[0] == '(') + { + pos++; + } + + if (grub_strncmp(pos, "vtimghd", 7) == 0) + { + return grub_env_write_root(var, val); + } + + pos = grub_strchr(val, ','); + if (!pos) + { + return grub_env_write_root(var, val); + } + + if (val[0] == '(') + { + grub_snprintf(buf, sizeof(buf), "(vtimghd%s", pos); + } + else + { + grub_snprintf(buf, sizeof(buf), "vtimghd%s", pos); + } + + return grub_env_write_root(var, buf); +} + static void grub_set_prefix_and_root (void) { @@ -123,7 +169,7 @@ grub_set_prefix_and_root (void) if (header->type == OBJ_TYPE_PREFIX) prefix = (char *) header + sizeof (struct grub_module_header); - grub_register_variable_hook ("root", 0, grub_env_write_root); + grub_register_variable_hook ("root", 0, ventoy_env_write_root); grub_machine_get_bootlocation (&fwdevice, &fwpath); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S new file mode 100644 index 00000000..c1fb4d44 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/cache.S @@ -0,0 +1,23 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + +FUNCTION (grub_arch_sync_caches) + jr.hb $ra + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c new file mode 100644 index 00000000..7c6a0833 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/dl.c @@ -0,0 +1,150 @@ +/* dl-mips64.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2007,2009,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Check if EHDR is a valid ELF header. */ +grub_err_t +grub_arch_dl_check_header (void *ehdr) +{ + Elf_Ehdr *e = ehdr; + + /* Check the magic numbers. */ +#ifdef GRUB_CPU_WORDS_BIGENDIAN + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2MSB + || e->e_machine != EM_MIPS) +#else + if (e->e_ident[EI_CLASS] != ELFCLASS64 + || e->e_ident[EI_DATA] != ELFDATA2LSB + || e->e_machine != EM_MIPS) +#endif + return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); + + return GRUB_ERR_NONE; +} + +#pragma GCC diagnostic ignored "-Wcast-align" + +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr __attribute__ ((unused)), + grub_size_t *tramp, grub_size_t *got) +{ + *tramp = 0; + *got = 0; + return GRUB_ERR_NONE; +} + +/* Relocate symbols. */ +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg) +{ + Elf_Ehdr *e = ehdr; + Elf_Rel *rel, *max; + + for (rel = (Elf_Rel *) ((char *) e + s->sh_offset), + max = (Elf_Rel *) ((char *) rel + s->sh_size); + rel < max; + rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) + { + grub_uint8_t *addr; + Elf_Sym *sym; + Elf_Addr r_info; + grub_uint64_t sym_value; + + if (seg->size < rel->r_offset) + return grub_error (GRUB_ERR_BAD_MODULE, + "reloc offset is out of the segment"); + + r_info = ((grub_uint64_t) rel->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (rel->r_info); + + addr = (grub_uint8_t *) ((char *) seg->addr + rel->r_offset); + sym = (Elf_Sym *) ((char *) mod->symtab + + mod->symsize * ELF_R_SYM (r_info)); + sym_value = sym->st_value; + if (s->sh_type == SHT_RELA) + { + sym_value += ((Elf_Rela *) rel)->r_addend; + } + switch (ELF_R_TYPE (r_info)) + { + case R_MIPS_64: + *(grub_uint64_t *) addr += sym_value; + break; + case R_MIPS_32: + *(grub_uint32_t *) addr += sym_value; + break; + case R_MIPS_26: + { + grub_uint32_t value; + grub_uint32_t raw; + raw = (*(grub_uint32_t *) addr) & 0x3ffffff; + value = raw << 2; + value += sym_value; + raw = (value >> 2) & 0x3ffffff; + + *(grub_uint32_t *) addr = + raw | ((*(grub_uint32_t *) addr) & 0xfc000000); + } + break; + case R_MIPS_LO16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) sym_value; + break; + case R_MIPS_HI16: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x8000UL) >> 16); + break; + case R_MIPS_HIGHER: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_int16_t) ((sym_value + 0x80008000UL) >> 32); + break; + case R_MIPS_HIGHEST: +#ifdef GRUB_CPU_WORDS_BIGENDIAN + addr += 2; +#endif + *(grub_uint16_t *) addr = (grub_uint16_t) ((sym_value + 0x800080008000UL) >> 48); + break; + default: + { + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("relocation 0x%x is not implemented yet"), + ELF_R_TYPE (r_info)); + } + break; + } + } + + return GRUB_ERR_NONE; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c new file mode 100644 index 00000000..f9f846e9 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/init.c @@ -0,0 +1,85 @@ +/* init.c - initialize an arm-based EFI system */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static grub_uint64_t tmr; +static grub_efi_event_t tmr_evt; + +static grub_uint64_t +grub_efi_get_time_ms (void) +{ + return tmr; +} + +static void +grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), + void *context __attribute__ ((unused))) +{ + tmr += 10; +} + + + +void +grub_machine_init (void) +{ + grub_efi_boot_services_t *b; + + grub_efi_init (); + + b = grub_efi_system_table->boot_services; + efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, + GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); + efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); + + grub_install_get_time_ms (grub_efi_get_time_ms); + + if (grub_efi_is_loongson ()) + grub_efi_loongson_init (); + else + /* FIXME: Get cpuclock from EFI. */ + grub_timer_init (1000000000U); +} + +void +grub_machine_fini (int flags) +{ + grub_efi_boot_services_t *b; + + if (!(flags & GRUB_LOADER_FLAG_NORETURN)) + return; + + b = grub_efi_system_table->boot_services; + + efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); + efi_call_1 (b->close_event, tmr_evt); + + if (grub_efi_is_loongson ()) + grub_efi_loongson_fini (); + grub_efi_fini (); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c new file mode 100644 index 00000000..fde01b44 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/loongson.c @@ -0,0 +1,33 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +void +grub_efi_loongson_init (void) +{ +} + +void +grub_efi_loongson_fini (void) +{ +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S new file mode 100644 index 00000000..4fee9bee --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/efi/startup.S @@ -0,0 +1,47 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + + .file "startup.S" + .text + + .set push + .align 4 + +FUNCTION(_start) + /* + * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. + */ + daddiu $sp, -16 + sd $ra, ($sp) + + dla $a2, grub_efi_image_handle + sd $a0, ($a2) + dla $a2, grub_efi_system_table + sd $a1, ($a2) + + jal grub_main + +1: + ld $ra, ($sp) + daddiu $sp, 16 + jr $ra + + .set pop + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c new file mode 100644 index 00000000..8fd0a88a --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/mips64/init.c @@ -0,0 +1,47 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +grub_uint32_t grub_arch_cpuclock; + +/* FIXME: use interrupt to count high. */ +grub_uint64_t +grub_get_rtc (void) +{ + static grub_uint32_t high = 0; + static grub_uint32_t last = 0; + grub_uint32_t low; + + asm volatile ("mfc0 %0, " GRUB_CPU_MIPS_COP0_TIMER_COUNT : "=r" (low)); + if (low < last) + high++; + last = low; + + return (((grub_uint64_t) high) << 32) | low; +} + +void +grub_timer_init (grub_uint32_t cpuclock) +{ + grub_arch_cpuclock = cpuclock; + grub_install_get_time_ms (grub_rtc_get_time_ms); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c new file mode 100644 index 00000000..816a4058 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/kern/term.c @@ -0,0 +1,133 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +struct grub_term_output *grub_term_outputs_disabled; +struct grub_term_input *grub_term_inputs_disabled; +struct grub_term_output *grub_term_outputs; +struct grub_term_input *grub_term_inputs; + +/* Current color state. */ +grub_uint8_t grub_term_normal_color = GRUB_TERM_DEFAULT_NORMAL_COLOR; +grub_uint8_t grub_term_highlight_color = GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR; + +void (*grub_term_poll_usb) (int wait_for_completion) = NULL; +void (*grub_net_poll_cards_idle) (void) = NULL; + +/* Put a Unicode character. */ +static void +grub_putcode_dumb (grub_uint32_t code, + struct grub_term_output *term) +{ + struct grub_unicode_glyph c = + { + .base = code, + .variant = 0, + .attributes = 0, + .ncomb = 0, + .estimated_width = 1 + }; + + if (code == '\t' && term->getxy) + { + int n; + + n = GRUB_TERM_TAB_WIDTH - ((term->getxy (term).x) + % GRUB_TERM_TAB_WIDTH); + while (n--) + grub_putcode_dumb (' ', term); + + return; + } + + (term->putchar) (term, &c); + if (code == '\n') + grub_putcode_dumb ('\r', term); +} + +static void +grub_xputs_dumb (const char *str) +{ + for (; *str; str++) + { + grub_term_output_t term; + grub_uint32_t code = *str; + if (code > 0x7f) + code = '?'; + + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_putcode_dumb (code, term); + } +} + +void (*grub_xputs) (const char *str) = grub_xputs_dumb; + +int (*grub_key_remap)(int key) = NULL; +int +grub_getkey_noblock (void) +{ + grub_term_input_t term; + + if (grub_term_poll_usb) + grub_term_poll_usb (0); + + if (grub_net_poll_cards_idle) + grub_net_poll_cards_idle (); + + FOR_ACTIVE_TERM_INPUTS(term) + { + int key = term->getkey (term); + if (grub_key_remap) + key = grub_key_remap(key); + if (key != GRUB_TERM_NO_KEY) + return key; + } + + return GRUB_TERM_NO_KEY; +} + +int +grub_getkey (void) +{ + int ret; + + grub_refresh (); + + while (1) + { + ret = grub_getkey_noblock (); + if (ret != GRUB_TERM_NO_KEY) + return ret; + grub_cpu_idle (); + } +} + +void +grub_refresh (void) +{ + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_term_refresh (term); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c new file mode 100644 index 00000000..7ea51825 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/efi/halt.c @@ -0,0 +1,40 @@ +/* efi.c - generic EFI support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include + +void +grub_halt (void) +{ + grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); +#if !defined(__ia64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__mips__) &&\ + !defined(__riscv) + grub_acpi_halt (); +#endif + efi_call_4 (grub_efi_system_table->runtime_services->reset_system, + GRUB_EFI_RESET_SHUTDOWN, GRUB_EFI_SUCCESS, 0, NULL); + + while (1); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c new file mode 100644 index 00000000..42e2b280 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson.c @@ -0,0 +1,495 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wunused-function" + +#define loongson_params (&loongson_boot_params->boot_params.efi.smbios.lp) +#define loongson_boot_params_size ALIGN_UP (sizeof (*loongson_boot_params), 8) +#define loongson_reset_code_size (&grub_efi_loongson_reset_end - &grub_efi_loongson_reset_start) + +extern grub_uint8_t grub_efi_loongson_reset_start; +extern grub_uint8_t grub_efi_loongson_reset_end; + +static struct +{ + grub_efi_loongson_boot_params boot_params; + grub_efi_loongson_memory_map memory_map; + grub_efi_loongson_cpu_info cpu_info; + grub_efi_loongson_system_info system_info; + grub_efi_loongson_irq_src_routing_table irq_src_routing_table; + grub_efi_loongson_interface_info interface_info; + grub_efi_loongson_special_attribute special_attribute; + grub_efi_loongson_board_devices board_devices; +} GRUB_PACKED +* loongson_boot_params; + +static void +grub_efi_loongson_init_reset_system (void) +{ + grub_efi_loongson_boot_params *boot_params; + grub_uint8_t *reset_code_addr = (grub_uint8_t *) loongson_boot_params + + loongson_boot_params_size; + + boot_params = &loongson_boot_params->boot_params; + grub_efi_loongson_reset_system_addr = + (grub_uint64_t) grub_efi_system_table->runtime_services->reset_system; + grub_memcpy (reset_code_addr, &grub_efi_loongson_reset_start, loongson_reset_code_size); + grub_arch_sync_caches (reset_code_addr, loongson_reset_code_size); + + boot_params->reset_system.reset_cold = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_cold - + (grub_uint64_t) &grub_efi_loongson_reset_start); + boot_params->reset_system.reset_warm = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_warm - + (grub_uint64_t) &grub_efi_loongson_reset_start); + boot_params->reset_system.shutdown = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_shutdown - + (grub_uint64_t) &grub_efi_loongson_reset_start); + boot_params->reset_system.do_suspend = (grub_uint64_t) reset_code_addr + + ((grub_uint64_t) &grub_efi_loongson_reset_suspend - + (grub_uint64_t) &grub_efi_loongson_reset_start); +} + +static void +grub_efi_loongson_init_smbios (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_smbios_table *dst = &loongson_boot_params->boot_params.efi.smbios; + + dst->vers = smbios_table->vers; + dst->vga_bios = smbios_table->vga_bios; +} + +static void +grub_efi_loongson_init_cpu_info (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_cpu_info *src = (void *) smbios_table->lp.cpu_offset; + grub_efi_loongson_cpu_info *dst = &loongson_boot_params->cpu_info; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_cpu_info)); + loongson_params->cpu_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_system_info (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_system_info *src = (void *) smbios_table->lp.system_offset; + grub_efi_loongson_system_info *dst = &loongson_boot_params->system_info; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_system_info)); + loongson_params->system_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_irq_src_routing_table (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_irq_src_routing_table *src = (void *) smbios_table->lp.irq_offset; + grub_efi_loongson_irq_src_routing_table *dst = &loongson_boot_params->irq_src_routing_table; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_irq_src_routing_table)); + loongson_params->irq_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_interface_info (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_interface_info *src = (void *) smbios_table->lp.interface_offset; + grub_efi_loongson_interface_info *dst = &loongson_boot_params->interface_info; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_interface_info)); + loongson_params->interface_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_special_attribute (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_special_attribute *src = (void *) smbios_table->lp.special_offset; + grub_efi_loongson_special_attribute *dst = &loongson_boot_params->special_attribute; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_special_attribute)); + loongson_params->special_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +static void +grub_efi_loongson_init_board_devices (grub_efi_loongson_smbios_table *smbios_table) +{ + grub_efi_loongson_board_devices *src = (void *) smbios_table->lp.boarddev_table_offset; + grub_efi_loongson_board_devices *dst = &loongson_boot_params->board_devices; + + if (!src) + return; + + grub_memcpy (dst, src, sizeof (grub_efi_loongson_board_devices)); + loongson_params->boarddev_table_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; +} + +#define ADD_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) + (size))) + +static void +grub_efi_loongson_init_memory_map (grub_efi_loongson_smbios_table *smbios_table, + grub_efi_memory_descriptor_t *mmap_buf, + grub_efi_uintn_t mmap_size, + grub_efi_uintn_t desc_size) +{ + grub_efi_loongson_memory_map *src = (void *) smbios_table->lp.memory_offset; + grub_efi_loongson_memory_map *dst = &loongson_boot_params->memory_map; + grub_efi_memory_descriptor_t *mmap_end; + grub_efi_memory_descriptor_t *desc; + grub_efi_memory_descriptor_t *desc_next; + grub_efi_uint32_t mem_types_reserved[] = + { + 1, // GRUB_EFI_RESERVED_MEMORY_TYPE + 0, // GRUB_EFI_LOADER_CODE + 0, // GRUB_EFI_LOADER_DATA + 0, // GRUB_EFI_BOOT_SERVICES_CODE + 0, // GRUB_EFI_BOOT_SERVICES_DATA + 1, // GRUB_EFI_RUNTIME_SERVICES_CODE + 1, // GRUB_EFI_RUNTIME_SERVICES_DATA + 0, // GRUB_EFI_CONVENTIONAL_MEMORY + 1, // GRUB_EFI_UNUSABLE_MEMORY + 0, // GRUB_EFI_ACPI_RECLAIM_MEMORY + 0, // GRUB_EFI_ACPI_MEMORY_NVS + 1, // GRUB_EFI_MEMORY_MAPPED_IO + 1, // GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE + 1, // GRUB_EFI_PAL_CODE + 1, // GRUB_EFI_PERSISTENT_MEMORY + }; + grub_uint32_t need_sort = 1; + + if (!src) + return; + + dst->vers = src->vers; + dst->nr_map = 0; + dst->mem_freq = src->mem_freq; + loongson_params->memory_offset = (grub_uint64_t) dst - (grub_uint64_t) loongson_params; + + if (!mmap_buf || !mmap_size || !desc_size) + return; + + mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); + + /* drop reserved */ + for (desc = mmap_buf, + desc_next = desc; + desc < mmap_end; + desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) + { + desc->type = mem_types_reserved[desc->type]; + if (desc->type) + continue; + + if (desc != desc_next) + *desc_next = *desc; + desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size); + } + mmap_end = desc_next; + + /* sort: low->high */ + while (need_sort) + { + need_sort = 0; + + for (desc = mmap_buf, + desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + (desc < mmap_end) && (desc_next < mmap_end); + desc = desc_next, + desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_memory_descriptor_t tmp; + + if (desc->physical_start <= desc_next->physical_start) + continue; + + tmp = *desc; + *desc = *desc_next; + *desc_next = tmp; + need_sort = 1; + } + } + + /* combine continuous memory map */ + for (desc = mmap_buf, + desc_next = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + desc_next < mmap_end; + desc_next = ADD_MEMORY_DESCRIPTOR (desc_next, desc_size)) + { + grub_efi_physical_address_t prev_end = desc->physical_start + (desc->num_pages << 12); + + if (prev_end == desc_next->physical_start) + { + desc->num_pages += desc_next->num_pages; + continue; + } + + desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + grub_memcpy (desc, desc_next, desc_size); + } + mmap_end = ADD_MEMORY_DESCRIPTOR (desc, desc_size); + + /* write to loongson memory map */ + for (desc = mmap_buf; + desc < mmap_end; + desc = ADD_MEMORY_DESCRIPTOR (desc, desc_size)) + { + grub_efi_physical_address_t physical_start = grub_vtop ((void *) desc->physical_start); + grub_efi_physical_address_t physical_end = physical_start + (desc->num_pages << 12); + + physical_start = ALIGN_UP (physical_start, 0x100000); + physical_end = ALIGN_DOWN (physical_end, 0x100000); + + if (physical_start >= physical_end || (physical_end - physical_start) < 0x100000) + continue; + + dst->map[dst->nr_map].node_id = (desc->physical_start >> 44) & 0xf; + dst->map[dst->nr_map].mem_type = (physical_end <= 0x10000000) ? + GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW : + GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH; + dst->map[dst->nr_map].mem_start = physical_start; + dst->map[dst->nr_map].mem_size = (physical_end - physical_start) >> 20; + + grub_dprintf ("loongson", "memory map %03u: 0x%016lx 0x%016lx @ %u\n", + dst->nr_map, physical_start, physical_end - physical_start, + dst->map[dst->nr_map].node_id); + + dst->nr_map ++; + } +} + +#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) +#define SUB_MEMORY_DESCRIPTOR(desc, size) \ + ((grub_efi_memory_descriptor_t *) ((char *) (desc) - (size))) + +void +grub_efi_loongson_alloc_boot_params (void) +{ + grub_efi_memory_descriptor_t *mmap_buf; + grub_efi_memory_descriptor_t *mmap_end; + grub_efi_memory_descriptor_t *desc; + grub_efi_uintn_t mmap_size; + grub_efi_uintn_t desc_size; + grub_efi_physical_address_t address; + grub_efi_allocate_type_t type; + grub_efi_uintn_t pages; + grub_efi_status_t status; + grub_efi_boot_services_t *b; + int mm_status; + + type = GRUB_EFI_ALLOCATE_ADDRESS; + pages = BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size); + + mmap_size = (1 << 12); + mmap_buf = grub_malloc (mmap_size); + if (!mmap_buf) + grub_fatal ("out of memory!"); + + mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); + if (mm_status == 0) + { + grub_free (mmap_buf); + mmap_size += desc_size * 32; + + mmap_buf = grub_malloc (mmap_size); + if (!mmap_buf) + grub_fatal ("out of memory!"); + + mm_status = grub_efi_get_memory_map (&mmap_size, mmap_buf, 0, &desc_size, 0); + } + + if (mm_status < 0) + grub_fatal ("cannot get memory map!"); + + mmap_end = ADD_MEMORY_DESCRIPTOR (mmap_buf, mmap_size); + + for (desc = SUB_MEMORY_DESCRIPTOR (mmap_end, desc_size); + desc >= mmap_buf; + desc = SUB_MEMORY_DESCRIPTOR (desc, desc_size)) + { + if (desc->type != GRUB_EFI_CONVENTIONAL_MEMORY) + continue; + if (desc->physical_start >= GRUB_EFI_MAX_USABLE_ADDRESS) + continue; + if (desc->num_pages < pages) + continue; + + address = desc->physical_start; + break; + } + + grub_free (mmap_buf); + + b = grub_efi_system_table->boot_services; + status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_RUNTIME_SERVICES_DATA, pages, &address); + if (status != GRUB_EFI_SUCCESS) + grub_fatal ("cannot allocate Loongson boot parameters!"); + + loongson_boot_params = (void *) ((grub_addr_t) address); +} + +void +grub_efi_loongson_free_boot_params (void) +{ + grub_efi_free_pages ((grub_addr_t) loongson_boot_params, + BYTES_TO_PAGES (loongson_boot_params_size + loongson_reset_code_size)); +} + +void * +grub_efi_loongson_get_smbios_table (void) +{ + static grub_efi_loongson_smbios_table *smbios_table; + grub_efi_loongson_boot_params *old_boot_params; + struct bootparamsinterface* boot_params; + void * tmp_boot_params = NULL; + char * p = NULL; + if(smbios_table) + return smbios_table; + + tmp_boot_params = grub_efi_loongson_get_boot_params(); + if(tmp_boot_params == NULL) + { + grub_dprintf("loongson", "tmp_boot_params is NULL\n"); + return tmp_boot_params; + } + + boot_params = (struct bootparamsinterface *)tmp_boot_params; + p = (char *)&(boot_params->signature); + if(grub_strncmp(p, "BPI", 3) == 0) + { + grub_dprintf("loongson", "find new bpi\n"); + return boot_params ? boot_params : 0; + } + else + { + old_boot_params = (grub_efi_loongson_boot_params *)tmp_boot_params; + return old_boot_params ? &old_boot_params->efi.smbios : 0; + } + +} + +int +grub_efi_is_loongson (void) +{ + return grub_efi_loongson_get_smbios_table () ? 1 : 0; +} + +void * +grub_efi_loongson_get_boot_params (void) +{ + static void * boot_params = NULL; + grub_efi_configuration_table_t *tables; + grub_efi_guid_t smbios_guid = GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID; + unsigned int i; + + if (boot_params) + return boot_params; + + /* Look for Loongson SMBIOS in UEFI config tables. */ + tables = grub_efi_system_table->configuration_table; + + for (i = 0; i < grub_efi_system_table->num_table_entries; i++) + if (grub_memcmp (&tables[i].vendor_guid, &smbios_guid, sizeof (smbios_guid)) == 0) + { + boot_params= tables[i].vendor_table; + grub_dprintf ("loongson", "found registered SMBIOS @ %p\n", boot_params); + break; + } + return boot_params; +} + +grub_uint8_t +grub_efi_loongson_calculatesum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) +{ + grub_uint8_t sum; + grub_efi_uintn_t count; + + for (sum = 0, count = 0; count < length; count++) + { + sum = (grub_uint8_t) (sum + *(buffer + count)); + } + return sum; +} + +grub_uint8_t +grub_efi_loongson_grub_calculatechecksum8 (const grub_uint8_t *buffer, grub_efi_uintn_t length) +{ + grub_uint8_t checksum; + + checksum = grub_efi_loongson_calculatesum8(buffer, length); + + return (grub_uint8_t) (0x100 - checksum); +} + + +grub_uint32_t +grub_efi_loongson_memmap_sort(struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype) +{ + grub_uint64_t tempmemsize = 0; + grub_uint32_t j = 0; + grub_uint32_t t = 0; + + for(j = 0; j < length;) + { + tempmemsize = array[j].memsize; + for(t = j + 1; t < length; t++) + { + if(array[j].memstart + tempmemsize == array[t].memstart) + { + tempmemsize += array[t].memsize; + } + else + { + break; + } + } + bpmem->map[index].memtype = memtype; + bpmem->map[index].memstart = array[j].memstart; + bpmem->map[index].memsize = tempmemsize; + grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", + index, + bpmem->map[index].memtype, + (unsigned long long)bpmem->map[index].memstart, + (unsigned long long)bpmem->map[index].memstart+ bpmem->map[index].memsize + ); + j = t; + index++; + } + return index; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S new file mode 100644 index 00000000..976ebd44 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/efi/loongson_asm.S @@ -0,0 +1,61 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + + .file "loongson.S" + .text + + .set push + .set noreorder + .align 4 + +VARIABLE (grub_efi_loongson_reset_start) + +VARIABLE (grub_efi_loongson_reset_system_addr) + .dword 0 + +reset_system: + bal 1f + move $a1, $zero +1: + ld $t9, -16($ra) + move $a2, $zero + jalr $t9 + move $a3, $zero + +FUNCTION(grub_efi_loongson_reset_cold) + b reset_system + li $a0, 0 + +FUNCTION(grub_efi_loongson_reset_warm) + b reset_system + li $a0, 1 + +FUNCTION(grub_efi_loongson_reset_shutdown) + b reset_system + li $a0, 2 + +FUNCTION(grub_efi_loongson_reset_suspend) + b reset_system + li $a0, 3 + +VARIABLE (grub_efi_loongson_reset_end) + + .set pop + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c new file mode 100644 index 00000000..9712b6f7 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator.c @@ -0,0 +1,169 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include + +#include +#include +#include +#include + +#include +#include + +extern grub_uint8_t grub_relocator_forward_start; +extern grub_uint8_t grub_relocator_forward_end; +extern grub_uint8_t grub_relocator_backward_start; +extern grub_uint8_t grub_relocator_backward_end; + +#define REGW_SIZEOF (6 * sizeof (grub_uint32_t)) +#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) + +#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ + - &grub_relocator_##x##_start) +#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ + + REGW_SIZEOF * 3) +grub_size_t grub_relocator_align = sizeof (grub_uint64_t); +grub_size_t grub_relocator_forward_size; +grub_size_t grub_relocator_backward_size; +grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; + +void +grub_cpu_relocator_init (void) +{ + grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); + grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); +} + +static void +write_reg (int regn, grub_uint64_t val, void **target) +{ + grub_uint32_t lui; + grub_uint32_t ori; + grub_uint32_t dsll; + + /* lui $r, 0 */ + lui = (0x3c00 | regn) << 16; + /* ori $r, $r, 0 */ + ori = (0x3400 | (regn << 5) | regn) << 16; + /* dsll $r, $r, 16 */ + dsll = (regn << 16) | (regn << 11) | (16 << 6) | 56; + + /* lui $r, val[63:48]. */ + *(grub_uint32_t *) *target = lui | (grub_uint16_t) (val >> 48); + *target = ((grub_uint32_t *) *target) + 1; + /* ori $r, val[47:32]. */ + *(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 32); + *target = ((grub_uint32_t *) *target) + 1; + /* dsll $r, $r, 16 */ + *(grub_uint32_t *) *target = dsll; + *target = ((grub_uint32_t *) *target) + 1; + /* ori $r, val[31:16]. */ + *(grub_uint32_t *) *target = ori | (grub_uint16_t) (val >> 16); + *target = ((grub_uint32_t *) *target) + 1; + /* dsll $r, $r, 16 */ + *(grub_uint32_t *) *target = dsll; + *target = ((grub_uint32_t *) *target) + 1; + /* ori $r, val[15:0]. */ + *(grub_uint32_t *) *target = ori | (grub_uint16_t) val; + *target = ((grub_uint32_t *) *target) + 1; +} + +static void +write_jump (int regn, void **target) +{ + /* j $r. */ + *(grub_uint32_t *) *target = (regn << 21) | 0x8; + *target = ((grub_uint32_t *) *target) + 1; + /* nop. */ + *(grub_uint32_t *) *target = 0; + *target = ((grub_uint32_t *) *target) + 1; +} + +void +grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) +{ + write_reg (1, addr, &rels); + write_jump (1, &rels); +} + +void +grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, + grub_size_t size) +{ + void *ptr = ptr0; + write_reg (8, (grub_uint64_t) src, &ptr); + write_reg (9, (grub_uint64_t) dest, &ptr); + write_reg (10, (grub_uint64_t) size, &ptr); + grub_memcpy (ptr, &grub_relocator_backward_start, + RELOCATOR_SRC_SIZEOF (backward)); +} + +void +grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, + grub_size_t size) +{ + void *ptr = ptr0; + write_reg (8, (grub_uint64_t) src, &ptr); + write_reg (9, (grub_uint64_t) dest, &ptr); + write_reg (10, (grub_uint64_t) size, &ptr); + grub_memcpy (ptr, &grub_relocator_forward_start, + RELOCATOR_SRC_SIZEOF (forward)); +} + +grub_err_t +grub_relocator64_boot (struct grub_relocator *rel, + struct grub_relocator64_state state) +{ + grub_relocator_chunk_t ch; + void *ptr; + grub_err_t err; + void *relst; + grub_size_t relsize; + grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; + unsigned i; + grub_addr_t vtarget; + + err = grub_relocator_alloc_chunk_align (rel, &ch, 0, + (0xffffffff - stateset_size) + + 1, stateset_size, + grub_relocator_align, + GRUB_RELOCATOR_PREFERENCE_NONE, 0); + if (err) + return err; + + ptr = get_virtual_current_address (ch); + for (i = 1; i < 32; i++) + write_reg (i, state.gpr[i], &ptr); + write_jump (state.jumpreg, &ptr); + + vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), + stateset_size); + + err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); + if (err) + return err; + + grub_arch_sync_caches ((void *) relst, relsize); + + ((void (*) (void)) relst) (); + + /* Not reached. */ + return GRUB_ERR_NONE; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S new file mode 100644 index 00000000..ae37be3b --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/relocator_asm.S @@ -0,0 +1,56 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + + .p2align 4 /* force 16-byte alignment */ + + .set push + .set noreorder + .set nomacro + +VARIABLE (grub_relocator_forward_start) + +copycont1: + ld $11,0($8) + sd $11,0($9) + daddiu $8, $8, 8 + daddiu $10, $10, -8 + bne $10, $0, copycont1 + daddiu $9, $9, 8 + +VARIABLE (grub_relocator_forward_end) + +VARIABLE (grub_relocator_backward_start) + + daddu $9, $9, $10 + daddu $8, $8, $10 + /* Backward movsl is implicitly off-by-one. compensate that. */ + daddiu $9, $9, -8 + daddiu $8, $8, -8 +copycont2: + ld $11,0($8) + sd $11,0($9) + daddiu $8, $8, -8 + daddiu $10, $10, -8 + bne $10, $0, copycont2 + daddiu $9, $9, -8 + +VARIABLE (grub_relocator_backward_end) + + .set pop diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S new file mode 100644 index 00000000..99ae22c1 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/mips64/setjmp.S @@ -0,0 +1,69 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2007,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include + + .file "setjmp.S" + +GRUB_MOD_LICENSE "GPLv3+" + + .text + +/* + * int grub_setjmp (grub_jmp_buf env) + */ +FUNCTION(grub_setjmp) + GRUB_ASM_REG_S $s0, 0($a0) + GRUB_ASM_REG_S $s1, 8($a0) + GRUB_ASM_REG_S $s2, 16($a0) + GRUB_ASM_REG_S $s3, 24($a0) + GRUB_ASM_REG_S $s4, 32($a0) + GRUB_ASM_REG_S $s5, 40($a0) + GRUB_ASM_REG_S $s6, 48($a0) + GRUB_ASM_REG_S $s7, 56($a0) + GRUB_ASM_REG_S $s8, 64($a0) + GRUB_ASM_REG_S $gp, 72($a0) + GRUB_ASM_REG_S $sp, 80($a0) + GRUB_ASM_REG_S $ra, 88($a0) + move $v0, $zero + move $v1, $zero + jr $ra + nop +/* + * int grub_longjmp (grub_jmp_buf env, int val) + */ +FUNCTION(grub_longjmp) + GRUB_ASM_REG_L $s0, 0($a0) + GRUB_ASM_REG_L $s1, 8($a0) + GRUB_ASM_REG_L $s2, 16($a0) + GRUB_ASM_REG_L $s3, 24($a0) + GRUB_ASM_REG_L $s4, 32($a0) + GRUB_ASM_REG_L $s5, 40($a0) + GRUB_ASM_REG_L $s6, 48($a0) + GRUB_ASM_REG_L $s7, 56($a0) + GRUB_ASM_REG_L $s8, 64($a0) + GRUB_ASM_REG_L $gp, 72($a0) + GRUB_ASM_REG_L $sp, 80($a0) + GRUB_ASM_REG_L $ra, 88($a0) + addiu $v0, $zero, 1 + movn $v0, $a1, $a1 + move $v1, $zero + jr $ra + nop diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c new file mode 100644 index 00000000..0ee1cb57 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/relocator.c @@ -0,0 +1,1660 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009, 2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +struct grub_relocator +{ + struct grub_relocator_chunk *chunks; + grub_phys_addr_t postchunks; + grub_phys_addr_t highestaddr; + grub_phys_addr_t highestnonpostaddr; + grub_size_t relocators_size; +}; + +struct grub_relocator_subchunk +{ + enum {CHUNK_TYPE_IN_REGION, CHUNK_TYPE_REGION_START, +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + CHUNK_TYPE_FIRMWARE, CHUNK_TYPE_LEFTOVER +#endif + } type; + grub_mm_region_t reg; + grub_phys_addr_t start; + grub_size_t size; + grub_size_t pre_size; + struct grub_relocator_extra_block *extra; +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + struct grub_relocator_fw_leftover *pre, *post; +#endif +}; + +struct grub_relocator_chunk +{ + struct grub_relocator_chunk *next; + grub_phys_addr_t src; + void *srcv; + grub_phys_addr_t target; + grub_size_t size; + struct grub_relocator_subchunk *subchunks; + unsigned nsubchunks; +}; + +struct grub_relocator_extra_block +{ + struct grub_relocator_extra_block *next; + struct grub_relocator_extra_block **prev; + grub_phys_addr_t start; + grub_phys_addr_t end; +}; + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS +struct grub_relocator_fw_leftover +{ + struct grub_relocator_fw_leftover *next; + struct grub_relocator_fw_leftover **prev; + grub_phys_addr_t quantstart; + grub_uint8_t freebytes[GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT / 8]; +}; + +static struct grub_relocator_fw_leftover *leftovers; +#endif + +static struct grub_relocator_extra_block *extra_blocks; + +void * +get_virtual_current_address (grub_relocator_chunk_t in) +{ + return in->srcv; +} + +grub_phys_addr_t +get_physical_target_address (grub_relocator_chunk_t in) +{ + return in->target; +} + +struct grub_relocator * +grub_relocator_new (void) +{ + struct grub_relocator *ret; + + grub_cpu_relocator_init (); + + ret = grub_zalloc (sizeof (struct grub_relocator)); + if (!ret) + return NULL; + + ret->postchunks = ~(grub_phys_addr_t) 0; + ret->relocators_size = grub_relocator_jumper_size; + grub_dprintf ("relocator", "relocators_size=%lu\n", + (unsigned long) ret->relocators_size); + return ret; +} + +#define DIGITSORT_BITS 8 +#define DIGITSORT_MASK ((1 << DIGITSORT_BITS) - 1) +#define BITS_IN_BYTE 8 + +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) + +static inline int +is_start (int type) +{ + return !(type & 1) && (type != COLLISION_START); +} + +static void +allocate_regstart (grub_phys_addr_t addr, grub_size_t size, grub_mm_region_t rb, + grub_mm_region_t *regancestor, grub_mm_header_t hancestor) +{ + grub_addr_t newreg_start, newreg_raw_start + = (grub_addr_t) rb + (addr - grub_vtop (rb)) + size; + grub_addr_t newreg_size, newreg_presize; + grub_mm_header_t new_header; + grub_mm_header_t hb = (grub_mm_header_t) (rb + 1); + +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "ra = %p, rb = %p\n", regancestor, rb); +#endif + newreg_start = ALIGN_UP (newreg_raw_start, GRUB_MM_ALIGN); + newreg_presize = newreg_start - newreg_raw_start; + newreg_size = rb->size - (newreg_start - (grub_addr_t) rb); + if ((hb->size << GRUB_MM_ALIGN_LOG2) >= newreg_start + - (grub_addr_t) rb) + { + grub_mm_header_t newhnext = hb->next; + grub_size_t newhsize = ((hb->size << GRUB_MM_ALIGN_LOG2) + - (newreg_start + - (grub_addr_t) rb)) >> GRUB_MM_ALIGN_LOG2; + new_header = (void *) (newreg_start + sizeof (*rb)); + if (newhnext == hb) + newhnext = new_header; + new_header->next = newhnext; + new_header->size = newhsize; + new_header->magic = GRUB_MM_FREE_MAGIC; + } + else + { + new_header = hb->next; + if (new_header == hb) + new_header = (void *) (newreg_start + sizeof (*rb)); + } + { + struct grub_mm_header *newregfirst = rb->first; + struct grub_mm_region *newregnext = rb->next; + struct grub_mm_region *newreg = (void *) newreg_start; + hancestor->next = new_header; + if (newregfirst == hb) + newregfirst = new_header; + newreg->first = newregfirst; + newreg->next = newregnext; + newreg->pre_size = newreg_presize; + newreg->size = newreg_size; + *regancestor = newreg; + { + grub_mm_header_t h = newreg->first, hp = NULL; + do + { + if ((void *) h < (void *) (newreg + 1)) + grub_fatal ("Failed to adjust memory region: %p, %p, %p, %p, %p", + newreg, newreg->first, h, hp, hb); +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + if ((void *) h == (void *) (newreg + 1)) + grub_dprintf ("relocator", + "Free start memory region: %p, %p, %p, %p, %p", + newreg, newreg->first, h, hp, hb); +#endif + hp = h; + h = h->next; + } + while (h != newreg->first); + } + } +} + +static void +allocate_inreg (grub_phys_addr_t paddr, grub_size_t size, + grub_mm_header_t hb, grub_mm_header_t hbp, + grub_mm_region_t rb) +{ + struct grub_mm_header *foll = NULL; + grub_addr_t vaddr = (grub_addr_t) hb + (paddr - grub_vtop (hb)); + +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "inreg paddr = 0x%lx, size = %lu," + " hb = %p, hbp = %p, rb = %p, vaddr = 0x%lx\n", + (unsigned long) paddr, (unsigned long) size, hb, hbp, + rb, (unsigned long) vaddr); +#endif + + if (ALIGN_UP (vaddr + size, GRUB_MM_ALIGN) + GRUB_MM_ALIGN + <= (grub_addr_t) (hb + hb->size)) + { + foll = (void *) ALIGN_UP (vaddr + size, GRUB_MM_ALIGN); + foll->magic = GRUB_MM_FREE_MAGIC; + foll->size = hb + hb->size - foll; +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "foll = %p, foll->size = %lu\n", foll, + (unsigned long) foll->size); +#endif + } + + if (vaddr - (grub_addr_t) hb >= sizeof (*hb)) + { + hb->size = ((vaddr - (grub_addr_t) hb) >> GRUB_MM_ALIGN_LOG2); + if (foll) + { + foll->next = hb; + hbp->next = foll; + if (rb->first == hb) + { + rb->first = foll; + } + } + } + else + { + if (foll) + { + foll->next = hb->next; + } + else + foll = hb->next; + + hbp->next = foll; + if (rb->first == hb) + { + rb->first = foll; + } + if (rb->first == hb) + { + rb->first = (void *) (rb + 1); + } + } +} + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS +static void +check_leftover (struct grub_relocator_fw_leftover *lo) +{ + unsigned i; + for (i = 0; i < sizeof (lo->freebytes); i++) + if (lo->freebytes[i] != 0xff) + return; + grub_relocator_firmware_free_region (lo->quantstart, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + *lo->prev = lo->next; + if (lo->next) + lo->next->prev = lo->prev; +} +#endif + +static void +free_subchunk (const struct grub_relocator_subchunk *subchu) +{ + switch (subchu->type) + { + case CHUNK_TYPE_REGION_START: + { + grub_mm_region_t r1, r2, *rp; + grub_mm_header_t h; + grub_size_t pre_size; + r1 = subchu->reg; + r2 = (grub_mm_region_t) ALIGN_UP ((grub_addr_t) subchu->reg + + (grub_vtop (subchu->reg) + - subchu->start) + subchu->size, + GRUB_MM_ALIGN); + for (rp = &grub_mm_base; *rp && *rp != r2; rp = &((*rp)->next)); + pre_size = subchu->pre_size; + + if (*rp) + { + grub_mm_header_t h2, *hp; + r1->first = r2->first; + r1->next = r2->next; + r1->pre_size = pre_size; + r1->size = r2->size + (r2 - r1) * sizeof (*r2); + *rp = r1; + h = (grub_mm_header_t) (r1 + 1); + h->next = r2->first; + h->magic = GRUB_MM_FREE_MAGIC; + h->size = (r2 - r1 - 1); + for (hp = &r2->first, h2 = *hp; h2->next != r2->first; + hp = &(h2->next), h2 = *hp) + if (h2 == (grub_mm_header_t) (r2 + 1)) + break; + if (h2 == (grub_mm_header_t) (r2 + 1)) + { + h->size = h2->size + (h2 - h); + h->next = h2->next; + *hp = h; + if (hp == &r2->first) + { + for (h2 = r2->first; h2->next != r2->first; h2 = h2->next); + h2->next = h; + } + } + else + { + h2->next = h; + } + } + else + { + r1->pre_size = pre_size; + r1->size = (r2 - r1) * sizeof (*r2); + /* Find where to insert this region. + Put a smaller one before bigger ones, + to prevent fragmentation. */ + for (rp = &grub_mm_base; *rp; rp = &((*rp)->next)) + if ((*rp)->size > r1->size) + break; + r1->next = *rp; + *rp = r1->next; + h = (grub_mm_header_t) (r1 + 1); + r1->first = h; + h->next = h; + h->magic = GRUB_MM_FREE_MAGIC; + h->size = (r2 - r1 - 1); + } + for (r2 = grub_mm_base; r2; r2 = r2->next) + if ((grub_addr_t) r2 + r2->size == (grub_addr_t) r1) + break; + if (r2) + { + grub_mm_header_t hl2, hl, g; + g = (grub_mm_header_t) ((grub_addr_t) r2 + r2->size); + g->size = (grub_mm_header_t) r1 - g; + r2->size += r1->size; + for (hl = r2->first; hl->next != r2->first; hl = hl->next); + for (hl2 = r1->first; hl2->next != r1->first; hl2 = hl2->next); + hl2->next = r2->first; + r2->first = r1->first; + hl->next = r2->first; + *rp = (*rp)->next; + grub_free (g + 1); + } + break; + } + case CHUNK_TYPE_IN_REGION: + { + grub_mm_header_t h = (grub_mm_header_t) ALIGN_DOWN ((grub_addr_t) subchu->start, + GRUB_MM_ALIGN); + h->size + = ((subchu->start + subchu->size + GRUB_MM_ALIGN - 1) / GRUB_MM_ALIGN) + - (subchu->start / GRUB_MM_ALIGN) - 1; + h->next = h; + h->magic = GRUB_MM_ALLOC_MAGIC; + grub_free (h + 1); + break; + } +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case CHUNK_TYPE_FIRMWARE: + case CHUNK_TYPE_LEFTOVER: + { + grub_addr_t fstart, fend; + fstart = ALIGN_UP (subchu->start, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + fend = ALIGN_DOWN (subchu->start + subchu->size, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + if (fstart < fend) + grub_relocator_firmware_free_region (fstart, fend - fstart); +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + if (subchu->pre) + { + int off = subchu->start - fstart + - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + grub_memset (subchu->pre->freebytes + off / 8 + 1, + 0xff, sizeof (subchu->pre->freebytes) - off / 8 - 1); + subchu->pre->freebytes[off / 8] |= ~((1 << (off % 8)) - 1); + check_leftover (subchu->pre); + } + if (subchu->post) + { + int off = subchu->start + subchu->size - fend; + grub_memset (subchu->pre->freebytes, + 0xff, sizeof (subchu->pre->freebytes) - off / 8); + subchu->pre->freebytes[off / 8] |= ((1 << (8 - (off % 8))) - 1); + check_leftover (subchu->post); + } +#endif + *subchu->extra->prev = subchu->extra->next; + grub_free (subchu->extra); + } + break; +#endif + } +} + +static int +malloc_in_range (struct grub_relocator *rel, + grub_addr_t start, grub_addr_t end, grub_addr_t align, + grub_size_t size, struct grub_relocator_chunk *res, + int from_low_priv, int collisioncheck) +{ + grub_mm_region_t r, *ra, base_saved; + struct grub_relocator_mmap_event *events = NULL, *eventt = NULL, *t; + /* 128 is just in case of additional malloc (shouldn't happen). */ + unsigned maxevents = 2 + 128; + grub_mm_header_t p, pa; + unsigned *counter; + int nallocs = 0; + unsigned j, N = 0; + grub_addr_t target = 0; + + grub_dprintf ("relocator", + "trying to allocate in 0x%lx-0x%lx aligned 0x%lx size 0x%lx\n", + (unsigned long) start, (unsigned long) end, + (unsigned long) align, (unsigned long) size); + + start = ALIGN_UP (start, align); + end = ALIGN_DOWN (end - size, align) + size; + + if (end < start + size) + return 0; + + /* We have to avoid any allocations when filling scanline events. + Hence 2-stages. + */ + for (r = grub_mm_base; r; r = r->next) + { + p = r->first; + do + { + if ((grub_addr_t) p < (grub_addr_t) (r + 1) + || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) + grub_fatal ("%d: out of range pointer: %p\n", __LINE__, p); + maxevents += 2; + p = p->next; + } + while (p != r->first); + maxevents += 4; + } + + if (collisioncheck && rel) + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + maxevents += 2; + } + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + { + struct grub_relocator_extra_block *cur; + for (cur = extra_blocks; cur; cur = cur->next) + maxevents += 2; + } + for (r = grub_mm_base; r; r = r->next) + maxevents += 2; + + maxevents += grub_relocator_firmware_get_max_events (); +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + { + struct grub_relocator_fw_leftover *cur; + for (cur = leftovers; cur; cur = cur->next) + { + int l = 0; + unsigned i; + for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++) + { + if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1)) + maxevents++; + l = ((cur->freebytes[i / 8] >> (i % 8)) & 1); + } + if (l) + maxevents++; + } + } +#endif + + eventt = grub_malloc (maxevents * sizeof (events[0])); + counter = grub_malloc ((DIGITSORT_MASK + 2) * sizeof (counter[0])); + events = grub_malloc (maxevents * sizeof (events[0])); + if (!events || !eventt || !counter) + { + grub_dprintf ("relocator", "events or counter allocation failed %d\n", + maxevents); + grub_free (events); + grub_free (eventt); + grub_free (counter); + return 0; + } + + if (collisioncheck && rel) + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + { + events[N].type = COLLISION_START; + events[N].pos = chunk->target; + N++; + events[N].type = COLLISION_END; + events[N].pos = chunk->target + chunk->size; + N++; + } + } + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + for (r = grub_mm_base; r; r = r->next) + { +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n", + (unsigned long) r - r->pre_size, + (unsigned long) (r + 1) + r->size); +#endif + events[N].type = FIRMWARE_BLOCK_START; + events[N].pos = (grub_addr_t) r - r->pre_size; + N++; + events[N].type = FIRMWARE_BLOCK_END; + events[N].pos = (grub_addr_t) (r + 1) + r->size; + N++; + } + { + struct grub_relocator_extra_block *cur; + for (cur = extra_blocks; cur; cur = cur->next) + { +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "Blocking at 0x%lx-0x%lx\n", + (unsigned long) cur->start, (unsigned long) cur->end); +#endif + events[N].type = FIRMWARE_BLOCK_START; + events[N].pos = cur->start; + N++; + events[N].type = FIRMWARE_BLOCK_END; + events[N].pos = cur->end; + N++; + } + } + + N += grub_relocator_firmware_fill_events (events + N); + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + { + struct grub_relocator_fw_leftover *cur; + for (cur = leftovers; cur; cur = cur->next) + { + unsigned i; + int l = 0; + for (i = 0; i < GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; i++) + { + if (l != ((cur->freebytes[i / 8] >> (i % 8)) & 1)) + { + events[N].type = l ? REG_LEFTOVER_END : REG_LEFTOVER_START; + events[N].pos = cur->quantstart + i; + events[N].leftover = cur; + N++; + } + l = ((cur->freebytes[i / 8] >> (i % 8)) & 1); + } + if (l) + { + events[N].type = REG_LEFTOVER_END; + events[N].pos = cur->quantstart + i; + events[N].leftover = cur; + N++; + } + } + } +#endif +#endif + + /* No malloc from this point. */ + base_saved = grub_mm_base; + grub_mm_base = NULL; + + for (ra = &base_saved, r = *ra; r; ra = &(r->next), r = *ra) + { + pa = r->first; + p = pa->next; + if (p->magic == GRUB_MM_ALLOC_MAGIC) + continue; + do + { + if (p->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", + __FILE__, + __LINE__, p, p->magic); + if (p == (grub_mm_header_t) (r + 1)) + { + events[N].type = REG_BEG_START; + events[N].pos = grub_vtop (r) - r->pre_size; + events[N].reg = r; + events[N].regancestor = ra; + events[N].head = p; + events[N].hancestor = pa; + N++; + events[N].type = REG_BEG_END; + events[N].pos = grub_vtop (p + p->size) - sizeof (*r) + - sizeof (struct grub_mm_header); + N++; + } + else + { + events[N].type = IN_REG_START; + events[N].pos = grub_vtop (p); + events[N].head = p; + events[N].hancestor = pa; + events[N].reg = r; + N++; + events[N].type = IN_REG_END; + events[N].pos = grub_vtop (p + p->size); + N++; + } + pa = p; + p = pa->next; + } + while (pa != r->first); + } + + /* Put ending events after starting events. */ + { + int st = 0, e = N / 2; + for (j = 0; j < N; j++) + if (is_start (events[j].type) || events[j].type == COLLISION_START) + eventt[st++] = events[j]; + else + eventt[e++] = events[j]; + t = eventt; + eventt = events; + events = t; + } + + { + unsigned i; + for (i = 0; i < (BITS_IN_BYTE * sizeof (grub_addr_t) / DIGITSORT_BITS); + i++) + { + grub_memset (counter, 0, (1 + (1 << DIGITSORT_BITS)) * sizeof (counter[0])); + for (j = 0; j < N; j++) + counter[((events[j].pos >> (DIGITSORT_BITS * i)) + & DIGITSORT_MASK) + 1]++; + for (j = 0; j <= DIGITSORT_MASK; j++) + counter[j+1] += counter[j]; + for (j = 0; j < N; j++) + eventt[counter[((events[j].pos >> (DIGITSORT_BITS * i)) + & DIGITSORT_MASK)]++] = events[j]; + t = eventt; + eventt = events; + events = t; + } + } + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + retry: +#endif + + /* Now events are nicely sorted. */ + { + int nstarted = 0, ncollisions = 0, nstartedfw = 0, nblockfw = 0; +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + int nlefto = 0; +#else + const int nlefto = 0; +#endif + grub_addr_t starta = 0; + for (j = from_low_priv ? 0 : N - 1; from_low_priv ? j < N : (j + 1); + from_low_priv ? j++ : j--) + { + int isinsidebefore, isinsideafter; + isinsidebefore = (!ncollisions && (nstarted || (((nlefto || nstartedfw) + && !nblockfw)))); + switch (events[j].type) + { +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case REG_FIRMWARE_START: + nstartedfw++; + break; + + case REG_FIRMWARE_END: + nstartedfw--; + break; + + case FIRMWARE_BLOCK_START: + nblockfw++; + break; + + case FIRMWARE_BLOCK_END: + nblockfw--; + break; +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case REG_LEFTOVER_START: + nlefto++; + break; + + case REG_LEFTOVER_END: + nlefto--; + break; +#endif + + case COLLISION_START: + ncollisions++; + break; + + case COLLISION_END: + ncollisions--; + break; + + case IN_REG_START: + case REG_BEG_START: + nstarted++; + break; + + case IN_REG_END: + case REG_BEG_END: + nstarted--; + break; + } + isinsideafter = (!ncollisions && (nstarted || ((nlefto || nstartedfw) + && !nblockfw))); + if (from_low_priv) { + if (!isinsidebefore && isinsideafter) + starta = ALIGN_UP (events[j].pos, align); + + if (isinsidebefore && !isinsideafter) + { + target = starta; + if (target < start) + target = start; + if (target + size <= end && target + size <= events[j].pos) + /* Found an usable address. */ + goto found; + } + } else { + if (!isinsidebefore && isinsideafter) + { + if (events[j].pos >= size) + starta = ALIGN_DOWN (events[j].pos - size, align) + size; + else + starta = 0; + } + if (isinsidebefore && !isinsideafter && starta >= size) + { + target = starta - size; + if (target > end - size) + target = end - size; + if (target >= start && target >= events[j].pos) + goto found; + } + } + } + } + + grub_mm_base = base_saved; + grub_free (events); + grub_free (eventt); + grub_free (counter); + return 0; + + found: + { + int inreg = 0, regbeg = 0, ncol = 0; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + int fwin = 0, fwb = 0, fwlefto = 0; +#endif +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + int last_lo = 0; +#endif + int last_start = 0; + for (j = 0; j < N; j++) + { + int typepre; + if (ncol) + typepre = -1; + else if (regbeg) + typepre = CHUNK_TYPE_REGION_START; + else if (inreg) + typepre = CHUNK_TYPE_IN_REGION; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + else if (fwin && !fwb) + typepre = CHUNK_TYPE_FIRMWARE; + else if (fwlefto && !fwb) + typepre = CHUNK_TYPE_LEFTOVER; +#endif + else + typepre = -1; + + if (j != 0 && events[j - 1].pos != events[j].pos) + { + grub_addr_t alloc_start, alloc_end; + alloc_start = max (events[j - 1].pos, target); + alloc_end = min (events[j].pos, target + size); + if (alloc_end > alloc_start) + { + switch (typepre) + { + case CHUNK_TYPE_REGION_START: + allocate_regstart (alloc_start, alloc_end - alloc_start, + events[last_start].reg, + events[last_start].regancestor, + events[last_start].hancestor); + /* TODO: maintain a reverse lookup tree for hancestor. */ + { + unsigned k; + for (k = 0; k < N; k++) + if (events[k].hancestor == events[last_start].head) + events[k].hancestor = events[last_start].hancestor; + } + break; + case CHUNK_TYPE_IN_REGION: + allocate_inreg (alloc_start, alloc_end - alloc_start, + events[last_start].head, + events[last_start].hancestor, + events[last_start].reg); + { + unsigned k; + for (k = 0; k < N; k++) + if (events[k].hancestor == events[last_start].head) + events[k].hancestor = events[last_start].hancestor; + } + break; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case CHUNK_TYPE_FIRMWARE: + { + grub_addr_t fstart, fend; + fstart + = ALIGN_DOWN (alloc_start, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + fend + = ALIGN_UP (alloc_end, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "requesting %lx-%lx\n", + (unsigned long) fstart, + (unsigned long) fend); +#endif + /* The failure here can be very expensive. */ + if (!grub_relocator_firmware_alloc_region (fstart, + fend - fstart)) + { + if (from_low_priv) + start = fend; + else + end = fstart; + goto retry; + } + break; + } +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case CHUNK_TYPE_LEFTOVER: + { + unsigned offstart = alloc_start + % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + unsigned offend = alloc_end + % GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + struct grub_relocator_fw_leftover *lo + = events[last_lo].leftover; + if (offend == 0 && alloc_end != alloc_start) + offend = GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + lo->freebytes[offstart / 8] + &= ((1 << (8 - (start % 8))) - 1); + grub_memset (lo->freebytes + (offstart + 7) / 8, 0, + offend / 8 - (offstart + 7) / 8); + lo->freebytes[offend / 8] &= ~((1 << (offend % 8)) - 1); + } + break; +#endif + } + nallocs++; + } + } + + switch (events[j].type) + { + case REG_BEG_START: + case IN_REG_START: + if (events[j].type == REG_BEG_START && + (grub_addr_t) (events[j].reg + 1) > target) + regbeg++; + else + inreg++; + last_start = j; + break; + + case REG_BEG_END: + case IN_REG_END: + if (regbeg) + regbeg--; + else + inreg--; + break; + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case REG_FIRMWARE_START: + fwin++; + break; + + case REG_FIRMWARE_END: + fwin--; + break; + + case FIRMWARE_BLOCK_START: + fwb++; + break; + + case FIRMWARE_BLOCK_END: + fwb--; + break; +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case REG_LEFTOVER_START: + fwlefto++; + last_lo = j; + break; + + case REG_LEFTOVER_END: + fwlefto--; + break; +#endif + case COLLISION_START: + ncol++; + break; + case COLLISION_END: + ncol--; + break; + } + + } + } + + /* Malloc is available again. */ + grub_mm_base = base_saved; + + grub_free (eventt); + grub_free (counter); + + { + int last_start = 0; + int inreg = 0, regbeg = 0, ncol = 0; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + int fwin = 0, fwlefto = 0, fwb = 0; +#endif + unsigned cural = 0; + int oom = 0; + res->subchunks = grub_malloc (sizeof (res->subchunks[0]) * nallocs); + if (!res->subchunks) + oom = 1; + res->nsubchunks = nallocs; + + for (j = 0; j < N; j++) + { + int typepre; + if (ncol) + typepre = -1; + else if (regbeg) + typepre = CHUNK_TYPE_REGION_START; + else if (inreg) + typepre = CHUNK_TYPE_IN_REGION; +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + else if (fwin && !fwb) + typepre = CHUNK_TYPE_FIRMWARE; + else if (fwlefto && !fwb) + typepre = CHUNK_TYPE_LEFTOVER; +#endif + else + typepre = -1; + + if (j != 0 && events[j - 1].pos != events[j].pos) + { + grub_addr_t alloc_start, alloc_end; + struct grub_relocator_subchunk tofree; + struct grub_relocator_subchunk *curschu = &tofree; + if (!oom) + curschu = &res->subchunks[cural]; + alloc_start = max (events[j - 1].pos, target); + alloc_end = min (events[j].pos, target + size); + if (alloc_end > alloc_start) + { +#ifdef DEBUG_RELOCATOR_NOMEM_DPRINTF + grub_dprintf ("relocator", "subchunk 0x%lx-0x%lx, %d\n", + (unsigned long) alloc_start, + (unsigned long) alloc_end, typepre); +#endif + curschu->type = typepre; + curschu->start = alloc_start; + curschu->size = alloc_end - alloc_start; + if (typepre == CHUNK_TYPE_REGION_START + || typepre == CHUNK_TYPE_IN_REGION) + { + curschu->reg = events[last_start].reg; + curschu->pre_size = alloc_start - events[j - 1].pos; + } + if (!oom && (typepre == CHUNK_TYPE_REGION_START +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + || typepre == CHUNK_TYPE_FIRMWARE +#endif + )) + { + struct grub_relocator_extra_block *ne; + ne = grub_malloc (sizeof (*ne)); + if (!ne) + { + oom = 1; + grub_memcpy (&tofree, curschu, sizeof (tofree)); + } + else + { + ne->start = alloc_start; + ne->end = alloc_end; + ne->next = extra_blocks; + ne->prev = &extra_blocks; + if (extra_blocks) + extra_blocks->prev = &(ne->next); + extra_blocks = ne; + curschu->extra = ne; + } + } + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + if (!oom && typepre == CHUNK_TYPE_FIRMWARE) + { + grub_addr_t fstart, fend; + + fstart + = ALIGN_DOWN (alloc_start, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + fend + = ALIGN_UP (alloc_end, + GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT); + + { + struct grub_relocator_fw_leftover *lo1 = NULL; + struct grub_relocator_fw_leftover *lo2 = NULL; + if (fstart != alloc_start) + lo1 = grub_malloc (sizeof (*lo1)); + if (fend != alloc_end) + lo2 = grub_malloc (sizeof (*lo2)); + if ((!lo1 && fstart != alloc_start) + || (!lo2 && fend != alloc_end)) + { + struct grub_relocator_extra_block *ne; + grub_free (lo1); + grub_free (lo2); + lo1 = NULL; + lo2 = NULL; + oom = 1; + grub_memcpy (&tofree, curschu, sizeof (tofree)); + ne = extra_blocks; + extra_blocks = extra_blocks->next; + grub_free (ne); + } + if (lo1) + { + lo1->quantstart = fstart; + grub_memset (lo1->freebytes, 0xff, + (alloc_start - fstart) / 8); + lo1->freebytes[(alloc_start - fstart) / 8] + = (1 << ((alloc_start - fstart) % 8)) - 1; + grub_memset (lo1->freebytes + + ((alloc_start - fstart) / 8) + 1, 0, + sizeof (lo1->freebytes) + - (alloc_start - fstart) / 8 - 1); + lo1->next = leftovers; + lo1->prev = &leftovers; + if (leftovers) + leftovers->prev = &lo1->next; + leftovers = lo1; + } + if (lo2) + { + lo2->quantstart + = fend - GRUB_RELOCATOR_FIRMWARE_REQUESTS_QUANT; + grub_memset (lo2->freebytes, 0, + (alloc_end - lo2->quantstart) / 8); + lo2->freebytes[(alloc_end - lo2->quantstart) / 8] + = ~((1 << ((alloc_end - lo2->quantstart) % 8)) - 1); + grub_memset (lo2->freebytes + + ((alloc_end - lo2->quantstart) / 8) + + 1, 0, sizeof (lo2->freebytes) + - (alloc_end - lo2->quantstart) / 8 - 1); + lo2->prev = &leftovers; + if (leftovers) + leftovers->prev = &lo2->next; + lo2->next = leftovers; + leftovers = lo2; + } + curschu->pre = lo1; + curschu->post = lo2; + } + } + + if (typepre == CHUNK_TYPE_LEFTOVER) + { + curschu->pre = events[last_start].leftover; + curschu->post = events[last_start].leftover; + } +#endif + + if (!oom) + cural++; + else + free_subchunk (&tofree); + } + } + + switch (events[j].type) + { + case REG_BEG_START: + case IN_REG_START: + if (events[j].type == REG_BEG_START && + (grub_addr_t) (events[j].reg + 1) > target) + regbeg++; + else + inreg++; + last_start = j; + break; + + case REG_BEG_END: + case IN_REG_END: + inreg = regbeg = 0; + break; + +#if GRUB_RELOCATOR_HAVE_FIRMWARE_REQUESTS + case REG_FIRMWARE_START: + fwin++; + break; + + case REG_FIRMWARE_END: + fwin--; + break; + + case FIRMWARE_BLOCK_START: + fwb++; + break; + + case FIRMWARE_BLOCK_END: + fwb--; + break; +#endif + +#if GRUB_RELOCATOR_HAVE_LEFTOVERS + case REG_LEFTOVER_START: + fwlefto++; + break; + + case REG_LEFTOVER_END: + fwlefto--; + break; +#endif + case COLLISION_START: + ncol++; + break; + case COLLISION_END: + ncol--; + break; + } + } + if (oom) + { + unsigned i; + for (i = 0; i < cural; i++) + free_subchunk (&res->subchunks[i]); + grub_free (res->subchunks); + grub_dprintf ("relocator", "allocation failed with out-of-memory\n"); + grub_free (events); + + return 0; + } + } + + res->src = target; + res->size = size; + + grub_free (events); + + grub_dprintf ("relocator", "allocated: 0x%lx+0x%lx\n", (unsigned long) target, + (unsigned long) size); + + return 1; +} + +static void +adjust_limits (struct grub_relocator *rel, + grub_phys_addr_t *min_addr, grub_phys_addr_t *max_addr, + grub_phys_addr_t in_min, grub_phys_addr_t in_max) +{ + struct grub_relocator_chunk *chunk; + + *min_addr = 0; + *max_addr = rel->postchunks; + + /* Keep chunks in memory in the same order as they'll be after relocation. */ + for (chunk = rel->chunks; chunk; chunk = chunk->next) + { + if (chunk->target > in_max && chunk->src < *max_addr + && chunk->src < rel->postchunks) + *max_addr = chunk->src; + if (chunk->target + chunk->size <= in_min + && chunk->src + chunk->size > *min_addr + && chunk->src < rel->postchunks) + *min_addr = chunk->src + chunk->size; + } +} + +grub_err_t +grub_relocator_alloc_chunk_addr (struct grub_relocator *rel, + grub_relocator_chunk_t *out, + grub_phys_addr_t target, grub_size_t size) +{ + struct grub_relocator_chunk *chunk; + grub_phys_addr_t min_addr = 0, max_addr; + + if (target > ~size) + return grub_error (GRUB_ERR_BUG, "address is out of range"); + + adjust_limits (rel, &min_addr, &max_addr, target, target); + + for (chunk = rel->chunks; chunk; chunk = chunk->next) + if ((chunk->target <= target && target < chunk->target + chunk->size) + || (target <= chunk->target && chunk->target < target + size)) + return grub_error (GRUB_ERR_BUG, "overlap detected"); + + chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); + if (!chunk) + return grub_errno; + + grub_dprintf ("relocator", + "min_addr = 0x%llx, max_addr = 0x%llx, target = 0x%llx\n", + (unsigned long long) min_addr, (unsigned long long) max_addr, + (unsigned long long) target); + + do + { + /* A trick to improve Linux allocation. */ +#if defined (__i386__) || defined (__x86_64__) + if (target < 0x100000) + if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, + size, chunk, 0, 1)) + { + if (rel->postchunks > chunk->src) + rel->postchunks = chunk->src; + break; + } +#elif defined(__mips__) && (_MIPS_SIM == _ABI64) + if (malloc_in_range (rel, target, max_addr, 8, size, chunk, 1, 0)) + break; +#endif + if (malloc_in_range (rel, target, max_addr, 1, size, chunk, 1, 0)) + break; + + if (malloc_in_range (rel, min_addr, target, 1, size, chunk, 0, 0)) + break; + + if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, + size, chunk, 0, 1)) + { + if (rel->postchunks > chunk->src) + rel->postchunks = chunk->src; + break; + } + + grub_dprintf ("relocator", "not allocated\n"); + grub_free (chunk); + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + } + while (0); + + grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n", + (unsigned long long) chunk->src, (unsigned long long) target); + + if (rel->highestaddr < target + size) + rel->highestaddr = target + size; + + if (rel->highestaddr < chunk->src + size) + rel->highestaddr = chunk->src + size; + + if (chunk->src < rel->postchunks) + { + if (rel->highestnonpostaddr < target + size) + rel->highestnonpostaddr = target + size; + + if (rel->highestnonpostaddr < chunk->src + size) + rel->highestnonpostaddr = chunk->src + size; + } + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + if (chunk->src < target) + rel->relocators_size += grub_relocator_backward_size; + if (chunk->src > target) + rel->relocators_size += grub_relocator_forward_size; + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + chunk->target = target; + chunk->size = size; + chunk->next = rel->chunks; + rel->chunks = chunk; + grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks, + rel->chunks->next); + + chunk->srcv = grub_map_memory (chunk->src, chunk->size); + *out = chunk; +#ifdef DEBUG_RELOCATOR + grub_memset (chunk->srcv, 0xfa, chunk->size); + grub_mm_check (); +#endif + return GRUB_ERR_NONE; +} + +/* Context for grub_relocator_alloc_chunk_align. */ +struct grub_relocator_alloc_chunk_align_ctx +{ + grub_phys_addr_t min_addr, max_addr; + grub_size_t size, align; + int preference; + struct grub_relocator_chunk *chunk; + int found; +}; + +/* Helper for grub_relocator_alloc_chunk_align. */ +static int +grub_relocator_alloc_chunk_align_iter (grub_uint64_t addr, grub_uint64_t sz, + grub_memory_type_t type, void *data) +{ + struct grub_relocator_alloc_chunk_align_ctx *ctx = data; + grub_uint64_t candidate; + + if (type != GRUB_MEMORY_AVAILABLE) + return 0; + candidate = ALIGN_UP (addr, ctx->align); + if (candidate < ctx->min_addr) + candidate = ALIGN_UP (ctx->min_addr, ctx->align); + if (candidate + ctx->size > addr + sz + || candidate > ALIGN_DOWN (ctx->max_addr, ctx->align)) + return 0; + if (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH) + candidate = ALIGN_DOWN (min (addr + sz - ctx->size, ctx->max_addr), + ctx->align); + if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_HIGH + && candidate > ctx->chunk->target)) + ctx->chunk->target = candidate; + if (!ctx->found || (ctx->preference == GRUB_RELOCATOR_PREFERENCE_LOW + && candidate < ctx->chunk->target)) + ctx->chunk->target = candidate; + ctx->found = 1; + return 0; +} + +grub_err_t +grub_relocator_alloc_chunk_align (struct grub_relocator *rel, + grub_relocator_chunk_t *out, + grub_phys_addr_t min_addr, + grub_phys_addr_t max_addr, + grub_size_t size, grub_size_t align, + int preference, + int avoid_efi_boot_services) +{ + struct grub_relocator_alloc_chunk_align_ctx ctx = { + .min_addr = min_addr, + .max_addr = max_addr, + .size = size, + .align = align, + .preference = preference, + .found = 0 + }; + grub_addr_t min_addr2 = 0, max_addr2; + + if (max_addr > ~size) + max_addr = ~size; + +#ifdef GRUB_MACHINE_PCBIOS + if (min_addr < 0x1000) + min_addr = 0x1000; +#endif + + grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); + + ctx.chunk = grub_malloc (sizeof (struct grub_relocator_chunk)); + if (!ctx.chunk) + return grub_errno; + + if (malloc_in_range (rel, min_addr, max_addr, align, + size, ctx.chunk, + preference != GRUB_RELOCATOR_PREFERENCE_HIGH, 1)) + { + grub_dprintf ("relocator", "allocated 0x%llx/0x%llx\n", + (unsigned long long) ctx.chunk->src, + (unsigned long long) ctx.chunk->src); + grub_dprintf ("relocator", "chunks = %p\n", rel->chunks); + ctx.chunk->target = ctx.chunk->src; + ctx.chunk->size = size; + ctx.chunk->next = rel->chunks; + rel->chunks = ctx.chunk; + ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); + *out = ctx.chunk; + return GRUB_ERR_NONE; + } + + adjust_limits (rel, &min_addr2, &max_addr2, min_addr, max_addr); + grub_dprintf ("relocator", "Adjusted limits from %lx-%lx to %lx-%lx\n", + (unsigned long) min_addr, (unsigned long) max_addr, + (unsigned long) min_addr2, (unsigned long) max_addr2); + + do + { + if (malloc_in_range (rel, min_addr2, max_addr2, align, + size, ctx.chunk, 1, 1)) + break; + + if (malloc_in_range (rel, rel->highestnonpostaddr, ~(grub_addr_t)0, 1, + size, ctx.chunk, 0, 1)) + { + if (rel->postchunks > ctx.chunk->src) + rel->postchunks = ctx.chunk->src; + break; + } + + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + } + while (0); + + { +#ifdef GRUB_MACHINE_EFI + grub_efi_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx, + avoid_efi_boot_services); +#elif defined (__powerpc__) || defined (GRUB_MACHINE_XEN) + (void) avoid_efi_boot_services; + grub_machine_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); +#else + (void) avoid_efi_boot_services; + grub_mmap_iterate (grub_relocator_alloc_chunk_align_iter, &ctx); +#endif + if (!ctx.found) + return grub_error (GRUB_ERR_BAD_OS, "couldn't find suitable memory target"); + } + while (1) + { + struct grub_relocator_chunk *chunk2; + for (chunk2 = rel->chunks; chunk2; chunk2 = chunk2->next) + if ((chunk2->target <= ctx.chunk->target + && ctx.chunk->target < chunk2->target + chunk2->size) + || (ctx.chunk->target <= chunk2->target && chunk2->target + < ctx.chunk->target + size)) + { + if (preference == GRUB_RELOCATOR_PREFERENCE_HIGH) + ctx.chunk->target = ALIGN_DOWN (chunk2->target, align); + else + ctx.chunk->target = ALIGN_UP (chunk2->target + chunk2->size, + align); + break; + } + if (!chunk2) + break; + } + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + if (ctx.chunk->src < ctx.chunk->target) + rel->relocators_size += grub_relocator_backward_size; + if (ctx.chunk->src > ctx.chunk->target) + rel->relocators_size += grub_relocator_forward_size; + + grub_dprintf ("relocator", "relocators_size=%ld\n", + (unsigned long) rel->relocators_size); + + ctx.chunk->size = size; + ctx.chunk->next = rel->chunks; + rel->chunks = ctx.chunk; + grub_dprintf ("relocator", "cur = %p, next = %p\n", rel->chunks, + rel->chunks->next); + ctx.chunk->srcv = grub_map_memory (ctx.chunk->src, ctx.chunk->size); + *out = ctx.chunk; +#ifdef DEBUG_RELOCATOR + grub_memset (ctx.chunk->srcv, 0xfa, ctx.chunk->size); + grub_mm_check (); +#endif + return GRUB_ERR_NONE; +} + +void +grub_relocator_unload (struct grub_relocator *rel) +{ + struct grub_relocator_chunk *chunk, *next; + if (!rel) + return; + for (chunk = rel->chunks; chunk; chunk = next) + { + unsigned i; + for (i = 0; i < chunk->nsubchunks; i++) + free_subchunk (&chunk->subchunks[i]); + grub_unmap_memory (chunk->srcv, chunk->size); + next = chunk->next; + grub_free (chunk->subchunks); + grub_free (chunk); + } + grub_free (rel); +} + +grub_err_t +grub_relocator_prepare_relocs (struct grub_relocator *rel, grub_addr_t addr, + void **relstart, grub_size_t *relsize) +{ + grub_uint8_t *rels; + grub_uint8_t *rels0; + struct grub_relocator_chunk *sorted; + grub_size_t nchunks = 0; + unsigned j; + struct grub_relocator_chunk movers_chunk; + + grub_dprintf ("relocator", "Preparing relocs (size=%ld)\n", + (unsigned long) rel->relocators_size); + + if (!malloc_in_range (rel, 0, ~(grub_addr_t)0 - rel->relocators_size + 1, + grub_relocator_align, + rel->relocators_size, &movers_chunk, 1, 1)) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + movers_chunk.srcv = rels = rels0 + = grub_map_memory (movers_chunk.src, movers_chunk.size); + + if (relsize) + *relsize = rel->relocators_size; + + grub_dprintf ("relocator", "Relocs allocated at %p\n", movers_chunk.srcv); + + { + unsigned i; + grub_size_t count[257]; + struct grub_relocator_chunk *from, *to, *tmp; + + grub_memset (count, 0, sizeof (count)); + + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + { + grub_dprintf ("relocator", "chunk %p->%p, 0x%lx\n", + (void *) chunk->src, (void *) chunk->target, + (unsigned long) chunk->size); + nchunks++; + count[(chunk->src & 0xff) + 1]++; + } + } + from = grub_malloc (nchunks * sizeof (sorted[0])); + to = grub_malloc (nchunks * sizeof (sorted[0])); + if (!from || !to) + { + grub_free (from); + grub_free (to); + return grub_errno; + } + + for (j = 0; j < 256; j++) + count[j+1] += count[j]; + + { + struct grub_relocator_chunk *chunk; + for (chunk = rel->chunks; chunk; chunk = chunk->next) + from[count[chunk->src & 0xff]++] = *chunk; + } + + for (i = 1; i < GRUB_CPU_SIZEOF_VOID_P; i++) + { + grub_memset (count, 0, sizeof (count)); + for (j = 0; j < nchunks; j++) + count[((from[j].src >> (8 * i)) & 0xff) + 1]++; + for (j = 0; j < 256; j++) + count[j+1] += count[j]; + for (j = 0; j < nchunks; j++) + to[count[(from[j].src >> (8 * i)) & 0xff]++] = from[j]; + tmp = to; + to = from; + from = tmp; + } + sorted = from; + grub_free (to); + } + + for (j = 0; j < nchunks; j++) + { + grub_dprintf ("relocator", "sorted chunk %p->%p, 0x%lx\n", + (void *) sorted[j].src, (void *) sorted[j].target, + (unsigned long) sorted[j].size); + if (sorted[j].src < sorted[j].target) + { + grub_cpu_relocator_backward ((void *) rels, + sorted[j].srcv, + grub_map_memory (sorted[j].target, + sorted[j].size), + sorted[j].size); + rels += grub_relocator_backward_size; + } + if (sorted[j].src > sorted[j].target) + { + grub_cpu_relocator_forward ((void *) rels, + sorted[j].srcv, + grub_map_memory (sorted[j].target, + sorted[j].size), + sorted[j].size); + rels += grub_relocator_forward_size; + } + if (sorted[j].src == sorted[j].target) + grub_arch_sync_caches (sorted[j].srcv, sorted[j].size); + } + grub_cpu_relocator_jumper ((void *) rels, (grub_addr_t) addr); + *relstart = rels0; + grub_free (sorted); + return GRUB_ERR_NONE; +} + +void +grub_mm_check_real (const char *file, int line) +{ + grub_mm_region_t r; + grub_mm_header_t p, pa; + + for (r = grub_mm_base; r; r = r->next) + { + pa = r->first; + p = pa->next; + if (p->magic == GRUB_MM_ALLOC_MAGIC) + continue; + do + { + if ((grub_addr_t) p < (grub_addr_t) (r + 1) + || (grub_addr_t) p >= (grub_addr_t) (r + 1) + r->size) + grub_fatal ("%s:%d: out of range pointer: %p\n", file, line, p); + if (p->magic != GRUB_MM_FREE_MAGIC) + grub_fatal ("%s:%d free magic broken at %p (0x%x)\n", file, + line, p, p->magic); + pa = p; + p = pa->next; + } + while (pa != r->first); + } +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S new file mode 100644 index 00000000..617b8275 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/setjmp.S @@ -0,0 +1,26 @@ +#if defined(__i386__) +#include "./i386/setjmp.S" +#elif defined(__x86_64__) +#include "./x86_64/setjmp.S" +#elif defined(__sparc__) +#include "./sparc64/setjmp.S" +#elif defined(__mips__) +#if _MIPS_SIM == _ABI64 +#include "./mips64/setjmp.S" +#else +#include "./mips/setjmp.S" +#endif +#elif defined(__powerpc__) || defined(__PPC__) +#include "./powerpc/setjmp.S" +#elif defined(__ia64__) +#include "./ia64/setjmp.S" +#include "./ia64/longjmp.S" +#elif defined(__arm__) +#include "./arm/setjmp.S" +#elif defined(__aarch64__) +#include "./arm64/setjmp.S" +#elif defined(__riscv) +#include "./riscv/setjmp.S" +#else +#error "Unknown target cpu type" +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/syslinux_parse.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/syslinux_parse.c new file mode 100644 index 00000000..44649d41 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/lib/syslinux_parse.c @@ -0,0 +1,1559 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include + +struct syslinux_say +{ + struct syslinux_say *next; + struct syslinux_say *prev; + char msg[0]; +}; + +struct initrd_list +{ + struct initrd_list *next; + char *file; +}; + +struct syslinux_menuentry +{ + struct syslinux_menuentry *next; + struct syslinux_menuentry *prev; + char *label; + char *extlabel; + char *kernel_file; + struct initrd_list *initrds; + struct initrd_list *initrds_last; + char *append; + char *argument; + char *help; + char *comments; + grub_size_t commentslen; + char hotkey; + int make_default; + struct syslinux_say *say; + + enum { KERNEL_NO_KERNEL, KERNEL_LINUX, KERNEL_CHAINLOADER, + KERNEL_BIN, KERNEL_PXE, KERNEL_CHAINLOADER_BPB, + KERNEL_COM32, KERNEL_COM, KERNEL_IMG, KERNEL_CONFIG, LOCALBOOT } + entry_type; +}; + +struct syslinux_menu +{ + struct syslinux_menu *parent; + struct syslinux_menuentry *entries; + char *def; + char *comments; + char *background; + const char *root_read_directory; + const char *root_target_directory; + const char *current_read_directory; + const char *current_target_directory; + const char *filename; + grub_size_t commentslen; + unsigned long timeout; + struct syslinux_say *say; + grub_syslinux_flavour_t flavour; +}; + +struct output_buffer +{ + grub_size_t alloc; + grub_size_t ptr; + char *buf; +}; + +static grub_err_t +syslinux_parse_real (struct syslinux_menu *menu); +static grub_err_t +config_file (struct output_buffer *outbuf, + const char *root, const char *target_root, + const char *cwd, const char *target_cwd, + const char *fname, struct syslinux_menu *parent, + grub_syslinux_flavour_t flav); +static grub_err_t +print_entry (struct output_buffer *outbuf, + struct syslinux_menu *menu, + const char *str); + +static grub_err_t +ensure_space (struct output_buffer *outbuf, grub_size_t len) +{ + grub_size_t newlen; + char *newbuf; + if (len < outbuf->alloc - outbuf->ptr) + return GRUB_ERR_NONE; + newlen = (outbuf->ptr + len + 10) * 2; + newbuf = grub_realloc (outbuf->buf, newlen); + if (!newbuf) + return grub_errno; + outbuf->alloc = newlen; + outbuf->buf = newbuf; + return GRUB_ERR_NONE; +} + +static grub_err_t +print (struct output_buffer *outbuf, const char *str, grub_size_t len) +{ + grub_err_t err; + err = ensure_space (outbuf, len); + if (err) + return err; + grub_memcpy (&outbuf->buf[outbuf->ptr], str, len); + outbuf->ptr += len; + return GRUB_ERR_NONE; +} + +static grub_err_t +add_comment (struct syslinux_menu *menu, const char *comment, int nl) +{ + if (menu->entries) + { + if (menu->entries->commentslen == 0 && *comment == 0) + return GRUB_ERR_NONE; + menu->entries->comments = grub_realloc (menu->entries->comments, + menu->entries->commentslen + + 2 + grub_strlen (comment)); + if (!menu->entries->comments) + return grub_errno; + menu->entries->commentslen + += grub_stpcpy (menu->entries->comments + menu->entries->commentslen, + comment) + - (menu->entries->comments + menu->entries->commentslen); + if (nl) + menu->entries->comments[menu->entries->commentslen++] = '\n'; + menu->entries->comments[menu->entries->commentslen] = '\0'; + } + else + { + if (menu->commentslen == 0 && *comment == 0) + return GRUB_ERR_NONE; + menu->comments = grub_realloc (menu->comments, menu->commentslen + + 2 + grub_strlen (comment)); + if (!menu->comments) + return grub_errno; + menu->commentslen += grub_stpcpy (menu->comments + menu->commentslen, + comment) + - (menu->comments + menu->commentslen); + if (nl) + menu->comments[menu->commentslen++] = '\n'; + menu->comments[menu->commentslen] = '\0'; + } + return GRUB_ERR_NONE; +} + + +#define print_string(x) do { err = print (outbuf, x, sizeof (x) - 1); if (err) return err; } while (0) + +static grub_err_t +print_num (struct output_buffer *outbuf, int n) +{ + char buf[20]; + grub_snprintf (buf, sizeof (buf), "%d", n); + return print (outbuf, buf, grub_strlen (buf)); +} + +static grub_err_t +label (const char *line, struct syslinux_menu *menu) +{ + struct syslinux_menuentry *entry; + + entry = grub_malloc (sizeof (*entry)); + if (!entry) + return grub_errno; + grub_memset (entry, 0, sizeof (*entry)); + entry->label = grub_strdup (line); + if (!entry->label) + { + grub_free (entry); + return grub_errno; + } + entry->next = menu->entries; + entry->prev = NULL; + if (menu->entries) + menu->entries->prev = entry; + menu->entries = entry; + return GRUB_ERR_NONE; +} + +static grub_err_t +kernel (const char *line, struct syslinux_menu *menu) +{ + const char *end = line + grub_strlen (line); + + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + + menu->entries->entry_type = KERNEL_LINUX; + + if (end - line >= 2 && grub_strcmp (end - 2, ".0") == 0) + menu->entries->entry_type = KERNEL_PXE; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".bin") == 0) + menu->entries->entry_type = KERNEL_BIN; + + if (end - line >= 3 && grub_strcasecmp (end - 3, ".bs") == 0) + menu->entries->entry_type = KERNEL_CHAINLOADER; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".bss") == 0) + menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".c32") == 0) + menu->entries->entry_type = KERNEL_COM32; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".cbt") == 0) + menu->entries->entry_type = KERNEL_COM; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".com") == 0) + menu->entries->entry_type = KERNEL_COM; + + if (end - line >= 4 && grub_strcasecmp (end - 4, ".img") == 0) + menu->entries->entry_type = KERNEL_IMG; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_linux (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_LINUX; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_boot (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_CHAINLOADER; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_bss (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_CHAINLOADER_BPB; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_pxe (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_PXE; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_fdimage (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_IMG; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_comboot (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_COM; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_com32 (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = KERNEL_COM32; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_config (const char *line, struct syslinux_menu *menu) +{ + const char *space; + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + for (space = line; *space && !grub_isspace (*space); space++); + menu->entries->kernel_file = grub_strndup (line, space - line); + if (!menu->entries->kernel_file) + return grub_errno; + for (; *space && grub_isspace (*space); space++); + if (*space) + { + menu->entries->argument = grub_strdup (space); + if (!menu->entries->argument) + return grub_errno; + } + menu->entries->entry_type = KERNEL_CONFIG; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_append (const char *line, struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->append = grub_strdup (line); + if (!menu->entries->append) + return grub_errno; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_initrd (const char *line, struct syslinux_menu *menu) +{ + struct initrd_list *ninitrd; + const char *comma; + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + while (*line) + { + for (comma = line; *comma && *comma != ','; comma++); + + ninitrd = grub_malloc (sizeof (*ninitrd)); + if (!ninitrd) + return grub_errno; + ninitrd->file = grub_strndup (line, comma - line); + if (!ninitrd->file) + { + grub_free (ninitrd); + return grub_errno; + } + ninitrd->next = NULL; + if (menu->entries->initrds_last) + menu->entries->initrds_last->next = ninitrd; + else + { + menu->entries->initrds_last = ninitrd; + menu->entries->initrds = ninitrd; + } + + line = comma; + while (*line == ',') + line++; + } + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_default (const char *line, struct syslinux_menu *menu) +{ + menu->def = grub_strdup (line); + if (!menu->def) + return grub_errno; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_timeout (const char *line, struct syslinux_menu *menu) +{ + menu->timeout = grub_strtoul (line, NULL, 0); + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_menudefault (const char *line __attribute__ ((unused)), + struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->make_default = 1; + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_menubackground (const char *line, + struct syslinux_menu *menu) +{ + menu->background = grub_strdup (line); + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_localboot (const char *line, + struct syslinux_menu *menu) +{ + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->kernel_file = grub_strdup (line); + if (!menu->entries->kernel_file) + return grub_errno; + menu->entries->entry_type = LOCALBOOT; + + return GRUB_ERR_NONE; +} + +static grub_err_t +cmd_extlabel (const char *line, struct syslinux_menu *menu) +{ + const char *in; + char *out; + + if (!menu->entries) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label"); + + menu->entries->extlabel = grub_malloc (grub_strlen (line) + 1); + if (!menu->entries->extlabel) + return grub_errno; + in = line; + out = menu->entries->extlabel; + while (*in) + { + if (in[0] == '^' && in[1]) + { + menu->entries->hotkey = grub_tolower (in[1]); + in++; + } + *out++ = *in++; + } + *out = 0; + + return GRUB_ERR_NONE; +} + + +static grub_err_t +cmd_say (const char *line, struct syslinux_menu *menu) +{ + struct syslinux_say *nsay; + nsay = grub_malloc (sizeof (*nsay) + grub_strlen (line) + 1); + if (!nsay) + return grub_errno; + nsay->prev = NULL; + if (menu->entries) + { + nsay->next = menu->entries->say; + menu->entries->say = nsay; + } + else + { + nsay->next = menu->say; + menu->say = nsay; + } + + if (nsay->next) + nsay->next->prev = nsay; + + grub_memcpy (nsay->msg, line, grub_strlen (line) + 1); + return GRUB_ERR_NONE; +} + +static char * +get_read_filename (struct syslinux_menu *menu, + const char *filename) +{ + return grub_xasprintf ("%s/%s", + filename[0] == '/' ? menu->root_read_directory + : menu->current_read_directory, filename); +} + +static char * +get_target_filename (struct syslinux_menu *menu, + const char *filename) +{ + return grub_xasprintf ("%s/%s", + filename[0] == '/' ? menu->root_target_directory + : menu->current_target_directory, filename); +} + +static grub_err_t +syslinux_parse (const char *filename, + struct syslinux_menu *menu) +{ + const char *old_filename = menu->filename; + grub_err_t ret; + char *nf; + nf = get_read_filename (menu, filename); + if (!nf) + return grub_errno; + menu->filename = nf; + ret = syslinux_parse_real (menu); + if (ret == GRUB_ERR_FILE_NOT_FOUND + || ret == GRUB_ERR_BAD_FILENAME) + { + grub_errno = ret = GRUB_ERR_NONE; + add_comment (menu, "# File ", 0); + add_comment (menu, nf, 0); + add_comment (menu, " not found", 1); + } + grub_free (nf); + menu->filename = old_filename; + return ret; +} + +struct +{ + const char *name1; + const char *name2; + grub_err_t (*parse) (const char *line, struct syslinux_menu *menu); +} commands[] = { + /* FIXME: support tagname. */ + {"include", NULL, syslinux_parse}, + {"menu", "include", syslinux_parse}, + {"label", NULL, label}, + {"kernel", NULL, kernel}, + {"linux", NULL, cmd_linux}, + {"boot", NULL, cmd_boot}, + {"bss", NULL, cmd_bss}, + {"pxe", NULL, cmd_pxe}, + {"fdimage", NULL, cmd_fdimage}, + {"comboot", NULL, cmd_comboot}, + {"com32", NULL, cmd_com32}, + {"config", NULL, cmd_config}, + {"append", NULL, cmd_append}, + /* FIXME: ipappend not supported. */ + {"localboot", NULL, cmd_localboot}, + {"initrd", NULL, cmd_initrd}, + {"default", NULL, cmd_default}, + {"menu", "label", cmd_extlabel}, + /* FIXME: MENU LABEL not supported. */ + /* FIXME: MENU HIDDEN not supported. */ + /* FIXME: MENU SEPARATOR not supported. */ + /* FIXME: MENU INDENT not supported. */ + /* FIXME: MENU DISABLE not supported. */ + /* FIXME: MENU HIDE not supported. */ + {"menu", "default", cmd_menudefault}, + /* FIXME: MENU PASSWD not supported. */ + /* FIXME: MENU MASTER PASSWD not supported. */ + {"menu", "background", cmd_menubackground}, + /* FIXME: MENU BEGIN not supported. */ + /* FIXME: MENU GOTO not supported. */ + /* FIXME: MENU EXIT not supported. */ + /* FIXME: MENU QUIT not supported. */ + /* FIXME: MENU START not supported. */ + /* FIXME: MENU AUTOBOOT not supported. */ + /* FIXME: MENU TABMSG not supported. */ + /* FIXME: MENU NOTABMSG not supported. */ + /* FIXME: MENU PASSPROMPT not supported. */ + /* FIXME: MENU COLOR not supported. */ + /* FIXME: MENU MSGCOLOR not supported. */ + /* FIXME: MENU WIDTH not supported. */ + /* FIXME: MENU MARGIN not supported. */ + /* FIXME: MENU PASSWORDMARGIN not supported. */ + /* FIXME: MENU ROWS not supported. */ + /* FIXME: MENU TABMSGROW not supported. */ + /* FIXME: MENU CMDLINEROW not supported. */ + /* FIXME: MENU ENDROW not supported. */ + /* FIXME: MENU PASSWORDROW not supported. */ + /* FIXME: MENU TIMEOUTROW not supported. */ + /* FIXME: MENU HELPMSGROW not supported. */ + /* FIXME: MENU HELPMSGENDROW not supported. */ + /* FIXME: MENU HIDDENROW not supported. */ + /* FIXME: MENU HSHIFT not supported. */ + /* FIXME: MENU VSHIFT not supported. */ + {"timeout", NULL, cmd_timeout}, + /* FIXME: TOTALTIMEOUT not supported. */ + /* FIXME: ONTIMEOUT not supported. */ + /* FIXME: ONERROR not supported. */ + /* FIXME: SERIAL not supported. */ + /* FIXME: CONSOLE not supported. */ + /* FIXME: FONT not supported. */ + /* FIXME: KBDMAP not supported. */ + {"say", NULL, cmd_say}, + /* FIXME: DISPLAY not supported. */ + /* FIXME: F* not supported. */ + + /* Commands to control interface behaviour which aren't needed with GRUB. + If they are important in your environment please contact GRUB team. + */ + {"prompt", NULL, NULL}, + {"nocomplete", NULL, NULL}, + {"noescape", NULL, NULL}, + {"implicit", NULL, NULL}, + {"allowoptions", NULL, NULL} +}; + +static grub_err_t +helptext (const char *line, grub_file_t file, struct syslinux_menu *menu) +{ + char *help; + char *buf = NULL; + grub_size_t helplen, alloclen = 0; + + help = grub_strdup (line); + if (!help) + return grub_errno; + helplen = grub_strlen (line); + while ((grub_free (buf), buf = grub_file_getline (file))) + { + char *ptr; + grub_size_t needlen; + for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); + if (grub_strncasecmp (ptr, "endtext", sizeof ("endtext") - 1) == 0) + { + ptr += sizeof ("endtext") - 1; + for (; *ptr && (grub_isspace (*ptr) || *ptr == '\n' || *ptr == '\r'); + ptr++); + if (!*ptr) + { + menu->entries->help = help; + grub_free (buf); + return GRUB_ERR_NONE; + } + } + needlen = helplen + 1 + grub_strlen (buf); + if (alloclen < needlen) + { + alloclen = 2 * needlen; + help = grub_realloc (help, alloclen); + if (!help) + { + grub_free (buf); + return grub_errno; + } + } + helplen += grub_stpcpy (help + helplen, buf) - (help + helplen); + } + + grub_free (buf); + grub_free (help); + return grub_errno; +} + + +static grub_err_t +syslinux_parse_real (struct syslinux_menu *menu) +{ + grub_file_t file; + char *buf = NULL; + grub_err_t err = GRUB_ERR_NONE; + + file = grub_file_open (menu->filename, GRUB_FILE_TYPE_CONFIG); + if (!file) + return grub_errno; + while ((grub_free (buf), buf = grub_file_getline (file))) + { + const char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5; + char *end; + unsigned i; + end = buf + grub_strlen (buf); + while (end > buf && (end[-1] == '\n' || end[-1] == '\r')) + end--; + *end = 0; + for (ptr1 = buf; *ptr1 && grub_isspace (*ptr1); ptr1++); + if (*ptr1 == '#' || *ptr1 == 0) + { + err = add_comment (menu, ptr1, 1); + if (err) + goto fail; + continue; + } + for (ptr2 = ptr1; !grub_isspace (*ptr2) && *ptr2; ptr2++); + for (ptr3 = ptr2; grub_isspace (*ptr3) && *ptr3; ptr3++); + for (ptr4 = ptr3; !grub_isspace (*ptr4) && *ptr4; ptr4++); + for (ptr5 = ptr4; grub_isspace (*ptr5) && *ptr5; ptr5++); + for (i = 0; i < ARRAY_SIZE(commands); i++) + if (grub_strlen (commands[i].name1) == (grub_size_t) (ptr2 - ptr1) + && grub_strncasecmp (commands[i].name1, ptr1, ptr2 - ptr1) == 0 + && (commands[i].name2 == NULL + || (grub_strlen (commands[i].name2) + == (grub_size_t) (ptr4 - ptr3) + && grub_strncasecmp (commands[i].name2, ptr3, ptr4 - ptr3) + == 0))) + break; + if (i == ARRAY_SIZE(commands)) + { + if (sizeof ("text") - 1 == ptr2 - ptr1 + && grub_strncasecmp ("text", ptr1, ptr2 - ptr1) == 0 + && (sizeof ("help") - 1 == ptr4 - ptr3 + && grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0)) + { + if (helptext (ptr5, file, menu)) + return 1; + continue; + } + + add_comment (menu, " # UNSUPPORTED command '", 0); + add_comment (menu, ptr1, 0); + add_comment (menu, "'", 1); + + continue; + } + if (commands[i].parse) + { + err = commands[i].parse (commands[i].name2 + ? ptr5 : ptr3, menu); + if (err) + goto fail; + } + } + fail: + grub_file_close (file); + return err; +} + +static grub_err_t +print_escaped (struct output_buffer *outbuf, + const char *from, const char *to) +{ + const char *ptr; + grub_err_t err; + if (!to) + to = from + grub_strlen (from); + err = ensure_space (outbuf, (to - from) * 4 + 2); + if (err) + return err; + outbuf->buf[outbuf->ptr++] = '\''; + for (ptr = from; *ptr && ptr < to; ptr++) + { + if (*ptr == '\'') + { + outbuf->buf[outbuf->ptr++] = '\''; + outbuf->buf[outbuf->ptr++] = '\\'; + outbuf->buf[outbuf->ptr++] = '\''; + outbuf->buf[outbuf->ptr++] = '\''; + } + else + outbuf->buf[outbuf->ptr++] = *ptr; + } + outbuf->buf[outbuf->ptr++] = '\''; + return GRUB_ERR_NONE; +} + +static grub_err_t +print_file (struct output_buffer *outbuf, + struct syslinux_menu *menu, const char *from, const char *to) +{ + grub_err_t err; + if (!to) + to = from + grub_strlen (from); + err = print_escaped (outbuf, from[0] == '/' + ? menu->root_target_directory + : menu->current_target_directory, NULL); + if (err) + return err; + + err = print (outbuf, "/", 1); + if (err) + return err; + return print_escaped (outbuf, from, to); +} + +/* + * Makefile.am mimics this when generating tests/syslinux/ubuntu10.04_grub.cfg, + * so changes here may need to be reflected there too. + */ +static void +simplify_filename (char *str) +{ + char *iptr, *optr = str; + for (iptr = str; *iptr; iptr++) + { + if (*iptr == '/' && optr != str && optr[-1] == '/') + continue; + if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '/') + { + iptr += 2; + continue; + } + if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '.' + && iptr[3] == '/') + { + iptr += 3; + while (optr >= str && *optr != '/') + optr--; + if (optr < str) + { + str[0] = '/'; + optr = str; + } + optr++; + continue; + } + *optr++ = *iptr; + } + *optr = '\0'; +} + +static grub_err_t +print_config (struct output_buffer *outbuf, + struct syslinux_menu *menu, + const char *filename, const char *basedir) +{ + struct syslinux_menu *menuptr; + grub_err_t err = GRUB_ERR_NONE; + char *new_cwd = NULL; + char *new_target_cwd = NULL; + char *newname = NULL; + int depth = 0; + + new_cwd = get_read_filename (menu, basedir); + if (!new_cwd) + { + err = grub_errno; + goto out; + } + new_target_cwd = get_target_filename (menu, basedir); + if (!new_target_cwd) + { + err = grub_errno; + goto out; + } + newname = get_read_filename (menu, filename); + if (!newname) + { + err = grub_errno; + goto out; + } + simplify_filename (newname); + + print_string ("#"); + print_file (outbuf, menu, filename, NULL); + print_string (" "); + err = print (outbuf, newname, grub_strlen (newname)); + if (err) + return err; + print_string (":\n"); + + for (menuptr = menu; menuptr; menuptr = menuptr->parent, depth++) + if (grub_strcmp (menuptr->filename, newname) == 0 + || depth > 20) + break; + if (menuptr) + { + print_string (" syslinux_configfile -r "); + print_file (outbuf, menu, "/", NULL); + print_string (" -c "); + print_file (outbuf, menu, basedir, NULL); + print_string (" "); + print_file (outbuf, menu, filename, NULL); + print_string ("\n"); + } + else + { + err = config_file (outbuf, menu->root_read_directory, + menu->root_target_directory, new_cwd, new_target_cwd, + newname, menu, menu->flavour); + if (err == GRUB_ERR_FILE_NOT_FOUND + || err == GRUB_ERR_BAD_FILENAME) + { + grub_errno = err = GRUB_ERR_NONE; + print_string ("# File "); + err = print (outbuf, newname, grub_strlen (newname)); + if (err) + goto out; + print_string (" not found\n"); + } + } + + out: + grub_free (newname); + grub_free (new_cwd); + grub_free (new_target_cwd); + return err; +} + +static grub_err_t +write_entry (struct output_buffer *outbuf, + struct syslinux_menu *menu, + struct syslinux_menuentry *curentry) +{ + grub_err_t err; + if (curentry->comments) + { + err = print (outbuf, curentry->comments, + grub_strlen (curentry->comments)); + if (err) + return err; + } + { + struct syslinux_say *say; + for (say = curentry->say; say && say->next; say = say->next); + for (; say && say->prev; say = say->prev) + { + print_string ("echo "); + if (print_escaped (outbuf, say->msg, NULL)) return grub_errno; + print_string ("\n"); + } + } + + /* FIXME: support help text. */ + switch (curentry->entry_type) + { + case KERNEL_LINUX: + { + const char *ptr; + const char *initrd = NULL, *initrde= NULL; + for (ptr = curentry->append; ptr && *ptr; ptr++) + if ((ptr == curentry->append || grub_isspace (ptr[-1])) + && grub_strncasecmp (ptr, "initrd=", sizeof ("initrd=") - 1) + == 0) + break; + if (ptr && *ptr) + { + initrd = ptr + sizeof ("initrd=") - 1; + for (initrde = initrd; *initrde && !grub_isspace (*initrde); initrde++); + } + print_string (" if test x$ventoy_linux_16 = x1; then " + "linux_suffix=16; else linux_suffix= ; fi\n"); + print_string (" linux$linux_suffix "); + print_file (outbuf, menu, curentry->kernel_file, NULL); + print_string (" "); + if (curentry->append) + { + err = print (outbuf, curentry->append, grub_strlen (curentry->append)); + if (err) + return err; + } + print_string ("\n"); + if (initrd || curentry->initrds) + { + struct initrd_list *lst; + print_string (" initrd$linux_suffix "); + if (initrd) + { + print_file (outbuf, menu, initrd, initrde); + print_string (" "); + } + for (lst = curentry->initrds; lst; lst = lst->next) + { + print_file (outbuf, menu, lst->file, NULL); + print_string (" "); + } + + print_string ("\n"); + } + print_string ("boot\n"); + } + break; + case KERNEL_CHAINLOADER: + print_string (" chainloader "); + print_file (outbuf, menu, curentry->kernel_file, NULL); + print_string ("\n"); + break; + case KERNEL_CHAINLOADER_BPB: + print_string (" chainloader --bpb "); + print_file (outbuf, menu, curentry->kernel_file, NULL); + print_string ("\n"); + break; + case LOCALBOOT: + /* FIXME: support -1. */ + /* FIXME: PXELINUX. */ + { + int n = grub_strtol (curentry->kernel_file, NULL, 0); + if (n >= 0 && n <= 0x02) + { + print_string (" root=fd"); + if (print_num (outbuf, n)) + return grub_errno; + print_string (";\n chainloader +1;\n"); + + break; + } + if (n >= 0x80 && n < 0x8a) + { + print_string (" root=hd"); + if (print_num (outbuf, n - 0x80)) + return grub_errno; + print_string (";\n chainloader +1;\n"); + break; + } + print_string (" # UNSUPPORTED localboot type "); + print_string ("\ntrue;\n"); + if (print_num (outbuf, n)) + return grub_errno; + print_string ("\n"); + break; + } + case KERNEL_COM32: + case KERNEL_COM: + { + char *basename = NULL; + + { + char *ptr; + for (ptr = curentry->kernel_file; *ptr; ptr++) + if (*ptr == '/' || *ptr == '\\') + basename = ptr; + } + if (!basename) + basename = curentry->kernel_file; + else + basename++; + if (grub_strcasecmp (basename, "chain.c32") == 0) + { + char *file = NULL; + int is_fd = -1, devn = 0; + int part = -1; + int swap = 0; + char *ptr; + for (ptr = curentry->append; *ptr; ) + { + while (grub_isspace (*ptr)) + ptr++; + /* FIXME: support mbr: and boot. */ + if (ptr[0] == 'h' && ptr[1] == 'd') + { + is_fd = 0; + devn = grub_strtoul (ptr + 2, &ptr, 0); + continue; + } + if (grub_strncasecmp (ptr, "file=", 5) == 0) + { + file = ptr + 5; + for (ptr = file; *ptr && !grub_isspace (*ptr); ptr++); + if (*ptr) + { + *ptr = 0; + ptr++; + } + continue; + } + if (grub_strncasecmp (ptr, "swap", sizeof ("swap") - 1) == 0) + { + swap = 1; + ptr += sizeof ("swap") - 1; + continue; + } + + if (ptr[0] == 'f' && ptr[1] == 'd') + { + is_fd = 1; + devn = grub_strtoul (ptr + 2, &ptr, 0); + continue; + } + if (grub_isdigit (ptr[0])) + { + part = grub_strtoul (ptr, &ptr, 0); + continue; + } + /* FIXME: isolinux, ntldr, cmldr, *dos, seg, hide + FIXME: sethidden. */ + print_string (" # UNSUPPORTED option "); + if (print (outbuf, ptr, grub_strlen (ptr))) + return 0; + print_string ("\n"); + break; + } + if (is_fd == -1) + { + print_string (" # no drive specified\n"); + break; + } + if (!*ptr) + { + print_string (is_fd ? " root=fd": " root=hd"); + if (print_num (outbuf, devn)) + return grub_errno; + if (part != -1) + { + print_string (","); + if (print_num (outbuf, part + 1)) + return grub_errno; + } + print_string (";\n"); + if (file) + { + print_string (" chainloader "); + print_file (outbuf, menu, file, NULL); + print_string (";\n"); + } + else + print_string (" chainloader +1;\n"); + if (swap) + print_string (" drivemap -s hd0 \"root\";\n"); + } + break; + } + + if (grub_strcasecmp (basename, "mboot.c32") == 0) + { + char *ptr; + int first = 1; + int is_kernel = 1; + for (ptr = curentry->append; *ptr; ) + { + char *ptrr = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + if (ptrr + 2 == ptr && ptrr[0] == '-' && ptrr[1] == '-') + { + print_string ("\n"); + first = 1; + continue; + } + if (first) + { + if (is_kernel) + print_string (" multiboot "); + else + print_string (" module "); + first = 0; + is_kernel = 0; + if (print_file (outbuf, menu, ptrr, ptr)) + return grub_errno; + continue; + } + if (print_escaped (outbuf, ptrr, ptr)) + return grub_errno; + } + break; + } + + if (grub_strcasecmp (basename, "ifcpu64.c32") == 0) + { + char *lm, *lme, *pae = 0, *paee = 0, *i386s = 0, *i386e = 0; + char *ptr; + ptr = curentry->append; + while (grub_isspace (*ptr)) + ptr++; + lm = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + lme = ptr; + while (grub_isspace (*ptr)) + ptr++; + if (ptr[0] == '-' && ptr[1] == '-') + { + ptr += 2; + while (grub_isspace (*ptr)) + ptr++; + pae = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + paee = ptr; + } + while (grub_isspace (*ptr)) + ptr++; + if (ptr[0] == '-' && ptr[1] == '-') + { + ptr += 2; + while (grub_isspace (*ptr)) + ptr++; + i386s = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + i386e = ptr; + } + *lme = '\0'; + if (paee) + *paee = '\0'; + if (i386e) + *i386e = '\0'; + if (!i386s) + { + i386s = pae; + pae = 0; + } + print_string ("if cpuid --long-mode; then true;\n"); + if (print_entry (outbuf, menu, lm)) + return grub_errno; + if (pae) + { + print_string ("elif cpuid --pae; then true;\n"); + if (print_entry (outbuf, menu, pae)) + return grub_errno; + } + print_string ("else\n"); + if (print_entry (outbuf, menu, i386s)) + return grub_errno; + print_string ("fi\n"); + break; + } + + if (grub_strcasecmp (basename, "reboot.c32") == 0) + { + print_string (" reboot\n"); + break; + } + + if (grub_strcasecmp (basename, "poweroff.com") == 0) + { + print_string (" halt\n"); + break; + } + + if (grub_strcasecmp (basename, "whichsys.c32") == 0) + { + grub_syslinux_flavour_t flavour = GRUB_SYSLINUX_ISOLINUX; + const char *flav[] = + { + [GRUB_SYSLINUX_ISOLINUX] = "iso", + [GRUB_SYSLINUX_PXELINUX] = "pxe", + [GRUB_SYSLINUX_SYSLINUX] = "sys" + }; + char *ptr; + for (ptr = curentry->append; *ptr; ) + { + char *bptr, c; + while (grub_isspace (*ptr)) + ptr++; + if (grub_strncasecmp (ptr, "-iso-", 5) == 0) + { + ptr += sizeof ("-iso-") - 1; + flavour = GRUB_SYSLINUX_ISOLINUX; + continue; + } + if (grub_strncasecmp (ptr, "-pxe-", 5) == 0) + { + ptr += sizeof ("-pxe-") - 1; + flavour = GRUB_SYSLINUX_PXELINUX; + continue; + } + if (grub_strncasecmp (ptr, "-sys-", 5) == 0) + { + ptr += sizeof ("-sys-") - 1; + flavour = GRUB_SYSLINUX_SYSLINUX; + continue; + } + bptr = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + c = *ptr; + *ptr = '\0'; + if (menu->flavour == GRUB_SYSLINUX_UNKNOWN + && flavour == GRUB_SYSLINUX_ISOLINUX) + { + print_string ("if [ x$syslinux_flavour = xiso -o x$syslinux_flavour = x ]; then true;\n"); + menu->flavour = GRUB_SYSLINUX_ISOLINUX; + print_entry (outbuf, menu, bptr); + menu->flavour = GRUB_SYSLINUX_UNKNOWN; + print_string ("fi\n"); + } + else if (menu->flavour == GRUB_SYSLINUX_UNKNOWN) + { + print_string ("if [ x$syslinux_flavour = x"); + err = print (outbuf, flav[flavour], grub_strlen (flav[flavour])); + if (err) + return err; + print_string (" ]; then true;\n"); + menu->flavour = flavour; + print_entry (outbuf, menu, bptr); + menu->flavour = GRUB_SYSLINUX_UNKNOWN; + print_string ("fi\n"); + } + if (menu->flavour != GRUB_SYSLINUX_UNKNOWN + && menu->flavour == flavour) + print_entry (outbuf, menu, bptr); + *ptr = c; + } + break; + } + + if (grub_strcasecmp (basename, "menu.c32") == 0 || + grub_strcasecmp (basename, "vesamenu.c32") == 0) + { + char *ptr; + char *end; + + ptr = curentry->append; + if (!ptr) + return grub_errno; + + while (*ptr) + { + end = ptr; + for (end = ptr; *end && !grub_isspace (*end); end++); + if (*end) + *end++ = '\0'; + + /* "~" is supposed to be current file, so let's skip it */ + if (grub_strcmp (ptr, "~") != 0) + { + err = print_config (outbuf, menu, ptr, ""); + if (err != GRUB_ERR_NONE) + break; + } + for (ptr = end; *ptr && grub_isspace (*ptr); ptr++); + } + err = GRUB_ERR_NONE; + break; + } + + /* FIXME: gdb, GFXBoot, Hdt, Ifcpu, Ifplop, Kbdmap, + FIXME: Linux, Lua, Meminfo, rosh, Sanbboot */ + + print_string (" # UNSUPPORTED com(32) "); + err = print (outbuf, basename, grub_strlen (basename)); + if (err) + return err; + print_string ("\ntrue;\n"); + break; + } + case KERNEL_CONFIG: + { + const char *ap; + ap = curentry->append; + if (!ap) + ap = curentry->argument; + if (!ap) + ap = ""; + print_config (outbuf, menu, curentry->kernel_file, ap); + } + break; + case KERNEL_NO_KERNEL: + /* FIXME: support this. */ + case KERNEL_BIN: + case KERNEL_PXE: + case KERNEL_IMG: + print_string (" # UNSUPPORTED entry type "); + if (print_num (outbuf, curentry->entry_type)) + return grub_errno; + print_string ("\ntrue;\n"); + break; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +print_entry (struct output_buffer *outbuf, + struct syslinux_menu *menu, + const char *str) +{ + struct syslinux_menuentry *curentry; + for (curentry = menu->entries; curentry; curentry = curentry->next) + if (grub_strcasecmp (curentry->label, str) == 0) + { + grub_err_t err; + err = write_entry (outbuf, menu, curentry); + if (err) + return err; + } + return GRUB_ERR_NONE; +} + +static void +free_menu (struct syslinux_menu *menu) +{ + struct syslinux_say *say, *nsay; + struct syslinux_menuentry *entry, *nentry; + + grub_free (menu->def); + grub_free (menu->comments); + grub_free (menu->background); + for (say = menu->say; say ; say = nsay) + { + nsay = say->next; + grub_free (say); + } + + for (entry = menu->entries; entry ; entry = nentry) + { + nentry = entry->next; + struct initrd_list *initrd, *ninitrd; + + for (initrd = entry->initrds; initrd ; initrd = ninitrd) + { + ninitrd = initrd->next; + grub_free (initrd->file); + grub_free (initrd); + } + + grub_free (entry->comments); + grub_free (entry->kernel_file); + grub_free (entry->label); + grub_free (entry->extlabel); + grub_free (entry->append); + grub_free (entry->help); + grub_free (entry); + } +} + +static grub_err_t +config_file (struct output_buffer *outbuf, + const char *root, const char *target_root, + const char *cwd, const char *target_cwd, + const char *fname, struct syslinux_menu *parent, + grub_syslinux_flavour_t flav) +{ + const char *data; + grub_err_t err; + struct syslinux_menu menu; + struct syslinux_menuentry *curentry, *lentry; + struct syslinux_say *say; + + grub_memset (&menu, 0, sizeof (menu)); + menu.flavour = flav; + menu.root_read_directory = root; + menu.root_target_directory = target_root; + menu.current_read_directory = cwd; + menu.current_target_directory = target_cwd; + + menu.filename = fname; + menu.parent = parent; + + data = grub_env_get("vtdebug_flag"); + if (data && data[0]) + { + menu.timeout = 100; + } + + err = syslinux_parse_real (&menu); + if (err) + return err; + + for (say = menu.say; say && say->next; say = say->next); + for (; say && say->prev; say = say->prev) + { + print_string ("echo "); + err = print_escaped (outbuf, say->msg, NULL); + if (err) + return err; + print_string ("\n"); + } + + if (menu.background) + { + print_string (" background_image "); + err = print_file (outbuf, &menu, menu.background, NULL); + if (err) + return err; + print_string ("\n"); + } + + if (menu.comments) + { + err = print (outbuf, menu.comments, grub_strlen (menu.comments)); + if (err) + return err; + } + + if (menu.timeout == 0 && menu.entries && menu.def) + { + err = print_entry (outbuf, &menu, menu.def); + if (err) + return err; + } + else if (menu.entries) + { + for (curentry = menu.entries; curentry->next; curentry = curentry->next); + lentry = curentry; + + print_string ("set timeout="); + err = print_num (outbuf, (menu.timeout + 9) / 10); + if (err) + return err; + print_string ("\n"); + + if (menu.def) + { + print_string (" default="); + err = print_escaped (outbuf, menu.def, NULL); + if (err) + return err; + print_string ("\n"); + } + for (curentry = lentry; curentry; curentry = curentry->prev) + { + print_string ("menuentry "); + err = print_escaped (outbuf, + curentry->extlabel ? : curentry->label, NULL); + if (err) + return err; + if (curentry->hotkey) + { + char hk[] = { curentry->hotkey, '\0' }; + print_string (" --hotkey '"); + print_string (hk); + print_string ("'"); + } + print_string (" --id "); + err = print_escaped (outbuf, curentry->label, NULL); + if (err) + return err; + print_string (" {\n"); + + err = write_entry (outbuf, &menu, curentry); + if (err) + return err; + + print_string ("}\n"); + } + } + free_menu (&menu); + return GRUB_ERR_NONE; +} + +char * +grub_syslinux_config_file (const char *base, const char *target_base, + const char *cwd, const char *target_cwd, + const char *fname, grub_syslinux_flavour_t flav) +{ + struct output_buffer outbuf = { 0, 0, 0 }; + grub_err_t err; + err = config_file (&outbuf, base, target_base, cwd, target_cwd, + fname, NULL, flav); + if (err) + return NULL; + err = print (&outbuf, "\0", 1); + if (err) + return NULL; + return outbuf.buf; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c new file mode 100644 index 00000000..f8dfec64 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/arm64/linux.c @@ -0,0 +1,852 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +static grub_dl_t my_mod; +static int loaded; + +static void *kernel_addr; +static grub_uint64_t kernel_size; + +static char *linux_args; +static grub_uint32_t cmdline_size; + +static grub_addr_t initrd_start; +static grub_addr_t initrd_end; + +#define LINUX_MAX_ARGC 1024 +static int ventoy_debug = 0; +static int ventoy_initrd_called = 0; +static int ventoy_linux_argc = 0; +static char **ventoy_linux_args = NULL; +static int ventoy_extra_initrd_num = 0; +static char *ventoy_extra_initrd_list[256]; +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]); + +grub_err_t +grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) +{ + if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE) + return grub_error(GRUB_ERR_BAD_OS, "invalid magic number"); + + if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC) + return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, + N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled")); + + grub_dprintf ("linux", "UEFI stub kernel:\n"); + grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); + + return GRUB_ERR_NONE; +} + +static grub_err_t +finalize_params_linux (void) +{ + int node, retval; + + void *fdt; + + fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE); + + if (!fdt) + goto failure; + + node = grub_fdt_find_subnode (fdt, 0, "chosen"); + if (node < 0) + node = grub_fdt_add_subnode (fdt, 0, "chosen"); + + if (node < 1) + goto failure; + + /* Set initrd info */ + if (initrd_start && initrd_end > initrd_start) + { + grub_dprintf ("linux", "Initrd @ %p-%p\n", + (void *) initrd_start, (void *) initrd_end); + + retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", + initrd_start); + if (retval) + goto failure; + retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", + initrd_end); + if (retval) + goto failure; + } + + if (grub_fdt_install() != GRUB_ERR_NONE) + goto failure; + + return GRUB_ERR_NONE; + +failure: + grub_fdt_unload(); + return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); +} + +grub_err_t +grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) +{ + grub_efi_memory_mapped_device_path_t *mempath; + grub_efi_handle_t image_handle; + grub_efi_boot_services_t *b; + grub_efi_status_t status; + grub_efi_loaded_image_t *loaded_image; + int len; + + mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); + if (!mempath) + return grub_errno; + + mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; + mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; + mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); + mempath[0].memory_type = GRUB_EFI_LOADER_DATA; + mempath[0].start_address = addr; + mempath[0].end_address = addr + size; + + mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; + mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; + mempath[1].header.length = sizeof (grub_efi_device_path_t); + + b = grub_efi_system_table->boot_services; + status = b->load_image (0, grub_efi_image_handle, + (grub_efi_device_path_t *) mempath, + (void *) addr, size, &image_handle); + if (status != GRUB_EFI_SUCCESS) + return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); + + grub_dprintf ("linux", "linux command line: '%s'\n", args); + + /* Convert command line to UCS-2 */ + loaded_image = grub_efi_get_loaded_image (image_handle); + loaded_image->load_options_size = len = + (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); + loaded_image->load_options = + grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); + if (!loaded_image->load_options) + return grub_errno; + + loaded_image->load_options_size = + 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, + (grub_uint8_t *) args, len, NULL); + + grub_dprintf ("linux", "starting image %p\n", image_handle); + status = b->start_image (image_handle, 0, NULL); + + /* When successful, not reached */ + b->unload_image (image_handle); + grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, + GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); + + return grub_errno; +} + + +static void ventoy_debug_pause(void) +{ + char key; + + if (0 == ventoy_debug) + { + return; + } + + grub_printf("press Enter to continue ......\n"); + while (1) + { + key = grub_getkey(); + if (key == '\n' || key == '\r') + { + break; + } + } +} + +static int ventoy_preboot(void) +{ + int i; + const char *file; + char buf[128]; + + if (ventoy_debug) + { + grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called); + ventoy_debug_pause(); + } + + if (ventoy_linux_argc == 0) + { + return 0; + } + + if (ventoy_initrd_called) + { + ventoy_initrd_called = 0; + return 0; + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + + ventoy_debug_pause(); + } + + grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list); + + return 0; +} + +static int ventoy_boot_opt_filter(char *opt) +{ + if (grub_strcmp(opt, "noinitrd") == 0) + { + return 1; + } + + if (grub_strcmp(opt, "vga=current") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "rdinit=", 7) == 0) + { + if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0) + { + opt[0] = 'v'; + opt[1] = 't'; + } + return 0; + } + + if (grub_strncmp(opt, "init=", 5) == 0) + { + opt[0] = 'v'; + opt[1] = 't'; + return 0; + } + + if (ventoy_debug) + { + if (grub_strcmp(opt, "quiet") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "loglevel=", 9) == 0) + { + return 1; + } + + if (grub_strcmp(opt, "splash") == 0) + { + return 1; + } + } + + return 0; +} + +static int ventoy_bootopt_hook(int argc, char *argv[]) +{ + int i; + int TmpIdx; + int count = 0; + const char *env; + char c; + char *newenv; + char *last, *pos; + + //grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return 0; + } + + /* To avoid --- parameter, we split two parts */ + for (TmpIdx = 0; TmpIdx < argc; TmpIdx++) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + if (grub_strncmp(argv[TmpIdx], "--", 2) == 0) + { + break; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + } + + for (i = 0; i < ventoy_linux_argc; i++) + { + ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)]; + ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL; + + if (ventoy_linux_args[count][0] == '@') + { + env = grub_env_get(ventoy_linux_args[count] + 1); + if (env) + { + grub_free(ventoy_linux_args[count]); + + newenv = grub_strdup(env); + last = newenv; + + while (*last) + { + while (*last) + { + if (*last != ' ' && *last != '\t') + { + break; + } + last++; + } + + if (*last == 0) + { + break; + } + + for (pos = last; *pos; pos++) + { + if (*pos == ' ' || *pos == '\t') + { + c = *pos; + *pos = 0; + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + *pos = c; + break; + } + } + + if (*pos == 0) + { + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + break; + } + + last = pos + 1; + } + } + else + { + count++; + } + } + else + { + count++; + } + } + + while (TmpIdx < argc) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + TmpIdx++; + } + + if (ventoy_debug) + { + ventoy_linux_args[count++] = grub_strdup("loglevel=7"); + } + + ventoy_linux_argc = count; + + if (ventoy_debug) + { + grub_printf("========== bootoption ==========\n"); + for (i = 0; i < count; i++) + { + grub_printf("%s ", ventoy_linux_args[i]); + } + grub_printf("\n================================\n"); + } + + return 0; +} + +static grub_err_t +grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *vtdebug; + + for (i = 0; i < argc; i++) + { + ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]); + ventoy_linux_argc++; + } + + vtdebug = grub_env_get("vtdebug_flag"); + if (vtdebug && vtdebug[0]) + { + ventoy_debug = 1; + } + + if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc); + + return 0; +} + +static grub_err_t +grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < LINUX_MAX_ARGC; i++) + { + if (ventoy_linux_args[i]) + { + grub_free(ventoy_linux_args[i]); + } + } + + ventoy_debug = 0; + ventoy_linux_argc = 0; + ventoy_initrd_called = 0; + grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC); + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int newclen = 0; + char *pos = NULL; + char *end = NULL; + char buf[256] = {0}; + + if (argc != 1) + { + return 1; + } + + for (pos = argv[0]; *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + /* grub2 newc bug workaround */ + newclen = (int)grub_strlen(end + 1); + if ((110 + newclen) % 4 == 0) + { + grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]); + } + else + { + grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]); + } + + if (ventoy_extra_initrd_num < 256) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + } + } + + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + if (ventoy_extra_initrd_list[i]) + { + grub_free(ventoy_extra_initrd_list[i]); + } + } + + grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list)); + + return 0; +} + + +static grub_err_t +grub_linux_boot (void) +{ + ventoy_preboot(); + + if (finalize_params_linux () != GRUB_ERR_NONE) + return grub_errno; + + return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr, + kernel_size, linux_args)); +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_dl_unref (my_mod); + loaded = 0; + if (initrd_start) + grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start, + GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); + initrd_start = initrd_end = 0; + grub_free (linux_args); + if (kernel_addr) + grub_efi_free_pages ((grub_addr_t) kernel_addr, + GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + grub_fdt_unload (); + return GRUB_ERR_NONE; +} + +/* + * As per linux/Documentation/arm/Booting + * ARM initrd needs to be covered by kernel linear mapping, + * so place it in the first 512MB of DRAM. + * + * As per linux/Documentation/arm64/booting.txt + * ARM64 initrd needs to be contained entirely within a 1GB aligned window + * of up to 32GB of size that covers the kernel image as well. + * Since the EFI stub loader will attempt to load the kernel near start of + * RAM, place the buffer in the first 32GB of RAM. + */ +#ifdef __arm__ +#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024) +#else /* __aarch64__ */ +#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) +#endif + +/* + * This function returns a pointer to a legally allocated initrd buffer, + * or NULL if unsuccessful + */ +static void * +allocate_initrd_mem (int initrd_pages) +{ + grub_addr_t max_addr; + + if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) + return NULL; + + max_addr += INITRD_MAX_ADDRESS_OFFSET - 1; + + return grub_efi_allocate_pages_real (max_addr, initrd_pages, + GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_LOADER_DATA); +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + int initrd_size, initrd_pages; + void *initrd_mem = NULL; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + if (!loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("you need to load the kernel first")); + goto fail; + } + + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + + initrd_size = grub_get_initrd_size (&initrd_ctx); + grub_dprintf ("linux", "Loading initrd\n"); + + initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); + initrd_mem = allocate_initrd_mem (initrd_pages); + + if (!initrd_mem) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + + if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + goto fail; + + initrd_start = (grub_addr_t) initrd_mem; + initrd_end = initrd_start + initrd_size; + grub_dprintf ("linux", "[addr=%p, size=0x%x]\n", + (void *) initrd_start, initrd_size); + + fail: + grub_initrd_close (&initrd_ctx); + if (initrd_mem && !initrd_start) + grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages); + + return grub_errno; +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_arch_kernel_header lh; + grub_err_t err; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (!file) + goto fail; + + kernel_size = grub_file_size (file); + + if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) + return grub_errno; + + if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) + goto fail; + + grub_loader_unset(); + + grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size); + kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + grub_dprintf ("linux", "kernel numpages: %lld\n", + (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + if (!kernel_addr) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + + grub_file_seek (file, 0); + if (grub_file_read (file, kernel_addr, kernel_size) + < (grub_int64_t) kernel_size) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); + goto fail; + } + + grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); + + cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); + linux_args = grub_malloc (cmdline_size); + if (!linux_args) + { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); + goto fail; + } + grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + + if (ventoy_linux_argc) + { + ventoy_bootopt_hook(argc, argv); + err = grub_create_loader_cmdline (ventoy_linux_argc, ventoy_linux_args, + linux_args + sizeof (LINUX_IMAGE) - 1, + cmdline_size, + GRUB_VERIFY_KERNEL_CMDLINE); } + else + { + err = grub_create_loader_cmdline (argc, argv, + linux_args + sizeof (LINUX_IMAGE) - 1, + cmdline_size, + GRUB_VERIFY_KERNEL_CMDLINE); + } + + if (err) + goto fail; + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + loaded = 1; + } + +fail: + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } + + if (linux_args && !loaded) + grub_free (linux_args); + + if (kernel_addr && !loaded) + grub_efi_free_pages ((grub_addr_t) kernel_addr, + GRUB_EFI_BYTES_TO_PAGES (kernel_size)); + + return grub_errno; +} + +static grub_err_t +ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *file; + char buf[64]; + + if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return grub_cmd_initrd(cmd, argc, argv); + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + if (ventoy_debug) grub_printf("membuf=%s\n", buf); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + for (i = 0; i < argc; i++) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]); + } + + ventoy_initrd_called = 1; + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + } + + return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list); +} + + +static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi; +static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset; + + +GRUB_MOD_INIT (linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0, + N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd, 0, + N_("Load initrd.")); + + cmd_linuxefi = grub_register_command ("linuxefi", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrdefi = grub_register_command ("initrdefi", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + + cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt")); + cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt")); + + cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_("")); + cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_("")); + + ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC); + + my_mod = mod; +} + +GRUB_MOD_FINI (linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/i386/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/i386/linux.c new file mode 100644 index 00000000..f6c879f5 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/i386/linux.c @@ -0,0 +1,1602 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#ifdef GRUB_MACHINE_PCBIOS +#include +#endif + +#ifdef GRUB_MACHINE_EFI +#include +#define HAS_VGA_TEXT 0 +#define DEFAULT_VIDEO_MODE "auto" +#define ACCEPTS_PURE_TEXT 0 +#elif defined (GRUB_MACHINE_IEEE1275) +#include +#define HAS_VGA_TEXT 0 +#define DEFAULT_VIDEO_MODE "text" +#define ACCEPTS_PURE_TEXT 1 +#else +#include +#include +#define HAS_VGA_TEXT 1 +#define DEFAULT_VIDEO_MODE "text" +#define ACCEPTS_PURE_TEXT 1 +#endif + +static grub_dl_t my_mod; + +static grub_size_t linux_mem_size; +static int loaded; +static void *prot_mode_mem; +static grub_addr_t prot_mode_target; +static void *initrd_mem; +static grub_addr_t initrd_mem_target; +static grub_size_t prot_init_space; +static struct grub_relocator *relocator = NULL; +static void *efi_mmap_buf; +static grub_size_t maximal_cmdline_size; +static struct linux_kernel_params linux_params; +static char *linux_cmdline; +#ifdef GRUB_MACHINE_EFI +static grub_efi_uintn_t efi_mmap_size; +#else +static const grub_size_t efi_mmap_size = 0; +#endif + +#define LINUX_MAX_ARGC 1024 +static int ventoy_debug = 0; +static int ventoy_initrd_called = 0; +static int ventoy_linux_argc = 0; +static char **ventoy_linux_args = NULL; +static int ventoy_extra_initrd_num = 0; +static char *ventoy_extra_initrd_list[256]; +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]); + +/* FIXME */ +#if 0 +struct idt_descriptor +{ + grub_uint16_t limit; + void *base; +} GRUB_PACKED; + +static struct idt_descriptor idt_desc = + { + 0, + 0 + }; +#endif + +static inline grub_size_t +page_align (grub_size_t size) +{ + return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +} + +/* Helper for find_mmap_size. */ +static int +count_hook (grub_uint64_t addr __attribute__ ((unused)), + grub_uint64_t size __attribute__ ((unused)), + grub_memory_type_t type __attribute__ ((unused)), void *data) +{ + grub_size_t *count = data; + + (*count)++; + return 0; +} + +/* Find the optimal number of pages for the memory map. */ +static grub_size_t +find_mmap_size (void) +{ + grub_size_t count = 0, mmap_size; + + grub_mmap_iterate (count_hook, &count); + + mmap_size = count * sizeof (struct grub_e820_mmap); + + /* Increase the size a bit for safety, because GRUB allocates more on + later. */ + mmap_size += (1 << 12); + + return page_align (mmap_size); +} + +static void +free_pages (void) +{ + grub_relocator_unload (relocator); + relocator = NULL; + prot_mode_mem = initrd_mem = 0; + prot_mode_target = initrd_mem_target = 0; +} + +/* Allocate pages for the real mode code and the protected mode code + for linux as well as a memory map buffer. */ +static grub_err_t +allocate_pages (grub_size_t prot_size, grub_size_t *align, + grub_size_t min_align, int relocatable, + grub_uint64_t preferred_address) +{ + grub_err_t err; + + if (prot_size == 0) + prot_size = 1; + + prot_size = page_align (prot_size); + + /* Initialize the memory pointers with NULL for convenience. */ + free_pages (); + + relocator = grub_relocator_new (); + if (!relocator) + { + err = grub_errno; + goto fail; + } + + /* FIXME: Should request low memory from the heap when this feature is + implemented. */ + + { + grub_relocator_chunk_t ch; + if (relocatable) + { + err = grub_relocator_alloc_chunk_align (relocator, &ch, + preferred_address, + preferred_address, + prot_size, 1, + GRUB_RELOCATOR_PREFERENCE_LOW, + 1); + for (; err && *align + 1 > min_align; (*align)--) + { + grub_errno = GRUB_ERR_NONE; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + 0x1000000, + 0xffffffff & ~prot_size, + prot_size, 1 << *align, + GRUB_RELOCATOR_PREFERENCE_LOW, + 1); + } + if (err) + goto fail; + } + else + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + preferred_address, + prot_size); + if (err) + goto fail; + prot_mode_mem = get_virtual_current_address (ch); + prot_mode_target = get_physical_target_address (ch); + } + + grub_dprintf ("linux", "prot_mode_mem = %p, prot_mode_target = %lx, prot_size = %x\n", + prot_mode_mem, (unsigned long) prot_mode_target, + (unsigned) prot_size); + return GRUB_ERR_NONE; + + fail: + free_pages (); + return err; +} + +static grub_err_t +grub_e820_add_region (struct grub_e820_mmap *e820_map, int *e820_num, + grub_uint64_t start, grub_uint64_t size, + grub_uint32_t type) +{ + int n = *e820_num; + + if ((n > 0) && (e820_map[n - 1].addr + e820_map[n - 1].size == start) && + (e820_map[n - 1].type == type)) + e820_map[n - 1].size += size; + else + { + e820_map[n].addr = start; + e820_map[n].size = size; + e820_map[n].type = type; + (*e820_num)++; + } + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_setup_video (struct linux_kernel_params *params) +{ + struct grub_video_mode_info mode_info; + void *framebuffer; + grub_err_t err; + grub_video_driver_id_t driver_id; + const char *gfxlfbvar = grub_env_get ("gfxpayloadforcelfb"); + + driver_id = grub_video_get_driver_id (); + + if (driver_id == GRUB_VIDEO_DRIVER_NONE) + return 1; + + err = grub_video_get_info_and_fini (&mode_info, &framebuffer); + + if (err) + { + grub_errno = GRUB_ERR_NONE; + return 1; + } + + params->lfb_width = mode_info.width; + params->lfb_height = mode_info.height; + params->lfb_depth = mode_info.bpp; + params->lfb_line_len = mode_info.pitch; + + params->lfb_base = (grub_size_t) framebuffer; + +#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__) + params->ext_lfb_base = (grub_size_t) (((grub_uint64_t)(grub_size_t) framebuffer) >> 32); + params->capabilities |= VIDEO_CAPABILITY_64BIT_BASE; +#endif + + params->lfb_size = ALIGN_UP (params->lfb_line_len * params->lfb_height, 65536); + + params->red_mask_size = mode_info.red_mask_size; + params->red_field_pos = mode_info.red_field_pos; + params->green_mask_size = mode_info.green_mask_size; + params->green_field_pos = mode_info.green_field_pos; + params->blue_mask_size = mode_info.blue_mask_size; + params->blue_field_pos = mode_info.blue_field_pos; + params->reserved_mask_size = mode_info.reserved_mask_size; + params->reserved_field_pos = mode_info.reserved_field_pos; + + if (gfxlfbvar && (gfxlfbvar[0] == '1' || gfxlfbvar[0] == 'y')) + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + else + { + switch (driver_id) + { + case GRUB_VIDEO_DRIVER_VBE: + params->lfb_size >>= 16; + params->have_vga = GRUB_VIDEO_LINUX_TYPE_VESA; + break; + + case GRUB_VIDEO_DRIVER_EFI_UGA: + case GRUB_VIDEO_DRIVER_EFI_GOP: + params->have_vga = GRUB_VIDEO_LINUX_TYPE_EFIFB; + break; + + /* FIXME: check if better id is available. */ + case GRUB_VIDEO_DRIVER_SM712: + case GRUB_VIDEO_DRIVER_SIS315PRO: + case GRUB_VIDEO_DRIVER_VGA: + case GRUB_VIDEO_DRIVER_CIRRUS: + case GRUB_VIDEO_DRIVER_BOCHS: + case GRUB_VIDEO_DRIVER_RADEON_FULOONG2E: + case GRUB_VIDEO_DRIVER_RADEON_YEELOONG3A: + case GRUB_VIDEO_DRIVER_IEEE1275: + case GRUB_VIDEO_DRIVER_COREBOOT: + /* Make gcc happy. */ + case GRUB_VIDEO_DRIVER_XEN: + case GRUB_VIDEO_DRIVER_SDL: + case GRUB_VIDEO_DRIVER_NONE: + case GRUB_VIDEO_ADAPTER_CAPTURE: + params->have_vga = GRUB_VIDEO_LINUX_TYPE_SIMPLE; + break; + } + } + +#ifdef GRUB_MACHINE_PCBIOS + /* VESA packed modes may come with zeroed mask sizes, which need + to be set here according to DAC Palette width. If we don't, + this results in Linux displaying a black screen. */ + if (driver_id == GRUB_VIDEO_DRIVER_VBE && mode_info.bpp <= 8) + { + struct grub_vbe_info_block controller_info; + int status; + int width = 8; + + status = grub_vbe_bios_get_controller_info (&controller_info); + + if (status == GRUB_VBE_STATUS_OK && + (controller_info.capabilities & GRUB_VBE_CAPABILITY_DACWIDTH)) + status = grub_vbe_bios_set_dac_palette_width (&width); + + if (status != GRUB_VBE_STATUS_OK) + /* 6 is default after mode reset. */ + width = 6; + + params->red_mask_size = params->green_mask_size + = params->blue_mask_size = width; + params->reserved_mask_size = 0; + } +#endif + + return GRUB_ERR_NONE; +} + +/* Context for grub_linux_boot. */ +struct grub_linux_boot_ctx +{ + grub_addr_t real_mode_target; + grub_size_t real_size; + struct linux_kernel_params *params; + int e820_num; +}; + +/* Helper for grub_linux_boot. */ +static int +grub_linux_boot_mmap_find (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type, void *data) +{ + struct grub_linux_boot_ctx *ctx = data; + + /* We must put real mode code in the traditional space. */ + if (type != GRUB_MEMORY_AVAILABLE || addr > 0x90000) + return 0; + + if (addr + size < 0x10000) + return 0; + + if (addr < 0x10000) + { + size += addr - 0x10000; + addr = 0x10000; + } + + if (addr + size > 0x90000) + size = 0x90000 - addr; + + if (ctx->real_size + efi_mmap_size > size) + return 0; + + grub_dprintf ("linux", "addr = %lx, size = %x, need_size = %x\n", + (unsigned long) addr, + (unsigned) size, + (unsigned) (ctx->real_size + efi_mmap_size)); + ctx->real_mode_target = ((addr + size) - (ctx->real_size + efi_mmap_size)); + return 1; +} + +/* GRUB types conveniently match E820 types. */ +static int +grub_linux_boot_mmap_fill (grub_uint64_t addr, grub_uint64_t size, + grub_memory_type_t type, void *data) +{ + struct grub_linux_boot_ctx *ctx = data; + + if (grub_e820_add_region (ctx->params->e820_map, &ctx->e820_num, + addr, size, type)) + return 1; + + return 0; +} + +static void ventoy_debug_pause(void) +{ + char key; + + if (0 == ventoy_debug) + { + return; + } + + grub_printf("press Enter to continue ......\n"); + while (1) + { + key = grub_getkey(); + if (key == '\n' || key == '\r') + { + break; + } + } +} + +static int ventoy_preboot(void) +{ + int i; + const char *file; + char buf[128]; + + if (ventoy_debug) + { + grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called); + ventoy_debug_pause(); + } + + if (ventoy_linux_argc == 0) + { + return 0; + } + + if (ventoy_initrd_called) + { + ventoy_initrd_called = 0; + return 0; + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + + ventoy_debug_pause(); + } + + grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list); + + return 0; +} + +static int ventoy_boot_opt_filter(char *opt) +{ + if (grub_strcmp(opt, "noinitrd") == 0) + { + return 1; + } + + if (grub_strcmp(opt, "vga=current") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "rdinit=", 7) == 0) + { + if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0) + { + opt[0] = 'v'; + opt[1] = 't'; + } + return 0; + } + + if (grub_strncmp(opt, "init=", 5) == 0) + { + opt[0] = 'v'; + opt[1] = 't'; + return 0; + } + + if (ventoy_debug) + { + if (grub_strcmp(opt, "quiet") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "loglevel=", 9) == 0) + { + return 1; + } + + if (grub_strcmp(opt, "splash") == 0) + { + return 1; + } + } + + return 0; +} + +static int ventoy_bootopt_hook(int argc, char *argv[]) +{ + int i; + int TmpIdx; + int count = 0; + const char *env; + char c; + char *newenv; + char *last, *pos; + + //grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return 0; + } + + /* To avoid --- parameter, we split two parts */ + for (TmpIdx = 0; TmpIdx < argc; TmpIdx++) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + if (grub_strncmp(argv[TmpIdx], "--", 2) == 0) + { + break; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + } + + for (i = 0; i < ventoy_linux_argc; i++) + { + ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)]; + ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL; + + if (ventoy_linux_args[count][0] == '@') + { + env = grub_env_get(ventoy_linux_args[count] + 1); + if (env) + { + grub_free(ventoy_linux_args[count]); + + newenv = grub_strdup(env); + last = newenv; + + while (*last) + { + while (*last) + { + if (*last != ' ' && *last != '\t') + { + break; + } + last++; + } + + if (*last == 0) + { + break; + } + + for (pos = last; *pos; pos++) + { + if (*pos == ' ' || *pos == '\t') + { + c = *pos; + *pos = 0; + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + *pos = c; + break; + } + } + + if (*pos == 0) + { + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + break; + } + + last = pos + 1; + } + } + else + { + count++; + } + } + else + { + count++; + } + } + + while (TmpIdx < argc) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + TmpIdx++; + } + + if (ventoy_debug) + { + ventoy_linux_args[count++] = grub_strdup("loglevel=7"); + } + + ventoy_linux_argc = count; + + if (ventoy_debug) + { + grub_printf("========== bootoption ==========\n"); + for (i = 0; i < count; i++) + { + grub_printf("%s ", ventoy_linux_args[i]); + } + grub_printf("\n================================\n"); + } + + return 0; +} + +static grub_err_t +grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *vtdebug; + + for (i = 0; i < argc; i++) + { + ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]); + ventoy_linux_argc++; + } + + vtdebug = grub_env_get("vtdebug_flag"); + if (vtdebug && vtdebug[0]) + { + ventoy_debug = 1; + } + + if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc); + + return 0; +} + +static grub_err_t +grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < LINUX_MAX_ARGC; i++) + { + if (ventoy_linux_args[i]) + { + grub_free(ventoy_linux_args[i]); + } + } + + ventoy_debug = 0; + ventoy_linux_argc = 0; + ventoy_initrd_called = 0; + grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC); + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int newclen = 0; + char *pos = NULL; + char *end = NULL; + char buf[256] = {0}; + + if (argc != 1) + { + return 1; + } + + for (pos = argv[0]; *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + /* grub2 newc bug workaround */ + newclen = (int)grub_strlen(end + 1); + if ((110 + newclen) % 4 == 0) + { + grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]); + } + else + { + grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]); + } + + if (ventoy_extra_initrd_num < 256) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + } + } + + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + if (ventoy_extra_initrd_list[i]) + { + grub_free(ventoy_extra_initrd_list[i]); + } + } + + grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list)); + + return 0; +} + + +static grub_err_t +grub_linux_boot (void) +{ + grub_err_t err = 0; + const char *modevar; + char *tmp; + struct grub_relocator32_state state; + void *real_mode_mem; + struct grub_linux_boot_ctx ctx = { + .real_mode_target = 0 + }; + grub_size_t mmap_size; + grub_size_t cl_offset; + + ventoy_preboot(); + +#ifdef GRUB_MACHINE_IEEE1275 + { + const char *bootpath; + grub_ssize_t len; + + bootpath = grub_env_get ("root"); + if (bootpath) + grub_ieee1275_set_property (grub_ieee1275_chosen, + "bootpath", bootpath, + grub_strlen (bootpath) + 1, + &len); + linux_params.ofw_signature = GRUB_LINUX_OFW_SIGNATURE; + linux_params.ofw_num_items = 1; + linux_params.ofw_cif_handler = (grub_uint32_t) grub_ieee1275_entry_fn; + linux_params.ofw_idt = 0; + } +#endif + + modevar = grub_env_get ("gfxpayload"); + + /* Now all graphical modes are acceptable. + May change in future if we have modes without framebuffer. */ + if (modevar && *modevar != 0) + { + tmp = grub_xasprintf ("%s;" DEFAULT_VIDEO_MODE, modevar); + if (! tmp) + return grub_errno; +#if ACCEPTS_PURE_TEXT + err = grub_video_set_mode (tmp, 0, 0); +#else + err = grub_video_set_mode (tmp, GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +#endif + grub_free (tmp); + } + else /* We can't go back to text mode from coreboot fb. */ +#ifdef GRUB_MACHINE_COREBOOT + if (grub_video_get_driver_id () == GRUB_VIDEO_DRIVER_COREBOOT) + err = GRUB_ERR_NONE; + else +#endif + { +#if ACCEPTS_PURE_TEXT + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, 0, 0); +#else + err = grub_video_set_mode (DEFAULT_VIDEO_MODE, + GRUB_VIDEO_MODE_TYPE_PURE_TEXT, 0); +#endif + } + + if (err) + { + grub_print_error (); + grub_puts_ (N_("Booting in blind mode")); + grub_errno = GRUB_ERR_NONE; + } + + if (grub_linux_setup_video (&linux_params)) + { +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) || defined (GRUB_MACHINE_QEMU) + linux_params.have_vga = GRUB_VIDEO_LINUX_TYPE_TEXT; + linux_params.video_mode = 0x3; +#else + linux_params.have_vga = 0; + linux_params.video_mode = 0; + linux_params.video_width = 0; + linux_params.video_height = 0; +#endif + } + + +#ifndef GRUB_MACHINE_IEEE1275 + if (linux_params.have_vga == GRUB_VIDEO_LINUX_TYPE_TEXT) +#endif + { + grub_term_output_t term; + int found = 0; + FOR_ACTIVE_TERM_OUTPUTS(term) + if (grub_strcmp (term->name, "vga_text") == 0 + || grub_strcmp (term->name, "console") == 0 + || grub_strcmp (term->name, "ofconsole") == 0) + { + struct grub_term_coordinate pos = grub_term_getxy (term); + linux_params.video_cursor_x = pos.x; + linux_params.video_cursor_y = pos.y; + linux_params.video_width = grub_term_width (term); + linux_params.video_height = grub_term_height (term); + found = 1; + break; + } + if (!found) + { + linux_params.video_cursor_x = 0; + linux_params.video_cursor_y = 0; + linux_params.video_width = 80; + linux_params.video_height = 25; + } + } + +#ifdef GRUB_KERNEL_USE_RSDP_ADDR + linux_params.acpi_rsdp_addr = grub_le_to_cpu64 (grub_rsdp_addr); +#endif + + mmap_size = find_mmap_size (); + /* Make sure that each size is aligned to a page boundary. */ + cl_offset = ALIGN_UP (mmap_size + sizeof (linux_params), 4096); + if (cl_offset < ((grub_size_t) linux_params.setup_sects << GRUB_DISK_SECTOR_BITS)) + cl_offset = ALIGN_UP ((grub_size_t) (linux_params.setup_sects + << GRUB_DISK_SECTOR_BITS), 4096); + ctx.real_size = ALIGN_UP (cl_offset + maximal_cmdline_size, 4096); + +#ifdef GRUB_MACHINE_EFI + efi_mmap_size = grub_efi_find_mmap_size (); + if (efi_mmap_size == 0) + return grub_errno; +#endif + + grub_dprintf ("linux", "real_size = %x, mmap_size = %x\n", + (unsigned) ctx.real_size, (unsigned) mmap_size); + +#ifdef GRUB_MACHINE_EFI + grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 1); + if (! ctx.real_mode_target) + grub_efi_mmap_iterate (grub_linux_boot_mmap_find, &ctx, 0); +#else + grub_mmap_iterate (grub_linux_boot_mmap_find, &ctx); +#endif + grub_dprintf ("linux", "real_mode_target = %lx, real_size = %x, efi_mmap_size = %x\n", + (unsigned long) ctx.real_mode_target, + (unsigned) ctx.real_size, + (unsigned) efi_mmap_size); + + if (! ctx.real_mode_target) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate real mode pages"); + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + ctx.real_mode_target, + (ctx.real_size + efi_mmap_size)); + if (err) + return err; + real_mode_mem = get_virtual_current_address (ch); + } + efi_mmap_buf = (grub_uint8_t *) real_mode_mem + ctx.real_size; + + grub_dprintf ("linux", "real_mode_mem = %p\n", + real_mode_mem); + + ctx.params = real_mode_mem; + + *ctx.params = linux_params; + ctx.params->cmd_line_ptr = ctx.real_mode_target + cl_offset; + grub_memcpy ((char *) ctx.params + cl_offset, linux_cmdline, + maximal_cmdline_size); + + grub_dprintf ("linux", "code32_start = %x\n", + (unsigned) ctx.params->code32_start); + + ctx.e820_num = 0; + if (grub_mmap_iterate (grub_linux_boot_mmap_fill, &ctx)) + return grub_errno; + ctx.params->mmap_size = ctx.e820_num; + +#ifdef GRUB_MACHINE_EFI + { + grub_efi_uintn_t efi_desc_size; + grub_size_t efi_mmap_target; + grub_efi_uint32_t efi_desc_version; + err = grub_efi_finish_boot_services (&efi_mmap_size, efi_mmap_buf, NULL, + &efi_desc_size, &efi_desc_version); + if (err) + return err; + + /* Note that no boot services are available from here. */ + efi_mmap_target = ctx.real_mode_target + + ((grub_uint8_t *) efi_mmap_buf - (grub_uint8_t *) real_mode_mem); + /* Pass EFI parameters. */ + if (grub_le_to_cpu16 (ctx.params->version) >= 0x0208) + { + ctx.params->v0208.efi_mem_desc_size = efi_desc_size; + ctx.params->v0208.efi_mem_desc_version = efi_desc_version; + ctx.params->v0208.efi_mmap = efi_mmap_target; + ctx.params->v0208.efi_mmap_size = efi_mmap_size; + +#ifdef __x86_64__ + ctx.params->v0208.efi_mmap_hi = (efi_mmap_target >> 32); +#endif + } + else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0206) + { + ctx.params->v0206.efi_mem_desc_size = efi_desc_size; + ctx.params->v0206.efi_mem_desc_version = efi_desc_version; + ctx.params->v0206.efi_mmap = efi_mmap_target; + ctx.params->v0206.efi_mmap_size = efi_mmap_size; + } + else if (grub_le_to_cpu16 (ctx.params->version) >= 0x0204) + { + ctx.params->v0204.efi_mem_desc_size = efi_desc_size; + ctx.params->v0204.efi_mem_desc_version = efi_desc_version; + ctx.params->v0204.efi_mmap = efi_mmap_target; + ctx.params->v0204.efi_mmap_size = efi_mmap_size; + } + } +#endif + + /* FIXME. */ + /* asm volatile ("lidt %0" : : "m" (idt_desc)); */ + state.ebp = state.edi = state.ebx = 0; + state.esi = ctx.real_mode_target; + state.esp = ctx.real_mode_target; + state.eip = ctx.params->code32_start; + return grub_relocator32_boot (relocator, state, 0); +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_dl_unref (my_mod); + loaded = 0; + grub_free (linux_cmdline); + linux_cmdline = 0; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_file_t file = 0; + struct linux_i386_kernel_header lh; + grub_uint8_t setup_sects; + grub_size_t real_size, prot_size, prot_file_size; + grub_ssize_t len; + int i; + grub_size_t align, min_align; + int relocatable; + grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + + grub_dl_ref (my_mod); + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (! file) + goto fail; + + if (ventoy_linux_argc) + { + const char *tip = grub_env_get("ventoy_loading_tip"); + if (tip) + { + grub_printf("%s\n", tip); + grub_refresh(); + } + } + + if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + goto fail; + } + + if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) + { + grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); + goto fail; + } + + if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) + { + grub_error (GRUB_ERR_BAD_OS, "too many setup sectors"); + goto fail; + } + + /* FIXME: 2.03 is not always good enough (Linux 2.4 can be 2.03 and + still not support 32-bit boot. */ + if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) + || grub_le_to_cpu16 (lh.version) < 0x0203) + { + grub_error (GRUB_ERR_BAD_OS, "version too old for 32-bit boot" +#ifdef GRUB_MACHINE_PCBIOS + " (try with `linux16')" +#endif + ); + goto fail; + } + + if (! (lh.loadflags & GRUB_LINUX_FLAG_BIG_KERNEL)) + { + grub_error (GRUB_ERR_BAD_OS, "zImage doesn't support 32-bit boot" +#ifdef GRUB_MACHINE_PCBIOS + " (try with `linux16')" +#endif + ); + goto fail; + } + + if (grub_le_to_cpu16 (lh.version) >= 0x0206) + maximal_cmdline_size = grub_le_to_cpu32 (lh.cmdline_size) + 1; + else + maximal_cmdline_size = 256; + + if (maximal_cmdline_size < 128) + maximal_cmdline_size = 128; + + setup_sects = lh.setup_sects; + + /* If SETUP_SECTS is not set, set it to the default (4). */ + if (! setup_sects) + setup_sects = GRUB_LINUX_DEFAULT_SETUP_SECTS; + + real_size = setup_sects << GRUB_DISK_SECTOR_BITS; + prot_file_size = grub_file_size (file) - real_size - GRUB_DISK_SECTOR_SIZE; + + if (grub_le_to_cpu16 (lh.version) >= 0x205 + && lh.kernel_alignment != 0 + && ((lh.kernel_alignment - 1) & lh.kernel_alignment) == 0) + { + for (align = 0; align < 32; align++) + if (grub_le_to_cpu32 (lh.kernel_alignment) & (1 << align)) + break; + relocatable = grub_le_to_cpu32 (lh.relocatable); + } + else + { + align = 0; + relocatable = 0; + } + + if (grub_le_to_cpu16 (lh.version) >= 0x020a) + { + min_align = lh.min_alignment; + prot_size = grub_le_to_cpu32 (lh.init_size); + prot_init_space = page_align (prot_size); + if (relocatable) + preferred_address = grub_le_to_cpu64 (lh.pref_address); + else + preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + } + else + { + min_align = align; + prot_size = prot_file_size; + preferred_address = GRUB_LINUX_BZIMAGE_ADDR; + /* Usually, the compression ratio is about 50%. */ + prot_init_space = page_align (prot_size) * 3; + } + + if (allocate_pages (prot_size, &align, + min_align, relocatable, + preferred_address)) + goto fail; + + grub_memset (&linux_params, 0, sizeof (linux_params)); + grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1); + + linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; + linux_params.kernel_alignment = (1 << align); + linux_params.ps_mouse = linux_params.padding10 = 0; + + /* + * The Linux 32-bit boot protocol defines the setup header end + * to be at 0x202 + the byte value at 0x201. + */ + len = 0x202 + *((char *) &linux_params.jump + 1); + + /* Verify the struct is big enough so we do not write past the end. */ + if (len > (char *) &linux_params.edd_mbr_sig_buffer - (char *) &linux_params) { + grub_error (GRUB_ERR_BAD_OS, "Linux setup header too big"); + goto fail; + } + + /* We've already read lh so there is no need to read it second time. */ + len -= sizeof(lh); + + if (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len) + { + if (!grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + goto fail; + } + + linux_params.type_of_loader = GRUB_LINUX_BOOT_LOADER_TYPE; + + /* These two are used (instead of cmd_line_ptr) by older versions of Linux, + and otherwise ignored. */ + linux_params.cl_magic = GRUB_LINUX_CL_MAGIC; + linux_params.cl_offset = 0x1000; + + linux_params.ramdisk_image = 0; + linux_params.ramdisk_size = 0; + + linux_params.heap_end_ptr = GRUB_LINUX_HEAP_END_OFFSET; + linux_params.loadflags |= GRUB_LINUX_FLAG_CAN_USE_HEAP; + + /* These are not needed to be precise, because Linux uses these values + only to raise an error when the decompression code cannot find good + space. */ + linux_params.ext_mem = ((32 * 0x100000) >> 10); + linux_params.alt_mem = ((32 * 0x100000) >> 10); + + /* Ignored by Linux. */ + linux_params.video_page = 0; + + /* Only used when `video_mode == 0x7', otherwise ignored. */ + linux_params.video_ega_bx = 0; + + linux_params.font_size = 16; /* XXX */ + +#ifdef GRUB_MACHINE_EFI +#ifdef __x86_64__ + if (grub_le_to_cpu16 (linux_params.version) < 0x0208 && + ((grub_addr_t) grub_efi_system_table >> 32) != 0) + return grub_error(GRUB_ERR_BAD_OS, + "kernel does not support 64-bit addressing"); +#endif + + if (grub_le_to_cpu16 (linux_params.version) >= 0x0208) + { + linux_params.v0208.efi_signature = GRUB_LINUX_EFI_SIGNATURE; + linux_params.v0208.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; +#ifdef __x86_64__ + linux_params.v0208.efi_system_table_hi = (grub_uint32_t) ((grub_uint64_t) grub_efi_system_table >> 32); +#endif + } + else if (grub_le_to_cpu16 (linux_params.version) >= 0x0206) + { + linux_params.v0206.efi_signature = GRUB_LINUX_EFI_SIGNATURE; + linux_params.v0206.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; + } + else if (grub_le_to_cpu16 (linux_params.version) >= 0x0204) + { + linux_params.v0204.efi_signature = GRUB_LINUX_EFI_SIGNATURE_0204; + linux_params.v0204.efi_system_table = (grub_uint32_t) (grub_addr_t) grub_efi_system_table; + } +#endif + + /* The other parameters are filled when booting. */ + + grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); + + grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n", + (unsigned) real_size, (unsigned) prot_size); + + /* Look for memory size and video mode specified on the command line. */ + linux_mem_size = 0; + for (i = 1; i < argc; i++) +#ifdef GRUB_MACHINE_PCBIOS + if (grub_memcmp (argv[i], "vga=", 4) == 0 && (grub_memcmp (argv[i], "vga=current", 11) != 0)) + { + /* Video mode selection support. */ + char *val = argv[i] + 4; + unsigned vid_mode = GRUB_LINUX_VID_MODE_NORMAL; + struct grub_vesa_mode_table_entry *linux_mode; + grub_err_t err; + char *buf; + + grub_dl_load ("vbe"); + + if (grub_strcmp (val, "normal") == 0) + vid_mode = GRUB_LINUX_VID_MODE_NORMAL; + else if (grub_strcmp (val, "ext") == 0) + vid_mode = GRUB_LINUX_VID_MODE_EXTENDED; + else if (grub_strcmp (val, "ask") == 0) + { + grub_puts_ (N_("Legacy `ask' parameter no longer supported.")); + + /* We usually would never do this in a loader, but "vga=ask" means user + requested interaction, so it can't hurt to request keyboard input. */ + grub_wait_after_message (); + + goto fail; + } + else + vid_mode = (grub_uint16_t) grub_strtoul (val, 0, 0); + + switch (vid_mode) + { + case 0: + case GRUB_LINUX_VID_MODE_NORMAL: + grub_env_set ("gfxpayload", "text"); + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), + argv[i], "text"); + break; + + case 1: + case GRUB_LINUX_VID_MODE_EXTENDED: + /* FIXME: support 80x50 text. */ + grub_env_set ("gfxpayload", "text"); + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), + argv[i], "text"); + break; + default: + /* Ignore invalid values. */ + if (vid_mode < GRUB_VESA_MODE_TABLE_START || + vid_mode > GRUB_VESA_MODE_TABLE_END) + { + grub_env_set ("gfxpayload", "text"); + /* TRANSLATORS: "x" has to be entered in, like an identifier, + so please don't use better Unicode codepoints. */ + grub_printf_ (N_("%s is deprecated. VGA mode %d isn't recognized. " + "Use set gfxpayload=WIDTHxHEIGHT[xDEPTH] " + "before linux command instead.\n"), + argv[i], vid_mode); + break; + } + + linux_mode = &grub_vesa_mode_table[vid_mode + - GRUB_VESA_MODE_TABLE_START]; + + buf = grub_xasprintf ("%ux%ux%u,%ux%u", + linux_mode->width, linux_mode->height, + linux_mode->depth, + linux_mode->width, linux_mode->height); + if (! buf) + goto fail; + + grub_printf_ (N_("%s is deprecated. " + "Use set gfxpayload=%s before " + "linux command instead.\n"), + argv[i], buf); + err = grub_env_set ("gfxpayload", buf); + grub_free (buf); + if (err) + goto fail; + } + } + else +#endif /* GRUB_MACHINE_PCBIOS */ + if (grub_memcmp (argv[i], "mem=", 4) == 0) + { + char *val = argv[i] + 4; + + linux_mem_size = grub_strtoul (val, &val, 0); + + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; + linux_mem_size = 0; + } + else + { + int shift = 0; + + switch (grub_tolower (val[0])) + { + case 'g': + shift += 10; + /* FALLTHROUGH */ + case 'm': + shift += 10; + /* FALLTHROUGH */ + case 'k': + shift += 10; + /* FALLTHROUGH */ + default: + break; + } + + /* Check an overflow. */ + if (linux_mem_size > (~0UL >> shift)) + linux_mem_size = 0; + else + linux_mem_size <<= shift; + } + } + else if (grub_memcmp (argv[i], "quiet", sizeof ("quiet") - 1) == 0) + { + linux_params.loadflags |= GRUB_LINUX_FLAG_QUIET; + } + + /* Create kernel command line. */ + linux_cmdline = grub_zalloc (maximal_cmdline_size + 1); + if (!linux_cmdline) + goto fail; + grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); + { + grub_err_t err; + + if (ventoy_linux_argc) + { + ventoy_bootopt_hook(argc, argv); + err = grub_create_loader_cmdline (ventoy_linux_argc, ventoy_linux_args, + linux_cmdline + + sizeof (LINUX_IMAGE) - 1, + maximal_cmdline_size + - (sizeof (LINUX_IMAGE) - 1), + GRUB_VERIFY_KERNEL_CMDLINE); + } + else + { + err = grub_create_loader_cmdline (argc, argv, + linux_cmdline + + sizeof (LINUX_IMAGE) - 1, + maximal_cmdline_size + - (sizeof (LINUX_IMAGE) - 1), + GRUB_VERIFY_KERNEL_CMDLINE); + } + + if (err) + goto fail; + } + + len = prot_file_size; + if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) + grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), + argv[0]); + + if (grub_errno == GRUB_ERR_NONE) + { + grub_loader_set (grub_linux_boot, grub_linux_unload, + 0 /* set noreturn=0 in order to avoid grub_console_fini() */); + loaded = 1; + } + + fail: + + if (file) + grub_file_close (file); + + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); + loaded = 0; + } + + return grub_errno; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_size_t size = 0, aligned_size = 0; + grub_addr_t addr_min, addr_max; + grub_addr_t addr; + grub_err_t err; + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + + if (argc == 0) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + goto fail; + } + + if (! loaded) + { + grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); + goto fail; + } + + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + + size = grub_get_initrd_size (&initrd_ctx); + aligned_size = ALIGN_UP (size, 4096); + + /* Get the highest address available for the initrd. */ + if (grub_le_to_cpu16 (linux_params.version) >= 0x0203) + { + addr_max = grub_cpu_to_le32 (linux_params.initrd_addr_max); + + /* XXX in reality, Linux specifies a bogus value, so + it is necessary to make sure that ADDR_MAX does not exceed + 0x3fffffff. */ + if (addr_max > GRUB_LINUX_INITRD_MAX_ADDRESS) + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + } + else + addr_max = GRUB_LINUX_INITRD_MAX_ADDRESS; + + if (linux_mem_size != 0 && linux_mem_size < addr_max) + addr_max = linux_mem_size; + + /* Linux 2.3.xx has a bug in the memory range check, so avoid + the last page. + Linux 2.2.xx has a bug in the memory range check, which is + worse than that of Linux 2.3.xx, so avoid the last 64kb. */ + addr_max -= 0x10000; + + addr_min = (grub_addr_t) prot_mode_target + prot_init_space; + + /* Put the initrd as high as possible, 4KiB aligned. */ + addr = (addr_max - aligned_size) & ~0xFFF; + + if (addr < addr_min) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, "the initrd is too big"); + goto fail; + } + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + addr_min, addr, aligned_size, + 0x1000, + GRUB_RELOCATOR_PREFERENCE_HIGH, + 1); + if (err) + return err; + initrd_mem = get_virtual_current_address (ch); + initrd_mem_target = get_physical_target_address (ch); + } + + if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) + goto fail; + + grub_dprintf ("linux", "Initrd, addr=0x%x, size=0x%x\n", + (unsigned) addr, (unsigned) size); + + linux_params.ramdisk_image = initrd_mem_target; + linux_params.ramdisk_size = size; + linux_params.root_dev = 0x0100; /* XXX */ + + fail: + grub_initrd_close (&initrd_ctx); + + return grub_errno; +} + +static grub_err_t +ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *file; + char buf[64]; + + if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return grub_cmd_initrd(cmd, argc, argv); + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + if (ventoy_debug) grub_printf("membuf=%s\n", buf); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + for (i = 0; i < argc; i++) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]); + } + + ventoy_initrd_called = 1; + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + } + + return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list); +} + + +static grub_command_t cmd_linux, cmd_initrd, cmd_linuxefi, cmd_initrdefi; +static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset; + +GRUB_MOD_INIT(linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + + cmd_linuxefi = grub_register_command ("linuxefi", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrdefi = grub_register_command ("initrdefi", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt")); + cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt")); + + cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_("")); + cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_("")); + + ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC); + + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c new file mode 100644 index 00000000..92492f9d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/linux.c @@ -0,0 +1,316 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +struct newc_head +{ + char magic[6]; + char ino[8]; + char mode[8]; + char uid[8]; + char gid[8]; + char nlink[8]; + char mtime[8]; + char filesize[8]; + char devmajor[8]; + char devminor[8]; + char rdevmajor[8]; + char rdevminor[8]; + char namesize[8]; + char check[8]; +} GRUB_PACKED; + +struct grub_linux_initrd_component +{ + grub_file_t file; + char *newc_name; + grub_off_t size; +}; + +struct dir +{ + char *name; + struct dir *next; + struct dir *child; +}; + +static char +hex (grub_uint8_t val) +{ + if (val < 10) + return '0' + val; + return 'a' + val - 10; +} + +static void +set_field (char *var, grub_uint32_t val) +{ + int i; + char *ptr = var; + for (i = 28; i >= 0; i -= 4) + *ptr++ = hex((val >> i) & 0xf); +} + +static grub_uint8_t * +make_header (grub_uint8_t *ptr, + const char *name, grub_size_t len, + grub_uint32_t mode, + grub_off_t fsize) +{ + struct newc_head *head = (struct newc_head *) ptr; + grub_uint8_t *optr; + grub_size_t oh = 0; + grub_memcpy (head->magic, "070701", 6); + set_field (head->ino, 0); + set_field (head->mode, mode); + set_field (head->uid, 0); + set_field (head->gid, 0); + set_field (head->nlink, 1); + set_field (head->mtime, 0); + set_field (head->filesize, fsize); + set_field (head->devmajor, 0); + set_field (head->devminor, 0); + set_field (head->rdevmajor, 0); + set_field (head->rdevminor, 0); + set_field (head->namesize, len); + set_field (head->check, 0); + optr = ptr; + ptr += sizeof (struct newc_head); + grub_memcpy (ptr, name, len); + ptr += len; + oh = ALIGN_UP_OVERHEAD (ptr - optr, 4); + grub_memset (ptr, 0, oh); + ptr += oh; + return ptr; +} + +static void +free_dir (struct dir *root) +{ + if (!root) + return; + free_dir (root->next); + free_dir (root->child); + grub_free (root->name); + grub_free (root); +} + +static grub_size_t +insert_dir (const char *name, struct dir **root, + grub_uint8_t *ptr) +{ + struct dir *cur, **head = root; + const char *cb, *ce = name; + grub_size_t size = 0; + while (1) + { + for (cb = ce; *cb == '/'; cb++); + for (ce = cb; *ce && *ce != '/'; ce++); + if (!*ce) + break; + + for (cur = *root; cur; cur = cur->next) + if (grub_memcmp (cur->name, cb, ce - cb) + && cur->name[ce - cb] == 0) + break; + if (!cur) + { + struct dir *n; + n = grub_zalloc (sizeof (*n)); + if (!n) + return 0; + n->next = *head; + n->name = grub_strndup (cb, ce - cb); + if (ptr) + { + grub_dprintf ("linux", "Creating directory %s, %s\n", name, ce); + ptr = make_header (ptr, name, ce - name, + 040777, 0); + } + size += ALIGN_UP ((ce - (char *) name) + + sizeof (struct newc_head), 4); + *head = n; + cur = n; + } + root = &cur->next; + } + return size; +} + +grub_err_t +grub_initrd_init (int argc, char *argv[], + struct grub_linux_initrd_context *initrd_ctx) +{ + int i; + int newc = 0; + struct dir *root = 0; + + initrd_ctx->nfiles = 0; + initrd_ctx->components = 0; + + initrd_ctx->components = grub_zalloc (argc + * sizeof (initrd_ctx->components[0])); + if (!initrd_ctx->components) + return grub_errno; + + initrd_ctx->size = 0; + + for (i = 0; i < argc; i++) + { + const char *fname = argv[i]; + + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); + + if (grub_memcmp (argv[i], "newc:", 5) == 0) + { + const char *ptr, *eptr; + ptr = argv[i] + 5; + while (*ptr == '/') + ptr++; + eptr = grub_strchr (ptr, ':'); + if (eptr) + { + initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); + if (!initrd_ctx->components[i].newc_name) + { + grub_initrd_close (initrd_ctx); + return grub_errno; + } + initrd_ctx->size + += ALIGN_UP (sizeof (struct newc_head) + + grub_strlen (initrd_ctx->components[i].newc_name), + 4); + initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, + &root, 0); + newc = 1; + fname = eptr + 1; + } + } + else if (newc) + { + initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) + + sizeof ("TRAILER!!!") - 1, 4); + free_dir (root); + root = 0; + newc = 0; + } + initrd_ctx->components[i].file = grub_file_open (fname, + GRUB_FILE_TYPE_LINUX_INITRD + | GRUB_FILE_TYPE_NO_DECOMPRESS); + if (!initrd_ctx->components[i].file) + { + grub_initrd_close (initrd_ctx); + return grub_errno; + } + initrd_ctx->nfiles++; + initrd_ctx->components[i].size + = grub_file_size (initrd_ctx->components[i].file); + initrd_ctx->size += initrd_ctx->components[i].size; + } + + if (newc) + { + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); + initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) + + sizeof ("TRAILER!!!") - 1, 4); + free_dir (root); + root = 0; + } + + return GRUB_ERR_NONE; +} + +grub_size_t +grub_get_initrd_size (struct grub_linux_initrd_context *initrd_ctx) +{ + return initrd_ctx->size; +} + +void +grub_initrd_close (struct grub_linux_initrd_context *initrd_ctx) +{ + int i; + if (!initrd_ctx->components) + return; + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_free (initrd_ctx->components[i].newc_name); + grub_file_close (initrd_ctx->components[i].file); + } + grub_free (initrd_ctx->components); + initrd_ctx->components = 0; +} + +extern int ventoy_need_prompt_load_file(void); +extern grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size); +grub_err_t +grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + char *argv[], void *target) +{ + grub_uint8_t *ptr = target; + int i; + int newc = 0; + struct dir *root = 0; + grub_ssize_t cursize = 0; + grub_ssize_t readsize = 0; + + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + + if (initrd_ctx->components[i].newc_name) + { + ptr += insert_dir (initrd_ctx->components[i].newc_name, + &root, ptr); + ptr = make_header (ptr, initrd_ctx->components[i].newc_name, + grub_strlen (initrd_ctx->components[i].newc_name), + 0100777, + initrd_ctx->components[i].size); + newc = 1; + } + else if (newc) + { + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, + 0, 0); + free_dir (root); + root = 0; + newc = 0; + } + + cursize = initrd_ctx->components[i].size; + if (ventoy_need_prompt_load_file() && initrd_ctx->components[i].newc_name && + grub_strcmp(initrd_ctx->components[i].newc_name, "boot.wim") == 0) + { + readsize = ventoy_load_file_with_prompt(initrd_ctx->components[i].file, ptr, cursize); + } + else + { + readsize = grub_file_read (initrd_ctx->components[i].file, ptr, cursize); + } + + if (readsize != cursize) + { + if (!grub_errno) + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), + argv[i]); + grub_initrd_close (initrd_ctx); + return grub_errno; + } + ptr += cursize; + } + if (newc) + { + grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); + ptr += ALIGN_UP_OVERHEAD (cursize, 4); + ptr = make_header (ptr, "TRAILER!!!", sizeof ("TRAILER!!!") - 1, 0, 0); + } + free_dir (root); + root = 0; + return GRUB_ERR_NONE; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c new file mode 100644 index 00000000..2822187d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/loader/mips64/linux.c @@ -0,0 +1,1034 @@ +/* linux.c - boot Linux */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2009,2010,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define _ull unsigned long long +#pragma GCC diagnostic ignored "-Wcast-align" + +typedef unsigned long size_t; + +static grub_dl_t my_mod; + +static int loaded; + +static grub_uint32_t tmp_index = 0; +static grub_size_t linux_size; + +static struct grub_relocator *relocator; +static grub_addr_t target_addr, entry_addr; +static int linux_argc; +static grub_uint8_t *linux_args_addr; +static grub_off_t rd_addr_arg_off, rd_size_arg_off; +static int initrd_loaded = 0; + + +static grub_uint32_t j = 0; +static grub_uint32_t t = 0; +grub_uint64_t tempMemsize = 0; +grub_uint32_t free_index = 0; +grub_uint32_t reserve_index = 0; +grub_uint32_t acpi_table_index = 0; +grub_uint32_t acpi_nvs_index = 0; + +#define LINUX_MAX_ARGC 1024 +static int ventoy_debug = 0; +static int ventoy_initrd_called = 0; +static int ventoy_linux_argc = 0; +static char **ventoy_linux_args = NULL; +static int ventoy_extra_initrd_num = 0; +static char *ventoy_extra_initrd_list[256]; +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]); + + + +static inline grub_size_t +page_align (grub_size_t size) +{ + return (size + (1 << 12) - 1) & (~((1 << 12) - 1)); +} + +/* Find the optimal number of pages for the memory map. Is it better to + move this code to efi/mm.c? */ +static grub_efi_uintn_t +find_mmap_size (void) +{ + static grub_efi_uintn_t mmap_size = 0; + + if (mmap_size != 0) + return mmap_size; + + mmap_size = (1 << 12); + while (1) + { + int ret; + grub_efi_memory_descriptor_t *mmap; + grub_efi_uintn_t desc_size; + + mmap = grub_malloc (mmap_size); + if (! mmap) + return 0; + + ret = grub_efi_get_memory_map (&mmap_size, mmap, 0, &desc_size, 0); + grub_free (mmap); + + if (ret < 0) + { + grub_error (GRUB_ERR_IO, "cannot get memory map"); + return 0; + } + else if (ret > 0) + break; + + mmap_size += (1 << 12); + } + + + /* Increase the size a bit for safety, because GRUB allocates more on + later, and EFI itself may allocate more. */ + mmap_size += (1 << 12); + + return page_align (mmap_size); +} + + +static void ventoy_debug_pause(void) +{ + char key; + + if (0 == ventoy_debug) + { + return; + } + + grub_printf("press Enter to continue ......\n"); + while (1) + { + key = grub_getkey(); + if (key == '\n' || key == '\r') + { + break; + } + } +} + +static int ventoy_preboot(void) +{ + int i; + const char *file; + char buf[128]; + + if (ventoy_debug) + { + grub_printf("ventoy_preboot %d %d\n", ventoy_linux_argc, ventoy_initrd_called); + ventoy_debug_pause(); + } + + if (ventoy_linux_argc == 0) + { + return 0; + } + + if (ventoy_initrd_called) + { + ventoy_initrd_called = 0; + return 0; + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + + ventoy_debug_pause(); + } + + grub_cmd_initrd(NULL, ventoy_extra_initrd_num, ventoy_extra_initrd_list); + + return 0; +} + +static int ventoy_boot_opt_filter(char *opt) +{ + if (grub_strcmp(opt, "noinitrd") == 0) + { + return 1; + } + + if (grub_strcmp(opt, "vga=current") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "rdinit=", 7) == 0) + { + if (grub_strcmp(opt, "rdinit=/vtoy/vtoy") != 0) + { + opt[0] = 'v'; + opt[1] = 't'; + } + return 0; + } + + if (grub_strncmp(opt, "init=", 5) == 0) + { + opt[0] = 'v'; + opt[1] = 't'; + return 0; + } + + if (ventoy_debug) + { + if (grub_strcmp(opt, "quiet") == 0) + { + return 1; + } + + if (grub_strncmp(opt, "loglevel=", 9) == 0) + { + return 1; + } + + if (grub_strcmp(opt, "splash") == 0) + { + return 1; + } + } + + return 0; +} + +static int ventoy_bootopt_hook(int argc, char *argv[]) +{ + int i; + int TmpIdx; + int count = 0; + const char *env; + char c; + char *newenv; + char *last, *pos; + + //grub_printf("ventoy_bootopt_hook: %d %d\n", argc, ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return 0; + } + + /* To avoid --- parameter, we split two parts */ + for (TmpIdx = 0; TmpIdx < argc; TmpIdx++) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + if (grub_strncmp(argv[TmpIdx], "--", 2) == 0) + { + break; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + } + + for (i = 0; i < ventoy_linux_argc; i++) + { + ventoy_linux_args[count] = ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)]; + ventoy_linux_args[i + (LINUX_MAX_ARGC / 2)] = NULL; + + if (ventoy_linux_args[count][0] == '@') + { + env = grub_env_get(ventoy_linux_args[count] + 1); + if (env) + { + grub_free(ventoy_linux_args[count]); + + newenv = grub_strdup(env); + last = newenv; + + while (*last) + { + while (*last) + { + if (*last != ' ' && *last != '\t') + { + break; + } + last++; + } + + if (*last == 0) + { + break; + } + + for (pos = last; *pos; pos++) + { + if (*pos == ' ' || *pos == '\t') + { + c = *pos; + *pos = 0; + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + *pos = c; + break; + } + } + + if (*pos == 0) + { + if (0 == ventoy_boot_opt_filter(last)) + { + ventoy_linux_args[count++] = grub_strdup(last); + } + break; + } + + last = pos + 1; + } + } + else + { + count++; + } + } + else + { + count++; + } + } + + while (TmpIdx < argc) + { + if (ventoy_boot_opt_filter(argv[TmpIdx])) + { + continue; + } + + ventoy_linux_args[count++] = grub_strdup(argv[TmpIdx]); + TmpIdx++; + } + + if (ventoy_debug) + { + ventoy_linux_args[count++] = grub_strdup("loglevel=7"); + } + + ventoy_linux_argc = count; + + if (ventoy_debug) + { + grub_printf("========== bootoption ==========\n"); + for (i = 0; i < count; i++) + { + grub_printf("%s ", ventoy_linux_args[i]); + } + grub_printf("\n================================\n"); + } + + return 0; +} + +static grub_err_t +grub_cmd_set_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *vtdebug; + + for (i = 0; i < argc; i++) + { + ventoy_linux_args[ventoy_linux_argc + (LINUX_MAX_ARGC / 2) ] = grub_strdup(argv[i]); + ventoy_linux_argc++; + } + + vtdebug = grub_env_get("vtdebug_flag"); + if (vtdebug && vtdebug[0]) + { + ventoy_debug = 1; + } + + if (ventoy_debug) grub_printf("ventoy set boot opt %d\n", ventoy_linux_argc); + + return 0; +} + +static grub_err_t +grub_cmd_unset_boot_opt (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < LINUX_MAX_ARGC; i++) + { + if (ventoy_linux_args[i]) + { + grub_free(ventoy_linux_args[i]); + } + } + + ventoy_debug = 0; + ventoy_linux_argc = 0; + ventoy_initrd_called = 0; + grub_memset(ventoy_linux_args, 0, sizeof(char *) * LINUX_MAX_ARGC); + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_append (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int newclen = 0; + char *pos = NULL; + char *end = NULL; + char buf[256] = {0}; + + if (argc != 1) + { + return 1; + } + + for (pos = argv[0]; *pos; pos++) + { + if (*pos == '/') + { + end = pos; + } + } + + if (end) + { + /* grub2 newc bug workaround */ + newclen = (int)grub_strlen(end + 1); + if ((110 + newclen) % 4 == 0) + { + grub_snprintf(buf, sizeof(buf), "newc:.%s:%s", end + 1, argv[0]); + } + else + { + grub_snprintf(buf, sizeof(buf), "newc:%s:%s", end + 1, argv[0]); + } + + if (ventoy_extra_initrd_num < 256) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + } + } + + return 0; +} + +static grub_err_t +grub_cmd_extra_initrd_reset (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + + (void)argc; + (void)argv; + + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + if (ventoy_extra_initrd_list[i]) + { + grub_free(ventoy_extra_initrd_list[i]); + } + } + + grub_memset(ventoy_extra_initrd_list, 0, sizeof(ventoy_extra_initrd_list)); + + return 0; +} + + +static grub_err_t +grub_linux_boot (void) +{ + struct grub_relocator64_state state; + grub_int8_t checksum = 0; + grub_efi_memory_descriptor_t * lsdesc = NULL; + + ventoy_preboot(); + + grub_memset (&state, 0, sizeof (state)); + + /* Boot the kernel. */ + state.gpr[1] = entry_addr; + grub_dprintf("loongson", "entry_addr is 0x%llx\n", (_ull)state.gpr[1]); + state.gpr[4] = linux_argc; + grub_dprintf("loongson", "linux_argc is %lld\n", (_ull)state.gpr[4]); + state.gpr[5] = (grub_addr_t) linux_args_addr; + grub_dprintf("loongson", "args_addr is 0x%llx\n", (_ull)state.gpr[5]); + + if(grub_efi_is_loongson ()) + { + grub_efi_uintn_t mmap_size; + grub_efi_uintn_t desc_size; + grub_efi_memory_descriptor_t *mmap_buf; + grub_err_t err; + struct bootparamsinterface * boot_params; + void * tmp_boot_params = NULL; + grub_efi_uint8_t new_interface_flag = 0; + mem_map * new_interface_mem = NULL; + char *p = NULL; + + struct memmap reserve_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + struct memmap free_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + struct memmap acpi_table_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + struct memmap acpi_nvs_mem[GRUB_EFI_LOONGSON_MMAP_MAX]; + + grub_memset(reserve_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + grub_memset(free_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + grub_memset(acpi_table_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + grub_memset(acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_EFI_LOONGSON_MMAP_MAX); + + tmp_boot_params = grub_efi_loongson_get_boot_params(); + if(tmp_boot_params == NULL) + { + grub_printf("not find param\n"); + return -1; + } + + boot_params = (struct bootparamsinterface *)tmp_boot_params; + p = (char *)&(boot_params->signature); + if(grub_strncmp(p, "BPI", 3) == 0) + { + /* Check extlist headers */ + ext_list * listpointer = NULL; + listpointer = boot_params->extlist; + for( ;listpointer != NULL; listpointer = listpointer->next) + { + char *pl= (char *)&(listpointer->signature); + if(grub_strncmp(pl, "MEM", 3) == 0) + { + new_interface_mem = (mem_map *)listpointer; + } + } + + new_interface_flag = 1; + grub_dprintf("loongson", "get new parameter interface\n"); + }else{ + new_interface_flag = 0; + grub_dprintf("loongson", "get old parameter interface\n"); + + } + state.gpr[6] = (grub_uint64_t)tmp_boot_params; + grub_dprintf("loongson", "boot_params is 0x%llx\n", (_ull)state.gpr[6]); + + mmap_size = find_mmap_size (); + if (! mmap_size) + return grub_errno; + mmap_buf = grub_efi_allocate_any_pages (page_align (mmap_size) >> 12); + if (! mmap_buf) + return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); + err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, + &desc_size, NULL); + //grub_printf("%s-%d\n", __func__, __LINE__); + if (err) + return err; + + if(new_interface_flag) + { + if (!mmap_buf || !mmap_size || !desc_size) + return -1; + + tmp_index = new_interface_mem -> mapcount; + //grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index); + + /* + According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ + now we can fill platform specific memory structure. + */ + for(lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) + { + /* Recovery */ + if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ + (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ + (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ + (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ + (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ + (lsdesc->type != GRUB_EFI_PAL_CODE)) + { + + free_mem[free_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW; + free_mem[free_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + free_mem[free_index].memsize = lsdesc->num_pages * 4096; + free_index++; + /*ACPI*/ + }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ + acpi_table_mem[acpi_table_index].memtype = GRUB_EFI_LOONGSON_ACPI_TABLE; + acpi_table_mem[acpi_table_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + acpi_table_mem[acpi_table_index].memsize = lsdesc->num_pages * 4096; + acpi_table_index++; + + }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ + acpi_nvs_mem[acpi_nvs_index].memtype = GRUB_EFI_LOONGSON_ACPI_NVS; + acpi_nvs_mem[acpi_nvs_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + acpi_nvs_mem[acpi_nvs_index].memsize = lsdesc->num_pages * 4096; + acpi_nvs_index++; + + /* Reserve */ + }else{ + reserve_mem[reserve_index].memtype = GRUB_EFI_LOONGSON_MEMORY_RESERVED; + reserve_mem[reserve_index].memstart = (lsdesc->physical_start) & 0xffffffffffff; + reserve_mem[reserve_index].memsize = lsdesc->num_pages * 4096; + reserve_index++; + } + } + + /* Recovery sort */ + for(j = 0; j < free_index;) + { + tempMemsize = free_mem[j].memsize; + for(t = j + 1; t < free_index; t++) + { + if((free_mem[j].memstart + tempMemsize == free_mem[t].memstart) && (free_mem[j].memtype == free_mem[t].memtype)) + { + tempMemsize += free_mem[t].memsize; + }else{ + break; + } + } + if(free_mem[j].memstart >= 0x10000000) /*HIGH MEM*/ + new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH; + else + new_interface_mem->map[tmp_index].memtype = GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW; + new_interface_mem->map[tmp_index].memstart = free_mem[j].memstart; + new_interface_mem->map[tmp_index].memsize = tempMemsize; + grub_dprintf("loongson", "map[%d]:type %x, start 0x%llx, end 0x%llx\n", + tmp_index, + new_interface_mem->map[tmp_index].memtype, + (_ull)new_interface_mem->map[tmp_index].memstart, + (_ull)new_interface_mem->map[tmp_index].memstart+ new_interface_mem->map[tmp_index].memsize + ); + j = t; + tmp_index++; + } + + /*ACPI Sort*/ + tmp_index = grub_efi_loongson_memmap_sort(acpi_table_mem, acpi_table_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_TABLE); + tmp_index = grub_efi_loongson_memmap_sort(acpi_nvs_mem, acpi_nvs_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_ACPI_NVS); + /*Reserve Sort*/ + tmp_index = grub_efi_loongson_memmap_sort(reserve_mem, reserve_index, new_interface_mem, tmp_index, GRUB_EFI_LOONGSON_MEMORY_RESERVED); + + new_interface_mem->mapcount = tmp_index; + new_interface_mem->header.checksum = 0; + //grub_printf("%s-%d mapcount %d\n", __func__, __LINE__, tmp_index); + + checksum = grub_efi_loongson_grub_calculatechecksum8((grub_uint8_t *)new_interface_mem, new_interface_mem->header.length); + new_interface_mem->header.checksum = checksum; + } + } + + state.jumpreg = 1; + grub_relocator64_boot (relocator, state); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_unload (void) +{ + grub_relocator_unload (relocator); + grub_dl_unref (my_mod); + + loaded = 0; + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_linux_load32 (grub_elf_t elf, const char *filename) +{ + Elf32_Addr base; + grub_err_t err; + grub_uint8_t *playground; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr32.e_entry; + + linux_size = grub_elf32_size (elf, &base, 0); + if (linux_size == 0) + return grub_errno; + target_addr = base; + linux_size = ALIGN_UP (base + linux_size - base, 8); + + relocator = grub_relocator_new (); + if (!relocator) + return grub_errno; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + grub_vtop ((void *) target_addr), + linux_size); + if (err) + return err; + playground = get_virtual_current_address (ch); + } + + /* Now load the segments into the area we claimed. */ + return grub_elf32_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); +} + +static grub_err_t +grub_linux_load64 (grub_elf_t elf, const char *filename) +{ + Elf64_Addr base; + grub_err_t err; + grub_uint8_t *playground; + + /* Linux's entry point incorrectly contains a virtual address. */ + entry_addr = elf->ehdr.ehdr64.e_entry; + grub_dprintf("loongson", "entry address = 0x%llx\n", (_ull)entry_addr); + + linux_size = grub_elf64_size (elf, &base, 0); + grub_dprintf("loongson", "base = 0x%llx\n", (_ull)base); + + if (linux_size == 0) + return grub_errno; + target_addr = base; + linux_size = ALIGN_UP (base + linux_size - base, 8); + + relocator = grub_relocator_new (); + if (!relocator) + return grub_errno; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_addr (relocator, &ch, + grub_vtop ((void *) target_addr), + linux_size); + if (err) + return err; + playground = get_virtual_current_address (ch); + //playground = 0xffffffff81ee0000; //½«ÄÚºËÖ±½Óloadµ½elfÍ·Ö¸¶¨Äڴ棬¶ø·Çgrub·ÖÅäµÄ¿Õ¼ä + //playground = 0xffffffff80200000; + } + + grub_printf("playground:0x%llx\n", (_ull)playground); + + /* Now load the segments into the area we claimed. */ + return grub_elf64_load (elf, filename, playground - base, GRUB_ELF_LOAD_FLAGS_NONE, 0, 0); +} + +static grub_err_t +grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_elf_t elf = 0; + int size; + int i; + grub_uint32_t *linux_argv; + char *linux_args; + grub_err_t err; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + if (ventoy_linux_argc) + { + ventoy_bootopt_hook(argc, argv); + argc = ventoy_linux_argc; + argv = ventoy_linux_args; + } + + elf = grub_elf_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL); + if (! elf) + return grub_errno; + + if (elf->ehdr.ehdr32.e_type != ET_EXEC) + { + grub_elf_close (elf); + return grub_error (GRUB_ERR_UNKNOWN_OS, + N_("this ELF file is not of the right type")); + } + + /* Release the previously used memory. */ + grub_loader_unset (); + loaded = 0; + + /* For arguments. */ + linux_argc = argc; + /* Main arguments. */ + size = (linux_argc) * sizeof (grub_uint32_t); + /* Initrd address and size. */ + size += 2 * sizeof (grub_uint32_t); + /* NULL terminator. */ + size += sizeof (grub_uint32_t); + /* First argument is always "a0". */ + size += ALIGN_UP (sizeof ("a0"), 4); + /* Normal arguments. */ + for (i = 1; i < argc; i++) + size += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + + /* rd arguments. */ + size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); + size += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); + + size = ALIGN_UP (size, 8); + + if (grub_elf_is_elf32 (elf)) + err = grub_linux_load32 (elf, argv[0]); + else + if (grub_elf_is_elf64 (elf)) + err = grub_linux_load64 (elf, argv[0]); + else + err = grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); + + grub_elf_close (elf); + + if (err) + return err; + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + 0, (0xffffffff - size) + 1, + size, 8, + GRUB_RELOCATOR_PREFERENCE_HIGH, 0); + if (err) + return err; + linux_args_addr = get_virtual_current_address (ch); + } + + linux_argv = (grub_uint32_t *) linux_args_addr; + linux_args = (char *) (linux_argv + (linux_argc + 1 + 2)); + + grub_memcpy (linux_args, "a0", sizeof ("a0")); + *linux_argv = (grub_uint32_t) (grub_addr_t) linux_args; + linux_argv++; + linux_args += ALIGN_UP (sizeof ("a0"), 4); + + for (i = 1; i < argc; i++) + { + grub_memcpy (linux_args, argv[i], grub_strlen (argv[i]) + 1); + *linux_argv = (grub_uint32_t) (grub_addr_t) linux_args; + linux_argv++; + linux_args += ALIGN_UP (grub_strlen (argv[i]) + 1, 4); + } + + /* Reserve space for rd arguments. */ + rd_addr_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; + linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); + *linux_argv = 0; + linux_argv++; + + rd_size_arg_off = (grub_uint8_t *) linux_args - linux_args_addr; + linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); + *linux_argv = 0; + linux_argv++; + + *linux_argv = 0; + + //wake up other cores + { + __asm__( + "dli $8, 0x900000003ff01000\n\t" + "dli $11, 0 \n\t" + "dsll $11, 8 \n\t" + "or $8, $8,$11 \n\t" + "li $9, 0x5a5a \n\t" + "sw $9, 32($8) \n\t" + "nop \n\t" + : + : + ); + } + grub_loader_set (grub_linux_boot, grub_linux_unload, 0); + initrd_loaded = 0; + loaded = 1; + grub_dl_ref (my_mod); + + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + grub_size_t size = 0; + void *initrd_dest; + grub_err_t err; + struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); + + if (!loaded) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first")); + + if (initrd_loaded) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "only one initrd command can be issued."); + + if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + + size = grub_get_initrd_size (&initrd_ctx); + + { + grub_relocator_chunk_t ch; + err = grub_relocator_alloc_chunk_align (relocator, &ch, + 0, (0xffffffff - size) + 1, + size, 0x10000, + GRUB_RELOCATOR_PREFERENCE_HIGH, 0); + + if (err) + goto fail; + initrd_dest = get_virtual_current_address (ch); + } + + if (grub_initrd_load (&initrd_ctx, argv, initrd_dest)) + goto fail; + + grub_snprintf ((char *) linux_args_addr + rd_addr_arg_off, + sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), "rd_start=0x%lx", + (grub_uint64_t) initrd_dest); + ((grub_uint32_t *) linux_args_addr)[linux_argc] + = (grub_uint32_t) ((grub_addr_t) linux_args_addr + rd_addr_arg_off); + linux_argc++; + + grub_snprintf ((char *) linux_args_addr + rd_size_arg_off, + sizeof ("rd_size=0xXXXXXXXXXXXXXXXXX"), "rd_size=0x%lx", + (grub_uint64_t) size); + ((grub_uint32_t *) linux_args_addr)[linux_argc] + = (grub_uint32_t) ((grub_addr_t) linux_args_addr + rd_size_arg_off); + linux_argc++; + + initrd_loaded = 1; + + fail: + grub_initrd_close (&initrd_ctx); + + return grub_errno; +} + +static grub_err_t +ventoy_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + int i; + const char *file; + char buf[64]; + + if (ventoy_debug) grub_printf("ventoy_cmd_initrd %d\n", ventoy_linux_argc); + + if (ventoy_linux_argc == 0) + { + return grub_cmd_initrd(cmd, argc, argv); + } + + grub_snprintf(buf, sizeof(buf), "mem:%s:size:%s", grub_env_get("ventoy_cpio_addr"), grub_env_get("ventoy_cpio_size")); + + if (ventoy_debug) grub_printf("membuf=%s\n", buf); + + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(buf); + + file = grub_env_get("vtoy_img_part_file"); + if (file) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(file); + } + + for (i = 0; i < argc; i++) + { + ventoy_extra_initrd_list[ventoy_extra_initrd_num++] = grub_strdup(argv[i]); + } + + ventoy_initrd_called = 1; + + if (ventoy_debug) + { + grub_printf("========== initrd list ==========\n"); + for (i = 0; i < ventoy_extra_initrd_num; i++) + { + grub_printf("%s\n", ventoy_extra_initrd_list[i]); + } + grub_printf("=================================\n"); + } + + return grub_cmd_initrd(cmd, ventoy_extra_initrd_num, ventoy_extra_initrd_list); +} + +static grub_command_t cmd_linux, cmd_initrd; +static grub_command_t cmd_set_bootopt, cmd_unset_bootopt, cmd_extra_initrd_append, cmd_extra_initrd_reset; + +GRUB_MOD_INIT(linux) +{ + cmd_linux = grub_register_command ("linux", grub_cmd_linux, + 0, N_("Load Linux.")); + cmd_initrd = grub_register_command ("initrd", ventoy_cmd_initrd, + 0, N_("Load initrd.")); + + cmd_set_bootopt = grub_register_command ("vt_set_boot_opt", grub_cmd_set_boot_opt, 0, N_("set ext boot opt")); + cmd_unset_bootopt = grub_register_command ("vt_unset_boot_opt", grub_cmd_unset_boot_opt, 0, N_("unset ext boot opt")); + + cmd_extra_initrd_append = grub_register_command ("vt_img_extra_initrd_append", grub_cmd_extra_initrd_append, 0, N_("")); + cmd_extra_initrd_reset = grub_register_command ("vt_img_extra_initrd_reset", grub_cmd_extra_initrd_reset, 0, N_("")); + + ventoy_linux_args = grub_zalloc(sizeof(char *) * LINUX_MAX_ARGC); + + my_mod = mod; +} + +GRUB_MOD_FINI(linux) +{ + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c index 87edd254..9ed3c8d2 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/context.c @@ -99,7 +99,7 @@ grub_env_new_context (int export_all) grub_err_t grub_env_context_open (void) { - return grub_env_new_context (1); + return grub_env_new_context (grub_env_get("ventoy_new_context") ? 0 : 1); } int grub_extractor_level = 0; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/main.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/main.c new file mode 100644 index 00000000..bc29d3be --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/main.c @@ -0,0 +1,575 @@ +/* main.c - the normal mode main routine */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define GRUB_DEFAULT_HISTORY_SIZE 50 + +static int nested_level = 0; +int grub_normal_exit_level = 0; + +void +grub_normal_free_menu (grub_menu_t menu) +{ + grub_menu_entry_t entry = menu->entry_list; + + while (entry) + { + grub_menu_entry_t next_entry = entry->next; + grub_size_t i; + + if (entry->classes) + { + struct grub_menu_entry_class *class; + for (class = entry->classes; class; class = class->next) + grub_free (class->name); + grub_free (entry->classes); + } + + if (entry->args) + { + for (i = 0; entry->args[i]; i++) + grub_free (entry->args[i]); + grub_free (entry->args); + } + + if (entry->bls) + { + entry->bls->visible = 0; + } + + grub_free ((void *) entry->id); + grub_free ((void *) entry->users); + grub_free ((void *) entry->title); + grub_free ((void *) entry->sourcecode); + grub_free (entry); + entry = next_entry; + } + + grub_free (menu); + grub_env_unset_menu (); +} + +/* Helper for read_config_file. */ +static grub_err_t +read_config_file_getline (char **line, int cont __attribute__ ((unused)), + void *data) +{ + grub_file_t file = data; + + while (1) + { + char *buf; + + *line = buf = grub_file_getline (file); + if (! buf) + return grub_errno; + + if (buf[0] == '#') + grub_free (*line); + else + break; + } + + return GRUB_ERR_NONE; +} + +static grub_menu_t +read_config_file (const char *config) +{ + grub_file_t rawfile, file; + char *old_file = 0, *old_dir = 0; + char *config_dir, *ptr = 0; + const char *ctmp; + + grub_menu_t newmenu; + + newmenu = grub_env_get_menu (); + if (! newmenu) + { + newmenu = grub_zalloc (sizeof (*newmenu)); + if (! newmenu) + return 0; + + grub_env_set_menu (newmenu); + } + + /* Try to open the config file. */ + rawfile = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); + if (! rawfile) + return 0; + + file = grub_bufio_open (rawfile, 0); + if (! file) + { + grub_file_close (rawfile); + return 0; + } + + ctmp = grub_env_get ("config_file"); + if (ctmp) + old_file = grub_strdup (ctmp); + ctmp = grub_env_get ("config_directory"); + if (ctmp) + old_dir = grub_strdup (ctmp); + if (*config == '(') + { + grub_env_set ("config_file", config); + config_dir = grub_strdup (config); + } + else + { + /* $root is guranteed to be defined, otherwise open above would fail */ + config_dir = grub_xasprintf ("(%s)%s", grub_env_get ("root"), config); + if (config_dir) + grub_env_set ("config_file", config_dir); + } + if (config_dir) + { + ptr = grub_strrchr (config_dir, '/'); + if (ptr) + *ptr = 0; + grub_env_set ("config_directory", config_dir); + grub_free (config_dir); + } + + grub_env_export ("config_file"); + grub_env_export ("config_directory"); + + while (1) + { + char *line; + + /* Print an error, if any. */ + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + if ((read_config_file_getline (&line, 0, file)) || (! line)) + break; + + grub_normal_parse_line (line, read_config_file_getline, file); + grub_free (line); + } + + if (old_file) + grub_env_set ("config_file", old_file); + else + grub_env_unset ("config_file"); + if (old_dir) + grub_env_set ("config_directory", old_dir); + else + grub_env_unset ("config_directory"); + grub_free (old_file); + grub_free (old_dir); + + grub_file_close (file); + + return newmenu; +} + +/* Initialize the screen. */ +void +grub_normal_init_page (struct grub_term_output *term, + int y) +{ + grub_ssize_t msg_len; + int posx; + char *msg_formatted; + grub_uint32_t *unicode_msg; + grub_uint32_t *last_position; + + grub_term_cls (term); + + msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION); + if (!msg_formatted) + return; + + msg_len = grub_utf8_to_ucs4_alloc (msg_formatted, + &unicode_msg, &last_position); + grub_free (msg_formatted); + + if (msg_len < 0) + { + return; + } + + posx = grub_getstringwidth (unicode_msg, last_position, term); + posx = ((int) grub_term_width (term) - posx) / 2; + if (posx < 0) + posx = 0; + grub_term_gotoxy (term, (struct grub_term_coordinate) { posx, y }); + + grub_print_ucs4 (unicode_msg, last_position, 0, 0, term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + grub_free (unicode_msg); +} + +static void +read_lists (const char *val) +{ + if (! grub_no_modules) + { + read_command_list (val); + read_fs_list (val); + read_crypto_list (val); + read_terminal_list (val); + } + grub_gettext_reread_prefix (val); +} + +static char * +read_lists_hook (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + read_lists (val); + return val ? grub_strdup (val) : NULL; +} + +/* Read the config file CONFIG and execute the menu interface or + the command line interface if BATCH is false. */ +void +grub_normal_execute (const char *config, int nested, int batch) +{ + grub_menu_t menu = 0; + const char *prefix; + + if (! nested) + { + prefix = grub_env_get ("prefix"); + read_lists (prefix); + grub_register_variable_hook ("prefix", NULL, read_lists_hook); + } + + grub_boot_time ("Executing config file"); + + if (config) + { + menu = read_config_file (config); + + /* Ignore any error. */ + grub_errno = GRUB_ERR_NONE; + } + + grub_boot_time ("Executed config file"); + + if (! batch) + { + if (menu && menu->size) + { + + grub_boot_time ("Entering menu"); + grub_show_menu (menu, nested, 0); + if (nested) + grub_normal_free_menu (menu); + } + } +} + +/* This starts the normal mode. */ +void +grub_enter_normal_mode (const char *config) +{ + grub_boot_time ("Entering normal mode"); + nested_level++; + grub_normal_execute (config, 0, 0); + grub_boot_time ("Entering shell"); + grub_cmdline_run (0, 1); + nested_level--; + if (grub_normal_exit_level) + grub_normal_exit_level--; + grub_boot_time ("Exiting normal mode"); +} + +/* Enter normal mode from rescue mode. */ +static grub_err_t +grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), + int argc, char *argv[]) +{ + if (argc == 0) + { + /* Guess the config filename. It is necessary to make CONFIG static, + so that it won't get broken by longjmp. */ + char *config; + const char *prefix; + + prefix = grub_env_get ("prefix"); + if (prefix) + { + config = grub_xasprintf ("%s/grub.cfg", prefix); + if (! config) + goto quit; + + grub_enter_normal_mode (config); + grub_free (config); + } + else + grub_enter_normal_mode (0); + } + else + grub_enter_normal_mode (argv[0]); + +quit: + return 0; +} + +/* Exit from normal mode to rescue mode. */ +static grub_err_t +grub_cmd_normal_exit (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + if (nested_level <= grub_normal_exit_level) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "not in normal environment"); + grub_normal_exit_level++; + return GRUB_ERR_NONE; +} + +static grub_err_t +grub_normal_reader_init (int nested) +{ + struct grub_term_output *term; + const char *msg_esc = _("ESC at any time exits."); + char *msg_formatted; + + msg_formatted = grub_xasprintf (_("Minimal BASH-like line editing is supported. For " + "the first word, TAB lists possible command completions. Anywhere " + "else TAB lists possible device or file completions. %s"), + nested ? msg_esc : ""); + if (!msg_formatted) + return grub_errno; + + FOR_ACTIVE_TERM_OUTPUTS(term) + { + grub_normal_init_page (term, 1); + grub_term_setcursor (term, 1); + + if (grub_term_width (term) > 3 + STANDARD_MARGIN + 20) + grub_print_message_indented (msg_formatted, 3, STANDARD_MARGIN, term); + else + grub_print_message_indented (msg_formatted, 0, 0, term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + grub_putcode ('\n', term); + } + grub_free (msg_formatted); + + return 0; +} + +static grub_err_t +grub_normal_read_line_real (char **line, int cont, int nested) +{ + const char *prompt; + + if (cont) + /* TRANSLATORS: it's command line prompt. */ + prompt = _(">"); + else + /* TRANSLATORS: it's command line prompt. */ + prompt = _("grub>"); + + if (!prompt) + return grub_errno; + + while (1) + { + *line = grub_cmdline_get (prompt); + if (*line) + return 0; + + if (cont || nested) + { + grub_free (*line); + *line = 0; + return grub_errno; + } + } + +} + +static grub_err_t +grub_normal_read_line (char **line, int cont, + void *data __attribute__ ((unused))) +{ + return grub_normal_read_line_real (line, cont, 0); +} + +void +grub_cmdline_run (int nested, int force_auth) +{ + grub_err_t err = GRUB_ERR_NONE; + + do + { + err = grub_auth_check_authentication (NULL); + } + while (err && force_auth); + + if (err) + { + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + return; + } + + grub_normal_reader_init (nested); + + while (1) + { + char *line = NULL; + + if (grub_normal_exit_level) + break; + + /* Print an error, if any. */ + grub_print_error (); + grub_errno = GRUB_ERR_NONE; + + grub_normal_read_line_real (&line, 0, nested); + if (! line) + break; + + grub_normal_parse_line (line, grub_normal_read_line, NULL); + grub_free (line); + } +} + +static char * +grub_env_write_pager (struct grub_env_var *var __attribute__ ((unused)), + const char *val) +{ + grub_set_more ((*val == '1')); + return grub_strdup (val); +} + +/* clear */ +static grub_err_t +grub_mini_cmd_clear (struct grub_command *cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), + char *argv[] __attribute__ ((unused))) +{ + grub_cls (); + return 0; +} + +static grub_command_t cmd_clear; + +static void (*grub_xputs_saved) (const char *str); +static const char *features[] = { + "feature_chainloader_bpb", "feature_ntldr", "feature_platform_search_hint", + "feature_default_font_path", "feature_all_video_module", + "feature_menuentry_id", "feature_menuentry_options", "feature_200_final", + "feature_nativedisk_cmd", "feature_timeout_style" +}; + +GRUB_MOD_INIT(normal) +{ + unsigned i; + + grub_boot_time ("Preparing normal module"); + + /* Previously many modules depended on gzio. Be nice to user and load it. */ + grub_dl_load ("gzio"); + grub_errno = 0; + + grub_normal_auth_init (); + grub_context_init (); + grub_script_init (); + grub_menu_init (); + + grub_xputs_saved = grub_xputs; + grub_xputs = grub_xputs_normal; + + /* Normal mode shouldn't be unloaded. */ + if (mod) + grub_dl_ref (mod); + + cmd_clear = + grub_register_command ("clear", grub_mini_cmd_clear, + 0, N_("Clear the screen.")); + + grub_set_history (GRUB_DEFAULT_HISTORY_SIZE); + + grub_register_variable_hook ("pager", 0, grub_env_write_pager); + grub_env_export ("pager"); + + /* Register a command "normal" for the rescue mode. */ + grub_register_command ("normal", grub_cmd_normal, + 0, N_("Enter normal mode.")); + grub_register_command ("normal_exit", grub_cmd_normal_exit, + 0, N_("Exit from normal mode.")); + + /* Reload terminal colors when these variables are written to. */ + grub_register_variable_hook ("color_normal", NULL, grub_env_write_color_normal); + grub_register_variable_hook ("color_highlight", NULL, grub_env_write_color_highlight); + + /* Preserve hooks after context changes. */ + grub_env_export ("color_normal"); + grub_env_export ("color_highlight"); + + /* Set default color names. */ + grub_env_set ("color_normal", "light-gray/black"); + grub_env_set ("color_highlight", "black/light-gray"); + + for (i = 0; i < ARRAY_SIZE (features); i++) + { + grub_env_set (features[i], "y"); + grub_env_export (features[i]); + } + grub_env_set ("grub_cpu", GRUB_TARGET_CPU); + grub_env_export ("grub_cpu"); + grub_env_set ("grub_platform", GRUB_PLATFORM); + grub_env_export ("grub_platform"); + + grub_boot_time ("Normal module prepared"); +} + +GRUB_MOD_FINI(normal) +{ + grub_context_fini (); + grub_script_fini (); + grub_menu_fini (); + grub_normal_auth_fini (); + + grub_xputs = grub_xputs_saved; + + grub_set_history (0); + grub_register_variable_hook ("pager", 0, 0); + grub_fs_autoload_hook = 0; + grub_unregister_command (cmd_clear); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c index e1033d18..14e3dac5 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu.c @@ -37,11 +37,14 @@ int g_ventoy_menu_refresh = 0; int g_ventoy_memdisk_mode = 0; int g_ventoy_iso_raw = 0; +int g_ventoy_grub2_mode = 0; +int g_ventoy_wimboot_mode = 0; int g_ventoy_iso_uefi_drv = 0; int g_ventoy_last_entry = -1; int g_ventoy_suppress_esc = 0; int g_ventoy_menu_esc = 0; int g_ventoy_fn_mutex = 0; +int g_ventoy_terminal_output = 0; /* Time to delay after displaying an error message about a default/fallback entry failing to boot. */ @@ -803,6 +806,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) goto refresh; case GRUB_TERM_KEY_F2: + case '2': if (0 == g_ventoy_fn_mutex) { cmdstr = grub_env_get("VTOY_F2_CMD"); if (cmdstr) @@ -816,6 +820,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } break; case GRUB_TERM_KEY_F3: + case '3': if (0 == g_ventoy_fn_mutex) { cmdstr = grub_env_get("VTOY_F3_CMD"); if (cmdstr) @@ -827,6 +832,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } break; case GRUB_TERM_KEY_F4: + case '4': if (0 == g_ventoy_fn_mutex) { cmdstr = grub_env_get("VTOY_F4_CMD"); if (cmdstr) @@ -840,6 +846,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } break; case GRUB_TERM_KEY_F5: + case '5': if (0 == g_ventoy_fn_mutex) { cmdstr = grub_env_get("VTOY_F5_CMD"); if (cmdstr) @@ -853,24 +860,34 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) } break; case GRUB_TERM_KEY_F6: - cmdstr = grub_env_get("VTOY_F6_CMD"); - if (cmdstr) - { - menu_fini (); - grub_script_execute_sourcecode(cmdstr); - goto refresh; + case '6': + if (0 == g_ventoy_fn_mutex) { + cmdstr = grub_env_get("VTOY_F6_CMD"); + if (cmdstr) + { + menu_fini (); + g_ventoy_fn_mutex = 1; + grub_script_execute_sourcecode(cmdstr); + g_ventoy_fn_mutex = 0; + goto refresh; + } } break; case GRUB_TERM_KEY_F7: - cmdstr = grub_env_get("VTOY_F7_CMD"); - if (cmdstr) + menu_fini (); + if (g_ventoy_terminal_output == 0) { - menu_fini (); - grub_script_execute_sourcecode(cmdstr); - goto refresh; + grub_script_execute_sourcecode("terminal_output console"); + g_ventoy_terminal_output = 1; } - break; + else + { + grub_script_execute_sourcecode("terminal_output gfxterm"); + g_ventoy_terminal_output = 0; + } + goto refresh; case GRUB_TERM_KEY_F1: + case '1': menu_fini (); g_ventoy_memdisk_mode = 1 - g_ventoy_memdisk_mode; g_ventoy_menu_refresh = 1; @@ -882,6 +899,18 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) g_ventoy_menu_refresh = 1; goto refresh; + case (GRUB_TERM_CTRL | 'r'): + menu_fini (); + g_ventoy_grub2_mode = 1 - g_ventoy_grub2_mode; + g_ventoy_menu_refresh = 1; + goto refresh; + + case (GRUB_TERM_CTRL | 'w'): + menu_fini (); + g_ventoy_wimboot_mode = 1 - g_ventoy_wimboot_mode; + g_ventoy_menu_refresh = 1; + goto refresh; + case (GRUB_TERM_CTRL | 'u'): menu_fini (); g_ventoy_iso_uefi_drv = 1 - g_ventoy_iso_uefi_drv; @@ -958,19 +987,28 @@ static struct grub_menu_execute_callback execution_callback = static grub_err_t show_menu (grub_menu_t menu, int nested, int autobooted) { + const char *def; + def = grub_env_get("VTOY_DEFAULT_IMAGE"); + while (1) { int boot_entry; grub_menu_entry_t e; int auto_boot; - + boot_entry = run_menu (menu, nested, &auto_boot); if (boot_entry < 0) break; - g_ventoy_last_entry = boot_entry; - if (g_ventoy_menu_esc) - break; + if (auto_boot && def && grub_strcmp(def, "VTOY_EXIT") == 0) { + grub_exit(); + } + + if (autobooted == 0 && auto_boot == 0) { + g_ventoy_last_entry = boot_entry; + if (g_ventoy_menu_esc) + break; + } e = grub_menu_get_entry (menu, boot_entry); if (! e) @@ -988,6 +1026,9 @@ show_menu (grub_menu_t menu, int nested, int autobooted) grub_menu_execute_entry (e, 0); if (autobooted) break; + + if (2 == e->argc && e->args && e->args[1] && grub_strncmp(e->args[1], "VTOY_RUN_RET", 12) == 0) + break; } return GRUB_ERR_NONE; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c index cb1d3d61..0f3ea8a6 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/normal/menu_text.c @@ -180,22 +180,31 @@ command-line or ESC to discard edits and return to the GRUB menu."), if (nested) { + #if 0 ret += grub_print_message_indented_real (_("Press enter to boot the selected OS, " "`e' to edit the commands before booting " "or `c' for a command-line. ESC to return previous menu."), STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + #endif } else { + char szLine[128]; + const char *checkret = grub_env_get("VTOY_CHKDEV_RESULT_STRING"); + if (checkret == NULL || checkret[0] != '0') { + grub_snprintf(szLine, sizeof(szLine), "%s [Unofficial Ventoy]", grub_env_get("VTOY_TEXT_MENU_VER")); + } else { + grub_snprintf(szLine, sizeof(szLine), "%s", grub_env_get("VTOY_TEXT_MENU_VER")); + } + ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); - ret += grub_print_message_indented_real(grub_env_get("VTOY_TEXT_MENU_VER"), - STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + ret += grub_print_message_indented_real(szLine, STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ret += grub_print_message_indented_real("\n", STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ret += grub_print_message_indented_real(grub_env_get("VTOY_HOTKEY_TIP"), - STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); + 3, 6, term, dry_run); } } return ret; diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/keyboard_layout.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/keyboard_layout.c new file mode 100644 index 00000000..8d139b5f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/keyboard_layout.c @@ -0,0 +1,795 @@ + +#define ventoy_keyboard_set_layout(name) if (grub_strcmp(layout, #name) == 0) return ventoy_keyboard_layout_##name() + +static void ventoy_keyboard_layout_QWERTY_USA(void) { + grub_keymap_reset(); + grub_keymap_disable(); +} +static void ventoy_keyboard_layout_AZERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("caret", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("numbersign", "braceright"); +grub_keymap_add_by_string("backslash", "question"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "underscore"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("caret", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DVORAK_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("[", "minus"); +grub_keymap_add_by_string("braceleft", "underscore"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("z", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("backslash", "backslash"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("period", "e"); +grub_keymap_add_by_string("greater", "E"); +grub_keymap_add_by_string("p", "r"); +grub_keymap_add_by_string("P", "R"); +grub_keymap_add_by_string("y", "t"); +grub_keymap_add_by_string("Y", "T"); +grub_keymap_add_by_string("f", "y"); +grub_keymap_add_by_string("F", "Y"); +grub_keymap_add_by_string("g", "u"); +grub_keymap_add_by_string("G", "U"); +grub_keymap_add_by_string("c", "c"); +grub_keymap_add_by_string("C", "I"); +grub_keymap_add_by_string("r", "o"); +grub_keymap_add_by_string("R", "O"); +grub_keymap_add_by_string("l", "p"); +grub_keymap_add_by_string("L", "P"); +grub_keymap_add_by_string("bracketright", "equal"); +grub_keymap_add_by_string("braceright", "plus"); +grub_keymap_add_by_string("a", "a"); +grub_keymap_add_by_string("A", "A"); +grub_keymap_add_by_string("o", "s"); +grub_keymap_add_by_string("O", "S"); +grub_keymap_add_by_string("e", "d"); +grub_keymap_add_by_string("E", "D"); +grub_keymap_add_by_string("u", "f"); +grub_keymap_add_by_string("U", "F"); +grub_keymap_add_by_string("i", "g"); +grub_keymap_add_by_string("I", "G"); +grub_keymap_add_by_string("d", "h"); +grub_keymap_add_by_string("D", "H"); +grub_keymap_add_by_string("h", "j"); +grub_keymap_add_by_string("H", "J"); +grub_keymap_add_by_string("t", "k"); +grub_keymap_add_by_string("T", "K"); +grub_keymap_add_by_string("n", "l"); +grub_keymap_add_by_string("N", "L"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("minus", "quote"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("q", "x"); +grub_keymap_add_by_string("Q", "X"); +grub_keymap_add_by_string("j", "c"); +grub_keymap_add_by_string("J", "C"); +grub_keymap_add_by_string("k", "v"); +grub_keymap_add_by_string("K", "V"); +grub_keymap_add_by_string("x", "b"); +grub_keymap_add_by_string("X", "B"); +grub_keymap_add_by_string("b", "n"); +grub_keymap_add_by_string("B", "N"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("V", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("Z", "question"); +grub_keymap_add_by_string("slash", "bracketleft"); +grub_keymap_add_by_string("question", "braceleft"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("plus", "braceright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_FRENCH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("backslash", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("numbersign", "underscore"); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("caret", "bracketleft"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("bracketleft", "quote"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("bar", "question"); +grub_keymap_add_by_string("tilde", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("braceleft", "A4"); +grub_keymap_add_by_string("bracketleft", "A5"); +grub_keymap_add_by_string("bar", "A6"); +grub_keymap_add_by_string("quote", "A7"); +grub_keymap_add_by_string("backslash", "A8"); +grub_keymap_add_by_string("caret", "A9"); +grub_keymap_add_by_string("at", "A0"); +grub_keymap_add_by_string("bracketright", "Aminus"); +grub_keymap_add_by_string("braceright", "Aequal"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_GERMAN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("bar", "bracketleft"); +grub_keymap_add_by_string("at", "braceleft"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("greater", "semicolon"); +grub_keymap_add_by_string("less", "colon"); +grub_keymap_add_by_string("bar", "quote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_ITALIANO(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "numbersign"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "plus"); +grub_keymap_add_by_string("bracketleft", "bracketleft"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("braceleft", "colon"); +grub_keymap_add_by_string("numbersign", "quote"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("at", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Aquote"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_JAPAN_106(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "bracketleft"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("quote", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("underscore", "parenright"); +grub_keymap_add_by_string("equal", "underscore"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("colon", "quote"); +grub_keymap_add_by_string("asterisk", "doublequote"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("tilde", "plus"); +grub_keymap_add_by_string("caret", "equal"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_LATIN_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("bar", "backquote"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("bracketleft", "doublequote"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_add_by_string("doublequote", "braceleft"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("greater", "plus"); +grub_keymap_add_by_string("less", "equal"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_PORTU_BRAZIL(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "backquote"); +grub_keymap_add_by_string("quote", "bracketleft"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("tilde", "quote"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("semicolon", "slash"); +grub_keymap_add_by_string("bar", "colon"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("caret", "doublequote"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("backslash", "semicolon"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("slash", "Aq"); +grub_keymap_add_by_string("question", "Aw"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTY_UK(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "bar"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("backslash", "numbersign"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("backslash", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "percent"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("backquote", "equal"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("percent", "caret"); +grub_keymap_add_by_string("less", "numbersign"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_HUN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("0", "backquote"); +grub_keymap_add_by_string("quote", "exclam"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("plus", "numbersign"); +grub_keymap_add_by_string("exclam", "dollar"); +grub_keymap_add_by_string("slash", "caret"); +grub_keymap_add_by_string("equal", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("greater", "Az"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Am"); +grub_keymap_add_by_string("dollar", "colon"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("asterisk", "0"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("semicolon", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_add_by_string("backquote", "A9"); +grub_keymap_add_by_string("doublequote", "A0"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_SLOV_CROAT(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("plus", "equal"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("asterisk", "plus"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SPANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("caret", "braceleft"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("bar", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("tilde", "A4"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("braceleft", "Aquote"); +grub_keymap_add_by_string("braceright", "Abackslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SWEDISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_TURKISH_Q(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "backquote"); +grub_keymap_add_by_string("asterisk", "minus"); +grub_keymap_add_by_string("minus", "equal"); +grub_keymap_add_by_string("comma", "backslash"); +grub_keymap_add_by_string("period", "slash"); +grub_keymap_add_by_string("quote", "at"); +grub_keymap_add_by_string("caret", "numbersign"); +grub_keymap_add_by_string("plus", "dollar"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("underscore", "plus"); +grub_keymap_add_by_string("semicolon", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("less", "Abackquote"); +grub_keymap_add_by_string("greater", "A1"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("bar", "Aequal"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("doublequote", "Abracketleft"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_VIETNAMESE(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("quote", "Aquote"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Aless"); +grub_keymap_add_by_string("greater", "Agreater"); +grub_keymap_add_by_string("comma", "Acomma"); +grub_keymap_add_by_string("period", "Aperiod"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_add_by_string("doublequote", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_enable(); +} +void ventoy_set_keyboard_layout(const char *layout); +void ventoy_set_keyboard_layout(const char *layout) { +ventoy_keyboard_set_layout(QWERTY_USA); +ventoy_keyboard_set_layout(AZERTY); +ventoy_keyboard_set_layout(CZECH_QWERTY); +ventoy_keyboard_set_layout(CZECH_QWERTZ); +ventoy_keyboard_set_layout(DANISH); +ventoy_keyboard_set_layout(DVORAK_USA); +ventoy_keyboard_set_layout(FRENCH); +ventoy_keyboard_set_layout(GERMAN); +ventoy_keyboard_set_layout(ITALIANO); +ventoy_keyboard_set_layout(JAPAN_106); +ventoy_keyboard_set_layout(LATIN_USA); +ventoy_keyboard_set_layout(PORTU_BRAZIL); +ventoy_keyboard_set_layout(QWERTY_UK); +ventoy_keyboard_set_layout(QWERTZ); +ventoy_keyboard_set_layout(QWERTZ_HUN); +ventoy_keyboard_set_layout(QWERTZ_SLOV_CROAT); +ventoy_keyboard_set_layout(SPANISH); +ventoy_keyboard_set_layout(SWEDISH); +ventoy_keyboard_set_layout(TURKISH_Q); +ventoy_keyboard_set_layout(VIETNAMESE); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c new file mode 100644 index 00000000..3b2e01c9 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/serial.c @@ -0,0 +1,463 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#if !defined (GRUB_MACHINE_EMU) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) +#include +#endif +#include +#include +#include +#ifdef GRUB_MACHINE_MIPS_LOONGSON +#include +#endif +#ifdef GRUB_MACHINE_IEEE1275 +#include +#endif + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define FOR_SERIAL_PORTS(var) FOR_LIST_ELEMENTS((var), (grub_serial_ports)) + +enum + { + OPTION_UNIT, + OPTION_PORT, + OPTION_SPEED, + OPTION_WORD, + OPTION_PARITY, + OPTION_STOP, + OPTION_BASE_CLOCK, + OPTION_RTSCTS + }; + +/* Argument options. */ +static const struct grub_arg_option options[] = +{ + {"unit", 'u', 0, N_("Set the serial unit."), 0, ARG_TYPE_INT}, + {"port", 'p', 0, N_("Set the serial port address."), 0, ARG_TYPE_STRING}, + {"speed", 's', 0, N_("Set the serial port speed."), 0, ARG_TYPE_INT}, + {"word", 'w', 0, N_("Set the serial port word length."), 0, ARG_TYPE_INT}, + {"parity", 'r', 0, N_("Set the serial port parity."), 0, ARG_TYPE_STRING}, + {"stop", 't', 0, N_("Set the serial port stop bits."), 0, ARG_TYPE_INT}, + {"base-clock", 'b', 0, N_("Set the base frequency."), 0, ARG_TYPE_STRING}, + {"rtscts", 'f', 0, N_("Enable/disable RTS/CTS."), "on|off", ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} +}; + +static struct grub_serial_port *grub_serial_ports; + +struct grub_serial_output_state +{ + struct grub_terminfo_output_state tinfo; + struct grub_serial_port *port; +}; + +struct grub_serial_input_state +{ + struct grub_terminfo_input_state tinfo; + struct grub_serial_port *port; +}; + +static void +serial_put (grub_term_output_t term, const int c) +{ + struct grub_serial_output_state *data = term->data; + data->port->driver->put (data->port, c); +} + +static int +serial_fetch (grub_term_input_t term) +{ + struct grub_serial_input_state *data = term->data; + return data->port->driver->fetch (data->port); +} + +static const struct grub_serial_input_state grub_serial_terminfo_input_template = + { + .tinfo = + { + .readkey = serial_fetch + } + }; + +static const struct grub_serial_output_state grub_serial_terminfo_output_template = + { + .tinfo = + { + .put = serial_put, + .size = { 80, 24 } + } + }; + +static struct grub_serial_input_state grub_serial_terminfo_input; + +static struct grub_serial_output_state grub_serial_terminfo_output; + +static int registered = 0; + +static struct grub_term_input grub_serial_term_input = +{ + .name = "serial", + .init = grub_terminfo_input_init, + .getkey = grub_terminfo_getkey, + .data = &grub_serial_terminfo_input +}; + +static struct grub_term_output grub_serial_term_output = +{ + .name = "serial", + .init = grub_terminfo_output_init, + .putchar = grub_terminfo_putchar, + .getwh = grub_terminfo_getwh, + .getxy = grub_terminfo_getxy, + .gotoxy = grub_terminfo_gotoxy, + .cls = grub_terminfo_cls, + .setcolorstate = grub_terminfo_setcolorstate, + .setcursor = grub_terminfo_setcursor, + .flags = GRUB_TERM_CODE_TYPE_ASCII, + .data = &grub_serial_terminfo_output, + .progress_update_divisor = GRUB_PROGRESS_SLOW +}; + + + +struct grub_serial_port * +grub_serial_find (const char *name) +{ + struct grub_serial_port *port; + + FOR_SERIAL_PORTS (port) + if (grub_strcmp (port->name, name) == 0) + break; + +#if ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) && !defined(GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) + if (!port && grub_memcmp (name, "port", sizeof ("port") - 1) == 0 + && grub_isxdigit (name [sizeof ("port") - 1])) + { + name = grub_serial_ns8250_add_port (grub_strtoul (&name[sizeof ("port") - 1], + 0, 16)); + if (!name) + return NULL; + + FOR_SERIAL_PORTS (port) + if (grub_strcmp (port->name, name) == 0) + break; + } +#endif + +#ifdef GRUB_MACHINE_IEEE1275 + if (!port && grub_memcmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) == 0) + { + name = grub_ofserial_add_port (&name[sizeof ("ieee1275/") - 1]); + if (!name) + return NULL; + + FOR_SERIAL_PORTS (port) + if (grub_strcmp (port->name, name) == 0) + break; + } +#endif + + return port; +} + +static grub_err_t +grub_cmd_serial (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + char pname[40]; + const char *name = NULL; + struct grub_serial_port *port; + struct grub_serial_config config; + grub_err_t err; + + if (state[OPTION_UNIT].set) + { + grub_snprintf (pname, sizeof (pname), "com%ld", + grub_strtoul (state[0].arg, 0, 0)); + name = pname; + } + + if (state[OPTION_PORT].set) + { + grub_snprintf (pname, sizeof (pname), "port%lx", + grub_strtoul (state[1].arg, 0, 0)); + name = pname; + } + + if (argc >= 1) + name = args[0]; + + if (!name) + name = "com0"; + + port = grub_serial_find (name); + if (!port) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("serial port `%s' isn't found"), + name); + + config = port->config; + + if (state[OPTION_SPEED].set) { + config.speed = grub_strtoul (state[OPTION_SPEED].arg, 0, 0); + if (config.speed == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port parity")); + } + + if (state[OPTION_WORD].set) + config.word_len = grub_strtoul (state[OPTION_WORD].arg, 0, 0); + + if (state[OPTION_PARITY].set) + { + if (! grub_strcmp (state[OPTION_PARITY].arg, "no")) + config.parity = GRUB_SERIAL_PARITY_NONE; + else if (! grub_strcmp (state[OPTION_PARITY].arg, "odd")) + config.parity = GRUB_SERIAL_PARITY_ODD; + else if (! grub_strcmp (state[OPTION_PARITY].arg, "even")) + config.parity = GRUB_SERIAL_PARITY_EVEN; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port parity")); + } + + if (state[OPTION_RTSCTS].set) + { + if (grub_strcmp (state[OPTION_RTSCTS].arg, "on") == 0) + config.rtscts = 1; + else if (grub_strcmp (state[OPTION_RTSCTS].arg, "off") == 0) + config.rtscts = 0; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port flow control")); + } + + if (state[OPTION_STOP].set) + { + if (! grub_strcmp (state[OPTION_STOP].arg, "1")) + config.stop_bits = GRUB_SERIAL_STOP_BITS_1; + else if (! grub_strcmp (state[OPTION_STOP].arg, "2")) + config.stop_bits = GRUB_SERIAL_STOP_BITS_2; + else if (! grub_strcmp (state[OPTION_STOP].arg, "1.5")) + config.stop_bits = GRUB_SERIAL_STOP_BITS_1_5; + else + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unsupported serial port stop bits number")); + } + + if (state[OPTION_BASE_CLOCK].set) + { + char *ptr; + config.base_clock = grub_strtoull (state[OPTION_BASE_CLOCK].arg, &ptr, 0); + if (grub_errno) + return grub_errno; + if (ptr && *ptr == 'M') + config.base_clock *= 1000000; + if (ptr && (*ptr == 'k' || *ptr == 'K')) + config.base_clock *= 1000; + } + + if (config.speed == 0) + config.speed = 9600; + + /* Initialize with new settings. */ + err = port->driver->configure (port, &config); + if (err) + return err; +#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) + + /* Compatibility kludge. */ + if (port->driver == &grub_ns8250_driver) + { + if (!registered) + { + grub_terminfo_output_register (&grub_serial_term_output, "vt100"); + + grub_term_register_input ("serial", &grub_serial_term_input); + grub_term_register_output ("serial", &grub_serial_term_output); + } + grub_serial_terminfo_output.port = port; + grub_serial_terminfo_input.port = port; + registered = 1; + } +#endif + return GRUB_ERR_NONE; +} + +#ifdef GRUB_MACHINE_MIPS_LOONGSON +const char loongson_defserial[][6] = + { + [GRUB_ARCH_MACHINE_YEELOONG] = "com0", + [GRUB_ARCH_MACHINE_FULOONG2F] = "com2", + [GRUB_ARCH_MACHINE_FULOONG2E] = "com1" + }; +#endif + +grub_err_t +grub_serial_register (struct grub_serial_port *port) +{ + struct grub_term_input *in; + struct grub_term_output *out; + struct grub_serial_input_state *indata; + struct grub_serial_output_state *outdata; + + in = grub_malloc (sizeof (*in)); + if (!in) + return grub_errno; + + indata = grub_malloc (sizeof (*indata)); + if (!indata) + { + grub_free (in); + return grub_errno; + } + + grub_memcpy (in, &grub_serial_term_input, sizeof (*in)); + in->data = indata; + in->name = grub_xasprintf ("serial_%s", port->name); + grub_memcpy (indata, &grub_serial_terminfo_input, sizeof (*indata)); + + if (!in->name) + { + grub_free (in); + grub_free (indata); + return grub_errno; + } + + out = grub_zalloc (sizeof (*out)); + if (!out) + { + grub_free (indata); + grub_free ((char *) in->name); + grub_free (in); + return grub_errno; + } + + outdata = grub_malloc (sizeof (*outdata)); + if (!outdata) + { + grub_free (indata); + grub_free ((char *) in->name); + grub_free (out); + grub_free (in); + return grub_errno; + } + + grub_memcpy (out, &grub_serial_term_output, sizeof (*out)); + out->data = outdata; + out->name = in->name; + grub_memcpy (outdata, &grub_serial_terminfo_output, sizeof (*outdata)); + + grub_list_push (GRUB_AS_LIST_P (&grub_serial_ports), GRUB_AS_LIST (port)); + ((struct grub_serial_input_state *) in->data)->port = port; + ((struct grub_serial_output_state *) out->data)->port = port; + port->term_in = in; + port->term_out = out; + grub_terminfo_output_register (out, "vt100"); +#ifdef GRUB_MACHINE_MIPS_LOONGSON + if (grub_strcmp (port->name, loongson_defserial[grub_arch_machine]) == 0) + { + grub_term_register_input_active ("serial_*", in); + grub_term_register_output_active ("serial_*", out); + } + else + { + grub_term_register_input_inactive ("serial_*", in); + grub_term_register_output_inactive ("serial_*", out); + } +#else + grub_term_register_input ("serial_*", in); + grub_term_register_output ("serial_*", out); +#endif + + return GRUB_ERR_NONE; +} + +void +grub_serial_unregister (struct grub_serial_port *port) +{ + if (port->driver->fini) + port->driver->fini (port); + + if (port->term_in) + grub_term_unregister_input (port->term_in); + if (port->term_out) + grub_term_unregister_output (port->term_out); + + grub_list_remove (GRUB_AS_LIST (port)); +} + +void +grub_serial_unregister_driver (struct grub_serial_driver *driver) +{ + struct grub_serial_port *port, *next; + for (port = grub_serial_ports; port; port = next) + { + next = port->next; + if (port->driver == driver) + grub_serial_unregister (port); + } +} + +static grub_extcmd_t cmd; + +GRUB_MOD_INIT(serial) +{ + cmd = grub_register_extcmd ("serial", grub_cmd_serial, 0, + N_("[OPTIONS...]"), + N_("Configure serial port."), options); + grub_memcpy (&grub_serial_terminfo_output, + &grub_serial_terminfo_output_template, + sizeof (grub_serial_terminfo_output)); + + grub_memcpy (&grub_serial_terminfo_input, + &grub_serial_terminfo_input_template, + sizeof (grub_serial_terminfo_input)); + +#if !defined (GRUB_MACHINE_EMU) && !defined(GRUB_MACHINE_ARC) && ((defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__)) + grub_ns8250_init (); +#endif +#ifdef GRUB_MACHINE_IEEE1275 + grub_ofserial_init (); +#endif +#ifdef GRUB_MACHINE_EFI + grub_efiserial_init (); +#endif +#ifdef GRUB_MACHINE_ARC + grub_arcserial_init (); +#endif +} + +GRUB_MOD_FINI(serial) +{ + while (grub_serial_ports) + grub_serial_unregister (grub_serial_ports); + if (registered) + { + grub_term_unregister_input (&grub_serial_term_input); + grub_term_unregister_output (&grub_serial_term_output); + } + grub_unregister_extcmd (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/term/setkey.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/setkey.c new file mode 100644 index 00000000..a0963529 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/term/setkey.c @@ -0,0 +1,388 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define MAX_KEYMAP 255 + +struct keymap +{ + int cnt; + int in[MAX_KEYMAP]; + int out[MAX_KEYMAP]; +}; + +static struct keymap setkey_keymap; + +struct keysym +{ + const char *name; /* the name in unshifted state */ + int code; /* scan code */ +}; + +/* The table for key symbols. (from GRUB4DOS) */ +static struct keysym keysym_table[] = +{ + {"escape", GRUB_TERM_ESC}, // ESC + {"exclam", 0x21}, // '!' + {"at", 0x40}, // '@' + {"numbersign", 0x23}, // '#' + {"dollar", 0x24}, // '$' + {"percent", 0x25}, // '%' + {"caret", 0x5E}, // '^' + {"ampersand", 0x26}, // '&' + {"asterisk", 0x2A}, // '*' + {"parenleft", 0x28}, // '(' + {"parenright", 0x29}, // ')' + {"minus", 0x2D}, // '-' + {"underscore", 0x5F}, // '_' + {"equal", 0x3D}, // '=' + {"plus", 0x2B}, // '+' + {"backspace", GRUB_TERM_BACKSPACE}, // BS + {"ctrlbackspace", GRUB_TERM_CTRL | GRUB_TERM_BACKSPACE}, // (DEL) + {"tab", GRUB_TERM_TAB}, // Tab + {"bracketleft", 0x5B}, // '[' + {"braceleft", 0x7B}, // '{' + {"bracketright", 0x5D}, // ']' + {"braceright", 0x7D}, // '}' + {"enter", 0x0D}, // Enter + {"semicolon", 0x3B}, // ';' + {"colon", 0x3A}, // ':' + {"quote", 0x27}, // '\'' + {"doublequote", 0x22}, // '"' + {"backquote", 0x60}, // '`' + {"tilde", 0x7E}, // '~' + {"backslash", 0x5C}, // '\\' + {"bar", 0x7C}, // '|' + {"comma", 0x2C}, // ',' + {"less", 0x3C}, // '<' + {"period", 0x2E}, // '.' + {"greater", 0x3E}, // '>' + {"slash", 0x2F}, // '/' + {"question", 0x3F}, // '?' + {"space", 0x20}, // Space + {"F1", GRUB_TERM_KEY_F1}, + {"F2", GRUB_TERM_KEY_F2}, + {"F3", GRUB_TERM_KEY_F3}, + {"F4", GRUB_TERM_KEY_F4}, + {"F5", GRUB_TERM_KEY_F5}, + {"F6", GRUB_TERM_KEY_F6}, + {"F7", GRUB_TERM_KEY_F7}, + {"F8", GRUB_TERM_KEY_F8}, + {"F9", GRUB_TERM_KEY_F9}, + {"F10", GRUB_TERM_KEY_F10}, + {"F11", GRUB_TERM_KEY_F11}, + {"F12", GRUB_TERM_KEY_F12}, + {"home", GRUB_TERM_KEY_HOME}, + {"uparrow", GRUB_TERM_KEY_UP}, + {"pageup", GRUB_TERM_KEY_NPAGE}, // PgUp + {"leftarrow", GRUB_TERM_KEY_LEFT}, + {"center", GRUB_TERM_KEY_CENTER}, // keypad center key + {"rightarrow", GRUB_TERM_KEY_RIGHT}, + {"end", GRUB_TERM_KEY_END}, + {"downarrow", GRUB_TERM_KEY_DOWN}, + {"pagedown", GRUB_TERM_KEY_PPAGE}, // PgDn + {"insert", GRUB_TERM_KEY_INSERT}, // Insert + {"delete", GRUB_TERM_KEY_DC}, // Delete + {"shiftF1", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F1}, + {"shiftF2", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F2}, + {"shiftF3", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F3}, + {"shiftF4", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F4}, + {"shiftF5", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F5}, + {"shiftF6", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F6}, + {"shiftF7", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F7}, + {"shiftF8", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F8}, + {"shiftF9", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F9}, + {"shiftF10", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F10}, + {"shiftF11", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F11}, + {"shiftF12", GRUB_TERM_SHIFT | GRUB_TERM_KEY_F12}, + {"ctrlF1", GRUB_TERM_CTRL | GRUB_TERM_KEY_F1}, + {"ctrlF2", GRUB_TERM_CTRL | GRUB_TERM_KEY_F2}, + {"ctrlF3", GRUB_TERM_CTRL | GRUB_TERM_KEY_F3}, + {"ctrlF4", GRUB_TERM_CTRL | GRUB_TERM_KEY_F4}, + {"ctrlF5", GRUB_TERM_CTRL | GRUB_TERM_KEY_F5}, + {"ctrlF6", GRUB_TERM_CTRL | GRUB_TERM_KEY_F6}, + {"ctrlF7", GRUB_TERM_CTRL | GRUB_TERM_KEY_F7}, + {"ctrlF8", GRUB_TERM_CTRL | GRUB_TERM_KEY_F8}, + {"ctrlF9", GRUB_TERM_CTRL | GRUB_TERM_KEY_F9}, + {"ctrlF10", GRUB_TERM_CTRL | GRUB_TERM_KEY_F10}, + {"ctrlF11", GRUB_TERM_CTRL | GRUB_TERM_KEY_F11}, + {"ctrlF12", GRUB_TERM_CTRL | GRUB_TERM_KEY_F12}, + // A=Alt or AltGr. Provided by steve. + {"Aq", GRUB_TERM_ALT | 0x71}, + {"Aw", GRUB_TERM_ALT | 0x77}, + {"Ae", GRUB_TERM_ALT | 0x65}, + {"Ar", GRUB_TERM_ALT | 0x72}, + {"At", GRUB_TERM_ALT | 0x74}, + {"Ay", GRUB_TERM_ALT | 0x79}, + {"Au", GRUB_TERM_ALT | 0x75}, + {"Ai", GRUB_TERM_ALT | 0x69}, + {"Ao", GRUB_TERM_ALT | 0x6F}, + {"Ap", GRUB_TERM_ALT | 0x70}, + {"Aa", GRUB_TERM_ALT | 0x61}, + {"As", GRUB_TERM_ALT | 0x73}, + {"Ad", GRUB_TERM_ALT | 0x64}, + {"Af", GRUB_TERM_ALT | 0x66}, + {"Ag", GRUB_TERM_ALT | 0x67}, + {"Ah", GRUB_TERM_ALT | 0x68}, + {"Aj", GRUB_TERM_ALT | 0x6A}, + {"Ak", GRUB_TERM_ALT | 0x6B}, + {"Al", GRUB_TERM_ALT | 0x6C}, + {"Az", GRUB_TERM_ALT | 0x7A}, + {"Ax", GRUB_TERM_ALT | 0x78}, + {"Ac", GRUB_TERM_ALT | 0x63}, + {"Av", GRUB_TERM_ALT | 0x76}, + {"Ab", GRUB_TERM_ALT | 0x62}, + {"An", GRUB_TERM_ALT | 0x6E}, + {"Am", GRUB_TERM_ALT | 0x6D}, + {"A1", GRUB_TERM_ALT | 0x31}, + {"A2", GRUB_TERM_ALT | 0x32}, + {"A3", GRUB_TERM_ALT | 0x33}, + {"A4", GRUB_TERM_ALT | 0x34}, + {"A5", GRUB_TERM_ALT | 0x35}, + {"A6", GRUB_TERM_ALT | 0x36}, + {"A7", GRUB_TERM_ALT | 0x37}, + {"A8", GRUB_TERM_ALT | 0x38}, + {"A9", GRUB_TERM_ALT | 0x39}, + {"A0", GRUB_TERM_ALT | 0x30}, + //{"oem102", 0x5c}, + //{"shiftoem102", 0x7c}, + {"Aminus", GRUB_TERM_ALT | 0x2D}, + {"Aequal", GRUB_TERM_ALT | 0x3D}, + {"Abracketleft", GRUB_TERM_ALT | 0x5B}, + {"Abracketright", GRUB_TERM_ALT | 0x5D}, + {"Asemicolon", GRUB_TERM_ALT | 0x3B}, + {"Aquote", GRUB_TERM_ALT | 0x27}, + {"Abackquote", GRUB_TERM_ALT | 0x60}, + {"Abackslash", GRUB_TERM_ALT | 0x5C}, + {"Acomma", GRUB_TERM_ALT | 0x2C}, + {"Aperiod", GRUB_TERM_ALT | 0x2E}, + {"Aslash", GRUB_TERM_ALT | 0x2F}, + {"Acolon", GRUB_TERM_ALT | 0x3A}, + {"Aplus", GRUB_TERM_ALT | 0x2B}, + {"Aless", GRUB_TERM_ALT | 0x3C}, + {"Aunderscore", GRUB_TERM_ALT | 0x5F}, + {"Agreater", GRUB_TERM_ALT | 0x3E}, + {"Aquestion", GRUB_TERM_ALT | 0x3F}, + {"Atilde", GRUB_TERM_ALT | 0x7E}, + {"Abraceleft", GRUB_TERM_ALT | 0x7B}, + {"Abar", GRUB_TERM_ALT | 0x7C}, + {"Abraceright", GRUB_TERM_ALT | 0x7D}, + {"Adoublequote", GRUB_TERM_ALT | 0x22}, +}; + +static int grub_keymap_getkey (int key) +{ + int i; + if (key == GRUB_TERM_NO_KEY) + return key; + if (setkey_keymap.cnt > MAX_KEYMAP) + setkey_keymap.cnt = MAX_KEYMAP; + for (i = 0; i < setkey_keymap.cnt; i++) + { + if (key == setkey_keymap.in[i]) + { + key = setkey_keymap.out[i]; + break; + } + } + return key; +} + +static void +grub_keymap_reset (void) +{ + grub_memset (&setkey_keymap, 0, sizeof (struct keymap)); +} + +static grub_err_t +grub_keymap_add (int in, int out) +{ + if (in == GRUB_TERM_NO_KEY || out == GRUB_TERM_NO_KEY) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid key: %d -> %d", in, out); + if (setkey_keymap.cnt >= MAX_KEYMAP) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, + "keymap FULL %d", setkey_keymap.cnt); + setkey_keymap.in[setkey_keymap.cnt] = in; + setkey_keymap.out[setkey_keymap.cnt] = out; + setkey_keymap.cnt++; + return GRUB_ERR_NONE; +} + +static void +grub_keymap_enable (void) +{ + grub_key_remap = grub_keymap_getkey; +} + +static void +grub_keymap_disable (void) +{ + grub_key_remap = NULL; +} + +static void +grub_keymap_status (void) +{ + int i; + if (setkey_keymap.cnt > MAX_KEYMAP) + setkey_keymap.cnt = MAX_KEYMAP; + for (i = 0; i < setkey_keymap.cnt; i++) + { + grub_printf ("0x%x -> 0x%x\n", setkey_keymap.in[i], setkey_keymap.out[i]); + } +} + +static const struct grub_arg_option options[] = +{ + {"reset", 'r', 0, N_("Reset keymap."), 0, 0}, + {"enable", 'e', 0, N_("Enable keymap."), 0, 0}, + {"disable", 'd', 0, N_("Disable keymap."), 0, 0}, + {"status", 's', 0, N_("Display keymap."), 0, 0}, + {0, 0, 0, 0, 0, 0} +}; + +enum options +{ + SETKEY_RESET, + SETKEY_ENABLE, + SETKEY_DISABLE, + SETKEY_STATUS, +}; + +static int +ishex (const char *str) +{ + if (grub_strlen (str) < 3 || str[0] != '0') + return 0; + if (str[1] != 'x' && str[1] != 'X') + return 0; + return 1; +} + +static int +parse_key (const char *str) +{ + int i; + if (ishex (str)) + return grub_strtol (str, NULL, 16); + if (grub_strlen (str) == 1) + return (int) str[0]; + for (i = 0; i < (int) (sizeof (keysym_table) / sizeof (keysym_table[0])); i++) + { + if (grub_strcmp (str, keysym_table[i].name) == 0) + return keysym_table[i].code; + } + grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid key %s", str); + return 0; +} + +static grub_err_t +grub_cmd_setkey (grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_arg_list *state = ctxt->state; + int in, out; + if (state[SETKEY_ENABLE].set) + { + grub_keymap_enable (); + goto out; + } + if (state[SETKEY_DISABLE].set) + { + grub_keymap_disable (); + goto out; + } + if (state[SETKEY_RESET].set) + { + grub_keymap_reset (); + goto out; + } + if (state[SETKEY_STATUS].set) + { + grub_keymap_status (); + goto out; + } + if (argc != 2) + { + grub_printf + ("Key names: 0-9, A-Z, a-z or escape, exclam, at, numbersign, dollar," + "percent, caret, ampersand, asterisk, parenleft, parenright, minus," + "underscore, equal, plus, backspace, tab, bracketleft, braceleft," + "bracketright, braceright, enter, semicolon, colon, quote, doublequote," + "backquote, tilde, backslash, bar, comma, less, period, greater," + "slash, question, alt, space, delete, [ctrl|shift]F1-12." + "For Alt+ prefix with A, e.g. \'setkey at Aequal\'."); + goto out; + } + in = parse_key (args[1]); + out = parse_key (args[0]); + if (!in || !out) + goto out; + grub_keymap_add (in, out); +out: + return grub_errno; +} + +static void grub_keymap_add_by_string(const char *src, const char *dst) +{ + int in = 0; + int out = 0; + + in = parse_key(dst); + out = parse_key(src); + + if (in && out) + { + grub_keymap_add (in, out); + } +} + +#include "keyboard_layout.c" + +static grub_err_t grub_cmd_set_keylayout (grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + ventoy_set_keyboard_layout(args[0]); + return 0; +} + +static grub_extcmd_t cmd, setcmd; + +GRUB_MOD_INIT(setkey) +{ + cmd = grub_register_extcmd ("setkey", grub_cmd_setkey, 0, N_("NEW_KEY USA_KEY"), + N_("Map default USA_KEY to NEW_KEY."), options); + setcmd = grub_register_extcmd ("set_keyboard_layout", grub_cmd_set_keylayout, 0, N_("layout"), + N_("Set keyboard layout."), NULL); +} + +GRUB_MOD_FINI(setkey) +{ + grub_unregister_extcmd (cmd); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.c index 56dd7dd2..732a96f2 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/lzx.c @@ -462,6 +462,8 @@ static int lzx_uncompressed ( struct lzx *lzx ) { if ( len % 2 ) lzx->input.offset++; + lzx->output.offset += len; + return 0; } @@ -614,7 +616,7 @@ ssize_t lzx_decompress ( const void *data, size_t len, void *buf ) { /* Sanity check */ if ( len % 2 ) { DBG ( "LZX cannot handle odd-length input data\n" ); - return -1; + //return -1; } /* Initialise global state, if required */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.c new file mode 100644 index 00000000..60312a99 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.c @@ -0,0 +1,2587 @@ +/* miniz.c v1.12 - public domain deflate/inflate + See "unlicense" statement at the end of this file. + Rich Geldreich , last updated April 12, 2012 + Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt + + * Change History + 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple minor level_and_flags issues in the archive API's. + level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce Dawson for the feedback/bug report. + 5/28/11 v1.11 - Added statement from unlicense.org + 5/27/11 v1.10 - Substantial compressor optimizations: + Level 1 is now ~4x faster than before. The L1 compressor's throughput now varies between 70-110MB/sec. on a + Core i7 (actual throughput varies depending on the type of data, and x64 vs. x86). + Improved baseline L2-L9 compression perf. Also, greatly improved compression perf. issues on some file types. + Refactored the compression code for better readability and maintainability. + Added level 10 compression level (L10 has slightly better ratio than level 9, but could have a potentially large + drop in throughput on some files). + 5/15/11 v1.09 - Initial stable release. + + * Low-level Deflate/Inflate implementation notes: + + Compression: Use the "tdefl" API's. The compressor supports raw, static, and dynamic blocks, lazy or + greedy parsing, match length filtering, RLE-only, and Huffman-only streams. It performs and compresses + approximately as well as zlib. + + Decompression: Use the "tinfl" API's. The entire decompressor is implemented as a single function + coroutine: see tinfl_decompress(). It supports decompression into a 32KB (or larger power of 2) wrapping buffer, or into a memory + block large enough to hold the entire file. + + The low-level tdefl/tinfl API's do not make any use of dynamic memory allocation. + + * zlib-style API notes: + + miniz.c implements a fairly large subset of zlib. There's enough functionality present for it to be a drop-in + zlib replacement in many apps: + The z_stream struct, optional memory allocation callbacks + deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound + inflateInit/inflateInit2/inflate/inflateEnd + compress, compress2, compressBound, uncompress + CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly routines. + Supports raw deflate streams or standard zlib streams with adler-32 checking. + + Limitations: + The callback API's are not implemented yet. No support for gzip headers or zlib static dictionaries. + I've tried to closely emulate zlib's various flavors of stream flushing and return status codes, but + there are no guarantees that miniz.c pulls this off perfectly. + + * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function, originally written by + Alex Evans. Supports 1-4 bytes/pixel images. + + * This is a header file library, like stb_image.c. To get only a header file, either cut and paste the + below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then include miniz.c from it. + + * Important: For best perf. be sure to customize the below macros for your target platform: + #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0 + #define MINIZ_LITTLE_ENDIAN 1 + #define MINIZ_HAS_64BIT_REGISTERS 1 +*/ + +#ifndef MINIZ_HEADER_INCLUDED +#define MINIZ_HEADER_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wundef" + +#define size_t grub_size_t +#define uint8_t grub_uint8_t +#define uint16_t grub_uint16_t +#define uint32_t grub_uint32_t +#define uint64_t grub_uint64_t + +#define assert(a) + +#define memset grub_memset +#define memcpy grub_memcpy +#define memcmp grub_memcmp + +// Defines to completely disable specific portions of miniz.c: +// If all macros here are defined the only functionality remaining will be CRC-32, adler-32, tinfl, and tdefl. + +// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression API's. +//#define MINIZ_NO_ZLIB_APIS + +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent conflicts against stock zlib. +//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc. +// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom user alloc/free/realloc +// callbacks to the zlib and archive API's, and a few stand-alone helper API's which don't provide custom user +// functions (such as tdefl_compress_mem_to_heap() and tinfl_decompress_mem_to_heap()) won't work. +//#define MINIZ_NO_MALLOC + +#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(i386) || defined(__ia64__) || defined(__x86_64__) +// MINIZ_X86_OR_X64_CPU is only used to help set the below macros. +#define MINIZ_X86_OR_X64_CPU 1 +#endif + +#if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU +// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian. +#define MINIZ_LITTLE_ENDIAN 1 +#else +#error ("Not little endian") +#endif + +#if MINIZ_X86_OR_X64_CPU +// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient integer loads and stores from unaligned addresses. +#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1 +#endif + +#define MINIZ_HAS_64BIT_REGISTERS 1 + +// ------------------- zlib-style API Definitions. + +// For more compatibility with zlib, miniz.c uses unsigned long for some parameters/struct members. +typedef unsigned long mz_ulong; + +// Heap allocation callbacks. +// Note that mz_alloc_func parameter types purpsosely differ from zlib's: items/size is size_t, not unsigned long. +typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size); +typedef void (*mz_free_func)(void *opaque, void *address); +typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items, size_t size); + +#define MZ_ADLER32_INIT (1) +// mz_adler32() returns the initial adler-32 value to use when called with ptr==NULL. +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len); + +#define MZ_CRC32_INIT (0) +// mz_crc32() returns the initial CRC-32 value to use when called with ptr==NULL. +mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len); + +// Compression strategies. +enum { MZ_DEFAULT_STRATEGY = 0, MZ_FILTERED = 1, MZ_HUFFMAN_ONLY = 2, MZ_RLE = 3, MZ_FIXED = 4 }; + +// Method +#define MZ_DEFLATED 8 + +#ifndef MINIZ_NO_ZLIB_APIS + +#define MZ_VERSION "9.1.12" +#define MZ_VERNUM 0x91C0 +#define MZ_VER_MAJOR 9 +#define MZ_VER_MINOR 1 +#define MZ_VER_REVISION 12 +#define MZ_VER_SUBREVISION 0 + +// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The other values are for advanced use (refer to the zlib docs). +enum { MZ_NO_FLUSH = 0, MZ_PARTIAL_FLUSH = 1, MZ_SYNC_FLUSH = 2, MZ_FULL_FLUSH = 3, MZ_FINISH = 4, MZ_BLOCK = 5 }; + +// Return status codes. MZ_PARAM_ERROR is non-standard. +enum { MZ_OK = 0, MZ_STREAM_END = 1, MZ_NEED_DICT = 2, MZ_ERRNO = -1, MZ_STREAM_ERROR = -2, MZ_DATA_ERROR = -3, MZ_MEM_ERROR = -4, MZ_BUF_ERROR = -5, MZ_VERSION_ERROR = -6, MZ_PARAM_ERROR = -10000 }; + +// Compression levels: 0-9 are the standard zlib-style levels, 10 is best possible compression (not zlib compatible, and may be very slow), MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL. +enum { MZ_NO_COMPRESSION = 0, MZ_BEST_SPEED = 1, MZ_BEST_COMPRESSION = 9, MZ_UBER_COMPRESSION = 10, MZ_DEFAULT_LEVEL = 6, MZ_DEFAULT_COMPRESSION = -1 }; + +// Window bits +#define MZ_DEFAULT_WINDOW_BITS 15 + +struct mz_internal_state; + +// Compression/decompression stream struct. +typedef struct mz_stream_s +{ + const unsigned char *next_in; // pointer to next byte to read + unsigned int avail_in; // number of bytes available at next_in + mz_ulong total_in; // total number of bytes consumed so far + + unsigned char *next_out; // pointer to next byte to write + unsigned int avail_out; // number of bytes that can be written to next_out + mz_ulong total_out; // total number of bytes produced so far + + char *msg; // error msg (unused) + struct mz_internal_state *state; // internal state, allocated by zalloc/zfree + + mz_alloc_func zalloc; // optional heap allocation function (defaults to malloc) + mz_free_func zfree; // optional heap free function (defaults to free) + void *opaque; // heap alloc function user pointer + + int data_type; // data_type (unused) + mz_ulong adler; // adler32 of the source or uncompressed data + mz_ulong crc32; // crc32 of the source or uncompressed data + mz_ulong reserved; +} mz_stream; + +typedef mz_stream *mz_streamp; + +// Returns the version string of miniz.c. +const char *mz_version(void); + +// mz_deflateInit() initializes a compressor with default options: +// Parameters: +// pStream must point to an initialized mz_stream struct. +// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION]. +// level 1 enables a specially optimized compression function that's been optimized purely for performance, not ratio. +// (This special func. is currently only enabled when MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.) +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if the input parameters are bogus. +// MZ_MEM_ERROR on out of memory. +int mz_deflateInit(mz_streamp pStream, int level); + +// mz_deflateInit2() is like mz_deflate(), except with more control: +// Additional parameters: +// method must be MZ_DEFLATED +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no header or footer) +// mem_level must be between [1, 9] (it's checked but ignored by miniz.c) +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy); + +// Quickly resets a compressor without having to reallocate anything. Same as calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2(). +int mz_deflateReset(mz_streamp pStream); + +// mz_deflate() compresses the input to output, consuming as much of the input and producing as much output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or MZ_FINISH. +// Return values: +// MZ_OK on success (when flushing, or if more input is needed but not available, and/or there's more output to be written but the output buffer is full). +// MZ_STREAM_END if all input has been consumed and all output bytes have been written. Don't call mz_deflate() on the stream anymore. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input and/or output buffers are empty. (Fill up the input buffer or free up some output space and try again.) +int mz_deflate(mz_streamp pStream, int flush); + +// mz_deflateEnd() deinitializes a compressor: +// Return values: +// MZ_OK on success. +// MZ_STREAM_ERROR if the stream is bogus. +int mz_deflateEnd(mz_streamp pStream); + +// mz_deflateBound() returns a (very) conservative upper bound on the amount of data that could be generated by deflate(), assuming flush is set to only MZ_NO_FLUSH or MZ_FINISH. +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len); + +// Single-call compression functions mz_compress() and mz_compress2(): +// Returns MZ_OK on success, or one of the error codes from mz_deflate() on failure. +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level); + +// mz_compressBound() returns a (very) conservative upper bound on the amount of data that could be generated by calling mz_compress(). +mz_ulong mz_compressBound(mz_ulong source_len); + +// Initializes a decompressor. +int mz_inflateInit(mz_streamp pStream); + +// mz_inflateInit2() is like mz_inflateInit() with an additional option that controls the window size and whether or not the stream has been wrapped with a zlib header/footer: +// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate). +int mz_inflateInit2(mz_streamp pStream, int window_bits); + +// Decompresses the input stream to the output, consuming only as much of the input as needed, and writing as much to the output as possible. +// Parameters: +// pStream is the stream to read from and write to. You must initialize/update the next_in, avail_in, next_out, and avail_out members. +// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH. +// On the first call, if flush is MZ_FINISH it's assumed the input and output buffers are both sized large enough to decompress the entire stream in a single call (this is slightly faster). +// MZ_FINISH implies that there are no more source bytes available beside what's already in the input buffer, and that the output buffer is large enough to hold the rest of the decompressed data. +// Return values: +// MZ_OK on success. Either more input is needed but not available, and/or there's more output to be written but the output buffer is full. +// MZ_STREAM_END if all needed input has been consumed and all output bytes have been written. For zlib streams, the adler-32 of the decompressed data has also been verified. +// MZ_STREAM_ERROR if the stream is bogus. +// MZ_DATA_ERROR if the deflate stream is invalid. +// MZ_PARAM_ERROR if one of the parameters is invalid. +// MZ_BUF_ERROR if no forward progress is possible because the input buffer is empty but the inflater needs more input to continue, or if the output buffer is not large enough. Call mz_inflate() again +// with more input data, or with more room in the output buffer (except when using single call decompression, described above). +int mz_inflate(mz_streamp pStream, int flush); + +// Deinitializes a decompressor. +int mz_inflateEnd(mz_streamp pStream); + +// Single-call decompression. +// Returns MZ_OK on success, or one of the error codes from mz_inflate() on failure. +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len); + +// Returns a string description of the specified error code, or NULL if the error code is invalid. +const char *mz_error(int err); + +// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used as a drop-in replacement for the subset of zlib that miniz.c supports. +// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you use zlib in the same project. +#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + typedef unsigned char Byte; + typedef unsigned int uInt; + typedef mz_ulong uLong; + typedef Byte Bytef; + typedef uInt uIntf; + typedef char charf; + typedef int intf; + typedef void *voidpf; + typedef uLong uLongf; + typedef void *voidp; + typedef void *const voidpc; + #define Z_NULL 0 + #define Z_NO_FLUSH MZ_NO_FLUSH + #define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH + #define Z_SYNC_FLUSH MZ_SYNC_FLUSH + #define Z_FULL_FLUSH MZ_FULL_FLUSH + #define Z_FINISH MZ_FINISH + #define Z_BLOCK MZ_BLOCK + #define Z_OK MZ_OK + #define Z_STREAM_END MZ_STREAM_END + #define Z_NEED_DICT MZ_NEED_DICT + #define Z_ERRNO MZ_ERRNO + #define Z_STREAM_ERROR MZ_STREAM_ERROR + #define Z_DATA_ERROR MZ_DATA_ERROR + #define Z_MEM_ERROR MZ_MEM_ERROR + #define Z_BUF_ERROR MZ_BUF_ERROR + #define Z_VERSION_ERROR MZ_VERSION_ERROR + #define Z_PARAM_ERROR MZ_PARAM_ERROR + #define Z_NO_COMPRESSION MZ_NO_COMPRESSION + #define Z_BEST_SPEED MZ_BEST_SPEED + #define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION + #define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION + #define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY + #define Z_FILTERED MZ_FILTERED + #define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY + #define Z_RLE MZ_RLE + #define Z_FIXED MZ_FIXED + #define Z_DEFLATED MZ_DEFLATED + #define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS + #define alloc_func mz_alloc_func + #define free_func mz_free_func + #define internal_state mz_internal_state + #define z_stream mz_stream + #define deflateInit mz_deflateInit + #define deflateInit2 mz_deflateInit2 + #define deflateReset mz_deflateReset + #define deflate mz_deflate + #define deflateEnd mz_deflateEnd + #define deflateBound mz_deflateBound + #define compress mz_compress + #define compress2 mz_compress2 + #define compressBound mz_compressBound + #define inflateInit mz_inflateInit + #define inflateInit2 mz_inflateInit2 + #define inflate mz_inflate + #define inflateEnd mz_inflateEnd + #define uncompress mz_uncompress + #define z_crc32 mz_crc32 + #define z_adler32 mz_adler32 + #define MAX_WBITS 15 + #define MAX_MEM_LEVEL 9 + #define zError mz_error + #define ZLIB_VERSION MZ_VERSION + #define ZLIB_VERNUM MZ_VERNUM + #define ZLIB_VER_MAJOR MZ_VER_MAJOR + #define ZLIB_VER_MINOR MZ_VER_MINOR + #define ZLIB_VER_REVISION MZ_VER_REVISION + #define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION + #define zlibVersion mz_version + #define zlib_version mz_version() +#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES + +#endif // MINIZ_NO_ZLIB_APIS + +// ------------------- Types and macros + +typedef unsigned char mz_uint8; +typedef signed short mz_int16; +typedef unsigned short mz_uint16; +typedef unsigned int mz_uint32; +typedef unsigned int mz_uint; +typedef long long mz_int64; +typedef unsigned long long mz_uint64; +typedef int mz_bool; + +#define MZ_FALSE (0) +#define MZ_TRUE (1) + +#ifndef __WIN__ +#define MZ_MACRO_END while (0) +#else +// Works around MSVC's spammy "warning C4127: conditional expression is constant" message. +#define MZ_MACRO_END while (0, 0) +#endif + +// ------------------- Low-level Decompression API Definitions + +// Decompression flags used by tinfl_decompress(). +// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream. +// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input. +// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB). +// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes. +enum +{ + TINFL_FLAG_PARSE_ZLIB_HEADER = 1, + TINFL_FLAG_HAS_MORE_INPUT = 2, + TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4, + TINFL_FLAG_COMPUTE_ADLER32 = 8 +}; + +// High level decompression functions: +// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress. +// On return: +// Function returns a pointer to the decompressed data, or NULL on failure. +// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory. +// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success. +#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1)) +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer. +// Returns 1 on success or 0 on failure. +typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor; + +// Max size of LZ dictionary. +#define TINFL_LZ_DICT_SIZE 32768 + +// Return status. +typedef enum +{ + TINFL_STATUS_BAD_PARAM = -3, + TINFL_STATUS_ADLER32_MISMATCH = -2, + TINFL_STATUS_FAILED = -1, + TINFL_STATUS_DONE = 0, + TINFL_STATUS_NEEDS_MORE_INPUT = 1, + TINFL_STATUS_HAS_MORE_OUTPUT = 2 +} tinfl_status; + +// Initializes the decompressor to its initial state. +#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END +#define tinfl_get_adler32(r) (r)->m_check_adler32 +#define tinfl_get_crc32(r) (r)->m_check_crc32 + +// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability. +// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output. +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags); + +// Internal/private bits follow. +enum +{ + TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19, + TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS +}; + +typedef struct +{ + mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0]; + mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2]; +} tinfl_huff_table; + +#if MINIZ_HAS_64BIT_REGISTERS + #define TINFL_USE_64BIT_BITBUF 1 +#endif + +#if TINFL_USE_64BIT_BITBUF + typedef mz_uint64 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (64) +#else + typedef mz_uint32 tinfl_bit_buf_t; + #define TINFL_BITBUF_SIZE (32) +#endif + +struct tinfl_decompressor_tag +{ + mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_z_crc32, m_final, m_type, m_check_adler32, m_check_crc32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; + tinfl_bit_buf_t m_bit_buf; + size_t m_dist_from_out_buf_start; + tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; + mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; +}; + +// ------------------- Low-level Compression API Definitions + +// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly slower, and raw/dynamic blocks will be output more frequently). +#define TDEFL_LESS_MEMORY 0 + +// tdefl_init() compression flags logically OR'd together (low 12 bits contain the max. number of probes per dictionary search): +// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap compression), 4095=Huffman+LZ (slowest/best compression). +enum +{ + TDEFL_HUFFMAN_ONLY = 0, TDEFL_DEFAULT_MAX_PROBES = 128, TDEFL_MAX_PROBES_MASK = 0xFFF +}; + +// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before the deflate data, and the Adler-32 of the source data at the end. Otherwise, you'll get raw deflate data. +// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even when not writing zlib headers). +// TDEFL_COMPUTE_CRC32: Always compute the crc-32 of the input data. +// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more efficient lazy parsing. +// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's initialization time to the minimum, but the output may vary from run to run given the same input (depending on the contents of memory). +// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1) +// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled. +// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables. +// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks. +enum +{ + TDEFL_WRITE_ZLIB_HEADER = 0x001000, + TDEFL_COMPUTE_ADLER32 = 0x002000, + TDEFL_COMPUTE_CRC32 = 0x004000, + TDEFL_GREEDY_PARSING_FLAG = 0x008000, + TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x010000, + TDEFL_RLE_MATCHES = 0x020000, + TDEFL_FILTER_MATCHES = 0x040000, + TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x080000, + TDEFL_FORCE_ALL_RAW_BLOCKS = 0x100000, +}; + +// High level compression functions: +// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block allocated via malloc(). +// On entry: +// pSrc_buf, src_buf_len: Pointer and size of source block to compress. +// flags: The max match finder probes (default is 128) logically OR'd against the above flags. Higher probes are slower but improve compression. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pOut_len will be set to the compressed data's size, which could be larger than src_buf_len on uncompressible data. +// The caller must free() the returned block when it's no longer needed. +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags); + +// tdefl_compress_mem_to_mem() compresses a block in memory to another block in memory. +// Returns 0 on failure. +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags); + +// Compresses an image to a compressed PNG file in memory. +// On entry: +// pImage, w, h, and num_chans describe the image to compress. num_chans may be 1, 2, 3, or 4. +// On return: +// Function returns a pointer to the compressed data, or NULL on failure. +// *pLen_out will be set to the size of the PNG image file. +// The caller must free() the returned heap block (which will typically be larger than *pLen_out) when it's no longer needed. +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out); + +// Output stream interface. The compressor uses this interface to write compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time. +typedef mz_bool (*tdefl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser); + +// tdefl_compress_mem_to_output() compresses a block to an output stream. The above helpers use this function internally. +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +enum { TDEFL_MAX_HUFF_TABLES = 3, TDEFL_MAX_HUFF_SYMBOLS_0 = 288, TDEFL_MAX_HUFF_SYMBOLS_1 = 32, TDEFL_MAX_HUFF_SYMBOLS_2 = 19, TDEFL_LZ_DICT_SIZE = 32768, TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1, TDEFL_MIN_MATCH_LEN = 3, TDEFL_MAX_MATCH_LEN = 258 }; + +// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed output block (using static/fixed Huffman codes). +#if TDEFL_LESS_MEMORY +enum { TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 12, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#else +enum { TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024, TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13 ) / 10, TDEFL_MAX_HUFF_SYMBOLS = 288, TDEFL_LZ_HASH_BITS = 15, TDEFL_LEVEL1_HASH_SIZE_MASK = 4095, TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3, TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS }; +#endif + +// The low-level tdefl functions below may be used directly if the above helper functions aren't flexible enough. The low-level functions don't make any heap allocations, unlike the above helper functions. +typedef enum +{ + TDEFL_STATUS_BAD_PARAM = -2, + TDEFL_STATUS_PUT_BUF_FAILED = -1, + TDEFL_STATUS_OKAY = 0, + TDEFL_STATUS_DONE = 1, +} tdefl_status; + +// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums +typedef enum +{ + TDEFL_NO_FLUSH = 0, + TDEFL_SYNC_FLUSH = 2, + TDEFL_FULL_FLUSH = 3, + TDEFL_FINISH = 4 +} tdefl_flush; + +// tdefl's compression state structure. +typedef struct +{ + tdefl_put_buf_func_ptr m_pPut_buf_func; + void *m_pPut_buf_user; + mz_uint m_flags, m_max_probes[2]; + int m_greedy_parsing; + mz_uint m_adler32, m_crc32, m_lookahead_pos, m_lookahead_size, m_dict_size; + mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end; + mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in, m_bit_buffer; + mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit, m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index, m_wants_to_finish; + tdefl_status m_prev_return_status; + const void *m_pIn_buf; + void *m_pOut_buf; + size_t *m_pIn_buf_size, *m_pOut_buf_size; + tdefl_flush m_flush; + const mz_uint8 *m_pSrc; + size_t m_src_buf_left, m_out_buf_ofs; + mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1]; + mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS]; + mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE]; + mz_uint16 m_next[TDEFL_LZ_DICT_SIZE]; + mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE]; + mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE]; +} tdefl_compressor; + +// Initializes the compressor. +// There is no corresponding deinit() function because the tdefl API's do not dynamically allocate memory. +// pBut_buf_func: If NULL, output data will be supplied to the specified callback. In this case, the user should call the tdefl_compress_buffer() API for compression. +// If pBut_buf_func is NULL the user should always call the tdefl_compress() API. +// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER, etc.) +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags); + +// Compresses a block of data, consuming as much of the specified input buffer as possible, and writing as much compressed data to the specified output buffer as possible. +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush); + +// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a non-NULL tdefl_put_buf_func_ptr. +// tdefl_compress_buffer() always consumes the entire input buffer. +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush); + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d); +mz_uint32 tdefl_get_adler32(tdefl_compressor *d); +mz_uint32 tdefl_get_crc32(tdefl_compressor *d); + +// Create tdefl_compress() flags given zlib-style compression parameters. +// level may range from [0,10] (where 10 is absolute max compression, but may be much slower on some files) +// window_bits may be -15 (raw deflate) or 15 (zlib) +// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY, MZ_RLE, or MZ_FIXED +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy); + +#endif // MINIZ_HEADER_INCLUDED + +// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.) + +#ifndef MINIZ_HEADER_FILE_ONLY + +typedef unsigned char mz_validate_uint16[sizeof(mz_uint16)==2 ? 1 : -1]; +typedef unsigned char mz_validate_uint32[sizeof(mz_uint32)==4 ? 1 : -1]; +typedef unsigned char mz_validate_uint64[sizeof(mz_uint64)==8 ? 1 : -1]; + +#define MZ_ASSERT(x) assert(x) + +#ifdef MINIZ_NO_MALLOC + #define MZ_MALLOC(x) NULL + #define MZ_FREE(x) x, ((void)0) + #define MZ_REALLOC(p, x) NULL +#else + #define MZ_MALLOC(x) grub_malloc(x) + #define MZ_FREE(x) grub_free(x) + #define MZ_REALLOC(p, x) grub_realloc(p, x) +#endif + +#define MZ_MAX(a,b) (((a)>(b))?(a):(b)) +#define MZ_MIN(a,b) (((a)<(b))?(a):(b)) +#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj)) + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + #define MZ_READ_LE16(p) *((const mz_uint16 *)(p)) + #define MZ_READ_LE32(p) *((const mz_uint32 *)(p)) +#else + #define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U)) + #define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U)) +#endif + +#if !defined(_MSC_VER) && !defined(__MINGW32__) && !defined(__MINGW64__) && !defined(__forceinline) + #define __forceinline +#endif + +// ------------------- zlib-style API's + +static void *def_alloc_func(void *opaque, size_t items, size_t size) { (void)opaque; return MZ_MALLOC(items * size); } +static void def_free_func(void *opaque, void *address) { (void)opaque, MZ_FREE(address); } + +mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) +{ + mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16); size_t block_len = buf_len % 5552; + if (!ptr) return MZ_ADLER32_INIT; + while (buf_len) { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + return (s2 << 16) + s1; +} + +// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C implementation that balances processor cache usage against speed": http://www.geocities.com/malbrain/ +mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) +{ + static const mz_uint32 s_crc32[16] = { 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c, + 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c }; + if (!ptr) return MZ_CRC32_INIT; + crc = ~crc; while (buf_len--) { mz_uint8 b = *ptr++; crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b & 0xF)]; crc = (crc >> 4) ^ s_crc32[(crc & 0xF) ^ (b >> 4)]; } return ~crc; +} + +#ifndef MINIZ_NO_ZLIB_APIS + +const char *mz_version(void) +{ + return MZ_VERSION; +} + +int mz_deflateInit(mz_streamp pStream, int level) +{ + return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9, MZ_DEFAULT_STRATEGY); +} + +int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits, int mem_level, int strategy) +{ + tdefl_compressor *pComp; + mz_uint comp_flags = TDEFL_COMPUTE_ADLER32 | TDEFL_COMPUTE_CRC32 | tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy); + + if (!pStream) return MZ_STREAM_ERROR; + if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) || ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS))) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = MZ_ADLER32_INIT; + pStream->crc32 = MZ_CRC32_INIT; + pStream->msg = NULL; + pStream->reserved = 0; + pStream->total_in = 0; + pStream->total_out = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1, sizeof(tdefl_compressor)); + if (!pComp) + return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pComp; + + if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) + { + mz_deflateEnd(pStream); + return MZ_PARAM_ERROR; + } + + return MZ_OK; +} + +int mz_deflateReset(mz_streamp pStream) +{ + if ((!pStream) || (!pStream->state) || (!pStream->zalloc) || (!pStream->zfree)) return MZ_STREAM_ERROR; + pStream->total_in = pStream->total_out = 0; + tdefl_init((tdefl_compressor*)pStream->state, NULL, NULL, ((tdefl_compressor*)pStream->state)->m_flags); + return MZ_OK; +} + +int mz_deflate(mz_streamp pStream, int flush) +{ + size_t in_bytes, out_bytes; + mz_ulong orig_total_in, orig_total_out; + int mz_status = MZ_OK; + + if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) || (!pStream->next_out)) return MZ_STREAM_ERROR; + if (!pStream->avail_out) return MZ_BUF_ERROR; + + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + + if (((tdefl_compressor*)pStream->state)->m_prev_return_status == TDEFL_STATUS_DONE) + return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR; + + orig_total_in = pStream->total_in; orig_total_out = pStream->total_out; + for ( ; ; ) + { + tdefl_status defl_status; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + + defl_status = tdefl_compress((tdefl_compressor*)pStream->state, pStream->next_in, &in_bytes, pStream->next_out, &out_bytes, (tdefl_flush)flush); + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tdefl_get_adler32((tdefl_compressor*)pStream->state); pStream->crc32 = tdefl_get_crc32((tdefl_compressor*)pStream->state); + + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; + pStream->total_out += (mz_uint)out_bytes; + + if (defl_status < 0) + { + mz_status = MZ_STREAM_ERROR; + break; + } + else if (defl_status == TDEFL_STATUS_DONE) + { + mz_status = MZ_STREAM_END; + break; + } + else if (!pStream->avail_out) + break; + else if ((!pStream->avail_in) && (flush != MZ_FINISH)) + { + if ((flush) || (pStream->total_in != orig_total_in) || (pStream->total_out != orig_total_out)) + break; + return MZ_BUF_ERROR; // Can't make forward progress without some input. + } + } + return mz_status; +} + +int mz_deflateEnd(mz_streamp pStream) +{ + if (!pStream) return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) +{ + (void)pStream; + // This is really over conservative. (And lame, but it's actually pretty tricky to compute a true upper bound given the way tdefl's blocking works.) + return MZ_MAX(128 + (source_len * 110) / 100, 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5); +} + +int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len, int level) +{ + int status; + mz_stream stream; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_deflateInit(&stream, level); + if (status != MZ_OK) return status; + + status = mz_deflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_deflateEnd(&stream); + return (status == MZ_OK) ? MZ_BUF_ERROR : status; + } + + *pDest_len = stream.total_out; + return mz_deflateEnd(&stream); +} + +int mz_compress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + return mz_compress2(pDest, pDest_len, pSource, source_len, MZ_DEFAULT_COMPRESSION); +} + +mz_ulong mz_compressBound(mz_ulong source_len) +{ + return mz_deflateBound(NULL, source_len); +} + +typedef struct +{ + tinfl_decompressor m_decomp; + mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed; int m_window_bits; + mz_uint8 m_dict[TINFL_LZ_DICT_SIZE]; + tinfl_status m_last_status; +} inflate_state; + +int mz_inflateInit2(mz_streamp pStream, int window_bits) +{ + inflate_state *pDecomp; + if (!pStream) return MZ_STREAM_ERROR; + if ((window_bits != MZ_DEFAULT_WINDOW_BITS) && (-window_bits != MZ_DEFAULT_WINDOW_BITS)) return MZ_PARAM_ERROR; + + pStream->data_type = 0; + pStream->adler = 0; + pStream->crc32 = 0; + pStream->msg = NULL; + pStream->total_in = 0; + pStream->total_out = 0; + pStream->reserved = 0; + if (!pStream->zalloc) pStream->zalloc = def_alloc_func; + if (!pStream->zfree) pStream->zfree = def_free_func; + + pDecomp = (inflate_state*)pStream->zalloc(pStream->opaque, 1, sizeof(inflate_state)); + if (!pDecomp) return MZ_MEM_ERROR; + + pStream->state = (struct mz_internal_state *)pDecomp; + + tinfl_init(&pDecomp->m_decomp); + pDecomp->m_dict_ofs = 0; + pDecomp->m_dict_avail = 0; + pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT; + pDecomp->m_first_call = 1; + pDecomp->m_has_flushed = 0; + pDecomp->m_window_bits = window_bits; + + return MZ_OK; +} + +int mz_inflateInit(mz_streamp pStream) +{ + return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS); +} + +int mz_inflate(mz_streamp pStream, int flush) +{ + inflate_state* pState; + mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32; + size_t in_bytes, out_bytes, orig_avail_in; + tinfl_status status; + + if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR; + if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH; + if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + + pState = (inflate_state*)pStream->state; + if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER; + orig_avail_in = pStream->avail_in; + + first_call = pState->m_first_call; pState->m_first_call = 0; + if (pState->m_last_status < 0) return MZ_DATA_ERROR; + + if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR; + pState->m_has_flushed |= (flush == MZ_FINISH); + + if ((flush == MZ_FINISH) && (first_call)) + { + // MZ_FINISH on the first call implies that the input and output buffers are large enough to hold the entire compressed/decompressed file. + decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF; + in_bytes = pStream->avail_in; out_bytes = pStream->avail_out; + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pStream->next_out, pStream->next_out, &out_bytes, decomp_flags); + pState->m_last_status = status; + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; pStream->total_in += (mz_uint)in_bytes; + pStream->adler = tinfl_get_adler32(&pState->m_decomp); + pStream->crc32 = tinfl_get_crc32(&pState->m_decomp); + pStream->next_out += (mz_uint)out_bytes; pStream->avail_out -= (mz_uint)out_bytes; pStream->total_out += (mz_uint)out_bytes; + + if (status < 0) + return MZ_DATA_ERROR; + else if (status != TINFL_STATUS_DONE) + { + pState->m_last_status = TINFL_STATUS_FAILED; + return MZ_BUF_ERROR; + } + return MZ_STREAM_END; + } + // flush != MZ_FINISH then we must assume there's more input. + if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT; + + if (pState->m_dict_avail) + { + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + return ((pState->m_last_status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; + } + + for ( ; ; ) + { + in_bytes = pStream->avail_in; + out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs; + + status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict, pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags); + pState->m_last_status = status; + + pStream->next_in += (mz_uint)in_bytes; pStream->avail_in -= (mz_uint)in_bytes; + pStream->total_in += (mz_uint)in_bytes; pStream->adler = tinfl_get_adler32(&pState->m_decomp); pStream->crc32 = tinfl_get_crc32(&pState->m_decomp); + + pState->m_dict_avail = (mz_uint)out_bytes; + + n = MZ_MIN(pState->m_dict_avail, pStream->avail_out); + memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n); + pStream->next_out += n; pStream->avail_out -= n; pStream->total_out += n; + pState->m_dict_avail -= n; pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1); + + if (status < 0) + return MZ_DATA_ERROR; // Stream is corrupted (there could be some uncompressed data left in the output dictionary - oh well). + else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in)) + return MZ_BUF_ERROR; // Signal caller that we can't make forward progress without supplying more input or by setting flush to MZ_FINISH. + else if (flush == MZ_FINISH) + { + // The output buffer MUST be large to hold the remaining uncompressed data when flush==MZ_FINISH. + if (status == TINFL_STATUS_DONE) + return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END; + // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's at least 1 more byte on the way. If there's no more room left in the output buffer then something is wrong. + else if (!pStream->avail_out) + return MZ_BUF_ERROR; + } + else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) || (!pStream->avail_out) || (pState->m_dict_avail)) + break; + } + + return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail)) ? MZ_STREAM_END : MZ_OK; +} + +int mz_inflateEnd(mz_streamp pStream) +{ + if (!pStream) + return MZ_STREAM_ERROR; + if (pStream->state) + { + pStream->zfree(pStream->opaque, pStream->state); + pStream->state = NULL; + } + return MZ_OK; +} + +int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len, const unsigned char *pSource, mz_ulong source_len) +{ + mz_stream stream; + int status; + memset(&stream, 0, sizeof(stream)); + + // In case mz_ulong is 64-bits (argh I hate longs). + if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR; + + stream.next_in = pSource; + stream.avail_in = (mz_uint32)source_len; + stream.next_out = pDest; + stream.avail_out = (mz_uint32)*pDest_len; + + status = mz_inflateInit(&stream); + if (status != MZ_OK) + return status; + + status = mz_inflate(&stream, MZ_FINISH); + if (status != MZ_STREAM_END) + { + mz_inflateEnd(&stream); + return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR : status; + } + *pDest_len = stream.total_out; + + return mz_inflateEnd(&stream); +} + +const char *mz_error(int err) +{ + static struct { int m_err; const char *m_pDesc; } s_error_descs[] = + { + { MZ_OK, "" }, { MZ_STREAM_END, "stream end" }, { MZ_NEED_DICT, "need dictionary" }, { MZ_ERRNO, "file error" }, { MZ_STREAM_ERROR, "stream error" }, + { MZ_DATA_ERROR, "data error" }, { MZ_MEM_ERROR, "out of memory" }, { MZ_BUF_ERROR, "buf error" }, { MZ_VERSION_ERROR, "version error" }, { MZ_PARAM_ERROR, "parameter error" } + }; + mz_uint i; for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i) if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc; + return NULL; +} + +#endif //MINIZ_NO_ZLIB_APIS + +// ------------------- Low-level Decompression (completely independent from all compression API's) + +#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l) +#define TINFL_MEMSET(p, c, l) memset(p, c, l) + +#define TINFL_CR_BEGIN switch(r->m_state) { case 0: +#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END +#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END +#define TINFL_CR_FINISH } + +// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never +// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario. +#define TINFL_GET_BYTE(state_index, c) do { \ + if (pIn_buf_cur >= pIn_buf_end) { \ + for ( ; ; ) { \ + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \ + TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \ + if (pIn_buf_cur < pIn_buf_end) { \ + c = *pIn_buf_cur++; \ + break; \ + } \ + } else { \ + c = 0; \ + break; \ + } \ + } \ + } else c = *pIn_buf_cur++; } MZ_MACRO_END + +#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n)) +#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END +#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END + +// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2. +// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a +// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the +// bit buffer contains >=15 bits (deflate's max. Huffman code size). +#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ + do { \ + temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ + if (temp >= 0) { \ + code_len = temp >> 9; \ + if ((code_len) && (num_bits >= code_len)) \ + break; \ + } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \ + code_len = TINFL_FAST_LOOKUP_BITS; \ + do { \ + temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ + } while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \ + } TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \ + } while (num_bits < 15); + +// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read +// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully +// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32. +// The slow path is only executed at the very end of the input buffer. +#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \ + int temp; mz_uint code_len, c; \ + if (num_bits < 15) { \ + if ((pIn_buf_end - pIn_buf_cur) < 2) { \ + TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ + } else { \ + bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \ + } \ + } \ + if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ + code_len = temp >> 9, temp &= 511; \ + else { \ + code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \ + } sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmisleading-indentation" +#endif + +tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) +{ + static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 }; + static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; + static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; + static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; + static const int s_min_table_sizes[3] = { 257, 1, 4 }; + + tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf; + const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size; + mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size; + size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start; + + // Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter). + if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; } + + num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start; + TINFL_CR_BEGIN + + bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1; + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1); + counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8)); + if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4))))); + if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); } + } + + do + { + TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1; + if (r->m_type == 0) + { + TINFL_SKIP_BITS(5, num_bits & 7); + for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); } + if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); } + while ((counter) && (num_bits)) + { + TINFL_GET_BITS(51, dist, 8); + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)dist; + counter--; + } + while (counter) + { + size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); } + while (pIn_buf_cur >= pIn_buf_end) + { + if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) + { + TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT); + } + else + { + TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED); + } + } + n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter); + TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n; + } + } + else if (r->m_type == 3) + { + TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED); + } + else + { + if (r->m_type == 1) + { + mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i; + r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); + for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8; + } + else + { + for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; } + MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; } + r->m_table_sizes[2] = 19; + } + for ( ; (int)r->m_type >= 0; r->m_type--) + { + int tree_next, tree_cur; tinfl_huff_table *pTable; + mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree); + for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++; + used_syms = 0, total = 0; next_code[0] = next_code[1] = 0; + for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); } + if ((65536 != total) && (used_syms > 1)) + { + TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED); + } + for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) + { + mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue; + cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1); + if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; } + if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } + rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1); + for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) + { + tree_cur -= ((rev_code >>= 1) & 1); + if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1]; + } + tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; + } + if (r->m_type == 2) + { + for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); ) + { + mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; } + if ((dist == 16) && (!counter)) + { + TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED); + } + num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16]; + TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s; + } + if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) + { + TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); + } + TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); + } + } + for ( ; ; ) + { + mz_uint8 *pSrc; + for ( ; ; ) + { + if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) + { + TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); + if (counter >= 256) + break; + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = (mz_uint8)counter; + } + else + { + int sym2; mz_uint code_len; +#if TINFL_USE_64BIT_BITBUF + if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; } +#else + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + counter = sym2; bit_buf >>= code_len; num_bits -= code_len; + if (counter & 256) + break; + +#if !TINFL_USE_64BIT_BITBUF + if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; } +#endif + if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) + code_len = sym2 >> 9; + else + { + code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0); + } + bit_buf >>= code_len; num_bits -= code_len; + + pOut_buf_cur[0] = (mz_uint8)counter; + if (sym2 & 256) + { + pOut_buf_cur++; + counter = sym2; + break; + } + pOut_buf_cur[1] = (mz_uint8)sym2; + pOut_buf_cur += 2; + } + } + if ((counter &= 511) == 256) break; + + num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; } + + TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); + num_extra = s_dist_extra[dist]; dist = s_dist_base[dist]; + if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; } + + dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start; + if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) + { + TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED); + } + + pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask); + + if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) + { + while (counter--) + { + while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); } + *pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask]; + } + continue; + } +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + else if ((counter >= 9) && (counter <= dist)) + { + const mz_uint8 *pSrc_end = pSrc + (counter & ~7); + do + { + ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0]; + ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1]; + pOut_buf_cur += 8; + } while ((pSrc += 8) < pSrc_end); + if ((counter &= 7) < 3) + { + if (counter) + { + pOut_buf_cur[0] = pSrc[0]; + if (counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + continue; + } + } +#endif + do + { + pOut_buf_cur[0] = pSrc[0]; + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur[2] = pSrc[2]; + pOut_buf_cur += 3; pSrc += 3; + } while ((int)(counter -= 3) > 2); + if ((int)counter > 0) + { + pOut_buf_cur[0] = pSrc[0]; + if ((int)counter > 1) + pOut_buf_cur[1] = pSrc[1]; + pOut_buf_cur += counter; + } + } + } + } while (!(r->m_final & 1)); + if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) + { + TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; } + } + TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE); + TINFL_CR_FINISH + +common_exit: + r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start; + *pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next; + if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0)) + { + const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size; + mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552; + while (buf_len) + { + for (i = 0; i + 7 < block_len; i += 8, ptr += 8) + { + s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1; + s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1; + } + for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1; + s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552; + } + r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH; + } + return status; +} + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic pop +#endif + +// Higher level helper functions. +void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0; + *pOut_len = 0; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size, + (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + src_buf_ofs += src_buf_size; + *pOut_len += dst_buf_size; + if (status == TINFL_STATUS_DONE) break; + new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128; + pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity); + if (!pNew_buf) + { + MZ_FREE(pBuf); *pOut_len = 0; return NULL; + } + pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity; + } + return pBuf; +} + +size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp); + status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF); + return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len; +} + +int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + int result = 0; + tinfl_decompressor decomp; + mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0; + if (!pDict) + return TINFL_STATUS_FAILED; + tinfl_init(&decomp); + for ( ; ; ) + { + size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs; + tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size, + (flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))); + in_buf_ofs += in_buf_size; + if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user))) + break; + if (status != TINFL_STATUS_HAS_MORE_OUTPUT) + { + result = (status == TINFL_STATUS_DONE); + break; + } + dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1); + } + MZ_FREE(pDict); + *pIn_buf_size = in_buf_ofs; + return result; +} + +// ------------------- Low-level Compression (independent from all decompression API's) + +// Purposely making these tables static for faster init and thread safety. +static const mz_uint16 s_tdefl_len_sym[256] = { + 257,258,259,260,261,262,263,264,265,265,266,266,267,267,268,268,269,269,269,269,270,270,270,270,271,271,271,271,272,272,272,272, + 273,273,273,273,273,273,273,273,274,274,274,274,274,274,274,274,275,275,275,275,275,275,275,275,276,276,276,276,276,276,276,276, + 277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,277,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278, + 279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,279,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280,280, + 281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281,281, + 282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282,282, + 283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283,283, + 284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,284,285 }; + +static const mz_uint8 s_tdefl_len_extra[256] = { + 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, + 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0 }; + +static const mz_uint8 s_tdefl_small_dist_sym[512] = { + 0,1,2,3,4,4,5,5,6,6,6,6,7,7,7,7,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,11,11,11,11,11,11, + 11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, + 14,14,14,14,14,14,14,14,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, + 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, + 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17, + 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 }; + +static const mz_uint8 s_tdefl_small_dist_extra[512] = { + 0,0,0,0,1,1,1,1,2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7 }; + +static const mz_uint8 s_tdefl_large_dist_sym[128] = { + 0,0,18,19,20,20,21,21,22,22,22,22,23,23,23,23,24,24,24,24,24,24,24,24,25,25,25,25,25,25,25,25,26,26,26,26,26,26,26,26,26,26,26,26, + 26,26,26,26,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28, + 28,28,28,28,28,28,28,28,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 }; + +static const mz_uint8 s_tdefl_large_dist_extra[128] = { + 0,0,8,8,9,9,9,9,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, + 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, + 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 }; + +// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted values. +typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq; +static tdefl_sym_freq* tdefl_radix_sort_syms(mz_uint num_syms, tdefl_sym_freq* pSyms0, tdefl_sym_freq* pSyms1) +{ + mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2]; tdefl_sym_freq* pCur_syms = pSyms0, *pNew_syms = pSyms1; MZ_CLEAR_OBJ(hist); + for (i = 0; i < num_syms; i++) { mz_uint freq = pSyms0[i].m_key; hist[freq & 0xFF]++; hist[256 + ((freq >> 8) & 0xFF)]++; } + while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256])) total_passes--; + for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) + { + const mz_uint32* pHist = &hist[pass << 8]; + mz_uint offsets[256], cur_ofs = 0; + for (i = 0; i < 256; i++) { offsets[i] = cur_ofs; cur_ofs += pHist[i]; } + for (i = 0; i < num_syms; i++) pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] = pCur_syms[i]; + { tdefl_sym_freq* t = pCur_syms; pCur_syms = pNew_syms; pNew_syms = t; } + } + return pCur_syms; +} + +// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat, alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996. +static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) +{ + int root, leaf, next, avbl, used, dpth; + if (n==0) return; else if (n==1) { A[0].m_key = 1; return; } + A[0].m_key += A[1].m_key; root = 0; leaf = 2; + for (next=1; next < n-1; next++) + { + if (leaf>=n || A[root].m_key=n || (root=0; next--) A[next].m_key = A[A[next].m_key].m_key+1; + avbl = 1; used = dpth = 0; root = n-2; next = n-1; + while (avbl>0) + { + while (root>=0 && (int)A[root].m_key==dpth) { used++; root--; } + while (avbl>used) { A[next--].m_key = (mz_uint16)(dpth); avbl--; } + avbl = 2*used; dpth++; used = 0; + } +} + +// Limits canonical Huffman code table's max code size. +enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 }; +static void tdefl_huffman_enforce_max_code_size(int *pNum_codes, int code_list_len, int max_code_size) +{ + int i; mz_uint32 total = 0; if (code_list_len <= 1) return; + for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++) pNum_codes[max_code_size] += pNum_codes[i]; + for (i = max_code_size; i > 0; i--) total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i)); + while (total != (1UL << max_code_size)) + { + pNum_codes[max_code_size]--; + for (i = max_code_size - 1; i > 0; i--) if (pNum_codes[i]) { pNum_codes[i]--; pNum_codes[i + 1] += 2; break; } + total--; + } +} + +static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num, int table_len, int code_size_limit, int static_table) +{ + int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE]; mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1]; MZ_CLEAR_OBJ(num_codes); + if (static_table) + { + for (i = 0; i < table_len; i++) num_codes[d->m_huff_code_sizes[table_num][i]]++; + } + else + { + tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS], *pSyms; + int num_used_syms = 0; + const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0]; + for (i = 0; i < table_len; i++) if (pSym_count[i]) { syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i]; syms0[num_used_syms++].m_sym_index = (mz_uint16)i; } + + pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1); tdefl_calculate_minimum_redundancy(pSyms, num_used_syms); + + for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++; + + tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms, code_size_limit); + + MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]); MZ_CLEAR_OBJ(d->m_huff_codes[table_num]); + for (i = 1, j = num_used_syms; i <= code_size_limit; i++) + for (l = num_codes[i]; l > 0; l--) d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i); + } + + next_code[1] = 0; for (j = 0, i = 2; i <= code_size_limit; i++) next_code[i] = j = ((j + num_codes[i - 1]) << 1); + + for (i = 0; i < table_len; i++) + { + mz_uint rev_code = 0, code, code_size; if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue; + code = next_code[code_size]++; for (l = code_size; l > 0; l--, code >>= 1) rev_code = (rev_code << 1) | (code & 1); + d->m_huff_codes[table_num][i] = (mz_uint16)rev_code; + } +} + +#define TDEFL_PUT_BITS(b, l) do { \ + mz_uint bits = b; mz_uint len = l; MZ_ASSERT(bits <= ((1U << len) - 1U)); \ + d->m_bit_buffer |= (bits << d->m_bits_in); d->m_bits_in += len; \ + while (d->m_bits_in >= 8) { \ + if (d->m_pOutput_buf < d->m_pOutput_buf_end) \ + *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \ + d->m_bit_buffer >>= 8; \ + d->m_bits_in -= 8; \ + } \ +} MZ_MACRO_END + +#define TDEFL_RLE_PREV_CODE_SIZE() { if (rle_repeat_count) { \ + if (rle_repeat_count < 3) { \ + d->m_huff_count[2][prev_code_size] = (mz_uint16)(d->m_huff_count[2][prev_code_size] + rle_repeat_count); \ + while (rle_repeat_count--) packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \ + } else { \ + d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); packed_code_sizes[num_packed_code_sizes++] = 16; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_repeat_count - 3); \ +} rle_repeat_count = 0; } } + +#define TDEFL_RLE_ZERO_CODE_SIZE() { if (rle_z_count) { \ + if (rle_z_count < 3) { \ + d->m_huff_count[2][0] = (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \ + } else if (rle_z_count <= 10) { \ + d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); packed_code_sizes[num_packed_code_sizes++] = 17; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 3); \ + } else { \ + d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); packed_code_sizes[num_packed_code_sizes++] = 18; packed_code_sizes[num_packed_code_sizes++] = (mz_uint8)(rle_z_count - 11); \ +} rle_z_count = 0; } } + +static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; + +static void tdefl_start_dynamic_block(tdefl_compressor *d) +{ + int num_lit_codes, num_dist_codes, num_bit_lengths; mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count, rle_repeat_count, packed_code_sizes_index; + mz_uint8 code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1], prev_code_size = 0xFF; + + d->m_huff_count[0][256] = 1; + + tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE); + tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE); + + for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--) if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break; + for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--) if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break; + + memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes); + memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0], num_dist_codes); + total_code_sizes_to_pack = num_lit_codes + num_dist_codes; num_packed_code_sizes = 0; rle_z_count = 0; rle_repeat_count = 0; + + memset(&d->m_huff_count[2][0], 0, sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2); + for (i = 0; i < total_code_sizes_to_pack; i++) + { + mz_uint8 code_size = code_sizes_to_pack[i]; + if (!code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + if (++rle_z_count == 138) { TDEFL_RLE_ZERO_CODE_SIZE(); } + } + else + { + TDEFL_RLE_ZERO_CODE_SIZE(); + if (code_size != prev_code_size) + { + TDEFL_RLE_PREV_CODE_SIZE(); + d->m_huff_count[2][code_size] = (mz_uint16)(d->m_huff_count[2][code_size] + 1); packed_code_sizes[num_packed_code_sizes++] = code_size; + } + else if (++rle_repeat_count == 6) + { + TDEFL_RLE_PREV_CODE_SIZE(); + } + } + prev_code_size = code_size; + } + if (rle_repeat_count) { TDEFL_RLE_PREV_CODE_SIZE(); } else { TDEFL_RLE_ZERO_CODE_SIZE(); } + + tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE); + + TDEFL_PUT_BITS(2, 2); + + TDEFL_PUT_BITS(num_lit_codes - 257, 5); + TDEFL_PUT_BITS(num_dist_codes - 1, 5); + + for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--) if (d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]]) break; + num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1)); TDEFL_PUT_BITS(num_bit_lengths - 4, 4); + for (i = 0; (int)i < num_bit_lengths; i++) TDEFL_PUT_BITS(d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3); + + for (packed_code_sizes_index = 0; packed_code_sizes_index < num_packed_code_sizes; ) + { + mz_uint code = packed_code_sizes[packed_code_sizes_index++]; MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2); + TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]); + if (code >= 16) TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++], "\02\03\07"[code - 16]); + } +} + +static void tdefl_start_static_block(tdefl_compressor *d) +{ + mz_uint i; + mz_uint8 *p = &d->m_huff_code_sizes[0][0]; + + for (i = 0; i <= 143; ++i) *p++ = 8; + for ( ; i <= 255; ++i) *p++ = 9; + for ( ; i <= 279; ++i) *p++ = 7; + for ( ; i <= 287; ++i) *p++ = 8; + + memset(d->m_huff_code_sizes[1], 5, 32); + + tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE); + tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE); + + TDEFL_PUT_BITS(1, 2); +} + +static const mz_uint mz_bitmasks[17] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF }; + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + mz_uint8 *pOutput_buf = d->m_pOutput_buf; + mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf; + mz_uint64 bit_buffer = d->m_bit_buffer; + mz_uint bits_in = d->m_bits_in; + +#define TDEFL_PUT_BITS_FAST(b, l) { bit_buffer |= (((mz_uint64)(b)) << bits_in); bits_in += (l); } + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + + if (flags & 1) + { + mz_uint s0, s1, n0, n1, sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = *(const mz_uint16 *)(pLZ_codes + 1); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + // This sequence coaxes MSVC into using cmov's vs. jmp's. + s0 = s_tdefl_small_dist_sym[match_dist & 511]; + n0 = s_tdefl_small_dist_extra[match_dist & 511]; + s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + n1 = s_tdefl_large_dist_extra[match_dist >> 8]; + sym = (match_dist < 512) ? s0 : s1; + num_extra_bits = (match_dist < 512) ? n0 : n1; + + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + + if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) + { + flags >>= 1; + lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + } + + if (pOutput_buf >= d->m_pOutput_buf_end) + return MZ_FALSE; + + *(mz_uint64*)pOutput_buf = bit_buffer; + pOutput_buf += (bits_in >> 3); + bit_buffer >>= (bits_in & ~7); + bits_in &= 7; + } + +#undef TDEFL_PUT_BITS_FAST + + d->m_pOutput_buf = pOutput_buf; + d->m_bits_in = 0; + d->m_bit_buffer = 0; + + while (bits_in) + { + mz_uint32 n = MZ_MIN(bits_in, 16); + TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n); + bit_buffer >>= n; + bits_in -= n; + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#else +static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) +{ + mz_uint flags; + mz_uint8 *pLZ_codes; + + flags = 1; + for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf; flags >>= 1) + { + if (flags == 1) + flags = *pLZ_codes++ | 0x100; + if (flags & 1) + { + mz_uint sym, num_extra_bits; + mz_uint match_len = pLZ_codes[0], match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8)); pLZ_codes += 3; + + MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]], d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]); + TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]], s_tdefl_len_extra[match_len]); + + if (match_dist < 512) + { + sym = s_tdefl_small_dist_sym[match_dist]; num_extra_bits = s_tdefl_small_dist_extra[match_dist]; + } + else + { + sym = s_tdefl_large_dist_sym[match_dist >> 8]; num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8]; + } + MZ_ASSERT(d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]); + TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits); + } + else + { + mz_uint lit = *pLZ_codes++; + MZ_ASSERT(d->m_huff_code_sizes[0][lit]); + TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]); + } + } + + TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]); + + return (d->m_pOutput_buf < d->m_pOutput_buf_end); +} +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && MINIZ_HAS_64BIT_REGISTERS + +static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) +{ + if (static_block) + tdefl_start_static_block(d); + else + tdefl_start_dynamic_block(d); + return tdefl_compress_lz_codes(d); +} + +static int tdefl_flush_block(tdefl_compressor *d, int flush) +{ + mz_uint saved_bit_buf, saved_bits_in; + mz_uint8 *pSaved_output_buf; + mz_bool comp_block_succeeded = MZ_FALSE; + int n, use_raw_block = ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) && (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size; + mz_uint8 *pOutput_buf_start = ((d->m_pPut_buf_func == NULL) && ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE)) ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs) : d->m_output_buf; + + d->m_pOutput_buf = pOutput_buf_start; + d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16; + + MZ_ASSERT(!d->m_output_flush_remaining); + d->m_output_flush_ofs = 0; + d->m_output_flush_remaining = 0; + + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left); + d->m_pLZ_code_buf -= (d->m_num_flags_left == 8); + + if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) + { + TDEFL_PUT_BITS(0x78, 8); TDEFL_PUT_BITS(0x01, 8); + } + + TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1); + + pSaved_output_buf = d->m_pOutput_buf; saved_bit_buf = d->m_bit_buffer; saved_bits_in = d->m_bits_in; + + if (!use_raw_block) + comp_block_succeeded = tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) || (d->m_total_lz_bytes < 48)); + + // If the block gets expanded, forget the current contents of the output buffer and send a raw block instead. + if ( ((use_raw_block) || ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >= d->m_total_lz_bytes))) && + ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size) ) + { + mz_uint i; d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + TDEFL_PUT_BITS(0, 2); + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) + { + TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16); + } + for (i = 0; i < d->m_total_lz_bytes; ++i) + { + TDEFL_PUT_BITS(d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK], 8); + } + } + // Check for the extremely unlikely (if not impossible) case of the compressed block not fitting into the output buffer when using dynamic codes. + else if (!comp_block_succeeded) + { + d->m_pOutput_buf = pSaved_output_buf; d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in; + tdefl_compress_block(d, MZ_TRUE); + } + + if (flush) + { + if (flush == TDEFL_FINISH) + { + if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } + if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) { mz_uint i, a = d->m_adler32; for (i = 0; i < 4; i++) { TDEFL_PUT_BITS((a >> 24) & 0xFF, 8); a <<= 8; } } + } + else + { + mz_uint i, z = 0; TDEFL_PUT_BITS(0, 3); if (d->m_bits_in) { TDEFL_PUT_BITS(0, 8 - d->m_bits_in); } for (i = 2; i; --i, z ^= 0xFFFF) { TDEFL_PUT_BITS(z & 0xFFFF, 16); } + } + } + + MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end); + + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes; d->m_total_lz_bytes = 0; d->m_block_index++; + + if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) + { + if (d->m_pPut_buf_func) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user)) + return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED); + } + else if (pOutput_buf_start == d->m_output_buf) + { + int bytes_to_copy = (int)MZ_MIN((size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs)); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf, bytes_to_copy); + d->m_out_buf_ofs += bytes_to_copy; + if ((n -= bytes_to_copy) != 0) + { + d->m_output_flush_ofs = bytes_to_copy; + d->m_output_flush_remaining = n; + } + } + else + { + d->m_out_buf_ofs += n; + } + } + + return d->m_output_flush_remaining; +} + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" + +#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16*)(p) +static __forceinline void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) + +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint16 *s = (const mz_uint16*)(d->m_dict + pos), *p, *q; + mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]), s01 = TDEFL_READ_UNALIGNED_WORD(s); + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + if (!probe_len) + { + *pMatch_dist = dist; *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN); break; + } + else if ((probe_len = ((mz_uint)(p - s) * 2) + (mz_uint)(*(const mz_uint8*)p == *(const mz_uint8*)q)) > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) == max_match_len) break; + c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]); + } + } +} + +#pragma GCC diagnostic pop + +#else + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmisleading-indentation" +#endif + +static __forceinline void tdefl_find_match(tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist, mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) +{ + mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK, match_len = *pMatch_len, probe_pos = pos, next_probe_pos, probe_len; + mz_uint num_probes_left = d->m_max_probes[match_len >= 32]; + const mz_uint8 *s = d->m_dict + pos, *p, *q; + mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1]; + MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN); if (max_match_len <= match_len) return; + for ( ; ; ) + { + for ( ; ; ) + { + if (--num_probes_left == 0) return; + #define TDEFL_PROBE \ + next_probe_pos = d->m_next[probe_pos]; \ + if ((!next_probe_pos) || ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) return; \ + probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \ + if ((d->m_dict[probe_pos + match_len] == c0) && (d->m_dict[probe_pos + match_len - 1] == c1)) break; + TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE; + } + if (!dist) break; p = s; q = d->m_dict + probe_pos; for (probe_len = 0; probe_len < max_match_len; probe_len++) if (*p++ != *q++) break; + if (probe_len > match_len) + { + *pMatch_dist = dist; if ((*pMatch_len = match_len = probe_len) == max_match_len) return; + c0 = d->m_dict[pos + match_len]; c1 = d->m_dict[pos + match_len - 1]; + } + } +} + +#if defined(__aarch64__) || defined(__arm__) +#pragma GCC diagnostic pop +#endif + +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +static mz_bool tdefl_compress_fast(tdefl_compressor *d) +{ + // Faster, minimally featured LZRW1-style match+parse loop with better register utilization. Intended for applications where raw throughput is valued more highly than ratio. + mz_uint lookahead_pos = d->m_lookahead_pos, lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size, total_lz_bytes = d->m_total_lz_bytes, num_flags_left = d->m_num_flags_left; + mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags; + mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + + while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) + { + const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096; + mz_uint dst_pos = (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size); + d->m_src_buf_left -= num_bytes_to_process; + lookahead_size += num_bytes_to_process; + + while (num_bytes_to_process) + { + mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process); + memcpy(d->m_dict + dst_pos, d->m_pSrc, n); + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc, MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos)); + d->m_pSrc += n; + dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK; + num_bytes_to_process -= n; + } + + dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size); + if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE)) break; + + while (lookahead_size >= 4) + { + mz_uint cur_match_dist, cur_match_len = 1; + mz_uint8 *pCur_dict = d->m_dict + cur_pos; + mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF; + mz_uint hash = (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) & TDEFL_LEVEL1_HASH_SIZE_MASK; + mz_uint probe_pos = d->m_hash[hash]; + d->m_hash[hash] = (mz_uint16)lookahead_pos; + + if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <= dict_size) && ((*(const mz_uint32 *)(d->m_dict + (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) & 0xFFFFFF) == first_trigram)) + { + const mz_uint16 *p = (const mz_uint16 *)pCur_dict; + const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos); + mz_uint32 probe_len = 32; + do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && + (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) ); + cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) + (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q); + if (!probe_len) + cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0; + + if ((cur_match_len < TDEFL_MIN_MATCH_LEN) || ((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U))) + { + cur_match_len = 1; + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + else + { + mz_uint32 s0, s1; + cur_match_len = MZ_MIN(cur_match_len, lookahead_size); + + MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 1) && (cur_match_dist <= TDEFL_LZ_DICT_SIZE)); + + cur_match_dist--; + + pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN); + *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist; + pLZ_code_buf += 3; + *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80); + + s0 = s_tdefl_small_dist_sym[cur_match_dist & 511]; + s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8]; + d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[cur_match_len - TDEFL_MIN_MATCH_LEN]]++; + } + } + else + { + *pLZ_code_buf++ = (mz_uint8)first_trigram; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + d->m_huff_count[0][(mz_uint8)first_trigram]++; + } + + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + total_lz_bytes += cur_match_len; + lookahead_pos += cur_match_len; + dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK; + MZ_ASSERT(lookahead_size >= cur_match_len); + lookahead_size -= cur_match_len; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + + while (lookahead_size) + { + mz_uint8 lit = d->m_dict[cur_pos]; + + total_lz_bytes++; + *pLZ_code_buf++ = lit; + *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1); + if (--num_flags_left == 0) { num_flags_left = 8; pLZ_flags = pLZ_code_buf++; } + + d->m_huff_count[0][lit]++; + + lookahead_pos++; + dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE); + cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; + lookahead_size--; + + if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) + { + int n; + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + total_lz_bytes = d->m_total_lz_bytes; pLZ_code_buf = d->m_pLZ_code_buf; pLZ_flags = d->m_pLZ_flags; num_flags_left = d->m_num_flags_left; + } + } + } + + d->m_lookahead_pos = lookahead_pos; d->m_lookahead_size = lookahead_size; d->m_dict_size = dict_size; + d->m_total_lz_bytes = total_lz_bytes; d->m_pLZ_code_buf = pLZ_code_buf; d->m_pLZ_flags = pLZ_flags; d->m_num_flags_left = num_flags_left; + return MZ_TRUE; +} +#pragma GCC diagnostic pop +#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + +static __forceinline void tdefl_record_literal(tdefl_compressor *d, mz_uint8 lit) +{ + d->m_total_lz_bytes++; + *d->m_pLZ_code_buf++ = lit; + *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + d->m_huff_count[0][lit]++; +} + +static __forceinline void tdefl_record_match(tdefl_compressor *d, mz_uint match_len, mz_uint match_dist) +{ + mz_uint32 s0, s1; + + MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) && (match_dist <= TDEFL_LZ_DICT_SIZE)); + + d->m_total_lz_bytes += match_len; + + d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN); + + match_dist -= 1; + d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF); + d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8); d->m_pLZ_code_buf += 3; + + *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80); if (--d->m_num_flags_left == 0) { d->m_num_flags_left = 8; d->m_pLZ_flags = d->m_pLZ_code_buf++; } + + s0 = s_tdefl_small_dist_sym[match_dist & 511]; s1 = s_tdefl_large_dist_sym[match_dist >> 8]; + d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++; + + d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++; +} + +static mz_bool tdefl_compress_normal(tdefl_compressor *d) +{ + const mz_uint8 *pSrc = d->m_pSrc; size_t src_buf_left = d->m_src_buf_left; + tdefl_flush flush = d->m_flush; + + while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) + { + mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos; + // Update dictionary and hash chains. Keeps the lookahead size equal to TDEFL_MAX_MATCH_LEN. + if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) + { + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK, ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2; + mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]; + mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size); + const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process; + src_buf_left -= num_bytes_to_process; + d->m_lookahead_size += num_bytes_to_process; + while (pSrc != pSrc_end) + { + mz_uint8 c = *pSrc++; d->m_dict[dst_pos] = c; if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK; ins_pos++; + } + } + else + { + while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + { + mz_uint8 c = *pSrc++; + mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK; + src_buf_left--; + d->m_dict[dst_pos] = c; + if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1)) + d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c; + if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) + { + mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2; + mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] << (TDEFL_LZ_HASH_SHIFT * 2)) ^ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK] << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1); + d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash]; d->m_hash[hash] = (mz_uint16)(ins_pos); + } + } + } + d->m_dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size); + if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) + break; + + // Simple lazy/greedy parsing state machine. + len_to_move = 1; cur_match_dist = 0; cur_match_len = d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1); cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK; + if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) + { + if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) + { + mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK]; + cur_match_len = 0; while (cur_match_len < d->m_lookahead_size) { if (d->m_dict[cur_pos + cur_match_len] != c) break; cur_match_len++; } + if (cur_match_len < TDEFL_MIN_MATCH_LEN) cur_match_len = 0; else cur_match_dist = 1; + } + } + else + { + tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size, d->m_lookahead_size, &cur_match_dist, &cur_match_len); + } + if (((cur_match_len == TDEFL_MIN_MATCH_LEN) && (cur_match_dist >= 8U*1024U)) || (cur_pos == cur_match_dist) || ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) + { + cur_match_dist = cur_match_len = 0; + } + if (d->m_saved_match_len) + { + if (cur_match_len > d->m_saved_match_len) + { + tdefl_record_literal(d, (mz_uint8)d->m_saved_lit); + if (cur_match_len >= 128) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + d->m_saved_match_len = 0; len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + } + else + { + tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist); + len_to_move = d->m_saved_match_len - 1; d->m_saved_match_len = 0; + } + } + else if (!cur_match_dist) + tdefl_record_literal(d, d->m_dict[cur_pos]); + else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) || (cur_match_len >= 128)) + { + tdefl_record_match(d, cur_match_len, cur_match_dist); + len_to_move = cur_match_len; + } + else + { + d->m_saved_lit = d->m_dict[cur_pos]; d->m_saved_match_dist = cur_match_dist; d->m_saved_match_len = cur_match_len; + } + // Move the lookahead forward by len_to_move bytes. + d->m_lookahead_pos += len_to_move; + MZ_ASSERT(d->m_lookahead_size >= len_to_move); + d->m_lookahead_size -= len_to_move; + d->m_dict_size = MZ_MIN(d->m_dict_size + len_to_move, TDEFL_LZ_DICT_SIZE); + // Check if it's time to flush the current LZ codes to the internal output buffer. + if ( (d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) || + ( (d->m_total_lz_bytes > 31*1024) && (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >= d->m_total_lz_bytes) || (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) ) + { + int n; + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + if ((n = tdefl_flush_block(d, 0)) != 0) + return (n < 0) ? MZ_FALSE : MZ_TRUE; + } + } + + d->m_pSrc = pSrc; d->m_src_buf_left = src_buf_left; + return MZ_TRUE; +} + +static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) +{ + if (d->m_pIn_buf_size) + { + *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf; + } + + if (d->m_pOut_buf_size) + { + size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs, d->m_output_flush_remaining); + memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf + d->m_output_flush_ofs, n); + d->m_output_flush_ofs += (mz_uint)n; + d->m_output_flush_remaining -= (mz_uint)n; + d->m_out_buf_ofs += n; + + *d->m_pOut_buf_size = d->m_out_buf_ofs; + } + + return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE : TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf, size_t *pIn_buf_size, void *pOut_buf, size_t *pOut_buf_size, tdefl_flush flush) +{ + if (!d) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return TDEFL_STATUS_BAD_PARAM; + } + + d->m_pIn_buf = pIn_buf; d->m_pIn_buf_size = pIn_buf_size; + d->m_pOut_buf = pOut_buf; d->m_pOut_buf_size = pOut_buf_size; + d->m_pSrc = (const mz_uint8 *)(pIn_buf); d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0; + d->m_out_buf_ofs = 0; + d->m_flush = flush; + + if ( ((d->m_pPut_buf_func != NULL) == ((pOut_buf != NULL) || (pOut_buf_size != NULL))) || (d->m_prev_return_status != TDEFL_STATUS_OKAY) || + (d->m_wants_to_finish && (flush != TDEFL_FINISH)) || (pIn_buf_size && *pIn_buf_size && !pIn_buf) || (pOut_buf_size && *pOut_buf_size && !pOut_buf) ) + { + if (pIn_buf_size) *pIn_buf_size = 0; + if (pOut_buf_size) *pOut_buf_size = 0; + return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM); + } + d->m_wants_to_finish |= (flush == TDEFL_FINISH); + + if ((d->m_output_flush_remaining) || (d->m_finished)) + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); + +#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) && + ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) && + ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS | TDEFL_RLE_MATCHES)) == 0)) + { + if (!tdefl_compress_fast(d)) + return d->m_prev_return_status; + } + else +#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN + { + if (!tdefl_compress_normal(d)) + return d->m_prev_return_status; + } + + if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) && (pIn_buf)) + d->m_adler32 = (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if (d->m_flags & TDEFL_COMPUTE_CRC32) + d->m_crc32 = (mz_uint32)mz_crc32(d->m_crc32, (const mz_uint8 *)pIn_buf, d->m_pSrc - (const mz_uint8 *)pIn_buf); + + if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) && (!d->m_output_flush_remaining)) + { + if (tdefl_flush_block(d, flush) < 0) + return d->m_prev_return_status; + d->m_finished = (flush == TDEFL_FINISH); + if (flush == TDEFL_FULL_FLUSH) { MZ_CLEAR_OBJ(d->m_hash); MZ_CLEAR_OBJ(d->m_next); d->m_dict_size = 0; } + } + + return (d->m_prev_return_status = tdefl_flush_output_buffer(d)); +} + +tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf, size_t in_buf_size, tdefl_flush flush) +{ + MZ_ASSERT(d->m_pPut_buf_func); return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush); +} + +tdefl_status tdefl_init(tdefl_compressor *d, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + d->m_pPut_buf_func = pPut_buf_func; d->m_pPut_buf_user = pPut_buf_user; + d->m_flags = (mz_uint)(flags); d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3; d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0; + d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3; + if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash); + d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size = d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0; + d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished = d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0; + d->m_pLZ_code_buf = d->m_lz_code_buf + 1; d->m_pLZ_flags = d->m_lz_code_buf; d->m_num_flags_left = 8; + d->m_pOutput_buf = d->m_output_buf; d->m_pOutput_buf_end = d->m_output_buf; d->m_prev_return_status = TDEFL_STATUS_OKAY; + d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0; d->m_adler32 = 1; d->m_crc32 = 1; + d->m_pIn_buf = NULL; d->m_pOut_buf = NULL; + d->m_pIn_buf_size = NULL; d->m_pOut_buf_size = NULL; + d->m_flush = TDEFL_NO_FLUSH; d->m_pSrc = NULL; d->m_src_buf_left = 0; d->m_out_buf_ofs = 0; + memset(&d->m_huff_count[0][0], 0, sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0); + memset(&d->m_huff_count[1][0], 0, sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1); + return TDEFL_STATUS_OKAY; +} + +tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) +{ + return d->m_prev_return_status; +} + +mz_uint32 tdefl_get_adler32(tdefl_compressor *d) +{ + return d->m_adler32; +} + +mz_uint32 tdefl_get_crc32(tdefl_compressor *d) +{ + return d->m_crc32; +} + +mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len, tdefl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags) +{ + tdefl_compressor *pComp; mz_bool succeeded; if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE; + pComp = (tdefl_compressor*)MZ_MALLOC(sizeof(tdefl_compressor)); if (!pComp) return MZ_FALSE; + succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) == TDEFL_STATUS_OKAY); + succeeded = succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) == TDEFL_STATUS_DONE); + MZ_FREE(pComp); return succeeded; +} + +typedef struct +{ + size_t m_size, m_capacity; + mz_uint8 *m_pBuf; + mz_bool m_expandable; +} tdefl_output_buffer; + +static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len, void *pUser) +{ + tdefl_output_buffer *p = (tdefl_output_buffer *)pUser; + size_t new_size = p->m_size + len; + if (new_size > p->m_capacity) + { + size_t new_capacity = p->m_capacity; mz_uint8 *pNew_buf; if (!p->m_expandable) return MZ_FALSE; + do { new_capacity = MZ_MAX(128U, new_capacity << 1U); } while (new_size > new_capacity); + pNew_buf = (mz_uint8*)MZ_REALLOC(p->m_pBuf, new_capacity); if (!pNew_buf) return MZ_FALSE; + p->m_pBuf = pNew_buf; p->m_capacity = new_capacity; + } + memcpy((mz_uint8*)p->m_pBuf + p->m_size, pBuf, len); p->m_size = new_size; + return MZ_TRUE; +} + +void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_len) return MZ_FALSE; else *pOut_len = 0; + out_buf.m_expandable = MZ_TRUE; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return NULL; + *pOut_len = out_buf.m_size; return out_buf.m_pBuf; +} + +size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags) +{ + tdefl_output_buffer out_buf; MZ_CLEAR_OBJ(out_buf); + if (!pOut_buf) return 0; + out_buf.m_pBuf = (mz_uint8*)pOut_buf; out_buf.m_capacity = out_buf_len; + if (!tdefl_compress_mem_to_output(pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags)) return 0; + return out_buf.m_size; +} + +static const mz_uint s_tdefl_num_probes[11] = { 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500 }; + +// level may actually range from [0,10] (10 is a "hidden" max level, where we want a bit more compression and it's fine if throughput to fall off a cliff on some files). +mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits, int strategy) +{ + mz_uint comp_flags = s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] | ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); + if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER; + + if (!level) comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; + else if (strategy == MZ_FILTERED) comp_flags |= TDEFL_FILTER_MATCHES; + else if (strategy == MZ_HUFFMAN_ONLY) comp_flags &= ~TDEFL_MAX_PROBES_MASK; + else if (strategy == MZ_FIXED) comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS; + else if (strategy == MZ_RLE) comp_flags |= TDEFL_RLE_MATCHES; + + return comp_flags; +} + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable:4204) // nonstandard extension used : non-constant aggregate initializer (also supported by GNU C and C99, so no big deal) +#endif + +// Simple PNG writer function by Alex Evans, 2011. Released into the public domain: https://gist.github.com/908299, more context at +// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/. +void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h, int num_chans, size_t *pLen_out) +{ + tdefl_compressor *pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor)); tdefl_output_buffer out_buf; int i, bpl = w * num_chans, y, z; mz_uint32 c; *pLen_out = 0; + if (!pComp) return NULL; + MZ_CLEAR_OBJ(out_buf); out_buf.m_expandable = MZ_TRUE; out_buf.m_capacity = 57+MZ_MAX(64, (1+bpl)*h); if (NULL == (out_buf.m_pBuf = (mz_uint8*)MZ_MALLOC(out_buf.m_capacity))) { MZ_FREE(pComp); return NULL; } + // write dummy header + for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf); + // compress image data + tdefl_init(pComp, tdefl_output_buffer_putter, &out_buf, TDEFL_DEFAULT_MAX_PROBES | TDEFL_WRITE_ZLIB_HEADER); + for (y = 0; y < h; ++y) { tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH); tdefl_compress_buffer(pComp, (mz_uint8*)pImage + y * bpl, bpl, TDEFL_NO_FLUSH); } + if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) != TDEFL_STATUS_DONE) { MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + // write real header + *pLen_out = out_buf.m_size-41; + { + mz_uint8 pnghdr[41]={0x89,0x50,0x4e,0x47,0x0d,0x0a,0x1a,0x0a,0x00,0x00,0x00,0x0d,0x49,0x48,0x44,0x52, + 0,0,(mz_uint8)(w>>8),(mz_uint8)w,0,0,(mz_uint8)(h>>8),(mz_uint8)h,8,"\0\0\04\02\06"[num_chans],0,0,0,0,0,0,0, + (mz_uint8)(*pLen_out>>24),(mz_uint8)(*pLen_out>>16),(mz_uint8)(*pLen_out>>8),(mz_uint8)*pLen_out,0x49,0x44,0x41,0x54}; + c=(mz_uint32)mz_crc32(MZ_CRC32_INIT,pnghdr+12,17); for (i=0; i<4; ++i, c<<=8) ((mz_uint8*)(pnghdr+29))[i]=(mz_uint8)(c>>24); + memcpy(out_buf.m_pBuf, pnghdr, 41); + } + // write footer (IDAT CRC-32, followed by IEND chunk) + if (!tdefl_output_buffer_putter("\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) { *pLen_out = 0; MZ_FREE(pComp); MZ_FREE(out_buf.m_pBuf); return NULL; } + c = (mz_uint32)mz_crc32(MZ_CRC32_INIT,out_buf.m_pBuf+41-4, *pLen_out+4); for (i=0; i<4; ++i, c<<=8) (out_buf.m_pBuf+out_buf.m_size-16)[i] = (mz_uint8)(c >> 24); + // compute final size of file, grab compressed data buffer and return + *pLen_out += 57; MZ_FREE(pComp); return out_buf.m_pBuf; +} + +#ifdef _MSC_VER +#pragma warning (pop) +#endif + +#pragma GCC diagnostic pop + +#endif // MINIZ_HEADER_FILE_ONLY + +/* + This is free and unencumbered software released into the public domain. + + Anyone is free to copy, modify, publish, use, compile, sell, or + distribute this software, either in source code form or as a compiled + binary, for any purpose, commercial or non-commercial, and by any + means. + + In jurisdictions that recognize copyright laws, the author or authors + of this software dedicate any and all copyright interest in the + software to the public domain. We make this dedication for the benefit + of the public at large and to the detriment of our heirs and + successors. We intend this dedication to be an overt act of + relinquishment in perpetuity of all present and future rights to this + software under copyright law. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + + For more information, please refer to +*/ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.h new file mode 100644 index 00000000..971d34e8 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/miniz.h @@ -0,0 +1,2 @@ +#define MINIZ_HEADER_FILE_ONLY +#include "miniz.c" diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c index 32200f14..14dae6e0 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy.c @@ -31,14 +31,10 @@ #include #include #include -#include #include #include -#ifdef GRUB_MACHINE_EFI -#include -#endif +#include #include -#include #include #include "ventoy_def.h" @@ -46,60 +42,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); int g_ventoy_debug = 0; static int g_efi_os = 0xFF; -initrd_info *g_initrd_img_list = NULL; -initrd_info *g_initrd_img_tail = NULL; -int g_initrd_img_count = 0; -int g_valid_initrd_count = 0; -int g_default_menu_mode = 0; -int g_filt_dot_underscore_file = 0; -static grub_file_t g_old_file; - -char g_iso_path[256]; -char g_img_swap_tmp_buf[1024]; -img_info g_img_swap_tmp; -img_info *g_ventoy_img_list = NULL; - -int g_ventoy_img_count = 0; - -grub_device_t g_enum_dev = NULL; -grub_fs_t g_enum_fs = NULL; -img_iterator_node g_img_iterator_head; -img_iterator_node *g_img_iterator_tail = NULL; - -grub_uint8_t g_ventoy_break_level = 0; -grub_uint8_t g_ventoy_debug_level = 0; -grub_uint8_t g_ventoy_chain_type = 0; - -grub_uint8_t *g_ventoy_cpio_buf = NULL; -grub_uint32_t g_ventoy_cpio_size = 0; -cpio_newc_header *g_ventoy_initrd_head = NULL; -grub_uint8_t *g_ventoy_runtime_buf = NULL; - -ventoy_grub_param *g_grub_param = NULL; - -ventoy_guid g_ventoy_guid = VENTOY_GUID; - -ventoy_img_chunk_list g_img_chunk_list; - -int g_wimboot_enable = 0; -ventoy_img_chunk_list g_wimiso_chunk_list; -char *g_wimiso_path = NULL; - -static char *g_tree_script_buf = NULL; -static int g_tree_script_pos = 0; - -static char *g_list_script_buf = NULL; -static int g_list_script_pos = 0; - -static const char *g_menu_class[] = -{ - "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg" -}; - -static const char *g_menu_prefix[] = -{ - "iso", "wim", "efi", "img" -}; +grub_uint32_t g_ventoy_plat_data; void ventoy_debug(const char *fmt, ...) { @@ -110,6 +53,54 @@ void ventoy_debug(const char *fmt, ...) va_end (args); } +int ventoy_strcmp(const char *pattern, const char *str) +{ + while (*pattern && *str) + { + if ((*pattern != *str) && (*pattern != '*')) + break; + + pattern++; + str++; + } + + return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str; +} + +int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n) +{ + if (n == 0) + return 0; + + while (*pattern && *str && --n) + { + if ((*pattern != *str) && (*pattern != '*')) + break; + + pattern++; + str++; + } + + return (int)(grub_uint8_t)*pattern - (int)(grub_uint8_t)*str; +} + +void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid) +{ + int i; + + if (!g_ventoy_debug) + { + return; + } + + debug("%s", prefix); + for (i = 0; i < 16; i++) + { + grub_printf("%02x ", guid[i]); + } + grub_printf("\n"); +} + int ventoy_is_efi_os(void) { if (g_efi_os > 1) @@ -120,2264 +111,46 @@ int ventoy_is_efi_os(void) return g_efi_os; } -static int ventoy_get_fs_type(const char *fs) +static int ventoy_arch_mode_init(void) { - if (NULL == fs) + #ifdef GRUB_MACHINE_EFI + if (grub_strcmp(GRUB_TARGET_CPU, "i386") == 0) { - return ventoy_fs_max; + g_ventoy_plat_data = VTOY_PLAT_I386_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "ia32"); } - else if (grub_strncmp(fs, "exfat", 5) == 0) + else if (grub_strcmp(GRUB_TARGET_CPU, "arm64") == 0) { - return ventoy_fs_exfat; + g_ventoy_plat_data = VTOY_PLAT_ARM64_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "aa64"); } - else if (grub_strncmp(fs, "ntfs", 4) == 0) + else if (grub_strcmp(GRUB_TARGET_CPU, "mips64el") == 0) { - return ventoy_fs_ntfs; - } - else if (grub_strncmp(fs, "ext", 3) == 0) - { - return ventoy_fs_ext; - } - else if (grub_strncmp(fs, "xfs", 3) == 0) - { - return ventoy_fs_xfs; - } - else if (grub_strncmp(fs, "udf", 3) == 0) - { - return ventoy_fs_udf; - } - else if (grub_strncmp(fs, "fat", 3) == 0) - { - return ventoy_fs_fat; - } - - return ventoy_fs_max; -} - -static int ventoy_string_check(const char *str, grub_char_check_func check) -{ - if (!str) - { - return 0; - } - - for ( ; *str; str++) - { - if (!check(*str)) - { - return 0; - } - } - - return 1; -} - - -static grub_ssize_t ventoy_fs_read(grub_file_t file, char *buf, grub_size_t len) -{ - grub_memcpy(buf, (char *)file->data + file->offset, len); - return len; -} - -static grub_err_t ventoy_fs_close(grub_file_t file) -{ - grub_file_close(g_old_file); - grub_free(file->data); - - file->device = 0; - file->name = 0; - - return 0; -} - -static grub_file_t ventoy_wrapper_open(grub_file_t rawFile, enum grub_file_type type) -{ - int len; - grub_file_t file; - static struct grub_fs vtoy_fs = - { - .name = "vtoy", - .fs_dir = 0, - .fs_open = 0, - .fs_read = ventoy_fs_read, - .fs_close = ventoy_fs_close, - .fs_label = 0, - .next = 0 - }; - - if (type != 52) - { - return rawFile; - } - - file = (grub_file_t)grub_zalloc(sizeof (*file)); - if (!file) - { - return 0; - } - - file->data = grub_malloc(rawFile->size + 4096); - if (!file->data) - { - return 0; - } - - grub_file_read(rawFile, file->data, rawFile->size); - len = ventoy_fill_data(4096, (char *)file->data + rawFile->size); - - g_old_file = rawFile; - - file->size = rawFile->size + len; - file->device = rawFile->device; - file->fs = &vtoy_fs; - file->not_easily_seekable = 1; - - return file; -} - -static int ventoy_check_decimal_var(const char *name, long *value) -{ - const char *value_str = NULL; - - value_str = grub_env_get(name); - if (NULL == value_str) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s not found", name); - } - - if (!ventoy_is_decimal(value_str)) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s value '%s' is not an integer", name, value_str); - } - - *value = grub_strtol(value_str, NULL, 10); - - return GRUB_ERR_NONE; -} - -static grub_err_t ventoy_cmd_debug(grub_extcmd_context_t ctxt, int argc, char **args) -{ - if (argc != 1) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {on|off}", cmd_raw_name); - } - - if (0 == grub_strcmp(args[0], "on")) - { - g_ventoy_debug = 1; - grub_env_set("vtdebug_flag", "debug"); + g_ventoy_plat_data = VTOY_PLAT_MIPS_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "mips"); } else { - g_ventoy_debug = 0; - grub_env_set("vtdebug_flag", ""); + g_ventoy_plat_data = VTOY_PLAT_X86_64_UEFI; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "uefi"); } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_break(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - - if (argc < 1 || (args[0][0] != '0' && args[0][0] != '1')) - { - grub_printf("Usage: %s {level} [debug]\r\n", cmd_raw_name); - grub_printf(" level:\r\n"); - grub_printf(" 01/11: busybox / (+cat log)\r\n"); - grub_printf(" 02/12: initrd / (+cat log)\r\n"); - grub_printf(" 03/13: hook / (+cat log)\r\n"); - grub_printf("\r\n"); - grub_printf(" debug:\r\n"); - grub_printf(" 0: debug is on\r\n"); - grub_printf(" 1: debug is off\r\n"); - grub_printf("\r\n"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); - } - - g_ventoy_break_level = (grub_uint8_t)grub_strtoul(args[0], NULL, 16); - - if (argc > 1 && grub_strtoul(args[1], NULL, 10) > 0) - { - g_ventoy_debug_level = 1; - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_incr(grub_extcmd_context_t ctxt, int argc, char **args) -{ - long value_long = 0; - char buf[32]; - - if ((argc != 2) || (!ventoy_is_decimal(args[1]))) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Variable} {Int}", cmd_raw_name); - } - - if (GRUB_ERR_NONE != ventoy_check_decimal_var(args[0], &value_long)) - { - return grub_errno; - } - - value_long += grub_strtol(args[1], NULL, 10); - - grub_snprintf(buf, sizeof(buf), "%ld", value_long); - grub_env_set(args[0], buf); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - char buf[32]; - grub_file_t file; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 2) - { - return rc; - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s> for udf check\n", args[0]); - return 1; - } - - grub_snprintf(buf, sizeof(buf), "%llu", (unsigned long long)file->size); - - grub_env_set(args[1], buf); - - grub_file_close(file); - rc = 0; - - return rc; -} - -static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_file_t file; - - (void)ctxt; - (void)argc; - (void)args; - - g_wimboot_enable = 0; - grub_check_free(g_wimiso_path); - grub_check_free(g_wimiso_chunk_list.chunk); - - file = grub_file_open(args[0], VENTOY_FILE_TYPE); - if (!file) - { - return 0; - } - - grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list)); - g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); - if (NULL == g_wimiso_chunk_list.chunk) - { - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); - } - - g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; - g_wimiso_chunk_list.cur_chunk = 0; - - ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start); - - g_wimboot_enable = 1; - g_wimiso_path = grub_strdup(args[0]); - - grub_file_close(file); - - return 0; -} - -static grub_err_t ventoy_cmd_load_iso_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 1; - char name[32]; - char value[32]; - char *buf = NULL; - grub_file_t file; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 2) - { - return rc; - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s> for udf check\n", args[0]); - return 1; - } - -#ifdef GRUB_MACHINE_EFI - buf = (char *)grub_efi_allocate_iso_buf(file->size); #else - buf = (char *)grub_malloc(file->size); -#endif - - grub_file_read(file, buf, file->size); - - grub_snprintf(name, sizeof(name), "%s_addr", args[1]); - grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); - grub_env_set(name, value); - - grub_snprintf(name, sizeof(name), "%s_size", args[1]); - grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size); - grub_env_set(name, value); - - grub_file_close(file); - rc = 0; - - return rc; -} - -static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - - if (argc != 1) - { - return 1; - } - - if (args[0][0] == '1') - { - grub_iso9660_set_nojoliet(1); - } - else - { - grub_iso9660_set_nojoliet(0); - } - - return 0; -} - -static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - int rc = 1; - grub_file_t file; - grub_uint8_t buf[32]; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 1) - { - return rc; - } - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (file == NULL) - { - debug("failed to open file <%s> for udf check\n", args[0]); - return 1; - } - - for (i = 16; i < 32; i++) - { - grub_file_seek(file, i * 2048); - grub_file_read(file, buf, sizeof(buf)); - if (buf[0] == 255) - { - break; - } - } - - i++; - grub_file_seek(file, i * 2048); - grub_file_read(file, buf, sizeof(buf)); - - if (grub_memcmp(buf + 1, "BEA01", 5) == 0) - { - i++; - grub_file_seek(file, i * 2048); - grub_file_read(file, buf, sizeof(buf)); - - if (grub_memcmp(buf + 1, "NSR02", 5) == 0 || - grub_memcmp(buf + 1, "NSR03", 5) == 0) - { - rc = 0; - } - } - - grub_file_close(file); - - debug("ISO UDF: %s\n", rc ? "NO" : "YES"); - - return rc; -} - -static grub_err_t ventoy_cmd_cmp(grub_extcmd_context_t ctxt, int argc, char **args) -{ - long value_long1 = 0; - long value_long2 = 0; - - if ((argc != 3) || (!ventoy_is_decimal(args[0])) || (!ventoy_is_decimal(args[2]))) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq|ne|gt|lt|ge|le } {Int2}", cmd_raw_name); - } - - value_long1 = grub_strtol(args[0], NULL, 10); - value_long2 = grub_strtol(args[2], NULL, 10); - - if (0 == grub_strcmp(args[1], "eq")) - { - grub_errno = (value_long1 == value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "ne")) - { - grub_errno = (value_long1 != value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "gt")) - { - grub_errno = (value_long1 > value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "lt")) - { - grub_errno = (value_long1 < value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "ge")) - { - grub_errno = (value_long1 >= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else if (0 == grub_strcmp(args[1], "le")) - { - grub_errno = (value_long1 <= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; - } - else - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq ne gt lt ge le } {Int2}", cmd_raw_name); - } - - return grub_errno; -} - -static grub_err_t ventoy_cmd_device(grub_extcmd_context_t ctxt, int argc, char **args) -{ - char *pos = NULL; - char buf[128] = {0}; - - if (argc != 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s path var", cmd_raw_name); - } - - grub_strncpy(buf, (args[0][0] == '(') ? args[0] + 1 : args[0], sizeof(buf) - 1); - pos = grub_strstr(buf, ","); - if (pos) - { - *pos = 0; - } - - grub_env_set(args[1], buf); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - char buf[256]; - grub_disk_t disk; - char *pos = NULL; - const char *files[] = { "ventoy.dat", "VENTOY.DAT" }; - - (void)ctxt; - - if (argc != 1) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s (loop)", cmd_raw_name); - } - - for (i = 0; i < (int)ARRAY_SIZE(files); i++) - { - grub_snprintf(buf, sizeof(buf) - 1, "[ -e %s/%s ]", args[0], files[i]); - if (0 == grub_script_execute_sourcecode(buf)) - { - debug("file %s exist, ventoy_compatible YES\n", buf); - grub_env_set("ventoy_compatible", "YES"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); - } - else - { - debug("file %s NOT exist\n", buf); - } - } - - grub_snprintf(buf, sizeof(buf) - 1, "%s", args[0][0] == '(' ? (args[0] + 1) : args[0]); - pos = grub_strstr(buf, ")"); - if (pos) - { - *pos = 0; - } - - disk = grub_disk_open(buf); - if (disk) - { - grub_disk_read(disk, 16 << 2, 0, 1024, g_img_swap_tmp_buf); - grub_disk_close(disk); - - g_img_swap_tmp_buf[703] = 0; - for (i = 319; i < 703; i++) - { - if (g_img_swap_tmp_buf[i] == 'V' && - 0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN)) - { - debug("Ventoy compatible string exist at %d, ventoy_compatible YES\n", i); - grub_env_set("ventoy_compatible", "YES"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); - } - } - } - else - { - debug("failed to open disk <%s>\n", buf); - } - - grub_env_set("ventoy_compatible", "NO"); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -int ventoy_cmp_img(img_info *img1, img_info *img2) -{ - char *s1, *s2; - int c1 = 0; - int c2 = 0; - - for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++) - { - c1 = *s1; - c2 = *s2; - - if (grub_islower(c1)) - { - c1 = c1 - 'a' + 'A'; - } - - if (grub_islower(c2)) - { - c2 = c2 - 'a' + 'A'; - } - - if (c1 != c2) - { - break; - } - } - - return (c1 - c2); -} - -void ventoy_swap_img(img_info *img1, img_info *img2) -{ - grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info)); - - grub_memcpy(img1, img2, sizeof(img_info)); - img1->next = g_img_swap_tmp.next; - img1->prev = g_img_swap_tmp.prev; - - g_img_swap_tmp.next = img2->next; - g_img_swap_tmp.prev = img2->prev; - grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info)); -} - -static int ventoy_img_name_valid(const char *filename, grub_size_t namelen) -{ - grub_size_t i; - - if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') - { - return 0; - } - - for (i = 0; i < namelen; i++) - { - if (filename[i] == ' ' || filename[i] == '\t') - { - return 0; - } - - if ((grub_uint8_t)(filename[i]) >= 127) - { - return 0; - } - } - - return 1; -} - -static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data) -{ - if (0 == info->dir) - { - if (filename && filename[0] == '.' && 0 == grub_strncmp(filename, ".ventoyignore", 13)) - { - *((int *)data) = 1; - return 0; - } - } - - return 0; -} - -static int ventoy_colect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) -{ - int i = 0; - int type = 0; - int ignore = 0; - grub_size_t len; - img_info *img; - img_info *tail; - img_iterator_node *tmp; - img_iterator_node *new_node; - img_iterator_node *node = (img_iterator_node *)data; - - len = grub_strlen(filename); - - if (info->dir) - { - if ((len == 1 && filename[0] == '.') || - (len == 2 && filename[0] == '.' && filename[1] == '.')) - { - return 0; - } - - if (!ventoy_img_name_valid(filename, len)) - { - return 0; - } - - if (filename[0] == '$' && 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12)) - { - return 0; - } - - new_node = grub_zalloc(sizeof(img_iterator_node)); - if (new_node) - { - new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename); - - g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore); - if (ignore) - { - debug("Directory %s ignored...\n", new_node->dir); - grub_free(new_node); - return 0; - } - - new_node->tail = node->tail; - - new_node->parent = node; - if (!node->firstchild) - { - node->firstchild = new_node; - } - - if (g_img_iterator_tail) - { - g_img_iterator_tail->next = new_node; - g_img_iterator_tail = new_node; - } - else - { - g_img_iterator_head.next = new_node; - g_img_iterator_tail = new_node; - } - } - } - else - { - debug("Find a file %s\n", filename); - if (len <= 4) - { - return 0; - } - - if (0 == grub_strcasecmp(filename + len - 4, ".iso")) - { - type = img_type_iso; - } - else if (g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim"))) - { - type = img_type_wim; - } - #ifdef GRUB_MACHINE_EFI - else if (0 == grub_strcasecmp(filename + len - 4, ".efi")) - { - type = img_type_efi; - } - #endif - else - { - return 0; - } - - if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') - { - return 0; - } - - img = grub_zalloc(sizeof(img_info)); - if (img) - { - img->type = type; - grub_snprintf(img->name, sizeof(img->name), "%s", filename); - - for (i = 0; i < (int)len; i++) - { - if (filename[i] == ' ' || filename[i] == '\t' || (0 == grub_isprint(filename[i]))) - { - img->name[i] = '*'; - img->unsupport = 1; - } - } - - img->pathlen = grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name); - - img->size = info->size; - if (0 == img->size) - { - img->size = ventoy_grub_get_file_size("%s/%s%s", g_iso_path, node->dir, filename); - } - - if (img->size < VTOY_FILT_MIN_FILE_SIZE) - { - debug("img <%s> size too small %llu\n", img->name, (ulonglong)img->size); - grub_free(img); - return 0; - } - - if (g_ventoy_img_list) - { - tail = *(node->tail); - img->prev = tail; - tail->next = img; - } - else - { - g_ventoy_img_list = img; - } - - img->id = g_ventoy_img_count; - img->parent = node; - if (node && NULL == node->firstiso) - { - node->firstiso = img; - } - - node->isocnt++; - tmp = node->parent; - while (tmp) - { - tmp->isocnt++; - tmp = tmp->parent; - } - - *((img_info **)(node->tail)) = img; - g_ventoy_img_count++; - - img->alias = ventoy_plugin_get_menu_alias(img->path); - img->class = ventoy_plugin_get_menu_class(img->name); - if (!img->class) - { - img->class = g_menu_class[type]; - } - img->menu_prefix = g_menu_prefix[type]; - - debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); - } - } - - return 0; -} - -int ventoy_fill_data(grub_uint32_t buflen, char *buffer) -{ - int len = GRUB_UINT_MAX; - const char *value = NULL; - char name[32] = {0}; - char plat[32] = {0}; - char guidstr[32] = {0}; - ventoy_guid guid = VENTOY_GUID; - const char *fmt1 = NULL; - const char *fmt2 = NULL; - const char *fmt3 = NULL; - grub_uint32_t *puint = (grub_uint32_t *)name; - grub_uint32_t *puint2 = (grub_uint32_t *)plat; - const char fmtdata[]={ 0x39, 0x35, 0x25, 0x00, 0x35, 0x00, 0x23, 0x30, 0x30, 0x30, 0x30, 0x66, 0x66, 0x00 }; - const char fmtcode[]={ - 0x22, 0x0A, 0x2B, 0x20, 0x68, 0x62, 0x6F, 0x78, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x74, 0x6F, 0x70, - 0x20, 0x3D, 0x20, 0x25, 0x73, 0x0A, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x3D, 0x20, 0x25, - 0x73, 0x0A, 0x20, 0x20, 0x2B, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x74, 0x65, 0x78, - 0x74, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x20, 0x25, 0x73, 0x25, 0x73, 0x22, 0x20, 0x63, 0x6F, - 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, - 0x20, 0x3D, 0x20, 0x22, 0x6C, 0x65, 0x66, 0x74, 0x22, 0x7D, 0x0A, 0x7D, 0x0A, 0x22, 0x00 - }; - - grub_memset(name, 0, sizeof(name)); - puint[0] = grub_swap_bytes32(0x56454e54); - puint[3] = grub_swap_bytes32(0x4f4e0000); - puint[2] = grub_swap_bytes32(0x45525349); - puint[1] = grub_swap_bytes32(0x4f595f56); - value = ventoy_get_env(name); - - grub_memset(name, 0, sizeof(name)); - puint[1] = grub_swap_bytes32(0x5f544f50); - puint[0] = grub_swap_bytes32(0x56544c45); - fmt1 = ventoy_get_env(name); - if (!fmt1) - { - fmt1 = fmtdata; - } - - grub_memset(name, 0, sizeof(name)); - puint[1] = grub_swap_bytes32(0x5f4c4654); - puint[0] = grub_swap_bytes32(0x56544c45); - fmt2 = ventoy_get_env(name); - - grub_memset(name, 0, sizeof(name)); - puint[1] = grub_swap_bytes32(0x5f434c52); - puint[0] = grub_swap_bytes32(0x56544c45); - fmt3 = ventoy_get_env(name); - - grub_memcpy(guidstr, &guid, sizeof(guid)); - - #if defined (GRUB_MACHINE_EFI) - puint2[0] = grub_swap_bytes32(0x55454649); - #else - puint2[0] = grub_swap_bytes32(0x42494f53); - #endif - - /* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */ - #pragma GCC diagnostic push - #pragma GCC diagnostic ignored "-Wformat-nonliteral" - len = grub_snprintf(buffer, buflen, fmtcode, - fmt1 ? fmt1 : fmtdata, - fmt2 ? fmt2 : fmtdata + 4, - value ? value : "", plat, guidstr, - fmt3 ? fmt3 : fmtdata + 6); - #pragma GCC diagnostic pop - - grub_memset(name, 0, sizeof(name)); - puint[0] = grub_swap_bytes32(0x76746f79); - puint[2] = grub_swap_bytes32(0x656e7365); - puint[1] = grub_swap_bytes32(0x5f6c6963); - ventoy_set_env(name, guidstr); - - return len; -} - -static img_info * ventoy_get_min_iso(img_iterator_node *node) -{ - img_info *minimg = NULL; - img_info *img = (img_info *)(node->firstiso); - - while (img && (img_iterator_node *)(img->parent) == node) - { - if (img->select == 0 && (NULL == minimg || grub_strcmp(img->name, minimg->name) < 0)) - { - minimg = img; - } - img = img->next; - } - - if (minimg) - { - minimg->select = 1; - } - - return minimg; -} - -static img_iterator_node * ventoy_get_min_child(img_iterator_node *node) -{ - img_iterator_node *Minchild = NULL; - img_iterator_node *child = node->firstchild; - - while (child && child->parent == node) - { - if (child->select == 0 && (NULL == Minchild || grub_strcmp(child->dir, Minchild->dir) < 0)) - { - Minchild = child; - } - child = child->next; - } - - if (Minchild) - { - Minchild->select = 1; - } - - return Minchild; -} - -static int ventoy_dynamic_tree_menu(img_iterator_node *node) -{ - int offset = 1; - img_info *img; - img_iterator_node *child = NULL; - - if (node->isocnt == 0 || node->done == 1) - { - return 0; - } - - if (node->parent && node->parent->dirlen < node->dirlen) - { - offset = node->parent->dirlen; - } - - if (node == &g_img_iterator_head) - { - if (g_default_menu_mode == 0) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo 'return ...' \n" - "}\n", "<--"); - } - } - else - { - node->dir[node->dirlen - 1] = 0; - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "submenu \"%-10s [%s]\" --class=\"vtoydir\" {\n", - "DIR", node->dir + offset); - - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo 'return ...' \n" - "}\n", "<--"); - } - - while ((child = ventoy_get_min_child(node)) != NULL) - { - ventoy_dynamic_tree_menu(child); - } - - while ((img = ventoy_get_min_iso(node)) != NULL) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, - "menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" - " %s_%s \n" - "}\n", - grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), - img->unsupport ? "[unsupported] " : "", - img->alias ? img->alias : img->name, img->class, img->id, - img->menu_prefix, - img->unsupport ? "unsupport_menuentry" : "common_menuentry"); - } - - if (node != &g_img_iterator_head) - { - vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "%s", "}\n"); - } - - node->done = 1; - return 0; -} - -static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int len; - grub_fs_t fs; - grub_device_t dev = NULL; - img_info *cur = NULL; - img_info *tail = NULL; - img_info *default_node = NULL; - const char *strdata = NULL; - char *device_name = NULL; - const char *default_image = NULL; - int img_len = 0; - char buf[32]; - img_iterator_node *node = NULL; - img_iterator_node *tmp = NULL; - - (void)ctxt; - - if (argc != 2) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {device} {cntvar}", cmd_raw_name); - } - - if (g_ventoy_img_list || g_ventoy_img_count) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Must clear image before list"); - } - - strdata = ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE"); - if (strdata && strdata[0] == '1' && strdata[1] == 0) - { - g_filt_dot_underscore_file = 1; - } - - device_name = grub_file_get_device_name(args[0]); - if (!device_name) - { - goto fail; - } - - g_enum_dev = dev = grub_device_open(device_name); - if (!dev) - { - goto fail; - } - - g_enum_fs = fs = grub_fs_probe(dev); - if (!fs) - { - goto fail; - } - - if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) - { - debug("unsupported fs:<%s>\n", fs->name); - ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system"); - goto fail; - } - - strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE"); - if (strdata && strdata[0] == '1') - { - g_default_menu_mode = 1; - } - - grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head)); - - grub_snprintf(g_iso_path, sizeof(g_iso_path), "%s", args[0]); - - strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); - if (strdata && strdata[0] == '/') - { - len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata); - if (g_img_iterator_head.dir[len - 1] != '/') - { - g_img_iterator_head.dir[len++] = '/'; - } - g_img_iterator_head.dirlen = len; - } - else - { - g_img_iterator_head.dirlen = 1; - grub_strcpy(g_img_iterator_head.dir, "/"); - } - - g_img_iterator_head.tail = &tail; - - for (node = &g_img_iterator_head; node; node = node->next) - { - fs->fs_dir(dev, node->dir, ventoy_colect_img_files, node); - } - - for (node = &g_img_iterator_head; node; node = node->next) - { - ventoy_dynamic_tree_menu(node); - } - - /* free node */ - node = g_img_iterator_head.next; - while (node) - { - tmp = node->next; - grub_free(node); - node = tmp; - } - - /* sort image list by image name */ - for (cur = g_ventoy_img_list; cur; cur = cur->next) - { - for (tail = cur->next; tail; tail = tail->next) - { - if (ventoy_cmp_img(cur, tail) > 0) - { - ventoy_swap_img(cur, tail); - } - } - } - - if (g_default_menu_mode == 1) - { - vtoy_ssprintf(g_list_script_buf, g_list_script_pos, - "menuentry \"%s [Return to TreeView]\" --class=\"vtoyret\" VTOY_RET {\n " - " echo 'return ...' \n" - "}\n", "<--"); - } - - if (g_default_menu_mode == 0) - { - default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE"); - if (default_image) - { - img_len = grub_strlen(default_image); - } - } - - for (cur = g_ventoy_img_list; cur; cur = cur->next) - { - vtoy_ssprintf(g_list_script_buf, g_list_script_pos, - "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" - " %s_%s \n" - "}\n", - cur->unsupport ? "[unsupported] " : "", - cur->alias ? cur->alias : cur->name, cur->class, cur->id, - cur->menu_prefix, - cur->unsupport ? "unsupport_menuentry" : "common_menuentry"); - - if (g_default_menu_mode == 0 && default_image && default_node == NULL) - { - if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0) - { - default_node = cur; - } - } - } - - if (default_node) - { - vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%d'\n", default_node->id); - } - - g_list_script_buf[g_list_script_pos] = 0; - - grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count); - grub_env_set(args[1], buf); - -fail: - - check_free(device_name, grub_free); - check_free(dev, grub_device_close); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - - -static grub_err_t ventoy_cmd_clear_img(grub_extcmd_context_t ctxt, int argc, char **args) -{ - img_info *next = NULL; - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - (void)argc; - (void)args; - - while (cur) - { - next = cur->next; - grub_free(cur); - cur = next; - } - - g_ventoy_img_list = NULL; - g_ventoy_img_count = 0; - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char **args) -{ - long img_id = 0; - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - - if (argc != 2 || (!ventoy_is_decimal(args[0]))) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {imageID} {var}", cmd_raw_name); - } - - img_id = grub_strtol(args[0], NULL, 10); - if (img_id >= g_ventoy_img_count) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images %ld %ld", img_id, g_ventoy_img_count); - } - - debug("Find image %ld name \n", img_id); - - while (cur && img_id > 0) - { - img_id--; - cur = cur->next; - } - - if (!cur) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images"); - } - - debug("image name is %s\n", cur->name); - - grub_env_set(args[1], cur->name); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int img_id = 0; - char *pos = NULL; - const char *id = NULL; - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - - if (argc != 1) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); - } - - id = grub_env_get("chosen"); - - pos = grub_strstr(id, "VID_"); - if (pos) - { - img_id = (int)grub_strtoul(pos + 4, NULL, 10); - } - else - { - img_id = (int)grub_strtoul(id, NULL, 10); - } - - while (cur) - { - if (img_id == cur->id) - { - break; - } - cur = cur->next; - } - - if (!cur) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); - } - - grub_env_set(args[0], cur->path); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid) -{ - grub_disk_t disk; - char *device_name; - char *pos; - char *pos2; - - device_name = grub_file_get_device_name(filename); - if (!device_name) - { - return 1; - } - - pos = device_name; - if (pos[0] == '(') - { - pos++; - } - - pos2 = grub_strstr(pos, ","); - if (!pos2) - { - pos2 = grub_strstr(pos, ")"); - } - - if (pos2) - { - *pos2 = 0; - } - - disk = grub_disk_open(pos); - if (disk) - { - grub_disk_read(disk, 0, 0x180, 16, guid); - grub_disk_close(disk); - } - else - { - return 1; - } - - grub_free(device_name); - return 0; -} - -grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file) -{ - eltorito_descriptor desc; - - grub_memset(&desc, 0, sizeof(desc)); - grub_file_seek(file, 17 * 2048); - grub_file_read(file, &desc, sizeof(desc)); - - if (desc.type != 0 || desc.version != 1) - { - return 0; - } - - if (grub_strncmp((char *)desc.id, "CD001", 5) != 0 || - grub_strncmp((char *)desc.system_id, "EL TORITO SPECIFICATION", 23) != 0) - { - return 0; - } - - return desc.sector; -} - -int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) -{ - int i; - grub_uint8_t buf[512]; - - grub_file_seek(file, sector * 2048); - grub_file_read(file, buf, sizeof(buf)); - - if (buf[0] == 0x01 && buf[1] == 0xEF) - { - debug("%s efi eltorito in Validation Entry\n", file->name); - return 1; - } - - for (i = 64; i < (int)sizeof(buf); i += 32) - { - if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) - { - debug("%s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); - return 1; - } - } - - debug("%s does not contain efi eltorito\n", file->name); - return 0; -} - -void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) -{ - char *pos; - const char *fs = NULL; - const char *cdprompt = NULL; - grub_uint32_t i; - grub_uint8_t chksum = 0; - grub_disk_t disk; - - disk = file->device->disk; - grub_memcpy(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid)); - - param->vtoy_disk_size = disk->total_sectors * (1 << disk->log_sector_size); - param->vtoy_disk_part_id = disk->partition->number + 1; - param->vtoy_disk_part_type = ventoy_get_fs_type(file->fs->name); - - pos = grub_strstr(file->name, "/"); - if (!pos) - { - pos = file->name; - } - - grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos); - - ventoy_get_disk_guid(file->name, param->vtoy_disk_guid); - - param->vtoy_img_size = file->size; - - param->vtoy_reserved[0] = g_ventoy_break_level; - param->vtoy_reserved[1] = g_ventoy_debug_level; - - param->vtoy_reserved[2] = g_ventoy_chain_type; - - /* Windows CD/DVD prompt 0:suppress 1:reserved */ - param->vtoy_reserved[4] = 0; - if (g_ventoy_chain_type == 1) /* Windows */ - { - cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT"); - if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0) - { - param->vtoy_reserved[4] = 1; - } - } - - fs = ventoy_get_env("ventoy_fs_probe"); - if (fs && grub_strcmp(fs, "udf") == 0) - { - param->vtoy_reserved[3] = 1; - } - - /* calculate checksum */ - for (i = 0; i < sizeof(ventoy_os_param); i++) - { - chksum += *((grub_uint8_t *)param + i); - } - param->chksum = (grub_uint8_t)(0x100 - chksum); - - return; -} - -int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) -{ - grub_uint32_t i = 0; - grub_uint64_t total = 0; - ventoy_img_chunk *chunk = NULL; - - for (i = 0; i < chunklist->cur_chunk; i++) - { - chunk = chunklist->chunk + i; - - if (chunk->disk_start_sector <= start) - { - debug("%u disk start invalid %lu\n", i, (ulong)start); - return 1; - } - - total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; - } - - if (total != ((file->size + 511) / 512)) - { - debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)((file->size + 511) / 512)); - return 1; - } - - return 0; -} - -int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) -{ - int fs_type; - grub_uint32_t i = 0; - grub_uint32_t sector = 0; - grub_uint32_t count = 0; - grub_off_t size = 0; - grub_off_t read = 0; - - fs_type = ventoy_get_fs_type(file->fs->name); - if (fs_type == ventoy_fs_exfat) - { - grub_fat_get_file_chunk(start, file, chunklist); - } - else if (fs_type == ventoy_fs_ext) - { - grub_ext_get_file_chunk(start, file, chunklist); - } - else - { - file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read; - file->read_hook_data = chunklist; - - for (size = file->size; size > 0; size -= read) - { - read = (size > VTOY_SIZE_1GB) ? VTOY_SIZE_1GB : size; - grub_file_read(file, NULL, read); - } - - for (i = 0; start > 0 && i < chunklist->cur_chunk; i++) - { - chunklist->chunk[i].disk_start_sector += start; - chunklist->chunk[i].disk_end_sector += start; - } - - if (ventoy_fs_udf == fs_type) - { - for (i = 0; i < chunklist->cur_chunk; i++) - { - count = (chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector) >> 2; - chunklist->chunk[i].img_start_sector = sector; - chunklist->chunk[i].img_end_sector = sector + count - 1; - sector += count; - } - } - } - - return 0; -} - -static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc; - grub_file_t file; - grub_disk_addr_t start; - - (void)ctxt; - (void)argc; - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); - } - - if (g_img_chunk_list.chunk) - { - grub_free(g_img_chunk_list.chunk); - } - - /* get image chunk data */ - grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list)); - g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); - if (NULL == g_img_chunk_list.chunk) - { - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); - } - - g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; - g_img_chunk_list.cur_chunk = 0; - - start = file->device->disk->partition->start; - - ventoy_get_block_list(file, &g_img_chunk_list, start); - - rc = ventoy_check_block_list(file, &g_img_chunk_list, start); - grub_file_close(file); - - if (rc) - { - return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported chunk list.\n"); - } - - grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace)); - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i = 0; - int pos = 0; - char *buf = NULL; - char configfile[128]; - install_template *node = NULL; - - (void)ctxt; - (void)argc; - (void)args; - - debug("select auto installation %d\n", argc); - - if (argc < 1) - { - return 0; - } - - node = ventoy_plugin_find_install_template(args[0]); - if (!node) - { - debug("Install template not found for %s\n", args[0]); - return 0; - } - - buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); - if (!buf) - { - return 0; - } - - vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n" - " echo %s\n}\n", "123"); - - for (i = 0; i < node->templatenum; i++) - { - vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" - " echo 123\n}\n", - node->templatepath[i].path); - } - - g_ventoy_menu_esc = 1; - g_ventoy_suppress_esc = 1; - - grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); - grub_script_execute_sourcecode(configfile); - - g_ventoy_menu_esc = 0; - g_ventoy_suppress_esc = 0; - - grub_free(buf); - - node->cursel = g_ventoy_last_entry - 1; - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i = 0; - int pos = 0; - char *buf = NULL; - char configfile[128]; - persistence_config *node; - - (void)ctxt; - (void)argc; - (void)args; - - debug("select persistece %d\n", argc); - - if (argc < 1) - { - return 0; - } - - node = ventoy_plugin_find_persistent(args[0]); - if (!node) - { - debug("Persistence image not found for %s\n", args[0]); - return 0; - } - - buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); - if (!buf) - { - return 0; - } - - vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n" - " echo %s\n}\n", "123"); - - for (i = 0; i < node->backendnum; i++) - { - vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" - " echo 123\n}\n", - node->backendpath[i].path); - - } - - g_ventoy_menu_esc = 1; - g_ventoy_suppress_esc = 1; - - grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); - grub_script_execute_sourcecode(configfile); - - g_ventoy_menu_esc = 0; - g_ventoy_suppress_esc = 0; - - grub_free(buf); - - node->cursel = g_ventoy_last_entry - 1; - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint32_t i; - ventoy_img_chunk *cur; - - (void)ctxt; - (void)argc; - (void)args; - - for (i = 0; i < g_img_chunk_list.cur_chunk; i++) - { - cur = g_img_chunk_list.chunk + i; - grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n", - cur->img_start_sector, cur->img_end_sector, - (unsigned long long)cur->disk_start_sector, (unsigned long long)cur->disk_end_sector - ); - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -#ifdef GRUB_MACHINE_EFI -static grub_err_t ventoy_cmd_relocator_chaindata(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - return 0; -} -#else -static grub_err_t ventoy_cmd_relocator_chaindata(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int rc = 0; - ulong chain_len = 0; - char *chain_data = NULL; - char *relocator_addr = NULL; - grub_relocator_chunk_t ch; - struct grub_relocator *relocator = NULL; - char envbuf[64] = { 0 }; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 2) - { - return 1; - } - - chain_data = (char *)grub_strtoul(args[0], NULL, 16); - chain_len = grub_strtoul(args[1], NULL, 10); - - relocator = grub_relocator_new (); - if (!relocator) - { - debug("grub_relocator_new failed %p %lu\n", chain_data, chain_len); - return 1; - } - - rc = grub_relocator_alloc_chunk_addr (relocator, &ch, - 0x100000, // GRUB_LINUX_BZIMAGE_ADDR, - chain_len); - if (rc) - { - debug("grub_relocator_alloc_chunk_addr failed %d %p %lu\n", rc, chain_data, chain_len); - grub_relocator_unload (relocator); - return 1; - } - - relocator_addr = get_virtual_current_address(ch); - - grub_memcpy(relocator_addr, chain_data, chain_len); - - grub_relocator_unload (relocator); - - grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)relocator_addr); - grub_env_set("vtoy_chain_relocator_addr", envbuf); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} + g_ventoy_plat_data = VTOY_PLAT_X86_LEGACY; + grub_snprintf(g_arch_mode_suffix, sizeof(g_arch_mode_suffix), "%s", "legacy"); #endif -static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_uint32_t i; - grub_file_t file; - ventoy_img_chunk_list chunklist; - - (void)ctxt; - (void)argc; - - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); - if (!file) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); - } - - /* get image chunk data */ - grub_memset(&chunklist, 0, sizeof(chunklist)); - chunklist.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); - if (NULL == chunklist.chunk) - { - return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); - } - - chunklist.max_chunk = DEFAULT_CHUNK_NUM; - chunklist.cur_chunk = 0; - - ventoy_get_block_list(file, &chunklist, 0); - - if (0 != ventoy_check_block_list(file, &chunklist, 0)) - { - grub_printf("########## UNSUPPORTED ###############\n"); - } - - grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk); - - for (i = 0; i < chunklist.cur_chunk; i++) - { - grub_printf("%llu+%llu,", (ulonglong)chunklist.chunk[i].disk_start_sector, - (ulonglong)(chunklist.chunk[i].disk_end_sector + 1 - chunklist.chunk[i].disk_start_sector)); - } - - grub_printf("\n==================================\n"); - - for (i = 0; i < chunklist.cur_chunk; i++) - { - grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i, - (ulonglong)chunklist.chunk[i].img_start_sector, - (ulonglong)chunklist.chunk[i].img_end_sector, - (ulonglong)chunklist.chunk[i].disk_start_sector, - (ulonglong)chunklist.chunk[i].disk_end_sector - ); - } - - grub_free(chunklist.chunk); - grub_file_close(file); - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int i; - ventoy_grub_param_file_replace *replace = NULL; - - (void)ctxt; - (void)argc; - (void)args; - - if (argc >= 2) - { - replace = &(g_grub_param->file_replace); - replace->magic = GRUB_FILE_REPLACE_MAGIC; - - replace->old_name_cnt = 0; - for (i = 0; i < 4 && i + 1 < argc; i++) - { - replace->old_name_cnt++; - grub_snprintf(replace->old_file_name[i], sizeof(replace->old_file_name[i]), "%s", args[i + 1]); - } - - replace->new_file_virtual_id = (grub_uint32_t)grub_strtoul(args[0], NULL, 10); - } - - VENTOY_CMD_RETURN(GRUB_ERR_NONE); -} - -static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - if (argc == 0) - { - grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF); - grub_printf("%s", g_list_script_buf); - } - else - { - grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF); - grub_printf("%s", g_tree_script_buf); - } - return 0; } -static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args) -{ - img_info *cur = g_ventoy_img_list; - - (void)ctxt; - (void)argc; - (void)args; - - while (cur) - { - grub_printf("path:<%s> id=%d\n", cur->path, cur->id); - grub_printf("name:<%s>\n\n", cur->name); - cur = cur->next; - } - - return 0; -} - -static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - -{ - grub_file_t file; - char *buf; - char name[128]; - - file = grub_file_open("(hd0,1)/ventoy/ventoy.disk.img.xz", GRUB_FILE_TYPE_NONE); - if (file) - { - grub_printf("Open File OK (size:%llu)\n", (ulonglong)file->size); - - buf = grub_malloc(file->size); - grub_file_read(file, buf, file->size); - - grub_file_close(file); - - grub_snprintf(name, sizeof(name), "mem:0x%llx:size:%llu", (ulonglong)(ulong)buf, (ulonglong)file->size); - grub_printf("<%s>\n", name); - } -} - - - ventoy_plugin_dump_auto_install(); - - return 0; -} - -static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - ventoy_plugin_dump_persistence(); - - return 0; -} - -static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args) -{ - (void)ctxt; - (void)argc; - (void)args; - - if (argc != 1) - { - return 1; - } - - if (args[0][0] == '0') - { - return g_ventoy_memdisk_mode ? 0 : 1; - } - else if (args[0][0] == '1') - { - return g_ventoy_iso_raw ? 0 : 1; - } - else if (args[0][0] == '2') - { - return g_ventoy_iso_uefi_drv ? 0 : 1; - } - - return 1; -} - -static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args) -{ - static int configfile_mode = 0; - char memfile[128] = {0}; - - (void)ctxt; - (void)argc; - (void)args; - - /* - * args[0]: 0:normal 1:configfile - * args[1]: 0:list_buf 1:tree_buf - */ - - if (argc != 2) - { - debug("Invalid argc %d\n", argc); - return 0; - } - - if (args[0][0] == '0') - { - if (args[1][0] == '0') - { - grub_script_execute_sourcecode(g_list_script_buf); - } - else - { - grub_script_execute_sourcecode(g_tree_script_buf); - } - } - else - { - if (configfile_mode) - { - debug("Now already in F3 mode %d\n", configfile_mode); - return 0; - } - - if (args[1][0] == '0') - { - grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", - (ulonglong)(ulong)g_list_script_buf, g_list_script_pos); - } - else - { - g_ventoy_last_entry = -1; - grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", - (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos); - } - - configfile_mode = 1; - grub_script_execute_sourcecode(memfile); - configfile_mode = 0; - } - - return 0; -} - -static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args) -{ - grub_file_t file; - - (void)ctxt; - - if (argc != 1) - { - return 1; - } - - g_ventoy_case_insensitive = 1; - file = grub_file_open(args[0], VENTOY_FILE_TYPE); - g_ventoy_case_insensitive = 0; - - grub_errno = 0; - - if (file) - { - grub_file_close(file); - return 0; - } - return 1; -} - -static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args) -{ - int id = 0; - int find = 0; - grub_disk_t disk; - const char *isopath = NULL; - char hdname[32]; - ventoy_mbr_head mbr; - - (void)ctxt; - (void)argc; - - if (argc != 1) - { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name); - } - - isopath = grub_env_get("iso_path"); - if (!isopath) - { - debug("isopath is null %p\n", isopath); - return 0; - } - - debug("isopath is %s\n", isopath); - - for (id = 0; id < 30 && (find == 0); id++) - { - grub_snprintf(hdname, sizeof(hdname), "hd%d,", id); - if (grub_strstr(isopath, hdname)) - { - debug("skip %s ...\n", hdname); - continue; - } - - grub_snprintf(hdname, sizeof(hdname), "hd%d", id); - - disk = grub_disk_open(hdname); - if (!disk) - { - debug("%s not exist\n", hdname); - break; - } - - grub_memset(&mbr, 0, sizeof(mbr)); - if (0 == grub_disk_read(disk, 0, 0, 512, &mbr)) - { - if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA) - { - if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 || - mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80) - { - - grub_env_set(args[0], hdname); - find = 1; - } - } - debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable"); - } - else - { - debug("read %s failed\n", hdname); - } - - grub_disk_close(disk); - } - - return 0; -} - -grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...) -{ - grub_uint64_t size = 0; - grub_file_t file; - va_list ap; - char fullpath[256] = {0}; - - va_start (ap, fmt); - grub_vsnprintf(fullpath, 255, fmt, ap); - va_end (ap); - - file = grub_file_open(fullpath, VENTOY_FILE_TYPE); - if (!file) - { - debug("grub_file_open failed <%s>\n", fullpath); - grub_errno = 0; - return 0; - } - - size = file->size; - grub_file_close(file); - return size; -} - -grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...) -{ - va_list ap; - grub_file_t file; - char fullpath[256] = {0}; - - va_start (ap, fmt); - grub_vsnprintf(fullpath, 255, fmt, ap); - va_end (ap); - - file = grub_file_open(fullpath, type); - if (!file) - { - debug("grub_file_open failed <%s>\n", fullpath); - grub_errno = 0; - } - - return file; -} - -int ventoy_is_file_exist(const char *fmt, ...) -{ - va_list ap; - int len; - char *pos = NULL; - char buf[256] = {0}; - - grub_snprintf(buf, sizeof(buf), "%s", "[ -f "); - pos = buf + 5; - - va_start (ap, fmt); - len = grub_vsnprintf(pos, 255, fmt, ap); - va_end (ap); - - grub_strncpy(pos + len, " ]", 2); - - debug("script exec %s\n", buf); - - if (0 == grub_script_execute_sourcecode(buf)) - { - return 1; - } - - return 0; -} - -static int ventoy_env_init(void) -{ - char buf[64]; - - grub_env_set("vtdebug_flag", ""); - grub_env_export("vtdebug_flag"); - - - - g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); - g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); - - ventoy_filt_register(0, ventoy_wrapper_open); - - g_grub_param = (ventoy_grub_param *)grub_zalloc(sizeof(ventoy_grub_param)); - if (g_grub_param) - { - g_grub_param->grub_env_get = grub_env_get; - grub_snprintf(buf, sizeof(buf), "%p", g_grub_param); - grub_env_set("env_param", buf); - } - - return 0; -} - -static cmd_para ventoy_cmds[] = -{ - { "vt_incr", ventoy_cmd_incr, 0, NULL, "{Var} {INT}", "Increase integer variable", NULL }, - { "vt_debug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, - { "vtdebug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, - { "vtbreak", ventoy_cmd_break, 0, NULL, "{level}", "set debug break", NULL }, - { "vt_cmp", ventoy_cmd_cmp, 0, NULL, "{Int1} { eq|ne|gt|lt|ge|le } {Int2}", "Comare two integers", NULL }, - { "vt_device", ventoy_cmd_device, 0, NULL, "path var", "", NULL }, - { "vt_check_compatible", ventoy_cmd_check_compatible, 0, NULL, "", "", NULL }, - { "vt_list_img", ventoy_cmd_list_img, 0, NULL, "{device} {cntvar}", "find all iso file in device", NULL }, - { "vt_clear_img", ventoy_cmd_clear_img, 0, NULL, "", "clear image list", NULL }, - { "vt_img_name", ventoy_cmd_img_name, 0, NULL, "{imageID} {var}", "get image name", NULL }, - { "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get chosen img path", NULL }, - { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL }, - { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL }, - { "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL }, - { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL }, - { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL }, - { "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL }, - { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, - { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, - { "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL }, - { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, - { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, - { "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL }, - { "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL }, - - { "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL }, - { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, - { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, - { "vt_load_iso_to_mem", ventoy_cmd_load_iso_to_mem, 0, NULL, "", "", NULL }, - - { "vt_linux_parse_initrd_isolinux", ventoy_cmd_isolinux_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, - { "vt_linux_parse_initrd_grub", ventoy_cmd_grub_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, - { "vt_linux_specify_initrd_file", ventoy_cmd_specify_initrd_file, 0, NULL, "", "", NULL }, - { "vt_linux_clear_initrd", ventoy_cmd_clear_initrd_list, 0, NULL, "", "", NULL }, - { "vt_linux_dump_initrd", ventoy_cmd_dump_initrd_list, 0, NULL, "", "", NULL }, - { "vt_linux_initrd_count", ventoy_cmd_initrd_count, 0, NULL, "", "", NULL }, - { "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL }, - { "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL }, - { "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL }, - { "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index, 0, NULL, "", "", NULL }, - - { "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL }, - { "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL }, - { "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL }, - { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL }, - { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL }, - { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL }, - { "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL }, - - { "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL }, - { "vt_relocator_chaindata", ventoy_cmd_relocator_chaindata, 0, NULL, "", "", NULL }, - { "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL }, - { "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL }, - - - { "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL }, - { "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL }, - -}; - - - GRUB_MOD_INIT(ventoy) { - grub_uint32_t i; - cmd_para *cur = NULL; - ventoy_env_init(); - - for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) - { - cur = ventoy_cmds + i; - cur->cmd = grub_register_extcmd(cur->name, cur->func, cur->flags, - cur->summary, cur->description, cur->parser); - } + ventoy_arch_mode_init(); + ventoy_register_all_cmd(); } GRUB_MOD_FINI(ventoy) { - grub_uint32_t i; - - for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) - { - grub_unregister_extcmd(ventoy_cmds[i].cmd); - } + ventoy_unregister_all_cmd(); } diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c new file mode 100644 index 00000000..848ba874 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_cmd.c @@ -0,0 +1,5003 @@ +/****************************************************************************** + * ventoy_cmd.c + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GRUB_MACHINE_EFI +#include +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" +#include "miniz.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +initrd_info *g_initrd_img_list = NULL; +initrd_info *g_initrd_img_tail = NULL; +int g_initrd_img_count = 0; +int g_valid_initrd_count = 0; +int g_default_menu_mode = 0; +int g_filt_dot_underscore_file = 0; +int g_sort_case_sensitive = 0; +int g_tree_view_menu_style = 0; +static grub_file_t g_old_file; +static int g_ventoy_last_entry_back; + +char g_iso_path[256]; +char g_img_swap_tmp_buf[1024]; +img_info g_img_swap_tmp; +img_info *g_ventoy_img_list = NULL; + +int g_ventoy_img_count = 0; + +grub_device_t g_enum_dev = NULL; +grub_fs_t g_enum_fs = NULL; +int g_img_max_search_level = -1; +img_iterator_node g_img_iterator_head; +img_iterator_node *g_img_iterator_tail = NULL; + +grub_uint8_t g_ventoy_break_level = 0; +grub_uint8_t g_ventoy_debug_level = 0; +grub_uint8_t g_ventoy_chain_type = 0; + +grub_uint8_t *g_ventoy_cpio_buf = NULL; +grub_uint32_t g_ventoy_cpio_size = 0; +cpio_newc_header *g_ventoy_initrd_head = NULL; +grub_uint8_t *g_ventoy_runtime_buf = NULL; + +int g_plugin_image_list = 0; + +ventoy_grub_param *g_grub_param = NULL; + +ventoy_guid g_ventoy_guid = VENTOY_GUID; + +ventoy_img_chunk_list g_img_chunk_list; + +int g_wimboot_enable = 0; +ventoy_img_chunk_list g_wimiso_chunk_list; +char *g_wimiso_path = NULL; + +int g_vhdboot_enable = 0; + +grub_uint64_t g_conf_replace_offset = 0; +grub_uint64_t g_svd_replace_offset = 0; +conf_replace *g_conf_replace_node = NULL; +grub_uint8_t *g_conf_replace_new_buf = NULL; +int g_conf_replace_new_len = 0; +int g_conf_replace_new_len_align = 0; + +ventoy_gpt_info *g_ventoy_part_info = NULL; +grub_uint64_t g_ventoy_disk_size = 0; +grub_uint64_t g_ventoy_disk_part_size[2]; + +static char *g_tree_script_buf = NULL; +static int g_tree_script_pos = 0; + +static char *g_list_script_buf = NULL; +static int g_list_script_pos = 0; + +static char *g_part_list_buf = NULL; +static int g_part_list_pos = 0; + +static int g_video_mode_max = 0; +static int g_video_mode_num = 0; +static ventoy_video_mode *g_video_mode_list = NULL; + +static int g_enumerate_time_checked = 0; +static grub_uint64_t g_enumerate_start_time_ms; +static grub_uint64_t g_enumerate_finish_time_ms; +static int g_vtoy_file_flt[VTOY_FILE_FLT_BUTT] = {0}; + +static int g_pager_flag = 0; +static char g_old_pager[32]; + +static const char *g_vtoy_winpeshl_ini = "[LaunchApps]\r\nvtoyjump.exe"; + +static const char *g_menu_class[] = +{ + "vtoyiso", "vtoywim", "vtoyefi", "vtoyimg", "vtoyvhd", "vtoyvtoy" +}; + +const char *g_menu_prefix[img_type_max] = +{ + "iso", "wim", "efi", "img", "vhd", "vtoy" +}; + +static int g_vtoy_load_prompt = 0; +static char g_vtoy_prompt_msg[64]; + +static char g_json_case_mis_path[32]; + +static int ventoy_get_fs_type(const char *fs) +{ + if (NULL == fs) + { + return ventoy_fs_max; + } + else if (grub_strncmp(fs, "exfat", 5) == 0) + { + return ventoy_fs_exfat; + } + else if (grub_strncmp(fs, "ntfs", 4) == 0) + { + return ventoy_fs_ntfs; + } + else if (grub_strncmp(fs, "ext", 3) == 0) + { + return ventoy_fs_ext; + } + else if (grub_strncmp(fs, "xfs", 3) == 0) + { + return ventoy_fs_xfs; + } + else if (grub_strncmp(fs, "udf", 3) == 0) + { + return ventoy_fs_udf; + } + else if (grub_strncmp(fs, "fat", 3) == 0) + { + return ventoy_fs_fat; + } + + return ventoy_fs_max; +} + +static int ventoy_string_check(const char *str, grub_char_check_func check) +{ + if (!str) + { + return 0; + } + + for ( ; *str; str++) + { + if (!check(*str)) + { + return 0; + } + } + + return 1; +} + + +static grub_ssize_t ventoy_fs_read(grub_file_t file, char *buf, grub_size_t len) +{ + grub_memcpy(buf, (char *)file->data + file->offset, len); + return len; +} + +static int ventoy_control_get_flag(const char *key) +{ + const char *val = ventoy_get_env(key); + + if (val && val[0] == '1' && val[1] == 0) + { + return 1; + } + return 0; +} + +static grub_err_t ventoy_fs_close(grub_file_t file) +{ + grub_file_close(g_old_file); + grub_free(file->data); + + file->device = 0; + file->name = 0; + + return 0; +} + +static int ventoy_video_hook(const struct grub_video_mode_info *info, void *hook_arg) +{ + int i; + + (void)hook_arg; + + if (info->mode_type & GRUB_VIDEO_MODE_TYPE_PURE_TEXT) + { + return 0; + } + + for (i = 0; i < g_video_mode_num; i++) + { + if (g_video_mode_list[i].width == info->width && + g_video_mode_list[i].height == info->height && + g_video_mode_list[i].bpp == info->bpp) + { + return 0; + } + } + + g_video_mode_list[g_video_mode_num].width = info->width; + g_video_mode_list[g_video_mode_num].height = info->height; + g_video_mode_list[g_video_mode_num].bpp = info->bpp; + g_video_mode_num++; + + if (g_video_mode_num == g_video_mode_max) + { + g_video_mode_max *= 2; + g_video_mode_list = grub_realloc(g_video_mode_list, g_video_mode_max * sizeof(ventoy_video_mode)); + } + + return 0; +} + +static int ventoy_video_mode_cmp(ventoy_video_mode *v1, ventoy_video_mode *v2) +{ + if (v1->bpp == v2->bpp) + { + if (v1->width == v2->width) + { + if (v1->height == v2->height) + { + return 0; + } + else + { + return (v1->height < v2->height) ? -1 : 1; + } + } + else + { + return (v1->width < v2->width) ? -1 : 1; + } + } + else + { + return (v1->bpp < v2->bpp) ? -1 : 1; + } +} + +static int ventoy_enum_video_mode(void) +{ + int i, j; + grub_video_adapter_t adapter; + grub_video_driver_id_t id; + ventoy_video_mode mode; + + g_video_mode_num = 0; + g_video_mode_max = 1024; + g_video_mode_list = grub_malloc(sizeof(ventoy_video_mode) * g_video_mode_max); + if (!g_video_mode_list) + { + return 0; + } + + #ifdef GRUB_MACHINE_PCBIOS + grub_dl_load ("vbe"); + #endif + + id = grub_video_get_driver_id (); + + FOR_VIDEO_ADAPTERS (adapter) + { + if (!adapter->iterate || + (adapter->id != id && (id != GRUB_VIDEO_DRIVER_NONE || + adapter->init() != GRUB_ERR_NONE))) + { + continue; + } + + adapter->iterate(ventoy_video_hook, NULL); + + if (adapter->id != id) + { + adapter->fini(); + } + } + + /* sort video mode */ + for (i = 0; i < g_video_mode_num; i++) + for (j = i + 1; j < g_video_mode_num; j++) + { + if (ventoy_video_mode_cmp(g_video_mode_list + i, g_video_mode_list + j) < 0) + { + grub_memcpy(&mode, g_video_mode_list + i, sizeof(ventoy_video_mode)); + grub_memcpy(g_video_mode_list + i, g_video_mode_list + j, sizeof(ventoy_video_mode)); + grub_memcpy(g_video_mode_list + j, &mode, sizeof(ventoy_video_mode)); + } + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_file_t ventoy_wrapper_open(grub_file_t rawFile, enum grub_file_type type) +{ + int len; + grub_file_t file; + static struct grub_fs vtoy_fs = + { + .name = "vtoy", + .fs_dir = 0, + .fs_open = 0, + .fs_read = ventoy_fs_read, + .fs_close = ventoy_fs_close, + .fs_label = 0, + .next = 0 + }; + + if (type != 52) + { + return rawFile; + } + + file = (grub_file_t)grub_zalloc(sizeof (*file)); + if (!file) + { + return 0; + } + + file->data = grub_malloc(rawFile->size + 4096); + if (!file->data) + { + return 0; + } + + grub_file_read(rawFile, file->data, rawFile->size); + len = ventoy_fill_data(4096, (char *)file->data + rawFile->size); + + g_old_file = rawFile; + + file->size = rawFile->size + len; + file->device = rawFile->device; + file->fs = &vtoy_fs; + file->not_easily_seekable = 1; + + return file; +} + +static int ventoy_check_decimal_var(const char *name, long *value) +{ + const char *value_str = NULL; + + value_str = grub_env_get(name); + if (NULL == value_str) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s not found", name); + } + + if (!ventoy_is_decimal(value_str)) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Variable %s value '%s' is not an integer", name, value_str); + } + + *value = grub_strtol(value_str, NULL, 10); + + return GRUB_ERR_NONE; +} + +grub_uint64_t ventoy_get_vtoy_partsize(int part) +{ + grub_uint64_t sectors; + + if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + sectors = g_ventoy_part_info->PartTbl[part].LastLBA + 1 - g_ventoy_part_info->PartTbl[part].StartLBA; + } + else + { + sectors = g_ventoy_part_info->MBR.PartTbl[part].SectorCount; + } + + return sectors * 512; +} + +static int ventoy_load_efiboot_template(char **buf, int *datalen, int *direntoff) +{ + int len; + grub_file_t file; + char exec[128]; + char *data = NULL; + grub_uint32_t offset; + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy_efiboot.img.xz", ventoy_get_env("vtoy_efi_part")); + if (file == NULL) + { + debug("failed to open file <%s>\n", "ventoy_efiboot.img.xz"); + return 1; + } + + len = (int)file->size; + + data = (char *)grub_malloc(file->size); + if (!data) + { + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + grub_snprintf(exec, sizeof(exec), "loopback efiboot mem:0x%llx:size:%d", (ulonglong)(ulong)data, len); + grub_script_execute_sourcecode(exec); + + file = grub_file_open("(efiboot)/EFI/BOOT/BOOTX64.EFI", GRUB_FILE_TYPE_LINUX_INITRD); + offset = (grub_uint32_t)grub_iso9660_get_last_file_dirent_pos(file); + grub_file_close(file); + + grub_script_execute_sourcecode("loopback -d efiboot"); + + *buf = data; + *datalen = len; + *direntoff = offset + 2; + + return 0; +} + +static int ventoy_set_check_result(int ret) +{ + char buf[32]; + + grub_snprintf(buf, sizeof(buf), "%d", (ret & 0x7FFF)); + grub_env_set("VTOY_CHKDEV_RESULT_STRING", buf); + grub_env_export("VTOY_CHKDEV_RESULT_STRING"); + + if (ret) + { + grub_printf(VTOY_WARNING"\n"); + grub_printf(VTOY_WARNING"\n"); + grub_printf(VTOY_WARNING"\n\n\n"); + + grub_printf("This is NOT a standard Ventoy device and is NOT supported (0x%x).\n\n", ret); + grub_printf("You should follow the instructions in https://www.ventoy.net to use Ventoy.\n"); + + grub_printf("\n\nWill exit after 10 seconds ...... "); + grub_refresh(); + grub_sleep(10); + } + + return ret; +} + +static int ventoy_check_official_device(grub_device_t dev) +{ + int workaround = 0; + grub_file_t file; + grub_uint64_t offset; + char devname[64]; + grub_fs_t fs; + grub_device_t dev2; + char *label = NULL; + struct grub_partition *partition; + + if (dev->disk == NULL || dev->disk->partition == NULL) + { + return ventoy_set_check_result(1 | 0x1000); + } + + if (0 == ventoy_check_file_exist("(%s,2)/ventoy/ventoy.cpio", dev->disk->name) || + 0 == ventoy_check_file_exist("(%s,2)/grub/localboot.cfg", dev->disk->name) || + 0 == ventoy_check_file_exist("(%s,2)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + { + #ifndef GRUB_MACHINE_EFI + if (0 == ventoy_check_file_exist("(ventoydisk)/ventoy/ventoy.cpio", dev->disk->name) || + 0 == ventoy_check_file_exist("(ventoydisk)/grub/localboot.cfg", dev->disk->name) || + 0 == ventoy_check_file_exist("(ventoydisk)/tool/mount.exfat-fuse_aarch64", dev->disk->name)) + { + return ventoy_set_check_result(2 | 0x1000); + } + else + { + workaround = 1; + } + #endif + } + + /* We must have partition 2 */ + if (workaround) + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(ventoydisk)/ventoy/ventoy.cpio"); + } + else + { + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(%s,2)/ventoy/ventoy.cpio", dev->disk->name); + } + if (!file) + { + return ventoy_set_check_result(3 | 0x1000); + } + + if (NULL == grub_strstr(file->fs->name, "fat")) + { + grub_file_close(file); + return ventoy_set_check_result(4 | 0x1000); + } + + partition = dev->disk->partition; + if (partition->number != 0 || partition->start != 2048) + { + return ventoy_set_check_result(5); + } + + if (workaround) + { + if (grub_strncmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + ventoy_gpt_part_tbl *PartTbl = g_ventoy_part_info->PartTbl; + if (PartTbl[1].StartLBA != PartTbl[0].LastLBA + 1 || + (PartTbl[1].LastLBA + 1 - PartTbl[1].StartLBA) != 65536) + { + grub_file_close(file); + return ventoy_set_check_result(6); + } + } + else + { + ventoy_part_table *PartTbl = g_ventoy_part_info->MBR.PartTbl; + if (PartTbl[1].StartSectorId != PartTbl[0].StartSectorId + PartTbl[0].SectorCount || + PartTbl[1].SectorCount != 65536) + { + grub_file_close(file); + return ventoy_set_check_result(6); + } + } + } + else + { + offset = partition->start + partition->len; + partition = file->device->disk->partition; + if ((partition->number != 1) || (partition->len != 65536) || (offset != partition->start)) + { + grub_file_close(file); + return ventoy_set_check_result(7); + } + } + + grub_file_close(file); + + if (workaround == 0) + { + grub_snprintf(devname, sizeof(devname), "%s,2", dev->disk->name); + dev2 = grub_device_open(devname); + if (!dev2) + { + return ventoy_set_check_result(8); + } + + fs = grub_fs_probe(dev2); + if (!fs) + { + grub_device_close(dev2); + return ventoy_set_check_result(9); + } + + fs->fs_label(dev2, &label); + if ((!label) || grub_strncmp("VTOYEFI", label, 7)) + { + grub_device_close(dev2); + return ventoy_set_check_result(10); + } + + grub_device_close(dev2); + } + + return ventoy_set_check_result(0); +} + +static int ventoy_check_ignore_flag(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (0 == info->dir) + { + if (filename && filename[0] == '.' && 0 == grub_strncmp(filename, ".ventoyignore", 13)) + { + *((int *)data) = 1; + return 0; + } + } + + return 0; +} + +grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...) +{ + grub_uint64_t size = 0; + grub_file_t file; + va_list ap; + char fullpath[256] = {0}; + + va_start (ap, fmt); + grub_vsnprintf(fullpath, 255, fmt, ap); + va_end (ap); + + file = grub_file_open(fullpath, VENTOY_FILE_TYPE); + if (!file) + { + debug("grub_file_open failed <%s>\n", fullpath); + grub_errno = 0; + return 0; + } + + size = file->size; + grub_file_close(file); + return size; +} + +grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...) +{ + va_list ap; + grub_file_t file; + char fullpath[256] = {0}; + + va_start (ap, fmt); + grub_vsnprintf(fullpath, 255, fmt, ap); + va_end (ap); + + file = grub_file_open(fullpath, type); + if (!file) + { + debug("grub_file_open failed <%s> %d\n", fullpath, grub_errno); + grub_errno = 0; + } + + return file; +} + +int ventoy_is_file_exist(const char *fmt, ...) +{ + va_list ap; + int len; + char *pos = NULL; + char buf[256] = {0}; + + grub_snprintf(buf, sizeof(buf), "%s", "[ -f \""); + pos = buf + 6; + + va_start (ap, fmt); + len = grub_vsnprintf(pos, 255, fmt, ap); + va_end (ap); + + grub_strncpy(pos + len, "\" ]", 3); + + debug("script exec %s\n", buf); + + if (0 == grub_script_execute_sourcecode(buf)) + { + return 1; + } + + return 0; +} + +int ventoy_is_dir_exist(const char *fmt, ...) +{ + va_list ap; + int len; + char *pos = NULL; + char buf[256] = {0}; + + grub_snprintf(buf, sizeof(buf), "%s", "[ -d \""); + pos = buf + 6; + + va_start (ap, fmt); + len = grub_vsnprintf(pos, 255, fmt, ap); + va_end (ap); + + grub_strncpy(pos + len, "\" ]", 3); + + debug("script exec %s\n", buf); + + if (0 == grub_script_execute_sourcecode(buf)) + { + return 1; + } + + return 0; +} + +int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len) +{ + mz_stream s; + grub_uint8_t *outbuf; + grub_uint8_t gzHdr[10] = + { + 0x1F, 0x8B, /* magic */ + 8, /* z method */ + 0, /* flags */ + 0,0,0,0, /* mtime */ + 4, /* xfl */ + 3, /* OS */ + }; + + grub_memset(&s, 0, sizeof(mz_stream)); + + mz_deflateInit2(&s, 1, MZ_DEFLATED, -MZ_DEFAULT_WINDOW_BITS, 6, MZ_DEFAULT_STRATEGY); + + outbuf = (grub_uint8_t *)mem_out; + + mem_out_len -= sizeof(gzHdr) + 8; + grub_memcpy(outbuf, gzHdr, sizeof(gzHdr)); + outbuf += sizeof(gzHdr); + + s.avail_in = mem_in_len; + s.next_in = mem_in; + + s.avail_out = mem_out_len; + s.next_out = outbuf; + + mz_deflate(&s, MZ_FINISH); + + mz_deflateEnd(&s); + + outbuf += s.total_out; + *(grub_uint32_t *)outbuf = grub_getcrc32c(0, outbuf, s.total_out); + *(grub_uint32_t *)(outbuf + 4) = (grub_uint32_t)(s.total_out); + + return s.total_out + sizeof(gzHdr) + 8; +} + + +#if 0 +ventoy grub cmds +#endif + +static grub_err_t ventoy_cmd_debug(grub_extcmd_context_t ctxt, int argc, char **args) +{ + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {on|off}", cmd_raw_name); + } + + if (0 == grub_strcmp(args[0], "on")) + { + g_ventoy_debug = 1; + grub_env_set("vtdebug_flag", "debug"); + } + else + { + g_ventoy_debug = 0; + grub_env_set("vtdebug_flag", ""); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_break(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc < 1 || (args[0][0] != '0' && args[0][0] != '1')) + { + grub_printf("Usage: %s {level} [debug]\r\n", cmd_raw_name); + grub_printf(" level:\r\n"); + grub_printf(" 01/11: busybox / (+cat log)\r\n"); + grub_printf(" 02/12: initrd / (+cat log)\r\n"); + grub_printf(" 03/13: hook / (+cat log)\r\n"); + grub_printf("\r\n"); + grub_printf(" debug:\r\n"); + grub_printf(" 0: debug is off\r\n"); + grub_printf(" 1: debug is on\r\n"); + grub_printf("\r\n"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + + g_ventoy_break_level = (grub_uint8_t)grub_strtoul(args[0], NULL, 16); + + if (argc > 1 && grub_strtoul(args[1], NULL, 10) > 0) + { + g_ventoy_debug_level = 1; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_strstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + return (grub_strstr(args[0], args[1])) ? 0 : 1; +} + +static grub_err_t ventoy_cmd_strbegin(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *c0, *c1; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + c0 = args[0]; + c1 = args[1]; + + while (*c0 && *c1) + { + if (*c0 != *c1) + { + return 1; + } + c0++; + c1++; + } + + if (*c1) + { + return 1; + } + + return 0; +} + +static grub_err_t ventoy_cmd_incr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long value_long = 0; + char buf[32]; + + if ((argc != 2) || (!ventoy_is_decimal(args[1]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Variable} {Int}", cmd_raw_name); + } + + if (GRUB_ERR_NONE != ventoy_check_decimal_var(args[0], &value_long)) + { + return grub_errno; + } + + value_long += grub_strtol(args[1], NULL, 10); + + grub_snprintf(buf, sizeof(buf), "%ld", value_long); + grub_env_set(args[0], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_mod(grub_extcmd_context_t ctxt, int argc, char **args) +{ + ulonglong value1 = 0; + ulonglong value2 = 0; + char buf[32]; + + if (argc != 3) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int} {Int} {Variable}", cmd_raw_name); + } + + value1 = grub_strtoull(args[0], NULL, 10); + value2 = grub_strtoull(args[1], NULL, 10); + + grub_snprintf(buf, sizeof(buf), "%llu", (value1 & (value2 - 1))); + grub_env_set(args[2], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_file_size(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char buf[32]; + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + grub_snprintf(buf, sizeof(buf), "%llu", (unsigned long long)file->size); + + grub_env_set(args[1], buf); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_load_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + g_wimboot_enable = 0; + grub_check_free(g_wimiso_path); + grub_check_free(g_wimiso_chunk_list.chunk); + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 0; + } + + grub_memset(&g_wimiso_chunk_list, 0, sizeof(g_wimiso_chunk_list)); + g_wimiso_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == g_wimiso_chunk_list.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + g_wimiso_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; + g_wimiso_chunk_list.cur_chunk = 0; + + ventoy_get_block_list(file, &g_wimiso_chunk_list, file->device->disk->partition->start); + + g_wimboot_enable = 1; + g_wimiso_path = grub_strdup(args[0]); + + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_concat_efi_iso(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + int totlen = 0; + int offset = 0; + grub_file_t file; + char name[32]; + char value[32]; + char *buf = NULL; + char *data = NULL; + ventoy_iso9660_override *dirent; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + totlen = sizeof(ventoy_chain_head); + + if (ventoy_load_efiboot_template(&buf, &len, &offset)) + { + debug("failed to load efiboot template %d\n", len); + return 1; + } + + totlen += len; + + debug("efiboot template len:%d offset:%d\n", len, offset); + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s>\n", args[0]); + return 1; + } + + totlen += ventoy_align_2k(file->size); + + dirent = (ventoy_iso9660_override *)(buf + offset); + dirent->first_sector = len / 2048; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size = (grub_uint32_t)file->size; + dirent->size_be = grub_swap_bytes32(dirent->size); + + debug("rawiso len:%d efilen:%d total:%d\n", len, (int)file->size, totlen); + +#ifdef GRUB_MACHINE_EFI + data = (char *)grub_efi_allocate_iso_buf(totlen); +#else + data = (char *)grub_malloc(totlen); +#endif + + ventoy_fill_os_param(file, (ventoy_os_param *)data); + + grub_memcpy(data + sizeof(ventoy_chain_head), buf, len); + grub_check_free(buf); + + grub_file_read(file, data + sizeof(ventoy_chain_head) + len, file->size); + grub_file_close(file); + + grub_snprintf(name, sizeof(name), "%s_addr", args[1]); + grub_snprintf(value, sizeof(value), "0x%llx", (ulonglong)(ulong)data); + grub_env_set(name, value); + + grub_snprintf(name, sizeof(name), "%s_size", args[1]); + grub_snprintf(value, sizeof(value), "%d", (int)(totlen)); + grub_env_set(name, value); + + return 0; +} + +grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_vtoy_load_prompt = 0; + grub_memset(g_vtoy_prompt_msg, 0, sizeof(g_vtoy_prompt_msg)); + + if (argc == 2 && args[0][0] == '1') + { + g_vtoy_load_prompt = 1; + grub_snprintf(g_vtoy_prompt_msg, sizeof(g_vtoy_prompt_msg), "%s", args[1]); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_need_prompt_load_file(void) +{ + return g_vtoy_load_prompt; +} + +grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size) +{ + grub_uint64_t ro = 0; + grub_uint64_t div = 0; + grub_ssize_t left = size; + char *cur = (char *)buf; + + grub_printf("\r%s 1%% ", g_vtoy_prompt_msg); + grub_refresh(); + + while (left >= VTOY_SIZE_2MB) + { + grub_file_read(file, cur, VTOY_SIZE_2MB); + cur += VTOY_SIZE_2MB; + left -= VTOY_SIZE_2MB; + + div = grub_divmod64((grub_uint64_t)((size - left) * 100), (grub_uint64_t)size, &ro); + grub_printf("\r%s %d%% ", g_vtoy_prompt_msg, (int)div); + grub_refresh(); + } + + if (left > 0) + { + grub_file_read(file, cur, left); + } + + grub_printf("\r%s 100%% \n", g_vtoy_prompt_msg); + grub_refresh(); + + return size; +} + +static grub_err_t ventoy_cmd_load_file_to_mem(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char name[32]; + char value[32]; + char *buf = NULL; + grub_file_t file; + enum grub_file_type type; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 3) + { + return rc; + } + + if (grub_strcmp(args[0], "nodecompress") == 0) + { + type = VENTOY_FILE_TYPE; + } + else + { + type = GRUB_FILE_TYPE_LINUX_INITRD; + } + + file = ventoy_grub_file_open(type, "%s", args[1]); + if (file == NULL) + { + debug("failed to open file <%s>\n", args[1]); + return 1; + } + +#ifdef GRUB_MACHINE_EFI + buf = (char *)grub_efi_allocate_chain_buf(file->size); +#else + buf = (char *)grub_malloc(file->size); +#endif + + if (!buf) + { + grub_file_close(file); + return 1; + } + + if (g_vtoy_load_prompt) + { + ventoy_load_file_with_prompt(file, buf, file->size); + } + else + { + grub_file_read(file, buf, file->size); + } + + grub_snprintf(name, sizeof(name), "%s_addr", args[2]); + grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); + grub_env_set(name, value); + + grub_snprintf(name, sizeof(name), "%s_size", args[2]); + grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size); + grub_env_set(name, value); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_load_img_memdisk(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + int headlen; + char name[32]; + char value[32]; + char *buf = NULL; + grub_file_t file; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 2) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + headlen = sizeof(ventoy_chain_head); + +#ifdef GRUB_MACHINE_EFI + buf = (char *)grub_efi_allocate_iso_buf(headlen + file->size); +#else + buf = (char *)grub_malloc(headlen + file->size); +#endif + + ventoy_fill_os_param(file, (ventoy_os_param *)buf); + + grub_file_read(file, buf + headlen, file->size); + + grub_snprintf(name, sizeof(name), "%s_addr", args[1]); + grub_snprintf(value, sizeof(value), "0x%llx", (unsigned long long)(unsigned long)buf); + grub_env_set(name, value); + + grub_snprintf(name, sizeof(name), "%s_size", args[1]); + grub_snprintf(value, sizeof(value), "%llu", (unsigned long long)file->size); + grub_env_set(name, value); + + grub_file_close(file); + rc = 0; + + return rc; +} + +static grub_err_t ventoy_cmd_iso9660_is_joliet(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (grub_iso9660_is_joliet()) + { + debug("This time has joliet process\n"); + return 0; + } + else + { + return 1; + } +} + +static grub_err_t ventoy_cmd_iso9660_nojoliet(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + if (args[0][0] == '1') + { + grub_iso9660_set_nojoliet(1); + } + else + { + grub_iso9660_set_nojoliet(0); + } + + return 0; +} + +static grub_err_t ventoy_cmd_is_udf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int rc = 1; + grub_file_t file; + grub_uint8_t buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1) + { + return rc; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (file == NULL) + { + debug("failed to open file <%s> for udf check\n", args[0]); + return 1; + } + + for (i = 16; i < 32; i++) + { + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + if (buf[0] == 255) + { + break; + } + } + + i++; + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (grub_memcmp(buf + 1, "BEA01", 5) == 0) + { + i++; + grub_file_seek(file, i * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (grub_memcmp(buf + 1, "NSR02", 5) == 0 || + grub_memcmp(buf + 1, "NSR03", 5) == 0) + { + rc = 0; + } + } + + grub_file_close(file); + + debug("ISO UDF: %s\n", rc ? "NO" : "YES"); + + return rc; +} + +static grub_err_t ventoy_cmd_cmp(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long value_long1 = 0; + long value_long2 = 0; + + if ((argc != 3) || (!ventoy_is_decimal(args[0])) || (!ventoy_is_decimal(args[2]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq|ne|gt|lt|ge|le } {Int2}", cmd_raw_name); + } + + value_long1 = grub_strtol(args[0], NULL, 10); + value_long2 = grub_strtol(args[2], NULL, 10); + + if (0 == grub_strcmp(args[1], "eq")) + { + grub_errno = (value_long1 == value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "ne")) + { + grub_errno = (value_long1 != value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "gt")) + { + grub_errno = (value_long1 > value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "lt")) + { + grub_errno = (value_long1 < value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "ge")) + { + grub_errno = (value_long1 >= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else if (0 == grub_strcmp(args[1], "le")) + { + grub_errno = (value_long1 <= value_long2) ? GRUB_ERR_NONE : GRUB_ERR_TEST_FAILURE; + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {Int1} { eq ne gt lt ge le } {Int2}", cmd_raw_name); + } + + return grub_errno; +} + +static grub_err_t ventoy_cmd_device(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *pos = NULL; + char buf[128] = {0}; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s path var", cmd_raw_name); + } + + grub_strncpy(buf, (args[0][0] == '(') ? args[0] + 1 : args[0], sizeof(buf) - 1); + pos = grub_strstr(buf, ","); + if (pos) + { + *pos = 0; + } + + grub_env_set(args[1], buf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_check_compatible(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + char buf[256]; + grub_disk_t disk; + char *pos = NULL; + const char *files[] = { "ventoy.dat", "VENTOY.DAT" }; + + (void)ctxt; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s (loop)", cmd_raw_name); + } + + for (i = 0; i < (int)ARRAY_SIZE(files); i++) + { + grub_snprintf(buf, sizeof(buf) - 1, "[ -e \"%s/%s\" ]", args[0], files[i]); + if (0 == grub_script_execute_sourcecode(buf)) + { + debug("file %s exist, ventoy_compatible YES\n", buf); + grub_env_set("ventoy_compatible", "YES"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + else + { + debug("file %s NOT exist\n", buf); + } + } + + grub_snprintf(buf, sizeof(buf) - 1, "%s", args[0][0] == '(' ? (args[0] + 1) : args[0]); + pos = grub_strstr(buf, ")"); + if (pos) + { + *pos = 0; + } + + disk = grub_disk_open(buf); + if (disk) + { + grub_disk_read(disk, 16 << 2, 0, 1024, g_img_swap_tmp_buf); + grub_disk_close(disk); + + g_img_swap_tmp_buf[703] = 0; + for (i = 318; i < 703; i++) + { + if (g_img_swap_tmp_buf[i] == 'V' && + 0 == grub_strncmp(g_img_swap_tmp_buf + i, VENTOY_COMPATIBLE_STR, VENTOY_COMPATIBLE_STR_LEN)) + { + debug("Ventoy compatible string exist at %d, ventoy_compatible YES\n", i); + grub_env_set("ventoy_compatible", "YES"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); + } + } + } + else + { + debug("failed to open disk <%s>\n", buf); + } + + grub_env_set("ventoy_compatible", "NO"); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_cmp_img(img_info *img1, img_info *img2) +{ + char *s1, *s2; + int c1 = 0; + int c2 = 0; + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + return (img1->plugin_list_index - img2->plugin_list_index); + } + + for (s1 = img1->name, s2 = img2->name; *s1 && *s2; s1++, s2++) + { + c1 = *s1; + c2 = *s2; + + if (0 == g_sort_case_sensitive) + { + if (grub_islower(c1)) + { + c1 = c1 - 'a' + 'A'; + } + + if (grub_islower(c2)) + { + c2 = c2 - 'a' + 'A'; + } + } + + if (c1 != c2) + { + break; + } + } + + return (c1 - c2); +} + +static int ventoy_cmp_subdir(img_iterator_node *node1, img_iterator_node *node2) +{ + char *s1, *s2; + int c1 = 0; + int c2 = 0; + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + return (node1->plugin_list_index - node2->plugin_list_index); + } + + for (s1 = node1->dir, s2 = node2->dir; *s1 && *s2; s1++, s2++) + { + c1 = *s1; + c2 = *s2; + + if (0 == g_sort_case_sensitive) + { + if (grub_islower(c1)) + { + c1 = c1 - 'a' + 'A'; + } + + if (grub_islower(c2)) + { + c2 = c2 - 'a' + 'A'; + } + } + + if (c1 != c2) + { + break; + } + } + + return (c1 - c2); +} + +void ventoy_swap_img(img_info *img1, img_info *img2) +{ + grub_memcpy(&g_img_swap_tmp, img1, sizeof(img_info)); + + grub_memcpy(img1, img2, sizeof(img_info)); + img1->next = g_img_swap_tmp.next; + img1->prev = g_img_swap_tmp.prev; + + g_img_swap_tmp.next = img2->next; + g_img_swap_tmp.prev = img2->prev; + grub_memcpy(img2, &g_img_swap_tmp, sizeof(img_info)); +} + +static int ventoy_img_name_valid(const char *filename, grub_size_t namelen) +{ + (void)namelen; + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + return 1; +} + +static int ventoy_collect_img_files(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + //int i = 0; + int type = 0; + int ignore = 0; + int index = 0; + grub_size_t len; + img_info *img; + img_info *tail; + img_iterator_node *tmp; + img_iterator_node *new_node; + img_iterator_node *node = (img_iterator_node *)data; + + if (g_enumerate_time_checked == 0) + { + g_enumerate_finish_time_ms = grub_get_time_ms(); + if ((g_enumerate_finish_time_ms - g_enumerate_start_time_ms) >= 3000) + { + grub_cls(); + grub_printf("\n\n Ventoy scanning files, please wait...\n"); + grub_refresh(); + g_enumerate_time_checked = 1; + } + } + + len = grub_strlen(filename); + + if (info->dir) + { + if (node->level + 1 > g_img_max_search_level) + { + return 0; + } + + if ((len == 1 && filename[0] == '.') || + (len == 2 && filename[0] == '.' && filename[1] == '.')) + { + return 0; + } + + if (!ventoy_img_name_valid(filename, len)) + { + return 0; + } + + if (filename[0] == '$' && 0 == grub_strncmp(filename, "$RECYCLE.BIN", 12)) + { + return 0; + } + + if (g_plugin_image_list == VENTOY_IMG_WHITE_LIST) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s/", node->dir, filename); + index = ventoy_plugin_get_image_list_index(vtoy_class_directory, g_img_swap_tmp_buf); + if (index == 0) + { + debug("Directory %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); + return 0; + } + } + + new_node = grub_zalloc(sizeof(img_iterator_node)); + if (new_node) + { + new_node->level = node->level + 1; + new_node->plugin_list_index = index; + new_node->dirlen = grub_snprintf(new_node->dir, sizeof(new_node->dir), "%s%s/", node->dir, filename); + + g_enum_fs->fs_dir(g_enum_dev, new_node->dir, ventoy_check_ignore_flag, &ignore); + if (ignore) + { + debug("Directory %s ignored...\n", new_node->dir); + grub_free(new_node); + return 0; + } + + new_node->tail = node->tail; + + new_node->parent = node; + if (!node->firstchild) + { + node->firstchild = new_node; + } + + if (g_img_iterator_tail) + { + g_img_iterator_tail->next = new_node; + g_img_iterator_tail = new_node; + } + else + { + g_img_iterator_head.next = new_node; + g_img_iterator_tail = new_node; + } + } + } + else + { + debug("Find a file %s\n", filename); + if (len < 4) + { + return 0; + } + + if (FILE_FLT(ISO) && 0 == grub_strcasecmp(filename + len - 4, ".iso")) + { + type = img_type_iso; + } + else if (FILE_FLT(WIM) && g_wimboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".wim"))) + { + type = img_type_wim; + } + else if (FILE_FLT(VHD) && g_vhdboot_enable && (0 == grub_strcasecmp(filename + len - 4, ".vhd") || + (len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vhdx")))) + { + type = img_type_vhd; + } + #ifdef GRUB_MACHINE_EFI + else if (FILE_FLT(EFI) && 0 == grub_strcasecmp(filename + len - 4, ".efi")) + { + type = img_type_efi; + } + #endif + else if (FILE_FLT(IMG) && 0 == grub_strcasecmp(filename + len - 4, ".img")) + { + if (len == 18 && grub_strncmp(filename, "ventoy_", 7) == 0) + { + if (grub_strncmp(filename + 7, "wimboot", 7) == 0 || + grub_strncmp(filename + 7, "vhdboot", 7) == 0) + { + return 0; + } + } + type = img_type_img; + } + else if (FILE_FLT(VTOY) && len >= 5 && 0 == grub_strcasecmp(filename + len - 5, ".vtoy")) + { + type = img_type_vtoy; + } + else if (len >= 9 && 0 == grub_strcasecmp(filename + len - 5, ".vcfg")) + { + if (filename[len - 9] == '.' || (len >= 10 && filename[len - 10] == '.')) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); + ventoy_plugin_add_custom_boot(g_img_swap_tmp_buf); + } + return 0; + } + else + { + return 0; + } + + if (g_filt_dot_underscore_file && filename[0] == '.' && filename[1] == '_') + { + return 0; + } + + if (g_plugin_image_list) + { + grub_snprintf(g_img_swap_tmp_buf, sizeof(g_img_swap_tmp_buf), "%s%s", node->dir, filename); + index = ventoy_plugin_get_image_list_index(vtoy_class_image_file, g_img_swap_tmp_buf); + if (VENTOY_IMG_WHITE_LIST == g_plugin_image_list && index == 0) + { + debug("File %s not found in image_list plugin config...\n", g_img_swap_tmp_buf); + return 0; + } + else if (VENTOY_IMG_BLACK_LIST == g_plugin_image_list && index > 0) + { + debug("File %s found in image_blacklist plugin config %d ...\n", g_img_swap_tmp_buf, index); + return 0; + } + } + + img = grub_zalloc(sizeof(img_info)); + if (img) + { + img->type = type; + img->plugin_list_index = index; + grub_snprintf(img->name, sizeof(img->name), "%s", filename); + + img->pathlen = grub_snprintf(img->path, sizeof(img->path), "%s%s", node->dir, img->name); + + img->size = info->size; + if (0 == img->size) + { + img->size = ventoy_grub_get_file_size("%s/%s%s", g_iso_path, node->dir, filename); + } + + if (img->size < VTOY_FILT_MIN_FILE_SIZE) + { + debug("img <%s> size too small %llu\n", img->name, (ulonglong)img->size); + grub_free(img); + return 0; + } + + if (g_ventoy_img_list) + { + tail = *(node->tail); + img->prev = tail; + tail->next = img; + } + else + { + g_ventoy_img_list = img; + } + + img->id = g_ventoy_img_count; + img->parent = node; + if (node && NULL == node->firstiso) + { + node->firstiso = img; + } + + node->isocnt++; + tmp = node->parent; + while (tmp) + { + tmp->isocnt++; + tmp = tmp->parent; + } + + *((img_info **)(node->tail)) = img; + g_ventoy_img_count++; + + img->alias = ventoy_plugin_get_menu_alias(vtoy_alias_image_file, img->path); + img->class = ventoy_plugin_get_menu_class(vtoy_class_image_file, img->name, img->path); + if (!img->class) + { + img->class = g_menu_class[type]; + } + img->menu_prefix = g_menu_prefix[type]; + + if (img_type_iso == type) + { + if (ventoy_plugin_check_memdisk(img->path)) + { + img->menu_prefix = "miso"; + } + } + + debug("Add %s%s to list %d\n", node->dir, filename, g_ventoy_img_count); + } + } + + return 0; +} + +int ventoy_fill_data(grub_uint32_t buflen, char *buffer) +{ + int len = GRUB_UINT_MAX; + const char *value = NULL; + char name[32] = {0}; + char plat[32] = {0}; + char guidstr[32] = {0}; + ventoy_guid guid = VENTOY_GUID; + const char *fmt1 = NULL; + const char *fmt2 = NULL; + const char *fmt3 = NULL; + grub_uint32_t *puint = (grub_uint32_t *)name; + grub_uint32_t *puint2 = (grub_uint32_t *)plat; + const char fmtdata[]={ 0x39, 0x35, 0x25, 0x00, 0x35, 0x00, 0x23, 0x30, 0x30, 0x30, 0x30, 0x66, 0x66, 0x00 }; + const char fmtcode[]={ + 0x22, 0x0A, 0x2B, 0x20, 0x68, 0x62, 0x6F, 0x78, 0x20, 0x7B, 0x0A, 0x20, 0x20, 0x74, 0x6F, 0x70, + 0x20, 0x3D, 0x20, 0x25, 0x73, 0x0A, 0x20, 0x20, 0x6C, 0x65, 0x66, 0x74, 0x20, 0x3D, 0x20, 0x25, + 0x73, 0x0A, 0x20, 0x20, 0x2B, 0x20, 0x6C, 0x61, 0x62, 0x65, 0x6C, 0x20, 0x7B, 0x74, 0x65, 0x78, + 0x74, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x20, 0x25, 0x73, 0x25, 0x73, 0x22, 0x20, 0x63, 0x6F, + 0x6C, 0x6F, 0x72, 0x20, 0x3D, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x61, 0x6C, 0x69, 0x67, 0x6E, + 0x20, 0x3D, 0x20, 0x22, 0x6C, 0x65, 0x66, 0x74, 0x22, 0x7D, 0x0A, 0x7D, 0x0A, 0x22, 0x00 + }; + + grub_memset(name, 0, sizeof(name)); + puint[0] = grub_swap_bytes32(0x56454e54); + puint[3] = grub_swap_bytes32(0x4f4e0000); + puint[2] = grub_swap_bytes32(0x45525349); + puint[1] = grub_swap_bytes32(0x4f595f56); + value = ventoy_get_env(name); + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f544f50); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt1 = ventoy_get_env(name); + if (!fmt1) + { + fmt1 = fmtdata; + } + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f4c4654); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt2 = ventoy_get_env(name); + + grub_memset(name, 0, sizeof(name)); + puint[1] = grub_swap_bytes32(0x5f434c52); + puint[0] = grub_swap_bytes32(0x56544c45); + fmt3 = ventoy_get_env(name); + + grub_memcpy(guidstr, &guid, sizeof(guid)); + + puint2[0] = grub_swap_bytes32(g_ventoy_plat_data); + + /* Easter egg :) It will be appreciated if you reserve it, but NOT mandatory. */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + len = grub_snprintf(buffer, buflen, fmtcode, + fmt1 ? fmt1 : fmtdata, + fmt2 ? fmt2 : fmtdata + 4, + value ? value : "", plat, guidstr, + fmt3 ? fmt3 : fmtdata + 6); + #pragma GCC diagnostic pop + + grub_memset(name, 0, sizeof(name)); + puint[0] = grub_swap_bytes32(0x76746f79); + puint[2] = grub_swap_bytes32(0x656e7365); + puint[1] = grub_swap_bytes32(0x5f6c6963); + ventoy_set_env(name, guidstr); + + return len; +} + +int ventoy_check_password(const vtoy_password *pwd, int retry) +{ + int offset; + char input[256]; + grub_uint8_t md5[16]; + + while (retry--) + { + grub_memset(input, 0, sizeof(input)); + + grub_printf("Enter password: "); + grub_refresh(); + + if (pwd->type == VTOY_PASSWORD_TXT) + { + grub_password_get(input, 128); + if (grub_strcmp(pwd->text, input) == 0) + { + return 0; + } + } + else if (pwd->type == VTOY_PASSWORD_MD5) + { + grub_password_get(input, 128); + grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); + if (grub_memcmp(pwd->md5, md5, 16) == 0) + { + return 0; + } + } + else if (pwd->type == VTOY_PASSWORD_SALT_MD5) + { + offset = (int)grub_snprintf(input, 128, "%s", pwd->salt); + grub_password_get(input + offset, 128); + + grub_crypto_hash(GRUB_MD_MD5, md5, input, grub_strlen(input)); + if (grub_memcmp(pwd->md5, md5, 16) == 0) + { + return 0; + } + } + + grub_printf("Invalid password!\n\n"); + grub_refresh(); + } + + return 1; +} + +static img_info * ventoy_get_min_iso(img_iterator_node *node) +{ + img_info *minimg = NULL; + img_info *img = (img_info *)(node->firstiso); + + while (img && (img_iterator_node *)(img->parent) == node) + { + if (img->select == 0 && (NULL == minimg || ventoy_cmp_img(img, minimg) < 0)) + { + minimg = img; + } + img = img->next; + } + + if (minimg) + { + minimg->select = 1; + } + + return minimg; +} + +static img_iterator_node * ventoy_get_min_child(img_iterator_node *node) +{ + img_iterator_node *Minchild = NULL; + img_iterator_node *child = node->firstchild; + + while (child && child->parent == node) + { + if (child->select == 0 && (NULL == Minchild || ventoy_cmp_subdir(child, Minchild) < 0)) + { + Minchild = child; + } + child = child->next; + } + + if (Minchild) + { + Minchild->select = 1; + } + + return Minchild; +} + +static int ventoy_dynamic_tree_menu(img_iterator_node *node) +{ + int offset = 1; + img_info *img = NULL; + const char *dir_class = NULL; + const char *dir_alias = NULL; + img_iterator_node *child = NULL; + + if (node->isocnt == 0 || node->done == 1) + { + return 0; + } + + if (node->parent && node->parent->dirlen < node->dirlen) + { + offset = node->parent->dirlen; + } + + if (node == &g_img_iterator_head) + { + if (g_default_menu_mode == 0) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"[Return to ListView]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo '%s ...' \n" + "}\n", "return"); + } + } + } + else + { + node->dir[node->dirlen - 1] = 0; + dir_class = ventoy_plugin_get_menu_class(vtoy_class_directory, node->dir, node->dir); + if (!dir_class) + { + dir_class = "vtoydir"; + } + + dir_alias = ventoy_plugin_get_menu_alias(vtoy_alias_directory, node->dir); + if (dir_alias) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s %s\" --class=\"%s\" --id=\"DIR_%s\" {\n", + "DIR", dir_alias, dir_class, node->dir + offset); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%s\" --class=\"%s\" --id=\"DIR_%s\" {\n", + dir_alias, dir_class, node->dir + offset); + } + } + else + { + dir_alias = node->dir + offset; + + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"%-10s [%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n", + "DIR", dir_alias, dir_class, node->dir + offset); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "submenu \"[%s]\" --class=\"%s\" --id=\"DIR_%s\" {\n", + dir_alias, dir_class, node->dir + offset); + } + } + + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s [../]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"[../]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo '%s ...' \n" + "}\n", "return"); + } + } + + while ((child = ventoy_get_min_child(node)) != NULL) + { + ventoy_dynamic_tree_menu(child); + } + + while ((img = ventoy_get_min_iso(node)) != NULL) + { + if (g_tree_view_menu_style == 0) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%-10s %s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" + "}\n", + grub_get_human_size(img->size, GRUB_HUMAN_SIZE_SHORT), + img->unsupport ? "[***********] " : "", + img->alias ? img->alias : img->name, img->class, img->id, + img->menu_prefix, + img->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + else + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, + "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" + "}\n", + img->unsupport ? "[***********] " : "", + img->alias ? img->alias : img->name, img->class, img->id, + img->menu_prefix, + img->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + } + + if (node != &g_img_iterator_head) + { + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "%s", "}\n"); + } + + node->done = 1; + return 0; +} + +static int ventoy_set_default_menu(void) +{ + int img_len = 0; + char *pos = NULL; + char *end = NULL; + char *def = NULL; + const char *strdata = NULL; + img_info *cur = NULL; + img_info *default_node = NULL; + const char *default_image = NULL; + + default_image = ventoy_get_env("VTOY_DEFAULT_IMAGE"); + if (default_image && default_image[0] == '/') + { + img_len = grub_strlen(default_image); + + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + if (img_len == cur->pathlen && grub_strcmp(default_image, cur->path) == 0) + { + default_node = cur; + break; + } + } + + if (!default_node) + { + return 1; + } + + if (0 == g_default_menu_mode) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, "set default='VID_%d'\n", default_node->id); + } + else + { + def = grub_strdup(default_image); + if (!def) + { + return 1; + } + + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "set default=%c", '\''); + + strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); + if (strdata && strdata[0] == '/') + { + pos = def + grub_strlen(strdata); + if (*pos == '/') + { + pos++; + } + } + else + { + pos = def + 1; + } + + while ((end = grub_strchr(pos, '/')) != NULL) + { + *end = 0; + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "DIR_%s>", pos); + pos = end + 1; + } + + vtoy_ssprintf(g_tree_script_buf, g_tree_script_pos, "VID_%d'\n", default_node->id); + grub_free(def); + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_clear_img(grub_extcmd_context_t ctxt, int argc, char **args) +{ + img_info *next = NULL; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + (void)argc; + (void)args; + + while (cur) + { + next = cur->next; + grub_free(cur); + cur = next; + } + + g_ventoy_img_list = NULL; + g_ventoy_img_count = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_img_name(grub_extcmd_context_t ctxt, int argc, char **args) +{ + long img_id = 0; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc != 2 || (!ventoy_is_decimal(args[0]))) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {imageID} {var}", cmd_raw_name); + } + + img_id = grub_strtol(args[0], NULL, 10); + if (img_id >= g_ventoy_img_count) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images %ld %ld", img_id, g_ventoy_img_count); + } + + debug("Find image %ld name \n", img_id); + + while (cur && img_id > 0) + { + img_id--; + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such many images"); + } + + debug("image name is %s\n", cur->name); + + grub_env_set(args[1], cur->name); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_ext_select_img_path(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 0; + char id[32] = {0}; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); + } + + len = (int)grub_strlen(args[0]); + + while (cur) + { + if (len == cur->pathlen && 0 == grub_strcmp(args[0], cur->path)) + { + break; + } + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); + } + + grub_snprintf(id, sizeof(id), "VID_%d", cur->id); + grub_env_set("chosen", id); + grub_env_export("chosen"); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_chosen_img_path(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int img_id = 0; + char value[32]; + char *pos = NULL; + const char *id = NULL; + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + + if (argc < 1 || argc > 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {var}", cmd_raw_name); + } + + id = grub_env_get("chosen"); + + pos = grub_strstr(id, "VID_"); + if (pos) + { + img_id = (int)grub_strtoul(pos + 4, NULL, 10); + } + else + { + img_id = (int)grub_strtoul(id, NULL, 10); + } + + while (cur) + { + if (img_id == cur->id) + { + break; + } + cur = cur->next; + } + + if (!cur) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "No such image"); + } + + grub_env_set(args[0], cur->path); + + if (argc > 1) + { + grub_snprintf(value, sizeof(value), "%llu", (ulonglong)(cur->size)); + grub_env_set(args[1], value); + } + + g_svd_replace_offset = 0; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + + +static grub_err_t ventoy_cmd_list_img(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_fs_t fs; + grub_device_t dev = NULL; + img_info *cur = NULL; + img_info *tail = NULL; + const char *strdata = NULL; + char *device_name = NULL; + char buf[32]; + img_iterator_node *node = NULL; + img_iterator_node *tmp = NULL; + + (void)ctxt; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s {device} {cntvar}", cmd_raw_name); + } + + if (g_ventoy_img_list || g_ventoy_img_count) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Must clear image before list"); + } + + VTOY_CMD_CHECK(1); + + g_enumerate_time_checked = 0; + g_enumerate_start_time_ms = grub_get_time_ms(); + + strdata = ventoy_get_env("VTOY_FILT_DOT_UNDERSCORE_FILE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_filt_dot_underscore_file = 1; + } + + strdata = ventoy_get_env("VTOY_SORT_CASE_SENSITIVE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_sort_case_sensitive = 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto fail; + } + + g_enum_dev = dev = grub_device_open(device_name); + if (!dev) + { + goto fail; + } + + g_enum_fs = fs = grub_fs_probe(dev); + if (!fs) + { + goto fail; + } + + if (ventoy_get_fs_type(fs->name) >= ventoy_fs_max) + { + debug("unsupported fs:<%s>\n", fs->name); + ventoy_set_env("VTOY_NO_ISO_TIP", "unsupported file system"); + goto fail; + } + + ventoy_set_env("vtoy_iso_fs", fs->name); + + strdata = ventoy_get_env("VTOY_DEFAULT_MENU_MODE"); + if (strdata && strdata[0] == '1') + { + g_default_menu_mode = 1; + } + + grub_memset(&g_img_iterator_head, 0, sizeof(g_img_iterator_head)); + + grub_snprintf(g_iso_path, sizeof(g_iso_path), "%s", args[0]); + + strdata = ventoy_get_env("VTOY_DEFAULT_SEARCH_ROOT"); + if (strdata && strdata[0] == '/') + { + len = grub_snprintf(g_img_iterator_head.dir, sizeof(g_img_iterator_head.dir) - 1, "%s", strdata); + if (g_img_iterator_head.dir[len - 1] != '/') + { + g_img_iterator_head.dir[len++] = '/'; + } + g_img_iterator_head.dirlen = len; + } + else + { + g_img_iterator_head.dirlen = 1; + grub_strcpy(g_img_iterator_head.dir, "/"); + } + + g_img_iterator_head.tail = &tail; + + if (g_img_max_search_level < 0) + { + g_img_max_search_level = GRUB_INT_MAX; + strdata = ventoy_get_env("VTOY_MAX_SEARCH_LEVEL"); + if (strdata && ventoy_is_decimal(strdata)) + { + g_img_max_search_level = (int)grub_strtoul(strdata, NULL, 10); + } + } + + g_vtoy_file_flt[VTOY_FILE_FLT_ISO] = ventoy_control_get_flag("VTOY_FILE_FLT_ISO"); + g_vtoy_file_flt[VTOY_FILE_FLT_WIM] = ventoy_control_get_flag("VTOY_FILE_FLT_WIM"); + g_vtoy_file_flt[VTOY_FILE_FLT_EFI] = ventoy_control_get_flag("VTOY_FILE_FLT_EFI"); + g_vtoy_file_flt[VTOY_FILE_FLT_IMG] = ventoy_control_get_flag("VTOY_FILE_FLT_IMG"); + g_vtoy_file_flt[VTOY_FILE_FLT_VHD] = ventoy_control_get_flag("VTOY_FILE_FLT_VHD"); + g_vtoy_file_flt[VTOY_FILE_FLT_VTOY] = ventoy_control_get_flag("VTOY_FILE_FLT_VTOY"); + + for (node = &g_img_iterator_head; node; node = node->next) + { + fs->fs_dir(dev, node->dir, ventoy_collect_img_files, node); + } + + strdata = ventoy_get_env("VTOY_TREE_VIEW_MENU_STYLE"); + if (strdata && strdata[0] == '1' && strdata[1] == 0) + { + g_tree_view_menu_style = 1; + } + + ventoy_set_default_menu(); + + for (node = &g_img_iterator_head; node; node = node->next) + { + ventoy_dynamic_tree_menu(node); + } + + /* free node */ + node = g_img_iterator_head.next; + while (node) + { + tmp = node->next; + grub_free(node); + node = tmp; + } + + /* sort image list by image name */ + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + for (tail = cur->next; tail; tail = tail->next) + { + if (ventoy_cmp_img(cur, tail) > 0) + { + ventoy_swap_img(cur, tail); + } + } + } + + if (g_default_menu_mode == 1) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s [Return to TreeView]\" --class=\"vtoyret\" VTOY_RET {\n " + " echo 'return ...' \n" + "}\n", "<--"); + } + + for (cur = g_ventoy_img_list; cur; cur = cur->next) + { + vtoy_ssprintf(g_list_script_buf, g_list_script_pos, + "menuentry \"%s%s\" --class=\"%s\" --id=\"VID_%d\" {\n" + " %s_%s \n" + "}\n", + cur->unsupport ? "[***********] " : "", + cur->alias ? cur->alias : cur->name, cur->class, cur->id, + cur->menu_prefix, + cur->unsupport ? "unsupport_menuentry" : "common_menuentry"); + } + + g_tree_script_buf[g_tree_script_pos] = 0; + g_list_script_buf[g_list_script_pos] = 0; + + grub_snprintf(buf, sizeof(buf), "%d", g_ventoy_img_count); + grub_env_set(args[1], buf); + +fail: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature) +{ + grub_disk_t disk; + char *device_name; + char *pos; + char *pos2; + + device_name = grub_file_get_device_name(filename); + if (!device_name) + { + return 1; + } + + pos = device_name; + if (pos[0] == '(') + { + pos++; + } + + pos2 = grub_strstr(pos, ","); + if (!pos2) + { + pos2 = grub_strstr(pos, ")"); + } + + if (pos2) + { + *pos2 = 0; + } + + disk = grub_disk_open(pos); + if (disk) + { + grub_disk_read(disk, 0, 0x180, 16, guid); + grub_disk_read(disk, 0, 0x1b8, 4, signature); + grub_disk_close(disk); + } + else + { + return 1; + } + + grub_free(device_name); + return 0; +} + +grub_uint32_t ventoy_get_iso_boot_catlog(grub_file_t file) +{ + eltorito_descriptor desc; + + grub_memset(&desc, 0, sizeof(desc)); + grub_file_seek(file, 17 * 2048); + grub_file_read(file, &desc, sizeof(desc)); + + if (desc.type != 0 || desc.version != 1) + { + return 0; + } + + if (grub_strncmp((char *)desc.id, "CD001", 5) != 0 || + grub_strncmp((char *)desc.system_id, "EL TORITO SPECIFICATION", 23) != 0) + { + return 0; + } + + return desc.sector; +} + +int ventoy_has_efi_eltorito(grub_file_t file, grub_uint32_t sector) +{ + int i; + int x86count = 0; + grub_uint8_t buf[512]; + grub_uint8_t parttype[] = { 0x04, 0x06, 0x0B, 0x0C }; + + grub_file_seek(file, sector * 2048); + grub_file_read(file, buf, sizeof(buf)); + + if (buf[0] == 0x01 && buf[1] == 0xEF) + { + debug("%s efi eltorito in Validation Entry\n", file->name); + return 1; + } + + if (buf[0] == 0x01 && buf[1] == 0x00) + { + x86count++; + } + + for (i = 64; i < (int)sizeof(buf); i += 32) + { + if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) + { + debug("%s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); + return 1; + } + + if ((buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0x00 && x86count == 1) + { + debug("0x9100 assume %s efi eltorito offset %d 0x%02x\n", file->name, i, buf[i]); + return 1; + } + } + + if (x86count && buf[32] == 0x88 && buf[33] == 0x04) + { + for (i = 0; i < (int)(ARRAY_SIZE(parttype)); i++) + { + if (buf[36] == parttype[i]) + { + debug("hard disk image assume %s efi eltorito, part type 0x%x\n", file->name, buf[36]); + return 1; + } + } + } + + debug("%s does not contain efi eltorito\n", file->name); + return 0; +} + +void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param) +{ + char *pos; + const char *fs = NULL; + const char *cdprompt = NULL; + grub_uint32_t i; + grub_uint8_t chksum = 0; + grub_disk_t disk; + + disk = file->device->disk; + grub_memcpy(¶m->guid, &g_ventoy_guid, sizeof(ventoy_guid)); + + param->vtoy_disk_size = disk->total_sectors * (1 << disk->log_sector_size); + param->vtoy_disk_part_id = disk->partition->number + 1; + param->vtoy_disk_part_type = ventoy_get_fs_type(file->fs->name); + + pos = grub_strstr(file->name, "/"); + if (!pos) + { + pos = file->name; + } + + grub_snprintf(param->vtoy_img_path, sizeof(param->vtoy_img_path), "%s", pos); + + ventoy_get_disk_guid(file->name, param->vtoy_disk_guid, param->vtoy_disk_signature); + + param->vtoy_img_size = file->size; + + param->vtoy_reserved[0] = g_ventoy_break_level; + param->vtoy_reserved[1] = g_ventoy_debug_level; + + param->vtoy_reserved[2] = g_ventoy_chain_type; + + /* Windows CD/DVD prompt 0:suppress 1:reserved */ + param->vtoy_reserved[4] = 0; + if (g_ventoy_chain_type == 1) /* Windows */ + { + cdprompt = ventoy_get_env("VTOY_WINDOWS_CD_PROMPT"); + if (cdprompt && cdprompt[0] == '1' && cdprompt[1] == 0) + { + param->vtoy_reserved[4] = 1; + } + } + + fs = ventoy_get_env("ventoy_fs_probe"); + if (fs && grub_strcmp(fs, "udf") == 0) + { + param->vtoy_reserved[3] = 1; + } + + /* calculate checksum */ + for (i = 0; i < sizeof(ventoy_os_param); i++) + { + chksum += *((grub_uint8_t *)param + i); + } + param->chksum = (grub_uint8_t)(0x100 - chksum); + + return; +} + +int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) +{ + grub_uint32_t i = 0; + grub_uint64_t total = 0; + grub_uint64_t fileblk = 0; + ventoy_img_chunk *chunk = NULL; + + for (i = 0; i < chunklist->cur_chunk; i++) + { + chunk = chunklist->chunk + i; + + if (chunk->disk_start_sector <= start) + { + debug("%u disk start invalid %lu\n", i, (ulong)start); + return 1; + } + + total += chunk->disk_end_sector + 1 - chunk->disk_start_sector; + } + + fileblk = (file->size + 511) / 512; + + if (total != fileblk) + { + debug("Invalid total: %llu %llu\n", (ulonglong)total, (ulonglong)fileblk); + if ((file->size % 512) && (total + 1 == fileblk)) + { + debug("maybe img file to be processed.\n"); + return 0; + } + + return 1; + } + + return 0; +} + +int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start) +{ + int fs_type; + int len; + grub_uint32_t i = 0; + grub_uint32_t sector = 0; + grub_uint32_t count = 0; + grub_off_t size = 0; + grub_off_t read = 0; + + fs_type = ventoy_get_fs_type(file->fs->name); + if (fs_type == ventoy_fs_exfat) + { + grub_fat_get_file_chunk(start, file, chunklist); + } + else if (fs_type == ventoy_fs_ext) + { + grub_ext_get_file_chunk(start, file, chunklist); + } + else + { + file->read_hook = (grub_disk_read_hook_t)grub_disk_blocklist_read; + file->read_hook_data = chunklist; + + for (size = file->size; size > 0; size -= read) + { + read = (size > VTOY_SIZE_1GB) ? VTOY_SIZE_1GB : size; + grub_file_read(file, NULL, read); + } + + for (i = 0; start > 0 && i < chunklist->cur_chunk; i++) + { + chunklist->chunk[i].disk_start_sector += start; + chunklist->chunk[i].disk_end_sector += start; + } + + if (ventoy_fs_udf == fs_type) + { + for (i = 0; i < chunklist->cur_chunk; i++) + { + count = (chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector) >> 2; + chunklist->chunk[i].img_start_sector = sector; + chunklist->chunk[i].img_end_sector = sector + count - 1; + sector += count; + } + } + } + + len = (int)grub_strlen(file->name); + if ((len > 4 && grub_strncasecmp(file->name + len - 4, ".img", 4) == 0) || + (len > 4 && grub_strncasecmp(file->name + len - 4, ".vhd", 4) == 0) || + (len > 5 && grub_strncasecmp(file->name + len - 5, ".vhdx", 5) == 0) || + (len > 5 && grub_strncasecmp(file->name + len - 5, ".vtoy", 5) == 0)) + { + for (i = 0; i < chunklist->cur_chunk; i++) + { + count = chunklist->chunk[i].disk_end_sector + 1 - chunklist->chunk[i].disk_start_sector; + if (count < 4) + { + count = 1; + } + else + { + count >>= 2; + } + + chunklist->chunk[i].img_start_sector = sector; + chunklist->chunk[i].img_end_sector = sector + count - 1; + sector += count; + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc; + grub_file_t file; + grub_disk_addr_t start; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + g_conf_replace_node = NULL; + g_conf_replace_offset = 0; + + if (g_img_chunk_list.chunk) + { + grub_free(g_img_chunk_list.chunk); + } + + if (ventoy_get_fs_type(file->fs->name) >= ventoy_fs_max) + { + grub_file_close(file); + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Unsupported filesystem %s\n", file->fs->name); + } + + /* get image chunk data */ + grub_memset(&g_img_chunk_list, 0, sizeof(g_img_chunk_list)); + g_img_chunk_list.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == g_img_chunk_list.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + g_img_chunk_list.max_chunk = DEFAULT_CHUNK_NUM; + g_img_chunk_list.cur_chunk = 0; + + start = file->device->disk->partition->start; + + ventoy_get_block_list(file, &g_img_chunk_list, start); + + rc = ventoy_check_block_list(file, &g_img_chunk_list, start); + grub_file_close(file); + + if (rc) + { + return grub_error(GRUB_ERR_NOT_IMPLEMENTED_YET, "Unsupported chunk list.\n"); + } + + grub_memset(&g_grub_param->file_replace, 0, sizeof(g_grub_param->file_replace)); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_select_conf_replace(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint64_t offset = 0; + grub_uint32_t align = 0; + grub_file_t file = NULL; + conf_replace *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select conf replace argc:%d\n", argc); + + if (argc < 2) + { + return 0; + } + + node = ventoy_plugin_find_conf_replace(args[1]); + if (!node) + { + debug("Conf replace not found for %s\n", args[1]); + goto end; + } + + debug("Find conf replace for %s\n", args[1]); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", node->orgconf); + if (!file) + { + debug("<(loop)%s> NOT exist\n", node->orgconf); + goto end; + } + + offset = grub_iso9660_get_last_file_dirent_pos(file); + grub_file_close(file); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], node->newconf); + if (!file) + { + debug("New config file <%s%s> NOT exist\n", args[0], node->newconf); + goto end; + } + + align = ((int)file->size + 2047) / 2048 * 2048; + + if (align > vtoy_max_replace_file_size) + { + debug("New config file <%s%s> too big\n", args[0], node->newconf); + goto end; + } + + grub_file_read(file, g_conf_replace_new_buf, file->size); + g_conf_replace_new_len = (int)file->size; + g_conf_replace_new_len_align = align; + + g_conf_replace_node = node; + g_conf_replace_offset = offset + 2; + + debug("conf_replace OK: newlen: %d\n", g_conf_replace_new_len); + +end: + if (file) + { + grub_file_close(file); + } + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_sel_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int pos = 0; + char *buf = NULL; + char configfile[128]; + install_template *node = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select auto installation argc:%d\n", argc); + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_install_template(args[0]); + if (!node) + { + debug("Auto install template not found for %s\n", args[0]); + return 0; + } + + if (node->autosel >= 0 && node->autosel <= node->templatenum) + { + node->cursel = node->autosel - 1; + debug("Auto install template auto select %d\n", node->autosel); + return 0; + } + + buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!buf) + { + return 0; + } + + vtoy_ssprintf(buf, pos, "menuentry \"Boot without auto installation template\" {\n" + " echo %s\n}\n", "123"); + + for (i = 0; i < node->templatenum; i++) + { + vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" + " echo 123\n}\n", + node->templatepath[i].path); + } + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + + grub_free(buf); + + node->cursel = g_ventoy_last_entry - 1; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_sel_persistence(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i = 0; + int pos = 0; + char *buf = NULL; + char configfile[128]; + persistence_config *node; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select persistence argc:%d\n", argc); + + if (argc < 1) + { + return 0; + } + + node = ventoy_plugin_find_persistent(args[0]); + if (!node) + { + debug("Persistence image not found for %s\n", args[0]); + return 0; + } + + if (node->autosel >= 0 && node->autosel <= node->backendnum) + { + node->cursel = node->autosel - 1; + debug("Persistence image auto select %d\n", node->autosel); + return 0; + } + + buf = (char *)grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!buf) + { + return 0; + } + + vtoy_ssprintf(buf, pos, "menuentry \"Boot without persistence\" {\n" + " echo %s\n}\n", "123"); + + for (i = 0; i < node->backendnum; i++) + { + vtoy_ssprintf(buf, pos, "menuentry \"Boot with %s\" {\n" + " echo 123\n}\n", + node->backendpath[i].path); + + } + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, pos); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + + grub_free(buf); + + node->cursel = g_ventoy_last_entry - 1; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_dump_img_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + ventoy_img_chunk *cur; + + (void)ctxt; + (void)argc; + (void)args; + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + cur = g_img_chunk_list.chunk + i; + grub_printf("image:[%u - %u] <==> disk:[%llu - %llu]\n", + cur->img_start_sector, cur->img_end_sector, + (unsigned long long)cur->disk_start_sector, (unsigned long long)cur->disk_end_sector + ); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_test_block_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + grub_file_t file; + ventoy_img_chunk_list chunklist; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + /* get image chunk data */ + grub_memset(&chunklist, 0, sizeof(chunklist)); + chunklist.chunk = grub_malloc(sizeof(ventoy_img_chunk) * DEFAULT_CHUNK_NUM); + if (NULL == chunklist.chunk) + { + return grub_error(GRUB_ERR_OUT_OF_MEMORY, "Can't allocate image chunk memoty\n"); + } + + chunklist.max_chunk = DEFAULT_CHUNK_NUM; + chunklist.cur_chunk = 0; + + ventoy_get_block_list(file, &chunklist, 0); + + if (0 != ventoy_check_block_list(file, &chunklist, 0)) + { + grub_printf("########## UNSUPPORTED ###############\n"); + } + + grub_printf("filesystem: <%s> entry number:<%u>\n", file->fs->name, chunklist.cur_chunk); + + for (i = 0; i < chunklist.cur_chunk; i++) + { + grub_printf("%llu+%llu,", (ulonglong)chunklist.chunk[i].disk_start_sector, + (ulonglong)(chunklist.chunk[i].disk_end_sector + 1 - chunklist.chunk[i].disk_start_sector)); + } + + grub_printf("\n==================================\n"); + + for (i = 0; i < chunklist.cur_chunk; i++) + { + grub_printf("%2u: [%llu %llu] - [%llu %llu]\n", i, + (ulonglong)chunklist.chunk[i].img_start_sector, + (ulonglong)chunklist.chunk[i].img_end_sector, + (ulonglong)chunklist.chunk[i].disk_start_sector, + (ulonglong)chunklist.chunk[i].disk_end_sector + ); + } + + grub_free(chunklist.chunk); + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_add_replace_file(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + ventoy_grub_param_file_replace *replace = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc >= 2) + { + replace = &(g_grub_param->file_replace); + replace->magic = GRUB_FILE_REPLACE_MAGIC; + + replace->old_name_cnt = 0; + for (i = 0; i < 4 && i + 1 < argc; i++) + { + replace->old_name_cnt++; + grub_snprintf(replace->old_file_name[i], sizeof(replace->old_file_name[i]), "%s", args[i + 1]); + } + + replace->new_file_virtual_id = (grub_uint32_t)grub_strtoul(args[0], NULL, 10); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_get_replace_file_cnt(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char buf[32]; + ventoy_grub_param_file_replace *replace = &(g_grub_param->file_replace); + + (void)ctxt; + + if (argc >= 1) + { + grub_snprintf(buf, sizeof(buf), "%u", replace->old_name_cnt); + grub_env_set(args[0], buf); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_dump_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (argc == 0) + { + grub_printf("List Mode: CurLen:%d MaxLen:%u\n", g_list_script_pos, VTOY_MAX_SCRIPT_BUF); + grub_printf("%s", g_list_script_buf); + } + else + { + grub_printf("Tree Mode: CurLen:%d MaxLen:%u\n", g_tree_script_pos, VTOY_MAX_SCRIPT_BUF); + grub_printf("%s", g_tree_script_buf); + } + + return 0; +} + +static grub_err_t ventoy_cmd_dump_img_list(grub_extcmd_context_t ctxt, int argc, char **args) +{ + img_info *cur = g_ventoy_img_list; + + (void)ctxt; + (void)argc; + (void)args; + + while (cur) + { + grub_printf("path:<%s> id=%d list_index=%d\n", cur->path, cur->id, cur->plugin_list_index); + grub_printf("name:<%s>\n\n", cur->name); + cur = cur->next; + } + + return 0; +} + +static grub_err_t ventoy_cmd_dump_injection(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_injection(); + + return 0; +} + +static grub_err_t ventoy_cmd_dump_auto_install(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_auto_install(); + + return 0; +} + +static grub_err_t ventoy_cmd_dump_persistence(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_plugin_dump_persistence(); + + return 0; +} + +static grub_err_t ventoy_cmd_check_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 1) + { + return 1; + } + + if (args[0][0] == '0') + { + return g_ventoy_memdisk_mode ? 0 : 1; + } + else if (args[0][0] == '1') + { + return g_ventoy_iso_raw ? 0 : 1; + } + else if (args[0][0] == '2') + { + return g_ventoy_iso_uefi_drv ? 0 : 1; + } + else if (args[0][0] == '3') + { + return g_ventoy_grub2_mode ? 0 : 1; + } + else if (args[0][0] == '4') + { + return g_ventoy_wimboot_mode ? 0 : 1; + } + + return 1; +} + +static grub_err_t ventoy_cmd_dynamic_menu(grub_extcmd_context_t ctxt, int argc, char **args) +{ + static int configfile_mode = 0; + char memfile[128] = {0}; + + (void)ctxt; + (void)argc; + (void)args; + + /* + * args[0]: 0:normal 1:configfile + * args[1]: 0:list_buf 1:tree_buf + */ + + if (argc != 2) + { + debug("Invalid argc %d\n", argc); + return 0; + } + + VTOY_CMD_CHECK(1); + + if (args[0][0] == '0') + { + if (args[1][0] == '0') + { + grub_script_execute_sourcecode(g_list_script_buf); + } + else + { + grub_script_execute_sourcecode(g_tree_script_buf); + } + } + else + { + if (configfile_mode) + { + debug("Now already in F3 mode %d\n", configfile_mode); + return 0; + } + + if (args[1][0] == '0') + { + grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", + (ulonglong)(ulong)g_list_script_buf, g_list_script_pos); + } + else + { + g_ventoy_last_entry = -1; + grub_snprintf(memfile, sizeof(memfile), "configfile mem:0x%llx:size:%d", + (ulonglong)(ulong)g_tree_script_buf, g_tree_script_pos); + } + + configfile_mode = 1; + grub_script_execute_sourcecode(memfile); + configfile_mode = 0; + } + + return 0; +} + +static grub_err_t ventoy_cmd_file_exist_nocase(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + + (void)ctxt; + + if (argc != 1) + { + return 1; + } + + g_ventoy_case_insensitive = 1; + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + g_ventoy_case_insensitive = 0; + + grub_errno = 0; + + if (file) + { + grub_file_close(file); + return 0; + } + return 1; +} + +static grub_err_t ventoy_cmd_find_bootable_hdd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id = 0; + int find = 0; + grub_disk_t disk; + const char *isopath = NULL; + char hdname[32]; + ventoy_mbr_head mbr; + + (void)ctxt; + (void)argc; + + if (argc != 1) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s variable\n", cmd_raw_name); + } + + isopath = grub_env_get("vtoy_iso_part"); + if (!isopath) + { + debug("isopath is null %p\n", isopath); + return 0; + } + + debug("isopath is %s\n", isopath); + + for (id = 0; id < 30 && (find == 0); id++) + { + grub_snprintf(hdname, sizeof(hdname), "hd%d,", id); + if (grub_strstr(isopath, hdname)) + { + debug("skip %s ...\n", hdname); + continue; + } + + grub_snprintf(hdname, sizeof(hdname), "hd%d", id); + + disk = grub_disk_open(hdname); + if (!disk) + { + debug("%s not exist\n", hdname); + break; + } + + grub_memset(&mbr, 0, sizeof(mbr)); + if (0 == grub_disk_read(disk, 0, 0, 512, &mbr)) + { + if (mbr.Byte55 == 0x55 && mbr.ByteAA == 0xAA) + { + if (mbr.PartTbl[0].Active == 0x80 || mbr.PartTbl[1].Active == 0x80 || + mbr.PartTbl[2].Active == 0x80 || mbr.PartTbl[3].Active == 0x80) + { + + grub_env_set(args[0], hdname); + find = 1; + } + } + debug("%s is %s\n", hdname, find ? "bootable" : "NOT bootable"); + } + else + { + debug("read %s failed\n", hdname); + } + + grub_disk_close(disk); + } + + return 0; +} + +static grub_err_t ventoy_cmd_read_1st_line(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len = 1024; + grub_file_t file; + char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + buf = grub_malloc(len); + if (!buf) + { + goto end; + } + + buf[len - 1] = 0; + grub_file_read(file, buf, len - 1); + + ventoy_get_line(buf); + ventoy_set_env(args[1], buf); + +end: + + grub_check_free(buf); + grub_file_close(file); + + return 0; +} + +static int ventoy_img_partition_callback (struct grub_disk *disk, const grub_partition_t partition, void *data) +{ + (void)disk; + (void)data; + + g_part_list_pos += grub_snprintf(g_part_list_buf + g_part_list_pos, VTOY_MAX_SCRIPT_BUF - g_part_list_pos, + "0 %llu linear /dev/ventoy %llu\n", + (ulonglong)partition->len, (ulonglong)partition->start); + + return 0; +} + +static grub_err_t ventoy_cmd_img_part_info(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *device_name = NULL; + grub_device_t dev = NULL; + char buf[64]; + + (void)ctxt; + + g_part_list_pos = 0; + grub_env_unset("vtoy_img_part_file"); + + if (argc != 1) + { + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("ventoy_cmd_img_part_info failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + grub_partition_iterate(dev->disk, ventoy_img_partition_callback, NULL); + + grub_snprintf(buf, sizeof(buf), "newc:vtoy_dm_table:mem:0x%llx:size:%d", (ulonglong)(ulong)g_part_list_buf, g_part_list_pos); + grub_env_set("vtoy_img_part_file", buf); + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return 0; +} + + +static grub_err_t ventoy_cmd_file_strstr(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + grub_file_t file; + char *buf = NULL; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s file str \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 1; + } + + buf = grub_malloc(file->size + 1); + if (!buf) + { + goto end; + } + + buf[file->size] = 0; + grub_file_read(file, buf, file->size); + + if (grub_strstr(buf, args[1])) + { + rc = 0; + } + +end: + + grub_check_free(buf); + grub_file_close(file); + + return rc; +} + +static grub_err_t ventoy_cmd_parse_volume(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + grub_uint64_t size; + ventoy_iso9660_vd pvd; + + (void)ctxt; + (void)argc; + + if (argc != 4) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s sysid volid space \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_file_seek(file, 16 * 2048); + len = (int)grub_file_read(file, &pvd, sizeof(pvd)); + if (len != sizeof(pvd)) + { + debug("failed to read pvd %d\n", len); + goto end; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.sys, sizeof(pvd.sys)); + ventoy_set_env(args[1], buf); + + grub_memset(buf, 0, sizeof(buf)); + grub_memcpy(buf, pvd.vol, sizeof(pvd.vol)); + ventoy_set_env(args[2], buf); + + size = pvd.space; + size *= 2048; + grub_snprintf(buf, sizeof(buf), "%llu", (ulonglong)size); + ventoy_set_env(args[3], buf); + +end: + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_parse_create_date(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int len; + grub_file_t file; + char buf[64]; + + (void)ctxt; + (void)argc; + + if (argc != 2) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s var \n", cmd_raw_name); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 0; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_file_seek(file, 16 * 2048 + 813); + len = (int)grub_file_read(file, buf, 17); + if (len != 17) + { + debug("failed to read create date %d\n", len); + goto end; + } + + ventoy_set_env(args[1], buf); + +end: + grub_file_close(file); + + return 0; +} + +static grub_err_t ventoy_cmd_img_hook_root(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_env_hook_root(1); + + return 0; +} + +static grub_err_t ventoy_cmd_img_unhook_root(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + ventoy_env_hook_root(0); + + return 0; +} + +#ifdef GRUB_MACHINE_EFI +static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + grub_uint8_t *var; + grub_size_t size; + grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; + + (void)ctxt; + (void)argc; + (void)args; + + var = grub_efi_get_variable("SecureBoot", &global, &size); + if (var && *var == 1) + { + return 0; + } + + return ret; +} +#else +static grub_err_t ventoy_cmd_check_secureboot_var(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + return 1; +} +#endif + +static grub_err_t ventoy_cmd_img_check_range(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int ret = 1; + grub_file_t file; + grub_uint64_t FileSectors = 0; + ventoy_gpt_info *gpt = NULL; + ventoy_part_table *pt = NULL; + grub_uint8_t zeroguid[16] = {0}; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("failed to open file %s\n", args[0]); + return 1; + } + + if (file->size % 512) + { + debug("unaligned file size: %llu\n", (ulonglong)file->size); + goto out; + } + + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!gpt) + { + goto out; + } + + FileSectors = file->size / 512; + + grub_file_read(file, gpt, sizeof(ventoy_gpt_info)); + if (grub_strncmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + debug("This is EFI partition table\n"); + + for (i = 0; i < 128; i++) + { + if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16)) + { + if (FileSectors < gpt->PartTbl[i].LastLBA) + { + debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, + (ulonglong)gpt->PartTbl[i].LastLBA, (ulonglong)FileSectors); + goto out; + } + } + } + } + else + { + debug("This is MBR partition table\n"); + + for (i = 0; i < 4; i++) + { + pt = gpt->MBR.PartTbl + i; + if (FileSectors < pt->StartSectorId + pt->SectorCount) + { + debug("out of range: part[%d] LastLBA:%llu FileSectors:%llu\n", i, + (ulonglong)(pt->StartSectorId + pt->SectorCount), + (ulonglong)FileSectors); + goto out; + } + } + } + + ret = 0; + +out: + grub_file_close(file); + grub_check_free(gpt); + grub_errno = GRUB_ERR_NONE; + return ret; +} + +static grub_err_t ventoy_cmd_clear_key(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int ret; + + (void)ctxt; + (void)argc; + (void)args; + + for (i = 0; i < 500; i++) + { + ret = grub_getkey_noblock(); + if (ret == GRUB_TERM_NO_KEY) + { + break; + } + } + + if (i >= 500) + { + grub_cls(); + grub_printf("\n\n Still have key input after clear.\n"); + grub_refresh(); + grub_sleep(5); + } + + return 0; +} + +static grub_err_t ventoy_cmd_acpi_param(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int buflen; + int datalen; + int loclen; + int img_chunk_num; + int image_sector_size; + char cmd[64]; + ventoy_chain_head *chain; + ventoy_img_chunk *chunk; + ventoy_os_param *osparam; + ventoy_image_location *location; + ventoy_image_disk_region *region; + struct grub_acpi_table_header *acpi; + + (void)ctxt; + + if (argc != 2) + { + return 1; + } + + debug("ventoy_cmd_acpi_param %s %s\n", args[0], args[1]); + + chain = (ventoy_chain_head *)(ulong)grub_strtoul(args[0], NULL, 16); + if (!chain) + { + return 1; + } + + image_sector_size = (int)grub_strtol(args[1], NULL, 10); + + if (grub_memcmp(&g_ventoy_guid, &(chain->os_param.guid), 16)) + { + debug("Invalid ventoy guid 0x%x\n", chain->os_param.guid.data1); + return 1; + } + + img_chunk_num = chain->img_chunk_num; + + loclen = sizeof(ventoy_image_location) + (img_chunk_num - 1) * sizeof(ventoy_image_disk_region); + datalen = sizeof(ventoy_os_param) + loclen; + + buflen = sizeof(struct grub_acpi_table_header) + datalen; + acpi = grub_zalloc(buflen); + if (!acpi) + { + return 1; + } + + /* Step1: Fill acpi table header */ + grub_memcpy(acpi->signature, "VTOY", 4); + acpi->length = buflen; + acpi->revision = 1; + grub_memcpy(acpi->oemid, "VENTOY", 6); + grub_memcpy(acpi->oemtable, "OSPARAMS", 8); + acpi->oemrev = 1; + acpi->creator_id[0] = 1; + acpi->creator_rev = 1; + + /* Step2: Fill data */ + osparam = (ventoy_os_param *)(acpi + 1); + grub_memcpy(osparam, &chain->os_param, sizeof(ventoy_os_param)); + osparam->vtoy_img_location_addr = 0; + osparam->vtoy_img_location_len = loclen; + osparam->chksum = 0; + osparam->chksum = 0x100 - grub_byte_checksum(osparam, sizeof(ventoy_os_param)); + + location = (ventoy_image_location *)(osparam + 1); + grub_memcpy(&location->guid, &osparam->guid, sizeof(ventoy_guid)); + location->image_sector_size = image_sector_size; + location->disk_sector_size = chain->disk_sector_size; + location->region_count = img_chunk_num; + + region = location->regions; + chunk = (ventoy_img_chunk *)((char *)chain + chain->img_chunk_offset); + if (512 == image_sector_size) + { + for (i = 0; i < img_chunk_num; i++) + { + region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; + region->image_start_sector = chunk->img_start_sector * 4; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + else + { + for (i = 0; i < img_chunk_num; i++) + { + region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; + region->image_start_sector = chunk->img_start_sector; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + + /* Step3: Fill acpi checksum */ + acpi->checksum = 0; + acpi->checksum = 0x100 - grub_byte_checksum(acpi, acpi->length); + + /* load acpi table */ + grub_snprintf(cmd, sizeof(cmd), "acpi mem:0x%lx:size:%d", (ulong)acpi, acpi->length); + grub_script_execute_sourcecode(cmd); + + grub_free(acpi); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_push_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_ventoy_last_entry_back = g_ventoy_last_entry; + g_ventoy_last_entry = -1; + + return 0; +} + +static grub_err_t ventoy_cmd_pop_last_entry(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_ventoy_last_entry = g_ventoy_last_entry_back; + + return 0; +} + +static int ventoy_lib_module_callback(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + const char *pos = filename + 1; + + if (info->dir) + { + while (*pos) + { + if (*pos == '.') + { + if ((*(pos - 1) >= '0' && *(pos - 1) <= '9') && (*(pos + 1) >= '0' && *(pos + 1) <= '9')) + { + grub_strncpy((char *)data, filename, 128); + return 1; + } + } + pos++; + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_lib_module_ver(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char buf[128] = {0}; + + (void)ctxt; + + if (argc != 3) + { + debug("ventoy_cmd_lib_module_ver, invalid param num %d\n", argc); + return 1; + } + + debug("ventoy_cmd_lib_module_ver %s %s %s\n", args[0], args[1], args[2]); + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("grub_fs_probe failed, %s\n", device_name); + goto end; + } + + fs->fs_dir(dev, args[1], ventoy_lib_module_callback, buf); + + if (buf[0]) + { + ventoy_set_env(args[2], buf); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +int ventoy_load_part_table(const char *diskname) +{ + char name[64]; + int ret; + grub_disk_t disk; + grub_device_t dev; + + g_ventoy_part_info = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!g_ventoy_part_info) + { + return 1; + } + + disk = grub_disk_open(diskname); + if (!disk) + { + debug("Failed to open disk %s\n", diskname); + return 1; + } + + g_ventoy_disk_size = disk->total_sectors * (1U << disk->log_sector_size); + + grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), g_ventoy_part_info); + grub_disk_close(disk); + + grub_snprintf(name, sizeof(name), "%s,1", diskname); + dev = grub_device_open(name); + if (dev) + { + /* Check for official Ventoy device */ + ret = ventoy_check_official_device(dev); + grub_device_close(dev); + + if (ret) + { + return 1; + } + } + + g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0); + g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1); + + return 0; +} + +static grub_err_t ventoy_cmd_load_part_table(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret; + + (void)argc; + (void)ctxt; + + ret = ventoy_load_part_table(args[0]); + if (ret) + { + grub_exit(); + } + + g_ventoy_disk_part_size[0] = ventoy_get_vtoy_partsize(0); + g_ventoy_disk_part_size[1] = ventoy_get_vtoy_partsize(1); + + return 0; +} + +static grub_err_t ventoy_cmd_check_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + const char *vcfg = NULL; + + (void)argc; + (void)ctxt; + + vcfg = ventoy_plugin_get_custom_boot(args[0]); + if (vcfg) + { + debug("custom boot <%s>:<%s>\n", args[0], vcfg); + grub_env_set(args[1], vcfg); + ret = 0; + } + else + { + debug("custom boot <%s>:\n", args[0]); + } + + grub_errno = 0; + return ret; +} + + +static grub_err_t ventoy_cmd_part_exist(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id; + grub_uint8_t zeroguid[16] = {0}; + + (void)argc; + (void)ctxt; + + id = (int)grub_strtoul(args[0], NULL, 10); + grub_errno = 0; + + if (grub_memcmp(g_ventoy_part_info->Head.Signature, "EFI PART", 8) == 0) + { + if (id >= 1 && id <= 128) + { + if (grub_memcmp(g_ventoy_part_info->PartTbl[id - 1].PartGuid, zeroguid, 16)) + { + return 0; + } + } + } + else + { + if (id >= 1 && id <= 4) + { + if (g_ventoy_part_info->MBR.PartTbl[id - 1].FsFlag) + { + return 0; + } + } + } + + return 1; +} + +static grub_err_t ventoy_cmd_get_fs_label(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char *label = NULL; + + (void)ctxt; + + debug("get fs label for %s\n", args[0]); + + if (argc != 2) + { + debug("ventoy_cmd_get_fs_label, invalid param num %d\n", argc); + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (NULL == fs || NULL == fs->fs_label) + { + debug("grub_fs_probe failed, %s %p %p\n", device_name, fs, fs->fs_label); + goto end; + } + + fs->fs_label(dev, &label); + if (label) + { + debug("label=<%s>\n", label); + ventoy_set_env(args[1], label); + grub_free(label); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +static int ventoy_fs_enum_1st_file(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (!info->dir) + { + grub_snprintf((char *)data, 256, "%s", filename); + return 1; + } + + return 0; +} + +static int ventoy_fs_enum_1st_dir(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (info->dir && filename && filename[0] != '.') + { + grub_snprintf((char *)data, 256, "%s", filename); + return 1; + } + + return 0; +} + +static grub_err_t ventoy_fs_enum_1st_child(int argc, char **args, grub_fs_dir_hook_t hook) +{ + int rc = 1; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + char name[256] ={0}; + + if (argc != 3) + { + debug("ventoy_fs_enum_1st_child, invalid param num %d\n", argc); + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + debug("grub_file_get_device_name failed, %s\n", args[0]); + goto end; + } + + dev = grub_device_open(device_name); + if (!dev) + { + debug("grub_device_open failed, %s\n", device_name); + goto end; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + debug("grub_fs_probe failed, %s\n", device_name); + goto end; + } + + fs->fs_dir(dev, args[1], hook, name); + if (name[0]) + { + ventoy_set_env(args[2], name); + } + + rc = 0; + +end: + + check_free(device_name, grub_free); + check_free(dev, grub_device_close); + + return rc; +} + +static grub_err_t ventoy_cmd_fs_enum_1st_file(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + return ventoy_fs_enum_1st_child(argc, args, ventoy_fs_enum_1st_file); +} + +static grub_err_t ventoy_cmd_fs_enum_1st_dir(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + return ventoy_fs_enum_1st_child(argc, args, ventoy_fs_enum_1st_dir); +} + +static grub_err_t ventoy_cmd_basename(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char c; + char *pos = NULL; + char *end = NULL; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_basename, invalid param num %d\n", argc); + return 1; + } + + for (pos = args[0]; *pos; pos++) + { + if (*pos == '.') + { + end = pos; + } + } + + if (end) + { + c = *end; + *end = 0; + } + + grub_env_set(args[1], args[0]); + + if (end) + { + *end = c; + } + + return 0; +} + +static grub_err_t ventoy_cmd_basefile(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int len; + const char *buf; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_basefile, invalid param num %d\n", argc); + return 1; + } + + buf = args[0]; + len = (int)grub_strlen(buf); + for (i = len; i > 0; i--) + { + if (buf[i - 1] == '/') + { + grub_env_set(args[1], buf + i); + return 0; + } + } + + grub_env_set(args[1], buf); + + return 0; +} + +static grub_err_t ventoy_cmd_enum_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_video_mode_info info; + char buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (!g_video_mode_list) + { + ventoy_enum_video_mode(); + } + + if (grub_video_get_info(&info) == GRUB_ERR_NONE) + { + grub_snprintf(buf, sizeof(buf), "Resolution (%ux%u)", info.width, info.height); + } + else + { + grub_snprintf(buf, sizeof(buf), "Resolution (0x0)"); + } + + grub_env_set("VTOY_CUR_VIDEO_MODE", buf); + + grub_snprintf(buf, sizeof(buf), "%d", g_video_mode_num); + grub_env_set("VTOY_VIDEO_MODE_NUM", buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t vt_cmd_update_cur_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + struct grub_video_mode_info info; + char buf[32]; + + (void)ctxt; + (void)argc; + (void)args; + + if (grub_video_get_info(&info) == GRUB_ERR_NONE) + { + grub_snprintf(buf, sizeof(buf), "%ux%ux%u", info.width, info.height, info.bpp); + } + else + { + grub_snprintf(buf, sizeof(buf), "0x0x0"); + } + + grub_env_set(args[0], buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_get_video_mode(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int id; + char buf[32]; + + (void)ctxt; + (void)argc; + + if (!g_video_mode_list) + { + return 0; + } + + id = (int)grub_strtoul(args[0], NULL, 10); + if (id < g_video_mode_num) + { + grub_snprintf(buf, sizeof(buf), "%ux%ux%u", + g_video_mode_list[id].width, g_video_mode_list[id].height, g_video_mode_list[id].bpp); + } + + grub_env_set(args[1], buf); + + VENTOY_CMD_RETURN(0); +} + +static grub_err_t ventoy_cmd_get_efivdisk_offset(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + grub_uint32_t loadsector = 0; + grub_file_t file; + char value[32]; + grub_uint32_t boot_catlog = 0; + grub_uint8_t buf[512]; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_get_efivdisk_offset, invalid param num %d\n", argc); + return 1; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + debug("failed to open %s\n", args[0]); + return 1; + } + + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog == 0) + { + debug("No bootcatlog found\n"); + grub_file_close(file); + return 1; + } + + grub_memset(buf, 0, sizeof(buf)); + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, buf, sizeof(buf)); + grub_file_close(file); + + for (i = 0; i < sizeof(buf); i += 32) + { + if ((buf[i] == 0 || buf[i] == 0x90 || buf[i] == 0x91) && buf[i + 1] == 0xEF) + { + if (buf[i + 32] == 0x88) + { + loadsector = *(grub_uint32_t *)(buf + i + 32 + 8); + grub_snprintf(value, sizeof(value), "%u", loadsector * 4); //change to sector size 512 + break; + } + } + } + + if (loadsector == 0) + { + debug("No EFI eltorito info found\n"); + return 1; + } + + debug("ventoy_cmd_get_efivdisk_offset <%s>\n", value); + grub_env_set(args[1], value); + VENTOY_CMD_RETURN(0); +} + +static int ventoy_collect_replace_initrd(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + int curpos; + int printlen; + grub_size_t len; + replace_fs_dir *pfsdir = (replace_fs_dir *)data; + + if (pfsdir->initrd[0]) + { + return 1; + } + + curpos = pfsdir->curpos; + len = grub_strlen(filename); + + if (info->dir) + { + if ((len == 1 && filename[0] == '.') || + (len == 2 && filename[0] == '.' && filename[1] == '.')) + { + return 0; + } + + //debug("#### [DIR] <%s> <%s>\n", pfsdir->fullpath, filename); + pfsdir->dircnt++; + + printlen = grub_snprintf(pfsdir->fullpath + curpos, 512 - curpos, "%s/", filename); + pfsdir->curpos = curpos + printlen; + pfsdir->fs->fs_dir(pfsdir->dev, pfsdir->fullpath, ventoy_collect_replace_initrd, pfsdir); + pfsdir->curpos = curpos; + pfsdir->fullpath[curpos] = 0; + } + else + { + //debug("#### [FILE] <%s> <%s>\n", pfsdir->fullpath, filename); + pfsdir->filecnt++; + + /* We consider the xxx.img file bigger than 32MB is the initramfs file */ + if (len > 4 && grub_strncmp(filename + len - 4, ".img", 4) == 0) + { + if (info->size > 32 * VTOY_SIZE_1MB) + { + grub_snprintf(pfsdir->initrd, sizeof(pfsdir->initrd), "%s%s", pfsdir->fullpath, filename); + return 1; + } + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_search_replace_initrd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + char *pos = NULL; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + replace_fs_dir *pfsdir = NULL; + + (void)ctxt; + + if (argc != 2) + { + debug("ventoy_cmd_search_replace_initrd, invalid param num %d\n", argc); + return 1; + } + + pfsdir = grub_zalloc(sizeof(replace_fs_dir)); + if (!pfsdir) + { + return 1; + } + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto fail; + } + + dev = grub_device_open(device_name); + if (!dev) + { + goto fail; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + goto fail; + } + + pfsdir->dev = dev; + pfsdir->fs = fs; + pfsdir->curpos = 1; + pfsdir->fullpath[0] = '/'; + fs->fs_dir(dev, "/", ventoy_collect_replace_initrd, pfsdir); + + if (pfsdir->initrd[0]) + { + debug("Replace initrd <%s> <%d %d>\n", pfsdir->initrd, pfsdir->dircnt, pfsdir->filecnt); + + for (i = 0; i < (int)sizeof(pfsdir->initrd) && pfsdir->initrd[i]; i++) + { + if (pfsdir->initrd[i] == '/') + { + pfsdir->initrd[i] = '\\'; + } + } + + pos = (pfsdir->initrd[0] == '\\') ? pfsdir->initrd + 1 : pfsdir->initrd; + grub_env_set(args[1], pos); + } + else + { + debug("Replace initrd NOT found <%s> <%d %d>\n", args[0], pfsdir->dircnt, pfsdir->filecnt); + } + +fail: + + grub_check_free(pfsdir); + grub_check_free(device_name); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_push_pager(grub_extcmd_context_t ctxt, int argc, char **args) +{ + const char *pager = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + pager = grub_env_get("pager"); + if (NULL == pager) + { + g_pager_flag = 1; + grub_env_set("pager", "1"); + } + else if (pager[0] == '1') + { + g_pager_flag = 0; + } + else + { + grub_snprintf(g_old_pager, sizeof(g_old_pager), "%s", pager); + g_pager_flag = 2; + grub_env_set("pager", "1"); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static grub_err_t ventoy_cmd_pop_pager(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (g_pager_flag == 1) + { + grub_env_unset("pager"); + } + else if (g_pager_flag == 2) + { + grub_env_set("pager", g_old_pager); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +static int ventoy_chk_case_file(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + if (g_json_case_mis_path[0]) + { + return 1; + } + + if (0 == info->dir && grub_strncasecmp(filename, "ventoy.json", 11) == 0) + { + grub_snprintf(g_json_case_mis_path, 32, "%s/%s", (char *)data, filename); + return 1; + } + return 0; +} + +static int ventoy_chk_case_dir(const char *filename, const struct grub_dirhook_info *info, void *data) +{ + char path[16]; + chk_case_fs_dir *fs_dir = (chk_case_fs_dir *)data; + + if (g_json_case_mis_path[0]) + { + return 1; + } + + if (info->dir && (filename[0] == 'v' || filename[0] == 'V')) + { + if (grub_strncasecmp(filename, "ventoy", 6) == 0) + { + grub_snprintf(path, sizeof(path), "/%s", filename); + fs_dir->fs->fs_dir(fs_dir->dev, path, ventoy_chk_case_file, path); + if (g_json_case_mis_path[0]) + { + return 1; + } + } + } + + return 0; +} + +static grub_err_t ventoy_cmd_chk_json_pathcase(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int fstype = 0; + char *device_name = NULL; + grub_device_t dev = NULL; + grub_fs_t fs = NULL; + chk_case_fs_dir fs_dir; + + (void)ctxt; + (void)argc; + (void)args; + + device_name = grub_file_get_device_name(args[0]); + if (!device_name) + { + goto out; + } + + dev = grub_device_open(device_name); + if (!dev) + { + goto out; + } + + fs = grub_fs_probe(dev); + if (!fs) + { + goto out; + } + + fstype = ventoy_get_fs_type(fs->name); + if (fstype == ventoy_fs_fat || fstype == ventoy_fs_exfat || fstype >= ventoy_fs_max) + { + goto out; + } + + g_json_case_mis_path[0] = 0; + fs_dir.dev = dev; + fs_dir.fs = fs; + fs->fs_dir(dev, "/", ventoy_chk_case_dir, &fs_dir); + + if (g_json_case_mis_path[0]) + { + grub_env_set("VTOY_PLUGIN_PATH_CASE_MISMATCH", g_json_case_mis_path); + } + +out: + + grub_check_free(device_name); + check_free(dev, grub_device_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +int ventoy_env_init(void) +{ + char buf[64]; + + grub_env_set("vtdebug_flag", ""); + + g_part_list_buf = grub_malloc(VTOY_PART_BUF_LEN); + g_tree_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); + g_list_script_buf = grub_malloc(VTOY_MAX_SCRIPT_BUF); + g_conf_replace_new_buf = grub_malloc(vtoy_max_replace_file_size); + + ventoy_filt_register(0, ventoy_wrapper_open); + + g_grub_param = (ventoy_grub_param *)grub_zalloc(sizeof(ventoy_grub_param)); + if (g_grub_param) + { + g_grub_param->grub_env_get = grub_env_get; + g_grub_param->grub_env_set = (grub_env_set_pf)grub_env_set; + g_grub_param->grub_env_printf = (grub_env_printf_pf)grub_printf; + grub_snprintf(buf, sizeof(buf), "%p", g_grub_param); + grub_env_set("env_param", buf); + grub_env_set("ventoy_env_param", buf); + + grub_env_export("env_param"); + grub_env_export("ventoy_env_param"); + } + + grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)g_vtoy_winpeshl_ini); + grub_env_set("vtoy_winpeshl_ini_addr", buf); + + grub_snprintf(buf, sizeof(buf), "%d", (int)grub_strlen(g_vtoy_winpeshl_ini)); + grub_env_set("vtoy_winpeshl_ini_size", buf); + + grub_env_export("vtoy_winpeshl_ini_addr"); + grub_env_export("vtoy_winpeshl_ini_size"); + + grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_chain_file_size); + grub_env_set("vtoy_chain_file_size", buf); + grub_env_export("vtoy_chain_file_size"); + + grub_snprintf(buf, sizeof(buf), "0x%lx", (ulong)ventoy_chain_file_read); + grub_env_set("vtoy_chain_file_read", buf); + grub_env_export("vtoy_chain_file_read"); + + return 0; +} + +static cmd_para ventoy_cmds[] = +{ + { "vt_incr", ventoy_cmd_incr, 0, NULL, "{Var} {INT}", "Increase integer variable", NULL }, + { "vt_mod", ventoy_cmd_mod, 0, NULL, "{Int} {Int} {Var}", "mod integer variable", NULL }, + { "vt_strstr", ventoy_cmd_strstr, 0, NULL, "", "", NULL }, + { "vt_str_begin", ventoy_cmd_strbegin, 0, NULL, "", "", NULL }, + { "vt_debug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, + { "vtdebug", ventoy_cmd_debug, 0, NULL, "{on|off}", "turn debug on/off", NULL }, + { "vtbreak", ventoy_cmd_break, 0, NULL, "{level}", "set debug break", NULL }, + { "vt_cmp", ventoy_cmd_cmp, 0, NULL, "{Int1} { eq|ne|gt|lt|ge|le } {Int2}", "Comare two integers", NULL }, + { "vt_device", ventoy_cmd_device, 0, NULL, "path var", "", NULL }, + { "vt_check_compatible", ventoy_cmd_check_compatible, 0, NULL, "", "", NULL }, + { "vt_list_img", ventoy_cmd_list_img, 0, NULL, "{device} {cntvar}", "find all iso file in device", NULL }, + { "vt_clear_img", ventoy_cmd_clear_img, 0, NULL, "", "clear image list", NULL }, + { "vt_img_name", ventoy_cmd_img_name, 0, NULL, "{imageID} {var}", "get image name", NULL }, + { "vt_chosen_img_path", ventoy_cmd_chosen_img_path, 0, NULL, "{var}", "get chosen img path", NULL }, + { "vt_ext_select_img_path", ventoy_cmd_ext_select_img_path, 0, NULL, "{var}", "select chosen img path", NULL }, + { "vt_img_sector", ventoy_cmd_img_sector, 0, NULL, "{imageName}", "", NULL }, + { "vt_dump_img_sector", ventoy_cmd_dump_img_sector, 0, NULL, "", "", NULL }, + { "vt_load_wimboot", ventoy_cmd_load_wimboot, 0, NULL, "", "", NULL }, + { "vt_load_vhdboot", ventoy_cmd_load_vhdboot, 0, NULL, "", "", NULL }, + { "vt_patch_vhdboot", ventoy_cmd_patch_vhdboot, 0, NULL, "", "", NULL }, + { "vt_raw_chain_data", ventoy_cmd_raw_chain_data, 0, NULL, "", "", NULL }, + { "vt_get_vtoy_type", ventoy_cmd_get_vtoy_type, 0, NULL, "", "", NULL }, + { "vt_check_custom_boot", ventoy_cmd_check_custom_boot, 0, NULL, "", "", NULL }, + { "vt_dump_custom_boot", ventoy_cmd_dump_custom_boot, 0, NULL, "", "", NULL }, + + { "vt_skip_svd", ventoy_cmd_skip_svd, 0, NULL, "", "", NULL }, + { "vt_cpio_busybox64", ventoy_cmd_cpio_busybox_64, 0, NULL, "", "", NULL }, + { "vt_load_cpio", ventoy_cmd_load_cpio, 0, NULL, "", "", NULL }, + { "vt_trailer_cpio", ventoy_cmd_trailer_cpio, 0, NULL, "", "", NULL }, + { "vt_push_last_entry", ventoy_cmd_push_last_entry, 0, NULL, "", "", NULL }, + { "vt_pop_last_entry", ventoy_cmd_pop_last_entry, 0, NULL, "", "", NULL }, + { "vt_get_lib_module_ver", ventoy_cmd_lib_module_ver, 0, NULL, "", "", NULL }, + + { "vt_load_part_table", ventoy_cmd_load_part_table, 0, NULL, "", "", NULL }, + { "vt_check_part_exist", ventoy_cmd_part_exist, 0, NULL, "", "", NULL }, + { "vt_get_fs_label", ventoy_cmd_get_fs_label, 0, NULL, "", "", NULL }, + { "vt_fs_enum_1st_file", ventoy_cmd_fs_enum_1st_file, 0, NULL, "", "", NULL }, + { "vt_fs_enum_1st_dir", ventoy_cmd_fs_enum_1st_dir, 0, NULL, "", "", NULL }, + { "vt_file_basename", ventoy_cmd_basename, 0, NULL, "", "", NULL }, + { "vt_file_basefile", ventoy_cmd_basefile, 0, NULL, "", "", NULL }, + { "vt_enum_video_mode", ventoy_cmd_enum_video_mode, 0, NULL, "", "", NULL }, + { "vt_get_video_mode", ventoy_cmd_get_video_mode, 0, NULL, "", "", NULL }, + { "vt_update_cur_video_mode", vt_cmd_update_cur_video_mode, 0, NULL, "", "", NULL }, + + + { "vt_find_first_bootable_hd", ventoy_cmd_find_bootable_hdd, 0, NULL, "", "", NULL }, + { "vt_dump_menu", ventoy_cmd_dump_menu, 0, NULL, "", "", NULL }, + { "vt_dynamic_menu", ventoy_cmd_dynamic_menu, 0, NULL, "", "", NULL }, + { "vt_check_mode", ventoy_cmd_check_mode, 0, NULL, "", "", NULL }, + { "vt_dump_img_list", ventoy_cmd_dump_img_list, 0, NULL, "", "", NULL }, + { "vt_dump_injection", ventoy_cmd_dump_injection, 0, NULL, "", "", NULL }, + { "vt_dump_auto_install", ventoy_cmd_dump_auto_install, 0, NULL, "", "", NULL }, + { "vt_dump_persistence", ventoy_cmd_dump_persistence, 0, NULL, "", "", NULL }, + { "vt_select_auto_install", ventoy_cmd_sel_auto_install, 0, NULL, "", "", NULL }, + { "vt_select_persistence", ventoy_cmd_sel_persistence, 0, NULL, "", "", NULL }, + { "vt_select_conf_replace", ventoy_select_conf_replace, 0, NULL, "", "", NULL }, + + { "vt_iso9660_nojoliet", ventoy_cmd_iso9660_nojoliet, 0, NULL, "", "", NULL }, + { "vt_iso9660_isjoliet", ventoy_cmd_iso9660_is_joliet, 0, NULL, "", "", NULL }, + { "vt_is_udf", ventoy_cmd_is_udf, 0, NULL, "", "", NULL }, + { "vt_file_size", ventoy_cmd_file_size, 0, NULL, "", "", NULL }, + { "vt_load_file_to_mem", ventoy_cmd_load_file_to_mem, 0, NULL, "", "", NULL }, + { "vt_load_img_memdisk", ventoy_cmd_load_img_memdisk, 0, NULL, "", "", NULL }, + { "vt_concat_efi_iso", ventoy_cmd_concat_efi_iso, 0, NULL, "", "", NULL }, + + { "vt_linux_parse_initrd_isolinux", ventoy_cmd_isolinux_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, + { "vt_linux_parse_initrd_grub", ventoy_cmd_grub_initrd_collect, 0, NULL, "{cfgfile}", "", NULL }, + { "vt_linux_specify_initrd_file", ventoy_cmd_specify_initrd_file, 0, NULL, "", "", NULL }, + { "vt_linux_clear_initrd", ventoy_cmd_clear_initrd_list, 0, NULL, "", "", NULL }, + { "vt_linux_dump_initrd", ventoy_cmd_dump_initrd_list, 0, NULL, "", "", NULL }, + { "vt_linux_initrd_count", ventoy_cmd_initrd_count, 0, NULL, "", "", NULL }, + { "vt_linux_valid_initrd_count", ventoy_cmd_valid_initrd_count, 0, NULL, "", "", NULL }, + { "vt_linux_locate_initrd", ventoy_cmd_linux_locate_initrd, 0, NULL, "", "", NULL }, + { "vt_linux_chain_data", ventoy_cmd_linux_chain_data, 0, NULL, "", "", NULL }, + { "vt_linux_get_main_initrd_index", ventoy_cmd_linux_get_main_initrd_index, 0, NULL, "", "", NULL }, + + { "vt_windows_reset", ventoy_cmd_wimdows_reset, 0, NULL, "", "", NULL }, + { "vt_windows_chain_data", ventoy_cmd_windows_chain_data, 0, NULL, "", "", NULL }, + { "vt_windows_wimboot_data", ventoy_cmd_windows_wimboot_data, 0, NULL, "", "", NULL }, + { "vt_windows_collect_wim_patch", ventoy_cmd_collect_wim_patch, 0, NULL, "", "", NULL }, + { "vt_windows_locate_wim_patch", ventoy_cmd_locate_wim_patch, 0, NULL, "", "", NULL }, + { "vt_windows_count_wim_patch", ventoy_cmd_wim_patch_count, 0, NULL, "", "", NULL }, + { "vt_dump_wim_patch", ventoy_cmd_dump_wim_patch, 0, NULL, "", "", NULL }, + { "vt_wim_check_bootable", ventoy_cmd_wim_check_bootable, 0, NULL, "", "", NULL }, + { "vt_wim_chain_data", ventoy_cmd_wim_chain_data, 0, NULL, "", "", NULL }, + + { "vt_add_replace_file", ventoy_cmd_add_replace_file, 0, NULL, "", "", NULL }, + { "vt_get_replace_file_cnt", ventoy_cmd_get_replace_file_cnt, 0, NULL, "", "", NULL }, + { "vt_test_block_list", ventoy_cmd_test_block_list, 0, NULL, "", "", NULL }, + { "vt_file_exist_nocase", ventoy_cmd_file_exist_nocase, 0, NULL, "", "", NULL }, + + + { "vt_load_plugin", ventoy_cmd_load_plugin, 0, NULL, "", "", NULL }, + { "vt_check_plugin_json", ventoy_cmd_plugin_check_json, 0, NULL, "", "", NULL }, + { "vt_check_password", ventoy_cmd_check_password, 0, NULL, "", "", NULL }, + + { "vt_1st_line", ventoy_cmd_read_1st_line, 0, NULL, "", "", NULL }, + { "vt_file_strstr", ventoy_cmd_file_strstr, 0, NULL, "", "", NULL }, + { "vt_img_part_info", ventoy_cmd_img_part_info, 0, NULL, "", "", NULL }, + + + { "vt_parse_iso_volume", ventoy_cmd_parse_volume, 0, NULL, "", "", NULL }, + { "vt_parse_iso_create_date", ventoy_cmd_parse_create_date, 0, NULL, "", "", NULL }, + { "vt_parse_freenas_ver", ventoy_cmd_parse_freenas_ver, 0, NULL, "", "", NULL }, + { "vt_unix_parse_freebsd_ver", ventoy_cmd_unix_freebsd_ver, 0, NULL, "", "", NULL }, + { "vt_unix_parse_freebsd_ver_elf", ventoy_cmd_unix_freebsd_ver_elf, 0, NULL, "", "", NULL }, + { "vt_unix_reset", ventoy_cmd_unix_reset, 0, NULL, "", "", NULL }, + { "vt_unix_replace_conf", ventoy_cmd_unix_replace_conf, 0, NULL, "", "", NULL }, + { "vt_unix_replace_ko", ventoy_cmd_unix_replace_ko, 0, NULL, "", "", NULL }, + { "vt_unix_fill_image_desc", ventoy_cmd_unix_fill_image_desc, 0, NULL, "", "", NULL }, + { "vt_unix_gzip_new_ko", ventoy_cmd_unix_gzip_newko, 0, NULL, "", "", NULL }, + { "vt_unix_chain_data", ventoy_cmd_unix_chain_data, 0, NULL, "", "", NULL }, + + { "vt_img_hook_root", ventoy_cmd_img_hook_root, 0, NULL, "", "", NULL }, + { "vt_img_unhook_root", ventoy_cmd_img_unhook_root, 0, NULL, "", "", NULL }, + { "vt_acpi_param", ventoy_cmd_acpi_param, 0, NULL, "", "", NULL }, + { "vt_check_secureboot_var", ventoy_cmd_check_secureboot_var, 0, NULL, "", "", NULL }, + { "vt_clear_key", ventoy_cmd_clear_key, 0, NULL, "", "", NULL }, + { "vt_img_check_range", ventoy_cmd_img_check_range, 0, NULL, "", "", NULL }, + { "vt_is_pe64", ventoy_cmd_is_pe64, 0, NULL, "", "", NULL }, + { "vt_sel_wimboot", ventoy_cmd_sel_wimboot, 0, NULL, "", "", NULL }, + { "vt_set_wim_load_prompt", ventoy_cmd_set_wim_prompt, 0, NULL, "", "", NULL }, + { "vt_set_theme", ventoy_cmd_set_theme, 0, NULL, "", "", NULL }, + + { "vt_get_efi_vdisk_offset", ventoy_cmd_get_efivdisk_offset, 0, NULL, "", "", NULL }, + { "vt_search_replace_initrd", ventoy_cmd_search_replace_initrd, 0, NULL, "", "", NULL }, + { "vt_push_pager", ventoy_cmd_push_pager, 0, NULL, "", "", NULL }, + { "vt_pop_pager", ventoy_cmd_pop_pager, 0, NULL, "", "", NULL }, + { "vt_check_json_path_case", ventoy_cmd_chk_json_pathcase, 0, NULL, "", "", NULL }, + { "vt_append_extra_sector", ventoy_cmd_append_ext_sector, 0, NULL, "", "", NULL }, +}; + +int ventoy_register_all_cmd(void) +{ + grub_uint32_t i; + cmd_para *cur = NULL; + + for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) + { + cur = ventoy_cmds + i; + cur->cmd = grub_register_extcmd(cur->name, cur->func, cur->flags, + cur->summary, cur->description, cur->parser); + } + + return 0; +} + +int ventoy_unregister_all_cmd(void) +{ + grub_uint32_t i; + + for (i = 0; i < ARRAY_SIZE(ventoy_cmds); i++) + { + grub_unregister_extcmd(ventoy_cmds[i].cmd); + } + + return 0; +} + + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h index 4717f094..8e503b1e 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_def.h @@ -23,10 +23,16 @@ #define VTOY_MAX_SCRIPT_BUF (4 * 1024 * 1024) +#define VTOY_PART_BUF_LEN (128 * 1024) + #define VTOY_FILT_MIN_FILE_SIZE 32768 #define VTOY_SIZE_1GB 1073741824 -#define VTOY_SIZE_512KB (512 * 1024) +#define VTOY_SIZE_1MB (1024 * 1024) +#define VTOY_SIZE_2MB (2 * 1024 * 1024) +#define VTOY_SIZE_4MB (4 * 1024 * 1024) +#define VTOY_SIZE_512KB (512 * 1024) +#define VTOY_SIZE_1KB 1024 #define JSON_SUCCESS 0 #define JSON_FAILED 1 @@ -46,6 +52,49 @@ #define ventoy_get_env(key) ventoy_env_op1(get, key) #define ventoy_set_env(key, val) ventoy_env_op2(set, key, val) +#define VTOY_WARNING "!!!!!!!!!!!!! WARNING !!!!!!!!!!!!!" + +#define VTOY_PLAT_I386_UEFI 0x49413332 +#define VTOY_PLAT_ARM64_UEFI 0x41413634 +#define VTOY_PLAT_X86_64_UEFI 0x55454649 +#define VTOY_PLAT_X86_LEGACY 0x42494f53 +#define VTOY_PLAT_MIPS_UEFI 0x4D495053 + +#define VTOY_COMM_CPIO "ventoy.cpio" +#if defined(__arm__) || defined(__aarch64__) +#define VTOY_ARCH_CPIO "ventoy_arm64.cpio" +#elif defined(__mips__) +#define VTOY_ARCH_CPIO "ventoy_mips64.cpio" +#else +#define VTOY_ARCH_CPIO "ventoy_x86.cpio" +#endif + +#define ventoy_varg_4(arg) arg[0], arg[1], arg[2], arg[3] +#define ventoy_varg_8(arg) arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7] + +#define VTOY_PWD_CORRUPTED(err) \ +{\ + grub_printf("\n\n Password corrupted, will reboot after 5 seconds.\n\n"); \ + grub_refresh(); \ + grub_sleep(5); \ + grub_exit(); \ + return (err);\ +} + +typedef enum VTOY_FILE_FLT +{ + VTOY_FILE_FLT_ISO = 0, /* .iso */ + VTOY_FILE_FLT_WIM, /* .wim */ + VTOY_FILE_FLT_EFI, /* .efi */ + VTOY_FILE_FLT_IMG, /* .img */ + VTOY_FILE_FLT_VHD, /* .vhd(x) */ + VTOY_FILE_FLT_VTOY, /* .vtoy */ + + VTOY_FILE_FLT_BUTT +}VTOY_FILE_FLT; + +#define FILE_FLT(type) (0 == g_vtoy_file_flt[VTOY_FILE_FLT_##type]) + typedef struct ventoy_initrd_ctx { const char *path_prefix; @@ -96,6 +145,19 @@ typedef struct cpio_newc_header typedef int (*grub_char_check_func)(int c); #define ventoy_is_decimal(str) ventoy_string_check(str, grub_isdigit) +#define OFFSET_OF(TYPE, MEMBER) ((grub_size_t) &((TYPE *)0)->MEMBER) + +#pragma pack(1) +typedef struct ventoy_patch_vhd +{ + grub_uint8_t part_offset_or_guid[16]; + grub_uint32_t reserved1; + grub_uint32_t part_type; + grub_uint8_t disk_signature_or_guid[16]; + grub_uint8_t reserved2[16]; + grub_uint8_t vhd_file_path[1]; +}ventoy_patch_vhd; +#pragma pack() // El Torito Boot Record Volume Descriptor #pragma pack(1) @@ -123,12 +185,28 @@ typedef struct ventoy_udf_override grub_uint32_t position; }ventoy_udf_override; +typedef struct ventoy_iso9660_vd +{ + grub_uint8_t type; + grub_uint8_t id[5]; + grub_uint8_t ver; + grub_uint8_t res; + char sys[32]; + char vol[32]; + grub_uint8_t res2[8]; + grub_uint32_t space; +}ventoy_iso9660_vd; + #pragma pack() -#define img_type_iso 0 -#define img_type_wim 1 -#define img_type_efi 2 -#define img_type_img 3 +#define img_type_start 0 +#define img_type_iso 0 +#define img_type_wim 1 +#define img_type_efi 2 +#define img_type_img 3 +#define img_type_vhd 4 +#define img_type_vtoy 5 +#define img_type_max 6 typedef struct img_info { @@ -142,6 +220,7 @@ typedef struct img_info int id; int type; + int plugin_list_index; grub_uint64_t size; int select; int unsupport; @@ -158,10 +237,13 @@ typedef struct img_iterator_node img_info **tail; char dir[400]; int dirlen; + int level; int isocnt; int done; int select; + int plugin_list_index; + struct img_iterator_node *parent; struct img_iterator_node *firstchild; @@ -206,10 +288,12 @@ extern ventoy_guid g_ventoy_guid; extern ventoy_img_chunk_list g_img_chunk_list; extern ventoy_img_chunk_list g_wimiso_chunk_list; extern char *g_wimiso_path; +extern char g_arch_mode_suffix[64]; +extern const char *g_menu_prefix[img_type_max]; extern int g_ventoy_debug; void ventoy_debug(const char *fmt, ...); -#define debug(fmt, ...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, __VA_ARGS__) +#define debug(fmt, args...) if (g_ventoy_debug) ventoy_debug("[VTOY]: "fmt, ##args) #define vtoy_ssprintf(buf, pos, fmt, ...) \ pos += grub_snprintf(buf + pos, VTOY_MAX_SCRIPT_BUF - pos, fmt, __VA_ARGS__) @@ -225,6 +309,7 @@ void ventoy_debug(const char *fmt, ...); #define FLAG_HEADER_COMPRESS_RESERVED 0x00010000 #define FLAG_HEADER_COMPRESS_XPRESS 0x00020000 #define FLAG_HEADER_COMPRESS_LZX 0x00040000 +#define FLAG_HEADER_COMPRESS_LZMS 0x00080000 #define RESHDR_FLAG_FREE 0x01 #define RESHDR_FLAG_METADATA 0x02 @@ -314,6 +399,15 @@ typedef struct wim_security_header grub_uint32_t count; /* Number of entries */ }wim_security_header; +typedef struct wim_stream_entry +{ + grub_uint64_t len; + grub_uint64_t unused1; + wim_hash hash; + grub_uint16_t name_len; + /* name */ +}wim_stream_entry; + /* Directory entry */ typedef struct wim_directory_entry { @@ -442,7 +536,25 @@ typedef struct plugin_entry ventoy_plugin_check_pf checkfunc; }plugin_entry; +typedef struct replace_fs_dir +{ + grub_device_t dev; + grub_fs_t fs; + char fullpath[512]; + char initrd[512]; + int curpos; + int dircnt; + int filecnt; +}replace_fs_dir; +typedef struct chk_case_fs_dir +{ + grub_device_t dev; + grub_fs_t fs; +}chk_case_fs_dir; + +int ventoy_strcmp(const char *pattern, const char *str); +int ventoy_strncmp (const char *pattern, const char *str, grub_size_t n); void ventoy_fill_os_param(grub_file_t file, ventoy_os_param *param); grub_err_t ventoy_cmd_isolinux_initrd_collect(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_grub_initrd_collect(grub_extcmd_context_t ctxt, int argc, char **args); @@ -456,16 +568,28 @@ grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, grub_err_t ventoy_cmd_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_valid_initrd_count(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_append_ext_sector(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_skip_svd(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_cpio_busybox_64(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_trailer_cpio(grub_extcmd_context_t ctxt, int argc, char **args); int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, const char *name); grub_file_t ventoy_grub_file_open(enum grub_file_type type, const char *fmt, ...); grub_uint64_t ventoy_grub_get_file_size(const char *fmt, ...); int ventoy_is_file_exist(const char *fmt, ...); +int ventoy_is_dir_exist(const char *fmt, ...); int ventoy_fill_data(grub_uint32_t buflen, char *buffer); grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_is_pe64(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_dump_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_set_wim_prompt(grub_extcmd_context_t ctxt, int argc, char **args); +grub_ssize_t ventoy_load_file_with_prompt(grub_file_t file, void *buf, grub_ssize_t size); +int ventoy_need_prompt_load_file(void); VTOY_JSON *vtoy_json_find_item ( @@ -588,18 +712,108 @@ typedef struct ventoy_mbr_head grub_uint8_t Byte55; grub_uint8_t ByteAA; }ventoy_mbr_head; + +typedef struct ventoy_gpt_head +{ + char Signature[8]; /* EFI PART */ + grub_uint8_t Version[4]; + grub_uint32_t Length; + grub_uint32_t Crc; + grub_uint8_t Reserved1[4]; + grub_uint64_t EfiStartLBA; + grub_uint64_t EfiBackupLBA; + grub_uint64_t PartAreaStartLBA; + grub_uint64_t PartAreaEndLBA; + grub_uint8_t DiskGuid[16]; + grub_uint64_t PartTblStartLBA; + grub_uint32_t PartTblTotNum; + grub_uint32_t PartTblEntryLen; + grub_uint32_t PartTblCrc; + grub_uint8_t Reserved2[420]; +}ventoy_gpt_head; + +typedef struct ventoy_gpt_part_tbl +{ + grub_uint8_t PartType[16]; + grub_uint8_t PartGuid[16]; + grub_uint64_t StartLBA; + grub_uint64_t LastLBA; + grub_uint64_t Attr; + grub_uint16_t Name[36]; +}ventoy_gpt_part_tbl; + +typedef struct ventoy_gpt_info +{ + ventoy_mbr_head MBR; + ventoy_gpt_head Head; + ventoy_gpt_part_tbl PartTbl[128]; +}ventoy_gpt_info; + +typedef struct vhd_footer_t +{ + char cookie[8]; // Cookie + grub_uint32_t features; // Features + grub_uint32_t ffversion; // File format version + grub_uint32_t dataoffset; // Data offset + grub_uint32_t timestamp; // Timestamp + grub_uint32_t creatorapp; // Creator application + grub_uint32_t creatorver; // Creator version + grub_uint32_t creatorhos; // Creator host OS + grub_uint32_t origsize; // Original size + grub_uint32_t currsize; // Current size + grub_uint32_t diskgeom; // Disk geometry + grub_uint32_t disktype; // Disk type + grub_uint32_t checksum; // Checksum + grub_uint8_t uniqueid[16]; // Unique ID + grub_uint8_t savedst; // Saved state +}vhd_footer_t; + +#define VDI_IMAGE_FILE_INFO "<<< Oracle VM VirtualBox Disk Image >>>\n" + +/** Image signature. */ +#define VDI_IMAGE_SIGNATURE (0xbeda107f) + +typedef struct VDIPREHEADER +{ + /** Just text info about image type, for eyes only. */ + char szFileInfo[64]; + /** The image signature (VDI_IMAGE_SIGNATURE). */ + grub_uint32_t u32Signature; + /** The image version (VDI_IMAGE_VERSION). */ + grub_uint32_t u32Version; +} VDIPREHEADER, *PVDIPREHEADER; + #pragma pack() +typedef struct ventoy_video_mode +{ + grub_uint32_t width; + grub_uint32_t height; + grub_uint32_t bpp; +}ventoy_video_mode; + + + typedef struct file_fullpath { char path[256]; }file_fullpath; +typedef struct theme_list +{ + file_fullpath theme; + struct theme_list *next; +}theme_list; + +#define auto_install_type_file 0 +#define auto_install_type_parent 1 typedef struct install_template { + int type; int pathlen; char isopath[256]; + int autosel; int cursel; int templatenum; file_fullpath *templatepath; @@ -607,11 +821,30 @@ typedef struct install_template struct install_template *next; }install_template; +typedef struct dudfile +{ + int size; + char *buf; +}dudfile; + +typedef struct dud +{ + int pathlen; + char isopath[256]; + + int dudnum; + file_fullpath *dudpath; + dudfile *files; + + struct dud *next; +}dud; + typedef struct persistence_config { int pathlen; char isopath[256]; + int autosel; int cursel; int backendnum; file_fullpath *backendpath; @@ -619,8 +852,12 @@ typedef struct persistence_config struct persistence_config *next; }persistence_config; +#define vtoy_alias_image_file 0 +#define vtoy_alias_directory 1 + typedef struct menu_alias { + int type; int pathlen; char isopath[256]; char alias[256]; @@ -628,42 +865,214 @@ typedef struct menu_alias struct menu_alias *next; }menu_alias; +#define vtoy_class_image_file 0 +#define vtoy_class_directory 1 + typedef struct menu_class { + int type; int patlen; + int parent; char pattern[256]; char class[64]; struct menu_class *next; }menu_class; +#define vtoy_custom_boot_image_file 0 +#define vtoy_custom_boot_directory 1 + +typedef struct custom_boot +{ + int type; + int pathlen; + char path[256]; + char cfg[256]; + + struct custom_boot *next; +}custom_boot; + +#define vtoy_max_replace_file_size (2 * 1024 * 1024) +typedef struct conf_replace +{ + int pathlen; + char isopath[256]; + char orgconf[256]; + char newconf[256]; + + struct conf_replace *next; +}conf_replace; + +#define injection_type_file 0 +#define injection_type_parent 1 +typedef struct injection_config +{ + int type; + int pathlen; + char isopath[256]; + char archive[256]; + + struct injection_config *next; +}injection_config; + +typedef struct auto_memdisk +{ + int pathlen; + char isopath[256]; + + struct auto_memdisk *next; +}auto_memdisk; + +typedef struct image_list +{ + int pathlen; + char isopath[256]; + + struct image_list *next; +}image_list; + +#define VTOY_PASSWORD_NONE 0 +#define VTOY_PASSWORD_TXT 1 +#define VTOY_PASSWORD_MD5 2 +#define VTOY_PASSWORD_SALT_MD5 3 + +typedef struct vtoy_password +{ + int type; + char text[128]; + char salt[64]; + grub_uint8_t md5[16]; +}vtoy_password; + +#define vtoy_menu_pwd_file 0 +#define vtoy_menu_pwd_parent 1 + +typedef struct menu_password +{ + int type; + int pathlen; + char isopath[256]; + + vtoy_password password; + + struct menu_password *next; +}menu_password; + extern int g_ventoy_menu_esc; extern int g_ventoy_suppress_esc; extern int g_ventoy_last_entry; extern int g_ventoy_memdisk_mode; extern int g_ventoy_iso_raw; +extern int g_ventoy_grub2_mode; +extern int g_ventoy_wimboot_mode; extern int g_ventoy_iso_uefi_drv; extern int g_ventoy_case_insensitive; extern grub_uint8_t g_ventoy_chain_type; +extern int g_vhdboot_enable; +#define VENTOY_IMG_WHITE_LIST 1 +#define VENTOY_IMG_BLACK_LIST 2 +extern int g_plugin_image_list; + +extern ventoy_gpt_info *g_ventoy_part_info; +extern grub_uint64_t g_conf_replace_offset; +extern grub_uint64_t g_svd_replace_offset; +extern conf_replace *g_conf_replace_node; +extern grub_uint8_t *g_conf_replace_new_buf; +extern int g_conf_replace_new_len; +extern int g_conf_replace_new_len_align; +extern grub_uint64_t g_ventoy_disk_size; +extern grub_uint64_t g_ventoy_disk_part_size[2]; +extern grub_uint32_t g_ventoy_plat_data; + +#define ventoy_unix_fill_virt(new_data, new_len) \ +{ \ + data_secs = (new_len + 2047) / 2048; \ + cur->mem_sector_start = sector; \ + cur->mem_sector_end = cur->mem_sector_start + data_secs; \ + cur->mem_sector_offset = offset; \ + cur->remap_sector_start = 0; \ + cur->remap_sector_end = 0; \ + cur->org_sector_start = 0; \ + grub_memcpy(override + offset, new_data, new_len); \ + cur++; \ + sector += data_secs; \ + offset += new_len; \ + chain->virt_img_size_in_bytes += data_secs * 2048; \ +} + +#define ventoy_syscall0(name) grub_##name() +#define ventoy_syscall1(name, a) grub_##name(a) + +char * ventoy_get_line(char *start); int ventoy_cmp_img(img_info *img1, img_info *img2); void ventoy_swap_img(img_info *img1, img_info *img2); char * ventoy_plugin_get_cur_install_template(const char *isopath); install_template * ventoy_plugin_find_install_template(const char *isopath); persistence_config * ventoy_plugin_find_persistent(const char *isopath); +grub_uint64_t ventoy_get_vtoy_partsize(int part); +void ventoy_plugin_dump_injection(void); void ventoy_plugin_dump_auto_install(void); int ventoy_fill_windows_rtdata(void *buf, char *isopath); int ventoy_plugin_get_persistent_chunklist(const char *isopath, int index, ventoy_img_chunk_list *chunk_list); -const char * ventoy_plugin_get_menu_alias(const char *isopath); -const char * ventoy_plugin_get_menu_class(const char *isoname); +const char * ventoy_plugin_get_injection(const char *isopath); +const char * ventoy_plugin_get_menu_alias(int type, const char *isopath); +const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path); +int ventoy_plugin_check_memdisk(const char *isopath); +int ventoy_plugin_get_image_list_index(int type, const char *name); +conf_replace * ventoy_plugin_find_conf_replace(const char *iso); +dud * ventoy_plugin_find_dud(const char *iso); +int ventoy_plugin_load_dud(dud *node, const char *isopart); int ventoy_get_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); int ventoy_check_block_list(grub_file_t file, ventoy_img_chunk_list *chunklist, grub_disk_addr_t start); void ventoy_plugin_dump_persistence(void); +grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_linux_get_main_initrd_index(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_collect_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_wim_patch_count(grub_extcmd_context_t ctxt, int argc, char **args); grub_err_t ventoy_cmd_locate_wim_patch(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_get_disk_guid(const char *filename, grub_uint8_t *guid, grub_uint8_t *signature); +grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_gzip_newko(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_unix_freebsd_ver_elf(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_check_device_result(int ret); +int ventoy_check_device(grub_device_t dev); +void ventoy_debug_dump_guid(const char *prefix, grub_uint8_t *guid); +grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args); +grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_check_password(const vtoy_password *pwd, int retry); +int ventoy_plugin_add_custom_boot(const char *vcfgpath); +const char * ventoy_plugin_get_custom_boot(const char *isopath); +grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args); +int ventoy_gzip_compress(void *mem_in, int mem_in_len, void *mem_out, int mem_out_len); +int ventoy_load_part_table(const char *diskname); +int ventoy_env_init(void); +int ventoy_register_all_cmd(void); +int ventoy_unregister_all_cmd(void); +int ventoy_chain_file_size(const char *path); +int ventoy_chain_file_read(const char *path, int offset, int len, void *buf); + +#define VTOY_CMD_CHECK(a) if (33554432 != g_ventoy_disk_part_size[a]) ventoy_syscall0(exit) + +#define vtoy_theme_random_boot_second 0 +#define vtoy_theme_random_boot_day 1 +#define vtoy_theme_random_boot_month 2 + +#define ventoy_env_export(env, name) \ +{\ + grub_env_set((env), (name));\ + grub_env_export(env);\ +} #endif /* __VENTOY_DEF_H__ */ diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c index b9e4a743..8f81779f 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_json.c @@ -152,6 +152,23 @@ static int vtoy_json_parse_string return JSON_FAILED; } + if (*(pcPos - 1) == '\\') + { + for (pcPos++; *pcPos; pcPos++) + { + if (*pcPos == '"' && *(pcPos - 1) != '\\') + { + break; + } + } + + if (*pcPos == 0 || pcPos < pcTmp) + { + json_debug("Invalid quotes string %s.", pcData); + return JSON_FAILED; + } + } + *ppcEnd = pcPos + 1; uiLen = (grub_uint32_t)(unsigned long)(pcPos - pcTmp); diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c index ddd7499a..560355ab 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_linux.c @@ -38,8 +38,10 @@ GRUB_MOD_LICENSE ("GPLv3+"); +#define VTOY_APPEND_EXT_SIZE 4096 +static int g_append_ext_sector = 0; -static char * ventoy_get_line(char *start) +char * ventoy_get_line(char *start) { if (start == NULL) { @@ -334,6 +336,9 @@ end: static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName) { int i = 0; + int len = 0; + int dollar = 0; + int quotation = 0; grub_file_t file = NULL; char *buf = NULL; char *start = NULL; @@ -382,6 +387,12 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName) start++; } + if (*start == '"') + { + quotation = 1; + start++; + } + while (*start) { img = grub_zalloc(sizeof(initrd_info)); @@ -389,13 +400,28 @@ static grub_err_t ventoy_grub_cfg_initrd_collect(const char *fileName) { break; } - + + dollar = 0; for (i = 0; i < 255 && (0 == ventoy_is_word_end(*start)); i++) { img->name[i] = *start++; + if (img->name[i] == '$') + { + dollar = 1; + } } - if (ventoy_find_initrd_by_name(g_initrd_img_list, img->name)) + if (quotation) + { + len = (int)grub_strlen(img->name); + if (len > 2 && img->name[len - 1] == '"') + { + img->name[len - 1] = 0; + } + debug("Remove quotation <%s>\n", img->name); + } + + if (dollar == 1 || ventoy_find_initrd_by_name(g_initrd_img_list, img->name)) { grub_free(img); } @@ -565,6 +591,14 @@ grub_err_t ventoy_cmd_specify_initrd_file(grub_extcmd_context_t ctxt, int argc, VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +static int ventoy_cpio_newc_get_int(char *value) +{ + char buf[16] = {0}; + + grub_memcpy(buf, value, 8); + return (int)grub_strtoul(buf, NULL, 16); +} + static void ventoy_cpio_newc_fill_int(grub_uint32_t value, char *buf, int buflen) { int i; @@ -618,9 +652,40 @@ int ventoy_cpio_newc_fill_head(void *buf, int filesize, const void *filedata, co return headlen; } +static grub_uint32_t ventoy_linux_get_virt_chunk_count(void) +{ + grub_uint32_t count = g_valid_initrd_count; + + if (g_conf_replace_offset > 0) + { + count++; + } + + if (g_append_ext_sector > 0) + { + count++; + } + + return count; +} + static grub_uint32_t ventoy_linux_get_virt_chunk_size(void) { - return (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count; + grub_uint32_t size; + + size = (sizeof(ventoy_virt_chunk) + g_ventoy_cpio_size) * g_valid_initrd_count; + + if (g_conf_replace_offset > 0) + { + size += sizeof(ventoy_virt_chunk) + g_conf_replace_new_len_align; + } + + if (g_append_ext_sector > 0) + { + size += sizeof(ventoy_virt_chunk) + VTOY_APPEND_EXT_SIZE; + } + + return size; } static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain) @@ -639,7 +704,7 @@ static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_ sector = (isosize + 2047) / 2048; cpio_secs = g_ventoy_cpio_size / 2048; - offset = g_valid_initrd_count * sizeof(ventoy_virt_chunk); + offset = ventoy_linux_get_virt_chunk_count() * sizeof(ventoy_virt_chunk); cur = (ventoy_virt_chunk *)override; for (node = g_initrd_img_list; node; node = node->next) @@ -675,12 +740,82 @@ static void ventoy_linux_fill_virt_data( grub_uint64_t isosize, ventoy_chain_ cur++; } + /* Lenovo EasyStartup need an addional sector for boundary check */ + if (g_append_ext_sector > 0) + { + cpio_secs = VTOY_APPEND_EXT_SIZE / 2048; + + cur->mem_sector_start = sector; + cur->mem_sector_end = cur->mem_sector_start + cpio_secs; + cur->mem_sector_offset = offset; + cur->remap_sector_start = 0; + cur->remap_sector_end = 0; + cur->org_sector_start = 0; + + grub_memset(override + offset, 0, VTOY_APPEND_EXT_SIZE); + + chain->virt_img_size_in_bytes += VTOY_APPEND_EXT_SIZE; + + offset += VTOY_APPEND_EXT_SIZE; + sector += cpio_secs; + cur++; + } + + if (g_conf_replace_offset > 0) + { + cpio_secs = g_conf_replace_new_len_align / 2048; + + cur->mem_sector_start = sector; + cur->mem_sector_end = cur->mem_sector_start + cpio_secs; + cur->mem_sector_offset = offset; + cur->remap_sector_start = 0; + cur->remap_sector_end = 0; + cur->org_sector_start = 0; + + grub_memcpy(override + offset, g_conf_replace_new_buf, g_conf_replace_new_len); + + chain->virt_img_size_in_bytes += g_conf_replace_new_len_align; + + offset += g_conf_replace_new_len_align; + sector += cpio_secs; + cur++; + } + return; } +static grub_uint32_t ventoy_linux_get_override_chunk_count(void) +{ + grub_uint32_t count = g_valid_initrd_count; + + if (g_conf_replace_offset > 0) + { + count++; + } + + if (g_svd_replace_offset > 0) + { + count++; + } + + return count; +} + static grub_uint32_t ventoy_linux_get_override_chunk_size(void) { - return sizeof(ventoy_override_chunk) * g_valid_initrd_count; + int count = g_valid_initrd_count; + + if (g_conf_replace_offset > 0) + { + count++; + } + + if (g_svd_replace_offset > 0) + { + count++; + } + + return sizeof(ventoy_override_chunk) * count; } static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *override) @@ -690,6 +825,8 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove grub_uint32_t newlen; grub_uint64_t sector; ventoy_override_chunk *cur; + ventoy_iso9660_override *dirent; + ventoy_udf_override *udf; sector = (isosize + 2047) / 2048; @@ -705,12 +842,12 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove mod = newlen % 4; if (mod > 0) { - newlen += 4 - mod; + newlen += 4 - mod; /* cpio must align with 4 */ } if (node->iso_type == 0) { - ventoy_iso9660_override *dirent = (ventoy_iso9660_override *)node->override_data; + dirent = (ventoy_iso9660_override *)node->override_data; node->override_length = sizeof(ventoy_iso9660_override); dirent->first_sector = (grub_uint32_t)sector; @@ -722,7 +859,7 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove } else { - ventoy_udf_override *udf = (ventoy_udf_override *)node->override_data; + udf = (ventoy_udf_override *)node->override_data; node->override_length = sizeof(ventoy_udf_override); udf->length = newlen; @@ -737,6 +874,31 @@ static void ventoy_linux_fill_override_data( grub_uint64_t isosize, void *ove cur++; } + if (g_conf_replace_offset > 0) + { + cur->img_offset = g_conf_replace_offset; + cur->override_size = sizeof(ventoy_iso9660_override); + + newlen = (grub_uint32_t)(g_conf_replace_new_len); + + dirent = (ventoy_iso9660_override *)cur->override_data; + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = newlen; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + + sector += (dirent->size + 2047) / 2048; + cur++; + } + + if (g_svd_replace_offset > 0) + { + cur->img_offset = g_svd_replace_offset; + cur->override_size = 1; + cur->override_data[0] = 0xFF; + cur++; + } + return; } @@ -903,12 +1065,124 @@ grub_err_t ventoy_cmd_linux_locate_initrd(grub_extcmd_context_t ctxt, int argc, VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +static int ventoy_cpio_busybox64(cpio_newc_header *head, const char *file) +{ + char *name; + int namelen; + int offset; + int count = 0; + char filepath[128]; + + grub_snprintf(filepath, sizeof(filepath), "ventoy/busybox/%s", file); + + name = (char *)(head + 1); + while (name[0] && count < 2) + { + if (grub_strcmp(name, "ventoy/busybox/ash") == 0) + { + grub_memcpy(name, "ventoy/busybox/32h", 18); + count++; + } + else if (grub_strcmp(name, filepath) == 0) + { + grub_memcpy(name, "ventoy/busybox/ash", 18); + count++; + } + + namelen = ventoy_cpio_newc_get_int(head->c_namesize); + offset = sizeof(cpio_newc_header) + namelen; + offset = ventoy_align(offset, 4); + offset += ventoy_cpio_newc_get_int(head->c_filesize); + offset = ventoy_align(offset, 4); + + head = (cpio_newc_header *)((char *)head + offset); + name = (char *)(head + 1); + } + + return 0; +} + + +grub_err_t ventoy_cmd_cpio_busybox_64(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + debug("ventoy_cmd_busybox_64 %d\n", argc); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, args[0]); + return 0; +} + +grub_err_t ventoy_cmd_skip_svd(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_file_t file; + char buf[16]; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + } + + for (i = 0; i < 10; i++) + { + buf[0] = 0; + grub_file_seek(file, (17 + i) * 2048); + grub_file_read(file, buf, 16); + + if (buf[0] == 2 && grub_strncmp(buf + 1, "CD001", 5) == 0) + { + debug("Find SVD at VD %d\n", i); + g_svd_replace_offset = (17 + i) * 2048; + break; + } + } + + if (i >= 10) + { + debug("SVD not found %d\n", (int)g_svd_replace_offset); + } + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_append_ext_sector(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + if (args[0][0] == '1') + { + g_append_ext_sector = 1; + } + else + { + g_append_ext_sector = 0; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **args) { + int i; int rc; + char *pos = NULL; char *template_file = NULL; char *template_buf = NULL; char *persistent_buf = NULL; + char *injection_buf = NULL; + dud *dudnode = NULL; + char tmpname[128]; + const char *injection_file = NULL; grub_uint8_t *buf = NULL; grub_uint32_t mod; grub_uint32_t headlen; @@ -917,14 +1191,17 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg grub_uint32_t img_chunk_size; grub_uint32_t template_size = 0; grub_uint32_t persistent_size = 0; + grub_uint32_t injection_size = 0; + grub_uint32_t dud_size = 0; grub_file_t file; - grub_file_t scriptfile; + grub_file_t archfile; + grub_file_t tmpfile; ventoy_img_chunk_list chunk_list; (void)ctxt; (void)argc; - if (argc != 3) + if (argc != 4) { return grub_error(GRUB_ERR_BAD_ARGUMENT, "Usage: %s cpiofile\n", cmd_raw_name); } @@ -936,12 +1213,21 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/%s", args[0], VTOY_COMM_CPIO); if (!file) { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s\n", args[0]); + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s/%s\n", args[0], VTOY_COMM_CPIO); } + archfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/%s", args[0], VTOY_ARCH_CPIO); + if (!archfile) + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't open file %s/%s\n", args[0], VTOY_ARCH_CPIO); + grub_file_close(file); + } + + debug("load %s %s success\n", VTOY_COMM_CPIO, VTOY_ARCH_CPIO); + if (g_ventoy_cpio_buf) { grub_free(g_ventoy_cpio_buf); @@ -960,18 +1246,18 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg if (template_file) { debug("auto install template: <%s>\n", template_file); - scriptfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], template_file); - if (scriptfile) + tmpfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], template_file); + if (tmpfile) { - debug("auto install script size %d\n", (int)scriptfile->size); - template_size = scriptfile->size; + debug("auto install script size %d\n", (int)tmpfile->size); + template_size = tmpfile->size; template_buf = grub_malloc(template_size); if (template_buf) { - grub_file_read(scriptfile, template_buf, template_size); + grub_file_read(tmpfile, template_buf, template_size); } - grub_file_close(scriptfile); + grub_file_close(tmpfile); } else { @@ -983,21 +1269,74 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg debug("auto install script skipped or not configed %s\n", args[1]); } - g_ventoy_cpio_buf = grub_malloc(file->size + 4096 + template_size + persistent_size + img_chunk_size); + injection_file = ventoy_plugin_get_injection(args[1]); + if (injection_file) + { + debug("injection archive: <%s>\n", injection_file); + tmpfile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[2], injection_file); + if (tmpfile) + { + debug("injection archive size:%d\n", (int)tmpfile->size); + injection_size = tmpfile->size; + injection_buf = grub_malloc(injection_size); + if (injection_buf) + { + grub_file_read(tmpfile, injection_buf, injection_size); + } + + grub_file_close(tmpfile); + } + else + { + debug("Failed to open injection archive %s%s\n", args[2], injection_file); + } + } + else + { + debug("injection not configed %s\n", args[1]); + } + + dudnode = ventoy_plugin_find_dud(args[1]); + if (dudnode) + { + debug("dud file: <%d>\n", dudnode->dudnum); + ventoy_plugin_load_dud(dudnode, args[2]); + for (i = 0; i < dudnode->dudnum; i++) + { + if (dudnode->files[i].size > 0) + { + dud_size += dudnode->files[i].size + sizeof(cpio_newc_header); + } + } + } + else + { + debug("dud not configed %s\n", args[1]); + } + + g_ventoy_cpio_buf = grub_malloc(file->size + archfile->size + 40960 + template_size + + persistent_size + injection_size + dud_size + img_chunk_size); if (NULL == g_ventoy_cpio_buf) { grub_file_close(file); - return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't alloc memory %llu\n", file->size + 4096 + img_chunk_size); + grub_file_close(archfile); + return grub_error(GRUB_ERR_BAD_ARGUMENT, "Can't alloc memory %llu\n", file->size); } grub_file_read(file, g_ventoy_cpio_buf, file->size); - buf = (grub_uint8_t *)(g_ventoy_cpio_buf + file->size - 4); while (*((grub_uint32_t *)buf) != 0x37303730) { buf -= 4; } + grub_file_read(archfile, buf, archfile->size); + buf += (archfile->size - 4); + while (*((grub_uint32_t *)buf) != 0x37303730) + { + buf -= 4; + } + /* get initrd head len */ initrd_head_len = ventoy_cpio_newc_fill_head(buf, 0, NULL, "initrd000.xx"); @@ -1020,6 +1359,27 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg persistent_buf = NULL; } + if (injection_size > 0 && injection_buf) + { + headlen = ventoy_cpio_newc_fill_head(buf, injection_size, injection_buf, "ventoy/ventoy_injection"); + buf += headlen + ventoy_align(injection_size, 4); + + grub_free(injection_buf); + injection_buf = NULL; + } + + if (dud_size > 0) + { + for (i = 0; i < dudnode->dudnum; i++) + { + pos = grub_strrchr(dudnode->dudpath[i].path, '.'); + grub_snprintf(tmpname, sizeof(tmpname), "ventoy/ventoy_dud%d%s", i, (pos ? pos : ".iso")); + dud_size = dudnode->files[i].size; + headlen = ventoy_cpio_newc_fill_head(buf, dud_size, dudnode->files[i].buf, tmpname); + buf += headlen + ventoy_align(dud_size, 4); + } + } + /* step2: insert os param to cpio */ headlen = ventoy_cpio_newc_fill_head(buf, 0, NULL, "ventoy/ventoy_os_param"); padlen = sizeof(ventoy_os_param); @@ -1040,19 +1400,128 @@ grub_err_t ventoy_cmd_load_cpio(grub_extcmd_context_t ctxt, int argc, char **arg ventoy_cpio_newc_fill_head(g_ventoy_initrd_head, 0, NULL, "initrd000.xx"); grub_file_close(file); + grub_file_close(archfile); + + if (grub_strcmp(args[3], "busybox=64") == 0) + { + debug("cpio busybox proc %s\n", args[3]); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "64h"); + } + else if (grub_strcmp(args[3], "busybox=a64") == 0) + { + debug("cpio busybox proc %s\n", args[3]); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "a64"); + } + else if (grub_strcmp(args[3], "busybox=m64") == 0) + { + debug("cpio busybox proc %s\n", args[3]); + ventoy_cpio_busybox64((cpio_newc_header *)g_ventoy_cpio_buf, "m64"); + } VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +grub_err_t ventoy_cmd_trailer_cpio(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int mod; + int bufsize; + int namelen; + int offset; + char *name; + grub_uint8_t *bufend; + cpio_newc_header *head; + grub_file_t file; + char value[64]; + const grub_uint8_t trailler[124] = { + 0x30, 0x37, 0x30, 0x37, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x42, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x54, 0x52, + 0x41, 0x49, 0x4C, 0x45, 0x52, 0x21, 0x21, 0x21, 0x00, 0x00, 0x00, 0x00 + }; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", args[0], args[1]); + if (!file) + { + return 1; + } + + grub_memset(g_ventoy_runtime_buf, 0, sizeof(ventoy_os_param)); + ventoy_fill_os_param(file, (ventoy_os_param *)g_ventoy_runtime_buf); + + grub_file_close(file); + + grub_memcpy(g_ventoy_initrd_head, trailler, sizeof(trailler)); + bufend = (grub_uint8_t *)g_ventoy_initrd_head + sizeof(trailler); + + bufsize = (int)(bufend - g_ventoy_cpio_buf); + mod = bufsize % 512; + if (mod) + { + grub_memset(bufend, 0, 512 - mod); + bufsize += 512 - mod; + } + + if (argc > 1 && grub_strcmp(args[2], "noinit") == 0) + { + head = (cpio_newc_header *)g_ventoy_cpio_buf; + name = (char *)(head + 1); + + while (grub_strcmp(name, "TRAILER!!!")) + { + if (grub_strcmp(name, "init") == 0) + { + grub_memcpy(name, "xxxx", 4); + } + else if (grub_strcmp(name, "linuxrc") == 0) + { + grub_memcpy(name, "vtoyxrc", 7); + } + else if (grub_strcmp(name, "sbin") == 0) + { + grub_memcpy(name, "vtoy", 4); + } + else if (grub_strcmp(name, "sbin/init") == 0) + { + grub_memcpy(name, "vtoy/vtoy", 9); + } + + namelen = ventoy_cpio_newc_get_int(head->c_namesize); + offset = sizeof(cpio_newc_header) + namelen; + offset = ventoy_align(offset, 4); + offset += ventoy_cpio_newc_get_int(head->c_filesize); + offset = ventoy_align(offset, 4); + + head = (cpio_newc_header *)((char *)head + offset); + name = (char *)(head + 1); + } + } + + grub_snprintf(value, sizeof(value), "0x%llx", (ulonglong)(ulong)g_ventoy_cpio_buf); + ventoy_set_env("ventoy_cpio_addr", value); + grub_snprintf(value, sizeof(value), "%d", bufsize); + ventoy_set_env("ventoy_cpio_size", value); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) { + int len = 0; int ventoy_compatible = 0; grub_uint32_t size = 0; grub_uint64_t isosize = 0; grub_uint32_t boot_catlog = 0; grub_uint32_t img_chunk_size = 0; + grub_uint32_t override_count = 0; grub_uint32_t override_size = 0; + grub_uint32_t virt_chunk_count = 0; grub_uint32_t virt_chunk_size = 0; grub_file_t file; grub_disk_t disk; @@ -1084,27 +1553,38 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha isosize = file->size; - boot_catlog = ventoy_get_iso_boot_catlog(file); - if (boot_catlog) + len = (int)grub_strlen(args[0]); + if (len >= 4 && 0 == grub_strcasecmp(args[0] + len - 4, ".img")) { - if (ventoy_is_efi_os() && (!ventoy_has_efi_eltorito(file, boot_catlog))) - { - grub_env_set("LoadIsoEfiDriver", "on"); - } + debug("boot catlog %u for img file\n", boot_catlog); } else { - if (ventoy_is_efi_os()) + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog) { - grub_env_set("LoadIsoEfiDriver", "on"); + if (ventoy_is_efi_os() && (!ventoy_has_efi_eltorito(file, boot_catlog))) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } } else { - return grub_error(GRUB_ERR_BAD_ARGUMENT, "File %s is not bootable", args[0]); + if (ventoy_is_efi_os()) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "File %s is not bootable", args[0]); + } } } img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + override_count = ventoy_linux_get_override_chunk_count(); + virt_chunk_count = ventoy_linux_get_virt_chunk_count(); if (ventoy_compatible) { @@ -1144,7 +1624,7 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ - g_ventoy_chain_type = 0; + g_ventoy_chain_type = ventoy_chain_linux; ventoy_fill_os_param(file, &(chain->os_param)); /* part 2: chain head */ @@ -1171,20 +1651,21 @@ grub_err_t ventoy_cmd_linux_chain_data(grub_extcmd_context_t ctxt, int argc, cha return 0; } - if (g_valid_initrd_count == 0) + /* part 4: override chunk */ + if (override_count > 0) { - return 0; + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; + chain->override_chunk_num = override_count; + ventoy_linux_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset); } - /* part 4: override chunk */ - chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; - chain->override_chunk_num = g_valid_initrd_count; - ventoy_linux_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset); - /* part 5: virt chunk */ - chain->virt_chunk_offset = chain->override_chunk_offset + override_size; - chain->virt_chunk_num = g_valid_initrd_count; - ventoy_linux_fill_virt_data(isosize, chain); + if (virt_chunk_count > 0) + { + chain->virt_chunk_offset = chain->override_chunk_offset + override_size; + chain->virt_chunk_num = virt_chunk_count; + ventoy_linux_fill_virt_data(isosize, chain); + } VENTOY_CMD_RETURN(GRUB_ERR_NONE); } diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c index 6bb4e9c0..c41d9649 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_plugin.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -39,11 +40,47 @@ GRUB_MOD_LICENSE ("GPLv3+"); +char g_arch_mode_suffix[64]; static char g_iso_disk_name[128]; +static vtoy_password g_boot_pwd; +static vtoy_password g_file_type_pwd[img_type_max]; static install_template *g_install_template_head = NULL; +static dud *g_dud_head = NULL; +static menu_password *g_pwd_head = NULL; static persistence_config *g_persistence_head = NULL; static menu_alias *g_menu_alias_head = NULL; static menu_class *g_menu_class_head = NULL; +static custom_boot *g_custom_boot_head = NULL; +static injection_config *g_injection_head = NULL; +static auto_memdisk *g_auto_memdisk_head = NULL; +static image_list *g_image_list_head = NULL; +static conf_replace *g_conf_replace_head = NULL; + +static int g_theme_num = 0; +static theme_list *g_theme_head = NULL; +static int g_theme_random = vtoy_theme_random_boot_second; +static char g_theme_single_file[256]; + +static int ventoy_plugin_is_parent(const char *pat, int patlen, const char *isopath) +{ + if (patlen > 1) + { + if (isopath[patlen] == '/' && ventoy_strncmp(pat, isopath, patlen) == 0 && + grub_strchr(isopath + patlen + 1, '/') == NULL) + { + return 1; + } + } + else + { + if (pat[0] == '/' && grub_strchr(isopath + 1, '/') == NULL) + { + return 1; + } + } + + return 0; +} static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk) { @@ -66,7 +103,15 @@ static int ventoy_plugin_control_check(VTOY_JSON *json, const char *isodisk) pChild = pNode->pstChild; if (pChild->enDataType == JSON_TYPE_STRING) { - grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal); + if (grub_strcmp(pChild->pcName, "VTOY_DEFAULT_IMAGE") == 0) + { + grub_printf("%s: %s [%s]\n", pChild->pcName, pChild->unData.pcStrVal, + ventoy_check_file_exist("%s%s", isodisk, pChild->unData.pcStrVal) ? "OK" : "NOT EXIST"); + } + else + { + grub_printf("%s: %s\n", pChild->pcName, pChild->unData.pcStrVal); + } } else { @@ -137,6 +182,38 @@ static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk) return 1; } } + else + { + node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "file"); + if (node) + { + for (node = node->pstChild; node; node = node->pstNext) + { + value = node->unData.pcStrVal; + grub_printf("file: %s\n", value); + if (value[0] == '/') + { + exist = ventoy_is_file_exist("%s%s", isodisk, value); + } + else + { + exist = ventoy_is_file_exist("%s/ventoy/%s", isodisk, value); + } + + if (exist == 0) + { + grub_printf("Theme file %s does NOT exist\n", value); + return 1; + } + } + + value = vtoy_json_get_string_ex(json->pstChild, "random"); + if (value) + { + grub_printf("random: %s\n", value); + } + } + } value = vtoy_json_get_string_ex(json->pstChild, "gfxmode"); if (value) @@ -150,6 +227,12 @@ static int ventoy_plugin_theme_check(VTOY_JSON *json, const char *isodisk) grub_printf("display_mode: %s\n", value); } + value = vtoy_json_get_string_ex(json->pstChild, "serial_param"); + if (value) + { + grub_printf("serial_param %s\n", value); + } + value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left"); if (value) { @@ -198,8 +281,10 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) { const char *value; char filepath[256]; - VTOY_JSON *node; - + VTOY_JSON *node = NULL; + theme_list *tail = NULL; + theme_list *themenode = NULL; + value = vtoy_json_get_string_ex(json->pstChild, "file"); if (value) { @@ -212,46 +297,112 @@ static int ventoy_plugin_theme_entry(VTOY_JSON *json, const char *isodisk) grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value); } - if (ventoy_is_file_exist(filepath) == 0) + if (ventoy_check_file_exist(filepath) == 0) { debug("Theme file %s does not exist\n", filepath); return 0; } debug("vtoy_theme %s\n", filepath); - grub_env_set("vtoy_theme", filepath); + ventoy_env_export("vtoy_theme", filepath); + grub_snprintf(g_theme_single_file, sizeof(g_theme_single_file), "%s", filepath); + } + else + { + node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "file"); + if (node) + { + for (node = node->pstChild; node; node = node->pstNext) + { + value = node->unData.pcStrVal; + if (value[0] == '/') + { + grub_snprintf(filepath, sizeof(filepath), "%s%s", isodisk, value); + } + else + { + grub_snprintf(filepath, sizeof(filepath), "%s/ventoy/%s", isodisk, value); + } + + if (ventoy_check_file_exist(filepath) == 0) + { + continue; + } + + themenode = grub_zalloc(sizeof(theme_list)); + if (themenode) + { + grub_snprintf(themenode->theme.path, sizeof(themenode->theme.path), "%s", filepath); + if (g_theme_head) + { + tail->next = themenode; + } + else + { + g_theme_head = themenode; + } + tail = themenode; + g_theme_num++; + } + } + + ventoy_env_export("vtoy_theme", "random"); + value = vtoy_json_get_string_ex(json->pstChild, "random"); + if (value) + { + if (grub_strcmp(value, "boot_second") == 0) + { + g_theme_random = vtoy_theme_random_boot_second; + } + else if (grub_strcmp(value, "boot_day") == 0) + { + g_theme_random = vtoy_theme_random_boot_day; + } + else if (grub_strcmp(value, "boot_month") == 0) + { + g_theme_random = vtoy_theme_random_boot_month; + } + } + } } value = vtoy_json_get_string_ex(json->pstChild, "gfxmode"); if (value) { debug("vtoy_gfxmode %s\n", value); - grub_env_set("vtoy_gfxmode", value); + ventoy_env_export("vtoy_gfxmode", value); } value = vtoy_json_get_string_ex(json->pstChild, "display_mode"); if (value) { debug("display_mode %s\n", value); - grub_env_set("vtoy_display_mode", value); + ventoy_env_export("vtoy_display_mode", value); + } + + value = vtoy_json_get_string_ex(json->pstChild, "serial_param"); + if (value) + { + debug("serial_param %s\n", value); + ventoy_env_export("vtoy_serial_param", value); } value = vtoy_json_get_string_ex(json->pstChild, "ventoy_left"); if (value) { - grub_env_set("VTLE_LFT", value); + ventoy_env_export("VTLE_LFT", value); } value = vtoy_json_get_string_ex(json->pstChild, "ventoy_top"); if (value) { - grub_env_set("VTLE_TOP", value); + ventoy_env_export("VTLE_TOP", value); } value = vtoy_json_get_string_ex(json->pstChild, "ventoy_color"); if (value) { - grub_env_set("VTLE_CLR", value); + ventoy_env_export("VTLE_CLR", value); } node = vtoy_json_find_item(json->pstChild, JSON_TYPE_ARRAY, "fonts"); @@ -310,11 +461,13 @@ static int ventoy_plugin_check_fullpath ( VTOY_JSON *json, const char *isodisk, - const char *key + const char *key, + int *pathnum ) { int rc = 0; int ret = 0; + int cnt = 0; VTOY_JSON *node = json; VTOY_JSON *child = NULL; @@ -334,6 +487,7 @@ static int ventoy_plugin_check_fullpath if (JSON_TYPE_STRING == node->enDataType) { + cnt = 1; ret = ventoy_plugin_check_path(isodisk, node->unData.pcStrVal); grub_printf("%s: %s [%s]\n", key, node->unData.pcStrVal, ret ? "FAIL" : "OK"); } @@ -350,10 +504,12 @@ static int ventoy_plugin_check_fullpath rc = ventoy_plugin_check_path(isodisk, child->unData.pcStrVal); grub_printf("%s: %s [%s]\n", key, child->unData.pcStrVal, rc ? "FAIL" : "OK"); ret += rc; + cnt++; } } } + *pathnum = cnt; return ret; } @@ -443,6 +599,9 @@ static int ventoy_plugin_parse_fullpath static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk) { + int pathnum = 0; + int autosel = 0; + char *pos = NULL; const char *iso = NULL; VTOY_JSON *pNode = NULL; @@ -459,19 +618,55 @@ static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk grub_printf("NOT object type\n"); } - iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); - if (iso) + if ((iso = vtoy_json_get_string_ex(pNode->pstChild, "image")) != NULL) { - if (0 == ventoy_plugin_check_path(isodisk, iso)) + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) { - grub_printf("image: %s [OK]\n", iso); - ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template"); + grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK")); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } } else { grub_printf("image: %s [FAIL]\n", iso); } } + else if ((iso = vtoy_json_get_string_ex(pNode->pstChild, "parent")) != NULL) + { + if (ventoy_is_dir_exist("%s%s", isodisk, iso)) + { + grub_printf("parent: %s [OK]\n", iso); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "template", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } + } + else + { + grub_printf("parent: %s [FAIL]\n", iso); + } + } else { grub_printf("image not found\n"); @@ -483,7 +678,9 @@ static int ventoy_plugin_auto_install_check(VTOY_JSON *json, const char *isodisk static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk) { + int type = 0; int pathnum = 0; + int autosel = 0; const char *iso = NULL; VTOY_JSON *pNode = NULL; install_template *node = NULL; @@ -510,7 +707,14 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { + type = auto_install_type_file; iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!iso) + { + type = auto_install_type_parent; + iso = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + } + if (iso && iso[0] == '/') { if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "template", &templatepath, &pathnum)) @@ -518,10 +722,20 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk node = grub_zalloc(sizeof(install_template)); if (node) { + node->type = type; node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); node->templatepath = templatepath; node->templatenum = pathnum; + node->autosel = -1; + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + node->autosel = autosel; + } + } + if (g_install_template_head) { node->next = g_install_template_head; @@ -536,8 +750,10 @@ static int ventoy_plugin_auto_install_entry(VTOY_JSON *json, const char *isodisk return 0; } -static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) +static int ventoy_plugin_dud_check(VTOY_JSON *json, const char *isodisk) { + int pathnum = 0; + char *pos = NULL; const char *iso = NULL; VTOY_JSON *pNode = NULL; @@ -557,10 +773,445 @@ static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); if (iso) { - if (0 == ventoy_plugin_check_path(isodisk, iso)) + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) { - grub_printf("image: %s [OK]\n", iso); - ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend"); + grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK")); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "dud", &pathnum); + } + else + { + grub_printf("image: %s [FAIL]\n", iso); + } + } + else + { + grub_printf("image not found\n"); + } + } + + return 0; +} + +static int ventoy_plugin_dud_entry(VTOY_JSON *json, const char *isodisk) +{ + int pathnum = 0; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + dud *node = NULL; + dud *next = NULL; + file_fullpath *dudpath = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_dud_head) + { + for (node = g_dud_head; node; node = next) + { + next = node->next; + grub_check_free(node->dudpath); + grub_free(node); + } + + g_dud_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso && iso[0] == '/') + { + if (0 == ventoy_plugin_parse_fullpath(pNode->pstChild, isodisk, "dud", &dudpath, &pathnum)) + { + node = grub_zalloc(sizeof(dud)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->dudpath = dudpath; + node->dudnum = pathnum; + node->files = grub_zalloc(sizeof(dudfile) * pathnum); + + if (node->files) + { + if (g_dud_head) + { + node->next = g_dud_head; + } + + g_dud_head = node; + } + else + { + grub_free(node); + } + } + } + } + } + + return 0; +} + +static int ventoy_plugin_parse_pwdstr(char *pwdstr, vtoy_password *pwd) +{ + int i; + int len; + char ch; + char *pos; + char bytes[3]; + vtoy_password tmpPwd; + + len = (int)grub_strlen(pwdstr); + if (len > 64) + { + if (NULL == pwd) grub_printf("Password too long %d\n", len); + return 1; + } + + grub_memset(&tmpPwd, 0, sizeof(tmpPwd)); + + if (grub_strncmp(pwdstr, "txt#", 4) == 0) + { + tmpPwd.type = VTOY_PASSWORD_TXT; + grub_snprintf(tmpPwd.text, sizeof(tmpPwd.text), "%s", pwdstr + 4); + } + else if (grub_strncmp(pwdstr, "md5#", 4) == 0) + { + if ((len - 4) == 32) + { + for (i = 0; i < 16; i++) + { + bytes[0] = pwdstr[4 + i * 2]; + bytes[1] = pwdstr[4 + i * 2 + 1]; + bytes[2] = 0; + + if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1])) + { + tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16); + } + else + { + if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i); + return 1; + } + } + tmpPwd.type = VTOY_PASSWORD_MD5; + } + else if ((len - 4) > 32) + { + pos = grub_strchr(pwdstr + 4, '#'); + if (!pos) + { + if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr); + return 1; + } + + if (len - 1 - (int)(long)(pos - pwdstr) != 32) + { + if (NULL == pwd) grub_printf("Invalid md5 salt password format %s\n", pwdstr); + return 1; + } + + ch = *pos; + *pos = 0; + grub_snprintf(tmpPwd.salt, sizeof(tmpPwd.salt), "%s", pwdstr + 4); + *pos = ch; + + pos++; + for (i = 0; i < 16; i++) + { + bytes[0] = pos[i * 2]; + bytes[1] = pos[i * 2 + 1]; + bytes[2] = 0; + + if (grub_isxdigit(bytes[0]) && grub_isxdigit(bytes[1])) + { + tmpPwd.md5[i] = (grub_uint8_t)grub_strtoul(bytes, NULL, 16); + } + else + { + if (NULL == pwd) grub_printf("Invalid md5 hex format %s %d\n", pwdstr, i); + return 1; + } + } + + tmpPwd.type = VTOY_PASSWORD_SALT_MD5; + } + else + { + if (NULL == pwd) grub_printf("Invalid md5 password format %s\n", pwdstr); + return 1; + } + } + else + { + if (NULL == pwd) grub_printf("Invalid password format %s\n", pwdstr); + return 1; + } + + if (pwd) + { + grub_memcpy(pwd, &tmpPwd, sizeof(tmpPwd)); + } + + return 0; +} + +static int ventoy_plugin_get_pwd_type(const char *pwd) +{ + int i; + char pwdtype[64]; + + for (i = 0; pwd && i < (int)ARRAY_SIZE(g_menu_prefix); i++) + { + grub_snprintf(pwdtype, sizeof(pwdtype), "%spwd", g_menu_prefix[i]); + if (grub_strcmp(pwdtype, pwd) == 0) + { + return img_type_start + i; + } + } + + return -1; +} + +static int ventoy_plugin_pwd_entry(VTOY_JSON *json, const char *isodisk) +{ + int type = -1; + const char *iso = NULL; + const char *pwd = NULL; + VTOY_JSON *pNode = NULL; + VTOY_JSON *pCNode = NULL; + menu_password *node = NULL; + menu_password *tail = NULL; + menu_password *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_OBJECT) + { + debug("Not object %d\n", json->enDataType); + return 0; + } + + if (g_pwd_head) + { + for (node = g_pwd_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_pwd_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0) + { + ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, &g_boot_pwd); + } + else if ((type = ventoy_plugin_get_pwd_type(pNode->pcName)) >= 0) + { + ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, g_file_type_pwd + type); + } + else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0) + { + for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext) + { + if (pCNode->enDataType != JSON_TYPE_OBJECT) + { + continue; + } + + type = vtoy_menu_pwd_file; + iso = vtoy_json_get_string_ex(pCNode->pstChild, "file"); + if (!iso) + { + type = vtoy_menu_pwd_parent; + iso = vtoy_json_get_string_ex(pCNode->pstChild, "parent"); + } + + pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd"); + if (iso && pwd && iso[0] == '/') + { + node = grub_zalloc(sizeof(menu_password)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + + if (ventoy_plugin_parse_pwdstr((char *)pwd, &(node->password))) + { + grub_free(node); + continue; + } + + if (g_pwd_head) + { + tail->next = node; + } + else + { + g_pwd_head = node; + } + tail = node; + } + } + } + } + } + + return 0; +} + +static int ventoy_plugin_pwd_check(VTOY_JSON *json, const char *isodisk) +{ + int type = -1; + char *pos = NULL; + const char *iso = NULL; + const char *pwd = NULL; + VTOY_JSON *pNode = NULL; + VTOY_JSON *pCNode = NULL; + + if (json->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("Not object %d\n", json->enDataType); + return 0; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->pcName && grub_strcmp("bootpwd", pNode->pcName) == 0) + { + if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL)) + { + grub_printf("bootpwd:<%s>\n", pNode->unData.pcStrVal); + } + else + { + grub_printf("Invalid bootpwd.\n"); + } + } + else if ((type = ventoy_plugin_get_pwd_type(pNode->pcName)) >= 0) + { + if (0 == ventoy_plugin_parse_pwdstr(pNode->unData.pcStrVal, NULL)) + { + grub_printf("%s:<%s>\n", pNode->pcName, pNode->unData.pcStrVal); + } + else + { + grub_printf("Invalid pwd <%s>\n", pNode->unData.pcStrVal); + } + } + else if (pNode->pcName && grub_strcmp("menupwd", pNode->pcName) == 0) + { + grub_printf("\n"); + for (pCNode = pNode->pstChild; pCNode; pCNode = pCNode->pstNext) + { + if (pCNode->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("Not object %d\n", pCNode->enDataType); + continue; + } + + if ((iso = vtoy_json_get_string_ex(pCNode->pstChild, "file")) != NULL) + { + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) + { + pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd"); + + if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL)) + { + grub_printf("file:<%s> [%s]\n", iso, (pos ? "*" : "OK")); + grub_printf("pwd:<%s>\n\n", pwd); + } + else + { + grub_printf("Invalid password for <%s>\n", iso); + } + } + else + { + grub_printf("<%s%s> not found\n", isodisk, iso); + } + } + else if ((iso = vtoy_json_get_string_ex(pCNode->pstChild, "parent")) != NULL) + { + if (ventoy_is_dir_exist("%s%s", isodisk, iso)) + { + pwd = vtoy_json_get_string_ex(pCNode->pstChild, "pwd"); + if (0 == ventoy_plugin_parse_pwdstr((char *)pwd, NULL)) + { + grub_printf("dir:<%s> [%s]\n", iso, (pos ? "*" : "OK")); + grub_printf("pwd:<%s>\n\n", pwd); + } + else + { + grub_printf("Invalid password for <%s>\n", iso); + } + } + else + { + grub_printf("<%s%s> not found\n", isodisk, iso); + } + } + else + { + grub_printf("No file item found in json.\n"); + } + } + } + } + + return 0; +} + +static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) +{ + int autosel = 0; + int pathnum = 0; + char *pos = NULL; + const char *iso = NULL; + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array type %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType != JSON_TYPE_OBJECT) + { + grub_printf("NOT object type\n"); + } + + iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (iso) + { + pos = grub_strchr(iso, '*'); + if (pos || 0 == ventoy_plugin_check_path(isodisk, iso)) + { + grub_printf("image: %s [%s]\n", iso, (pos ? "*" : "OK")); + ventoy_plugin_check_fullpath(pNode->pstChild, isodisk, "backend", &pathnum); + + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + grub_printf("autosel: %d [OK]\n", autosel); + } + else + { + grub_printf("autosel: %d [FAIL]\n", autosel); + } + } } else { @@ -578,6 +1229,7 @@ static int ventoy_plugin_persistence_check(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) { + int autosel = 0; int pathnum = 0; const char *iso = NULL; VTOY_JSON *pNode = NULL; @@ -619,6 +1271,15 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) node->backendpath = backendpath; node->backendnum = pathnum; + node->autosel = -1; + if (JSON_SUCCESS == vtoy_json_get_int(pNode->pstChild, "autosel", &autosel)) + { + if (autosel >= 0 && autosel <= pathnum) + { + node->autosel = autosel; + } + } + if (g_persistence_head) { node->next = g_persistence_head; @@ -635,7 +1296,8 @@ static int ventoy_plugin_persistence_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk) { - const char *iso = NULL; + int type; + const char *path = NULL; const char *alias = NULL; VTOY_JSON *pNode = NULL; @@ -649,17 +1311,42 @@ static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { - iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); - alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); - if (iso && iso[0] == '/' && alias) + type = vtoy_alias_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) { - if (ventoy_is_file_exist("%s%s", isodisk, iso)) + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_alias_directory; + } + + alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); + if (path && path[0] == '/' && alias) + { + if (vtoy_alias_image_file == type) { - grub_printf("image: <%s> [ OK ]\n", iso); + if (grub_strchr(path, '*')) + { + grub_printf("image: <%s> [ * ]\n", path); + } + else if (ventoy_is_file_exist("%s%s", isodisk, path)) + { + grub_printf("image: <%s> [ OK ]\n", path); + } + else + { + grub_printf("image: <%s> [ NOT EXIST ]\n", path); + } } else { - grub_printf("image: <%s> [ NOT EXIST ]\n", iso); + if (ventoy_is_dir_exist("%s%s", isodisk, path)) + { + grub_printf("dir: <%s> [ OK ]\n", path); + } + else + { + grub_printf("dir: <%s> [ NOT EXIST ]\n", path); + } } grub_printf("alias: <%s>\n\n", alias); @@ -671,7 +1358,8 @@ static int ventoy_plugin_menualias_check(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk) { - const char *iso = NULL; + int type; + const char *path = NULL; const char *alias = NULL; VTOY_JSON *pNode = NULL; menu_alias *node = NULL; @@ -698,14 +1386,22 @@ static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { - iso = vtoy_json_get_string_ex(pNode->pstChild, "image"); + type = vtoy_alias_image_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + path = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_alias_directory; + } + alias = vtoy_json_get_string_ex(pNode->pstChild, "alias"); - if (iso && iso[0] == '/' && alias) + if (path && path[0] == '/' && alias) { node = grub_zalloc(sizeof(menu_alias)); if (node) { - node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", iso); + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path); grub_snprintf(node->alias, sizeof(node->alias), "%s", alias); if (g_menu_alias_head) @@ -721,8 +1417,132 @@ static int ventoy_plugin_menualias_entry(VTOY_JSON *json, const char *isodisk) return 0; } + +static int ventoy_plugin_injection_check(VTOY_JSON *json, const char *isodisk) +{ + int type = 0; + const char *path = NULL; + const char *archive = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 0; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = injection_type_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + type = injection_type_parent; + path = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + if (!path) + { + grub_printf("image/parent not found\n"); + continue; + } + } + + archive = vtoy_json_get_string_ex(pNode->pstChild, "archive"); + if (!archive) + { + grub_printf("archive not found\n"); + continue; + } + + if (type == injection_type_file) + { + if (grub_strchr(path, '*')) + { + grub_printf("image: <%s> [*]\n", path); + } + else + { + grub_printf("image: <%s> [%s]\n", path, ventoy_check_file_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST"); + } + } + else + { + grub_printf("parent: <%s> [%s]\n", path, + ventoy_is_dir_exist("%s%s", isodisk, path) ? "OK" : "NOT EXIST"); + } + + grub_printf("archive: <%s> [%s]\n\n", archive, ventoy_check_file_exist("%s%s", isodisk, archive) ? "OK" : "NOT EXIST"); + } + + return 0; +} + +static int ventoy_plugin_injection_entry(VTOY_JSON *json, const char *isodisk) +{ + int type = 0; + const char *path = NULL; + const char *archive = NULL; + VTOY_JSON *pNode = NULL; + injection_config *node = NULL; + injection_config *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_injection_head) + { + for (node = g_injection_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_injection_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = injection_type_file; + path = vtoy_json_get_string_ex(pNode->pstChild, "image"); + if (!path) + { + type = injection_type_parent; + path = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + } + + archive = vtoy_json_get_string_ex(pNode->pstChild, "archive"); + if (path && path[0] == '/' && archive && archive[0] == '/') + { + node = grub_zalloc(sizeof(injection_config)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", path); + grub_snprintf(node->archive, sizeof(node->archive), "%s", archive); + + if (g_injection_head) + { + node->next = g_injection_head; + } + + g_injection_head = node; + } + } + } + + return 0; +} + static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk) { + int type; + int parent = 0; const char *key = NULL; const char *class = NULL; VTOY_JSON *pNode = NULL; @@ -751,13 +1571,31 @@ static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { + parent = 0; + type = vtoy_class_image_file; key = vtoy_json_get_string_ex(pNode->pstChild, "key"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + if (key) + { + parent = 1; + } + else + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_class_directory; + } + } + class = vtoy_json_get_string_ex(pNode->pstChild, "class"); if (key && class) { node = grub_zalloc(sizeof(menu_class)); if (node) { + node->type = type; + node->parent = parent; node->patlen = grub_snprintf(node->pattern, sizeof(node->pattern), "%s", key); grub_snprintf(node->class, sizeof(node->class), "%s", class); @@ -779,6 +1617,7 @@ static int ventoy_plugin_menuclass_entry(VTOY_JSON *json, const char *isodisk) static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk) { + const char *name = NULL; const char *key = NULL; const char *class = NULL; VTOY_JSON *pNode = NULL; @@ -793,11 +1632,23 @@ static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk) for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) { + name = "key"; key = vtoy_json_get_string_ex(pNode->pstChild, "key"); + if (!key) + { + name = "parent"; + key = vtoy_json_get_string_ex(pNode->pstChild, "parent"); + if (!key) + { + name = "dir"; + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + } + } + class = vtoy_json_get_string_ex(pNode->pstChild, "class"); if (key && class) { - grub_printf("key: <%s>\n", key); + grub_printf("%s: <%s>\n", name, key); grub_printf("class: <%s>\n\n", class); } } @@ -805,6 +1656,444 @@ static int ventoy_plugin_menuclass_check(VTOY_JSON *json, const char *isodisk) return 0; } +static int ventoy_plugin_custom_boot_entry(VTOY_JSON *json, const char *isodisk) +{ + int type; + int len; + const char *key = NULL; + const char *cfg = NULL; + VTOY_JSON *pNode = NULL; + custom_boot *tail = NULL; + custom_boot *node = NULL; + custom_boot *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_custom_boot_head) + { + for (node = g_custom_boot_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_custom_boot_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_custom_boot_image_file; + key = vtoy_json_get_string_ex(pNode->pstChild, "file"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_custom_boot_directory; + } + + cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg"); + if (key && cfg) + { + node = grub_zalloc(sizeof(custom_boot)); + if (node) + { + node->type = type; + node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", key); + len = (int)grub_snprintf(node->cfg, sizeof(node->cfg), "%s", cfg); + + if (len >= 5 && grub_strncmp(node->cfg + len - 5, ".vcfg", 5) == 0) + { + if (g_custom_boot_head) + { + tail->next = node; + } + else + { + g_custom_boot_head = node; + } + tail = node; + } + else + { + grub_free(node); + } + } + } + } + + return 0; +} + +static int ventoy_plugin_custom_boot_check(VTOY_JSON *json, const char *isodisk) +{ + int type; + int len; + const char *key = NULL; + const char *cfg = NULL; + VTOY_JSON *pNode = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + type = vtoy_custom_boot_image_file; + key = vtoy_json_get_string_ex(pNode->pstChild, "file"); + if (!key) + { + key = vtoy_json_get_string_ex(pNode->pstChild, "dir"); + type = vtoy_custom_boot_directory; + } + + cfg = vtoy_json_get_string_ex(pNode->pstChild, "vcfg"); + len = (int)grub_strlen(cfg); + if (key && cfg) + { + if (len < 5 || grub_strncmp(cfg + len - 5, ".vcfg", 5)) + { + grub_printf("<%s> does not have \".vcfg\" suffix\n\n", cfg); + } + else + { + grub_printf("%s: <%s>\n", (type == vtoy_custom_boot_directory) ? "dir" : "file", key); + grub_printf("vcfg: <%s>\n\n", cfg); + } + } + } + + return 0; +} + +static int ventoy_plugin_conf_replace_entry(VTOY_JSON *json, const char *isodisk) +{ + const char *isof = NULL; + const char *orgf = NULL; + const char *newf = NULL; + VTOY_JSON *pNode = NULL; + conf_replace *tail = NULL; + conf_replace *node = NULL; + conf_replace *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_conf_replace_head) + { + for (node = g_conf_replace_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_conf_replace_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + isof = vtoy_json_get_string_ex(pNode->pstChild, "iso"); + orgf = vtoy_json_get_string_ex(pNode->pstChild, "org"); + newf = vtoy_json_get_string_ex(pNode->pstChild, "new"); + if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/') + { + node = grub_zalloc(sizeof(conf_replace)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", isof); + grub_snprintf(node->orgconf, sizeof(node->orgconf), "%s", orgf); + grub_snprintf(node->newconf, sizeof(node->newconf), "%s", newf); + + if (g_conf_replace_head) + { + tail->next = node; + } + else + { + g_conf_replace_head = node; + } + tail = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_conf_replace_check(VTOY_JSON *json, const char *isodisk) +{ + const char *isof = NULL; + const char *orgf = NULL; + const char *newf = NULL; + VTOY_JSON *pNode = NULL; + grub_file_t file = NULL; + char cmd[256]; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + isof = vtoy_json_get_string_ex(pNode->pstChild, "iso"); + orgf = vtoy_json_get_string_ex(pNode->pstChild, "org"); + newf = vtoy_json_get_string_ex(pNode->pstChild, "new"); + if (isof && orgf && newf && isof[0] == '/' && orgf[0] == '/' && newf[0] == '/') + { + if (ventoy_check_file_exist("%s%s", isodisk, isof)) + { + grub_printf("iso:<%s> [OK]\n", isof); + + grub_snprintf(cmd, sizeof(cmd), "loopback vtisocheck \"%s%s\"", isodisk, isof); + grub_script_execute_sourcecode(cmd); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vtisocheck)/%s", orgf); + if (file) + { + if (grub_strcmp(file->fs->name, "iso9660") == 0) + { + grub_printf("org:<%s> [OK]\n", orgf); + } + else + { + grub_printf("org:<%s> [Exist But NOT ISO9660]\n", orgf); + } + grub_file_close(file); + } + else + { + grub_printf("org:<%s> [NOT Exist]\n", orgf); + } + + grub_script_execute_sourcecode("loopback -d vtisocheck"); + } + else if (grub_strchr(isof, '*')) + { + grub_printf("iso:<%s> [*]\n", isof); + grub_printf("org:<%s>\n", orgf); + } + else + { + grub_printf("iso:<%s> [NOT Exist]\n", isof); + grub_printf("org:<%s>\n", orgf); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isodisk, newf); + if (file) + { + if (file->size > vtoy_max_replace_file_size) + { + grub_printf("new:<%s> [Too Big %lu] \n", newf, (ulong)file->size); + } + else + { + grub_printf("new:<%s> [OK]\n", newf); + } + grub_file_close(file); + } + else + { + grub_printf("new:<%s> [NOT Exist]\n", newf); + } + grub_printf("\n"); + } + } + + return 0; +} + +static int ventoy_plugin_auto_memdisk_entry(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + auto_memdisk *node = NULL; + auto_memdisk *next = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_auto_memdisk_head) + { + for (node = g_auto_memdisk_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_auto_memdisk_head = NULL; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + node = grub_zalloc(sizeof(auto_memdisk)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal); + + if (g_auto_memdisk_head) + { + node->next = g_auto_memdisk_head; + } + + g_auto_memdisk_head = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_auto_memdisk_check(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + grub_printf("<%s> ", pNode->unData.pcStrVal); + + if (grub_strchr(pNode->unData.pcStrVal, '*')) + { + grub_printf(" [*]\n"); + } + else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal)) + { + grub_printf(" [OK]\n"); + } + else + { + grub_printf(" [NOT EXIST]\n"); + } + } + } + + return 0; +} + +static int ventoy_plugin_image_list_entry(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + image_list *node = NULL; + image_list *next = NULL; + image_list *tail = NULL; + + (void)isodisk; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + debug("Not array %d\n", json->enDataType); + return 0; + } + + if (g_image_list_head) + { + for (node = g_image_list_head; node; node = next) + { + next = node->next; + grub_free(node); + } + + g_image_list_head = NULL; + } + + if (grub_strncmp(json->pcName, "image_blacklist", 15) == 0) + { + g_plugin_image_list = VENTOY_IMG_BLACK_LIST; + } + else + { + g_plugin_image_list = VENTOY_IMG_WHITE_LIST; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + node = grub_zalloc(sizeof(image_list)); + if (node) + { + node->pathlen = grub_snprintf(node->isopath, sizeof(node->isopath), "%s", pNode->unData.pcStrVal); + + if (g_image_list_head) + { + tail->next = node; + } + else + { + g_image_list_head = node; + } + tail = node; + } + } + } + + return 0; +} + +static int ventoy_plugin_image_list_check(VTOY_JSON *json, const char *isodisk) +{ + VTOY_JSON *pNode = NULL; + + if (json->enDataType != JSON_TYPE_ARRAY) + { + grub_printf("Not array %d\n", json->enDataType); + return 1; + } + + for (pNode = json->pstChild; pNode; pNode = pNode->pstNext) + { + if (pNode->enDataType == JSON_TYPE_STRING) + { + grub_printf("<%s> ", pNode->unData.pcStrVal); + + if (grub_strchr(pNode->unData.pcStrVal, '*')) + { + grub_printf(" [*]\n"); + } + else if (ventoy_check_file_exist("%s%s", isodisk, pNode->unData.pcStrVal)) + { + grub_printf(" [OK]\n"); + } + else + { + grub_printf(" [NOT EXIST]\n"); + } + } + } + + return 0; +} + static plugin_entry g_plugin_entries[] = { { "control", ventoy_plugin_control_entry, ventoy_plugin_control_check }, @@ -813,11 +2102,20 @@ static plugin_entry g_plugin_entries[] = { "persistence", ventoy_plugin_persistence_entry, ventoy_plugin_persistence_check }, { "menu_alias", ventoy_plugin_menualias_entry, ventoy_plugin_menualias_check }, { "menu_class", ventoy_plugin_menuclass_entry, ventoy_plugin_menuclass_check }, + { "injection", ventoy_plugin_injection_entry, ventoy_plugin_injection_check }, + { "auto_memdisk", ventoy_plugin_auto_memdisk_entry, ventoy_plugin_auto_memdisk_check }, + { "image_list", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check }, + { "image_blacklist", ventoy_plugin_image_list_entry, ventoy_plugin_image_list_check }, + { "conf_replace", ventoy_plugin_conf_replace_entry, ventoy_plugin_conf_replace_check }, + { "dud", ventoy_plugin_dud_entry, ventoy_plugin_dud_check }, + { "password", ventoy_plugin_pwd_entry, ventoy_plugin_pwd_check }, + { "custom_boot", ventoy_plugin_custom_boot_entry, ventoy_plugin_custom_boot_check }, }; static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) { int i; + char key[128]; VTOY_JSON *cur = json; grub_snprintf(g_iso_disk_name, sizeof(g_iso_disk_name), "%s", isodisk); @@ -826,7 +2124,8 @@ static int ventoy_parse_plugin_config(VTOY_JSON *json, const char *isodisk) { for (i = 0; i < (int)ARRAY_SIZE(g_plugin_entries); i++) { - if (grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0) + grub_snprintf(key, sizeof(key), "%s_%s", g_plugin_entries[i].key, g_arch_mode_suffix); + if (grub_strcmp(g_plugin_entries[i].key, cur->pcName) == 0 || grub_strcmp(key, cur->pcName) == 0) { debug("Plugin entry for %s\n", g_plugin_entries[i].key); g_plugin_entries[i].entryfunc(cur, isodisk); @@ -850,14 +2149,14 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a (void)ctxt; (void)argc; - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/ventoy/ventoy.json", args[0]); + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]); if (!file) { return GRUB_ERR_NONE; } debug("json configuration file size %d\n", (int)file->size); - + buf = grub_malloc(file->size + 1); if (!buf) { @@ -880,6 +2179,9 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a ret = vtoy_json_parse(json, buf); if (ret) { + grub_env_set("VTOY_PLUGIN_SYNTAX_ERROR", "1"); + grub_env_export("VTOY_PLUGIN_SYNTAX_ERROR"); + debug("Failed to parse json string %d\n", ret); grub_free(buf); return 1; @@ -891,9 +2193,35 @@ grub_err_t ventoy_cmd_load_plugin(grub_extcmd_context_t ctxt, int argc, char **a grub_free(buf); + if (g_boot_pwd.type) + { + grub_printf("\n\n======= %s ======\n\n", grub_env_get("VTOY_TEXT_MENU_VER")); + if (ventoy_check_password(&g_boot_pwd, 3)) + { + grub_printf("\n!!! Password check failed, will exit after 5 seconds. !!!\n"); + grub_refresh(); + grub_sleep(5); + grub_exit(); + } + } + VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +void ventoy_plugin_dump_injection(void) +{ + injection_config *node = NULL; + + for (node = g_injection_head; node; node = node->next) + { + grub_printf("\n%s:<%s>\n", (node->type == injection_type_file) ? "IMAGE" : "PARENT", node->isopath); + grub_printf("ARCHIVE:<%s>\n", node->archive); + } + + return; +} + + void ventoy_plugin_dump_auto_install(void) { int i; @@ -901,7 +2229,9 @@ void ventoy_plugin_dump_auto_install(void) for (node = g_install_template_head; node; node = node->next) { - grub_printf("\nIMAGE:<%s>\n", node->isopath); + grub_printf("\n%s:<%s> <%d>\n", + (node->type == auto_install_type_file) ? "IMAGE" : "PARENT", + node->isopath, node->templatenum); for (i = 0; i < node->templatenum; i++) { grub_printf("SCRIPT %d:<%s>\n", i, node->templatepath[i].path); @@ -920,7 +2250,7 @@ void ventoy_plugin_dump_persistence(void) for (node = g_persistence_head; node; node = node->next) { - grub_printf("\nIMAGE:<%s>\n", node->isopath); + grub_printf("\nIMAGE:<%s> <%d>\n", node->isopath, node->backendnum); for (i = 0; i < node->backendnum; i++) { @@ -943,14 +2273,34 @@ void ventoy_plugin_dump_persistence(void) install_template * ventoy_plugin_find_install_template(const char *isopath) { + int len; install_template *node = NULL; - int len = (int)grub_strlen(isopath); + + if (!g_install_template_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + for (node = g_install_template_head; node; node = node->next) + { + if (node->type == auto_install_type_file) + { + if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0) + { + return node; + } + } + } for (node = g_install_template_head; node; node = node->next) { - if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) + if (node->type == auto_install_type_parent) { - return node; + if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath)) + { + return node; + } } } @@ -977,12 +2327,18 @@ char * ventoy_plugin_get_cur_install_template(const char *isopath) persistence_config * ventoy_plugin_find_persistent(const char *isopath) { + int len; persistence_config *node = NULL; - int len = (int)grub_strlen(isopath); - + + if (!g_persistence_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); for (node = g_persistence_head; node; node = node->next) { - if ((len == node->pathlen) && (grub_strcmp(node->isopath, isopath) == 0)) + if ((len == node->pathlen) && (ventoy_strcmp(node->isopath, isopath) == 0)) { return node; } @@ -1050,14 +2406,57 @@ end: return rc; } -const char * ventoy_plugin_get_menu_alias(const char *isopath) +const char * ventoy_plugin_get_injection(const char *isopath) { - menu_alias *node = NULL; - int len = (int)grub_strlen(isopath); + int len; + injection_config *node = NULL; + + if (!g_injection_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + for (node = g_injection_head; node; node = node->next) + { + if (node->type == injection_type_file) + { + if (node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0) + { + return node->archive; + } + } + } + for (node = g_injection_head; node; node = node->next) + { + if (node->type == injection_type_parent) + { + if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath)) + { + return node->archive; + } + } + } + + return NULL; +} + +const char * ventoy_plugin_get_menu_alias(int type, const char *isopath) +{ + int len; + menu_alias *node = NULL; + + if (!g_menu_alias_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); for (node = g_menu_alias_head; node; node = node->next) { - if (node->pathlen == len && grub_strcmp(node->isopath, isopath) == 0) + if (node->type == type && node->pathlen && + node->pathlen == len && ventoy_strcmp(node->isopath, isopath) == 0) { return node->alias; } @@ -1066,28 +2465,386 @@ const char * ventoy_plugin_get_menu_alias(const char *isopath) return NULL; } -const char * ventoy_plugin_get_menu_class(const char *isoname) +const char * ventoy_plugin_get_menu_class(int type, const char *name, const char *path) { + int namelen; + int pathlen; menu_class *node = NULL; - int len = (int)grub_strlen(isoname); - - for (node = g_menu_class_head; node; node = node->next) + + if (!g_menu_class_head) { - if (node->patlen <= len && grub_strstr(isoname, node->pattern)) + return NULL; + } + + namelen = (int)grub_strlen(name); + pathlen = (int)grub_strlen(path); + + if (vtoy_class_image_file == type) + { + for (node = g_menu_class_head; node; node = node->next) { - return node->class; + if (node->type != type) + { + continue; + } + + if (node->parent == 0) + { + if ((node->patlen < namelen) && grub_strstr(name, node->pattern)) + { + return node->class; + } + } + } + + for (node = g_menu_class_head; node; node = node->next) + { + if (node->type != type) + { + continue; + } + + if (node->parent) + { + if ((node->patlen < pathlen) && ventoy_plugin_is_parent(node->pattern, node->patlen, path)) + { + return node->class; + } + } + } + } + else + { + for (node = g_menu_class_head; node; node = node->next) + { + if (node->type == type && node->patlen == namelen && grub_strncmp(name, node->pattern, namelen) == 0) + { + return node->class; + } } } return NULL; } +int ventoy_plugin_add_custom_boot(const char *vcfgpath) +{ + int len; + custom_boot *node = NULL; + + node = grub_zalloc(sizeof(custom_boot)); + if (node) + { + node->type = vtoy_custom_boot_image_file; + node->pathlen = grub_snprintf(node->path, sizeof(node->path), "%s", vcfgpath); + grub_snprintf(node->cfg, sizeof(node->cfg), "%s", vcfgpath); + + /* .vcfg */ + len = node->pathlen - 5; + node->path[len] = 0; + node->pathlen = len; + + if (g_custom_boot_head) + { + node->next = g_custom_boot_head; + } + g_custom_boot_head = node; + } + + return 0; +} + +const char * ventoy_plugin_get_custom_boot(const char *isopath) +{ + int i; + int len; + custom_boot *node = NULL; + + if (!g_custom_boot_head) + { + return NULL; + } + + len = (int)grub_strlen(isopath); + + for (node = g_custom_boot_head; node; node = node->next) + { + if (node->type == vtoy_custom_boot_image_file) + { + if (node->pathlen == len && grub_strncmp(isopath, node->path, len) == 0) + { + return node->cfg; + } + } + else + { + if (node->pathlen < len && isopath[node->pathlen] == '/' && + grub_strncmp(isopath, node->path, node->pathlen) == 0) + { + for (i = node->pathlen + 1; i < len; i++) + { + if (isopath[i] == '/') + { + break; + } + } + + if (i >= len) + { + return node->cfg; + } + } + } + } + + return NULL; +} + +grub_err_t ventoy_cmd_dump_custom_boot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + custom_boot *node = NULL; + + (void)argc; + (void)ctxt; + (void)args; + + for (node = g_custom_boot_head; node; node = node->next) + { + grub_printf("[%s] <%s>:<%s>\n", (node->type == vtoy_custom_boot_directory) ? "dir" : "file", + node->path, node->cfg); + } + + return 0; +} + +int ventoy_plugin_check_memdisk(const char *isopath) +{ + int len; + auto_memdisk *node = NULL; + + if (!g_auto_memdisk_head) + { + return 0; + } + + len = (int)grub_strlen(isopath); + for (node = g_auto_memdisk_head; node; node = node->next) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0) + { + return 1; + } + } + + return 0; +} + +int ventoy_plugin_get_image_list_index(int type, const char *name) +{ + int len; + int index = 1; + image_list *node = NULL; + + if (!g_image_list_head) + { + return 0; + } + + len = (int)grub_strlen(name); + + for (node = g_image_list_head; node; node = node->next, index++) + { + if (vtoy_class_directory == type) + { + if (len < node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0) + { + return index; + } + } + else + { + if (len == node->pathlen && ventoy_strncmp(node->isopath, name, len) == 0) + { + return index; + } + } + } + + return 0; +} + +conf_replace * ventoy_plugin_find_conf_replace(const char *iso) +{ + int len; + conf_replace *node; + + if (!g_conf_replace_head) + { + return NULL; + } + + len = (int)grub_strlen(iso); + + for (node = g_conf_replace_head; node; node = node->next) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0) + { + return node; + } + } + + return NULL; +} + +dud * ventoy_plugin_find_dud(const char *iso) +{ + int len; + dud *node; + + if (!g_dud_head) + { + return NULL; + } + + len = (int)grub_strlen(iso); + for (node = g_dud_head; node; node = node->next) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, iso, len) == 0) + { + return node; + } + } + + return NULL; +} + +int ventoy_plugin_load_dud(dud *node, const char *isopart) +{ + int i; + char *buf; + grub_file_t file; + + for (i = 0; i < node->dudnum; i++) + { + if (node->files[i].size > 0) + { + debug("file %d has been loaded\n", i); + continue; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s%s", isopart, node->dudpath[i].path); + if (file) + { + buf = grub_malloc(file->size); + if (buf) + { + grub_file_read(file, buf, file->size); + node->files[i].size = (int)file->size; + node->files[i].buf = buf; + } + grub_file_close(file); + } + } + + return 0; +} + +static const vtoy_password * ventoy_plugin_get_password(const char *isopath) +{ + int i; + int len; + const char *pos = NULL; + menu_password *node = NULL; + + if (!isopath) + { + return NULL; + } + + if (g_pwd_head) + { + len = (int)grub_strlen(isopath); + for (node = g_pwd_head; node; node = node->next) + { + if (node->type == vtoy_menu_pwd_file) + { + if (node->pathlen == len && ventoy_strncmp(node->isopath, isopath, len) == 0) + { + return &(node->password); + } + } + } + + for (node = g_pwd_head; node; node = node->next) + { + if (node->type == vtoy_menu_pwd_parent) + { + if (node->pathlen < len && ventoy_plugin_is_parent(node->isopath, node->pathlen, isopath)) + { + return &(node->password); + } + } + } + } + + while (*isopath) + { + if (*isopath == '.') + { + pos = isopath; + } + isopath++; + } + + if (pos) + { + for (i = 0; i < (int)ARRAY_SIZE(g_menu_prefix); i++) + { + if (g_file_type_pwd[i].type && 0 == grub_strcasecmp(pos + 1, g_menu_prefix[i])) + { + return g_file_type_pwd + i; + } + } + } + + return NULL; +} + +grub_err_t ventoy_cmd_check_password(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret; + const vtoy_password *pwd = NULL; + + (void)ctxt; + (void)argc; + + pwd = ventoy_plugin_get_password(args[0]); + if (pwd) + { + if (0 == ventoy_check_password(pwd, 1)) + { + ret = 1; + } + else + { + ret = 0; + } + } + else + { + ret = 1; + } + + grub_errno = 0; + return ret; +} grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, char **args) { int i = 0; int ret = 0; char *buf = NULL; + char key[128]; grub_file_t file; VTOY_JSON *node = NULL; VTOY_JSON *json = NULL; @@ -1099,10 +2856,11 @@ grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, ch return 0; } - file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s/ventoy/ventoy.json", args[0]); + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s/ventoy/ventoy.json", args[0]); if (!file) { grub_printf("Plugin json file /ventoy/ventoy.json does NOT exist.\n"); + grub_printf("Attention: directory name and filename are both case-sensitive.\n"); goto end; } @@ -1130,9 +2888,10 @@ grub_err_t ventoy_cmd_plugin_check_json(grub_extcmd_context_t ctxt, int argc, ch goto end; } + grub_snprintf(key, sizeof(key), "%s_%s", args[1], g_arch_mode_suffix); for (node = json->pstChild; node; node = node->pstNext) { - if (grub_strcmp(node->pcName, args[1]) == 0) + if (grub_strcmp(node->pcName, args[1]) == 0 || grub_strcmp(node->pcName, key) == 0) { break; } @@ -1164,3 +2923,62 @@ end: return 0; } +grub_err_t ventoy_cmd_set_theme(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i = 0; + grub_uint32_t mod = 0; + theme_list *node = g_theme_head; + struct grub_datetime datetime; + + (void)argc; + (void)args; + (void)ctxt; + + if (g_theme_single_file[0]) + { + debug("single theme %s\n", g_theme_single_file); + grub_env_set("theme", g_theme_single_file); + goto end; + } + + debug("g_theme_num = %d\n", g_theme_num); + + if (g_theme_num == 0) + { + goto end; + } + + grub_memset(&datetime, 0, sizeof(datetime)); + grub_get_datetime(&datetime); + + if (g_theme_random == vtoy_theme_random_boot_second) + { + grub_divmod32((grub_uint32_t)datetime.second, (grub_uint32_t)g_theme_num, &mod); + } + else if (g_theme_random == vtoy_theme_random_boot_day) + { + grub_divmod32((grub_uint32_t)datetime.day, (grub_uint32_t)g_theme_num, &mod); + } + else if (g_theme_random == vtoy_theme_random_boot_month) + { + grub_divmod32((grub_uint32_t)datetime.month, (grub_uint32_t)g_theme_num, &mod); + } + + debug("%04d/%02d/%02d %02d:%02d:%02d radom:%d mod:%d\n", + datetime.year, datetime.month, datetime.day, + datetime.hour, datetime.minute, datetime.second, + g_theme_random, mod); + + for (i = 0; i < mod && node; i++) + { + node = node->next; + } + + debug("random theme %s\n", node->theme.path); + grub_env_set("theme", node->theme.path); + +end: + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c new file mode 100644 index 00000000..179739b2 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_unix.c @@ -0,0 +1,922 @@ +/****************************************************************************** + * ventoy_unix.c + * + * Copyright (c) 2020, longpanda + * + * 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 . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +char g_ko_mod_path[256]; +int g_conf_new_len = 0; +char *g_conf_new_data = NULL; + +int g_mod_new_len = 0; +char *g_mod_new_data = NULL; + +grub_uint64_t g_mod_override_offset = 0; +grub_uint64_t g_conf_override_offset = 0; + +static int ventoy_get_file_override(const char *filename, grub_uint64_t *offset) +{ + grub_file_t file; + + *offset = 0; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(loop)%s", filename); + if (!file) + { + return 1; + } + + *offset = grub_iso9660_get_last_file_dirent_pos(file) + 2; + + grub_file_close(file); + + return 0; +} + +static grub_uint32_t ventoy_unix_get_override_chunk_count(void) +{ + grub_uint32_t count = 0; + + if (g_conf_new_len > 0) + { + count++; + } + + if (g_mod_new_len > 0) + { + count++; + } + + return count; +} + +static grub_uint32_t ventoy_unix_get_virt_chunk_count(void) +{ + grub_uint32_t count = 0; + + if (g_conf_new_len > 0) + { + count++; + } + + if (g_mod_new_len > 0) + { + count++; + } + + return count; +} +static grub_uint32_t ventoy_unix_get_virt_chunk_size(void) +{ + grub_uint32_t size; + + size = sizeof(ventoy_virt_chunk) * ventoy_unix_get_virt_chunk_count(); + + if (g_conf_new_len > 0) + { + size += ventoy_align_2k(g_conf_new_len); + } + + if (g_mod_new_len > 0) + { + size += ventoy_align_2k(g_mod_new_len); + } + + return size; +} + +static void ventoy_unix_fill_override_data( grub_uint64_t isosize, void *override) +{ + grub_uint64_t sector; + ventoy_override_chunk *cur; + ventoy_iso9660_override *dirent; + + sector = (isosize + 2047) / 2048; + + cur = (ventoy_override_chunk *)override; + + if (g_conf_new_len > 0) + { + /* loader.conf */ + cur->img_offset = g_conf_override_offset; + cur->override_size = sizeof(ventoy_iso9660_override); + dirent = (ventoy_iso9660_override *)cur->override_data; + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = (grub_uint32_t)g_conf_new_len; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + sector += (dirent->size + 2047) / 2048; + } + + if (g_mod_new_len > 0) + { + /* mod.ko */ + cur++; + cur->img_offset = g_mod_override_offset; + cur->override_size = sizeof(ventoy_iso9660_override); + dirent = (ventoy_iso9660_override *)cur->override_data; + dirent->first_sector = (grub_uint32_t)sector; + dirent->size = (grub_uint32_t)g_mod_new_len; + dirent->first_sector_be = grub_swap_bytes32(dirent->first_sector); + dirent->size_be = grub_swap_bytes32(dirent->size); + sector += (dirent->size + 2047) / 2048; + } + + return; +} + +static void ventoy_unix_fill_virt_data( grub_uint64_t isosize, ventoy_chain_head *chain) +{ + grub_uint64_t sector; + grub_uint32_t offset; + grub_uint32_t data_secs; + char *override; + ventoy_virt_chunk *cur; + + override = (char *)chain + chain->virt_chunk_offset; + cur = (ventoy_virt_chunk *)override; + + sector = (isosize + 2047) / 2048; + offset = 2 * sizeof(ventoy_virt_chunk); + + if (g_conf_new_len > 0) + { + ventoy_unix_fill_virt(g_conf_new_data, g_conf_new_len); + } + + if (g_mod_new_len > 0) + { + ventoy_unix_fill_virt(g_mod_new_data, g_mod_new_len); + } + + return; +} + +static int ventoy_freebsd_append_conf(char *buf, const char *isopath) +{ + int pos = 0; + grub_uint32_t i; + grub_disk_t disk; + grub_file_t isofile; + char uuid[64] = {0}; + ventoy_img_chunk *chunk; + grub_uint8_t disk_sig[4]; + grub_uint8_t disk_guid[16]; + + debug("ventoy_freebsd_append_conf %s\n", isopath); + + isofile = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", isopath); + if (!isofile) + { + return 1; + } + + vtoy_ssprintf(buf, pos, "ventoy_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "ventoy_name=\"%s\"\n", g_ko_mod_path); + + disk = isofile->device->disk; + + ventoy_get_disk_guid(isofile->name, disk_guid, disk_sig); + + for (i = 0; i < 16; i++) + { + grub_snprintf(uuid + i * 2, sizeof(uuid), "%02x", disk_guid[i]); + } + + vtoy_ssprintf(buf, pos, "hint.ventoy.0.disksize=%llu\n", (ulonglong)(disk->total_sectors * (1 << disk->log_sector_size))); + vtoy_ssprintf(buf, pos, "hint.ventoy.0.diskuuid=\"%s\"\n", uuid); + vtoy_ssprintf(buf, pos, "hint.ventoy.0.disksignature=%02x%02x%02x%02x\n", disk_sig[0], disk_sig[1], disk_sig[2], disk_sig[3]); + vtoy_ssprintf(buf, pos, "hint.ventoy.0.segnum=%u\n", g_img_chunk_list.cur_chunk); + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + chunk = g_img_chunk_list.chunk + i; + vtoy_ssprintf(buf, pos, "hint.ventoy.%u.seg=\"0x%llx@0x%llx\"\n", + i, (ulonglong)(chunk->disk_start_sector * 512), + (ulonglong)((chunk->disk_end_sector + 1) * 512)); + } + + grub_file_close(isofile); + + return pos; +} + +static int ventoy_dragonfly_append_conf(char *buf, const char *isopath) +{ + int pos = 0; + + debug("ventoy_dragonfly_append_conf %s\n", isopath); + + vtoy_ssprintf(buf, pos, "tmpfs_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "dm_target_linear_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "initrd.img_load=\"%s\"\n", "YES"); + vtoy_ssprintf(buf, pos, "initrd.img_type=\"%s\"\n", "md_image"); + vtoy_ssprintf(buf, pos, "vfs.root.mountfrom=\"%s\"\n", "ufs:md0s0"); + + return pos; +} + +grub_err_t ventoy_cmd_unix_reset(grub_extcmd_context_t ctxt, int argc, char **args) +{ + (void)ctxt; + (void)argc; + (void)args; + + g_conf_new_len = 0; + g_mod_new_len = 0; + g_mod_override_offset = 0; + g_conf_override_offset = 0; + + check_free(g_mod_new_data, grub_free); + check_free(g_conf_new_data, grub_free); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_parse_freenas_ver(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + const char *ver = NULL; + char *buf = NULL; + VTOY_JSON *json = NULL; + + (void)ctxt; + (void)argc; + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + debug("Failed to open file %s\n", args[0]); + return 1; + } + + buf = grub_malloc(file->size + 2); + if (!buf) + { + grub_file_close(file); + return 0; + } + grub_file_read(file, buf, file->size); + buf[file->size] = 0; + + json = vtoy_json_create(); + if (!json) + { + goto end; + } + + if (vtoy_json_parse(json, buf)) + { + goto end; + } + + ver = vtoy_json_get_string_ex(json->pstChild, "Version"); + if (ver) + { + debug("freenas version:<%s>\n", ver); + ventoy_set_env(args[1], ver); + } + else + { + debug("freenas version:<%s>\n", "NOT FOUND"); + grub_env_unset(args[1]); + } + +end: + grub_check_free(buf); + check_free(json, vtoy_json_destroy); + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_freebsd_ver(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_file_t file; + char *buf; + char *start = NULL; + char *nextline = NULL; + + (void)ctxt; + (void)argc; + (void)args; + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[0]); + if (!file) + { + debug("Failed to open file %s\n", args[0]); + return 1; + } + + buf = grub_zalloc(file->size + 2); + if (!buf) + { + grub_file_close(file); + return 0; + } + grub_file_read(file, buf, file->size); + + for (start = buf; start; start = nextline) + { + if (grub_strncmp(start, "USERLAND_VERSION", 16) == 0) + { + nextline = start; + while (*nextline && *nextline != '\r' && *nextline != '\n') + { + nextline++; + } + + *nextline = 0; + break; + } + nextline = ventoy_get_line(start); + } + + if (start) + { + debug("freebsd version:<%s>\n", start); + ventoy_set_env(args[1], start); + } + else + { + debug("freebsd version:<%s>\n", "NOT FOUND"); + grub_env_unset(args[1]); + } + + grub_free(buf); + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_freebsd_ver_elf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int j; + int k; + grub_elf_t elf = NULL; + grub_off_t offset = 0; + grub_uint32_t len = 0; + char *str = NULL; + char *data = NULL; + void *hdr = NULL; + char ver[64] = {0}; + + (void)ctxt; + (void)argc; + (void)args; + + if (argc != 3) + { + debug("Invalid argc %d\n", argc); + return 1; + } + + data = grub_zalloc(8192); + if (!data) + { + goto out; + } + + elf = grub_elf_open(args[0], GRUB_FILE_TYPE_LINUX_INITRD); + if (!elf) + { + debug("Failed to open file %s\n", args[0]); + goto out; + } + + if (args[1][0] == '6') + { + Elf64_Ehdr *e = &(elf->ehdr.ehdr64); + Elf64_Shdr *h; + Elf64_Shdr *s; + Elf64_Shdr *t; + Elf64_Half i; + + h = hdr = grub_zalloc(e->e_shnum * e->e_shentsize); + if (!h) + { + goto out; + } + + debug("read section header %u %u %u\n", e->e_shnum, e->e_shentsize, e->e_shstrndx); + grub_file_seek(elf->file, e->e_shoff); + grub_file_read(elf->file, h, e->e_shnum * e->e_shentsize); + + s = (Elf64_Shdr *)((char *)h + e->e_shstrndx * e->e_shentsize); + str = grub_malloc(s->sh_size + 1); + if (!str) + { + goto out; + } + str[s->sh_size] = 0; + + debug("read string table %u %u\n", (grub_uint32_t)s->sh_offset, (grub_uint32_t)s->sh_size); + grub_file_seek(elf->file, s->sh_offset); + grub_file_read(elf->file, str, s->sh_size); + + for (t = h, i = 0; i < e->e_shnum; i++) + { + if (grub_strcmp(str + t->sh_name, ".data") == 0) + { + offset = t->sh_offset; + len = t->sh_size; + debug("find .data section at %u %u\n", (grub_uint32_t)offset, len); + break; + } + t = (Elf64_Shdr *)((char *)t + e->e_shentsize); + } + } + else + { + Elf32_Ehdr *e = &(elf->ehdr.ehdr32); + Elf32_Shdr *h; + Elf32_Shdr *s; + Elf32_Shdr *t; + Elf32_Half i; + + h = hdr = grub_zalloc(e->e_shnum * e->e_shentsize); + if (!h) + { + goto out; + } + + debug("read section header %u %u %u\n", e->e_shnum, e->e_shentsize, e->e_shstrndx); + grub_file_seek(elf->file, e->e_shoff); + grub_file_read(elf->file, h, e->e_shnum * e->e_shentsize); + + s = (Elf32_Shdr *)((char *)h + e->e_shstrndx * e->e_shentsize); + str = grub_malloc(s->sh_size + 1); + if (!str) + { + goto out; + } + str[s->sh_size] = 0; + + debug("read string table %u %u\n", (grub_uint32_t)s->sh_offset, (grub_uint32_t)s->sh_size); + grub_file_seek(elf->file, s->sh_offset); + grub_file_read(elf->file, str, s->sh_size); + + for (t = h, i = 0; i < e->e_shnum; i++) + { + if (grub_strcmp(str + t->sh_name, ".data") == 0) + { + offset = t->sh_offset; + len = t->sh_size; + debug("find .data section at %u %u\n", (grub_uint32_t)offset, len); + break; + } + t = (Elf32_Shdr *)((char *)t + e->e_shentsize); + } + } + + if (offset == 0 || len == 0) + { + debug(".data section not found %s\n", args[0]); + goto out; + } + + grub_file_seek(elf->file, offset + len - 8192); + grub_file_read(elf->file, data, 8192); + + for (j = 0; j < 8192 - 12; j++) + { + if (grub_strncmp(data + j, "@(#)FreeBSD ", 12) == 0) + { + for (k = j + 12; k < 8192; k++) + { + if (0 == grub_isdigit(data[k]) && data[k] != '.') + { + data[k] = 0; + break; + } + } + + grub_snprintf(ver, sizeof(ver), "%s", data + j + 12); + break; + } + } + + if (ver[0]) + { + k = (int)grub_strtoul(ver, NULL, 10); + debug("freebsd version:<%s> <%d.x>\n", ver, k); + grub_snprintf(ver, sizeof(ver), "%d.x", k); + ventoy_set_env(args[2], ver); + } + else + { + debug("freebsd version:<%s>\n", "NOT FOUND"); + } + +out: + grub_check_free(str); + grub_check_free(hdr); + grub_check_free(data); + check_free(elf, grub_elf_close); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_replace_conf(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t i; + char *data; + grub_uint64_t offset; + grub_file_t file; + const char *confile = NULL; + const char * loader_conf[] = + { + "/boot/loader.conf", + "/boot/defaults/loader.conf", + }; + + (void)ctxt; + + if (argc != 2) + { + debug("Replace conf invalid argc %d\n", argc); + return 1; + } + + for (i = 0; i < sizeof(loader_conf) / sizeof(loader_conf[0]); i++) + { + if (ventoy_get_file_override(loader_conf[i], &offset) == 0) + { + confile = loader_conf[i]; + g_conf_override_offset = offset; + break; + } + } + + if (confile == NULL) + { + debug("Can't find loader.conf file from %u locations\n", i); + return 1; + } + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "(loop)/%s", confile); + if (!file) + { + debug("Failed to open %s \n", confile); + return 1; + } + + debug("old conf file size:%d\n", (int)file->size); + + data = grub_malloc(VTOY_MAX_SCRIPT_BUF); + if (!data) + { + grub_file_close(file); + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + g_conf_new_data = data; + g_conf_new_len = (int)file->size; + + if (grub_strcmp(args[0], "FreeBSD") == 0) + { + g_conf_new_len += ventoy_freebsd_append_conf(data + file->size, args[1]); + } + else if (grub_strcmp(args[0], "DragonFly") == 0) + { + g_conf_new_len += ventoy_dragonfly_append_conf(data + file->size, args[1]); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_replace_ko(grub_extcmd_context_t ctxt, int argc, char **args) +{ + char *data; + grub_uint64_t offset; + grub_file_t file; + + (void)ctxt; + + if (argc != 2) + { + debug("Replace ko invalid argc %d\n", argc); + return 1; + } + + debug("replace ko %s\n", args[0]); + + if (ventoy_get_file_override(args[0], &offset) == 0) + { + grub_snprintf(g_ko_mod_path, sizeof(g_ko_mod_path), "%s", args[0]); + g_mod_override_offset = offset; + } + else + { + debug("Can't find replace ko file from %s\n", args[0]); + return 1; + } + + file = ventoy_grub_file_open(GRUB_FILE_TYPE_LINUX_INITRD, "%s", args[1]); + if (!file) + { + debug("Failed to open %s \n", args[1]); + return 1; + } + + debug("new ko file size:%d\n", (int)file->size); + + data = grub_malloc(file->size); + if (!data) + { + debug("Failed to alloc memory for new ko %d\n", (int)file->size); + grub_file_close(file); + return 1; + } + + grub_file_read(file, data, file->size); + grub_file_close(file); + + g_mod_new_data = data; + g_mod_new_len = (int)file->size; + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_fill_image_desc(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + grub_uint8_t *byte; + grub_uint32_t memsize; + ventoy_image_desc *desc; + grub_uint8_t flag[32] = { + 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF + }; + + (void)ctxt; + (void)argc; + (void)args; + + debug("ventoy_cmd_unix_fill_image_desc %p\n", g_mod_new_data); + + if (!g_mod_new_data) + { + goto end; + } + + byte = (grub_uint8_t *)g_mod_new_data; + for (i = 0; i < g_mod_new_len - 32; i += 16) + { + if (byte[i] == 0xFF && byte[i + 1] == 0xEE) + { + if (grub_memcmp(flag, byte + i, 32) == 0) + { + debug("Find position flag at %d(0x%x)\n", i, i); + break; + } + } + } + + if (i >= g_mod_new_len - 32) + { + debug("Failed to find position flag %d\n", i); + goto end; + } + + desc = (ventoy_image_desc *)(byte + i); + desc->disk_size = g_ventoy_disk_size; + desc->part1_size = g_ventoy_disk_part_size[0]; + grub_memcpy(desc->disk_uuid, g_ventoy_part_info->MBR.BootCode + 0x180, 16); + grub_memcpy(desc->disk_signature, g_ventoy_part_info->MBR.BootCode + 0x1B8, 4); + + desc->img_chunk_count = g_img_chunk_list.cur_chunk; + memsize = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + debug("image chunk count:%u memsize:%u\n", desc->img_chunk_count, memsize); + + if (memsize >= VTOY_SIZE_1MB * 8) + { + grub_printf("image chunk count:%u memsize:%u too big\n", desc->img_chunk_count, memsize); + goto end; + } + + grub_memcpy(desc + 1, g_img_chunk_list.chunk, memsize); + +end: + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_gzip_newko(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int newlen; + grub_uint8_t *buf; + + (void)ctxt; + (void)argc; + (void)args; + + debug("ventoy_cmd_unix_gzip_newko %p\n", g_mod_new_data); + + if (!g_mod_new_data) + { + goto end; + } + + buf = grub_malloc(g_mod_new_len); + if (!buf) + { + goto end; + } + + newlen = ventoy_gzip_compress(g_mod_new_data, g_mod_new_len, buf, g_mod_new_len); + + grub_free(g_mod_new_data); + + debug("gzip org len:%d newlen:%d\n", g_mod_new_len, newlen); + + g_mod_new_data = (char *)buf; + g_mod_new_len = newlen; + +end: + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_unix_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ventoy_compatible = 0; + grub_uint32_t size = 0; + grub_uint64_t isosize = 0; + grub_uint32_t boot_catlog = 0; + grub_uint32_t img_chunk_size = 0; + grub_uint32_t override_count = 0; + grub_uint32_t override_size = 0; + grub_uint32_t virt_chunk_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + const char *compatible; + ventoy_chain_head *chain; + char envbuf[64]; + + (void)ctxt; + (void)argc; + + compatible = grub_env_get("ventoy_compatible"); + if (compatible && compatible[0] == 'Y') + { + ventoy_compatible = 1; + } + + if (NULL == g_img_chunk_list.chunk) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return 1; + } + + isosize = file->size; + + boot_catlog = ventoy_get_iso_boot_catlog(file); + if (boot_catlog) + { + if (ventoy_is_efi_os() && (!ventoy_has_efi_eltorito(file, boot_catlog))) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + } + else + { + if (ventoy_is_efi_os()) + { + grub_env_set("LoadIsoEfiDriver", "on"); + } + else + { + return grub_error(GRUB_ERR_BAD_ARGUMENT, "File %s is not bootable", args[0]); + } + } + + img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + if (ventoy_compatible) + { + size = sizeof(ventoy_chain_head) + img_chunk_size; + } + else + { + override_count = ventoy_unix_get_override_chunk_count(); + override_size = override_count * sizeof(ventoy_override_chunk); + + virt_chunk_size = ventoy_unix_get_virt_chunk_size(); + size = sizeof(ventoy_chain_head) + img_chunk_size + override_size + virt_chunk_size; + } + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = grub_malloc(size); + if (!chain) + { + grub_printf("Failed to alloc chain memory size %u\n", size); + grub_file_close(file); + return 1; + } + + grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); + grub_env_set("vtoy_chain_mem_addr", envbuf); + grub_snprintf(envbuf, sizeof(envbuf), "%u", size); + grub_env_set("vtoy_chain_mem_size", envbuf); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_linux; + ventoy_fill_os_param(file, &(chain->os_param)); + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + chain->real_img_size_in_bytes = file->size; + chain->virt_img_size_in_bytes = (file->size + 2047) / 2048 * 2048; + chain->boot_catalog = boot_catlog; + + if (!ventoy_is_efi_os()) + { + grub_file_seek(file, boot_catlog * 2048); + grub_file_read(file, chain->boot_catalog_sector, sizeof(chain->boot_catalog_sector)); + } + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_img_chunk_list.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size); + + if (ventoy_compatible) + { + return 0; + } + + /* part 4: override chunk */ + chain->override_chunk_offset = chain->img_chunk_offset + img_chunk_size; + chain->override_chunk_num = override_count; + ventoy_unix_fill_override_data(isosize, (char *)chain + chain->override_chunk_offset); + + /* part 5: virt chunk */ + chain->virt_chunk_offset = chain->override_chunk_offset + override_size; + chain->virt_chunk_num = ventoy_unix_get_virt_chunk_count(); + ventoy_unix_fill_virt_data(isosize, chain); + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c new file mode 100644 index 00000000..b37cf0ac --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_vhd.c @@ -0,0 +1,732 @@ +/****************************************************************************** + * ventoy_vhd.c + * + * Copyright (c) 2020, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef GRUB_MACHINE_EFI +#include +#endif +#include +#include "ventoy_def.h" + +GRUB_MOD_LICENSE ("GPLv3+"); + +static int g_vhdboot_isolen = 0; +static char *g_vhdboot_totbuf = NULL; +static char *g_vhdboot_isobuf = NULL; +static grub_uint64_t g_img_trim_head_secnum = 0; + +static int ventoy_vhd_find_bcd(int *bcdoffset, int *bcdlen, const char *path) +{ + grub_uint32_t offset; + grub_file_t file; + char cmdbuf[128]; + + grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback vhdiso mem:0x%lx:size:%d", (ulong)g_vhdboot_isobuf, g_vhdboot_isolen); + + grub_script_execute_sourcecode(cmdbuf); + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "(vhdiso)%s", path); + if (!file) + { + return 1; + } + + grub_file_read(file, &offset, 4); + offset = (grub_uint32_t)grub_iso9660_get_last_read_pos(file); + + *bcdoffset = (int)offset; + *bcdlen = (int)file->size; + + debug("vhdiso bcd file offset:%d len:%d\n", *bcdoffset, *bcdlen); + + grub_file_close(file); + + grub_script_execute_sourcecode("loopback -d vhdiso"); + + return 0; +} + +static int ventoy_vhd_patch_path(char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2, + int bcdoffset, int bcdlen) +{ + int i; + int cnt = 0; + char *pos; + grub_size_t pathlen; + const char *plat; + char *newpath = NULL; + grub_uint16_t *unicode_path; + const grub_uint8_t winloadexe[] = + { + 0x77, 0x00, 0x69, 0x00, 0x6E, 0x00, 0x6C, 0x00, 0x6F, 0x00, 0x61, 0x00, 0x64, 0x00, 0x2E, 0x00, + 0x65, 0x00, 0x78, 0x00, 0x65, 0x00 + }; + + while ((*vhdpath) != '/') + { + vhdpath++; + } + + pathlen = sizeof(grub_uint16_t) * (grub_strlen(vhdpath) + 1); + debug("unicode path for <%s> len:%d\n", vhdpath, (int)pathlen); + + unicode_path = grub_zalloc(pathlen); + if (!unicode_path) + { + return 0; + } + + plat = grub_env_get("grub_platform"); + + if (plat && (plat[0] == 'e')) /* UEFI */ + { + pos = g_vhdboot_isobuf + bcdoffset; + + /* winload.exe ==> winload.efi */ + for (i = 0; i + (int)sizeof(winloadexe) < bcdlen; i++) + { + if (*((grub_uint32_t *)(pos + i)) == 0x00690077 && + grub_memcmp(pos + i, winloadexe, sizeof(winloadexe)) == 0) + { + pos[i + sizeof(winloadexe) - 4] = 0x66; + pos[i + sizeof(winloadexe) - 2] = 0x69; + cnt++; + } + } + + debug("winload patch %d times\n", cnt); + } + + newpath = grub_strdup(vhdpath); + for (pos = newpath; *pos; pos++) + { + if (*pos == '/') + { + *pos = '\\'; + } + } + + grub_utf8_to_utf16(unicode_path, pathlen, (grub_uint8_t *)newpath, -1, NULL); + grub_memcpy(patch1->vhd_file_path, unicode_path, pathlen); + grub_memcpy(patch2->vhd_file_path, unicode_path, pathlen); + + grub_free(newpath); + return 0; +} + +static int ventoy_vhd_read_parttbl(const char *filename, ventoy_gpt_info *gpt, int *index) +{ + int i; + int ret = 1; + grub_uint64_t start; + grub_file_t file = NULL; + grub_disk_t disk = NULL; + grub_uint8_t zeroguid[16] = {0}; + + file = grub_file_open(filename, VENTOY_FILE_TYPE); + if (!file) + { + goto end; + } + + disk = grub_disk_open(file->device->disk->name); + if (!disk) + { + goto end; + } + + grub_disk_read(disk, 0, 0, sizeof(ventoy_gpt_info), gpt); + + start = file->device->disk->partition->start; + + if (grub_memcmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + debug("GPT part start: %llu\n", (ulonglong)start); + for (i = 0; i < 128; i++) + { + if (grub_memcmp(gpt->PartTbl[i].PartGuid, zeroguid, 16)) + { + if (start == gpt->PartTbl[i].StartLBA) + { + *index = i; + break; + } + } + } + } + else + { + debug("MBR part start: %llu\n", (ulonglong)start); + for (i = 0; i < 4; i++) + { + if ((grub_uint32_t)start == gpt->MBR.PartTbl[i].StartSectorId) + { + *index = i; + break; + } + } + } + + ret = 0; + +end: + check_free(file, grub_file_close); + check_free(disk, grub_disk_close); + + return ret; +} + +static int ventoy_vhd_patch_disk(const char *vhdpath, ventoy_patch_vhd *patch1, ventoy_patch_vhd *patch2) +{ + int partIndex = 0; + grub_uint64_t offset = 0; + char efipart[16] = {0}; + ventoy_gpt_info *gpt = NULL; + + if (vhdpath[0] == '/') + { + gpt = g_ventoy_part_info; + partIndex = 0; + debug("This is Ventoy ISO partIndex %d %s\n", partIndex, vhdpath); + } + else + { + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + ventoy_vhd_read_parttbl(vhdpath, gpt, &partIndex); + debug("This is HDD partIndex %d %s\n", partIndex, vhdpath); + } + + grub_memcpy(efipart, gpt->Head.Signature, sizeof(gpt->Head.Signature)); + + grub_memset(patch1, 0, OFFSET_OF(ventoy_patch_vhd, vhd_file_path)); + grub_memset(patch2, 0, OFFSET_OF(ventoy_patch_vhd, vhd_file_path)); + + if (grub_strncmp(efipart, "EFI PART", 8) == 0) + { + ventoy_debug_dump_guid("GPT disk GUID: ", gpt->Head.DiskGuid); + ventoy_debug_dump_guid("GPT partIndex GUID: ", gpt->PartTbl[partIndex].PartGuid); + + grub_memcpy(patch1->disk_signature_or_guid, gpt->Head.DiskGuid, 16); + grub_memcpy(patch1->part_offset_or_guid, gpt->PartTbl[partIndex].PartGuid, 16); + grub_memcpy(patch2->disk_signature_or_guid, gpt->Head.DiskGuid, 16); + grub_memcpy(patch2->part_offset_or_guid, gpt->PartTbl[partIndex].PartGuid, 16); + + patch1->part_type = patch2->part_type = 0; + } + else + { + offset = gpt->MBR.PartTbl[partIndex].StartSectorId; + offset *= 512; + + debug("MBR disk signature: %02x%02x%02x%02x Part(%d) offset:%llu\n", + gpt->MBR.BootCode[0x1b8 + 0], gpt->MBR.BootCode[0x1b8 + 1], + gpt->MBR.BootCode[0x1b8 + 2], gpt->MBR.BootCode[0x1b8 + 3], + partIndex + 1, offset); + + grub_memcpy(patch1->part_offset_or_guid, &offset, 8); + grub_memcpy(patch2->part_offset_or_guid, &offset, 8); + + grub_memcpy(patch1->disk_signature_or_guid, gpt->MBR.BootCode + 0x1b8, 4); + grub_memcpy(patch2->disk_signature_or_guid, gpt->MBR.BootCode + 0x1b8, 4); + + patch1->part_type = patch2->part_type = 1; + } + + if (gpt != g_ventoy_part_info) + { + grub_free(gpt); + } + + return 0; +} + +static int ventoy_find_vhdpatch_offset(int bcdoffset, int bcdlen, int *offset) +{ + int i; + int cnt = 0; + grub_uint8_t *buf = (grub_uint8_t *)(g_vhdboot_isobuf + bcdoffset); + grub_uint8_t magic[16] = { + 0x5C, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00, 0x58, 0x00 + }; + + for (i = 0; i < bcdlen - 16 && cnt < 2; i++) + { + if (*(grub_uint32_t *)(buf + i) == 0x0058005C) + { + if (grub_memcmp(magic, buf + i, 16) == 0) + { + *offset++ = i - (int)OFFSET_OF(ventoy_patch_vhd, vhd_file_path); + cnt++; + } + } + } + + return 0; +} + +grub_err_t ventoy_cmd_patch_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int rc; + int bcdoffset, bcdlen; + int patchoffset[2]; + ventoy_patch_vhd *patch1; + ventoy_patch_vhd *patch2; + char envbuf[64]; + + (void)ctxt; + (void)argc; + + grub_env_unset("vtoy_vhd_buf_addr"); + + debug("patch vhd <%s>\n", args[0]); + + if ((!g_vhdboot_enable) || (!g_vhdboot_totbuf)) + { + debug("vhd boot not ready %d %p\n", g_vhdboot_enable, g_vhdboot_totbuf); + return 0; + } + + rc = ventoy_vhd_find_bcd(&bcdoffset, &bcdlen, "/boot/bcd"); + if (rc) + { + debug("failed to get bcd location %d\n", rc); + } + else + { + ventoy_find_vhdpatch_offset(bcdoffset, bcdlen, patchoffset); + patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[0]); + patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[1]); + + debug("Find /boot/bcd (%d %d) now patch it (offset: 0x%x 0x%x) ...\n", + bcdoffset, bcdlen, patchoffset[0], patchoffset[1]); + ventoy_vhd_patch_disk(args[0], patch1, patch2); + ventoy_vhd_patch_path(args[0], patch1, patch2, bcdoffset, bcdlen); + } + + rc = ventoy_vhd_find_bcd(&bcdoffset, &bcdlen, "/boot/BCD"); + if (rc) + { + debug("No file /boot/BCD \n"); + } + else + { + ventoy_find_vhdpatch_offset(bcdoffset, bcdlen, patchoffset); + patch1 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[0]); + patch2 = (ventoy_patch_vhd *)(g_vhdboot_isobuf + bcdoffset + patchoffset[1]); + + debug("Find /boot/BCD (%d %d) now patch it (offset: 0x%x 0x%x) ...\n", + bcdoffset, bcdlen, patchoffset[0], patchoffset[1]); + ventoy_vhd_patch_disk(args[0], patch1, patch2); + ventoy_vhd_patch_path(args[0], patch1, patch2, bcdoffset, bcdlen); + } + + /* set buffer and size */ +#ifdef GRUB_MACHINE_EFI + grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_totbuf); + grub_env_set("vtoy_vhd_buf_addr", envbuf); + grub_snprintf(envbuf, sizeof(envbuf), "%d", (int)(g_vhdboot_isolen + sizeof(ventoy_chain_head))); + grub_env_set("vtoy_vhd_buf_size", envbuf); +#else + grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (ulong)g_vhdboot_isobuf); + grub_env_set("vtoy_vhd_buf_addr", envbuf); + grub_snprintf(envbuf, sizeof(envbuf), "%d", g_vhdboot_isolen); + grub_env_set("vtoy_vhd_buf_size", envbuf); +#endif + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_load_vhdboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int buflen; + grub_file_t file; + + (void)ctxt; + (void)argc; + + g_vhdboot_enable = 0; + grub_check_free(g_vhdboot_totbuf); + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 0; + } + + debug("load vhd boot: <%s> <%lu>\n", args[0], (ulong)file->size); + + if (file->size < VTOY_SIZE_1KB * 32) + { + grub_file_close(file); + return 0; + } + + g_vhdboot_isolen = (int)file->size; + + buflen = (int)(file->size + sizeof(ventoy_chain_head)); + +#ifdef GRUB_MACHINE_EFI + g_vhdboot_totbuf = (char *)grub_efi_allocate_iso_buf(buflen); +#else + g_vhdboot_totbuf = (char *)grub_malloc(buflen); +#endif + + if (!g_vhdboot_totbuf) + { + grub_file_close(file); + return 0; + } + + g_vhdboot_isobuf = g_vhdboot_totbuf + sizeof(ventoy_chain_head); + + grub_file_read(file, g_vhdboot_isobuf, file->size); + grub_file_close(file); + + g_vhdboot_enable = 1; + + return 0; +} + +static int ventoy_raw_trim_head(grub_uint64_t offset) +{ + grub_uint32_t i; + grub_uint32_t memsize; + grub_uint32_t imgstart = 0; + grub_uint32_t imgsecs = 0; + grub_uint64_t sectors = 0; + grub_uint64_t cursecs = 0; + grub_uint64_t delta = 0; + + if ((!g_img_chunk_list.chunk) || (!offset)) + { + debug("image chunk not ready %p %lu\n", g_img_chunk_list.chunk, (ulong)offset); + return 0; + } + + debug("image trim head %lu\n", (ulong)offset); + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + cursecs = g_img_chunk_list.chunk[i].disk_end_sector + 1 - g_img_chunk_list.chunk[i].disk_start_sector; + sectors += cursecs; + if (sectors >= offset) + { + delta = cursecs - (sectors - offset); + break; + } + } + + if (sectors < offset || i >= g_img_chunk_list.cur_chunk) + { + debug("Invalid size %lu %lu\n", (ulong)sectors, (ulong)offset); + return 0; + } + + if (sectors == offset) + { + memsize = (g_img_chunk_list.cur_chunk - (i + 1)) * sizeof(ventoy_img_chunk); + grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i + 1, memsize); + g_img_chunk_list.cur_chunk -= (i + 1); + } + else + { + g_img_chunk_list.chunk[i].disk_start_sector += delta; + g_img_chunk_list.chunk[i].img_start_sector += (grub_uint32_t)(delta / 4); + + if (i > 0) + { + memsize = (g_img_chunk_list.cur_chunk - i) * sizeof(ventoy_img_chunk); + grub_memmove(g_img_chunk_list.chunk, g_img_chunk_list.chunk + i, memsize); + g_img_chunk_list.cur_chunk -= i; + } + } + + for (i = 0; i < g_img_chunk_list.cur_chunk; i++) + { + imgsecs = g_img_chunk_list.chunk[i].img_end_sector + 1 - g_img_chunk_list.chunk[i].img_start_sector; + g_img_chunk_list.chunk[i].img_start_sector = imgstart; + g_img_chunk_list.chunk[i].img_end_sector = imgstart + (imgsecs - 1); + imgstart += imgsecs; + } + + return 0; +} + +grub_err_t ventoy_cmd_get_vtoy_type(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int i; + int altboot = 0; + int offset = -1; + grub_file_t file; + grub_uint8_t data = 0; + vhd_footer_t vhdfoot; + VDIPREHEADER vdihdr; + char type[16] = {0}; + ventoy_gpt_info *gpt; + + (void)ctxt; + + g_img_trim_head_secnum = 0; + + if (argc != 4) + { + return 0; + } + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + debug("Failed to open file %s\n", args[0]); + return 0; + } + + grub_snprintf(type, sizeof(type), "unknown"); + + grub_file_seek(file, file->size - 512); + grub_file_read(file, &vhdfoot, sizeof(vhdfoot)); + + if (grub_strncmp(vhdfoot.cookie, "conectix", 8) == 0) + { + offset = 0; + grub_snprintf(type, sizeof(type), "vhd%u", grub_swap_bytes32(vhdfoot.disktype)); + } + else + { + grub_file_seek(file, 0); + grub_file_read(file, &vdihdr, sizeof(vdihdr)); + if (vdihdr.u32Signature == VDI_IMAGE_SIGNATURE && + grub_strncmp(vdihdr.szFileInfo, VDI_IMAGE_FILE_INFO, grub_strlen(VDI_IMAGE_FILE_INFO)) == 0) + { + offset = 2 * 1048576; + g_img_trim_head_secnum = offset / 512; + grub_snprintf(type, sizeof(type), "vdi"); + } + else + { + offset = 0; + grub_snprintf(type, sizeof(type), "raw"); + } + } + + grub_env_set(args[1], type); + debug("<%s> vtoy type: <%s> offset:%d\n", args[0], type, offset); + + if (offset >= 0) + { + gpt = grub_zalloc(sizeof(ventoy_gpt_info)); + if (!gpt) + { + grub_env_set(args[1], "unknown"); + goto end; + } + + grub_file_seek(file, offset); + grub_file_read(file, gpt, sizeof(ventoy_gpt_info)); + + if (gpt->MBR.Byte55 != 0x55 || gpt->MBR.ByteAA != 0xAA) + { + grub_env_set(args[1], "unknown"); + debug("invalid mbr signature: 0x%x 0x%x\n", gpt->MBR.Byte55, gpt->MBR.ByteAA); + goto end; + } + + if (grub_memcmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + grub_env_set(args[2], "gpt"); + debug("part type: %s\n", "GPT"); + + if (gpt->MBR.PartTbl[0].FsFlag == 0xEE) + { + for (i = 0; i < 128; i++) + { + if (grub_memcmp(gpt->PartTbl[i].PartType, "Hah!IdontNeedEFI", 16) == 0) + { + debug("part %d is grub_bios part\n", i); + altboot = 1; + grub_env_set(args[3], "1"); + break; + } + else if (gpt->PartTbl[i].LastLBA == 0) + { + break; + } + } + } + + if (!altboot) + { + if (gpt->MBR.BootCode[92] == 0x22) + { + grub_file_seek(file, offset + 17908); + grub_file_read(file, &data, 1); + if (data == 0x23) + { + altboot = 1; + grub_env_set(args[3], "1"); + } + else + { + debug("offset data=0x%x\n", data); + } + } + else + { + debug("BootCode: 0x%x\n", gpt->MBR.BootCode[92]); + } + } + } + else + { + grub_env_set(args[2], "mbr"); + debug("part type: %s\n", "MBR"); + + for (i = 0; i < 4; i++) + { + if (gpt->MBR.PartTbl[i].FsFlag == 0xEF) + { + debug("part %d is esp part in MBR mode\n", i); + altboot = 1; + grub_env_set(args[3], "1"); + break; + } + } + } + } + else + { + debug("part type: %s\n", "xxx"); + } + +end: + grub_check_free(gpt); + grub_file_close(file); + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + +grub_err_t ventoy_cmd_raw_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t size = 0; + grub_uint32_t img_chunk_size = 0; + grub_file_t file; + grub_disk_t disk; + const char *pLastChain = NULL; + ventoy_chain_head *chain; + char envbuf[64]; + + (void)ctxt; + (void)argc; + + if (NULL == g_img_chunk_list.chunk) + { + grub_printf("ventoy not ready\n"); + return 1; + } + + if (g_img_trim_head_secnum > 0) + { + ventoy_raw_trim_head(g_img_trim_head_secnum); + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + return 1; + } + + img_chunk_size = g_img_chunk_list.cur_chunk * sizeof(ventoy_img_chunk); + + size = sizeof(ventoy_chain_head) + img_chunk_size; + + pLastChain = grub_env_get("vtoy_chain_mem_addr"); + if (pLastChain) + { + chain = (ventoy_chain_head *)grub_strtoul(pLastChain, NULL, 16); + if (chain) + { + debug("free last chain memory %p\n", chain); + grub_free(chain); + } + } + + chain = grub_malloc(size); + if (!chain) + { + grub_printf("Failed to alloc chain memory size %u\n", size); + grub_file_close(file); + return 1; + } + + grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)chain); + grub_env_set("vtoy_chain_mem_addr", envbuf); + grub_snprintf(envbuf, sizeof(envbuf), "%u", size); + grub_env_set("vtoy_chain_mem_size", envbuf); + + grub_env_export("vtoy_chain_mem_addr"); + grub_env_export("vtoy_chain_mem_size"); + + grub_memset(chain, 0, sizeof(ventoy_chain_head)); + + /* part 1: os parameter */ + g_ventoy_chain_type = ventoy_chain_linux; + ventoy_fill_os_param(file, &(chain->os_param)); + + /* part 2: chain head */ + disk = file->device->disk; + chain->disk_drive = disk->id; + chain->disk_sector_size = (1 << disk->log_sector_size); + + chain->real_img_size_in_bytes = file->size; + if (g_img_trim_head_secnum > 0) + { + chain->real_img_size_in_bytes -= g_img_trim_head_secnum * 512; + } + + chain->virt_img_size_in_bytes = chain->real_img_size_in_bytes; + chain->boot_catalog = 0; + + /* part 3: image chunk */ + chain->img_chunk_offset = sizeof(ventoy_chain_head); + chain->img_chunk_num = g_img_chunk_list.cur_chunk; + grub_memcpy((char *)chain + chain->img_chunk_offset, g_img_chunk_list.chunk, img_chunk_size); + + grub_file_seek(file, g_img_trim_head_secnum * 512); + grub_file_read(file, chain->boot_catalog_sector, 512); + + grub_file_close(file); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c index 76975dbf..9f7615ce 100644 --- a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/ventoy_windows.c @@ -51,6 +51,7 @@ static grub_uint32_t g_suppress_wincd_override_data = 0; grub_uint8_t g_temp_buf[512]; grub_ssize_t lzx_decompress ( const void *data, grub_size_t len, void *buf ); +grub_ssize_t xca_decompress ( const void *data, grub_size_t len, void *buf ); static wim_patch *ventoy_find_wim_patch(const char *path) { @@ -313,6 +314,90 @@ static int ventoy_is_pe64(grub_uint8_t *buffer) return 0; } +grub_err_t ventoy_cmd_is_pe64(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int ret = 1; + grub_file_t file; + grub_uint8_t buf[512]; + + (void)ctxt; + (void)argc; + + file = grub_file_open(args[0], VENTOY_FILE_TYPE); + if (!file) + { + return 1; + } + + grub_memset(buf, 0, 512); + grub_file_read(file, buf, 512); + if (ventoy_is_pe64(buf)) + { + debug("%s is PE64\n", args[0]); + ret = 0; + } + else + { + debug("%s is PE32\n", args[0]); + } + grub_file_close(file); + + return ret; +} + +grub_err_t ventoy_cmd_sel_wimboot(grub_extcmd_context_t ctxt, int argc, char **args) +{ + int size; + char *buf = NULL; + char configfile[128]; + + (void)ctxt; + (void)argc; + (void)args; + + debug("select wimboot argc:%d\n", argc); + + buf = (char *)grub_malloc(8192); + if (!buf) + { + return 0; + } + + size = (int)grub_snprintf(buf, 8192, + "menuentry \"Windows Setup (32-bit)\" {\n" + " set vtoy_wimboot_sel=32\n" + "}\n" + "menuentry \"Windows Setup (64-bit)\" {\n" + " set vtoy_wimboot_sel=64\n" + "}\n" + ); + buf[size] = 0; + + g_ventoy_menu_esc = 1; + g_ventoy_suppress_esc = 1; + + grub_snprintf(configfile, sizeof(configfile), "configfile mem:0x%llx:size:%d", (ulonglong)(ulong)buf, size); + grub_script_execute_sourcecode(configfile); + + g_ventoy_menu_esc = 0; + g_ventoy_suppress_esc = 0; + + grub_free(buf); + + if (g_ventoy_last_entry == 0) + { + debug("last entry=%d %s=32\n", g_ventoy_last_entry, args[0]); + grub_env_set(args[0], "32"); + } + else + { + debug("last entry=%d %s=64\n", g_ventoy_last_entry, args[0]); + grub_env_set(args[0], "64"); + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char **args) { wim_patch *next = NULL; @@ -332,7 +417,7 @@ grub_err_t ventoy_cmd_wimdows_reset(grub_extcmd_context_t ctxt, int argc, char * g_wim_patch_head = NULL; g_wim_total_patch_count = 0; g_wim_valid_patch_count = 0; - + return 0; } @@ -427,7 +512,7 @@ static int ventoy_get_override_info(grub_file_t file, wim_tail *wim_data) return 0; } -static int ventoy_read_resource(grub_file_t fp, wim_resource_header *head, void **buffer) +static int ventoy_read_resource(grub_file_t fp, wim_header *wimhdr, wim_resource_header *head, void **buffer) { int decompress_len = 0; int total_decompress = 0; @@ -463,6 +548,8 @@ static int ventoy_read_resource(grub_file_t fp, wim_resource_header *head, void chunk_num = (head->raw_size + WIM_CHUNK_LEN - 1) / WIM_CHUNK_LEN; cur_offset = (chunk_num - 1) * 4; chunk_offset = (grub_uint32_t *)buffer_compress; + + //debug("%llu %llu chunk_num=%lu", (ulonglong)head->size_in_wim, (ulonglong)head->raw_size, chunk_num); cur_dst = buffer_decompress; @@ -477,7 +564,14 @@ static int ventoy_read_resource(grub_file_t fp, wim_resource_header *head, void } else { - decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + if (wimhdr->flags & FLAG_HEADER_COMPRESS_XPRESS) + { + decompress_len = (int)xca_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + } + else + { + decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, chunk_size, cur_dst); + } } //debug("chunk_size:%u decompresslen:%d\n", chunk_size, decompress_len); @@ -499,11 +593,20 @@ static int ventoy_read_resource(grub_file_t fp, wim_resource_header *head, void } else { - decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + if (wimhdr->flags & FLAG_HEADER_COMPRESS_XPRESS) + { + decompress_len = (int)xca_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + } + else + { + decompress_len = (int)lzx_decompress(buffer_compress + cur_offset, head->size_in_wim - cur_offset, cur_dst); + } } - + cur_dst += decompress_len; total_decompress += decompress_len; + + //debug("last chunk_size:%u decompresslen:%d tot:%d\n", last_chunk_size, decompress_len, total_decompress); if (cur_dst != buffer_decompress + head->raw_size) { @@ -549,35 +652,31 @@ static wim_directory_entry * search_full_wim_dirent { subdir = (wim_directory_entry *)((char *)meta_data + search->subdir); search = search_wim_dirent(subdir, *path); - if (!search) - { - debug("%s search failed\n", *path); - } - path++; } + return search; } static wim_directory_entry * search_replace_wim_dirent(void *meta_data, wim_directory_entry *dir) { wim_directory_entry *wim_dirent = NULL; + const char *pecmd_path[] = { "Windows", "System32", "pecmd.exe", NULL }; const char *winpeshl_path[] = { "Windows", "System32", "winpeshl.exe", NULL }; - //const char *pecmd_path[] = { "Windows", "System32", "PECMD.exe", NULL }; + + wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path); + debug("search pecmd.exe %p\n", wim_dirent); + if (wim_dirent) + { + return wim_dirent; + } wim_dirent = search_full_wim_dirent(meta_data, dir, winpeshl_path); + debug("search winpeshl.exe %p\n", wim_dirent); if (wim_dirent) { return wim_dirent; } - - #if 0 - wim_dirent = search_full_wim_dirent(meta_data, dir, pecmd_path); - if (wim_dirent) - { - return wim_dirent; - } - #endif return NULL; } @@ -623,6 +722,42 @@ static wim_lookup_entry * ventoy_find_meta_entry(wim_header *header, wim_lookup_ return NULL; } +static grub_uint64_t ventoy_get_stream_len(wim_directory_entry *dir) +{ + grub_uint16_t i; + grub_uint64_t offset = 0; + wim_stream_entry *stream = (wim_stream_entry *)((char *)dir + dir->len); + + for (i = 0; i < dir->streams; i++) + { + offset += stream->len; + stream = (wim_stream_entry *)((char *)stream + stream->len); + } + + return offset; +} + +static int ventoy_update_stream_hash(wim_patch *patch, wim_directory_entry *dir) +{ + grub_uint16_t i; + grub_uint64_t offset = 0; + wim_stream_entry *stream = (wim_stream_entry *)((char *)dir + dir->len); + + for (i = 0; i < dir->streams; i++) + { + if (grub_memcmp(stream->hash.sha1, patch->old_hash.sha1, sizeof(wim_hash)) == 0) + { + debug("find target stream %u, name_len:%u upadte hash\n", i, stream->name_len); + grub_memcpy(stream->hash.sha1, &(patch->wim_data.bin_hash), sizeof(wim_hash)); + } + + offset += stream->len; + stream = (wim_stream_entry *)((char *)stream + stream->len); + } + + return offset; +} + static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directory_entry *dir) { if ((meta_data == NULL) || (dir == NULL)) @@ -647,8 +782,16 @@ static int ventoy_update_all_hash(wim_patch *patch, void *meta_data, wim_directo { ventoy_update_all_hash(patch, meta_data, (wim_directory_entry *)((char *)meta_data + dir->subdir)); } - - dir = (wim_directory_entry *)((char *)dir + dir->len); + + if (dir->streams) + { + ventoy_update_stream_hash(patch, dir); + dir = (wim_directory_entry *)((char *)dir + dir->len + ventoy_get_stream_len(dir)); + } + else + { + dir = (wim_directory_entry *)((char *)dir + dir->len); + } } while (dir->len >= sizeof(wim_directory_entry)); return 0; @@ -709,6 +852,24 @@ int ventoy_fill_windows_rtdata(void *buf, char *isopath) { debug("auto install script skipped or not configed %s\n", pos); } + + script = (char *)ventoy_plugin_get_injection(pos); + if (script) + { + if (ventoy_check_file_exist("%s%s", ventoy_get_env("vtoy_iso_part"), script)) + { + debug("injection archive <%s> OK\n", script); + grub_snprintf(data->injection_archive, sizeof(data->injection_archive) - 1, "%s", script); + } + else + { + debug("injection archive <%s> NOT exist\n", script); + } + } + else + { + debug("injection archive not configed %s\n", pos); + } return 0; } @@ -745,7 +906,14 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath) grub_crypto_hash(GRUB_MD_SHA1, wim_data->bin_hash.sha1, wim_data->jump_bin_data, wim_data->bin_raw_len); security = (wim_security_header *)wim_data->new_meta_data; - rootdir = (wim_directory_entry *)(wim_data->new_meta_data + ((security->len + 7) & 0xFFFFFFF8U)); + if (security->len > 0) + { + rootdir = (wim_directory_entry *)(wim_data->new_meta_data + ((security->len + 7) & 0xFFFFFFF8U)); + } + else + { + rootdir = (wim_directory_entry *)(wim_data->new_meta_data + 8); + } /* update all winpeshl.exe dirent entry's hash */ ventoy_update_all_hash(node, wim_data->new_meta_data, rootdir); @@ -778,6 +946,7 @@ static int ventoy_update_before_chain(ventoy_os_param *param, char *isopath) static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) { int rc; + grub_uint16_t i; grub_file_t file; grub_uint32_t exe_len; grub_uint8_t *exe_data = NULL; @@ -786,6 +955,7 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) wim_security_header *security = NULL; wim_directory_entry *rootdir = NULL; wim_directory_entry *search = NULL; + wim_stream_entry *stream = NULL; wim_header *head = &(patch->wim_data.wim_header); wim_tail *wim_data = &patch->wim_data; @@ -813,14 +983,14 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) return 1; } - if (head->flags & FLAG_HEADER_COMPRESS_XPRESS) + if (head->flags & FLAG_HEADER_COMPRESS_LZMS) { - debug("Xpress compress is not supported 0x%x\n", head->flags); + debug("LZMS compress is not supported 0x%x\n", head->flags); grub_file_close(file); return 1; } - rc = ventoy_read_resource(file, &head->metadata, (void **)&decompress_data); + rc = ventoy_read_resource(file, head, &head->metadata, (void **)&decompress_data); if (rc) { grub_printf("failed to read meta data %d\n", rc); @@ -829,7 +999,14 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) } security = (wim_security_header *)decompress_data; - rootdir = (wim_directory_entry *)(decompress_data + ((security->len + 7) & 0xFFFFFFF8U)); + if (security->len > 0) + { + rootdir = (wim_directory_entry *)(decompress_data + ((security->len + 7) & 0xFFFFFFF8U)); + } + else + { + rootdir = (wim_directory_entry *)(decompress_data + 8); + } /* search winpeshl.exe dirent entry */ search = search_replace_wim_dirent(decompress_data, rootdir); @@ -841,8 +1018,28 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) } debug("find replace file at %p\n", search); - - grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash)); + + grub_memset(&patch->old_hash, 0, sizeof(wim_hash)); + if (grub_memcmp(&patch->old_hash, search->hash.sha1, sizeof(wim_hash)) == 0) + { + debug("search hash all 0, now do deep search\n"); + stream = (wim_stream_entry *)((char *)search + search->len); + for (i = 0; i < search->streams; i++) + { + if (stream->name_len == 0) + { + grub_memcpy(&patch->old_hash, stream->hash.sha1, sizeof(wim_hash)); + debug("new search hash: %02x %02x %02x %02x %02x %02x %02x %02x\n", + ventoy_varg_8(patch->old_hash.sha1)); + break; + } + stream = (wim_stream_entry *)((char *)stream + stream->len); + } + } + else + { + grub_memcpy(&patch->old_hash, search->hash.sha1, sizeof(wim_hash)); + } debug("read lookup offset:%llu size:%llu\n", (ulonglong)head->lookup.offset, (ulonglong)head->lookup.raw_size); lookup = grub_malloc(head->lookup.raw_size); @@ -857,7 +1054,7 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) debug("find replace lookup entry_id:%ld raw_size:%u\n", ((long)patch->replace_look - (long)lookup) / sizeof(wim_lookup_entry), exe_len); - if (0 == ventoy_read_resource(file, &(patch->replace_look->resource), (void **)&(exe_data))) + if (0 == ventoy_read_resource(file, head, &(patch->replace_look->resource), (void **)&(exe_data))) { ventoy_cat_exe_file_data(wim_data, exe_len, exe_data); grub_free(exe_data); @@ -869,8 +1066,8 @@ static int ventoy_wimdows_locate_wim(const char *disk, wim_patch *patch) } else { - debug("failed to find lookup entry for replace file 0x%02x 0x%02x\n", - patch->old_hash.sha1[0], patch->old_hash.sha1[1]); + debug("failed to find lookup entry for replace file %02x %02x %02x %02x\n", + ventoy_varg_4(patch->old_hash.sha1)); } wim_data->wim_raw_size = (grub_uint32_t)file->size; @@ -1023,7 +1220,48 @@ static void ventoy_windows_fill_override_data_iso9660( grub_uint64_t isosize, return; } -static void ventoy_windows_fill_override_data_udf( grub_uint64_t isosize, void *override) +static int ventoy_windows_fill_udf_short_ad(grub_file_t isofile, grub_uint32_t curpos, + wim_tail *wim_data, grub_uint32_t new_wim_size) +{ + int i; + grub_uint32_t total = 0; + grub_uint32_t left_size = 0; + ventoy_udf_override *udf = NULL; + ventoy_udf_override tmp[4]; + + grub_memset(tmp, 0, sizeof(tmp)); + grub_file_seek(isofile, wim_data->override_offset); + grub_file_read(isofile, tmp, sizeof(tmp)); + + left_size = new_wim_size; + udf = (ventoy_udf_override *)wim_data->override_data; + + for (i = 0; i < 4; i++) + { + total += tmp[i].length; + if (total >= wim_data->wim_raw_size) + { + udf->length = left_size; + udf->position = curpos; + return 0; + } + else + { + udf->length = tmp[i].length; + udf->position = curpos; + } + + left_size -= tmp[i].length; + curpos += udf->length / 2048; + udf++; + wim_data->override_len += sizeof(ventoy_udf_override); + } + + debug("######## Too many udf ad ######\n"); + return 1; +} + +static void ventoy_windows_fill_override_data_udf(grub_file_t isofile, void *override) { grub_uint32_t data32; grub_uint64_t data64; @@ -1034,9 +1272,8 @@ static void ventoy_windows_fill_override_data_udf( grub_uint64_t isosize, voi ventoy_override_chunk *cur; wim_patch *node = NULL; wim_tail *wim_data = NULL; - ventoy_udf_override *udf = NULL; - sector = (isosize + 2047) / 2048; + sector = (isofile->size + 2047) / 2048; cur = (ventoy_override_chunk *)override; @@ -1046,7 +1283,7 @@ static void ventoy_windows_fill_override_data_udf( grub_uint64_t isosize, voi cur++; } - debug("ventoy_windows_fill_override_data_udf %lu\n", (ulong)isosize); + debug("ventoy_windows_fill_override_data_udf %lu\n", (ulong)isofile->size); for (node = g_wim_patch_head; node; node = node->next) { @@ -1087,13 +1324,11 @@ static void ventoy_windows_fill_override_data_udf( grub_uint64_t isosize, voi data64 = new_wim_size; grub_memcpy(cur->override_data, &(data64), 8); - udf = (ventoy_udf_override *)wim_data->override_data; - udf->length = new_wim_size; - udf->position = (grub_uint32_t)sector - udf_start_block; + /* override 3: position and length in extend data */ + ventoy_windows_fill_udf_short_ad(isofile, (grub_uint32_t)sector - udf_start_block, wim_data, new_wim_size); sector += (new_wim_size / 2048); - - /* override 3: position and length in extend data */ + cur++; cur->img_offset = wim_data->override_offset; cur->override_size = wim_data->override_len; @@ -1270,6 +1505,54 @@ end: return rc; } +grub_err_t ventoy_cmd_windows_wimboot_data(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t size = 0; + const char *addr = NULL; + ventoy_chain_head *chain = NULL; + ventoy_os_param *param = NULL; + char envbuf[64]; + + (void)ctxt; + (void)argc; + (void)args; + + addr = grub_env_get("vtoy_chain_mem_addr"); + if (!addr) + { + debug("Failed to find vtoy_chain_mem_addr\n"); + return 1; + } + + chain = (ventoy_chain_head *)(void *)grub_strtoul(addr, NULL, 16); + + if (grub_memcmp(&g_ventoy_guid, &chain->os_param.guid, 16) != 0) + { + debug("os_param.guid not match\n"); + return 1; + } + + size = sizeof(ventoy_os_param) + sizeof(ventoy_windows_data); + param = (ventoy_os_param *)grub_zalloc(size); + if (!param) + { + return 1; + } + + grub_memcpy(param, &chain->os_param, sizeof(ventoy_os_param)); + ventoy_fill_windows_rtdata(param + 1, param->vtoy_img_path); + + grub_snprintf(envbuf, sizeof(envbuf), "0x%lx", (unsigned long)param); + grub_env_set("vtoy_wimboot_mem_addr", envbuf); + debug("vtoy_wimboot_mem_addr: %s\n", envbuf); + + grub_snprintf(envbuf, sizeof(envbuf), "%u", size); + grub_env_set("vtoy_wimboot_mem_size", envbuf); + debug("vtoy_wimboot_mem_size: %s\n", envbuf); + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) { int unknown_image = 0; @@ -1385,7 +1668,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ - g_ventoy_chain_type = 1; + g_ventoy_chain_type = ventoy_chain_windows; ventoy_fill_os_param(file, &(chain->os_param)); if (0 == unknown_image) @@ -1439,7 +1722,7 @@ grub_err_t ventoy_cmd_windows_chain_data(grub_extcmd_context_t ctxt, int argc, c } else { - ventoy_windows_fill_override_data_udf(isosize, (char *)chain + chain->override_chunk_offset); + ventoy_windows_fill_override_data_udf(file, (char *)chain + chain->override_chunk_offset); } /* part 5: virt chunk */ @@ -1461,7 +1744,7 @@ static grub_uint32_t ventoy_get_wim_iso_offset(const char *filepath) grub_file_t file; char cmdbuf[128]; - grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback wimiso %s", filepath); + grub_snprintf(cmdbuf, sizeof(cmdbuf), "loopback wimiso \"%s\"", filepath); grub_script_execute_sourcecode(cmdbuf); file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", "(wimiso)/boot/boot.wim"); @@ -1511,6 +1794,41 @@ static int ventoy_get_wim_chunklist(const char *filename, ventoy_img_chunk_list return 0; } +grub_err_t ventoy_cmd_wim_check_bootable(grub_extcmd_context_t ctxt, int argc, char **args) +{ + grub_uint32_t boot_index; + grub_file_t file = NULL; + wim_header *wimhdr = NULL; + + (void)ctxt; + (void)argc; + + wimhdr = grub_zalloc(sizeof(wim_header)); + if (!wimhdr) + { + return 1; + } + + file = ventoy_grub_file_open(VENTOY_FILE_TYPE, "%s", args[0]); + if (!file) + { + grub_free(wimhdr); + return 1; + } + + grub_file_read(file, wimhdr, sizeof(wim_header)); + grub_file_close(file); + boot_index = wimhdr->boot_index; + grub_free(wimhdr); + + if (boot_index == 0) + { + return 1; + } + + VENTOY_CMD_RETURN(GRUB_ERR_NONE); +} + grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char **args) { grub_uint32_t i = 0; @@ -1597,7 +1915,7 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char grub_memset(chain, 0, sizeof(ventoy_chain_head)); /* part 1: os parameter */ - g_ventoy_chain_type = 0; + g_ventoy_chain_type = ventoy_chain_wim; ventoy_fill_os_param(file, &(chain->os_param)); /* part 2: chain head */ @@ -1667,3 +1985,29 @@ grub_err_t ventoy_cmd_wim_chain_data(grub_extcmd_context_t ctxt, int argc, char VENTOY_CMD_RETURN(GRUB_ERR_NONE); } +int ventoy_chain_file_size(const char *path) +{ + int size; + grub_file_t file; + + file = grub_file_open(path, VENTOY_FILE_TYPE); + size = (int)(file->size); + + grub_file_close(file); + + return size; +} + +int ventoy_chain_file_read(const char *path, int offset, int len, void *buf) +{ + int size; + grub_file_t file; + + file = grub_file_open(path, VENTOY_FILE_TYPE); + grub_file_seek(file, offset); + size = grub_file_read(file, buf, len); + grub_file_close(file); + + return size; +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c new file mode 100644 index 00000000..bfb3125e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.c @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2012 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * Xpress Compression Algorithm (MS-XCA) decompression + * + */ + +#include "wimboot.h" +#include "huffman.h" +#include "xpress.h" + +#pragma GCC diagnostic ignored "-Wcast-align" + +/** + * Decompress XCA-compressed data + * + * @v data Compressed data + * @v len Length of compressed data + * @v buf Decompression buffer, or NULL + * @ret out_len Length of decompressed data, or negative error + */ +ssize_t xca_decompress ( const void *data, size_t len, void *buf ) { + const void *src = data; + const void *end = ( uint8_t * ) src + len; + uint8_t *out = buf; + size_t out_len = 0; + size_t out_len_threshold = 0; + const struct xca_huf_len *lengths; + struct xca xca; + uint32_t accum = 0; + int extra_bits = 0; + unsigned int huf; + struct huffman_symbols *sym; + unsigned int raw; + unsigned int match_len; + unsigned int match_offset_bits; + unsigned int match_offset; + const uint8_t *copy; + int rc; + + /* Process data stream */ + while ( src < end ) { + + /* (Re)initialise decompressor if applicable */ + if ( out_len >= out_len_threshold ) { + + /* Construct symbol lengths */ + lengths = src; + src = ( uint8_t * ) src + sizeof ( *lengths ); + if ( src > end ) { + DBG ( "XCA too short to hold Huffman lengths table.\n"); + return -1; + } + for ( raw = 0 ; raw < XCA_CODES ; raw++ ) + xca.lengths[raw] = xca_huf_len ( lengths, raw ); + + /* Construct Huffman alphabet */ + if ( ( rc = huffman_alphabet ( &xca.alphabet, + xca.lengths, + XCA_CODES ) ) != 0 ) + return rc; + + /* Initialise state */ + accum = XCA_GET16 ( src ); + accum <<= 16; + accum |= XCA_GET16 ( src ); + extra_bits = 16; + + /* Determine next threshold */ + out_len_threshold = ( out_len + XCA_BLOCK_SIZE ); + } + + /* Determine symbol */ + huf = ( accum >> ( 32 - HUFFMAN_BITS ) ); + sym = huffman_sym ( &xca.alphabet, huf ); + raw = huffman_raw ( sym, huf ); + accum <<= huffman_len ( sym ); + extra_bits -= huffman_len ( sym ); + if ( extra_bits < 0 ) { + accum |= ( XCA_GET16 ( src ) << ( -extra_bits ) ); + extra_bits += 16; + } + + /* Process symbol */ + if ( raw < XCA_END_MARKER ) { + + /* Literal symbol - add to output stream */ + if ( buf ) + *(out++) = raw; + out_len++; + + } else if ( ( raw == XCA_END_MARKER ) && + ( (uint8_t *) src >= ( ( uint8_t * ) end - 1 ) ) ) { + + /* End marker symbol */ + return out_len; + + } else { + + /* LZ77 match symbol */ + raw -= XCA_END_MARKER; + match_offset_bits = ( raw >> 4 ); + match_len = ( raw & 0x0f ); + if ( match_len == 0x0f ) { + match_len = XCA_GET8 ( src ); + if ( match_len == 0xff ) { + match_len = XCA_GET16 ( src ); + } else { + match_len += 0x0f; + } + } + match_len += 3; + if ( match_offset_bits ) { + match_offset = + ( ( accum >> ( 32 - match_offset_bits )) + + ( 1 << match_offset_bits ) ); + } else { + match_offset = 1; + } + accum <<= match_offset_bits; + extra_bits -= match_offset_bits; + if ( extra_bits < 0 ) { + accum |= ( XCA_GET16 ( src ) << (-extra_bits) ); + extra_bits += 16; + } + + /* Copy data */ + out_len += match_len; + if ( buf ) { + copy = ( out - match_offset ); + while ( match_len-- ) + *(out++) = *(copy++); + } + } + } + + return out_len; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h new file mode 100644 index 00000000..6a430f7f --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/grub-core/ventoy/xpress.h @@ -0,0 +1,87 @@ +#ifndef _XCA_H +#define _XCA_H + +/* + * Copyright (C) 2012 Michael Brown . + * + * 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. + */ + +/** + * @file + * + * Xpress Compression Algorithm (MS-XCA) decompression + * + */ + +#include "huffman.h" + +/** Number of XCA codes */ +#define XCA_CODES 512 + +/** XCA decompressor */ +struct xca { + /** Huffman alphabet */ + struct huffman_alphabet alphabet; + /** Raw symbols + * + * Must immediately follow the Huffman alphabet. + */ + huffman_raw_symbol_t raw[XCA_CODES]; + /** Code lengths */ + uint8_t lengths[XCA_CODES]; +}; + +/** XCA symbol Huffman lengths table */ +struct xca_huf_len { + /** Lengths of each symbol */ + uint8_t nibbles[ XCA_CODES / 2 ]; +} __attribute__ (( packed )); + +/** + * Extract Huffman-coded length of a raw symbol + * + * @v lengths Huffman lengths table + * @v symbol Raw symbol + * @ret len Huffman-coded length + */ +static inline unsigned int xca_huf_len ( const struct xca_huf_len *lengths, + unsigned int symbol ) { + return ( ( ( lengths->nibbles[ symbol / 2 ] ) >> + ( 4 * ( symbol % 2 ) ) ) & 0x0f ); +} + +/** Get word from source data stream */ +#define XCA_GET16( src ) ( { \ + const uint16_t *src16 = src; \ + src = ( uint8_t * ) src + sizeof ( *src16 ); \ + *src16; } ) + +/** Get byte from source data stream */ +#define XCA_GET8( src ) ( { \ + const uint8_t *src8 = src; \ + src = ( uint8_t * ) src + sizeof ( *src8 ); \ + *src8; } ) + +/** XCA source data stream end marker */ +#define XCA_END_MARKER 256 + +/** XCA block size */ +#define XCA_BLOCK_SIZE ( 64 * 1024 ) + +extern ssize_t xca_decompress ( const void *data, size_t len, void *buf ); + +#endif /* _XCA_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h new file mode 100644 index 00000000..7a4070d2 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/cache.h @@ -0,0 +1,56 @@ +/* cache.h - Flush the processor's cache. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2007 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_CACHE_H +#define GRUB_CACHE_H 1 + +#include +#include + +#if defined (__i386__) || defined (__x86_64__) +static inline void +grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} +#else +void EXPORT_FUNC(grub_arch_sync_caches) (void *address, grub_size_t len); +#endif + +#ifndef GRUB_MACHINE_EMU +#if defined (__aarch64__) || defined (__ia64__) || defined (__powerpc__) || \ + defined (__sparc__) + +#elif defined (__i386__) || defined (__x86_64__) +static inline void +grub_arch_sync_dma_caches (volatile void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) +{ +} +#elif defined(__mips__) && (_MIPS_SIM != _ABI64) +void EXPORT_FUNC(grub_arch_sync_dma_caches) (volatile void *address, grub_size_t len); +#endif +#endif + +#ifdef __arm__ +void +grub_arm_cache_enable (void); +#endif + +#endif /* ! GRUB_CACHE_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/compiler.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/compiler.h new file mode 100644 index 00000000..9859ff4c --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/compiler.h @@ -0,0 +1,53 @@ +/* compiler.h - macros for various compiler features */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010,2014 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_COMPILER_HEADER +#define GRUB_COMPILER_HEADER 1 + +/* GCC version checking borrowed from glibc. */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) +# define GNUC_PREREQ(maj,min) \ + ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min)) +#else +# define GNUC_PREREQ(maj,min) 0 +#endif + +/* Does this compiler support compile-time error attributes? */ +#if GNUC_PREREQ(4,3) +# define ATTRIBUTE_ERROR(msg) \ + __attribute__ ((__error__ (msg))) +#else +# define ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn)) +#endif + +#if GNUC_PREREQ(4,4) +# define GNU_PRINTF gnu_printf +#else +# define GNU_PRINTF printf +#endif + +#if GNUC_PREREQ(3,4) +# define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) +#else +# define WARN_UNUSED_RESULT +#endif + +#define UNUSED __attribute__((__unused__)) + +#endif /* ! GRUB_COMPILER_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h new file mode 100644 index 00000000..f70498da --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/dl.h @@ -0,0 +1,309 @@ +/* dl.h - types and prototypes for loadable module support */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2005,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_DL_H +#define GRUB_DL_H 1 + +#include +#ifndef ASM_FILE +#include +#include +#include +#include +#include +#endif + +/* + * Macros GRUB_MOD_INIT and GRUB_MOD_FINI are also used by build rules + * to collect module names, so we define them only when they are not + * defined already. + */ +#ifndef ASM_FILE + +#ifndef GRUB_MOD_INIT + +#if !defined (GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) && !defined (GRUB_KERNEL) + +#define GRUB_MOD_INIT(name) \ +static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ +static void \ +grub_mod_init (grub_dl_t mod __attribute__ ((unused))) + +#define GRUB_MOD_FINI(name) \ +static void grub_mod_fini (void) __attribute__ ((used)); \ +static void \ +grub_mod_fini (void) + +#elif defined (GRUB_KERNEL) + +#define GRUB_MOD_INIT(name) \ +static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ +void \ +grub_##name##_init (void) { grub_mod_init (0); } \ +static void \ +grub_mod_init (grub_dl_t mod __attribute__ ((unused))) + +#define GRUB_MOD_FINI(name) \ +static void grub_mod_fini (void) __attribute__ ((used)); \ +void \ +grub_##name##_fini (void) { grub_mod_fini (); } \ +static void \ +grub_mod_fini (void) + +#else + +#define GRUB_MOD_INIT(name) \ +static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ +void grub_##name##_init (void); \ +void \ +grub_##name##_init (void) { grub_mod_init (0); } \ +static void \ +grub_mod_init (grub_dl_t mod __attribute__ ((unused))) + +#define GRUB_MOD_FINI(name) \ +static void grub_mod_fini (void) __attribute__ ((used)); \ +void grub_##name##_fini (void); \ +void \ +grub_##name##_fini (void) { grub_mod_fini (); } \ +static void \ +grub_mod_fini (void) + +#endif + +#endif + +#endif + +#ifndef ASM_FILE +#ifdef __APPLE__ +#define GRUB_MOD_SECTION(x) "_" #x ", _" #x "" +#else +#define GRUB_MOD_SECTION(x) "." #x +#endif +#else +#ifdef __APPLE__ +#define GRUB_MOD_SECTION(x) _ ## x , _ ##x +#else +#define GRUB_MOD_SECTION(x) . ## x +#endif +#endif + +/* Me, Vladimir Serbinenko, hereby I add this module check as per new + GNU module policy. Note that this license check is informative only. + Modules have to be licensed under GPLv3 or GPLv3+ (optionally + multi-licensed under other licences as well) independently of the + presence of this check and solely by linking (module loading in GRUB + constitutes linking) and GRUB core being licensed under GPLv3+. + Be sure to understand your license obligations. +*/ +#ifndef ASM_FILE +#if GNUC_PREREQ (3,2) +#define ATTRIBUTE_USED __used__ +#else +#define ATTRIBUTE_USED __unused__ +#endif +#define GRUB_MOD_LICENSE(license) \ + static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license; +#define GRUB_MOD_DEP(name) \ +static const char grub_module_depend_##name[] \ + __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name +#define GRUB_MOD_NAME(name) \ +static const char grub_module_name_##name[] \ + __attribute__((section(GRUB_MOD_SECTION(modname)), __used__)) = #name +#else +#ifdef __APPLE__ +.macro GRUB_MOD_LICENSE + .section GRUB_MOD_SECTION(module_license) + .ascii "LICENSE=" + .ascii $0 + .byte 0 +.endm +#else +.macro GRUB_MOD_LICENSE license + .section GRUB_MOD_SECTION(module_license), "a" + .ascii "LICENSE=" + .ascii "\license" + .byte 0 +.endm +#endif +#endif + +/* Under GPL license obligations you have to distribute your module + under GPLv3(+). However, you can also distribute the same code under + another license as long as GPLv3(+) version is provided. +*/ +#define GRUB_MOD_DUAL_LICENSE(x) + +#ifndef ASM_FILE + +struct grub_dl_segment +{ + struct grub_dl_segment *next; + void *addr; + grub_size_t size; + unsigned section; +}; +typedef struct grub_dl_segment *grub_dl_segment_t; + +struct grub_dl; + +struct grub_dl_dep +{ + struct grub_dl_dep *next; + struct grub_dl *mod; +}; +typedef struct grub_dl_dep *grub_dl_dep_t; + +#ifndef GRUB_UTIL +struct grub_dl +{ + char *name; + int ref_count; + int persistent; + grub_dl_dep_t dep; + grub_dl_segment_t segment; + Elf_Sym *symtab; + grub_size_t symsize; + void (*init) (struct grub_dl *mod); + void (*fini) (void); +#if !defined (__i386__) && !defined (__x86_64__) + void *got; + void *gotptr; + void *tramp; + void *trampptr; +#endif +#if defined(__mips__) && (_MIPS_SIM != _ABI64) + grub_uint32_t *reginfo; +#endif + void *base; + grub_size_t sz; + struct grub_dl *next; +}; +#endif +typedef struct grub_dl *grub_dl_t; + +grub_dl_t grub_dl_load_file (const char *filename); +grub_dl_t EXPORT_FUNC(grub_dl_load) (const char *name); +grub_dl_t grub_dl_load_core (void *addr, grub_size_t size); +grub_dl_t EXPORT_FUNC(grub_dl_load_core_noinit) (void *addr, grub_size_t size); +int EXPORT_FUNC(grub_dl_unload) (grub_dl_t mod); +void grub_dl_unload_unneeded (void); +int EXPORT_FUNC(grub_dl_ref) (grub_dl_t mod); +int EXPORT_FUNC(grub_dl_unref) (grub_dl_t mod); +extern grub_dl_t EXPORT_VAR(grub_dl_head); + +#ifndef GRUB_UTIL + +#define FOR_DL_MODULES(var) FOR_LIST_ELEMENTS ((var), (grub_dl_head)) + +#ifdef GRUB_MACHINE_EMU +void * +grub_osdep_dl_memalign (grub_size_t align, grub_size_t size); +void +grub_dl_osdep_dl_free (void *ptr); +#endif + +static inline void +grub_dl_init (grub_dl_t mod) +{ + if (mod->init) + (mod->init) (mod); + + mod->next = grub_dl_head; + grub_dl_head = mod; +} + +static inline grub_dl_t +grub_dl_get (const char *name) +{ + grub_dl_t l; + + FOR_DL_MODULES(l) + if (grub_strcmp (name, l->name) == 0) + return l; + + return 0; +} + +static inline void +grub_dl_set_persistent (grub_dl_t mod) +{ + mod->persistent = 1; +} + +static inline int +grub_dl_is_persistent (grub_dl_t mod) +{ + return mod->persistent; +} + +#endif + +grub_err_t grub_dl_register_symbol (const char *name, void *addr, + int isfunc, grub_dl_t mod); + +grub_err_t grub_arch_dl_check_header (void *ehdr); +#ifndef GRUB_UTIL +grub_err_t +grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, + Elf_Shdr *s, grub_dl_segment_t seg); +#endif + +#if defined (__mips__) && (_MIPS_SIM != _ABI64) +#define GRUB_LINKER_HAVE_INIT 1 +void grub_arch_dl_init_linker (void); +#endif + +#define GRUB_IA64_DL_TRAMP_ALIGN 16 +#define GRUB_IA64_DL_GOT_ALIGN 16 + +grub_err_t +grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); +grub_err_t +grub_arm64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); + +#if defined (__ia64__) +#define GRUB_ARCH_DL_TRAMP_ALIGN GRUB_IA64_DL_TRAMP_ALIGN +#define GRUB_ARCH_DL_GOT_ALIGN GRUB_IA64_DL_GOT_ALIGN +#define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size +#elif defined (__aarch64__) +#define grub_arch_dl_get_tramp_got_size grub_arm64_dl_get_tramp_got_size +#else +grub_err_t +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); +#endif + +#if defined (__powerpc__) || (defined (__mips__) && (_MIPS_SIM != _ABI64)) || defined (__arm__) || \ + (defined(__riscv) && (__riscv_xlen == 32)) +#define GRUB_ARCH_DL_TRAMP_ALIGN 4 +#define GRUB_ARCH_DL_GOT_ALIGN 4 +#endif + +#if defined (__aarch64__) || defined (__sparc__) || (defined (__mips__) && (_MIPS_SIM == _ABI64)) || \ + (defined(__riscv) && (__riscv_xlen == 64)) +#define GRUB_ARCH_DL_TRAMP_ALIGN 8 +#define GRUB_ARCH_DL_GOT_ALIGN 8 +#endif + +#endif + +#endif /* ! GRUB_DL_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h new file mode 100644 index 00000000..5635882e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/api.h @@ -0,0 +1,1761 @@ +/* efi.h - declare EFI types and functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EFI_API_HEADER +#define GRUB_EFI_API_HEADER 1 + +#include +#include + +/* For consistency and safety, we name the EFI-defined types differently. + All names are transformed into lower case, _t appended, and + grub_efi_ prepended. */ + +/* Constants. */ +#define GRUB_EFI_EVT_TIMER 0x80000000 +#define GRUB_EFI_EVT_RUNTIME 0x40000000 +#define GRUB_EFI_EVT_RUNTIME_CONTEXT 0x20000000 +#define GRUB_EFI_EVT_NOTIFY_WAIT 0x00000100 +#define GRUB_EFI_EVT_NOTIFY_SIGNAL 0x00000200 +#define GRUB_EFI_EVT_SIGNAL_EXIT_BOOT_SERVICES 0x00000201 +#define GRUB_EFI_EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE 0x60000202 + +#define GRUB_EFI_TPL_APPLICATION 4 +#define GRUB_EFI_TPL_CALLBACK 8 +#define GRUB_EFI_TPL_NOTIFY 16 +#define GRUB_EFI_TPL_HIGH_LEVEL 31 + +#define GRUB_EFI_MEMORY_UC 0x0000000000000001LL +#define GRUB_EFI_MEMORY_WC 0x0000000000000002LL +#define GRUB_EFI_MEMORY_WT 0x0000000000000004LL +#define GRUB_EFI_MEMORY_WB 0x0000000000000008LL +#define GRUB_EFI_MEMORY_UCE 0x0000000000000010LL +#define GRUB_EFI_MEMORY_WP 0x0000000000001000LL +#define GRUB_EFI_MEMORY_RP 0x0000000000002000LL +#define GRUB_EFI_MEMORY_XP 0x0000000000004000LL +#define GRUB_EFI_MEMORY_NV 0x0000000000008000LL +#define GRUB_EFI_MEMORY_MORE_RELIABLE 0x0000000000010000LL +#define GRUB_EFI_MEMORY_RO 0x0000000000020000LL +#define GRUB_EFI_MEMORY_RUNTIME 0x8000000000000000LL + +#define GRUB_EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001 +#define GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002 +#define GRUB_EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004 +#define GRUB_EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008 +#define GRUB_EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010 +#define GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE 0x00000020 + +#define GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001ULL + +#define GRUB_EFI_VARIABLE_NON_VOLATILE 0x0000000000000001 +#define GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002 +#define GRUB_EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004 + +#define GRUB_EFI_TIME_ADJUST_DAYLIGHT 0x01 +#define GRUB_EFI_TIME_IN_DAYLIGHT 0x02 + +#define GRUB_EFI_UNSPECIFIED_TIMEZONE 0x07FF + +#define GRUB_EFI_OPTIONAL_PTR 0x00000001 + +#define GRUB_EFI_LOADED_IMAGE_GUID \ + { 0x5b1b31a1, 0x9562, 0x11d2, \ + { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_DISK_IO_GUID \ + { 0xce345171, 0xba0b, 0x11d2, \ + { 0x8e, 0x4f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_BLOCK_IO_GUID \ + { 0x964e5b21, 0x6459, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SERIAL_IO_GUID \ + { 0xbb25cf6f, 0xf1d4, 0x11d2, \ + { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0xfd } \ + } + +#define GRUB_EFI_SIMPLE_NETWORK_GUID \ + { 0xa19832b9, 0xac25, 0x11d3, \ + { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_PXE_GUID \ + { 0x03c4e603, 0xac28, 0x11d3, \ + { 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_DEVICE_PATH_GUID \ + { 0x09576e91, 0x6d3f, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \ + { 0x387477c1, 0x69c7, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID \ + { 0xdd9e7534, 0x7762, 0x4698, \ + { 0x8c, 0x14, 0xf5, 0x85, 0x17, 0xa6, 0x25, 0xaa } \ + } + +#define GRUB_EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID \ + { 0x387477c2, 0x69c7, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_SIMPLE_POINTER_PROTOCOL_GUID \ + { 0x31878c87, 0xb75, 0x11d5, \ + { 0x9a, 0x4f, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID \ + { 0x8D59D32B, 0xC655, 0x4AE9, \ + { 0x9B, 0x15, 0xF2, 0x59, 0x04, 0x99, 0x2A, 0x43 } \ + } + +#define GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID \ + { 0x18A031AB, 0xB443, 0x4D1A, \ + { 0xA5, 0xC0, 0x0C, 0x09, 0x26, 0x1E, 0x9F, 0x71 } \ + } + +#define GRUB_EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { 0x5B1B31A1, 0x9562, 0x11d2, \ + { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ + } + +#define GRUB_EFI_LOAD_FILE_PROTOCOL_GUID \ + { 0x56EC3091, 0x954C, 0x11d2, \ + { 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B } \ + } + +#define GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \ + { 0x0964e5b22, 0x6459, 0x11d2, \ + { 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + +#define GRUB_EFI_TAPE_IO_PROTOCOL_GUID \ + { 0x1e93e633, 0xd65a, 0x459e, \ + { 0xab, 0x84, 0x93, 0xd9, 0xec, 0x26, 0x6d, 0x18 } \ + } + +#define GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID \ + { 0x1d85cd7f, 0xf43d, 0x11d2, \ + { 0x9a, 0x0c, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_SCSI_IO_PROTOCOL_GUID \ + { 0x932f47e6, 0x2362, 0x4002, \ + { 0x80, 0x3e, 0x3c, 0xd5, 0x4b, 0x13, 0x8f, 0x85 } \ + } + +#define GRUB_EFI_USB2_HC_PROTOCOL_GUID \ + { 0x3e745226, 0x9818, 0x45b6, \ + { 0xa2, 0xac, 0xd7, 0xcd, 0x0e, 0x8b, 0xa2, 0xbc } \ + } + +#define GRUB_EFI_DEBUG_SUPPORT_PROTOCOL_GUID \ + { 0x2755590C, 0x6F3C, 0x42FA, \ + { 0x9E, 0xA4, 0xA3, 0xBA, 0x54, 0x3C, 0xDA, 0x25 } \ + } + +#define GRUB_EFI_DEBUGPORT_PROTOCOL_GUID \ + { 0xEBA4E8D2, 0x3858, 0x41EC, \ + { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 } \ + } + +#define GRUB_EFI_DECOMPRESS_PROTOCOL_GUID \ + { 0xd8117cfe, 0x94a6, 0x11d4, \ + { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \ + { 0x8b843e20, 0x8132, 0x4852, \ + { 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c } \ + } + +#define GRUB_EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \ + { 0x379be4e, 0xd706, 0x437d, \ + { 0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4 } \ + } + +#define GRUB_EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL_GUID \ + { 0x5c99a21, 0xc70f, 0x4ad2, \ + { 0x8a, 0x5f, 0x35, 0xdf, 0x33, 0x43, 0xf5, 0x1e } \ + } + +#define GRUB_EFI_ACPI_TABLE_PROTOCOL_GUID \ + { 0xffe06bdd, 0x6107, 0x46a6, \ + { 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c} \ + } + +#define GRUB_EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \ + { 0x587e72d7, 0xcc50, 0x4f79, \ + { 0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f } \ + } + +#define GRUB_EFI_HII_DATABASE_PROTOCOL_GUID \ + { 0xef9fc172, 0xa1b2, 0x4693, \ + { 0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42 } \ + } + +#define GRUB_EFI_HII_STRING_PROTOCOL_GUID \ + { 0xfd96974, 0x23aa, 0x4cdc, \ + { 0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a } \ + } + +#define GRUB_EFI_HII_IMAGE_PROTOCOL_GUID \ + { 0x31a6406a, 0x6bdf, 0x4e46, \ + { 0xb2, 0xa2, 0xeb, 0xaa, 0x89, 0xc4, 0x9, 0x20 } \ + } + +#define GRUB_EFI_HII_FONT_PROTOCOL_GUID \ + { 0xe9ca4775, 0x8657, 0x47fc, \ + { 0x97, 0xe7, 0x7e, 0xd6, 0x5a, 0x8, 0x43, 0x24 } \ + } + +#define GRUB_EFI_HII_CONFIGURATION_ACCESS_PROTOCOL_GUID \ + { 0x330d4706, 0xf2a0, 0x4e4f, \ + { 0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85 } \ + } + +#define GRUB_EFI_COMPONENT_NAME2_PROTOCOL_GUID \ + { 0x6a7a5cff, 0xe8d9, 0x4f70, \ + { 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14} \ + } + +#define GRUB_EFI_USB_IO_PROTOCOL_GUID \ + { 0x2B2F68D6, 0x0CD2, 0x44cf, \ + { 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75 } \ + } + +#define GRUB_EFI_TIANO_CUSTOM_DECOMPRESS_GUID \ + { 0xa31280ad, 0x481e, 0x41b6, \ + { 0x95, 0xe8, 0x12, 0x7f, 0x4c, 0x98, 0x47, 0x79 } \ + } + +#define GRUB_EFI_CRC32_GUIDED_SECTION_EXTRACTION_GUID \ + { 0xfc1bcdb0, 0x7d31, 0x49aa, \ + { 0x93, 0x6a, 0xa4, 0x60, 0x0d, 0x9d, 0xd0, 0x83 } \ + } + +#define GRUB_EFI_LZMA_CUSTOM_DECOMPRESS_GUID \ + { 0xee4e5898, 0x3914, 0x4259, \ + { 0x9d, 0x6e, 0xdc, 0x7b, 0xd7, 0x94, 0x03, 0xcf } \ + } + +#define GRUB_EFI_TSC_FREQUENCY_GUID \ + { 0xdba6a7e3, 0xbb57, 0x4be7, \ + { 0x8a, 0xf8, 0xd5, 0x78, 0xdb, 0x7e, 0x56, 0x87 } \ + } + +#define GRUB_EFI_SYSTEM_RESOURCE_TABLE_GUID \ + { 0xb122a263, 0x3661, 0x4f68, \ + { 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 } \ + } + +#define GRUB_EFI_DXE_SERVICES_TABLE_GUID \ + { 0x05ad34ba, 0x6f02, 0x4214, \ + { 0x95, 0x2e, 0x4d, 0xa0, 0x39, 0x8e, 0x2b, 0xb9 } \ + } + +#define GRUB_EFI_HOB_LIST_GUID \ + { 0x7739f24c, 0x93d7, 0x11d4, \ + { 0x9a, 0x3a, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_MEMORY_TYPE_INFORMATION_GUID \ + { 0x4c19049f, 0x4137, 0x4dd3, \ + { 0x9c, 0x10, 0x8b, 0x97, 0xa8, 0x3f, 0xfd, 0xfa } \ + } + +#define GRUB_EFI_DEBUG_IMAGE_INFO_TABLE_GUID \ + { 0x49152e77, 0x1ada, 0x4764, \ + { 0xb7, 0xa2, 0x7a, 0xfe, 0xfe, 0xd9, 0x5e, 0x8b } \ + } + +#define GRUB_EFI_MPS_TABLE_GUID \ + { 0xeb9d2d2f, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ACPI_TABLE_GUID \ + { 0xeb9d2d30, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_ACPI_20_TABLE_GUID \ + { 0x8868e871, 0xe4f1, 0x11d3, \ + { 0xbc, 0x22, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81 } \ + } + +#define GRUB_EFI_SMBIOS_TABLE_GUID \ + { 0xeb9d2d31, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_SAL_TABLE_GUID \ + { 0xeb9d2d32, 0x2d88, 0x11d3, \ + { 0x9a, 0x16, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ + } + +#define GRUB_EFI_HCDP_TABLE_GUID \ + { 0xf951938d, 0x620b, 0x42ef, \ + { 0x82, 0x79, 0xa8, 0x4b, 0x79, 0x61, 0x78, 0x98 } \ + } + +#define GRUB_EFI_DEVICE_TREE_GUID \ + { 0xb1b621d5, 0xf19c, 0x41a5, \ + { 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 } \ + } + +#define GRUB_EFI_VENDOR_APPLE_GUID \ + { 0x2B0585EB, 0xD8B8, 0x49A9, \ + { 0x8B, 0x8C, 0xE2, 0x1B, 0x01, 0xAE, 0xF2, 0xB7 } \ + } + +struct grub_efi_sal_system_table +{ + grub_uint32_t signature; + grub_uint32_t total_table_len; + grub_uint16_t sal_rev; + grub_uint16_t entry_count; + grub_uint8_t checksum; + grub_uint8_t reserved1[7]; + grub_uint16_t sal_a_version; + grub_uint16_t sal_b_version; + grub_uint8_t oem_id[32]; + grub_uint8_t product_id[32]; + grub_uint8_t reserved2[8]; + grub_uint8_t entries[0]; +}; + +enum + { + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_ENTRYPOINT_DESCRIPTOR = 0, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_MEMORY_DESCRIPTOR = 1, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PLATFORM_FEATURES = 2, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_TRANSLATION_REGISTER_DESCRIPTOR = 3, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_PURGE_TRANSLATION_COHERENCE = 4, + GRUB_EFI_SAL_SYSTEM_TABLE_TYPE_AP_WAKEUP = 5 + }; + +struct grub_efi_sal_system_table_entrypoint_descriptor +{ + grub_uint8_t type; + grub_uint8_t pad[7]; + grub_uint64_t pal_proc_addr; + grub_uint64_t sal_proc_addr; + grub_uint64_t global_data_ptr; + grub_uint64_t reserved[2]; +}; + +struct grub_efi_sal_system_table_memory_descriptor +{ + grub_uint8_t type; + grub_uint8_t sal_used; + grub_uint8_t attr; + grub_uint8_t ar; + grub_uint8_t attr_mask; + grub_uint8_t mem_type; + grub_uint8_t usage; + grub_uint8_t unknown; + grub_uint64_t addr; + grub_uint64_t len; + grub_uint64_t unknown2; +}; + +struct grub_efi_sal_system_table_platform_features +{ + grub_uint8_t type; + grub_uint8_t flags; + grub_uint8_t reserved[14]; +}; + +struct grub_efi_sal_system_table_translation_register_descriptor +{ + grub_uint8_t type; + grub_uint8_t register_type; + grub_uint8_t register_number; + grub_uint8_t reserved[5]; + grub_uint64_t addr; + grub_uint64_t page_size; + grub_uint64_t reserver; +}; + +struct grub_efi_sal_system_table_purge_translation_coherence +{ + grub_uint8_t type; + grub_uint8_t reserved[3]; + grub_uint32_t ndomains; + grub_uint64_t coherence; +}; + +struct grub_efi_sal_system_table_ap_wakeup +{ + grub_uint8_t type; + grub_uint8_t mechanism; + grub_uint8_t reserved[6]; + grub_uint64_t vector; +}; + +enum + { + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_BUSLOCK = 1, + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IRQREDIRECT = 2, + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_IPIREDIRECT = 4, + GRUB_EFI_SAL_SYSTEM_TABLE_PLATFORM_FEATURE_ITCDRIFT = 8, + }; + +typedef enum grub_efi_parity_type + { + GRUB_EFI_SERIAL_DEFAULT_PARITY, + GRUB_EFI_SERIAL_NO_PARITY, + GRUB_EFI_SERIAL_EVEN_PARITY, + GRUB_EFI_SERIAL_ODD_PARITY + } +grub_efi_parity_type_t; + +typedef enum grub_efi_stop_bits + { + GRUB_EFI_SERIAL_DEFAULT_STOP_BITS, + GRUB_EFI_SERIAL_1_STOP_BIT, + GRUB_EFI_SERIAL_1_5_STOP_BITS, + GRUB_EFI_SERIAL_2_STOP_BITS + } + grub_efi_stop_bits_t; + +/* Enumerations. */ +enum grub_efi_timer_delay + { + GRUB_EFI_TIMER_CANCEL, + GRUB_EFI_TIMER_PERIODIC, + GRUB_EFI_TIMER_RELATIVE + }; +typedef enum grub_efi_timer_delay grub_efi_timer_delay_t; + +enum grub_efi_allocate_type + { + GRUB_EFI_ALLOCATE_ANY_PAGES, + GRUB_EFI_ALLOCATE_MAX_ADDRESS, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_MAX_ALLOCATION_TYPE + }; +typedef enum grub_efi_allocate_type grub_efi_allocate_type_t; + +enum grub_efi_memory_type + { + GRUB_EFI_RESERVED_MEMORY_TYPE, + GRUB_EFI_LOADER_CODE, + GRUB_EFI_LOADER_DATA, + GRUB_EFI_BOOT_SERVICES_CODE, + GRUB_EFI_BOOT_SERVICES_DATA, + GRUB_EFI_RUNTIME_SERVICES_CODE, + GRUB_EFI_RUNTIME_SERVICES_DATA, + GRUB_EFI_CONVENTIONAL_MEMORY, + GRUB_EFI_UNUSABLE_MEMORY, + GRUB_EFI_ACPI_RECLAIM_MEMORY, + GRUB_EFI_ACPI_MEMORY_NVS, + GRUB_EFI_MEMORY_MAPPED_IO, + GRUB_EFI_MEMORY_MAPPED_IO_PORT_SPACE, + GRUB_EFI_PAL_CODE, + GRUB_EFI_PERSISTENT_MEMORY, + GRUB_EFI_MAX_MEMORY_TYPE + }; +typedef enum grub_efi_memory_type grub_efi_memory_type_t; + +enum grub_efi_interface_type + { + GRUB_EFI_NATIVE_INTERFACE + }; +typedef enum grub_efi_interface_type grub_efi_interface_type_t; + +enum grub_efi_locate_search_type + { + GRUB_EFI_ALL_HANDLES, + GRUB_EFI_BY_REGISTER_NOTIFY, + GRUB_EFI_BY_PROTOCOL + }; +typedef enum grub_efi_locate_search_type grub_efi_locate_search_type_t; + +enum grub_efi_reset_type + { + GRUB_EFI_RESET_COLD, + GRUB_EFI_RESET_WARM, + GRUB_EFI_RESET_SHUTDOWN + }; +typedef enum grub_efi_reset_type grub_efi_reset_type_t; + +/* Types. */ +typedef char grub_efi_boolean_t; +#if GRUB_CPU_SIZEOF_VOID_P == 8 +typedef grub_int64_t grub_efi_intn_t; +typedef grub_uint64_t grub_efi_uintn_t; +#else +typedef grub_int32_t grub_efi_intn_t; +typedef grub_uint32_t grub_efi_uintn_t; +#endif +typedef grub_int8_t grub_efi_int8_t; +typedef grub_uint8_t grub_efi_uint8_t; +typedef grub_int16_t grub_efi_int16_t; +typedef grub_uint16_t grub_efi_uint16_t; +typedef grub_int32_t grub_efi_int32_t; +typedef grub_uint32_t grub_efi_uint32_t; +typedef grub_int64_t grub_efi_int64_t; +typedef grub_uint64_t grub_efi_uint64_t; +typedef grub_uint8_t grub_efi_char8_t; +typedef grub_uint16_t grub_efi_char16_t; + +typedef grub_efi_intn_t grub_efi_status_t; + +#define GRUB_EFI_ERROR_CODE(value) \ + ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) + +#define GRUB_EFI_WARNING_CODE(value) (value) + +#define GRUB_EFI_SUCCESS 0 + +#define GRUB_EFI_LOAD_ERROR GRUB_EFI_ERROR_CODE (1) +#define GRUB_EFI_INVALID_PARAMETER GRUB_EFI_ERROR_CODE (2) +#define GRUB_EFI_UNSUPPORTED GRUB_EFI_ERROR_CODE (3) +#define GRUB_EFI_BAD_BUFFER_SIZE GRUB_EFI_ERROR_CODE (4) +#define GRUB_EFI_BUFFER_TOO_SMALL GRUB_EFI_ERROR_CODE (5) +#define GRUB_EFI_NOT_READY GRUB_EFI_ERROR_CODE (6) +#define GRUB_EFI_DEVICE_ERROR GRUB_EFI_ERROR_CODE (7) +#define GRUB_EFI_WRITE_PROTECTED GRUB_EFI_ERROR_CODE (8) +#define GRUB_EFI_OUT_OF_RESOURCES GRUB_EFI_ERROR_CODE (9) +#define GRUB_EFI_VOLUME_CORRUPTED GRUB_EFI_ERROR_CODE (10) +#define GRUB_EFI_VOLUME_FULL GRUB_EFI_ERROR_CODE (11) +#define GRUB_EFI_NO_MEDIA GRUB_EFI_ERROR_CODE (12) +#define GRUB_EFI_MEDIA_CHANGED GRUB_EFI_ERROR_CODE (13) +#define GRUB_EFI_NOT_FOUND GRUB_EFI_ERROR_CODE (14) +#define GRUB_EFI_ACCESS_DENIED GRUB_EFI_ERROR_CODE (15) +#define GRUB_EFI_NO_RESPONSE GRUB_EFI_ERROR_CODE (16) +#define GRUB_EFI_NO_MAPPING GRUB_EFI_ERROR_CODE (17) +#define GRUB_EFI_TIMEOUT GRUB_EFI_ERROR_CODE (18) +#define GRUB_EFI_NOT_STARTED GRUB_EFI_ERROR_CODE (19) +#define GRUB_EFI_ALREADY_STARTED GRUB_EFI_ERROR_CODE (20) +#define GRUB_EFI_ABORTED GRUB_EFI_ERROR_CODE (21) +#define GRUB_EFI_ICMP_ERROR GRUB_EFI_ERROR_CODE (22) +#define GRUB_EFI_TFTP_ERROR GRUB_EFI_ERROR_CODE (23) +#define GRUB_EFI_PROTOCOL_ERROR GRUB_EFI_ERROR_CODE (24) +#define GRUB_EFI_INCOMPATIBLE_VERSION GRUB_EFI_ERROR_CODE (25) +#define GRUB_EFI_SECURITY_VIOLATION GRUB_EFI_ERROR_CODE (26) +#define GRUB_EFI_CRC_ERROR GRUB_EFI_ERROR_CODE (27) + +#define GRUB_EFI_WARN_UNKNOWN_GLYPH GRUB_EFI_WARNING_CODE (1) +#define GRUB_EFI_WARN_DELETE_FAILURE GRUB_EFI_WARNING_CODE (2) +#define GRUB_EFI_WARN_WRITE_FAILURE GRUB_EFI_WARNING_CODE (3) +#define GRUB_EFI_WARN_BUFFER_TOO_SMALL GRUB_EFI_WARNING_CODE (4) + +typedef void *grub_efi_handle_t; +typedef void *grub_efi_event_t; +typedef grub_efi_uint64_t grub_efi_lba_t; +typedef grub_efi_uintn_t grub_efi_tpl_t; +typedef grub_uint8_t grub_efi_mac_address_t[32]; +typedef grub_uint8_t grub_efi_ipv4_address_t[4]; +typedef grub_uint16_t grub_efi_ipv6_address_t[8]; +typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); +typedef grub_efi_uint64_t grub_efi_physical_address_t; +typedef grub_efi_uint64_t grub_efi_virtual_address_t; + +struct grub_efi_guid +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +} __attribute__ ((aligned(8))); +typedef struct grub_efi_guid grub_efi_guid_t; + +struct grub_efi_packed_guid +{ + grub_uint32_t data1; + grub_uint16_t data2; + grub_uint16_t data3; + grub_uint8_t data4[8]; +} GRUB_PACKED; +typedef struct grub_efi_packed_guid grub_efi_packed_guid_t; + +/* XXX although the spec does not specify the padding, this actually + must have the padding! */ +struct grub_efi_memory_descriptor +{ + grub_efi_uint32_t type; + grub_efi_uint32_t padding; + grub_efi_physical_address_t physical_start; + grub_efi_virtual_address_t virtual_start; + grub_efi_uint64_t num_pages; + grub_efi_uint64_t attribute; +} GRUB_PACKED; +typedef struct grub_efi_memory_descriptor grub_efi_memory_descriptor_t; + +/* Device Path definitions. */ +struct grub_efi_device_path +{ + grub_efi_uint8_t type; + grub_efi_uint8_t subtype; + grub_efi_uint16_t length; +} GRUB_PACKED; +typedef struct grub_efi_device_path grub_efi_device_path_t; +/* XXX EFI does not define EFI_DEVICE_PATH_PROTOCOL but uses it. + It seems to be identical to EFI_DEVICE_PATH. */ +typedef struct grub_efi_device_path grub_efi_device_path_protocol_t; + +#define GRUB_EFI_DEVICE_PATH_TYPE(dp) ((dp)->type & 0x7f) +#define GRUB_EFI_DEVICE_PATH_SUBTYPE(dp) ((dp)->subtype) +#define GRUB_EFI_DEVICE_PATH_LENGTH(dp) ((dp)->length) + +/* The End of Device Path nodes. */ +#define GRUB_EFI_END_DEVICE_PATH_TYPE (0xff & 0x7f) + +#define GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff +#define GRUB_EFI_END_THIS_DEVICE_PATH_SUBTYPE 0x01 + +#define GRUB_EFI_END_ENTIRE_DEVICE_PATH(dp) \ + (GRUB_EFI_DEVICE_PATH_TYPE (dp) == GRUB_EFI_END_DEVICE_PATH_TYPE \ + && (GRUB_EFI_DEVICE_PATH_SUBTYPE (dp) \ + == GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)) + +#define GRUB_EFI_NEXT_DEVICE_PATH(dp) \ + ((grub_efi_device_path_t *) ((char *) (dp) \ + + GRUB_EFI_DEVICE_PATH_LENGTH (dp))) + +/* Hardware Device Path. */ +#define GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE 1 + +#define GRUB_EFI_PCI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_pci_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t function; + grub_efi_uint8_t device; +} GRUB_PACKED; +typedef struct grub_efi_pci_device_path grub_efi_pci_device_path_t; + +#define GRUB_EFI_PCCARD_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_pccard_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t function; +} GRUB_PACKED; +typedef struct grub_efi_pccard_device_path grub_efi_pccard_device_path_t; + +#define GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_memory_mapped_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t memory_type; + grub_efi_physical_address_t start_address; + grub_efi_physical_address_t end_address; +} GRUB_PACKED; +typedef struct grub_efi_memory_mapped_device_path grub_efi_memory_mapped_device_path_t; + +#define GRUB_EFI_VENDOR_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_vendor_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t vendor_guid; + grub_efi_uint8_t vendor_defined_data[0]; +} GRUB_PACKED; +typedef struct grub_efi_vendor_device_path grub_efi_vendor_device_path_t; + +#define GRUB_EFI_CONTROLLER_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_controller_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t controller_number; +} GRUB_PACKED; +typedef struct grub_efi_controller_device_path grub_efi_controller_device_path_t; + +/* ACPI Device Path. */ +#define GRUB_EFI_ACPI_DEVICE_PATH_TYPE 2 + +#define GRUB_EFI_ACPI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_acpi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t hid; + grub_efi_uint32_t uid; +} GRUB_PACKED; +typedef struct grub_efi_acpi_device_path grub_efi_acpi_device_path_t; + +#define GRUB_EFI_EXPANDED_ACPI_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_expanded_acpi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t hid; + grub_efi_uint32_t uid; + grub_efi_uint32_t cid; + char hidstr[0]; +} GRUB_PACKED; +typedef struct grub_efi_expanded_acpi_device_path grub_efi_expanded_acpi_device_path_t; + +#define GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \ + (((grub_efi_expanded_acpi_device_path_t *) dp)->hidstr) +#define GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \ + (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp) \ + + grub_strlen (GRUB_EFI_EXPANDED_ACPI_HIDSTR(dp)) + 1) +#define GRUB_EFI_EXPANDED_ACPI_CIDSTR(dp) \ + (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp) \ + + grub_strlen (GRUB_EFI_EXPANDED_ACPI_UIDSTR(dp)) + 1) + +/* Messaging Device Path. */ +#define GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE 3 + +#define GRUB_EFI_ATAPI_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_atapi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t primary_secondary; + grub_efi_uint8_t slave_master; + grub_efi_uint16_t lun; +} GRUB_PACKED; +typedef struct grub_efi_atapi_device_path grub_efi_atapi_device_path_t; + +#define GRUB_EFI_SCSI_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_scsi_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t pun; + grub_efi_uint16_t lun; +} GRUB_PACKED; +typedef struct grub_efi_scsi_device_path grub_efi_scsi_device_path_t; + +#define GRUB_EFI_FIBRE_CHANNEL_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_fibre_channel_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t wwn; + grub_efi_uint64_t lun; +} GRUB_PACKED; +typedef struct grub_efi_fibre_channel_device_path grub_efi_fibre_channel_device_path_t; + +#define GRUB_EFI_1394_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_1394_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t guid; +} GRUB_PACKED; +typedef struct grub_efi_1394_device_path grub_efi_1394_device_path_t; + +#define GRUB_EFI_USB_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_usb_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint8_t parent_port_number; + grub_efi_uint8_t usb_interface; +} GRUB_PACKED; +typedef struct grub_efi_usb_device_path grub_efi_usb_device_path_t; + +#define GRUB_EFI_USB_CLASS_DEVICE_PATH_SUBTYPE 15 + +struct grub_efi_usb_class_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t vendor_id; + grub_efi_uint16_t product_id; + grub_efi_uint8_t device_class; + grub_efi_uint8_t device_subclass; + grub_efi_uint8_t device_protocol; +} GRUB_PACKED; +typedef struct grub_efi_usb_class_device_path grub_efi_usb_class_device_path_t; + +#define GRUB_EFI_I2O_DEVICE_PATH_SUBTYPE 6 + +struct grub_efi_i2o_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t tid; +} GRUB_PACKED; +typedef struct grub_efi_i2o_device_path grub_efi_i2o_device_path_t; + +#define GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE 11 + +struct grub_efi_mac_address_device_path +{ + grub_efi_device_path_t header; + grub_efi_mac_address_t mac_address; + grub_efi_uint8_t if_type; +} GRUB_PACKED; +typedef struct grub_efi_mac_address_device_path grub_efi_mac_address_device_path_t; + +#define GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE 12 + +struct grub_efi_ipv4_device_path +{ + grub_efi_device_path_t header; + grub_efi_ipv4_address_t local_ip_address; + grub_efi_ipv4_address_t remote_ip_address; + grub_efi_uint16_t local_port; + grub_efi_uint16_t remote_port; + grub_efi_uint16_t protocol; + grub_efi_uint8_t static_ip_address; +} GRUB_PACKED; +typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; + +#define GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE 13 + +struct grub_efi_ipv6_device_path +{ + grub_efi_device_path_t header; + grub_efi_ipv6_address_t local_ip_address; + grub_efi_ipv6_address_t remote_ip_address; + grub_efi_uint16_t local_port; + grub_efi_uint16_t remote_port; + grub_efi_uint16_t protocol; + grub_efi_uint8_t static_ip_address; +} GRUB_PACKED; +typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t; + +#define GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE 9 + +struct grub_efi_infiniband_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t resource_flags; + grub_efi_uint8_t port_gid[16]; + grub_efi_uint64_t remote_id; + grub_efi_uint64_t target_port_id; + grub_efi_uint64_t device_id; +} GRUB_PACKED; +typedef struct grub_efi_infiniband_device_path grub_efi_infiniband_device_path_t; + +#define GRUB_EFI_UART_DEVICE_PATH_SUBTYPE 14 + +struct grub_efi_uart_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t reserved; + grub_efi_uint64_t baud_rate; + grub_efi_uint8_t data_bits; + grub_efi_uint8_t parity; + grub_efi_uint8_t stop_bits; +} GRUB_PACKED; +typedef struct grub_efi_uart_device_path grub_efi_uart_device_path_t; + +#define GRUB_EFI_SATA_DEVICE_PATH_SUBTYPE 18 + +struct grub_efi_sata_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t hba_port; + grub_efi_uint16_t multiplier_port; + grub_efi_uint16_t lun; +} GRUB_PACKED; +typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; + +#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 + +/* Media Device Path. */ +#define GRUB_EFI_MEDIA_DEVICE_PATH_TYPE 4 + +#define GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_hard_drive_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t partition_number; + grub_efi_lba_t partition_start; + grub_efi_lba_t partition_size; + grub_efi_uint8_t partition_signature[16]; + grub_efi_uint8_t partmap_type; + grub_efi_uint8_t signature_type; +} GRUB_PACKED; +typedef struct grub_efi_hard_drive_device_path grub_efi_hard_drive_device_path_t; + +#define GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE 2 + +struct grub_efi_cdrom_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint32_t boot_entry; + grub_efi_lba_t partition_start; + grub_efi_lba_t partition_size; +} GRUB_PACKED; +typedef struct grub_efi_cdrom_device_path grub_efi_cdrom_device_path_t; + +#define GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE 3 + +struct grub_efi_vendor_media_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t vendor_guid; + grub_efi_uint8_t vendor_defined_data[0]; +} GRUB_PACKED; +typedef struct grub_efi_vendor_media_device_path grub_efi_vendor_media_device_path_t; + +#define GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE 4 + +struct grub_efi_file_path_device_path +{ + grub_efi_device_path_t header; + grub_efi_char16_t path_name[0]; +} GRUB_PACKED; +typedef struct grub_efi_file_path_device_path grub_efi_file_path_device_path_t; + +#define GRUB_EFI_PROTOCOL_DEVICE_PATH_SUBTYPE 5 + +struct grub_efi_protocol_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t guid; +} GRUB_PACKED; +typedef struct grub_efi_protocol_device_path grub_efi_protocol_device_path_t; + +#define GRUB_EFI_PIWG_DEVICE_PATH_SUBTYPE 6 + +struct grub_efi_piwg_device_path +{ + grub_efi_device_path_t header; + grub_efi_packed_guid_t guid; +} GRUB_PACKED; +typedef struct grub_efi_piwg_device_path grub_efi_piwg_device_path_t; + + +/* BIOS Boot Specification Device Path. */ +#define GRUB_EFI_BIOS_DEVICE_PATH_TYPE 5 + +#define GRUB_EFI_BIOS_DEVICE_PATH_SUBTYPE 1 + +struct grub_efi_bios_device_path +{ + grub_efi_device_path_t header; + grub_efi_uint16_t device_type; + grub_efi_uint16_t status_flags; + char description[0]; +} GRUB_PACKED; +typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t; + +struct grub_efi_open_protocol_information_entry +{ + grub_efi_handle_t agent_handle; + grub_efi_handle_t controller_handle; + grub_efi_uint32_t attributes; + grub_efi_uint32_t open_count; +}; +typedef struct grub_efi_open_protocol_information_entry grub_efi_open_protocol_information_entry_t; + +struct grub_efi_time +{ + grub_efi_uint16_t year; + grub_efi_uint8_t month; + grub_efi_uint8_t day; + grub_efi_uint8_t hour; + grub_efi_uint8_t minute; + grub_efi_uint8_t second; + grub_efi_uint8_t pad1; + grub_efi_uint32_t nanosecond; + grub_efi_int16_t time_zone; + grub_efi_uint8_t daylight; + grub_efi_uint8_t pad2; +} GRUB_PACKED; +typedef struct grub_efi_time grub_efi_time_t; + +struct grub_efi_time_capabilities +{ + grub_efi_uint32_t resolution; + grub_efi_uint32_t accuracy; + grub_efi_boolean_t sets_to_zero; +}; +typedef struct grub_efi_time_capabilities grub_efi_time_capabilities_t; + +struct grub_efi_input_key +{ + grub_efi_uint16_t scan_code; + grub_efi_char16_t unicode_char; +}; +typedef struct grub_efi_input_key grub_efi_input_key_t; + +typedef grub_efi_uint8_t grub_efi_key_toggle_state_t; +struct grub_efi_key_state +{ + grub_efi_uint32_t key_shift_state; + grub_efi_key_toggle_state_t key_toggle_state; +}; +typedef struct grub_efi_key_state grub_efi_key_state_t; + +#define GRUB_EFI_SHIFT_STATE_VALID 0x80000000 +#define GRUB_EFI_RIGHT_SHIFT_PRESSED 0x00000001 +#define GRUB_EFI_LEFT_SHIFT_PRESSED 0x00000002 +#define GRUB_EFI_RIGHT_CONTROL_PRESSED 0x00000004 +#define GRUB_EFI_LEFT_CONTROL_PRESSED 0x00000008 +#define GRUB_EFI_RIGHT_ALT_PRESSED 0x00000010 +#define GRUB_EFI_LEFT_ALT_PRESSED 0x00000020 +#define GRUB_EFI_RIGHT_LOGO_PRESSED 0x00000040 +#define GRUB_EFI_LEFT_LOGO_PRESSED 0x00000080 +#define GRUB_EFI_MENU_KEY_PRESSED 0x00000100 +#define GRUB_EFI_SYS_REQ_PRESSED 0x00000200 + +#define GRUB_EFI_TOGGLE_STATE_VALID 0x80 +#define GRUB_EFI_KEY_STATE_EXPOSED 0x40 +#define GRUB_EFI_SCROLL_LOCK_ACTIVE 0x01 +#define GRUB_EFI_NUM_LOCK_ACTIVE 0x02 +#define GRUB_EFI_CAPS_LOCK_ACTIVE 0x04 + +struct grub_efi_simple_text_output_mode +{ + grub_efi_int32_t max_mode; + grub_efi_int32_t mode; + grub_efi_int32_t attribute; + grub_efi_int32_t cursor_column; + grub_efi_int32_t cursor_row; + grub_efi_boolean_t cursor_visible; +}; +typedef struct grub_efi_simple_text_output_mode grub_efi_simple_text_output_mode_t; + +/* Tables. */ +struct grub_efi_table_header +{ + grub_efi_uint64_t signature; + grub_efi_uint32_t revision; + grub_efi_uint32_t header_size; + grub_efi_uint32_t crc32; + grub_efi_uint32_t reserved; +}; +typedef struct grub_efi_table_header grub_efi_table_header_t; + +struct grub_efi_boot_services +{ + grub_efi_table_header_t hdr; + + grub_efi_tpl_t + (*raise_tpl) (grub_efi_tpl_t new_tpl); + + void + (*restore_tpl) (grub_efi_tpl_t old_tpl); + + grub_efi_status_t + (*allocate_pages) (grub_efi_allocate_type_t type, + grub_efi_memory_type_t memory_type, + grub_efi_uintn_t pages, + grub_efi_physical_address_t *memory); + + grub_efi_status_t + (*free_pages) (grub_efi_physical_address_t memory, + grub_efi_uintn_t pages); + + grub_efi_status_t + (*get_memory_map) (grub_efi_uintn_t *memory_map_size, + grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t *map_key, + grub_efi_uintn_t *descriptor_size, + grub_efi_uint32_t *descriptor_version); + + grub_efi_status_t + (*allocate_pool) (grub_efi_memory_type_t pool_type, + grub_efi_uintn_t size, + void **buffer); + + grub_efi_status_t + (*free_pool) (void *buffer); + + grub_efi_status_t + (*create_event) (grub_efi_uint32_t type, + grub_efi_tpl_t notify_tpl, + void (*notify_function) (grub_efi_event_t event, + void *context), + void *notify_context, + grub_efi_event_t *event); + + grub_efi_status_t + (*set_timer) (grub_efi_event_t event, + grub_efi_timer_delay_t type, + grub_efi_uint64_t trigger_time); + + grub_efi_status_t + (*wait_for_event) (grub_efi_uintn_t num_events, + grub_efi_event_t *event, + grub_efi_uintn_t *index); + + grub_efi_status_t + (*signal_event) (grub_efi_event_t event); + + grub_efi_status_t + (*close_event) (grub_efi_event_t event); + + grub_efi_status_t + (*check_event) (grub_efi_event_t event); + + grub_efi_status_t + (*install_protocol_interface) (grub_efi_handle_t *handle, + grub_efi_guid_t *protocol, + grub_efi_interface_type_t protocol_interface_type, + void *protocol_interface); + + grub_efi_status_t + (*reinstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *old_interface, + void *new_interface); + + grub_efi_status_t + (*uninstall_protocol_interface) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void *protocol_interface); + + grub_efi_status_t + (*handle_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void **protocol_interface); + + void *reserved; + + grub_efi_status_t + (*register_protocol_notify) (grub_efi_guid_t *protocol, + grub_efi_event_t event, + void **registration); + + grub_efi_status_t + (*locate_handle) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *buffer_size, + grub_efi_handle_t *buffer); + + grub_efi_status_t + (*locate_device_path) (grub_efi_guid_t *protocol, + grub_efi_device_path_t **device_path, + grub_efi_handle_t *device); + + grub_efi_status_t + (*install_configuration_table) (grub_efi_guid_t *guid, void *table); + + grub_efi_status_t + (*load_image) (grub_efi_boolean_t boot_policy, + grub_efi_handle_t parent_image_handle, + grub_efi_device_path_t *file_path, + void *source_buffer, + grub_efi_uintn_t source_size, + grub_efi_handle_t *image_handle); + + grub_efi_status_t + (*start_image) (grub_efi_handle_t image_handle, + grub_efi_uintn_t *exit_data_size, + grub_efi_char16_t **exit_data); + + grub_efi_status_t + (*exit) (grub_efi_handle_t image_handle, + grub_efi_status_t exit_status, + grub_efi_uintn_t exit_data_size, + grub_efi_char16_t *exit_data) __attribute__((noreturn)); + + grub_efi_status_t + (*unload_image) (grub_efi_handle_t image_handle); + + grub_efi_status_t + (*exit_boot_services) (grub_efi_handle_t image_handle, + grub_efi_uintn_t map_key); + + grub_efi_status_t + (*get_next_monotonic_count) (grub_efi_uint64_t *count); + + grub_efi_status_t + (*stall) (grub_efi_uintn_t microseconds); + + grub_efi_status_t + (*set_watchdog_timer) (grub_efi_uintn_t timeout, + grub_efi_uint64_t watchdog_code, + grub_efi_uintn_t data_size, + grub_efi_char16_t *watchdog_data); + + grub_efi_status_t + (*connect_controller) (grub_efi_handle_t controller_handle, + grub_efi_handle_t *driver_image_handle, + grub_efi_device_path_protocol_t *remaining_device_path, + grub_efi_boolean_t recursive); + + grub_efi_status_t + (*disconnect_controller) (grub_efi_handle_t controller_handle, + grub_efi_handle_t driver_image_handle, + grub_efi_handle_t child_handle); + + grub_efi_status_t + (*open_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + void **protocol_interface, + grub_efi_handle_t agent_handle, + grub_efi_handle_t controller_handle, + grub_efi_uint32_t attributes); + + grub_efi_status_t + (*close_protocol) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_handle_t agent_handle, + grub_efi_handle_t controller_handle); + + grub_efi_status_t + (*open_protocol_information) (grub_efi_handle_t handle, + grub_efi_guid_t *protocol, + grub_efi_open_protocol_information_entry_t **entry_buffer, + grub_efi_uintn_t *entry_count); + + grub_efi_status_t + (*protocols_per_handle) (grub_efi_handle_t handle, + grub_efi_packed_guid_t ***protocol_buffer, + grub_efi_uintn_t *protocol_buffer_count); + + grub_efi_status_t + (*locate_handle_buffer) (grub_efi_locate_search_type_t search_type, + grub_efi_guid_t *protocol, + void *search_key, + grub_efi_uintn_t *no_handles, + grub_efi_handle_t **buffer); + + grub_efi_status_t + (*locate_protocol) (grub_efi_guid_t *protocol, + void *registration, + void **protocol_interface); + + grub_efi_status_t + (*install_multiple_protocol_interfaces) (grub_efi_handle_t *handle, ...); + + grub_efi_status_t + (*uninstall_multiple_protocol_interfaces) (grub_efi_handle_t handle, ...); + + grub_efi_status_t + (*calculate_crc32) (void *data, + grub_efi_uintn_t data_size, + grub_efi_uint32_t *crc32); + + void + (*copy_mem) (void *destination, void *source, grub_efi_uintn_t length); + + void + (*set_mem) (void *buffer, grub_efi_uintn_t size, grub_efi_uint8_t value); +}; +typedef struct grub_efi_boot_services grub_efi_boot_services_t; + +struct grub_efi_runtime_services +{ + grub_efi_table_header_t hdr; + + grub_efi_status_t + (*get_time) (grub_efi_time_t *time, + grub_efi_time_capabilities_t *capabilities); + + grub_efi_status_t + (*set_time) (grub_efi_time_t *time); + + grub_efi_status_t + (*get_wakeup_time) (grub_efi_boolean_t *enabled, + grub_efi_boolean_t *pending, + grub_efi_time_t *time); + + grub_efi_status_t + (*set_wakeup_time) (grub_efi_boolean_t enabled, + grub_efi_time_t *time); + + grub_efi_status_t + (*set_virtual_address_map) (grub_efi_uintn_t memory_map_size, + grub_efi_uintn_t descriptor_size, + grub_efi_uint32_t descriptor_version, + grub_efi_memory_descriptor_t *virtual_map); + + grub_efi_status_t + (*convert_pointer) (grub_efi_uintn_t debug_disposition, void **address); + +#define GRUB_EFI_GLOBAL_VARIABLE_GUID \ + { 0x8BE4DF61, 0x93CA, 0x11d2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B,0x8C }} + + + grub_efi_status_t + (*get_variable) (grub_efi_char16_t *variable_name, + const grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t *attributes, + grub_efi_uintn_t *data_size, + void *data); + + grub_efi_status_t + (*get_next_variable_name) (grub_efi_uintn_t *variable_name_size, + grub_efi_char16_t *variable_name, + grub_efi_guid_t *vendor_guid); + + grub_efi_status_t + (*set_variable) (grub_efi_char16_t *variable_name, + const grub_efi_guid_t *vendor_guid, + grub_efi_uint32_t attributes, + grub_efi_uintn_t data_size, + void *data); + + grub_efi_status_t + (*get_next_high_monotonic_count) (grub_efi_uint32_t *high_count); + + void + (*reset_system) (grub_efi_reset_type_t reset_type, + grub_efi_status_t reset_status, + grub_efi_uintn_t data_size, + grub_efi_char16_t *reset_data); +}; +typedef struct grub_efi_runtime_services grub_efi_runtime_services_t; + +struct grub_efi_configuration_table +{ + grub_efi_packed_guid_t vendor_guid; + void *vendor_table; +} GRUB_PACKED; +typedef struct grub_efi_configuration_table grub_efi_configuration_table_t; + +#define GRUB_EFIEMU_SYSTEM_TABLE_SIGNATURE 0x5453595320494249LL +#define GRUB_EFIEMU_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552LL + +struct grub_efi_serial_io_interface +{ + grub_efi_uint32_t revision; + void (*reset) (void); + grub_efi_status_t (*set_attributes) (struct grub_efi_serial_io_interface *this, + grub_efi_uint64_t speed, + grub_efi_uint32_t fifo_depth, + grub_efi_uint32_t timeout, + grub_efi_parity_type_t parity, + grub_uint8_t word_len, + grub_efi_stop_bits_t stop_bits); + grub_efi_status_t (*set_control_bits) (struct grub_efi_serial_io_interface *this, + grub_efi_uint32_t flags); + void (*get_control_bits) (void); + grub_efi_status_t (*write) (struct grub_efi_serial_io_interface *this, + grub_efi_uintn_t *buf_size, + void *buffer); + grub_efi_status_t (*read) (struct grub_efi_serial_io_interface *this, + grub_efi_uintn_t *buf_size, + void *buffer); +}; + +struct grub_efi_simple_input_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_input_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*read_key_stroke) (struct grub_efi_simple_input_interface *this, + grub_efi_input_key_t *key); + + grub_efi_event_t wait_for_key; +}; +typedef struct grub_efi_simple_input_interface grub_efi_simple_input_interface_t; + +struct grub_efi_key_data { + grub_efi_input_key_t key; + grub_efi_key_state_t key_state; +}; +typedef struct grub_efi_key_data grub_efi_key_data_t; + +typedef grub_efi_status_t (*grub_efi_key_notify_function_t) ( + grub_efi_key_data_t *key_data + ); + +struct grub_efi_simple_text_input_ex_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*read_key_stroke) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_key_data_t *key_data); + + grub_efi_event_t wait_for_key; + + grub_efi_status_t + (*set_state) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_key_toggle_state_t *key_toggle_state); + + grub_efi_status_t + (*register_key_notify) (struct grub_efi_simple_text_input_ex_interface *this, + grub_efi_key_data_t *key_data, + grub_efi_key_notify_function_t key_notification_function); + + grub_efi_status_t + (*unregister_key_notify) (struct grub_efi_simple_text_input_ex_interface *this, + void *notification_handle); +}; +typedef struct grub_efi_simple_text_input_ex_interface grub_efi_simple_text_input_ex_interface_t; + +struct grub_efi_simple_text_output_interface +{ + grub_efi_status_t + (*reset) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t extended_verification); + + grub_efi_status_t + (*output_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); + + grub_efi_status_t + (*test_string) (struct grub_efi_simple_text_output_interface *this, + grub_efi_char16_t *string); + + grub_efi_status_t + (*query_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number, + grub_efi_uintn_t *columns, + grub_efi_uintn_t *rows); + + grub_efi_status_t + (*set_mode) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t mode_number); + + grub_efi_status_t + (*set_attributes) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t attribute); + + grub_efi_status_t + (*clear_screen) (struct grub_efi_simple_text_output_interface *this); + + grub_efi_status_t + (*set_cursor_position) (struct grub_efi_simple_text_output_interface *this, + grub_efi_uintn_t column, + grub_efi_uintn_t row); + + grub_efi_status_t + (*enable_cursor) (struct grub_efi_simple_text_output_interface *this, + grub_efi_boolean_t visible); + + grub_efi_simple_text_output_mode_t *mode; +}; +typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; + +typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; + +typedef struct grub_efi_pxe_mode +{ + grub_uint8_t unused[52]; + grub_efi_pxe_packet_t dhcp_discover; + grub_efi_pxe_packet_t dhcp_ack; + grub_efi_pxe_packet_t proxy_offer; + grub_efi_pxe_packet_t pxe_discover; + grub_efi_pxe_packet_t pxe_reply; +} grub_efi_pxe_mode_t; + +typedef struct grub_efi_pxe +{ + grub_uint64_t rev; + void (*start) (void); + void (*stop) (void); + void (*dhcp) (void); + void (*discover) (void); + void (*mftp) (void); + void (*udpwrite) (void); + void (*udpread) (void); + void (*setipfilter) (void); + void (*arp) (void); + void (*setparams) (void); + void (*setstationip) (void); + void (*setpackets) (void); + struct grub_efi_pxe_mode *mode; +} grub_efi_pxe_t; + +#define GRUB_EFI_BLACK 0x00 +#define GRUB_EFI_BLUE 0x01 +#define GRUB_EFI_GREEN 0x02 +#define GRUB_EFI_CYAN 0x03 +#define GRUB_EFI_RED 0x04 +#define GRUB_EFI_MAGENTA 0x05 +#define GRUB_EFI_BROWN 0x06 +#define GRUB_EFI_LIGHTGRAY 0x07 +#define GRUB_EFI_BRIGHT 0x08 +#define GRUB_EFI_DARKGRAY 0x08 +#define GRUB_EFI_LIGHTBLUE 0x09 +#define GRUB_EFI_LIGHTGREEN 0x0A +#define GRUB_EFI_LIGHTCYAN 0x0B +#define GRUB_EFI_LIGHTRED 0x0C +#define GRUB_EFI_LIGHTMAGENTA 0x0D +#define GRUB_EFI_YELLOW 0x0E +#define GRUB_EFI_WHITE 0x0F + +#define GRUB_EFI_BACKGROUND_BLACK 0x00 +#define GRUB_EFI_BACKGROUND_BLUE 0x10 +#define GRUB_EFI_BACKGROUND_GREEN 0x20 +#define GRUB_EFI_BACKGROUND_CYAN 0x30 +#define GRUB_EFI_BACKGROUND_RED 0x40 +#define GRUB_EFI_BACKGROUND_MAGENTA 0x50 +#define GRUB_EFI_BACKGROUND_BROWN 0x60 +#define GRUB_EFI_BACKGROUND_LIGHTGRAY 0x70 + +#define GRUB_EFI_TEXT_ATTR(fg, bg) ((fg) | ((bg))) + +struct grub_efi_system_table +{ + grub_efi_table_header_t hdr; + grub_efi_char16_t *firmware_vendor; + grub_efi_uint32_t firmware_revision; + grub_efi_handle_t console_in_handler; + grub_efi_simple_input_interface_t *con_in; + grub_efi_handle_t console_out_handler; + grub_efi_simple_text_output_interface_t *con_out; + grub_efi_handle_t standard_error_handle; + grub_efi_simple_text_output_interface_t *std_err; + grub_efi_runtime_services_t *runtime_services; + grub_efi_boot_services_t *boot_services; + grub_efi_uintn_t num_table_entries; + grub_efi_configuration_table_t *configuration_table; +}; +typedef struct grub_efi_system_table grub_efi_system_table_t; + +struct grub_efi_loaded_image +{ + grub_efi_uint32_t revision; + grub_efi_handle_t parent_handle; + grub_efi_system_table_t *system_table; + + grub_efi_handle_t device_handle; + grub_efi_device_path_t *file_path; + void *reserved; + + grub_efi_uint32_t load_options_size; + void *load_options; + + void *image_base; + grub_efi_uint64_t image_size; + grub_efi_memory_type_t image_code_type; + grub_efi_memory_type_t image_data_type; + + grub_efi_status_t (*unload) (grub_efi_handle_t image_handle); +}; +typedef struct grub_efi_loaded_image grub_efi_loaded_image_t; + +struct grub_efi_disk_io +{ + grub_efi_uint64_t revision; + grub_efi_status_t (*read) (struct grub_efi_disk_io *this, + grub_efi_uint32_t media_id, + grub_efi_uint64_t offset, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*write) (struct grub_efi_disk_io *this, + grub_efi_uint32_t media_id, + grub_efi_uint64_t offset, + grub_efi_uintn_t buffer_size, + void *buffer); +}; +typedef struct grub_efi_disk_io grub_efi_disk_io_t; + +struct grub_efi_block_io_media +{ + grub_efi_uint32_t media_id; + grub_efi_boolean_t removable_media; + grub_efi_boolean_t media_present; + grub_efi_boolean_t logical_partition; + grub_efi_boolean_t read_only; + grub_efi_boolean_t write_caching; + grub_efi_uint8_t pad[3]; + grub_efi_uint32_t block_size; + grub_efi_uint32_t io_align; + grub_efi_uint8_t pad2[4]; + grub_efi_lba_t last_block; +}; +typedef struct grub_efi_block_io_media grub_efi_block_io_media_t; + +typedef grub_uint8_t grub_efi_mac_t[32]; + +struct grub_efi_simple_network_mode +{ + grub_uint32_t state; + grub_uint32_t hwaddr_size; + grub_uint32_t media_header_size; + grub_uint32_t max_packet_size; + grub_uint32_t nvram_size; + grub_uint32_t nvram_access_size; + grub_uint32_t receive_filter_mask; + grub_uint32_t receive_filter_setting; + grub_uint32_t max_mcast_filter_count; + grub_uint32_t mcast_filter_count; + grub_efi_mac_t mcast_filter[16]; + grub_efi_mac_t current_address; + grub_efi_mac_t broadcast_address; + grub_efi_mac_t permanent_address; + grub_uint8_t if_type; + grub_uint8_t mac_changeable; + grub_uint8_t multitx_supported; + grub_uint8_t media_present_supported; + grub_uint8_t media_present; +}; + +enum + { + GRUB_EFI_NETWORK_STOPPED, + GRUB_EFI_NETWORK_STARTED, + GRUB_EFI_NETWORK_INITIALIZED, + }; + +enum + { + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_UNICAST = 0x01, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST = 0x02, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST = 0x04, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS = 0x08, + GRUB_EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST = 0x10, + }; + +struct grub_efi_simple_network +{ + grub_uint64_t revision; + grub_efi_status_t (*start) (struct grub_efi_simple_network *this); + grub_efi_status_t (*stop) (struct grub_efi_simple_network *this); + grub_efi_status_t (*initialize) (struct grub_efi_simple_network *this, + grub_efi_uintn_t extra_rx, + grub_efi_uintn_t extra_tx); + void (*reset) (void); + grub_efi_status_t (*shutdown) (struct grub_efi_simple_network *this); + grub_efi_status_t (*receive_filters) (struct grub_efi_simple_network *this, + grub_uint32_t enable, + grub_uint32_t disable, + grub_efi_boolean_t reset_mcast_filter, + grub_efi_uintn_t mcast_filter_count, + grub_efi_mac_address_t *mcast_filter); + void (*station_address) (void); + void (*statistics) (void); + void (*mcastiptomac) (void); + void (*nvdata) (void); + grub_efi_status_t (*get_status) (struct grub_efi_simple_network *this, + grub_uint32_t *int_status, + void **txbuf); + grub_efi_status_t (*transmit) (struct grub_efi_simple_network *this, + grub_efi_uintn_t header_size, + grub_efi_uintn_t buffer_size, + void *buffer, + grub_efi_mac_t *src_addr, + grub_efi_mac_t *dest_addr, + grub_efi_uint16_t *protocol); + grub_efi_status_t (*receive) (struct grub_efi_simple_network *this, + grub_efi_uintn_t *header_size, + grub_efi_uintn_t *buffer_size, + void *buffer, + grub_efi_mac_t *src_addr, + grub_efi_mac_t *dest_addr, + grub_uint16_t *protocol); + void (*waitforpacket) (void); + struct grub_efi_simple_network_mode *mode; +}; +typedef struct grub_efi_simple_network grub_efi_simple_network_t; + + +struct grub_efi_block_io +{ + grub_efi_uint64_t revision; + grub_efi_block_io_media_t *media; + grub_efi_status_t (*reset) (struct grub_efi_block_io *this, + grub_efi_boolean_t extended_verification); + grub_efi_status_t (*read_blocks) (struct grub_efi_block_io *this, + grub_efi_uint32_t media_id, + grub_efi_lba_t lba, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*write_blocks) (struct grub_efi_block_io *this, + grub_efi_uint32_t media_id, + grub_efi_lba_t lba, + grub_efi_uintn_t buffer_size, + void *buffer); + grub_efi_status_t (*flush_blocks) (struct grub_efi_block_io *this); +}; +typedef struct grub_efi_block_io grub_efi_block_io_t; + +#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ + || defined (__aarch64__) || defined(__mips__) || defined (__MINGW64__) || defined (__CYGWIN__) \ + || defined(__riscv) + +#define efi_call_0(func) func() +#define efi_call_1(func, a) func(a) +#define efi_call_2(func, a, b) func(a, b) +#define efi_call_3(func, a, b, c) func(a, b, c) +#define efi_call_4(func, a, b, c, d) func(a, b, c, d) +#define efi_call_5(func, a, b, c, d, e) func(a, b, c, d, e) +#define efi_call_6(func, a, b, c, d, e, f) func(a, b, c, d, e, f) +#define efi_call_7(func, a, b, c, d, e, f, g) func(a, b, c, d, e, f, g) +#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) func(a, b, c, d, e, f, g, h, i, j) + +#else + +#define efi_call_0(func) \ + efi_wrap_0(func) +#define efi_call_1(func, a) \ + efi_wrap_1(func, (grub_uint64_t) (a)) +#define efi_call_2(func, a, b) \ + efi_wrap_2(func, (grub_uint64_t) (a), (grub_uint64_t) (b)) +#define efi_call_3(func, a, b, c) \ + efi_wrap_3(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c)) +#define efi_call_4(func, a, b, c, d) \ + efi_wrap_4(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d)) +#define efi_call_5(func, a, b, c, d, e) \ + efi_wrap_5(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e)) +#define efi_call_6(func, a, b, c, d, e, f) \ + efi_wrap_6(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f)) +#define efi_call_7(func, a, b, c, d, e, f, g) \ + efi_wrap_7(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f), (grub_uint64_t) (g)) +#define efi_call_10(func, a, b, c, d, e, f, g, h, i, j) \ + efi_wrap_10(func, (grub_uint64_t) (a), (grub_uint64_t) (b), \ + (grub_uint64_t) (c), (grub_uint64_t) (d), (grub_uint64_t) (e), \ + (grub_uint64_t) (f), (grub_uint64_t) (g), (grub_uint64_t) (h), \ + (grub_uint64_t) (i), (grub_uint64_t) (j)) + +grub_uint64_t EXPORT_FUNC(efi_wrap_0) (void *func); +grub_uint64_t EXPORT_FUNC(efi_wrap_1) (void *func, grub_uint64_t arg1); +grub_uint64_t EXPORT_FUNC(efi_wrap_2) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2); +grub_uint64_t EXPORT_FUNC(efi_wrap_3) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3); +grub_uint64_t EXPORT_FUNC(efi_wrap_4) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4); +grub_uint64_t EXPORT_FUNC(efi_wrap_5) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5); +grub_uint64_t EXPORT_FUNC(efi_wrap_6) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6); +grub_uint64_t EXPORT_FUNC(efi_wrap_7) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6, grub_uint64_t arg7); +grub_uint64_t EXPORT_FUNC(efi_wrap_10) (void *func, grub_uint64_t arg1, + grub_uint64_t arg2, grub_uint64_t arg3, + grub_uint64_t arg4, grub_uint64_t arg5, + grub_uint64_t arg6, grub_uint64_t arg7, + grub_uint64_t arg8, grub_uint64_t arg9, + grub_uint64_t arg10); +#endif + +#endif /* ! GRUB_EFI_API_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h index 263359db..4abd5db6 100644 --- a/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/efi.h @@ -87,6 +87,7 @@ EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, const grub_efi_device_path_t *dp2); void * EXPORT_FUNC (grub_efi_allocate_iso_buf) (grub_uint64_t size); +void * EXPORT_FUNC (grub_efi_allocate_chain_buf) (grub_uint64_t size); extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h new file mode 100644 index 00000000..5b4a0358 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/efi/pe32.h @@ -0,0 +1,339 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EFI_PE32_HEADER +#define GRUB_EFI_PE32_HEADER 1 + +#include +#include + +/* The MSDOS compatibility stub. This was copied from the output of + objcopy, and it is not necessary to care about what this means. */ +#define GRUB_PE32_MSDOS_STUB \ + { \ + 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, \ + 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, \ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, \ + 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, 0xcd, \ + 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, 0x54, 0x68, \ + 0x69, 0x73, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, \ + 0x61, 0x6d, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, \ + 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6e, \ + 0x20, 0x69, 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, \ + 0x6d, 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, \ + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 \ + } + +#define GRUB_PE32_MSDOS_STUB_SIZE 0x80 + +#define GRUB_PE32_MAGIC 0x5a4d + +/* According to the spec, the minimal alignment is 512 bytes... + But some examples (such as EFI drivers in the Intel + Sample Implementation) use 32 bytes (0x20) instead, and it seems + to be working. + + However, there is firmware showing up in the field now with + page alignment constraints to guarantee that page protection + bits take effect. Because currently existing GRUB code can not + properly distinguish between in-memory and in-file layout, let's + bump all alignment to GRUB_EFI_PAGE_SIZE. */ +#define GRUB_PE32_SECTION_ALIGNMENT GRUB_EFI_PAGE_SIZE +#define GRUB_PE32_FILE_ALIGNMENT GRUB_PE32_SECTION_ALIGNMENT + +struct grub_pe32_coff_header +{ + grub_uint16_t machine; + grub_uint16_t num_sections; + grub_uint32_t time; + grub_uint32_t symtab_offset; + grub_uint32_t num_symbols; + grub_uint16_t optional_header_size; + grub_uint16_t characteristics; +}; + +#define GRUB_PE32_MACHINE_I386 0x14c +#define GRUB_PE32_MACHINE_MIPS 0x166 +#define GRUB_PE32_MACHINE_IA64 0x200 +#define GRUB_PE32_MACHINE_X86_64 0x8664 +#define GRUB_PE32_MACHINE_ARMTHUMB_MIXED 0x01c2 +#define GRUB_PE32_MACHINE_ARM64 0xAA64 +#define GRUB_PE32_MACHINE_RISCV32 0x5032 +#define GRUB_PE32_MACHINE_RISCV64 0x5064 + +#define GRUB_PE32_RELOCS_STRIPPED 0x0001 +#define GRUB_PE32_EXECUTABLE_IMAGE 0x0002 +#define GRUB_PE32_LINE_NUMS_STRIPPED 0x0004 +#define GRUB_PE32_LOCAL_SYMS_STRIPPED 0x0008 +#define GRUB_PE32_AGGRESSIVE_WS_TRIM 0x0010 +#define GRUB_PE32_LARGE_ADDRESS_AWARE 0x0020 +#define GRUB_PE32_16BIT_MACHINE 0x0040 +#define GRUB_PE32_BYTES_REVERSED_LO 0x0080 +#define GRUB_PE32_32BIT_MACHINE 0x0100 +#define GRUB_PE32_DEBUG_STRIPPED 0x0200 +#define GRUB_PE32_REMOVABLE_RUN_FROM_SWAP 0x0400 +#define GRUB_PE32_SYSTEM 0x1000 +#define GRUB_PE32_DLL 0x2000 +#define GRUB_PE32_UP_SYSTEM_ONLY 0x4000 +#define GRUB_PE32_BYTES_REVERSED_HI 0x8000 + +struct grub_pe32_data_directory +{ + grub_uint32_t rva; + grub_uint32_t size; +}; + +struct grub_pe32_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + + grub_uint32_t data_base; + grub_uint32_t image_base; + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; + + grub_uint32_t stack_reserve_size; + grub_uint32_t stack_commit_size; + grub_uint32_t heap_reserve_size; + grub_uint32_t heap_commit_size; + + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; + +struct grub_pe64_optional_header +{ + grub_uint16_t magic; + grub_uint8_t major_linker_version; + grub_uint8_t minor_linker_version; + grub_uint32_t code_size; + grub_uint32_t data_size; + grub_uint32_t bss_size; + grub_uint32_t entry_addr; + grub_uint32_t code_base; + + grub_uint64_t image_base; + + grub_uint32_t section_alignment; + grub_uint32_t file_alignment; + grub_uint16_t major_os_version; + grub_uint16_t minor_os_version; + grub_uint16_t major_image_version; + grub_uint16_t minor_image_version; + grub_uint16_t major_subsystem_version; + grub_uint16_t minor_subsystem_version; + grub_uint32_t reserved; + grub_uint32_t image_size; + grub_uint32_t header_size; + grub_uint32_t checksum; + grub_uint16_t subsystem; + grub_uint16_t dll_characteristics; + + grub_uint64_t stack_reserve_size; + grub_uint64_t stack_commit_size; + grub_uint64_t heap_reserve_size; + grub_uint64_t heap_commit_size; + + grub_uint32_t loader_flags; + grub_uint32_t num_data_directories; + + /* Data directories. */ + struct grub_pe32_data_directory export_table; + struct grub_pe32_data_directory import_table; + struct grub_pe32_data_directory resource_table; + struct grub_pe32_data_directory exception_table; + struct grub_pe32_data_directory certificate_table; + struct grub_pe32_data_directory base_relocation_table; + struct grub_pe32_data_directory debug; + struct grub_pe32_data_directory architecture; + struct grub_pe32_data_directory global_ptr; + struct grub_pe32_data_directory tls_table; + struct grub_pe32_data_directory load_config_table; + struct grub_pe32_data_directory bound_import; + struct grub_pe32_data_directory iat; + struct grub_pe32_data_directory delay_import_descriptor; + struct grub_pe32_data_directory com_runtime_header; + struct grub_pe32_data_directory reserved_entry; +}; + +#define GRUB_PE32_PE32_MAGIC 0x10b +#define GRUB_PE32_PE64_MAGIC 0x20b + +#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10 + +#define GRUB_PE32_NUM_DATA_DIRECTORIES 16 + +struct grub_pe32_section_table +{ + char name[8]; + grub_uint32_t virtual_size; + grub_uint32_t virtual_address; + grub_uint32_t raw_data_size; + grub_uint32_t raw_data_offset; + grub_uint32_t relocations_offset; + grub_uint32_t line_numbers_offset; + grub_uint16_t num_relocations; + grub_uint16_t num_line_numbers; + grub_uint32_t characteristics; +}; + +#define GRUB_PE32_SCN_CNT_CODE 0x00000020 +#define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040 +#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000 +#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000 +#define GRUB_PE32_SCN_MEM_READ 0x40000000 +#define GRUB_PE32_SCN_MEM_WRITE 0x80000000 + +#define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000 +#define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000 +#define GRUB_PE32_SCN_ALIGN_4BYTES 0x00300000 +#define GRUB_PE32_SCN_ALIGN_8BYTES 0x00400000 +#define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000 +#define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000 +#define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000 + +#define GRUB_PE32_SCN_ALIGN_SHIFT 20 +#define GRUB_PE32_SCN_ALIGN_MASK 7 + +#define GRUB_PE32_SIGNATURE_SIZE 4 + +struct grub_pe32_header +{ + /* This should be filled in with GRUB_PE32_MSDOS_STUB. */ + grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE]; + + /* This is always PE\0\0. */ + char signature[GRUB_PE32_SIGNATURE_SIZE]; + + /* The COFF file header. */ + struct grub_pe32_coff_header coff_header; + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 + /* The Optional header. */ + struct grub_pe64_optional_header optional_header; +#else + /* The Optional header. */ + struct grub_pe32_optional_header optional_header; +#endif +}; + +struct grub_pe32_fixup_block +{ + grub_uint32_t page_rva; + grub_uint32_t block_size; + grub_uint16_t entries[0]; +}; + +#define GRUB_PE32_FIXUP_ENTRY(type, offset) (((type) << 12) | (offset)) + +#define GRUB_PE32_REL_BASED_ABSOLUTE 0 +#define GRUB_PE32_REL_BASED_HIGH 1 +#define GRUB_PE32_REL_BASED_LOW 2 +#define GRUB_PE32_REL_BASED_HIGHLOW 3 +#define GRUB_PE32_REL_BASED_HIGHADJ 4 +#define GRUB_PE32_REL_BASED_MIPS_JMPADDR 5 +#define GRUB_PE32_REL_BASED_MIPS_LOW 6 +#define GRUB_PE32_REL_BASED_MIPS_HIGH 4 +#define GRUB_PE32_REL_BASED_MIPS_HIGHER 7 +#define GRUB_PE32_REL_BASED_MIPS_HIGHEST 8 +#define GRUB_PE32_REL_BASED_ARM_MOV32A 5 +#define GRUB_PE32_REL_BASED_RISCV_HI20 5 +#define GRUB_PE32_REL_BASED_SECTION 6 +#define GRUB_PE32_REL_BASED_REL 7 +#define GRUB_PE32_REL_BASED_ARM_MOV32T 7 +#define GRUB_PE32_REL_BASED_RISCV_LOW12I 7 +#define GRUB_PE32_REL_BASED_RISCV_LOW12S 8 +#define GRUB_PE32_REL_BASED_IA64_IMM64 9 +#define GRUB_PE32_REL_BASED_DIR64 10 +#define GRUB_PE32_REL_BASED_HIGH3ADJ 11 + +struct grub_pe32_symbol +{ + union + { + char short_name[8]; + grub_uint32_t long_name[2]; + }; + + grub_uint32_t value; + grub_uint16_t section; + grub_uint16_t type; + grub_uint8_t storage_class; + grub_uint8_t num_aux; +} GRUB_PACKED; + +#define GRUB_PE32_SYM_CLASS_EXTERNAL 2 +#define GRUB_PE32_SYM_CLASS_STATIC 3 +#define GRUB_PE32_SYM_CLASS_FILE 0x67 + +#define GRUB_PE32_DT_FUNCTION 0x20 + +struct grub_pe32_reloc +{ + grub_uint32_t offset; + grub_uint32_t symtab_index; + grub_uint16_t type; +} GRUB_PACKED; + +#define GRUB_PE32_REL_I386_DIR32 0x6 +#define GRUB_PE32_REL_I386_REL32 0x14 + +#endif /* ! GRUB_EFI_PE32_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/kernel.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/kernel.h new file mode 100644 index 00000000..55c1c128 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/kernel.h @@ -0,0 +1,133 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_HEADER +#define GRUB_KERNEL_HEADER 1 + +#include +#include + +enum +{ + OBJ_TYPE_ELF, + OBJ_TYPE_MEMDISK, + OBJ_TYPE_CONFIG, + OBJ_TYPE_PREFIX, + OBJ_TYPE_PUBKEY, + OBJ_TYPE_DTB +}; + +/* The module header. */ +struct grub_module_header +{ + /* The type of object. */ + grub_uint32_t type; + /* The size of object (including this header). */ + grub_uint32_t size; +}; + +/* "gmim" (GRUB Module Info Magic). */ +#define GRUB_MODULE_MAGIC 0x676d696d + +struct grub_module_info32 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + /* The offset of the modules. */ + grub_uint32_t offset; + /* The size of all modules plus this header. */ + grub_uint32_t size; +}; + +struct grub_module_info64 +{ + /* Magic number so we know we have modules present. */ + grub_uint32_t magic; + grub_uint32_t padding; + /* The offset of the modules. */ + grub_uint64_t offset; + /* The size of all modules plus this header. */ + grub_uint64_t size; +}; + +#ifndef GRUB_UTIL +/* Space isn't reusable on some platforms. */ +/* On Qemu the preload space is readonly. */ +/* On emu there is no preload space. */ +/* On ieee1275 our code assumes that heap is p=v which isn't guaranteed for module space. */ +#if defined (GRUB_MACHINE_QEMU) || defined (GRUB_MACHINE_EMU) \ + || defined (GRUB_MACHINE_EFI) \ + || (defined (GRUB_MACHINE_IEEE1275) && !defined (__sparc__)) +#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 0 +#endif + +#if defined (GRUB_MACHINE_PCBIOS) || defined (GRUB_MACHINE_COREBOOT) \ + || defined (GRUB_MACHINE_MULTIBOOT) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) \ + || defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_ARC) \ + || (defined (__sparc__) && defined (GRUB_MACHINE_IEEE1275)) \ + || defined (GRUB_MACHINE_UBOOT) || defined (GRUB_MACHINE_XEN) \ + || defined(GRUB_MACHINE_XEN_PVH) +/* FIXME: stack is between 2 heap regions. Move it. */ +#define GRUB_KERNEL_PRELOAD_SPACE_REUSABLE 1 +#endif + +#ifndef GRUB_KERNEL_PRELOAD_SPACE_REUSABLE +#error "Please check if preload space is reusable on this platform!" +#endif + +#if GRUB_TARGET_SIZEOF_VOID_P == 8 +#define grub_module_info grub_module_info64 +#else +#define grub_module_info grub_module_info32 +#endif + +extern grub_addr_t EXPORT_VAR (grub_modbase); + +void EXPORT_FUNC(ventoy_env_hook_root)(int hook); + +#define FOR_MODULES(var) for (\ + var = (grub_modbase && ((((struct grub_module_info *) grub_modbase)->magic) == GRUB_MODULE_MAGIC)) ? (struct grub_module_header *) \ + (grub_modbase + (((struct grub_module_info *) grub_modbase)->offset)) : 0;\ + var && (grub_addr_t) var \ + < (grub_modbase + (((struct grub_module_info *) grub_modbase)->size)); \ + var = (struct grub_module_header *) \ + (((grub_uint32_t *) var) + ((((struct grub_module_header *) var)->size + sizeof (grub_addr_t) - 1) / sizeof (grub_addr_t)) * (sizeof (grub_addr_t) / sizeof (grub_uint32_t)))) + +grub_addr_t grub_modules_get_end (void); + +#endif + +/* The start point of the C code. */ +void grub_main (void) __attribute__ ((noreturn)); + +/* The machine-specific initialization. This must initialize memory. */ +void grub_machine_init (void); + +/* The machine-specific finalization. */ +void EXPORT_FUNC(grub_machine_fini) (int flags); + +/* The machine-specific prefix initialization. */ +void +grub_machine_get_bootlocation (char **device, char **path); + +/* Register all the exported symbols. This is automatically generated. */ +void grub_register_exported_symbols (void); + +extern void (*EXPORT_VAR(grub_net_poll_cards_idle)) (void); + +#endif /* ! GRUB_KERNEL_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/menu.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/menu.h new file mode 100644 index 00000000..0acdc2aa --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/menu.h @@ -0,0 +1,119 @@ +/* menu.h - Menu model function prototypes and data structures. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_MENU_HEADER +#define GRUB_MENU_HEADER 1 + +struct bls_entry +{ + struct bls_entry *next; + struct bls_entry *prev; + struct keyval **keyvals; + int nkeyvals; + char *filename; + int visible; +}; + +struct grub_menu_entry_class +{ + char *name; + struct grub_menu_entry_class *next; +}; + +/* The menu entry. */ +struct grub_menu_entry +{ + /* The title name. */ + const char *title; + + /* The identifier. */ + const char *id; + + /* If set means not everybody is allowed to boot this entry. */ + int restricted; + + /* Allowed users. */ + const char *users; + + /* The classes associated with the menu entry: + used to choose an icon or other style attributes. + This is a dummy head node for the linked list, so for an entry E, + E.classes->next is the first class if it is not NULL. */ + struct grub_menu_entry_class *classes; + + /* The sourcecode of the menu entry, used by the editor. */ + const char *sourcecode; + + /* Parameters to be passed to menu definition. */ + int argc; + char **args; + + int hotkey; + + int submenu; + + /* The next element. */ + struct grub_menu_entry *next; + + /* BLS used to populate the entry */ + struct bls_entry *bls; +}; +typedef struct grub_menu_entry *grub_menu_entry_t; + +/* The menu. */ +struct grub_menu +{ + /* The size of a menu. */ + int size; + + /* The list of menu entries. */ + grub_menu_entry_t entry_list; +}; +typedef struct grub_menu *grub_menu_t; + +/* Callback structure menu viewers can use to provide user feedback when + default entries are executed, possibly including fallback entries. */ +typedef struct grub_menu_execute_callback +{ + /* Called immediately before ENTRY is booted. */ + void (*notify_booting) (grub_menu_entry_t entry, void *userdata); + + /* Called when executing one entry has failed, and another entry, ENTRY, will + be executed as a fallback. The implementation of this function should + delay for a period of at least 2 seconds before returning in order to + allow the user time to read the information before it can be lost by + executing ENTRY. */ + void (*notify_fallback) (grub_menu_entry_t entry, void *userdata); + + /* Called when an entry has failed to execute and there is no remaining + fallback entry to attempt. */ + void (*notify_failure) (void *userdata); +} +*grub_menu_execute_callback_t; + +grub_menu_entry_t grub_menu_get_entry (grub_menu_t menu, int no); +int grub_menu_get_timeout (void); +void grub_menu_set_timeout (int timeout); +void grub_menu_entry_run (grub_menu_entry_t entry); +int grub_menu_get_default_entry_index (grub_menu_t menu); + +void grub_menu_init (void); +void grub_menu_fini (void); + +#endif /* GRUB_MENU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h new file mode 100644 index 00000000..062bdf5e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/asm.h @@ -0,0 +1,10 @@ +#ifndef GRUB_MIPS64_ASM_HEADER +#define GRUB_MIPS64_ASM_HEADER 1 + +#define GRUB_ASM_T4 $a4 +#define GRUB_ASM_T5 $a5 +#define GRUB_ASM_SZREG 8 +#define GRUB_ASM_REG_S sd +#define GRUB_ASM_REG_L ld + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/boot.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/boot.h new file mode 100644 index 00000000..e69de29b diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loader.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loader.h new file mode 100644 index 00000000..71a01597 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loader.h @@ -0,0 +1,25 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2006,2007,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_LOADER_MACHINE_HEADER +#define GRUB_LOADER_MACHINE_HEADER 1 + +#include +#include + +#endif /* ! GRUB_LOADER_MACHINE_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loongson.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loongson.h new file mode 100644 index 00000000..180c3a5d --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/loongson.h @@ -0,0 +1,303 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_EFI_LOONGSON_HEADER +#define GRUB_EFI_LOONGSON_HEADER 1 + +#include + +#include + +#define GRUB_EFI_LOONGSON_SMBIOS_TABLE_GUID \ + { 0x4660f721, 0x2ec5, 0x416a, \ + { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ + } + +#define GRUB_EFI_LOONGSON_MMAP_MAX 128 +typedef enum + { + GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW = 1, + GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH, + GRUB_EFI_LOONGSON_MEMORY_RESERVED, + GRUB_EFI_LOONGSON_PCI_IO, + GRUB_EFI_LOONGSON_PCI_MEM, + GRUB_EFI_LOONGSON_CFG_REG, + GRUB_EFI_LOONGSON_VIDEO_ROM, + GRUB_EFI_LOONGSON_ADAPTER_ROM, + GRUB_EFI_LOONGSON_ACPI_TABLE, + GRUB_EFI_LOONGSON_SMBIOS_TABLE, + GRUB_EFI_LOONGSON_UMA_VIDEO_RAM, + GRUB_EFI_LOONGSON_VUMA_VIDEO_RAM, + GRUB_EFI_LOONGSON_SYSTEM_RAM_LOW_DMA, + GRUB_EFI_LOONGSON_SYSTEM_RAM_HIGH_DMA, + GRUB_EFI_LOONGSON_ACPI_NVS, + GRUB_EFI_LOONGSON_MAX_MEMORY_TYPE + } +grub_efi_loongson_memory_type; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint32_t nr_map; /* number of memory_maps */ + grub_uint32_t mem_freq; /* memory frequence */ + struct mem_map { + grub_uint32_t node_id; /* node_id which memory attached to */ + grub_uint32_t mem_type; /* system memory, pci memory, pci io, etc. */ + grub_uint64_t mem_start; /* memory map start address */ + grub_uint32_t mem_size; /* each memory_map size, not the total size */ + } map[GRUB_EFI_LOONGSON_MMAP_MAX]; +} GRUB_PACKED +grub_efi_loongson_memory_map; + +/* + * Capability and feature descriptor structure for MIPS CPU + */ +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint32_t processor_id; /* PRID, e.g. 6305, 6306 */ + grub_uint32_t cputype; /* Loongson_3A/3B, etc. */ + grub_uint32_t total_node; /* num of total numa nodes */ + grub_uint16_t cpu_startup_core_id; /* Boot core id */ + grub_uint16_t reserved_cores_mask; + grub_uint32_t cpu_clock_freq; /* cpu_clock */ + grub_uint32_t nr_cpus; +} GRUB_PACKED +grub_efi_loongson_cpu_info; + +#define GRUB_EFI_LOONGSON_MAX_UARTS 64 + +typedef struct +{ + grub_uint32_t iotype; /* see include/linux/serial_core.h */ + grub_uint32_t uartclk; + grub_uint32_t int_offset; + grub_uint64_t uart_base; +} GRUB_PACKED +grub_efi_loongson_uart_device; + +#define GRUB_EFI_LOONGSON_MAX_SENSORS 64 + +typedef struct +{ + char name[32]; /* a formal name */ + char label[64]; /* a flexible description */ + grub_uint32_t type; /* SENSOR_* */ + grub_uint32_t id; /* instance id of a sensor-class */ + grub_uint32_t fan_policy; + grub_uint32_t fan_percent; /* only for constant speed policy */ + grub_uint64_t base_addr; /* base address of device registers */ +} GRUB_PACKED +grub_efi_loongson_sensor_device; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint32_t ccnuma_smp; /* 0: no numa; 1: has numa */ + grub_uint32_t sing_double_channel; /* 1:single; 2:double */ + grub_uint32_t nr_uarts; + grub_efi_loongson_uart_device uarts[GRUB_EFI_LOONGSON_MAX_UARTS]; + grub_uint32_t nr_sensors; + grub_efi_loongson_sensor_device sensors[GRUB_EFI_LOONGSON_MAX_SENSORS]; + char has_ec; + char ec_name[32]; + grub_uint64_t ec_base_addr; + char has_tcm; + char tcm_name[32]; + grub_uint64_t tcm_base_addr; + grub_uint64_t workarounds; /* see workarounds.h */ +} GRUB_PACKED +grub_efi_loongson_system_info; + +typedef struct +{ + grub_uint16_t vers; + grub_uint16_t size; + grub_uint16_t rtr_bus; + grub_uint16_t rtr_devfn; + grub_uint32_t vendor; + grub_uint32_t device; + grub_uint32_t PIC_type; /* conform use HT or PCI to route to CPU-PIC */ + grub_uint64_t ht_int_bit; /* 3A: 1<<24; 3B: 1<<16 */ + grub_uint64_t ht_enable; /* irqs used in this PIC */ + grub_uint32_t node_id; /* node id: 0x0-0; 0x1-1; 0x10-2; 0x11-3 */ + grub_uint64_t pci_mem_start_addr; + grub_uint64_t pci_mem_end_addr; + grub_uint64_t pci_io_start_addr; + grub_uint64_t pci_io_end_addr; + grub_uint64_t pci_config_addr; + grub_uint32_t dma_mask_bits; +} GRUB_PACKED +grub_efi_loongson_irq_src_routing_table; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint16_t size; + grub_uint8_t flag; + char description[64]; +} GRUB_PACKED +grub_efi_loongson_interface_info; + +#define GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER 128 + +typedef struct +{ + grub_uint64_t start; /* resource start address */ + grub_uint64_t end; /* resource end address */ + char name[64]; + grub_uint32_t flags; +} +grub_efi_loongson_resource; + +/* arch specific additions */ +typedef struct +{ +} +grub_efi_loongson_archdev_data; + +typedef struct +{ + char name[64]; /* hold the device name */ + grub_uint32_t num_resources; /* number of device_resource */ + /* for each device's resource */ + grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; + /* arch specific additions */ + grub_efi_loongson_archdev_data archdata; +} +grub_efi_loongson_board_devices; + +typedef struct +{ + grub_uint16_t vers; /* version */ + char special_name[64]; /* special_atribute_name */ + grub_uint32_t loongson_special_type; /* type of special device */ + /* for each device's resource */ + grub_efi_loongson_resource resource[GRUB_EFI_LOONGSON_MAX_RESOURCE_NUMBER]; +} +grub_efi_loongson_special_attribute; + +typedef struct +{ + grub_uint64_t memory_offset; /* efi_loongson_memory_map struct offset */ + grub_uint64_t cpu_offset; /* efi_loongson_cpuinfo struct offset */ + grub_uint64_t system_offset; /* efi_loongson_system_info struct offset */ + grub_uint64_t irq_offset; /* efi_loongson_irq_src_routing_table struct offset */ + grub_uint64_t interface_offset; /* interface_info struct offset */ + grub_uint64_t special_offset; /* efi_loongson_special_attribute struct offset */ + grub_uint64_t boarddev_table_offset; /* efi_loongson_board_devices offset */ +} +grub_efi_loongson_params; + +typedef struct +{ + grub_uint16_t vers; /* version */ + grub_uint64_t vga_bios; /* vga_bios address */ + grub_efi_loongson_params lp; +} +grub_efi_loongson_smbios_table; + +typedef struct +{ + grub_uint64_t reset_cold; + grub_uint64_t reset_warm; + grub_uint64_t reset_type; + grub_uint64_t shutdown; + grub_uint64_t do_suspend; /* NULL if not support */ +} +grub_efi_loongson_reset_system; + +typedef struct +{ + grub_uint64_t mps; /* MPS table */ + grub_uint64_t acpi; /* ACPI table (IA64 ext 0.71) */ + grub_uint64_t acpi20; /* ACPI table (ACPI 2.0) */ + grub_efi_loongson_smbios_table smbios; /* SM BIOS table */ + grub_uint64_t sal_systab; /* SAL system table */ + grub_uint64_t boot_info; /* boot info table */ +} +grub_efi_loongson; + +typedef struct +{ + grub_efi_loongson efi; + grub_efi_loongson_reset_system reset_system; +} +grub_efi_loongson_boot_params; + +extern grub_uint64_t grub_efi_loongson_reset_system_addr; + +extern void grub_efi_loongson_reset_cold (void); +extern void grub_efi_loongson_reset_warm (void); +extern void grub_efi_loongson_reset_shutdown (void); +extern void grub_efi_loongson_reset_suspend (void); + +void grub_efi_loongson_init (void); +void grub_efi_loongson_fini (void); +void grub_efi_loongson_alloc_boot_params (void); +void grub_efi_loongson_free_boot_params (void); +void * grub_efi_loongson_get_smbios_table (void); + +int EXPORT_FUNC(grub_efi_is_loongson) (void); + +grub_uint8_t +EXPORT_FUNC(grub_efi_loongson_calculatesum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); + +grub_uint8_t +EXPORT_FUNC(grub_efi_loongson_grub_calculatechecksum8) (const grub_uint8_t *Buffer, grub_efi_uintn_t Length); + + +void * +EXPORT_FUNC(grub_efi_loongson_get_boot_params) (void); + +typedef struct _extention_list_hdr{ + grub_uint64_t signature; + grub_uint32_t length; + grub_uint8_t revision; + grub_uint8_t checksum; + struct _extention_list_hdr *next; +}GRUB_PACKED +ext_list; + +typedef struct bootparamsinterface { + grub_uint64_t signature; //{'B', 'P', 'I', '_', '0', '_', '1'} + grub_efi_system_table_t *systemtable; + ext_list *extlist; +}GRUB_PACKED +bootparamsinterface; + +typedef struct { + ext_list header; // {'M', 'E', 'M'} + grub_uint8_t mapcount; + struct GRUB_PACKED memmap { + grub_uint32_t memtype; + grub_uint64_t memstart; + grub_uint64_t memsize; + } map[GRUB_EFI_LOONGSON_MMAP_MAX]; +}GRUB_PACKED +mem_map; + +typedef struct { + ext_list header; // {VBIOS} + grub_uint64_t vbiosaddr; +}GRUB_PACKED +vbios; + +grub_uint32_t +EXPORT_FUNC (grub_efi_loongson_memmap_sort) (struct memmap array[], grub_uint32_t length, mem_map * bpmem, grub_uint32_t index, grub_uint32_t memtype); +#endif /* ! GRUB_EFI_LOONGSON_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/memory.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/memory.h new file mode 100644 index 00000000..2692d833 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/memory.h @@ -0,0 +1,7 @@ +#ifndef GRUB_MEMORY_CPU_HEADER +#include + +//#define GRUB_EFI_MAX_USABLE_ADDRESS 0x980000000fffffffUL +#define GRUB_EFI_MAX_USABLE_ADDRESS 0x98000000ffffffffUL + +#endif /* ! GRUB_MEMORY_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/time.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/efi/time.h new file mode 100644 index 00000000..e69de29b diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/io.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/io.h new file mode 100644 index 00000000..5f341037 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/io.h @@ -0,0 +1,62 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_IO_H +#define GRUB_IO_H 1 + +#include + +typedef grub_addr_t grub_port_t; + +static __inline unsigned char +grub_inb (grub_port_t port) +{ + return *(volatile grub_uint8_t *) port; +} + +static __inline unsigned short int +grub_inw (grub_port_t port) +{ + return *(volatile grub_uint16_t *) port; +} + +static __inline unsigned int +grub_inl (grub_port_t port) +{ + return *(volatile grub_uint32_t *) port; +} + +static __inline void +grub_outb (unsigned char value, grub_port_t port) +{ + *(volatile grub_uint8_t *) port = value; +} + +static __inline void +grub_outw (unsigned short int value, grub_port_t port) +{ + *(volatile grub_uint16_t *) port = value; +} + +static __inline void +grub_outl (unsigned int value, grub_port_t port) +{ + *(volatile grub_uint32_t *) port = value; +} + +#endif /* _SYS_IO_H */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/kernel.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/kernel.h new file mode 100644 index 00000000..909d5397 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/kernel.h @@ -0,0 +1,24 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2005,2006,2007,2008,2009,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_KERNEL_CPU_HEADER +#define GRUB_KERNEL_CPU_HEADER 1 + +#include + +#endif /* ! GRUB_KERNEL_MACHINE_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/memory.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/memory.h new file mode 100644 index 00000000..d322dbd4 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/memory.h @@ -0,0 +1,57 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_MEMORY_CPU_HEADER +#define GRUB_MEMORY_CPU_HEADER 1 + +#ifndef ASM_FILE +#include +#include +#include +#endif + +#ifndef ASM_FILE + +typedef grub_addr_t grub_phys_addr_t; + +static inline grub_phys_addr_t +grub_vtop (void *a) +{ + if (-1 == ((grub_int64_t) a >> 32)) + return ((grub_phys_addr_t) a) & 0x1fffffffUL; + return ((grub_phys_addr_t) a) & 0xffffffffffffUL; +} + +static inline void * +grub_map_memory (grub_phys_addr_t a, grub_size_t size) +{ + if ((a + size) < 0x20000000UL) + return (void *) (a | 0xffffffff80000000UL); +// return (void *) (a | 0x9800000000000000UL); + return (void *) ((a&0x8fffffff) | 0xffffffff00000000UL); +} + +static inline void +grub_unmap_memory (void *a __attribute__ ((unused)), + grub_size_t size __attribute__ ((unused))) +{ +} + +#endif + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/mips.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/mips.h new file mode 100644 index 00000000..a13c709e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/mips.h @@ -0,0 +1,30 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_REGISTERS_CPU_HEADER +#define GRUB_REGISTERS_CPU_HEADER 1 + +#ifdef ASM_FILE +#define GRUB_CPU_REGISTER_WRAP(x) x +#else +#define GRUB_CPU_REGISTER_WRAP(x) #x +#endif + +#define GRUB_CPU_MIPS_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP($9) + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/relocator.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/relocator.h new file mode 100644 index 00000000..88153142 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/relocator.h @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_RELOCATOR_CPU_HEADER +#define GRUB_RELOCATOR_CPU_HEADER 1 + +#include +#include +#include + +struct grub_relocator64_state +{ + /* gpr[0] is ignored since it's hardwired to 0. */ + grub_uint64_t gpr[32]; + /* Register holding target $pc. */ + int jumpreg; +}; + +grub_err_t +grub_relocator64_boot (struct grub_relocator *rel, + struct grub_relocator64_state state); + +#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/setjmp.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/setjmp.h new file mode 100644 index 00000000..d9a0776b --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/setjmp.h @@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2004,2006,2007,2009,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_SETJMP_CPU_HEADER +#define GRUB_SETJMP_CPU_HEADER 1 + +typedef grub_uint64_t grub_jmp_buf[12]; + +int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; +void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + +#endif /* ! GRUB_SETJMP_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/time.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/time.h new file mode 100644 index 00000000..c9a73348 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/time.h @@ -0,0 +1,39 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2003,2004,2005,2007,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef KERNEL_CPU_TIME_HEADER +#define KERNEL_CPU_TIME_HEADER 1 + +#ifndef GRUB_UTIL + +#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) + +void grub_timer_init (grub_uint32_t cpuclock); + +/* Return the real time in ticks. */ +grub_uint64_t grub_get_rtc (void); + +extern grub_uint32_t grub_arch_cpuclock; +#endif + +static inline void +grub_cpu_idle(void) +{ +} + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/types.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/types.h new file mode 100644 index 00000000..fc896c83 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/mips64/types.h @@ -0,0 +1,38 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2006,2007,2009,2017 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_TYPES_CPU_HEADER +#define GRUB_TYPES_CPU_HEADER 1 + +/* The size of void *. */ +#define GRUB_TARGET_SIZEOF_VOID_P 8 + +/* The size of long. */ +#define GRUB_TARGET_SIZEOF_LONG 8 + +#ifdef GRUB_CPU_MIPS64EL +/* mips64EL is little-endian. */ +#undef GRUB_TARGET_WORDS_BIGENDIAN +#elif defined (GRUB_CPU_MIPS64) +/* mips64 is big-endian. */ +#define GRUB_TARGET_WORDS_BIGENDIAN +#elif !defined (GRUB_SYMBOL_GENERATOR) +#error Neither GRUB_CPU_MIPS64 nor GRUB_CPU_MIPS64EL is defined +#endif + +#endif /* ! GRUB_TYPES_CPU_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/misc.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/misc.h new file mode 100644 index 00000000..ec48e717 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/misc.h @@ -0,0 +1,466 @@ +/* misc.h - prototypes for misc functions */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_MISC_HEADER +#define GRUB_MISC_HEADER 1 + +#include +#include +#include +#include +#include +#include + +#define ALIGN_UP(addr, align) \ + ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1)) +#define ALIGN_UP_OVERHEAD(addr, align) ((-(addr)) & ((typeof (addr)) (align) - 1)) +#define ALIGN_DOWN(addr, align) \ + ((addr) & ~((typeof (addr)) align - 1)) +#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) +#define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } + +#define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) + +void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); +char *EXPORT_FUNC(grub_strcpy) (char *dest, const char *src); + +static inline char * +grub_strncpy (char *dest, const char *src, int c) +{ + char *p = dest; + + while ((*p++ = *src++) != '\0' && --c) + ; + + return dest; +} + +static inline char * +grub_stpcpy (char *dest, const char *src) +{ + char *d = dest; + const char *s = src; + + do + *d++ = *s; + while (*s++ != '\0'); + + return d - 1; +} + +/* XXX: If grub_memmove is too slow, we must implement grub_memcpy. */ +static inline void * +grub_memcpy (void *dest, const void *src, grub_size_t n) +{ + return grub_memmove (dest, src, n); +} + +#if defined(__x86_64__) && !defined (GRUB_UTIL) +#if defined (__MINGW32__) || defined (__CYGWIN__) || defined (__MINGW64__) +#define GRUB_ASM_ATTR __attribute__ ((sysv_abi)) +#else +#define GRUB_ASM_ATTR +#endif +#endif + +int EXPORT_FUNC(grub_memcmp) (const void *s1, const void *s2, grub_size_t n); +int EXPORT_FUNC(grub_strcmp) (const char *s1, const char *s2); +int EXPORT_FUNC(grub_strncmp) (const char *s1, const char *s2, grub_size_t n); + +char *EXPORT_FUNC(grub_strchr) (const char *s, int c); +char *EXPORT_FUNC(grub_strrchr) (const char *s, int c); +int EXPORT_FUNC(grub_strword) (const char *s, const char *w); + +/* Copied from gnulib. + Written by Bruno Haible , 2005. */ +static inline char * +grub_strstr (const char *haystack, const char *needle) +{ + /* Be careful not to look at the entire extent of haystack or needle + until needed. This is useful because of these two cases: + - haystack may be very long, and a match of needle found early, + - needle may be very long, and not even a short initial segment of + needle may be found in haystack. */ + if (*needle != '\0') + { + /* Speed up the following searches of needle by caching its first + character. */ + char b = *needle++; + + for (;; haystack++) + { + if (*haystack == '\0') + /* No match. */ + return 0; + if (*haystack == b) + /* The first character matches. */ + { + const char *rhaystack = haystack + 1; + const char *rneedle = needle; + + for (;; rhaystack++, rneedle++) + { + if (*rneedle == '\0') + /* Found a match. */ + return (char *) haystack; + if (*rhaystack == '\0') + /* No match. */ + return 0; + if (*rhaystack != *rneedle) + /* Nothing in this round. */ + break; + } + } + } + } + else + return (char *) haystack; +} + +int EXPORT_FUNC(grub_isspace) (int c); + +static inline int +grub_isprint (int c) +{ + return (c >= ' ' && c <= '~'); +} + +static inline int +grub_iscntrl (int c) +{ + return (c >= 0x00 && c <= 0x1F) || c == 0x7F; +} + +static inline int +grub_isalpha (int c) +{ + return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); +} + +static inline int +grub_islower (int c) +{ + return (c >= 'a' && c <= 'z'); +} + +static inline int +grub_isupper (int c) +{ + return (c >= 'A' && c <= 'Z'); +} + +static inline int +grub_isgraph (int c) +{ + return (c >= '!' && c <= '~'); +} + +static inline int +grub_isdigit (int c) +{ + return (c >= '0' && c <= '9'); +} + +static inline int +grub_isxdigit (int c) +{ + return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} + +static inline int +grub_isalnum (int c) +{ + return grub_isalpha (c) || grub_isdigit (c); +} + +static inline int +grub_tolower (int c) +{ + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + + return c; +} + +static inline int +grub_toupper (int c) +{ + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + + return c; +} + +static inline int +grub_strcasecmp (const char *s1, const char *s2) +{ + while (*s1 && *s2) + { + if (grub_tolower ((grub_uint8_t) *s1) + != grub_tolower ((grub_uint8_t) *s2)) + break; + + s1++; + s2++; + } + + return (int) grub_tolower ((grub_uint8_t) *s1) + - (int) grub_tolower ((grub_uint8_t) *s2); +} + +static inline int +grub_strncasecmp (const char *s1, const char *s2, grub_size_t n) +{ + if (n == 0) + return 0; + + while (*s1 && *s2 && --n) + { + if (grub_tolower (*s1) != grub_tolower (*s2)) + break; + + s1++; + s2++; + } + + return (int) grub_tolower ((grub_uint8_t) *s1) + - (int) grub_tolower ((grub_uint8_t) *s2); +} + +unsigned long EXPORT_FUNC(grub_strtoul) (const char *str, char **end, int base); +unsigned long long EXPORT_FUNC(grub_strtoull) (const char *str, char **end, int base); + +static inline long +grub_strtol (const char *str, char **end, int base) +{ + int negative = 0; + unsigned long long magnitude; + + while (*str && grub_isspace (*str)) + str++; + + if (*str == '-') + { + negative = 1; + str++; + } + + magnitude = grub_strtoull (str, end, base); + if (negative) + { + if (magnitude > (unsigned long) GRUB_LONG_MAX + 1) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + return GRUB_LONG_MIN; + } + return -((long) magnitude); + } + else + { + if (magnitude > GRUB_LONG_MAX) + { + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + return GRUB_LONG_MAX; + } + return (long) magnitude; + } +} + +char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT; +char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) WARN_UNUSED_RESULT; +void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n); +grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT; +int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); +int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); + +/* Replace all `ch' characters of `input' with `with' and copy the + result into `output'; return EOS address of `output'. */ +static inline char * +grub_strchrsub (char *output, const char *input, char ch, const char *with) +{ + while (*input) + { + if (*input == ch) + { + grub_strcpy (output, with); + output += grub_strlen (with); + input++; + continue; + } + *output++ = *input++; + } + *output = '\0'; + return output; +} + +extern void (*EXPORT_VAR (grub_xputs)) (const char *str); + +static inline int +grub_puts (const char *s) +{ + const char nl[2] = "\n"; + grub_xputs (s); + grub_xputs (nl); + + return 1; /* Cannot fail. */ +} + +int EXPORT_FUNC(grub_puts_) (const char *s); +void EXPORT_FUNC(grub_real_dprintf) (const char *file, + const int line, + const char *condition, + const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5))); +int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); +int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) + __attribute__ ((format (GNU_PRINTF, 3, 4))); +int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, + va_list args); +char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) + __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; +char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT; +void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); +grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, + grub_uint64_t d, + grub_uint64_t *r); + +/* Must match softdiv group in gentpl.py. */ +#if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \ + (defined(__riscv) && (__riscv_xlen == 32))) +#define GRUB_DIVISION_IN_SOFTWARE 1 +#else +#define GRUB_DIVISION_IN_SOFTWARE 0 +#endif + +/* Some division functions need to be in kernel if compiler generates calls + to them. Otherwise we still need them for consistent tests but they go + into a separate module. */ +#if GRUB_DIVISION_IN_SOFTWARE +#define EXPORT_FUNC_IF_SOFTDIV EXPORT_FUNC +#else +#define EXPORT_FUNC_IF_SOFTDIV(x) x +#endif + +grub_int64_t +EXPORT_FUNC_IF_SOFTDIV(grub_divmod64s) (grub_int64_t n, + grub_int64_t d, + grub_int64_t *r); + +grub_uint32_t +EXPORT_FUNC_IF_SOFTDIV (grub_divmod32) (grub_uint32_t n, + grub_uint32_t d, + grub_uint32_t *r); + +grub_int32_t +EXPORT_FUNC_IF_SOFTDIV (grub_divmod32s) (grub_int32_t n, + grub_int32_t d, + grub_int32_t *r); + +/* Inline functions. */ + +static inline char * +grub_memchr (const void *p, int c, grub_size_t len) +{ + const char *s = (const char *) p; + const char *e = s + len; + + for (; s < e; s++) + if (*s == c) + return (char *) s; + + return 0; +} + + +static inline unsigned int +grub_abs (int x) +{ + if (x < 0) + return (unsigned int) (-x); + else + return (unsigned int) x; +} + +/* Reboot the machine. */ +#if defined (GRUB_MACHINE_EMU) || defined (GRUB_MACHINE_QEMU_MIPS) || \ + defined (GRUB_MACHINE_EFI) +void EXPORT_FUNC(grub_reboot) (void) __attribute__ ((noreturn)); +#else +void grub_reboot (void) __attribute__ ((noreturn)); +#endif + +#if defined (__clang__) && !defined (GRUB_UTIL) +void __attribute__ ((noreturn)) EXPORT_FUNC (abort) (void); +#endif + +#ifdef GRUB_MACHINE_PCBIOS +/* Halt the system, using APM if possible. If NO_APM is true, don't + * use APM even if it is available. */ +void grub_halt (int no_apm) __attribute__ ((noreturn)); +#elif (defined (__mips__) && (_MIPS_SIM != _ABI64)) && !defined (GRUB_MACHINE_EMU) +void EXPORT_FUNC (grub_halt) (void) __attribute__ ((noreturn)); +#else +void grub_halt (void) __attribute__ ((noreturn)); +#endif + +#ifdef GRUB_MACHINE_EMU +/* Flag to check if module loading is available. */ +extern const int EXPORT_VAR(grub_no_modules); +#else +#define grub_no_modules 0 +#endif + +static inline void +grub_error_save (struct grub_error_saved *save) +{ + grub_memcpy (save->errmsg, grub_errmsg, sizeof (save->errmsg)); + save->grub_errno = grub_errno; + grub_errno = GRUB_ERR_NONE; +} + +static inline void +grub_error_load (const struct grub_error_saved *save) +{ + grub_memcpy (grub_errmsg, save->errmsg, sizeof (grub_errmsg)); + grub_errno = save->grub_errno; +} + +#if BOOT_TIME_STATS +struct grub_boot_time +{ + struct grub_boot_time *next; + grub_uint64_t tp; + const char *file; + int line; + char *msg; +}; + +extern struct grub_boot_time *EXPORT_VAR(grub_boot_time_head); + +void EXPORT_FUNC(grub_real_boot_time) (const char *file, + const int line, + const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4))); +#define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__) +#else +#define grub_boot_time(...) +#endif + +#define grub_max(a, b) (((a) > (b)) ? (a) : (b)) +#define grub_min(a, b) (((a) < (b)) ? (a) : (b)) + +#endif /* ! GRUB_MISC_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/normal.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/normal.h new file mode 100644 index 00000000..8839ad85 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/normal.h @@ -0,0 +1,177 @@ +/* normal.h - prototypes for the normal mode */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2006,2007,2008,2009 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_NORMAL_HEADER +#define GRUB_NORMAL_HEADER 1 + +#include +#include +#include +#include +#include +#include +#include + +/* The standard left and right margin for some messages. */ +#define STANDARD_MARGIN 6 + +/* The type of a completion item. */ +enum grub_completion_type + { + GRUB_COMPLETION_TYPE_COMMAND, + GRUB_COMPLETION_TYPE_DEVICE, + GRUB_COMPLETION_TYPE_PARTITION, + GRUB_COMPLETION_TYPE_FILE, + GRUB_COMPLETION_TYPE_ARGUMENT + }; +typedef enum grub_completion_type grub_completion_type_t; + +extern struct grub_menu_viewer grub_normal_text_menu_viewer; +extern int grub_normal_exit_level; + +/* Defined in `main.c'. */ +void grub_enter_normal_mode (const char *config); +void grub_normal_execute (const char *config, int nested, int batch); +struct grub_term_screen_geometry +{ + /* The number of entries shown at a time. */ + int num_entries; + int first_entry_y; + int first_entry_x; + int entry_width; + int timeout_y; + int timeout_lines; + int border; + int right_margin; +}; + +void grub_menu_init_page (int nested, int edit, + struct grub_term_screen_geometry *geo, + struct grub_term_output *term); +void grub_normal_init_page (struct grub_term_output *term, int y); +char *grub_file_getline (grub_file_t file); +void grub_cmdline_run (int nested, int force_auth); + +/* Defined in `cmdline.c'. */ +char *grub_cmdline_get (const char *prompt); +grub_err_t grub_set_history (int newsize); + +/* Defined in `completion.c'. */ +char *grub_normal_do_completion (char *buf, int *restore, + void (*hook) (const char *item, grub_completion_type_t type, int count)); + +/* Defined in `misc.c'. */ +grub_err_t grub_normal_print_device_info (const char *name); + +/* Defined in `color.c'. */ +char *grub_env_write_color_normal (struct grub_env_var *var, const char *val); +char *grub_env_write_color_highlight (struct grub_env_var *var, const char *val); +int grub_parse_color_name_pair (grub_uint8_t *ret, const char *name); + +/* Defined in `menu_text.c'. */ +void grub_wait_after_message (void); +void +grub_print_ucs4 (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term); + +void +grub_print_ucs4_menu (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term, + int skip_lines, int max_lines, grub_uint32_t contchar, + struct grub_term_pos *pos); +int +grub_ucs4_count_lines (const grub_uint32_t * str, + const grub_uint32_t * last_position, + int margin_left, int margin_right, + struct grub_term_output *term); +grub_size_t grub_getstringwidth (grub_uint32_t * str, + const grub_uint32_t * last_position, + struct grub_term_output *term); +void grub_print_message_indented (const char *msg, int margin_left, + int margin_right, + struct grub_term_output *term); +void +grub_menu_text_register_instances (int entry, grub_menu_t menu, int nested); +grub_err_t +grub_show_menu (grub_menu_t menu, int nested, int autobooted); + +/* Defined in `handler.c'. */ +void read_handler_list (void); +void free_handler_list (void); + +/* Defined in `dyncmd.c'. */ +void read_command_list (const char *prefix); + +/* Defined in `autofs.c'. */ +void read_fs_list (const char *prefix); + +void grub_context_init (void); +void grub_context_fini (void); + +void read_crypto_list (const char *prefix); + +void read_terminal_list (const char *prefix); + +void grub_set_more (int onoff); + +void grub_normal_reset_more (void); + +void grub_xputs_normal (const char *str); + +extern int grub_extractor_level; + +grub_err_t +grub_normal_add_menu_entry (int argc, const char **args, char **classes, + const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, + int submenu, int *index, struct bls_entry *bls); + +grub_err_t +grub_normal_set_password (const char *user, const char *password); + +void grub_normal_free_menu (grub_menu_t menu); + +void grub_normal_auth_init (void); +void grub_normal_auth_fini (void); + +void +grub_xnputs (const char *str, grub_size_t msg_len); + +grub_command_t +grub_dyncmd_get_cmd (grub_command_t cmd); + +void +grub_gettext_reread_prefix (const char *val); + +enum grub_human_size_type + { + GRUB_HUMAN_SIZE_NORMAL, + GRUB_HUMAN_SIZE_SHORT, + GRUB_HUMAN_SIZE_SPEED, + }; + +const char * +grub_get_human_size (grub_uint64_t size, enum grub_human_size_type type); + +#endif /* ! GRUB_NORMAL_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/serial.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/serial.h new file mode 100644 index 00000000..f8cc4612 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/serial.h @@ -0,0 +1,205 @@ +/* serial.h - serial device interface */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_SERIAL_HEADER +#define GRUB_SERIAL_HEADER 1 + +#include +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) +#include +#endif +#include +#include +#include +#ifdef GRUB_MACHINE_IEEE1275 +#include +#endif +#ifdef GRUB_MACHINE_ARC +#include +#endif + +struct grub_serial_port; +struct grub_serial_config; + +struct grub_serial_driver +{ + grub_err_t (*configure) (struct grub_serial_port *port, + struct grub_serial_config *config); + int (*fetch) (struct grub_serial_port *port); + void (*put) (struct grub_serial_port *port, const int c); + void (*fini) (struct grub_serial_port *port); +}; + +/* The type of parity. */ +typedef enum + { + GRUB_SERIAL_PARITY_NONE, + GRUB_SERIAL_PARITY_ODD, + GRUB_SERIAL_PARITY_EVEN, + } grub_serial_parity_t; + +typedef enum + { + GRUB_SERIAL_STOP_BITS_1, + GRUB_SERIAL_STOP_BITS_1_5, + GRUB_SERIAL_STOP_BITS_2, + } grub_serial_stop_bits_t; + +struct grub_serial_config +{ + unsigned speed; + int word_len; + grub_serial_parity_t parity; + grub_serial_stop_bits_t stop_bits; + grub_uint64_t base_clock; + int rtscts; +}; + +struct grub_serial_port +{ + struct grub_serial_port *next; + struct grub_serial_port **prev; + char *name; + struct grub_serial_driver *driver; + struct grub_serial_config config; + int configured; + int broken; + + /* This should be void *data but since serial is useful as an early console + when malloc isn't available it's a union. + */ + union + { +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) + grub_port_t port; +#endif + struct + { + grub_usb_device_t usbdev; + int configno; + int interfno; + char buf[64]; + int bufstart, bufend; + struct grub_usb_desc_endp *in_endp; + struct grub_usb_desc_endp *out_endp; + }; + struct grub_escc_descriptor *escc_desc; +#ifdef GRUB_MACHINE_IEEE1275 + struct + { + grub_ieee1275_ihandle_t handle; + struct ofserial_hash_ent *elem; + }; +#endif +#ifdef GRUB_MACHINE_EFI + struct grub_efi_serial_io_interface *interface; +#endif +#ifdef GRUB_MACHINE_ARC + struct + { + grub_arc_fileno_t handle; + int handle_valid; + }; +#endif + }; + grub_term_output_t term_out; + grub_term_input_t term_in; +}; + +grub_err_t EXPORT_FUNC(grub_serial_register) (struct grub_serial_port *port); + +void EXPORT_FUNC(grub_serial_unregister) (struct grub_serial_port *port); + + /* Convenience functions to perform primitive operations on a port. */ +static inline grub_err_t +grub_serial_port_configure (struct grub_serial_port *port, + struct grub_serial_config *config) +{ + return port->driver->configure (port, config); +} + +static inline int +grub_serial_port_fetch (struct grub_serial_port *port) +{ + return port->driver->fetch (port); +} + +static inline void +grub_serial_port_put (struct grub_serial_port *port, const int c) +{ + port->driver->put (port, c); +} + +static inline void +grub_serial_port_fini (struct grub_serial_port *port) +{ + port->driver->fini (port); +} + + /* Set default settings. */ +static inline grub_err_t +grub_serial_config_defaults (struct grub_serial_port *port) +{ + struct grub_serial_config config = + { +#ifdef GRUB_MACHINE_MIPS_LOONGSON + .speed = 115200, + /* On Loongson machines serial port has only 3 wires. */ + .rtscts = 0, +#else + .speed = 9600, + .rtscts = 1, +#endif + .word_len = 8, + .parity = GRUB_SERIAL_PARITY_NONE, + .stop_bits = GRUB_SERIAL_STOP_BITS_1, + .base_clock = 0 + }; + + return port->driver->configure (port, &config); +} + +#if (defined(__mips__) && _MIPS_SIM != _ABI64) || defined (__i386__) || defined (__x86_64__) +void grub_ns8250_init (void); +char *grub_serial_ns8250_add_port (grub_port_t port); +#endif +#ifdef GRUB_MACHINE_IEEE1275 +void grub_ofserial_init (void); +#endif +#ifdef GRUB_MACHINE_EFI +void +grub_efiserial_init (void); +#endif +#ifdef GRUB_MACHINE_ARC +void +grub_arcserial_init (void); +const char * +grub_arcserial_add_port (const char *path); +#endif + +struct grub_serial_port *grub_serial_find (const char *name); +extern struct grub_serial_driver grub_ns8250_driver; +void EXPORT_FUNC(grub_serial_unregister_driver) (struct grub_serial_driver *driver); + +#ifndef GRUB_MACHINE_EMU +extern void grub_serial_init (void); +extern void grub_serial_fini (void); +#endif + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/term.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/term.h new file mode 100644 index 00000000..a2bd7a99 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/term.h @@ -0,0 +1,466 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2005,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_TERM_HEADER +#define GRUB_TERM_HEADER 1 + +#define GRUB_TERM_NO_KEY 0 + +/* Internal codes used by GRUB to represent terminal input. */ +/* Only for keys otherwise not having shifted modification. */ +#define GRUB_TERM_SHIFT 0x01000000 +#define GRUB_TERM_CTRL 0x02000000 +#define GRUB_TERM_ALT 0x04000000 + +/* Keys without associated character. */ +#define GRUB_TERM_EXTENDED 0x00800000 +#define GRUB_TERM_KEY_MASK 0x00ffffff + +#define GRUB_TERM_KEY_LEFT (GRUB_TERM_EXTENDED | 0x4b) +#define GRUB_TERM_KEY_RIGHT (GRUB_TERM_EXTENDED | 0x4d) +#define GRUB_TERM_KEY_UP (GRUB_TERM_EXTENDED | 0x48) +#define GRUB_TERM_KEY_DOWN (GRUB_TERM_EXTENDED | 0x50) +#define GRUB_TERM_KEY_HOME (GRUB_TERM_EXTENDED | 0x47) +#define GRUB_TERM_KEY_END (GRUB_TERM_EXTENDED | 0x4f) +#define GRUB_TERM_KEY_DC (GRUB_TERM_EXTENDED | 0x53) +#define GRUB_TERM_KEY_PPAGE (GRUB_TERM_EXTENDED | 0x49) +#define GRUB_TERM_KEY_NPAGE (GRUB_TERM_EXTENDED | 0x51) +#define GRUB_TERM_KEY_F1 (GRUB_TERM_EXTENDED | 0x3b) +#define GRUB_TERM_KEY_F2 (GRUB_TERM_EXTENDED | 0x3c) +#define GRUB_TERM_KEY_F3 (GRUB_TERM_EXTENDED | 0x3d) +#define GRUB_TERM_KEY_F4 (GRUB_TERM_EXTENDED | 0x3e) +#define GRUB_TERM_KEY_F5 (GRUB_TERM_EXTENDED | 0x3f) +#define GRUB_TERM_KEY_F6 (GRUB_TERM_EXTENDED | 0x40) +#define GRUB_TERM_KEY_F7 (GRUB_TERM_EXTENDED | 0x41) +#define GRUB_TERM_KEY_F8 (GRUB_TERM_EXTENDED | 0x42) +#define GRUB_TERM_KEY_F9 (GRUB_TERM_EXTENDED | 0x43) +#define GRUB_TERM_KEY_F10 (GRUB_TERM_EXTENDED | 0x44) +#define GRUB_TERM_KEY_F11 (GRUB_TERM_EXTENDED | 0x57) +#define GRUB_TERM_KEY_F12 (GRUB_TERM_EXTENDED | 0x58) +#define GRUB_TERM_KEY_INSERT (GRUB_TERM_EXTENDED | 0x52) +#define GRUB_TERM_KEY_CENTER (GRUB_TERM_EXTENDED | 0x4c) + +/* Hex value is used for ESC, since '\e' is nonstandard */ +#define GRUB_TERM_ESC 0x1b +#define GRUB_TERM_TAB '\t' +#define GRUB_TERM_BACKSPACE '\b' + +#define GRUB_PROGRESS_NO_UPDATE -1 +#define GRUB_PROGRESS_FAST 0 +#define GRUB_PROGRESS_SLOW 2 + +#ifndef ASM_FILE + +#include +#include +#include +#include +#include + +/* These are used to represent the various color states we use. */ +typedef enum + { + /* The color used to display all text that does not use the + user defined colors below. */ + GRUB_TERM_COLOR_STANDARD, + /* The user defined colors for normal text. */ + GRUB_TERM_COLOR_NORMAL, + /* The user defined colors for highlighted text. */ + GRUB_TERM_COLOR_HIGHLIGHT + } +grub_term_color_state; + +/* Flags for representing the capabilities of a terminal. */ +/* Some notes about the flags: + - These flags are used by higher-level functions but not terminals + themselves. + - If a terminal is dumb, you may assume that only putchar, getkey and + checkkey are called. + - Some fancy features (setcolorstate, setcolor and setcursor) can be set + to NULL. */ + +/* Set when input characters shouldn't be echoed back. */ +#define GRUB_TERM_NO_ECHO (1 << 0) +/* Set when the editing feature should be disabled. */ +#define GRUB_TERM_NO_EDIT (1 << 1) +/* Set when the terminal cannot do fancy things. */ +#define GRUB_TERM_DUMB (1 << 2) +/* Which encoding does terminal expect stream to be. */ +#define GRUB_TERM_CODE_TYPE_SHIFT 3 +#define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT) +/* Only ASCII characters accepted. */ +#define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT) +/* Expects CP-437 characters (ASCII + pseudographics). */ +#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT) +/* UTF-8 stream in logical order. Usually used for terminals + which just forward the stream to another computer. */ +#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT) +/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */ +#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT) +/* Glyph description in visual order. */ +#define GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS (4 << GRUB_TERM_CODE_TYPE_SHIFT) + + +/* Bitmasks for modifier keys returned by grub_getkeystatus. */ +#define GRUB_TERM_STATUS_RSHIFT (1 << 0) +#define GRUB_TERM_STATUS_LSHIFT (1 << 1) +#define GRUB_TERM_STATUS_RCTRL (1 << 2) +#define GRUB_TERM_STATUS_RALT (1 << 3) +#define GRUB_TERM_STATUS_SCROLL (1 << 4) +#define GRUB_TERM_STATUS_NUM (1 << 5) +#define GRUB_TERM_STATUS_CAPS (1 << 6) +#define GRUB_TERM_STATUS_LCTRL (1 << 8) +#define GRUB_TERM_STATUS_LALT (1 << 9) + +/* Menu-related geometrical constants. */ + +/* The number of columns/lines between messages/borders/etc. */ +#define GRUB_TERM_MARGIN 1 + +/* The number of columns of scroll information. */ +#define GRUB_TERM_SCROLL_WIDTH 1 + +struct grub_term_input +{ + /* The next terminal. */ + struct grub_term_input *next; + struct grub_term_input **prev; + + /* The terminal name. */ + const char *name; + + /* Initialize the terminal. */ + grub_err_t (*init) (struct grub_term_input *term); + + /* Clean up the terminal. */ + grub_err_t (*fini) (struct grub_term_input *term); + + /* Get a character if any input character is available. Otherwise return -1 */ + int (*getkey) (struct grub_term_input *term); + + /* Get keyboard modifier status. */ + int (*getkeystatus) (struct grub_term_input *term); + + void *data; +}; +typedef struct grub_term_input *grub_term_input_t; + +/* Made in a way to fit into uint32_t and so be passed in a register. */ +struct grub_term_coordinate +{ + grub_uint16_t x; + grub_uint16_t y; +}; + +struct grub_term_output +{ + /* The next terminal. */ + struct grub_term_output *next; + struct grub_term_output **prev; + + /* The terminal name. */ + const char *name; + + /* Initialize the terminal. */ + grub_err_t (*init) (struct grub_term_output *term); + + /* Clean up the terminal. */ + grub_err_t (*fini) (struct grub_term_output *term); + + /* Put a character. C is encoded in Unicode. */ + void (*putchar) (struct grub_term_output *term, + const struct grub_unicode_glyph *c); + + /* Get the number of columns occupied by a given character C. C is + encoded in Unicode. */ + grub_size_t (*getcharwidth) (struct grub_term_output *term, + const struct grub_unicode_glyph *c); + + /* Get the screen size. */ + struct grub_term_coordinate (*getwh) (struct grub_term_output *term); + + /* Get the cursor position. The return value is ((X << 8) | Y). */ + struct grub_term_coordinate (*getxy) (struct grub_term_output *term); + + /* Go to the position (X, Y). */ + void (*gotoxy) (struct grub_term_output *term, + struct grub_term_coordinate pos); + + /* Clear the screen. */ + void (*cls) (struct grub_term_output *term); + + /* Set the current color to be used */ + void (*setcolorstate) (struct grub_term_output *term, + grub_term_color_state state); + + /* Turn on/off the cursor. */ + void (*setcursor) (struct grub_term_output *term, int on); + + /* Update the screen. */ + void (*refresh) (struct grub_term_output *term); + + /* gfxterm only: put in fullscreen mode. */ + grub_err_t (*fullscreen) (void); + + /* The feature flags defined above. */ + grub_uint32_t flags; + + /* Progress data. */ + grub_uint32_t progress_update_divisor; + grub_uint32_t progress_update_counter; + + void *data; +}; +typedef struct grub_term_output *grub_term_output_t; + +#define GRUB_TERM_DEFAULT_NORMAL_COLOR 0x07 +#define GRUB_TERM_DEFAULT_HIGHLIGHT_COLOR 0x70 +#define GRUB_TERM_DEFAULT_STANDARD_COLOR 0x07 + +/* Current color state. */ +extern grub_uint8_t EXPORT_VAR(grub_term_normal_color); +extern grub_uint8_t EXPORT_VAR(grub_term_highlight_color); + +extern struct grub_term_output *EXPORT_VAR(grub_term_outputs_disabled); +extern struct grub_term_input *EXPORT_VAR(grub_term_inputs_disabled); +extern struct grub_term_output *EXPORT_VAR(grub_term_outputs); +extern struct grub_term_input *EXPORT_VAR(grub_term_inputs); + +static inline void +grub_term_register_input (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + if (grub_term_inputs) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); + else + { + /* If this is the first terminal, enable automatically. */ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); + } +} + +static inline void +grub_term_register_input_inactive (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs_disabled), + GRUB_AS_LIST (term)); +} + +static inline void +grub_term_register_input_active (const char *name __attribute__ ((unused)), + grub_term_input_t term) +{ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_inputs), GRUB_AS_LIST (term)); +} + +static inline void +grub_term_register_output (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + if (grub_term_outputs) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); + else + { + /* If this is the first terminal, enable automatically. */ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); + } +} + +static inline void +grub_term_register_output_inactive (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs_disabled), + GRUB_AS_LIST (term)); +} + +static inline void +grub_term_register_output_active (const char *name __attribute__ ((unused)), + grub_term_output_t term) +{ + if (! term->init || term->init (term) == GRUB_ERR_NONE) + grub_list_push (GRUB_AS_LIST_P (&grub_term_outputs), + GRUB_AS_LIST (term)); +} + +static inline void +grub_term_unregister_input (grub_term_input_t term) +{ + grub_list_remove (GRUB_AS_LIST (term)); + grub_list_remove (GRUB_AS_LIST (term)); +} + +static inline void +grub_term_unregister_output (grub_term_output_t term) +{ + grub_list_remove (GRUB_AS_LIST (term)); + grub_list_remove (GRUB_AS_LIST (term)); +} + +#define FOR_ACTIVE_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs)) +#define FOR_DISABLED_TERM_INPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_inputs_disabled)) +#define FOR_ACTIVE_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs)) +#define FOR_DISABLED_TERM_OUTPUTS(var) FOR_LIST_ELEMENTS((var), (grub_term_outputs_disabled)) + +void grub_putcode (grub_uint32_t code, struct grub_term_output *term); +int EXPORT_FUNC(grub_getkey) (void); +int EXPORT_FUNC(grub_getkey_noblock) (void); +extern int (*EXPORT_VAR (grub_key_remap))(int key); +void grub_cls (void); +void EXPORT_FUNC(grub_refresh) (void); +void grub_puts_terminal (const char *str, struct grub_term_output *term); +struct grub_term_coordinate *grub_term_save_pos (void); +void grub_term_restore_pos (struct grub_term_coordinate *pos); + +static inline unsigned grub_term_width (struct grub_term_output *term) +{ + return term->getwh(term).x ? : 80; +} + +static inline unsigned grub_term_height (struct grub_term_output *term) +{ + return term->getwh(term).y ? : 24; +} + +static inline struct grub_term_coordinate +grub_term_getxy (struct grub_term_output *term) +{ + return term->getxy (term); +} + +static inline void +grub_term_refresh (struct grub_term_output *term) +{ + if (term->refresh) + term->refresh (term); +} + +static inline void +grub_term_gotoxy (struct grub_term_output *term, struct grub_term_coordinate pos) +{ + term->gotoxy (term, pos); +} + +static inline void +grub_term_setcolorstate (struct grub_term_output *term, + grub_term_color_state state) +{ + if (term->setcolorstate) + term->setcolorstate (term, state); +} + +static inline void +grub_setcolorstate (grub_term_color_state state) +{ + struct grub_term_output *term; + + FOR_ACTIVE_TERM_OUTPUTS(term) + grub_term_setcolorstate (term, state); +} + +/* Turn on/off the cursor. */ +static inline void +grub_term_setcursor (struct grub_term_output *term, int on) +{ + if (term->setcursor) + term->setcursor (term, on); +} + +static inline void +grub_term_cls (struct grub_term_output *term) +{ + if (term->cls) + (term->cls) (term); + else + { + grub_putcode ('\n', term); + grub_term_refresh (term); + } +} + +#if HAVE_FONT_SOURCE + +grub_size_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c); + +#else + +static inline grub_size_t +grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((unused))) +{ + if (grub_unicode_get_comb_type (c->base)) + return 0; + return 1; +} + +#endif + +#define GRUB_TERM_TAB_WIDTH 8 + +static inline grub_size_t +grub_term_getcharwidth (struct grub_term_output *term, + const struct grub_unicode_glyph *c) +{ + if (c->base == '\t') + return GRUB_TERM_TAB_WIDTH; + + if (term->getcharwidth) + return term->getcharwidth (term, c); + else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_LOGICAL) + || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_UTF8_VISUAL) + || ((term->flags & GRUB_TERM_CODE_TYPE_MASK) + == GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS)) + return grub_unicode_estimate_width (c); + else + return 1; +} + +struct grub_term_autoload +{ + struct grub_term_autoload *next; + char *name; + char *modname; +}; + +extern struct grub_term_autoload *grub_term_input_autoload; +extern struct grub_term_autoload *grub_term_output_autoload; + +static inline void +grub_print_spaces (struct grub_term_output *term, int number_spaces) +{ + while (--number_spaces >= 0) + grub_putcode (' ', term); +} + +extern void (*EXPORT_VAR (grub_term_poll_usb)) (int wait_for_completion); + +#define GRUB_TERM_REPEAT_PRE_INTERVAL 400 +#define GRUB_TERM_REPEAT_INTERVAL 50 + +#endif /* ! ASM_FILE */ + +#endif /* ! GRUB_TERM_HEADER */ diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/util/install.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/util/install.h new file mode 100644 index 00000000..58aa50ee --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/util/install.h @@ -0,0 +1,269 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#ifndef GRUB_UTIL_INSTALL_HEADER +#define GRUB_UTIL_INSTALL_HEADER 1 + +#include +#include + +#include +#include +#include + +#define GRUB_INSTALL_OPTIONS \ + { "modules", GRUB_INSTALL_OPTIONS_MODULES, N_("MODULES"), \ + 0, N_("pre-load specified modules MODULES"), 1 }, \ + { "dtb", GRUB_INSTALL_OPTIONS_DTB, N_("FILE"), \ + 0, N_("embed a specific DTB"), 1 }, \ + { "install-modules", GRUB_INSTALL_OPTIONS_INSTALL_MODULES, \ + N_("MODULES"), 0, \ + N_("install only MODULES and their dependencies [default=all]"), 1 }, \ + { "themes", GRUB_INSTALL_OPTIONS_INSTALL_THEMES, N_("THEMES"), \ + 0, N_("install THEMES [default=%s]"), 1 }, \ + { "fonts", GRUB_INSTALL_OPTIONS_INSTALL_FONTS, N_("FONTS"), \ + 0, N_("install FONTS [default=%s]"), 1 }, \ + { "locales", GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, N_("LOCALES"),\ + 0, N_("install only LOCALES [default=all]"), 1 }, \ + { "compress", GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, \ + "no|xz|gz|lzo", 0, \ + N_("compress GRUB files [optional]"), 1 }, \ + {"core-compress", GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, \ + "xz|none|auto", \ + 0, N_("choose the compression to use for core image"), 2}, \ + /* TRANSLATORS: platform here isn't identifier. It can be translated. */ \ + { "directory", 'd', N_("DIR"), 0, \ + N_("use images and modules under DIR [default=%s/]"), 1 }, \ + { "override-directory", GRUB_INSTALL_OPTIONS_DIRECTORY2, \ + N_("DIR"), OPTION_HIDDEN, \ + N_("use images and modules under DIR [default=%s/]"), 1 }, \ + { "locale-directory", GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, \ + N_("DIR"), 0, \ + N_("use translations under DIR [default=%s]"), 1 }, \ + { "themes-directory", GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, \ + N_("DIR"), OPTION_HIDDEN, \ + N_("use themes under DIR [default=%s]"), 1 }, \ + { "grub-mkimage", GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, \ + "FILE", OPTION_HIDDEN, 0, 1 }, \ + /* TRANSLATORS: "embed" is a verb (command description). "*/ \ + { "pubkey", 'k', N_("FILE"), 0, \ + N_("embed FILE as public key for signature checking"), 0}, \ + { "verbose", 'v', 0, 0, \ + N_("print verbose messages."), 1 } + +int +grub_install_parse (int key, char *arg); + +void +grub_install_push_module (const char *val); + +void +grub_install_pop_module (void); + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))); + +enum grub_install_plat + { + GRUB_INSTALL_PLATFORM_I386_PC, + GRUB_INSTALL_PLATFORM_I386_EFI, + GRUB_INSTALL_PLATFORM_I386_QEMU, + GRUB_INSTALL_PLATFORM_I386_COREBOOT, + GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, + GRUB_INSTALL_PLATFORM_I386_IEEE1275, + GRUB_INSTALL_PLATFORM_X86_64_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, + GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, + GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, + GRUB_INSTALL_PLATFORM_MIPSEL_ARC, + GRUB_INSTALL_PLATFORM_MIPS_ARC, + GRUB_INSTALL_PLATFORM_IA64_EFI, + GRUB_INSTALL_PLATFORM_ARM_UBOOT, + GRUB_INSTALL_PLATFORM_ARM_EFI, + GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, + GRUB_INSTALL_PLATFORM_I386_XEN, + GRUB_INSTALL_PLATFORM_X86_64_XEN, + GRUB_INSTALL_PLATFORM_I386_XEN_PVH, + GRUB_INSTALL_PLATFORM_ARM64_EFI, + GRUB_INSTALL_PLATFORM_MIPS64EL_EFI, + GRUB_INSTALL_PLATFORM_ARM_COREBOOT, + GRUB_INSTALL_PLATFORM_RISCV32_EFI, + GRUB_INSTALL_PLATFORM_RISCV64_EFI, + GRUB_INSTALL_PLATFORM_MAX + }; + +enum grub_install_options { + GRUB_INSTALL_OPTIONS_DIRECTORY = 'd', + GRUB_INSTALL_OPTIONS_VERBOSITY = 'v', + GRUB_INSTALL_OPTIONS_MODULES = 0x201, + GRUB_INSTALL_OPTIONS_INSTALL_MODULES, + GRUB_INSTALL_OPTIONS_INSTALL_THEMES, + GRUB_INSTALL_OPTIONS_INSTALL_FONTS, + GRUB_INSTALL_OPTIONS_INSTALL_LOCALES, + GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS, + GRUB_INSTALL_OPTIONS_DIRECTORY2, + GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY, + GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY, + GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE, + GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, + GRUB_INSTALL_OPTIONS_DTB +}; + +extern char *grub_install_source_directory; + +enum grub_install_plat +grub_install_get_target (const char *src); +void +grub_install_mkdir_p (const char *dst); + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid); +char * +grub_install_get_platform_name (enum grub_install_plat platid); + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid); + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid); + +char * +grub_install_get_platforms_string (void); + +typedef enum { + GRUB_COMPRESSION_AUTO, + GRUB_COMPRESSION_NONE, + GRUB_COMPRESSION_XZ, + GRUB_COMPRESSION_LZMA +} grub_compression_t; + +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *format, int note); +void +grub_install_make_image_wrap_file (const char *dir, const char *prefix, + FILE *fp, const char *outname, + char *memdisk_path, + char *config_path, + const char *mkimage_target, int note); + +int +grub_install_copy_file (const char *src, + const char *dst, + int is_critical); + +struct grub_install_image_target_desc; + +void +grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, + const char *outname, char *mods[], + char *memdisk_path, char **pubkey_paths, + size_t npubkeys, + char *config_path, + const struct grub_install_image_target_desc *image_target, + int note, + grub_compression_t comp, const char *dtb_file); + +const struct grub_install_image_target_desc * +grub_install_get_image_target (const char *arg); + +void +grub_util_bios_setup (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy, + int add_rs_codes); +void +grub_util_sparc_setup (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy, + int add_rs_codes); + +char * +grub_install_get_image_targets_string (void); + +const char * +grub_util_get_target_dirname (const struct grub_install_image_target_desc *t); + +void +grub_install_create_envblk_file (const char *name); + +const char * +grub_install_get_default_arm_platform (void); + +const char * +grub_install_get_default_x86_platform (void); + +int +grub_install_register_efi (grub_device_t efidir_grub_dev, + const char *efifile_path, + const char *efi_distributor); + +void +grub_install_register_ieee1275 (int is_prep, const char *install_device, + int partno, const char *relpath); + +void +grub_install_sgi_setup (const char *install_device, + const char *imgfile, const char *destname); + +int +grub_install_compress_gzip (const char *src, const char *dest); +int +grub_install_compress_lzop (const char *src, const char *dest); +int +grub_install_compress_xz (const char *src, const char *dest); + +void +grub_install_get_blocklist (grub_device_t root_dev, + const char *core_path, const char *core_img, + size_t core_size, + void (*callback) (grub_disk_addr_t sector, + unsigned offset, + unsigned length, + void *data), + void *hook_data); + +void +grub_util_create_envblk_file (const char *name); + +void +grub_util_glue_efi (const char *file32, const char *file64, const char *out); + +void +grub_util_render_label (const char *label_font, + const char *label_bgcolor, + const char *label_color, + const char *label_string, + const char *label); + +const char * +grub_util_get_target_name (const struct grub_install_image_target_desc *t); + +extern char *grub_install_copy_buffer; +#define GRUB_INSTALL_COPY_BUFFER_SIZE 1048576 + +#endif diff --git a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h index 5b684b49..11384b25 100644 --- a/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h +++ b/GRUB2/MOD_SRC/grub-2.04/include/grub/ventoy.h @@ -21,7 +21,7 @@ #ifndef __VENTOY_H__ #define __VENTOY_H__ -#define COMPILE_ASSERT(expr) extern char __compile_assert[(expr) ? 1 : -1] +#define COMPILE_ASSERT(a, expr) extern char __compile_assert##a[(expr) ? 1 : -1] #define VENTOY_COMPATIBLE_STR "VENTOY COMPATIBLE" #define VENTOY_COMPATIBLE_STR_LEN 17 @@ -40,6 +40,15 @@ typedef enum ventoy_fs_type ventoy_fs_max }ventoy_fs_type; +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + #pragma pack(1) typedef struct ventoy_guid @@ -62,7 +71,7 @@ typedef struct ventoy_image_location { ventoy_guid guid; - /* image sector size, currently this value is always 2048 */ + /* image sector size, 2048/512 */ grub_uint32_t image_sector_size; /* disk sector size, normally the value is 512 */ @@ -109,29 +118,42 @@ typedef struct ventoy_os_param * * vtoy_reserved[0]: vtoy_break_level * vtoy_reserved[1]: vtoy_debug_level - * vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows + * vtoy_reserved[2]: vtoy_chain_type 0:Linux 1:Windows 2:wimfile * vtoy_reserved[3]: vtoy_iso_format 0:iso9660 1:udf * vtoy_reserved[4]: vtoy_windows_cd_prompt * */ grub_uint8_t vtoy_reserved[32]; // Internal use by ventoy - grub_uint8_t reserved[31]; + grub_uint8_t vtoy_disk_signature[4]; + + grub_uint8_t reserved[27]; }ventoy_os_param; typedef struct ventoy_windows_data { char auto_install_script[384]; - grub_uint8_t reserved[128]; + char injection_archive[384]; + grub_uint8_t reserved[256]; }ventoy_windows_data; +typedef struct ventoy_secure_data +{ + grub_uint8_t magic1[16]; /* VENTOY_GUID */ + grub_uint8_t diskuuid[16]; + grub_uint8_t Checksum[16]; + grub_uint8_t adminSHA256[32]; + grub_uint8_t reserved[4000]; + grub_uint8_t magic2[16]; /* VENTOY_GUID */ +}ventoy_secure_data; #pragma pack() // compile assert check : sizeof(ventoy_os_param) must be 512 -COMPILE_ASSERT(sizeof(ventoy_os_param) == 512); +COMPILE_ASSERT(1,sizeof(ventoy_os_param) == 512); +COMPILE_ASSERT(2,sizeof(ventoy_secure_data) == 4096); @@ -164,6 +186,18 @@ typedef struct ventoy_chain_head grub_uint32_t virt_chunk_num; }ventoy_chain_head; +typedef struct ventoy_image_desc +{ + grub_uint64_t disk_size; + grub_uint64_t part1_size; + grub_uint8_t disk_uuid[16]; + grub_uint8_t disk_signature[4]; + grub_uint32_t img_chunk_count; + /* ventoy_img_chunk list */ +}ventoy_image_desc; + + + typedef struct ventoy_img_chunk { grub_uint32_t img_start_sector; // sector size: 2KB @@ -204,12 +238,14 @@ typedef struct ventoy_img_chunk_list #define ventoy_filt_register grub_file_filter_register -typedef const char * (*grub_env_get_pf)(const char *name); - #pragma pack(1) #define GRUB_FILE_REPLACE_MAGIC 0x1258BEEF +typedef const char * (*grub_env_get_pf)(const char *name); +typedef int (*grub_env_set_pf)(const char *name, const char *val); +typedef int (*grub_env_printf_pf)(const char *fmt, ...); + typedef struct ventoy_grub_param_file_replace { grub_uint32_t magic; @@ -221,16 +257,17 @@ typedef struct ventoy_grub_param_file_replace typedef struct ventoy_grub_param { grub_env_get_pf grub_env_get; - + grub_env_set_pf grub_env_set; ventoy_grub_param_file_replace file_replace; + grub_env_printf_pf grub_env_printf; }ventoy_grub_param; #pragma pack() - int grub_ext_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); int grub_fat_get_file_chunk(grub_uint64_t part_start, grub_file_t file, ventoy_img_chunk_list *chunk_list); void grub_iso9660_set_nojoliet(int nojoliet); +int grub_iso9660_is_joliet(void); grub_uint64_t grub_iso9660_get_last_read_pos(grub_file_t file); grub_uint64_t grub_iso9660_get_last_file_dirent_pos(grub_file_t file); grub_uint64_t grub_udf_get_file_offset(grub_file_t file); diff --git a/GRUB2/MOD_SRC/grub-2.04/install.sh b/GRUB2/MOD_SRC/grub-2.04/install.sh index 1dc952af..5b7175b4 100644 --- a/GRUB2/MOD_SRC/grub-2.04/install.sh +++ b/GRUB2/MOD_SRC/grub-2.04/install.sh @@ -12,19 +12,41 @@ make install PATH=$PATH:$VT_DIR/GRUB2/INSTALL/bin/:$VT_DIR/GRUB2/INSTALL/sbin/ net_modules_legacy="net tftp http" -all_modules_legacy="date drivemap blocklist ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_gpt part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" +all_modules_legacy="file setkey date drivemap blocklist regexp newc vga_text ntldr search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio lspci pci ext2 xfs ventoy chain read halt iso9660 linux16 test true sleep reboot echo videotest videoinfo videotest_checksum video_colors video_cirrus video_bochs vga vbe video_fb font video gettext extcmd terminal linux minicmd help configfile tr trig boot biosdisk disk ls tar squash4 password_pbkdf2 all_video png jpeg part_gpt part_msdos fat exfat ntfs loopback gzio normal udf gfxmenu gfxterm gfxterm_background gfxterm_menu" net_modules_uefi="efinet net tftp http" -all_modules_uefi="blocklist ventoy test search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu" +all_modules_uefi="file setkey blocklist ventoy test true regexp newc search at_keyboard usb_keyboard gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux relocator jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop efi_uga video_bochs video_cirrus video video_fb gfxterm_background gfxterm_menu" + +all_modules_arm64_uefi="file setkey blocklist ventoy test true regexp newc search gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop video video_fb gfxterm_background gfxterm_menu" + +all_modules_mips64el_uefi="file setkey blocklist ventoy test true regexp newc search gcry_md5 hashsum gzio xzio lzopio ext2 xfs read halt sleep serial terminfo png password_pbkdf2 gcry_sha512 pbkdf2 part_gpt part_msdos ls tar squash4 loopback part_apple minicmd diskfilter linux jpeg iso9660 udf hfsplus halt acpi mmap gfxmenu video_colors trig bitmap_scale gfxterm bitmap font fat exfat ntfs fshelp efifwsetup reboot echo configfile normal terminal gettext chain priority_queue bufio datetime cat extcmd crypto gzio boot all_video efi_gop video video_fb gfxterm_background gfxterm_menu" -all_extra_modules="elf macho offsetio regexp file" if [ "$1" = "uefi" ]; then - all_modules="$net_modules_uefi $all_modules_uefi $all_extra_modules" - grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,msdos2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos' + all_modules="$net_modules_uefi $all_modules_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubx64_real.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi + + #grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/bootx64.efi" --format 'x86_64-efi' --compression 'auto' $all_modules_uefi 'fat' 'part_msdos' +elif [ "$1" = "i386efi" ]; then + all_modules="$net_modules_uefi $all_modules_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/grubia32_real.efi" --format 'i386-efi' --compression 'auto' $all_modules_uefi +elif [ "$1" = "arm64" ]; then + all_modules="$net_modules_uefi $all_modules_arm64_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/BOOTAA64.EFI" --format 'arm64-efi' --compression 'auto' $all_modules_arm64_uefi +elif [ "$1" = "mips64el" ]; then + all_modules="$net_modules_uefi $all_modules_mips64el_uefi " + + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/EFI/BOOT/BOOTMIPS.EFI" --format 'mips64el-efi' --compression 'auto' $all_modules_mips64el_uefi else - all_modules="$net_modules_legacy $all_modules_legacy" - grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,msdos2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk' + all_modules="$net_modules_legacy $all_modules_legacy " + grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" --prefix '(,2)/grub' --output "$VT_DIR/INSTALL/grub/i386-pc/core.img" --format 'i386-pc' --compression 'auto' $all_modules_legacy 'fat' 'part_msdos' 'biosdisk' + + #grub-mkimage -v --directory "$VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc" -c "$VT_DIR/LiveCD/GRUB/embed.cfg" --prefix '/EFI/boot' --output "$VT_DIR/LiveCD/GRUB/cdrom.img" --format 'i386-pc-eltorito' --compression 'auto' $all_modules_legacy 'biosdisk' 'iso9660' 'fat' 'part_msdos' + #rm -f $VT_DIR/LiveCD/GRUB/boot_hybrid.img + #cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot_hybrid.img $VT_DIR/LiveCD/GRUB/boot_hybrid.img fi grub-mknetdir --modules="$all_modules" --net-directory=$VT_DIR/GRUB2/PXE --subdir=grub2 --locales=en@quot || exit 1 @@ -33,17 +55,83 @@ if [ "$1" = "uefi" ]; then rm -f $VT_DIR/GRUB2/NBP/core.efi cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 - rm -f $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod - cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/normal.mod $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod || exit 1 + rm -rf $VT_DIR/INSTALL/grub/x86_64-efi + mkdir -p $VT_DIR/INSTALL/grub/x86_64-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/x86_64-efi/normal.mod $VT_DIR/INSTALL/grub/x86_64-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/x86_64-efi/$line $VT_DIR/INSTALL/grub/x86_64-efi/ + fi + done +elif [ "$1" = "i386efi" ]; then + rm -f $VT_DIR/GRUB2/NBP/core.efi + cp -a $VT_DIR/GRUB2/PXE/grub2/i386-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 + + rm -rf $VT_DIR/INSTALL/grub/i386-efi + mkdir -p $VT_DIR/INSTALL/grub/i386-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/i386-efi/normal.mod $VT_DIR/INSTALL/grub/i386-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/i386-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-efi/$line $VT_DIR/INSTALL/grub/i386-efi/ + fi + done +elif [ "$1" = "arm64" ]; then + rm -f $VT_DIR/GRUB2/NBP/core.efi + cp -a $VT_DIR/GRUB2/PXE/grub2/arm64-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 + + rm -rf $VT_DIR/INSTALL/grub/arm64-efi + mkdir -p $VT_DIR/INSTALL/grub/arm64-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/arm64-efi/normal.mod $VT_DIR/INSTALL/grub/arm64-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/arm64-efi/$line $VT_DIR/INSTALL/grub/arm64-efi/ + xz $VT_DIR/INSTALL/grub/arm64-efi/$line + mv $VT_DIR/INSTALL/grub/arm64-efi/${line}.xz $VT_DIR/INSTALL/grub/arm64-efi/${line} + fi + done +elif [ "$1" = "mips64el" ]; then + rm -f $VT_DIR/GRUB2/NBP/core.efi + cp -a $VT_DIR/GRUB2/PXE/grub2/mips64el-efi/core.efi $VT_DIR/GRUB2/NBP/core.efi || exit 1 + + rm -rf $VT_DIR/INSTALL/grub/mips64el-efi + mkdir -p $VT_DIR/INSTALL/grub/mips64el-efi + + cp -a $VT_DIR/GRUB2/PXE/grub2/mips64el-efi/normal.mod $VT_DIR/INSTALL/grub/mips64el-efi/normal.mod || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/mips64el-efi/$line $VT_DIR/INSTALL/grub/mips64el-efi/ + xz $VT_DIR/INSTALL/grub/mips64el-efi/$line + mv $VT_DIR/INSTALL/grub/mips64el-efi/${line}.xz $VT_DIR/INSTALL/grub/mips64el-efi/${line} + fi + done else rm -f $VT_DIR/GRUB2/NBP/core.0 cp -a $VT_DIR/GRUB2/PXE/grub2/i386-pc/core.0 $VT_DIR/GRUB2/NBP/core.0 || exit 1 - for md in $all_extra_modules; do - rm -f $VT_DIR/INSTALL/grub/i386-pc/${md}.mod - cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/${md}.mod $VT_DIR/INSTALL/grub/i386-pc/ - done - rm -f $VT_DIR/INSTALL/grub/i386-pc/boot.img cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/boot.img $VT_DIR/INSTALL/grub/i386-pc/boot.img || exit 1 + + #copy other modules + ls -1 $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/ | egrep '\.(lst|mod)$' | while read line; do + if ! echo $all_modules | grep -q " ${line%.mod} "; then + echo "Copy $line ..." + rm -f $VT_DIR/INSTALL/grub/i386-pc/$line + cp -a $VT_DIR/GRUB2/INSTALL/lib/grub/i386-pc/$line $VT_DIR/INSTALL/grub/i386-pc/ + fi + done fi diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c new file mode 100644 index 00000000..b18d55fd --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-install-common.c @@ -0,0 +1,1000 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +char * +grub_install_help_filter (int key, const char *text, + void *input __attribute__ ((unused))) +{ + switch (key) + { + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + return xasprintf(text, "starfield"); + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + return xasprintf(text, "unicode"); + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + return xasprintf(text, grub_util_get_pkglibdir ()); + case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY: + return xasprintf(text, grub_util_get_localedir ()); + case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY: + return grub_util_path_concat (2, grub_util_get_pkgdatadir (), "themes"); + default: + return (char *) text; + } +} + +#pragma GCC diagnostic error "-Wformat-nonliteral" + +static int (*compress_func) (const char *src, const char *dest) = NULL; +char *grub_install_copy_buffer; +static char *dtb; + +int +grub_install_copy_file (const char *src, + const char *dst, + int is_needed) +{ + grub_util_fd_t in, out; + ssize_t r; + + grub_util_info ("copying `%s' -> `%s'", src, dst); + + in = grub_util_fd_open (src, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (in)) + { + if (is_needed) + grub_util_error (_("cannot open `%s': %s"), src, grub_util_fd_strerror ()); + else + grub_util_info (_("cannot open `%s': %s"), src, grub_util_fd_strerror ()); + return 0; + } + out = grub_util_fd_open (dst, GRUB_UTIL_FD_O_WRONLY + | GRUB_UTIL_FD_O_CREATTRUNC); + if (!GRUB_UTIL_FD_IS_VALID (out)) + { + grub_util_error (_("cannot open `%s': %s"), dst, + grub_util_fd_strerror ()); + grub_util_fd_close (in); + return 0; + } + + if (!grub_install_copy_buffer) + grub_install_copy_buffer = xmalloc (GRUB_INSTALL_COPY_BUFFER_SIZE); + + while (1) + { + r = grub_util_fd_read (in, grub_install_copy_buffer, GRUB_INSTALL_COPY_BUFFER_SIZE); + if (r <= 0) + break; + r = grub_util_fd_write (out, grub_install_copy_buffer, r); + if (r <= 0) + break; + } + if (grub_util_fd_sync (out) < 0) + r = -1; + if (grub_util_fd_close (in) < 0) + r = -1; + if (grub_util_fd_close (out) < 0) + r = -1; + + if (r < 0) + grub_util_error (_("cannot copy `%s' to `%s': %s"), + src, dst, grub_util_fd_strerror ()); + + return 1; +} + +static int +grub_install_compress_file (const char *in_name, + const char *out_name, + int is_needed) +{ + int ret; + + if (!compress_func) + ret = grub_install_copy_file (in_name, out_name, is_needed); + else + { + grub_util_info ("compressing `%s' -> `%s'", in_name, out_name); + ret = !compress_func (in_name, out_name); + if (!ret && is_needed) + grub_util_warn (_("can't compress `%s' to `%s'"), in_name, out_name); + } + + if (!ret && is_needed) + grub_util_error (_("cannot copy `%s' to `%s': %s"), + in_name, out_name, grub_util_fd_strerror ()); + + return ret; +} + +static int +is_path_separator (char c) +{ +#if defined (__MINGW32__) || defined (__CYGWIN__) + if (c == '\\') + return 1; +#endif + if (c == '/') + return 1; + return 0; +} + +void +grub_install_mkdir_p (const char *dst) +{ + char *t = xstrdup (dst); + char *p; + for (p = t; *p; p++) + { + if (is_path_separator (*p)) + { + char s = *p; + *p = '\0'; + grub_util_mkdir (t); + *p = s; + } + } + grub_util_mkdir (t); + free (t); +} + +static void +clean_grub_dir (const char *di) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (di); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + di, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + const char *ext = strrchr (de->d_name, '.'); + if ((ext && (strcmp (ext, ".mod") == 0 + || strcmp (ext, ".lst") == 0 + || strcmp (ext, ".img") == 0 + || strcmp (ext, ".mo") == 0) + && strcmp (de->d_name, "menu.lst") != 0) + || strcmp (de->d_name, "efiemu32.o") == 0 + || strcmp (de->d_name, "efiemu64.o") == 0) + { + char *x = grub_util_path_concat (2, di, de->d_name); + if (grub_util_unlink (x) < 0) + grub_util_error (_("cannot delete `%s': %s"), x, + grub_util_fd_strerror ()); + free (x); + } + } + grub_util_fd_closedir (d); +} + +struct install_list +{ + int is_default; + char **entries; + size_t n_entries; + size_t n_alloc; +}; + +struct install_list install_modules = { 1, 0, 0, 0 }; +struct install_list modules = { 1, 0, 0, 0 }; +struct install_list install_locales = { 1, 0, 0, 0 }; +struct install_list install_fonts = { 1, 0, 0, 0 }; +struct install_list install_themes = { 1, 0, 0, 0 }; +char *grub_install_source_directory = NULL; +char *grub_install_locale_directory = NULL; +char *grub_install_themes_directory = NULL; + +void +grub_install_push_module (const char *val) +{ + modules.is_default = 0; + if (modules.n_entries + 1 >= modules.n_alloc) + { + modules.n_alloc <<= 1; + if (modules.n_alloc < 16) + modules.n_alloc = 16; + modules.entries = xrealloc (modules.entries, + modules.n_alloc * sizeof (*modules.entries)); + } + modules.entries[modules.n_entries++] = xstrdup (val); + modules.entries[modules.n_entries] = NULL; +} + +void +grub_install_pop_module (void) +{ + modules.n_entries--; + free (modules.entries[modules.n_entries]); + modules.entries[modules.n_entries] = NULL; +} + + +static void +handle_install_list (struct install_list *il, const char *val, + int default_all) +{ + const char *ptr; + char **ce; + il->is_default = 0; + free (il->entries); + il->entries = NULL; + il->n_entries = 0; + if (strcmp (val, "all") == 0 && default_all) + { + il->is_default = 1; + return; + } + ptr = val; + while (1) + { + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + il->n_entries++; + } + il->n_alloc = il->n_entries + 1; + il->entries = xmalloc (il->n_alloc * sizeof (il->entries[0])); + ptr = val; + for (ce = il->entries; ; ce++) + { + const char *bptr; + while (*ptr && grub_isspace (*ptr)) + ptr++; + if (!*ptr) + break; + bptr = ptr; + while (*ptr && !grub_isspace (*ptr)) + ptr++; + *ce = xmalloc (ptr - bptr + 1); + memcpy (*ce, bptr, ptr - bptr); + (*ce)[ptr - bptr] = '\0'; + } + *ce = NULL; +} + +static char **pubkeys; +static size_t npubkeys; +static grub_compression_t compression; + +int +grub_install_parse (int key, char *arg) +{ + switch (key) + { + case 'C': + if (grub_strcmp (arg, "xz") == 0) + { +#ifdef HAVE_LIBLZMA + compression = GRUB_COMPRESSION_XZ; +#else + grub_util_error ("%s", + _("grub-mkimage is compiled without XZ support")); +#endif + } + else if (grub_strcmp (arg, "none") == 0) + compression = GRUB_COMPRESSION_NONE; + else if (grub_strcmp (arg, "auto") == 0) + compression = GRUB_COMPRESSION_AUTO; + else + grub_util_error (_("Unknown compression format %s"), arg); + return 1; + case 'k': + pubkeys = xrealloc (pubkeys, + sizeof (pubkeys[0]) + * (npubkeys + 1)); + pubkeys[npubkeys++] = xstrdup (arg); + return 1; + + case GRUB_INSTALL_OPTIONS_VERBOSITY: + verbosity++; + return 1; + + case GRUB_INSTALL_OPTIONS_DIRECTORY: + case GRUB_INSTALL_OPTIONS_DIRECTORY2: + free (grub_install_source_directory); + grub_install_source_directory = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_LOCALE_DIRECTORY: + free (grub_install_locale_directory); + grub_install_locale_directory = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_THEMES_DIRECTORY: + free (grub_install_themes_directory); + grub_install_themes_directory = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_MODULES: + handle_install_list (&install_modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_MODULES: + handle_install_list (&modules, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_LOCALES: + handle_install_list (&install_locales, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_THEMES: + handle_install_list (&install_themes, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_FONTS: + handle_install_list (&install_fonts, arg, 0); + return 1; + case GRUB_INSTALL_OPTIONS_DTB: + if (dtb) + free (dtb); + dtb = xstrdup (arg); + return 1; + case GRUB_INSTALL_OPTIONS_INSTALL_COMPRESS: + if (strcmp (arg, "no") == 0 + || strcmp (arg, "none") == 0) + { + compress_func = NULL; + return 1; + } + if (strcmp (arg, "gz") == 0) + { + compress_func = grub_install_compress_gzip; + return 1; + } + if (strcmp (arg, "xz") == 0) + { + compress_func = grub_install_compress_xz; + return 1; + } + if (strcmp (arg, "lzo") == 0) + { + compress_func = grub_install_compress_lzop; + return 1; + } + grub_util_error (_("Unrecognized compression `%s'"), arg); + case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE: + return 1; + default: + return 0; + } +} + +static int +decompressors (void) +{ + if (compress_func == grub_install_compress_gzip) + { + grub_install_push_module ("gzio"); + return 1; + } + if (compress_func == grub_install_compress_xz) + { + grub_install_push_module ("xzio"); + grub_install_push_module ("gcry_crc"); + return 2; + } + if (compress_func == grub_install_compress_lzop) + { + grub_install_push_module ("lzopio"); + grub_install_push_module ("adler32"); + grub_install_push_module ("gcry_crc"); + return 3; + } + return 0; +} + +void +grub_install_make_image_wrap_file (const char *dir, const char *prefix, + FILE *fp, const char *outname, + char *memdisk_path, + char *config_path, + const char *mkimage_target, int note) +{ + const struct grub_install_image_target_desc *tgt; + const char *const compnames[] = + { + [GRUB_COMPRESSION_AUTO] = "auto", + [GRUB_COMPRESSION_NONE] = "none", + [GRUB_COMPRESSION_XZ] = "xz", + [GRUB_COMPRESSION_LZMA] = "lzma", + }; + grub_size_t slen = 1; + char *s, *p; + char **pk, **md; + int dc = decompressors (); + + if (memdisk_path) + slen += 20 + grub_strlen (memdisk_path); + if (config_path) + slen += 20 + grub_strlen (config_path); + + for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) + slen += 20 + grub_strlen (*pk); + + for (md = modules.entries; *md; md++) + { + slen += 10 + grub_strlen (*md); + } + + p = s = xmalloc (slen); + if (memdisk_path) + { + p = grub_stpcpy (p, "--memdisk '"); + p = grub_stpcpy (p, memdisk_path); + *p++ = '\''; + *p++ = ' '; + } + if (config_path) + { + p = grub_stpcpy (p, "--config '"); + p = grub_stpcpy (p, config_path); + *p++ = '\''; + *p++ = ' '; + } + for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) + { + p = grub_stpcpy (p, "--pubkey '"); + p = grub_stpcpy (p, *pk); + *p++ = '\''; + *p++ = ' '; + } + + for (md = modules.entries; *md; md++) + { + *p++ = '\''; + p = grub_stpcpy (p, *md); + *p++ = '\''; + *p++ = ' '; + } + + *p = '\0'; + + grub_util_info ("grub-mkimage --directory '%s' --prefix '%s'" + " --output '%s' " + " --dtb '%s' " + "--format '%s' --compression '%s' %s %s\n", + dir, prefix, + outname, dtb ? : "", mkimage_target, + compnames[compression], note ? "--note" : "", s); + free (s); + + tgt = grub_install_get_image_target (mkimage_target); + if (!tgt) + grub_util_error (_("unknown target format %s"), mkimage_target); + + grub_install_generate_image (dir, prefix, fp, outname, + modules.entries, memdisk_path, + pubkeys, npubkeys, config_path, tgt, + note, compression, dtb); + while (dc--) + grub_install_pop_module (); +} + +void +grub_install_make_image_wrap (const char *dir, const char *prefix, + const char *outname, char *memdisk_path, + char *config_path, + const char *mkimage_target, int note) +{ + FILE *fp; + + fp = grub_util_fopen (outname, "wb"); + if (! fp) + grub_util_error (_("cannot open `%s': %s"), outname, + strerror (errno)); + grub_install_make_image_wrap_file (dir, prefix, fp, outname, + memdisk_path, config_path, + mkimage_target, note); + if (grub_util_file_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), outname, strerror (errno)); + fclose (fp); +} + +static void +copy_by_ext (const char *srcd, + const char *dstd, + const char *extf, + int req) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (srcd); + if (!d && !req) + return; + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + const char *ext = strrchr (de->d_name, '.'); + if (ext && strcmp (ext, extf) == 0) + { + char *srcf = grub_util_path_concat (2, srcd, de->d_name); + char *dstf = grub_util_path_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + } + grub_util_fd_closedir (d); +} + +static void +copy_all (const char *srcd, + const char *dstd) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (srcd); + if (!d) + grub_util_error (_("cannot open directory `%s': %s"), + srcd, grub_util_fd_strerror ()); + + while ((de = grub_util_fd_readdir (d))) + { + char *srcf; + char *dstf; + if (strcmp (de->d_name, ".") == 0 + || strcmp (de->d_name, "..") == 0) + continue; + srcf = grub_util_path_concat (2, srcd, de->d_name); + if (grub_util_is_special_file (srcf) + || grub_util_is_directory (srcf)) + continue; + dstf = grub_util_path_concat (2, dstd, de->d_name); + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + grub_util_fd_closedir (d); +} + +#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) +static const char * +get_localedir (void) +{ + if (grub_install_locale_directory) + return grub_install_locale_directory; + else + return grub_util_get_localedir (); +} + +static void +copy_locales (const char *dstd) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + const char *locale_dir = get_localedir (); + + d = grub_util_fd_opendir (locale_dir); + if (!d) + { + grub_util_warn (_("cannot open directory `%s': %s"), + locale_dir, grub_util_fd_strerror ()); + return; + } + + while ((de = grub_util_fd_readdir (d))) + { + char *srcf; + char *dstf; + char *ext; + if (strcmp (de->d_name, ".") == 0) + continue; + if (strcmp (de->d_name, "..") == 0) + continue; + ext = grub_strrchr (de->d_name, '.'); + if (ext && (grub_strcmp (ext, ".mo") == 0 + || grub_strcmp (ext, ".gmo") == 0)) + { + srcf = grub_util_path_concat (2, locale_dir, de->d_name); + dstf = grub_util_path_concat (2, dstd, de->d_name); + ext = grub_strrchr (dstf, '.'); + grub_strcpy (ext, ".mo"); + } + else + { + srcf = grub_util_path_concat_ext (4, locale_dir, de->d_name, + "LC_MESSAGES", PACKAGE, ".mo"); + dstf = grub_util_path_concat_ext (2, dstd, de->d_name, ".mo"); + } + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } + grub_util_fd_closedir (d); +} +#endif + +static void +grub_install_copy_nls(const char *src __attribute__ ((unused)), + const char *dst __attribute__ ((unused))) +{ +#if !(defined (GRUB_UTIL) && defined(ENABLE_NLS) && ENABLE_NLS) + char *dst_locale; + + dst_locale = grub_util_path_concat (2, dst, "locale"); + grub_install_mkdir_p (dst_locale); + clean_grub_dir (dst_locale); + + if (install_locales.is_default) + { + char *srcd = grub_util_path_concat (2, src, "po"); + copy_by_ext (srcd, dst_locale, ".mo", 0); + copy_locales (dst_locale); + free (srcd); + } + else + { + size_t i; + const char *locale_dir = get_localedir (); + + for (i = 0; i < install_locales.n_entries; i++) + { + char *srcf = grub_util_path_concat_ext (3, src, "po", + install_locales.entries[i], + ".mo"); + char *dstf = grub_util_path_concat_ext (2, dst_locale, + install_locales.entries[i], + ".mo"); + if (grub_install_compress_file (srcf, dstf, 0)) + { + free (srcf); + free (dstf); + continue; + } + free (srcf); + srcf = grub_util_path_concat_ext (4, locale_dir, + install_locales.entries[i], + "LC_MESSAGES", PACKAGE, ".mo"); + if (grub_install_compress_file (srcf, dstf, 0) == 0) + grub_util_error (_("cannot find locale `%s'"), + install_locales.entries[i]); + free (srcf); + free (dstf); + } + } + free (dst_locale); +#endif +} + +static struct +{ + const char *cpu; + const char *platform; +} platforms[GRUB_INSTALL_PLATFORM_MAX] = + { + [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386", "pc" }, + [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_QEMU] = { "i386", "qemu" }, + [GRUB_INSTALL_PLATFORM_I386_COREBOOT] = { "i386", "coreboot" }, + [GRUB_INSTALL_PLATFORM_I386_MULTIBOOT] = { "i386", "multiboot" }, + [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64", "efi" }, + [GRUB_INSTALL_PLATFORM_I386_XEN] = { "i386", "xen" }, + [GRUB_INSTALL_PLATFORM_X86_64_XEN] = { "x86_64", "xen" }, + [GRUB_INSTALL_PLATFORM_I386_XEN_PVH] = { "i386", "xen_pvh" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON] = { "mipsel", "loongson" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS] = { "mipsel", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS] = { "mips", "qemu_mips" }, + [GRUB_INSTALL_PLATFORM_MIPSEL_ARC] = { "mipsel", "arc" }, + [GRUB_INSTALL_PLATFORM_MIPS_ARC] = { "mips", "arc" }, + [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc", "ieee1275" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm", "efi" }, + [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64", "efi" }, + [GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] = { "mips64el","efi" }, + [GRUB_INSTALL_PLATFORM_ARM_UBOOT] = { "arm", "uboot" }, + [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, + [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" }, + [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" }, + }; + +char * +grub_install_get_platforms_string (void) +{ + char **arr = xmalloc (sizeof (char *) * ARRAY_SIZE (platforms)); + int platform_strins_len = 0; + char *platforms_string; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (platforms); i++) + { + arr[i] = xasprintf ("%s-%s", platforms[i].cpu, + platforms[i].platform); + platform_strins_len += strlen (arr[i]) + 2; + } + ptr = platforms_string = xmalloc (platform_strins_len); + qsort (arr, ARRAY_SIZE (platforms), sizeof (char *), grub_qsort_strcmp); + for (i = 0; i < ARRAY_SIZE (platforms); i++) + { + strcpy (ptr, arr[i]); + ptr += strlen (arr[i]); + *ptr++ = ','; + *ptr++ = ' '; + free (arr[i]); + } + ptr[-2] = 0; + free (arr); + + return platforms_string; +} + +char * +grub_install_get_platform_name (enum grub_install_plat platid) +{ + return xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); +} + +const char * +grub_install_get_platform_cpu (enum grub_install_plat platid) +{ + return platforms[platid].cpu; +} + +const char * +grub_install_get_platform_platform (enum grub_install_plat platid) +{ + return platforms[platid].platform; +} + + +void +grub_install_copy_files (const char *src, + const char *dst, + enum grub_install_plat platid) +{ + char *dst_platform, *dst_fonts; + const char *pkgdatadir = grub_util_get_pkgdatadir (); + char *themes_dir; + + { + char *platform; + platform = xasprintf ("%s-%s", platforms[platid].cpu, + platforms[platid].platform); + dst_platform = grub_util_path_concat (2, dst, platform); + free (platform); + } + dst_fonts = grub_util_path_concat (2, dst, "fonts"); + grub_install_mkdir_p (dst_platform); + clean_grub_dir (dst); + clean_grub_dir (dst_platform); + + grub_install_copy_nls(src, dst); + + if (install_modules.is_default) + copy_by_ext (src, dst_platform, ".mod", 1); + else + { + struct grub_util_path_list *path_list, *p; + + path_list = grub_util_resolve_dependencies (src, "moddep.lst", + install_modules.entries); + for (p = path_list; p; p = p->next) + { + const char *srcf = p->name; + const char *dir; + char *dstf; + + dir = grub_strrchr (srcf, '/'); + if (dir) + dir++; + else + dir = srcf; + dstf = grub_util_path_concat (2, dst_platform, dir); + grub_install_compress_file (srcf, dstf, 1); + free (dstf); + } + + grub_util_free_path_list (path_list); + } + + const char *pkglib_DATA[] = {"efiemu32.o", "efiemu64.o", + "moddep.lst", "command.lst", + "fs.lst", "partmap.lst", + "parttool.lst", + "video.lst", "crypto.lst", + "terminal.lst", "modinfo.sh" }; + size_t i; + + for (i = 0; i < ARRAY_SIZE (pkglib_DATA); i++) + { + char *srcf = grub_util_path_concat (2, src, pkglib_DATA[i]); + char *dstf = grub_util_path_concat (2, dst_platform, pkglib_DATA[i]); + if (i == 0 || i == 1) + grub_install_compress_file (srcf, dstf, 0); + else + grub_install_compress_file (srcf, dstf, 1); + free (srcf); + free (dstf); + } + + if (install_themes.is_default) + { + install_themes.is_default = 0; + install_themes.n_entries = 1; + install_themes.entries = xmalloc (2 * sizeof (install_themes.entries[0])); + install_themes.entries[0] = xstrdup ("starfield"); + install_themes.entries[1] = NULL; + } + + if (grub_install_themes_directory) + themes_dir = xstrdup (grub_install_themes_directory); + else + themes_dir = grub_util_path_concat (2, grub_util_get_pkgdatadir (), + "themes"); + + for (i = 0; i < install_themes.n_entries; i++) + { + char *srcf = grub_util_path_concat (3, themes_dir, + install_themes.entries[i], + "theme.txt"); + if (grub_util_is_regular (srcf)) + { + char *srcd = grub_util_path_concat (2, themes_dir, + install_themes.entries[i]); + char *dstd = grub_util_path_concat (3, dst, "themes", + install_themes.entries[i]); + grub_install_mkdir_p (dstd); + copy_all (srcd, dstd); + free (srcd); + free (dstd); + } + free (srcf); + } + + free (themes_dir); + + if (install_fonts.is_default) + { + install_fonts.is_default = 0; + install_fonts.n_entries = 1; + install_fonts.entries = xmalloc (2 * sizeof (install_fonts.entries[0])); + install_fonts.entries[0] = xstrdup ("unicode"); + install_fonts.entries[1] = NULL; + } + + grub_install_mkdir_p (dst_fonts); + + for (i = 0; i < install_fonts.n_entries; i++) + { + char *srcf = grub_util_path_concat_ext (2, pkgdatadir, + install_fonts.entries[i], + ".pf2"); + char *dstf = grub_util_path_concat_ext (2, dst_fonts, + install_fonts.entries[i], + ".pf2"); + + grub_install_compress_file (srcf, dstf, 0); + free (srcf); + free (dstf); + } + + free (dst_platform); + free (dst_fonts); +} + +enum grub_install_plat +grub_install_get_target (const char *src) +{ + char *fn; + grub_util_fd_t f; + char buf[8192]; + ssize_t r; + char *c, *pl, *p; + size_t i; + fn = grub_util_path_concat (2, src, "modinfo.sh"); + f = grub_util_fd_open (fn, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (f)) + grub_util_error (_("%s doesn't exist. Please specify --target or --directory"), + fn); + r = grub_util_fd_read (f, buf, sizeof (buf) - 1); + if (r < 0) + grub_util_error (_("cannot read `%s': %s"), fn, strerror (errno)); + grub_util_fd_close (f); + buf[r] = '\0'; + c = strstr (buf, "grub_modinfo_target_cpu="); + if (!c || (c != buf && !grub_isspace (*(c-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + pl = strstr (buf, "grub_modinfo_platform="); + if (!pl || (pl != buf && !grub_isspace (*(pl-1)))) + grub_util_error (_("invalid modinfo file `%s'"), fn); + c += sizeof ("grub_modinfo_target_cpu=") - 1; + pl += sizeof ("grub_modinfo_platform=") - 1; + for (p = c; *p && !grub_isspace (*p); p++); + *p = '\0'; + for (p = pl; *p && !grub_isspace (*p); p++); + *p = '\0'; + + for (i = 0; i < ARRAY_SIZE (platforms); i++) + if (strcmp (platforms[i].cpu, c) == 0 + && strcmp (platforms[i].platform, pl) == 0) + { + free (fn); + return i; + } + grub_util_error (_("Unknown platform `%s-%s'"), c, pl); +} + + +void +grub_util_unlink_recursive (const char *name) +{ + grub_util_fd_dir_t d; + grub_util_fd_dirent_t de; + + d = grub_util_fd_opendir (name); + + while ((de = grub_util_fd_readdir (d))) + { + char *fp; + if (strcmp (de->d_name, ".") == 0) + continue; + if (strcmp (de->d_name, "..") == 0) + continue; + fp = grub_util_path_concat (2, name, de->d_name); + if (grub_util_is_special_file (fp)) + { + free (fp); + continue; + } + if (grub_util_is_regular (fp)) + grub_util_unlink (fp); + else if (grub_util_is_directory (fp)) + grub_util_unlink_recursive (fp); + free (fp); + } + grub_util_rmdir (name); + grub_util_fd_closedir (d); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c new file mode 100644 index 00000000..fc4a9dc6 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-install.c @@ -0,0 +1,1981 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#include +#pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wmissing-declarations" + +#include "progname.h" + +static char *target; +static int removable = 0; +static int recheck = 0; +static int update_nvram = 1; +static char *install_device = NULL; +static char *debug_image = NULL; +static char *rootdir = NULL; +static char *bootdir = NULL; +static int allow_floppy = 0; +static int force_file_id = 0; +static char *disk_module = NULL; +static char *efidir = NULL; +static char *macppcdir = NULL; +static int force = 0; +static int have_abstractions = 0; +static int have_cryptodisk = 0; +static char * bootloader_id; +static int have_load_cfg = 0; +static FILE * load_cfg_f = NULL; +static char *load_cfg; +static int install_bootsector = 1; +static char *label_font; +static char *label_color; +static char *label_bgcolor; +static char *product_version; +static int add_rs_codes = 1; + +enum + { + OPTION_BOOT_DIRECTORY = 0x301, + OPTION_ROOT_DIRECTORY, + OPTION_TARGET, + OPTION_SETUP, + OPTION_MKRELPATH, + OPTION_MKDEVICEMAP, + OPTION_PROBE, + OPTION_EDITENV, + OPTION_ALLOW_FLOPPY, + OPTION_RECHECK, + OPTION_FORCE, + OPTION_FORCE_FILE_ID, + OPTION_NO_NVRAM, + OPTION_REMOVABLE, + OPTION_BOOTLOADER_ID, + OPTION_EFI_DIRECTORY, + OPTION_FONT, + OPTION_DEBUG, + OPTION_DEBUG_IMAGE, + OPTION_NO_FLOPPY, + OPTION_DISK_MODULE, + OPTION_NO_BOOTSECTOR, + OPTION_NO_RS_CODES, + OPTION_MACPPC_DIRECTORY, + OPTION_LABEL_FONT, + OPTION_LABEL_COLOR, + OPTION_LABEL_BGCOLOR, + OPTION_PRODUCT_VERSION + }; + +static int fs_probe = 1; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_FORCE_FILE_ID: + force_file_id = 1; + return 0; + case 's': + fs_probe = 0; + return 0; + + case OPTION_SETUP: + if (!grub_strstr (arg, "setup")) + install_bootsector = 0; + return 0; + + case OPTION_PRODUCT_VERSION: + free (product_version); + product_version = xstrdup (arg); + return 0; + case OPTION_LABEL_FONT: + free (label_font); + label_font = xstrdup (arg); + return 0; + + case OPTION_LABEL_COLOR: + free (label_color); + label_color = xstrdup (arg); + return 0; + + case OPTION_LABEL_BGCOLOR: + free (label_bgcolor); + label_bgcolor = xstrdup (arg); + return 0; + + /* Accept and ignore for compatibility. */ + case OPTION_FONT: + case OPTION_MKRELPATH: + case OPTION_PROBE: + case OPTION_EDITENV: + case OPTION_MKDEVICEMAP: + case OPTION_NO_FLOPPY: + return 0; + case OPTION_ROOT_DIRECTORY: + /* Accept for compatibility. */ + free (rootdir); + rootdir = xstrdup (arg); + return 0; + + case OPTION_BOOT_DIRECTORY: + free (bootdir); + bootdir = xstrdup (arg); + return 0; + + case OPTION_MACPPC_DIRECTORY: + free (macppcdir); + macppcdir = xstrdup (arg); + return 0; + + case OPTION_EFI_DIRECTORY: + free (efidir); + efidir = xstrdup (arg); + return 0; + + case OPTION_DISK_MODULE: + free (disk_module); + disk_module = xstrdup (arg); + return 0; + + case OPTION_TARGET: + free (target); + target = xstrdup (arg); + return 0; + + case OPTION_DEBUG_IMAGE: + free (debug_image); + debug_image = xstrdup (arg); + return 0; + + case OPTION_NO_NVRAM: + update_nvram = 0; + return 0; + + case OPTION_FORCE: + force = 1; + return 0; + + case OPTION_RECHECK: + recheck = 1; + return 0; + + case OPTION_REMOVABLE: + removable = 1; + return 0; + + case OPTION_ALLOW_FLOPPY: + allow_floppy = 1; + return 0; + + case OPTION_NO_BOOTSECTOR: + install_bootsector = 0; + return 0; + + case OPTION_NO_RS_CODES: + add_rs_codes = 0; + return 0; + + case OPTION_DEBUG: + verbosity++; + return 0; + + case OPTION_BOOTLOADER_ID: + free (bootloader_id); + bootloader_id = xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + if (install_device) + grub_util_error ("%s", _("More than one install device?")); + install_device = xstrdup (arg); + return 0; + + default: + return ARGP_ERR_UNKNOWN; + } +} + + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"boot-directory", OPTION_BOOT_DIRECTORY, N_("DIR"), + 0, N_("install GRUB images under the directory DIR/%s instead of the %s directory"), 2}, + {"root-directory", OPTION_ROOT_DIRECTORY, N_("DIR"), + OPTION_HIDDEN, 0, 2}, + {"font", OPTION_FONT, N_("FILE"), + OPTION_HIDDEN, 0, 2}, + {"target", OPTION_TARGET, N_("TARGET"), + /* TRANSLATORS: "TARGET" as in "target platform". */ + 0, N_("install GRUB for TARGET platform [default=%s]; available targets: %s"), 2}, + {"grub-setup", OPTION_SETUP, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkrelpath", OPTION_MKRELPATH, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-mkdevicemap", OPTION_MKDEVICEMAP, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-probe", OPTION_PROBE, "FILE", OPTION_HIDDEN, 0, 2}, + {"grub-editenv", OPTION_EDITENV, "FILE", OPTION_HIDDEN, 0, 2}, + {"allow-floppy", OPTION_ALLOW_FLOPPY, 0, 0, + /* TRANSLATORS: "may break" doesn't just mean that option wouldn't have any + effect but that it will make the resulting install unbootable from HDD. */ + N_("make the drive also bootable as floppy (default for fdX devices)." + " May break on some BIOSes."), 2}, + {"recheck", OPTION_RECHECK, 0, 0, + N_("delete device map if it already exists"), 2}, + {"force", OPTION_FORCE, 0, 0, + N_("install even if problems are detected"), 2}, + {"force-file-id", OPTION_FORCE_FILE_ID, 0, 0, + N_("use identifier file even if UUID is available"), 2}, + {"disk-module", OPTION_DISK_MODULE, N_("MODULE"), 0, + N_("disk module to use (biosdisk or native). " + "This option is only available on BIOS target."), 2}, + {"no-nvram", OPTION_NO_NVRAM, 0, 0, + N_("don't update the `boot-device'/`Boot*' NVRAM variables. " + "This option is only available on EFI and IEEE1275 targets."), 2}, + {"skip-fs-probe",'s',0, 0, + N_("do not probe for filesystems in DEVICE"), 0}, + {"no-bootsector", OPTION_NO_BOOTSECTOR, 0, 0, + N_("do not install bootsector"), 0}, + {"no-rs-codes", OPTION_NO_RS_CODES, 0, 0, + N_("Do not apply any reed-solomon codes when embedding core.img. " + "This option is only available on x86 BIOS targets."), 0}, + + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, + {"removable", OPTION_REMOVABLE, 0, 0, + N_("the installation device is removable. " + "This option is only available on EFI."), 2}, + {"bootloader-id", OPTION_BOOTLOADER_ID, N_("ID"), 0, + N_("the ID of bootloader. This option is only available on EFI and Macs."), 2}, + {"efi-directory", OPTION_EFI_DIRECTORY, N_("DIR"), 0, + N_("use DIR as the EFI System Partition root."), 2}, + {"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0, + N_("use DIR for PPC MAC install."), 2}, + {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, + {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, + {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, + {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2}, + {0, 0, 0, 0, 0, 0} +}; + +static const char * +get_default_platform (void) +{ +#ifdef __powerpc__ + return "powerpc-ieee1275"; +#elif defined (__sparc__) || defined (__sparc64__) + return "sparc64-ieee1275"; +#elif defined (__MIPSEL__) +#if _MIPS_SIM == _ABI64 + return "mips64el-efi"; +#else + return "mipsel-loongson"; +#endif +#elif defined (__MIPSEB__) + return "mips-arc"; +#elif defined (__ia64__) + return "ia64-efi"; +#elif defined (__arm__) + return grub_install_get_default_arm_platform (); +#elif defined (__aarch64__) + return "arm64-efi"; +#elif defined (__amd64__) || defined (__x86_64__) || defined (__i386__) + return grub_install_get_default_x86_platform (); +#else + return NULL; +#endif +} + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case OPTION_BOOT_DIRECTORY: + return xasprintf (text, GRUB_DIR_NAME, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME); + case OPTION_TARGET: + { + char *plats = grub_install_get_platforms_string (); + char *ret; + ret = xasprintf (text, get_default_platform (), plats); + free (plats); + return ret; + } + case ARGP_KEY_HELP_POST_DOC: + return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME); + default: + return grub_install_help_filter (key, text, input); + } +} + +#pragma GCC diagnostic error "-Wformat-nonliteral" + +/* TRANSLATORS: INSTALL_DEVICE isn't an identifier and is the DEVICE you + install to. */ +struct argp argp = { + options, argp_parser, N_("[OPTION] [INSTALL_DEVICE]"), + N_("Install GRUB on your drive.")"\v" + N_("INSTALL_DEVICE must be system device filename.\n" + "%s copies GRUB images into %s. On some platforms, it" + " may also install GRUB into the boot sector."), + NULL, help_filter, NULL +}; + +static int +probe_raid_level (grub_disk_t disk) +{ + /* disk might be NULL in the case of a LVM physical volume with no LVM + signature. Ignore such cases here. */ + if (!disk) + return -1; + + if (disk->dev->id != GRUB_DISK_DEVICE_DISKFILTER_ID) + return -1; + + if (disk->name[0] != 'm' || disk->name[1] != 'd') + return -1; + + if (!((struct grub_diskfilter_lv *) disk->data)->segments) + return -1; + return ((struct grub_diskfilter_lv *) disk->data)->segments->type; +} + +static void +push_partmap_module (const char *map, void *data __attribute__ ((unused))) +{ + char buf[50]; + + if (strcmp (map, "openbsd") == 0 || strcmp (map, "netbsd") == 0) + { + grub_install_push_module ("part_bsd"); + return; + } + + snprintf (buf, sizeof (buf), "part_%s", map); + grub_install_push_module (buf); +} + +static void +push_cryptodisk_module (const char *mod, void *data __attribute__ ((unused))) +{ + grub_install_push_module (mod); +} + +static void +probe_mods (grub_disk_t disk) +{ + grub_partition_t part; + grub_disk_memberlist_t list = NULL, tmp; + int raid_level; + + if (disk->partition == NULL) + grub_util_info ("no partition map found for %s", disk->name); + + for (part = disk->partition; part; part = part->parent) + push_partmap_module (part->partmap->name, NULL); + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) + { + grub_diskfilter_get_partmap (disk, push_partmap_module, NULL); + have_abstractions = 1; + } + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID + && (grub_memcmp (disk->name, "lvm/", sizeof ("lvm/") - 1) == 0 || + grub_memcmp (disk->name, "lvmid/", sizeof ("lvmid/") - 1) == 0)) + grub_install_push_module ("lvm"); + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID + && grub_memcmp (disk->name, "ldm/", sizeof ("ldm/") - 1) == 0) + grub_install_push_module ("ldm"); + + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + grub_util_cryptodisk_get_abstraction (disk, + push_cryptodisk_module, NULL); + have_abstractions = 1; + have_cryptodisk = 1; + } + + raid_level = probe_raid_level (disk); + if (raid_level >= 0) + { + grub_install_push_module ("diskfilter"); + if (disk->dev->disk_raidname) + grub_install_push_module (disk->dev->disk_raidname (disk)); + } + if (raid_level == 5) + grub_install_push_module ("raid5rec"); + if (raid_level == 6) + grub_install_push_module ("raid6rec"); + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->disk_memberlist) + list = disk->dev->disk_memberlist (disk); + while (list) + { + probe_mods (list->disk); + tmp = list->next; + free (list); + list = tmp; + } +} + +static int +have_bootdev (enum grub_install_plat pl) +{ + switch (pl) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + return 1; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + return 0; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + return 0; + } + return 0; +} + +static void +probe_cryptodisk_uuid (grub_disk_t disk) +{ + grub_disk_memberlist_t list = NULL, tmp; + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->disk_memberlist) + { + list = disk->dev->disk_memberlist (disk); + } + while (list) + { + probe_cryptodisk_uuid (list->disk); + tmp = list->next; + free (list); + list = tmp; + } + if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) + { + const char *uuid = grub_util_cryptodisk_get_uuid (disk); + if (!load_cfg_f) + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + + fprintf (load_cfg_f, "cryptomount -u %s\n", + uuid); + } +} + +static int +is_same_disk (const char *a, const char *b) +{ + while (1) + { + if ((*a == ',' || *a == '\0') && (*b == ',' || *b == '\0')) + return 1; + if (*a != *b) + return 0; + if (*a == '\\') + { + if (a[1] != b[1]) + return 0; + a += 2; + b += 2; + continue; + } + a++; + b++; + } +} + +static char * +get_rndstr (void) +{ + grub_uint8_t rnd[15]; + const size_t sz = sizeof (rnd) * GRUB_CHAR_BIT / 5; + char * ret = xmalloc (sz + 1); + size_t i; + if (grub_get_random (rnd, sizeof (rnd))) + grub_util_error ("%s", _("couldn't retrieve random data")); + for (i = 0; i < sz; i++) + { + grub_size_t b = i * 5; + grub_uint8_t r; + grub_size_t f1 = GRUB_CHAR_BIT - b % GRUB_CHAR_BIT; + grub_size_t f2; + if (f1 > 5) + f1 = 5; + f2 = 5 - f1; + r = (rnd[b / GRUB_CHAR_BIT] >> (b % GRUB_CHAR_BIT)) & ((1 << f1) - 1); + if (f2) + r |= (rnd[b / GRUB_CHAR_BIT + 1] & ((1 << f2) - 1)) << f1; + if (r < 10) + ret[i] = '0' + r; + else + ret[i] = 'a' + (r - 10); + } + ret[sz] = '\0'; + return ret; +} + +static char * +escape (const char *in) +{ + char *ptr; + char *ret; + int overhead = 0; + + for (ptr = (char*)in; *ptr; ptr++) + if (*ptr == '\'') + overhead += 3; + ret = grub_malloc (ptr - in + overhead + 1); + if (!ret) + return NULL; + + grub_strchrsub (ret, in, '\'', "'\\''"); + return ret; +} + +static struct grub_util_config config; + +static void +device_map_check_duplicates (const char *dev_map) +{ + FILE *fp; + char buf[1024]; /* XXX */ + size_t alloced = 8; + size_t filled = 0; + char **d; + size_t i; + + if (dev_map[0] == '\0') + return; + + fp = grub_util_fopen (dev_map, "r"); + if (! fp) + return; + + d = xmalloc (alloced * sizeof (d[0])); + + while (fgets (buf, sizeof (buf), fp)) + { + char *p = buf; + char *e; + + /* Skip leading spaces. */ + while (*p && grub_isspace (*p)) + p++; + + /* If the first character is `#' or NUL, skip this line. */ + if (*p == '\0' || *p == '#') + continue; + + if (*p != '(') + continue; + + p++; + + e = p; + p = strchr (p, ')'); + if (! p) + continue; + + if (filled >= alloced) + { + alloced *= 2; + d = xrealloc (d, alloced * sizeof (d[0])); + } + + *p = '\0'; + + d[filled++] = xstrdup (e); + } + + fclose (fp); + + qsort (d, filled, sizeof (d[0]), grub_qsort_strcmp); + + for (i = 0; i + 1 < filled; i++) + if (strcmp (d[i], d[i+1]) == 0) + { + grub_util_error (_("the drive %s is defined multiple times in the device map %s"), + d[i], dev_map); + } + + for (i = 0; i < filled; i++) + free (d[i]); + + free (d); +} + +static grub_err_t +write_to_disk (grub_device_t dev, const char *fn) +{ + char *core_img; + size_t core_size; + grub_err_t err; + + core_size = grub_util_get_image_size (fn); + + core_img = grub_util_read_image (fn); + + grub_util_info ("writing `%s' to `%s'", fn, dev->disk->name); + err = grub_disk_write (dev->disk, 0, 0, + core_size, core_img); + free (core_img); + return err; +} + +static int +is_prep_partition (grub_device_t dev) +{ + if (!dev->disk) + return 0; + if (!dev->disk->partition) + return 0; + if (strcmp(dev->disk->partition->partmap->name, "msdos") == 0) + return (dev->disk->partition->msdostype == 0x41); + + if (strcmp (dev->disk->partition->partmap->name, "gpt") == 0) + { + struct grub_gpt_partentry gptdata; + grub_partition_t p = dev->disk->partition; + int ret = 0; + dev->disk->partition = dev->disk->partition->parent; + + if (grub_disk_read (dev->disk, p->offset, p->index, + sizeof (gptdata), &gptdata) == 0) + { + const grub_gpt_part_guid_t template = { + grub_cpu_to_le32_compile_time (0x9e1a2d38), + grub_cpu_to_le16_compile_time (0xc612), + grub_cpu_to_le16_compile_time (0x4316), + { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b } + }; + + ret = grub_memcmp (&template, &gptdata.type, + sizeof (template)) == 0; + } + dev->disk->partition = p; + return ret; + } + + return 0; +} + +static int +is_prep_empty (grub_device_t dev) +{ + grub_disk_addr_t dsize, addr; + grub_uint32_t buffer[32768]; + + dsize = grub_disk_get_size (dev->disk); + for (addr = 0; addr < dsize; + addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE) + { + grub_size_t sz = sizeof (buffer); + grub_uint32_t *ptr; + + if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr) + sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE; + grub_disk_read (dev->disk, addr, 0, sz, buffer); + + if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0) + return 1; + + for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++) + if (*ptr) + return 0; + } + + return 1; +} + +static void +bless (grub_device_t dev, const char *path, int x86) +{ + struct stat st; + grub_err_t err; + + grub_util_info ("blessing %s", path); + + if (stat (path, &st) < 0) + grub_util_error (N_("cannot stat `%s': %s"), + path, strerror (errno)); + + err = grub_mac_bless_inode (dev, st.st_ino, S_ISDIR (st.st_mode), x86); + if (err) + grub_util_error ("%s", grub_errmsg); + grub_util_info ("blessed"); +} + +static void +fill_core_services (const char *core_services) +{ + char *label; + FILE *f; + char *label_text; + char *label_string = xasprintf ("%s %s", bootloader_id, product_version); + char *sysv_plist; + + label = grub_util_path_concat (2, core_services, ".disk_label"); + grub_util_info ("rendering label %s", label_string); + grub_util_render_label (label_font, label_bgcolor ? : "white", + label_color ? : "black", label_string, label); + grub_util_info ("label rendered"); + free (label); + label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails"); + f = grub_util_fopen (label_text, "wb"); + fprintf (f, "%s\n", label_string); + fclose (f); + free (label_string); + free (label_text); + + sysv_plist = grub_util_path_concat (2, core_services, "SystemVersion.plist"); + f = grub_util_fopen (sysv_plist, "wb"); + fprintf (f, + "\n" + "\n" + " ProductBuildVersion\n" + " \n" + " ProductName\n" + " %s\n" + " ProductVersion\n" + " %s\n" + "\n" + "\n", bootloader_id, product_version); + fclose (f); + free (sysv_plist); +} + +int +main (int argc, char *argv[]) +{ + int is_efi = 0; + const char *efi_distributor = NULL; + const char *efi_file = NULL; + char **grub_devices; + grub_fs_t grub_fs; + grub_device_t grub_dev = NULL; + enum grub_install_plat platform; + char *grubdir, *device_map; + char **curdev, **curdrive; + char **grub_drives; + char *relative_grubdir; + char **efidir_device_names = NULL; + grub_device_t efidir_grub_dev = NULL; + char *efidir_grub_devname; + int efidir_is_mac = 0; + int is_prep = 0; + const char *pkgdatadir; + + grub_util_host_init (&argc, &argv); + product_version = xstrdup (PACKAGE_VERSION); + pkgdatadir = grub_util_get_pkgdatadir (); + label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + if (verbosity > 1) + grub_env_set ("debug", "all"); + + grub_util_load_config (&config); + + if (!bootloader_id && config.grub_distributor) + { + char *ptr; + bootloader_id = xstrdup (config.grub_distributor); + for (ptr = bootloader_id; *ptr && *ptr != ' '; ptr++) + if (*ptr >= 'A' && *ptr <= 'Z') + *ptr = *ptr - 'A' + 'a'; + *ptr = '\0'; + } + if (!bootloader_id || bootloader_id[0] == '\0') + { + free (bootloader_id); + bootloader_id = xstrdup ("grub"); + } + + if (!grub_install_source_directory) + { + if (!target) + { + const char * t; + t = get_default_platform (); + if (!t) + grub_util_error ("%s", + _("Unable to determine your platform." + " Use --target.") + ); + target = xstrdup (t); + } + grub_install_source_directory + = grub_util_path_concat (2, grub_util_get_pkglibdir (), target); + } + + platform = grub_install_get_target (grub_install_source_directory); + + { + char *platname = grub_install_get_platform_name (platform); + fprintf (stderr, _("Installing for %s platform.\n"), platname); + free (platname); + } + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + if (!disk_module) + disk_module = xstrdup ("biosdisk"); + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + break; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + disk_module = xstrdup ("native"); + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + if (!install_device) + grub_util_error ("%s", _("install device isn't specified")); + break; + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + if (install_device) + is_prep = 1; + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + free (install_device); + install_device = NULL; + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + if (!bootdir) + bootdir = grub_util_path_concat (3, "/", rootdir, GRUB_BOOT_DIR_NAME); + + { + char * t = grub_util_path_concat (2, bootdir, GRUB_DIR_NAME); + grub_install_mkdir_p (t); + grubdir = grub_canonicalize_file_name (t); + if (!grubdir) + grub_util_error (_("failed to get canonical path of `%s'"), t); + free (t); + } + device_map = grub_util_path_concat (2, grubdir, "device.map"); + + if (recheck) + grub_util_unlink (device_map); + + device_map_check_duplicates (device_map); + grub_util_biosdisk_init (device_map); + + /* Initialize all modules. */ + grub_init_all (); + grub_gcry_init_all (); + grub_hostfs_init (); + grub_host_init (); + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + is_efi = 1; + break; + default: + is_efi = 0; + break; + + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + /* Find the EFI System Partition. */ + + if (is_efi) + { + grub_fs_t fs; + free (install_device); + install_device = NULL; + if (!efidir) + { + char *d = grub_util_path_concat (2, bootdir, "efi"); + char *dr = NULL; + if (!grub_util_is_directory (d)) + { + free (d); + d = grub_util_path_concat (2, bootdir, "EFI"); + } + /* + The EFI System Partition may have been given directly using + --root-directory. + */ + if (!grub_util_is_directory (d) + && rootdir && grub_strcmp (rootdir, "/") != 0) + { + free (d); + d = xstrdup (rootdir); + } + if (grub_util_is_directory (d)) + dr = grub_make_system_path_relative_to_its_root (d); + /* Is it a mount point? */ + if (dr && dr[0] == '\0') + efidir = d; + else + free (d); + free (dr); + } + if (!efidir) + grub_util_error ("%s", _("cannot find EFI directory")); + efidir_device_names = grub_guess_root_devices (efidir); + if (!efidir_device_names || !efidir_device_names[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + efidir); + install_device = efidir_device_names[0]; + + for (curdev = efidir_device_names; *curdev; curdev++) + grub_util_pull_device (*curdev); + + efidir_grub_devname = grub_util_get_grub_dev (efidir_device_names[0]); + if (!efidir_grub_devname) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + efidir_device_names[0]); + + efidir_grub_dev = grub_device_open (efidir_grub_devname); + if (! efidir_grub_dev) + grub_util_error ("%s", grub_errmsg); + + fs = grub_fs_probe (efidir_grub_dev); + if (! fs) + grub_util_error ("%s", grub_errmsg); + + efidir_is_mac = 0; + + if (grub_strcmp (fs->name, "hfs") == 0 + || grub_strcmp (fs->name, "hfsplus") == 0) + efidir_is_mac = 1; + + if (!efidir_is_mac && grub_strcmp (fs->name, "fat") != 0) + grub_util_error (_("%s doesn't look like an EFI partition"), efidir); + + /* The EFI specification requires that an EFI System Partition must + contain an "EFI" subdirectory, and that OS loaders are stored in + subdirectories below EFI. Vendors are expected to pick names that do + not collide with other vendors. To minimise collisions, we use the + name of our distributor if possible. + */ + char *t; + efi_distributor = bootloader_id; + if (removable) + { + /* The specification makes stricter requirements of removable + devices, in order that only one image can be automatically loaded + from them. The image must always reside under /EFI/BOOT, and it + must have a specific file name depending on the architecture. + */ + efi_distributor = "BOOT"; + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file = "BOOTIA32.EFI"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file = "BOOTX64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file = "BOOTIA64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file = "BOOTARM.EFI"; + break; + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + efi_file = "BOOTAA64.EFI"; + break; + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + efi_file = "BOOTMIPS64EL.EFI"; + break; + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + efi_file = "BOOTRISCV32.EFI"; + break; + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + efi_file = "BOOTRISCV64.EFI"; + break; + default: + grub_util_error ("%s", _("You've found a bug")); + break; + } + } + else + { + /* It is convenient for each architecture to have a different + efi_file, so that different versions can be installed in parallel. + */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + efi_file = "grubia32.efi"; + break; + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + efi_file = "grubx64.efi"; + break; + case GRUB_INSTALL_PLATFORM_IA64_EFI: + efi_file = "grubia64.efi"; + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + efi_file = "grubarm.efi"; + break; + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + efi_file = "grubaa64.efi"; + break; + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + efi_file = "grubmips64el.efi"; + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + efi_file = "grubriscv32.efi"; + break; + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + efi_file = "grubriscv64.efi"; + break; + default: + efi_file = "grub.efi"; + break; + } + } + t = grub_util_path_concat (3, efidir, "EFI", efi_distributor); + free (efidir); + efidir = t; + grub_install_mkdir_p (efidir); + } + + if (platform == GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) + { + int is_guess = 0; + if (!macppcdir) + { + char *d; + + is_guess = 1; + d = grub_util_path_concat (2, bootdir, "macppc"); + if (!grub_util_is_directory (d)) + { + free (d); + d = grub_util_path_concat (2, bootdir, "efi"); + } + /* Find the Mac HFS(+) System Partition. */ + if (!grub_util_is_directory (d)) + { + free (d); + d = grub_util_path_concat (2, bootdir, "EFI"); + } + if (!grub_util_is_directory (d)) + { + free (d); + d = 0; + } + if (d) + macppcdir = d; + } + if (macppcdir) + { + char **macppcdir_device_names = NULL; + grub_device_t macppcdir_grub_dev = NULL; + char *macppcdir_grub_devname; + grub_fs_t fs; + + macppcdir_device_names = grub_guess_root_devices (macppcdir); + if (!macppcdir_device_names || !macppcdir_device_names[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + macppcdir); + + for (curdev = macppcdir_device_names; *curdev; curdev++) + grub_util_pull_device (*curdev); + + macppcdir_grub_devname = grub_util_get_grub_dev (macppcdir_device_names[0]); + if (!macppcdir_grub_devname) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + macppcdir_device_names[0]); + + macppcdir_grub_dev = grub_device_open (macppcdir_grub_devname); + if (! macppcdir_grub_dev) + grub_util_error ("%s", grub_errmsg); + + fs = grub_fs_probe (macppcdir_grub_dev); + if (! fs) + grub_util_error ("%s", grub_errmsg); + + if (grub_strcmp (fs->name, "hfs") != 0 + && grub_strcmp (fs->name, "hfsplus") != 0 + && !is_guess) + grub_util_error (_("filesystem on %s is neither HFS nor HFS+"), + macppcdir); + if (grub_strcmp (fs->name, "hfs") == 0 + || grub_strcmp (fs->name, "hfsplus") == 0) + { + install_device = macppcdir_device_names[0]; + is_prep = 0; + } + } + } + + grub_install_copy_files (grub_install_source_directory, + grubdir, platform); + + char *envfile = grub_util_path_concat (2, grubdir, "grubenv"); + if (!grub_util_is_regular (envfile)) + grub_util_create_envblk_file (envfile); + + size_t ndev = 0; + + /* Write device to a variable so we don't have to traverse /dev every time. */ + grub_devices = grub_guess_root_devices (grubdir); + if (!grub_devices || !grub_devices[0]) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), + grubdir); + + for (curdev = grub_devices; *curdev; curdev++) + { + grub_util_pull_device (*curdev); + ndev++; + } + + grub_drives = xmalloc (sizeof (grub_drives[0]) * (ndev + 1)); + + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) + { + *curdrive = grub_util_get_grub_dev (*curdev); + if (! *curdrive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + *curdev); + } + *curdrive = 0; + + grub_dev = grub_device_open (grub_drives[0]); + if (! grub_dev) + grub_util_error ("%s", grub_errmsg); + + grub_fs = grub_fs_probe (grub_dev); + if (! grub_fs) + grub_util_error ("%s", grub_errmsg); + + grub_install_push_module (grub_fs->name); + + if (grub_dev->disk) + probe_mods (grub_dev->disk); + + for (curdrive = grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev = grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_mods (dev->disk); + grub_device_close (dev); + } + + if (!config.is_cryptodisk_enabled && have_cryptodisk) + grub_util_error (_("attempt to install to encrypted disk without cryptodisk enabled. " + "Set `%s' in file `%s'"), "GRUB_ENABLE_CRYPTODISK=y", + grub_util_get_config_filename ()); + + if (disk_module && grub_strcmp (disk_module, "ata") == 0) + grub_install_push_module ("pata"); + else if (disk_module && grub_strcmp (disk_module, "native") == 0) + { + grub_install_push_module ("pata"); + grub_install_push_module ("ahci"); + grub_install_push_module ("ohci"); + grub_install_push_module ("uhci"); + grub_install_push_module ("ehci"); + grub_install_push_module ("usbms"); + } + else if (disk_module && disk_module[0]) + grub_install_push_module (disk_module); + + relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir); + if (relative_grubdir[0] == '\0') + { + free (relative_grubdir); + relative_grubdir = xstrdup ("/"); + } + + char *platname = grub_install_get_platform_name (platform); + char *platdir; + { + char *t = grub_util_path_concat (2, grubdir, + platname); + platdir = grub_canonicalize_file_name (t); + if (!platdir) + grub_util_error (_("failed to get canonical path of `%s'"), + t); + free (t); + } + load_cfg = grub_util_path_concat (2, platdir, + "load.cfg"); + + grub_util_unlink (load_cfg); + + if (debug_image && debug_image[0]) + { + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "set debug='%s'\n", + debug_image); + } + char *prefix_drive = NULL; + char *install_drive = NULL; + + if (install_device) + { + if (install_device[0] == '(' + && install_device[grub_strlen (install_device) - 1] == ')') + { + size_t len = grub_strlen (install_device) - 2; + install_drive = xmalloc (len + 1); + memcpy (install_drive, install_device + 1, len); + install_drive[len] = '\0'; + } + else + { + grub_util_pull_device (install_device); + install_drive = grub_util_get_grub_dev (install_device); + if (!install_drive) + grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), + install_device); + } + } + + if (!have_abstractions) + { + if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0) + || grub_drives[1] + || (!install_drive + && platform != GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275) + || (install_drive && !is_same_disk (grub_drives[0], install_drive)) + || !have_bootdev (platform)) + { + char *uuid = NULL; + /* generic method (used on coreboot and ata mod). */ + if (!force_file_id + && grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid)) + { + grub_print_error (); + grub_errno = 0; + uuid = NULL; + } + + if (!load_cfg_f) + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + if (uuid) + { + fprintf (load_cfg_f, "search.fs_uuid %s root ", + uuid); + grub_install_push_module ("search_fs_uuid"); + } + else + { + char *rndstr = get_rndstr (); + char *fl = grub_util_path_concat (3, grubdir, + "uuid", rndstr); + char *fldir = grub_util_path_concat (2, grubdir, + "uuid"); + char *relfl; + FILE *flf; + grub_install_mkdir_p (fldir); + flf = grub_util_fopen (fl, "w"); + if (!flf) + grub_util_error (_("Can't create file: %s"), strerror (errno)); + fclose (flf); + relfl = grub_make_system_path_relative_to_its_root (fl); + fprintf (load_cfg_f, "search.file %s root ", + relfl); + grub_install_push_module ("search_fs_file"); + } + for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, + curdrive++) + { + const char *map; + char *g = NULL; + grub_device_t dev; + if (curdrive == grub_drives) + dev = grub_dev; + else + dev = grub_device_open (*curdrive); + if (!dev) + continue; + + if (dev->disk->dev->id != GRUB_DISK_DEVICE_HOSTDISK_ID) + { + grub_util_fprint_full_disk_name (load_cfg_f, + dev->disk->name, + dev); + fprintf (load_cfg_f, " "); + if (dev != grub_dev) + grub_device_close (dev); + continue; + } + + map = grub_util_biosdisk_get_compatibility_hint (dev->disk); + + if (map) + { + grub_util_fprint_full_disk_name (load_cfg_f, map, dev); + fprintf (load_cfg_f, " "); + } + + + if (disk_module && disk_module[0] + && grub_strcmp (disk_module, "biosdisk") != 0) + g = grub_util_guess_baremetal_drive (*curdev); + else + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + g = grub_util_guess_bios_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + g = grub_util_guess_efi_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + { + const char * ofpath = grub_util_devname_to_ofpath (*curdev); + g = xasprintf ("ieee1275/%s", ofpath); + break; + } + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + g = grub_util_guess_baremetal_drive (*curdev); + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance")); + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + if (g) + { + grub_util_fprint_full_disk_name (load_cfg_f, g, dev); + fprintf (load_cfg_f, " "); + free (g); + } + if (dev != grub_dev) + grub_device_close (dev); + } + fprintf (load_cfg_f, "\n"); + char *escaped_relpath = escape (relative_grubdir); + fprintf (load_cfg_f, "set prefix=($root)'%s'\n", + escaped_relpath); + } + else + { + /* We need to hardcode the partition number in the core image's prefix. */ + char *p; + for (p = grub_drives[0]; *p; ) + { + if (*p == '\\' && p[1]) + { + p += 2; + continue; + } + if (*p == ',' || *p == '\0') + break; + p++; + } + prefix_drive = xasprintf ("(%s)", p); + } + } + else + { + if (config.is_cryptodisk_enabled) + { + if (grub_dev->disk) + probe_cryptodisk_uuid (grub_dev->disk); + + for (curdrive = grub_drives + 1; *curdrive; curdrive++) + { + grub_device_t dev = grub_device_open (*curdrive); + if (!dev) + continue; + if (dev->disk) + probe_cryptodisk_uuid (dev->disk); + grub_device_close (dev); + } + } + prefix_drive = xasprintf ("(%s)", grub_drives[0]); + } + + char mkimage_target[200]; + const char *core_name = NULL; + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + core_name = "core.efi"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + core_name = "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s-elf", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + core_name = "core.elf"; + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + break; + + + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + snprintf (mkimage_target, sizeof (mkimage_target), + "%s-%s", + grub_install_get_platform_cpu (platform), + grub_install_get_platform_platform (platform)); + core_name = "core.img"; + break; + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + strcpy (mkimage_target, "sparc64-ieee1275-raw"); + core_name = "core.img"; + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + if (!core_name) + grub_util_error ("%s", _("You've found a bug")); + + if (load_cfg_f) + fclose (load_cfg_f); + + char *imgfile = grub_util_path_concat (2, platdir, + core_name); + char *prefix = xasprintf ("%s%s", prefix_drive ? : "", + relative_grubdir); + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /*prefix */ prefix, + /* output */ imgfile, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, 0); + /* Backward-compatibility kludges. */ + switch (platform) + { + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + { + char *dst = grub_util_path_concat (2, bootdir, "grub.elf"); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + { + char *dst = grub_util_path_concat (2, grubdir, "grub"); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + { + char *dst = grub_util_path_concat (2, platdir, "grub.efi"); + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /* prefix */ "", + /* output */ dst, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, 0); + } + break; + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_PC: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + /* Perform the platform-dependent install */ + + switch (platform) + { + case GRUB_INSTALL_PLATFORM_I386_PC: + { + char *boot_img_src = grub_util_path_concat (2, + grub_install_source_directory, + "boot.img"); + char *boot_img = grub_util_path_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img, 1); + + grub_util_info ("%sgrub-bios-setup %s %s %s %s %s --directory='%s' --device-map='%s' '%s'", + /* TRANSLATORS: This is a prefix in the log to indicate that usually + a command would be executed but due to an option was skipped. */ + install_bootsector ? "" : _("NOT RUNNING: "), + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + !fs_probe ? "--skip-fs-probe" : "", + !add_rs_codes ? "--no-rs-codes" : "", + platdir, + device_map, + install_device); + + /* Now perform the installation. */ + if (install_bootsector) + grub_util_bios_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy, add_rs_codes); + break; + } + case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: + { + char *boot_img_src = grub_util_path_concat (2, + grub_install_source_directory, + "boot.img"); + char *boot_img = grub_util_path_concat (2, platdir, + "boot.img"); + grub_install_copy_file (boot_img_src, boot_img, 1); + + grub_util_info ("%sgrub-sparc64-setup %s %s %s %s --directory='%s' --device-map='%s' '%s'", + install_bootsector ? "" : "NOT RUNNING: ", + allow_floppy ? "--allow-floppy " : "", + verbosity ? "--verbose " : "", + force ? "--force " : "", + !fs_probe ? "--skip-fs-probe" : "", + platdir, + device_map, + install_drive); + + /* Now perform the installation. */ + if (install_bootsector) + grub_util_sparc_setup (platdir, "boot.img", "core.img", + install_drive, force, + fs_probe, allow_floppy, + 0 /* unused */ ); + break; + } + + case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + if (macppcdir) + { + char *core_services = grub_util_path_concat (4, macppcdir, + "System", "Library", + "CoreServices"); + char *mach_kernel = grub_util_path_concat (2, macppcdir, + "mach_kernel"); + char *grub_elf, *bootx; + FILE *f; + grub_device_t ins_dev; + char *grub_chrp = grub_util_path_concat (2, + grub_install_source_directory, + "grub.chrp"); + + grub_install_mkdir_p (core_services); + + bootx = grub_util_path_concat (2, core_services, "BootX"); + grub_install_copy_file (grub_chrp, bootx, 1); + + grub_elf = grub_util_path_concat (2, core_services, "grub.elf"); + grub_install_copy_file (imgfile, grub_elf, 1); + + f = grub_util_fopen (mach_kernel, "a+"); + if (!f) + grub_util_error (_("Can't create file: %s"), strerror (errno)); + fclose (f); + + fill_core_services (core_services); + + ins_dev = grub_device_open (install_drive); + + bless (ins_dev, core_services, 0); + + if (update_nvram) + { + const char *dev; + int partno; + + partno = ins_dev->disk->partition + ? ins_dev->disk->partition->number + 1 : 0; + dev = grub_util_get_os_disk (install_device); + grub_install_register_ieee1275 (0, dev, partno, + "\\\\BootX"); + } + grub_device_close (ins_dev); + free (grub_elf); + free (bootx); + free (mach_kernel); + free (grub_chrp); + break; + } + /* If a install device is defined, copy the core.elf to PReP partition. */ + if (is_prep && install_device && install_device[0]) + { + grub_device_t ins_dev; + ins_dev = grub_device_open (install_drive); + if (!ins_dev || !is_prep_partition (ins_dev)) + { + grub_util_error ("%s", _("the chosen partition is not a PReP partition")); + } + if (is_prep_empty (ins_dev)) + { + if (write_to_disk (ins_dev, imgfile)) + grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); + } + else + { + char *s = xasprintf ("dd if=/dev/zero of=%s", install_device); + grub_util_error (_("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'"), + s); + } + grub_device_close (ins_dev); + if (update_nvram) + grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device), + 0, NULL); + break; + } + /* fallthrough. */ + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: + if (update_nvram) + { + const char *dev; + char *relpath; + int partno; + relpath = grub_make_system_path_relative_to_its_root (imgfile); + partno = grub_dev->disk->partition + ? grub_dev->disk->partition->number + 1 : 0; + dev = grub_util_get_os_disk (grub_devices[0]); + grub_install_register_ieee1275 (0, dev, + partno, relpath); + } + break; + case GRUB_INSTALL_PLATFORM_MIPS_ARC: + grub_install_sgi_setup (install_device, imgfile, "grub"); + break; + + case GRUB_INSTALL_PLATFORM_I386_EFI: + if (!efidir_is_mac) + { + char *dst = grub_util_path_concat (2, efidir, "grub.efi"); + /* For old macs. Suggested by Peter Jones. */ + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + /* Fallthrough. */ + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + if (efidir_is_mac) + { + char *boot_efi; + char *core_services = grub_util_path_concat (4, efidir, + "System", "Library", + "CoreServices"); + char *mach_kernel = grub_util_path_concat (2, efidir, + "mach_kernel"); + FILE *f; + grub_device_t ins_dev; + + grub_install_mkdir_p (core_services); + + boot_efi = grub_util_path_concat (2, core_services, "boot.efi"); + grub_install_copy_file (imgfile, boot_efi, 1); + + f = grub_util_fopen (mach_kernel, "r+"); + if (!f) + grub_util_error (_("Can't create file: %s"), strerror (errno)); + fclose (f); + + fill_core_services(core_services); + + ins_dev = grub_device_open (install_drive); + + bless (ins_dev, boot_efi, 1); + if (!removable && update_nvram) + { + /* Try to make this image bootable using the EFI Boot Manager, if available. */ + int ret; + ret = grub_install_register_efi (efidir_grub_dev, + "\\System\\Library\\CoreServices", + efi_distributor); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); + } + + grub_device_close (ins_dev); + free (boot_efi); + free (mach_kernel); + break; + } + /* FALLTHROUGH */ + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_MIPS64EL_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: + case GRUB_INSTALL_PLATFORM_IA64_EFI: + { + char *dst = grub_util_path_concat (2, efidir, efi_file); + grub_install_copy_file (imgfile, dst, 1); + free (dst); + } + if (!removable && update_nvram) + { + char * efifile_path; + char * part; + int ret; + + /* Try to make this image bootable using the EFI Boot Manager, if available. */ + if (!efi_distributor || efi_distributor[0] == '\0') + grub_util_error ("%s", _("EFI bootloader id isn't specified.")); + efifile_path = xasprintf ("\\EFI\\%s\\%s", + efi_distributor, + efi_file); + part = (efidir_grub_dev->disk->partition + ? grub_partition_get_name (efidir_grub_dev->disk->partition) + : 0); + grub_util_info ("Registering with EFI: distributor = `%s'," + " path = `%s', ESP at %s%s%s", + efi_distributor, efifile_path, + efidir_grub_dev->disk->name, + (part ? ",": ""), (part ? : "")); + grub_free (part); + ret = grub_install_register_efi (efidir_grub_dev, + efifile_path, efi_distributor); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); + } + break; + + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_MIPSEL_ARC: + case GRUB_INSTALL_PLATFORM_ARM_UBOOT: + case GRUB_INSTALL_PLATFORM_I386_QEMU: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: + grub_util_warn ("%s", + _("WARNING: no platform-specific install was performed")); + break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; + } + + fprintf (stderr, "%s\n", _("Installation finished. No error reported.")); + + /* Free resources. */ + grub_gcry_fini_all (); + grub_fini_all (); + + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in new file mode 100644 index 00000000..0c820d51 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkconfig_lib.in @@ -0,0 +1,373 @@ +# Helper library for grub-mkconfig +# Copyright (C) 2007,2008,2009,2010 Free Software Foundation, Inc. +# +# GRUB 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. +# +# GRUB 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 GRUB. If not, see . + +prefix="@prefix@" +exec_prefix="@exec_prefix@" +datarootdir="@datarootdir@" +datadir="@datadir@" +bindir="@bindir@" +sbindir="@sbindir@" +if [ "x$pkgdatadir" = x ]; then + pkgdatadir="${datadir}/@PACKAGE@" +fi + +if test "x$grub_probe" = x; then + grub_probe="${sbindir}/@grub_probe@" +fi +if test "x$grub_file" = x; then + grub_file="${bindir}/@grub_file@" +fi +if test "x$grub_mkrelpath" = x; then + grub_mkrelpath="${bindir}/@grub_mkrelpath@" +fi + +if which gettext >/dev/null 2>/dev/null; then + : +else + gettext () { + printf "%s" "$@" + } +fi + +grub_warn () +{ + echo "$(gettext "Warning:")" "$@" >&2 +} + +make_system_path_relative_to_its_root () +{ + "${grub_mkrelpath}" "$1" +} + +is_path_readable_by_grub () +{ + path="$1" + + # abort if path doesn't exist + if test -e "$path" ; then : ;else + return 1 + fi + + # abort if file is in a filesystem we can't read + if "${grub_probe}" -t fs "$path" > /dev/null 2>&1 ; then : ; else + return 1 + fi + + # ... or if we can't figure out the abstraction module, for example if + # memberlist fails on an LVM volume group. + if abstractions="`"${grub_probe}" -t abstraction "$path"`" 2> /dev/null ; then + : + else + return 1 + fi + + if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then + return 0 + fi + + for abstraction in $abstractions; do + if [ "x$abstraction" = xcryptodisk ]; then + return 1 + fi + done + + return 0 +} + +convert_system_path_to_grub_path () +{ + path="$1" + + grub_warn "convert_system_path_to_grub_path() is deprecated. Use prepare_grub_to_access_device() instead." + + # abort if GRUB can't access the path + if is_path_readable_by_grub "${path}" ; then : ; else + return 1 + fi + + if drive="`"${grub_probe}" -t drive "$path"`" ; then : ; else + return 1 + fi + + if relative_path="`make_system_path_relative_to_its_root "$path"`" ; then : ; else + return 1 + fi + + echo "${drive}${relative_path}" +} + +save_default_entry () +{ + if [ "x${GRUB_SAVEDEFAULT}" = "xtrue" ] ; then + cat << EOF +savedefault +EOF + fi +} + +prepare_grub_to_access_device () +{ + old_ifs="$IFS" + IFS=' +' +:<<\EOF + partmap="`"${grub_probe}" --device $@ --target=partmap`" + for module in ${partmap} ; do + case "${module}" in + netbsd | openbsd) + echo "insmod part_bsd";; + *) + echo "insmod part_${module}";; + esac + done +EOF + + # Abstraction modules aren't auto-loaded. + abstraction="`"${grub_probe}" --device $@ --target=abstraction`" + for module in ${abstraction} ; do + echo "insmod ${module}" + done + +# fs="`"${grub_probe}" --device $@ --target=fs`" +# for module in ${fs} ; do +# echo "insmod ${module}" +# done + + if [ x$GRUB_ENABLE_CRYPTODISK = xy ]; then + for uuid in `"${grub_probe}" --device $@ --target=cryptodisk_uuid`; do + echo "cryptomount -u $uuid" + done + fi + + # If there's a filesystem UUID that GRUB is capable of identifying, use it; + # otherwise set root as per value in device.map. + fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`" + if [ "x$fs_hint" != x ]; then + echo "set root='$fs_hint'" + fi + if fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then + hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= + echo "if [ x\$feature_platform_search_hint = xy ]; then" + echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" + echo "else" + echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" + echo "fi" + fi + IFS="$old_ifs" +} + +grub_get_device_id () +{ + old_ifs="$IFS" + IFS=' +' + device="$1" + if fs_uuid="`"${grub_probe}" --device ${device} --target=fs_uuid 2> /dev/null`" ; then + echo "$fs_uuid"; + else + echo $device |sed 's, ,_,g' + fi + IFS="$old_ifs" +} + +grub_file_is_not_garbage () +{ + if test -f "$1" ; then + case "$1" in + *.dpkg-*) return 1 ;; # debian dpkg + *.rpmsave|*.rpmnew) return 1 ;; + README*|*/README*) return 1 ;; # documentation + *.sig) return 1 ;; # signatures + esac + else + return 1 + fi + return 0 +} + +version_sort () +{ + case $version_sort_sort_has_v in + yes) + LC_ALL=C sort -V;; + no) + LC_ALL=C sort -n;; + *) + if sort -V /dev/null 2>&1; then + version_sort_sort_has_v=yes + LC_ALL=C sort -V + else + version_sort_sort_has_v=no + LC_ALL=C sort -n + fi;; + esac +} + +version_test_numeric () +{ + version_test_numeric_a="$1" + version_test_numeric_cmp="$2" + version_test_numeric_b="$3" + if [ "$version_test_numeric_a" = "$version_test_numeric_b" ] ; then + case "$version_test_numeric_cmp" in + ge|eq|le) return 0 ;; + gt|lt) return 1 ;; + esac + fi + if [ "$version_test_numeric_cmp" = "lt" ] ; then + version_test_numeric_c="$version_test_numeric_a" + version_test_numeric_a="$version_test_numeric_b" + version_test_numeric_b="$version_test_numeric_c" + fi + if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then + return 0 + else + return 1 + fi +} + +version_test_gt () +{ + version_test_gt_a="`echo "$1" | sed -e "s/[^-]*-//"`" + version_test_gt_b="`echo "$2" | sed -e "s/[^-]*-//"`" + version_test_gt_cmp=gt + if [ "x$version_test_gt_b" = "x" ] ; then + return 0 + fi + case "$version_test_gt_a:$version_test_gt_b" in + *.old:*.old) ;; + *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;; + *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;; + esac + version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" + return "$?" +} + +version_find_latest () +{ + version_find_latest_a="" + for i in "$@" ; do + if version_test_gt "$i" "$version_find_latest_a" ; then + version_find_latest_a="$i" + fi + done + echo "$version_find_latest_a" +} + +# One layer of quotation is eaten by "" and the second by sed; so this turns +# ' into \'. +grub_quote () { + sed "s/'/'\\\\''/g" +} + +gettext_quoted () { + gettext "$@" | grub_quote +} + +# Run the first argument through gettext, and then pass that and all +# remaining arguments to printf. This is a useful abbreviation and tends to +# be easier to type. +gettext_printf () { + gettext_printf_format="$1" + shift + printf "$(gettext "$gettext_printf_format")" "$@" +} + +uses_abstraction () { + device="$1" + old_ifs="$IFS" + IFS=' +' + + abstraction="`"${grub_probe}" --device ${device} --target=abstraction`" + for module in ${abstraction}; do + if test "x${module}" = "x$2"; then + IFS="$old_ifs" + return 0 + fi + done + IFS="$old_ifs" + return 1 +} + +print_option_help () { + if test x$print_option_help_wc = x; then + if wc -L /dev/null 2>&1; then + print_option_help_wc=-L + elif wc -m /dev/null 2>&1; then + print_option_help_wc=-m + else + print_option_help_wc=-b + fi + fi + if test x$grub_have_fmt = x; then + if fmt -w 40 /dev/null 2>&1; then + grub_have_fmt=y; + else + grub_have_fmt=n; + fi + fi + print_option_help_lead=" $1" + print_option_help_lspace="$(echo "$print_option_help_lead" | wc $print_option_help_wc)" + print_option_help_fill="$((26 - print_option_help_lspace))" + printf "%s" "$print_option_help_lead" + if test $print_option_help_fill -le 0; then + print_option_help_nl=y + echo + else + print_option_help_i=0; + while test $print_option_help_i -lt $print_option_help_fill; do + printf " " + print_option_help_i=$((print_option_help_i+1)) + done + print_option_help_nl=n + fi + if test x$grub_have_fmt = xy; then + print_option_help_split="$(echo "$2" | fmt -w 50)" + else + print_option_help_split="$2" + fi + if test x$print_option_help_nl = xy; then + echo "$print_option_help_split" | awk \ + '{ print " " $0; }' + else + echo "$print_option_help_split" | awk 'BEGIN { n = 0 } + { if (n == 1) print " " $0; else print $0; n = 1 ; }' + fi +} + +grub_fmt () { + if test x$grub_have_fmt = x; then + if fmt -w 40 < /dev/null > /dev/null; then + grub_have_fmt=y; + else + grub_have_fmt=n; + fi + fi + + if test x$grub_have_fmt = xy; then + fmt + else + cat + fi +} + +grub_tab=" " + +grub_add_tab () { + sed -e "s/^/$grub_tab/" +} + diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c new file mode 100644 index 00000000..de8fd250 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkimagexx.c @@ -0,0 +1,2689 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#pragma GCC diagnostic ignored "-Wcast-align" + +#define GRUB_MKIMAGEXX +#if !defined(MKIMAGE_ELF32) && !defined(MKIMAGE_ELF64) +#if __SIZEOF_POINTER__ == 8 +#include "grub-mkimage64.c" +#else +#include "grub-mkimage32.c" +#endif +#endif + +/* These structures are defined according to the CHRP binding to IEEE1275, + "Client Program Format" section. */ + +struct grub_ieee1275_note_desc +{ + grub_uint32_t real_mode; + grub_uint32_t real_base; + grub_uint32_t real_size; + grub_uint32_t virt_base; + grub_uint32_t virt_size; + grub_uint32_t load_base; +}; + +#define GRUB_IEEE1275_NOTE_NAME "PowerPC" +#define GRUB_IEEE1275_NOTE_TYPE 0x1275 + +struct grub_ieee1275_note +{ + Elf32_Nhdr header; + char name[ALIGN_UP(sizeof (GRUB_IEEE1275_NOTE_NAME), 4)]; + struct grub_ieee1275_note_desc descriptor; +}; + +#define GRUB_XEN_NOTE_NAME "Xen" + +struct fixup_block_list +{ + struct fixup_block_list *next; + int state; + struct grub_pe32_fixup_block b; +}; + +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +struct section_metadata +{ + Elf_Half num_sections; + Elf_Shdr *sections; + Elf_Addr *addrs; + Elf_Addr *vaddrs; + Elf_Half section_entsize; + Elf_Shdr *symtab; + const char *strtab; +}; + +static int +is_relocatable (const struct grub_install_image_target_desc *image_target) +{ + return image_target->id == IMAGE_EFI || image_target->id == IMAGE_UBOOT + || (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM); +} + +#ifdef MKIMAGE_ELF32 + +/* + * R_ARM_THM_CALL/THM_JUMP24 + * + * Relocate Thumb (T32) instruction set relative branches: + * B.W, BL and BLX + */ +static grub_err_t +grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + offset = grub_arm_thm_call_get_offset (target); + + grub_dprintf ("dl", " sym_addr = 0x%08x", sym_addr); + + offset += sym_addr; + + grub_dprintf("dl", " BL*: target=%p, sym_addr=0x%08x, offset=%d\n", + target, sym_addr, offset); + + /* Keep traditional (pre-Thumb2) limits on blx. In any case if the kernel + is bigger than 2M (currently under 150K) then we probably have a problem + somewhere else. */ + if (offset < -0x200000 || offset >= 0x200000) + return grub_error (GRUB_ERR_BAD_MODULE, + "THM_CALL Relocation out of range."); + + grub_dprintf ("dl", " relative destination = %p", + (char *) target + offset); + + return grub_arm_thm_call_set_offset (target, offset); +} + +/* + * R_ARM_THM_JUMP19 + * + * Relocate conditional Thumb (T32) B.W + */ +static grub_err_t +grub_arm_reloc_thm_jump19 (grub_uint16_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + if (!(sym_addr & 1)) + return grub_error (GRUB_ERR_BAD_MODULE, + "Relocation targeting wrong execution state"); + + offset = grub_arm_thm_jump19_get_offset (target); + + /* Adjust and re-truncate offset */ + offset += sym_addr; + + if (!grub_arm_thm_jump19_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + "THM_JUMP19 Relocation out of range."); + + grub_arm_thm_jump19_set_offset (target, offset); + + return GRUB_ERR_NONE; +} + +/* + * R_ARM_JUMP24 + * + * Relocate ARM (A32) B + */ +static grub_err_t +grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) +{ + grub_int32_t offset; + + if (sym_addr & 1) + return grub_error (GRUB_ERR_BAD_MODULE, + "Relocation targeting wrong execution state"); + + offset = grub_arm_jump24_get_offset (target); + offset += sym_addr; + + if (!grub_arm_jump24_check_offset (offset)) + return grub_error (GRUB_ERR_BAD_MODULE, + "JUMP24 Relocation out of range."); + + + grub_arm_jump24_set_offset (target, offset); + + return GRUB_ERR_NONE; +} + +#endif + +void +SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target, + int note, char **core_img, size_t *core_size, + Elf_Addr target_addr, + struct grub_mkimage_layout *layout) +{ + char *elf_img; + size_t program_size; + Elf_Ehdr *ehdr; + Elf_Phdr *phdr; + Elf_Shdr *shdr; + int header_size, footer_size = 0; + int phnum = 1; + int shnum = 4; + int string_size = sizeof (".text") + sizeof ("mods") + 1; + + if (image_target->id != IMAGE_LOONGSON_ELF) + phnum += 2; + + if (note) + { + phnum++; + footer_size += sizeof (struct grub_ieee1275_note); + } + if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) + { + phnum++; + shnum++; + string_size += sizeof (".xen"); + footer_size += (image_target->id == IMAGE_XEN) ? XEN_NOTE_SIZE : XEN_PVH_NOTE_SIZE; + } + header_size = ALIGN_UP (sizeof (*ehdr) + phnum * sizeof (*phdr) + + shnum * sizeof (*shdr) + string_size, layout->align); + + program_size = ALIGN_ADDR (*core_size); + + elf_img = xmalloc (program_size + header_size + footer_size); + memset (elf_img, 0, program_size + header_size + footer_size); + memcpy (elf_img + header_size, *core_img, *core_size); + ehdr = (void *) elf_img; + phdr = (void *) (elf_img + sizeof (*ehdr)); + shdr = (void *) (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)); + memcpy (ehdr->e_ident, ELFMAG, SELFMAG); + ehdr->e_ident[EI_CLASS] = ELFCLASSXX; + if (!image_target->bigendian) + ehdr->e_ident[EI_DATA] = ELFDATA2LSB; + else + ehdr->e_ident[EI_DATA] = ELFDATA2MSB; + ehdr->e_ident[EI_VERSION] = EV_CURRENT; + ehdr->e_ident[EI_OSABI] = ELFOSABI_NONE; + ehdr->e_type = grub_host_to_target16 (ET_EXEC); + ehdr->e_machine = grub_host_to_target16 (image_target->elf_target); + ehdr->e_version = grub_host_to_target32 (EV_CURRENT); + + ehdr->e_phoff = grub_host_to_target32 ((char *) phdr - (char *) ehdr); + ehdr->e_phentsize = grub_host_to_target16 (sizeof (*phdr)); + ehdr->e_phnum = grub_host_to_target16 (phnum); + + ehdr->e_shoff = grub_host_to_target32 ((grub_uint8_t *) shdr + - (grub_uint8_t *) ehdr); + if (image_target->id == IMAGE_LOONGSON_ELF) + ehdr->e_shentsize = grub_host_to_target16 (0); + else + ehdr->e_shentsize = grub_host_to_target16 (sizeof (Elf_Shdr)); + ehdr->e_shnum = grub_host_to_target16 (shnum); + ehdr->e_shstrndx = grub_host_to_target16 (1); + + ehdr->e_ehsize = grub_host_to_target16 (sizeof (*ehdr)); + + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + + ehdr->e_entry = grub_host_to_target32 (target_addr); + phdr->p_vaddr = grub_host_to_target32 (target_addr); + phdr->p_paddr = grub_host_to_target32 (target_addr); + phdr->p_align = grub_host_to_target32 (layout->align > image_target->link_align ? + layout->align : image_target->link_align); + if (image_target->id == IMAGE_LOONGSON_ELF) + ehdr->e_flags = grub_host_to_target32 (0x1000 | EF_MIPS_NOREORDER + | EF_MIPS_PIC | EF_MIPS_CPIC); + else + ehdr->e_flags = 0; + if (image_target->id == IMAGE_LOONGSON_ELF) + { + phdr->p_filesz = grub_host_to_target32 (*core_size); + phdr->p_memsz = grub_host_to_target32 (*core_size); + } + else + { + grub_uint32_t target_addr_mods; + phdr->p_filesz = grub_host_to_target32 (layout->kernel_size); + if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM) + phdr->p_memsz = grub_host_to_target32 (layout->kernel_size); + else + phdr->p_memsz = grub_host_to_target32 (layout->kernel_size + layout->bss_size); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_GNU_STACK); + phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size); + phdr->p_paddr = phdr->p_vaddr = phdr->p_filesz = phdr->p_memsz = 0; + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_LOAD); + phdr->p_offset = grub_host_to_target32 (header_size + layout->kernel_size); + phdr->p_flags = grub_host_to_target32 (PF_R | PF_W | PF_X); + phdr->p_filesz = phdr->p_memsz + = grub_host_to_target32 (*core_size - layout->kernel_size); + + if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_386) + target_addr_mods = GRUB_KERNEL_I386_COREBOOT_MODULES_ADDR; + else if (image_target->id == IMAGE_COREBOOT && image_target->elf_target == EM_ARM) + target_addr_mods = ALIGN_UP (target_addr + layout->end + + image_target->mod_gap, + image_target->mod_align); + else + target_addr_mods = ALIGN_UP (target_addr + layout->kernel_size + layout->bss_size + + image_target->mod_gap, + image_target->mod_align); + phdr->p_vaddr = grub_host_to_target_addr (target_addr_mods); + phdr->p_paddr = grub_host_to_target_addr (target_addr_mods); + phdr->p_align = grub_host_to_target32 (image_target->link_align); + } + + if (image_target->id == IMAGE_XEN) + { + char *note_start = (elf_img + program_size + header_size); + Elf_Nhdr *note_ptr; + char *ptr = (char *) note_start; + + grub_util_info ("adding XEN NOTE segment"); + + /* Guest OS. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof (PACKAGE_NAME)); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_GUEST_OS); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, PACKAGE_NAME, sizeof (PACKAGE_NAME)); + ptr += ALIGN_UP (sizeof (PACKAGE_NAME), 4); + + /* Loader. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof ("generic")); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_LOADER); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, "generic", sizeof ("generic")); + ptr += ALIGN_UP (sizeof ("generic"), 4); + + /* Version. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof ("xen-3.0")); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_XEN_VERSION); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, "xen-3.0", sizeof ("xen-3.0")); + ptr += ALIGN_UP (sizeof ("xen-3.0"), 4); + + /* Entry. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_ENTRY); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memset (ptr, 0, image_target->voidp_sizeof); + ptr += image_target->voidp_sizeof; + + /* Virt base. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_VIRT_BASE); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memset (ptr, 0, image_target->voidp_sizeof); + ptr += image_target->voidp_sizeof; + + /* PAE. */ + if (image_target->elf_target == EM_386) + { + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (sizeof ("yes,bimodal")); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PAE_MODE); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memcpy (ptr, "yes", sizeof ("yes")); + ptr += ALIGN_UP (sizeof ("yes"), 4); + } + + assert (XEN_NOTE_SIZE == (ptr - note_start)); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (XEN_NOTE_SIZE); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); + } + + if (image_target->id == IMAGE_XEN_PVH) + { + char *note_start = (elf_img + program_size + header_size); + Elf_Nhdr *note_ptr; + char *ptr = (char *) note_start; + + grub_util_info ("adding XEN NOTE segment"); + + /* Phys32 Entry. */ + note_ptr = (Elf_Nhdr *) ptr; + note_ptr->n_namesz = grub_host_to_target32 (sizeof (GRUB_XEN_NOTE_NAME)); + note_ptr->n_descsz = grub_host_to_target32 (image_target->voidp_sizeof); + note_ptr->n_type = grub_host_to_target32 (XEN_ELFNOTE_PHYS32_ENTRY); + ptr += sizeof (Elf_Nhdr); + memcpy (ptr, GRUB_XEN_NOTE_NAME, sizeof (GRUB_XEN_NOTE_NAME)); + ptr += ALIGN_UP (sizeof (GRUB_XEN_NOTE_NAME), 4); + memset (ptr, 0, image_target->voidp_sizeof); + *(grub_uint32_t *) ptr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR; + ptr += image_target->voidp_sizeof; + + assert (XEN_PVH_NOTE_SIZE == (ptr - note_start)); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (XEN_PVH_NOTE_SIZE); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); + } + + if (note) + { + int note_size = sizeof (struct grub_ieee1275_note); + struct grub_ieee1275_note *note_ptr = (struct grub_ieee1275_note *) + (elf_img + program_size + header_size); + + grub_util_info ("adding CHRP NOTE segment"); + + note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_IEEE1275_NOTE_NAME)); + note_ptr->header.n_descsz = grub_host_to_target32 (note_size); + note_ptr->header.n_type = grub_host_to_target32 (GRUB_IEEE1275_NOTE_TYPE); + strcpy (note_ptr->name, GRUB_IEEE1275_NOTE_NAME); + note_ptr->descriptor.real_mode = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.real_base = grub_host_to_target32 (0x00c00000); + note_ptr->descriptor.real_size = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.virt_base = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.virt_size = grub_host_to_target32 (0xffffffff); + note_ptr->descriptor.load_base = grub_host_to_target32 (0x00004000); + + phdr++; + phdr->p_type = grub_host_to_target32 (PT_NOTE); + phdr->p_flags = grub_host_to_target32 (PF_R); + phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof); + phdr->p_vaddr = 0; + phdr->p_paddr = 0; + phdr->p_filesz = grub_host_to_target32 (note_size); + phdr->p_memsz = 0; + phdr->p_offset = grub_host_to_target32 (header_size + program_size); + } + + { + char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr) + + shnum * sizeof (*shdr)); + char *ptr = str_start + 1; + + shdr++; + + shdr->sh_name = grub_host_to_target32 (0); + shdr->sh_type = grub_host_to_target32 (SHT_STRTAB); + shdr->sh_addr = grub_host_to_target_addr (0); + shdr->sh_offset = grub_host_to_target_addr (str_start - elf_img); + shdr->sh_size = grub_host_to_target32 (string_size); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (layout->align); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + + memcpy (ptr, ".text", sizeof (".text")); + + shdr->sh_name = grub_host_to_target32 (ptr - str_start); + ptr += sizeof (".text"); + shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); + shdr->sh_addr = grub_host_to_target_addr (target_addr); + shdr->sh_offset = grub_host_to_target_addr (header_size); + shdr->sh_size = grub_host_to_target32 (layout->kernel_size); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (layout->align); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + + memcpy (ptr, "mods", sizeof ("mods")); + shdr->sh_name = grub_host_to_target32 (ptr - str_start); + ptr += sizeof ("mods"); + shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); + shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size); + shdr->sh_offset = grub_host_to_target_addr (header_size + layout->kernel_size); + shdr->sh_size = grub_host_to_target32 (*core_size - layout->kernel_size); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + + if (image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) + { + memcpy (ptr, ".xen", sizeof (".xen")); + shdr->sh_name = grub_host_to_target32 (ptr - str_start); + ptr += sizeof (".xen"); + shdr->sh_type = grub_host_to_target32 (SHT_PROGBITS); + shdr->sh_addr = grub_host_to_target_addr (target_addr + layout->kernel_size); + shdr->sh_offset = grub_host_to_target_addr (program_size + header_size); + if (image_target->id == IMAGE_XEN) + shdr->sh_size = grub_host_to_target32 (XEN_NOTE_SIZE); + else + shdr->sh_size = grub_host_to_target32 (XEN_PVH_NOTE_SIZE); + shdr->sh_link = grub_host_to_target32 (0); + shdr->sh_info = grub_host_to_target32 (0); + shdr->sh_addralign = grub_host_to_target32 (image_target->voidp_sizeof); + shdr->sh_entsize = grub_host_to_target32 (0); + shdr++; + } + } + + free (*core_img); + *core_img = elf_img; + *core_size = program_size + header_size + footer_size; +} + +/* Relocate symbols; note that this function overwrites the symbol table. + Return the address of a start symbol. */ +static Elf_Addr +SUFFIX (relocate_symbols) (Elf_Ehdr *e, struct section_metadata *smd, + void *jumpers, Elf_Addr jumpers_addr, + Elf_Addr bss_start, Elf_Addr end, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Addr start_address = (Elf_Addr) -1; + Elf_Sym *sym; + Elf_Word i; + Elf_Shdr *symtab_section; + const char *symtab; + grub_uint64_t *jptr = jumpers; + + symtab_section = (Elf_Shdr *) ((char *) smd->sections + + grub_target_to_host32 (smd->symtab->sh_link) + * smd->section_entsize); + symtab = (char *) e + grub_target_to_host (symtab_section->sh_offset); + + symtab_size = grub_target_to_host (smd->symtab->sh_size); + sym_size = grub_target_to_host (smd->symtab->sh_entsize); + symtab_offset = grub_target_to_host (smd->symtab->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + { + Elf_Section cur_index; + const char *name; + + name = symtab + grub_target_to_host32 (sym->st_name); + + cur_index = grub_target_to_host16 (sym->st_shndx); + if (cur_index == STN_ABS) + { + continue; + } + else if (cur_index == STN_UNDEF) + { + if (sym->st_name && grub_strcmp (name, "__bss_start") == 0) + sym->st_value = bss_start; + else if (sym->st_name && grub_strcmp (name, "_end") == 0) + sym->st_value = end; + else if (sym->st_name) + grub_util_error ("undefined symbol %s", name); + else + continue; + } + else if (cur_index >= smd->num_sections) + grub_util_error ("section %d does not exist", cur_index); + else + { + sym->st_value = (grub_target_to_host (sym->st_value) + + smd->vaddrs[cur_index]); + } + + if (image_target->elf_target == EM_IA_64 && ELF_ST_TYPE (sym->st_info) + == STT_FUNC) + { + *jptr = grub_host_to_target64 (sym->st_value); + sym->st_value = (char *) jptr - (char *) jumpers + jumpers_addr; + jptr++; + *jptr = 0; + jptr++; + } + grub_util_info ("locating %s at 0x%" GRUB_HOST_PRIxLONG_LONG + " (0x%" GRUB_HOST_PRIxLONG_LONG ")", name, + (unsigned long long) sym->st_value, + (unsigned long long) smd->vaddrs[cur_index]); + + if (start_address == (Elf_Addr)-1) + if (strcmp (name, "_start") == 0 || strcmp (name, "start") == 0) + start_address = sym->st_value; + } + + return start_address; +} + +/* Return the address of a symbol at the index I in the section S. */ +static Elf_Addr +SUFFIX (get_symbol_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Word i, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host (s->sh_offset) + + i * grub_target_to_host (s->sh_entsize)); + return sym->st_value; +} + +/* Return the address of a modified value. */ +static Elf_Addr * +SUFFIX (get_target_address) (Elf_Ehdr *e, Elf_Shdr *s, Elf_Addr offset, + const struct grub_install_image_target_desc *image_target) +{ + return (Elf_Addr *) ((char *) e + grub_target_to_host (s->sh_offset) + offset); +} + +#ifdef MKIMAGE_ELF64 +static Elf_Addr +SUFFIX (count_funcs) (Elf_Ehdr *e, Elf_Shdr *symtab_section, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Word symtab_size, sym_size, num_syms; + Elf_Off symtab_offset; + Elf_Sym *sym; + Elf_Word i; + int ret = 0; + + symtab_size = grub_target_to_host (symtab_section->sh_size); + sym_size = grub_target_to_host (symtab_section->sh_entsize); + symtab_offset = grub_target_to_host (symtab_section->sh_offset); + num_syms = symtab_size / sym_size; + + for (i = 0, sym = (Elf_Sym *) ((char *) e + symtab_offset); + i < num_syms; + i++, sym = (Elf_Sym *) ((char *) sym + sym_size)) + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + ret++; + + return ret; +} +#endif + +#ifdef MKIMAGE_ELF32 +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static grub_size_t +arm_get_trampoline_size (Elf_Ehdr *e, + Elf_Shdr *sections, + Elf_Half section_entsize, + Elf_Half num_sections, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; + grub_size_t ret = 0; + + for (i = 0, s = sections; + i < num_sections; + i++, s = (Elf_Shdr *) ((char *) s + section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Word j; + + symtab_section = (Elf_Shdr *) ((char *) sections + + (grub_target_to_host32 (s->sh_link) + * section_entsize)); + + rtab_size = grub_target_to_host (s->sh_size); + r_size = grub_target_to_host (s->sh_entsize); + rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr sym_addr; + + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + + sym_addr += (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (r->r_addend) : 0; + + switch (ELF_R_TYPE (info)) + { + case R_ARM_ABS32: + case R_ARM_V4BX: + break; + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + case R_ARM_THM_JUMP19: + if (!(sym_addr & 1)) + ret += 8; + break; + + case R_ARM_CALL: + case R_ARM_JUMP24: + if (sym_addr & 1) + ret += 16; + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + } + } + return ret; +} +#endif + +static int +SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target); +static int +SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target, + struct section_metadata *smd); + +/* Deal with relocation information. This function relocates addresses + within the virtual address space starting from 0. So only relative + addresses can be fully resolved. Absolute addresses must be relocated + again by a PE32 relocator when loaded. */ +static void +SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, + char *pe_target, Elf_Addr tramp_off, Elf_Addr got_off, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Half i; + Elf_Shdr *s; +#ifdef MKIMAGE_ELF64 + struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off); + grub_uint64_t *gpptr = (void *) (pe_target + got_off); + unsigned unmatched_adr_got_page = 0; +#define MASK19 ((1 << 19) - 1) +#else + grub_uint32_t *tr = (void *) (pe_target + tramp_off); +#endif + + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if ((s->sh_type == grub_host_to_target32 (SHT_REL)) || + (s->sh_type == grub_host_to_target32 (SHT_RELA))) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Word target_section_index; + Elf_Addr target_section_addr; + Elf_Shdr *target_section; + Elf_Word j; + + if (!SUFFIX (is_kept_section) (s, image_target) && + !SUFFIX (is_kept_reloc_section) (s, image_target, smd)) + { + grub_util_info ("not translating relocations for omitted section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + continue; + } + + target_section_index = grub_target_to_host32 (s->sh_info); + target_section_addr = smd->addrs[target_section_index]; + target_section = (Elf_Shdr *) ((char *) smd->sections + + (target_section_index + * smd->section_entsize)); + + grub_util_info ("dealing with the relocation section %s for %s", + smd->strtab + grub_target_to_host32 (s->sh_name), + smd->strtab + grub_target_to_host32 (target_section->sh_name)); + + rtab_size = grub_target_to_host (s->sh_size); + r_size = grub_target_to_host (s->sh_entsize); + rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr sym_addr; + Elf_Addr *target; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + target = SUFFIX (get_target_address) (e, target_section, + offset, image_target); + if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8) + info = ((grub_uint64_t) r->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (r->r_info); + else + info = grub_target_to_host (r->r_info); + sym_addr = SUFFIX (get_symbol_address) (e, smd->symtab, + ELF_R_SYM (info), image_target); + + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (r->r_addend) : 0; + + switch (image_target->elf_target) + { + case EM_386: + switch (ELF_R_TYPE (info)) + { + case R_386_NONE: + break; + + case R_386_32: + /* This is absolute. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_386_32 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + + case R_386_PC32: + /* This is relative. */ + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_386_PC32 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#ifdef MKIMAGE_ELF64 + case EM_X86_64: + switch (ELF_R_TYPE (info)) + { + + case R_X86_64_NONE: + break; + + case R_X86_64_64: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_64 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + + case R_X86_64_PC32: + case R_X86_64_PLT32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC32 entry to 0x%x at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + *t32, (unsigned long long) offset); + break; + } + + case R_X86_64_PC64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_X86_64_PC64 entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) *target, + (unsigned long long) offset); + break; + } + + case R_X86_64_32: + case R_X86_64_32S: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + addend + sym_addr); + grub_util_info ("relocating an R_X86_64_32(S) entry to 0x%x at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + *t32, (unsigned long long) offset); + break; + } + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + case EM_IA_64: + switch (ELF_R_TYPE (info)) + { + case R_IA64_PCREL21B: + { + grub_uint64_t noff; + grub_ia64_make_trampoline (tr, addend + sym_addr); + noff = ((char *) tr - (char *) pe_target + - target_section_addr - (offset & ~3)) >> 4; + tr++; + if (noff & ~MASK19) + grub_util_error ("trampoline offset too big (%" + GRUB_HOST_PRIxLONG_LONG ")", + (unsigned long long) noff); + grub_ia64_add_value_to_slot_20b ((grub_addr_t) target, noff); + } + break; + + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + { + Elf_Sym *sym; + + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host (smd->symtab->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize)); + if (ELF_ST_TYPE (sym->st_info) == STT_FUNC) + sym_addr = grub_target_to_host64 (*(grub_uint64_t *) (pe_target + + sym->st_value + - image_target->vaddr_offset)); + } + /* FALLTHROUGH */ + case R_IA64_LTOFF_FPTR22: + *gpptr = grub_host_to_target64 (addend + sym_addr); + grub_ia64_add_value_to_slot_21 ((grub_addr_t) target, + (char *) gpptr - (char *) pe_target + + image_target->vaddr_offset); + gpptr++; + break; + + case R_IA64_GPREL22: + grub_ia64_add_value_to_slot_21 ((grub_addr_t) target, + addend + sym_addr); + break; + case R_IA64_GPREL64I: + grub_ia64_set_immu64 ((grub_addr_t) target, + addend + sym_addr); + break; + case R_IA64_PCREL64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + break; + + case R_IA64_SEGREL64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr - target_section_addr); + break; + case R_IA64_DIR64LSB: + case R_IA64_FPTR64LSB: + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + + addend + sym_addr); + grub_util_info ("relocating a direct entry to 0x%" + GRUB_HOST_PRIxLONG_LONG " at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) + grub_target_to_host64 (*target), + (unsigned long long) offset); + break; + + /* We treat LTOFF22X as LTOFF22, so we can ignore LDXMOV. */ + case R_IA64_LDXMOV: + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + case EM_AARCH64: + { + sym_addr += addend; + switch (ELF_R_TYPE (info)) + { + case R_AARCH64_ABS64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr); + } + break; + case R_AARCH64_PREL32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + + sym_addr + - target_section_addr - offset + - image_target->vaddr_offset); + grub_util_info ("relocating an R_AARCH64_PREL32 entry to 0x%x at the offset 0x%" + GRUB_HOST_PRIxLONG_LONG, + *t32, (unsigned long long) offset); + break; + } + case R_AARCH64_ADD_ABS_LO12_NC: + grub_arm64_set_abs_lo12 ((grub_uint32_t *) target, + sym_addr); + break; + case R_AARCH64_LDST64_ABS_LO12_NC: + grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) target, + sym_addr); + break; + case R_AARCH64_JUMP26: + case R_AARCH64_CALL26: + { + sym_addr -= offset; + sym_addr -= target_section_addr + image_target->vaddr_offset; + if (!grub_arm_64_check_xxxx26_offset (sym_addr)) + grub_util_error ("%s", "CALL26 Relocation out of range"); + + grub_arm64_set_xxxx26_offset((grub_uint32_t *)target, + sym_addr); + } + break; + case R_AARCH64_ADR_GOT_PAGE: + { + Elf64_Rela *rel2; + grub_int64_t gpoffset = (((char *) gpptr - (char *) pe_target + image_target->vaddr_offset) & ~0xfffULL) + - ((offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL); + unsigned k; + *gpptr = grub_host_to_target64 (sym_addr); + unmatched_adr_got_page++; + if (!grub_arm64_check_hi21_signed (gpoffset)) + grub_util_error ("HI21 out of range"); + grub_arm64_set_hi21((grub_uint32_t *)target, + gpoffset); + for (k = 0, rel2 = (Elf_Rela *) ((char *) r + r_size); + k < num_rs; + k++, rel2 = (Elf_Rela *) ((char *) rel2 + r_size)) + if (ELF_R_SYM (rel2->r_info) + == ELF_R_SYM (r->r_info) + && r->r_addend == rel2->r_addend + && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC) + { + grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) SUFFIX (get_target_address) (e, target_section, + grub_target_to_host (rel2->r_offset), image_target), + ((char *) gpptr - (char *) pe_target + image_target->vaddr_offset)); + break; + } + if (k >= num_rs) + grub_util_error ("ADR_GOT_PAGE without matching LD64_GOT_LO12_NC"); + gpptr++; + } + break; + case R_AARCH64_LD64_GOT_LO12_NC: + if (unmatched_adr_got_page == 0) + grub_util_error ("LD64_GOT_LO12_NC without matching ADR_GOT_PAGE"); + unmatched_adr_got_page--; + break; + case R_AARCH64_ADR_PREL_PG_HI21: + { + sym_addr &= ~0xfffULL; + sym_addr -= (offset + target_section_addr + image_target->vaddr_offset) & ~0xfffULL; + if (!grub_arm64_check_hi21_signed (sym_addr)) + grub_util_error ("%s", "CALL26 Relocation out of range"); + + grub_arm64_set_hi21((grub_uint32_t *)target, + sym_addr); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } + case EM_MIPS: + { + sym_addr += addend; + switch (ELF_R_TYPE (info)) + { + case R_MIPS_NONE: + break; + case R_MIPS_64: + { + *target = grub_host_to_target64 (grub_target_to_host64 (*target) + sym_addr); + } + break; + case R_MIPS_32: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + *t32 = grub_host_to_target64 (grub_target_to_host32 (*t32) + sym_addr); + } + break; + case R_MIPS_26: + { + grub_uint32_t *t32 = (grub_uint32_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t32 = ((*t32) & 0xfc000000U) | ((addr >> 2) & 0x3ffffffUL); + } + break; + case R_MIPS_LO16: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) addr; + } + break; + case R_MIPS_HI16: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) ((addr + 0x8000UL) >> 16); + } + break; + case R_MIPS_HIGHER: + { + grub_int16_t *t16 = (grub_int16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_int16_t) ((addr + 0x80008000UL) >> 32); + } + break; + case R_MIPS_HIGHEST: + { + grub_uint16_t *t16 = (grub_uint16_t *) target; + grub_addr_t addr = grub_host_to_target64 (sym_addr); + *t16 = (grub_uint16_t) ((addr + 0x800080008000UL) >> 48); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } +#endif +#if defined(MKIMAGE_ELF32) + case EM_ARM: + { + sym_addr += addend; + sym_addr -= image_target->vaddr_offset; + switch (ELF_R_TYPE (info)) + { + case R_ARM_ABS32: + { + grub_util_info (" ABS32:\toffset=%d\t(0x%08x)", + (int) sym_addr, (int) sym_addr); + /* Data will be naturally aligned */ + if (image_target->id == IMAGE_EFI) + sym_addr += GRUB_PE32_SECTION_ALIGNMENT; + *target = grub_host_to_target32 (grub_target_to_host32 (*target) + sym_addr); + } + break; + /* Happens when compiled with -march=armv4. + Since currently we need at least armv5, keep bx as-is. + */ + case R_ARM_V4BX: + break; + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP24: + case R_ARM_THM_JUMP19: + { + grub_err_t err; + Elf_Sym *sym; + grub_util_info (" THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", + (unsigned long) ((char *) target + - (char *) e), + sym_addr); + sym = (Elf_Sym *) ((char *) e + + grub_target_to_host (smd->symtab->sh_offset) + + ELF_R_SYM (info) * grub_target_to_host (smd->symtab->sh_entsize)); + if (ELF_ST_TYPE (sym->st_info) != STT_FUNC) + sym_addr |= 1; + if (!(sym_addr & 1)) + { + grub_uint32_t tr_addr; + grub_int32_t new_offset; + tr_addr = (char *) tr - (char *) pe_target + - target_section_addr; + new_offset = sym_addr - tr_addr - 12; + + if (!grub_arm_jump24_check_offset (new_offset)) + return grub_util_error ("jump24 relocation out of range"); + + tr[0] = grub_host_to_target32 (0x46c04778); /* bx pc; nop */ + tr[1] = grub_host_to_target32 (((new_offset >> 2) & 0xffffff) | 0xea000000); /* b new_offset */ + tr += 2; + sym_addr = tr_addr | 1; + } + sym_addr -= offset; + /* Thumb instructions can be 16-bit aligned */ + if (ELF_R_TYPE (info) == R_ARM_THM_JUMP19) + err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr); + else + err = grub_arm_reloc_thm_call ((grub_uint16_t *) target, + sym_addr); + if (err) + grub_util_error ("%s", grub_errmsg); + } + break; + + case R_ARM_CALL: + case R_ARM_JUMP24: + { + grub_err_t err; + grub_util_info (" JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)", (unsigned long) ((char *) target - (char *) e), sym_addr); + if (sym_addr & 1) + { + grub_uint32_t tr_addr; + grub_int32_t new_offset; + tr_addr = (char *) tr - (char *) pe_target + - target_section_addr; + new_offset = sym_addr - tr_addr - 12; + + /* There is no immediate version of bx, only register one... */ + tr[0] = grub_host_to_target32 (0xe59fc004); /* ldr ip, [pc, #4] */ + tr[1] = grub_host_to_target32 (0xe08cc00f); /* add ip, ip, pc */ + tr[2] = grub_host_to_target32 (0xe12fff1c); /* bx ip */ + tr[3] = grub_host_to_target32 (new_offset | 1); + tr += 4; + sym_addr = tr_addr; + } + sym_addr -= offset; + err = grub_arm_reloc_jump24 (target, + sym_addr); + if (err) + grub_util_error ("%s", grub_errmsg); + } + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } +#endif /* MKIMAGE_ELF32 */ + case EM_RISCV: + { + grub_uint64_t *t64 = (grub_uint64_t *) target; + grub_uint32_t *t32 = (grub_uint32_t *) target; + grub_uint16_t *t16 = (grub_uint16_t *) target; + grub_uint8_t *t8 = (grub_uint8_t *) target; + grub_int64_t off = (long)sym_addr - target_section_addr - offset + - image_target->vaddr_offset; + + /* + * Instructions and instruction encoding are documented in the RISC-V + * specification. This file is based on version 2.2: + * + * https://github.com/riscv/riscv-isa-manual/blob/master/release/riscv-spec-v2.2.pdf + */ + + sym_addr += addend; + + switch (ELF_R_TYPE (info)) + { + case R_RISCV_ADD8: + *t8 = *t8 + sym_addr; + break; + case R_RISCV_ADD16: + *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) + sym_addr); + break; + case R_RISCV_32: + case R_RISCV_ADD32: + *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) + sym_addr); + break; + case R_RISCV_64: + case R_RISCV_ADD64: + *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + sym_addr); + break; + + case R_RISCV_SUB8: + *t8 = sym_addr - *t8; + break; + case R_RISCV_SUB16: + *t16 = grub_host_to_target16 (grub_target_to_host16 (*t16) - sym_addr); + break; + case R_RISCV_SUB32: + *t32 = grub_host_to_target32 (grub_target_to_host32 (*t32) - sym_addr); + break; + case R_RISCV_SUB64: + *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) - sym_addr); + break; + case R_RISCV_BRANCH: + { + grub_uint32_t imm12 = (off & 0x1000) << (31 - 12); + grub_uint32_t imm11 = (off & 0x800) >> (11 - 7); + grub_uint32_t imm10_5 = (off & 0x7e0) << (30 - 10); + grub_uint32_t imm4_1 = (off & 0x1e) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) + | imm12 | imm11 | imm10_5 | imm4_1); + } + break; + case R_RISCV_JAL: + { + grub_uint32_t imm20 = (off & 0x100000) << (31 - 20); + grub_uint32_t imm19_12 = (off & 0xff000); + grub_uint32_t imm11 = (off & 0x800) << (20 - 11); + grub_uint32_t imm10_1 = (off & 0x7fe) << (30 - 10); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) + | imm20 | imm19_12 | imm11 | imm10_1); + } + break; + case R_RISCV_CALL: + { + grub_uint32_t hi20, lo12; + + if (off != (grub_int32_t)off) + grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e)); + + hi20 = (off + 0x800) & 0xfffff000; + lo12 = (off - hi20) & 0xfff; + t32[0] = grub_host_to_target32 ((grub_target_to_host32 (t32[0]) & 0xfff) | hi20); + t32[1] = grub_host_to_target32 ((grub_target_to_host32 (t32[1]) & 0xfffff) | (lo12 << 20)); + } + break; + case R_RISCV_RVC_BRANCH: + { + grub_uint16_t imm8 = (off & 0x100) << (12 - 8); + grub_uint16_t imm7_6 = (off & 0xc0) >> (6 - 5); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4_3 = (off & 0x18) << (12 - 5); + grub_uint16_t imm2_1 = (off & 0x6) << (12 - 10); + *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe383) + | imm8 | imm7_6 | imm5 | imm4_3 | imm2_1); + } + break; + case R_RISCV_RVC_JUMP: + { + grub_uint16_t imm11 = (off & 0x800) << (12 - 11); + grub_uint16_t imm10 = (off & 0x400) >> (10 - 8); + grub_uint16_t imm9_8 = (off & 0x300) << (12 - 11); + grub_uint16_t imm7 = (off & 0x80) >> (7 - 6); + grub_uint16_t imm6 = (off & 0x40) << (12 - 11); + grub_uint16_t imm5 = (off & 0x20) >> (5 - 2); + grub_uint16_t imm4 = (off & 0x10) << (12 - 5); + grub_uint16_t imm3_1 = (off & 0xe) << (12 - 10); + *t16 = grub_host_to_target16 ((grub_target_to_host16 (*t16) & 0xe003) + | imm11 | imm10 | imm9_8 | imm7 | imm6 + | imm5 | imm4 | imm3_1); + } + break; + case R_RISCV_PCREL_HI20: + { + grub_int32_t hi20; + + if (off != (grub_int32_t)off) + grub_util_error ("target %lx not reachable from pc=%lx", (long)sym_addr, (long)((char *)target - (char *)e)); + + hi20 = (off + 0x800) & 0xfffff000; + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | hi20); + } + break; + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: + { + Elf_Rela *rel2; + Elf_Word k; + /* Search backwards for matching HI20 reloc. */ + for (k = j, rel2 = (Elf_Rela *) ((char *) r - r_size); + k > 0; + k--, rel2 = (Elf_Rela *) ((char *) rel2 - r_size)) + { + Elf_Addr rel2_info; + Elf_Addr rel2_offset; + Elf_Addr rel2_sym_addr; + Elf_Addr rel2_addend; + Elf_Addr rel2_loc; + grub_int64_t rel2_off; + + rel2_offset = grub_target_to_host (rel2->r_offset); + rel2_info = grub_target_to_host (rel2->r_info); + rel2_loc = target_section_addr + rel2_offset + image_target->vaddr_offset; + + if (ELF_R_TYPE (rel2_info) == R_RISCV_PCREL_HI20 + && rel2_loc == sym_addr) + { + rel2_sym_addr = SUFFIX (get_symbol_address) + (e, smd->symtab, ELF_R_SYM (rel2_info), + image_target); + rel2_addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (rel2->r_addend) : 0; + rel2_off = rel2_sym_addr + rel2_addend - rel2_loc; + off = rel2_off - ((rel2_off + 0x800) & 0xfffff000); + + if (ELF_R_TYPE (info) == R_RISCV_PCREL_LO12_I) + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | (off & 0xfff) << 20); + else + { + grub_uint32_t imm11_5 = (off & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (off & 0x1f) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0); + } + break; + } + } + if (k == 0) + grub_util_error ("cannot find matching HI20 relocation"); + } + break; + case R_RISCV_HI20: + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfff) | (((grub_int32_t) sym_addr + 0x800) & 0xfffff000)); + break; + case R_RISCV_LO12_I: + { + grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0xfffff) | ((lo12 & 0xfff) << 20)); + } + break; + case R_RISCV_LO12_S: + { + grub_int32_t lo12 = (grub_int32_t) sym_addr - (((grub_int32_t) sym_addr + 0x800) & 0xfffff000); + grub_uint32_t imm11_5 = (lo12 & 0xfe0) << (31 - 11); + grub_uint32_t imm4_0 = (lo12 & 0x1f) << (11 - 4); + *t32 = grub_host_to_target32 ((grub_target_to_host32 (*t32) & 0x1fff07f) | imm11_5 | imm4_0); + } + break; + case R_RISCV_RELAX: + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + } + default: + grub_util_error ("unknown architecture type %d", + image_target->elf_target); + } + } + } +} + +/* Add a PE32's fixup entry for a relocation. Return the resulting address + after having written to the file OUT. */ +static Elf_Addr +add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, + Elf_Addr addr, int flush, Elf_Addr current_address, + const struct grub_install_image_target_desc *image_target) +{ + struct grub_pe32_fixup_block *b; + + b = &((*cblock)->b); + + /* First, check if it is necessary to write out the current block. */ + if ((*cblock)->state) + { + if (flush || (type && (addr < b->page_rva || b->page_rva + 0x1000 <= addr))) + { + grub_uint32_t size; + + if (flush) + { + /* Add as much padding as necessary to align the address + with a section boundary. */ + Elf_Addr next_address; + unsigned padding_size; + size_t cur_index; + + next_address = current_address + b->block_size; + padding_size = ((ALIGN_UP (next_address, image_target->section_align) + - next_address) + >> 1); + cur_index = ((b->block_size - sizeof (*b)) >> 1); + grub_util_info ("adding %d padding fixup entries", padding_size); + while (padding_size--) + { + b->entries[cur_index++] = 0; + b->block_size += 2; + } + } + else while (b->block_size & (8 - 1)) + { + /* If not aligned with a 32-bit boundary, add + a padding entry. */ + size_t cur_index; + + grub_util_info ("adding a padding fixup entry"); + cur_index = ((b->block_size - sizeof (*b)) >> 1); + b->entries[cur_index] = 0; + b->block_size += 2; + } + + /* Flush it. */ + grub_util_info ("writing %d bytes of a fixup block starting at 0x%x", + b->block_size, b->page_rva); + size = b->block_size; + current_address += size; + b->page_rva = grub_host_to_target32 (b->page_rva); + b->block_size = grub_host_to_target32 (b->block_size); + (*cblock)->next = xmalloc (sizeof (**cblock) + 2 * 0x1000); + memset ((*cblock)->next, 0, sizeof (**cblock) + 2 * 0x1000); + *cblock = (*cblock)->next; + } + } + + b = &((*cblock)->b); + + if (! flush) + { + grub_uint16_t entry; + size_t cur_index; + + /* If not allocated yet, allocate a block with enough entries. */ + if (! (*cblock)->state) + { + (*cblock)->state = 1; + + /* The spec does not mention the requirement of a Page RVA. + Here, align the address with a 4K boundary for safety. */ + if (type) + b->page_rva = (addr & ~(0x1000 - 1)); + b->block_size = sizeof (*b); + } + + /* Sanity check. */ + if (b->block_size >= sizeof (*b) + 2 * 0x1000) + grub_util_error ("too many fixup entries"); + + /* Add a new entry. */ + cur_index = ((b->block_size - sizeof (*b)) >> 1); + entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr); + b->entries[cur_index] = grub_host_to_target16 (entry); + b->block_size += 2; + } + + return current_address; +} + +struct raw_reloc +{ + struct raw_reloc *next; + grub_uint32_t offset; + enum raw_reloc_type { + RAW_RELOC_NONE = -1, + RAW_RELOC_32 = 0, + RAW_RELOC_MAX = 1, + } type; +}; + +struct translate_context +{ + /* PE */ + struct fixup_block_list *lst, *lst0; + Elf_Addr current_address; + + /* Raw */ + struct raw_reloc *raw_relocs; +}; + +static void +translate_reloc_start (struct translate_context *ctx, + const struct grub_install_image_target_desc *image_target) +{ + grub_memset (ctx, 0, sizeof (*ctx)); + if (image_target->id == IMAGE_EFI) + { + ctx->lst = ctx->lst0 = xmalloc (sizeof (*ctx->lst) + 2 * 0x1000); + memset (ctx->lst, 0, sizeof (*ctx->lst) + 2 * 0x1000); + ctx->current_address = 0; + } +} + +static void +translate_relocation_pe (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, + Elf_Addr sym_addr, + Elf_Addr addend, + const struct grub_install_image_target_desc *image_target) +{ + /* Necessary to relocate only absolute addresses. */ + switch (image_target->elf_target) + { + case EM_386: + if (ELF_R_TYPE (info) == R_386_32) + { + grub_util_info ("adding a relocation entry for 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) addr); + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } + break; + case EM_X86_64: + if ((ELF_R_TYPE (info) == R_X86_64_32) || + (ELF_R_TYPE (info) == R_X86_64_32S)) + { + grub_util_error ("can\'t add fixup entry for R_X86_64_32(S)"); + } + else if (ELF_R_TYPE (info) == R_X86_64_64) + { + grub_util_info ("adding a relocation entry for 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) addr); + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, ctx->current_address, + image_target); + } + break; + case EM_IA_64: + switch (ELF_R_TYPE (info)) + { + case R_IA64_PCREL64LSB: + case R_IA64_LDXMOV: + case R_IA64_PCREL21B: + case R_IA64_LTOFF_FPTR22: + case R_IA64_LTOFF22X: + case R_IA64_LTOFF22: + case R_IA64_GPREL22: + case R_IA64_GPREL64I: + case R_IA64_SEGREL64LSB: + break; + + case R_IA64_FPTR64LSB: + case R_IA64_DIR64LSB: +#if 1 + { + grub_util_info ("adding a relocation entry for 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) addr); + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, + 0, ctx->current_address, + image_target); + } +#endif + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + case EM_AARCH64: + switch (ELF_R_TYPE (info)) + { + case R_AARCH64_ABS64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + /* Relative relocations do not require fixup entries. */ + case R_AARCH64_CALL26: + case R_AARCH64_JUMP26: + case R_AARCH64_PREL32: + break; + /* Page-relative relocations do not require fixup entries. */ + case R_AARCH64_ADR_PREL_PG_HI21: + /* We page-align the whole kernel, so no need + for fixup entries. + */ + case R_AARCH64_ADD_ABS_LO12_NC: + case R_AARCH64_LDST64_ABS_LO12_NC: + break; + + /* GOT is relocated separately. */ + case R_AARCH64_ADR_GOT_PAGE: + case R_AARCH64_LD64_GOT_LO12_NC: + break; + + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#if defined(MKIMAGE_ELF64) + case EM_MIPS: + switch (ELF_R_TYPE (info)) + { + case R_MIPS_64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_32: +#if 0 + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } +#endif + break; + case R_MIPS_26: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_JMPADDR, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_LO16: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_LOW, + addr, 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HI16: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGH, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HIGHER: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGHER, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Highest */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_uint16_t) ((target & 0x800080008000UL) >> 48), + 0, ctx->current_address, + image_target); + } + break; + case R_MIPS_HIGHEST: + { + Elf_Addr target = sym_addr + addend; + + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_MIPS_HIGHEST, + addr, 0, ctx->current_address, + image_target); + /* Lo */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) target, + 0, ctx->current_address, + image_target); + /* Hi */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x8000UL) >> 16), + 0, ctx->current_address, + image_target); + /* Higher */ + ctx->current_address + = add_fixup_entry (&ctx->lst, 0, + (grub_int16_t) ((target & 0x80008000UL) >> 32), + 0, ctx->current_address, + image_target); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#endif +#if defined(MKIMAGE_ELF32) + case EM_ARM: + switch (ELF_R_TYPE (info)) + { + case R_ARM_V4BX: + /* Relative relocations do not require fixup entries. */ + case R_ARM_JUMP24: + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP19: + case R_ARM_THM_JUMP24: + case R_ARM_CALL: + { + grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address); + } + break; + /* Create fixup entry for PE/COFF loader */ + case R_ARM_ABS32: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; +#endif /* defined(MKIMAGE_ELF32) */ + case EM_RISCV: + switch (ELF_R_TYPE (info)) + { + case R_RISCV_32: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_HIGHLOW, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_64: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + addr, 0, ctx->current_address, + image_target); + } + break; + /* Relative relocations do not require fixup entries. */ + case R_RISCV_BRANCH: + case R_RISCV_JAL: + case R_RISCV_CALL: + case R_RISCV_PCREL_HI20: + case R_RISCV_PCREL_LO12_I: + case R_RISCV_PCREL_LO12_S: + case R_RISCV_RVC_BRANCH: + case R_RISCV_RVC_JUMP: + case R_RISCV_ADD32: + case R_RISCV_SUB32: + grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", __FUNCTION__, (unsigned int) addr, (unsigned int) ctx->current_address); + break; + case R_RISCV_HI20: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_HI20, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_LO12_I: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_LOW12I, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_LO12_S: + { + ctx->current_address + = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_RISCV_LOW12S, + addr, 0, ctx->current_address, + image_target); + } + break; + case R_RISCV_RELAX: + break; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + default: + grub_util_error ("unknown machine type 0x%x", image_target->elf_target); + } +} + +static enum raw_reloc_type +classify_raw_reloc (Elf_Addr info, + const struct grub_install_image_target_desc *image_target) +{ + /* Necessary to relocate only absolute addresses. */ + switch (image_target->elf_target) + { + case EM_ARM: + switch (ELF_R_TYPE (info)) + { + case R_ARM_V4BX: + case R_ARM_JUMP24: + case R_ARM_THM_CALL: + case R_ARM_THM_JUMP19: + case R_ARM_THM_JUMP24: + case R_ARM_CALL: + return RAW_RELOC_NONE; + case R_ARM_ABS32: + return RAW_RELOC_32; + default: + grub_util_error (_("relocation 0x%x is not implemented yet"), + (unsigned int) ELF_R_TYPE (info)); + break; + } + break; + default: + grub_util_error ("unknown machine type 0x%x", image_target->elf_target); + } +} + +static void +translate_relocation_raw (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, + const struct grub_install_image_target_desc *image_target) +{ + enum raw_reloc_type class = classify_raw_reloc (info, image_target); + struct raw_reloc *rel; + if (class == RAW_RELOC_NONE) + return; + rel = xmalloc (sizeof (*rel)); + rel->next = ctx->raw_relocs; + rel->type = class; + rel->offset = addr; + ctx->raw_relocs = rel; +} + +static void +translate_relocation (struct translate_context *ctx, + Elf_Addr addr, + Elf_Addr info, + Elf_Addr sym_addr, + Elf_Addr addend, + const struct grub_install_image_target_desc *image_target) +{ + if (image_target->id == IMAGE_EFI) + translate_relocation_pe (ctx, addr, info, sym_addr, addend, image_target); + else + translate_relocation_raw (ctx, addr, info, image_target); +} + +static void +finish_reloc_translation_pe (struct translate_context *ctx, struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + ctx->current_address = add_fixup_entry (&ctx->lst, 0, 0, 1, ctx->current_address, image_target); + + { + grub_uint8_t *ptr; + layout->reloc_section = ptr = xmalloc (ctx->current_address); + for (ctx->lst = ctx->lst0; ctx->lst; ctx->lst = ctx->lst->next) + if (ctx->lst->state) + { + memcpy (ptr, &ctx->lst->b, grub_target_to_host32 (ctx->lst->b.block_size)); + ptr += grub_target_to_host32 (ctx->lst->b.block_size); + } + assert ((ctx->current_address + (grub_uint8_t *) layout->reloc_section) == ptr); + } + + for (ctx->lst = ctx->lst0; ctx->lst; ) + { + struct fixup_block_list *next; + next = ctx->lst->next; + free (ctx->lst); + ctx->lst = next; + } + + layout->reloc_size = ctx->current_address; + if (image_target->elf_target == EM_ARM && layout->reloc_size > GRUB_KERNEL_ARM_STACK_SIZE) + grub_util_error ("Reloc section (%d) is bigger than stack size (%d). " + "This breaks assembly assumptions. Please increase stack size", + (int) layout->reloc_size, + (int) GRUB_KERNEL_ARM_STACK_SIZE); +} + +/* + Layout: + + + + + ... + + + each relocation starts with 32-bit offset. Rest depends on relocation. + mkimage stops when it sees first unknown type or end marker. + This allows images to be created with mismatched mkimage and + kernel as long as no relocations are present in kernel that mkimage + isn't aware of (in which case mkimage aborts). + This also allows simple assembly to do the relocs. +*/ + +#define RAW_SEPARATOR 0xfffffffe +#define RAW_END_MARKER 0xffffffff + +static void +finish_reloc_translation_raw (struct translate_context *ctx, struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + size_t count = 0, sz; + enum raw_reloc_type highest = RAW_RELOC_NONE; + enum raw_reloc_type curtype; + struct raw_reloc *cur; + grub_uint32_t *p; + if (!ctx->raw_relocs) + { + layout->reloc_section = p = xmalloc (sizeof (grub_uint32_t)); + p[0] = RAW_END_MARKER; + layout->reloc_size = sizeof (grub_uint32_t); + return; + } + for (cur = ctx->raw_relocs; cur; cur = cur->next) + { + count++; + if (cur->type > highest) + highest = cur->type; + } + /* highest separators, count relocations and one end marker. */ + sz = (highest + count + 1) * sizeof (grub_uint32_t); + layout->reloc_section = p = xmalloc (sz); + for (curtype = 0; curtype <= highest; curtype++) + { + /* Support for special cases would go here. */ + for (cur = ctx->raw_relocs; cur; cur = cur->next) + if (cur->type == curtype) + { + *p++ = cur->offset; + } + *p++ = RAW_SEPARATOR; + } + *--p = RAW_END_MARKER; + layout->reloc_size = sz; +} + +static void +finish_reloc_translation (struct translate_context *ctx, struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + if (image_target->id == IMAGE_EFI) + finish_reloc_translation_pe (ctx, layout, image_target); + else + finish_reloc_translation_raw (ctx, layout, image_target); +} + + +static void +create_u64_fixups (struct translate_context *ctx, + Elf_Addr jumpers, grub_size_t njumpers, + const struct grub_install_image_target_desc *image_target) +{ + unsigned i; + assert (image_target->id == IMAGE_EFI); + for (i = 0; i < njumpers; i++) + ctx->current_address = add_fixup_entry (&ctx->lst, + GRUB_PE32_REL_BASED_DIR64, + jumpers + 8 * i, + 0, ctx->current_address, + image_target); +} + +/* Make a .reloc section. */ +static void +make_reloc_section (Elf_Ehdr *e, struct grub_mkimage_layout *layout, + struct section_metadata *smd, + const struct grub_install_image_target_desc *image_target) +{ + unsigned i; + Elf_Shdr *s; + struct translate_context ctx; + + translate_reloc_start (&ctx, image_target); + + for (i = 0, s = smd->sections; i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if ((grub_target_to_host32 (s->sh_type) == SHT_REL) || + (grub_target_to_host32 (s->sh_type) == SHT_RELA)) + { + Elf_Rela *r; + Elf_Word rtab_size, r_size, num_rs; + Elf_Off rtab_offset; + Elf_Shdr *symtab_section; + Elf_Addr section_address; + Elf_Word j; + + if (!SUFFIX (is_kept_reloc_section) (s, image_target, smd)) + { + grub_util_info ("not translating the skipped relocation section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + continue; + } + + symtab_section = (Elf_Shdr *) ((char *) smd->sections + + (grub_target_to_host32 (s->sh_link) + * smd->section_entsize)); + + grub_util_info ("translating the relocation section %s", + smd->strtab + grub_le_to_cpu32 (s->sh_name)); + + rtab_size = grub_target_to_host (s->sh_size); + r_size = grub_target_to_host (s->sh_entsize); + rtab_offset = grub_target_to_host (s->sh_offset); + num_rs = rtab_size / r_size; + + section_address = smd->vaddrs[grub_le_to_cpu32 (s->sh_info)]; + + for (j = 0, r = (Elf_Rela *) ((char *) e + rtab_offset); + j < num_rs; + j++, r = (Elf_Rela *) ((char *) r + r_size)) + { + Elf_Addr info; + Elf_Addr offset; + Elf_Addr addr; + Elf_Addr sym_addr; + Elf_Addr addend; + + offset = grub_target_to_host (r->r_offset); + if (image_target->elf_target == EM_MIPS && image_target->voidp_sizeof == 8) + info = ((grub_uint64_t) r->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (r->r_info); + else + info = grub_target_to_host (r->r_info); + + sym_addr = SUFFIX (get_symbol_address) (e, symtab_section, + ELF_R_SYM (info), image_target); + addend = (s->sh_type == grub_target_to_host32 (SHT_RELA)) ? + grub_target_to_host (r->r_addend) : 0; + addr = section_address + offset; + + translate_relocation (&ctx, addr, info, sym_addr, addend, image_target); + } + } + + if (image_target->elf_target == EM_IA_64) + create_u64_fixups (&ctx, + layout->ia64jmp_off + + image_target->vaddr_offset, + 2 * layout->ia64jmpnum, + image_target); + if (image_target->elf_target == EM_IA_64 || image_target->elf_target == EM_AARCH64) + create_u64_fixups (&ctx, + layout->got_off + + image_target->vaddr_offset, + (layout->got_size / 8), + image_target); + + finish_reloc_translation (&ctx, layout, image_target); +} + +/* Determine if this section is a text section. Return false if this + section is not allocated. */ +static int +SUFFIX (is_text_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + if (!is_relocatable (image_target) + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == (SHF_EXECINSTR | SHF_ALLOC)); +} + +/* Determine if this section is a data section. */ +static int +SUFFIX (is_data_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + if (!is_relocatable (image_target) + && grub_target_to_host32 (s->sh_type) != SHT_PROGBITS) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC) && !(grub_target_to_host32 (s->sh_type) == SHT_NOBITS); +} + +static int +SUFFIX (is_bss_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + if (!is_relocatable (image_target)) + return 0; + return ((grub_target_to_host (s->sh_flags) & (SHF_EXECINSTR | SHF_ALLOC)) + == SHF_ALLOC) && (grub_target_to_host32 (s->sh_type) == SHT_NOBITS); +} + +/* Determine if a section is going to be in the final output */ +static int +SUFFIX (is_kept_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target) +{ + /* We keep .text and .data */ + if (SUFFIX (is_text_section) (s, image_target) + || SUFFIX (is_data_section) (s, image_target)) + return 1; + + /* + * And we keep .bss if we're producing PE binaries or the target doesn't + * have a relocating loader. Platforms other than EFI and U-boot shouldn't + * have .bss in their binaries as we build with -Wl,-Ttext. + */ + if (SUFFIX (is_bss_section) (s, image_target) + && (image_target->id == IMAGE_EFI || !is_relocatable (image_target))) + return 1; + + /* Otherwise this is not a section we're keeping in the final output. */ + return 0; +} + +static int +SUFFIX (is_kept_reloc_section) (Elf_Shdr *s, const struct grub_install_image_target_desc *image_target, + struct section_metadata *smd) +{ + int i; + int r = 0; + const char *name = smd->strtab + grub_host_to_target32 (s->sh_name); + + if (!strncmp (name, ".rela.", 6)) + name += 5; + else if (!strncmp (name, ".rel.", 5)) + name += 4; + else + return 1; + + for (i = 0, s = smd->sections; i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + { + const char *sname = smd->strtab + grub_host_to_target32 (s->sh_name); + if (strcmp (sname, name)) + continue; + + return SUFFIX (is_kept_section) (s, image_target); + } + + return r; +} + +/* Return if the ELF header is valid. */ +static int +SUFFIX (check_elf_header) (Elf_Ehdr *e, size_t size, const struct grub_install_image_target_desc *image_target) +{ + if (size < sizeof (*e) + || e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || e->e_ident[EI_CLASS] != ELFCLASSXX + || e->e_version != grub_host_to_target32 (EV_CURRENT)) + return 0; + + return 1; +} + +static Elf_Addr +SUFFIX (put_section) (Elf_Shdr *s, int i, + Elf_Addr current_address, + struct section_metadata *smd, + const struct grub_install_image_target_desc *image_target) +{ + Elf_Word align = grub_host_to_target_addr (s->sh_addralign); + const char *name = smd->strtab + grub_host_to_target32 (s->sh_name); + + if (align) + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%" + GRUB_HOST_PRIxLONG_LONG, + name, (unsigned long long) current_address); + if (!is_relocatable (image_target)) + current_address = grub_host_to_target_addr (s->sh_addr) + - image_target->link_addr; + smd->addrs[i] = current_address; + current_address += grub_host_to_target_addr (s->sh_size); + return current_address; +} + +/* + * Locate section addresses by merging code sections and data sections + * into .text and .data, respectively. + */ +static void +SUFFIX (locate_sections) (Elf_Ehdr *e, const char *kernel_path, + struct section_metadata *smd, + struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + int i; + Elf_Shdr *s; + + layout->align = 1; + /* Page-aligning simplifies relocation handling. */ + if (image_target->elf_target == EM_AARCH64) + layout->align = 4096; + + layout->kernel_size = 0; + + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if ((grub_target_to_host (s->sh_flags) & SHF_ALLOC) + && grub_host_to_target32 (s->sh_addralign) > layout->align) + layout->align = grub_host_to_target32 (s->sh_addralign); + + /* .text */ + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if (SUFFIX (is_text_section) (s, image_target)) + { + layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, + smd, image_target); + if (!is_relocatable (image_target) && + grub_host_to_target_addr (s->sh_addr) != image_target->link_addr) + { + char *msg + = grub_xasprintf (_("`%s' is miscompiled: its start address is 0x%llx" + " instead of 0x%llx: ld.gold bug?"), + kernel_path, + (unsigned long long) grub_host_to_target_addr (s->sh_addr), + (unsigned long long) image_target->link_addr); + grub_util_error ("%s", msg); + } + } + +#ifdef MKIMAGE_ELF32 + if (image_target->elf_target == EM_ARM) + { + grub_size_t tramp; + + layout->kernel_size = ALIGN_UP (layout->kernel_size, 16); + + tramp = arm_get_trampoline_size (e, smd->sections, smd->section_entsize, + smd->num_sections, image_target); + + layout->tramp_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (tramp, 16); + } +#endif + + layout->kernel_size = ALIGN_UP (layout->kernel_size + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + layout->exec_size = layout->kernel_size; + + /* .data */ + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + if (SUFFIX (is_data_section) (s, image_target)) + layout->kernel_size = SUFFIX (put_section) (s, i, layout->kernel_size, smd, + image_target); + + layout->bss_start = layout->kernel_size; + layout->end = layout->kernel_size; + + /* .bss */ + for (i = 0, s = smd->sections; + i < smd->num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd->section_entsize)) + { + if (SUFFIX (is_bss_section) (s, image_target)) + layout->end = SUFFIX (put_section) (s, i, layout->end, smd, image_target); + + /* + * This must to be in the last time this function passes through the loop. + */ + smd->vaddrs[i] = smd->addrs[i] + image_target->vaddr_offset; + } + + layout->end = ALIGN_UP (layout->end + image_target->vaddr_offset, + image_target->section_align) - image_target->vaddr_offset; + /* Explicitly initialize BSS + when producing PE32 to avoid a bug in EFI implementations. + Platforms other than EFI and U-boot shouldn't have .bss in + their binaries as we build with -Wl,-Ttext. + */ + if (image_target->id == IMAGE_EFI || !is_relocatable (image_target)) + layout->kernel_size = layout->end; +} + +char * +SUFFIX (grub_mkimage_load_image) (const char *kernel_path, + size_t total_module_size, + struct grub_mkimage_layout *layout, + const struct grub_install_image_target_desc *image_target) +{ + char *kernel_img, *out_img; + struct section_metadata smd = { 0, 0, 0, 0, 0, 0, 0 }; + Elf_Ehdr *e; + int i; + Elf_Shdr *s; + Elf_Off section_offset; + grub_size_t kernel_size; + + grub_memset (layout, 0, sizeof (*layout)); + + layout->start_address = 0; + + kernel_size = grub_util_get_image_size (kernel_path); + kernel_img = xmalloc (kernel_size); + grub_util_load_image (kernel_path, kernel_img); + + e = (Elf_Ehdr *) kernel_img; + if (! SUFFIX (check_elf_header) (e, kernel_size, image_target)) + grub_util_error ("invalid ELF header"); + + section_offset = grub_target_to_host (e->e_shoff); + smd.section_entsize = grub_target_to_host16 (e->e_shentsize); + smd.num_sections = grub_target_to_host16 (e->e_shnum); + + if (kernel_size < section_offset + + (grub_uint32_t) smd.section_entsize * smd.num_sections) + grub_util_error (_("premature end of file %s"), kernel_path); + + smd.sections = (Elf_Shdr *) (kernel_img + section_offset); + + /* Relocate sections then symbols in the virtual address space. */ + s = (Elf_Shdr *) ((char *) smd.sections + + grub_host_to_target16 (e->e_shstrndx) * smd.section_entsize); + smd.strtab = (char *) e + grub_host_to_target_addr (s->sh_offset); + + smd.addrs = xmalloc (sizeof (*smd.addrs) * smd.num_sections); + memset (smd.addrs, 0, sizeof (*smd.addrs) * smd.num_sections); + smd.vaddrs = xmalloc (sizeof (*smd.vaddrs) * smd.num_sections); + memset (smd.vaddrs, 0, sizeof (*smd.vaddrs) * smd.num_sections); + + SUFFIX (locate_sections) (e, kernel_path, &smd, layout, image_target); + + if (!is_relocatable (image_target)) + { + Elf_Addr current_address = layout->kernel_size; + + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + { + Elf_Word sec_align = grub_host_to_target_addr (s->sh_addralign); + const char *name = smd.strtab + grub_host_to_target32 (s->sh_name); + + if (sec_align) + current_address = ALIGN_UP (current_address + + image_target->vaddr_offset, + sec_align) + - image_target->vaddr_offset; + + grub_util_info ("locating the section %s at 0x%" + GRUB_HOST_PRIxLONG_LONG, + name, (unsigned long long) current_address); + if (!is_relocatable (image_target)) + current_address = grub_host_to_target_addr (s->sh_addr) + - image_target->link_addr; + + smd.vaddrs[i] = current_address + + image_target->vaddr_offset; + current_address += grub_host_to_target_addr (s->sh_size); + } + current_address = ALIGN_UP (current_address + image_target->vaddr_offset, + image_target->section_align) + - image_target->vaddr_offset; + layout->bss_size = current_address - layout->kernel_size; + } + else + layout->bss_size = 0; + + if (image_target->id == IMAGE_SPARC64_AOUT + || image_target->id == IMAGE_SPARC64_RAW + || image_target->id == IMAGE_UBOOT + || image_target->id == IMAGE_COREBOOT + || image_target->id == IMAGE_SPARC64_CDCORE) + layout->kernel_size = ALIGN_UP (layout->kernel_size, image_target->mod_align); + + if (is_relocatable (image_target)) + { + smd.symtab = NULL; + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) + if (s->sh_type == grub_host_to_target32 (SHT_SYMTAB)) + { + smd.symtab = s; + break; + } + if (! smd.symtab) + grub_util_error ("%s", _("no symbol table")); +#ifdef MKIMAGE_ELF64 + if (image_target->elf_target == EM_IA_64) + { + grub_size_t tramp; + + layout->kernel_size = ALIGN_UP (layout->kernel_size, 16); + + grub_ia64_dl_get_tramp_got_size (e, &tramp, &layout->got_size); + + layout->tramp_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (tramp, 16); + + layout->ia64jmp_off = layout->kernel_size; + layout->ia64jmpnum = SUFFIX (count_funcs) (e, smd.symtab, + image_target); + layout->kernel_size += 16 * layout->ia64jmpnum; + + layout->got_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (layout->got_size, 16); + } + if (image_target->elf_target == EM_AARCH64) + { + grub_size_t tramp; + + layout->kernel_size = ALIGN_UP (layout->kernel_size, 16); + + grub_arm64_dl_get_tramp_got_size (e, &tramp, &layout->got_size); + + layout->got_off = layout->kernel_size; + layout->kernel_size += ALIGN_UP (layout->got_size, 16); + } +#endif + } + else + { + layout->reloc_size = 0; + layout->reloc_section = NULL; + } + + out_img = xmalloc (layout->kernel_size + total_module_size); + memset (out_img, 0, layout->kernel_size + total_module_size); + + if (is_relocatable (image_target)) + { + layout->start_address = SUFFIX (relocate_symbols) (e, &smd, + (char *) out_img + layout->ia64jmp_off, + layout->ia64jmp_off + image_target->vaddr_offset, + layout->bss_start, layout->end, image_target); + + if (layout->start_address == (Elf_Addr) -1) + grub_util_error ("start symbol is not defined"); + + /* Resolve addrs in the virtual address space. */ + SUFFIX (relocate_addrs) (e, &smd, out_img, layout->tramp_off, + layout->got_off, image_target); + + make_reloc_section (e, layout, &smd, image_target); + if (image_target->id != IMAGE_EFI) + { + out_img = xrealloc (out_img, layout->kernel_size + total_module_size + + ALIGN_UP (layout->reloc_size, image_target->mod_align)); + memcpy (out_img + layout->kernel_size, layout->reloc_section, layout->reloc_size); + memset (out_img + layout->kernel_size + layout->reloc_size, 0, + total_module_size + ALIGN_UP (layout->reloc_size, image_target->mod_align) - layout->reloc_size); + layout->kernel_size += ALIGN_UP (layout->reloc_size, image_target->mod_align); + } + } + + for (i = 0, s = smd.sections; + i < smd.num_sections; + i++, s = (Elf_Shdr *) ((char *) s + smd.section_entsize)) + if (SUFFIX (is_kept_section) (s, image_target)) + { + if (grub_target_to_host32 (s->sh_type) == SHT_NOBITS) + memset (out_img + smd.addrs[i], 0, + grub_host_to_target_addr (s->sh_size)); + else + memcpy (out_img + smd.addrs[i], + kernel_img + grub_host_to_target_addr (s->sh_offset), + grub_host_to_target_addr (s->sh_size)); + } + free (kernel_img); + + free (smd.vaddrs); + smd.vaddrs = NULL; + free (smd.addrs); + smd.addrs = NULL; + + return out_img; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c new file mode 100644 index 00000000..4db1e53e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mknetdir.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2013 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . +*/ + +#include + +#include +#include +#include + +#include +#include + +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#include +#pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wmissing-declarations" + +static char *rootdir = NULL, *subdir = NULL; +static char *debug_image = NULL; + +enum + { + OPTION_NET_DIRECTORY = 0x301, + OPTION_SUBDIR, + OPTION_DEBUG, + OPTION_DEBUG_IMAGE + }; + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"net-directory", OPTION_NET_DIRECTORY, N_("DIR"), + 0, N_("root directory of TFTP server"), 2}, + {"subdir", OPTION_SUBDIR, N_("DIR"), + 0, N_("relative subdirectory on network server"), 2}, + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, + {0, 0, 0, 0, 0, 0} +}; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_NET_DIRECTORY: + free (rootdir); + rootdir = xstrdup (arg); + return 0; + case OPTION_SUBDIR: + free (subdir); + subdir = xstrdup (arg); + return 0; + /* This is an undocumented feature... */ + case OPTION_DEBUG: + verbosity++; + return 0; + case OPTION_DEBUG_IMAGE: + free (debug_image); + debug_image = xstrdup (arg); + return 0; + + case ARGP_KEY_ARG: + default: + return ARGP_ERR_UNKNOWN; + } +} + + +struct argp argp = { + options, argp_parser, NULL, + "\v"N_("Prepares GRUB network boot images at net_directory/subdir " + "assuming net_directory being TFTP root."), + NULL, grub_install_help_filter, NULL +}; + +static char *base; + +static const struct +{ + const char *mkimage_target; + const char *netmodule; + const char *ext; +} targets[GRUB_INSTALL_PLATFORM_MAX] = + { + [GRUB_INSTALL_PLATFORM_I386_PC] = { "i386-pc-pxe", "pxe", ".0" }, + [GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] = { "sparc64-ieee1275-aout", "ofnet", ".img" }, + [GRUB_INSTALL_PLATFORM_I386_IEEE1275] = { "i386-ieee1275", "ofnet", ".elf" }, + [GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] = { "powerpc-ieee1275", "ofnet", ".elf" }, + [GRUB_INSTALL_PLATFORM_I386_EFI] = { "i386-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_X86_64_EFI] = { "x86_64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_IA64_EFI] = { "ia64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_ARM_EFI] = { "arm-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_ARM64_EFI] = { "arm64-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] = { "mips64el-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32-efi", "efinet", ".efi" }, + [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64-efi", "efinet", ".efi" }, + }; + +static void +process_input_dir (const char *input_dir, enum grub_install_plat platform) +{ + char *platsub = grub_install_get_platform_name (platform); + char *grubdir = grub_util_path_concat (3, rootdir, subdir, platsub); + char *load_cfg = grub_util_path_concat (2, grubdir, "load.cfg"); + char *prefix; + char *output; + char *grub_cfg; + FILE *cfg; + + grub_install_copy_files (input_dir, base, platform); + grub_util_unlink (load_cfg); + + if (debug_image) + { + FILE *f = grub_util_fopen (load_cfg, "wb"); + if (!f) + grub_util_error (_("cannot open `%s': %s"), load_cfg, + strerror (errno)); + fprintf (f, "set debug='%s'\n", debug_image); + fclose (f); + } + else + { + free (load_cfg); + load_cfg = 0; + } + + prefix = xasprintf ("/%s", subdir); + if (!targets[platform].mkimage_target) + grub_util_error (_("unsupported platform %s"), platsub); + + grub_cfg = grub_util_path_concat (2, grubdir, "grub.cfg"); + cfg = grub_util_fopen (grub_cfg, "wb"); + if (!cfg) + grub_util_error (_("cannot open `%s': %s"), grub_cfg, + strerror (errno)); + fprintf (cfg, "source %s/grub.cfg", subdir); + fclose (cfg); + + grub_install_push_module (targets[platform].netmodule); + + output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext); + grub_install_make_image_wrap (input_dir, prefix, output, + 0, load_cfg, + targets[platform].mkimage_target, 0); + grub_install_pop_module (); + + /* TRANSLATORS: First %s is replaced by platform name. Second one by filename. */ + printf (_("Netboot directory for %s created. Configure your DHCP server to point to %s\n"), + platsub, output); + + free (platsub); + free (output); + free (prefix); + free (grub_cfg); + free (grubdir); +} + + +int +main (int argc, char *argv[]) +{ + const char *pkglibdir; + + grub_util_host_init (&argc, &argv); + grub_util_disable_fd_syncs (); + rootdir = xstrdup ("/srv/tftp"); + pkglibdir = grub_util_get_pkglibdir (); + + subdir = grub_util_path_concat (2, GRUB_BOOT_DIR_NAME, GRUB_DIR_NAME); + + argp_parse (&argp, argc, argv, 0, 0, 0); + + base = grub_util_path_concat (2, rootdir, subdir); + /* Create the GRUB directory if it is not present. */ + + grub_install_mkdir_p (base); + + grub_install_push_module ("tftp"); + + if (!grub_install_source_directory) + { + enum grub_install_plat plat; + + for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) + if (targets[plat].mkimage_target) + { + char *platdir = grub_util_path_concat (2, pkglibdir, + grub_install_get_platform_name (plat)); + + grub_util_info ("Looking for `%s'", platdir); + + if (!grub_util_is_directory (platdir)) + { + free (platdir); + continue; + } + process_input_dir (platdir, plat); + } + } + else + { + enum grub_install_plat plat; + plat = grub_install_get_target (grub_install_source_directory); + process_input_dir (grub_install_source_directory, plat); + } + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c new file mode 100644 index 00000000..190ebe43 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-mkrescue.c @@ -0,0 +1,1003 @@ +/* + * Make GRUB rescue image + * + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include + +#include +#include +#include +#include +#include +#pragma GCC diagnostic ignored "-Wmissing-prototypes" +#pragma GCC diagnostic ignored "-Wmissing-declarations" +#include +#pragma GCC diagnostic error "-Wmissing-prototypes" +#pragma GCC diagnostic error "-Wmissing-declarations" + +#include +#include + +#include +#include + +static char *source_dirs[GRUB_INSTALL_PLATFORM_MAX]; +static char *rom_directory; +static char *label_font; +static char *label_color; +static char *label_bgcolor; +static char *product_name; +static char *product_version; +static char *output_image; +static char *xorriso; +static char *boot_grub; +static int xorriso_argc; +static int xorriso_arg_alloc; +static char **xorriso_argv; +static char *iso_uuid; +static char *iso9660_dir; + +static void +xorriso_push (const char *val) +{ + if (xorriso_arg_alloc <= xorriso_argc + 1) + { + xorriso_arg_alloc = 2 * (4 + xorriso_argc); + xorriso_argv = xrealloc (xorriso_argv, + sizeof (xorriso_argv[0]) + * xorriso_arg_alloc); + } + xorriso_argv[xorriso_argc++] = xstrdup (val); +} + +static void +xorriso_link (const char *from, const char *to) +{ + char *tof = grub_util_path_concat (2, iso9660_dir, to); + char *val = xasprintf ("%s=%s", from, tof); + xorriso_push (val); + free (val); + free (tof); +} + +enum + { + OPTION_OUTPUT = 'o', + OPTION_ROM_DIRECTORY = 0x301, + OPTION_XORRISO, + OPTION_GLUE_EFI, + OPTION_RENDER_LABEL, + OPTION_LABEL_FONT, + OPTION_LABEL_COLOR, + OPTION_LABEL_BGCOLOR, + OPTION_PRODUCT_NAME, + OPTION_PRODUCT_VERSION, + OPTION_SPARC_BOOT, + OPTION_ARCS_BOOT + }; + +static struct argp_option options[] = { + GRUB_INSTALL_OPTIONS, + {"output", 'o', N_("FILE"), + 0, N_("save output in FILE [required]"), 2}, + {"rom-directory", OPTION_ROM_DIRECTORY, N_("DIR"), + 0, N_("save ROM images in DIR [optional]"), 2}, + {"xorriso", OPTION_XORRISO, N_("FILE"), + /* TRANSLATORS: xorriso is a program for creating ISOs and burning CDs. */ + 0, N_("use FILE as xorriso [optional]"), 2}, + {"grub-glue-efi", OPTION_GLUE_EFI, N_("FILE"), OPTION_HIDDEN, 0, 2}, + {"grub-render-label", OPTION_RENDER_LABEL, N_("FILE"), OPTION_HIDDEN, 0, 2}, + {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, + {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, + {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, + {"product-name", OPTION_PRODUCT_NAME, N_("STRING"), 0, N_("use STRING as product name"), 2}, + {"product-version", OPTION_PRODUCT_VERSION, N_("STRING"), 0, N_("use STRING as product version"), 2}, + {"sparc-boot", OPTION_SPARC_BOOT, 0, 0, N_("enable sparc boot. Disables HFS+, APM, ARCS and boot as disk image for i386-pc"), 2}, + {"arcs-boot", OPTION_ARCS_BOOT, 0, 0, N_("enable ARCS (big-endian mips machines, mostly SGI) boot. Disables HFS+, APM, sparc64 and boot as disk image for i386-pc"), 2}, + {0, 0, 0, 0, 0, 0} +}; + +#pragma GCC diagnostic ignored "-Wformat-nonliteral" + +static char * +help_filter (int key, const char *text, void *input __attribute__ ((unused))) +{ + switch (key) + { + case ARGP_KEY_HELP_PRE_DOC: + /* TRANSLATORS: it generates one single image which is bootable through any method. */ + return strdup (_("Make GRUB CD-ROM, disk, pendrive and floppy bootable image.")); + case ARGP_KEY_HELP_POST_DOC: + { + char *p1, *out; + + p1 = xasprintf (_("Generates a bootable CD/USB/floppy image. Arguments other than options to this program" + " are passed to xorriso, and indicate source files, source directories, or any of the " + "mkisofs options listed by the output of `%s'."), "xorriso -as mkisofs -help"); + out = xasprintf ("%s\n\n%s\n\n%s", p1, + _("Option -- switches to native xorriso command mode."), + _("Mail xorriso support requests to .")); + free (p1); + return out; + } + default: + return grub_install_help_filter (key, text, input); + } +} + +#pragma GCC diagnostic error "-Wformat-nonliteral" + +enum { + SYS_AREA_AUTO, + SYS_AREA_COMMON, + SYS_AREA_SPARC, + SYS_AREA_ARCS +} system_area = SYS_AREA_AUTO; + +static error_t +argp_parser (int key, char *arg, struct argp_state *state) +{ + if (grub_install_parse (key, arg)) + return 0; + switch (key) + { + case OPTION_OUTPUT: + free (output_image); + output_image = xstrdup (arg); + return 0; + case OPTION_ROM_DIRECTORY: + free (rom_directory); + rom_directory = xstrdup (arg); + return 0; + + /* + FIXME: + # Intentionally undocumented + --grub-mkimage-extra) + mkimage_extra_arg="$mkimage_extra_arg `argument $option "$@"`"; shift ;; + --grub-mkimage-extra=*) + mkimage_extra_arg="$mkimage_extra_arg `echo "$option" | sed 's/--grub-mkimage-extra=//'`" ;; + */ + case OPTION_SPARC_BOOT: + system_area = SYS_AREA_SPARC; + return 0; + case OPTION_ARCS_BOOT: + system_area = SYS_AREA_ARCS; + return 0; + case OPTION_PRODUCT_NAME: + free (product_name); + product_name = xstrdup (arg); + return 0; + case OPTION_PRODUCT_VERSION: + free (product_version); + product_version = xstrdup (arg); + return 0; + /* Accept and ignore for compatibility. */ + case OPTION_GLUE_EFI: + case OPTION_RENDER_LABEL: + return 0; + case OPTION_LABEL_FONT: + free (label_font); + label_font = xstrdup (arg); + return 0; + + case OPTION_LABEL_COLOR: + free (label_color); + label_color = xstrdup (arg); + return 0; + + case OPTION_LABEL_BGCOLOR: + free (label_bgcolor); + label_bgcolor = xstrdup (arg); + return 0; + + case OPTION_XORRISO: + free (xorriso); + xorriso = xstrdup (arg); + return 0; + + default: + return ARGP_ERR_UNKNOWN; + } +} + +struct argp argp = { + options, argp_parser, N_("[OPTION] SOURCE..."), + NULL, NULL, help_filter, NULL +}; + +static void +write_part (FILE *f, const char *srcdir) +{ + FILE *in; + char *inname = grub_util_path_concat (2, srcdir, "partmap.lst"); + char buf[260]; + in = grub_util_fopen (inname, "rb"); + if (!in) + return; + while (fgets (buf, 256, in)) + { + char *ptr; + for (ptr = buf + strlen (buf) - 1; + ptr >= buf && (*ptr == '\n' || *ptr == '\r'); + ptr--); + ptr[1] = '\0'; + fprintf (f, "insmod %s\n", buf); + } + fclose (in); +} + +static void +make_image_abs (enum grub_install_plat plat, + const char *mkimage_target, + const char *output) +{ + char *load_cfg; + FILE *load_cfg_f; + + if (!source_dirs[plat]) + return; + + grub_util_info (N_("enabling %s support ..."), + mkimage_target); + + load_cfg = grub_util_make_temporary_file (); + + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + fprintf (load_cfg_f, "search --fs-uuid --set=root %s\n", iso_uuid); + fprintf (load_cfg_f, "set prefix=(${root})/boot/grub\n"); + + write_part (load_cfg_f, source_dirs[plat]); + fclose (load_cfg_f); + + grub_install_push_module ("search"); + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[plat], "/boot/grub", output, + 0, load_cfg, + mkimage_target, 0); + grub_install_pop_module (); + grub_install_pop_module (); + grub_util_unlink (load_cfg); +} + +static void +make_image (enum grub_install_plat plat, + const char *mkimage_target, + const char *output_sub) +{ + char *out = grub_util_path_concat (2, boot_grub, output_sub); + make_image_abs (plat, mkimage_target, out); + free (out); +} + +static void +make_image_fwdisk_abs (enum grub_install_plat plat, + const char *mkimage_target, + const char *output) +{ + char *load_cfg; + FILE *load_cfg_f; + + if (!source_dirs[plat]) + return; + + grub_util_info (N_("enabling %s support ..."), + mkimage_target); + + load_cfg = grub_util_make_temporary_file (); + + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + write_part (load_cfg_f, source_dirs[plat]); + fclose (load_cfg_f); + + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[plat], "()/boot/grub", output, + 0, load_cfg, mkimage_target, 0); + grub_install_pop_module (); + grub_util_unlink (load_cfg); +} + +static int +check_xorriso (const char *val) +{ + const char *argv[5]; + int fd; + pid_t pid; + FILE *mdadm; + char *buf = NULL; + size_t len = 0; + int ret = 0; + int wstatus = 0; + + argv[0] = xorriso; + argv[1] = "-as"; + argv[2] = "mkisofs"; + argv[3] = "-help"; + argv[4] = NULL; + + pid = grub_util_exec_pipe_stderr (argv, &fd); + + if (!pid) + return 0; + + /* Parent. Read mdadm's output. */ + mdadm = fdopen (fd, "r"); + if (! mdadm) + return 0; + + while (getline (&buf, &len, mdadm) > 0) + { + if (grub_strstr (buf, val)) + ret = 1; + } + + close (fd); + waitpid (pid, &wstatus, 0); + free (buf); + if (!WIFEXITED (wstatus) || WEXITSTATUS(wstatus) != 0) + return 0; + return ret; +} + +static void +make_image_fwdisk (enum grub_install_plat plat, + const char *mkimage_target, + const char *output_sub) +{ + char *out = grub_util_path_concat (2, boot_grub, output_sub); + make_image_fwdisk_abs (plat, mkimage_target, out); + free (out); +} + +static int +option_is_end (const struct argp_option *opt) +{ + return !opt->key && !opt->name && !opt->doc && !opt->group; +} + + +static int +args_to_eat (const char *arg) +{ + int j; + + if (arg[0] != '-') + return 0; + + if (arg[1] == '-') + { + for (j = 0; !option_is_end(&options[j]); j++) + { + size_t len = strlen (options[j].name); + if (strncmp (arg + 2, options[j].name, len) == 0) + { + if (arg[2 + len] == '=') + return 1; + if (arg[2 + len] == '\0' && options[j].arg) + return 2; + if (arg[2 + len] == '\0') + return 1; + } + } + if (strcmp (arg, "--help") == 0) + return 1; + if (strcmp (arg, "--usage") == 0) + return 1; + if (strcmp (arg, "--version") == 0) + return 1; + return 0; + } + if (arg[2] && arg[3]) + return 0; + for (j = 0; !option_is_end(&options[j]); j++) + { + if (options[j].key > 0 && options[j].key < 128 && arg[1] == options[j].key) + { + if (options[j].arg) + return 2; + return 1; + } + if (arg[1] == '?') + return 1; + } + return 0; +} + +int +main (int argc, char *argv[]) +{ + char *romdir; + char *sysarea_img = NULL; + const char *pkgdatadir; + int argp_argc; + char **argp_argv; + int xorriso_tail_argc; + char **xorriso_tail_argv; + int rv; + + grub_util_host_init (&argc, &argv); + grub_util_disable_fd_syncs (); + + pkgdatadir = grub_util_get_pkgdatadir (); + + product_name = xstrdup (PACKAGE_NAME); + product_version = xstrdup (PACKAGE_VERSION); + xorriso = xstrdup ("xorriso"); + label_font = grub_util_path_concat (2, pkgdatadir, "unicode.pf2"); + + argp_argv = xmalloc (sizeof (argp_argv[0]) * argc); + xorriso_tail_argv = xmalloc (sizeof (argp_argv[0]) * argc); + + xorriso_tail_argc = 0; + /* Program name */ + argp_argv[0] = argv[0]; + argp_argc = 1; + + /* argp doesn't allow us to catch unknwon arguments, + so catch them before passing to argp + */ + { + int i; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "-output") == 0) { + argp_argv[argp_argc++] = (char *) "--output"; + i++; + argp_argv[argp_argc++] = argv[i]; + continue; + } + switch (args_to_eat (argv[i])) + { + case 2: + argp_argv[argp_argc++] = argv[i++]; + /* Fallthrough */ + case 1: + argp_argv[argp_argc++] = argv[i]; + break; + case 0: + xorriso_tail_argv[xorriso_tail_argc++] = argv[i]; + break; + } + } + } + + argp_parse (&argp, argp_argc, argp_argv, 0, 0, 0); + + if (!output_image) + grub_util_error ("%s", _("output file must be specified")); + + if (!check_xorriso ("graft-points")) { + grub_util_error ("%s", _("xorriso not found")); + } + + grub_init_all (); + grub_hostfs_init (); + grub_host_init (); + + xorriso_push (xorriso); + xorriso_push ("-as"); + xorriso_push ("mkisofs"); + xorriso_push ("-graft-points"); + + iso9660_dir = grub_util_make_temporary_dir (); + grub_util_info ("temporary iso9660 dir is `%s'", iso9660_dir); + boot_grub = grub_util_path_concat (3, iso9660_dir, "boot", "grub"); + grub_install_mkdir_p (boot_grub); + romdir = grub_util_path_concat (2, boot_grub, "roms"); + grub_util_mkdir (romdir); + + if (!grub_install_source_directory) + { + const char *pkglibdir = grub_util_get_pkglibdir (); + enum grub_install_plat plat; + + for (plat = 0; plat < GRUB_INSTALL_PLATFORM_MAX; plat++) + { + char *platdir = grub_util_path_concat (2, pkglibdir, + grub_install_get_platform_name (plat)); + + if (!grub_util_is_directory (platdir)) + { + free (platdir); + continue; + } + source_dirs[plat] = platdir; + grub_install_copy_files (platdir, + boot_grub, plat); + } + } + else + { + enum grub_install_plat plat; + plat = grub_install_get_target (grub_install_source_directory); + grub_install_copy_files (grub_install_source_directory, + boot_grub, plat); + source_dirs[plat] = xstrdup (grub_install_source_directory); + } + if (system_area == SYS_AREA_AUTO || grub_install_source_directory) + { + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC] + || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275] + || source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + system_area = SYS_AREA_COMMON; + else if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275]) + system_area = SYS_AREA_SPARC; + else if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) + system_area = SYS_AREA_ARCS; + } + + /* obtain date-based UUID. */ + { + time_t tim; + struct tm *tmm; + tim = time (NULL); + tmm = gmtime (&tim); + iso_uuid = xmalloc (55); + grub_snprintf (iso_uuid, 50, + "%04d-%02d-%02d-%02d-%02d-%02d-00", + tmm->tm_year + 1900, + tmm->tm_mon + 1, + tmm->tm_mday, + tmm->tm_hour, + tmm->tm_min, + tmm->tm_sec); + } + { + char *uuid_out = xmalloc (strlen (iso_uuid) + 1 + 40); + char *optr; + const char *iptr; + optr = grub_stpcpy (uuid_out, "--modification-date="); + for (iptr = iso_uuid; *iptr; iptr++) + if (*iptr != '-') + *optr++ = *iptr; + *optr = '\0'; + xorriso_push (uuid_out); + free (uuid_out); + } + + /* build BIOS core.img. */ + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]) + { + char *load_cfg; + FILE *load_cfg_f; + char *output = grub_util_path_concat (3, boot_grub, "i386-pc", "eltorito.img"); + load_cfg = grub_util_make_temporary_file (); + + grub_util_info (N_("enabling %s support ..."), "BIOS"); + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + write_part (load_cfg_f, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC]); + fclose (load_cfg_f); + + grub_install_push_module ("biosdisk"); + grub_install_push_module ("iso9660"); + grub_install_make_image_wrap (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "/boot/grub", output, + 0, load_cfg, + "i386-pc-eltorito", 0); + + xorriso_push ("-b"); + xorriso_push ("boot/grub/i386-pc/eltorito.img"); + xorriso_push ("-no-emul-boot"); + xorriso_push ("-boot-load-size"); + xorriso_push ("4"); + xorriso_push ("-boot-info-table"); + if (system_area == SYS_AREA_COMMON) + { + if (check_xorriso ("grub2-boot-info")) + { + char *boot_hybrid = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "boot_hybrid.img"); + xorriso_push ("--grub2-boot-info"); + xorriso_push ("--grub2-mbr"); + xorriso_push (boot_hybrid); + } + else + { + FILE *sa, *bi; + size_t sz; + char buf[512]; + char *bin = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "boot.img"); + grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Some features are disabled. Please use xorriso 1.2.9 or later.")); + sysarea_img = grub_util_make_temporary_file (); + sa = grub_util_fopen (sysarea_img, "wb"); + if (!sa) + grub_util_error (_("cannot open `%s': %s"), sysarea_img, + strerror (errno)); + bi = grub_util_fopen (bin, "rb"); + if (!bi) + grub_util_error (_("cannot open `%s': %s"), bin, + strerror (errno)); + if (fread (buf, 1, 512, bi) != 512) + grub_util_error (_("cannot read `%s': %s"), bin, + strerror (errno)); + fclose (bi); + fwrite (buf, 1, 512, sa); + + grub_install_make_image_wrap_file (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC], + "/boot/grub", sa, sysarea_img, + 0, load_cfg, + "i386-pc", 0); + sz = ftello (sa); + fflush (sa); + grub_util_fd_sync (fileno (sa)); + fclose (sa); + + if (sz > 32768) + { + grub_util_warn ("%s", _("Your xorriso doesn't support `--grub2-boot-info'. Your core image is too big. Boot as disk is disabled. Please use xorriso 1.2.9 or later.")); + } + else + { + xorriso_push ("-G"); + xorriso_push (sysarea_img); + } + } + } + grub_install_pop_module (); + grub_install_pop_module (); + grub_util_unlink (load_cfg); + } + + /** build multiboot core.img */ + grub_install_push_module ("pata"); + grub_install_push_module ("ahci"); + grub_install_push_module ("at_keyboard"); + make_image (GRUB_INSTALL_PLATFORM_I386_MULTIBOOT, "i386-multiboot", "i386-multiboot/core.elf"); + grub_install_pop_module (); + grub_install_pop_module (); + grub_install_pop_module (); + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_I386_IEEE1275, "i386-ieee1275", "ofwx86.elf"); + + char *core_services = NULL; + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) + { + char *mach_ker, *sv, *label, *label_text; + FILE *f; + core_services = grub_util_path_concat (4, iso9660_dir, "System", "Library", "CoreServices"); + grub_install_mkdir_p (core_services); + + mach_ker = grub_util_path_concat (2, iso9660_dir, "mach_kernel"); + f = grub_util_fopen (mach_ker, "wb"); + fclose (f); + free (mach_ker); + + sv = grub_util_path_concat (2, core_services, "SystemVersion.plist"); + f = grub_util_fopen (sv, "wb"); + fprintf (f, "\n" + "\n" + " ProductBuildVersion\n" + " \n" + " ProductName\n" + " %s\n" + " ProductVersion\n" + " %s\n" + "\n" + "\n", product_name, product_version); + fclose (f); + free (sv); + label = grub_util_path_concat (2, core_services, ".disk_label"); + char *label_string = xasprintf ("%s %s", product_name, product_version); + grub_util_render_label (label_font, label_bgcolor ? : "white", + label_color ? : "black", label_string, label); + free (label); + label_text = grub_util_path_concat (2, core_services, ".disk_label.contentDetails"); + f = grub_util_fopen (label_text, "wb"); + fprintf (f, "%s\n", label_string); + fclose (f); + free (label_string); + free (label_text); + if (system_area == SYS_AREA_COMMON) + { + xorriso_push ("-hfsplus"); + xorriso_push ("-apm-block-size"); + xorriso_push ("2048"); + xorriso_push ("-hfsplus-file-creator-type"); + xorriso_push ("chrp"); + xorriso_push ("tbxj"); + xorriso_push ("/System/Library/CoreServices/.disk_label"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + { + xorriso_push ("-hfs-bless-by"); + xorriso_push ("i"); + xorriso_push ("/System/Library/CoreServices/boot.efi"); + } + } + } + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_IA64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_ARM64_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_MIPS64EL_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV32_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_RISCV64_EFI]) + { + char *efidir = grub_util_make_temporary_dir (); + char *efidir_efi = grub_util_path_concat (2, efidir, "efi"); + char *efidir_efi_boot = grub_util_path_concat (3, efidir, "efi", "boot"); + char *imgname, *img32, *img64, *img_mac = NULL; + char *efiimgfat; + grub_install_mkdir_p (efidir_efi_boot); + + grub_install_push_module ("part_gpt"); + grub_install_push_module ("part_msdos"); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootia64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_IA64_EFI, "ia64-efi", imgname); + free (imgname); + + grub_install_push_module ("part_apple"); + img64 = grub_util_path_concat (2, efidir_efi_boot, "bootx64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_X86_64_EFI, "x86_64-efi", img64); + grub_install_pop_module (); + + grub_install_push_module ("part_apple"); + img32 = grub_util_path_concat (2, efidir_efi_boot, "bootia32.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_I386_EFI, "i386-efi", img32); + grub_install_pop_module (); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootarm.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM_EFI, "arm-efi", imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootaa64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_ARM64_EFI, "arm64-efi", + imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootmips64el.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_MIPS64EL_EFI, "mips64el-efi", + imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv32.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV32_EFI, "riscv32-efi", + imgname); + free (imgname); + + imgname = grub_util_path_concat (2, efidir_efi_boot, "bootriscv64.efi"); + make_image_fwdisk_abs (GRUB_INSTALL_PLATFORM_RISCV64_EFI, "riscv64-efi", + imgname); + free (imgname); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) + { + imgname = grub_util_path_concat (2, efidir_efi_boot, "boot.efi"); + /* For old macs. Suggested by Peter Jones. */ + grub_install_copy_file (img32, imgname, 1); + } + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + || source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + img_mac = grub_util_path_concat (2, core_services, "boot.efi"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI] + && source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + grub_util_glue_efi (img32, img64, img_mac); + else if (source_dirs[GRUB_INSTALL_PLATFORM_X86_64_EFI]) + grub_install_copy_file (img64, img_mac, 1); + else if (source_dirs[GRUB_INSTALL_PLATFORM_I386_EFI]) + grub_install_copy_file (img32, img_mac, 1); + + free (img_mac); + free (img32); + free (img64); + free (efidir_efi_boot); + + efiimgfat = grub_util_path_concat (2, iso9660_dir, "efi.img"); + rv = grub_util_exec ((const char * []) { "mformat", "-C", "-f", "2880", "-L", "16", "-i", + efiimgfat, "::", NULL }); + if (rv != 0) + grub_util_error ("`%s` invocation failed\n", "mformat"); + rv = grub_util_exec ((const char * []) { "mcopy", "-s", "-i", efiimgfat, efidir_efi, "::/", NULL }); + if (rv != 0) + grub_util_error ("`%s` invocation failed\n", "mcopy"); + xorriso_push ("--efi-boot"); + xorriso_push ("efi.img"); + xorriso_push ("-efi-boot-part"); + xorriso_push ("--efi-boot-image"); + + grub_util_unlink_recursive (efidir); + free (efiimgfat); + free (efidir_efi); + free (efidir); + grub_install_pop_module (); + grub_install_pop_module (); + } + + grub_install_push_module ("part_apple"); + make_image_fwdisk (GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275, "powerpc-ieee1275", "powerpc-ieee1275/core.elf"); + grub_install_pop_module (); + + if (source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275]) + { + char *grub_chrp = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], + "grub.chrp"); + char *bisrc = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275], + "bootinfo.txt"); + char *bootx = grub_util_path_concat (2, core_services, "BootX"); + char *ppc_chrp = grub_util_path_concat (3, iso9660_dir, "ppc", "chrp"); + char *bitgt = grub_util_path_concat (3, iso9660_dir, "ppc", "bootinfo.txt"); + grub_install_copy_file (grub_chrp, bootx, 1); + grub_install_mkdir_p (ppc_chrp); + grub_install_copy_file (bisrc, bitgt, 1); + xorriso_link ("/System/Library/CoreServices/grub.elf", "/boot/grub/powerpc-ieee1275/core.elf"); + xorriso_link ("/boot/grub/powerpc.elf", "/boot/grub/powerpc-ieee1275/core.elf"); + /* FIXME: add PreP */ + if (system_area == SYS_AREA_COMMON) + { + xorriso_push ("-hfsplus-file-creator-type"); + xorriso_push ("chrp"); + xorriso_push ("tbxi"); + xorriso_push ("/System/Library/CoreServices/BootX"); + xorriso_push ("-hfs-bless-by"); + xorriso_push ("p"); + xorriso_push ("/System/Library/CoreServices"); + } + xorriso_push ("-sysid"); + xorriso_push ("PPC"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275, + "sparc64-ieee1275-cdcore", "sparc64-ieee1275/core.img"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275] + && system_area == SYS_AREA_SPARC) + { + char *cdboot; + FILE *in, *out; + char buf[512]; + sysarea_img = grub_util_make_temporary_file (); + cdboot = grub_util_path_concat (2, source_dirs[GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275], + "cdboot.img"); + in = grub_util_fopen (cdboot, "rb"); + if (!in) + grub_util_error (_("cannot open `%s': %s"), cdboot, + strerror (errno)); + out = grub_util_fopen (sysarea_img, "wb"); + if (!out) + grub_util_error (_("cannot open `%s': %s"), sysarea_img, + strerror (errno)); + memset (buf, 0, 512); + fwrite (buf, 1, 512, out); + if (fread (buf, 1, 512, in) != 512) + grub_util_error (_("cannot read `%s': %s"), cdboot, + strerror (errno)); + fwrite (buf, 1, 512, out); + fclose (in); + fclose (out); + xorriso_push ("-G"); + xorriso_push (sysarea_img); + xorriso_push ("-B"); + xorriso_push (","); + xorriso_push ("--grub2-sparc-core"); + xorriso_push ("/boot/grub/sparc64-ieee1275/core.img"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPS_ARC, "mips-arc", "mips-arc/core.img"); + + if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC]) + { + xorriso_link ("/boot/grub/mips-arc/grub", "/boot/grub/mips-arc/core.img"); + xorriso_link ("/boot/grub/mips-arc/sashARCS", "/boot/grub/mips-arc/core.img"); + xorriso_link ("/boot/grub/mips-arc/sash", "/boot/grub/mips-arc/core.img"); + } + if (source_dirs[GRUB_INSTALL_PLATFORM_MIPS_ARC] && system_area == SYS_AREA_ARCS) + { + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/sashARCS"); + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/sash"); + xorriso_push ("-mips-boot"); + xorriso_push ("/boot/grub/mips-arc/grub"); + } + + make_image_fwdisk (GRUB_INSTALL_PLATFORM_MIPSEL_ARC, "mipsel-arc", "arc.exe"); + + grub_install_push_module ("pata"); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "mipsel-qemu_mips-elf", "roms/mipsel-qemu_mips.elf"); + + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-loongson-elf", "loongson.elf"); + + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-yeeloong-flash", "mipsel-yeeloong.bin"); + make_image (GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "mipsel-fuloong2f-flash", "mipsel-fuloong2f.bin"); + + make_image (GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "mips-qemu_mips-elf", "roms/mips-qemu_mips.elf"); + + grub_install_push_module ("at_keyboard"); + + make_image (GRUB_INSTALL_PLATFORM_I386_QEMU, "i386-qemu", "roms/qemu.img"); + + grub_install_push_module ("ahci"); + + make_image (GRUB_INSTALL_PLATFORM_I386_COREBOOT, "i386-coreboot", "roms/coreboot.elf"); + grub_install_pop_module (); + grub_install_pop_module (); + grub_install_pop_module (); + + if (rom_directory) + { + const struct + { + enum grub_install_plat plat; + const char *from, *to; + } roms[] = + { + {GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS, "roms/mipsel-qemu_mips.elf", "mipsel-qemu_mips.elf"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "loongson.elf", "mipsel-loongson.elf"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-yeeloong.bin", "mipsel-yeeloong.bin"}, + {GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON, "roms/mipsel-fulong.bin", "mipsel-fulong.bin"}, + {GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS, "roms/mips-qemu_mips.elf", "mips-qemu_mips.elf"}, + {GRUB_INSTALL_PLATFORM_I386_QEMU, "roms/qemu.img", "qemu.img"}, + {GRUB_INSTALL_PLATFORM_I386_COREBOOT, "roms/coreboot.elf", "coreboot.elf"}, + }; + grub_size_t i; + for (i = 0; i < ARRAY_SIZE (roms); i++) + { + char *from = grub_util_path_concat (2, boot_grub, roms[i].from); + char *to = grub_util_path_concat (2, rom_directory, roms[i].to); + grub_install_copy_file (from, to, 0); + } + } + + xorriso_push ("--protective-msdos-label"); + xorriso_push ("-o"); + xorriso_push (output_image); + xorriso_push ("-r"); + xorriso_push (iso9660_dir); + xorriso_push ("--sort-weight"); + xorriso_push ("0"); + xorriso_push ("/"); + xorriso_push ("--sort-weight"); + xorriso_push ("1"); + xorriso_push ("/boot"); + int i; + for (i = 0; i < xorriso_tail_argc; i++) + xorriso_push (xorriso_tail_argv[i]); + + xorriso_argv[xorriso_argc] = NULL; + + rv = grub_util_exec ((const char *const *)xorriso_argv); + if (rv != 0) + grub_util_error ("`%s` invocation failed\n", "xorriso"); + + grub_util_unlink_recursive (iso9660_dir); + + if (sysarea_img) + grub_util_unlink (sysarea_img); + + free (core_services); + free (romdir); + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c new file mode 100644 index 00000000..c1c053d8 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifier.c @@ -0,0 +1,247 @@ +#include +#include + +#include +#include +#include +#include + +struct grub_module_verifier_arch archs[] = { + { "i386", 4, 0, EM_386, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){ + R_386_32, + R_386_PC32, + -1 + } }, + { "x86_64", 8, 0, EM_X86_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_X86_64_64, + R_X86_64_PC64, + /* R_X86_64_32, R_X86_64_32S are supported but shouldn't be used because of their limited range. */ + -1 + }, (int[]){ + R_X86_64_PC32, + R_X86_64_PLT32, + -1 + } + }, + { "powerpc", 4, 1, EM_PPC, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + GRUB_ELF_R_PPC_ADDR16_LO, + GRUB_ELF_R_PPC_REL24, /* It has limited range but GRUB adds trampolines when necessarry. */ + GRUB_ELF_R_PPC_ADDR16_HA, + GRUB_ELF_R_PPC_ADDR32, + GRUB_ELF_R_PPC_REL32, + GRUB_ELF_R_PPC_PLTREL24, + -1 + } }, + { "sparc64", 8, 1, EM_SPARCV9, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_SPARC_WDISP30, /* It has limited range but GRUB adds trampolines when necessarry. */ + R_SPARC_HH22, + R_SPARC_HM10, + R_SPARC_LM22, + R_SPARC_LO10, + R_SPARC_64, + R_SPARC_OLO10, + /* Following 2 relocations have limited range but unfortunately + clang generates them, as it doesn't implement mcmodel=large properly. + At least our heap and core are under 4G, so it's not a problem + usually. */ + R_SPARC_HI22, + R_SPARC_32, + -1 + } }, + { "ia64", 8, 0, EM_IA_64, GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_IA64_PCREL21B, /* We should verify that it's pointing either + to a function or to a section in the same module. + Checking that external symbol is a function is + non-trivial and I have never seen this relocation used + for anything else, so assume that it always points to a + function. + */ + R_IA64_SEGREL64LSB, + R_IA64_FPTR64LSB, + R_IA64_DIR64LSB, + R_IA64_PCREL64LSB, + R_IA64_LTOFF22X, + R_IA64_LTOFF22, + R_IA64_GPREL64I, + R_IA64_LTOFF_FPTR22, + R_IA64_LDXMOV, + -1 + }, (int[]){ + R_IA64_GPREL22, + -1 + } }, + { "mipsel", 4, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_MIPS_HI16, + R_MIPS_LO16, + R_MIPS_32, + R_MIPS_GPREL32, + R_MIPS_26, + R_MIPS_GOT16, + R_MIPS_CALL16, + R_MIPS_JALR, + -1 + } }, + { "mips", 4, 1, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_MIPS_HI16, + R_MIPS_LO16, + R_MIPS_32, + R_MIPS_GPREL32, + R_MIPS_26, + R_MIPS_GOT16, + R_MIPS_CALL16, + R_MIPS_JALR, + -1 + } }, + { "arm", 4, 0, EM_ARM, GRUB_MODULE_VERIFY_SUPPORTS_REL, (int[]){ + /* Some relocations are range-limited but trampolines are added when necessarry. */ + R_ARM_ABS32, + R_ARM_CALL, + R_ARM_JUMP24, + R_ARM_THM_CALL, + R_ARM_THM_JUMP24, + R_ARM_V4BX, + R_ARM_THM_MOVW_ABS_NC, + R_ARM_THM_MOVT_ABS, + R_ARM_THM_JUMP19, + -1 + } }, + { "arm64", 8, 0, EM_AARCH64, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_AARCH64_ABS64, + R_AARCH64_CALL26, + R_AARCH64_JUMP26, + R_AARCH64_ADR_GOT_PAGE, + R_AARCH64_LD64_GOT_LO12_NC, + -1 + }, (int[]){ + R_AARCH64_ADR_PREL_PG_HI21, + R_AARCH64_ADD_ABS_LO12_NC, + R_AARCH64_LDST64_ABS_LO12_NC, + R_AARCH64_PREL32, + -1 + } }, + { "mips64el", 8, 0, EM_MIPS, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_MIPS_64, + R_MIPS_32, + R_MIPS_26, + R_MIPS_LO16, + R_MIPS_HI16, + R_MIPS_HIGHER, + R_MIPS_HIGHEST, + -1 + }, (int[]){ + -1 + } + }, + { "riscv32", 4, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_RISCV_32, + R_RISCV_64, + R_RISCV_ADD8, + R_RISCV_ADD16, + R_RISCV_ADD32, + R_RISCV_ADD64, + R_RISCV_SUB8, + R_RISCV_SUB16, + R_RISCV_SUB32, + R_RISCV_SUB64, + R_RISCV_ALIGN, + R_RISCV_BRANCH, + R_RISCV_CALL, + R_RISCV_CALL_PLT, + R_RISCV_GOT_HI20, + R_RISCV_HI20, + R_RISCV_JAL, + R_RISCV_LO12_I, + R_RISCV_LO12_S, + R_RISCV_PCREL_HI20, + R_RISCV_PCREL_LO12_I, + R_RISCV_PCREL_LO12_S, + R_RISCV_RELAX, + R_RISCV_RVC_BRANCH, + R_RISCV_RVC_JUMP, + -1 + } }, + { "riscv64", 8, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ + R_RISCV_32, + R_RISCV_64, + R_RISCV_ADD8, + R_RISCV_ADD16, + R_RISCV_ADD32, + R_RISCV_ADD64, + R_RISCV_SUB8, + R_RISCV_SUB16, + R_RISCV_SUB32, + R_RISCV_SUB64, + R_RISCV_ALIGN, + R_RISCV_BRANCH, + R_RISCV_CALL, + R_RISCV_CALL_PLT, + R_RISCV_GOT_HI20, + R_RISCV_HI20, + R_RISCV_JAL, + R_RISCV_LO12_I, + R_RISCV_LO12_S, + R_RISCV_PCREL_HI20, + R_RISCV_PCREL_LO12_I, + R_RISCV_PCREL_LO12_S, + R_RISCV_RELAX, + R_RISCV_RVC_BRANCH, + R_RISCV_RVC_JUMP, + -1 + } + }, +}; + +struct platform_whitelist { + const char *arch; + const char *platform; + const char **whitelist_empty; +}; + +static struct platform_whitelist whitelists[] = { + {"i386", "xen", (const char *[]) {"all_video", 0}}, + {"i386", "xen_pvh", (const char *[]) {"all_video", 0}}, + {"x86_64", "xen", (const char *[]) {"all_video", 0}}, + {"sparc64", "ieee1275", (const char *[]) {"all_video", 0}}, + + /* video is compiled-in on MIPS. */ + {"mipsel", "loongson", (const char *[]) {"all_video", 0}}, + {"mipsel", "qemu_mips", (const char *[]) {"all_video", 0}}, + {"mipsel", "arc", (const char *[]) {"all_video", 0}}, + {"mips", "qemu_mips", (const char *[]) {"all_video", 0}}, + {"mips", "arc", (const char *[]) {"all_video", 0}}, +}; + + +int +main (int argc, char **argv) +{ + size_t module_size; + unsigned arch, whitelist; + const char **whitelist_empty = 0; + char *module_img; + if (argc != 4) { + fprintf (stderr, "usage: %s FILE ARCH PLATFORM\n", argv[0]); + return 1; + } + + for (arch = 0; arch < ARRAY_SIZE(archs); arch++) + if (strcmp(archs[arch].name, argv[2]) == 0) + break; + if (arch == ARRAY_SIZE(archs)) + grub_util_error("%s: unknown arch: %s", argv[1], argv[2]); + + for (whitelist = 0; whitelist < ARRAY_SIZE(whitelists); whitelist++) + if (strcmp(whitelists[whitelist].arch, argv[2]) == 0 + && strcmp(whitelists[whitelist].platform, argv[3]) == 0) + break; + if (whitelist != ARRAY_SIZE(whitelists)) + whitelist_empty = whitelists[whitelist].whitelist_empty; + + module_size = grub_util_get_image_size (argv[1]); + module_img = grub_util_read_image (argv[1]); + if (archs[arch].voidp_sizeof == 8) + grub_module_verify64(argv[1], module_img, module_size, &archs[arch], whitelist_empty); + else + grub_module_verify32(argv[1], module_img, module_size, &archs[arch], whitelist_empty); + return 0; +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c new file mode 100644 index 00000000..b0ae428e --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/grub-module-verifierXX.c @@ -0,0 +1,446 @@ +#include + +#include +#include +#include + +#if defined(MODULEVERIFIER_ELF32) +# define SUFFIX(x) x ## 32 +# define ELFCLASSXX ELFCLASS32 +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Phdr Elf32_Phdr +# define Elf_Nhdr Elf32_Nhdr +# define Elf_Addr Elf32_Addr +# define Elf_Sym Elf32_Sym +# define Elf_Off Elf32_Off +# define Elf_Shdr Elf32_Shdr +# define Elf_Rela Elf32_Rela +# define Elf_Rel Elf32_Rel +# define Elf_Word Elf32_Word +# define Elf_Half Elf32_Half +# define Elf_Section Elf32_Section +# define ELF_R_SYM(val) ELF32_R_SYM(val) +# define ELF_R_TYPE(val) ELF32_R_TYPE(val) +# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val) +#elif defined(MODULEVERIFIER_ELF64) +# define SUFFIX(x) x ## 64 +# define ELFCLASSXX ELFCLASS64 +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Phdr Elf64_Phdr +# define Elf_Nhdr Elf64_Nhdr +# define Elf_Addr Elf64_Addr +# define Elf_Sym Elf64_Sym +# define Elf_Off Elf64_Off +# define Elf_Shdr Elf64_Shdr +# define Elf_Rela Elf64_Rela +# define Elf_Rel Elf64_Rel +# define Elf_Word Elf64_Word +# define Elf_Half Elf64_Half +# define Elf_Section Elf64_Section +# define ELF_R_SYM(val) ELF64_R_SYM(val) +# define ELF_R_TYPE(val) ELF64_R_TYPE(val) +# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val) +#else +#error "I'm confused" +#endif + +#define grub_target_to_host32(x) (grub_target_to_host32_real (arch, (x))) +#define grub_host_to_target32(x) (grub_host_to_target32_real (arch, (x))) +#define grub_target_to_host64(x) (grub_target_to_host64_real (arch, (x))) +#define grub_host_to_target64(x) (grub_host_to_target64_real (arch, (x))) +#define grub_host_to_target_addr(x) (grub_host_to_target_addr_real (arch, (x))) +#define grub_target_to_host16(x) (grub_target_to_host16_real (arch, (x))) +#define grub_host_to_target16(x) (grub_host_to_target16_real (arch, (x))) +#define grub_target_to_host(val) grub_target_to_host_real(arch, (val)) + +static inline grub_uint32_t +grub_target_to_host32_real (const struct grub_module_verifier_arch *arch, + grub_uint32_t in) +{ + if (arch->bigendian) + return grub_be_to_cpu32 (in); + else + return grub_le_to_cpu32 (in); +} + +static inline grub_uint64_t +grub_target_to_host64_real (const struct grub_module_verifier_arch *arch, + grub_uint64_t in) +{ + if (arch->bigendian) + return grub_be_to_cpu64 (in); + else + return grub_le_to_cpu64 (in); +} + +static inline grub_uint64_t +grub_host_to_target64_real (const struct grub_module_verifier_arch *arch, + grub_uint64_t in) +{ + if (arch->bigendian) + return grub_cpu_to_be64 (in); + else + return grub_cpu_to_le64 (in); +} + +static inline grub_uint32_t +grub_host_to_target32_real (const struct grub_module_verifier_arch *arch, + grub_uint32_t in) +{ + if (arch->bigendian) + return grub_cpu_to_be32 (in); + else + return grub_cpu_to_le32 (in); +} + +static inline grub_uint16_t +grub_target_to_host16_real (const struct grub_module_verifier_arch *arch, + grub_uint16_t in) +{ + if (arch->bigendian) + return grub_be_to_cpu16 (in); + else + return grub_le_to_cpu16 (in); +} + +static inline grub_uint16_t +grub_host_to_target16_real (const struct grub_module_verifier_arch *arch, + grub_uint16_t in) +{ + if (arch->bigendian) + return grub_cpu_to_be16 (in); + else + return grub_cpu_to_le16 (in); +} + +static inline grub_uint64_t +grub_host_to_target_addr_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in) +{ + if (arch->voidp_sizeof == 8) + return grub_host_to_target64_real (arch, in); + else + return grub_host_to_target32_real (arch, in); +} + +static inline grub_uint64_t +grub_target_to_host_real (const struct grub_module_verifier_arch *arch, grub_uint64_t in) +{ + if (arch->voidp_sizeof == 8) + return grub_target_to_host64_real (arch, in); + else + return grub_target_to_host32_real (arch, in); +} + + +static Elf_Shdr * +find_section (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, const char *name) +{ + Elf_Shdr *s; + const char *str; + unsigned i; + + s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host16 (e->e_shstrndx) * grub_target_to_host16 (e->e_shentsize)); + str = (char *) e + grub_target_to_host (s->sh_offset); + + for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); + i < grub_target_to_host16 (e->e_shnum); + i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) + if (strcmp (str + grub_target_to_host32 (s->sh_name), name) == 0) + return s; + return NULL; +} + +static void +check_license (const char * const filename, + const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) +{ + Elf_Shdr *s = find_section (arch, e, ".module_license"); + if (s && (strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3") == 0 + || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv3+") == 0 + || strcmp ((char *) e + grub_target_to_host(s->sh_offset), "LICENSE=GPLv2+") == 0)) + return; + grub_util_error ("%s: incompatible license", filename); +} + +static Elf_Sym * +get_symtab (const struct grub_module_verifier_arch *arch, Elf_Ehdr *e, Elf_Word *size, Elf_Word *entsize) +{ + unsigned i; + Elf_Shdr *s, *sections; + Elf_Sym *sym; + + sections = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); + for (i = 0, s = sections; + i < grub_target_to_host16 (e->e_shnum); + i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) + if (grub_target_to_host32 (s->sh_type) == SHT_SYMTAB) + break; + + if (i == grub_target_to_host16 (e->e_shnum)) + return NULL; + + sym = (Elf_Sym *) ((char *) e + grub_target_to_host (s->sh_offset)); + *size = grub_target_to_host (s->sh_size); + *entsize = grub_target_to_host (s->sh_entsize); + return sym; +} + +static int +is_whitelisted (const char *modname, const char **whitelist) +{ + const char **ptr; + if (!whitelist) + return 0; + if (!modname) + return 0; + for (ptr = whitelist; *ptr; ptr++) + if (strcmp (modname, *ptr) == 0) + return 1; + return 0; +} + +static void +check_symbols (const struct grub_module_verifier_arch *arch, + Elf_Ehdr *e, const char *modname, + const char **whitelist_empty) +{ + Elf_Sym *sym; + Elf_Word size, entsize; + unsigned i; + + /* Module without symbol table and without .moddeps section is useless + at boot time, so catch it early to prevent build errors */ + sym = get_symtab (arch, e, &size, &entsize); + if (!sym) + { + Elf_Shdr *s; + + /* However some modules are dependencies-only, + e.g. insmod all_video pulls in all video drivers. + Some platforms e.g. xen have no video drivers, so + the module does nothing. */ + if (is_whitelisted (modname, whitelist_empty)) + return; + + s = find_section (arch, e, ".moddeps"); + + if (!s) + grub_util_error ("%s: no symbol table and no .moddeps section", modname); + + if (!s->sh_size) + grub_util_error ("%s: no symbol table and empty .moddeps section", modname); + + return; + } + + for (i = 0; + i < size / entsize; + i++, sym = (Elf_Sym *) ((char *) sym + entsize)) + { + unsigned char type = ELF_ST_TYPE (sym->st_info); + + switch (type) + { + case STT_NOTYPE: + case STT_OBJECT: + case STT_FUNC: + case STT_SECTION: + case STT_FILE: + break; + + default: + return grub_util_error ("%s: unknown symbol type `%d'", modname, (int) type); + } + } +} + +static int +is_symbol_local(Elf_Sym *sym) +{ + switch (ELF_ST_TYPE (sym->st_info)) + { + case STT_NOTYPE: + case STT_OBJECT: + if (sym->st_name != 0 && sym->st_shndx == 0) + return 0; + return 1; + + case STT_FUNC: + case STT_SECTION: + return 1; + + default: + return 0; + } +} + +static void +section_check_relocations (const char * const modname, + const struct grub_module_verifier_arch *arch, void *ehdr, + Elf_Shdr *s, size_t target_seg_size) +{ + Elf_Rel *rel, *max; + Elf_Sym *symtab; + Elf_Word symtabsize, symtabentsize; + + symtab = get_symtab (arch, ehdr, &symtabsize, &symtabentsize); + if (!symtab) + grub_util_error ("%s: relocation without symbol table", modname); + + for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)), + max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size)); + rel < max; + rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize))) + { + Elf_Sym *sym; + unsigned i; + + if (target_seg_size < grub_target_to_host (rel->r_offset)) + grub_util_error ("%s: reloc offset is out of the segment", modname); + + grub_size_t r_info; + if (arch->machine == EM_MIPS && arch->voidp_sizeof == 8) + r_info = ((grub_uint64_t) rel->r_info << 32) | + (grub_uint32_t) grub_be_to_cpu64 (rel->r_info); + else + r_info = grub_target_to_host (rel->r_info); + + grub_uint32_t type = ELF_R_TYPE (r_info); + + if (arch->machine == EM_SPARCV9) + type &= 0xff; + + for (i = 0; arch->supported_relocations[i] != -1; i++) + if (type == arch->supported_relocations[i]) + break; + if (arch->supported_relocations[i] != -1) + continue; + if (!arch->short_relocations) + grub_util_error ("%s: unsupported relocation 0x%x", modname, type); + for (i = 0; arch->short_relocations[i] != -1; i++) + if (type == arch->short_relocations[i]) + break; + if (arch->short_relocations[i] == -1) + grub_util_error ("%s: unsupported relocation 0x%x", modname, type); + sym = (Elf_Sym *) ((char *) symtab + symtabentsize * ELF_R_SYM (r_info)); + + if (is_symbol_local (sym)) + continue; + grub_util_error ("%s: relocation 0x%x is not module-local", modname, type); + } +#if defined(MODULEVERIFIER_ELF64) + if (arch->machine == EM_AARCH64) + { + unsigned unmatched_adr_got_page = 0; + Elf_Rela *rel2; + for (rel = (Elf_Rel *) ((char *) ehdr + grub_target_to_host (s->sh_offset)), + max = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_size)); + rel < max; + rel = (Elf_Rel *) ((char *) rel + grub_target_to_host (s->sh_entsize))) + { + switch (ELF_R_TYPE (grub_target_to_host (rel->r_info))) + { + case R_AARCH64_ADR_GOT_PAGE: + unmatched_adr_got_page++; + for (rel2 = (Elf_Rela *) ((char *) rel + grub_target_to_host (s->sh_entsize)); + rel2 < (Elf_Rela *) max; + rel2 = (Elf_Rela *) ((char *) rel2 + grub_target_to_host (s->sh_entsize))) + if (ELF_R_SYM (rel2->r_info) + == ELF_R_SYM (rel->r_info) + && ((Elf_Rela *) rel)->r_addend == rel2->r_addend + && ELF_R_TYPE (rel2->r_info) == R_AARCH64_LD64_GOT_LO12_NC) + break; + if (rel2 >= (Elf_Rela *) max) + grub_util_error ("%s: ADR_GOT_PAGE without matching LD64_GOT_LO12_NC", modname); + break; + case R_AARCH64_LD64_GOT_LO12_NC: + if (unmatched_adr_got_page == 0) + grub_util_error ("%s: LD64_GOT_LO12_NC without matching ADR_GOT_PAGE", modname); + unmatched_adr_got_page--; + break; + } + } + } +#endif +} + +static void +check_relocations (const char * const modname, + const struct grub_module_verifier_arch *arch, Elf_Ehdr *e) +{ + Elf_Shdr *s; + unsigned i; + + for (i = 0, s = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff)); + i < grub_target_to_host16 (e->e_shnum); + i++, s = (Elf_Shdr *) ((char *) s + grub_target_to_host16 (e->e_shentsize))) + if (grub_target_to_host32 (s->sh_type) == SHT_REL || grub_target_to_host32 (s->sh_type) == SHT_RELA) + { + Elf_Shdr *ts; + + if (grub_target_to_host32 (s->sh_type) == SHT_REL && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_REL)) + grub_util_error ("%s: unsupported SHT_REL", modname); + if (grub_target_to_host32 (s->sh_type) == SHT_RELA && !(arch->flags & GRUB_MODULE_VERIFY_SUPPORTS_RELA)) + grub_util_error ("%s: unsupported SHT_RELA", modname); + + /* Find the target segment. */ + if (grub_target_to_host32 (s->sh_info) >= grub_target_to_host16 (e->e_shnum)) + grub_util_error ("%s: orphaned reloc section", modname); + ts = (Elf_Shdr *) ((char *) e + grub_target_to_host (e->e_shoff) + grub_target_to_host32 (s->sh_info) * grub_target_to_host16 (e->e_shentsize)); + + section_check_relocations (modname, arch, e, s, grub_target_to_host (ts->sh_size)); + } +} + +void +SUFFIX(grub_module_verify) (const char * const filename, + void *module_img, size_t size, + const struct grub_module_verifier_arch *arch, + const char **whitelist_empty) +{ + Elf_Ehdr *e = module_img; + + /* Check the header size. */ + if (size < sizeof (Elf_Ehdr)) + grub_util_error ("%s: ELF header smaller than expected", filename); + + /* Check the magic numbers. */ + if (e->e_ident[EI_MAG0] != ELFMAG0 + || e->e_ident[EI_MAG1] != ELFMAG1 + || e->e_ident[EI_MAG2] != ELFMAG2 + || e->e_ident[EI_MAG3] != ELFMAG3 + || e->e_ident[EI_VERSION] != EV_CURRENT + || grub_target_to_host32 (e->e_version) != EV_CURRENT) + grub_util_error ("%s: invalid arch-independent ELF magic", filename); + + if (e->e_ident[EI_CLASS] != ELFCLASSXX + || e->e_ident[EI_DATA] != (arch->bigendian ? ELFDATA2MSB : ELFDATA2LSB) + || grub_target_to_host16 (e->e_machine) != arch->machine) + grub_util_error ("%s: invalid arch-dependent ELF magic", filename); + + if (grub_target_to_host16 (e->e_type) != ET_REL) + { + grub_util_error ("%s: this ELF file is not of the right type", filename); + } + + /* Make sure that every section is within the core. */ + if (size < grub_target_to_host (e->e_shoff) + + (grub_uint32_t) grub_target_to_host16 (e->e_shentsize) * grub_target_to_host16(e->e_shnum)) + { + grub_util_error ("%s: ELF sections outside core", filename); + } + + check_license (filename, arch, e); + + Elf_Shdr *s; + const char *modname; + + s = find_section (arch, e, ".modname"); + if (!s) + grub_util_error ("%s: no module name found", filename); + + modname = (const char *) e + grub_target_to_host (s->sh_offset); + + check_symbols(arch, e, modname, whitelist_empty); + check_relocations(modname, arch, e); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/mkimage.c b/GRUB2/MOD_SRC/grub-2.04/util/mkimage.c new file mode 100644 index 00000000..766ab019 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/mkimage.c @@ -0,0 +1,1776 @@ +/* grub-mkimage.c - make a bootable image */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ALIGN_ADDR(x) (ALIGN_UP((x), image_target->voidp_sizeof)) + +#ifdef USE_LIBLZMA +#include +#endif + +#pragma GCC diagnostic ignored "-Wcast-align" + +#define TARGET_NO_FIELD 0xffffffff + +/* use 2015-01-01T00:00:00+0000 as a stock timestamp */ +#define STABLE_EMBEDDING_TIMESTAMP 1420070400 + +#define EFI32_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \ + + GRUB_PE32_SIGNATURE_SIZE \ + + sizeof (struct grub_pe32_coff_header) \ + + sizeof (struct grub_pe32_optional_header) \ + + 4 * sizeof (struct grub_pe32_section_table), \ + GRUB_PE32_FILE_ALIGNMENT) + +#define EFI64_HEADER_SIZE ALIGN_UP (GRUB_PE32_MSDOS_STUB_SIZE \ + + GRUB_PE32_SIGNATURE_SIZE \ + + sizeof (struct grub_pe32_coff_header) \ + + sizeof (struct grub_pe64_optional_header) \ + + 4 * sizeof (struct grub_pe32_section_table), \ + GRUB_PE32_FILE_ALIGNMENT) + +static const struct grub_install_image_target_desc image_targets[] = + { + { + .dirname = "i386-coreboot", + .names = { "i386-coreboot", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .reloc_table_offset = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .dirname = "i386-multiboot", + .names = { "i386-multiboot", NULL}, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_COREBOOT_LINK_ADDR, + .elf_target = EM_386, + .link_align = 4, + .mod_gap = GRUB_KERNEL_I386_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_COREBOOT_MOD_ALIGN + }, + { + .dirname = "i386-pc", + .names = { "i386-pc", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression = GRUB_COMPRESSION_LZMA + }, + { + .dirname = "i386-xen_pvh", + .names = { "i386-xen_pvh", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_XEN_PVH, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .elf_target = EM_386, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_XEN_PVH_LINK_ADDR, + .mod_align = GRUB_KERNEL_I386_XEN_PVH_MOD_ALIGN, + .link_align = 4 + }, + { + .dirname = "i386-pc", + .names = { "i386-pc-pxe", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC_PXE, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression = GRUB_COMPRESSION_LZMA + }, + { + .dirname = "i386-pc", + .names = { "i386-pc-eltorito", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_PC_ELTORITO, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_I386_PC_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_I386_PC_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_PC_LINK_ADDR, + .default_compression = GRUB_COMPRESSION_LZMA + }, + { + .dirname = "i386-efi", + .names = { "i386-efi", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI32_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_I386, + .elf_target = EM_386, + }, + { + .dirname = "i386-ieee1275", + .names = { "i386-ieee1275", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_I386_IEEE1275, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_IEEE1275_LINK_ADDR, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_IEEE1275_MOD_ALIGN, + .link_align = 4, + }, + { + .dirname = "i386-qemu", + .names = { "i386-qemu", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_I386_QEMU_LINK_ADDR + }, + { + .dirname = "x86_64-efi", + .names = { "x86_64-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_X86_64, + .elf_target = EM_X86_64, + }, + { + .dirname = "i386-xen", + .names = { "i386-xen", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_XEN, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = 0, + .elf_target = EM_386, + .mod_gap = GRUB_KERNEL_I386_XEN_MOD_GAP, + .mod_align = GRUB_KERNEL_I386_XEN_MOD_ALIGN, + .link_align = 4 + }, + { + .dirname = "x86_64-xen", + .names = { "x86_64-xen", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_XEN, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = 0, + .elf_target = EM_X86_64, + .mod_gap = GRUB_KERNEL_X86_64_XEN_MOD_GAP, + .mod_align = GRUB_KERNEL_X86_64_XEN_MOD_ALIGN, + .link_align = 8 + }, + { + .dirname = "mipsel-loongson", + .names = { "mipsel-yeeloong-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_YEELOONG_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-loongson", + .names = { "mipsel-fuloong2f-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_FULOONG2F_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-loongson", + .names = { "mipsel-loongson-elf", "mipsel-yeeloong-elf", + "mipsel-fuloong2f-elf", "mipsel-fuloong2e-elf", + "mipsel-fuloong-elf", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_LOONGSON_ELF, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_LOONGSON_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_LOONGSON_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "powerpc-ieee1275", + .names = { "powerpc-ieee1275", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_PPC, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR, + .elf_target = EM_PPC, + .mod_gap = GRUB_KERNEL_POWERPC_IEEE1275_MOD_GAP, + .mod_align = GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN, + .link_align = 4 + }, + { + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-raw", NULL }, + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_RAW, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, + }, + { + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-cdcore", NULL }, + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_CDCORE, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, + }, + { + .dirname = "sparc64-ieee1275", + .names = { "sparc64-ieee1275-aout", NULL }, + .voidp_sizeof = 8, + .bigendian = 1, + .id = IMAGE_SPARC64_AOUT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_SPARC64_IEEE1275_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR, + .mod_align = GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN, + }, + { + .dirname = "ia64-efi", + .names = {"ia64-efi", NULL}, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_IA64, + .elf_target = EM_IA_64, + }, + { + .dirname = "mips-arc", + .names = {"mips-arc", NULL}, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_MIPS_ARC, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_ARC_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-arc", + .names = {"mipsel-arc", NULL}, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_MIPS_ARC, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_ARC_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPSEL_ARC_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_ARC_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-qemu_mips", + .names = { "mipsel-qemu_mips-elf", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_LOONGSON_ELF, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mips-qemu_mips", + .names = { "mips-qemu_mips-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_QEMU_MIPS_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mipsel-qemu_mips", + .names = { "mipsel-qemu_mips-flash", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_QEMU_MIPS_FLASH, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "mips-qemu_mips", + .names = { "mips-qemu_mips-elf", NULL }, + .voidp_sizeof = 4, + .bigendian = 1, + .id = IMAGE_LOONGSON_ELF, + .flags = PLATFORM_FLAGS_DECOMPRESSORS, + .total_module_size = GRUB_KERNEL_MIPS_QEMU_MIPS_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_COMPRESSED_SIZE, + .decompressor_uncompressed_size = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_SIZE, + .decompressor_uncompressed_addr = GRUB_DECOMPRESSOR_MIPS_LOONGSON_UNCOMPRESSED_ADDR, + .section_align = 1, + .vaddr_offset = 0, + .link_addr = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ADDR, + .elf_target = EM_MIPS, + .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN, + .default_compression = GRUB_COMPRESSION_NONE + }, + { + .dirname = "arm-uboot", + .names = { "arm-uboot", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_UBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, + .vaddr_offset = 0, + .elf_target = EM_ARM, + .mod_gap = GRUB_KERNEL_ARM_UBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN, + .link_align = 4 + }, + /* For coreboot versions that don't support self-relocating images. */ + { + .dirname = "arm-coreboot-vexpress", + .names = { "arm-coreboot-vexpress", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .vaddr_offset = 0, + .elf_target = EM_ARM, + .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .link_align = 4, + .link_addr = 0x62000000, + }, + { + .dirname = "arm-coreboot-veyron", + .names = { "arm-coreboot-veyron", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_COREBOOT, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = GRUB_KERNEL_ARM_COREBOOT_TOTAL_MODULE_SIZE, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .vaddr_offset = 0, + .elf_target = EM_ARM, + .mod_gap = GRUB_KERNEL_ARM_COREBOOT_MOD_GAP, + .mod_align = GRUB_KERNEL_ARM_COREBOOT_MOD_ALIGN, + .link_align = 4, + .link_addr = 0x43000000, + }, + { + .dirname = "arm-efi", + .names = { "arm-efi", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI32_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_ARMTHUMB_MIXED, + .elf_target = EM_ARM, + }, + { + .dirname = "arm64-efi", + .names = { "arm64-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_ARM64, + .elf_target = EM_AARCH64, + }, + { + .dirname = "mips64el-efi", + .names = { "mips64el-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_MIPS, + .elf_target = EM_MIPS, + }, + { + .dirname = "riscv32-efi", + .names = { "riscv32-efi", NULL }, + .voidp_sizeof = 4, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI32_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_RISCV32, + .elf_target = EM_RISCV, + }, + { + .dirname = "riscv64-efi", + .names = { "riscv64-efi", NULL }, + .voidp_sizeof = 8, + .bigendian = 0, + .id = IMAGE_EFI, + .flags = PLATFORM_FLAGS_NONE, + .total_module_size = TARGET_NO_FIELD, + .decompressor_compressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_size = TARGET_NO_FIELD, + .decompressor_uncompressed_addr = TARGET_NO_FIELD, + .section_align = GRUB_PE32_SECTION_ALIGNMENT, + .vaddr_offset = EFI64_HEADER_SIZE, + .pe_target = GRUB_PE32_MACHINE_RISCV64, + .elf_target = EM_RISCV, + }, + }; + +#include + +static void *SzAlloc(void *p __attribute__ ((unused)), size_t size) { return xmalloc(size); } +static void SzFree(void *p __attribute__ ((unused)), void *address) { free(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + +static void +compress_kernel_lzma (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + CLzmaEncProps props; + unsigned char out_props[5]; + size_t out_props_size = 5; + + LzmaEncProps_Init(&props); + props.dictSize = 1 << 16; + props.lc = 3; + props.lp = 0; + props.pb = 2; + props.numThreads = 1; + + *core_img = xmalloc (kernel_size); + + *core_size = kernel_size; + if (LzmaEncode ((unsigned char *) *core_img, core_size, + (unsigned char *) kernel_img, + kernel_size, + &props, out_props, &out_props_size, + 0, NULL, &g_Alloc, &g_Alloc) != SZ_OK) + grub_util_error ("%s", _("cannot compress the kernel image")); +} + +#ifdef USE_LIBLZMA +static void +compress_kernel_xz (char *kernel_img, size_t kernel_size, + char **core_img, size_t *core_size) +{ + lzma_stream strm = LZMA_STREAM_INIT; + lzma_ret xzret; + lzma_options_lzma lzopts = { + .dict_size = 1 << 16, + .preset_dict = NULL, + .preset_dict_size = 0, + .lc = 3, + .lp = 0, + .pb = 2, + .mode = LZMA_MODE_NORMAL, + .nice_len = 64, + .mf = LZMA_MF_BT4, + .depth = 0, + }; + lzma_filter fltrs[] = { + { .id = LZMA_FILTER_LZMA2, .options = &lzopts}, + { .id = LZMA_VLI_UNKNOWN, .options = NULL} + }; + + xzret = lzma_stream_encoder (&strm, fltrs, LZMA_CHECK_NONE); + if (xzret != LZMA_OK) + grub_util_error ("%s", _("cannot compress the kernel image")); + + *core_img = xmalloc (kernel_size); + + *core_size = kernel_size; + strm.next_in = (unsigned char *) kernel_img; + strm.avail_in = kernel_size; + strm.next_out = (unsigned char *) *core_img; + strm.avail_out = *core_size; + + while (1) + { + xzret = lzma_code (&strm, LZMA_FINISH); + if (xzret == LZMA_OK) + continue; + if (xzret == LZMA_STREAM_END) + break; + grub_util_error ("%s", _("cannot compress the kernel image")); + } + + *core_size -= strm.avail_out; +} +#endif + +static void +compress_kernel (const struct grub_install_image_target_desc *image_target, char *kernel_img, + size_t kernel_size, char **core_img, size_t *core_size, + grub_compression_t comp) +{ + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp == GRUB_COMPRESSION_LZMA)) + { + compress_kernel_lzma (kernel_img, kernel_size, core_img, + core_size); + return; + } + +#ifdef USE_LIBLZMA + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp == GRUB_COMPRESSION_XZ)) + { + compress_kernel_xz (kernel_img, kernel_size, core_img, + core_size); + return; + } +#endif + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS + && (comp != GRUB_COMPRESSION_NONE)) + grub_util_error (_("unknown compression %d"), comp); + + *core_img = xmalloc (kernel_size); + memcpy (*core_img, kernel_img, kernel_size); + *core_size = kernel_size; +} + +const struct grub_install_image_target_desc * +grub_install_get_image_target (const char *arg) +{ + unsigned i, j; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + for (j = 0; j < ARRAY_SIZE (image_targets[i].names) && + image_targets[i].names[j]; j++) + if (strcmp (arg, image_targets[i].names[j]) == 0) + return &image_targets[i]; + return NULL; +} + +const char * +grub_util_get_target_dirname (const struct grub_install_image_target_desc *t) +{ + return t->dirname; +} + +const char * +grub_util_get_target_name (const struct grub_install_image_target_desc *t) +{ + return t->names[0]; +} + +char * +grub_install_get_image_targets_string (void) +{ + int format_len = 0; + char *formats; + char *ptr; + unsigned i; + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + format_len += strlen (image_targets[i].names[0]) + 2; + ptr = formats = xmalloc (format_len); + for (i = 0; i < ARRAY_SIZE (image_targets); i++) + { + strcpy (ptr, image_targets[i].names[0]); + ptr += strlen (image_targets[i].names[0]); + *ptr++ = ','; + *ptr++ = ' '; + } + ptr[-2] = 0; + + return formats; +} + +void +grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, const char *outname, char *mods[], + char *memdisk_path, char **pubkey_paths, + size_t npubkeys, char *config_path, + const struct grub_install_image_target_desc *image_target, + int note, grub_compression_t comp, const char *dtb_path) +{ + char *kernel_img, *core_img; + size_t total_module_size, core_size; + size_t memdisk_size = 0, config_size = 0; + size_t prefix_size = 0, dtb_size = 0; + char *kernel_path; + size_t offset; + struct grub_util_path_list *path_list, *p; + size_t decompress_size = 0; + struct grub_mkimage_layout layout; + + if (comp == GRUB_COMPRESSION_AUTO) + comp = image_target->default_compression; + + if (image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE + || image_target->id == IMAGE_I386_PC_ELTORITO) + comp = GRUB_COMPRESSION_LZMA; + + path_list = grub_util_resolve_dependencies (dir, "moddep.lst", mods); + + kernel_path = grub_util_get_path (dir, "kernel.img"); + + if (image_target->voidp_sizeof == 8) + total_module_size = sizeof (struct grub_module_info64); + else + total_module_size = sizeof (struct grub_module_info32); + + { + size_t i; + for (i = 0; i < npubkeys; i++) + { + size_t curs; + curs = ALIGN_ADDR (grub_util_get_image_size (pubkey_paths[i])); + grub_util_info ("the size of public key %u is 0x%" + GRUB_HOST_PRIxLONG_LONG, + (unsigned) i, (unsigned long long) curs); + total_module_size += curs + sizeof (struct grub_module_header); + } + } + + if (memdisk_path) + { + memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); + grub_util_info ("the size of memory disk is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) memdisk_size); + total_module_size += memdisk_size + sizeof (struct grub_module_header); + } + + if (dtb_path) + { + dtb_size = ALIGN_ADDR(grub_util_get_image_size (dtb_path)); + total_module_size += dtb_size + sizeof (struct grub_module_header); + } + + if (config_path) + { + config_size = ALIGN_ADDR (grub_util_get_image_size (config_path) + 1); + grub_util_info ("the size of config file is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) config_size); + total_module_size += config_size + sizeof (struct grub_module_header); + } + + if (prefix) + { + prefix_size = ALIGN_ADDR (strlen (prefix) + 1); + total_module_size += prefix_size + sizeof (struct grub_module_header); + } + + for (p = path_list; p; p = p->next) + total_module_size += (ALIGN_ADDR (grub_util_get_image_size (p->name)) + + sizeof (struct grub_module_header)); + + grub_util_info ("the total module size is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) total_module_size); + + if (image_target->voidp_sizeof == 4) + kernel_img = grub_mkimage_load_image32 (kernel_path, total_module_size, + &layout, image_target); + else + kernel_img = grub_mkimage_load_image64 (kernel_path, total_module_size, + &layout, image_target); + if ((image_target->id == IMAGE_XEN || image_target->id == IMAGE_XEN_PVH) && + layout.align < 4096) + layout.align = 4096; + + if ((image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + && (image_target->total_module_size != TARGET_NO_FIELD)) + *((grub_uint32_t *) (kernel_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + { + memmove (kernel_img + total_module_size, kernel_img, layout.kernel_size); + memset (kernel_img, 0, total_module_size); + } + + if (image_target->voidp_sizeof == 8) + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info64 *modinfo; + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo = (struct grub_module_info64 *) kernel_img; + else + modinfo = (struct grub_module_info64 *) (kernel_img + layout.kernel_size); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info64)); + modinfo->size = grub_host_to_target_addr (total_module_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset = sizeof (struct grub_module_info64); + else + offset = layout.kernel_size + sizeof (struct grub_module_info64); + } + else + { + /* Fill in the grub_module_info structure. */ + struct grub_module_info32 *modinfo; + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + modinfo = (struct grub_module_info32 *) kernel_img; + else + modinfo = (struct grub_module_info32 *) (kernel_img + layout.kernel_size); + modinfo->magic = grub_host_to_target32 (GRUB_MODULE_MAGIC); + modinfo->offset = grub_host_to_target_addr (sizeof (struct grub_module_info32)); + modinfo->size = grub_host_to_target_addr (total_module_size); + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + offset = sizeof (struct grub_module_info32); + else + offset = layout.kernel_size + sizeof (struct grub_module_info32); + } + + for (p = path_list; p; p = p->next) + { + struct grub_module_header *header; + size_t mod_size; + + mod_size = ALIGN_ADDR (grub_util_get_image_size (p->name)); + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_ELF); + header->size = grub_host_to_target32 (mod_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (p->name, kernel_img + offset); + offset += mod_size; + } + + { + size_t i; + for (i = 0; i < npubkeys; i++) + { + size_t curs; + struct grub_module_header *header; + + curs = grub_util_get_image_size (pubkey_paths[i]); + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_PUBKEY); + header->size = grub_host_to_target32 (curs + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (pubkey_paths[i], kernel_img + offset); + offset += ALIGN_ADDR (curs); + } + } + + if (memdisk_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_MEMDISK); + header->size = grub_host_to_target32 (memdisk_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (memdisk_path, kernel_img + offset); + offset += memdisk_size; + } + + if (dtb_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_DTB); + header->size = grub_host_to_target32 (dtb_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (dtb_path, kernel_img + offset); + offset += dtb_size; + } + + if (config_path) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_CONFIG); + header->size = grub_host_to_target32 (config_size + sizeof (*header)); + offset += sizeof (*header); + + grub_util_load_image (config_path, kernel_img + offset); + offset += config_size; + } + + if (prefix) + { + struct grub_module_header *header; + + header = (struct grub_module_header *) (kernel_img + offset); + header->type = grub_host_to_target32 (OBJ_TYPE_PREFIX); + header->size = grub_host_to_target32 (prefix_size + sizeof (*header)); + offset += sizeof (*header); + + grub_strcpy (kernel_img + offset, prefix); + offset += prefix_size; + } + + grub_util_info ("kernel_img=%p, kernel_size=0x%" GRUB_HOST_PRIxLONG_LONG, + kernel_img, + (unsigned long long) layout.kernel_size); + compress_kernel (image_target, kernel_img, layout.kernel_size + total_module_size, + &core_img, &core_size, comp); + free (kernel_img); + + grub_util_info ("the core size is 0x%" GRUB_HOST_PRIxLONG_LONG, + (unsigned long long) core_size); + + if (!(image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + && image_target->total_module_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (core_img + image_target->total_module_size)) + = grub_host_to_target32 (total_module_size); + + if (image_target->flags & PLATFORM_FLAGS_DECOMPRESSORS) + { + char *full_img; + size_t full_size; + char *decompress_path, *decompress_img; + const char *name; + + switch (comp) + { + case GRUB_COMPRESSION_XZ: + name = "xz_decompress.img"; + break; + case GRUB_COMPRESSION_LZMA: + name = "lzma_decompress.img"; + break; + case GRUB_COMPRESSION_NONE: + name = "none_decompress.img"; + break; + default: + grub_util_error (_("unknown compression %d"), comp); + } + + decompress_path = grub_util_get_path (dir, name); + decompress_size = grub_util_get_image_size (decompress_path); + decompress_img = grub_util_read_image (decompress_path); + + if ((image_target->id == IMAGE_I386_PC + || image_target->id == IMAGE_I386_PC_PXE + || image_target->id == IMAGE_I386_PC_ELTORITO) + && decompress_size > GRUB_KERNEL_I386_PC_LINK_ADDR - 0x8200) + grub_util_error ("%s", _("Decompressor is too big")); + + if (image_target->decompressor_compressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_compressed_size)) + = grub_host_to_target32 (core_size); + + if (image_target->decompressor_uncompressed_size != TARGET_NO_FIELD) + *((grub_uint32_t *) (decompress_img + + image_target->decompressor_uncompressed_size)) + = grub_host_to_target32 (layout.kernel_size + total_module_size); + + if (image_target->decompressor_uncompressed_addr != TARGET_NO_FIELD) + { + if (image_target->flags & PLATFORM_FLAGS_MODULES_BEFORE_KERNEL) + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr - total_module_size); + else + *((grub_uint32_t *) (decompress_img + image_target->decompressor_uncompressed_addr)) + = grub_host_to_target_addr (image_target->link_addr); + } + full_size = core_size + decompress_size; + + full_img = xmalloc (full_size); + + memcpy (full_img, decompress_img, decompress_size); + + memcpy (full_img + decompress_size, core_img, core_size); + + free (core_img); + core_img = full_img; + core_size = full_size; + free (decompress_img); + free (decompress_path); + } + + switch (image_target->id) + { + case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: + case IMAGE_I386_PC_ELTORITO: + if (GRUB_KERNEL_I386_PC_LINK_ADDR + core_size > 0x78000 + || (core_size > (0xffff << GRUB_DISK_SECTOR_BITS)) + || (layout.kernel_size + layout.bss_size + + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000)) + grub_util_error (_("core image is too big (0x%x > 0x%x)"), + GRUB_KERNEL_I386_PC_LINK_ADDR + (unsigned) core_size, + 0x78000); + /* fallthrough */ + case IMAGE_COREBOOT: + case IMAGE_QEMU: + if (image_target->elf_target != EM_ARM && layout.kernel_size + layout.bss_size + GRUB_KERNEL_I386_PC_LINK_ADDR > 0x68000) + grub_util_error (_("kernel image is too big (0x%x > 0x%x)"), + (unsigned) layout.kernel_size + (unsigned) layout.bss_size + + GRUB_KERNEL_I386_PC_LINK_ADDR, + 0x68000); + break; + case IMAGE_LOONGSON_ELF: + case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: + case IMAGE_EFI: + case IMAGE_MIPS_ARC: + case IMAGE_QEMU_MIPS_FLASH: + case IMAGE_XEN: + case IMAGE_XEN_PVH: + break; + case IMAGE_SPARC64_AOUT: + case IMAGE_SPARC64_RAW: + case IMAGE_SPARC64_CDCORE: + case IMAGE_I386_IEEE1275: + case IMAGE_PPC: + case IMAGE_UBOOT: + break; + } + + switch (image_target->id) + { + case IMAGE_I386_PC: + case IMAGE_I386_PC_PXE: + case IMAGE_I386_PC_ELTORITO: + { + unsigned num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + if (image_target->id == IMAGE_I386_PC_PXE) + { + char *pxeboot_path, *pxeboot_img; + size_t pxeboot_size; + grub_uint32_t *ptr; + + pxeboot_path = grub_util_get_path (dir, "pxeboot.img"); + pxeboot_size = grub_util_get_image_size (pxeboot_path); + pxeboot_img = grub_util_read_image (pxeboot_path); + + grub_util_write_image (pxeboot_img, pxeboot_size, out, + outname); + free (pxeboot_img); + free (pxeboot_path); + + /* Remove Multiboot header to avoid confusing ipxe. */ + for (ptr = (grub_uint32_t *) core_img; + ptr < (grub_uint32_t *) (core_img + MULTIBOOT_SEARCH); ptr++) + if (*ptr == grub_host_to_target32 (MULTIBOOT_HEADER_MAGIC) + && grub_target_to_host32 (ptr[0]) + + grub_target_to_host32 (ptr[1]) + + grub_target_to_host32 (ptr[2]) == 0) + { + *ptr = 0; + break; + } + } + + if (image_target->id == IMAGE_I386_PC_ELTORITO) + { + char *eltorito_path, *eltorito_img; + size_t eltorito_size; + + eltorito_path = grub_util_get_path (dir, "cdboot.img"); + eltorito_size = grub_util_get_image_size (eltorito_path); + eltorito_img = grub_util_read_image (eltorito_path); + + grub_util_write_image (eltorito_img, eltorito_size, out, + outname); + free (eltorito_img); + free (eltorito_path); + } + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); + + boot_img = grub_util_read_image (boot_path); + + { + struct grub_pc_bios_boot_blocklist *block; + block = (struct grub_pc_bios_boot_blocklist *) (boot_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*block)); + block->len = grub_host_to_target16 (num); + + /* This is filled elsewhere. Verify it just in case. */ + assert (block->segment + == grub_host_to_target16 (GRUB_BOOT_I386_PC_KERNEL_SEG + + (GRUB_DISK_SECTOR_SIZE >> 4))); + } + + grub_util_write_image (boot_img, boot_size, out, outname); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_EFI: + { + void *pe_img; + grub_uint8_t *header; + void *sections; + size_t pe_size; + struct grub_pe32_coff_header *c; + struct grub_pe32_section_table *text_section, *data_section; + struct grub_pe32_section_table *mods_section, *reloc_section; + static const grub_uint8_t stub[] = GRUB_PE32_MSDOS_STUB; + int header_size; + int reloc_addr; + + if (image_target->voidp_sizeof == 4) + header_size = EFI32_HEADER_SIZE; + else + header_size = EFI64_HEADER_SIZE; + + reloc_addr = ALIGN_UP (header_size + core_size, + GRUB_PE32_FILE_ALIGNMENT); + + pe_size = ALIGN_UP (reloc_addr + layout.reloc_size, + GRUB_PE32_FILE_ALIGNMENT); + pe_img = xmalloc (reloc_addr + layout.reloc_size); + memset (pe_img, 0, header_size); + memcpy ((char *) pe_img + header_size, core_img, core_size); + memset ((char *) pe_img + header_size + core_size, 0, reloc_addr - (header_size + core_size)); + memcpy ((char *) pe_img + reloc_addr, layout.reloc_section, layout.reloc_size); + header = pe_img; + + /* The magic. */ + memcpy (header, stub, GRUB_PE32_MSDOS_STUB_SIZE); + memcpy (header + GRUB_PE32_MSDOS_STUB_SIZE, "PE\0\0", + GRUB_PE32_SIGNATURE_SIZE); + + /* The COFF file header. */ + c = (struct grub_pe32_coff_header *) (header + GRUB_PE32_MSDOS_STUB_SIZE + + GRUB_PE32_SIGNATURE_SIZE); + c->machine = grub_host_to_target16 (image_target->pe_target); + + c->num_sections = grub_host_to_target16 (4); + c->time = grub_host_to_target32 (STABLE_EMBEDDING_TIMESTAMP); + c->characteristics = grub_host_to_target16 (GRUB_PE32_EXECUTABLE_IMAGE + | GRUB_PE32_LINE_NUMS_STRIPPED + | ((image_target->voidp_sizeof == 4) + ? GRUB_PE32_32BIT_MACHINE + : 0) + | GRUB_PE32_LOCAL_SYMS_STRIPPED + | GRUB_PE32_DEBUG_STRIPPED); + + /* The PE Optional header. */ + if (image_target->voidp_sizeof == 4) + { + struct grub_pe32_optional_header *o; + + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe32_optional_header)); + + o = (struct grub_pe32_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC); + o->code_size = grub_host_to_target32 (layout.exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size + - header_size); + o->bss_size = grub_cpu_to_le32 (layout.bss_size); + o->entry_addr = grub_cpu_to_le32 (layout.start_address); + o->code_base = grub_cpu_to_le32 (header_size); + + o->data_base = grub_host_to_target32 (header_size + layout.exec_size); + + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target32 (0x10000); + o->stack_commit_size = grub_host_to_target32 (0x10000); + o->heap_reserve_size = grub_host_to_target32 (0x10000); + o->heap_commit_size = grub_host_to_target32 (0x10000); + + o->num_data_directories = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size); + sections = o + 1; + } + else + { + struct grub_pe64_optional_header *o; + + c->optional_header_size = grub_host_to_target16 (sizeof (struct grub_pe64_optional_header)); + + o = (struct grub_pe64_optional_header *) + (header + GRUB_PE32_MSDOS_STUB_SIZE + GRUB_PE32_SIGNATURE_SIZE + + sizeof (struct grub_pe32_coff_header)); + o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC); + o->code_size = grub_host_to_target32 (layout.exec_size); + o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size + - header_size); + o->bss_size = grub_cpu_to_le32 (layout.bss_size); + o->entry_addr = grub_cpu_to_le32 (layout.start_address); + o->code_base = grub_cpu_to_le32 (header_size); + o->image_base = 0; + o->section_alignment = grub_host_to_target32 (image_target->section_align); + o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT); + o->image_size = grub_host_to_target32 (pe_size); + o->header_size = grub_host_to_target32 (header_size); + o->subsystem = grub_host_to_target16 (GRUB_PE32_SUBSYSTEM_EFI_APPLICATION); + + /* Do these really matter? */ + o->stack_reserve_size = grub_host_to_target64 (0x10000); + o->stack_commit_size = grub_host_to_target64 (0x10000); + o->heap_reserve_size = grub_host_to_target64 (0x10000); + o->heap_commit_size = grub_host_to_target64 (0x10000); + + o->num_data_directories + = grub_host_to_target32 (GRUB_PE32_NUM_DATA_DIRECTORIES); + + o->base_relocation_table.rva = grub_host_to_target32 (reloc_addr); + o->base_relocation_table.size = grub_host_to_target32 (layout.reloc_size); + sections = o + 1; + } + /* The sections. */ + text_section = sections; + strcpy (text_section->name, ".text"); + text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size); + text_section->virtual_address = grub_cpu_to_le32 (header_size); + text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size); + text_section->raw_data_offset = grub_cpu_to_le32 (header_size); + text_section->characteristics = grub_cpu_to_le32_compile_time ( + GRUB_PE32_SCN_CNT_CODE + | GRUB_PE32_SCN_MEM_EXECUTE + | GRUB_PE32_SCN_MEM_READ); + + data_section = text_section + 1; + strcpy (data_section->name, ".data"); + data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size); + data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size); + data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size); + data_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.exec_size); + data_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + +#if 0 + bss_section = data_section + 1; + strcpy (bss_section->name, ".bss"); + bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size); + bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size); + bss_section->raw_data_size = 0; + bss_section->raw_data_offset = 0; + bss_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE + | GRUB_PE32_SCN_ALIGN_64BYTES + | GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | 0x80); +#endif + + mods_section = data_section + 1; + strcpy (mods_section->name, "mods"); + mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size); + mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size); + mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size); + mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.kernel_size); + mods_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_READ + | GRUB_PE32_SCN_MEM_WRITE); + + reloc_section = mods_section + 1; + strcpy (reloc_section->name, ".reloc"); + reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size); + reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size); + reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size); + reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr); + reloc_section->characteristics + = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA + | GRUB_PE32_SCN_MEM_DISCARDABLE + | GRUB_PE32_SCN_MEM_READ); + free (core_img); + core_img = pe_img; + core_size = pe_size; + } + break; + case IMAGE_QEMU: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + + boot_path = grub_util_get_path (dir, "boot.img"); + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); + + /* Rom sizes must be 64k-aligned. */ + rom_size = ALIGN_UP (core_size + boot_size, 64 * 1024); + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + *((grub_int32_t *) (core_img + GRUB_KERNEL_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img, core_img, core_size); + + *((grub_int32_t *) (boot_img + GRUB_BOOT_I386_QEMU_CORE_ENTRY_ADDR)) + = grub_host_to_target32 ((grub_uint32_t) -rom_size); + + memcpy (rom_img + rom_size - boot_size, boot_img, boot_size); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_AOUT: + { + void *aout_img; + size_t aout_size; + struct grub_aout32_header *aout_head; + + aout_size = core_size + sizeof (*aout_head); + aout_img = xmalloc (aout_size); + aout_head = aout_img; + grub_memset (aout_head, 0, sizeof (*aout_head)); + aout_head->a_midmag = grub_host_to_target32 ((AOUT_MID_SUN << 16) + | AOUT32_OMAGIC); + aout_head->a_text = grub_host_to_target32 (core_size); + aout_head->a_entry + = grub_host_to_target32 (GRUB_BOOT_SPARC64_IEEE1275_IMAGE_ADDRESS); + memcpy ((char *) aout_img + sizeof (*aout_head), core_img, core_size); + + free (core_img); + core_img = aout_img; + core_size = aout_size; + } + break; + case IMAGE_SPARC64_RAW: + { + unsigned int num; + char *boot_path, *boot_img; + size_t boot_size; + + num = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS); + num <<= GRUB_DISK_SECTOR_BITS; + + boot_path = grub_util_get_path (dir, "diskboot.img"); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("diskboot.img size must be %u bytes"), + GRUB_DISK_SECTOR_SIZE); + + boot_img = grub_util_read_image (boot_path); + + *((grub_uint32_t *) (boot_img + GRUB_DISK_SECTOR_SIZE + - GRUB_BOOT_SPARC64_IEEE1275_LIST_SIZE + 8)) + = grub_host_to_target32 (num); + + grub_util_write_image (boot_img, boot_size, out, outname); + free (boot_img); + free (boot_path); + } + break; + case IMAGE_SPARC64_CDCORE: + break; + case IMAGE_YEELOONG_FLASH: + case IMAGE_FULOONG2F_FLASH: + { + char *rom_img; + size_t rom_size; + char *boot_path, *boot_img; + size_t boot_size; + /* fwstart.img is the only part which can't be tested by using *-elf + target. Check it against the checksum. */ + const grub_uint8_t yeeloong_fwstart_good_hash[512 / 8] = + { + 0x5f, 0x67, 0x46, 0x57, 0x31, 0x30, 0xc5, 0x0a, + 0xe9, 0x98, 0x18, 0xc9, 0xf3, 0xca, 0x45, 0xa5, + 0x75, 0x64, 0x6b, 0xbb, 0x24, 0xcd, 0xb4, 0xbc, + 0xf2, 0x3e, 0x23, 0xf9, 0xc2, 0x6a, 0x8c, 0xde, + 0x3b, 0x94, 0x9c, 0xcc, 0xa5, 0xa7, 0x58, 0xb1, + 0xbe, 0x8b, 0x3d, 0x73, 0x98, 0x18, 0x7e, 0x68, + 0x5e, 0x5f, 0x23, 0x7d, 0x7a, 0xe8, 0x51, 0xf7, + 0x1a, 0xaf, 0x2f, 0x54, 0x11, 0x2e, 0x5c, 0x25 + }; + const grub_uint8_t fuloong2f_fwstart_good_hash[512 / 8] = + { + 0x76, 0x9b, 0xad, 0x6e, 0xa2, 0x39, 0x47, 0x62, + 0x1f, 0xc9, 0x3a, 0x6d, 0x05, 0x5c, 0x43, 0x5c, + 0x29, 0x4a, 0x7e, 0x08, 0x2a, 0x31, 0x8f, 0x5d, + 0x02, 0x84, 0xa0, 0x85, 0xf2, 0xd1, 0xb9, 0x53, + 0xa2, 0xbc, 0xf2, 0xe1, 0x39, 0x1e, 0x51, 0xb5, + 0xaf, 0xec, 0x9e, 0xf2, 0xf1, 0xf3, 0x0a, 0x2f, + 0xe6, 0xf1, 0x08, 0x89, 0xbe, 0xbc, 0x73, 0xab, + 0x46, 0x50, 0xd6, 0x21, 0xce, 0x8e, 0x24, 0xa7 + }; + const grub_uint8_t *fwstart_good_hash; + grub_uint8_t fwstart_hash[512 / 8]; + + if (image_target->id == IMAGE_FULOONG2F_FLASH) + { + fwstart_good_hash = fuloong2f_fwstart_good_hash; + boot_path = grub_util_get_path (dir, "fwstart_fuloong2f.img"); + } + else + { + fwstart_good_hash = yeeloong_fwstart_good_hash; + boot_path = grub_util_get_path (dir, "fwstart.img"); + } + + boot_size = grub_util_get_image_size (boot_path); + boot_img = grub_util_read_image (boot_path); + + grub_crypto_hash (GRUB_MD_SHA512, fwstart_hash, boot_img, boot_size); + + if (grub_memcmp (fwstart_hash, fwstart_good_hash, + GRUB_MD_SHA512->mdlen) != 0) + /* TRANSLATORS: fwstart.img may still be good, just it wasn't checked. */ + grub_util_warn ("%s", + _("fwstart.img doesn't match the known good version. " + "proceed at your own risk")); + + if (core_size + boot_size > 512 * 1024) + grub_util_error ("%s", _("firmware image is too big")); + rom_size = 512 * 1024; + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + memcpy (rom_img, boot_img, boot_size); + + memcpy (rom_img + boot_size, core_img, core_size); + + memset (rom_img + boot_size + core_size, 0, + rom_size - (boot_size + core_size)); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + free (boot_img); + free (boot_path); + } + break; + case IMAGE_QEMU_MIPS_FLASH: + { + char *rom_img; + size_t rom_size; + + if (core_size > 512 * 1024) + grub_util_error ("%s", _("firmware image is too big")); + rom_size = 512 * 1024; + + rom_img = xmalloc (rom_size); + memset (rom_img, 0, rom_size); + + memcpy (rom_img, core_img, core_size); + + memset (rom_img + core_size, 0, + rom_size - core_size); + + free (core_img); + core_img = rom_img; + core_size = rom_size; + } + break; + + case IMAGE_UBOOT: + { + struct grub_uboot_image_header *hdr; + + hdr = xmalloc (core_size + sizeof (struct grub_uboot_image_header)); + memcpy (hdr + 1, core_img, core_size); + + memset (hdr, 0, sizeof (*hdr)); + hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC); + hdr->ih_time = grub_cpu_to_be32 (STABLE_EMBEDDING_TIMESTAMP); + hdr->ih_size = grub_cpu_to_be32 (core_size); + hdr->ih_load = 0; + hdr->ih_ep = 0; + hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL_NOLOAD; + hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX; + hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM; + hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE; + + grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_dcrc, hdr + 1, core_size); + grub_crypto_hash (GRUB_MD_CRC32, &hdr->ih_hcrc, hdr, sizeof (*hdr)); + + free (core_img); + core_img = (char *) hdr; + core_size += sizeof (struct grub_uboot_image_header); + } + break; + + case IMAGE_MIPS_ARC: + { + char *ecoff_img; + struct ecoff_header { + grub_uint16_t magic; + grub_uint16_t nsec; + grub_uint32_t time; + grub_uint32_t syms; + grub_uint32_t nsyms; + grub_uint16_t opt; + grub_uint16_t flags; + grub_uint16_t magic2; + grub_uint16_t version; + grub_uint32_t textsize; + grub_uint32_t datasize; + grub_uint32_t bsssize; + grub_uint32_t entry; + grub_uint32_t text_start; + grub_uint32_t data_start; + grub_uint32_t bss_start; + grub_uint32_t gprmask; + grub_uint32_t cprmask[4]; + grub_uint32_t gp_value; + }; + struct ecoff_section + { + char name[8]; + grub_uint32_t paddr; + grub_uint32_t vaddr; + grub_uint32_t size; + grub_uint32_t file_offset; + grub_uint32_t reloc; + grub_uint32_t gp; + grub_uint16_t nreloc; + grub_uint16_t ngp; + grub_uint32_t flags; + }; + struct ecoff_header *head; + struct ecoff_section *section; + grub_uint32_t target_addr; + size_t program_size; + + program_size = ALIGN_ADDR (core_size); + if (comp == GRUB_COMPRESSION_NONE) + target_addr = (image_target->link_addr - decompress_size); + else + target_addr = ALIGN_UP (image_target->link_addr + + layout.kernel_size + total_module_size, 32); + + ecoff_img = xmalloc (program_size + sizeof (*head) + sizeof (*section)); + grub_memset (ecoff_img, 0, program_size + sizeof (*head) + sizeof (*section)); + head = (void *) ecoff_img; + section = (void *) (head + 1); + head->magic = image_target->bigendian ? grub_host_to_target16 (0x160) + : grub_host_to_target16 (0x166); + head->nsec = grub_host_to_target16 (1); + head->time = grub_host_to_target32 (0); + head->opt = grub_host_to_target16 (0x38); + head->flags = image_target->bigendian + ? grub_host_to_target16 (0x207) + : grub_host_to_target16 (0x103); + head->magic2 = grub_host_to_target16 (0x107); + head->textsize = grub_host_to_target32 (program_size); + head->entry = grub_host_to_target32 (target_addr); + head->text_start = grub_host_to_target32 (target_addr); + head->data_start = grub_host_to_target32 (target_addr + program_size); + grub_memcpy (section->name, ".text", sizeof (".text") - 1); + section->vaddr = grub_host_to_target32 (target_addr); + section->size = grub_host_to_target32 (program_size); + section->file_offset = grub_host_to_target32 (sizeof (*head) + sizeof (*section)); + if (!image_target->bigendian) + { + section->paddr = grub_host_to_target32 (0xaa60); + section->flags = grub_host_to_target32 (0x20); + } + memcpy (section + 1, core_img, core_size); + free (core_img); + core_img = ecoff_img; + core_size = program_size + sizeof (*head) + sizeof (*section); + } + break; + case IMAGE_LOONGSON_ELF: + case IMAGE_PPC: + case IMAGE_XEN: + case IMAGE_XEN_PVH: + case IMAGE_COREBOOT: + case IMAGE_I386_IEEE1275: + { + grub_uint64_t target_addr; + if (image_target->id == IMAGE_LOONGSON_ELF) + { + if (comp == GRUB_COMPRESSION_NONE) + target_addr = (image_target->link_addr - decompress_size); + else + target_addr = ALIGN_UP (image_target->link_addr + + layout.kernel_size + total_module_size, 32); + } + else + target_addr = image_target->link_addr; + if (image_target->voidp_sizeof == 4) + grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size, + target_addr, &layout); + else + grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size, + target_addr, &layout); + } + break; + } + + grub_util_write_image (core_img, core_size, out, outname); + free (core_img); + free (kernel_path); + free (layout.reloc_section); + + grub_util_free_path_list (path_list); +} diff --git a/GRUB2/MOD_SRC/grub-2.04/util/setup.c b/GRUB2/MOD_SRC/grub-2.04/util/setup.c new file mode 100644 index 00000000..5d1c3e23 --- /dev/null +++ b/GRUB2/MOD_SRC/grub-2.04/util/setup.c @@ -0,0 +1,878 @@ +/* grub-setup.c - make GRUB usable */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011 Free Software Foundation, Inc. + * + * GRUB 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. + * + * GRUB 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 GRUB. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef GRUB_SETUP_SPARC64 +#include +#include +#include +#else +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "progname.h" +#include +#include +#include +#include +#include + +#include + +/* On SPARC this program fills in various fields inside of the 'boot' and 'core' + * image files. + * + * The 'boot' image needs to know the OBP path name of the root + * device. It also needs to know the initial block number of + * 'core' (which is 'diskboot' concatenated with 'kernel' and + * all the modules, this is created by grub-mkimage). This resulting + * 'boot' image is 512 bytes in size and is placed in the second block + * of a partition. + * + * The initial 'diskboot' block acts as a loader for the actual GRUB + * kernel. It contains the loading code and then a block list. + * + * The block list of 'core' starts at the end of the 'diskboot' image + * and works it's way backwards towards the end of the code of 'diskboot'. + * + * We patch up the images with the necessary values and write out the + * result. + */ + +#ifdef GRUB_SETUP_SPARC64 +#define grub_target_to_host16(x) grub_be_to_cpu16(x) +#define grub_target_to_host32(x) grub_be_to_cpu32(x) +#define grub_target_to_host64(x) grub_be_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_be16(x) +#define grub_host_to_target32(x) grub_cpu_to_be32(x) +#define grub_host_to_target64(x) grub_cpu_to_be64(x) +#elif defined (GRUB_SETUP_BIOS) +#define grub_target_to_host16(x) grub_le_to_cpu16(x) +#define grub_target_to_host32(x) grub_le_to_cpu32(x) +#define grub_target_to_host64(x) grub_le_to_cpu64(x) +#define grub_host_to_target16(x) grub_cpu_to_le16(x) +#define grub_host_to_target32(x) grub_cpu_to_le32(x) +#define grub_host_to_target64(x) grub_cpu_to_le64(x) +#else +#error Complete this +#endif + +static void +write_rootdev (grub_device_t root_dev, + char *boot_img, grub_uint64_t first_sector) +{ +#ifdef GRUB_SETUP_BIOS + { + grub_uint8_t *boot_drive; + void *kernel_sector; + boot_drive = (grub_uint8_t *) (boot_img + GRUB_BOOT_MACHINE_BOOT_DRIVE); + kernel_sector = (boot_img + GRUB_BOOT_MACHINE_KERNEL_SECTOR); + + /* FIXME: can this be skipped? */ + *boot_drive = 0xFF; + + grub_set_unaligned64 (kernel_sector, grub_cpu_to_le64 (first_sector)); + } +#endif +#ifdef GRUB_SETUP_SPARC64 + { + void *kernel_byte; + kernel_byte = (boot_img + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_KERNEL_BYTE); + grub_set_unaligned64 (kernel_byte, + grub_cpu_to_be64 (first_sector << GRUB_DISK_SECTOR_BITS)); + } +#endif +} + +#ifdef GRUB_SETUP_SPARC64 +#define BOOT_SECTOR 1 +#else +#define BOOT_SECTOR 0 +#endif + +/* Helper for setup. */ + +struct blocklists +{ + struct grub_boot_blocklist *first_block, *block; +#ifdef GRUB_SETUP_BIOS + grub_uint16_t current_segment; +#endif +#ifdef GRUB_SETUP_SPARC64 + grub_uint64_t gpt_offset; +#endif + grub_uint16_t last_length; + grub_disk_addr_t first_sector; +}; + +/* Helper for setup. */ +static void +save_blocklists (grub_disk_addr_t sector, unsigned offset, unsigned length, + void *data) +{ + struct blocklists *bl = data; + struct grub_boot_blocklist *prev = bl->block + 1; + grub_uint64_t seclen; + +#ifdef GRUB_SETUP_SPARC64 + sector -= bl->gpt_offset; +#endif + + grub_util_info ("saving <%" GRUB_HOST_PRIuLONG_LONG ",%u,%u>", + (unsigned long long) sector, offset, length); + + if (bl->first_sector == (grub_disk_addr_t) -1) + { + if (offset != 0 || length < GRUB_DISK_SECTOR_SIZE) + grub_util_error ("%s", _("the first sector of the core file is not sector-aligned")); + + bl->first_sector = sector; + sector++; + length -= GRUB_DISK_SECTOR_SIZE; + if (!length) + return; + } + + if (offset != 0 || bl->last_length != 0) + grub_util_error ("%s", _("non-sector-aligned data is found in the core file")); + + seclen = (length + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS; + + if (bl->block != bl->first_block + && (grub_target_to_host64 (prev->start) + + grub_target_to_host16 (prev->len)) == sector) + { + grub_uint16_t t = grub_target_to_host16 (prev->len); + t += seclen; + prev->len = grub_host_to_target16 (t); + } + else + { + bl->block->start = grub_host_to_target64 (sector); + bl->block->len = grub_host_to_target16 (seclen); +#ifdef GRUB_SETUP_BIOS + bl->block->segment = grub_host_to_target16 (bl->current_segment); +#endif + + bl->block--; + if (bl->block->len) + grub_util_error ("%s", _("the sectors of the core file are too fragmented")); + } + + bl->last_length = length & (GRUB_DISK_SECTOR_SIZE - 1); +#ifdef GRUB_SETUP_BIOS + bl->current_segment += seclen << (GRUB_DISK_SECTOR_BITS - 4); +#endif +} + +/* Context for setup/identify_partmap. */ +struct identify_partmap_ctx +{ + grub_partition_map_t dest_partmap; + grub_partition_t container; + int multiple_partmaps; +}; + +/* Helper for setup. + Unlike root_dev, with dest_dev we're interested in the partition map even + if dest_dev itself is a whole disk. */ +static int +identify_partmap (grub_disk_t disk __attribute__ ((unused)), + const grub_partition_t p, void *data) +{ + struct identify_partmap_ctx *ctx = data; + + if (p->parent != ctx->container) + return 0; + /* NetBSD and OpenBSD subpartitions have metadata inside a partition, + so they are safe to ignore. + */ + if (grub_strcmp (p->partmap->name, "netbsd") == 0 + || grub_strcmp (p->partmap->name, "openbsd") == 0) + return 0; + if (ctx->dest_partmap == NULL) + { + ctx->dest_partmap = p->partmap; + return 0; + } + if (ctx->dest_partmap == p->partmap) + return 0; + ctx->multiple_partmaps = 1; + return 1; +} + +#ifdef GRUB_SETUP_BIOS +#define SETUP grub_util_bios_setup +#elif GRUB_SETUP_SPARC64 +#define SETUP grub_util_sparc_setup +#else +#error "Shouldn't happen" +#endif + +void +SETUP (const char *dir, + const char *boot_file, const char *core_file, + const char *dest, int force, + int fs_probe, int allow_floppy, + int add_rs_codes __attribute__ ((unused))) /* unused on sparc64 */ +{ + char *core_path; + char *boot_img, *core_img, *boot_path; + char *root = 0; + size_t boot_size, core_size; + grub_uint16_t core_sectors; + grub_device_t root_dev = 0, dest_dev, core_dev; + grub_util_fd_t fp; + struct blocklists bl; + + bl.first_sector = (grub_disk_addr_t) -1; + +#ifdef GRUB_SETUP_BIOS + bl.current_segment = + GRUB_BOOT_I386_PC_KERNEL_SEG + (GRUB_DISK_SECTOR_SIZE >> 4); +#endif + bl.last_length = 0; + + /* Read the boot image by the OS service. */ + boot_path = grub_util_get_path (dir, boot_file); + boot_size = grub_util_get_image_size (boot_path); + if (boot_size != GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is not %u"), + boot_path, GRUB_DISK_SECTOR_SIZE); + boot_img = grub_util_read_image (boot_path); + free (boot_path); + + core_path = grub_util_get_path (dir, core_file); + core_size = grub_util_get_image_size (core_path); + core_sectors = ((core_size + GRUB_DISK_SECTOR_SIZE - 1) + >> GRUB_DISK_SECTOR_BITS); + if (core_size < GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is too small"), core_path); +#ifdef GRUB_SETUP_BIOS + if (core_size > 0xFFFF * GRUB_DISK_SECTOR_SIZE) + grub_util_error (_("the size of `%s' is too large"), core_path); +#endif + + core_img = grub_util_read_image (core_path); + + /* Have FIRST_BLOCK to point to the first blocklist. */ + bl.first_block = (struct grub_boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*bl.block)); + + grub_util_info ("Opening dest `%s'", dest); + dest_dev = grub_device_open (dest); + if (! dest_dev) + grub_util_error ("%s", grub_errmsg); + + core_dev = dest_dev; + + { + char **root_devices = grub_guess_root_devices (dir); + char **cur; + int found = 0; + + if (!root_devices) + grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), dir); + + for (cur = root_devices; *cur; cur++) + { + char *drive; + grub_device_t try_dev; + + drive = grub_util_get_grub_dev (*cur); + if (!drive) + continue; + try_dev = grub_device_open (drive); + if (! try_dev) + { + free (drive); + continue; + } + if (!found && try_dev->disk->id == dest_dev->disk->id + && try_dev->disk->dev->id == dest_dev->disk->dev->id) + { + if (root_dev) + grub_device_close (root_dev); + free (root); + root_dev = try_dev; + root = drive; + found = 1; + continue; + } + if (!root_dev) + { + root_dev = try_dev; + root = drive; + continue; + } + grub_device_close (try_dev); + free (drive); + } + if (!root_dev) + { + root = grub_util_get_grub_dev ("/dev/sda"); + root_dev = grub_device_open (root); + if (root_dev) + grub_util_info ("guessing the root device failed, because of `%s'", grub_errmsg); + else + grub_util_error ("guessing the root device failed, because of `%s'", grub_errmsg); + } + grub_util_info ("guessed root_dev `%s' from " + "dir `%s'", root_dev->disk->name, dir); + + for (cur = root_devices; *cur; cur++) + free (*cur); + free (root_devices); + } + + grub_util_info ("setting the root device to `%s'", root); + if (grub_env_set ("root", root) != GRUB_ERR_NONE) + grub_util_error ("%s", grub_errmsg); + + { +#ifdef GRUB_SETUP_BIOS + char *tmp_img; + grub_uint8_t *boot_drive_check; + + /* Read the original sector from the disk. */ + tmp_img = xmalloc (GRUB_DISK_SECTOR_SIZE); + if (grub_disk_read (dest_dev->disk, 0, 0, GRUB_DISK_SECTOR_SIZE, tmp_img)) + grub_util_error ("%s", grub_errmsg); + + boot_drive_check = (grub_uint8_t *) (boot_img + + GRUB_BOOT_MACHINE_DRIVE_CHECK); + /* Copy the possible DOS BPB. */ + memcpy (boot_img + GRUB_BOOT_MACHINE_BPB_START, + tmp_img + GRUB_BOOT_MACHINE_BPB_START, + GRUB_BOOT_MACHINE_BPB_END - GRUB_BOOT_MACHINE_BPB_START); + + /* If DEST_DRIVE is a hard disk, enable the workaround, which is + for buggy BIOSes which don't pass boot drive correctly. Instead, + they pass 0x00 or 0x01 even when booted from 0x80. */ + if (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk)) + { + /* Replace the jmp (2 bytes) with double nop's. */ + boot_drive_check[0] = 0x90; + boot_drive_check[1] = 0x90; + } +#endif + + struct identify_partmap_ctx ctx = { + .dest_partmap = NULL, + .container = dest_dev->disk->partition, + .multiple_partmaps = 0 + }; + int is_ldm; + grub_err_t err; + grub_disk_addr_t *sectors; + int i; + grub_fs_t fs; + unsigned int nsec, maxsec; + + grub_partition_iterate (dest_dev->disk, identify_partmap, &ctx); + +#ifdef GRUB_SETUP_BIOS + /* Copy the partition table. */ + if (ctx.dest_partmap || + (!allow_floppy && !grub_util_biosdisk_is_floppy (dest_dev->disk))) + memcpy (boot_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + tmp_img + GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC, + GRUB_BOOT_MACHINE_PART_END - GRUB_BOOT_MACHINE_WINDOWS_NT_MAGIC); + + free (tmp_img); +#endif + + if (ctx.container + && grub_strcmp (ctx.container->partmap->name, "msdos") == 0 + && ctx.dest_partmap + && (ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_NETBSD + || ctx.container->msdostype == GRUB_PC_PARTITION_TYPE_OPENBSD)) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet.")); + goto unable_to_embed; + } + + fs = grub_fs_probe (dest_dev); + if (!fs) + grub_errno = GRUB_ERR_NONE; + + is_ldm = grub_util_is_ldm (dest_dev->disk); + + if (fs_probe) + { + if (!fs && !ctx.dest_partmap) + grub_util_error (_("unable to identify a filesystem in %s; safety check can't be performed"), + dest_dev->disk->name); + if (fs && !fs->reserved_first_sector) + /* TRANSLATORS: Filesystem may reserve the space just GRUB isn't sure about it. */ + grub_util_error (_("%s appears to contain a %s filesystem which isn't known to " + "reserve space for DOS-style boot. Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), dest_dev->disk->name, fs->name); + + if (ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0 + && strcmp (ctx.dest_partmap->name, "gpt") != 0 + && strcmp (ctx.dest_partmap->name, "bsd") != 0 + && strcmp (ctx.dest_partmap->name, "netbsd") != 0 + && strcmp (ctx.dest_partmap->name, "openbsd") != 0 + && strcmp (ctx.dest_partmap->name, "sunpc") != 0) + /* TRANSLATORS: Partition map may reserve the space just GRUB isn't sure about it. */ + grub_util_error (_("%s appears to contain a %s partition map which isn't known to " + "reserve space for DOS-style boot. Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), dest_dev->disk->name, ctx.dest_partmap->name); + if (is_ldm && ctx.dest_partmap && strcmp (ctx.dest_partmap->name, "msdos") != 0 + && strcmp (ctx.dest_partmap->name, "gpt") != 0) + grub_util_error (_("%s appears to contain a %s partition map and " + "LDM which isn't known to be a safe combination." + " Installing GRUB there could " + "result in FILESYSTEM DESTRUCTION if valuable data" + " is overwritten " + "by grub-setup (--skip-fs-probe disables this " + "check, use at your own risk)"), + dest_dev->disk->name, ctx.dest_partmap->name); + + } + + if (! ctx.dest_partmap && ! fs && !is_ldm) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea.")); + goto unable_to_embed; + } + if (ctx.multiple_partmaps || (ctx.dest_partmap && fs) || (is_ldm && fs)) + { + grub_util_warn ("%s", _("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet.")); + goto unable_to_embed; + } + + if (ctx.dest_partmap && !ctx.dest_partmap->embed) + { + grub_util_warn (_("Partition style `%s' doesn't support embedding"), + ctx.dest_partmap->name); + goto unable_to_embed; + } + + if (fs && !fs->fs_embed) + { + grub_util_warn (_("File system `%s' doesn't support embedding"), + fs->name); + goto unable_to_embed; + } + + nsec = core_sectors; + + if (add_rs_codes) + maxsec = 2 * core_sectors; + else + maxsec = core_sectors; + +#ifdef GRUB_SETUP_BIOS + if (maxsec > ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS)) + maxsec = ((0x78000 - GRUB_KERNEL_I386_PC_LINK_ADDR) + >> GRUB_DISK_SECTOR_BITS); +#endif + +#ifdef GRUB_SETUP_SPARC64 + /* + * On SPARC we need two extra. One is because we are combining the + * core.img with the boot.img. The other is because the boot sector + * starts at 1. + */ + nsec += 2; + maxsec += 2; +#endif + + if (is_ldm) + err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + else if (ctx.dest_partmap) + err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + else + err = fs->fs_embed (dest_dev, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + if (!err && nsec < core_sectors) + { + err = grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("Your embedding area is unusually small. " + "core.img won't fit in it.")); + } + + if (err) + { + grub_util_warn ("%s", grub_errmsg); + grub_errno = GRUB_ERR_NONE; + goto unable_to_embed; + } + + assert (nsec <= maxsec); + + /* Clean out the blocklists. */ + bl.block = bl.first_block; + while (bl.block->len) + { + grub_memset (bl.block, 0, sizeof (*bl.block)); + + bl.block--; + + if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + + bl.block = bl.first_block; + for (i = 0; i < nsec; i++) + save_blocklists (sectors[i] + grub_partition_get_start (ctx.container), + 0, GRUB_DISK_SECTOR_SIZE, &bl); + + /* Make sure that the last blocklist is a terminator. */ + if (bl.block == bl.first_block) + bl.block--; + bl.block->start = 0; + bl.block->len = 0; +#ifdef GRUB_SETUP_BIOS + bl.block->segment = 0; +#endif + +#ifdef GRUB_SETUP_SPARC64 + { + /* + * On SPARC, the block-list entries need to be based off the beginning + * of the parition, not the beginning of the disk. + */ + struct grub_boot_blocklist *block; + block = bl.first_block; + + while (block->len) + { + block->start -= bl.first_sector; + block--; + } + } + + /* + * Reserve space for the boot block since it can not be in the + * Parition table on SPARC. + */ + assert (bl.first_block->len > 2); + bl.first_block->start += 2; + bl.first_block->len -= 2; + write_rootdev (root_dev, boot_img, sectors[BOOT_SECTOR + 1] - bl.first_sector); +#endif + +#ifdef GRUB_SETUP_BIOS + write_rootdev (root_dev, boot_img, bl.first_sector); +#endif + + /* Round up to the nearest sector boundary, and zero the extra memory */ + core_img = xrealloc (core_img, nsec * GRUB_DISK_SECTOR_SIZE); + assert (core_img && (nsec * GRUB_DISK_SECTOR_SIZE >= core_size)); + memset (core_img + core_size, 0, nsec * GRUB_DISK_SECTOR_SIZE - core_size); + + bl.first_block = (struct grub_boot_blocklist *) (core_img + + GRUB_DISK_SECTOR_SIZE + - sizeof (*bl.block)); +#if GRUB_SETUP_BIOS + grub_size_t no_rs_length; + no_rs_length = grub_target_to_host16 + (grub_get_unaligned16 (core_img + + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_I386_PC_NO_REED_SOLOMON_LENGTH)); + + if (no_rs_length == 0xffff) + grub_util_error ("%s", _("core.img version mismatch")); + + if (add_rs_codes) + { + grub_set_unaligned32 ((core_img + GRUB_DISK_SECTOR_SIZE + + GRUB_KERNEL_I386_PC_REED_SOLOMON_REDUNDANCY), + grub_host_to_target32 (nsec * GRUB_DISK_SECTOR_SIZE - core_size)); + + void *tmp = xmalloc (core_size); + grub_memcpy (tmp, core_img, core_size); + grub_reed_solomon_add_redundancy (core_img + no_rs_length + GRUB_DISK_SECTOR_SIZE, + core_size - no_rs_length - GRUB_DISK_SECTOR_SIZE, + nsec * GRUB_DISK_SECTOR_SIZE + - core_size); + assert (grub_memcmp (tmp, core_img, core_size) == 0); + free (tmp); + } + + /* Write the core image onto the disk. */ + for (i = 0; i < nsec; i++) + grub_disk_write (dest_dev->disk, sectors[i], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE); +#endif + +#ifdef GRUB_SETUP_SPARC64 + { + int isec = BOOT_SECTOR; + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, sectors[isec++], 0, + GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + + /* Write the core image onto the disk. */ + for (i = 0 ; isec < nsec; i++, isec++) + { + if (grub_disk_write (dest_dev->disk, sectors[isec], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE)) + grub_util_error ("%s", grub_errmsg); + } + } + +#endif + grub_free (sectors); + + goto finish; + } + +unable_to_embed: + + if (dest_dev->disk->dev->id != root_dev->disk->dev->id) + grub_util_error ("%s", _("embedding is not possible, but this is required for " + "RAID and LVM install")); + + { + grub_fs_t fs; + fs = grub_fs_probe (root_dev); + if (!fs) + grub_util_error (_("can't determine filesystem on %s"), root); + + if (!fs->blocklist_install) + grub_util_error (_("filesystem `%s' doesn't support blocklists"), + fs->name); + } + +#ifdef GRUB_SETUP_BIOS + if (dest_dev->disk->id != root_dev->disk->id + || dest_dev->disk->dev->id != root_dev->disk->dev->id) + /* TRANSLATORS: cross-disk refers to /boot being on one disk + but MBR on another. */ + grub_util_error ("%s", _("embedding is not possible, but this is required for " + "cross-disk install")); +#else + core_dev = root_dev; +#endif + + grub_util_warn ("%s", _("Embedding is not possible. GRUB can only be installed in this " + "setup by using blocklists. However, blocklists are UNRELIABLE and " + "their use is discouraged.")); + if (! force) + /* TRANSLATORS: Here GRUB refuses to continue with blocklist install. */ + grub_util_error ("%s", _("will not proceed with blocklists")); + + /* The core image must be put on a filesystem unfortunately. */ + grub_util_info ("will leave the core image on the filesystem"); + + grub_util_biosdisk_flush (root_dev->disk); + + /* Clean out the blocklists. */ + bl.block = bl.first_block; + while (bl.block->len) + { + bl.block->start = 0; + bl.block->len = 0; +#ifdef GRUB_SETUP_BIOS + bl.block->segment = 0; +#endif + + bl.block--; + + if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + + bl.block = bl.first_block; + +#ifdef GRUB_SETUP_SPARC64 + { + grub_partition_t container = root_dev->disk->partition; + bl.gpt_offset = 0; + + if (grub_strstr (container->partmap->name, "gpt")) + bl.gpt_offset = grub_partition_get_start (container); + } +#endif + + grub_install_get_blocklist (root_dev, core_path, core_img, core_size, + save_blocklists, &bl); + + if (bl.first_sector == (grub_disk_addr_t)-1) + grub_util_error ("%s", _("can't retrieve blocklists")); + +#ifdef GRUB_SETUP_SPARC64 + { + char *boot_devpath; + boot_devpath = (char *) (boot_img + + GRUB_BOOT_AOUT_HEADER_SIZE + + GRUB_BOOT_MACHINE_BOOT_DEVPATH); + if (dest_dev->disk->id != root_dev->disk->id + || dest_dev->disk->dev->id != root_dev->disk->dev->id) + { + char *dest_ofpath; + dest_ofpath + = grub_util_devname_to_ofpath (grub_util_biosdisk_get_osdev (root_dev->disk)); + /* FIXME handle NULL result */ + grub_util_info ("dest_ofpath is `%s'", dest_ofpath); + strncpy (boot_devpath, dest_ofpath, + GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1); + boot_devpath[GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH - 1] = 0; + free (dest_ofpath); + } + else + { + grub_util_info ("non cross-disk install"); + memset (boot_devpath, 0, GRUB_BOOT_MACHINE_BOOT_DEVPATH_END + - GRUB_BOOT_MACHINE_BOOT_DEVPATH); + } + grub_util_info ("boot device path %s", boot_devpath); + } +#endif + + write_rootdev (root_dev, boot_img, bl.first_sector); + + /* Write the first two sectors of the core image onto the disk. */ + grub_util_info ("opening the core image `%s'", core_path); + fp = grub_util_fd_open (core_path, GRUB_UTIL_FD_O_WRONLY); + if (! GRUB_UTIL_FD_IS_VALID (fp)) + grub_util_error (_("cannot open `%s': %s"), core_path, + grub_util_fd_strerror ()); + + if (grub_util_fd_write (fp, core_img, GRUB_DISK_SECTOR_SIZE * 2) + != GRUB_DISK_SECTOR_SIZE * 2) + grub_util_error (_("cannot write to `%s': %s"), + core_path, strerror (errno)); + if (grub_util_fd_sync (fp) < 0) + grub_util_error (_("cannot sync `%s': %s"), core_path, strerror (errno)); + if (grub_util_fd_close (fp) < 0) + grub_util_error (_("cannot close `%s': %s"), core_path, strerror (errno)); + grub_util_biosdisk_flush (root_dev->disk); + + grub_disk_cache_invalidate_all (); + + { + char *buf, *ptr = core_img; + size_t len = core_size; + grub_uint64_t blk, offset = 0; + grub_partition_t container = core_dev->disk->partition; + grub_err_t err; + + core_dev->disk->partition = 0; +#ifdef GRUB_SETUP_SPARC64 + offset = bl.gpt_offset; +#endif + + buf = xmalloc (core_size); + blk = bl.first_sector; + err = grub_disk_read (core_dev->disk, blk + offset, 0, GRUB_DISK_SECTOR_SIZE, buf); + if (err) + grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, + grub_errmsg); + if (grub_memcmp (buf, ptr, GRUB_DISK_SECTOR_SIZE) != 0) + grub_util_error ("%s", _("blocklists are invalid")); + + ptr += GRUB_DISK_SECTOR_SIZE; + len -= GRUB_DISK_SECTOR_SIZE; + + bl.block = bl.first_block; + while (bl.block->len) + { + size_t cur = grub_target_to_host16 (bl.block->len) << GRUB_DISK_SECTOR_BITS; + blk = grub_target_to_host64 (bl.block->start); + + if (cur > len) + cur = len; + + err = grub_disk_read (core_dev->disk, blk + offset, 0, cur, buf); + if (err) + grub_util_error (_("cannot read `%s': %s"), core_dev->disk->name, + grub_errmsg); + + if (grub_memcmp (buf, ptr, cur) != 0) + grub_util_error ("%s", _("blocklists are invalid")); + + ptr += cur; + len -= cur; + bl.block--; + + if ((char *) bl.block <= core_img) + grub_util_error ("%s", _("no terminator in the core image")); + } + if (len) + grub_util_error ("%s", _("blocklists are incomplete")); + core_dev->disk->partition = container; + free (buf); + } + +#ifdef GRUB_SETUP_BIOS + finish: +#endif + + /* Write the boot image onto the disk. */ + if (grub_disk_write (dest_dev->disk, BOOT_SECTOR, + 0, GRUB_DISK_SECTOR_SIZE, boot_img)) + grub_util_error ("%s", grub_errmsg); + +#ifdef GRUB_SETUP_SPARC64 + finish: +#endif + + grub_util_biosdisk_flush (root_dev->disk); + grub_util_biosdisk_flush (dest_dev->disk); + + free (core_path); + free (core_img); + free (boot_img); + grub_device_close (dest_dev); + grub_device_close (root_dev); +} + diff --git a/GRUB2/buildgrub.sh b/GRUB2/buildgrub.sh index 553a7531..ce278840 100644 --- a/GRUB2/buildgrub.sh +++ b/GRUB2/buildgrub.sh @@ -11,25 +11,77 @@ mkdir SRC mkdir NBP mkdir PXE -tar -xvf grub-2.04.tar.xz -C ./SRC/ +tar -xf grub-2.04.tar.xz -C ./SRC/ /bin/cp -a ./MOD_SRC/grub-2.04 ./SRC/ cd ./SRC/grub-2.04 -# build for Legacy BIOS -./autogen.sh -./configure --prefix=$VT_GRUB_DIR/INSTALL/ -make -j 16 -sh install.sh -# build for UEFI +# build for x86_64-efi +echo '======== build grub2 for x86_64-efi ===============' make distclean ./autogen.sh ./configure --with-platform=efi --prefix=$VT_GRUB_DIR/INSTALL/ -make -j 16 +make -j 16 || exit 1 sh install.sh uefi +#build for i386-efi +echo '======== build grub2 for i386-efi ===============' +make distclean +./autogen.sh +./configure --target=i386 --with-platform=efi --prefix=$VT_GRUB_DIR/INSTALL/ +make -j 16 || exit 1 +sh install.sh i386efi + + + +#build for arm64 EFI +echo '======== build grub2 for arm64-efi ===============' +PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin +make distclean +./autogen.sh +./configure --prefix=$VT_GRUB_DIR/INSTALL/ \ +--target=aarch64 --with-platform=efi \ +--host=x86_64-linux-gnu \ +HOST_CC=x86_64-linux-gnu-gcc \ +BUILD_CC=gcc \ +TARGET_CC=aarch64-linux-gnu-gcc \ +TARGET_OBJCOPY=aarch64-linux-gnu-objcopy \ +TARGET_STRIP=aarch64-linux-gnu-strip TARGET_NM=aarch64-linux-gnu-nm \ +TARGET_RANLIB=aarch64-linux-gnu-ranlib +make -j 16 || exit 1 +sh install.sh arm64 + + +#build for mips64el EFI +#http://ftp.loongnix.org/os/loongnix-server/1.7/os/Source/SPackages/grub2-2.02-0.40.lns7.14.loongnix.src.rpm +make distclean +./autogen.sh +./configure --prefix=/home/share/Ventoy/GRUB2/INSTALL/ \ +--target=mips64el --with-platform=efi \ +--host=x86_64-linux-gnu \ +HOST_CC=x86_64-linux-gnu-gcc \ +BUILD_CC=gcc \ +TARGET_CC="mips-linux-gnu-gcc -mabi=64 -Wno-error=cast-align -Wno-error=misleading-indentation" \ +TARGET_OBJCOPY=mips-linux-gnu-objcopy \ +TARGET_STRIP=mips-linux-gnu-strip TARGET_NM=mips-linux-gnu-nm \ +TARGET_RANLIB=mips-linux-gnu-ranlib +make -j 16 || exit 1 +sh install.sh mips64el + + + +# build for i386-pc +echo '======== build grub2 for i386-pc ===============' +make distclean +./autogen.sh +./configure --target=i386 --with-platform=pc --prefix=$VT_GRUB_DIR/INSTALL/ +make -j 16 || exit 1 +sh install.sh + + + cd ../../ diff --git a/GenUUID/build.sh b/GenUUID/build.sh deleted file mode 100644 index 65625d66..00000000 --- a/GenUUID/build.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -/opt/diet32/bin/diet gcc -Os -m32 vtoy_gen_uuid.c -o vtoy_gen_uuid - -if [ -e vtoy_gen_uuid ]; then - echo -e '\n############### SUCCESS ###############\n' - - rm -f ../INSTALL/tool/vtoy_gen_uuid - cp -a vtoy_gen_uuid ../INSTALL/tool/vtoy_gen_uuid -else - echo -e '\n############### FAILED ################\n' - exit 1 -fi - diff --git a/ICON/forums.png b/ICON/forums.png new file mode 100644 index 00000000..ca926982 Binary files /dev/null and b/ICON/forums.png differ diff --git a/ICON/logo_128.png b/ICON/logo_128.png new file mode 100644 index 00000000..a13884a4 Binary files /dev/null and b/ICON/logo_128.png differ diff --git a/ICON/logo_16.png b/ICON/logo_16.png new file mode 100644 index 00000000..a5b068f7 Binary files /dev/null and b/ICON/logo_16.png differ diff --git a/ICON/logo_256.png b/ICON/logo_256.png new file mode 100644 index 00000000..d6df64f6 Binary files /dev/null and b/ICON/logo_256.png differ diff --git a/ICON/logo_32.png b/ICON/logo_32.png new file mode 100644 index 00000000..6e6618eb Binary files /dev/null and b/ICON/logo_32.png differ diff --git a/ICON/logo_48.png b/ICON/logo_48.png new file mode 100644 index 00000000..9d0a332b Binary files /dev/null and b/ICON/logo_48.png differ diff --git a/ICON/logo_512.png b/ICON/logo_512.png new file mode 100644 index 00000000..6a1ec92b Binary files /dev/null and b/ICON/logo_512.png differ diff --git a/ICON/logo_64.png b/ICON/logo_64.png new file mode 100644 index 00000000..8b23b321 Binary files /dev/null and b/ICON/logo_64.png differ diff --git a/ICON/logo_72.png b/ICON/logo_72.png new file mode 100644 index 00000000..4f24cd0b Binary files /dev/null and b/ICON/logo_72.png differ diff --git a/IMG/cpio/sbin/init b/IMG/cpio/sbin/init index ef7b5d6d..17be33fb 100644 --- a/IMG/cpio/sbin/init +++ b/IMG/cpio/sbin/init @@ -1,4 +1,4 @@ -#!/ventoy/busybox/tmpsh +#!/ventoy/busybox/ash #************************************************************************************ # Copyright (c) 2020, longpanda # @@ -19,7 +19,7 @@ #################################################################### # # -# Step 1 : extract busybox & set busybox enviroment # +# Step 1 : extract busybox & set busybox environment # # # #################################################################### @@ -36,8 +36,46 @@ export SED=$BUSYBOX_PATH/sed export SLEEP=$BUSYBOX_PATH/sleep export HEAD=$BUSYBOX_PATH/head -$BUSYBOX_PATH/tmpxz -d $BUSYBOX_PATH/busybox.xz -$BUSYBOX_PATH/busybox --install $BUSYBOX_PATH +if [ -e $BUSYBOX_PATH/busyboxaa64.xz ]; then + export VTOY_ARCH=aarch64 +elif [ -e $BUSYBOX_PATH/busyboxm64e.xz ]; then + export VTOY_ARCH=mips64el +else + if [ -e $BUSYBOX_PATH/32h ]; then + export VTOY_ARCH=x86_64 + else + export VTOY_ARCH=i386 + fi +fi + +echo $VTOY_ARCH > $VTOY_PATH/ventoy_arch + + +if [ "$VTOY_ARCH" = "aarch64" ]; then + $BUSYBOX_PATH/xzminidecaa64 < $BUSYBOX_PATH/busyboxaa64.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmodaa64 $BUSYBOX_PATH/busybox +elif [ "$VTOY_ARCH" = "mips64el" ]; then + $BUSYBOX_PATH/xzminidecm64e < $BUSYBOX_PATH/busyboxm64e.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmodm64e $BUSYBOX_PATH/busybox +elif [ "$VTOY_ARCH" = "x86_64" ]; then + $BUSYBOX_PATH/xzminidec64 < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox + if [ -s $BUSYBOX_PATH/busybox ]; then + $BUSYBOX_PATH/vtchmod64 $BUSYBOX_PATH/busybox + else + $BUSYBOX_PATH/xzminidec64_musl < $BUSYBOX_PATH/busybox64.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmod64_musl $BUSYBOX_PATH/busybox + fi +else + $BUSYBOX_PATH/xzminidec32 < $BUSYBOX_PATH/busybox32.xz > $BUSYBOX_PATH/busybox + $BUSYBOX_PATH/vtchmod32 $BUSYBOX_PATH/busybox +fi + +if [ -e $BUSYBOX_PATH/busybox ]; then + $BUSYBOX_PATH/busybox --install $BUSYBOX_PATH +else + $BUSYBOX_PATH/tmpxz -d $BUSYBOX_PATH/busybox32.xz + $BUSYBOX_PATH/busybox32 --install $BUSYBOX_PATH +fi export PATH=$BUSYBOX_PATH/:$VTOY_PATH/tool @@ -54,14 +92,65 @@ if [ -z "$VTOY_REDT_BUG" ]; then fi cd $VTOY_PATH -xz -d ventoy.sh.xz +xz -d ventoy_chain.sh.xz +xz -d ventoy_loop.sh.xz if [ -n "$VTOY_REDT_BUG" ]; then xz -d -c hook.cpio.xz | cpio -idm xz -d -c tool.cpio.xz | cpio -idm + xz -d -c loop.cpio.xz | cpio -idm else xz -d -c hook.cpio.xz | cpio -idm 2>>$VTLOG xz -d -c tool.cpio.xz | cpio -idm 2>>$VTLOG + xz -d -c loop.cpio.xz | cpio -idm 2>>$VTLOG +fi + + +if [ "$VTOY_ARCH" = "x86_64" ]; then + echo "Use x86_64 busybox toolkit ..." >>$VTLOG + ln -s $BUSYBOX_PATH/xzminidec64 $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetup64 $VTOY_PATH/tool/dmsetup + ln -s $VTOY_PATH/tool/lunzip64 $VTOY_PATH/tool/lunzip + + rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/lz4cat64 $VTOY_PATH/tool/lz4cat + ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat +elif [ "$VTOY_ARCH" = "i386" ]; then + echo "Use i386 busybox toolkit ..." >>$VTLOG + ln -s $BUSYBOX_PATH/xzminidec32 $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetup32 $VTOY_PATH/tool/dmsetup + ln -s $VTOY_PATH/tool/lunzip32 $VTOY_PATH/tool/lunzip + + if uname -a | egrep -q 'x86_64|amd64'; then + echo "zstdcat use 64bit ..." >>$VTLOG + rm -f $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/zstdcat64 $VTOY_PATH/tool/zstdcat + fi +elif [ "$VTOY_ARCH" = "mips64el" ]; then + echo "Use MIPS64 busybox toolkit ..." >>$VTLOG + ln -s $BUSYBOX_PATH/xzminidecm64e $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetupm64e $VTOY_PATH/tool/dmsetup + + # TBD + #ln -s $VTOY_PATH/tool/lunzipm64e $VTOY_PATH/tool/lunzip + + rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/lz4catm64e $VTOY_PATH/tool/lz4cat + + # TBD + #ln -s $VTOY_PATH/tool/zstdcataa64 $VTOY_PATH/tool/zstdcat + +elif [ "$VTOY_ARCH" = "aarch64" ]; then + echo "Use ARM64 busybox toolkit ..." >>$VTLOG + ln -s $BUSYBOX_PATH/xzminidecaa64 $BUSYBOX_PATH/xzminidec + ln -s $VTOY_PATH/tool/dmsetupaa64 $VTOY_PATH/tool/dmsetup + ln -s $VTOY_PATH/tool/lunzipaa64 $VTOY_PATH/tool/lunzip + + rm -f $VTOY_PATH/tool/lz4cat $VTOY_PATH/tool/zstdcat + ln -s $VTOY_PATH/tool/lz4cataa64 $VTOY_PATH/tool/lz4cat + ln -s $VTOY_PATH/tool/zstdcataa64 $VTOY_PATH/tool/zstdcat +else + echo "Unknown busybox toolkit ..." >>$VTLOG fi rm -f *.xz diff --git a/IMG/cpio/ventoy/busybox/tmpxz b/IMG/cpio/ventoy/busybox/tmpxz deleted file mode 100644 index 34acebf8..00000000 Binary files a/IMG/cpio/ventoy/busybox/tmpxz and /dev/null differ diff --git a/IMG/cpio/ventoy/hook/alpine/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/alpine/udev_disk_hook.sh index 930009bc..91391cca 100644 --- a/IMG/cpio/ventoy/hook/alpine/udev_disk_hook.sh +++ b/IMG/cpio/ventoy/hook/alpine/udev_disk_hook.sh @@ -59,7 +59,15 @@ mkdir -p $VTOY_PATH/mnt mount /vt_modloop $VTOY_PATH/mnt KoModPath=$(find $VTOY_PATH/mnt/ -name 'dm-mod.ko*') -vtlog "insmod $KoModPath" +vtlog "KoModPath=$KoModPath" + +if modinfo $KoModPath | grep -q 'depend.*dax'; then + vtlog "First install dax mod ..." + DaxModPath=$(echo $KoModPath | sed 's#md/dm-mod#dax/dax#') + vtlog "insmod $DaxModPath" + insmod $DaxModPath +fi + insmod $KoModPath umount $VTOY_PATH/mnt diff --git a/IMG/cpio/ventoy/hook/arch/ventoy-disk.sh b/IMG/cpio/ventoy/hook/arch/ventoy-disk.sh index 356c77f8..c1765376 100644 --- a/IMG/cpio/ventoy/hook/arch/ventoy-disk.sh +++ b/IMG/cpio/ventoy/hook/arch/ventoy-disk.sh @@ -35,14 +35,32 @@ fi ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "blkdev_num=$blkdev_num vtDM=$vtDM ..." + +while [ -n "Y" ]; do + if [ -b /dev/$vtDM ]; then + break + else + sleep 0.3 + fi +done + if [ -n "$1" ]; then - blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') - vtDM=$(ventoy_find_dm_id ${blkdev_num}) - vtlog "ln -s /dev/$vtDM $1" ln -s /dev/$vtDM "$1" +else + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + vtlog "vtLABEL is $vtLABEL" + + if [ -z "$vtLABEL" ]; then + vtLABEL=$($SED "s/.*label=\([^ ]*\)/\1/" /proc/cmdline) + vtlog "vtLABEL is $vtLABEL from cmdline" + fi + + ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL" fi # OK finish set_ventoy_hook_finish - diff --git a/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh b/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh index 7c99f77e..1dde3053 100644 --- a/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/arch/ventoy-hook.sh @@ -21,11 +21,23 @@ if $GREP -q '^"$mount_handler"' /init; then echo 'use mount_handler ...' >> $VTLOG - $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$archisodevice\"" -i /init - if [ -f /hooks/archiso ]; then - $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/arch/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/archiso + vthookfile=/hooks/archiso + + if [ -e /hooks/miso ]; then + vthookfile=/hooks/miso + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$misodevice\"" -i /init + elif [ -e /hooks/artix ]; then + vthookfile=/hooks/artix + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$artixdevice\"" -i /init + else + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ventoy-disk.sh \"\$archisodevice\"" -i /init fi + + if [ -f $vthookfile ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/arch/ventoy-timeout.sh ${dev}; then break; fi' -i $vthookfile + fi + elif $GREP -q '^KEEP_SEARCHING' /init; then echo 'KEEP_SEARCHING found ...' >> $VTLOG $SED "/^KEEP_SEARCHING/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/arch/ovios-disk.sh " -i /init @@ -49,3 +61,7 @@ else ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + $SED "1 aexport cow_label=vtoycow" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/aryalinux/disk_hook.sh b/IMG/cpio/ventoy/hook/aryalinux/disk_hook.sh new file mode 100644 index 00000000..4b625c51 --- /dev/null +++ b/IMG/cpio/ventoy/hook/aryalinux/disk_hook.sh @@ -0,0 +1,51 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +mkdir /sys +mount -t sysfs sys /sys + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "blkdev_num=$blkdev_num blkdev_num_mknod=$blkdev_num_mknod vtDM=$vtDM" + +if [ -b /dev/$vtDM ]; then + vtlog "dev already exist ..." +else + vtlog "mknode dev ..." + mknod -m 660 /dev/$vtDM b $blkdev_num_mknod +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/aryalinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/aryalinux/ventoy-hook.sh new file mode 100644 index 00000000..557566f4 --- /dev/null +++ b/IMG/cpio/ventoy/hook/aryalinux/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir /dev +$BUSYBOX_PATH/mknod -m 660 /dev/console b 5 1 + +$SED "/for device in/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/aryalinux/disk_hook.sh" -i /init +#$SED "/for device in/i exec $BUSYBOX_PATH/sh" -i /init diff --git a/IMG/cpio/ventoy/hook/austrumi/disk_hook.sh b/IMG/cpio/ventoy/hook/austrumi/disk_hook.sh new file mode 100644 index 00000000..431ccd53 --- /dev/null +++ b/IMG/cpio/ventoy/hook/austrumi/disk_hook.sh @@ -0,0 +1,54 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if check_usb_disk_ready "$vtdiskname"; then + vtlog "check_usb_disk_ready ok" +else + vtlog "check_usb_disk_ready error" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +# blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +# blkdev_num_mknod=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +# vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +# vtlog "blkdev_num=$blkdev_num blkdev_num_mknod=$blkdev_num_mknod vtDM=$vtDM" + +# if [ -b /dev/$vtDM ]; then + # vtlog "dev already exist ..." +# else + # vtlog "mknode dev ..." + # mknod -m 660 /dev/$vtDM b $blkdev_num_mknod +# fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/austrumi/ventoy-hook.sh b/IMG/cpio/ventoy/hook/austrumi/ventoy-hook.sh new file mode 100644 index 00000000..5785dee2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/austrumi/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_usb *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/austrumi/disk_hook.sh" -i /init +$SED "s/BOOT_TYPE=livecd/BOOT_TYPE=usb/g" -i /init + diff --git a/IMG/cpio/ventoy/hook/blackPanther/ventoy-hook.sh b/IMG/cpio/ventoy/hook/blackPanther/ventoy-hook.sh new file mode 100644 index 00000000..bdcea43c --- /dev/null +++ b/IMG/cpio/ventoy/hook/blackPanther/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +ventoy_set_inotify_script blackPanther/ventoy-inotifyd-hook.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/blackPanther/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/00-ventoy-inotifyd-start.sh + +$SED "s#printf\(.*\)\$CMDLINE#printf\1 root=/dev/dm-0 \$CMDLINE root=/dev/dm-0#" -i /lib/dracut-lib.sh diff --git a/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-hook.sh new file mode 100644 index 00000000..3b11f7ca --- /dev/null +++ b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-hook.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + blkdev_num_dev=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + if ! [ -e /dev/dm-0 ]; then + mknod -m 660 /dev/dm-0 b $blkdev_num_dev + fi + blackPanther-root /dev/dm-0 + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-start.sh new file mode 100644 index 00000000..62e10a3b --- /dev/null +++ b/IMG/cpio/ventoy/hook/blackPanther/ventoy-inotifyd-start.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi + diff --git a/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh b/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh new file mode 100644 index 00000000..3e46fbfd --- /dev/null +++ b/IMG/cpio/ventoy/hook/cdlinux/disk-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh new file mode 100644 index 00000000..0bbe835b --- /dev/null +++ b/IMG/cpio/ventoy/hook/cdlinux/ventoy-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +echo "CDlinux process..." >> $VTLOG + +$BUSYBOX_PATH/mknod -m 0660 /ventoy/ram0 b 1 0 + +$BUSYBOX_PATH/mkdir /vtmnt /ventoy_rdroot +$BUSYBOX_PATH/mount -t squashfs /ventoy/ram0 /vtmnt + +$BUSYBOX_PATH/mount -nt tmpfs -o mode=755 tmpfs /ventoy_rdroot + +$BUSYBOX_PATH/cp -a /vtmnt/* /ventoy_rdroot +$BUSYBOX_PATH/ls -1a /vtmnt/ | $GREP '^\.[^.]' | while read vtLine; do + $BUSYBOX_PATH/cp -a /vtmnt/$vtLine /ventoy_rdroot +done + +$BUSYBOX_PATH/umount /vtmnt && $BUSYBOX_PATH/rm -rf /vtmnt +$BUSYBOX_PATH/cp -a /ventoy /ventoy_rdroot + +if [ -f /etc/default/cdlinux ]; then + echo "CDL_WAIT=60" >> /etc/default/cdlinux +fi + +echo 'echo "CDL_DEV=/dev/mapper/ventoy" >>"$VAR_FILE"' >> /ventoy_rdroot/etc/rc.d/rc.var + +ventoy_set_rule_dir_prefix /ventoy_rdroot +ventoy_systemd_udevd_work_around +ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" diff --git a/IMG/cpio/ventoy/hook/crux/disk_hook.sh b/IMG/cpio/ventoy/hook/crux/disk_hook.sh new file mode 100644 index 00000000..a4a6ed0a --- /dev/null +++ b/IMG/cpio/ventoy/hook/crux/disk_hook.sh @@ -0,0 +1,41 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + $SLEEP 3 + else + break + fi +done + +ventoy_extract_vtloopex ${vtdiskname}2 crux + + +vtKver=$(uname -r) +vtLoopExDir=$VTOY_PATH/vtloopex/crux/vtloopex + +ventoy_check_install_module_xz $vtLoopExDir/dm-mod/$vtKver/64/dax.ko +ventoy_check_install_module_xz $vtLoopExDir/dm-mod/$vtKver/64/dm-mod.ko + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" diff --git a/IMG/cpio/ventoy/hook/crux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/crux/ventoy-hook.sh new file mode 100644 index 00000000..8c5d048d --- /dev/null +++ b/IMG/cpio/ventoy/hook/crux/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_and_mount_media.*(/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/crux/disk_hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh b/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh new file mode 100644 index 00000000..a5b7b955 --- /dev/null +++ b/IMG/cpio/ventoy/hook/cucumber/disk-hook.sh @@ -0,0 +1,52 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "mount media /dev/$vtDM ..." +if ! [ -e /media/install ]; then + mkdir -p /media/install +fi +mount /dev/$vtDM /media/install + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh b/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh new file mode 100644 index 00000000..4f0363c2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/cucumber/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -e /sbin/mount_installer ]; then + echo "hook at mount_installer ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/cucumber/disk-hook.sh" -i /sbin/mount_installer +fi + diff --git a/IMG/cpio/ventoy/hook/daphile/disk_hook.sh b/IMG/cpio/ventoy/hook/daphile/disk_hook.sh new file mode 100644 index 00000000..9ae2f6d9 --- /dev/null +++ b/IMG/cpio/ventoy/hook/daphile/disk_hook.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +# Just for KVM test environment +$BUSYBOX_PATH/modprobe virtio_blk 2>/dev/null +$BUSYBOX_PATH/modprobe virtio_pci 2>/dev/null + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + $SLEEP 2 + else + break + fi +done + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" diff --git a/IMG/cpio/ventoy/hook/daphile/ventoy-hook.sh b/IMG/cpio/ventoy/hook/daphile/ventoy-hook.sh new file mode 100644 index 00000000..176db16b --- /dev/null +++ b/IMG/cpio/ventoy/hook/daphile/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount_boot /i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init + +$SED "s#'\.\*/block/mmcblk[^ ]*'#'\.\*/block/dm-[0-9]*'#" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/antix-disk.sh b/IMG/cpio/ventoy/hook/debian/antix-disk.sh index 5ef8f511..fc11c53b 100644 --- a/IMG/cpio/ventoy/hook/debian/antix-disk.sh +++ b/IMG/cpio/ventoy/hook/debian/antix-disk.sh @@ -43,6 +43,7 @@ ventoy_os_install_dmsetup_by_unsquashfs() { vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk if ! [ -e $VTOY_PATH/sqfs${dmModPath} ]; then + rm -rf $VTOY_PATH/sqfs dmModPath="/lib/modules/$vtKerVer/kernel/drivers/md/dm-mod.$vtKoPo" echo $dmModPath > $VTOY_PATH/fsextract vtoy_unsquashfs -d $VTOY_PATH/sqfs -n -q -e $VTOY_PATH/fsextract $VTOY_PATH/fsdisk diff --git a/IMG/cpio/ventoy/hook/debian/antix-hook.sh b/IMG/cpio/ventoy/hook/debian/antix-hook.sh index fa9d0834..64ad6ee2 100644 --- a/IMG/cpio/ventoy/hook/debian/antix-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/antix-hook.sh @@ -23,7 +23,12 @@ elif $GREP -q '\[ "$FILTERED_LIST" \]' /init; then $SED '/\[ "$FILTERED_LIST" \]/i\ FILTERED_LIST="/dev/mapper/ventoy $FILTERED_LIST"' -i /init fi -$SED -i "/_search_for_boot_device_/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/antix-disk.sh" /init +if $GREP -q '_search_for_boot_device_' /init; then + $SED -i "/_search_for_boot_device_/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/antix-disk.sh" /init +elif $GREP -q 'FILTERED_LIST=.*ventoy' /init; then + $SED -i "/FILTERED_LIST=.*ventoy/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/antix-disk.sh" /init +fi + if [ -f $VTOY_PATH/ventoy_persistent_map ]; then $SED 's#for param in $cmdline#for param in persist_all $cmdline#g' -i /init diff --git a/IMG/cpio/ventoy/hook/debian/bliss-disk.sh b/IMG/cpio/ventoy/hook/debian/bliss-disk.sh new file mode 100644 index 00000000..b340bbea --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/bliss-disk.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/bliss-hook.sh b/IMG/cpio/ventoy/hook/debian/bliss-hook.sh new file mode 100644 index 00000000..3910ea8c --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/bliss-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +$BUSYBOX_PATH/mkdir /dev +$BUSYBOX_PATH/mknod /dev/null c 1 3 + +$SED "/echo.*Detecting/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/bliss-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/debian/default-hook.sh b/IMG/cpio/ventoy/hook/debian/default-hook.sh index bd2dd1ea..4b528320 100644 --- a/IMG/cpio/ventoy/hook/debian/default-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/default-hook.sh @@ -17,6 +17,8 @@ # #************************************************************************************ +CD_DETECT="/var/lib/dpkg/info/cdrom-detect.postinst" + if [ -e /init ] && $GREP -q '^mountroot$' /init; then echo "Here before mountroot ..." >> $VTLOG @@ -29,7 +31,14 @@ if [ -e /init ] && $GREP -q '^mountroot$' /init; then $SED "s#^ *LIVEMEDIA=.*#LIVEMEDIA=/dev/mapper/ventoy#" -i /scripts/casper fi fi +elif [ -e "$CD_DETECT" ]; then + echo "$CD_DETECT exist, now add hook in it..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i "$CD_DETECT" + if [ -e /bin/list-devices ]; then + mv /bin/list-devices /bin/list-devices-bk + cp -a /ventoy/hook/debian/list-devices /bin/list-devices + fi elif [ -e /init ] && $GREP -q '/start-udev$' /init; then echo "Here use notify ..." >> $VTLOG @@ -50,3 +59,21 @@ if [ -f $VTOY_PATH/autoinstall ]; then fi fi +#for ARMA aka Omoikane +if [ -f /mod.img ] && [ -f /mod/fs/cramfs.ko ]; then + echo "mount mod.img and install dm-mod.ko" >> $VTLOG + $BUSYBOX_PATH/insmod /mod/fs/cramfs.ko + + $BUSYBOX_PATH/mkdir $VTOY_PATH/modmnt + $BUSYBOX_PATH/mount /mod.img $VTOY_PATH/modmnt + $BUSYBOX_PATH/insmod $VTOY_PATH/modmnt/md/dm-mod.ko + $BUSYBOX_PATH/umount $VTOY_PATH/modmnt + + $BUSYBOX_PATH/rmmod cramfs +fi + +#for siduction-patience-nox- +if [ -f /scripts/fll ]; then + $SED "/unset FINGERED/a\\echo '/dev/mapper/ventoy';return;" -i /scripts/fll +fi + diff --git a/IMG/cpio/ventoy/hook/debian/kerio-disk.sh b/IMG/cpio/ventoy/hook/debian/kerio-disk.sh new file mode 100644 index 00000000..a589d8f8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kerio-disk.sh @@ -0,0 +1,79 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_ko() { + vtlog "ventoy_os_install_dmsetup_by_ko $1" + + vtVer=$(uname -r) + if uname -m | $GREP -q 64; then + vtBit=64 + else + vtBit=32 + fi + + ventoy_extract_vtloopex $1 kerio + vtLoopExDir=$VTOY_PATH/vtloopex/kerio/vtloopex + + if [ -e $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz ]; then + $BUSYBOX_PATH/xz -d $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz + insmod $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko + fi +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if echo $vtdiskname | $EGREP -q "nvme|mmc|nbd"; then + ventoy_os_install_dmsetup_by_ko "${vtdiskname}p2" +else + ventoy_os_install_dmsetup_by_ko "${vtdiskname}2" +fi + + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +vtlog "/dev/$vtDM" +mount -t iso9660 /dev/$vtDM /cdrom +modprobe squashfs +echo "/dev/$vtDM" > /ventoy/vtDM + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/kerio-hook.sh b/IMG/cpio/ventoy/hook/debian/kerio-hook.sh new file mode 100644 index 00000000..864292b7 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kerio-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +$SED "/for drive in/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/kerio-disk.sh >/dev/null 2>&1; cat /ventoy/vtDM; exit 0" -i /installer/install_init diff --git a/IMG/cpio/ventoy/hook/debian/kylin-disk.sh b/IMG/cpio/ventoy/hook/debian/kylin-disk.sh new file mode 100644 index 00000000..0bfb2851 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kylin-disk.sh @@ -0,0 +1,68 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + sfsfile=$VTOY_PATH/mnt/iso/casper/filesystem.squashfs + + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + + kVer=$(uname -r) + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$kVer/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs + umount $VTOY_PATH/mnt/iso + umount $VTOY_PATH/mnt/fuse +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if ! grep -q 'device-mapper' /proc/devices; then + ventoy_os_install_dmsetup_by_fuse $vtdiskname +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/kylin-hook.sh b/IMG/cpio/ventoy/hook/debian/kylin-hook.sh new file mode 100644 index 00000000..051ec4a2 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/kylin-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/kylin-disk.sh" -i /init + $SED "/^mountroot$/i\\export LIVEMEDIA=/dev/mapper/ventoy" -i /init + $SED "/^mountroot$/i\\export LIVE_MEDIA=/dev/mapper/ventoy" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh b/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh new file mode 100644 index 00000000..e5bb7cbb --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/linuxconsole-disk.sh @@ -0,0 +1,71 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + + +vtoydm -i -f $VTOY_PATH/ventoy_image_map -d $vtdiskname > $VTOY_PATH/iso_file_list + +vtline=$(grep '[-][-] drivers-.*\.squashfs' $VTOY_PATH/iso_file_list) +sector=$(echo $vtline | awk '{print $(NF-1)}') +length=$(echo $vtline | awk '{print $NF}') + +vtoydm -e -f $VTOY_PATH/ventoy_image_map -d $vtdiskname -s $sector -l $length -o $VTOY_PATH/driver.squashfs +mount -t squashfs $VTOY_PATH/driver.squashfs /lib/modules +modprobe dm-mod + +umount /lib/modules +rm -f $VTOY_PATH/driver.squashfs + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_dev=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if ! [ -b /dev/$vtDM ]; then + mknod -m 0660 /dev/$vtDM b $blkdev_dev +fi + +if mount /dev/$vtDM /media/ydfs; then + vtlog "mount success" +else + vtlog "mount failed" +fi + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh b/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh new file mode 100644 index 00000000..a8e1db71 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/linuxconsole-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +$SED "s#/busybox/bin/sleep 2#/busybox/bin/sleep 10#" -i /etc/init.d/tty1 +$SED "/install *-d *.media.ydfs/a return" -i /ydfs/detect/media +$SED "/install *-d *.media.ydfs/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/linuxconsole-disk.sh" -i /ydfs/detect/media + diff --git a/IMG/cpio/ventoy/hook/debian/list-devices b/IMG/cpio/ventoy/hook/debian/list-devices new file mode 100644 index 00000000..874bb68b --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/list-devices @@ -0,0 +1,9 @@ +#! /bin/sh + +if [ "$1" = "usb-partition" -a -z "$2" ]; then + if [ -f /ventoy/list-devices-usb-part ]; then + cat /ventoy/list-devices-usb-part + fi +fi + +/bin/list-devices-bk $* diff --git a/IMG/cpio/ventoy/hook/debian/mll-disk.sh b/IMG/cpio/ventoy/hook/debian/mll-disk.sh new file mode 100644 index 00000000..8ee05793 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mll-disk.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/mll-hook.sh b/IMG/cpio/ventoy/hook/debian/mll-hook.sh new file mode 100644 index 00000000..5186f024 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mll-hook.sh @@ -0,0 +1,21 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +$SED "/^for DEVICE in/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/mll-disk.sh" -i /etc/02_overlay.sh + diff --git a/IMG/cpio/ventoy/hook/debian/mocaccino-disk.sh b/IMG/cpio/ventoy/hook/debian/mocaccino-disk.sh new file mode 100644 index 00000000..7d876549 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mocaccino-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "/dev/$vtDM" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/mocaccino-hook.sh b/IMG/cpio/ventoy/hook/debian/mocaccino-hook.sh new file mode 100644 index 00000000..31143c32 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/mocaccino-hook.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +$SED "/mount_system *$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/mocaccino-disk.sh" -i /loader diff --git a/IMG/cpio/ventoy/hook/debian/puppy-disk.sh b/IMG/cpio/ventoy/hook/debian/puppy-disk.sh index 6872f589..7f987223 100644 --- a/IMG/cpio/ventoy/hook/debian/puppy-disk.sh +++ b/IMG/cpio/ventoy/hook/debian/puppy-disk.sh @@ -42,6 +42,7 @@ if ! [ -e $VTOY_DM_PATH ]; then blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') mknod -m 0666 $VTOY_DM_PATH b $blkdev_num fi +cp -a $VTOY_DM_PATH /dev/ventoy PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/debian/puppy-hook.sh b/IMG/cpio/ventoy/hook/debian/puppy-hook.sh index 69e18f3d..cbb5a20b 100644 --- a/IMG/cpio/ventoy/hook/debian/puppy-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/puppy-hook.sh @@ -19,4 +19,10 @@ $SED '1 apmedia=usbhd' -i /init $SED "/^ *HAVE_PARTS=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/puppy-disk.sh" -i /init -$SED "/^ *HAVE_PARTS=/a\ HAVE_PARTS='mapper/ventoy|iso9660'" -i /init +$SED "/^ *HAVE_PARTS=/a\ HAVE_PARTS='ventoy|iso9660'" -i /init + +if [ -f /DISTRO_SPECS ]; then + if ! [ -d /dev ]; then + $BUSYBOX_PATH/mkdir /dev + fi +fi diff --git a/IMG/cpio/ventoy/hook/debian/slax-disk.sh b/IMG/cpio/ventoy/hook/debian/slax-disk.sh index 0e0cbfb9..f38c24ba 100644 --- a/IMG/cpio/ventoy/hook/debian/slax-disk.sh +++ b/IMG/cpio/ventoy/hook/debian/slax-disk.sh @@ -60,8 +60,6 @@ ventoy_os_install_dmsetup() { fi } -wait_for_usb_disk_ready - vtdiskname=$(get_ventoy_disk_name) if [ "$vtdiskname" = "unknown" ]; then vtlog "ventoy disk not found" @@ -69,6 +67,14 @@ if [ "$vtdiskname" = "unknown" ]; then exit 0 fi +if check_usb_disk_ready "$vtdiskname"; then + vtlog "check_usb_disk_ready ok" +else + vtlog "check_usb_disk_ready error" + PATH=$VTPATH_OLD + exit 0 +fi + ventoy_os_install_dmsetup $vtdiskname ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" diff --git a/IMG/cpio/ventoy/hook/debian/slax-hook.sh b/IMG/cpio/ventoy/hook/debian/slax-hook.sh index 93790fa8..5663c0ee 100644 --- a/IMG/cpio/ventoy/hook/debian/slax-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/slax-hook.sh @@ -17,4 +17,8 @@ # #************************************************************************************ -$SED "/find_data/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/slax-disk.sh" -i /init +if [ -f /lib/livekitlib ] && $GREP -q 'debug_log.*find_data_try' /lib/livekitlib; then + $SED "/debug_log.*find_data_try/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/slax-disk.sh" -i /lib/livekitlib +else + $SED "/find_data/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/slax-disk.sh" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/debian/tails-hook.sh b/IMG/cpio/ventoy/hook/debian/tails-hook.sh index dd880498..54a3e822 100644 --- a/IMG/cpio/ventoy/hook/debian/tails-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/tails-hook.sh @@ -20,5 +20,11 @@ $SED "s#.*livefs_root=.*find_livefs.*#$BUSYBOX_PATH/mount -t iso9660 /dev/mapper/ventoy \$mountpoint; livefs_root=\$mountpoint#" -i /usr/lib/live/boot/9990-main.sh $SED "s#.*livefs_root=.*find_livefs.*#$BUSYBOX_PATH/mount -t iso9660 /dev/mapper/ventoy \$mountpoint; livefs_root=\$mountpoint#" -i /usr/bin/boot/9990-main.sh -ventoy_systemd_udevd_work_around -ventoy_add_udev_rule "$VTOY_PATH/hook/debian/udev_disk_hook.sh %k" +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/disk_mount_hook.sh" -i /init +else + echo "Use default hook ..." >> $VTLOG + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/debian/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh index 6dd6882b..c46f85b4 100644 --- a/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh +++ b/IMG/cpio/ventoy/hook/debian/udev_disk_hook.sh @@ -41,8 +41,20 @@ ventoy_os_install_dmsetup() { fi # install md-modules - LINE=$($GREP ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list) + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list) if [ $? -eq 0 ]; then + LINTCNT=$($GREP -i -c ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list) + if [ $LINTCNT -gt 1 ]; then + vtlog "more than one pkgs, need to filter..." + VER=$($BUSYBOX_PATH/uname -r) + + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i $VER) + LINTCNT=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i -c $VER) + if [ $LINTCNT -gt 1 ]; then + vtlog "Still more than one pkgs, use the first one..." + LINE=$($GREP -i ' md-modules.*\.udeb' $VTOY_PATH/iso_file_list | $GREP -i -m1 $VER) + fi + fi install_udeb_from_line "$LINE" ${vt_usb_disk} fi @@ -50,7 +62,7 @@ ventoy_os_install_dmsetup() { if $GREP -q 'device-mapper' /proc/devices; then vtlog "device mapper module is loaded" else - vtlog"device mapper module is NOT loaded, now load it..." + vtlog "device mapper module is NOT loaded, now load it..." VER=$($BUSYBOX_PATH/uname -r) KO=$($FIND /lib/modules/$VER/kernel/drivers/md -name "dm-mod*") @@ -83,6 +95,8 @@ if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then exit 0 fi +vtlog "==== $0 $* ====" + dmsetup_path=$(ventoy_find_bin_path dmsetup) if [ -z "$dmsetup_path" ]; then ventoy_os_install_dmsetup "/dev/${1:0:-1}" @@ -99,8 +113,20 @@ ventoy_udev_disk_common_hook $* # So if ventoy is installed on a non-USB device, we just mount /cdrom here except # for these has boot=live or boot=casper parameter in cmdline # -if echo $ID_BUS | $GREP -q -i usb; then +VT_BUS_USB="" +if [ -n "$ID_BUS" ]; then + if echo $ID_BUS | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +else + if $BUSYBOX_PATH/ls -l /sys/class/block/${1:0:-1} | $GREP -q -i usb; then + VT_BUS_USB="YES" + fi +fi + +if [ -n "$VT_BUS_USB" ]; then vtlog "$1 is USB device" + echo /dev/$1 > /ventoy/list-devices-usb-part else vtlog "$1 is NOT USB device (bus $ID_BUS)" @@ -108,15 +134,7 @@ else vtlog "boot=, or casper, don't mount" else vtlog "No boot param, need to mount" - $BUSYBOX_PATH/mkdir /cdrom - - if [ -b $VTOY_DM_PATH ]; then - vtlog "mount $VTOY_DM_PATH ..." - $BUSYBOX_PATH/mount -t iso9660 $VTOY_DM_PATH /cdrom - else - vtlog "mount /dev/$1 ..." - $BUSYBOX_PATH/mount -t iso9660 /dev/$1 /cdrom - fi + echo /dev/$1 > /ventoy/list-devices-usb-part fi fi diff --git a/IMG/cpio/ventoy/hook/debian/veket-disk.sh b/IMG/cpio/ventoy/hook/debian/veket-disk.sh index 38a9c050..b0b51311 100644 --- a/IMG/cpio/ventoy/hook/debian/veket-disk.sh +++ b/IMG/cpio/ventoy/hook/debian/veket-disk.sh @@ -37,9 +37,17 @@ ventoy_os_install_dmsetup_by_fuse() { mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso - sfsfile=$(ls $VTOY_PATH/mnt/iso/adrv_veket*.sfs) - - mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + for sfsfile in $(ls $VTOY_PATH/mnt/iso/*drv_veket*.sfs); do + mount -t squashfs $sfsfile $VTOY_PATH/mnt/squashfs + if [ -d $VTOY_PATH/mnt/squashfs/lib/modules ]; then + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + if [ -n "$KoName" -a -f $KoName ]; then + break + fi + fi + + umount $VTOY_PATH/mnt/squashfs + done KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/dax/dax.ko*) vtlog "insmod $KoName" diff --git a/IMG/cpio/ventoy/hook/debian/veket-hook.sh b/IMG/cpio/ventoy/hook/debian/veket-hook.sh index 922e2366..5093cbb1 100644 --- a/IMG/cpio/ventoy/hook/debian/veket-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/veket-hook.sh @@ -20,3 +20,10 @@ $SED '1 apmedia=usbhd' -i /init $SED "/^ *HAVE_PARTS=/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/veket-disk.sh" -i /init $SED "/^ *HAVE_PARTS=/a\ HAVE_PARTS='ventoy|iso9660'" -i /init + +if [ -d /dev ]; then + [ -e /dev/null ] || $BUSYBOX_PATH/mknod /dev/null c 1 3 +else + $BUSYBOX_PATH/mkdir /dev + $BUSYBOX_PATH/mknod /dev/null c 1 3 +fi diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh index 2bc7a860..402eb4d3 100644 --- a/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/ventoy-hook.sh @@ -28,6 +28,12 @@ ventoy_get_debian_distro() { fi fi + if [ -e /DISTRO_SPECS ]; then + if $GREP -q veket /DISTRO_SPECS; then + echo 'veket'; return + fi + fi + if [ -e /init ]; then if $GREP -q PUPPYSFS /init; then if $GREP -q VEKETSFS /init; then @@ -35,6 +41,8 @@ ventoy_get_debian_distro() { else echo 'puppy'; return fi + elif $GREP -m1 -q 'Minimal.*Linux.*Live' /init; then + echo 'mll'; return fi fi @@ -60,6 +68,32 @@ ventoy_get_debian_distro() { echo 'porteus'; return fi + if $GREP -q 'linuxconsole' /proc/version; then + echo 'linuxconsole'; return + fi + + if $GREP -q 'vyos' /proc/version; then + echo 'vyos'; return + fi + + if $GREP -q 'kylin' /proc/version; then + echo 'kylin'; return + fi + + if [ -f /scripts/00-ver ]; then + if $GREP -q 'Bliss-OS' /scripts/00-ver; then + echo 'bliss'; return + fi + fi + + if [ -e /opt/kerio ]; then + echo 'kerio'; return + fi + + if $GREP -q 'mocaccino' /proc/version; then + echo 'mocaccino'; return + fi + echo 'default' } @@ -68,10 +102,10 @@ DISTRO=$(ventoy_get_debian_distro) echo "##### distribution = $DISTRO ######" >> $VTLOG . $VTOY_PATH/hook/debian/${DISTRO}-hook.sh - - - - +if [ -f /bin/env2debconf ]; then + $SED "1a /bin/sh $VTOY_PATH/hook/debian/ventoy_env2debconf.sh" -i /bin/env2debconf + $SED "s#in *\$(set)#in \$(cat /ventoy/envset)#" -i /bin/env2debconf +fi diff --git a/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh index 53916c6a..e1547225 100644 --- a/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/debian/ventoy-inotifyd-hook.sh @@ -23,13 +23,15 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." vtlog "find ventoy partition $3 ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/udev_disk_hook.sh "$3" +else + vtlog "##### INOTIFYD: $2/$3 is created (NO)..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/debian/ventoy_env2debconf.sh b/IMG/cpio/ventoy/hook/debian/ventoy_env2debconf.sh new file mode 100644 index 00000000..53b3effe --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/ventoy_env2debconf.sh @@ -0,0 +1,33 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +PATH=$PATH:/ventoy/busybox + +set > /ventoy/tmpenvset + +for i in $(cat /proc/cmdline); do + if echo $i | grep -q "="; then + vtKey=${i%=*} + if ! grep -q "^$vtKey" /ventoy/tmpenvset; then + echo $i >> /ventoy/envset + fi + fi +done + +cat /ventoy/tmpenvset >> /ventoy/envset diff --git a/IMG/cpio/ventoy/hook/debian/vyos-disk.sh b/IMG/cpio/ventoy/hook/debian/vyos-disk.sh new file mode 100644 index 00000000..468adfd9 --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/vyos-disk.sh @@ -0,0 +1,49 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +mkdir -p /live/vtoyfuse /live/vtoyiso + +modprobe fuse +vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $vtdiskname > $VTOY_PATH/ventoy_dm_table +vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m /live/vtoyfuse + +mount -t iso9660 /live/vtoyfuse/ventoy.iso /live/vtoyiso + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/debian/vyos-hook.sh b/IMG/cpio/ventoy/hook/debian/vyos-hook.sh new file mode 100644 index 00000000..007f823b --- /dev/null +++ b/IMG/cpio/ventoy/hook/debian/vyos-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +if [ -e /init ] && $GREP -q '^mountroot$' /init; then + echo "Here before mountroot ..." >> $VTLOG + $SED "/^mountroot$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/hook/debian/vyos-disk.sh" -i /init + $SED "/^mountroot$/i\\export LIVE_MEDIA=/live/vtoyiso" -i /init + #$SED "/^mountroot$/i\\exec /ventoy/busybox/sh" -i /init +fi diff --git a/IMG/cpio/ventoy/hook/default/10-dm.rules b/IMG/cpio/ventoy/hook/default/10-dm.rules new file mode 100644 index 00000000..f33df582 --- /dev/null +++ b/IMG/cpio/ventoy/hook/default/10-dm.rules @@ -0,0 +1,150 @@ +# Copyright (C) 2009 Red Hat, Inc. All rights reserved. +# +# This file is part of LVM2. + +# Udev rules for device-mapper devices. +# +# These rules create a DM control node in /dev/mapper directory. +# The rules also create nodes named dm-x (x is a number) in /dev +# directory and symlinks to these nodes with names given by +# the actual DM names. Some udev environment variables are set +# for use in later rules: +# DM_NAME - actual DM device's name +# DM_UUID - UUID set for DM device (blank if not specified) +# DM_SUSPENDED - suspended state of DM device (0 or 1) +# DM_UDEV_RULES_VSN - DM udev rules version +# +# These rules cover only basic device-mapper functionality in udev. +# +# Various DM subsystems may contain further subsystem-specific rules +# in 11-dm-.rules which should be installed together +# with the DM subsystem and which extend these basic rules. +# For example: +# 11-dm-lvm.rules for LVM subsystem +# 11-dm-mpath.rules for multipath subsystem (since version 0.6.0, recommended!) +# +# Even more specific rules may be required by subsystems so always +# check subsystem's upstream repository for recent set of rules. +# Also, keep in mind that recent rules may also require recent +# subsystem-specific binaries. + +KERNEL=="device-mapper", NAME="mapper/control" + +SUBSYSTEM!="block", GOTO="dm_end" +KERNEL!="dm-[0-9]*", GOTO="dm_end" + + +# Device created, major and minor number assigned - "add" event generated. +# Table loaded - no event generated. +# Device resumed (or renamed) - "change" event generated. +# Device removed - "remove" event generated. +# +# The dm-X nodes are always created, even on "add" event, we can't suppress +# that (the node is created even earlier with devtmpfs). All the symlinks +# (e.g. /dev/mapper) are created in right time after a device has its table +# loaded and is properly resumed. For this reason, direct use of dm-X nodes +# is not recommended. +ACTION!="add|change", GOTO="dm_end" + +# Decode udev control flags and set environment variables appropriately. +# These flags are encoded in DM_COOKIE variable that was introduced in +# kernel version 2.6.31. Therefore, we can use this feature with +# kernels >= 2.6.31 only. Cookie is not decoded for remove event. +ENV{DM_COOKIE}=="?*", IMPORT{program}="/usr/sbin/dmsetup udevflags $env{DM_COOKIE}" + +# Rule out easy-to-detect inappropriate events first. +ENV{DISK_RO}=="1", GOTO="dm_disable" + +# There is no cookie set nor any flags encoded in events not originating +# in libdevmapper so we need to detect this and try to behave correctly. +# For such spurious events, regenerate all flags from current udev database content +# (this information would normally be inaccessible for spurious ADD and CHANGE events). +ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}="1", GOTO="dm_flags_done" +IMPORT{db}="DM_UDEV_DISABLE_DM_RULES_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_DISK_RULES_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_OTHER_RULES_FLAG" +IMPORT{db}="DM_UDEV_LOW_PRIORITY_FLAG" +IMPORT{db}="DM_UDEV_DISABLE_LIBRARY_FALLBACK_FLAG" +IMPORT{db}="DM_UDEV_PRIMARY_SOURCE_FLAG" +IMPORT{db}="DM_UDEV_FLAG7" +IMPORT{db}="DM_UDEV_RULES_VSN" +LABEL="dm_flags_done" + +# Normally, we operate on "change" events. But when coldplugging, there's an +# "add" event present. We have to recognize this and do our actions in this +# particular situation, too. Also, we don't want the nodes to be created +# prematurely on "add" events while not coldplugging. We check +# DM_UDEV_PRIMARY_SOURCE_FLAG to see if the device was activated correctly +# before and if not, we ignore the "add" event totally. This way we can support +# udev triggers generating "add" events (e.g. "udevadm trigger --action=add" or +# "echo add > /sys/block//uevent"). The trigger with "add" event is +# also used at boot to reevaluate udev rules for all existing devices activated +# before (e.g. in initrd). If udev is used in initrd, we require the udev init +# script to not remove the existing udev database so we can reuse the information +# stored at the time of device activation in the initrd. +ACTION!="add", GOTO="dm_no_coldplug" +ENV{DM_UDEV_RULES_VSN}!="1", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}!="1", GOTO="dm_disable" +ENV{DM_ACTIVATION}="1" +LABEL="dm_no_coldplug" + +# Putting it together, following table is used to recognize genuine and spurious events. +# N.B. Spurious events are generated based on use of the WATCH udev +# rule or by triggering an event manually by "udevadm trigger" call +# or by "echo > /sys/block/dm-X/uevent". +# +# EVENT DM_UDEV_PRIMARY_SOURCE_FLAG DM_ACTIVATION +# ====================================================================== +# add event (genuine) 0 0 +# change event (genuine) 1 1 +# add event (spurious) +# |_ dev still not active 0 0 +# \_ dev already active 1 1 +# change event (spurious) +# |_ dev still not active 0 0 +# \_ dev already active 1 0 + +# "dm" sysfs subdirectory is available in newer versions of DM +# only (kernels >= 2.6.29). We have to check for its existence +# and use dmsetup tool instead to get the DM name, uuid and +# suspended state if the "dm" subdirectory is not present. +# The "suspended" item was added even later (kernels >= 2.6.31), +# so we also have to call dmsetup if the kernel version used +# is in between these releases. +TEST=="dm", ENV{DM_NAME}="$attr{dm/name}", ENV{DM_UUID}="$attr{dm/uuid}", ENV{DM_SUSPENDED}="$attr{dm/suspended}" +TEST!="dm", IMPORT{program}="/usr/sbin/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o name,uuid,suspended" +ENV{DM_SUSPENDED}!="?*", IMPORT{program}="/usr/sbin/dmsetup info -j %M -m %m -c --nameprefixes --noheadings --rows -o suspended" + +# dmsetup tool provides suspended state information in textual +# form with values "Suspended"/"Active". We translate it to +# 0/1 respectively to be consistent with sysfs values. +ENV{DM_SUSPENDED}=="Active", ENV{DM_SUSPENDED}="0" +ENV{DM_SUSPENDED}=="Suspended", ENV{DM_SUSPENDED}="1" + +# This variable provides a reliable way to check that device-mapper +# rules were installed. It means that all needed variables are set +# by these rules directly so there's no need to acquire them again +# later. Other rules can alternate the functionality based on this +# fact (e.g. fallback to rules that behave correctly even without +# these rules installed). It also provides versioning for any +# possible future changes. +# VSN 1 - original rules +# VSN 2 - add support for synthesized events +ENV{DM_UDEV_RULES_VSN}="2" + +ENV{DM_UDEV_DISABLE_DM_RULES_FLAG}!="1", ENV{DM_NAME}=="?*", SYMLINK+="mapper/$env{DM_NAME}" + +# Avoid processing and scanning a DM device in the other (foreign) +# rules if it is in suspended state. However, we still keep 'disk' +# and 'DM subsystem' related rules enabled in this case. +ENV{DM_SUSPENDED}=="1", ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" + +GOTO="dm_end" + +LABEL="dm_disable" +ENV{DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG}="1" +ENV{DM_UDEV_DISABLE_DISK_RULES_FLAG}="1" +ENV{DM_UDEV_DISABLE_OTHER_RULES_FLAG}="1" +OPTIONS:="nowatch" + +LABEL="dm_end" diff --git a/IMG/cpio/ventoy/hook/default/ventoy-hook.sh b/IMG/cpio/ventoy/hook/default/ventoy-hook.sh index 152dd06b..56e0e35e 100644 --- a/IMG/cpio/ventoy/hook/default/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/default/ventoy-hook.sh @@ -22,3 +22,12 @@ ventoy_systemd_udevd_work_around ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" + +if [ -f /init ]; then + vtSize=$($BUSYBOX_PATH/stat -c '%s' /init) + if ! [ -L /init ]; then + if [ $vtSize -eq 0 ]; then + rm -f /init + fi + fi +fi diff --git a/IMG/cpio/ventoy/hook/dragora/disk_hook.sh b/IMG/cpio/ventoy/hook/dragora/disk_hook.sh new file mode 100644 index 00000000..600bfc0c --- /dev/null +++ b/IMG/cpio/ventoy/hook/dragora/disk_hook.sh @@ -0,0 +1,41 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_extract_vtloopex ${vtdiskname}2 dragora +vtLoopExDir=$VTOY_PATH/vtloopex/dragora/vtloopex +$BUSYBOX_PATH/xz -d $vtLoopExDir/dm-mod/$(uname -r)/64/dm-mod.ko.xz +$BUSYBOX_PATH/insmod $vtLoopExDir/dm-mod/$(uname -r)/64/dm-mod.ko + + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/dragora/ventoy-hook.sh b/IMG/cpio/ventoy/hook/dragora/ventoy-hook.sh new file mode 100644 index 00000000..a0a2c198 --- /dev/null +++ b/IMG/cpio/ventoy/hook/dragora/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/iso9660/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/dragora/disk_hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/easystartup/disk_hook.sh b/IMG/cpio/ventoy/hook/easystartup/disk_hook.sh new file mode 100644 index 00000000..d9b3d48b --- /dev/null +++ b/IMG/cpio/ventoy/hook/easystartup/disk_hook.sh @@ -0,0 +1,83 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +get_rhel_ver() { + if uname -m | grep -q '64'; then + machine='_X64' + fi + + if grep -q '6[.]1' /etc/redhat-release; then + echo "RHAS6U1$machine"; return + fi + + echo "RHAS6U1$machine" +} + +install_dm_mod_ko() { + # dump iso file location + vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vtdiskname} > $VTOY_PATH/iso_file_list + + sysver=$(get_rhel_ver) + vtlog "sysver=$sysver" + + LINE=$(grep "$sysver" -n -m1 $VTOY_PATH/iso_file_list | awk -F: '{print $1}') + vtlog "LINE=$LINE" + + LINE=$(sed -n "$LINE,\$p" $VTOY_PATH/iso_file_list | grep -m1 'initrd.img') + vtlog "LINE=$LINE" + + sector=$(echo $LINE | $AWK '{print $(NF-1)}') + length=$(echo $LINE | $AWK '{print $NF}') + vtlog "sector=$sector length=$length" + + mkdir xxx + vtoydm -e -f $VTOY_PATH/ventoy_image_map -d ${vtdiskname} -s $sector -l $length -o ./xxx.img + + cd xxx/ + zcat ../xxx.img | cpio -idmu + ko=$(find -name dm-mod.ko*) + vtlog "ko=$ko ..." + insmod $ko + + cd ../ + rm -f xxx.img + rm -rf xxx +} + +vtdiskname=$(get_ventoy_disk_name) +vtlog "vtdiskname=$vtdiskname ..." +if [ "$vtdiskname" = "unknown" ]; then + exit 0 +fi + +if grep -q 'device-mapper' /proc/devices; then + vtlog "device-mapper module check ko" +else + install_dm_mod_ko +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ln -s /dev/dm-0 /dev/root + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/easystartup/ventoy-hook.sh b/IMG/cpio/ventoy/hook/easystartup/ventoy-hook.sh new file mode 100644 index 00000000..39658c44 --- /dev/null +++ b/IMG/cpio/ventoy/hook/easystartup/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "s#^CDROM=.*#CDROM=/dev/dm-0#" -i /init +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/easystartup/ventoy-initqueue.sh /initqueue/ventoy.sh diff --git a/IMG/cpio/ventoy/hook/easystartup/ventoy-initqueue.sh b/IMG/cpio/ventoy/hook/easystartup/ventoy-initqueue.sh new file mode 100644 index 00000000..d4c8b5f0 --- /dev/null +++ b/IMG/cpio/ventoy/hook/easystartup/ventoy-initqueue.sh @@ -0,0 +1,20 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2021, longpanda +# +# 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 . +# +#************************************************************************************ + +/ventoy/busybox/sh /ventoy/hook/easystartup/disk_hook.sh $* diff --git a/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh b/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh new file mode 100644 index 00000000..8ee05793 --- /dev/null +++ b/IMG/cpio/ventoy/hook/fatdog/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh b/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh new file mode 100644 index 00000000..8b164329 --- /dev/null +++ b/IMG/cpio/ventoy/hook/fatdog/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find_local_device *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/fatdog/disk-hook.sh" -i /init +$SED "/find_and_choose_local_device *(/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/fatdog/disk-hook.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/gentoo/disk_hook.sh b/IMG/cpio/ventoy/hook/gentoo/disk_hook.sh index 3f515bff..9ae2f6d9 100644 --- a/IMG/cpio/ventoy/hook/gentoo/disk_hook.sh +++ b/IMG/cpio/ventoy/hook/gentoo/disk_hook.sh @@ -19,7 +19,7 @@ . /ventoy/hook/ventoy-hook-lib.sh -# Just for KVM test enviroment +# Just for KVM test environment $BUSYBOX_PATH/modprobe virtio_blk 2>/dev/null $BUSYBOX_PATH/modprobe virtio_pci 2>/dev/null diff --git a/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh index e4d90ee7..5ee237ad 100644 --- a/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/gentoo/ventoy-hook.sh @@ -21,6 +21,9 @@ if $GREP -q kaspersky /proc/version; then $SED "/sysresccd_stage1_normal[^(]*$/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/gentoo/disk_hook.sh" -i /init + if [ -f /ventoy/ventoy_persistent_map ]; then + $SED "/sysresccd_parsecmdline[^(]*$/a\ BACKSTORE_CMD='LABEL=casper-rw,noloop'" -i /init + fi elif [ -d /etc/udev/rules.d ] || [ -d /lib/udev/rules.d ]; then ventoy_systemd_udevd_work_around ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k noreplace" diff --git a/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh index ff52bbb0..76009e86 100644 --- a/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/gobo/ventoy-inotifyd-hook.sh @@ -23,11 +23,11 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES)..." + vtlog "find ventoy partition $3 ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace @@ -42,6 +42,8 @@ if is_inotify_ventoy_part $3; then # fi set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO)..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/hyperbola/ventoy-disk.sh b/IMG/cpio/ventoy/hook/hyperbola/ventoy-disk.sh new file mode 100644 index 00000000..356c77f8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/hyperbola/ventoy-disk.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if [ -n "$1" ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" +fi + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/hyperbola/ventoy-hook.sh b/IMG/cpio/ventoy/hook/hyperbola/ventoy-hook.sh new file mode 100644 index 00000000..aebe57ad --- /dev/null +++ b/IMG/cpio/ventoy/hook/hyperbola/ventoy-hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler ...' >> $VTLOG + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/hyperbola/ventoy-disk.sh \"\$hyperisodevice\"" -i /init + + if [ -f /hooks/parabolaiso ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/hyperbola/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/hyperiso + fi + +else + # some archlinux initramfs doesn't contain device-mapper udev rules file + ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) + if [ -s "$ARCH_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'dm-disk rule exist' >> $VTLOG + else + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$ARCH_UDEV_DIR/13-dm-disk.rules" + fi + + # use default proc + ventoy_systemd_udevd_work_around + + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/hyperbola/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/hyperbola/ventoy-timeout.sh new file mode 100644 index 00000000..fec9cc07 --- /dev/null +++ b/IMG/cpio/ventoy/hook/hyperbola/ventoy-timeout.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -b /dev/$vtDM ]; then + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" + exit 0 +else + vtlog "Device-mapper not found" + exit 1 +fi + + diff --git a/IMG/cpio/ventoy/hook/kwort/disk-hook.sh b/IMG/cpio/ventoy/hook/kwort/disk-hook.sh new file mode 100644 index 00000000..8ee05793 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kwort/disk-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh b/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh new file mode 100644 index 00000000..78f56150 --- /dev/null +++ b/IMG/cpio/ventoy/hook/kwort/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/kwort/disk-hook.sh" -i /etc/rc.d/init/media diff --git a/IMG/cpio/ventoy/hook/lunar/ventoy-hook.sh b/IMG/cpio/ventoy/hook/lunar/ventoy-hook.sh new file mode 100644 index 00000000..08e32d42 --- /dev/null +++ b/IMG/cpio/ventoy/hook/lunar/ventoy-hook.sh @@ -0,0 +1,27 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=/dev/dm-0#" -i /lib/dracut-lib.sh + +$BUSYBOX_PATH/rm -f /usr/lib/systemd/system-generators/systemd-fstab-generator /lib/systemd/system-generators/systemd-fstab-generator + +ventoy_set_inotify_script lunar/ventoy-inotifyd-hook.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/lunar/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh diff --git a/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-hook.sh new file mode 100644 index 00000000..da310136 --- /dev/null +++ b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-hook.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + mount -t iso9660 /dev/$vtDM /sysroot + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-start.sh new file mode 100644 index 00000000..6be81555 --- /dev/null +++ b/IMG/cpio/ventoy/hook/lunar/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh index bc604ffd..226cbcad 100644 --- a/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/mageia/ventoy-inotifyd-hook.sh @@ -23,12 +23,11 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then - + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + vtlog "find ventoy partition ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace @@ -64,6 +63,8 @@ if is_inotify_ventoy_part $3; then fi set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh b/IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh new file mode 100644 index 00000000..d23fe499 --- /dev/null +++ b/IMG/cpio/ventoy/hook/manjaro/ventoy-disk.sh @@ -0,0 +1,75 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtlog "blkdev_num=$blkdev_num vtDM=$vtDM ..." + +while [ -n "Y" ]; do + if [ -b /dev/$vtDM ]; then + break + else + sleep 0.3 + fi +done + +if [ -n "$1" ]; then + vtlog "ln -s /dev/$vtDM $1" + + if [ -e "$1" ]; then + vtlog "$1 already exist" + else + ln -s /dev/$vtDM "$1" + fi +else + vtLABEL=$($BUSYBOX_PATH/blkid /dev/$vtDM | $SED 's/.*LABEL="\([^"]*\)".*/\1/') + vtlog "vtLABEL is $vtLABEL" + + if [ -z "$vtLABEL" ]; then + vtLABEL=$($SED "s/.*label=\([^ ]*\)/\1/" /proc/cmdline) + vtlog "vtLABEL is $vtLABEL from cmdline" + fi + + if [ -e "/dev/disk/by-label/$vtLABEL" ]; then + vtlog "/dev/disk/by-label/$vtLABEL already exist" + else + ln -s /dev/$vtDM "/dev/disk/by-label/$vtLABEL" + fi +fi + +# OK finish +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/manjaro/ventoy-hook.sh b/IMG/cpio/ventoy/hook/manjaro/ventoy-hook.sh index ebd828ec..f5cdcf57 100644 --- a/IMG/cpio/ventoy/hook/manjaro/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/manjaro/ventoy-hook.sh @@ -28,8 +28,22 @@ else $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$DISTRO_UDEV_DIR/13-dm-disk.rules" fi - -if $GREP -q '^mount_setup$' init; then +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler ...' >> $VTLOG + + vthookfile=/hooks/archiso + + if [ -e /hooks/miso ]; then + vthookfile=/hooks/miso + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/manjaro/ventoy-disk.sh \"\$misodevice\"" -i /init + else + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/manjaro/ventoy-disk.sh \"\$archisodevice\"" -i /init + fi + + if [ -f $vthookfile ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/manjaro/ventoy-timeout.sh ${dev}; then break; fi' -i $vthookfile + fi +elif $GREP -q '^mount_setup$' init; then echo "Here use notify ..." >> $VTLOG ventoy_set_inotify_script manjaro/ventoy-inotifyd-hook.sh diff --git a/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh index 60cff43a..5f2d45cb 100644 --- a/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/manjaro/ventoy-inotifyd-hook.sh @@ -23,11 +23,10 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." vtlog "find ventoy partition $3 ..." $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh "$3" @@ -41,6 +40,8 @@ if is_inotify_ventoy_part $3; then mkdir -p /dev/disk/by-label fi $BUSYBOX_PATH/cp -a /dev/$vtDM /dev/disk/by-label/$vtLABEL +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-hook.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-hook.sh new file mode 100644 index 00000000..63bd4910 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-hook.sh @@ -0,0 +1,91 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -f $VTOY_PATH/autoinstall ]; then + VTKS="inst.ks=file:$VTOY_PATH/autoinstall" +else + for vtParam in $($CAT /proc/cmdline); do + if echo $vtParam | $GREP -q 'inst.ks=hd:LABEL='; then + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="inst.ks=hd:/dev/dm-0:$vtRawKs" + break + fi + + if echo $vtParam | $GREP -q '^ks=.*:/'; then + vtRawKs=$(echo $vtParam | $AWK -F: '{print $NF}') + VTKS="ks=hd:/dev/dm-0:$vtRawKs" + break + fi + done +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + VTOVERLAY="rd.live.overlay=/dev/dm-1:/vtoyoverlayfs/overlayfs" + + if [ -e /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root for persistent ..." >> $VTLOG + $SED "/mount.*devspec.*\/run\/initramfs\/overlayfs/a . /ventoy/hook/openEuler/ventoy-overlay.sh" -i /sbin/dmsquash-live-root + fi + + #close selinux + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/selinuxfs + if $BUSYBOX_PATH/mount -t selinuxfs selinuxfs $VTOY_PATH/selinuxfs; then + echo 1 > $VTOY_PATH/selinuxfs/disable + $BUSYBOX_PATH/umount $VTOY_PATH/selinuxfs + fi + $BUSYBOX_PATH/rm -rf $VTOY_PATH/selinuxfs +fi + + +echo "VTKS=$VTKS VTOVERLAY=$VTOVERLAY" >> $VTLOG + +if ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + for vtDud in $(ls $VTOY_PATH/ventoy_dud*); do + vtInstDD="$vtInstDD inst.dd=file:$vtDud" + done +fi +echo "vtInstDD=$vtInstDD" >> $VTLOG + +$SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0 $VTKS $vtInstDD#" -i /lib/dracut-lib.sh + +ventoy_set_inotify_script openEuler/ventoy-inotifyd-hook.sh + +#Fedora +if $BUSYBOX_PATH/which dmsquash-live-root > /dev/null; then + vtPriority=99 +else + vtPriority=01 +fi + +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/openEuler/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/${vtPriority}-ventoy-inotifyd-start.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/openEuler/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/${vtPriority}-ventoy-timeout.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/openEuler/ventoy-repo.sh /lib/dracut/hooks/pre-pivot/99-ventoy-repo.sh + +if [ -f /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/openEuler/ventoy-make-link.sh" -i /sbin/dmsquash-live-root +fi + +# suppress write protected mount warning +if [ -f /usr/sbin/anaconda-diskroot ]; then + $SED 's/^mount $dev $repodir/mount -oro $dev $repodir/' -i /usr/sbin/anaconda-diskroot +fi + diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-hook.sh new file mode 100644 index 00000000..1da3a197 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-hook.sh @@ -0,0 +1,58 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + + #vtReplaceOpt=noreplace + + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + if [ "$vtDM" = "dm-0" ]; then + vtlog "This is dm-0, OK ..." + else + vtlog "####### This is $vtDM ####### this is abnormal ..." + ventoy_swap_device /dev/dm-0 /dev/$vtDM + fi + + if [ -e /sbin/anaconda-diskroot ]; then + vtlog "set anaconda-diskroot ..." + /sbin/anaconda-diskroot /dev/dm-0 + fi + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-start.sh new file mode 100644 index 00000000..6be81555 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-make-link.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-make-link.sh new file mode 100644 index 00000000..22a3dd4a --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-make-link.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if ! [ -e /dev/mapper/ventoy ]; then + vtlog "link to /dev/mapper/ventoy" + ln -s /dev/dm-0 /dev/mapper/ventoy +fi + +VTLABEL=$($BUSYBOX_PATH/blkid /dev/dm-0 | $SED 's/.*LABEL="\([^"]*\)".*/\1/') +vtlog "VTLABEL=$VTLABEL" + +if [ -n "$VTLABEL" ]; then + if ! [ -e "/dev/disk/by-label/$VTLABEL" ]; then + vtlog "link to /dev/disk/by-label/$VTLABEL" + ln -s /dev/dm-0 "/dev/disk/by-label/$VTLABEL" + fi +fi diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-overlay.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-overlay.sh new file mode 100644 index 00000000..d8fe0799 --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-overlay.sh @@ -0,0 +1,21 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +[ -d /run/initramfs/overlayfs$pathspec ] || mkdir -p /run/initramfs/overlayfs$pathspec +[ -d /run/initramfs/overlayfs$pathspec/../ovlwork ] || mkdir -p /run/initramfs/overlayfs$pathspec/../ovlwork diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-repo.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-repo.sh new file mode 100644 index 00000000..af85bebd --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-repo.sh @@ -0,0 +1,29 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "##### $0 $* ..." + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +repodev=$(ls $VTOY_PATH/dev_backup*) +echo "inst.repo=hd:/dev/${repodev#*dev_backup_}" >> /sysroot/etc/cmdline + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/openEuler/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/openEuler/ventoy-timeout.sh new file mode 100644 index 00000000..87ece3be --- /dev/null +++ b/IMG/cpio/ventoy/hook/openEuler/ventoy-timeout.sh @@ -0,0 +1,34 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "##### $0 $* ..." + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -e /sbin/anaconda-diskroot ]; then + vtlog "set anaconda-diskroot ..." + /sbin/anaconda-diskroot /dev/dm-0 +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh new file mode 100644 index 00000000..356c77f8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-disk.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +if is_ventoy_hook_finished; then + exit 0 +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +if [ -n "$1" ]; then + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') + vtDM=$(ventoy_find_dm_id ${blkdev_num}) + + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" +fi + +# OK finish +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh new file mode 100644 index 00000000..b8b3a5d5 --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-hook.sh @@ -0,0 +1,44 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q '^"$mount_handler"' /init; then + echo 'use mount_handler ...' >> $VTLOG + $SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/parabola/ventoy-disk.sh \"\$parabolaisodevice\"" -i /init + + if [ -f /hooks/parabolaiso ]; then + $SED '/while ! poll_device "${dev}"/a\ if /ventoy/busybox/sh /ventoy/hook/parabola/ventoy-timeout.sh ${dev}; then break; fi' -i /hooks/parabolaiso + fi + +else + # some archlinux initramfs doesn't contain device-mapper udev rules file + ARCH_UDEV_DIR=$(ventoy_get_udev_conf_dir) + if [ -s "$ARCH_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'dm-disk rule exist' >> $VTLOG + else + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$ARCH_UDEV_DIR/13-dm-disk.rules" + fi + + # use default proc + ventoy_systemd_udevd_work_around + + ventoy_add_udev_rule "$VTOY_PATH/hook/default/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh b/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh new file mode 100644 index 00000000..fec9cc07 --- /dev/null +++ b/IMG/cpio/ventoy/hook/parabola/ventoy-timeout.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "######### $0 $* ############" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ -b /dev/$vtDM ]; then + vtlog "ln -s /dev/$vtDM $1" + ln -s /dev/$vtDM "$1" + exit 0 +else + vtlog "Device-mapper not found" + exit 1 +fi + + diff --git a/IMG/cpio/ventoy/hook/phoenixos/disk_hook.sh b/IMG/cpio/ventoy/hook/phoenixos/disk_hook.sh new file mode 100644 index 00000000..56b97b21 --- /dev/null +++ b/IMG/cpio/ventoy/hook/phoenixos/disk_hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +for i in 0 1 2 3 4 5 6 7 8 9; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" = "unknown" ]; then + vtlog "wait for disk ..." + sleep 3 + else + break + fi +done + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + +set_ventoy_hook_finish + +PATH=$VTPATH_OLD + + diff --git a/IMG/cpio/ventoy/hook/phoenixos/ventoy-hook.sh b/IMG/cpio/ventoy/hook/phoenixos/ventoy-hook.sh new file mode 100644 index 00000000..0ead131c --- /dev/null +++ b/IMG/cpio/ventoy/hook/phoenixos/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir /dev +$SED "/for device in/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/phoenixos/disk_hook.sh" -i /init +$SED "s#for device in #for device in /dev/ventoy #" -i /init diff --git a/IMG/cpio/ventoy/hook/photon/ventoy-hook.sh b/IMG/cpio/ventoy/hook/photon/ventoy-hook.sh new file mode 100644 index 00000000..9a298071 --- /dev/null +++ b/IMG/cpio/ventoy/hook/photon/ventoy-hook.sh @@ -0,0 +1,34 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED 's#/dev/cdrom#/dev/ventoy#' -i /installer/isoInstaller.py + +ventoy_set_inotify_script photon/ventoy-inotifyd-hook.sh + +[ -d /dev ] || $BUSYBOX_PATH/mkdir /dev +[ -d /sys ] || $BUSYBOX_PATH/mkdir /sys + +$BUSYBOX_PATH/mount -t devtmpfs -o mode=0755,noexec,nosuid,strictatime devtmpfs /dev +$BUSYBOX_PATH/mount -t sysfs sys /sys + +$BUSYBOX_PATH/rm -f /init +$BUSYBOX_PATH/sh $VTOY_PATH/hook/photon/ventoy-inotifyd-start.sh + diff --git a/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-hook.sh new file mode 100644 index 00000000..424d84e9 --- /dev/null +++ b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-hook.sh @@ -0,0 +1,43 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +if is_inotify_ventoy_part $3; then + + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + vtlog "find ventoy partition ..." + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + mknod -m 0660 /dev/ventoy b $blkdev_num + + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-start.sh new file mode 100644 index 00000000..6be81555 --- /dev/null +++ b/IMG/cpio/ventoy/hook/photon/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-hook-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/hook/pisilinux/ventoy-disk.sh b/IMG/cpio/ventoy/hook/pisilinux/ventoy-disk.sh new file mode 100644 index 00000000..891cd905 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pisilinux/ventoy-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$(dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 660 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/pisilinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/pisilinux/ventoy-hook.sh new file mode 100644 index 00000000..9fc1fc58 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pisilinux/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/pisilinux/ventoy-disk.sh" -i /init +$SED "/^\"\$mount_handler\"/i\ export root=/dev/ventoy" -i /init + diff --git a/IMG/cpio/ventoy/hook/ploplinux/disk_hook.sh b/IMG/cpio/ventoy/hook/ploplinux/disk_hook.sh new file mode 100644 index 00000000..336b7bbf --- /dev/null +++ b/IMG/cpio/ventoy/hook/ploplinux/disk_hook.sh @@ -0,0 +1,38 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/ploplinux/ventoy-hook.sh b/IMG/cpio/ventoy/hook/ploplinux/ventoy-hook.sh new file mode 100644 index 00000000..8eaef67b --- /dev/null +++ b/IMG/cpio/ventoy/hook/ploplinux/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/export *CMDLINE/i CMDLINE=\"root=/dev/ventoy \${CMDLINE}\"" -i /etc/rc.d/init.d/rc.S +$SED "1a $BUSYBOX_PATH/sh $VTOY_PATH/hook/ploplinux/disk_hook.sh" -i /etc/rc.d/init.d/rootmount + diff --git a/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh b/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh new file mode 100644 index 00000000..3e46fbfd --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/disk-hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/tinycore/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh similarity index 66% rename from IMG/cpio/ventoy/hook/tinycore/udev_disk_hook.sh rename to IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh index 6851668d..93e0548e 100644 --- a/IMG/cpio/ventoy/hook/tinycore/udev_disk_hook.sh +++ b/IMG/cpio/ventoy/hook/pmagic/udev_disk_hook.sh @@ -23,23 +23,10 @@ if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then exit 0 fi -# TinyCore linux distro doesn't contain dmsetup, we use aoe here -sudo $BUSYBOX_PATH/modprobe aoe aoe_iflist=lo -if [ -e /sys/module/aoe ]; then - VBLADE_BIN=$(ventoy_get_vblade_bin) - sudo $VBLADE_BIN -r -f $VTOY_PATH/ventoy_image_map 9 0 lo "/dev/${1:0:-1}" & - - while ! [ -b /dev/etherd/e9.0 ]; do - vtlog 'Wait for /dev/etherd/e9.0 ....' - $SLEEP 0.1 - done - - sudo $BUSYBOX_PATH/cp -a /dev/etherd/e9.0 "/dev/$1" - - ventoy_find_bin_run rebuildfstab -else - vterr "aoe driver module load failed..." -fi +ventoy_udev_disk_common_hook $* "noreplace" +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0666 /dev/ventoy b $blkdev_num # OK finish set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh b/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh new file mode 100644 index 00000000..d4768875 --- /dev/null +++ b/IMG/cpio/ventoy/hook/pmagic/ventoy-hook.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if $GREP -q 'Searching *for *PMAGIC' /init; then + echo "Find Searching PMAGIC" >> $VTLOG + $SED "/Searching *for *PMAGIC/a\ root=/dev/ventoy" -i /init + $SED "/Searching *for *PMAGIC/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/pmagic/disk-hook.sh" -i /init +else + echo "Use default..." >> $VTLOG + $SED "s#^root=.*cmdline.*#root=/dev/ventoy#g'" -i /init + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/pmagic/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/primeos/ventoy-disk.sh b/IMG/cpio/ventoy/hook/primeos/ventoy-disk.sh new file mode 100644 index 00000000..c678bdd1 --- /dev/null +++ b/IMG/cpio/ventoy/hook/primeos/ventoy-disk.sh @@ -0,0 +1,38 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n "/dev/$vtDM" > /ventoy/rootdev + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/primeos/ventoy-hook.sh b/IMG/cpio/ventoy/hook/primeos/ventoy-hook.sh new file mode 100644 index 00000000..05c33700 --- /dev/null +++ b/IMG/cpio/ventoy/hook/primeos/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/mkdir /dev + +$SED '/Detecting *PrimeOS/a\ ROOT=$(cat /ventoy/rootdev)' -i /init +$SED "/Detecting *PrimeOS/a\ $BUSYBOX_PATH/sh $VTOY_PATH/hook/primeos/ventoy-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/hook/rancher/disk_hook.sh b/IMG/cpio/ventoy/hook/rancher/disk_hook.sh new file mode 100644 index 00000000..336b7bbf --- /dev/null +++ b/IMG/cpio/ventoy/hook/rancher/disk_hook.sh @@ -0,0 +1,38 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/rancher/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rancher/ventoy-hook.sh new file mode 100644 index 00000000..e2f27faa --- /dev/null +++ b/IMG/cpio/ventoy/hook/rancher/ventoy-hook.sh @@ -0,0 +1,21 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + diff --git a/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh index d2f0f6ba..cfbe43fb 100644 --- a/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel6/ventoy-hook.sh @@ -26,3 +26,13 @@ ventoy_add_udev_rule "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k" #loop7 was used by loader ventoy_add_kernel_udev_rule "loop6" "$VTOY_PATH/hook/rhel6/udev_disk_hook.sh %k" + +if [ -f $VTOY_PATH/autoinstall ]; then + $BUSYBOX_PATH/mv /sbin/loader /sbin/loader_bk + $BUSYBOX_PATH/mv $VTOY_PATH/tool/loader /sbin/loader + + RawCmdLine=$($BUSYBOX_PATH/cat /proc/cmdline) + echo -n "/sbin/loader_bk" > "/ventoy/loader_exec_file" + echo -n "--cmdline=$RawCmdLine ks=file:$VTOY_PATH/autoinstall" > "/ventoy/loader_exec_cmdline" + #echo 111 > "/ventoy/loader_debug" +fi diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh index 1bb6a6b1..aab1e264 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-hook.sh @@ -40,12 +40,38 @@ else done fi -echo "VTKS=$VTKS" >> $VTLOG +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + VTOVERLAY="rd.live.overlay=/dev/dm-1:/vtoyoverlayfs/overlayfs" + + if [ -e /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root for persistent ..." >> $VTLOG + $SED "/mount.*devspec.*\/run\/initramfs\/overlayfs/a . /ventoy/hook/rhel7/ventoy-overlay.sh" -i /sbin/dmsquash-live-root + $SED "s/osmin.img/osmin.imgxxxx/g" -i /sbin/dmsquash-live-root + fi + + #close selinux + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/selinuxfs + if $BUSYBOX_PATH/mount -t selinuxfs selinuxfs $VTOY_PATH/selinuxfs; then + echo 1 > $VTOY_PATH/selinuxfs/disable + $BUSYBOX_PATH/umount $VTOY_PATH/selinuxfs + fi + $BUSYBOX_PATH/rm -rf $VTOY_PATH/selinuxfs +fi + + +echo "VTKS=$VTKS VTOVERLAY=$VTOVERLAY" >> $VTLOG + +if ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + for vtDud in $(ls $VTOY_PATH/ventoy_dud*); do + vtInstDD="$vtInstDD inst.dd=file:$vtDud" + done +fi +echo "vtInstDD=$vtInstDD" >> $VTLOG if $GREP -q 'root=live' /proc/cmdline; then - $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/dm-0 $VTKS#" -i /lib/dracut-lib.sh + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE root=live:/dev/dm-0 $VTKS $VTOVERLAY $vtInstDD#" -i /lib/dracut-lib.sh else - $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0 $VTKS#" -i /lib/dracut-lib.sh + $SED "s#printf\(.*\)\$CMDLINE#printf\1\$CMDLINE inst.stage2=hd:/dev/dm-0 $VTKS $VTOVERLAY $vtInstDD#" -i /lib/dracut-lib.sh fi ventoy_set_inotify_script rhel7/ventoy-inotifyd-hook.sh @@ -60,6 +86,31 @@ fi $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/${vtPriority}-ventoy-inotifyd-start.sh $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-timeout.sh /lib/dracut/hooks/initqueue/timeout/${vtPriority}-ventoy-timeout.sh +vtNeedRepo= +if [ -f /etc/system-release ]; then + if $GREP -q 'RED OS' /etc/system-release; then + vtNeedRepo="yes" + fi +fi +if $GREP -q el8 /proc/version; then + vtNeedRepo="yes" +fi + +if $GREP -i -q Fedora /proc/version; then + if $GREP -q 'Server Edition' /etc/os-release; then + vtNeedRepo="yes" + fi +fi + +if [ "$vtNeedRepo" = "yes" ]; then + $BUSYBOX_PATH/cp -a $VTOY_PATH/hook/rhel7/ventoy-repo.sh /lib/dracut/hooks/pre-pivot/99-ventoy-repo.sh +fi + +if [ -e /sbin/dmsquash-live-root ]; then + echo "patch /sbin/dmsquash-live-root ..." >> $VTLOG + $SED "1 a $BUSYBOX_PATH/sh $VTOY_PATH/hook/rhel7/ventoy-make-link.sh" -i /sbin/dmsquash-live-root +fi + # suppress write protected mount warning if [ -e /usr/sbin/anaconda-diskroot ]; then $SED 's/^mount $dev $repodir/mount -oro $dev $repodir/' -i /usr/sbin/anaconda-diskroot diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh index a565098b..4a2435e1 100644 --- a/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-inotifyd-hook.sh @@ -23,12 +23,12 @@ if is_ventoy_hook_finished; then exit 0 fi -vtlog "##### INOTIFYD: $2/$3 is created ..." - VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + vtGenRulFile='/etc/udev/rules.d/99-live-squash.rules' if [ -e $vtGenRulFile ] && $GREP -q dmsquash $vtGenRulFile; then vtScript=$($GREP -m1 'RUN.=' $vtGenRulFile | $AWK -F'RUN.=' '{print $2}' | $SED 's/"\(.*\)".*/\1/') @@ -39,7 +39,13 @@ if is_inotify_ventoy_part $3; then fi vtlog "find ventoy partition ..." - $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 noreplace + + vtReplaceOpt=noreplace + if [ -f /lib/dracut/hooks/pre-pivot/99-ventoy-repo.sh ]; then + vtReplaceOpt="" + fi + + $BUSYBOX_PATH/sh $VTOY_PATH/hook/default/udev_disk_hook.sh $3 $vtReplaceOpt blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') vtDM=$(ventoy_find_dm_id ${blkdev_num}) @@ -57,6 +63,8 @@ if is_inotify_ventoy_part $3; then fi set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." fi PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh new file mode 100644 index 00000000..22a3dd4a --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-make-link.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if ! [ -e /dev/mapper/ventoy ]; then + vtlog "link to /dev/mapper/ventoy" + ln -s /dev/dm-0 /dev/mapper/ventoy +fi + +VTLABEL=$($BUSYBOX_PATH/blkid /dev/dm-0 | $SED 's/.*LABEL="\([^"]*\)".*/\1/') +vtlog "VTLABEL=$VTLABEL" + +if [ -n "$VTLABEL" ]; then + if ! [ -e "/dev/disk/by-label/$VTLABEL" ]; then + vtlog "link to /dev/disk/by-label/$VTLABEL" + ln -s /dev/dm-0 "/dev/disk/by-label/$VTLABEL" + fi +fi diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-overlay.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-overlay.sh new file mode 100644 index 00000000..d8fe0799 --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-overlay.sh @@ -0,0 +1,21 @@ +#!/bin/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +[ -d /run/initramfs/overlayfs$pathspec ] || mkdir -p /run/initramfs/overlayfs$pathspec +[ -d /run/initramfs/overlayfs$pathspec/../ovlwork ] || mkdir -p /run/initramfs/overlayfs$pathspec/../ovlwork diff --git a/IMG/cpio/ventoy/hook/rhel7/ventoy-repo.sh b/IMG/cpio/ventoy/hook/rhel7/ventoy-repo.sh new file mode 100644 index 00000000..af85bebd --- /dev/null +++ b/IMG/cpio/ventoy/hook/rhel7/ventoy-repo.sh @@ -0,0 +1,29 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtlog "##### $0 $* ..." + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +repodev=$(ls $VTOY_PATH/dev_backup*) +echo "inst.repo=hd:/dev/${repodev#*dev_backup_}" >> /sysroot/etc/cmdline + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/slackware/disk_hook.sh b/IMG/cpio/ventoy/hook/slackware/disk_hook.sh new file mode 100644 index 00000000..03bc90a8 --- /dev/null +++ b/IMG/cpio/ventoy/hook/slackware/disk_hook.sh @@ -0,0 +1,35 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/slackware/ventoy-hook.sh b/IMG/cpio/ventoy/hook/slackware/ventoy-hook.sh index 570e9098..1b3f0483 100644 --- a/IMG/cpio/ventoy/hook/slackware/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/slackware/ventoy-hook.sh @@ -2,7 +2,11 @@ . $VTOY_PATH/hook/ventoy-os-lib.sh -ventoy_systemd_udevd_work_around +if $GREP '^mediadetected=' /init; then + $SED "/^mediadetected=/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/slackware/disk_hook.sh" -i /init +else + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/slackware/udev_disk_hook.sh %k noreplace" +fi -ventoy_add_udev_rule "$VTOY_PATH/hook/slackware/udev_disk_hook.sh %k noreplace" diff --git a/IMG/cpio/ventoy/hook/smgl/disk_hook.sh b/IMG/cpio/ventoy/hook/smgl/disk_hook.sh new file mode 100644 index 00000000..bc135d32 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smgl/disk_hook.sh @@ -0,0 +1,42 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +#exec /ventoy/busybox/sh + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 660 /dev/ventoy b $blkdev_num + +echo "/dev/ventoy" > cdrom.hint + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/smgl/ventoy-hook.sh b/IMG/cpio/ventoy/hook/smgl/ventoy-hook.sh new file mode 100644 index 00000000..9eb20d59 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smgl/ventoy-hook.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +PATH=$PATH:$VTOY_PATH/busybox + +mkdir /ventoy_rdroot + +mknod -m 660 /ram0 b 1 0 + +dd if=/initrd001 of=/ram0 +rm -f /initrd001 + +mount /ram0 /ventoy_rdroot + +vtSize=$(du -m -s $VTOY_PATH | awk '{print $1}') +let vtSize=vtSize+4 + +mkdir -p /ventoy_rdroot/ventoy +mount -t tmpfs -o size=${vtSize}m tmpfs /ventoy_rdroot/ventoy +cp -a /ventoy/* /ventoy_rdroot/ventoy/ + + +cd /ventoy_rdroot + +sed "/scan_cdroms *$/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/smgl/disk_hook.sh" -i sbin/smgl.init + + diff --git a/IMG/cpio/ventoy/hook/smoothwall/cd_list.sh b/IMG/cpio/ventoy/hook/smoothwall/cd_list.sh new file mode 100644 index 00000000..5e7cbab3 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smoothwall/cd_list.sh @@ -0,0 +1,33 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +vtSize=$(cat /sys/block/$vtDM/size) + +cp -a /tmp/cd.list /tmp/cd_new.list +echo "$vtDM $vtSize UNK_MODEL " > /tmp/cd.list +cat /tmp/cd_new.list >> /tmp/cd.list +rm -f /tmp/cd_new.list + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/smoothwall/disk_hook.sh b/IMG/cpio/ventoy/hook/smoothwall/disk_hook.sh new file mode 100644 index 00000000..94827cde --- /dev/null +++ b/IMG/cpio/ventoy/hook/smoothwall/disk_hook.sh @@ -0,0 +1,52 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +if [ "$1" = "fakecdrom" ]; then + if [ -e /dev/sr0 ]; then + for i in 0 1 2 3 4 5 6 7 8; do + if ! [ -e /dev/sr$i ]; then + mv /dev/sr0 /dev/sr$i + cp -a /dev/$vtDM /dev/sr0 + break + fi + done + else + cp -a /dev/$vtDM /dev/sr0 + fi +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/smoothwall/ventoy-hook.sh b/IMG/cpio/ventoy/hook/smoothwall/ventoy-hook.sh new file mode 100644 index 00000000..c2dd6116 --- /dev/null +++ b/IMG/cpio/ventoy/hook/smoothwall/ventoy-hook.sh @@ -0,0 +1,25 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/Running installer/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/smoothwall/disk_hook.sh fakecdrom" -i /etc/install.rc + +$SED "/cd \/sys\/block/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/smoothwall/disk_hook.sh" -i /etc/config-install.rc +$SED "/wc *-l *\/tmp\/cd.list/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/smoothwall/cd_list.sh" -i /etc/config-install.rc diff --git a/IMG/cpio/ventoy/hook/suse/disk_hook.sh b/IMG/cpio/ventoy/hook/suse/disk_hook.sh new file mode 100644 index 00000000..d736cb8d --- /dev/null +++ b/IMG/cpio/ventoy/hook/suse/disk_hook.sh @@ -0,0 +1,64 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + + +ventoy_os_install_dmsetup_by_fuse() { + vtlog "ventoy_os_install_dmsetup_by_fuse $*" + + mkdir -p $VTOY_PATH/mnt/fuse $VTOY_PATH/mnt/iso $VTOY_PATH/mnt/squashfs + + vtoydm -p -f $VTOY_PATH/ventoy_image_map -d $1 > $VTOY_PATH/ventoy_dm_table + vtoy_fuse_iso -f $VTOY_PATH/ventoy_dm_table -m $VTOY_PATH/mnt/fuse + + mount -t iso9660 $VTOY_PATH/mnt/fuse/ventoy.iso $VTOY_PATH/mnt/iso + + mount -t squashfs $VTOY_PATH/mnt/iso/system/squashfs_sys.img $VTOY_PATH/mnt/squashfs + + KoName=$(ls $VTOY_PATH/mnt/squashfs/lib/modules/$2/kernel/drivers/md/dm-mod.ko*) + vtlog "insmod $KoName" + insmod $KoName + + umount $VTOY_PATH/mnt/squashfs 2>>$VTLOG + umount $VTOY_PATH/mnt/iso 2>>$VTLOG + umount $VTOY_PATH/mnt/fuse 2>>$VTLOG +} + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +modprobe fuse +ventoy_os_install_dmsetup_by_fuse $vtdiskname $(uname -r) + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh b/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh new file mode 100644 index 00000000..ff796664 --- /dev/null +++ b/IMG/cpio/ventoy/hook/suse/udev_setup_hook.sh @@ -0,0 +1,42 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + exit 0 +fi + +vtlog "wait_for_usb_disk_ready $vtdiskname ..." + +if echo $vtdiskname | $EGREP -q "nvme|mmc|nbd"; then + vtpart2=${vtdiskname}p2 +else + vtpart2=${vtdiskname}2 +fi + +/ventoy/busybox/sh /ventoy/hook/suse/udev_disk_hook.sh "${vtpart2#/dev/}" + +if $GREP -q 'mediacheck=1' /proc/cmdline; then + ventoy_copy_device_mapper "${vtdiskname}" +fi diff --git a/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh b/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh index 19b90687..da1eb2c6 100644 --- a/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/suse/ventoy-hook.sh @@ -26,10 +26,48 @@ if [ -f $VTOY_PATH/autoinstall ]; then fi fi +if $BUSYBOX_PATH/ls $VTOY_PATH | $GREP -q 'ventoy_dud[0-9]'; then + if [ -f /linuxrc.config ]; then + vtKerVer=$($BUSYBOX_PATH/uname -r) + ventoy_check_insmod /modules/loop.ko + ventoy_check_insmod /modules/squashfs.ko + + ventoy_check_mount /parts/00_lib /modules + ventoy_check_insmod /modules/lib/modules/$vtKerVer/initrd/isofs.ko + $BUSYBOX_PATH/umount /modules + + for vtDud in $($BUSYBOX_PATH/ls $VTOY_PATH/ventoy_dud*); do + $BUSYBOX_PATH/mkdir -p ${vtDud%.*}_mnt + if $BUSYBOX_PATH/mount $vtDud ${vtDud%.*}_mnt > /dev/null 2>&1; then + $BUSYBOX_PATH/cp -a ${vtDud%.*}_mnt ${vtDud%.*}_data + $BUSYBOX_PATH/umount ${vtDud%.*}_mnt + echo "dud: file://${vtDud%.*}_data" >> /linuxrc.config + else + echo "mount $vtDud failed" >> $VTLOG + fi + done + + $BUSYBOX_PATH/rmmod isofs >> $VTLOG 2>&1 + $BUSYBOX_PATH/rmmod squashfs >> $VTLOG 2>&1 + $BUSYBOX_PATH/rmmod loop >> $VTLOG 2>&1 + fi +fi #echo "Exec: /bin/sh $VTOY_PATH/hook/suse/cdrom-hook.sh" >> /info-ventoy #echo "install: hd:/?device=/dev/mapper/ventoy" >> /info-ventoy #$SED "1 iinfo: file:/info-ventoy" -i /linuxrc.config -ventoy_systemd_udevd_work_around -ventoy_add_udev_rule "$VTOY_PATH/hook/suse/udev_disk_hook.sh %k" +if [ -e /etc/initrd.functions ] && $GREP -q 'HPIP' /etc/initrd.functions; then + echo "HPIP" >> $VTLOG + $BUSYBOX_PATH/mkdir /dev + $BUSYBOX_PATH/mknod -m 660 /dev/console b 5 1 + $SED "/CD_DEVICES=/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/suse/disk_hook.sh" -i /etc/initrd.functions + $SED "/CD_DEVICES=/a CD_DEVICES=\"/dev/ventoy \$CD_DEVICES\"" -i /etc/initrd.functions +elif [ -f /scripts/udev_setup ]; then + echo "udev_setup" >> $VTLOG + echo "/ventoy/busybox/sh /ventoy/hook/suse/udev_setup_hook.sh" >> /scripts/udev_setup +else + echo "SUSE" >> $VTLOG + ventoy_systemd_udevd_work_around + ventoy_add_udev_rule "$VTOY_PATH/hook/suse/udev_disk_hook.sh %k" +fi diff --git a/IMG/cpio/ventoy/hook/t2/disk_hook.sh b/IMG/cpio/ventoy/hook/t2/disk_hook.sh new file mode 100644 index 00000000..d3b79a43 --- /dev/null +++ b/IMG/cpio/ventoy/hook/t2/disk_hook.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +modprobe dm-mod + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +mknod -m 0660 /dev/ventoy b $blkdev_num + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish + diff --git a/IMG/cpio/ventoy/hook/t2/ventoy-hook.sh b/IMG/cpio/ventoy/hook/t2/ventoy-hook.sh new file mode 100644 index 00000000..2329265c --- /dev/null +++ b/IMG/cpio/ventoy/hook/t2/ventoy-hook.sh @@ -0,0 +1,24 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/getdevice *devicefile/i $BUSYBOX_PATH/sh $VTOY_PATH/hook/t2/disk_hook.sh" -i /init +$SED "/getdevice *devicefile/a devicefile=/dev/ventoy" -i /init + diff --git a/IMG/cpio/ventoy/hook/tinycore/ventoy-disk.sh b/IMG/cpio/ventoy/hook/tinycore/ventoy-disk.sh new file mode 100644 index 00000000..90ebbafe --- /dev/null +++ b/IMG/cpio/ventoy/hook/tinycore/ventoy-disk.sh @@ -0,0 +1,68 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +if echo $vtdiskname | egrep -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then + vPart="${vtdiskname}p2" +else + vPart="${vtdiskname}2" +fi + +# TinyCore linux distro doesn't contain dmsetup, we use aoe here +sudo modprobe aoe aoe_iflist=lo +if [ -e /sys/module/aoe ]; then + VBLADE_BIN=$(ventoy_get_vblade_bin) + + sudo nohup $VBLADE_BIN -r -f $VTOY_PATH/ventoy_image_map 9 0 lo "$vtdiskname" > /dev/null & + sleep 2 + + while ! [ -b /dev/etherd/e9.0 ]; do + vtlog 'Wait for /dev/etherd/e9.0 ....' + sleep 2 + done + + sudo cp -a /dev/etherd/e9.0 "$vPart" + + ventoy_find_bin_run rebuildfstab +else + vterr "aoe driver module load failed..." +fi + +# OK finish +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/hook/tinycore/ventoy-hook.sh b/IMG/cpio/ventoy/hook/tinycore/ventoy-hook.sh index b7880309..2bd18b3e 100644 --- a/IMG/cpio/ventoy/hook/tinycore/ventoy-hook.sh +++ b/IMG/cpio/ventoy/hook/tinycore/ventoy-hook.sh @@ -19,6 +19,5 @@ . $VTOY_PATH/hook/ventoy-os-lib.sh -ventoy_systemd_udevd_work_around - -ventoy_add_udev_rule_with_name "$VTOY_PATH/hook/tinycore/udev_disk_hook.sh %k" "90-ventoy.rules" +$SED "/\[.*-n.*WAITUSB/i\WAITUSB=10" -i /etc/init.d/tc-config +$SED "/\[.*-n.*AOE/i\$VTOY_PATH/hook/tinycore/ventoy-disk.sh" -i /etc/init.d/tc-config diff --git a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh index c656c6fe..8b50cc61 100644 --- a/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh +++ b/IMG/cpio/ventoy/hook/ventoy-hook-lib.sh @@ -57,14 +57,14 @@ vterr() { is_ventoy_hook_finished() { - [ -e $VTOY_PATH/hook_finish ] + [ -e $VTOY_PATH/hook_finish ] } set_ventoy_hook_finish() { - echo 'Y' > $VTOY_PATH/hook_finish + echo 'Y' > $VTOY_PATH/hook_finish } -get_ventoy_disk_name() { +get_ventoy_disk_name() { line=$($VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param) if [ $? -eq 0 ]; then echo ${line%%#*} @@ -74,7 +74,7 @@ get_ventoy_disk_name() { } get_ventoy_iso_name() { - line=$($VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param) + line=$($VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param) if [ $? -eq 0 ]; then echo ${line##*#} else @@ -83,17 +83,41 @@ get_ventoy_iso_name() { } wait_for_usb_disk_ready() { - while [ -n "Y" ]; do - usb_disk=$(get_ventoy_disk_name) + vtloop=0 + while [ -n "Y" ]; do + usb_disk=$(get_ventoy_disk_name) vtlog "wait_for_usb_disk_ready $usb_disk ..." - if [ -e "${usb_disk}2" ]; then + if echo $usb_disk | $EGREP -q "nvme|mmc|nbd"; then + vtpart2=${usb_disk}p2 + else + vtpart2=${usb_disk}2 + fi + + if [ -e "${vtpart2}" ]; then vtlog "wait_for_usb_disk_ready $usb_disk finish" - break - else - $SLEEP 0.3 - fi - done + break + else + let vtloop=vtloop+1 + if [ $vtloop -gt 2 ]; then + if [ "$VTLOG" != "$VTOY_PATH/log" ]; then + $VTOY_PATH/tool/vtoydump -f /ventoy/ventoy_os_param -v > $VTLOG + fi + fi + $SLEEP 0.3 + fi + done +} + + +check_usb_disk_ready() { + if echo $1 | $EGREP -q "nvme|mmc|nbd"; then + vtpart2=${1}p2 + else + vtpart2=${1}2 + fi + + [ -e "${vtpart2}" ] } is_ventoy_disk() { @@ -105,7 +129,13 @@ is_ventoy_disk() { } not_ventoy_disk() { - if $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c "$1"; then + if echo $1 | $EGREP -q "nvme.*p$|mmc.*p$|nbd.*p$"; then + vtDiskName=${1:0:-1} + else + vtDiskName=$1 + fi + + if $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c "$vtDiskName"; then $BUSYBOX_PATH/false else $BUSYBOX_PATH/true @@ -343,6 +373,37 @@ extract_file_from_line() { fi } +extract_rpm_from_line() { + vtlog "extract_rpm_from_line $1 disk=#$2#" + + if ! [ -b "$2" ]; then + vterr "disk #$2# not exist" + return + fi + + sector=$(echo $1 | $AWK '{print $(NF-1)}') + length=$(echo $1 | $AWK '{print $NF}') + vtlog "sector=$sector length=$length" + + $VTOY_PATH/tool/vtoydm -e -f $VTOY_PATH/ventoy_image_map -d ${2} -s $sector -l $length -o /tmp/xxx.rpm + if [ -e /tmp/xxx.rpm ]; then + vtlog "extract rpm file from iso success" + else + vterr "extract rpm file from iso fail" + return + fi + + CURPWD=$($BUSYBOX_PATH/pwd) + + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/rpm + cd $VTOY_PATH/rpm + vtlog "extract rpm..." + $BUSYBOX_PATH/rpm2cpio /tmp/xxx.rpm | $BUSYBOX_PATH/cpio -idm 2>>$VTLOG + cd $CURPWD + + $BUSYBOX_PATH/rm -f /tmp/xxx.rpm +} + install_rpm_from_line() { vtlog "install_rpm_from_line $1 disk=#$2#" @@ -432,12 +493,21 @@ ventoy_create_persistent_link() { fi } -ventoy_udev_disk_common_hook() { +ventoy_udev_disk_common_hook() { + if echo $1 | $EGREP -q "nvme.*p[0-9]$|mmc.*p[0-9]$|nbd.*p[0-9]$"; then + VTDISK="${1:0:-2}" + else + VTDISK="${1:0:-1}" + fi - VTDISK="${1:0:-1}" + if [ -e /vtoy/vtoy ]; then + VTRWMOD="" + else + VTRWMOD="--readonly" + fi # create device mapper for iso image file - if create_ventoy_device_mapper "/dev/$VTDISK" --readonly; then + if create_ventoy_device_mapper "/dev/$VTDISK" $VTRWMOD; then vtlog "==== create ventoy device mapper success ====" else vtlog "==== create ventoy device mapper failed ====" @@ -453,7 +523,7 @@ ventoy_udev_disk_common_hook() { done fi - if create_ventoy_device_mapper "/dev/$VTDISK" --readonly; then + if create_ventoy_device_mapper "/dev/$VTDISK" $VTRWMOD; then vtlog "==== create ventoy device mapper success after retry ====" else vtlog "==== create ventoy device mapper failed after retry ====" @@ -473,13 +543,37 @@ ventoy_udev_disk_common_hook() { fi } +ventoy_create_dev_ventoy_part() { + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 0666 /dev/ventoy b $blkdev_num + + if [ -e /vtoy_dm_table ]; then + vtPartid=1 + + $CAT /vtoy_dm_table | while read vtline; do + echo $vtline > /ventoy/dm_table_part${vtPartid} + $VTOY_PATH/tool/dmsetup create ventoy${vtPartid} /ventoy/dm_table_part${vtPartid} + + blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy${vtPartid} | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') + $BUSYBOX_PATH/mknod -m 0666 /dev/ventoy${vtPartid} b $blkdev_num + + vtPartid=$(expr $vtPartid + 1) + done + fi +} is_inotify_ventoy_part() { - if echo $1 | grep -q "2$"; then + if echo $1 | $GREP -q "2$"; then if ! [ -e /sys/block/$1 ]; then if [ -e /sys/class/block/$1 ]; then - if [ -e /dev/${1:0:-1} ]; then - $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c ${1:0:-1} + if echo $1 | $EGREP -q "nvme|mmc|nbd"; then + vtShortName=${1:0:-2} + else + vtShortName=${1:0:-1} + fi + + if [ -e /dev/$vtShortName ]; then + $VTOY_PATH/tool/vtoydump -f $VTOY_PATH/ventoy_os_param -c $vtShortName return fi fi @@ -508,3 +602,26 @@ ventoy_swap_device() { mv $VTOY_PATH/swap_tmp_dev $2 } +ventoy_extract_vtloopex() { + vtCurPwd=$PWD + $BUSYBOX_PATH/mkdir -p $VTOY_PATH/partmnt $VTOY_PATH/vtloopex + $BUSYBOX_PATH/mount -o ro -t vfat $1 $VTOY_PATH/partmnt + cd $VTOY_PATH/vtloopex + $CAT $VTOY_PATH/partmnt/ventoy/vtloopex.cpio | $BUSYBOX_PATH/cpio -idm >> $VTLOG 2>&1 + $BUSYBOX_PATH/umount $VTOY_PATH/partmnt + $BUSYBOX_PATH/rm -rf $VTOY_PATH/partmnt + + if [ -n "$2" ]; then + cd $VTOY_PATH/vtloopex/$2/ + $BUSYBOX_PATH/tar -xJf vtloopex.tar.xz + fi + + cd $vtCurPwd +} + +ventoy_check_install_module_xz() { + if [ -f "${1}.xz" ]; then + $BUSYBOX_PATH/xz -d "${1}.xz" + $BUSYBOX_PATH/insmod "$1" + fi +} diff --git a/IMG/cpio/ventoy/hook/ventoy-os-lib.sh b/IMG/cpio/ventoy/hook/ventoy-os-lib.sh index 05533347..dbd015f8 100644 --- a/IMG/cpio/ventoy/hook/ventoy-os-lib.sh +++ b/IMG/cpio/ventoy/hook/ventoy-os-lib.sh @@ -105,3 +105,19 @@ ventoy_print_yum_repo() { ventoy_set_inotify_script() { echo $VTOY_PATH/hook/$1 > $VTOY_PATH/inotifyd-hook-script.txt } + +ventoy_set_loop_inotify_script() { + echo $VTOY_PATH/loop/$1 > $VTOY_PATH/inotifyd-loop-script.txt +} + +ventoy_check_insmod() { + if [ -e $1 ]; then + $BUSYBOX_PATH/insmod $1 + fi +} + +ventoy_check_mount() { + if [ -e $1 ]; then + $BUSYBOX_PATH/mount $1 $2 + fi +} diff --git a/IMG/cpio/ventoy/hook/vine/dev-listen.sh b/IMG/cpio/ventoy/hook/vine/dev-listen.sh new file mode 100644 index 00000000..a358fc11 --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/dev-listen.sh @@ -0,0 +1,63 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vine_wait_for_exist() { + while [ -n "1" ]; do + if [ -e $1 ]; then + break + else + $SLEEP 0.5 + fi + done +} + +vine_wait_for_exist /dev/null +vine_wait_for_exist /sys/block +vine_wait_for_exist /proc/ide + + +while [ -n "Y" ]; do + vtdiskname=$(get_ventoy_disk_name) + if [ "$vtdiskname" != "unknown" ]; then + break + else + $SLEEP 0.5 + fi +done + +vtshortdev=${vtdiskname#/dev/} + +if ! [ -b $vtdiskname ]; then + blkdev=$($CAT /sys/class/block/$vtshortdev/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 $vtdiskname b $blkdev +fi + +if ! [ -b "${vtdiskname}1" ]; then + blkdev=$($CAT /sys/class/block/${vtshortdev}1/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 "${vtdiskname}1" b $blkdev +fi + +if ! [ -b "${vtdiskname}2" ]; then + blkdev=$($CAT /sys/class/block/${vtshortdev}2/dev | $SED 's/:/ /g') + $BUSYBOX_PATH/mknod -m 0660 "${vtdiskname}2" b $blkdev +fi + +$BUSYBOX_PATH/sh $VTOY_PATH/hook/vine/udev_disk_hook.sh "${vtdiskname#/dev/}2" diff --git a/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh b/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh new file mode 100644 index 00000000..1ea6d671 --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/udev_disk_hook.sh @@ -0,0 +1,95 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +ventoy_os_install_dmsetup_by_ko() { + vtlog "ventoy_os_install_dmsetup_by_ko $1" + + vtVer=$($BUSYBOX_PATH/uname -r) + if $BUSYBOX_PATH/uname -m | $GREP -q 64; then + vtBit=64 + else + vtBit=32 + fi + + ventoy_extract_vtloopex $1 vine + vtLoopExDir=$VTOY_PATH/vtloopex/vine/vtloopex + + if [ -e $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz ]; then + $BUSYBOX_PATH/xz -d $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko.xz + insmod $vtLoopExDir/dm-mod/$vtVer/$vtBit/dm-mod.ko + fi +} + +ventoy_os_install_dmsetup_by_rpm() { + vtlog "ventoy_os_install_dmsetup_by_rpm $1" + + vt_usb_disk=$1 + + # dump iso file location + $VTOY_PATH/tool/vtoydm -i -f $VTOY_PATH/ventoy_image_map -d ${vt_usb_disk} > $VTOY_PATH/iso_file_list + + # install dmsetup + LINE=$($GREP 'kernel-[0-9].*\.rpm' $VTOY_PATH/iso_file_list) + if [ $? -eq 0 ]; then + extract_rpm_from_line "$LINE" ${vt_usb_disk} + fi + + vtKoName=$($BUSYBOX_PATH/find $VTOY_PATH/rpm/ -name dm-mod.ko*) + vtlog "vtKoName=$vtKoName" + + insmod $vtKoName + + $BUSYBOX_PATH/rm -rf $VTOY_PATH/rpm/ +} + +if is_ventoy_hook_finished || not_ventoy_disk "${1:0:-1}"; then + exit 0 +fi + +ventoy_os_install_dmsetup_by_ko "/dev/$1" +if $GREP -q 'device.mapper' /proc/devices; then + vtlog "device-mapper module install OK" +else + ventoy_os_install_dmsetup_by_rpm "/dev/${1:0:-1}" +fi + +ventoy_udev_disk_common_hook $* + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +blkdev_num_dev=$($VTOY_PATH/tool/dmsetup ls | $GREP ventoy | $SED 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1 \2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) + +[ -b /dev/$vtDM ] || $BUSYBOX_PATH/mknod -m 0660 /dev/$vtDM b $blkdev_num_dev +$BUSYBOX_PATH/rm -rf /dev/mapper + +#Create a fake IDE-CDROM driver can't be ide-scsi /proc has been patched to /vtoy +$BUSYBOX_PATH/mkdir -p /vtoy +$BUSYBOX_PATH/cp -a /proc/ide /vtoy/ +$BUSYBOX_PATH/mkdir -p /vtoy/ide/aztcd + +echo 'ide' > /vtoy/ide/aztcd/driver +echo 'cdrom' > /vtoy/ide/aztcd/media + + +# OK finish +set_ventoy_hook_finish + +exit 0 diff --git a/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh b/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh new file mode 100644 index 00000000..d10c2ea1 --- /dev/null +++ b/IMG/cpio/ventoy/hook/vine/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/cp -a /sbin/loader /sbin/loader_bk +$VTOY_PATH/tool/vine_patch_loader /sbin/loader 253 -v >> $VTLOG + +$BUSYBOX_PATH/mknod -m 0660 /dev/null c 1 3 +$VTOY_PATH/hook/vine/dev-listen.sh & diff --git a/IMG/cpio/ventoy/hook/wifislax/disk_hook.sh b/IMG/cpio/ventoy/hook/wifislax/disk_hook.sh new file mode 100644 index 00000000..aff0f98b --- /dev/null +++ b/IMG/cpio/ventoy/hook/wifislax/disk_hook.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtlog "##### $0 $* #####" + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +while true; do + if blkid | grep -q '/dev/dm'; then + vtlog 'Find /dev/dm ...' + break + else + vtlog 'Wait /dev/dm ...' + sleep 0.3 + fi +done + + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/hook/wifislax/ventoy-hook.sh b/IMG/cpio/ventoy/hook/wifislax/ventoy-hook.sh new file mode 100644 index 00000000..cc0be889 --- /dev/null +++ b/IMG/cpio/ventoy/hook/wifislax/ventoy-hook.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +if [ -e /linuxrc ]; then + INITFILE=/linuxrc +elif [ -e /init ]; then + INITFILE=/init +fi + +$SED "/mount.*devtmpfs/a $BUSYBOX_PATH/sh $VTOY_PATH/hook/wifislax/disk_hook.sh" -i $INITFILE + +#replace original blkid +$BUSYBOX_PATH/rm -f /usr/bin/blkid +$BUSYBOX_PATH/cp -a $BUSYBOX_PATH/blkid /usr/bin/blkid diff --git a/IMG/cpio/ventoy/init b/IMG/cpio/ventoy/init index 61659fc3..b1040bcf 100644 --- a/IMG/cpio/ventoy/init +++ b/IMG/cpio/ventoy/init @@ -23,17 +23,27 @@ # Step 1 : parse kernel debug parameter # # # #################################################################### -[ -d /proc ] || mkdir /proc; mount -t proc proc /proc -vtcmdline=$(cat /proc/cmdline) -vtkerver=$(cat /proc/version) -umount /proc; rm -rf /proc + +if ! [ -d /proc ]; then + mkdir /proc + vtrmproc='Y' +fi + +mount -t proc proc /proc +export vtcmdline=$(cat /proc/cmdline) +export vtkerver=$(cat /proc/version) +umount /proc; + +if [ "$vtrmproc" = "Y" ]; then + rm -rf /proc +fi echo "kenel version=$vtkerver" >>$VTLOG echo "kenel cmdline=$vtcmdline" >>$VTLOG #break here for debug if [ "$VTOY_BREAK_LEVEL" = "01" ] || [ "$VTOY_BREAK_LEVEL" = "11" ]; then - sleep 5 + sleep 5 echo -e "\n\n\033[32m ################################################# \033[0m" echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" echo -e "\033[32m ################################################# \033[0m \n" @@ -44,138 +54,11 @@ if [ "$VTOY_BREAK_LEVEL" = "01" ] || [ "$VTOY_BREAK_LEVEL" = "11" ]; then exec $BUSYBOX_PATH/sh fi - -#################################################################### -# # -# Step 2 : extract real initramfs to / # -# # -#################################################################### -cd / -rm -rf /init /linuxrc /dev/ /root - -vtSbinFileNum=$(ls -1 /sbin | wc -l) -if [ $vtSbinFileNum -eq 1 ]; then - echo "remove whole sbin directory" >> $VTLOG - rm -rf /sbin +if echo $vtcmdline | grep -q 'rdinit=/vtoy/vtoy'; then + echo "handover to init_loop" >>$VTLOG + rm -f /xxxx /vtoyxrc + exec $BUSYBOX_PATH/sh $VTOY_PATH/init_loop else - echo "remove only sbin/init file" >> $VTLOG - ls -l /sbin >> $VTLOG - rm -f /sbin/init + echo "handover to init_chain" >>$VTLOG + exec $BUSYBOX_PATH/sh $VTOY_PATH/init_chain fi - -ventoy_is_initrd_ramdisk() { - #As I known, PCLinuxOS use ramdisk - if echo $vtkerver | grep -i -q 'PCLinuxOS'; then - true - else - false - fi -} - -# param: file skip magic tmp -ventoy_unpack_initramfs() { - vtfile=$1; vtskip=$2; vtmagic=$3; vttmp=$4 - echo "=====ventoy_unpack_initramfs: #$*#" >> $VTLOG - - #special process - #if [ "${vtmagic:0:4}" = '5678' ]; then - # echo -en '\x1F\x8B' | dd status=none of=$vtfile bs=1 count=2 conv=notrunc - # vtmagic='1F8B' - #fi - - for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat'; do - if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then - echo "vtx=$vtx" >> $VTLOG - if [ $vtskip -eq 0 ]; then - if [ "${vtx:5}" = "xzcat" ]; then - rm -f $VTOY_PATH/xzlog - ${vtx:5} $vtfile 2> $VTOY_PATH/xzlog | (cpio -idmu 2>>$VTLOG; cat > $vttmp) - - if grep -q 'corrupted data' $VTOY_PATH/xzlog; then - echo 'xzcat failed, now try xzminidec...' >> $VTLOG - cat $vtfile | xzminidec | (cpio -idmu 2>>$VTLOG; cat > $vttmp) - fi - - else - ${vtx:5} $vtfile | (cpio -idmu 2>>$VTLOG; cat > $vttmp) - fi - else - dd if=$vtfile skip=$vtskip iflag=skip_bytes status=none | ${vtx:5} | (cpio -idmu 2>>$VTLOG; cat > $vttmp) - fi - break - fi - done -} - -# param: file magic tmp -ventoy_unpack_initrd() { - vtfile=$1; vtmagic=$2; vttmp=$3 - echo "=====ventoy_unpack_initrd: #$*#" >> $VTLOG - - for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat'; do - if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then - echo "vtx=$vtx" >> $VTLOG - ${vtx:5} $vtfile > $vttmp - break - fi - done -} - - -# This export is for busybox cpio command -export EXTRACT_UNSAFE_SYMLINKS=1 - -for vtfile in $(ls /initrd*); do - #decompress first initrd - vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $vtfile) - - if ventoy_is_initrd_ramdisk; then - ventoy_unpack_initrd $vtfile $vtmagic ${vtfile}_tmp - mv ${vtfile}_tmp $vtfile - break - else - ventoy_unpack_initramfs $vtfile 0 $vtmagic ${vtfile}_tmp - fi - - #only for cpio,cpio,...,initrd sequence, initrd,cpio or initrd,initrd sequence is not supported - while [ -e ${vtfile}_tmp ] && [ $(stat -c '%s' ${vtfile}_tmp) -gt 512 ]; do - mv ${vtfile}_tmp $vtfile - vtdump=$(hexdump -n 512 -e '512/1 "%02X"' $vtfile) - vtmagic=$(echo $vtdump | sed 's/^\(00\)*//') - let vtoffset="(${#vtdump}-${#vtmagic})/2" - - if [ -z "$vtmagic" ]; then - echo "terminate with all zero data file" >> $VTLOG - break - fi - - ventoy_unpack_initramfs $vtfile $vtoffset ${vtmagic:0:4} ${vtfile}_tmp - done - - rm -f $vtfile ${vtfile}_tmp -done - - -#break here for debug -if [ "$VTOY_BREAK_LEVEL" = "02" ] || [ "$VTOY_BREAK_LEVEL" = "12" ]; then - sleep 5 - echo -e "\n\n\033[32m ################################################# \033[0m" - echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" - echo -e "\033[32m ################################################# \033[0m \n" - if [ "$VTOY_BREAK_LEVEL" = "12" ]; then - cat $VTOY_PATH/log - fi - exec $BUSYBOX_PATH/sh -fi - - -#################################################################### -# # -# Step 3 : Hand over to ventoy.sh # -# # -#################################################################### -echo "Now hand over to ventoy.sh" >>$VTLOG -. $VTOY_PATH/tool/vtoytool_install.sh - -export PATH=$VTOY_ORG_PATH -exec $BUSYBOX_PATH/sh $VTOY_PATH/ventoy.sh diff --git a/IMG/cpio/ventoy/init_chain b/IMG/cpio/ventoy/init_chain new file mode 100644 index 00000000..18dba2c5 --- /dev/null +++ b/IMG/cpio/ventoy/init_chain @@ -0,0 +1,201 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + + +#################################################################### +# # +# Step 1 : extract real initramfs to / # +# # +#################################################################### +cd / +rm -rf /init /linuxrc /dev/ /root + +vtSbinFileNum=$(ls -1 /sbin | wc -l) +if [ $vtSbinFileNum -eq 1 ]; then + echo "remove whole sbin directory" >> $VTLOG + rm -rf /sbin +else + echo "remove only sbin/init file" >> $VTLOG + ls -l /sbin >> $VTLOG + rm -f /sbin/init +fi + +ventoy_is_initrd_ramdisk() { + #As I known, PCLinuxOS/smgl use ramdisk + if echo $vtkerver | grep -i -q 'PCLinuxOS'; then + true + elif echo $vtkerver | grep -i -q 'SMGL-'; then + true + else + false + fi +} + +ventoy_mount_squashfs() { + mkdir /dev + mount -t devtmpfs devtmpfs /dev + dd if=$1 of=/dev/ram0 status=none + umount /dev && rm -rf /dev +} + +# param: file skip magic tmp +ventoy_unpack_initramfs() { + vtfile=$1; vtskip=$2; vtmagic=$3; vttmp=$4 + echo "=====ventoy_unpack_initramfs: #$*#" >> $VTLOG + + #special process + #if [ "${vtmagic:0:4}" = '5678' ]; then + # echo -en '\x1F\x8B' | dd status=none of=$vtfile bs=1 count=2 conv=notrunc + # vtmagic='1F8B' + #fi + + if [ "${vtmagic:0:4}" = '6873' ]; then + ventoy_mount_squashfs $vtfile + return + fi + + for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat' '4C5A lunzip -c'; do + if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then + echo "vtx=$vtx" >> $VTLOG + if [ $vtskip -eq 0 ]; then + if [ "${vtx:5}" = "xzcat" ]; then + rm -f $VTOY_PATH/xzlog + ${vtx:5} $vtfile 2> $VTOY_PATH/xzlog | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + + if grep -q 'corrupted data' $VTOY_PATH/xzlog; then + echo 'xzcat failed, now try xzminidec...' >> $VTLOG + cat $vtfile | xzminidec | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + fi + + else + ${vtx:5} $vtfile | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + fi + else + dd if=$vtfile skip=$vtskip iflag=skip_bytes status=none | ${vtx:5} | (cpio -idmu 2>>$VTLOG; cat > $vttmp) + fi + break + fi + done +} + +# param: file magic tmp +ventoy_unpack_initrd() { + vtfile=$1; vtmagic=$2; vttmp=$3 + echo "=====ventoy_unpack_initrd: #$*#" >> $VTLOG + + for vtx in '1F8B zcat' '1F9E zcat' '425A bzcat' '5D00 lzcat' 'FD37 xzcat' '894C lzopcat' '0221 lz4cat' '28B5 zstdcat' '3037 cat'; do + if [ "${vtx:0:4}" = "${vtmagic:0:4}" ]; then + echo "vtx=$vtx" >> $VTLOG + ${vtx:5} $vtfile > $vttmp + break + fi + done +} + + +# This export is for busybox cpio command +export EXTRACT_UNSAFE_SYMLINKS=1 + +for vtfile in $(ls /initrd*); do + #decompress first initrd + vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $vtfile) + + if ventoy_is_initrd_ramdisk; then + ventoy_unpack_initrd $vtfile $vtmagic ${vtfile}_tmp + mv ${vtfile}_tmp $vtfile + break + else + ventoy_unpack_initramfs $vtfile 0 $vtmagic ${vtfile}_tmp + fi + + #only for cpio,cpio,...,initrd sequence, initrd,cpio or initrd,initrd sequence is not supported + while [ -e ${vtfile}_tmp ] && [ $(stat -c '%s' ${vtfile}_tmp) -gt 512 ]; do + mv ${vtfile}_tmp $vtfile + vtdump=$(hexdump -n 512 -e '512/1 "%02X"' $vtfile) + vtmagic=$(echo $vtdump | sed 's/^\(00\)*//') + let vtoffset="(${#vtdump}-${#vtmagic})/2" + + if [ -z "$vtmagic" ]; then + echo "terminate with all zero data file" >> $VTLOG + break + fi + + ventoy_unpack_initramfs $vtfile $vtoffset ${vtmagic:0:4} ${vtfile}_tmp + done + + rm -f $vtfile ${vtfile}_tmp +done + + +#break here for debug +if [ "$VTOY_BREAK_LEVEL" = "02" ] || [ "$VTOY_BREAK_LEVEL" = "12" ]; then + sleep 5 + echo -e "\n\n\033[32m ################################################# \033[0m" + echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" + echo -e "\033[32m ################################################# \033[0m \n" + if [ "$VTOY_BREAK_LEVEL" = "12" ]; then + cat $VTOY_PATH/log + fi + exec $BUSYBOX_PATH/sh +fi + + +#################################################################### +# # +# Step 3 : Extract injection archive # +# # +#################################################################### +ventoy_unpack_injection() { + vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $VTOY_PATH/ventoy_injection) + echo "ventoy_unpack_injection vtmagic=$vtmagic ..." + + if [ "1F8B" = "$vtmagic" ] || [ "1F9E" = "$vtmagic" ]; then + echo "tar.gz tar -xzvf" + tar -xzvf $VTOY_PATH/ventoy_injection -C / + elif [ "425A" = "$vtmagic" ]; then + echo "tar.bz2 tar -xjvf" + tar -xjvf $VTOY_PATH/ventoy_injection -C / + elif [ "FD37" = "$vtmagic" ]; then + echo "tar.xz tar -xJvf" + tar -xJvf $VTOY_PATH/ventoy_injection -C / + elif [ "5D00" = "$vtmagic" ]; then + echo "tar.lzma tar -xavf" + tar -xavf $VTOY_PATH/ventoy_injection -C / + else + echo "unzip -o" + unzip -o $VTOY_PATH/ventoy_injection -d / + fi +} + +if [ -e $VTOY_PATH/ventoy_injection ]; then + echo "### decompress injection ... ###" >>$VTLOG + ventoy_unpack_injection > $VTOY_PATH/injection.log 2>&1 +fi + + +#################################################################### +# # +# Step 4 : Hand over to ventoy_chain.sh # +# # +#################################################################### +echo "Now hand over to ventoy.sh" >>$VTLOG +. $VTOY_PATH/tool/vtoytool_install.sh + +export PATH=$VTOY_ORG_PATH +exec $BUSYBOX_PATH/sh $VTOY_PATH/ventoy_chain.sh diff --git a/IMG/cpio/ventoy/init_loop b/IMG/cpio/ventoy/init_loop new file mode 100644 index 00000000..92886330 --- /dev/null +++ b/IMG/cpio/ventoy/init_loop @@ -0,0 +1,63 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + + +#################################################################### +# # +# Step 1 : Extract injection archive # +# # +#################################################################### +ventoy_unpack_injection() { + vtmagic=$(hexdump -n 2 -e '2/1 "%02X"' $VTOY_PATH/ventoy_injection) + echo "ventoy_unpack_injection vtmagic=$vtmagic ..." + + if [ "1F8B" = "$vtmagic" ] || [ "1F9E" = "$vtmagic" ]; then + echo "tar.gz tar -xzvf" + tar -xzvf $VTOY_PATH/ventoy_injection -C / + elif [ "425A" = "$vtmagic" ]; then + echo "tar.bz2 tar -xjvf" + tar -xjvf $VTOY_PATH/ventoy_injection -C / + elif [ "FD37" = "$vtmagic" ]; then + echo "tar.xz tar -xJvf" + tar -xJvf $VTOY_PATH/ventoy_injection -C / + elif [ "5D00" = "$vtmagic" ]; then + echo "tar.lzma tar -xavf" + tar -xavf $VTOY_PATH/ventoy_injection -C / + else + echo "unzip -o" + unzip -o $VTOY_PATH/ventoy_injection -d / + fi +} + +if [ -e $VTOY_PATH/ventoy_injection ]; then + echo "### decompress injection ... ###" >>$VTLOG + ventoy_unpack_injection > $VTOY_PATH/injection.log 2>&1 +fi + + +#################################################################### +# # +# Step 3 : Hand over to ventoy_loop.sh # +# # +#################################################################### +echo "Now hand over to ventoy.sh" >>$VTLOG +. $VTOY_PATH/tool/vtoytool_install.sh + +export PATH=$VTOY_ORG_PATH +exec $BUSYBOX_PATH/sh $VTOY_PATH/ventoy_loop.sh diff --git a/IMG/cpio/ventoy/loop/LibreELEC/ventoy-disk.sh b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-disk.sh new file mode 100644 index 00000000..027a4c64 --- /dev/null +++ b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-disk.sh @@ -0,0 +1,62 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtKerVer=$(uname -r) +if uname -m | grep -q 64; then + vtBit=64 +else + vtBit=32 +fi + +xz -d $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko.xz +insmod $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko + + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +mkdir /ventoy/mnt +mount /dev/ventoy2 /ventoy/mnt +rm -f /ventoy/mnt/.please_resize_me +sync +umount /ventoy/mnt + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/LibreELEC/ventoy-hook.sh b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-hook.sh new file mode 100644 index 00000000..16366326 --- /dev/null +++ b/IMG/cpio/ventoy/loop/LibreELEC/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount_flash.*{/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/LibreELEC/ventoy-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/loop/batocera/ventoy-disk.sh b/IMG/cpio/ventoy/loop/batocera/ventoy-disk.sh new file mode 100644 index 00000000..08c9d73d --- /dev/null +++ b/IMG/cpio/ventoy/loop/batocera/ventoy-disk.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/batocera/ventoy-hook.sh b/IMG/cpio/ventoy/loop/batocera/ventoy-hook.sh new file mode 100644 index 00000000..2bb7c8e7 --- /dev/null +++ b/IMG/cpio/ventoy/loop/batocera/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount.*devtmpfs/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/batocera/ventoy-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/loop/easyos/ventoy-disk.sh b/IMG/cpio/ventoy/loop/easyos/ventoy-disk.sh new file mode 100644 index 00000000..2fa00497 --- /dev/null +++ b/IMG/cpio/ventoy/loop/easyos/ventoy-disk.sh @@ -0,0 +1,53 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +$BUSYBOX_PATH/insmod $VTOY_PATH/modules/dax.ko +$BUSYBOX_PATH/insmod $VTOY_PATH/modules/dm-mod.ko + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n $vtDM > /ventoy/vtDM + +ventoy_create_dev_ventoy_part +mdev -s + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/easyos/ventoy-hook.sh b/IMG/cpio/ventoy/loop/easyos/ventoy-hook.sh new file mode 100644 index 00000000..7310b0d7 --- /dev/null +++ b/IMG/cpio/ventoy/loop/easyos/ventoy-hook.sh @@ -0,0 +1,32 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/find drives/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/easyos/ventoy-disk.sh; vtDM=\$(cat /ventoy/vtDM)" -i /init + +$SED "1a boot_dev=ventoy1;wkg_dev=ventoy2" -i /init + +#check for ssd will read /sys/block/ventoy, will no exist, need a workaround +$SED "s#/sys/block/\${WKG_DRV}/#/sys/block/\$vtDM/#g" -i /init + +#skip the resizing process, can't resizing partition +$SED "s#640M#0M#g" -i /init + + diff --git a/IMG/cpio/ventoy/loop/endless/ventoy-hook.sh b/IMG/cpio/ventoy/loop/endless/ventoy-hook.sh new file mode 100644 index 00000000..7d0820d6 --- /dev/null +++ b/IMG/cpio/ventoy/loop/endless/ventoy-hook.sh @@ -0,0 +1,36 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +END_UDEV_DIR=$(ventoy_get_udev_conf_dir) + +if ! [ -e "$END_UDEV_DIR/10-dm.rules" ]; then + echo 'Copy dm rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/10-dm.rules > "$END_UDEV_DIR/10-dm.rules" +fi + +if ! [ -e "$END_UDEV_DIR/13-dm-disk.rules" ]; then + echo 'Copy dm-disk rule file' >> $VTLOG + $CAT $VTOY_PATH/hook/default/13-dm-disk.rules > "$END_UDEV_DIR/13-dm-disk.rules" +fi + +ventoy_set_loop_inotify_script endless/ventoy-inotifyd-hook.sh +$BUSYBOX_PATH/cp -a $VTOY_PATH/loop/endless/ventoy-inotifyd-start.sh /lib/dracut/hooks/pre-udev/01-ventoy-inotifyd-start.sh + diff --git a/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-hook.sh b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-hook.sh new file mode 100644 index 00000000..cc9050da --- /dev/null +++ b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-hook.sh @@ -0,0 +1,37 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +VTPATH_OLD=$PATH; PATH=$PATH:$BUSYBOX_PATH:$VTOY_PATH/tool + +if is_inotify_ventoy_part $3; then + vtlog "##### INOTIFYD: $2/$3 is created (YES) ..." + + ventoy_udev_disk_common_hook "$3" "noreplace" + set_ventoy_hook_finish +else + vtlog "##### INOTIFYD: $2/$3 is created (NO) ..." +fi + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-start.sh b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-start.sh new file mode 100644 index 00000000..6375dc5e --- /dev/null +++ b/IMG/cpio/ventoy/loop/endless/ventoy-inotifyd-start.sh @@ -0,0 +1,31 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +vtHook=$($CAT $VTOY_PATH/inotifyd-loop-script.txt) + +vtdisk=$(get_ventoy_disk_name) +if [ "$vtdisk" = "unknown" ]; then + vtlog "... start inotifyd listen $vtHook ..." + $BUSYBOX_PATH/nohup $VTOY_PATH/tool/inotifyd $vtHook /dev:n 2>&- & +else + vtlog "... $vtdisk already exist ..." + $BUSYBOX_PATH/sh $vtHook n /dev "${vtdisk#/dev/}2" +fi diff --git a/IMG/cpio/ventoy/loop/freedombox/ventoy-disk.sh b/IMG/cpio/ventoy/loop/freedombox/ventoy-disk.sh new file mode 100644 index 00000000..5ebc7f96 --- /dev/null +++ b/IMG/cpio/ventoy/loop/freedombox/ventoy-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +insmod $VTOY_PATH/modules/dm-mod.ko + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/freedombox/ventoy-hook.sh b/IMG/cpio/ventoy/loop/freedombox/ventoy-hook.sh new file mode 100644 index 00000000..25853914 --- /dev/null +++ b/IMG/cpio/ventoy/loop/freedombox/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/local_mount_root *$/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/freedombox/ventoy-disk.sh" -i /scripts/local diff --git a/IMG/cpio/ventoy/loop/lakka/ventoy-disk.sh b/IMG/cpio/ventoy/loop/lakka/ventoy-disk.sh new file mode 100644 index 00000000..42a8e7fe --- /dev/null +++ b/IMG/cpio/ventoy/loop/lakka/ventoy-disk.sh @@ -0,0 +1,72 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +vtKerVer=$(uname -r) +if uname -m | grep -q 64; then + vtBit=64 +else + vtBit=32 +fi + +if grep -q "device-mapper" /proc/devices; then + vtlog "device-mapper enabled by system" +else + if [ -f $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dax.ko.xz ]; then + xz -d $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dax.ko.xz + insmod $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dax.ko + fi + + if [ -f $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko.xz ]; then + xz -d $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko.xz + insmod $VTOY_PATH/vtloopex/dm-mod/$vtKerVer/$vtBit/dm-mod.ko + fi +fi + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +mkdir /ventoy/mnt +mount /dev/ventoy2 /ventoy/mnt +rm -f /ventoy/mnt/.please_resize_me +sync +umount /ventoy/mnt + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/lakka/ventoy-hook.sh b/IMG/cpio/ventoy/loop/lakka/ventoy-hook.sh new file mode 100644 index 00000000..0fd01807 --- /dev/null +++ b/IMG/cpio/ventoy/loop/lakka/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount_flash.*{/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/lakka/ventoy-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/loop/openwrt/ventoy-disk.sh b/IMG/cpio/ventoy/loop/openwrt/ventoy-disk.sh new file mode 100644 index 00000000..52f46d66 --- /dev/null +++ b/IMG/cpio/ventoy/loop/openwrt/ventoy-disk.sh @@ -0,0 +1,131 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +check_mkdev_node() { + for i in $(ls /sys/class/block/); do + if ! [ -e /dev/$i ]; then + blkdev_num=$(sed 's/:/ /g' /sys/class/block/$i/dev) + vtlog "mknod -m 0666 /dev/$i b $blkdev_num" + mknod -m 0666 /dev/$i b $blkdev_num + fi + done +} + +check_insmod() { + if [ -f "$1" ]; then + vtlog "insmod $1" + insmod "$1" >> $VTOY_PATH/log 2>&1 + else + vtlog "$1 not exist" + fi +} + +wrt_insmod() { + kbit=$1 + kv=$(uname -r) + + vtlog "insmod $kv $kbit" + + check_insmod /ventoy_openwrt/$kv/$kbit/dax.ko + check_insmod /ventoy_openwrt/$kv/$kbit/dm-mod.ko +} + +insmod_dm_mod() { + if grep -q "device-mapper" /proc/devices; then + vtlog "device-mapper enabled by system 0" + return + fi + + check_insmod /ventoy/modules/dax.ko + check_insmod /ventoy/modules/dm-mod.ko + + if grep -q "device-mapper" /proc/devices; then + vtlog "device-mapper enabled by system 1" + return + fi + + if [ -f /ventoy_openwrt.xz ]; then + tar xf /ventoy_openwrt.xz -C / + rm -f /ventoy_openwrt.xz + fi + + if uname -m | egrep -q "amd64|x86_64"; then + wrt_insmod 64 + else + wrt_insmod generic + if lsmod | grep -q 'dm-mod'; then + vterr "insmod generic failed" + else + wrt_insmod legacy + fi + fi +} + +insmod_dm_mod + +check_mkdev_node +sleep 1 + +while [ -n "Y" ]; do + vtusb_disk=$(get_ventoy_disk_name) + if check_usb_disk_ready "$vtusb_disk"; then + vtlog "get_ventoy_disk_name $vtusb_disk ready" + break; + else + vtlog "get_ventoy_disk_name $vtusb_disk not ready" + sleep 2 + check_mkdev_node + fi +done + + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +blkdev_num=$($VTOY_PATH/tool/dmsetup ls | grep ventoy | sed 's/.*(\([0-9][0-9]*\),.*\([0-9][0-9]*\).*/\1:\2/') +vtDM=$(ventoy_find_dm_id ${blkdev_num}) +echo -n $vtDM > /ventoy/vtDM + +ventoy_create_dev_ventoy_part +mdev -s +check_mkdev_node + + +mkdir /ventoy_rdroot +mount /dev/ventoy2 /ventoy_rdroot + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/openwrt/ventoy-hook.sh b/IMG/cpio/ventoy/loop/openwrt/ventoy-hook.sh new file mode 100644 index 00000000..f6c1c8c6 --- /dev/null +++ b/IMG/cpio/ventoy/loop/openwrt/ventoy-hook.sh @@ -0,0 +1,28 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +mkdir /sys +mount -t sysfs sys /sys +mdev -s + +sh $VTOY_PATH/loop/openwrt/ventoy-disk.sh diff --git a/IMG/cpio/ventoy/loop/paldo/ventoy-disk.sh b/IMG/cpio/ventoy/loop/paldo/ventoy-disk.sh new file mode 100644 index 00000000..ef45f04a --- /dev/null +++ b/IMG/cpio/ventoy/loop/paldo/ventoy-disk.sh @@ -0,0 +1,47 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +modprobe dm-mod + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/paldo/ventoy-hook.sh b/IMG/cpio/ventoy/loop/paldo/ventoy-hook.sh new file mode 100644 index 00000000..efdff627 --- /dev/null +++ b/IMG/cpio/ventoy/loop/paldo/ventoy-hook.sh @@ -0,0 +1,22 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/for *dev *in .*root/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/paldo/ventoy-disk.sh" -i /init diff --git a/IMG/cpio/ventoy/loop/recalbox/ventoy-disk.sh b/IMG/cpio/ventoy/loop/recalbox/ventoy-disk.sh new file mode 100644 index 00000000..08c9d73d --- /dev/null +++ b/IMG/cpio/ventoy/loop/recalbox/ventoy-disk.sh @@ -0,0 +1,45 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/recalbox/ventoy-hook.sh b/IMG/cpio/ventoy/loop/recalbox/ventoy-hook.sh new file mode 100644 index 00000000..b1a6ed3e --- /dev/null +++ b/IMG/cpio/ventoy/loop/recalbox/ventoy-hook.sh @@ -0,0 +1,23 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/mount.*devtmpfs/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/recalbox/ventoy-disk.sh" -i /init + diff --git a/IMG/cpio/ventoy/loop/tails/ventoy-disk.sh b/IMG/cpio/ventoy/loop/tails/ventoy-disk.sh new file mode 100644 index 00000000..a4e4706c --- /dev/null +++ b/IMG/cpio/ventoy/loop/tails/ventoy-disk.sh @@ -0,0 +1,61 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +modprobe dm-mod + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +if [ -n "${FSUUID}" ]; then + vtPartid=0 + MaxPart=$(cat /vtoy_dm_table|wc -l) + + while [ $vtPartid -le $MaxPart ]; do + if blkid /dev/dm-${vtPartid} | grep -q "${FSUUID}"; then + ln -s ../../dm-${vtPartid} "/dev/disk/by-uuid/${FSUUID}" + break + fi + vtPartid=$(expr $vtPartid + 1) + done +fi + + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/tails/ventoy-hook.sh b/IMG/cpio/ventoy/loop/tails/ventoy-hook.sh new file mode 100644 index 00000000..4eec2ae6 --- /dev/null +++ b/IMG/cpio/ventoy/loop/tails/ventoy-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/^mount_premount$/i\\$BUSYBOX_PATH/sh $VTOY_PATH/loop/tails/ventoy-disk.sh" -i /init + +if [ -f /scripts/init-premount/partitioning ]; then + $SED "1a exit 0" -i /scripts/init-premount/partitioning +fi diff --git a/IMG/cpio/ventoy/loop/ubos/newroot-hook.sh b/IMG/cpio/ventoy/loop/ubos/newroot-hook.sh new file mode 100644 index 00000000..ecc0f18e --- /dev/null +++ b/IMG/cpio/ventoy/loop/ubos/newroot-hook.sh @@ -0,0 +1,26 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +sed "/.* \/boot /d" -i /new_root/etc/fstab + +PATH=$VTPATH_OLD diff --git a/IMG/cpio/ventoy/loop/ubos/ventoy-disk.sh b/IMG/cpio/ventoy/loop/ubos/ventoy-disk.sh new file mode 100644 index 00000000..a095067e --- /dev/null +++ b/IMG/cpio/ventoy/loop/ubos/ventoy-disk.sh @@ -0,0 +1,48 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +xz -d $VTOY_PATH/modules/dm-mod.ko.xz +insmod $VTOY_PATH/modules/dm-mod.ko + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/ubos/ventoy-hook.sh b/IMG/cpio/ventoy/loop/ubos/ventoy-hook.sh new file mode 100644 index 00000000..ef79b2a8 --- /dev/null +++ b/IMG/cpio/ventoy/loop/ubos/ventoy-hook.sh @@ -0,0 +1,30 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/default/10-dm.rules /lib/udev/rules.d/ +$BUSYBOX_PATH/cp -a $VTOY_PATH/hook/default/13-dm-disk.rules /lib/udev/rules.d/ + +$SED "/^\"\$mount_handler\"/i\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/ubos/ventoy-disk.sh" -i /init + +$SED "/^\"\$mount_handler\"/a\ $BUSYBOX_PATH/sh $VTOY_PATH/loop/ubos/newroot-hook.sh" -i /init + +$SED "/^\"\$mount_handler\"/a\ init=/usr/lib/systemd/systemd" -i /init + diff --git a/IMG/cpio/ventoy/loop/volumio/ventoy-disk.sh b/IMG/cpio/ventoy/loop/volumio/ventoy-disk.sh new file mode 100644 index 00000000..8b249255 --- /dev/null +++ b/IMG/cpio/ventoy/loop/volumio/ventoy-disk.sh @@ -0,0 +1,46 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. /ventoy/hook/ventoy-hook-lib.sh + +if is_ventoy_hook_finished; then + exit 0 +fi + +vtlog "####### $0 $* ########" + +VTPATH_OLD=$PATH; PATH=$BUSYBOX_PATH:$VTOY_PATH/tool:$PATH + +wait_for_usb_disk_ready + +vtdiskname=$(get_ventoy_disk_name) +if [ "$vtdiskname" = "unknown" ]; then + vtlog "ventoy disk not found" + PATH=$VTPATH_OLD + exit 0 +fi + +ventoy_udev_disk_common_hook "${vtdiskname#/dev/}2" "noreplace" + +ventoy_create_dev_ventoy_part +mdev -s + +PATH=$VTPATH_OLD + +set_ventoy_hook_finish diff --git a/IMG/cpio/ventoy/loop/volumio/ventoy-hook.sh b/IMG/cpio/ventoy/loop/volumio/ventoy-hook.sh new file mode 100644 index 00000000..7b616d29 --- /dev/null +++ b/IMG/cpio/ventoy/loop/volumio/ventoy-hook.sh @@ -0,0 +1,28 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +. $VTOY_PATH/hook/ventoy-os-lib.sh + +$SED "/^CMDLINE=/i $BUSYBOX_PATH/sh $VTOY_PATH/loop/volumio/ventoy-disk.sh" -i /init + +#skip the resizing process +$SED "/^FREESIZE=/a FREESIZE=0" -i /init + +$SED "/exec.*switch_root/i $SED 's@\\\\(.*/boot \\\\)@#\\\\1@' -i /mnt/ext/union/etc/fstab" -i /init + diff --git a/IMG/cpio/ventoy/tool/vtoytool_install.sh b/IMG/cpio/ventoy/tool/vtoytool_install.sh deleted file mode 100644 index 5a643b68..00000000 --- a/IMG/cpio/ventoy/tool/vtoytool_install.sh +++ /dev/null @@ -1,63 +0,0 @@ -#!/ventoy/busybox/sh -#************************************************************************************ -# Copyright (c) 2020, longpanda -# -# 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 . -# -#************************************************************************************ - -echo "#### install vtoytool #####" >> $VTLOG - -if ! [ -e $BUSYBOX_PATH/ar ]; then - $BUSYBOX_PATH/ln -s $VTOY_PATH/tool/ar $BUSYBOX_PATH/ar -fi - -for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do - echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG - if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_64 --install 2>>$VTLOG; then - echo "vtoytool_64 OK" >> $VTLOG - break - fi - - if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_32 --install 2>>$VTLOG; then - echo "vtoytool_32 OK" >> $VTLOG - break - fi -done - -if $VTOY_PATH/tool/vtoy_fuse_iso_64 -t 2>>$VTLOG; then - echo "use vtoy_fuse_iso_64" >>$VTLOG - $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_64 $VTOY_PATH/tool/vtoy_fuse_iso -else - echo "use vtoy_fuse_iso_32" >>$VTLOG - $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_32 $VTOY_PATH/tool/vtoy_fuse_iso -fi - -if $VTOY_PATH/tool/unsquashfs_64 -t 2>>$VTLOG; then - echo "use unsquashfs_64" >>$VTLOG - $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_64 $VTOY_PATH/tool/vtoy_unsquashfs -else - echo "use unsquashfs_32" >>$VTLOG - $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_32 $VTOY_PATH/tool/vtoy_unsquashfs -fi - - -if $VTOY_PATH/tool/unsquashfs_64 -t 2>>$VTLOG; then - echo "use unsquashfs_64" >>$VTLOG - $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_64 $VTOY_PATH/tool/vtoy_unsquashfs -else - echo "use unsquashfs_32" >>$VTLOG - $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_32 $VTOY_PATH/tool/vtoy_unsquashfs -fi - diff --git a/IMG/cpio/ventoy/ventoy.sh b/IMG/cpio/ventoy/ventoy_chain.sh similarity index 69% rename from IMG/cpio/ventoy/ventoy.sh rename to IMG/cpio/ventoy/ventoy_chain.sh index 640b08a9..3b12922b 100644 --- a/IMG/cpio/ventoy/ventoy.sh +++ b/IMG/cpio/ventoy/ventoy_chain.sh @@ -37,7 +37,6 @@ for i in $vtcmdline; do fi done - #################################################################### # # # Step 2 : Do OS specific hook # @@ -47,12 +46,24 @@ ventoy_get_os_type() { echo "kernel version" >> $VTLOG $CAT /proc/version >> $VTLOG + if [ -d /twres ]; then + if $GREP -q 'Phoenix' /init; then + echo 'phoenixos'; return + fi + fi + # rhel5/CentOS5 and all other distributions based on them if $GREP -q 'el5' /proc/version; then echo 'rhel5'; return # rhel6/CentOS6 and all other distributions based on them elif $GREP -q 'el6' /proc/version; then + if [ -f /sbin/detectcd ]; then + if $GREP -q -i 'LENOVO-EasyStartup' /sbin/detectcd; then + echo 'easystartup'; return + fi + fi + echo 'rhel6'; return # rhel7/CentOS7/rhel8/CentOS8 and all other distributions based on them @@ -93,6 +104,10 @@ ventoy_get_os_type() { # gentoo elif $EGREP -q '[Gg]entoo' /proc/version; then + if $GREP -q 'daphile' /proc/version; then + echo 'daphile'; return + fi + echo 'gentoo'; return # TinyCore @@ -119,10 +134,14 @@ ventoy_get_os_type() { elif $GREP -q 'Alpine' /proc/version; then echo 'alpine'; return + elif $GREP -i -q 'PhoenixOS' /proc/version; then + echo 'phoenixos'; return + # NixOS elif $GREP -i -q 'NixOS' /proc/version; then echo 'nixos'; return + fi if [ -e /lib/debian-installer ]; then @@ -133,8 +152,15 @@ ventoy_get_os_type() { if $GREP -q 'XenServer' /etc/os-release; then echo 'xen'; return elif $GREP -q 'SUSE ' /etc/os-release; then - echo 'suse'; return - + echo 'suse'; return + elif $GREP -q 'uruk' /etc/os-release; then + echo 'debian'; return + elif $GREP -q 'Solus' /etc/os-release; then + echo 'rhel7'; return + elif $GREP -q 'openEuler' /etc/os-release; then + echo 'openEuler'; return + elif $GREP -q 'fuyu' /etc/os-release; then + echo 'openEuler'; return fi fi @@ -196,6 +222,118 @@ ventoy_get_os_type() { echo 'adelie'; return fi + if $GREP -q 'pmagic' /proc/version; then + echo 'pmagic'; return + fi + + if $GREP -q 'CDlinux' /proc/cmdline; then + echo 'cdlinux'; return + fi + + if $GREP -q 'parabola' /proc/version; then + echo 'parabola'; return + fi + + if $GREP -q 'cucumber' /proc/version; then + echo 'cucumber'; return + fi + + if $GREP -q 'fatdog' /proc/version; then + echo 'fatdog'; return + fi + + if $GREP -q 'KWORT' /proc/version; then + echo 'kwort'; return + fi + + if $GREP -q 'iwamoto' /proc/version; then + echo 'vine'; return + fi + + if $GREP -q 'hyperbola' /proc/cmdline; then + echo 'hyperbola'; return + fi + + if $GREP -q 'CRUX' /proc/version; then + echo 'crux'; return + fi + + if [ -f /init ]; then + if $GREP -q 'AryaLinux' /init; then + echo 'aryalinux'; return + elif $GREP -q 'Dragora' /init; then + echo 'dragora'; return + + fi + fi + + if $GREP -q 'slackware' /proc/version; then + echo 'slackware'; return + fi + + if $BUSYBOX_PATH/hostname | $GREP -q 'smoothwall'; then + echo 'smoothwall'; return + fi + + if $GREP -q 'photon' /proc/version; then + echo 'photon'; return + fi + + if $GREP -q 'ploplinux' /proc/version; then + echo 'ploplinux'; return + fi + + if $GREP -q 'lunar' /proc/version; then + echo 'lunar'; return + fi + + if $GREP -q 'SMGL-' /proc/version; then + echo 'smgl'; return + fi + + if $GREP -q 'rancher' /proc/version; then + echo 'rancher'; return + fi + + + if [ -e /init ]; then + if $GREP -q -m1 'T2 SDE' /init; then + echo 't2'; return + fi + fi + + if $GREP -q 'wifislax' /proc/version; then + echo 'wifislax'; return + fi + + if $GREP -q 'pisilinux' /proc/version; then + echo 'pisilinux'; return + fi + + if $GREP -q 'blackPanther' /proc/version; then + echo 'blackPanther'; return + fi + + if $GREP -q 'primeos' /proc/version; then + echo 'primeos'; return + fi + + if $GREP -q 'austrumi' /proc/version; then + echo 'austrumi'; return + fi + + if [ -f /DISTRO_SPECS ]; then + if $GREP -q '[Pp]uppy' /DISTRO_SPECS; then + echo 'debian'; return + elif $GREP -q 'veket' /DISTRO_SPECS; then + echo 'debian'; return + fi + fi + + if [ -f /etc/openEuler-release ]; then + echo "openEuler"; return + fi + echo "default" } @@ -222,6 +360,7 @@ if [ "$VTOY_BREAK_LEVEL" = "03" ] || [ "$VTOY_BREAK_LEVEL" = "13" ]; then exec $BUSYBOX_PATH/sh fi + #################################################################### # # # Step 4 : Hand over to real init # @@ -239,7 +378,7 @@ fi cd / -unset VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD +unset VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD vtcmdline for vtinit in $user_rdinit /init /sbin/init /linuxrc; do if [ -d /ventoy_rdroot ]; then diff --git a/IMG/cpio/ventoy/ventoy_loop.sh b/IMG/cpio/ventoy/ventoy_loop.sh new file mode 100644 index 00000000..bf67ec47 --- /dev/null +++ b/IMG/cpio/ventoy/ventoy_loop.sh @@ -0,0 +1,443 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +#################################################################### +# # +# Step 1 : Parse kernel parameter # +# # +#################################################################### +if ! [ -e /proc ]; then + $BUSYBOX_PATH/mkdir /proc + rmproc='Y' +fi +$BUSYBOX_PATH/mount -t proc proc /proc + +# vtinit=xxx to replace rdinit=xxx +vtcmdline=$($CAT /proc/cmdline) +for i in $vtcmdline; do + if echo $i | $GREP -q vtinit; then + user_rdinit=${i#vtinit=} + echo "user set user_rdinit=${user_rdinit}" >>$VTLOG + fi +done + +#################################################################### +# # +# Step 2 : Process ko # +# # +#################################################################### +$BUSYBOX_PATH/mkdir -p /ventoy/modules +$BUSYBOX_PATH/ls -1a / | $EGREP '\.ko$|\.ko.[gx]z$' | while read vtline; do + if [ "${vtline:0:1}" = "." ]; then + $BUSYBOX_PATH/mv /${vtline} /ventoy/modules/${vtline:1} + else + $BUSYBOX_PATH/mv /${vtline} /ventoy/modules/ + fi +done + +if [ -e /vtloopex.tar.xz ]; then + echo "extract vtloopex ..." >> $VTLOG + $BUSYBOX_PATH/tar -xJf /vtloopex.tar.xz -C $VTOY_PATH/ + $BUSYBOX_PATH/rm -f /vtloopex.tar.xz +fi + + +#################################################################### +# # +# Step 3 : Do OS specific hook # +# # +#################################################################### +ventoy_get_os_type() { + echo "kernel version" >> $VTLOG + $CAT /proc/version >> $VTLOG + + if $GREP -q 'endless' /proc/version; then + echo 'endless'; return + fi + + if $GREP -q 'OpenWrt' /proc/version; then + echo 'openwrt'; return + fi + + if [ -e /BOOT_SPECS ]; then + if $GREP -q 'easyos' /BOOT_SPECS; then + echo 'easyos'; return + fi + fi + + if [ -e /etc/os-release ]; then + if $GREP -q 'volumio' /etc/os-release; then + echo 'volumio'; return + fi + fi + + if $GREP -q 'ventoyos=' /proc/cmdline; then + $SED "s/.*ventoyos=\([a-zA-Z0-9_-]*\).*/\1/" /proc/cmdline; return + fi + + if [ -d /twres ]; then + if $GREP -q 'Phoenix' /init; then + echo 'phoenixos'; return + fi + fi + + # rhel5/CentOS5 and all other distributions based on them + if $GREP -q 'el5' /proc/version; then + echo 'rhel5'; return + + # rhel6/CentOS6 and all other distributions based on them + elif $GREP -q 'el6' /proc/version; then + echo 'rhel6'; return + + # rhel7/CentOS7/rhel8/CentOS8 and all other distributions based on them + elif $GREP -q 'el[78]' /proc/version; then + echo 'rhel7'; return + + # Maybe rhel9 rhel1x use the same way? Who knows! + elif $EGREP -q 'el9|el1[0-9]' /proc/version; then + echo 'rhel7'; return + + # Fedora : do the same process with rhel7 + elif $GREP -q '\.fc[0-9][0-9]\.' /proc/version; then + echo 'rhel7'; return + + # Debian : + elif $GREP -q '[Dd]ebian' /proc/version; then + echo 'debian'; return + + # Ubuntu : do the same process with debian + elif $GREP -q '[Uu]buntu' /proc/version; then + echo 'debian'; return + + # Deepin : do the same process with debian + elif $GREP -q '[Dd]eepin' /proc/version; then + echo 'debian'; return + + # SUSE + elif $GREP -q 'SUSE' /proc/version; then + echo 'suse'; return + + # ArchLinux + elif $EGREP -q 'archlinux|ARCH' /proc/version; then + echo 'arch'; return + + # kiosk + elif $EGREP -q 'kiosk' /proc/version; then + echo 'kiosk'; return + + # gentoo + elif $EGREP -q '[Gg]entoo' /proc/version; then + if $GREP -q 'daphile' /proc/version; then + echo 'daphile'; return + fi + + echo 'gentoo'; return + + # TinyCore + elif $EGREP -q 'tinycore' /proc/version; then + echo 'tinycore'; return + + # manjaro + elif $EGREP -q 'manjaro|MANJARO' /proc/version; then + echo 'manjaro'; return + + # mageia + elif $EGREP -q 'mageia' /proc/version; then + echo 'mageia'; return + + # pclinux OS + elif $GREP -i -q 'PCLinuxOS' /proc/version; then + echo 'pclos'; return + + # KaOS + elif $GREP -i -q 'kaos' /proc/version; then + echo 'kaos'; return + + # Alpine + elif $GREP -q 'Alpine' /proc/version; then + echo 'alpine'; return + + elif $GREP -i -q 'PhoenixOS' /proc/version; then + echo 'phoenixos'; return + + # NixOS + elif $GREP -i -q 'NixOS' /proc/version; then + echo 'nixos'; return + + + fi + + if [ -e /lib/debian-installer ]; then + echo 'debian'; return + fi + + if [ -e /etc/os-release ]; then + if $GREP -q 'XenServer' /etc/os-release; then + echo 'xen'; return + elif $GREP -q 'SUSE ' /etc/os-release; then + echo 'suse'; return + elif $GREP -q 'uruk' /etc/os-release; then + echo 'debian'; return + elif $GREP -q 'Solus' /etc/os-release; then + echo 'rhel7'; return + elif $GREP -q 'openEuler' /etc/os-release; then + echo 'openEuler'; return + elif $GREP -q 'fuyu' /etc/os-release; then + echo 'openEuler'; return + fi + fi + + if $BUSYBOX_PATH/dmesg | $GREP -q -m1 "Xen:"; then + echo 'xen'; return + fi + + + if [ -e /etc/HOSTNAME ] && $GREP -i -q 'slackware' /etc/HOSTNAME; then + echo 'slackware'; return + fi + + if [ -e /init ]; then + if $GREP -i -q zeroshell /init; then + echo 'zeroshell'; return + fi + fi + + if $EGREP -q 'ALT ' /proc/version; then + echo 'alt'; return + fi + + if $EGREP -q 'porteus' /proc/version; then + echo 'debian'; return + fi + + if $GREP -q 'Clear Linux ' /proc/version; then + echo 'clear'; return + fi + + if $GREP -q 'artix' /proc/version; then + echo 'arch'; return + fi + + if $GREP -q 'berry ' /proc/version; then + echo 'berry'; return + fi + + if $GREP -q 'Gobo ' /proc/version; then + echo 'gobo'; return + fi + + if $GREP -q 'NuTyX' /proc/version; then + echo 'nutyx'; return + fi + + if [ -d /gnu ]; then + vtLineNum=$($FIND /gnu/ -name guix | $BUSYBOX_PATH/wc -l) + if [ $vtLineNum -gt 0 ]; then + echo 'guix'; return + fi + fi + + if $GREP -q 'android.x86' /proc/version; then + echo 'android'; return + fi + + if $GREP -q 'adelielinux' /proc/version; then + echo 'adelie'; return + fi + + if $GREP -q 'pmagic' /proc/version; then + echo 'pmagic'; return + fi + + if $GREP -q 'CDlinux' /proc/cmdline; then + echo 'cdlinux'; return + fi + + if $GREP -q 'parabola' /proc/version; then + echo 'parabola'; return + fi + + if $GREP -q 'cucumber' /proc/version; then + echo 'cucumber'; return + fi + + if $GREP -q 'fatdog' /proc/version; then + echo 'fatdog'; return + fi + + if $GREP -q 'KWORT' /proc/version; then + echo 'kwort'; return + fi + + if $GREP -q 'iwamoto' /proc/version; then + echo 'vine'; return + fi + + if $GREP -q 'hyperbola' /proc/cmdline; then + echo 'hyperbola'; return + fi + + if $GREP -q 'CRUX' /proc/version; then + echo 'crux'; return + fi + + if [ -f /init ]; then + if $GREP -q 'AryaLinux' /init; then + echo 'aryalinux'; return + elif $GREP -q 'Dragora' /init; then + echo 'dragora'; return + + fi + fi + + if $GREP -q 'slackware' /proc/version; then + echo 'slackware'; return + fi + + if $BUSYBOX_PATH/hostname | $GREP -q 'smoothwall'; then + echo 'smoothwall'; return + fi + + if $GREP -q 'photon' /proc/version; then + echo 'photon'; return + fi + + if $GREP -q 'ploplinux' /proc/version; then + echo 'ploplinux'; return + fi + + if $GREP -q 'lunar' /proc/version; then + echo 'lunar'; return + fi + + if $GREP -q 'SMGL-' /proc/version; then + echo 'smgl'; return + fi + + if $GREP -q 'rancher' /proc/version; then + echo 'rancher'; return + fi + + + if [ -e /init ]; then + if $GREP -q -m1 'T2 SDE' /init; then + echo 't2'; return + fi + fi + + if $GREP -q 'wifislax' /proc/version; then + echo 'wifislax'; return + fi + + if $GREP -q 'pisilinux' /proc/version; then + echo 'pisilinux'; return + fi + + if $GREP -q 'blackPanther' /proc/version; then + echo 'blackPanther'; return + fi + + if $GREP -q 'primeos' /proc/version; then + echo 'primeos'; return + fi + + if $GREP -q 'austrumi' /proc/version; then + echo 'austrumi'; return + fi + + if [ -f /DISTRO_SPECS ]; then + if $GREP -q '[Pp]uppy' /DISTRO_SPECS; then + echo 'debian'; return + elif $GREP -q 'veket' /DISTRO_SPECS; then + echo 'debian'; return + fi + fi + + if [ -f /etc/openEuler-release ]; then + echo "openEuler"; return + fi + + echo "default" +} + +VTOS=$(ventoy_get_os_type) +echo "OS=###${VTOS}###" >>$VTLOG +if [ -e "$VTOY_PATH/loop/$VTOS/ventoy-hook.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/loop/$VTOS/ventoy-hook.sh" +elif [ -e "$VTOY_PATH/hook/$VTOS/ventoy-hook.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/hook/$VTOS/ventoy-hook.sh" +fi + + +#################################################################### +# # +# Step 4 : Check for debug break # +# # +#################################################################### +if [ "$VTOY_BREAK_LEVEL" = "03" ] || [ "$VTOY_BREAK_LEVEL" = "13" ]; then + $SLEEP 5 + echo -e "\n\n\033[32m ################################################# \033[0m" + echo -e "\033[32m ################ VENTOY DEBUG ################### \033[0m" + echo -e "\033[32m ################################################# \033[0m \n" + if [ "$VTOY_BREAK_LEVEL" = "13" ]; then + $CAT $VTOY_PATH/log + fi + exec $BUSYBOX_PATH/sh +fi + + +#################################################################### +# # +# Step 5 : Hand over to real init # +# # +#################################################################### +$BUSYBOX_PATH/umount /proc +if [ "$rmproc" = "Y" ]; then + $BUSYBOX_PATH/rm -rf /proc +fi + +if [ -f $VTOY_PATH/ventoy_persistent_map ]; then + export PERSISTENT='YES' + export PERSISTENCE='true' +fi + +cd / + +unset VTLOG FIND GREP EGREP CAT AWK SED SLEEP HEAD vtcmdline + +for vtinit in $user_rdinit /init /sbin/init /linuxrc; do + if [ -d /ventoy_rdroot ]; then + if [ -e "/ventoy_rdroot$vtinit" ]; then + # switch_root will check /init file, this is a cheat code + echo 'switch_root' > /init + exec $BUSYBOX_PATH/switch_root /ventoy_rdroot "$vtinit" + fi + else + if [ -e "$vtinit" ];then + if [ -f "$VTOY_PATH/hook/$VTOS/ventoy-before-init.sh" ]; then + $BUSYBOX_PATH/sh "$VTOY_PATH/hook/$VTOS/ventoy-before-init.sh" + fi + exec "$vtinit" + fi + fi +done + +# Should never reach here +echo -e "\n\n\033[31m ############ INIT NOT FOUND ############### \033[0m \n" +exec $BUSYBOX_PATH/sh diff --git a/IMG/cpio_arm64/ventoy/busybox/a64 b/IMG/cpio_arm64/ventoy/busybox/a64 new file mode 100644 index 00000000..55eb1455 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/a64 differ diff --git a/IMG/cpio_arm64/ventoy/busybox/busyboxaa64.xz b/IMG/cpio_arm64/ventoy/busybox/busyboxaa64.xz new file mode 100644 index 00000000..f171481d Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/busyboxaa64.xz differ diff --git a/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 b/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 new file mode 100644 index 00000000..593c021f Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/vtchmodaa64 differ diff --git a/IMG/cpio_arm64/ventoy/busybox/xzminidecaa64 b/IMG/cpio_arm64/ventoy/busybox/xzminidecaa64 new file mode 100644 index 00000000..914eba69 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/busybox/xzminidecaa64 differ diff --git a/IMG/cpio_arm64/ventoy/tool/lz4cataa64 b/IMG/cpio_arm64/ventoy/tool/lz4cataa64 new file mode 100644 index 00000000..7e025d4d Binary files /dev/null and b/IMG/cpio_arm64/ventoy/tool/lz4cataa64 differ diff --git a/IMG/cpio_arm64/ventoy/tool/zstdcataa64 b/IMG/cpio_arm64/ventoy/tool/zstdcataa64 new file mode 100644 index 00000000..513f4956 Binary files /dev/null and b/IMG/cpio_arm64/ventoy/tool/zstdcataa64 differ diff --git a/IMG/cpio_mips64/ventoy/busybox/busyboxm64e.xz b/IMG/cpio_mips64/ventoy/busybox/busyboxm64e.xz new file mode 100644 index 00000000..3cab6d5b Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/busyboxm64e.xz differ diff --git a/IMG/cpio_mips64/ventoy/busybox/m64 b/IMG/cpio_mips64/ventoy/busybox/m64 new file mode 100644 index 00000000..039e82a6 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/m64 differ diff --git a/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e b/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e new file mode 100644 index 00000000..47e84be6 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/vtchmodm64e differ diff --git a/IMG/cpio_mips64/ventoy/busybox/xzminidecm64e b/IMG/cpio_mips64/ventoy/busybox/xzminidecm64e new file mode 100644 index 00000000..5d44c729 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/busybox/xzminidecm64e differ diff --git a/IMG/cpio_mips64/ventoy/tool/lz4catm64e b/IMG/cpio_mips64/ventoy/tool/lz4catm64e new file mode 100644 index 00000000..3d803307 Binary files /dev/null and b/IMG/cpio_mips64/ventoy/tool/lz4catm64e differ diff --git a/IMG/cpio_x86/ventoy/busybox/64h b/IMG/cpio_x86/ventoy/busybox/64h new file mode 100644 index 00000000..a137ff35 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/64h differ diff --git a/IMG/cpio/ventoy/busybox/tmpsh b/IMG/cpio_x86/ventoy/busybox/ash similarity index 100% rename from IMG/cpio/ventoy/busybox/tmpsh rename to IMG/cpio_x86/ventoy/busybox/ash diff --git a/IMG/cpio/ventoy/busybox/busybox.xz b/IMG/cpio_x86/ventoy/busybox/busybox32.xz similarity index 100% rename from IMG/cpio/ventoy/busybox/busybox.xz rename to IMG/cpio_x86/ventoy/busybox/busybox32.xz diff --git a/IMG/cpio_x86/ventoy/busybox/busybox64.xz b/IMG/cpio_x86/ventoy/busybox/busybox64.xz new file mode 100644 index 00000000..df9d768f Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/busybox64.xz differ diff --git a/IMG/cpio_x86/ventoy/busybox/vtchmod32 b/IMG/cpio_x86/ventoy/busybox/vtchmod32 new file mode 100644 index 00000000..4b66db3c Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/vtchmod32 differ diff --git a/IMG/cpio_x86/ventoy/busybox/vtchmod64 b/IMG/cpio_x86/ventoy/busybox/vtchmod64 new file mode 100644 index 00000000..9c799581 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/vtchmod64 differ diff --git a/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl b/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl new file mode 100644 index 00000000..d4cd5c6b Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/vtchmod64_musl differ diff --git a/IMG/cpio/ventoy/tool/xzminidec b/IMG/cpio_x86/ventoy/busybox/xzminidec32 similarity index 100% rename from IMG/cpio/ventoy/tool/xzminidec rename to IMG/cpio_x86/ventoy/busybox/xzminidec32 diff --git a/IMG/cpio_x86/ventoy/busybox/xzminidec64 b/IMG/cpio_x86/ventoy/busybox/xzminidec64 new file mode 100644 index 00000000..e2dde491 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/xzminidec64 differ diff --git a/IMG/cpio_x86/ventoy/busybox/xzminidec64_musl b/IMG/cpio_x86/ventoy/busybox/xzminidec64_musl new file mode 100644 index 00000000..de7fa3d1 Binary files /dev/null and b/IMG/cpio_x86/ventoy/busybox/xzminidec64_musl differ diff --git a/IMG/cpio/ventoy/tool/ar b/IMG/cpio_x86/ventoy/tool/ar similarity index 100% rename from IMG/cpio/ventoy/tool/ar rename to IMG/cpio_x86/ventoy/tool/ar diff --git a/IMG/cpio/ventoy/tool/inotifyd b/IMG/cpio_x86/ventoy/tool/inotifyd similarity index 100% rename from IMG/cpio/ventoy/tool/inotifyd rename to IMG/cpio_x86/ventoy/tool/inotifyd diff --git a/IMG/cpio/ventoy/tool/lz4cat b/IMG/cpio_x86/ventoy/tool/lz4cat similarity index 100% rename from IMG/cpio/ventoy/tool/lz4cat rename to IMG/cpio_x86/ventoy/tool/lz4cat diff --git a/IMG/cpio_x86/ventoy/tool/lz4cat64 b/IMG/cpio_x86/ventoy/tool/lz4cat64 new file mode 100644 index 00000000..2790fa9f Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/lz4cat64 differ diff --git a/IMG/cpio/ventoy/tool/ventoy_loader.sh b/IMG/cpio_x86/ventoy/tool/ventoy_loader.sh similarity index 100% rename from IMG/cpio/ventoy/tool/ventoy_loader.sh rename to IMG/cpio_x86/ventoy/tool/ventoy_loader.sh diff --git a/IMG/cpio_x86/ventoy/tool/vtoytool_install.sh b/IMG/cpio_x86/ventoy/tool/vtoytool_install.sh new file mode 100644 index 00000000..d6b34706 --- /dev/null +++ b/IMG/cpio_x86/ventoy/tool/vtoytool_install.sh @@ -0,0 +1,86 @@ +#!/ventoy/busybox/sh +#************************************************************************************ +# Copyright (c) 2020, longpanda +# +# 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 . +# +#************************************************************************************ + +echo "#### install vtoytool #####" >> $VTLOG + +for app in ar inotifyd; do + if [ -e $BUSYBOX_PATH/$app ]; then + $BUSYBOX_PATH/rm -f $VTOY_PATH/tool/$app + $BUSYBOX_PATH/ln -s $BUSYBOX_PATH/$app $VTOY_PATH/tool/$app + else + $BUSYBOX_PATH/ln -s $VTOY_PATH/tool/$app $BUSYBOX_PATH/$app + fi +done + + +if $GREP -q aarch64 $VTOY_PATH/ventoy_arch; then + for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do + echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_aa64 --install 2>>$VTLOG; then + echo "vtoytool_aa64 OK" >> $VTLOG + break + fi + done + + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_aa64 $VTOY_PATH/tool/vtoy_fuse_iso + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_aa64 $VTOY_PATH/tool/vtoy_unsquashfs +elif $GREP -q mips64el $VTOY_PATH/ventoy_arch; then + for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do + echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_m64e --install 2>>$VTLOG; then + echo "vtoytool_m64e OK" >> $VTLOG + break + fi + done + + # TBD + #$BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_aa64 $VTOY_PATH/tool/vtoy_fuse_iso + #$BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_aa64 $VTOY_PATH/tool/vtoy_unsquashfs +else + for vtdir in $(ls $VTOY_PATH/tool/vtoytool/); do + echo "try $VTOY_PATH/tool/vtoytool/$vtdir/ ..." >> $VTLOG + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_64 --install 2>>$VTLOG; then + echo "vtoytool_64 OK" >> $VTLOG + break + fi + + if $VTOY_PATH/tool/vtoytool/$vtdir/vtoytool_32 --install 2>>$VTLOG; then + echo "vtoytool_32 OK" >> $VTLOG + break + fi + done + + if $VTOY_PATH/tool/vtoy_fuse_iso_64 -t 2>>$VTLOG; then + echo "use vtoy_fuse_iso_64" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_64 $VTOY_PATH/tool/vtoy_fuse_iso + else + echo "use vtoy_fuse_iso_32" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/vtoy_fuse_iso_32 $VTOY_PATH/tool/vtoy_fuse_iso + fi + + if $VTOY_PATH/tool/unsquashfs_64 -t 2>>$VTLOG; then + echo "use unsquashfs_64" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_64 $VTOY_PATH/tool/vtoy_unsquashfs + else + echo "use unsquashfs_32" >>$VTLOG + $BUSYBOX_PATH/cp -a $VTOY_PATH/tool/unsquashfs_32 $VTOY_PATH/tool/vtoy_unsquashfs + fi + +fi + diff --git a/IMG/cpio/ventoy/tool/zstdcat b/IMG/cpio_x86/ventoy/tool/zstdcat similarity index 100% rename from IMG/cpio/ventoy/tool/zstdcat rename to IMG/cpio_x86/ventoy/tool/zstdcat diff --git a/IMG/cpio_x86/ventoy/tool/zstdcat64 b/IMG/cpio_x86/ventoy/tool/zstdcat64 new file mode 100644 index 00000000..eb4045a4 Binary files /dev/null and b/IMG/cpio_x86/ventoy/tool/zstdcat64 differ diff --git a/IMG/mkcpio.sh b/IMG/mkcpio.sh index c288ed94..270eb8f6 100644 --- a/IMG/mkcpio.sh +++ b/IMG/mkcpio.sh @@ -2,9 +2,15 @@ VENTOY_PATH=$PWD/../ -rm -f ventoy.cpio +if [ -d cpio_tmp ]; then + rm -rf cpio_tmp +fi + + +############### cpio ############ chmod -R 777 cpio +rm -f ventoy.cpio ventoy_x86.cpio ventoy_arm64.cpio ventoy_mips64.cpio cp -a cpio cpio_tmp @@ -15,33 +21,133 @@ ln -s sbin/init linuxrc cd ventoy +find ./loop | cpio -o -H newc --owner=root:root >loop.cpio +xz loop.cpio +rm -rf loop -cp -a $VENTOY_PATH/DMSETUP/dmsetup tool/ -cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_* tool/ -cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_* tool/ -cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/ -cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_* tool/ +xz ventoy_chain.sh +xz ventoy_loop.sh -chmod -R 777 ./tool - -find ./tool | cpio -o -H newc>tool.cpio -xz tool.cpio -rm -rf tool - -xz ventoy.sh - -find ./hook | cpio -o -H newc>hook.cpio +find ./hook | cpio -o -H newc --owner=root:root >hook.cpio xz hook.cpio rm -rf hook cd .. -find .| cpio -o -H newc>../ventoy.cpio +find .| cpio -o -H newc --owner=root:root >../ventoy.cpio cd .. rm -rf cpio_tmp + + + +########## cpio_x86 ############## +chmod -R 777 cpio_x86 +cp -a cpio_x86 cpio_tmp + +cd cpio_tmp/ventoy + +cp -a $VENTOY_PATH/DMSETUP/dmsetup32 tool/ +cp -a $VENTOY_PATH/DMSETUP/dmsetup64 tool/ +cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_32 tool/ +cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_64 tool/ +cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_32 tool/ +cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_64 tool/ +cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/ +rm -f tool/vtoytool/00/vtoytool_aa64 +rm -f tool/vtoytool/00/vtoytool_m64e +cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_32 tool/ +cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_64 tool/ + +cp -a $VENTOY_PATH/LZIP/lunzip32 tool/ +cp -a $VENTOY_PATH/LZIP/lunzip64 tool/ + +chmod -R 777 ./tool + +find ./tool | cpio -o -H newc --owner=root:root >tool.cpio +xz tool.cpio +rm -rf tool + +cd .. +find .| cpio -o -H newc --owner=root:root >../ventoy_x86.cpio + +cd .. +rm -rf cpio_tmp + + +########## cpio_arm64 ############## +chmod -R 777 cpio_arm64 +cp -a cpio_arm64 cpio_tmp +cp -a cpio_x86/ventoy/tool/*.sh cpio_tmp/ventoy/tool/ + +cd cpio_tmp/ventoy + +cp -a $VENTOY_PATH/DMSETUP/dmsetupaa64 tool/ +cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_aa64 tool/ +cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_aa64 tool/ +cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/ +rm -f tool/vtoytool/00/vtoytool_32 +rm -f tool/vtoytool/00/vtoytool_64 +rm -f tool/vtoytool/00/vtoytool_m64e +cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_aa64 tool/ + +cp -a $VENTOY_PATH/LZIP/lunzipaa64 tool/ + +chmod -R 777 ./tool + +find ./tool | cpio -o -H newc --owner=root:root >tool.cpio +xz tool.cpio +rm -rf tool + +cd .. +find .| cpio -o -H newc --owner=root:root >../ventoy_arm64.cpio + +cd .. +rm -rf cpio_tmp + + + +########## cpio_mips64 ############## +chmod -R 777 cpio_mips64 +cp -a cpio_mips64 cpio_tmp +cp -a cpio_x86/ventoy/tool/*.sh cpio_tmp/ventoy/tool/ + +cd cpio_tmp/ventoy + +cp -a $VENTOY_PATH/DMSETUP/dmsetupm64e tool/ +# cp -a $VENTOY_PATH/SQUASHFS/unsquashfs_m64e tool/ +# cp -a $VENTOY_PATH/FUSEISO/vtoy_fuse_iso_m64e tool/ +cp -a $VENTOY_PATH/VtoyTool/vtoytool tool/ +rm -f tool/vtoytool/00/vtoytool_32 +rm -f tool/vtoytool/00/vtoytool_64 +rm -f tool/vtoytool/00/vtoytool_aa64 +# cp -a $VENTOY_PATH/VBLADE/vblade-master/vblade_m64e tool/ + +# cp -a $VENTOY_PATH/LZIP/lunzipaa64 tool/ + +chmod -R 777 ./tool + +find ./tool | cpio -o -H newc --owner=root:root >tool.cpio +xz tool.cpio +rm -rf tool + +cd .. +find .| cpio -o -H newc --owner=root:root >../ventoy_mips64.cpio + +cd .. +rm -rf cpio_tmp + + + + echo '======== SUCCESS =============' rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy.cpio +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy_x86.cpio +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy_arm64.cpio +rm -f $VENTOY_PATH/INSTALL/ventoy/ventoy_mips64.cpio cp -a ventoy.cpio $VENTOY_PATH/INSTALL/ventoy/ +cp -a ventoy_x86.cpio $VENTOY_PATH/INSTALL/ventoy/ +cp -a ventoy_arm64.cpio $VENTOY_PATH/INSTALL/ventoy/ +cp -a ventoy_mips64.cpio $VENTOY_PATH/INSTALL/ventoy/ diff --git a/IMG/mkloopex.sh b/IMG/mkloopex.sh new file mode 100644 index 00000000..1a87dec6 --- /dev/null +++ b/IMG/mkloopex.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +VENTOY_PATH=$PWD/../ + +rm -f vtloopex.cpio +cp -a vtloopex vtloopex_tmp +cd vtloopex_tmp + + +for dir in $(ls); do + cd $dir + tar -cJf vtloopex.tar.xz vtloopex + rm -rf vtloopex + cd .. +done + +find . | cpio -o -H newc --owner=root:root >../vtloopex.cpio + +cd .. + +rm -rf vtloopex_tmp + +rm -f $VENTOY_PATH/INSTALL/ventoy/vtloopex.cpio +cp -a vtloopex.cpio $VENTOY_PATH/INSTALL/ventoy/ + +echo '======== SUCCESS =============' + diff --git a/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.1.16/64/dm-mod.ko.xz b/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.1.16/64/dm-mod.ko.xz new file mode 100644 index 00000000..e4a5d79c Binary files /dev/null and b/IMG/vtloopex/LibreELEC/vtloopex/dm-mod/5.1.16/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dax.ko.xz b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dax.ko.xz new file mode 100644 index 00000000..7b9e0df5 Binary files /dev/null and b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dax.ko.xz differ diff --git a/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dm-mod.ko.xz b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dm-mod.ko.xz new file mode 100644 index 00000000..bfefb617 Binary files /dev/null and b/IMG/vtloopex/crux/vtloopex/dm-mod/4.19.48/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/dragora/vtloopex/dm-mod/4.19.79-gnu/64/dm-mod.ko.xz b/IMG/vtloopex/dragora/vtloopex/dm-mod/4.19.79-gnu/64/dm-mod.ko.xz new file mode 100644 index 00000000..14ff12fd Binary files /dev/null and b/IMG/vtloopex/dragora/vtloopex/dm-mod/4.19.79-gnu/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/kerio/vtloopex/dm-mod/3.16.0-k5-kerio-amd64/64/dm-mod.ko.xz b/IMG/vtloopex/kerio/vtloopex/dm-mod/3.16.0-k5-kerio-amd64/64/dm-mod.ko.xz new file mode 100644 index 00000000..27d9fcb7 Binary files /dev/null and b/IMG/vtloopex/kerio/vtloopex/dm-mod/3.16.0-k5-kerio-amd64/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/lakka/vtloopex/dm-mod/4.11.12-rt14/64/dm-mod.ko.xz b/IMG/vtloopex/lakka/vtloopex/dm-mod/4.11.12-rt14/64/dm-mod.ko.xz new file mode 100644 index 00000000..20a1a7f8 Binary files /dev/null and b/IMG/vtloopex/lakka/vtloopex/dm-mod/4.11.12-rt14/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dax.ko.xz b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dax.ko.xz new file mode 100644 index 00000000..36d89edd Binary files /dev/null and b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dax.ko.xz differ diff --git a/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dm-mod.ko.xz b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dm-mod.ko.xz new file mode 100644 index 00000000..347aa8aa Binary files /dev/null and b/IMG/vtloopex/lakka/vtloopex/dm-mod/5.10.35/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/openwrt/vtloopex/dm-mod/4.14.180/64/dm-mod.ko.xz b/IMG/vtloopex/openwrt/vtloopex/dm-mod/4.14.180/64/dm-mod.ko.xz new file mode 100644 index 00000000..b201ca35 Binary files /dev/null and b/IMG/vtloopex/openwrt/vtloopex/dm-mod/4.14.180/64/dm-mod.ko.xz differ diff --git a/IMG/vtloopex/vine/vtloopex/dm-mod/4.4.52-2vl6/64/dm-mod.ko.xz b/IMG/vtloopex/vine/vtloopex/dm-mod/4.4.52-2vl6/64/dm-mod.ko.xz new file mode 100644 index 00000000..84084f6f Binary files /dev/null and b/IMG/vtloopex/vine/vtloopex/dm-mod/4.4.52-2vl6/64/dm-mod.ko.xz differ diff --git a/INSTALL/CreatePersistentImg.sh b/INSTALL/CreatePersistentImg.sh index 83f1e7e1..8a4480db 100644 --- a/INSTALL/CreatePersistentImg.sh +++ b/INSTALL/CreatePersistentImg.sh @@ -3,13 +3,17 @@ size=1024 fstype=ext4 label=casper-rw +config='' +outputfile=persistence.dat print_usage() { - echo 'Usage: CreatePersistentImg.sh [ -s size ] [ -t fstype ] [ -l LABEL ]' + echo 'Usage: CreatePersistentImg.sh [ -s size ] [ -t fstype ] [ -l LABEL ] [ -c CFG ]' echo ' OPTION: (optional)' echo ' -s size in MB, default is 1024' echo ' -t filesystem type, default is ext4 ext2/ext3/ext4/xfs are supported now' echo ' -l label, default is casper-rw' + echo ' -c configfile name inside the persistence file. File content is "/ union"' + echo ' -o outputfile name, default is persistence.dat' echo '' } @@ -23,6 +27,15 @@ while [ -n "$1" ]; do elif [ "$1" = "-l" ]; then shift label=$1 + elif [ "$1" = "-c" ]; then + shift + config=$1 + elif [ "$1" = "-o" ]; then + shift + outputfile=$1 + elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + print_usage + exit 0 else print_usage exit 1 @@ -61,17 +74,34 @@ else exit 1 fi +if [ "$outputdir" != "persistence.dat" ]; then + mkdir -p "$(dirname "$outputfile")" +fi + # 00->ff avoid sparse file -dd if=/dev/zero bs=1M count=$size | tr '\000' '\377' > persistence.img +dd if=/dev/zero bs=1M count=$size | tr '\000' '\377' > "$outputfile" sync freeloop=$(losetup -f) -losetup $freeloop persistence.img +losetup $freeloop "$outputfile" mkfs -t $fstype $fsopt -L $label $freeloop sync -losetup -d $freeloop +if [ -n "$config" ]; then + if [ -d ./persist_tmp_mnt ]; then + rm -rf ./persist_tmp_mnt + fi + + mkdir ./persist_tmp_mnt + if mount $freeloop ./persist_tmp_mnt; then + echo '/ union' > ./persist_tmp_mnt/$config + sync + umount ./persist_tmp_mnt + fi + rm -rf ./persist_tmp_mnt +fi +losetup -d $freeloop diff --git a/INSTALL/EFI/BOOT/BOOTAA64.EFI b/INSTALL/EFI/BOOT/BOOTAA64.EFI new file mode 100644 index 00000000..6248fd37 Binary files /dev/null and b/INSTALL/EFI/BOOT/BOOTAA64.EFI differ diff --git a/INSTALL/EFI/BOOT/BOOTIA32.EFI b/INSTALL/EFI/BOOT/BOOTIA32.EFI new file mode 100644 index 00000000..319af488 Binary files /dev/null and b/INSTALL/EFI/BOOT/BOOTIA32.EFI differ diff --git a/INSTALL/EFI/BOOT/BOOTMIPS.EFI b/INSTALL/EFI/BOOT/BOOTMIPS.EFI new file mode 100644 index 00000000..6684b478 Binary files /dev/null and b/INSTALL/EFI/BOOT/BOOTMIPS.EFI differ diff --git a/INSTALL/EFI/BOOT/grubia32.efi b/INSTALL/EFI/BOOT/grubia32.efi new file mode 100644 index 00000000..2d7ea64a Binary files /dev/null and b/INSTALL/EFI/BOOT/grubia32.efi differ diff --git a/INSTALL/EFI/BOOT/grubia32_real.efi b/INSTALL/EFI/BOOT/grubia32_real.efi new file mode 100644 index 00000000..394c77bb Binary files /dev/null and b/INSTALL/EFI/BOOT/grubia32_real.efi differ diff --git a/INSTALL/EFI/BOOT/grubx64_real.efi b/INSTALL/EFI/BOOT/grubx64_real.efi index c6874c33..779781bc 100644 Binary files a/INSTALL/EFI/BOOT/grubx64_real.efi and b/INSTALL/EFI/BOOT/grubx64_real.efi differ diff --git a/INSTALL/EFI/BOOT/mmia32.efi b/INSTALL/EFI/BOOT/mmia32.efi new file mode 100644 index 00000000..2125582c Binary files /dev/null and b/INSTALL/EFI/BOOT/mmia32.efi differ diff --git a/INSTALL/ExtendPersistentImg.sh b/INSTALL/ExtendPersistentImg.sh new file mode 100644 index 00000000..21c8435a --- /dev/null +++ b/INSTALL/ExtendPersistentImg.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +print_usage() { + echo 'Usage: ExtendPersistentImg.sh file size' + echo ' file persistent dat file' + echo ' size extend size in MB' + echo 'Example:' + echo ' sh ExtendPersistentImg.sh ubuntu.dat 2048' + echo '' +} + +if [ -z "$1" -o "$1" = "-h" ]; then + print_usage + exit 1 +fi + +if [ -z "$2" ]; then + print_usage + exit 1 +fi + +file=$1 +size=$2 + +if [ ! -f "$file" ]; then + echo "$file not exist." + exit 1 +fi + +if echo $size | grep -q "[^0-9]"; then + print_usage + exit 1 +fi + +fsize=$(stat -c '%s' $file) + +fsmod=$(expr $fsize % 1024) +if [ $fsmod -ne 0 ]; then + echo "File size of $file is not aligned by 1MB, please check." + exit 1 +fi + + +fsMB=$(expr $fsize / 1024 / 1024) +total=$(expr $fsMB + $size) + +magic=$(hexdump -n3 -e '3/1 "%02X"' $file) +if [ "$magic" = "584653" ]; then + if which xfs_growfs >/dev/null 2>&1; then + cmd=xfs_growfs + else + echo 'xfs_growfs not found, please install xfsprogs first' + exit 1 + fi +else + if which resize2fs >/dev/null 2>&1; then + cmd=resize2fs + else + echo 'resize2fs not found, please install e2fsprogs first' + exit 1 + fi +fi + + +echo "Extend dat file... (current is ${fsMB}MB, append ${size}MB, total ${total}MB)" +dd if=/dev/zero bs=1M count=$size status=none >> "$file" +sync + +freeloop=$(losetup -f) +losetup $freeloop "$file" + +if [ "$cmd" = "resize2fs" ]; then + echo "Extend ext filesystem by resize2fs ..." + echo "resize2fs $freeloop ${total}M" + e2fsck -f $freeloop + resize2fs $freeloop ${total}M + ret=$? +else + echo "Extend xfs filesystem by xfs_growfs ..." + + tmpdir=$(mktemp -d) + mount $freeloop $tmpdir + xfs_growfs $freeloop + ret=$? + umount $tmpdir && rm -rf $tmpdir +fi + +losetup -d $freeloop + +echo "" +if [ $ret -eq 0 ]; then + echo "======= SUCCESS =========" +else + echo "======= FAILED =========" +fi +echo "" + diff --git a/INSTALL/README b/INSTALL/README new file mode 100644 index 00000000..01bfb34c --- /dev/null +++ b/INSTALL/README @@ -0,0 +1,46 @@ + +========== Ventoy2Disk.sh =============== + +sudo sh Ventoy2Disk.sh { -i | -I | -u } /dev/sdX sdX is the USB device, for example /dev/sdb. + +Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX + CMD: + -i install ventoy to sdX (fail if disk already installed with ventoy) + -I force install ventoy to sdX (no matter installed or not) + -u update ventoy in sdX + + OPTION: (optional) + -r SIZE_MB preserve some space at the bottom of the disk (only for install) + -s enable secure boot support (default is disabled) + -g use GPT partition style, default is MBR style (only for install) + +Please refer https://www.ventoy.net/en/doc_start.html for details. + + +========== VentoyWeb.sh =============== +1. sudo sh VentoyWeb.sh +2. open your browser and visit http://127.0.0.1:24680 + + +========== CreatePersistentImg.sh =============== + +sudo sh CreatePersistentImg.sh [ -s SIZE_IN_MB ] [ -t FSTYPE ] [ -l LABEL ] for example: + +sh CreatePersistentImg.sh ----> persistence.dat in 1GB size and ext4 filesystem and casper-rw label +sh CreatePersistentImg.sh -l MX-Persist ----> persistence.dat in 1GB size and ext4 filesystem and MX-Persist label +sh CreatePersistentImg.sh -s 2048 ----> persistence.dat in 2GB size and ext4 filesystem and casper-rw label +sh CreatePersistentImg.sh -s 4096 -t xfs ----> persistence.dat in 4GB size and xfs filesystem (ext2/3/4 xfs are supported) and casper-rw label + +Please refer https://www.ventoy.net/en/plugin_persistence.html for details. + + + +========== ExtendPersistentImg.sh =============== +sudo sh ExtendPersistentImg.sh file size +For example: +sh ExtendPersistentImg.sh persistence.dat 2048 ----> Extend persistence.dat by 2048MB +That is to say, persistence.dat file will grow to 3GB size (assume that it is 1GB size before extend) + +Please refer https://www.ventoy.net/en/plugin_persistence.html for details. + + diff --git a/INSTALL/Ventoy2Disk.exe b/INSTALL/Ventoy2Disk.exe index 1539d7b0..d207ffdb 100644 Binary files a/INSTALL/Ventoy2Disk.exe and b/INSTALL/Ventoy2Disk.exe differ diff --git a/INSTALL/Ventoy2Disk.sh b/INSTALL/Ventoy2Disk.sh index 02a69060..d8440d05 100644 --- a/INSTALL/Ventoy2Disk.sh +++ b/INSTALL/Ventoy2Disk.sh @@ -1,21 +1,38 @@ #!/bin/sh +OLDDIR=$(pwd) -echo '' -echo '***********************************************************' -echo '* Ventoy2Disk Script *' -echo '* longpanda admin@ventoy.net *' -echo '***********************************************************' -echo '' - -OLDDIR=$PWD - -if ! [ -f ./tool/xzcat ]; then - if [ -f ${0%Ventoy2Disk.sh}/tool/xzcat ]; then +if ! [ -f ./tool/ventoy_lib.sh ]; then + if [ -f ${0%Ventoy2Disk.sh}/tool/ventoy_lib.sh ]; then cd ${0%Ventoy2Disk.sh} fi fi +if [ -f ./ventoy/version ]; then + curver=$(cat ./ventoy/version) +fi + +if uname -m | egrep -q 'aarch64|arm64'; then + export TOOLDIR=aarch64 +elif uname -m | egrep -q 'x86_64|amd64'; then + export TOOLDIR=x86_64 +elif uname -m | egrep -q 'mips64'; then + export TOOLDIR=mips64el +else + export TOOLDIR=i386 +fi +export PATH="./tool/$TOOLDIR:$PATH" + + +echo '' +echo '**********************************************' +echo " Ventoy: $curver $TOOLDIR" +echo " longpanda admin@ventoy.net" +echo " https://www.ventoy.net" +echo '**********************************************' +echo '' + + if ! [ -f ./boot/boot.img ]; then if [ -d ./grub ]; then echo "Don't run Ventoy2Disk.sh here, please download the released install package, and run the script in it." @@ -25,26 +42,36 @@ if ! [ -f ./boot/boot.img ]; then exit 1 fi -echo "############# Ventoy2Disk $* ################" >> ./log.txt +echo "############# Ventoy2Disk $* [$TOOLDIR] ################" >> ./log.txt +date >> ./log.txt #decompress tool -if ! [ -f ./tool/ash ]; then - cd tool - chmod +x ./xzcat +if [ -f ./tool/$TOOLDIR/ash ]; then + echo "no need to decompress tools" >> ./log.txt +else + cd ./tool/$TOOLDIR + + [ -f ./xzcat ] && chmod +x ./xzcat + for file in $(ls *.xz); do - ./xzcat $file > ${file%.xz} - chmod +x ${file%.xz} + xzcat $file > ${file%.xz} + [ -f ./${file%.xz} ] && chmod +x ./${file%.xz} + [ -f ./$file ] && rm -f ./$file done - cd ../ - - if ! [ -f ./tool/ash ]; then - echo 'Failed to decompress tools ...' - cd $OLDDIR - exit 1 - fi + cd ../../ + + chmod +x -R ./tool/$TOOLDIR fi -./tool/ash ./tool/VentoyWorker.sh $* - -cd $OLDDIR +if [ -f /bin/bash ]; then + /bin/bash ./tool/VentoyWorker.sh $* +else + ash ./tool/VentoyWorker.sh $* +fi +if [ -n "$OLDDIR" ]; then + CURDIR=$(pwd) + if [ "$CURDIR" != "$OLDDIR" ]; then + cd "$OLDDIR" + fi +fi diff --git a/INSTALL/VentoyWeb.sh b/INSTALL/VentoyWeb.sh new file mode 100644 index 00000000..76ed0d56 --- /dev/null +++ b/INSTALL/VentoyWeb.sh @@ -0,0 +1,130 @@ +#!/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 ' -h print this help' + echo '' +} + +print_err() { + echo "" + echo "$*" + echo "" +} + +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 -m | egrep -q 'aarch64|arm64'; then + TOOLDIR=aarch64 +elif uname -m | egrep -q 'x86_64|amd64'; then + TOOLDIR=x86_64 +elif uname -m | egrep -q 'mips64'; then + TOOLDIR=mips64el +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 "Current directory is $PWD" + 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" = "-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 + +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 + fi +fi + + +if [ -f ./tool/$TOOLDIR/V2DServer.xz ]; then + xz -d ./tool/$TOOLDIR/V2DServer.xz + chmod +x ./tool/$TOOLDIR/V2DServer +fi + + +V2DServer "$HOST" "$PORT" & +wID=$! +sleep 1 + +vtVer=$(cat ventoy/version) +echo "" +echo "===============================================================" +if [ "$LANG" = "zh_CN.UTF-8" ]; then + echo " Ventoy Server $vtVer å·²ç»å¯åŠ¨ ..." + echo " 请打开æµè§ˆå™¨ï¼Œè®¿é—® http://${HOST}:${PORT}" +else + echo " Ventoy Server $vtVer is running ..." + echo " Please open your browser and visit http://${HOST}:${PORT}" +fi +echo "===============================================================" +echo "" +echo "################## Press Ctrl + C to exit #####################" +echo "" + +wait $wID + +if [ -n "$OLDDIR" ]; then + CURDIR=$(pwd) + if [ "$CURDIR" != "$OLDDIR" ]; then + cd "$OLDDIR" + fi +fi diff --git a/INSTALL/VentoyWebDeepin.sh b/INSTALL/VentoyWebDeepin.sh new file mode 100644 index 00000000..1bcaf2b9 --- /dev/null +++ b/INSTALL/VentoyWebDeepin.sh @@ -0,0 +1,109 @@ +#!/bin/sh + +if echo "$*" | grep -q '[-]v'; then + set -x +fi + +print_usage() { + echo 'Usage: VentoyWebDeepin.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 ' -h print this help' + echo ' -v print verbose info' + echo '' +} + +print_err() { + echo "" + echo "$*" + echo "" +} + +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 +} + +uid=$(id -u) +if [ $uid -ne 0 ]; then + exec sudo sh $0 $* +fi + +OLDDIR=$(pwd) + +if uname -m | egrep -q 'aarch64|arm64'; then + TOOLDIR=aarch64 +elif uname -m | egrep -q 'x86_64|amd64'; then + TOOLDIR=x86_64 +elif uname -m | egrep -q 'mips64'; then + TOOLDIR=mips64el +else + TOOLDIR=i386 +fi + +if [ ! -f ./tool/$TOOLDIR/V2DServer ]; then + if [ -f ${0%VentoyWebDeepin.sh}/tool/$TOOLDIR/V2DServer ]; then + cd ${0%VentoyWebDeepin.sh} + fi +fi + +PATH=./tool/$TOOLDIR:$PATH + +if [ ! -f ./boot/boot.img ]; then + if [ -d ./grub ]; then + echo "Don't run VentoyWebDeepin.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" = "-v" ]; then + VERBOSE=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 + +if grep -q -i uos /etc/os-release; then + . ./tool/WebUos.sh +else + . ./tool/WebDeepin.sh +fi diff --git a/INSTALL/all_in_one.sh b/INSTALL/all_in_one.sh index 89484e7c..14163f38 100644 --- a/INSTALL/all_in_one.sh +++ b/INSTALL/all_in_one.sh @@ -2,61 +2,83 @@ VTOY_PATH=$PWD/.. +cilog() { + datestr=$(date +"%Y/%m/%d %H:%M:%S") + echo "$datestr $*" +} + +LOG=$VTOY_PATH/DOC/build.log +[ -f $LOG ] && rm -f $LOG + cd $VTOY_PATH/DOC -sh installdietlibc.sh +cilog "prepare_env ..." +sh prepare_env.sh +export PATH=$PATH:/opt/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu/bin:/opt/aarch64--uclibc--stable-2020.08-1/bin:/opt/mips-loongson-gcc7.3-linux-gnu/2019.06-29/bin/:/opt/mips64el-linux-musl-gcc730/bin/ + +cilog "build grub2 ..." cd $VTOY_PATH/GRUB2 -sh buildgrub.sh || exit 1 +sh buildgrub.sh >> $LOG 2>&1 || exit 1 +cilog "build ipxe ..." cd $VTOY_PATH/IPXE -sh buildipxe.sh || exit 1 +sh buildipxe.sh >> $LOG 2>&1 || exit 1 +cilog "build edk2 ..." cd $VTOY_PATH/EDK2 -sh buildedk.sh || exit 1 - -cd $VTOY_PATH/VtoyTool -sh build.sh || exit 1 - -cd $VTOY_PATH/vtoyfat/fat_io_lib -sh buildlib.sh - -cd $VTOY_PATH/vtoyfat -sh build.sh || exit 1 +sh buildedk.sh >> $LOG 2>&1 || exit 1 -cd $VTOY_PATH/ExFAT -sh buidlibfuse.sh || exit 1 -sh buidexfat.sh || exit 1 -/bin/cp -a EXFAT/shared/mkexfatfs $VTOY_PATH/INSTALL/tool/mkexfatfs_64 -/bin/cp -a EXFAT/shared/mount.exfat-fuse $VTOY_PATH/INSTALL/tool/mount.exfat-fuse_64 + +# +# We almost rarely modifiy these code, so no need to build them everytime +# If you want to rebuild them, just uncomment them. +# + +#cd $VTOY_PATH/VtoyTool +#sh build.sh || exit 1 + +#cd $VTOY_PATH/vtoyfat/fat_io_lib +#sh buildlib.sh + +#cd $VTOY_PATH/vtoyfat +#sh build.sh || exit 1 + +#cd $VTOY_PATH/vtoygpt +#sh build.sh || exit 1 + +#cd $VTOY_PATH/FUSEISO +#sh build_libfuse.sh +#sh build.sh -cd $VTOY_PATH/FUSEISO -sh build_libfuse.sh -sh build.sh - -cd $VTOY_PATH/SQUASHFS/SRC -sh build_lz4.sh -sh build_lzma.sh -sh build_lzo.sh -sh build_zstd.sh - -cd $VTOY_PATH/SQUASHFS/squashfs-tools-4.4/squashfs-tools -sh build.sh - -cd $VTOY_PATH/VBLADE/vblade-master -sh build.sh - -cd $VTOY_PATH/Ventoy2Disk/Ventoy2Disk/xz-embedded-20130513/userspace -make -f ventoy_makefile -strip --strip-all xzminidec -rm -f $VTOY_PATH/IMG/cpio/ventoy/tool/xzminidec -cp -a xzminidec $VTOY_PATH/IMG/cpio/ventoy/tool/xzminidec -make clean; rm -f *.o +# cd $VTOY_PATH/ExFAT +# sh buidlibfuse.sh || exit 1 +# sh buidexfat.sh || exit 1 +# /bin/cp -a EXFAT/shared/mkexfatfs $VTOY_PATH/INSTALL/tool/mkexfatfs_64 +# /bin/cp -a EXFAT/shared/mount.exfat-fuse $VTOY_PATH/INSTALL/tool/mount.exfat-fuse_64 +# cd $VTOY_PATH/SQUASHFS/SRC +# sh build_lz4.sh +# sh build_lzma.sh +# sh build_lzo.sh +# sh build_zstd.sh + +# cd $VTOY_PATH/SQUASHFS/squashfs-tools-4.4/squashfs-tools +# sh build.sh + +# cd $VTOY_PATH/VBLADE/vblade-master +# sh build.sh cd $VTOY_PATH/INSTALL -sh ventoy_pack.sh || exit 1 + +if [ "$1" = "CI" ]; then + Ver=$(date +%m%d%H%M) + sed "s/VENTOY_VERSION=.*/VENTOY_VERSION=\"$Ver\"/" -i ./grub/grub.cfg +fi + +cilog "packing ventoy-$Ver ..." +sh ventoy_pack.sh $1 >> $LOG 2>&1 || exit 1 echo -e '\n============== SUCCESS ==================\n' diff --git a/INSTALL/docker_ci_build.sh b/INSTALL/docker_ci_build.sh new file mode 100644 index 00000000..7b7db0d4 --- /dev/null +++ b/INSTALL/docker_ci_build.sh @@ -0,0 +1,19 @@ +#!/bin/sh + +VTOY_PATH=$PWD/.. + +date +"%Y/%m/%d %H:%M:%S" +echo downloading envrionment ... + +wget -q -P $VTOY_PATH/DOC/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/dietlibc-0.34.tar.xz +wget -q -P $VTOY_PATH/DOC/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/musl-1.2.1.tar.gz +wget -q -P $VTOY_PATH/GRUB2/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/grub-2.04.tar.xz +wget -q -O $VTOY_PATH/EDK2/edk2-edk2-stable201911.zip https://codeload.github.com/tianocore/edk2/zip/edk2-stable201911 +wget -q -P /opt/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz +wget -q -P /opt/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/aarch64--uclibc--stable-2020.08-1.tar.bz2 +wget -q -P /opt/ https://github.com/ventoy/vtoytoolchain/releases/download/1.0/mips-loongson-gcc7.3-2019.06-29-linux-gnu.tar.gz + +date +"%Y/%m/%d %H:%M:%S" +echo downloading envrionment finish... + +sh all_in_one.sh CI diff --git a/INSTALL/grub/arm64-efi/adler32.mod b/INSTALL/grub/arm64-efi/adler32.mod new file mode 100644 index 00000000..17937684 Binary files /dev/null and b/INSTALL/grub/arm64-efi/adler32.mod differ diff --git a/INSTALL/grub/arm64-efi/affs.mod b/INSTALL/grub/arm64-efi/affs.mod new file mode 100644 index 00000000..b41d87d7 Binary files /dev/null and b/INSTALL/grub/arm64-efi/affs.mod differ diff --git a/INSTALL/grub/arm64-efi/afs.mod b/INSTALL/grub/arm64-efi/afs.mod new file mode 100644 index 00000000..d84f2d23 Binary files /dev/null and b/INSTALL/grub/arm64-efi/afs.mod differ diff --git a/INSTALL/grub/arm64-efi/archelp.mod b/INSTALL/grub/arm64-efi/archelp.mod new file mode 100644 index 00000000..30241dfa Binary files /dev/null and b/INSTALL/grub/arm64-efi/archelp.mod differ diff --git a/INSTALL/grub/arm64-efi/bfs.mod b/INSTALL/grub/arm64-efi/bfs.mod new file mode 100644 index 00000000..db600866 Binary files /dev/null and b/INSTALL/grub/arm64-efi/bfs.mod differ diff --git a/INSTALL/grub/arm64-efi/blscfg.mod b/INSTALL/grub/arm64-efi/blscfg.mod new file mode 100644 index 00000000..9b42d3d9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/blscfg.mod differ diff --git a/INSTALL/grub/arm64-efi/bswap_test.mod b/INSTALL/grub/arm64-efi/bswap_test.mod new file mode 100644 index 00000000..fd5ab451 Binary files /dev/null and b/INSTALL/grub/arm64-efi/bswap_test.mod differ diff --git a/INSTALL/grub/arm64-efi/btrfs.mod b/INSTALL/grub/arm64-efi/btrfs.mod new file mode 100644 index 00000000..16692055 Binary files /dev/null and b/INSTALL/grub/arm64-efi/btrfs.mod differ diff --git a/INSTALL/grub/arm64-efi/cbfs.mod b/INSTALL/grub/arm64-efi/cbfs.mod new file mode 100644 index 00000000..f700ae6e Binary files /dev/null and b/INSTALL/grub/arm64-efi/cbfs.mod differ diff --git a/INSTALL/grub/arm64-efi/cmdline_cat_test.mod b/INSTALL/grub/arm64-efi/cmdline_cat_test.mod new file mode 100644 index 00000000..3b0f38a0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/arm64-efi/cmp.mod b/INSTALL/grub/arm64-efi/cmp.mod new file mode 100644 index 00000000..a7d9210d Binary files /dev/null and b/INSTALL/grub/arm64-efi/cmp.mod differ diff --git a/INSTALL/grub/arm64-efi/cmp_test.mod b/INSTALL/grub/arm64-efi/cmp_test.mod new file mode 100644 index 00000000..f70cca2b Binary files /dev/null and b/INSTALL/grub/arm64-efi/cmp_test.mod differ diff --git a/INSTALL/grub/arm64-efi/command.lst b/INSTALL/grub/arm64-efi/command.lst new file mode 100644 index 00000000..23f101cd --- /dev/null +++ b/INSTALL/grub/arm64-efi/command.lst @@ -0,0 +1,144 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*bls_import: blscfg +*blscfg: blscfg +*cat: cat +*crc: hashsum +*cryptomount: cryptodisk +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*gettext: gettext +*hashsum: hashsum +*hello: hello +*help: help +*hexdump: hexdump +*keystatus: keystatus +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*md5sum: hashsum +*menuentry: normal +*probe: probe +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*serial: serial +*set_keyboard_layout: setkey +*setkey: setkey +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*zfskey: zfscrypt +.: configfile +[: test +authenticate: normal +background_color: gfxterm_background +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +chainloader: chain +clear: normal +cmp: cmp +configfile: configfile +continue: normal +cutmem: mmap +date: date +devicetree: fdt +distrust: pgp +dump: minicmd +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +false: true +fwsetup: efifwsetup +gptsync: gptsync +halt: halt +help: minicmd +initrd: linux +initrdefi: linux +linux: linux +linuxefi: linux +list_trusted: pgp +loadfont: font +lsefi: lsefi +lsefimmap: lsefimmap +lsefisystab: lsefisystab +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +lssal: lssal +macppcbless: macbless +mactelbless: macbless +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +videoinfo: videoinfo +videotest: videotest +vt_img_extra_initrd_append: linux +vt_img_extra_initrd_reset: linux +vt_set_boot_opt: linux +vt_unset_boot_opt: linux +write_byte: memrw +write_dword: memrw +write_word: memrw +xen_hypervisor: xen_boot +xen_module: xen_boot +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/arm64-efi/cpio.mod b/INSTALL/grub/arm64-efi/cpio.mod new file mode 100644 index 00000000..f7d966c5 Binary files /dev/null and b/INSTALL/grub/arm64-efi/cpio.mod differ diff --git a/INSTALL/grub/arm64-efi/cpio_be.mod b/INSTALL/grub/arm64-efi/cpio_be.mod new file mode 100644 index 00000000..5e90c17a Binary files /dev/null and b/INSTALL/grub/arm64-efi/cpio_be.mod differ diff --git a/INSTALL/grub/arm64-efi/crc64.mod b/INSTALL/grub/arm64-efi/crc64.mod new file mode 100644 index 00000000..8b084f15 Binary files /dev/null and b/INSTALL/grub/arm64-efi/crc64.mod differ diff --git a/INSTALL/grub/arm64-efi/crypto.lst b/INSTALL/grub/arm64-efi/crypto.lst new file mode 100644 index 00000000..77d9efc0 --- /dev/null +++ b/INSTALL/grub/arm64-efi/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/arm64-efi/cryptodisk.mod b/INSTALL/grub/arm64-efi/cryptodisk.mod new file mode 100644 index 00000000..1eac1a0e Binary files /dev/null and b/INSTALL/grub/arm64-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/arm64-efi/ctz_test.mod b/INSTALL/grub/arm64-efi/ctz_test.mod new file mode 100644 index 00000000..626f0c3b Binary files /dev/null and b/INSTALL/grub/arm64-efi/ctz_test.mod differ diff --git a/INSTALL/grub/arm64-efi/date.mod b/INSTALL/grub/arm64-efi/date.mod new file mode 100644 index 00000000..16ec0642 Binary files /dev/null and b/INSTALL/grub/arm64-efi/date.mod differ diff --git a/INSTALL/grub/arm64-efi/datehook.mod b/INSTALL/grub/arm64-efi/datehook.mod new file mode 100644 index 00000000..c8479fa2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/datehook.mod differ diff --git a/INSTALL/grub/arm64-efi/disk.mod b/INSTALL/grub/arm64-efi/disk.mod new file mode 100644 index 00000000..493ae1ea Binary files /dev/null and b/INSTALL/grub/arm64-efi/disk.mod differ diff --git a/INSTALL/grub/arm64-efi/div.mod b/INSTALL/grub/arm64-efi/div.mod new file mode 100644 index 00000000..07f9731d Binary files /dev/null and b/INSTALL/grub/arm64-efi/div.mod differ diff --git a/INSTALL/grub/arm64-efi/div_test.mod b/INSTALL/grub/arm64-efi/div_test.mod new file mode 100644 index 00000000..c30473ff Binary files /dev/null and b/INSTALL/grub/arm64-efi/div_test.mod differ diff --git a/INSTALL/grub/arm64-efi/dm_nv.mod b/INSTALL/grub/arm64-efi/dm_nv.mod new file mode 100644 index 00000000..0da01507 Binary files /dev/null and b/INSTALL/grub/arm64-efi/dm_nv.mod differ diff --git a/INSTALL/grub/arm64-efi/efinet.mod b/INSTALL/grub/arm64-efi/efinet.mod new file mode 100644 index 00000000..941db7d1 Binary files /dev/null and b/INSTALL/grub/arm64-efi/efinet.mod differ diff --git a/INSTALL/grub/arm64-efi/elf.mod b/INSTALL/grub/arm64-efi/elf.mod new file mode 100644 index 00000000..22959145 Binary files /dev/null and b/INSTALL/grub/arm64-efi/elf.mod differ diff --git a/INSTALL/grub/arm64-efi/eval.mod b/INSTALL/grub/arm64-efi/eval.mod new file mode 100644 index 00000000..3cd9d098 Binary files /dev/null and b/INSTALL/grub/arm64-efi/eval.mod differ diff --git a/INSTALL/grub/arm64-efi/exfctest.mod b/INSTALL/grub/arm64-efi/exfctest.mod new file mode 100644 index 00000000..62278bd9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/exfctest.mod differ diff --git a/INSTALL/grub/arm64-efi/f2fs.mod b/INSTALL/grub/arm64-efi/f2fs.mod new file mode 100644 index 00000000..73dc88bb Binary files /dev/null and b/INSTALL/grub/arm64-efi/f2fs.mod differ diff --git a/INSTALL/grub/arm64-efi/fdt.lst b/INSTALL/grub/arm64-efi/fdt.lst new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL/grub/arm64-efi/fdt.mod b/INSTALL/grub/arm64-efi/fdt.mod new file mode 100644 index 00000000..d295efe7 Binary files /dev/null and b/INSTALL/grub/arm64-efi/fdt.mod differ diff --git a/INSTALL/grub/arm64-efi/fs.lst b/INSTALL/grub/arm64-efi/fs.lst new file mode 100644 index 00000000..0acd240b --- /dev/null +++ b/INSTALL/grub/arm64-efi/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/arm64-efi/functional_test.mod b/INSTALL/grub/arm64-efi/functional_test.mod new file mode 100644 index 00000000..2db96334 Binary files /dev/null and b/INSTALL/grub/arm64-efi/functional_test.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_arcfour.mod b/INSTALL/grub/arm64-efi/gcry_arcfour.mod new file mode 100644 index 00000000..e78d0716 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_blowfish.mod b/INSTALL/grub/arm64-efi/gcry_blowfish.mod new file mode 100644 index 00000000..fe2c3a98 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_camellia.mod b/INSTALL/grub/arm64-efi/gcry_camellia.mod new file mode 100644 index 00000000..6c259ae5 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_cast5.mod b/INSTALL/grub/arm64-efi/gcry_cast5.mod new file mode 100644 index 00000000..cb0f5de7 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_crc.mod b/INSTALL/grub/arm64-efi/gcry_crc.mod new file mode 100644 index 00000000..ae0a4619 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_des.mod b/INSTALL/grub/arm64-efi/gcry_des.mod new file mode 100644 index 00000000..49e0723d Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_des.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_dsa.mod b/INSTALL/grub/arm64-efi/gcry_dsa.mod new file mode 100644 index 00000000..cfceba77 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_idea.mod b/INSTALL/grub/arm64-efi/gcry_idea.mod new file mode 100644 index 00000000..8a1e4928 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_md4.mod b/INSTALL/grub/arm64-efi/gcry_md4.mod new file mode 100644 index 00000000..514efcf5 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rfc2268.mod b/INSTALL/grub/arm64-efi/gcry_rfc2268.mod new file mode 100644 index 00000000..8f2bd3e3 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rijndael.mod b/INSTALL/grub/arm64-efi/gcry_rijndael.mod new file mode 100644 index 00000000..272b6bbb Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rmd160.mod b/INSTALL/grub/arm64-efi/gcry_rmd160.mod new file mode 100644 index 00000000..04827ec0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_rsa.mod b/INSTALL/grub/arm64-efi/gcry_rsa.mod new file mode 100644 index 00000000..50ffc9d2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_seed.mod b/INSTALL/grub/arm64-efi/gcry_seed.mod new file mode 100644 index 00000000..95611c1e Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_serpent.mod b/INSTALL/grub/arm64-efi/gcry_serpent.mod new file mode 100644 index 00000000..abfe5718 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_sha1.mod b/INSTALL/grub/arm64-efi/gcry_sha1.mod new file mode 100644 index 00000000..60c1aab0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_sha256.mod b/INSTALL/grub/arm64-efi/gcry_sha256.mod new file mode 100644 index 00000000..b592e9e0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_tiger.mod b/INSTALL/grub/arm64-efi/gcry_tiger.mod new file mode 100644 index 00000000..8795df34 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_twofish.mod b/INSTALL/grub/arm64-efi/gcry_twofish.mod new file mode 100644 index 00000000..fb2a6c92 Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/arm64-efi/gcry_whirlpool.mod b/INSTALL/grub/arm64-efi/gcry_whirlpool.mod new file mode 100644 index 00000000..e77346ed Binary files /dev/null and b/INSTALL/grub/arm64-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/arm64-efi/geli.mod b/INSTALL/grub/arm64-efi/geli.mod new file mode 100644 index 00000000..6aeb5bf8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/geli.mod differ diff --git a/INSTALL/grub/arm64-efi/gfxterm_menu.mod b/INSTALL/grub/arm64-efi/gfxterm_menu.mod new file mode 100644 index 00000000..0a2f103c Binary files /dev/null and b/INSTALL/grub/arm64-efi/gfxterm_menu.mod differ diff --git a/INSTALL/grub/arm64-efi/gptsync.mod b/INSTALL/grub/arm64-efi/gptsync.mod new file mode 100644 index 00000000..17924d5b Binary files /dev/null and b/INSTALL/grub/arm64-efi/gptsync.mod differ diff --git a/INSTALL/grub/arm64-efi/hello.mod b/INSTALL/grub/arm64-efi/hello.mod new file mode 100644 index 00000000..459aaa3d Binary files /dev/null and b/INSTALL/grub/arm64-efi/hello.mod differ diff --git a/INSTALL/grub/arm64-efi/help.mod b/INSTALL/grub/arm64-efi/help.mod new file mode 100644 index 00000000..81c4bb5a Binary files /dev/null and b/INSTALL/grub/arm64-efi/help.mod differ diff --git a/INSTALL/grub/arm64-efi/hexdump.mod b/INSTALL/grub/arm64-efi/hexdump.mod new file mode 100644 index 00000000..65c48830 Binary files /dev/null and b/INSTALL/grub/arm64-efi/hexdump.mod differ diff --git a/INSTALL/grub/arm64-efi/hfs.mod b/INSTALL/grub/arm64-efi/hfs.mod new file mode 100644 index 00000000..a0c1c314 Binary files /dev/null and b/INSTALL/grub/arm64-efi/hfs.mod differ diff --git a/INSTALL/grub/arm64-efi/hfspluscomp.mod b/INSTALL/grub/arm64-efi/hfspluscomp.mod new file mode 100644 index 00000000..ebc5b18e Binary files /dev/null and b/INSTALL/grub/arm64-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/arm64-efi/jfs.mod b/INSTALL/grub/arm64-efi/jfs.mod new file mode 100644 index 00000000..b48ca1c3 Binary files /dev/null and b/INSTALL/grub/arm64-efi/jfs.mod differ diff --git a/INSTALL/grub/arm64-efi/keystatus.mod b/INSTALL/grub/arm64-efi/keystatus.mod new file mode 100644 index 00000000..24e97080 Binary files /dev/null and b/INSTALL/grub/arm64-efi/keystatus.mod differ diff --git a/INSTALL/grub/arm64-efi/ldm.mod b/INSTALL/grub/arm64-efi/ldm.mod new file mode 100644 index 00000000..95e626ba Binary files /dev/null and b/INSTALL/grub/arm64-efi/ldm.mod differ diff --git a/INSTALL/grub/arm64-efi/loadenv.mod b/INSTALL/grub/arm64-efi/loadenv.mod new file mode 100644 index 00000000..996730c8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/loadenv.mod differ diff --git a/INSTALL/grub/arm64-efi/lsacpi.mod b/INSTALL/grub/arm64-efi/lsacpi.mod new file mode 100644 index 00000000..9915a649 Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsacpi.mod differ diff --git a/INSTALL/grub/arm64-efi/lsefi.mod b/INSTALL/grub/arm64-efi/lsefi.mod new file mode 100644 index 00000000..56e709d2 Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsefi.mod differ diff --git a/INSTALL/grub/arm64-efi/lsefimmap.mod b/INSTALL/grub/arm64-efi/lsefimmap.mod new file mode 100644 index 00000000..815e3da8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/arm64-efi/lsefisystab.mod b/INSTALL/grub/arm64-efi/lsefisystab.mod new file mode 100644 index 00000000..64831e1d Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/arm64-efi/lsmmap.mod b/INSTALL/grub/arm64-efi/lsmmap.mod new file mode 100644 index 00000000..98b8499b Binary files /dev/null and b/INSTALL/grub/arm64-efi/lsmmap.mod differ diff --git a/INSTALL/grub/arm64-efi/lssal.mod b/INSTALL/grub/arm64-efi/lssal.mod new file mode 100644 index 00000000..435c5a95 Binary files /dev/null and b/INSTALL/grub/arm64-efi/lssal.mod differ diff --git a/INSTALL/grub/arm64-efi/luks.mod b/INSTALL/grub/arm64-efi/luks.mod new file mode 100644 index 00000000..24c39745 Binary files /dev/null and b/INSTALL/grub/arm64-efi/luks.mod differ diff --git a/INSTALL/grub/arm64-efi/lvm.mod b/INSTALL/grub/arm64-efi/lvm.mod new file mode 100644 index 00000000..dd087446 Binary files /dev/null and b/INSTALL/grub/arm64-efi/lvm.mod differ diff --git a/INSTALL/grub/arm64-efi/macbless.mod b/INSTALL/grub/arm64-efi/macbless.mod new file mode 100644 index 00000000..970030b9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/macbless.mod differ diff --git a/INSTALL/grub/arm64-efi/macho.mod b/INSTALL/grub/arm64-efi/macho.mod new file mode 100644 index 00000000..2b09206a Binary files /dev/null and b/INSTALL/grub/arm64-efi/macho.mod differ diff --git a/INSTALL/grub/arm64-efi/mdraid09.mod b/INSTALL/grub/arm64-efi/mdraid09.mod new file mode 100644 index 00000000..82044c87 Binary files /dev/null and b/INSTALL/grub/arm64-efi/mdraid09.mod differ diff --git a/INSTALL/grub/arm64-efi/mdraid09_be.mod b/INSTALL/grub/arm64-efi/mdraid09_be.mod new file mode 100644 index 00000000..ec9e183a Binary files /dev/null and b/INSTALL/grub/arm64-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/arm64-efi/mdraid1x.mod b/INSTALL/grub/arm64-efi/mdraid1x.mod new file mode 100644 index 00000000..dc3c11ca Binary files /dev/null and b/INSTALL/grub/arm64-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/arm64-efi/memdisk.mod b/INSTALL/grub/arm64-efi/memdisk.mod new file mode 100644 index 00000000..6e48df2f Binary files /dev/null and b/INSTALL/grub/arm64-efi/memdisk.mod differ diff --git a/INSTALL/grub/arm64-efi/memrw.mod b/INSTALL/grub/arm64-efi/memrw.mod new file mode 100644 index 00000000..b7d77511 Binary files /dev/null and b/INSTALL/grub/arm64-efi/memrw.mod differ diff --git a/INSTALL/grub/arm64-efi/minix.mod b/INSTALL/grub/arm64-efi/minix.mod new file mode 100644 index 00000000..a22a811b Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix.mod differ diff --git a/INSTALL/grub/arm64-efi/minix2.mod b/INSTALL/grub/arm64-efi/minix2.mod new file mode 100644 index 00000000..b5e18f4d Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix2.mod differ diff --git a/INSTALL/grub/arm64-efi/minix2_be.mod b/INSTALL/grub/arm64-efi/minix2_be.mod new file mode 100644 index 00000000..56066e88 Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix2_be.mod differ diff --git a/INSTALL/grub/arm64-efi/minix3.mod b/INSTALL/grub/arm64-efi/minix3.mod new file mode 100644 index 00000000..f6e3337b Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix3.mod differ diff --git a/INSTALL/grub/arm64-efi/minix3_be.mod b/INSTALL/grub/arm64-efi/minix3_be.mod new file mode 100644 index 00000000..df5f6da4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix3_be.mod differ diff --git a/INSTALL/grub/arm64-efi/minix_be.mod b/INSTALL/grub/arm64-efi/minix_be.mod new file mode 100644 index 00000000..f3e4eebd Binary files /dev/null and b/INSTALL/grub/arm64-efi/minix_be.mod differ diff --git a/INSTALL/grub/arm64-efi/moddep.lst b/INSTALL/grub/arm64-efi/moddep.lst new file mode 100644 index 00000000..bc26700b --- /dev/null +++ b/INSTALL/grub/arm64-efi/moddep.lst @@ -0,0 +1,217 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +setkey: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +lsefimmap: +gcry_arcfour: crypto +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video +jfs: +help: extcmd normal +configfile: normal +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +afs: fshelp +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +xen_boot: linux boot fdt +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +fdt: +efinet: net +disk: +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +offsetio: +file: elf macho extcmd offsetio +video_colors: +hashsum: crypto extcmd normal +halt: +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: ventoy verifiers boot fdt +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +part_sun: +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +verifiers: +bufio: +blscfg: extcmd normal +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +minicmd: +signature_test: functional_test procfs +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +mul_test: functional_test +adler32: crypto +terminal: +div: +crypto: +part_bsd: part_msdos +ventoy: elf fshelp ext2 btrfs font crypto gcry_md5 exfat udf extcmd datetime div normal video gcry_sha1 iso9660 +gcry_sha512: crypto +password: crypto normal +fshelp: +sleep_test: functional_test datetime +mmap: +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +eval: normal +part_dvh: +lssal: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: mmap +strtoull_test: functional_test +bitmap: +ntfs: fshelp +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +archelp: +http: net +zfs: gzio +raid6rec: diskfilter +lsefisystab: +minix2: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +hfs: fshelp +procfs: archelp +boot: +progress: normal +kernel: +acpi: extcmd mmap +tga: bufio bitmap +reboot: +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +efifwsetup: +ctz_test: functional_test +video: +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp lzopio xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +gcry_tiger: crypto +search: search_fs_uuid search_fs_file extcmd search_label +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +ntfscomp: ntfs +lzopio: crypto +hello: extcmd +scsi: +cat: extcmd +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +chain: net efinet boot +cbfs: archelp +ufs2: +time: +gptsync: disk +search_label: +setjmp: +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +part_amiga: +efi_gop: video video_fb +minix: +echo: extcmd +lsefi: +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +all_video: efi_gop diff --git a/INSTALL/grub/arm64-efi/mpi.mod b/INSTALL/grub/arm64-efi/mpi.mod new file mode 100644 index 00000000..10dea4d9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/mpi.mod differ diff --git a/INSTALL/grub/arm64-efi/msdospart.mod b/INSTALL/grub/arm64-efi/msdospart.mod new file mode 100644 index 00000000..a3f545e6 Binary files /dev/null and b/INSTALL/grub/arm64-efi/msdospart.mod differ diff --git a/INSTALL/grub/arm64-efi/mul_test.mod b/INSTALL/grub/arm64-efi/mul_test.mod new file mode 100644 index 00000000..0c554df4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/mul_test.mod differ diff --git a/INSTALL/grub/arm64-efi/nilfs2.mod b/INSTALL/grub/arm64-efi/nilfs2.mod new file mode 100644 index 00000000..51f727a3 Binary files /dev/null and b/INSTALL/grub/arm64-efi/nilfs2.mod differ diff --git a/INSTALL/grub/arm64-efi/normal.mod b/INSTALL/grub/arm64-efi/normal.mod new file mode 100644 index 00000000..3eabbc40 Binary files /dev/null and b/INSTALL/grub/arm64-efi/normal.mod differ diff --git a/INSTALL/grub/arm64-efi/ntfscomp.mod b/INSTALL/grub/arm64-efi/ntfscomp.mod new file mode 100644 index 00000000..28f7fd43 Binary files /dev/null and b/INSTALL/grub/arm64-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/arm64-efi/odc.mod b/INSTALL/grub/arm64-efi/odc.mod new file mode 100644 index 00000000..e5ad8c65 Binary files /dev/null and b/INSTALL/grub/arm64-efi/odc.mod differ diff --git a/INSTALL/grub/arm64-efi/offsetio.mod b/INSTALL/grub/arm64-efi/offsetio.mod new file mode 100644 index 00000000..a6a9b17b Binary files /dev/null and b/INSTALL/grub/arm64-efi/offsetio.mod differ diff --git a/INSTALL/grub/arm64-efi/part_acorn.mod b/INSTALL/grub/arm64-efi/part_acorn.mod new file mode 100644 index 00000000..00f1bcf8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_acorn.mod differ diff --git a/INSTALL/grub/arm64-efi/part_amiga.mod b/INSTALL/grub/arm64-efi/part_amiga.mod new file mode 100644 index 00000000..6efa51fe Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_amiga.mod differ diff --git a/INSTALL/grub/arm64-efi/part_bsd.mod b/INSTALL/grub/arm64-efi/part_bsd.mod new file mode 100644 index 00000000..67303ffd Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_bsd.mod differ diff --git a/INSTALL/grub/arm64-efi/part_dfly.mod b/INSTALL/grub/arm64-efi/part_dfly.mod new file mode 100644 index 00000000..fe8deac8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_dfly.mod differ diff --git a/INSTALL/grub/arm64-efi/part_dvh.mod b/INSTALL/grub/arm64-efi/part_dvh.mod new file mode 100644 index 00000000..46c5d032 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_dvh.mod differ diff --git a/INSTALL/grub/arm64-efi/part_plan.mod b/INSTALL/grub/arm64-efi/part_plan.mod new file mode 100644 index 00000000..3e719ffe Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_plan.mod differ diff --git a/INSTALL/grub/arm64-efi/part_sun.mod b/INSTALL/grub/arm64-efi/part_sun.mod new file mode 100644 index 00000000..6ca0dd5a Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_sun.mod differ diff --git a/INSTALL/grub/arm64-efi/part_sunpc.mod b/INSTALL/grub/arm64-efi/part_sunpc.mod new file mode 100644 index 00000000..45ad50e4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/arm64-efi/partmap.lst b/INSTALL/grub/arm64-efi/partmap.lst new file mode 100644 index 00000000..761233aa --- /dev/null +++ b/INSTALL/grub/arm64-efi/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/arm64-efi/parttool.lst b/INSTALL/grub/arm64-efi/parttool.lst new file mode 100644 index 00000000..68b4b5c4 --- /dev/null +++ b/INSTALL/grub/arm64-efi/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/arm64-efi/parttool.mod b/INSTALL/grub/arm64-efi/parttool.mod new file mode 100644 index 00000000..0ca0e5f9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/parttool.mod differ diff --git a/INSTALL/grub/arm64-efi/password.mod b/INSTALL/grub/arm64-efi/password.mod new file mode 100644 index 00000000..c9640fce Binary files /dev/null and b/INSTALL/grub/arm64-efi/password.mod differ diff --git a/INSTALL/grub/arm64-efi/pbkdf2_test.mod b/INSTALL/grub/arm64-efi/pbkdf2_test.mod new file mode 100644 index 00000000..846ea5ca Binary files /dev/null and b/INSTALL/grub/arm64-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/arm64-efi/pgp.mod b/INSTALL/grub/arm64-efi/pgp.mod new file mode 100644 index 00000000..bc605698 Binary files /dev/null and b/INSTALL/grub/arm64-efi/pgp.mod differ diff --git a/INSTALL/grub/arm64-efi/probe.mod b/INSTALL/grub/arm64-efi/probe.mod new file mode 100644 index 00000000..85d414da Binary files /dev/null and b/INSTALL/grub/arm64-efi/probe.mod differ diff --git a/INSTALL/grub/arm64-efi/procfs.mod b/INSTALL/grub/arm64-efi/procfs.mod new file mode 100644 index 00000000..0c9d57f0 Binary files /dev/null and b/INSTALL/grub/arm64-efi/procfs.mod differ diff --git a/INSTALL/grub/arm64-efi/progress.mod b/INSTALL/grub/arm64-efi/progress.mod new file mode 100644 index 00000000..a33cc651 Binary files /dev/null and b/INSTALL/grub/arm64-efi/progress.mod differ diff --git a/INSTALL/grub/arm64-efi/raid5rec.mod b/INSTALL/grub/arm64-efi/raid5rec.mod new file mode 100644 index 00000000..7d879ac9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/raid5rec.mod differ diff --git a/INSTALL/grub/arm64-efi/raid6rec.mod b/INSTALL/grub/arm64-efi/raid6rec.mod new file mode 100644 index 00000000..c9bc6bab Binary files /dev/null and b/INSTALL/grub/arm64-efi/raid6rec.mod differ diff --git a/INSTALL/grub/arm64-efi/reiserfs.mod b/INSTALL/grub/arm64-efi/reiserfs.mod new file mode 100644 index 00000000..a1d3de69 Binary files /dev/null and b/INSTALL/grub/arm64-efi/reiserfs.mod differ diff --git a/INSTALL/grub/arm64-efi/romfs.mod b/INSTALL/grub/arm64-efi/romfs.mod new file mode 100644 index 00000000..807776f5 Binary files /dev/null and b/INSTALL/grub/arm64-efi/romfs.mod differ diff --git a/INSTALL/grub/arm64-efi/scsi.mod b/INSTALL/grub/arm64-efi/scsi.mod new file mode 100644 index 00000000..bf5e14bd Binary files /dev/null and b/INSTALL/grub/arm64-efi/scsi.mod differ diff --git a/INSTALL/grub/arm64-efi/search_fs_file.mod b/INSTALL/grub/arm64-efi/search_fs_file.mod new file mode 100644 index 00000000..9467d97b Binary files /dev/null and b/INSTALL/grub/arm64-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/arm64-efi/search_fs_uuid.mod b/INSTALL/grub/arm64-efi/search_fs_uuid.mod new file mode 100644 index 00000000..2fe64d64 Binary files /dev/null and b/INSTALL/grub/arm64-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/arm64-efi/search_label.mod b/INSTALL/grub/arm64-efi/search_label.mod new file mode 100644 index 00000000..536e2e7d Binary files /dev/null and b/INSTALL/grub/arm64-efi/search_label.mod differ diff --git a/INSTALL/grub/arm64-efi/setjmp.mod b/INSTALL/grub/arm64-efi/setjmp.mod new file mode 100644 index 00000000..8104cc7f Binary files /dev/null and b/INSTALL/grub/arm64-efi/setjmp.mod differ diff --git a/INSTALL/grub/arm64-efi/setjmp_test.mod b/INSTALL/grub/arm64-efi/setjmp_test.mod new file mode 100644 index 00000000..a7290efc Binary files /dev/null and b/INSTALL/grub/arm64-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/arm64-efi/sfs.mod b/INSTALL/grub/arm64-efi/sfs.mod new file mode 100644 index 00000000..680d753f Binary files /dev/null and b/INSTALL/grub/arm64-efi/sfs.mod differ diff --git a/INSTALL/grub/arm64-efi/shift_test.mod b/INSTALL/grub/arm64-efi/shift_test.mod new file mode 100644 index 00000000..4d7c7626 Binary files /dev/null and b/INSTALL/grub/arm64-efi/shift_test.mod differ diff --git a/INSTALL/grub/arm64-efi/signature_test.mod b/INSTALL/grub/arm64-efi/signature_test.mod new file mode 100644 index 00000000..781758ca Binary files /dev/null and b/INSTALL/grub/arm64-efi/signature_test.mod differ diff --git a/INSTALL/grub/arm64-efi/sleep_test.mod b/INSTALL/grub/arm64-efi/sleep_test.mod new file mode 100644 index 00000000..56269434 Binary files /dev/null and b/INSTALL/grub/arm64-efi/sleep_test.mod differ diff --git a/INSTALL/grub/arm64-efi/strtoull_test.mod b/INSTALL/grub/arm64-efi/strtoull_test.mod new file mode 100644 index 00000000..0463d252 Binary files /dev/null and b/INSTALL/grub/arm64-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/arm64-efi/syslinuxcfg.mod b/INSTALL/grub/arm64-efi/syslinuxcfg.mod new file mode 100644 index 00000000..b2fd45a9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/arm64-efi/terminal.lst b/INSTALL/grub/arm64-efi/terminal.lst new file mode 100644 index 00000000..6743731b --- /dev/null +++ b/INSTALL/grub/arm64-efi/terminal.lst @@ -0,0 +1,3 @@ +iserial_*: serial +ogfxterm: gfxterm +oserial_*: serial diff --git a/INSTALL/grub/arm64-efi/test_blockarg.mod b/INSTALL/grub/arm64-efi/test_blockarg.mod new file mode 100644 index 00000000..c5aaaff8 Binary files /dev/null and b/INSTALL/grub/arm64-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/arm64-efi/testload.mod b/INSTALL/grub/arm64-efi/testload.mod new file mode 100644 index 00000000..be494eb4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/testload.mod differ diff --git a/INSTALL/grub/arm64-efi/testspeed.mod b/INSTALL/grub/arm64-efi/testspeed.mod new file mode 100644 index 00000000..4206de50 Binary files /dev/null and b/INSTALL/grub/arm64-efi/testspeed.mod differ diff --git a/INSTALL/grub/arm64-efi/tga.mod b/INSTALL/grub/arm64-efi/tga.mod new file mode 100644 index 00000000..b0930b85 Binary files /dev/null and b/INSTALL/grub/arm64-efi/tga.mod differ diff --git a/INSTALL/grub/arm64-efi/time.mod b/INSTALL/grub/arm64-efi/time.mod new file mode 100644 index 00000000..ecf0c3d9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/time.mod differ diff --git a/INSTALL/grub/arm64-efi/tr.mod b/INSTALL/grub/arm64-efi/tr.mod new file mode 100644 index 00000000..e13edc9f Binary files /dev/null and b/INSTALL/grub/arm64-efi/tr.mod differ diff --git a/INSTALL/grub/arm64-efi/ufs1.mod b/INSTALL/grub/arm64-efi/ufs1.mod new file mode 100644 index 00000000..98104e66 Binary files /dev/null and b/INSTALL/grub/arm64-efi/ufs1.mod differ diff --git a/INSTALL/grub/arm64-efi/ufs1_be.mod b/INSTALL/grub/arm64-efi/ufs1_be.mod new file mode 100644 index 00000000..0e3c0e4e Binary files /dev/null and b/INSTALL/grub/arm64-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/arm64-efi/ufs2.mod b/INSTALL/grub/arm64-efi/ufs2.mod new file mode 100644 index 00000000..df0db5ff Binary files /dev/null and b/INSTALL/grub/arm64-efi/ufs2.mod differ diff --git a/INSTALL/grub/arm64-efi/verifiers.mod b/INSTALL/grub/arm64-efi/verifiers.mod new file mode 100644 index 00000000..a2f6231b Binary files /dev/null and b/INSTALL/grub/arm64-efi/verifiers.mod differ diff --git a/INSTALL/grub/arm64-efi/video.lst b/INSTALL/grub/arm64-efi/video.lst new file mode 100644 index 00000000..9f0892c6 --- /dev/null +++ b/INSTALL/grub/arm64-efi/video.lst @@ -0,0 +1 @@ +efi_gop diff --git a/INSTALL/grub/arm64-efi/videoinfo.mod b/INSTALL/grub/arm64-efi/videoinfo.mod new file mode 100644 index 00000000..7d6bcd57 Binary files /dev/null and b/INSTALL/grub/arm64-efi/videoinfo.mod differ diff --git a/INSTALL/grub/arm64-efi/videotest.mod b/INSTALL/grub/arm64-efi/videotest.mod new file mode 100644 index 00000000..a742213b Binary files /dev/null and b/INSTALL/grub/arm64-efi/videotest.mod differ diff --git a/INSTALL/grub/arm64-efi/videotest_checksum.mod b/INSTALL/grub/arm64-efi/videotest_checksum.mod new file mode 100644 index 00000000..9eccebb9 Binary files /dev/null and b/INSTALL/grub/arm64-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/arm64-efi/xen_boot.mod b/INSTALL/grub/arm64-efi/xen_boot.mod new file mode 100644 index 00000000..117f648e Binary files /dev/null and b/INSTALL/grub/arm64-efi/xen_boot.mod differ diff --git a/INSTALL/grub/arm64-efi/xnu_uuid.mod b/INSTALL/grub/arm64-efi/xnu_uuid.mod new file mode 100644 index 00000000..5ceebfe4 Binary files /dev/null and b/INSTALL/grub/arm64-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/arm64-efi/xnu_uuid_test.mod b/INSTALL/grub/arm64-efi/xnu_uuid_test.mod new file mode 100644 index 00000000..95ed9f61 Binary files /dev/null and b/INSTALL/grub/arm64-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/arm64-efi/zfs.mod b/INSTALL/grub/arm64-efi/zfs.mod new file mode 100644 index 00000000..67c4b2de Binary files /dev/null and b/INSTALL/grub/arm64-efi/zfs.mod differ diff --git a/INSTALL/grub/arm64-efi/zfscrypt.mod b/INSTALL/grub/arm64-efi/zfscrypt.mod new file mode 100644 index 00000000..8afa990e Binary files /dev/null and b/INSTALL/grub/arm64-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/arm64-efi/zfsinfo.mod b/INSTALL/grub/arm64-efi/zfsinfo.mod new file mode 100644 index 00000000..7a7db525 Binary files /dev/null and b/INSTALL/grub/arm64-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/arm64-efi/zstd.mod b/INSTALL/grub/arm64-efi/zstd.mod new file mode 100644 index 00000000..38314532 Binary files /dev/null and b/INSTALL/grub/arm64-efi/zstd.mod differ diff --git a/INSTALL/grub/debug.cfg b/INSTALL/grub/debug.cfg index 0def325c..aa833ffa 100644 --- a/INSTALL/grub/debug.cfg +++ b/INSTALL/grub/debug.cfg @@ -1,34 +1,99 @@ -submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { - menuentry 'Check global control plugin configuration' { + +source $prefix/keyboard.cfg + +submenu "Resolution Configuration" --class=debug_resolution --class=F5tool { + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } + + vt_update_cur_video_mode VT_CUR_MODE + set vdid=0 + while [ $vdid -lt $VTOY_VIDEO_MODE_NUM ]; do + vt_get_video_mode $vdid vtCurMode + + unset vtActive + if [ "$vtCurMode" = "$VT_CUR_MODE" ]; then + set vtActive="[*]" + fi + + menuentry "$vtCurMode $vtActive" --class=debug_videomode --class=debug_resolution --class=F5tool VTOY_RUN_RET { + terminal_output console + set gfxmode=$1 + terminal_output gfxterm + } + + vt_incr vdid 1 + done +} + +submenu "Screen Display Mode" --class=debug_screen_mode --class=F5tool { + menuentry 'Force Text Mode' --class=debug_text_mode --class=debug_screen_mode --class=F5tool { + terminal_output console + } + menuentry 'Force Graphics Mode' --class=debug_gui_mode --class=debug_screen_mode --class=F5tool { + terminal_output gfxterm + } + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } +} + +if [ "$grub_platform" != "pc" ]; then + submenu 'Ventoy UEFI Utilities' --class=debug_util --class=F5tool { + menuentry 'Show EFI Drivers' --class=debug_util_efidrv --class=debug_util --class=F5tool { + vt_push_pager + chainloader ${vtoy_path}/vtoyutil_${VTOY_EFI_ARCH}.efi env_param=${env_param} ${vtdebug_flag} feature=show_efi_drivers + boot + vt_pop_pager + echo -e "\npress ENTER to exit ..." + read vtInputKey + } + + menuentry 'Fixup Windows BlinitializeLibrary Failure' --class=debug_util_blinit --class=debug_util --class=F5tool { + chainloader ${vtoy_path}/vtoyutil_${VTOY_EFI_ARCH}.efi env_param=${env_param} ${vtdebug_flag} feature=fix_windows_mmap + boot + echo -e "\npress ENTER to exit ..." + read vtInputKey + } + + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } + } +fi + + +submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json --class=F5tool { + menuentry 'Check global control plugin configuration' --class=debug_control --class=debug_json --class=F5tool { set pager=1 - vt_check_plugin_json $vt_plugin_path control $iso_path + vt_check_plugin_json $vt_plugin_path control $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey unset pager } - menuentry 'Check theme plugin configuration' --class=debug_theme { + menuentry 'Check theme plugin configuration' --class=debug_theme --class=debug_json --class=F5tool { set pager=1 - vt_check_plugin_json $vt_plugin_path theme $iso_path + vt_check_plugin_json $vt_plugin_path theme $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey unset pager } - menuentry 'Check auto install plugin configuration' --class=debug_autoinstall { + menuentry 'Check auto install plugin configuration' --class=debug_autoinstall --class=debug_json --class=F5tool { set pager=1 - vt_check_plugin_json $vt_plugin_path auto_install $iso_path + vt_check_plugin_json $vt_plugin_path auto_install $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey unset pager } - menuentry 'Check persistence plugin configuration' --class=debug_persistence { + menuentry 'Check persistence plugin configuration' --class=debug_persistence --class=debug_json --class=F5tool { set pager=1 - vt_check_plugin_json $vt_plugin_path persistence $iso_path + vt_check_plugin_json $vt_plugin_path persistence $vtoy_iso_part echo -e "\n############### dump persistence ###############" vt_dump_persistence @@ -38,18 +103,90 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { unset pager } - menuentry 'Check menu alias plugin configuration' --class=debug_menualias { + menuentry 'Check menu alias plugin configuration' --class=debug_menualias --class=debug_json --class=F5tool { set pager=1 - vt_check_plugin_json $vt_plugin_path menu_alias $iso_path + vt_check_plugin_json $vt_plugin_path menu_alias $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey unset pager } - menuentry 'Check menu class plugin configuration' --class=debug_menuclass { + menuentry 'Check menu class plugin configuration' --class=debug_menuclass --class=debug_json --class=F5tool { set pager=1 - vt_check_plugin_json $vt_plugin_path menu_class $iso_path + vt_check_plugin_json $vt_plugin_path menu_class $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check injection plugin configuration' --class=debug_injection --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path injection $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check auto memdisk plugin configuration' --class=debug_automemdisk --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path auto_memdisk $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check image list plugin configuration' --class=debug_imagelist --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path image_list $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check image blacklist plugin configuration' --class=debug_imageblacklist --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path image_blacklist $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check boot conf replace plugin configuration' --class=debug_bootconf_replace --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path conf_replace $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check dud plugin configuration' --class=debug_dud --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path dud $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check password plugin configuration' --class=debug_pwd --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path password $vtoy_iso_part + + echo -e "\npress ENTER to exit ..." + read vtInputKey + unset pager + } + + menuentry 'Check custom boot plugin configuration' --class=debug_custom_boot --class=debug_json --class=F5tool { + set pager=1 + vt_check_plugin_json $vt_plugin_path custom_boot $vtoy_iso_part echo -e "\npress ENTER to exit ..." read vtInputKey @@ -61,6 +198,7 @@ submenu 'Check plugin json configuration (ventoy.json)' --class=debug_json { } } + menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } diff --git a/INSTALL/grub/grub.cfg b/INSTALL/grub/grub.cfg index 144b78e1..e596a0aa 100644 --- a/INSTALL/grub/grub.cfg +++ b/INSTALL/grub/grub.cfg @@ -17,10 +17,8 @@ #************************************************************************************ function ventoy_pause { - if [ -n "${vtdebug_flag}" ]; then - echo "press Enter to continue ......" - read vtTmpPause - fi + echo "press Enter to continue ......" + read vtTmpPause } function ventoy_debug_pause { @@ -30,19 +28,68 @@ function ventoy_debug_pause { fi } +function ventoy_cli_console { + if [ -z "$vtoy_display_mode" ]; then + terminal_output console + elif [ "$vtoy_display_mode" = "GUI" ]; then + terminal_output console + fi +} + +function ventoy_gui_console { + if [ -z "$vtoy_display_mode" ]; then + terminal_output gfxterm + elif [ "$vtoy_display_mode" = "GUI" ]; then + terminal_output gfxterm + fi +} + +function ventoy_acpi_param { + if [ "$VTOY_PARAM_NO_ACPI" != "1" ]; then + vt_acpi_param "$1" "$2" + fi +} + +function ventoy_vcfg_proc { + if vt_check_custom_boot "${1}" vt_vcfg; then + set vtoy_chosen_path="${1}" + vt_file_basefile "${vtoy_chosen_path}" vtoy_chosen_file + + export vtoy_chosen_path + export vtoy_chosen_file + ventoy_debug_pause + configfile "${vtoy_iso_part}${vt_vcfg}" + true + else + false + fi +} function ventoy_power { configfile $prefix/power.cfg } -function ventoy_diagnosis { +function ventoy_diagnosis { + vt_enum_video_mode configfile $prefix/debug.cfg } -function ventoy_localboot { +function ventoy_localboot { configfile $prefix/localboot.cfg } +function ventoy_ext_menu { + if [ -e $vt_plugin_path/ventoy/ventoy_grub.cfg ]; then + set ventoy_new_context=1 + configfile $vt_plugin_path/ventoy/ventoy_grub.cfg + unset ventoy_new_context + else + echo "ventoy_grub.cfg NOT exist." + echo -e "\npress ENTER to exit ..." + read vtInputKey + fi +} + function get_os_type { set vtoy_os=Linux @@ -53,16 +100,42 @@ function get_os_type { fi done + if [ "$vtoy_os" = "Linux" ]; then + if vt_strstr "$vt_system_id" "FreeBSD"; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif [ -e (loop)/bin/freebsd-version ]; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif vt_str_begin "$vt_system_id" "DragonFly"; then + set vtoy_os=Unix + set vt_unix_type=DragonFly + + + elif [ -e (loop)/boot/kernel/kernel ]; then + if file --is-x86-kfreebsd (loop)/boot/kernel/kernel; then + set vtoy_os=Unix + set vt_unix_type=FreeBSD + elif file --is-x86-knetbsd (loop)/boot/kernel/kernel; then + set vtoy_os=Unix + set vt_unix_type=NetBSD + fi + fi + fi + if [ -n "${vtdebug_flag}" ]; then - echo ISO is $vtoy_os + echo ISO is "$vtoy_os" fi } function vt_check_compatible_pe { #Check for PE without external tools - if [ -f $1/HBCD_PE.ini ]; then - set ventoy_compatible=YES + #set compatible if ISO file is less than 80MB + if [ $vt_chosen_size -gt 33554432 -a $vt_chosen_size -le 83886080 ]; then + set ventoy_compatible=YES fi + + return } function locate_initrd { @@ -91,7 +164,11 @@ function distro_specify_wim_patch { vt_windows_collect_wim_patch wim /BOOT/H3_7PE.WIM vt_windows_collect_wim_patch wim /BOOT/H3_8PE.WIM vt_windows_collect_wim_patch wim /BOOT/H3_81PE.WIM - fi + elif [ -d (loop)/2k10/winpe ]; then + vt_windows_collect_wim_patch wim /2k10/winpe/w1086pe.wim + vt_windows_collect_wim_patch wim /2k10/winpe/w8x86pe.wim + vt_windows_collect_wim_patch wim /2k10/winpe/w7x86pe.wim + fi } function distro_specify_wim_patch_phase2 { @@ -112,6 +189,9 @@ function distro_specify_initrd_file { if [ -e (loop)/casper/initrd ]; then vt_linux_specify_initrd_file /casper/initrd fi + if [ -e (loop)/casper/initrd.gz ]; then + vt_linux_specify_initrd_file /casper/initrd.gz + fi if [ -e (loop)/casper/initrd-oem ]; then vt_linux_specify_initrd_file /casper/initrd-oem fi @@ -125,14 +205,28 @@ function distro_specify_initrd_file { vt_linux_specify_initrd_file /pmagic/initrd.img elif [ -e (loop)/boot/initrd.xz ]; then vt_linux_specify_initrd_file /boot/initrd.xz + elif [ -e (loop)/boot/initrd.gz ]; then + vt_linux_specify_initrd_file /boot/initrd.gz elif [ -f (loop)/boot/initrd ]; then vt_linux_specify_initrd_file /boot/initrd elif [ -f (loop)/boot/x86_64/loader/initrd ]; then vt_linux_specify_initrd_file /boot/x86_64/loader/initrd elif [ -f (loop)/boot/initramfs-x86_64.img ]; then vt_linux_specify_initrd_file /boot/initramfs-x86_64.img - + elif [ -f (loop)/boot/isolinux/initramfs_data64.cpio.gz ]; then + vt_linux_specify_initrd_file /boot/isolinux/initramfs_data64.cpio.gz + + fi + + if [ -f (loop)/isolinux/initrd.gz ]; then + vt_linux_specify_initrd_file /isolinux/initrd.gz + fi + + if [ "$vt_chosen_size" = "1133375488" ]; then + if [ -d (loop)/boot/grub/x86_64-efi ]; then + vt_cpio_busybox64 "64h" + fi fi } @@ -154,10 +248,273 @@ function distro_specify_initrd_file_phase2 { vt_linux_specify_initrd_file /initrd.img elif [ -f (loop)/sysresccd/boot/x86_64/sysresccd.img ]; then vt_linux_specify_initrd_file /sysresccd/boot/x86_64/sysresccd.img + elif [ -f (loop)/CDlinux/initrd ]; then + vt_linux_specify_initrd_file /CDlinux/initrd + elif [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_linux_specify_initrd_file /parabola/boot/x86_64/parabolaiso.img + if [ -f (loop)/parabola/boot/i686/parabolaiso.img ]; then + vt_linux_specify_initrd_file /parabola/boot/i686/parabolaiso.img + fi + elif [ -f (loop)/parabola/boot/x86_64/initramfs-linux-libre.img ]; then + vt_linux_specify_initrd_file /parabola/boot/x86_64/initramfs-linux-libre.img + if [ -f (loop)/parabola/boot/i686/initramfs-linux-libre.img ]; then + vt_linux_specify_initrd_file /parabola/boot/i686/initramfs-linux-libre.img + fi + elif [ -f (loop)/hyperbola/boot/x86_64/hyperiso.img ]; then + vt_linux_specify_initrd_file /hyperbola/boot/x86_64/hyperiso.img + if [ -f (loop)/hyperbola/boot/i686/hyperiso.img ]; then + vt_linux_specify_initrd_file /hyperbola/boot/i686/hyperiso.img + fi + elif [ -f (loop)/EFI/BOOT/initrd.img ]; then + #Qubes + vt_linux_specify_initrd_file /EFI/BOOT/initrd.img + if [ "$grub_platform" != "pc" ]; then + vt_add_replace_file 0 "initrd.img" + fi + elif [ -f (loop)/initrd ]; then + vt_linux_specify_initrd_file /initrd + elif [ -f (loop)/live/initrd1 ]; then + vt_linux_specify_initrd_file /live/initrd1 + elif [ -f (loop)/isolinux/initrd.img ]; then + vt_linux_specify_initrd_file /isolinux/initrd.img + elif [ -f (loop)/isolinux/initrd.gz ]; then + vt_linux_specify_initrd_file /isolinux/initrd.gz + elif [ -f (loop)/syslinux/kernel/initramfs.gz ]; then + vt_linux_specify_initrd_file /syslinux/kernel/initramfs.gz + elif vt_strstr "$vt_volume_id" "Daphile"; then + vt_linux_parse_initrd_isolinux (loop)/isolinux/ + elif [ -f (loop)/boot/rootfs.xz ]; then + vt_linux_specify_initrd_file /boot/rootfs.xz + if [ "$grub_platform" != "pc" ]; then + vt_add_replace_file 0 "minimal\\x86_64\\rootfs.xz" + fi + elif [ -f (loop)/arch/boot/x86_64/archiso.img ]; then + vt_linux_specify_initrd_file /arch/boot/x86_64/archiso.img + if [ "$grub_platform" != "pc" ]; then + vt_add_replace_file 0 "EFI\\archiso\\archiso.img" + fi + elif [ -f (loop)/blackarch/boot/x86_64/archiso.img ]; then + vt_linux_specify_initrd_file /blackarch/boot/x86_64/archiso.img + elif [ -f (loop)/blackarch/boot/x86_64/initramfs-linux.img ]; then + vt_linux_specify_initrd_file /blackarch/boot/x86_64/initramfs-linux.img + + elif [ -f (loop)/install.amd/initrd.gz ]; then + vt_linux_specify_initrd_file /live/initrd2.img + vt_linux_specify_initrd_file /install.amd/initrd.gz + vt_linux_specify_initrd_file /install.amd/gtk/initrd.gz + elif [ -f (loop)/boot/grub/kernels.cfg ]; then + vt_linux_parse_initrd_grub file (loop)/boot/grub/kernels.cfg + elif [ -f (loop)/austrumi/initrd.gz ]; then + vt_linux_specify_initrd_file /austrumi/initrd.gz + if [ -f (loop)/EFI/BOOT/bootx64.efi ]; then + vt_cpio_busybox64 "64h" + fi + elif [ -f (loop)/boot/initfs.x86_64-efi ]; then + vt_linux_specify_initrd_file /boot/initfs.x86_64-efi + if [ -f (loop)/boot/initfs.i386-pc ]; then + vt_linux_specify_initrd_file /boot/initfs.i386-pc + fi + elif [ -f (loop)/antiX/initrd.gz ]; then + vt_linux_specify_initrd_file /antiX/initrd.gz + elif [ -f (loop)/360Disk/initrd.gz ]; then + vt_linux_specify_initrd_file /360Disk/initrd.gz + elif [ -f (loop)/porteus/initrd.xz ]; then + vt_linux_specify_initrd_file /porteus/initrd.xz fi } +function ventoy_get_ghostbsd_ver { + # fallback to parse version from elf /boot/kernel/kernel + set vt_freebsd_ver=xx +} + +function ventoy_get_furybsd_ver { + if regexp "13\.[0-9]" "$2"; then + set vt_freebsd_ver=13.x + else + set vt_freebsd_ver=12.x + fi +} + +function ventoy_get_freenas_ver { + set vt_freebsd_ver=11.x + + if [ -e (loop)/FreeNAS-MANIFEST ]; then + vt_parse_freenas_ver (loop)/FreeNAS-MANIFEST vt_freenas_ver + if regexp "^13\.[0-9]" "$vt_freenas_ver"; then + set vt_freebsd_ver=13.x + elif regexp "^12\.[0-9]" "$vt_freenas_ver"; then + set vt_freebsd_ver=12.x + elif regexp "^11\.[0-9]" "$vt_freenas_ver"; then + set vt_freebsd_ver=11.x + fi + fi +} + +function ventoy_get_truenas_ver { + set vt_freebsd_ver=12.x + + if [ -e (loop)/TrueNAS-MANIFEST ]; then + vt_parse_freenas_ver (loop)/TrueNAS-MANIFEST vt_truenas_ver + if regexp "^13\.[0-9]" "$vt_truenas_ver"; then + set vt_freebsd_ver=13.x + elif regexp "^12\.[0-9]" "$vt_truenas_ver"; then + set vt_freebsd_ver=12.x + elif regexp "^11\.[0-9]" "$vt_truenas_ver"; then + set vt_freebsd_ver=11.x + fi + fi +} + +function ventoy_get_midnightbsd_ver { + if vt_str_begin "$vt_volume_id" "1_"; then + set vt_freebsd_ver=11.x + elif vt_str_begin "$vt_volume_id" "2_"; then + set vt_freebsd_ver=2.x + elif vt_str_begin "$vt_volume_id" "3_"; then + set vt_freebsd_ver=3.x + fi +} + +function ventoy_freebsd_proc { + set vtFreeBsdDistro=FreeBSD + set vt_freebsd_ver=xx + + if vt_strstr "$vt_volume_id" "GHOSTBSD"; then + ventoy_get_ghostbsd_ver "$1" "${chosen_path}" + elif vt_strstr "$vt_volume_id" "FREENAS"; then + ventoy_get_freenas_ver "$1" "${chosen_path}" + elif vt_strstr "$vt_volume_id" "TRUENAS"; then + ventoy_get_truenas_ver "$1" "${chosen_path}" + elif vt_strstr "$vt_volume_id" "FURYBSD"; then + ventoy_get_furybsd_ver "$1" "${chosen_path}" + elif regexp "^13_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=13.x + elif regexp "^12_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=12.x + elif regexp "^11_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=11.x + elif regexp "^10_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=10.x + elif regexp "^9_[0-9]" "$vt_volume_id"; then + set vt_freebsd_ver=9.x + elif [ -d (loop)/usr/midnightbsd-dist ]; then + ventoy_get_midnightbsd_ver "$1" "${chosen_path}" + set vtFreeBsdDistro=MidnightBSD + elif [ -e (loop)/bin/freebsd-version ]; then + vt_unix_parse_freebsd_ver (loop)/bin/freebsd-version vt_userland_ver + if regexp "\"13\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=13.x + elif regexp "\"12\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=12.x + elif regexp "\"11\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=11.x + elif regexp "\"10\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=10.x + elif regexp "\"9\.[0-9]-" "$vt_userland_ver"; then + set vt_freebsd_ver=9.x + fi + elif [ -e (loop)/README.TXT ]; then + vt_1st_line (loop)/README.TXT vt_freebsd_line1 + if regexp "FreeBSD 13\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=13.x + elif regexp "FreeBSD 12\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=12.x + elif regexp "FreeBSD 11\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=11.x + elif regexp "FreeBSD 10\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=10.x + elif regexp "FreeBSD 9\.[0-9]-" "$vt_freebsd_line1"; then + set vt_freebsd_ver=9.x + fi + elif vt_strstr "${chosen_path}" "MidnightBSD"; then + set vt_freebsd_ver=9.x + fi + + + if [ -e (loop)/usr/freebsd-dist/cloninst.sh ]; then + set vtFreeBsdDistro=ClonOS + fi + + set vt_freebsd_bit=64 + for file in "/boot/kernel/kernel" "/boot/kernel/kernel.gz"; do + if [ -e (loop)/$file ]; then + if file --is-i386-kfreebsd (loop)/$file; then + set vt_freebsd_bit=32 + fi + break + fi + done + + if [ "$vt_freebsd_ver" = "xx" ]; then + if [ -e (loop)/boot/kernel/kernel ]; then + vt_unix_parse_freebsd_ver_elf (loop)/boot/kernel/kernel $vt_freebsd_bit vt_freebsd_ver + fi + + if [ "$vt_freebsd_ver" = "xx" ]; then + set vt_freebsd_ver=13.x + fi + fi + + if [ -n "${vtdebug_flag}" ]; then + echo "This is $vtFreeBsdDistro $vt_freebsd_ver ${vt_freebsd_bit}bit" + fi + + unset vt_unix_mod_path + for file in "/COPYRIGHT" "/FreeNAS-MANIFEST" "/TrueNAS-MANIFEST" "/version" "/etc/fstab"; do + if [ -e (loop)${file} ]; then + set vt_unix_mod_path=${file} + break + fi + done + + vt_unix_replace_ko $vt_unix_mod_path (vtunix)/ventoy_unix/$vtFreeBsdDistro/geom_ventoy_ko/$vt_freebsd_ver/$vt_freebsd_bit/geom_ventoy.ko.xz + vt_unix_replace_conf FreeBSD "${1}${chosen_path}" +} + +function ventoy_dragonfly_proc { + + unset vt_unix_mod_path + for file in "/boot/kernel/initrd.img.gz"; do + if [ -e (loop)${file} ]; then + set vt_unix_mod_path=${file} + break + fi + done + + vt_unix_replace_ko $vt_unix_mod_path ${vtoy_path}/dragonfly.mfs.xz + vt_unix_fill_image_desc + vt_unix_gzip_new_ko + vt_unix_replace_conf DragonFly "${1}${chosen_path}" +} + +function ventoy_unix_comm_proc { + vt_unix_reset + + if [ "$ventoy_compatible" = "NO" ]; then + loopback vtunix $vtoy_efi_part/ventoy/ventoy_unix.cpio + + if [ "$vt_unix_type" = "FreeBSD" ]; then + ventoy_freebsd_proc "$1" "${chosen_path}" + elif [ "$vt_unix_type" = "DragonFly" ]; then + ventoy_dragonfly_proc "$1" "${chosen_path}" + elif [ "$vt_unix_type" = "NetBSD" ]; then + echo "NetBSD not supported" + + + else + if [ -n "${vtdebug_flag}" ]; then + echo "Unknown unix type" + fi + fi + fi + + vt_unix_chain_data "${1}${chosen_path}" + ventoy_debug_pause +} + + function uefi_windows_menu_func { vt_windows_reset @@ -166,7 +523,7 @@ function uefi_windows_menu_func { if [ "$ventoy_fs_probe" = "iso9660" ]; then loopback -d loop vt_iso9660_nojoliet 1 - loopback loop $1$2 + loopback loop "$1$2" fi for file in "efi/microsoft/boot/bcd"; do @@ -182,12 +539,17 @@ function uefi_windows_menu_func { locate_wim fi - vt_windows_chain_data ${1}${chosen_path} + vt_windows_chain_data "${1}${chosen_path}" ventoy_debug_pause + if vt_check_mode 4; then + vtoy_windows_wimboot_func + fi + if [ -n "$vtoy_chain_mem_addr" ]; then - terminal_output console - chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} iso_${ventoy_fs_probe} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} boot else echo "chain empty failed" @@ -195,17 +557,34 @@ function uefi_windows_menu_func { fi } +function uefi_find_replace_initrd { + if vt_get_efi_vdisk_offset "${1}${2}" vt_efivdisk_offset; then + loopback -s $vt_efivdisk_offset vtefivdisk "${1}${2}" + + unset vt_rp_initrd + vt_search_replace_initrd (vtefivdisk) vt_rp_initrd + + if [ -n "$vt_rp_initrd" ]; then + vt_add_replace_file $3 "$vt_rp_initrd" + fi + + loopback -d vtefivdisk + ventoy_debug_pause + fi +} + function uefi_linux_menu_func { + if [ "$ventoy_compatible" = "NO" ]; then if [ "$ventoy_fs_probe" = "udf" ]; then loopback -d loop set ventoy_fs_probe=iso9660 - loopback loop $1$2 + loopback loop "$1$2" fi - vt_load_cpio ${vtoy_path}/ventoy.cpio $2 $1 - + vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver" + vt_linux_clear_initrd if [ -d (loop)/pmagic ]; then @@ -228,6 +607,7 @@ function uefi_linux_menu_func { distro_specify_initrd_file vt_linux_initrd_count vtcount + if [ $vtcount -eq 0 ]; then distro_specify_initrd_file_phase2 @@ -246,24 +626,128 @@ function uefi_linux_menu_func { if [ -d (loop)/arch ]; then if [ -f (loop)/arch/boot/x86_64/archiso.img ]; then vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img" + elif [ -f (loop)/arch/boot/x86_64/initramfs-linux.img ]; then + vt_add_replace_file $vtindex "arch\\boot\\x86_64\\initramfs-linux.img" elif [ -f (loop)/boot/initramfs_x86_64.img ]; then vt_add_replace_file $vtindex "boot\\initramfs_x86_64.img" fi + elif [ -d (loop)/blackarch ]; then + if [ -f (loop)/blackarch/boot/x86_64/archiso.img ]; then + vt_add_replace_file $vtindex "EFI\\archiso\\archiso.img" + elif [ -f (loop)/blackarch/boot/x86_64/initramfs-linux.img ]; then + vt_add_replace_file $vtindex "blackarch\\boot\\x86_64\\initramfs-linux.img" + fi + elif [ -d (loop)/anarchy ]; then + if [ -f (loop)/anarchy/boot/x86_64/initramfs-linux.img ]; then + vt_add_replace_file $vtindex "anarchy\\boot\\x86_64\\initramfs-linux.img" + fi + elif [ -d (loop)/parabola ]; then + if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_add_replace_file $vtindex "EFI\\parabolaiso\\parabolaiso.img" + elif [ -f (loop)/parabola/boot/x86_64/initramfs-linux-libre.img ]; then + vt_add_replace_file $vtindex "parabola\\boot\\x86_64\\initramfs-linux-libre.img" + fi elif [ -f (loop)/EFI/BOOT/initrd.gz ]; then vt_add_replace_file $vtindex "EFI\\BOOT\\initrd.gz" + elif [ -f (loop)/loader/entries/thinstation.conf ]; then + vt_add_replace_file $vtindex "boot\\initrd" + elif [ -f (loop)/loader/entries/pisi-efi-x86_64.conf ]; then + vt_add_replace_file $vtindex "EFI\\pisi\\initrd.img" + fi + + vt_get_replace_file_cnt vt_replace_cnt + if [ $vt_replace_cnt -eq 0 ]; then + uefi_find_replace_initrd "$1" "$2" $vtindex + fi + elif [ -d (loop)/EFI/boot/entries ]; then + if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img" + elif [ -f (loop)/hyperbola/boot/x86_64/hyperiso.img ]; then + vt_add_replace_file 0 "EFI\\hyperiso\\hyperiso.img" + fi + elif [ -d (loop)/EFI/BOOT/entries ]; then + vt_linux_get_main_initrd_index vtindex + + if [ -f (loop)/parabola/boot/x86_64/parabolaiso.img ]; then + vt_add_replace_file 0 "EFI\\parabolaiso\\parabolaiso.img" + elif [ -f (loop)/parabola/boot/x86_64/initramfs-linux-libre.img ]; then + vt_add_replace_file $vtindex "parabola\\boot\\x86_64\\initramfs-linux-libre.img" fi elif [ -e (loop)/syslinux/alt0/full.cz ]; then vt_add_replace_file 0 "EFI\\BOOT\\full.cz" set FirstTryBootFile='@EFI@BOOT@grubx64.efi' + + fi fi - vt_linux_chain_data ${1}${chosen_path} + vt_linux_chain_data "${1}${chosen_path}" + + if [ -n "$LoadIsoEfiDriver" -a $vt_chosen_size -lt 104857600 ]; then + if [ -f (loop)/efi/clover/cloverx64.efi ]; then + unset LoadIsoEfiDriver + fi + fi if [ -n "$vtoy_chain_mem_addr" ]; then - terminal_output console - chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + ventoy_cli_console + + if vt_check_mode 3; then + ventoy_debug_pause + else + if [ "$VTOY_EFI_ARCH" != "mips" ]; then + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi fallback env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + fi + fi + + # fallback + set vtback_root=$root + vt_push_last_entry + set vtback_theme=$theme + unset theme + + vt_trailer_cpio "$vtoy_iso_part" "$vt_chosen_path" noinit + vt_set_boot_opt rdinit=/vtoy/vtoy + + set root=(loop) + set vtback_cfg_find=0 + for cfg in "/boot/grub/grub.cfg" "/EFI/BOOT/grub.cfg" "/EFI/debian/grub.cfg" "EFI/boot/grub.cfg" "efi/boot/grub.cfg" "/grub/grub.cfg" "EFI/BOOT/BOOTX64.conf"; do + if [ -e "$cfg" ]; then + set vtback_cfg_find=1 + configfile "$cfg" + break + fi + done + + if [ "$vtback_cfg_find" = "0" ]; then + echo " " + echo "No bootfile found for UEFI!" + echo "Maybe the image does not support $VTOY_EFI_ARCH UEFI" + echo " " + sleep 30 + fi + + vt_unset_boot_opt + set root=$vtback_root + set theme=$vtback_theme + vt_pop_last_entry + ventoy_gui_console + else + echo "chain empty failed" + ventoy_pause + fi +} + +function uefi_unix_menu_func { + ventoy_unix_comm_proc $1 "${chosen_path}" + + if [ -n "$vtoy_chain_mem_addr" ]; then + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} boot else echo "chain empty failed" @@ -271,6 +755,15 @@ function uefi_linux_menu_func { fi } +function ventoy_reset_nojoliet { + if vt_str_begin "$vt_volume_id" "ARCARESCUE"; then + vt_iso9660_nojoliet 1 + else + vt_iso9660_nojoliet 0 + fi + + vt_append_extra_sector 0 +} function uefi_iso_menu_func { @@ -287,18 +780,24 @@ function uefi_iso_menu_func { unset LoadIsoEfiDriver fi - vt_chosen_img_path chosen_path - vt_select_auto_install ${chosen_path} - vt_select_persistence ${chosen_path} + set chosen_path="$2" + vt_select_auto_install "${chosen_path}" + vt_select_persistence "${chosen_path}" - if vt_is_udf ${1}${chosen_path}; then + if vt_is_udf "${1}${chosen_path}"; then set ventoy_fs_probe=udf else set ventoy_fs_probe=iso9660 - vt_iso9660_nojoliet 0 + ventoy_reset_nojoliet + + # Lenovo EasyStartup need an addional sector for boundary check + if vt_str_begin "$vt_volume_id" "EasyStartup"; then + vt_skip_svd "${vtoy_iso_part}${vt_chosen_path}" + vt_append_extra_sector 1 + fi fi - loopback loop ${1}${chosen_path} + loopback loop "${1}${chosen_path}" get_os_type (loop) if [ -d (loop)/EFI ]; then @@ -315,35 +814,119 @@ function uefi_iso_menu_func { elif vt_check_mode 1; then set ventoy_compatible=YES else - vt_check_compatible (loop) + vt_check_compatible (loop) fi - vt_img_sector ${1}${chosen_path} + vt_img_sector "${1}${chosen_path}" + + if [ "$ventoy_fs_probe" = "iso9660" ]; then + vt_select_conf_replace "${1}" "${chosen_path}" + fi if [ "$vtoy_os" = "Windows" ]; then vt_check_compatible_pe (loop) - uefi_windows_menu_func $1 ${chosen_path} + uefi_windows_menu_func "$1" "${chosen_path}" + elif [ "$vtoy_os" = "Unix" ]; then + uefi_unix_menu_func "$1" "${chosen_path}" else - uefi_linux_menu_func $1 ${chosen_path} + uefi_linux_menu_func "$1" "${chosen_path}" fi - terminal_output gfxterm + ventoy_gui_console } function uefi_iso_memdisk { - vt_chosen_img_path chosen_path - echo 'Loading ISO file to memory ...' - vt_load_iso_to_mem ${1}${chosen_path} vtoy_iso_buf + vt_load_img_memdisk "${1}${2}" vtoy_iso_buf - terminal_output console - chainloader ${vtoy_path}/ventoy_x64.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size} + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size} boot - terminal_output gfxterm + ventoy_gui_console } +function vtoy_windows_wimboot_func { + if [ -f (loop)/x86/sources/boot.wim -a -f (loop)/x64/sources/boot.wim ]; then + vt_sel_wimboot vtoy_wimboot_bit + if [ "$vtoy_wimboot_bit" = "32" ]; then + set vtoy_wimboot_prefix=(loop)/x86 + else + set vtoy_wimboot_prefix=(loop)/x64 + fi + else + set vtoy_wimboot_prefix=(loop) + if vt_is_pe64 $vtoy_wimboot_prefix/setup.exe; then + set vtoy_wimboot_bit=64 + else + set vtoy_wimboot_bit=32 + fi + fi + + if [ -n "${vtdebug_flag}" ]; then + echo vtoy_wimboot_prefix=$vtoy_wimboot_prefix vtoy_wimboot_bit=$vtoy_wimboot_bit + fi + + for wmfile in sources/boot.wim boot/bcd boot/boot.sdi; do + if [ ! -f $vtoy_wimboot_prefix/$wmfile ]; then + return + fi + done + + if [ -f $vtoy_wimboot_prefix/sources/install.wim -o -f $vtoy_wimboot_prefix/sources/install.esd ]; then + vt_windows_wimboot_data + else + return + fi + + if [ "$grub_platform" = "pc" ]; then + set vt_wimkernel=wimboot.x86_64.xz + + linux16 "$vtoy_path/$vt_wimkernel" quiet + ventoy_debug_pause + + vt_set_wim_load_prompt 1 "Loading files......" + initrd16 newc:vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe \ + newc:wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size} \ + newc:winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size} \ + newc:bcd:$vtoy_wimboot_prefix/boot/bcd \ + newc:boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi \ + newc:boot.wim:$vtoy_wimboot_prefix/sources/boot.wim + vt_set_wim_load_prompt 0 + boot + else + if [ "$grub_cpu" = "i386" ]; then + set vt_wimkernel=wimboot.i386.efi.xz + else + set vt_wimkernel=wimboot.x86_64.xz + fi + + vt_set_wim_load_prompt 1 "Loading files......" + vt_load_file_to_mem "nodecompress" $vtoy_wimboot_prefix/sources/boot.wim vtoy_wimfile_mem + vt_set_wim_load_prompt 0 + + if [ $? -eq 0 ]; then + set vtoy_wimfile_path=mem:${vtoy_wimfile_mem_addr}:size:${vtoy_wimfile_mem_size} + else + set vtoy_wimfile_path=$vtoy_wimboot_prefix/sources/boot.wim + fi + + ventoy_cli_console + chainloader "$vtoy_path/$vt_wimkernel" quiet \ + "vf=wimboot.data:mem:${vtoy_wimboot_mem_addr}:size:${vtoy_wimboot_mem_size}" \ + "vf=winpeshl.ini:mem:${vtoy_winpeshl_ini_addr}:size:${vtoy_winpeshl_ini_size}" \ + "vf=vtoyjump.exe:$vtoy_path/vtoyjump${vtoy_wimboot_bit}.exe" \ + "vf=bcd:$vtoy_wimboot_prefix/boot/bcd" \ + "vf=boot.sdi:$vtoy_wimboot_prefix/boot/boot.sdi" \ + "vf=boot.wim:$vtoy_wimfile_path" \ + pfsize=$vtoy_chain_file_size \ + pfread=$vtoy_chain_file_read + boot + ventoy_gui_console + fi +} + function legacy_windows_menu_func { vt_windows_reset @@ -352,10 +935,10 @@ function legacy_windows_menu_func { if [ "$ventoy_fs_probe" = "iso9660" ]; then loopback -d loop vt_iso9660_nojoliet 1 - loopback loop $1$2 + loopback loop "$1$2" fi - for file in "boot/bcd" "/efi/microsoft/boot/bcd" "SSTR/BCD"; do + for file in "boot/bcd" "/efi/microsoft/boot/bcd" "SSTR/BCD" "boot/bce"; do vt_windows_collect_wim_patch bcd (loop)/$file done @@ -370,11 +953,16 @@ function legacy_windows_menu_func { locate_wim fi - vt_windows_chain_data ${1}${chosen_path} + vt_windows_chain_data "${1}${chosen_path}" ventoy_debug_pause - + + if vt_check_mode 4; then + vtoy_windows_wimboot_func + fi + if [ -n "$vtoy_chain_mem_addr" ]; then - linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} ibft mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} ibft mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} boot else echo "chain empty failed" @@ -388,10 +976,18 @@ function legacy_linux_menu_func { if [ "$ventoy_fs_probe" = "udf" ]; then loopback -d loop set ventoy_fs_probe=iso9660 - loopback loop $1$2 + loopback loop "$1$2" + fi + + if [ -f (loop)/isolinux/isolinux.cfg ]; then + if vt_iso9660_isjoliet; then + vt_iso9660_nojoliet 1 + loopback -d loop + loopback loop "$1$2" + fi fi - vt_load_cpio $vtoy_path/ventoy.cpio $2 $1 + vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver" vt_linux_clear_initrd @@ -410,6 +1006,8 @@ function legacy_linux_menu_func { if [ -d (loop)/arch/boot/syslinux ]; then vt_linux_parse_initrd_isolinux (loop)/arch/boot/syslinux/ /arch/ vt_linux_parse_initrd_isolinux (loop)/arch/boot/syslinux/ /arch/boot/syslinux/ + elif [ -d (loop)/anarchy/boot/syslinux ]; then + vt_linux_parse_initrd_isolinux (loop)/anarchy/boot/syslinux/ /anarchy/ #manjaro elif [ -d (loop)/manjaro ]; then @@ -424,16 +1022,65 @@ function legacy_linux_menu_func { vt_linux_initrd_count vtcount if [ $vtcount -eq 0 ]; then + if [ -d (loop)/rancheros ]; then + vt_linux_parse_initrd_isolinux (loop)/boot/ /boot/isolinux/ + fi + distro_specify_initrd_file_phase2 fi locate_initrd fi - vt_linux_chain_data ${1}${chosen_path} + vt_linux_chain_data "${1}${chosen_path}" ventoy_debug_pause if [ -n "$vtoy_chain_mem_addr" ]; then + if vt_check_mode 3; then + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + ventoy_cli_console + + # fallback + set vtback_root=$root + vt_push_last_entry + set vtback_theme=$theme + unset theme + + vt_trailer_cpio "$vtoy_iso_part" "$vt_chosen_path" noinit + vt_set_boot_opt rdinit=/vtoy/vtoy + + set root=(loop) + set vtback_cfg_find=0 + for cfg in "/boot/grub/grub.cfg" "/EFI/BOOT/grub.cfg" "/EFI/debian/grub.cfg" "EFI/boot/grub.cfg" "efi/boot/grub.cfg" "/grub/grub.cfg" "EFI/BOOT/BOOTX64.conf"; do + if [ -e "$cfg" ]; then + set vtback_cfg_find=1 + configfile "$cfg" + break + fi + done + + vt_unset_boot_opt + set root=$vtback_root + set theme=$vtback_theme + vt_pop_last_entry + ventoy_gui_console + else + ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + fi + else + echo "chain empty failed" + ventoy_pause + fi +} + + +function legacy_unix_menu_func { + ventoy_unix_comm_proc $1 "${chosen_path}" + + if [ -n "$vtoy_chain_mem_addr" ]; then + #ventoy_acpi_param ${vtoy_chain_mem_addr} 2048 linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} boot else @@ -442,26 +1089,29 @@ function legacy_linux_menu_func { fi } + function legacy_iso_menu_func { if [ -d (loop)/ ]; then loopback -d loop fi - vt_chosen_img_path chosen_path - vt_select_auto_install ${chosen_path} - vt_select_persistence ${chosen_path} + set chosen_path="$2" + + vt_select_auto_install "${chosen_path}" + vt_select_persistence "${chosen_path}" - if vt_is_udf ${1}${chosen_path}; then + if vt_is_udf "${1}${chosen_path}"; then set ventoy_fs_probe=udf else set ventoy_fs_probe=iso9660 - vt_iso9660_nojoliet 0 + ventoy_reset_nojoliet fi - loopback loop ${1}${chosen_path} + loopback loop "${1}${chosen_path}" + get_os_type (loop) - + if [ -n "$vtcompat" ]; then set ventoy_compatible=YES unset vtcompat @@ -471,46 +1121,170 @@ function legacy_iso_menu_func { vt_check_compatible (loop) fi - vt_img_sector ${1}${chosen_path} + vt_img_sector "${1}${chosen_path}" + + if [ "$ventoy_fs_probe" = "iso9660" ]; then + vt_select_conf_replace "${1}" "${chosen_path}" + fi if [ "$vtoy_os" = "Windows" ]; then vt_check_compatible_pe (loop) - legacy_windows_menu_func $1 ${chosen_path} + legacy_windows_menu_func "$1" "${chosen_path}" + elif [ "$vtoy_os" = "Unix" ]; then + legacy_unix_menu_func "$1" "${chosen_path}" else - legacy_linux_menu_func $1 ${chosen_path} + legacy_linux_menu_func "$1" "${chosen_path}" fi } function legacy_iso_memdisk { - vt_chosen_img_path chosen_path linux16 $vtoy_path/memdisk iso raw echo "Loading ISO file to memory ..." - initrd16 ${1}${chosen_path} + initrd16 "${1}${2}" boot } + +function iso_endless_os_proc { + if [ -d (loop)/ ]; then + loopback -d loop + fi + + loopback loop "${1}${2}" + vt_img_sector "${1}${2}" + + vt_load_cpio $vtoy_path "$2" "$1" "busybox=$ventoy_busybox_ver" + vt_trailer_cpio "$1" "$2" noinit + + ventoy_debug_pause + + vt_set_boot_opt '@kparams' rdinit=/vtoy/vtoy + + set eosimage=loop + set ventoy_bls_bootdev=/boot + set ventoy_loading_tip="Loading files ......" + + export eosimage + configfile (loop)/endless/grub/grub.cfg + + unset eosimage + unset ventoy_bls_bootdev + unset ventoy_loading_tip + + vt_unset_boot_opt +} + + +function ventoy_iso_busybox_ver { + + if [ "$VTOY_EFI_ARCH" = "aa64" ]; then + set ventoy_busybox_ver=a64 + elif [ "$VTOY_EFI_ARCH" = "mips" ]; then + set ventoy_busybox_ver=m64 + else + set ventoy_busybox_ver=32 + + #special process for deepin-live iso + if [ "$vt_chosen_size" = "403701760" ]; then + if vt_str_str "$vt_chosen_path" "/deepin-live"; then + set ventoy_busybox_ver=64 + fi + elif vt_str_begin "$vt_volume_id" "PHOTON_"; then + set ventoy_busybox_ver=64 + elif vt_str_begin "$vt_volume_id" "smgl-test-quinq-x86_64"; then + set ventoy_busybox_ver=64 + elif vt_str_begin "$vt_volume_id" "LDiagBootable"; then + set ventoy_busybox_ver=64 + + fi + fi +} + + function iso_common_menuentry { + unset vt_system_id + unset vt_volume_id + + vt_chosen_img_path vt_chosen_path vt_chosen_size + + vt_parse_iso_volume "${vtoy_iso_part}${vt_chosen_path}" vt_system_id vt_volume_id vt_volume_space + if [ $vt_volume_space -ne $vt_chosen_size ]; then + vt_mod $vt_chosen_size 2048 vt_chosen_size_mod + if [ $vt_chosen_size_mod -ne 0 ]; then + echo -e "\n $vt_volume_space $vt_chosen_size $vt_chosen_size_mod\n" + echo -e "\n The size of the iso file \"$vt_chosen_size\" is invalid. File corrupted ?\n" + echo -e " æ­¤ISOæ–‡ä»¶çš„å¤§å° \"$vt_chosen_size\" 有问题,请确认文件是å¦æŸå。\n" + echo -e "\n press ENTER to exit (请按 回车 键返回) ..." + read vtInputKey + return + fi + fi + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + if vt_str_begin "$vt_volume_id" "Avira"; then + vt_skip_svd "${vtoy_iso_part}${vt_chosen_path}" + fi + + ventoy_iso_busybox_ver + + #special process for Endless OS + if vt_str_begin "$vt_volume_id" "Endless-OS"; then + iso_endless_os_proc $vtoy_iso_part "$vt_chosen_path" + elif vt_str_begin "$vt_volume_id" "TENS-Public"; then + set vtcompat=1 + fi + if [ "$grub_platform" = "pc" ]; then if vt_check_mode 0; then - legacy_iso_memdisk $iso_path + legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path" else - legacy_iso_menu_func $iso_path + legacy_iso_menu_func $vtoy_iso_part "$vt_chosen_path" fi else if vt_check_mode 0; then - uefi_iso_memdisk $iso_path + uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path" else - uefi_iso_menu_func $iso_path + uefi_iso_menu_func $vtoy_iso_part "$vt_chosen_path" fi fi } +function miso_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + echo "memdisk mode boot for $vt_chosen_path" + echo "" + ventoy_debug_pause + + if [ "$grub_platform" = "pc" ]; then + legacy_iso_memdisk $vtoy_iso_part "$vt_chosen_path" + else + uefi_iso_memdisk $vtoy_iso_part "$vt_chosen_path" + fi +} + + function common_unsupport_menuentry { echo -e "\n The name of the iso file could NOT contain space or non-ascii characters. \n" - echo -e " 文件å中ä¸èƒ½æœ‰ä¸­æ–‡æˆ–空格 \n" - echo -e "\n Will return to main menu after 10 seconds ...\n" - sleep 10 + echo -e " 文件å中ä¸èƒ½æœ‰ä¸­æ–‡æˆ–空格 \n" + echo -e "\npress ENTER to exit (请按 回车 键返回) ..." + read vtInputKey +} + +function miso_unsupport_menuentry { + common_unsupport_menuentry } function iso_unsupport_menuentry { @@ -518,18 +1292,32 @@ function iso_unsupport_menuentry { } function wim_common_menuentry { - vt_chosen_img_path chosen_path - vt_wim_chain_data ${iso_path}${chosen_path} + vt_chosen_img_path vt_chosen_path vt_chosen_size + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + if vt_wim_check_bootable "${vtoy_iso_part}${vt_chosen_path}"; then + vt_wim_chain_data "${vtoy_iso_part}${vt_chosen_path}" + else + echo -e "\n This is NOT a bootable WIM file. \n" + echo -e " è¿™ä¸æ˜¯ä¸€ä¸ªå¯å¯åŠ¨çš„ WIM 文件。\n" + fi ventoy_debug_pause if [ -n "$vtoy_chain_mem_addr" ]; then if [ "$grub_platform" = "pc" ]; then - linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} else - terminal_output console - chainloader ${vtoy_path}/ventoy_x64.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} - terminal_output gfxterm + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + ventoy_gui_console fi boot else @@ -543,18 +1331,537 @@ function wim_unsupport_menuentry { } function efi_common_menuentry { - vt_chosen_img_path chosen_path + vt_chosen_img_path vt_chosen_path vt_chosen_size - terminal_output console - chainloader ${iso_path}${chosen_path} + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + vt_concat_efi_iso "${vtoy_iso_part}${vt_chosen_path}" vtoy_iso_buf + + ventoy_debug_pause + + ventoy_cli_console + + unset vtoy_dotefi_retry + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} dotefi isoefi=on ${vtdebug_flag} mem:${vtoy_iso_buf_addr}:size:${vtoy_iso_buf_size} boot - terminal_output gfxterm + + if [ -n "$vtoy_dotefi_retry" ]; then + unset vtoy_dotefi_retry + chainloader "${vtoy_iso_part}${vt_chosen_path}" + boot + fi + + ventoy_gui_console } function efi_unsupport_menuentry { common_unsupport_menuentry } +function vhdboot_common_func { + vt_patch_vhdboot "$1" + + ventoy_debug_pause + + if [ -n "$vtoy_vhd_buf_addr" ]; then + if [ "$grub_platform" = "pc" ]; then + ventoy_cli_console + linux16 $vtoy_path/memdisk iso raw + initrd16 mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} + boot + ventoy_gui_console + else + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi memdisk env_param=${env_param} isoefi=${LoadIsoEfiDriver} ${vtdebug_flag} mem:${vtoy_vhd_buf_addr}:size:${vtoy_vhd_buf_size} + boot + ventoy_gui_console + fi + else + echo "Please put the right ventoy_vhdboot.img file to the 1st partition" + ventoy_pause + fi +} + +function vhd_common_menuentry { + + if [ "$VTOY_VHD_NO_WARNING" != "1" ]; then + if [ "$vtoy_iso_fs" != "ntfs" ]; then + echo -e "!!! WARNING !!!\n" + echo -e "\nPartition1 ($vtoy_iso_fs) is NOT ntfs, the VHD(x) file may not boot normally \n" + echo -e "\nVHD(x) 文件所在分区ä¸æ˜¯ ntfs æ ¼å¼, å¯èƒ½æ— æ³•æ­£å¸¸å¯åŠ¨ \n\n" + echo -n "press ENTER to continue boot (请按 回车 键继续) ..." + read vtInputKey + fi + fi + + vt_chosen_img_path vt_chosen_path vt_chosen_size + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + vhdboot_common_func "${vt_chosen_path}" +} + +function vhd_unsupport_menuentry { + common_unsupport_menuentry +} + +function vtoyboot_common_func { + set AltBootPart=0 + set vtoysupport=0 + + vt_get_vtoy_type "${1}" vtoytype parttype AltBootPart + + if vt_str_begin $vtoytype vhd; then + set vtoysupport=1 + elif [ "$vtoytype" = "raw" ]; then + set vtoysupport=1 + elif [ "$vtoytype" = "vdi" ]; then + set vtoysupport=1 + fi + + if [ $vtoysupport -eq 1 ]; then + if [ "$grub_platform" = "pc" ]; then + if [ "$parttype" = "gpt" -a $AltBootPart -eq 0 ]; then + echo "The OS in the vdisk was created in UEFI mode, but current is Legacy BIOS mode." + echo "虚拟ç£ç›˜å†…的系统是在UEFI模å¼ä¸‹åˆ›å»ºçš„,而当å‰ç³»ç»Ÿæ˜¯Legacy BIOS模å¼ï¼Œå¯èƒ½æ— æ³•æ­£å¸¸å¯åŠ¨ã€‚" + ventoy_pause + fi + else + if [ "$parttype" = "mbr" -a $AltBootPart -eq 0 ]; then + echo "The OS in the vdisk was created in Legacy BIOS mode, but current is UEFI mode." + echo "虚拟ç£ç›˜å†…的系统是在Legacy BIOS模å¼ä¸‹åˆ›å»ºçš„,而当å‰ç³»ç»Ÿæ˜¯UEFI模å¼ï¼Œå¯èƒ½æ— æ³•æ­£å¸¸å¯åŠ¨ã€‚" + ventoy_pause + fi + fi + + vt_img_sector "${1}" + vt_raw_chain_data "${1}" + + ventoy_debug_pause + + if [ -n "$vtoy_chain_mem_addr" ]; then + if [ "$grub_platform" = "pc" ]; then + vt_acpi_param ${vtoy_chain_mem_addr} 512 + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} bios80 sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + if vt_check_secureboot_var; then + vt_acpi_param ${vtoy_chain_mem_addr} 512 + fi + ventoy_cli_console + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi sector512 env_param=${ventoy_env_param} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + ventoy_gui_console + fi + else + echo "chain empty failed!" + ventoy_pause + fi + else + echo "Unsupported vtoy type $vtoytype" + ventoy_pause + fi +} + +function vtoy_common_menuentry { + vt_chosen_img_path vt_chosen_path vt_chosen_size + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + vtoyboot_common_func "${vtoy_iso_part}${vt_chosen_path}" +} + +function vtoy_unsupport_menuentry { + common_unsupport_menuentry +} + +# +#============================================================# +# IMG file boot process # +#============================================================# +# + + +function ventoy_img_easyos { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + loopback easysfs (vtimghd,1)/easy.sfs + vt_get_lib_module_ver (easysfs) /lib/modules/ vt_module_ver + + if [ -n "$vt_module_ver" ]; then + for mod in "kernel/drivers/md/dm-mod.ko" "kernel/drivers/dax/dax.ko"; do + vt_img_extra_initrd_append (easysfs)/lib/modules/$vt_module_ver/$mod + done + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy + vt_img_hook_root + + syslinux_configfile (vtimghd,1)/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt + loopback -d easysfs +} + +function ventoy_img_volumio { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy imgpart=/dev/ventoy2 bootpart=/dev/ventoy1 + vt_img_hook_root + + syslinux_configfile (vtimghd,1)/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_openelec { + elec_ver=$1 + + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + loopback vtloopex $vtoy_efi_part/ventoy/vtloopex.cpio + vt_img_extra_initrd_append (vtloopex)/$elec_ver/vtloopex.tar.xz + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=$elec_ver + vt_img_hook_root + + set root=(vtimghd,1) + syslinux_configfile (vtimghd,1)/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt + loopback -d vtloopex +} + + +function ventoy_img_freedombox { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + vt_get_lib_module_ver (vtimghd,1) /lib/modules/ vt_module_ver + if [ -n "$vt_module_ver" ]; then + vt_img_extra_initrd_append (vtimghd,1)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=freedombox + vt_img_hook_root + + configfile (vtimghd,1)/boot/grub/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_paldo { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=paldo + vt_img_hook_root + + vt_fs_enum_1st_file (vtimghd,1) /loader/entries/ vt_paldo_entry_conf + vt_file_basename $vt_paldo_entry_conf vtPaldoVer + + echo loading file... + linux (vtimghd,1)/linux-${vtPaldoVer} root=/dev/ventoy1 rootfstype=vfat + initrd (vtimghd,1)/initramfs-${vtPaldoVer} + boot + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_ubos { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + vt_get_lib_module_ver (vtimghd,3) /lib/modules/ vt_module_ver + if [ -n "$vt_module_ver" ]; then + vt_img_extra_initrd_append (vtimghd,3)/lib/modules/$vt_module_ver/kernel/drivers/md/dm-mod.ko.xz + fi + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=ubos + vt_img_hook_root + + echo loading file... + linux (vtimghd,2)/vmlinuz-linux root=/dev/ventoy3 rw + initrd (vtimghd,2)/initramfs-linux.img + boot + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_recalbox { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=recalbox + vt_img_hook_root + + set root=(vtimghd,1) + configfile (vtimghd,1)/boot/grub/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_batocera { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=batocera + vt_img_hook_root + + set root=(vtimghd,1) + syslinux_configfile (vtimghd,1)/boot/syslinux/syslinux.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_openwrt { + if [ -e (vtimghd,2)/lib64 ]; then + set ventoy_busybox_ver=64 + fi + + vt_fs_enum_1st_dir (vtimghd,2) /lib/modules/ vt_dir_name + + if [ -f (vtimghd,2)/lib/modules/$vt_dir_name/dm-mod.ko ]; then + set openwrt_plugin_need=0 + vt_img_extra_initrd_append (vtimghd,2)/lib/modules/$vt_dir_name/dm-mod.ko + if [ -f (vtimghd,2)/lib/modules/$vt_dir_name/dax.ko ]; then + vt_img_extra_initrd_append (vtimghd,2)/lib/modules/$vt_dir_name/dax.ko + fi + else + set openwrt_plugin_need=1 + if [ ! -f ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz ]; then + ventoy_gui_console + echo -e "\n ventoy_openwrt.xz not found. Please refer https://www.ventoy.net/en/doc_openwrt.html.\n" + echo -e " 未找到 ventoy_openwrt.xz 文件。请å‚考 https://www.ventoy.net/cn/doc_openwrt.html\n" + echo -e "\n press ENTER to exit (请按 回车 键返回) ..." + read vtInputKey + ventoy_cli_console + return + fi + fi + + if vt_img_check_range "${vtoy_iso_part}${vt_chosen_path}"; then + ventoy_debug_pause + else + ventoy_gui_console + echo -e "\n IMG file need processed. Please refer https://www.ventoy.net/en/doc_openwrt.html.\n" + echo -e " æ­¤ IMG 文件必须处ç†ä¹‹åŽæ‰èƒ½æ”¯æŒã€‚请å‚考 https://www.ventoy.net/cn/doc_openwrt.html\n" + echo -e "\n press ENTER to exit (请按 回车 键返回) ..." + read vtInputKey + ventoy_cli_console + return + fi + + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + if [ $openwrt_plugin_need -eq 1 ]; then + if [ -f ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz ]; then + vt_img_extra_initrd_append ${vtoy_iso_part}/ventoy/ventoy_openwrt.xz + fi + fi + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy ventoyos=openwrt + vt_img_hook_root + + set root=(vtimghd,1) + configfile (vtimghd,1)/boot/grub/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_tails { + vt_load_cpio $vtoy_path "${vt_chosen_path}" ${vtoy_iso_part} "busybox=$ventoy_busybox_ver" + vt_trailer_cpio ${vtoy_iso_part} "${vt_chosen_path}" noinit + + ventoy_debug_pause + + #boot image file + vt_set_boot_opt rdinit=/vtoy/vtoy live-media=/dev/dm-1 ventoyos=tails + vt_img_hook_root + + set root=(vtimghd,1) + configfile (vtimghd,1)/efi/debian/grub.cfg + + vt_img_unhook_root + vt_unset_boot_opt +} + +function ventoy_img_memtest86 { + chainloader (vtimghd,1)/efi/boot/BOOTX64.efi + boot +} + +function img_unsupport_tip { + echo -e "\n This IMG file is NOT supported now. \n" + echo -e " 当å‰ä¸æ”¯æŒå¯åŠ¨æ­¤ IMG 文件 \n" + echo -e "\npress ENTER to exit (请按 回车 键返回) ..." + read vtInputKey +} + +function legacy_img_memdisk { + linux16 $vtoy_path/memdisk + echo "Loading img file to memory ..." + initrd16 "${1}${2}" + + ventoy_cli_console + boot +} + +function img_common_menuentry { + set ventoy_compatible=YES + set ventoy_busybox_ver=32 + unset LoadIsoEfiDriver + + vt_chosen_img_path vt_chosen_path vt_chosen_size + + if vt_check_password "${vt_chosen_path}"; then + return + fi + + if ventoy_vcfg_proc "${vt_chosen_path}"; then + return + fi + + if [ "$grub_platform" = "pc" ]; then + if vt_check_mode 0; then + legacy_img_memdisk $vtoy_iso_part "$vt_chosen_path" + return + fi + fi + + loopback vtimghd "${vtoy_iso_part}${vt_chosen_path}" + vt_img_sector "${vtoy_iso_part}${vt_chosen_path}" + + vt_img_part_info (vtimghd) + + set vtback_root=$root + ventoy_cli_console + vt_push_last_entry + set vtback_theme=$theme + unset theme + + vt_img_extra_initrd_reset + + + vt_get_fs_label (vtimghd,1) vtImgHd1Label + if [ -d (vtimghd,2)/lib ]; then + vt_get_fs_label (vtimghd,2) vtImgHd2Label + fi + + if [ -e (vtimghd,1)/etc/hostname ]; then + vt_1st_line (vtimghd,1)/etc/hostname vtImgHostname + fi + + + if [ -e (vtimghd,1)/easy.sfs ]; then + ventoy_img_easyos + elif [ -e (vtimghd,1)/volumio.initrd ]; then + ventoy_img_volumio + elif vt_str_begin "$vtImgHd1Label" "LAKKA"; then + ventoy_img_openelec lakka + elif vt_str_begin "$vtImgHd1Label" "LIBREELEC"; then + ventoy_img_openelec LibreELEC + elif vt_str_begin "$vtImgHd1Label" "paldo-live"; then + ventoy_img_paldo + elif vt_str_begin "$vtImgHostname" "freedombox"; then + ventoy_img_freedombox + elif vt_str_begin "$vtImgHd1Label" "BATOCERA"; then + ventoy_img_batocera + elif vt_str_begin "$vtImgHd1Label" "Tails"; then + ventoy_img_tails + elif [ "$vtImgHd2Label" = "RECALBOX" ]; then + ventoy_img_recalbox + elif [ -f (vtimghd,2)/loader/entries/ubos.conf ]; then + ventoy_img_ubos + elif [ -f (vtimghd,2)/etc/openwrt_version ]; then + ventoy_img_openwrt + elif [ -f (vtimghd,1)/efi/boot/mt86.png ]; then + if [ "$grub_platform" = "pc" ]; then + img_unsupport_tip + else + ventoy_img_memtest86 + fi + else + vt_linux_chain_data "${vtoy_iso_part}${vt_chosen_path}" + ventoy_acpi_param ${vtoy_chain_mem_addr} 512 + if [ "$grub_platform" = "pc" ]; then + linux16 $vtoy_path/ipxe.krn ${vtdebug_flag} sector512 mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + else + chainloader ${vtoy_path}/ventoy_${VTOY_EFI_ARCH}.efi sector512 env_param=${env_param} isoefi=${LoadIsoEfiDriver} FirstTry=${FirstTryBootFile} ${vtdebug_flag} mem:${vtoy_chain_mem_addr}:size:${vtoy_chain_mem_size} + boot + fi + fi + + loopback -d vtimghd + + set root=$vtback_root + vt_pop_last_entry + set theme=$vtback_theme + ventoy_gui_console + set ventoy_compatible=NO +} + +function img_unsupport_menuentry { + common_unsupport_menuentry +} + ############################################################# ############################################################# ############################################################# @@ -563,7 +1870,10 @@ function efi_unsupport_menuentry { ############################################################# ############################################################# -set VENTOY_VERSION="1.0.14" +set VENTOY_VERSION="1.0.50" + +#ACPI not compatible with Window7/8, so disable by default +set VTOY_PARAM_NO_ACPI=1 # Default menu display mode, you can change it as you want. # 0: List mode @@ -572,16 +1882,31 @@ set VTOY_DEFAULT_MENU_MODE=0 set VTOY_MEM_DISK_STR="[Memdisk]" set VTOY_ISO_RAW_STR="Compatible Mode" +set VTOY_GRUB2_MODE_STR="GRUB2 Mode" +set VTOY_WIMBOOT_MODE_STR="WIMBOOT Mode" set VTOY_ISO_UEFI_DRV_STR="UEFI FS" set VTOY_F2_CMD="ventoy_power" set VTOY_F4_CMD="ventoy_localboot" set VTOY_F5_CMD="ventoy_diagnosis" +set VTOY_F6_CMD="ventoy_ext_menu" if [ "$grub_platform" = "pc" ]; then set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION BIOS www.ventoy.net" -else - set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net" +else + if [ "$grub_cpu" = "i386" ]; then + set VTOY_EFI_ARCH=ia32 + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION IA32 www.ventoy.net" + elif [ "$grub_cpu" = "arm64" ]; then + set VTOY_EFI_ARCH=aa64 + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION AA64 www.ventoy.net" + elif [ "$grub_cpu" = "mips64el" ]; then + set VTOY_EFI_ARCH=mips + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION MIPS www.ventoy.net" + else + set VTOY_EFI_ARCH=x64 + set VTOY_TEXT_MENU_VER="Ventoy $VENTOY_VERSION UEFI www.ventoy.net" + fi fi vt_device $root vtoy_dev @@ -589,16 +1914,17 @@ vt_device $root vtoy_dev if [ "$vtoy_dev" = "tftp" ]; then set vtoy_path=($root) for vtid in 0 1 2 3; do - if [ -d (hd$vtid,2)/ventoy ]; then - set iso_path=(hd$vtid,1) + if [ -f (hd$vtid,2)/ventoy/ventoy.cpio ]; then + set vtoy_iso_part=(hd$vtid,1) set vtoy_efi_part=(hd$vtid,2) + set vtoydev=hd$vtid break fi done loadfont ascii - if [ -f $iso_path/ventoy/ventoy.json ]; then - set vt_plugin_path=$iso_path + if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then + set vt_plugin_path=$vtoy_iso_part else set vt_plugin_path=$prefix vt_load_plugin $vt_plugin_path @@ -610,16 +1936,23 @@ else set vtoy_path=($root)/ventoy fi - set iso_path=($vtoy_dev,1) + set vtoydev=$vtoy_dev + set vtoy_iso_part=($vtoy_dev,1) set vtoy_efi_part=($vtoy_dev,2) loadfont unicode - set vt_plugin_path=$iso_path + set vt_plugin_path=$vtoy_iso_part fi +#Load Partition Table +vt_load_part_table $vtoydev #Load Plugin -if [ -f $iso_path/ventoy/ventoy.json ]; then - vt_load_plugin $iso_path +if [ -f $vtoy_iso_part/ventoy/ventoy.json ]; then + clear + vt_load_plugin $vtoy_iso_part + clear +else + vt_check_json_path_case $vtoy_iso_part fi if [ -n "$VTOY_MENU_TIMEOUT" ]; then @@ -628,43 +1961,146 @@ else unset timeout fi -if [ -f $iso_path/ventoy/ventoy_wimboot.img ]; then - vt_load_wimboot $iso_path/ventoy/ventoy_wimboot.img +if [ -f $vtoy_iso_part/ventoy/ventoy_wimboot.img ]; then + vt_load_wimboot $vtoy_iso_part/ventoy/ventoy_wimboot.img elif [ -f $vtoy_efi_part/ventoy/ventoy_wimboot.img ]; then vt_load_wimboot $vtoy_efi_part/ventoy/ventoy_wimboot.img fi +if [ -f $vtoy_iso_part/ventoy/ventoy_vhdboot.img ]; then + vt_load_vhdboot $vtoy_iso_part/ventoy/ventoy_vhdboot.img +elif [ -f $vtoy_efi_part/ventoy/ventoy_vhdboot.img ]; then + vt_load_vhdboot $vtoy_efi_part/ventoy/ventoy_vhdboot.img +fi + if [ $VTOY_DEFAULT_MENU_MODE -eq 0 ]; then set VTOY_F3_CMD="vt_dynamic_menu 1 1" - set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Debug" + set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:TreeView F4:Localboot F5:Tools F6:ExMenu" else set VTOY_F3_CMD="vt_dynamic_menu 1 0" - set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Debug" + set VTOY_HOTKEY_TIP="F1:Memdisk F2:Power F3:ListView F4:Localboot F5:Tools F6:ExMenu" fi if [ -n "$vtoy_gfxmode" ]; then set gfxmode=$vtoy_gfxmode + set gfxpayload=keep else - set gfxmode=1920x1080,1366x768,1024x768 + set gfxmode=1024x768 + set gfxpayload=keep fi -if [ -n "$vtoy_theme" ]; then - set theme=$vtoy_theme -else - set theme=$prefix/themes/ventoy/theme.txt -fi if [ "$vtoy_display_mode" = "CLI" ]; then terminal_output console -else +elif [ "$vtoy_display_mode" = "serial" ]; then + if [ -n "$vtoy_serial_param" ]; then + serial $vtoy_serial_param + fi + terminal_input serial + terminal_output serial +elif [ "$vtoy_display_mode" = "serial_console" ]; then + if [ -n "$vtoy_serial_param" ]; then + serial $vtoy_serial_param + fi + terminal_input serial console + terminal_output serial console +else + if [ -n "$vtoy_theme" ]; then + vt_set_theme + else + set theme=$prefix/themes/ventoy/theme.txt + fi terminal_output gfxterm fi +if [ -n "$VTOY_DEFAULT_KBD_LAYOUT" ]; then + set_keyboard_layout "$VTOY_DEFAULT_KBD_LAYOUT" +fi + +if [ -n "$VTOY_PLUGIN_PATH_CASE_MISMATCH" ]; then + clear + echo "$VTOY_PLUGIN_PATH_CASE_MISMATCH" + echo -e "\n\nPath case does not match! ventoy directory and ventoy.json MUST be all lowercase!" + echo -e "\n路径大å°å†™ä¸åŒ¹é…ï¼ventoy 目录和 ventoy.json 文件的å字必须是全部å°å†™ï¼Œè¯·ä¿®æ­£ï¼" + echo -e "\n\npress ENTER to continue (请按回车键继续) ..." + read vtInputKey +fi + +if [ -n "$VTOY_PLUGIN_SYNTAX_ERROR" ]; then + clear + echo -e "\n Syntax error detected in ventoy.json, please check! \n" + echo -e " ventoy.json 文件中有语法错误,所有é…置都ä¸ä¼šç”Ÿæ•ˆï¼Œè¯·æ£€æŸ¥ï¼\n" + echo -e "\n press ENTER to continue (请按 回车 键继续) ..." + read vtInputKey +fi + +for vtTFile in ventoy.json ventoy_grub.cfg; do + if [ -f $vtoy_efi_part/ventoy/$vtTFile ]; then + clear + echo -e "\n You need to put $vtTFile in the 1st partition which hold the ISO files.\n" + echo -e " $vtTFile 放错分区了,请放到镜åƒåˆ†åŒºé‡Œçš„ ventoy 目录下(此目录需è¦æ‰‹åŠ¨åˆ›å»ºï¼‰ï¼\n" + echo -e "\n press ENTER to continue (请按 回车 键继续) ..." + read vtInputKey + fi +done + +#clear all input key before show main menu +vt_clear_key + +#export necessary variable +export theme +export gfxmode +export gfxpayload +export vtoydev +export vtoy_path +export vtdebug_flag +export vtoy_iso_fs +export vtoy_iso_part +export vtoy_efi_part +export VENTOY_VERSION +export VTOY_CUR_VIDEO_MODE +export VTOY_EFI_ARCH +export VTOY_MEM_DISK_STR +export VTOY_ISO_RAW_STR +export VTOY_GRUB2_MODE_STR +export VTOY_WIMBOOT_MODE_STR +export VTOY_ISO_UEFI_DRV_STR + + +#special VTOY_DEFAULT_IMAGE process +if [ -n "$VTOY_DEFAULT_IMAGE" ]; then + if regexp --set 1:vtHotkey --set 2:vtDefault "(F[2-9])>(.*)" "$VTOY_DEFAULT_IMAGE"; then + + set default="$vtDefault" + if [ -z "$VTOY_MENU_TIMEOUT" ]; then + set timeout=0 + else + set timeout=$VTOY_MENU_TIMEOUT + fi + + export timeout + export default + + if [ "$vtHotkey" = "F2" ]; then + ventoy_power + elif [ "$vtHotkey" = "F4" ]; then + ventoy_localboot + elif [ "$vtHotkey" = "F5" ]; then + ventoy_diagnosis + elif [ "$vtHotkey" = "F6" ]; then + ventoy_ext_menu + fi + + unset timeout + unset default + fi +fi + #colect all image files (iso files) set ventoy_img_count=0 -vt_list_img $iso_path ventoy_img_count +vt_list_img $vtoy_iso_part ventoy_img_count #Main menu if [ $ventoy_img_count -gt 0 ]; then diff --git a/INSTALL/grub/i386-efi/adler32.mod b/INSTALL/grub/i386-efi/adler32.mod new file mode 100644 index 00000000..c92408e8 Binary files /dev/null and b/INSTALL/grub/i386-efi/adler32.mod differ diff --git a/INSTALL/grub/i386-efi/affs.mod b/INSTALL/grub/i386-efi/affs.mod new file mode 100644 index 00000000..8ba2f262 Binary files /dev/null and b/INSTALL/grub/i386-efi/affs.mod differ diff --git a/INSTALL/grub/i386-efi/afs.mod b/INSTALL/grub/i386-efi/afs.mod new file mode 100644 index 00000000..42260548 Binary files /dev/null and b/INSTALL/grub/i386-efi/afs.mod differ diff --git a/INSTALL/grub/i386-efi/ahci.mod b/INSTALL/grub/i386-efi/ahci.mod new file mode 100644 index 00000000..d795e65d Binary files /dev/null and b/INSTALL/grub/i386-efi/ahci.mod differ diff --git a/INSTALL/grub/i386-efi/aout.mod b/INSTALL/grub/i386-efi/aout.mod new file mode 100644 index 00000000..3e3ce9b1 Binary files /dev/null and b/INSTALL/grub/i386-efi/aout.mod differ diff --git a/INSTALL/grub/i386-efi/appleldr.mod b/INSTALL/grub/i386-efi/appleldr.mod new file mode 100644 index 00000000..8e49c940 Binary files /dev/null and b/INSTALL/grub/i386-efi/appleldr.mod differ diff --git a/INSTALL/grub/i386-efi/archelp.mod b/INSTALL/grub/i386-efi/archelp.mod new file mode 100644 index 00000000..b07a9464 Binary files /dev/null and b/INSTALL/grub/i386-efi/archelp.mod differ diff --git a/INSTALL/grub/i386-efi/ata.mod b/INSTALL/grub/i386-efi/ata.mod new file mode 100644 index 00000000..b0c3b6ef Binary files /dev/null and b/INSTALL/grub/i386-efi/ata.mod differ diff --git a/INSTALL/grub/i386-efi/backtrace.mod b/INSTALL/grub/i386-efi/backtrace.mod new file mode 100644 index 00000000..53fdb345 Binary files /dev/null and b/INSTALL/grub/i386-efi/backtrace.mod differ diff --git a/INSTALL/grub/i386-efi/bfs.mod b/INSTALL/grub/i386-efi/bfs.mod new file mode 100644 index 00000000..e69b0827 Binary files /dev/null and b/INSTALL/grub/i386-efi/bfs.mod differ diff --git a/INSTALL/grub/i386-efi/blscfg.mod b/INSTALL/grub/i386-efi/blscfg.mod new file mode 100644 index 00000000..a0a10425 Binary files /dev/null and b/INSTALL/grub/i386-efi/blscfg.mod differ diff --git a/INSTALL/grub/i386-efi/bsd.mod b/INSTALL/grub/i386-efi/bsd.mod new file mode 100644 index 00000000..ea3e86f9 Binary files /dev/null and b/INSTALL/grub/i386-efi/bsd.mod differ diff --git a/INSTALL/grub/i386-efi/bswap_test.mod b/INSTALL/grub/i386-efi/bswap_test.mod new file mode 100644 index 00000000..12e67f03 Binary files /dev/null and b/INSTALL/grub/i386-efi/bswap_test.mod differ diff --git a/INSTALL/grub/i386-efi/btrfs.mod b/INSTALL/grub/i386-efi/btrfs.mod new file mode 100644 index 00000000..20f080db Binary files /dev/null and b/INSTALL/grub/i386-efi/btrfs.mod differ diff --git a/INSTALL/grub/i386-efi/cbfs.mod b/INSTALL/grub/i386-efi/cbfs.mod new file mode 100644 index 00000000..7a6fa094 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbfs.mod differ diff --git a/INSTALL/grub/i386-efi/cbls.mod b/INSTALL/grub/i386-efi/cbls.mod new file mode 100644 index 00000000..30c278c1 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbls.mod differ diff --git a/INSTALL/grub/i386-efi/cbmemc.mod b/INSTALL/grub/i386-efi/cbmemc.mod new file mode 100644 index 00000000..2df81ee2 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbmemc.mod differ diff --git a/INSTALL/grub/i386-efi/cbtable.mod b/INSTALL/grub/i386-efi/cbtable.mod new file mode 100644 index 00000000..c9822026 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbtable.mod differ diff --git a/INSTALL/grub/i386-efi/cbtime.mod b/INSTALL/grub/i386-efi/cbtime.mod new file mode 100644 index 00000000..a171c170 Binary files /dev/null and b/INSTALL/grub/i386-efi/cbtime.mod differ diff --git a/INSTALL/grub/i386-efi/cmdline_cat_test.mod b/INSTALL/grub/i386-efi/cmdline_cat_test.mod new file mode 100644 index 00000000..271620be Binary files /dev/null and b/INSTALL/grub/i386-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/i386-efi/cmp.mod b/INSTALL/grub/i386-efi/cmp.mod new file mode 100644 index 00000000..e9eb48e3 Binary files /dev/null and b/INSTALL/grub/i386-efi/cmp.mod differ diff --git a/INSTALL/grub/i386-efi/cmp_test.mod b/INSTALL/grub/i386-efi/cmp_test.mod new file mode 100644 index 00000000..012426ff Binary files /dev/null and b/INSTALL/grub/i386-efi/cmp_test.mod differ diff --git a/INSTALL/grub/i386-efi/command.lst b/INSTALL/grub/i386-efi/command.lst new file mode 100644 index 00000000..18d5963b --- /dev/null +++ b/INSTALL/grub/i386-efi/command.lst @@ -0,0 +1,203 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*bls_import: blscfg +*blscfg: blscfg +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*gettext: gettext +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*serial: serial +*set_keyboard_layout: setkey +*setkey: setkey +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +appleloader: appleldr +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +fakebios: loadbios +false: true +fix_video: fixvideo +fwsetup: efifwsetup +gdbstub: gdb +gdbstub_break: gdb +gdbstub_stop: gdb +gptsync: gptsync +halt: halt +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +initrdefi: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +linuxefi: linux +list_trusted: pgp +loadbios: loadbios +loadfont: font +lscoreboot: cbls +lsefi: lsefi +lsefimmap: lsefimmap +lsefisystab: lsefisystab +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +lssal: lssal +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +usb: usbtest +videoinfo: videoinfo +videotest: videotest +vt_img_extra_initrd_append: linux +vt_img_extra_initrd_reset: linux +vt_set_boot_opt: linux +vt_unset_boot_opt: linux +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/i386-efi/cpio.mod b/INSTALL/grub/i386-efi/cpio.mod new file mode 100644 index 00000000..f23822c9 Binary files /dev/null and b/INSTALL/grub/i386-efi/cpio.mod differ diff --git a/INSTALL/grub/i386-efi/cpio_be.mod b/INSTALL/grub/i386-efi/cpio_be.mod new file mode 100644 index 00000000..60714628 Binary files /dev/null and b/INSTALL/grub/i386-efi/cpio_be.mod differ diff --git a/INSTALL/grub/i386-efi/cpuid.mod b/INSTALL/grub/i386-efi/cpuid.mod new file mode 100644 index 00000000..2e1f783b Binary files /dev/null and b/INSTALL/grub/i386-efi/cpuid.mod differ diff --git a/INSTALL/grub/i386-efi/crc64.mod b/INSTALL/grub/i386-efi/crc64.mod new file mode 100644 index 00000000..7e111a67 Binary files /dev/null and b/INSTALL/grub/i386-efi/crc64.mod differ diff --git a/INSTALL/grub/i386-efi/crypto.lst b/INSTALL/grub/i386-efi/crypto.lst new file mode 100644 index 00000000..77d9efc0 --- /dev/null +++ b/INSTALL/grub/i386-efi/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/i386-efi/cryptodisk.mod b/INSTALL/grub/i386-efi/cryptodisk.mod new file mode 100644 index 00000000..18bb82f1 Binary files /dev/null and b/INSTALL/grub/i386-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/i386-efi/cs5536.mod b/INSTALL/grub/i386-efi/cs5536.mod new file mode 100644 index 00000000..2f2f797f Binary files /dev/null and b/INSTALL/grub/i386-efi/cs5536.mod differ diff --git a/INSTALL/grub/i386-efi/ctz_test.mod b/INSTALL/grub/i386-efi/ctz_test.mod new file mode 100644 index 00000000..7583ee64 Binary files /dev/null and b/INSTALL/grub/i386-efi/ctz_test.mod differ diff --git a/INSTALL/grub/i386-efi/date.mod b/INSTALL/grub/i386-efi/date.mod new file mode 100644 index 00000000..c0116087 Binary files /dev/null and b/INSTALL/grub/i386-efi/date.mod differ diff --git a/INSTALL/grub/i386-efi/datehook.mod b/INSTALL/grub/i386-efi/datehook.mod new file mode 100644 index 00000000..9a2d6cbf Binary files /dev/null and b/INSTALL/grub/i386-efi/datehook.mod differ diff --git a/INSTALL/grub/i386-efi/disk.mod b/INSTALL/grub/i386-efi/disk.mod new file mode 100644 index 00000000..36498c15 Binary files /dev/null and b/INSTALL/grub/i386-efi/disk.mod differ diff --git a/INSTALL/grub/i386-efi/div.mod b/INSTALL/grub/i386-efi/div.mod new file mode 100644 index 00000000..1102fa22 Binary files /dev/null and b/INSTALL/grub/i386-efi/div.mod differ diff --git a/INSTALL/grub/i386-efi/div_test.mod b/INSTALL/grub/i386-efi/div_test.mod new file mode 100644 index 00000000..7a6a7c0f Binary files /dev/null and b/INSTALL/grub/i386-efi/div_test.mod differ diff --git a/INSTALL/grub/i386-efi/dm_nv.mod b/INSTALL/grub/i386-efi/dm_nv.mod new file mode 100644 index 00000000..e8414d79 Binary files /dev/null and b/INSTALL/grub/i386-efi/dm_nv.mod differ diff --git a/INSTALL/grub/i386-efi/efinet.mod b/INSTALL/grub/i386-efi/efinet.mod new file mode 100644 index 00000000..c811c956 Binary files /dev/null and b/INSTALL/grub/i386-efi/efinet.mod differ diff --git a/INSTALL/grub/i386-efi/ehci.mod b/INSTALL/grub/i386-efi/ehci.mod new file mode 100644 index 00000000..51b92be6 Binary files /dev/null and b/INSTALL/grub/i386-efi/ehci.mod differ diff --git a/INSTALL/grub/i386-efi/elf.mod b/INSTALL/grub/i386-efi/elf.mod new file mode 100644 index 00000000..5f9edb6b Binary files /dev/null and b/INSTALL/grub/i386-efi/elf.mod differ diff --git a/INSTALL/grub/i386-efi/eval.mod b/INSTALL/grub/i386-efi/eval.mod new file mode 100644 index 00000000..e37e6e8e Binary files /dev/null and b/INSTALL/grub/i386-efi/eval.mod differ diff --git a/INSTALL/grub/i386-efi/exfctest.mod b/INSTALL/grub/i386-efi/exfctest.mod new file mode 100644 index 00000000..65b54a95 Binary files /dev/null and b/INSTALL/grub/i386-efi/exfctest.mod differ diff --git a/INSTALL/grub/i386-efi/f2fs.mod b/INSTALL/grub/i386-efi/f2fs.mod new file mode 100644 index 00000000..b245c9d6 Binary files /dev/null and b/INSTALL/grub/i386-efi/f2fs.mod differ diff --git a/INSTALL/grub/i386-efi/fdt.lst b/INSTALL/grub/i386-efi/fdt.lst new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL/grub/i386-efi/fixvideo.mod b/INSTALL/grub/i386-efi/fixvideo.mod new file mode 100644 index 00000000..a959467d Binary files /dev/null and b/INSTALL/grub/i386-efi/fixvideo.mod differ diff --git a/INSTALL/grub/i386-efi/fs.lst b/INSTALL/grub/i386-efi/fs.lst new file mode 100644 index 00000000..0acd240b --- /dev/null +++ b/INSTALL/grub/i386-efi/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/i386-efi/functional_test.mod b/INSTALL/grub/i386-efi/functional_test.mod new file mode 100644 index 00000000..d45a47cc Binary files /dev/null and b/INSTALL/grub/i386-efi/functional_test.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_arcfour.mod b/INSTALL/grub/i386-efi/gcry_arcfour.mod new file mode 100644 index 00000000..b6c56757 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_blowfish.mod b/INSTALL/grub/i386-efi/gcry_blowfish.mod new file mode 100644 index 00000000..5e50e932 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_camellia.mod b/INSTALL/grub/i386-efi/gcry_camellia.mod new file mode 100644 index 00000000..33f7f280 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_cast5.mod b/INSTALL/grub/i386-efi/gcry_cast5.mod new file mode 100644 index 00000000..abca73bd Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_crc.mod b/INSTALL/grub/i386-efi/gcry_crc.mod new file mode 100644 index 00000000..e5fad447 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_des.mod b/INSTALL/grub/i386-efi/gcry_des.mod new file mode 100644 index 00000000..cba82a47 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_des.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_dsa.mod b/INSTALL/grub/i386-efi/gcry_dsa.mod new file mode 100644 index 00000000..c8f995e8 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_idea.mod b/INSTALL/grub/i386-efi/gcry_idea.mod new file mode 100644 index 00000000..08a0f986 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_md4.mod b/INSTALL/grub/i386-efi/gcry_md4.mod new file mode 100644 index 00000000..438ebe56 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rfc2268.mod b/INSTALL/grub/i386-efi/gcry_rfc2268.mod new file mode 100644 index 00000000..c2168f11 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rijndael.mod b/INSTALL/grub/i386-efi/gcry_rijndael.mod new file mode 100644 index 00000000..ff3366c8 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rmd160.mod b/INSTALL/grub/i386-efi/gcry_rmd160.mod new file mode 100644 index 00000000..c0ca9189 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_rsa.mod b/INSTALL/grub/i386-efi/gcry_rsa.mod new file mode 100644 index 00000000..7d013c9e Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_seed.mod b/INSTALL/grub/i386-efi/gcry_seed.mod new file mode 100644 index 00000000..338e31e4 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_serpent.mod b/INSTALL/grub/i386-efi/gcry_serpent.mod new file mode 100644 index 00000000..4bee73e2 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_sha1.mod b/INSTALL/grub/i386-efi/gcry_sha1.mod new file mode 100644 index 00000000..c66caea1 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_sha256.mod b/INSTALL/grub/i386-efi/gcry_sha256.mod new file mode 100644 index 00000000..cce31ff2 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_tiger.mod b/INSTALL/grub/i386-efi/gcry_tiger.mod new file mode 100644 index 00000000..2b841eca Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_twofish.mod b/INSTALL/grub/i386-efi/gcry_twofish.mod new file mode 100644 index 00000000..32db1b07 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/i386-efi/gcry_whirlpool.mod b/INSTALL/grub/i386-efi/gcry_whirlpool.mod new file mode 100644 index 00000000..11f3a743 Binary files /dev/null and b/INSTALL/grub/i386-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/i386-efi/gdb.mod b/INSTALL/grub/i386-efi/gdb.mod new file mode 100644 index 00000000..b2fcd3d3 Binary files /dev/null and b/INSTALL/grub/i386-efi/gdb.mod differ diff --git a/INSTALL/grub/i386-efi/geli.mod b/INSTALL/grub/i386-efi/geli.mod new file mode 100644 index 00000000..4ac79499 Binary files /dev/null and b/INSTALL/grub/i386-efi/geli.mod differ diff --git a/INSTALL/grub/i386-efi/gfxterm_menu.mod b/INSTALL/grub/i386-efi/gfxterm_menu.mod new file mode 100644 index 00000000..19889417 Binary files /dev/null and b/INSTALL/grub/i386-efi/gfxterm_menu.mod differ diff --git a/INSTALL/grub/i386-efi/gptsync.mod b/INSTALL/grub/i386-efi/gptsync.mod new file mode 100644 index 00000000..6b477346 Binary files /dev/null and b/INSTALL/grub/i386-efi/gptsync.mod differ diff --git a/INSTALL/grub/i386-efi/hdparm.mod b/INSTALL/grub/i386-efi/hdparm.mod new file mode 100644 index 00000000..7c794b5d Binary files /dev/null and b/INSTALL/grub/i386-efi/hdparm.mod differ diff --git a/INSTALL/grub/i386-efi/hello.mod b/INSTALL/grub/i386-efi/hello.mod new file mode 100644 index 00000000..81a5c364 Binary files /dev/null and b/INSTALL/grub/i386-efi/hello.mod differ diff --git a/INSTALL/grub/i386-efi/help.mod b/INSTALL/grub/i386-efi/help.mod new file mode 100644 index 00000000..5abbb8a8 Binary files /dev/null and b/INSTALL/grub/i386-efi/help.mod differ diff --git a/INSTALL/grub/i386-efi/hexdump.mod b/INSTALL/grub/i386-efi/hexdump.mod new file mode 100644 index 00000000..5cb22cac Binary files /dev/null and b/INSTALL/grub/i386-efi/hexdump.mod differ diff --git a/INSTALL/grub/i386-efi/hfs.mod b/INSTALL/grub/i386-efi/hfs.mod new file mode 100644 index 00000000..7e44a334 Binary files /dev/null and b/INSTALL/grub/i386-efi/hfs.mod differ diff --git a/INSTALL/grub/i386-efi/hfspluscomp.mod b/INSTALL/grub/i386-efi/hfspluscomp.mod new file mode 100644 index 00000000..2fab99cb Binary files /dev/null and b/INSTALL/grub/i386-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/i386-efi/iorw.mod b/INSTALL/grub/i386-efi/iorw.mod new file mode 100644 index 00000000..89f3ebd8 Binary files /dev/null and b/INSTALL/grub/i386-efi/iorw.mod differ diff --git a/INSTALL/grub/i386-efi/jfs.mod b/INSTALL/grub/i386-efi/jfs.mod new file mode 100644 index 00000000..d247fb56 Binary files /dev/null and b/INSTALL/grub/i386-efi/jfs.mod differ diff --git a/INSTALL/grub/i386-efi/keylayouts.mod b/INSTALL/grub/i386-efi/keylayouts.mod new file mode 100644 index 00000000..3af5cc92 Binary files /dev/null and b/INSTALL/grub/i386-efi/keylayouts.mod differ diff --git a/INSTALL/grub/i386-efi/keystatus.mod b/INSTALL/grub/i386-efi/keystatus.mod new file mode 100644 index 00000000..12a1fc70 Binary files /dev/null and b/INSTALL/grub/i386-efi/keystatus.mod differ diff --git a/INSTALL/grub/i386-efi/ldm.mod b/INSTALL/grub/i386-efi/ldm.mod new file mode 100644 index 00000000..6ca73848 Binary files /dev/null and b/INSTALL/grub/i386-efi/ldm.mod differ diff --git a/INSTALL/grub/i386-efi/legacy_password_test.mod b/INSTALL/grub/i386-efi/legacy_password_test.mod new file mode 100644 index 00000000..08e34bb0 Binary files /dev/null and b/INSTALL/grub/i386-efi/legacy_password_test.mod differ diff --git a/INSTALL/grub/i386-efi/legacycfg.mod b/INSTALL/grub/i386-efi/legacycfg.mod new file mode 100644 index 00000000..4e040af0 Binary files /dev/null and b/INSTALL/grub/i386-efi/legacycfg.mod differ diff --git a/INSTALL/grub/i386-efi/linux16.mod b/INSTALL/grub/i386-efi/linux16.mod new file mode 100644 index 00000000..9edbda4a Binary files /dev/null and b/INSTALL/grub/i386-efi/linux16.mod differ diff --git a/INSTALL/grub/i386-efi/loadbios.mod b/INSTALL/grub/i386-efi/loadbios.mod new file mode 100644 index 00000000..0601fe21 Binary files /dev/null and b/INSTALL/grub/i386-efi/loadbios.mod differ diff --git a/INSTALL/grub/i386-efi/loadenv.mod b/INSTALL/grub/i386-efi/loadenv.mod new file mode 100644 index 00000000..d32017db Binary files /dev/null and b/INSTALL/grub/i386-efi/loadenv.mod differ diff --git a/INSTALL/grub/i386-efi/lsacpi.mod b/INSTALL/grub/i386-efi/lsacpi.mod new file mode 100644 index 00000000..a6bc64c2 Binary files /dev/null and b/INSTALL/grub/i386-efi/lsacpi.mod differ diff --git a/INSTALL/grub/i386-efi/lsefi.mod b/INSTALL/grub/i386-efi/lsefi.mod new file mode 100644 index 00000000..01c06a6a Binary files /dev/null and b/INSTALL/grub/i386-efi/lsefi.mod differ diff --git a/INSTALL/grub/i386-efi/lsefimmap.mod b/INSTALL/grub/i386-efi/lsefimmap.mod new file mode 100644 index 00000000..b5807638 Binary files /dev/null and b/INSTALL/grub/i386-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/i386-efi/lsefisystab.mod b/INSTALL/grub/i386-efi/lsefisystab.mod new file mode 100644 index 00000000..e87988f2 Binary files /dev/null and b/INSTALL/grub/i386-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/i386-efi/lsmmap.mod b/INSTALL/grub/i386-efi/lsmmap.mod new file mode 100644 index 00000000..77a01841 Binary files /dev/null and b/INSTALL/grub/i386-efi/lsmmap.mod differ diff --git a/INSTALL/grub/i386-efi/lspci.mod b/INSTALL/grub/i386-efi/lspci.mod new file mode 100644 index 00000000..c1aad4d5 Binary files /dev/null and b/INSTALL/grub/i386-efi/lspci.mod differ diff --git a/INSTALL/grub/i386-efi/lssal.mod b/INSTALL/grub/i386-efi/lssal.mod new file mode 100644 index 00000000..b64092a7 Binary files /dev/null and b/INSTALL/grub/i386-efi/lssal.mod differ diff --git a/INSTALL/grub/i386-efi/luks.mod b/INSTALL/grub/i386-efi/luks.mod new file mode 100644 index 00000000..9fc8f339 Binary files /dev/null and b/INSTALL/grub/i386-efi/luks.mod differ diff --git a/INSTALL/grub/i386-efi/lvm.mod b/INSTALL/grub/i386-efi/lvm.mod new file mode 100644 index 00000000..4d570172 Binary files /dev/null and b/INSTALL/grub/i386-efi/lvm.mod differ diff --git a/INSTALL/grub/i386-efi/macbless.mod b/INSTALL/grub/i386-efi/macbless.mod new file mode 100644 index 00000000..f14033fb Binary files /dev/null and b/INSTALL/grub/i386-efi/macbless.mod differ diff --git a/INSTALL/grub/i386-efi/macho.mod b/INSTALL/grub/i386-efi/macho.mod new file mode 100644 index 00000000..b97d1050 Binary files /dev/null and b/INSTALL/grub/i386-efi/macho.mod differ diff --git a/INSTALL/grub/i386-efi/mdraid09.mod b/INSTALL/grub/i386-efi/mdraid09.mod new file mode 100644 index 00000000..f78c90e6 Binary files /dev/null and b/INSTALL/grub/i386-efi/mdraid09.mod differ diff --git a/INSTALL/grub/i386-efi/mdraid09_be.mod b/INSTALL/grub/i386-efi/mdraid09_be.mod new file mode 100644 index 00000000..d31d5414 Binary files /dev/null and b/INSTALL/grub/i386-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/i386-efi/mdraid1x.mod b/INSTALL/grub/i386-efi/mdraid1x.mod new file mode 100644 index 00000000..94ff0b5c Binary files /dev/null and b/INSTALL/grub/i386-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/i386-efi/memdisk.mod b/INSTALL/grub/i386-efi/memdisk.mod new file mode 100644 index 00000000..33ccaf26 Binary files /dev/null and b/INSTALL/grub/i386-efi/memdisk.mod differ diff --git a/INSTALL/grub/i386-efi/memrw.mod b/INSTALL/grub/i386-efi/memrw.mod new file mode 100644 index 00000000..fde77736 Binary files /dev/null and b/INSTALL/grub/i386-efi/memrw.mod differ diff --git a/INSTALL/grub/i386-efi/minix.mod b/INSTALL/grub/i386-efi/minix.mod new file mode 100644 index 00000000..08c6f713 Binary files /dev/null and b/INSTALL/grub/i386-efi/minix.mod differ diff --git a/INSTALL/grub/i386-efi/minix2.mod b/INSTALL/grub/i386-efi/minix2.mod new file mode 100644 index 00000000..372fec6a Binary files /dev/null and b/INSTALL/grub/i386-efi/minix2.mod differ diff --git a/INSTALL/grub/i386-efi/minix2_be.mod b/INSTALL/grub/i386-efi/minix2_be.mod new file mode 100644 index 00000000..34867dde Binary files /dev/null and b/INSTALL/grub/i386-efi/minix2_be.mod differ diff --git a/INSTALL/grub/i386-efi/minix3.mod b/INSTALL/grub/i386-efi/minix3.mod new file mode 100644 index 00000000..0e886a88 Binary files /dev/null and b/INSTALL/grub/i386-efi/minix3.mod differ diff --git a/INSTALL/grub/i386-efi/minix3_be.mod b/INSTALL/grub/i386-efi/minix3_be.mod new file mode 100644 index 00000000..f9eaba5b Binary files /dev/null and b/INSTALL/grub/i386-efi/minix3_be.mod differ diff --git a/INSTALL/grub/i386-efi/minix_be.mod b/INSTALL/grub/i386-efi/minix_be.mod new file mode 100644 index 00000000..2b2a0f13 Binary files /dev/null and b/INSTALL/grub/i386-efi/minix_be.mod differ diff --git a/INSTALL/grub/i386-efi/moddep.lst b/INSTALL/grub/i386-efi/moddep.lst new file mode 100644 index 00000000..970ddfd3 --- /dev/null +++ b/INSTALL/grub/i386-efi/moddep.lst @@ -0,0 +1,266 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +setkey: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +lsefimmap: +aout: +gcry_arcfour: crypto +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd +bsd: elf serial crypto gcry_md5 verifiers extcmd aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +efinet: net +disk: +appleldr: boot +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: +halt: acpi +gdb: serial backtrace +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: ventoy verifiers video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +blscfg: extcmd normal +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb +pata: ata +mul_test: functional_test +adler32: crypto +terminal: +div: +ehci: cs5536 usb boot +crypto: +part_bsd: part_msdos +cs5536: +ventoy: elf fshelp ext2 btrfs font crypto gcry_md5 exfat udf extcmd datetime div normal video gcry_sha1 iso9660 +gcry_sha512: crypto +password: crypto normal +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd boot video bitmap relocator mmap +mmap: +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +eval: normal +part_dvh: +lssal: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: mmap +strtoull_test: functional_test +bitmap: +ntfs: fshelp +multiboot: net linux video boot relocator mmap +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +archelp: +http: net +zfs: gzio +raid6rec: diskfilter +lsefisystab: +minix2: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +loadbios: +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +reboot: +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +efi_uga: video video_fb +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +efifwsetup: +ctz_test: functional_test +video: +cbmemc: cbtable normal terminfo +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp lzopio xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +gcry_tiger: crypto +fixvideo: +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +lzopio: crypto +video_cirrus: video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +chain: net efinet boot +cbfs: archelp +ufs2: +time: +setpci: extcmd +gptsync: disk +search_label: +setjmp: +multiboot2: linux net video boot relocator mmap acpi +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: crypto password gcry_md5 normal +play: +part_amiga: +efi_gop: video video_fb +minix: +echo: extcmd +lsefi: +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: efi_gop efi_uga video_bochs video_cirrus diff --git a/INSTALL/grub/i386-efi/morse.mod b/INSTALL/grub/i386-efi/morse.mod new file mode 100644 index 00000000..6788dba9 Binary files /dev/null and b/INSTALL/grub/i386-efi/morse.mod differ diff --git a/INSTALL/grub/i386-efi/mpi.mod b/INSTALL/grub/i386-efi/mpi.mod new file mode 100644 index 00000000..2f7b62fe Binary files /dev/null and b/INSTALL/grub/i386-efi/mpi.mod differ diff --git a/INSTALL/grub/i386-efi/msdospart.mod b/INSTALL/grub/i386-efi/msdospart.mod new file mode 100644 index 00000000..9d546338 Binary files /dev/null and b/INSTALL/grub/i386-efi/msdospart.mod differ diff --git a/INSTALL/grub/i386-efi/mul_test.mod b/INSTALL/grub/i386-efi/mul_test.mod new file mode 100644 index 00000000..39e99bfa Binary files /dev/null and b/INSTALL/grub/i386-efi/mul_test.mod differ diff --git a/INSTALL/grub/i386-efi/multiboot.mod b/INSTALL/grub/i386-efi/multiboot.mod new file mode 100644 index 00000000..12519fd4 Binary files /dev/null and b/INSTALL/grub/i386-efi/multiboot.mod differ diff --git a/INSTALL/grub/i386-efi/multiboot2.mod b/INSTALL/grub/i386-efi/multiboot2.mod new file mode 100644 index 00000000..c05719f7 Binary files /dev/null and b/INSTALL/grub/i386-efi/multiboot2.mod differ diff --git a/INSTALL/grub/i386-efi/nativedisk.mod b/INSTALL/grub/i386-efi/nativedisk.mod new file mode 100644 index 00000000..1779ad09 Binary files /dev/null and b/INSTALL/grub/i386-efi/nativedisk.mod differ diff --git a/INSTALL/grub/i386-efi/nilfs2.mod b/INSTALL/grub/i386-efi/nilfs2.mod new file mode 100644 index 00000000..4adb48c3 Binary files /dev/null and b/INSTALL/grub/i386-efi/nilfs2.mod differ diff --git a/INSTALL/grub/i386-efi/normal.mod b/INSTALL/grub/i386-efi/normal.mod new file mode 100644 index 00000000..1562ae8b Binary files /dev/null and b/INSTALL/grub/i386-efi/normal.mod differ diff --git a/INSTALL/grub/i386-efi/ntfscomp.mod b/INSTALL/grub/i386-efi/ntfscomp.mod new file mode 100644 index 00000000..020c2684 Binary files /dev/null and b/INSTALL/grub/i386-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/i386-efi/odc.mod b/INSTALL/grub/i386-efi/odc.mod new file mode 100644 index 00000000..a115affe Binary files /dev/null and b/INSTALL/grub/i386-efi/odc.mod differ diff --git a/INSTALL/grub/i386-efi/offsetio.mod b/INSTALL/grub/i386-efi/offsetio.mod new file mode 100644 index 00000000..aa681a7a Binary files /dev/null and b/INSTALL/grub/i386-efi/offsetio.mod differ diff --git a/INSTALL/grub/i386-efi/ohci.mod b/INSTALL/grub/i386-efi/ohci.mod new file mode 100644 index 00000000..f12eeca5 Binary files /dev/null and b/INSTALL/grub/i386-efi/ohci.mod differ diff --git a/INSTALL/grub/i386-efi/part_acorn.mod b/INSTALL/grub/i386-efi/part_acorn.mod new file mode 100644 index 00000000..05b0ec3d Binary files /dev/null and b/INSTALL/grub/i386-efi/part_acorn.mod differ diff --git a/INSTALL/grub/i386-efi/part_amiga.mod b/INSTALL/grub/i386-efi/part_amiga.mod new file mode 100644 index 00000000..eb4307c3 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_amiga.mod differ diff --git a/INSTALL/grub/i386-efi/part_bsd.mod b/INSTALL/grub/i386-efi/part_bsd.mod new file mode 100644 index 00000000..0b5baf28 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_bsd.mod differ diff --git a/INSTALL/grub/i386-efi/part_dfly.mod b/INSTALL/grub/i386-efi/part_dfly.mod new file mode 100644 index 00000000..6bfe671a Binary files /dev/null and b/INSTALL/grub/i386-efi/part_dfly.mod differ diff --git a/INSTALL/grub/i386-efi/part_dvh.mod b/INSTALL/grub/i386-efi/part_dvh.mod new file mode 100644 index 00000000..7f1e4389 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_dvh.mod differ diff --git a/INSTALL/grub/i386-efi/part_plan.mod b/INSTALL/grub/i386-efi/part_plan.mod new file mode 100644 index 00000000..95677425 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_plan.mod differ diff --git a/INSTALL/grub/i386-efi/part_sun.mod b/INSTALL/grub/i386-efi/part_sun.mod new file mode 100644 index 00000000..0dbb445d Binary files /dev/null and b/INSTALL/grub/i386-efi/part_sun.mod differ diff --git a/INSTALL/grub/i386-efi/part_sunpc.mod b/INSTALL/grub/i386-efi/part_sunpc.mod new file mode 100644 index 00000000..ec073466 Binary files /dev/null and b/INSTALL/grub/i386-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/i386-efi/partmap.lst b/INSTALL/grub/i386-efi/partmap.lst new file mode 100644 index 00000000..761233aa --- /dev/null +++ b/INSTALL/grub/i386-efi/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/i386-efi/parttool.lst b/INSTALL/grub/i386-efi/parttool.lst new file mode 100644 index 00000000..68b4b5c4 --- /dev/null +++ b/INSTALL/grub/i386-efi/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/i386-efi/parttool.mod b/INSTALL/grub/i386-efi/parttool.mod new file mode 100644 index 00000000..a54f0db3 Binary files /dev/null and b/INSTALL/grub/i386-efi/parttool.mod differ diff --git a/INSTALL/grub/i386-efi/password.mod b/INSTALL/grub/i386-efi/password.mod new file mode 100644 index 00000000..3111329e Binary files /dev/null and b/INSTALL/grub/i386-efi/password.mod differ diff --git a/INSTALL/grub/i386-efi/pata.mod b/INSTALL/grub/i386-efi/pata.mod new file mode 100644 index 00000000..9c145703 Binary files /dev/null and b/INSTALL/grub/i386-efi/pata.mod differ diff --git a/INSTALL/grub/i386-efi/pbkdf2_test.mod b/INSTALL/grub/i386-efi/pbkdf2_test.mod new file mode 100644 index 00000000..0c1edc4a Binary files /dev/null and b/INSTALL/grub/i386-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/i386-efi/pcidump.mod b/INSTALL/grub/i386-efi/pcidump.mod new file mode 100644 index 00000000..ac9aedfd Binary files /dev/null and b/INSTALL/grub/i386-efi/pcidump.mod differ diff --git a/INSTALL/grub/i386-efi/pgp.mod b/INSTALL/grub/i386-efi/pgp.mod new file mode 100644 index 00000000..fc272313 Binary files /dev/null and b/INSTALL/grub/i386-efi/pgp.mod differ diff --git a/INSTALL/grub/i386-efi/play.mod b/INSTALL/grub/i386-efi/play.mod new file mode 100644 index 00000000..d781f41f Binary files /dev/null and b/INSTALL/grub/i386-efi/play.mod differ diff --git a/INSTALL/grub/i386-efi/probe.mod b/INSTALL/grub/i386-efi/probe.mod new file mode 100644 index 00000000..3f2175e3 Binary files /dev/null and b/INSTALL/grub/i386-efi/probe.mod differ diff --git a/INSTALL/grub/i386-efi/procfs.mod b/INSTALL/grub/i386-efi/procfs.mod new file mode 100644 index 00000000..e30dd2bb Binary files /dev/null and b/INSTALL/grub/i386-efi/procfs.mod differ diff --git a/INSTALL/grub/i386-efi/progress.mod b/INSTALL/grub/i386-efi/progress.mod new file mode 100644 index 00000000..ee1481d8 Binary files /dev/null and b/INSTALL/grub/i386-efi/progress.mod differ diff --git a/INSTALL/grub/i386-efi/raid5rec.mod b/INSTALL/grub/i386-efi/raid5rec.mod new file mode 100644 index 00000000..f9e72d9a Binary files /dev/null and b/INSTALL/grub/i386-efi/raid5rec.mod differ diff --git a/INSTALL/grub/i386-efi/raid6rec.mod b/INSTALL/grub/i386-efi/raid6rec.mod new file mode 100644 index 00000000..3b17884e Binary files /dev/null and b/INSTALL/grub/i386-efi/raid6rec.mod differ diff --git a/INSTALL/grub/i386-efi/random.mod b/INSTALL/grub/i386-efi/random.mod new file mode 100644 index 00000000..82fd0341 Binary files /dev/null and b/INSTALL/grub/i386-efi/random.mod differ diff --git a/INSTALL/grub/i386-efi/rdmsr.mod b/INSTALL/grub/i386-efi/rdmsr.mod new file mode 100644 index 00000000..0b99c6a7 Binary files /dev/null and b/INSTALL/grub/i386-efi/rdmsr.mod differ diff --git a/INSTALL/grub/i386-efi/reiserfs.mod b/INSTALL/grub/i386-efi/reiserfs.mod new file mode 100644 index 00000000..6c85ff89 Binary files /dev/null and b/INSTALL/grub/i386-efi/reiserfs.mod differ diff --git a/INSTALL/grub/i386-efi/romfs.mod b/INSTALL/grub/i386-efi/romfs.mod new file mode 100644 index 00000000..34f5955f Binary files /dev/null and b/INSTALL/grub/i386-efi/romfs.mod differ diff --git a/INSTALL/grub/i386-efi/scsi.mod b/INSTALL/grub/i386-efi/scsi.mod new file mode 100644 index 00000000..5f958554 Binary files /dev/null and b/INSTALL/grub/i386-efi/scsi.mod differ diff --git a/INSTALL/grub/i386-efi/search_fs_file.mod b/INSTALL/grub/i386-efi/search_fs_file.mod new file mode 100644 index 00000000..10cf9376 Binary files /dev/null and b/INSTALL/grub/i386-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/i386-efi/search_fs_uuid.mod b/INSTALL/grub/i386-efi/search_fs_uuid.mod new file mode 100644 index 00000000..b8ba36ad Binary files /dev/null and b/INSTALL/grub/i386-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/i386-efi/search_label.mod b/INSTALL/grub/i386-efi/search_label.mod new file mode 100644 index 00000000..de0bf823 Binary files /dev/null and b/INSTALL/grub/i386-efi/search_label.mod differ diff --git a/INSTALL/grub/i386-efi/setjmp.mod b/INSTALL/grub/i386-efi/setjmp.mod new file mode 100644 index 00000000..2d35023b Binary files /dev/null and b/INSTALL/grub/i386-efi/setjmp.mod differ diff --git a/INSTALL/grub/i386-efi/setjmp_test.mod b/INSTALL/grub/i386-efi/setjmp_test.mod new file mode 100644 index 00000000..aa3aef3d Binary files /dev/null and b/INSTALL/grub/i386-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/i386-efi/setpci.mod b/INSTALL/grub/i386-efi/setpci.mod new file mode 100644 index 00000000..e10da067 Binary files /dev/null and b/INSTALL/grub/i386-efi/setpci.mod differ diff --git a/INSTALL/grub/i386-efi/sfs.mod b/INSTALL/grub/i386-efi/sfs.mod new file mode 100644 index 00000000..97103dee Binary files /dev/null and b/INSTALL/grub/i386-efi/sfs.mod differ diff --git a/INSTALL/grub/i386-efi/shift_test.mod b/INSTALL/grub/i386-efi/shift_test.mod new file mode 100644 index 00000000..b1628b4e Binary files /dev/null and b/INSTALL/grub/i386-efi/shift_test.mod differ diff --git a/INSTALL/grub/i386-efi/signature_test.mod b/INSTALL/grub/i386-efi/signature_test.mod new file mode 100644 index 00000000..61c5e99e Binary files /dev/null and b/INSTALL/grub/i386-efi/signature_test.mod differ diff --git a/INSTALL/grub/i386-efi/sleep_test.mod b/INSTALL/grub/i386-efi/sleep_test.mod new file mode 100644 index 00000000..0d91dd47 Binary files /dev/null and b/INSTALL/grub/i386-efi/sleep_test.mod differ diff --git a/INSTALL/grub/i386-efi/spkmodem.mod b/INSTALL/grub/i386-efi/spkmodem.mod new file mode 100644 index 00000000..ba4fe611 Binary files /dev/null and b/INSTALL/grub/i386-efi/spkmodem.mod differ diff --git a/INSTALL/grub/i386-efi/strtoull_test.mod b/INSTALL/grub/i386-efi/strtoull_test.mod new file mode 100644 index 00000000..52423291 Binary files /dev/null and b/INSTALL/grub/i386-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/i386-efi/syslinuxcfg.mod b/INSTALL/grub/i386-efi/syslinuxcfg.mod new file mode 100644 index 00000000..73c69112 Binary files /dev/null and b/INSTALL/grub/i386-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/i386-efi/terminal.lst b/INSTALL/grub/i386-efi/terminal.lst new file mode 100644 index 00000000..3c9a5a34 --- /dev/null +++ b/INSTALL/grub/i386-efi/terminal.lst @@ -0,0 +1,9 @@ +iat_keyboard: at_keyboard +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +oserial: serial +oserial_*: serial +ospkmodem: spkmodem diff --git a/INSTALL/grub/i386-efi/test_blockarg.mod b/INSTALL/grub/i386-efi/test_blockarg.mod new file mode 100644 index 00000000..d22bac43 Binary files /dev/null and b/INSTALL/grub/i386-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/i386-efi/testload.mod b/INSTALL/grub/i386-efi/testload.mod new file mode 100644 index 00000000..e053e283 Binary files /dev/null and b/INSTALL/grub/i386-efi/testload.mod differ diff --git a/INSTALL/grub/i386-efi/testspeed.mod b/INSTALL/grub/i386-efi/testspeed.mod new file mode 100644 index 00000000..dff3844a Binary files /dev/null and b/INSTALL/grub/i386-efi/testspeed.mod differ diff --git a/INSTALL/grub/i386-efi/tga.mod b/INSTALL/grub/i386-efi/tga.mod new file mode 100644 index 00000000..16523b6e Binary files /dev/null and b/INSTALL/grub/i386-efi/tga.mod differ diff --git a/INSTALL/grub/i386-efi/time.mod b/INSTALL/grub/i386-efi/time.mod new file mode 100644 index 00000000..11a3f329 Binary files /dev/null and b/INSTALL/grub/i386-efi/time.mod differ diff --git a/INSTALL/grub/i386-efi/tr.mod b/INSTALL/grub/i386-efi/tr.mod new file mode 100644 index 00000000..501de880 Binary files /dev/null and b/INSTALL/grub/i386-efi/tr.mod differ diff --git a/INSTALL/grub/i386-efi/ufs1.mod b/INSTALL/grub/i386-efi/ufs1.mod new file mode 100644 index 00000000..dc06fcab Binary files /dev/null and b/INSTALL/grub/i386-efi/ufs1.mod differ diff --git a/INSTALL/grub/i386-efi/ufs1_be.mod b/INSTALL/grub/i386-efi/ufs1_be.mod new file mode 100644 index 00000000..4371324c Binary files /dev/null and b/INSTALL/grub/i386-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/i386-efi/ufs2.mod b/INSTALL/grub/i386-efi/ufs2.mod new file mode 100644 index 00000000..a4a939b6 Binary files /dev/null and b/INSTALL/grub/i386-efi/ufs2.mod differ diff --git a/INSTALL/grub/i386-efi/uhci.mod b/INSTALL/grub/i386-efi/uhci.mod new file mode 100644 index 00000000..555a50ed Binary files /dev/null and b/INSTALL/grub/i386-efi/uhci.mod differ diff --git a/INSTALL/grub/i386-efi/usb.mod b/INSTALL/grub/i386-efi/usb.mod new file mode 100644 index 00000000..465004f7 Binary files /dev/null and b/INSTALL/grub/i386-efi/usb.mod differ diff --git a/INSTALL/grub/i386-efi/usbms.mod b/INSTALL/grub/i386-efi/usbms.mod new file mode 100644 index 00000000..9a2461fa Binary files /dev/null and b/INSTALL/grub/i386-efi/usbms.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_common.mod b/INSTALL/grub/i386-efi/usbserial_common.mod new file mode 100644 index 00000000..c492b11e Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_common.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_ftdi.mod b/INSTALL/grub/i386-efi/usbserial_ftdi.mod new file mode 100644 index 00000000..e7a9a41d Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_pl2303.mod b/INSTALL/grub/i386-efi/usbserial_pl2303.mod new file mode 100644 index 00000000..5737ced7 Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/i386-efi/usbserial_usbdebug.mod b/INSTALL/grub/i386-efi/usbserial_usbdebug.mod new file mode 100644 index 00000000..3463ad42 Binary files /dev/null and b/INSTALL/grub/i386-efi/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/i386-efi/usbtest.mod b/INSTALL/grub/i386-efi/usbtest.mod new file mode 100644 index 00000000..1399684a Binary files /dev/null and b/INSTALL/grub/i386-efi/usbtest.mod differ diff --git a/INSTALL/grub/i386-efi/verifiers.mod b/INSTALL/grub/i386-efi/verifiers.mod new file mode 100644 index 00000000..7bd45fe8 Binary files /dev/null and b/INSTALL/grub/i386-efi/verifiers.mod differ diff --git a/INSTALL/grub/i386-efi/video.lst b/INSTALL/grub/i386-efi/video.lst new file mode 100644 index 00000000..ae9ba23e --- /dev/null +++ b/INSTALL/grub/i386-efi/video.lst @@ -0,0 +1,4 @@ +efi_gop +efi_uga +video_bochs +video_cirrus diff --git a/INSTALL/grub/i386-efi/videoinfo.mod b/INSTALL/grub/i386-efi/videoinfo.mod new file mode 100644 index 00000000..39935288 Binary files /dev/null and b/INSTALL/grub/i386-efi/videoinfo.mod differ diff --git a/INSTALL/grub/i386-efi/videotest.mod b/INSTALL/grub/i386-efi/videotest.mod new file mode 100644 index 00000000..e9a71708 Binary files /dev/null and b/INSTALL/grub/i386-efi/videotest.mod differ diff --git a/INSTALL/grub/i386-efi/videotest_checksum.mod b/INSTALL/grub/i386-efi/videotest_checksum.mod new file mode 100644 index 00000000..da7e93f4 Binary files /dev/null and b/INSTALL/grub/i386-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/i386-efi/wrmsr.mod b/INSTALL/grub/i386-efi/wrmsr.mod new file mode 100644 index 00000000..776495de Binary files /dev/null and b/INSTALL/grub/i386-efi/wrmsr.mod differ diff --git a/INSTALL/grub/i386-efi/xnu.mod b/INSTALL/grub/i386-efi/xnu.mod new file mode 100644 index 00000000..6f71890e Binary files /dev/null and b/INSTALL/grub/i386-efi/xnu.mod differ diff --git a/INSTALL/grub/i386-efi/xnu_uuid.mod b/INSTALL/grub/i386-efi/xnu_uuid.mod new file mode 100644 index 00000000..ef4d7f41 Binary files /dev/null and b/INSTALL/grub/i386-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/i386-efi/xnu_uuid_test.mod b/INSTALL/grub/i386-efi/xnu_uuid_test.mod new file mode 100644 index 00000000..f01872b1 Binary files /dev/null and b/INSTALL/grub/i386-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/i386-efi/zfs.mod b/INSTALL/grub/i386-efi/zfs.mod new file mode 100644 index 00000000..0f9ee6a9 Binary files /dev/null and b/INSTALL/grub/i386-efi/zfs.mod differ diff --git a/INSTALL/grub/i386-efi/zfscrypt.mod b/INSTALL/grub/i386-efi/zfscrypt.mod new file mode 100644 index 00000000..04d5b2b1 Binary files /dev/null and b/INSTALL/grub/i386-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/i386-efi/zfsinfo.mod b/INSTALL/grub/i386-efi/zfsinfo.mod new file mode 100644 index 00000000..3013887c Binary files /dev/null and b/INSTALL/grub/i386-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/i386-efi/zstd.mod b/INSTALL/grub/i386-efi/zstd.mod new file mode 100644 index 00000000..991b61b2 Binary files /dev/null and b/INSTALL/grub/i386-efi/zstd.mod differ diff --git a/INSTALL/grub/i386-pc/acpi.mod b/INSTALL/grub/i386-pc/acpi.mod new file mode 100644 index 00000000..8768848c Binary files /dev/null and b/INSTALL/grub/i386-pc/acpi.mod differ diff --git a/INSTALL/grub/i386-pc/adler32.mod b/INSTALL/grub/i386-pc/adler32.mod new file mode 100644 index 00000000..f6b7276c Binary files /dev/null and b/INSTALL/grub/i386-pc/adler32.mod differ diff --git a/INSTALL/grub/i386-pc/affs.mod b/INSTALL/grub/i386-pc/affs.mod new file mode 100644 index 00000000..1aabc41c Binary files /dev/null and b/INSTALL/grub/i386-pc/affs.mod differ diff --git a/INSTALL/grub/i386-pc/afs.mod b/INSTALL/grub/i386-pc/afs.mod new file mode 100644 index 00000000..020612f3 Binary files /dev/null and b/INSTALL/grub/i386-pc/afs.mod differ diff --git a/INSTALL/grub/i386-pc/ahci.mod b/INSTALL/grub/i386-pc/ahci.mod new file mode 100644 index 00000000..79278035 Binary files /dev/null and b/INSTALL/grub/i386-pc/ahci.mod differ diff --git a/INSTALL/grub/i386-pc/aout.mod b/INSTALL/grub/i386-pc/aout.mod new file mode 100644 index 00000000..e775a1eb Binary files /dev/null and b/INSTALL/grub/i386-pc/aout.mod differ diff --git a/INSTALL/grub/i386-pc/archelp.mod b/INSTALL/grub/i386-pc/archelp.mod new file mode 100644 index 00000000..0aa3bb90 Binary files /dev/null and b/INSTALL/grub/i386-pc/archelp.mod differ diff --git a/INSTALL/grub/i386-pc/ata.mod b/INSTALL/grub/i386-pc/ata.mod new file mode 100644 index 00000000..10d98eda Binary files /dev/null and b/INSTALL/grub/i386-pc/ata.mod differ diff --git a/INSTALL/grub/i386-pc/backtrace.mod b/INSTALL/grub/i386-pc/backtrace.mod new file mode 100644 index 00000000..78c7fc1d Binary files /dev/null and b/INSTALL/grub/i386-pc/backtrace.mod differ diff --git a/INSTALL/grub/i386-pc/bfs.mod b/INSTALL/grub/i386-pc/bfs.mod new file mode 100644 index 00000000..07ac6456 Binary files /dev/null and b/INSTALL/grub/i386-pc/bfs.mod differ diff --git a/INSTALL/grub/i386-pc/bitmap.mod b/INSTALL/grub/i386-pc/bitmap.mod new file mode 100644 index 00000000..42404635 Binary files /dev/null and b/INSTALL/grub/i386-pc/bitmap.mod differ diff --git a/INSTALL/grub/i386-pc/bitmap_scale.mod b/INSTALL/grub/i386-pc/bitmap_scale.mod new file mode 100644 index 00000000..8b46a187 Binary files /dev/null and b/INSTALL/grub/i386-pc/bitmap_scale.mod differ diff --git a/INSTALL/grub/i386-pc/blscfg.mod b/INSTALL/grub/i386-pc/blscfg.mod new file mode 100644 index 00000000..8be07603 Binary files /dev/null and b/INSTALL/grub/i386-pc/blscfg.mod differ diff --git a/INSTALL/grub/i386-pc/boot.img b/INSTALL/grub/i386-pc/boot.img index 4b6f21c3..eedeba84 100644 Binary files a/INSTALL/grub/i386-pc/boot.img and b/INSTALL/grub/i386-pc/boot.img differ diff --git a/INSTALL/grub/i386-pc/bsd.mod b/INSTALL/grub/i386-pc/bsd.mod new file mode 100644 index 00000000..51d7358d Binary files /dev/null and b/INSTALL/grub/i386-pc/bsd.mod differ diff --git a/INSTALL/grub/i386-pc/bswap_test.mod b/INSTALL/grub/i386-pc/bswap_test.mod new file mode 100644 index 00000000..4112db95 Binary files /dev/null and b/INSTALL/grub/i386-pc/bswap_test.mod differ diff --git a/INSTALL/grub/i386-pc/btrfs.mod b/INSTALL/grub/i386-pc/btrfs.mod new file mode 100644 index 00000000..25aa06e2 Binary files /dev/null and b/INSTALL/grub/i386-pc/btrfs.mod differ diff --git a/INSTALL/grub/i386-pc/bufio.mod b/INSTALL/grub/i386-pc/bufio.mod new file mode 100644 index 00000000..73bd58e9 Binary files /dev/null and b/INSTALL/grub/i386-pc/bufio.mod differ diff --git a/INSTALL/grub/i386-pc/cat.mod b/INSTALL/grub/i386-pc/cat.mod new file mode 100644 index 00000000..4afb29f4 Binary files /dev/null and b/INSTALL/grub/i386-pc/cat.mod differ diff --git a/INSTALL/grub/i386-pc/cbfs.mod b/INSTALL/grub/i386-pc/cbfs.mod new file mode 100644 index 00000000..578ed2cd Binary files /dev/null and b/INSTALL/grub/i386-pc/cbfs.mod differ diff --git a/INSTALL/grub/i386-pc/cbls.mod b/INSTALL/grub/i386-pc/cbls.mod new file mode 100644 index 00000000..bb86e5ac Binary files /dev/null and b/INSTALL/grub/i386-pc/cbls.mod differ diff --git a/INSTALL/grub/i386-pc/cbmemc.mod b/INSTALL/grub/i386-pc/cbmemc.mod new file mode 100644 index 00000000..76253f79 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbmemc.mod differ diff --git a/INSTALL/grub/i386-pc/cbtable.mod b/INSTALL/grub/i386-pc/cbtable.mod new file mode 100644 index 00000000..47ebd776 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbtable.mod differ diff --git a/INSTALL/grub/i386-pc/cbtime.mod b/INSTALL/grub/i386-pc/cbtime.mod new file mode 100644 index 00000000..fde0d472 Binary files /dev/null and b/INSTALL/grub/i386-pc/cbtime.mod differ diff --git a/INSTALL/grub/i386-pc/cmdline_cat_test.mod b/INSTALL/grub/i386-pc/cmdline_cat_test.mod new file mode 100644 index 00000000..e22586dd Binary files /dev/null and b/INSTALL/grub/i386-pc/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/i386-pc/cmosdump.mod b/INSTALL/grub/i386-pc/cmosdump.mod new file mode 100644 index 00000000..23d4b7d8 Binary files /dev/null and b/INSTALL/grub/i386-pc/cmosdump.mod differ diff --git a/INSTALL/grub/i386-pc/cmostest.mod b/INSTALL/grub/i386-pc/cmostest.mod new file mode 100644 index 00000000..d94f1c1a Binary files /dev/null and b/INSTALL/grub/i386-pc/cmostest.mod differ diff --git a/INSTALL/grub/i386-pc/cmp.mod b/INSTALL/grub/i386-pc/cmp.mod new file mode 100644 index 00000000..d5155d7e Binary files /dev/null and b/INSTALL/grub/i386-pc/cmp.mod differ diff --git a/INSTALL/grub/i386-pc/cmp_test.mod b/INSTALL/grub/i386-pc/cmp_test.mod new file mode 100644 index 00000000..f9a14230 Binary files /dev/null and b/INSTALL/grub/i386-pc/cmp_test.mod differ diff --git a/INSTALL/grub/i386-pc/command.lst b/INSTALL/grub/i386-pc/command.lst new file mode 100644 index 00000000..fdc541a5 --- /dev/null +++ b/INSTALL/grub/i386-pc/command.lst @@ -0,0 +1,211 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*bls_import: blscfg +*blscfg: blscfg +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*drivemap: drivemap +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*gettext: gettext +*halt: halt +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*plan9: plan9 +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*sendkey: sendkey +*serial: serial +*set_keyboard_layout: setkey +*setkey: setkey +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmosclean: cmostest +cmosdump: cmosdump +cmosset: cmostest +cmostest: cmostest +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +efiemu_loadcore: efiemu +efiemu_prepare: efiemu +efiemu_unload: efiemu +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +false: true +freedos: freedos +gdbstub: gdb +gdbstub_break: gdb +gdbstub_stop: gdb +gptsync: gptsync +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +initrdefi: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +linuxefi: linux +list_trusted: pgp +loadfont: font +lsapm: lsapm +lscoreboot: cbls +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +ntldr: ntldr +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +pxechainloader: pxechain +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +truecrypt: truecrypt +usb: usbtest +vbeinfo: videoinfo +vbetest: videotest +videoinfo: videoinfo +videotest: videotest +vt_img_extra_initrd_append: linux +vt_img_extra_initrd_reset: linux +vt_set_boot_opt: linux +vt_unset_boot_opt: linux +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/i386-pc/core.img b/INSTALL/grub/i386-pc/core.img index fa74b5c9..727246ff 100644 Binary files a/INSTALL/grub/i386-pc/core.img and b/INSTALL/grub/i386-pc/core.img differ diff --git a/INSTALL/grub/i386-pc/cpio.mod b/INSTALL/grub/i386-pc/cpio.mod new file mode 100644 index 00000000..550b2af1 Binary files /dev/null and b/INSTALL/grub/i386-pc/cpio.mod differ diff --git a/INSTALL/grub/i386-pc/cpio_be.mod b/INSTALL/grub/i386-pc/cpio_be.mod new file mode 100644 index 00000000..42776b17 Binary files /dev/null and b/INSTALL/grub/i386-pc/cpio_be.mod differ diff --git a/INSTALL/grub/i386-pc/cpuid.mod b/INSTALL/grub/i386-pc/cpuid.mod new file mode 100644 index 00000000..cc4471aa Binary files /dev/null and b/INSTALL/grub/i386-pc/cpuid.mod differ diff --git a/INSTALL/grub/i386-pc/crc64.mod b/INSTALL/grub/i386-pc/crc64.mod new file mode 100644 index 00000000..441fc4a6 Binary files /dev/null and b/INSTALL/grub/i386-pc/crc64.mod differ diff --git a/INSTALL/grub/i386-pc/crypto.lst b/INSTALL/grub/i386-pc/crypto.lst new file mode 100644 index 00000000..77d9efc0 --- /dev/null +++ b/INSTALL/grub/i386-pc/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/i386-pc/crypto.mod b/INSTALL/grub/i386-pc/crypto.mod new file mode 100644 index 00000000..d9914aed Binary files /dev/null and b/INSTALL/grub/i386-pc/crypto.mod differ diff --git a/INSTALL/grub/i386-pc/cryptodisk.mod b/INSTALL/grub/i386-pc/cryptodisk.mod new file mode 100644 index 00000000..ee52348e Binary files /dev/null and b/INSTALL/grub/i386-pc/cryptodisk.mod differ diff --git a/INSTALL/grub/i386-pc/cs5536.mod b/INSTALL/grub/i386-pc/cs5536.mod new file mode 100644 index 00000000..c8fdce8e Binary files /dev/null and b/INSTALL/grub/i386-pc/cs5536.mod differ diff --git a/INSTALL/grub/i386-pc/ctz_test.mod b/INSTALL/grub/i386-pc/ctz_test.mod new file mode 100644 index 00000000..232ffa80 Binary files /dev/null and b/INSTALL/grub/i386-pc/ctz_test.mod differ diff --git a/INSTALL/grub/i386-pc/datehook.mod b/INSTALL/grub/i386-pc/datehook.mod new file mode 100644 index 00000000..a42ca57a Binary files /dev/null and b/INSTALL/grub/i386-pc/datehook.mod differ diff --git a/INSTALL/grub/i386-pc/datetime.mod b/INSTALL/grub/i386-pc/datetime.mod new file mode 100644 index 00000000..5de1ad49 Binary files /dev/null and b/INSTALL/grub/i386-pc/datetime.mod differ diff --git a/INSTALL/grub/i386-pc/diskfilter.mod b/INSTALL/grub/i386-pc/diskfilter.mod new file mode 100644 index 00000000..cf81580f Binary files /dev/null and b/INSTALL/grub/i386-pc/diskfilter.mod differ diff --git a/INSTALL/grub/i386-pc/div.mod b/INSTALL/grub/i386-pc/div.mod new file mode 100644 index 00000000..f9a5d9d4 Binary files /dev/null and b/INSTALL/grub/i386-pc/div.mod differ diff --git a/INSTALL/grub/i386-pc/div_test.mod b/INSTALL/grub/i386-pc/div_test.mod new file mode 100644 index 00000000..4ec3622a Binary files /dev/null and b/INSTALL/grub/i386-pc/div_test.mod differ diff --git a/INSTALL/grub/i386-pc/dm_nv.mod b/INSTALL/grub/i386-pc/dm_nv.mod new file mode 100644 index 00000000..8b48ad51 Binary files /dev/null and b/INSTALL/grub/i386-pc/dm_nv.mod differ diff --git a/INSTALL/grub/i386-pc/efiemu.mod b/INSTALL/grub/i386-pc/efiemu.mod new file mode 100644 index 00000000..88fd5f0a Binary files /dev/null and b/INSTALL/grub/i386-pc/efiemu.mod differ diff --git a/INSTALL/grub/i386-pc/ehci.mod b/INSTALL/grub/i386-pc/ehci.mod new file mode 100644 index 00000000..17429f59 Binary files /dev/null and b/INSTALL/grub/i386-pc/ehci.mod differ diff --git a/INSTALL/grub/i386-pc/eval.mod b/INSTALL/grub/i386-pc/eval.mod new file mode 100644 index 00000000..417bb915 Binary files /dev/null and b/INSTALL/grub/i386-pc/eval.mod differ diff --git a/INSTALL/grub/i386-pc/exfctest.mod b/INSTALL/grub/i386-pc/exfctest.mod new file mode 100644 index 00000000..9cfe4923 Binary files /dev/null and b/INSTALL/grub/i386-pc/exfctest.mod differ diff --git a/INSTALL/grub/i386-pc/f2fs.mod b/INSTALL/grub/i386-pc/f2fs.mod new file mode 100644 index 00000000..f0fe6fd1 Binary files /dev/null and b/INSTALL/grub/i386-pc/f2fs.mod differ diff --git a/INSTALL/grub/i386-pc/fdt.lst b/INSTALL/grub/i386-pc/fdt.lst new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL/grub/i386-pc/freedos.mod b/INSTALL/grub/i386-pc/freedos.mod new file mode 100644 index 00000000..08cabd0e Binary files /dev/null and b/INSTALL/grub/i386-pc/freedos.mod differ diff --git a/INSTALL/grub/i386-pc/fs.lst b/INSTALL/grub/i386-pc/fs.lst new file mode 100644 index 00000000..0acd240b --- /dev/null +++ b/INSTALL/grub/i386-pc/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/i386-pc/fshelp.mod b/INSTALL/grub/i386-pc/fshelp.mod new file mode 100644 index 00000000..e986d45a Binary files /dev/null and b/INSTALL/grub/i386-pc/fshelp.mod differ diff --git a/INSTALL/grub/i386-pc/functional_test.mod b/INSTALL/grub/i386-pc/functional_test.mod new file mode 100644 index 00000000..2b498463 Binary files /dev/null and b/INSTALL/grub/i386-pc/functional_test.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_arcfour.mod b/INSTALL/grub/i386-pc/gcry_arcfour.mod new file mode 100644 index 00000000..c49de7a0 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_arcfour.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_blowfish.mod b/INSTALL/grub/i386-pc/gcry_blowfish.mod new file mode 100644 index 00000000..83285b38 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_blowfish.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_camellia.mod b/INSTALL/grub/i386-pc/gcry_camellia.mod new file mode 100644 index 00000000..337637e6 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_camellia.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_cast5.mod b/INSTALL/grub/i386-pc/gcry_cast5.mod new file mode 100644 index 00000000..8a742756 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_cast5.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_crc.mod b/INSTALL/grub/i386-pc/gcry_crc.mod new file mode 100644 index 00000000..d3f30c44 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_crc.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_des.mod b/INSTALL/grub/i386-pc/gcry_des.mod new file mode 100644 index 00000000..2b1f3dee Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_des.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_dsa.mod b/INSTALL/grub/i386-pc/gcry_dsa.mod new file mode 100644 index 00000000..ab382c86 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_dsa.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_idea.mod b/INSTALL/grub/i386-pc/gcry_idea.mod new file mode 100644 index 00000000..b939c0dd Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_idea.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_md4.mod b/INSTALL/grub/i386-pc/gcry_md4.mod new file mode 100644 index 00000000..16f78faf Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_md4.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rfc2268.mod b/INSTALL/grub/i386-pc/gcry_rfc2268.mod new file mode 100644 index 00000000..db1c2b79 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rijndael.mod b/INSTALL/grub/i386-pc/gcry_rijndael.mod new file mode 100644 index 00000000..6a93d1b3 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rijndael.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rmd160.mod b/INSTALL/grub/i386-pc/gcry_rmd160.mod new file mode 100644 index 00000000..24b37c5c Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rmd160.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_rsa.mod b/INSTALL/grub/i386-pc/gcry_rsa.mod new file mode 100644 index 00000000..11dc6964 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_rsa.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_seed.mod b/INSTALL/grub/i386-pc/gcry_seed.mod new file mode 100644 index 00000000..157c74cc Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_seed.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_serpent.mod b/INSTALL/grub/i386-pc/gcry_serpent.mod new file mode 100644 index 00000000..8ed63641 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_serpent.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha1.mod b/INSTALL/grub/i386-pc/gcry_sha1.mod new file mode 100644 index 00000000..855afd66 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha1.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha256.mod b/INSTALL/grub/i386-pc/gcry_sha256.mod new file mode 100644 index 00000000..fc269cc4 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha256.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_sha512.mod b/INSTALL/grub/i386-pc/gcry_sha512.mod new file mode 100644 index 00000000..03b48b50 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_sha512.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_tiger.mod b/INSTALL/grub/i386-pc/gcry_tiger.mod new file mode 100644 index 00000000..a91e3152 Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_tiger.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_twofish.mod b/INSTALL/grub/i386-pc/gcry_twofish.mod new file mode 100644 index 00000000..8b8efaef Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_twofish.mod differ diff --git a/INSTALL/grub/i386-pc/gcry_whirlpool.mod b/INSTALL/grub/i386-pc/gcry_whirlpool.mod new file mode 100644 index 00000000..7918540b Binary files /dev/null and b/INSTALL/grub/i386-pc/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/i386-pc/gdb.mod b/INSTALL/grub/i386-pc/gdb.mod new file mode 100644 index 00000000..fa88b7ce Binary files /dev/null and b/INSTALL/grub/i386-pc/gdb.mod differ diff --git a/INSTALL/grub/i386-pc/geli.mod b/INSTALL/grub/i386-pc/geli.mod new file mode 100644 index 00000000..3a59c1ae Binary files /dev/null and b/INSTALL/grub/i386-pc/geli.mod differ diff --git a/INSTALL/grub/i386-pc/gfxterm_menu.mod b/INSTALL/grub/i386-pc/gfxterm_menu.mod new file mode 100644 index 00000000..a6aba54a Binary files /dev/null and b/INSTALL/grub/i386-pc/gfxterm_menu.mod differ diff --git a/INSTALL/grub/i386-pc/gptsync.mod b/INSTALL/grub/i386-pc/gptsync.mod new file mode 100644 index 00000000..6c75de0d Binary files /dev/null and b/INSTALL/grub/i386-pc/gptsync.mod differ diff --git a/INSTALL/grub/i386-pc/hdparm.mod b/INSTALL/grub/i386-pc/hdparm.mod new file mode 100644 index 00000000..7cecce6b Binary files /dev/null and b/INSTALL/grub/i386-pc/hdparm.mod differ diff --git a/INSTALL/grub/i386-pc/hello.mod b/INSTALL/grub/i386-pc/hello.mod new file mode 100644 index 00000000..14fd0951 Binary files /dev/null and b/INSTALL/grub/i386-pc/hello.mod differ diff --git a/INSTALL/grub/i386-pc/hexdump.mod b/INSTALL/grub/i386-pc/hexdump.mod new file mode 100644 index 00000000..7ccea176 Binary files /dev/null and b/INSTALL/grub/i386-pc/hexdump.mod differ diff --git a/INSTALL/grub/i386-pc/hfs.mod b/INSTALL/grub/i386-pc/hfs.mod new file mode 100644 index 00000000..eb1134c6 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfs.mod differ diff --git a/INSTALL/grub/i386-pc/hfsplus.mod b/INSTALL/grub/i386-pc/hfsplus.mod new file mode 100644 index 00000000..f07eedb4 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfsplus.mod differ diff --git a/INSTALL/grub/i386-pc/hfspluscomp.mod b/INSTALL/grub/i386-pc/hfspluscomp.mod new file mode 100644 index 00000000..b2b40870 Binary files /dev/null and b/INSTALL/grub/i386-pc/hfspluscomp.mod differ diff --git a/INSTALL/grub/i386-pc/iorw.mod b/INSTALL/grub/i386-pc/iorw.mod new file mode 100644 index 00000000..8b636058 Binary files /dev/null and b/INSTALL/grub/i386-pc/iorw.mod differ diff --git a/INSTALL/grub/i386-pc/jfs.mod b/INSTALL/grub/i386-pc/jfs.mod new file mode 100644 index 00000000..1dbc2684 Binary files /dev/null and b/INSTALL/grub/i386-pc/jfs.mod differ diff --git a/INSTALL/grub/i386-pc/keylayouts.mod b/INSTALL/grub/i386-pc/keylayouts.mod new file mode 100644 index 00000000..50d81834 Binary files /dev/null and b/INSTALL/grub/i386-pc/keylayouts.mod differ diff --git a/INSTALL/grub/i386-pc/keystatus.mod b/INSTALL/grub/i386-pc/keystatus.mod new file mode 100644 index 00000000..8b5088a3 Binary files /dev/null and b/INSTALL/grub/i386-pc/keystatus.mod differ diff --git a/INSTALL/grub/i386-pc/ldm.mod b/INSTALL/grub/i386-pc/ldm.mod new file mode 100644 index 00000000..f2993156 Binary files /dev/null and b/INSTALL/grub/i386-pc/ldm.mod differ diff --git a/INSTALL/grub/i386-pc/legacy_password_test.mod b/INSTALL/grub/i386-pc/legacy_password_test.mod new file mode 100644 index 00000000..b5c58fa1 Binary files /dev/null and b/INSTALL/grub/i386-pc/legacy_password_test.mod differ diff --git a/INSTALL/grub/i386-pc/legacycfg.mod b/INSTALL/grub/i386-pc/legacycfg.mod new file mode 100644 index 00000000..b910f873 Binary files /dev/null and b/INSTALL/grub/i386-pc/legacycfg.mod differ diff --git a/INSTALL/grub/i386-pc/loadenv.mod b/INSTALL/grub/i386-pc/loadenv.mod new file mode 100644 index 00000000..683cd904 Binary files /dev/null and b/INSTALL/grub/i386-pc/loadenv.mod differ diff --git a/INSTALL/grub/i386-pc/lsacpi.mod b/INSTALL/grub/i386-pc/lsacpi.mod new file mode 100644 index 00000000..7e94483f Binary files /dev/null and b/INSTALL/grub/i386-pc/lsacpi.mod differ diff --git a/INSTALL/grub/i386-pc/lsapm.mod b/INSTALL/grub/i386-pc/lsapm.mod new file mode 100644 index 00000000..5a053d70 Binary files /dev/null and b/INSTALL/grub/i386-pc/lsapm.mod differ diff --git a/INSTALL/grub/i386-pc/lsmmap.mod b/INSTALL/grub/i386-pc/lsmmap.mod new file mode 100644 index 00000000..683ecfe8 Binary files /dev/null and b/INSTALL/grub/i386-pc/lsmmap.mod differ diff --git a/INSTALL/grub/i386-pc/luks.mod b/INSTALL/grub/i386-pc/luks.mod new file mode 100644 index 00000000..9c18afa6 Binary files /dev/null and b/INSTALL/grub/i386-pc/luks.mod differ diff --git a/INSTALL/grub/i386-pc/lvm.mod b/INSTALL/grub/i386-pc/lvm.mod new file mode 100644 index 00000000..10c1267b Binary files /dev/null and b/INSTALL/grub/i386-pc/lvm.mod differ diff --git a/INSTALL/grub/i386-pc/macbless.mod b/INSTALL/grub/i386-pc/macbless.mod new file mode 100644 index 00000000..c7ed444b Binary files /dev/null and b/INSTALL/grub/i386-pc/macbless.mod differ diff --git a/INSTALL/grub/i386-pc/mda_text.mod b/INSTALL/grub/i386-pc/mda_text.mod new file mode 100644 index 00000000..8f343cc6 Binary files /dev/null and b/INSTALL/grub/i386-pc/mda_text.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid09.mod b/INSTALL/grub/i386-pc/mdraid09.mod new file mode 100644 index 00000000..ba29a59c Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid09.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid09_be.mod b/INSTALL/grub/i386-pc/mdraid09_be.mod new file mode 100644 index 00000000..f53e40f6 Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid09_be.mod differ diff --git a/INSTALL/grub/i386-pc/mdraid1x.mod b/INSTALL/grub/i386-pc/mdraid1x.mod new file mode 100644 index 00000000..c00a9af0 Binary files /dev/null and b/INSTALL/grub/i386-pc/mdraid1x.mod differ diff --git a/INSTALL/grub/i386-pc/memdisk.mod b/INSTALL/grub/i386-pc/memdisk.mod new file mode 100644 index 00000000..83aaf1b9 Binary files /dev/null and b/INSTALL/grub/i386-pc/memdisk.mod differ diff --git a/INSTALL/grub/i386-pc/memrw.mod b/INSTALL/grub/i386-pc/memrw.mod new file mode 100644 index 00000000..db9ae48d Binary files /dev/null and b/INSTALL/grub/i386-pc/memrw.mod differ diff --git a/INSTALL/grub/i386-pc/minix.mod b/INSTALL/grub/i386-pc/minix.mod new file mode 100644 index 00000000..87477bff Binary files /dev/null and b/INSTALL/grub/i386-pc/minix.mod differ diff --git a/INSTALL/grub/i386-pc/minix2.mod b/INSTALL/grub/i386-pc/minix2.mod new file mode 100644 index 00000000..01d2f609 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix2.mod differ diff --git a/INSTALL/grub/i386-pc/minix2_be.mod b/INSTALL/grub/i386-pc/minix2_be.mod new file mode 100644 index 00000000..260e1e7b Binary files /dev/null and b/INSTALL/grub/i386-pc/minix2_be.mod differ diff --git a/INSTALL/grub/i386-pc/minix3.mod b/INSTALL/grub/i386-pc/minix3.mod new file mode 100644 index 00000000..256f5d71 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix3.mod differ diff --git a/INSTALL/grub/i386-pc/minix3_be.mod b/INSTALL/grub/i386-pc/minix3_be.mod new file mode 100644 index 00000000..7212cb60 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix3_be.mod differ diff --git a/INSTALL/grub/i386-pc/minix_be.mod b/INSTALL/grub/i386-pc/minix_be.mod new file mode 100644 index 00000000..cf7f0462 Binary files /dev/null and b/INSTALL/grub/i386-pc/minix_be.mod differ diff --git a/INSTALL/grub/i386-pc/mmap.mod b/INSTALL/grub/i386-pc/mmap.mod new file mode 100644 index 00000000..f8b05f30 Binary files /dev/null and b/INSTALL/grub/i386-pc/mmap.mod differ diff --git a/INSTALL/grub/i386-pc/moddep.lst b/INSTALL/grub/i386-pc/moddep.lst new file mode 100644 index 00000000..ce643787 --- /dev/null +++ b/INSTALL/grub/i386-pc/moddep.lst @@ -0,0 +1,273 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +setkey: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +aout: +gcry_arcfour: crypto +vga_text: +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd pci +bsd: elf serial crypto gcry_md5 verifiers extcmd vbe aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot pci +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +vga: video video_fb +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +disk: +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +pxechain: pxe video boot relocator +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump acpi +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: pci +halt: extcmd acpi +gdb: serial backtrace +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: ventoy verifiers normal vbe video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +plan9: verifiers extcmd boot video relocator +sendkey: extcmd boot +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: pci video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +blscfg: extcmd normal +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb pci +pata: ata pci +mul_test: functional_test +adler32: crypto +terminal: +div: +ehci: cs5536 usb boot pci +crypto: +part_bsd: part_msdos +cs5536: pci +biosdisk: +ventoy: elf fshelp ext2 btrfs font crypto gcry_md5 exfat udf datetime div extcmd normal video gcry_sha1 iso9660 acpi +lsapm: +gcry_sha512: crypto +password: crypto normal +efiemu: gcry_crc crypto cpuid acpi +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd video bitmap boot relocator efiemu mmap +mmap: boot +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +cmostest: +eval: normal +part_dvh: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +drivemap: extcmd boot mmap +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: +strtoull_test: functional_test +bitmap: +vbe: video video_fb +ntfs: fshelp +multiboot: net linux vbe video boot relocator mmap lsapm +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +truecrypt: video boot relocator gzio mmap +archelp: +ntldr: chain boot video relocator +http: net +zfs: gzio +raid6rec: diskfilter +minix2: +mda_text: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +reboot: relocator +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +ctz_test: functional_test +video: +pci: +cbmemc: cbtable normal terminfo +cmosdump: +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp lzopio xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +pxe: net boot +gcry_tiger: crypto +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd pci +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +lzopio: crypto +video_cirrus: pci video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot pci +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +cbfs: archelp +chain: video boot relocator +ufs2: +time: +setpci: extcmd pci +gptsync: disk +freedos: chain boot video relocator +search_label: +setjmp: +multiboot2: linux net vbe boot video relocator mmap lsapm acpi +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: linux crypto password gcry_md5 normal +play: +part_amiga: +minix: +echo: extcmd +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: vbe vga video_bochs video_cirrus diff --git a/INSTALL/grub/i386-pc/morse.mod b/INSTALL/grub/i386-pc/morse.mod new file mode 100644 index 00000000..b482e26b Binary files /dev/null and b/INSTALL/grub/i386-pc/morse.mod differ diff --git a/INSTALL/grub/i386-pc/mpi.mod b/INSTALL/grub/i386-pc/mpi.mod new file mode 100644 index 00000000..0f9ec718 Binary files /dev/null and b/INSTALL/grub/i386-pc/mpi.mod differ diff --git a/INSTALL/grub/i386-pc/msdospart.mod b/INSTALL/grub/i386-pc/msdospart.mod new file mode 100644 index 00000000..3c9d393c Binary files /dev/null and b/INSTALL/grub/i386-pc/msdospart.mod differ diff --git a/INSTALL/grub/i386-pc/mul_test.mod b/INSTALL/grub/i386-pc/mul_test.mod new file mode 100644 index 00000000..d86701a9 Binary files /dev/null and b/INSTALL/grub/i386-pc/mul_test.mod differ diff --git a/INSTALL/grub/i386-pc/multiboot.mod b/INSTALL/grub/i386-pc/multiboot.mod new file mode 100644 index 00000000..0547a54d Binary files /dev/null and b/INSTALL/grub/i386-pc/multiboot.mod differ diff --git a/INSTALL/grub/i386-pc/multiboot2.mod b/INSTALL/grub/i386-pc/multiboot2.mod new file mode 100644 index 00000000..a4879c75 Binary files /dev/null and b/INSTALL/grub/i386-pc/multiboot2.mod differ diff --git a/INSTALL/grub/i386-pc/nativedisk.mod b/INSTALL/grub/i386-pc/nativedisk.mod new file mode 100644 index 00000000..df1a07df Binary files /dev/null and b/INSTALL/grub/i386-pc/nativedisk.mod differ diff --git a/INSTALL/grub/i386-pc/net.mod b/INSTALL/grub/i386-pc/net.mod new file mode 100644 index 00000000..33752703 Binary files /dev/null and b/INSTALL/grub/i386-pc/net.mod differ diff --git a/INSTALL/grub/i386-pc/newc.mod b/INSTALL/grub/i386-pc/newc.mod new file mode 100644 index 00000000..a693778f Binary files /dev/null and b/INSTALL/grub/i386-pc/newc.mod differ diff --git a/INSTALL/grub/i386-pc/nilfs2.mod b/INSTALL/grub/i386-pc/nilfs2.mod new file mode 100644 index 00000000..3d2b1387 Binary files /dev/null and b/INSTALL/grub/i386-pc/nilfs2.mod differ diff --git a/INSTALL/grub/i386-pc/ntfscomp.mod b/INSTALL/grub/i386-pc/ntfscomp.mod new file mode 100644 index 00000000..5d0cbc7c Binary files /dev/null and b/INSTALL/grub/i386-pc/ntfscomp.mod differ diff --git a/INSTALL/grub/i386-pc/odc.mod b/INSTALL/grub/i386-pc/odc.mod new file mode 100644 index 00000000..bf6ef93f Binary files /dev/null and b/INSTALL/grub/i386-pc/odc.mod differ diff --git a/INSTALL/grub/i386-pc/ohci.mod b/INSTALL/grub/i386-pc/ohci.mod new file mode 100644 index 00000000..52060546 Binary files /dev/null and b/INSTALL/grub/i386-pc/ohci.mod differ diff --git a/INSTALL/grub/i386-pc/part_acorn.mod b/INSTALL/grub/i386-pc/part_acorn.mod new file mode 100644 index 00000000..3fe82b0c Binary files /dev/null and b/INSTALL/grub/i386-pc/part_acorn.mod differ diff --git a/INSTALL/grub/i386-pc/part_amiga.mod b/INSTALL/grub/i386-pc/part_amiga.mod new file mode 100644 index 00000000..a8411865 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_amiga.mod differ diff --git a/INSTALL/grub/i386-pc/part_apple.mod b/INSTALL/grub/i386-pc/part_apple.mod new file mode 100644 index 00000000..a30a0a09 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_apple.mod differ diff --git a/INSTALL/grub/i386-pc/part_bsd.mod b/INSTALL/grub/i386-pc/part_bsd.mod new file mode 100644 index 00000000..9c660b8f Binary files /dev/null and b/INSTALL/grub/i386-pc/part_bsd.mod differ diff --git a/INSTALL/grub/i386-pc/part_dfly.mod b/INSTALL/grub/i386-pc/part_dfly.mod new file mode 100644 index 00000000..d59ec333 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_dfly.mod differ diff --git a/INSTALL/grub/i386-pc/part_dvh.mod b/INSTALL/grub/i386-pc/part_dvh.mod new file mode 100644 index 00000000..21b6fec9 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_dvh.mod differ diff --git a/INSTALL/grub/i386-pc/part_plan.mod b/INSTALL/grub/i386-pc/part_plan.mod new file mode 100644 index 00000000..d074510b Binary files /dev/null and b/INSTALL/grub/i386-pc/part_plan.mod differ diff --git a/INSTALL/grub/i386-pc/part_sun.mod b/INSTALL/grub/i386-pc/part_sun.mod new file mode 100644 index 00000000..81edb5e0 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_sun.mod differ diff --git a/INSTALL/grub/i386-pc/part_sunpc.mod b/INSTALL/grub/i386-pc/part_sunpc.mod new file mode 100644 index 00000000..5c649b65 Binary files /dev/null and b/INSTALL/grub/i386-pc/part_sunpc.mod differ diff --git a/INSTALL/grub/i386-pc/partmap.lst b/INSTALL/grub/i386-pc/partmap.lst new file mode 100644 index 00000000..761233aa --- /dev/null +++ b/INSTALL/grub/i386-pc/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/i386-pc/parttool.lst b/INSTALL/grub/i386-pc/parttool.lst new file mode 100644 index 00000000..68b4b5c4 --- /dev/null +++ b/INSTALL/grub/i386-pc/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/i386-pc/parttool.mod b/INSTALL/grub/i386-pc/parttool.mod new file mode 100644 index 00000000..44ea3933 Binary files /dev/null and b/INSTALL/grub/i386-pc/parttool.mod differ diff --git a/INSTALL/grub/i386-pc/password.mod b/INSTALL/grub/i386-pc/password.mod new file mode 100644 index 00000000..783c3293 Binary files /dev/null and b/INSTALL/grub/i386-pc/password.mod differ diff --git a/INSTALL/grub/i386-pc/pata.mod b/INSTALL/grub/i386-pc/pata.mod new file mode 100644 index 00000000..0f8a55e0 Binary files /dev/null and b/INSTALL/grub/i386-pc/pata.mod differ diff --git a/INSTALL/grub/i386-pc/pbkdf2.mod b/INSTALL/grub/i386-pc/pbkdf2.mod new file mode 100644 index 00000000..84f05eaf Binary files /dev/null and b/INSTALL/grub/i386-pc/pbkdf2.mod differ diff --git a/INSTALL/grub/i386-pc/pbkdf2_test.mod b/INSTALL/grub/i386-pc/pbkdf2_test.mod new file mode 100644 index 00000000..a204632c Binary files /dev/null and b/INSTALL/grub/i386-pc/pbkdf2_test.mod differ diff --git a/INSTALL/grub/i386-pc/pcidump.mod b/INSTALL/grub/i386-pc/pcidump.mod new file mode 100644 index 00000000..66c16493 Binary files /dev/null and b/INSTALL/grub/i386-pc/pcidump.mod differ diff --git a/INSTALL/grub/i386-pc/pgp.mod b/INSTALL/grub/i386-pc/pgp.mod new file mode 100644 index 00000000..3270fff7 Binary files /dev/null and b/INSTALL/grub/i386-pc/pgp.mod differ diff --git a/INSTALL/grub/i386-pc/plan9.mod b/INSTALL/grub/i386-pc/plan9.mod new file mode 100644 index 00000000..4845df34 Binary files /dev/null and b/INSTALL/grub/i386-pc/plan9.mod differ diff --git a/INSTALL/grub/i386-pc/play.mod b/INSTALL/grub/i386-pc/play.mod new file mode 100644 index 00000000..9317d39f Binary files /dev/null and b/INSTALL/grub/i386-pc/play.mod differ diff --git a/INSTALL/grub/i386-pc/priority_queue.mod b/INSTALL/grub/i386-pc/priority_queue.mod new file mode 100644 index 00000000..4a1e167c Binary files /dev/null and b/INSTALL/grub/i386-pc/priority_queue.mod differ diff --git a/INSTALL/grub/i386-pc/probe.mod b/INSTALL/grub/i386-pc/probe.mod new file mode 100644 index 00000000..f880f85c Binary files /dev/null and b/INSTALL/grub/i386-pc/probe.mod differ diff --git a/INSTALL/grub/i386-pc/procfs.mod b/INSTALL/grub/i386-pc/procfs.mod new file mode 100644 index 00000000..a0e20ec4 Binary files /dev/null and b/INSTALL/grub/i386-pc/procfs.mod differ diff --git a/INSTALL/grub/i386-pc/progress.mod b/INSTALL/grub/i386-pc/progress.mod new file mode 100644 index 00000000..67dd96e8 Binary files /dev/null and b/INSTALL/grub/i386-pc/progress.mod differ diff --git a/INSTALL/grub/i386-pc/pxe.mod b/INSTALL/grub/i386-pc/pxe.mod new file mode 100644 index 00000000..1795ffda Binary files /dev/null and b/INSTALL/grub/i386-pc/pxe.mod differ diff --git a/INSTALL/grub/i386-pc/pxechain.mod b/INSTALL/grub/i386-pc/pxechain.mod new file mode 100644 index 00000000..2a1bc6af Binary files /dev/null and b/INSTALL/grub/i386-pc/pxechain.mod differ diff --git a/INSTALL/grub/i386-pc/raid5rec.mod b/INSTALL/grub/i386-pc/raid5rec.mod new file mode 100644 index 00000000..c31877f0 Binary files /dev/null and b/INSTALL/grub/i386-pc/raid5rec.mod differ diff --git a/INSTALL/grub/i386-pc/raid6rec.mod b/INSTALL/grub/i386-pc/raid6rec.mod new file mode 100644 index 00000000..f16634f6 Binary files /dev/null and b/INSTALL/grub/i386-pc/raid6rec.mod differ diff --git a/INSTALL/grub/i386-pc/random.mod b/INSTALL/grub/i386-pc/random.mod new file mode 100644 index 00000000..e15beb77 Binary files /dev/null and b/INSTALL/grub/i386-pc/random.mod differ diff --git a/INSTALL/grub/i386-pc/rdmsr.mod b/INSTALL/grub/i386-pc/rdmsr.mod new file mode 100644 index 00000000..02db1169 Binary files /dev/null and b/INSTALL/grub/i386-pc/rdmsr.mod differ diff --git a/INSTALL/grub/i386-pc/reiserfs.mod b/INSTALL/grub/i386-pc/reiserfs.mod new file mode 100644 index 00000000..c51d8f63 Binary files /dev/null and b/INSTALL/grub/i386-pc/reiserfs.mod differ diff --git a/INSTALL/grub/i386-pc/relocator.mod b/INSTALL/grub/i386-pc/relocator.mod new file mode 100644 index 00000000..3f1ebdc3 Binary files /dev/null and b/INSTALL/grub/i386-pc/relocator.mod differ diff --git a/INSTALL/grub/i386-pc/romfs.mod b/INSTALL/grub/i386-pc/romfs.mod new file mode 100644 index 00000000..d420e236 Binary files /dev/null and b/INSTALL/grub/i386-pc/romfs.mod differ diff --git a/INSTALL/grub/i386-pc/scsi.mod b/INSTALL/grub/i386-pc/scsi.mod new file mode 100644 index 00000000..e764bcd9 Binary files /dev/null and b/INSTALL/grub/i386-pc/scsi.mod differ diff --git a/INSTALL/grub/i386-pc/search_fs_file.mod b/INSTALL/grub/i386-pc/search_fs_file.mod new file mode 100644 index 00000000..65489245 Binary files /dev/null and b/INSTALL/grub/i386-pc/search_fs_file.mod differ diff --git a/INSTALL/grub/i386-pc/search_fs_uuid.mod b/INSTALL/grub/i386-pc/search_fs_uuid.mod new file mode 100644 index 00000000..1612551a Binary files /dev/null and b/INSTALL/grub/i386-pc/search_fs_uuid.mod differ diff --git a/INSTALL/grub/i386-pc/search_label.mod b/INSTALL/grub/i386-pc/search_label.mod new file mode 100644 index 00000000..73ec8182 Binary files /dev/null and b/INSTALL/grub/i386-pc/search_label.mod differ diff --git a/INSTALL/grub/i386-pc/sendkey.mod b/INSTALL/grub/i386-pc/sendkey.mod new file mode 100644 index 00000000..d8605d60 Binary files /dev/null and b/INSTALL/grub/i386-pc/sendkey.mod differ diff --git a/INSTALL/grub/i386-pc/serial.mod b/INSTALL/grub/i386-pc/serial.mod new file mode 100644 index 00000000..521e28ef Binary files /dev/null and b/INSTALL/grub/i386-pc/serial.mod differ diff --git a/INSTALL/grub/i386-pc/setjmp.mod b/INSTALL/grub/i386-pc/setjmp.mod new file mode 100644 index 00000000..2d35023b Binary files /dev/null and b/INSTALL/grub/i386-pc/setjmp.mod differ diff --git a/INSTALL/grub/i386-pc/setjmp_test.mod b/INSTALL/grub/i386-pc/setjmp_test.mod new file mode 100644 index 00000000..b337f7be Binary files /dev/null and b/INSTALL/grub/i386-pc/setjmp_test.mod differ diff --git a/INSTALL/grub/i386-pc/setpci.mod b/INSTALL/grub/i386-pc/setpci.mod new file mode 100644 index 00000000..f0b84d94 Binary files /dev/null and b/INSTALL/grub/i386-pc/setpci.mod differ diff --git a/INSTALL/grub/i386-pc/sfs.mod b/INSTALL/grub/i386-pc/sfs.mod new file mode 100644 index 00000000..3cf881b4 Binary files /dev/null and b/INSTALL/grub/i386-pc/sfs.mod differ diff --git a/INSTALL/grub/i386-pc/shift_test.mod b/INSTALL/grub/i386-pc/shift_test.mod new file mode 100644 index 00000000..8236137c Binary files /dev/null and b/INSTALL/grub/i386-pc/shift_test.mod differ diff --git a/INSTALL/grub/i386-pc/signature_test.mod b/INSTALL/grub/i386-pc/signature_test.mod new file mode 100644 index 00000000..62c1e533 Binary files /dev/null and b/INSTALL/grub/i386-pc/signature_test.mod differ diff --git a/INSTALL/grub/i386-pc/sleep_test.mod b/INSTALL/grub/i386-pc/sleep_test.mod new file mode 100644 index 00000000..78d66481 Binary files /dev/null and b/INSTALL/grub/i386-pc/sleep_test.mod differ diff --git a/INSTALL/grub/i386-pc/spkmodem.mod b/INSTALL/grub/i386-pc/spkmodem.mod new file mode 100644 index 00000000..c5e06b56 Binary files /dev/null and b/INSTALL/grub/i386-pc/spkmodem.mod differ diff --git a/INSTALL/grub/i386-pc/strtoull_test.mod b/INSTALL/grub/i386-pc/strtoull_test.mod new file mode 100644 index 00000000..38de07ef Binary files /dev/null and b/INSTALL/grub/i386-pc/strtoull_test.mod differ diff --git a/INSTALL/grub/i386-pc/syslinuxcfg.mod b/INSTALL/grub/i386-pc/syslinuxcfg.mod new file mode 100644 index 00000000..3f3252b2 Binary files /dev/null and b/INSTALL/grub/i386-pc/syslinuxcfg.mod differ diff --git a/INSTALL/grub/i386-pc/terminal.lst b/INSTALL/grub/i386-pc/terminal.lst new file mode 100644 index 00000000..2cb224c4 --- /dev/null +++ b/INSTALL/grub/i386-pc/terminal.lst @@ -0,0 +1,11 @@ +iat_keyboard: at_keyboard +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +omda_text: mda_text +oserial: serial +oserial_*: serial +ospkmodem: spkmodem +ovga_text: vga_text diff --git a/INSTALL/grub/i386-pc/terminfo.mod b/INSTALL/grub/i386-pc/terminfo.mod new file mode 100644 index 00000000..a925b176 Binary files /dev/null and b/INSTALL/grub/i386-pc/terminfo.mod differ diff --git a/INSTALL/grub/i386-pc/test_blockarg.mod b/INSTALL/grub/i386-pc/test_blockarg.mod new file mode 100644 index 00000000..dde95fc4 Binary files /dev/null and b/INSTALL/grub/i386-pc/test_blockarg.mod differ diff --git a/INSTALL/grub/i386-pc/testload.mod b/INSTALL/grub/i386-pc/testload.mod new file mode 100644 index 00000000..1d428810 Binary files /dev/null and b/INSTALL/grub/i386-pc/testload.mod differ diff --git a/INSTALL/grub/i386-pc/testspeed.mod b/INSTALL/grub/i386-pc/testspeed.mod new file mode 100644 index 00000000..aa331842 Binary files /dev/null and b/INSTALL/grub/i386-pc/testspeed.mod differ diff --git a/INSTALL/grub/i386-pc/tga.mod b/INSTALL/grub/i386-pc/tga.mod new file mode 100644 index 00000000..c8fcd0b5 Binary files /dev/null and b/INSTALL/grub/i386-pc/tga.mod differ diff --git a/INSTALL/grub/i386-pc/time.mod b/INSTALL/grub/i386-pc/time.mod new file mode 100644 index 00000000..04d482d7 Binary files /dev/null and b/INSTALL/grub/i386-pc/time.mod differ diff --git a/INSTALL/grub/i386-pc/truecrypt.mod b/INSTALL/grub/i386-pc/truecrypt.mod new file mode 100644 index 00000000..6730bcd9 Binary files /dev/null and b/INSTALL/grub/i386-pc/truecrypt.mod differ diff --git a/INSTALL/grub/i386-pc/ufs1.mod b/INSTALL/grub/i386-pc/ufs1.mod new file mode 100644 index 00000000..4772a202 Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs1.mod differ diff --git a/INSTALL/grub/i386-pc/ufs1_be.mod b/INSTALL/grub/i386-pc/ufs1_be.mod new file mode 100644 index 00000000..31a50d7c Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs1_be.mod differ diff --git a/INSTALL/grub/i386-pc/ufs2.mod b/INSTALL/grub/i386-pc/ufs2.mod new file mode 100644 index 00000000..088fba39 Binary files /dev/null and b/INSTALL/grub/i386-pc/ufs2.mod differ diff --git a/INSTALL/grub/i386-pc/uhci.mod b/INSTALL/grub/i386-pc/uhci.mod new file mode 100644 index 00000000..0e714282 Binary files /dev/null and b/INSTALL/grub/i386-pc/uhci.mod differ diff --git a/INSTALL/grub/i386-pc/usb.mod b/INSTALL/grub/i386-pc/usb.mod new file mode 100644 index 00000000..3bf851ad Binary files /dev/null and b/INSTALL/grub/i386-pc/usb.mod differ diff --git a/INSTALL/grub/i386-pc/usbms.mod b/INSTALL/grub/i386-pc/usbms.mod new file mode 100644 index 00000000..3c41b5c9 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbms.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_common.mod b/INSTALL/grub/i386-pc/usbserial_common.mod new file mode 100644 index 00000000..25d8b0af Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_common.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_ftdi.mod b/INSTALL/grub/i386-pc/usbserial_ftdi.mod new file mode 100644 index 00000000..41eac15f Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_pl2303.mod b/INSTALL/grub/i386-pc/usbserial_pl2303.mod new file mode 100644 index 00000000..4dfbf9ae Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/i386-pc/usbserial_usbdebug.mod b/INSTALL/grub/i386-pc/usbserial_usbdebug.mod new file mode 100644 index 00000000..e8f3c413 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/i386-pc/usbtest.mod b/INSTALL/grub/i386-pc/usbtest.mod new file mode 100644 index 00000000..5c3a7fc1 Binary files /dev/null and b/INSTALL/grub/i386-pc/usbtest.mod differ diff --git a/INSTALL/grub/i386-pc/verifiers.mod b/INSTALL/grub/i386-pc/verifiers.mod new file mode 100644 index 00000000..f7b8ab91 Binary files /dev/null and b/INSTALL/grub/i386-pc/verifiers.mod differ diff --git a/INSTALL/grub/i386-pc/video.lst b/INSTALL/grub/i386-pc/video.lst new file mode 100644 index 00000000..6ca853e6 --- /dev/null +++ b/INSTALL/grub/i386-pc/video.lst @@ -0,0 +1,4 @@ +vbe +vga +video_bochs +video_cirrus diff --git a/INSTALL/grub/i386-pc/wrmsr.mod b/INSTALL/grub/i386-pc/wrmsr.mod new file mode 100644 index 00000000..1d7d2573 Binary files /dev/null and b/INSTALL/grub/i386-pc/wrmsr.mod differ diff --git a/INSTALL/grub/i386-pc/xnu.mod b/INSTALL/grub/i386-pc/xnu.mod new file mode 100644 index 00000000..96c2e583 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu.mod differ diff --git a/INSTALL/grub/i386-pc/xnu_uuid.mod b/INSTALL/grub/i386-pc/xnu_uuid.mod new file mode 100644 index 00000000..499f0b58 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu_uuid.mod differ diff --git a/INSTALL/grub/i386-pc/xnu_uuid_test.mod b/INSTALL/grub/i386-pc/xnu_uuid_test.mod new file mode 100644 index 00000000..a8532356 Binary files /dev/null and b/INSTALL/grub/i386-pc/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/i386-pc/zfs.mod b/INSTALL/grub/i386-pc/zfs.mod new file mode 100644 index 00000000..28adaa65 Binary files /dev/null and b/INSTALL/grub/i386-pc/zfs.mod differ diff --git a/INSTALL/grub/i386-pc/zfscrypt.mod b/INSTALL/grub/i386-pc/zfscrypt.mod new file mode 100644 index 00000000..e684ccd2 Binary files /dev/null and b/INSTALL/grub/i386-pc/zfscrypt.mod differ diff --git a/INSTALL/grub/i386-pc/zfsinfo.mod b/INSTALL/grub/i386-pc/zfsinfo.mod new file mode 100644 index 00000000..68844f45 Binary files /dev/null and b/INSTALL/grub/i386-pc/zfsinfo.mod differ diff --git a/INSTALL/grub/i386-pc/zstd.mod b/INSTALL/grub/i386-pc/zstd.mod new file mode 100644 index 00000000..721fe202 Binary files /dev/null and b/INSTALL/grub/i386-pc/zstd.mod differ diff --git a/INSTALL/grub/keyboard.cfg b/INSTALL/grub/keyboard.cfg new file mode 100644 index 00000000..8145dcbf --- /dev/null +++ b/INSTALL/grub/keyboard.cfg @@ -0,0 +1,62 @@ +submenu "Keyboard Layouts" --class=debug_krdlayout --class=F5tool { + menuentry QWERTY_USA --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTY_USA + } + menuentry AZERTY --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout AZERTY + } + menuentry CZECH_QWERTY --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout CZECH_QWERTY + } + menuentry CZECH_QWERTZ --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout CZECH_QWERTZ + } + menuentry DANISH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout DANISH + } + menuentry DVORAK_USA --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout DVORAK_USA + } + menuentry FRENCH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout FRENCH + } + menuentry GERMAN --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout GERMAN + } + menuentry ITALIANO --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout ITALIANO + } + menuentry JAPAN_106 --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout JAPAN_106 + } + menuentry LATIN_USA --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout LATIN_USA + } + menuentry PORTU_BRAZIL --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout PORTU_BRAZIL + } + menuentry QWERTY_UK --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTY_UK + } + menuentry QWERTZ --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTZ + } + menuentry QWERTZ_HUN --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTZ_HUN + } + menuentry QWERTZ_SLOV_CROAT --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout QWERTZ_SLOV_CROAT + } + menuentry SPANISH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout SPANISH + } + menuentry SWEDISH --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout SWEDISH + } + menuentry TURKISH_Q --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout TURKISH_Q + } + menuentry VIETNAMESE --class=debug_kbd --class=debug_krdlayout --class=F5tool { + set_keyboard_layout VIETNAMESE + } +} diff --git a/INSTALL/grub/localboot.cfg b/INSTALL/grub/localboot.cfg index 0afb3446..c1106af7 100644 --- a/INSTALL/grub/localboot.cfg +++ b/INSTALL/grub/localboot.cfg @@ -1,16 +1,44 @@ if [ "$grub_platform" = "pc" ]; then - menuentry 'Search and boot Windows' --class=boot_windows { - if search -n -s -f /bootmgr; then - ntldr /bootmgr - elif search -n -s -f /ntldr; then + menuentry 'Search and boot Windows' --class=boot_windows --class=F4boot { + + set partid=3 + while [ $partid -le 128 ]; do + if vt_check_part_exist $partid; then + for bt in bootmgr BOOTMGR Bootmgr BootMGR; do + if [ -f ($vtoydev,$partid)/$bt ]; then + set root=($vtoydev,$partid) + ntldr /$bt + boot + fi + done + else + break + fi + vt_incr partid 1 + done + + if search -n -s -f /Boot/BCD; then + for bt in bootmgr BOOTMGR Bootmgr BootMGR; do + if [ -f /$bt ]; then + if regexp '^hd0' $root; then + ntldr /$bt + else + drivemap -s hd0 $root + ntldr /$bt + fi + break + fi + done + elif search -n -s -f /NTDETECT.COM; then + drivemap -s hd0 $root ntldr /ntldr else echo "Windows NOT found ..." fi } - menuentry 'Search and boot Grub4dos' --class=boot_g4d { + menuentry 'Search and boot Grub4dos' --class=boot_g4d --class=F4boot { if search -n -s -f /grldr; then ntldr /grldr else @@ -18,19 +46,19 @@ if [ "$grub_platform" = "pc" ]; then fi } - menuentry 'Boot the 1st local disk' --class=boot_disk { + menuentry 'Boot the 1st local disk' --class=boot_disk --class=F4boot { set root=(hd0,1) chainloader +1 boot } - menuentry 'Boot the 2nd local disk' --class=boot_disk { + menuentry 'Boot the 2nd local disk' --class=boot_disk --class=F4boot { set root=(hd1,1) chainloader +1 boot } - menuentry 'Boot the 3rd local disk' --class=boot_disk { + menuentry 'Boot the 3rd local disk' --class=boot_disk --class=F4boot { set root=(hd2,1) chainloader +1 boot @@ -38,7 +66,23 @@ if [ "$grub_platform" = "pc" ]; then else - menuentry 'Search and boot Windows' --class=boot_windows { + menuentry 'Search and boot Windows' --class=boot_windows --class=F4boot { + + set partid=3 + while [ $partid -le 128 ]; do + if vt_check_part_exist $partid; then + if [ -f ($vtoydev,$partid)/EFI/Microsoft/Boot/bootmgfw.efi ]; then + set root=($vtoydev,$partid) + terminal_output console + chainloader /EFI/Microsoft/Boot/bootmgfw.efi + boot + fi + else + break + fi + vt_incr partid 1 + done + if search -n -s -f /EFI/Microsoft/Boot/bootmgfw.efi; then terminal_output console chainloader /EFI/Microsoft/Boot/bootmgfw.efi @@ -48,18 +92,84 @@ else fi } - menuentry 'Search and boot BOOTX64.EFI' --class=boot_uefi { - if search -n -s -f /efi/boot/bootx64.efi; then - terminal_output console - chainloader /efi/boot/bootx64.efi - boot - else - echo "BOOTX64.EFI NOT found ..." - fi - } + if [ "$grub_cpu" = "i386" ]; then + menuentry 'Search and boot BOOTIA32.EFI' --class=boot_uefi --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/boot/bootia32.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /efi/boot/bootia32.efi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "BOOTIA32.EFI NOT found ..." + fi + } + + menuentry 'Search and boot xorboot' --class=boot_xorboot --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/xorboot/xorboot32.xor; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + if [ -f /efi/xorboot/bootia32.efi ]; then + chainloader /efi/xorboot/bootia32.efi + elif [ -f /efi/xorboot/xorboot.efi ]; then + chainloader /efi/xorboot/xorboot.efi + fi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "xorboot NOT found ..." + fi + } + elif [ "$grub_cpu" = "arm64" ]; then + menuentry 'Search and boot BOOTAA64.EFI' --class=boot_uefi --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/boot/bootaa64.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /efi/boot/bootaa64.efi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "BOOTAA64.EFI NOT found ..." + fi + } + else + menuentry 'Search and boot BOOTX64.EFI' --class=boot_uefi --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/boot/bootx64.efi; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + chainloader /efi/boot/bootx64.efi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "BOOTX64.EFI NOT found ..." + fi + } + + menuentry 'Search and boot xorboot' --class=boot_xorboot --class=F4boot { + set VTOY_SEARCH_NO_VTOYEFI=1 + if search -n -s -f /efi/xorboot/xorboot.xor; then + unset VTOY_SEARCH_NO_VTOYEFI + terminal_output console + if [ -f /efi/xorboot/bootx64.efi ]; then + chainloader /efi/xorboot/bootx64.efi + elif [ -f /efi/xorboot/xorboot.efi ]; then + chainloader /efi/xorboot/xorboot.efi + fi + boot + else + unset VTOY_SEARCH_NO_VTOYEFI + echo "xorboot NOT found ..." + fi + } + fi + fi -menuentry 'Return to menu [Esc]' --class=vtoyret VTOY_RET { +menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } diff --git a/INSTALL/grub/mips64el-efi/adler32.mod b/INSTALL/grub/mips64el-efi/adler32.mod new file mode 100644 index 00000000..5c11d9a4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/adler32.mod differ diff --git a/INSTALL/grub/mips64el-efi/affs.mod b/INSTALL/grub/mips64el-efi/affs.mod new file mode 100644 index 00000000..80ee7ecc Binary files /dev/null and b/INSTALL/grub/mips64el-efi/affs.mod differ diff --git a/INSTALL/grub/mips64el-efi/afs.mod b/INSTALL/grub/mips64el-efi/afs.mod new file mode 100644 index 00000000..fe2a1c81 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/afs.mod differ diff --git a/INSTALL/grub/mips64el-efi/archelp.mod b/INSTALL/grub/mips64el-efi/archelp.mod new file mode 100644 index 00000000..75c84448 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/archelp.mod differ diff --git a/INSTALL/grub/mips64el-efi/bfs.mod b/INSTALL/grub/mips64el-efi/bfs.mod new file mode 100644 index 00000000..133bc607 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/bfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/blscfg.mod b/INSTALL/grub/mips64el-efi/blscfg.mod new file mode 100644 index 00000000..cdd0cd0a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/blscfg.mod differ diff --git a/INSTALL/grub/mips64el-efi/bswap_test.mod b/INSTALL/grub/mips64el-efi/bswap_test.mod new file mode 100644 index 00000000..e13d3333 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/bswap_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/btrfs.mod b/INSTALL/grub/mips64el-efi/btrfs.mod new file mode 100644 index 00000000..d268085b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/btrfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/cbfs.mod b/INSTALL/grub/mips64el-efi/cbfs.mod new file mode 100644 index 00000000..c3c2bfaa Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cbfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/cmdline_cat_test.mod b/INSTALL/grub/mips64el-efi/cmdline_cat_test.mod new file mode 100644 index 00000000..94df7a79 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/cmp.mod b/INSTALL/grub/mips64el-efi/cmp.mod new file mode 100644 index 00000000..98de3928 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cmp.mod differ diff --git a/INSTALL/grub/mips64el-efi/cmp_test.mod b/INSTALL/grub/mips64el-efi/cmp_test.mod new file mode 100644 index 00000000..ecc41ff0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cmp_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/command.lst b/INSTALL/grub/mips64el-efi/command.lst new file mode 100644 index 00000000..fcc9e843 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/command.lst differ diff --git a/INSTALL/grub/mips64el-efi/cpio.mod b/INSTALL/grub/mips64el-efi/cpio.mod new file mode 100644 index 00000000..1df9f5cb Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cpio.mod differ diff --git a/INSTALL/grub/mips64el-efi/cpio_be.mod b/INSTALL/grub/mips64el-efi/cpio_be.mod new file mode 100644 index 00000000..cb4e8a08 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cpio_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/crc64.mod b/INSTALL/grub/mips64el-efi/crc64.mod new file mode 100644 index 00000000..175d3474 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/crc64.mod differ diff --git a/INSTALL/grub/mips64el-efi/crypto.lst b/INSTALL/grub/mips64el-efi/crypto.lst new file mode 100644 index 00000000..bd0a97c6 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/crypto.lst differ diff --git a/INSTALL/grub/mips64el-efi/cryptodisk.mod b/INSTALL/grub/mips64el-efi/cryptodisk.mod new file mode 100644 index 00000000..d887d4bb Binary files /dev/null and b/INSTALL/grub/mips64el-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/mips64el-efi/ctz_test.mod b/INSTALL/grub/mips64el-efi/ctz_test.mod new file mode 100644 index 00000000..e8ffc844 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ctz_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/date.mod b/INSTALL/grub/mips64el-efi/date.mod new file mode 100644 index 00000000..9c9dd996 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/date.mod differ diff --git a/INSTALL/grub/mips64el-efi/datehook.mod b/INSTALL/grub/mips64el-efi/datehook.mod new file mode 100644 index 00000000..4dace4a0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/datehook.mod differ diff --git a/INSTALL/grub/mips64el-efi/disk.mod b/INSTALL/grub/mips64el-efi/disk.mod new file mode 100644 index 00000000..7c67ffcc Binary files /dev/null and b/INSTALL/grub/mips64el-efi/disk.mod differ diff --git a/INSTALL/grub/mips64el-efi/div.mod b/INSTALL/grub/mips64el-efi/div.mod new file mode 100644 index 00000000..f8477227 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/div.mod differ diff --git a/INSTALL/grub/mips64el-efi/div_test.mod b/INSTALL/grub/mips64el-efi/div_test.mod new file mode 100644 index 00000000..d16bb6a2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/div_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/dm_nv.mod b/INSTALL/grub/mips64el-efi/dm_nv.mod new file mode 100644 index 00000000..74749a33 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/dm_nv.mod differ diff --git a/INSTALL/grub/mips64el-efi/efinet.mod b/INSTALL/grub/mips64el-efi/efinet.mod new file mode 100644 index 00000000..c81d8bc0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/efinet.mod differ diff --git a/INSTALL/grub/mips64el-efi/elf.mod b/INSTALL/grub/mips64el-efi/elf.mod new file mode 100644 index 00000000..2a699951 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/elf.mod differ diff --git a/INSTALL/grub/mips64el-efi/eval.mod b/INSTALL/grub/mips64el-efi/eval.mod new file mode 100644 index 00000000..37eefdb6 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/eval.mod differ diff --git a/INSTALL/grub/mips64el-efi/exfctest.mod b/INSTALL/grub/mips64el-efi/exfctest.mod new file mode 100644 index 00000000..3db7c61c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/exfctest.mod differ diff --git a/INSTALL/grub/mips64el-efi/f2fs.mod b/INSTALL/grub/mips64el-efi/f2fs.mod new file mode 100644 index 00000000..373a97f2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/f2fs.mod differ diff --git a/INSTALL/grub/mips64el-efi/fdt.lst b/INSTALL/grub/mips64el-efi/fdt.lst new file mode 100644 index 00000000..ea28d9e0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/fdt.lst differ diff --git a/INSTALL/grub/mips64el-efi/fs.lst b/INSTALL/grub/mips64el-efi/fs.lst new file mode 100644 index 00000000..12c6c9d1 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/fs.lst differ diff --git a/INSTALL/grub/mips64el-efi/functional_test.mod b/INSTALL/grub/mips64el-efi/functional_test.mod new file mode 100644 index 00000000..164797a4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/functional_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_arcfour.mod b/INSTALL/grub/mips64el-efi/gcry_arcfour.mod new file mode 100644 index 00000000..69f507a2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_blowfish.mod b/INSTALL/grub/mips64el-efi/gcry_blowfish.mod new file mode 100644 index 00000000..ec968a3c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_camellia.mod b/INSTALL/grub/mips64el-efi/gcry_camellia.mod new file mode 100644 index 00000000..61d964ac Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_cast5.mod b/INSTALL/grub/mips64el-efi/gcry_cast5.mod new file mode 100644 index 00000000..bebfb7a2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_crc.mod b/INSTALL/grub/mips64el-efi/gcry_crc.mod new file mode 100644 index 00000000..2206b680 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_des.mod b/INSTALL/grub/mips64el-efi/gcry_des.mod new file mode 100644 index 00000000..8c1f69d4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_des.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_dsa.mod b/INSTALL/grub/mips64el-efi/gcry_dsa.mod new file mode 100644 index 00000000..9ab092d1 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_idea.mod b/INSTALL/grub/mips64el-efi/gcry_idea.mod new file mode 100644 index 00000000..8e52677d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_md4.mod b/INSTALL/grub/mips64el-efi/gcry_md4.mod new file mode 100644 index 00000000..6e016271 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rfc2268.mod b/INSTALL/grub/mips64el-efi/gcry_rfc2268.mod new file mode 100644 index 00000000..57760d97 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rijndael.mod b/INSTALL/grub/mips64el-efi/gcry_rijndael.mod new file mode 100644 index 00000000..d3a6068e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rmd160.mod b/INSTALL/grub/mips64el-efi/gcry_rmd160.mod new file mode 100644 index 00000000..6f8be832 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_rsa.mod b/INSTALL/grub/mips64el-efi/gcry_rsa.mod new file mode 100644 index 00000000..d19584c0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_seed.mod b/INSTALL/grub/mips64el-efi/gcry_seed.mod new file mode 100644 index 00000000..ba695b3b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_serpent.mod b/INSTALL/grub/mips64el-efi/gcry_serpent.mod new file mode 100644 index 00000000..95072461 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_sha1.mod b/INSTALL/grub/mips64el-efi/gcry_sha1.mod new file mode 100644 index 00000000..e71483ff Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_sha256.mod b/INSTALL/grub/mips64el-efi/gcry_sha256.mod new file mode 100644 index 00000000..6ce2ad44 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_tiger.mod b/INSTALL/grub/mips64el-efi/gcry_tiger.mod new file mode 100644 index 00000000..b771dc86 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_twofish.mod b/INSTALL/grub/mips64el-efi/gcry_twofish.mod new file mode 100644 index 00000000..5c13e906 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/mips64el-efi/gcry_whirlpool.mod b/INSTALL/grub/mips64el-efi/gcry_whirlpool.mod new file mode 100644 index 00000000..b48b76d9 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/mips64el-efi/geli.mod b/INSTALL/grub/mips64el-efi/geli.mod new file mode 100644 index 00000000..ca127cae Binary files /dev/null and b/INSTALL/grub/mips64el-efi/geli.mod differ diff --git a/INSTALL/grub/mips64el-efi/gfxterm_menu.mod b/INSTALL/grub/mips64el-efi/gfxterm_menu.mod new file mode 100644 index 00000000..ddc1d552 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gfxterm_menu.mod differ diff --git a/INSTALL/grub/mips64el-efi/gptsync.mod b/INSTALL/grub/mips64el-efi/gptsync.mod new file mode 100644 index 00000000..2efaf743 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/gptsync.mod differ diff --git a/INSTALL/grub/mips64el-efi/hello.mod b/INSTALL/grub/mips64el-efi/hello.mod new file mode 100644 index 00000000..b43acca8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hello.mod differ diff --git a/INSTALL/grub/mips64el-efi/help.mod b/INSTALL/grub/mips64el-efi/help.mod new file mode 100644 index 00000000..b5333a21 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/help.mod differ diff --git a/INSTALL/grub/mips64el-efi/hexdump.mod b/INSTALL/grub/mips64el-efi/hexdump.mod new file mode 100644 index 00000000..b056cba8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hexdump.mod differ diff --git a/INSTALL/grub/mips64el-efi/hfs.mod b/INSTALL/grub/mips64el-efi/hfs.mod new file mode 100644 index 00000000..bc579bdb Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/hfspluscomp.mod b/INSTALL/grub/mips64el-efi/hfspluscomp.mod new file mode 100644 index 00000000..72a99387 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/mips64el-efi/jfs.mod b/INSTALL/grub/mips64el-efi/jfs.mod new file mode 100644 index 00000000..38f9888c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/jfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/keystatus.mod b/INSTALL/grub/mips64el-efi/keystatus.mod new file mode 100644 index 00000000..aafda352 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/keystatus.mod differ diff --git a/INSTALL/grub/mips64el-efi/ldm.mod b/INSTALL/grub/mips64el-efi/ldm.mod new file mode 100644 index 00000000..7a4240c1 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ldm.mod differ diff --git a/INSTALL/grub/mips64el-efi/loadenv.mod b/INSTALL/grub/mips64el-efi/loadenv.mod new file mode 100644 index 00000000..091f014a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/loadenv.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsacpi.mod b/INSTALL/grub/mips64el-efi/lsacpi.mod new file mode 100644 index 00000000..f1dafe2d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsacpi.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsefi.mod b/INSTALL/grub/mips64el-efi/lsefi.mod new file mode 100644 index 00000000..e7428a28 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsefi.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsefimmap.mod b/INSTALL/grub/mips64el-efi/lsefimmap.mod new file mode 100644 index 00000000..d2bd3127 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsefisystab.mod b/INSTALL/grub/mips64el-efi/lsefisystab.mod new file mode 100644 index 00000000..f1994398 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/mips64el-efi/lsmmap.mod b/INSTALL/grub/mips64el-efi/lsmmap.mod new file mode 100644 index 00000000..28357746 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lsmmap.mod differ diff --git a/INSTALL/grub/mips64el-efi/lssal.mod b/INSTALL/grub/mips64el-efi/lssal.mod new file mode 100644 index 00000000..57f9eb37 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lssal.mod differ diff --git a/INSTALL/grub/mips64el-efi/luks.mod b/INSTALL/grub/mips64el-efi/luks.mod new file mode 100644 index 00000000..eade785b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/luks.mod differ diff --git a/INSTALL/grub/mips64el-efi/lvm.mod b/INSTALL/grub/mips64el-efi/lvm.mod new file mode 100644 index 00000000..88d2fb17 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/lvm.mod differ diff --git a/INSTALL/grub/mips64el-efi/macbless.mod b/INSTALL/grub/mips64el-efi/macbless.mod new file mode 100644 index 00000000..e0632178 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/macbless.mod differ diff --git a/INSTALL/grub/mips64el-efi/macho.mod b/INSTALL/grub/mips64el-efi/macho.mod new file mode 100644 index 00000000..30acfd54 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/macho.mod differ diff --git a/INSTALL/grub/mips64el-efi/mdraid09.mod b/INSTALL/grub/mips64el-efi/mdraid09.mod new file mode 100644 index 00000000..351ae1bf Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mdraid09.mod differ diff --git a/INSTALL/grub/mips64el-efi/mdraid09_be.mod b/INSTALL/grub/mips64el-efi/mdraid09_be.mod new file mode 100644 index 00000000..24394f45 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/mdraid1x.mod b/INSTALL/grub/mips64el-efi/mdraid1x.mod new file mode 100644 index 00000000..f9e374c3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/mips64el-efi/memdisk.mod b/INSTALL/grub/mips64el-efi/memdisk.mod new file mode 100644 index 00000000..86932db4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/memdisk.mod differ diff --git a/INSTALL/grub/mips64el-efi/memrw.mod b/INSTALL/grub/mips64el-efi/memrw.mod new file mode 100644 index 00000000..a0a6dde3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/memrw.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix.mod b/INSTALL/grub/mips64el-efi/minix.mod new file mode 100644 index 00000000..3a16c280 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix2.mod b/INSTALL/grub/mips64el-efi/minix2.mod new file mode 100644 index 00000000..7ad76d1a Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix2.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix2_be.mod b/INSTALL/grub/mips64el-efi/minix2_be.mod new file mode 100644 index 00000000..72ddc958 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix2_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix3.mod b/INSTALL/grub/mips64el-efi/minix3.mod new file mode 100644 index 00000000..979bb9d0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix3.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix3_be.mod b/INSTALL/grub/mips64el-efi/minix3_be.mod new file mode 100644 index 00000000..87021fe4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix3_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/minix_be.mod b/INSTALL/grub/mips64el-efi/minix_be.mod new file mode 100644 index 00000000..acc3187f Binary files /dev/null and b/INSTALL/grub/mips64el-efi/minix_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/moddep.lst b/INSTALL/grub/mips64el-efi/moddep.lst new file mode 100644 index 00000000..916d5bd4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/moddep.lst differ diff --git a/INSTALL/grub/mips64el-efi/mpi.mod b/INSTALL/grub/mips64el-efi/mpi.mod new file mode 100644 index 00000000..a847b2e4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mpi.mod differ diff --git a/INSTALL/grub/mips64el-efi/msdospart.mod b/INSTALL/grub/mips64el-efi/msdospart.mod new file mode 100644 index 00000000..1c485a35 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/msdospart.mod differ diff --git a/INSTALL/grub/mips64el-efi/mul_test.mod b/INSTALL/grub/mips64el-efi/mul_test.mod new file mode 100644 index 00000000..4d539b3c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/mul_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/nilfs2.mod b/INSTALL/grub/mips64el-efi/nilfs2.mod new file mode 100644 index 00000000..19594cf6 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/nilfs2.mod differ diff --git a/INSTALL/grub/mips64el-efi/normal.mod b/INSTALL/grub/mips64el-efi/normal.mod new file mode 100644 index 00000000..8723f43b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/normal.mod differ diff --git a/INSTALL/grub/mips64el-efi/ntfscomp.mod b/INSTALL/grub/mips64el-efi/ntfscomp.mod new file mode 100644 index 00000000..b24d9ae0 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/mips64el-efi/odc.mod b/INSTALL/grub/mips64el-efi/odc.mod new file mode 100644 index 00000000..1c004226 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/odc.mod differ diff --git a/INSTALL/grub/mips64el-efi/offsetio.mod b/INSTALL/grub/mips64el-efi/offsetio.mod new file mode 100644 index 00000000..e3d38127 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/offsetio.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_acorn.mod b/INSTALL/grub/mips64el-efi/part_acorn.mod new file mode 100644 index 00000000..6ecce91b Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_acorn.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_amiga.mod b/INSTALL/grub/mips64el-efi/part_amiga.mod new file mode 100644 index 00000000..af48dcfa Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_amiga.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_bsd.mod b/INSTALL/grub/mips64el-efi/part_bsd.mod new file mode 100644 index 00000000..c3c8d787 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_bsd.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_dfly.mod b/INSTALL/grub/mips64el-efi/part_dfly.mod new file mode 100644 index 00000000..25f78f25 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_dfly.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_dvh.mod b/INSTALL/grub/mips64el-efi/part_dvh.mod new file mode 100644 index 00000000..40974fa5 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_dvh.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_plan.mod b/INSTALL/grub/mips64el-efi/part_plan.mod new file mode 100644 index 00000000..4836bbcd Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_plan.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_sun.mod b/INSTALL/grub/mips64el-efi/part_sun.mod new file mode 100644 index 00000000..a08f049c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_sun.mod differ diff --git a/INSTALL/grub/mips64el-efi/part_sunpc.mod b/INSTALL/grub/mips64el-efi/part_sunpc.mod new file mode 100644 index 00000000..74774174 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/mips64el-efi/partmap.lst b/INSTALL/grub/mips64el-efi/partmap.lst new file mode 100644 index 00000000..720c55e3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/partmap.lst differ diff --git a/INSTALL/grub/mips64el-efi/parttool.lst b/INSTALL/grub/mips64el-efi/parttool.lst new file mode 100644 index 00000000..bfa2d4a8 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/parttool.lst differ diff --git a/INSTALL/grub/mips64el-efi/parttool.mod b/INSTALL/grub/mips64el-efi/parttool.mod new file mode 100644 index 00000000..d93f08c7 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/parttool.mod differ diff --git a/INSTALL/grub/mips64el-efi/password.mod b/INSTALL/grub/mips64el-efi/password.mod new file mode 100644 index 00000000..f7e90434 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/password.mod differ diff --git a/INSTALL/grub/mips64el-efi/pbkdf2_test.mod b/INSTALL/grub/mips64el-efi/pbkdf2_test.mod new file mode 100644 index 00000000..6dd14527 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/pgp.mod b/INSTALL/grub/mips64el-efi/pgp.mod new file mode 100644 index 00000000..7948f3f6 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/pgp.mod differ diff --git a/INSTALL/grub/mips64el-efi/probe.mod b/INSTALL/grub/mips64el-efi/probe.mod new file mode 100644 index 00000000..30ae5a88 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/probe.mod differ diff --git a/INSTALL/grub/mips64el-efi/procfs.mod b/INSTALL/grub/mips64el-efi/procfs.mod new file mode 100644 index 00000000..3d86a0a4 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/procfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/progress.mod b/INSTALL/grub/mips64el-efi/progress.mod new file mode 100644 index 00000000..3547a322 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/progress.mod differ diff --git a/INSTALL/grub/mips64el-efi/raid5rec.mod b/INSTALL/grub/mips64el-efi/raid5rec.mod new file mode 100644 index 00000000..2724de9e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/raid5rec.mod differ diff --git a/INSTALL/grub/mips64el-efi/raid6rec.mod b/INSTALL/grub/mips64el-efi/raid6rec.mod new file mode 100644 index 00000000..5dbcaf9d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/raid6rec.mod differ diff --git a/INSTALL/grub/mips64el-efi/reiserfs.mod b/INSTALL/grub/mips64el-efi/reiserfs.mod new file mode 100644 index 00000000..b425c034 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/reiserfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/relocator.mod b/INSTALL/grub/mips64el-efi/relocator.mod new file mode 100644 index 00000000..1d7be9d3 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/relocator.mod differ diff --git a/INSTALL/grub/mips64el-efi/romfs.mod b/INSTALL/grub/mips64el-efi/romfs.mod new file mode 100644 index 00000000..85a0a59e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/romfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/scsi.mod b/INSTALL/grub/mips64el-efi/scsi.mod new file mode 100644 index 00000000..4699e75c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/scsi.mod differ diff --git a/INSTALL/grub/mips64el-efi/search_fs_file.mod b/INSTALL/grub/mips64el-efi/search_fs_file.mod new file mode 100644 index 00000000..04ffff5d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/mips64el-efi/search_fs_uuid.mod b/INSTALL/grub/mips64el-efi/search_fs_uuid.mod new file mode 100644 index 00000000..deebcfee Binary files /dev/null and b/INSTALL/grub/mips64el-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/mips64el-efi/search_label.mod b/INSTALL/grub/mips64el-efi/search_label.mod new file mode 100644 index 00000000..d1f8d162 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/search_label.mod differ diff --git a/INSTALL/grub/mips64el-efi/setjmp.mod b/INSTALL/grub/mips64el-efi/setjmp.mod new file mode 100644 index 00000000..456d469f Binary files /dev/null and b/INSTALL/grub/mips64el-efi/setjmp.mod differ diff --git a/INSTALL/grub/mips64el-efi/setjmp_test.mod b/INSTALL/grub/mips64el-efi/setjmp_test.mod new file mode 100644 index 00000000..42dbc0e7 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/sfs.mod b/INSTALL/grub/mips64el-efi/sfs.mod new file mode 100644 index 00000000..484fb2da Binary files /dev/null and b/INSTALL/grub/mips64el-efi/sfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/shift_test.mod b/INSTALL/grub/mips64el-efi/shift_test.mod new file mode 100644 index 00000000..09e8693f Binary files /dev/null and b/INSTALL/grub/mips64el-efi/shift_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/signature_test.mod b/INSTALL/grub/mips64el-efi/signature_test.mod new file mode 100644 index 00000000..10354fc2 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/signature_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/sleep_test.mod b/INSTALL/grub/mips64el-efi/sleep_test.mod new file mode 100644 index 00000000..8100c642 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/sleep_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/strtoull_test.mod b/INSTALL/grub/mips64el-efi/strtoull_test.mod new file mode 100644 index 00000000..248498aa Binary files /dev/null and b/INSTALL/grub/mips64el-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/syslinuxcfg.mod b/INSTALL/grub/mips64el-efi/syslinuxcfg.mod new file mode 100644 index 00000000..f2721665 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/mips64el-efi/terminal.lst b/INSTALL/grub/mips64el-efi/terminal.lst new file mode 100644 index 00000000..b2cfb3ff Binary files /dev/null and b/INSTALL/grub/mips64el-efi/terminal.lst differ diff --git a/INSTALL/grub/mips64el-efi/test_blockarg.mod b/INSTALL/grub/mips64el-efi/test_blockarg.mod new file mode 100644 index 00000000..d84f601e Binary files /dev/null and b/INSTALL/grub/mips64el-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/mips64el-efi/testload.mod b/INSTALL/grub/mips64el-efi/testload.mod new file mode 100644 index 00000000..09e724aa Binary files /dev/null and b/INSTALL/grub/mips64el-efi/testload.mod differ diff --git a/INSTALL/grub/mips64el-efi/testspeed.mod b/INSTALL/grub/mips64el-efi/testspeed.mod new file mode 100644 index 00000000..145c704c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/testspeed.mod differ diff --git a/INSTALL/grub/mips64el-efi/tga.mod b/INSTALL/grub/mips64el-efi/tga.mod new file mode 100644 index 00000000..2e1e62d5 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/tga.mod differ diff --git a/INSTALL/grub/mips64el-efi/time.mod b/INSTALL/grub/mips64el-efi/time.mod new file mode 100644 index 00000000..ddb2b099 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/time.mod differ diff --git a/INSTALL/grub/mips64el-efi/tr.mod b/INSTALL/grub/mips64el-efi/tr.mod new file mode 100644 index 00000000..736b18b5 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/tr.mod differ diff --git a/INSTALL/grub/mips64el-efi/ufs1.mod b/INSTALL/grub/mips64el-efi/ufs1.mod new file mode 100644 index 00000000..738d7050 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ufs1.mod differ diff --git a/INSTALL/grub/mips64el-efi/ufs1_be.mod b/INSTALL/grub/mips64el-efi/ufs1_be.mod new file mode 100644 index 00000000..b38fd905 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/mips64el-efi/ufs2.mod b/INSTALL/grub/mips64el-efi/ufs2.mod new file mode 100644 index 00000000..177da8a1 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/ufs2.mod differ diff --git a/INSTALL/grub/mips64el-efi/verifiers.mod b/INSTALL/grub/mips64el-efi/verifiers.mod new file mode 100644 index 00000000..9d16385c Binary files /dev/null and b/INSTALL/grub/mips64el-efi/verifiers.mod differ diff --git a/INSTALL/grub/mips64el-efi/video.lst b/INSTALL/grub/mips64el-efi/video.lst new file mode 100644 index 00000000..ad1dbd09 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/video.lst differ diff --git a/INSTALL/grub/mips64el-efi/videoinfo.mod b/INSTALL/grub/mips64el-efi/videoinfo.mod new file mode 100644 index 00000000..09973fe7 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/videoinfo.mod differ diff --git a/INSTALL/grub/mips64el-efi/videotest.mod b/INSTALL/grub/mips64el-efi/videotest.mod new file mode 100644 index 00000000..a5884a22 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/videotest.mod differ diff --git a/INSTALL/grub/mips64el-efi/videotest_checksum.mod b/INSTALL/grub/mips64el-efi/videotest_checksum.mod new file mode 100644 index 00000000..c35ef24d Binary files /dev/null and b/INSTALL/grub/mips64el-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/mips64el-efi/xnu_uuid.mod b/INSTALL/grub/mips64el-efi/xnu_uuid.mod new file mode 100644 index 00000000..9d9b25b1 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/mips64el-efi/xnu_uuid_test.mod b/INSTALL/grub/mips64el-efi/xnu_uuid_test.mod new file mode 100644 index 00000000..1eaf08dc Binary files /dev/null and b/INSTALL/grub/mips64el-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/mips64el-efi/zfs.mod b/INSTALL/grub/mips64el-efi/zfs.mod new file mode 100644 index 00000000..13b9f823 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zfs.mod differ diff --git a/INSTALL/grub/mips64el-efi/zfscrypt.mod b/INSTALL/grub/mips64el-efi/zfscrypt.mod new file mode 100644 index 00000000..df770b33 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/mips64el-efi/zfsinfo.mod b/INSTALL/grub/mips64el-efi/zfsinfo.mod new file mode 100644 index 00000000..ff09333f Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/mips64el-efi/zstd.mod b/INSTALL/grub/mips64el-efi/zstd.mod new file mode 100644 index 00000000..ee571851 Binary files /dev/null and b/INSTALL/grub/mips64el-efi/zstd.mod differ diff --git a/INSTALL/grub/power.cfg b/INSTALL/grub/power.cfg index 7f6249f0..ede844c2 100644 --- a/INSTALL/grub/power.cfg +++ b/INSTALL/grub/power.cfg @@ -10,6 +10,6 @@ menuentry Halt --class=power_halt { halt } -menuentry 'Return to menu [Esc]' --class=vtoyret VTOY_RET { +menuentry 'Return to previous menu [Esc]' --class=vtoyret VTOY_RET { echo 'Return ...' } diff --git a/INSTALL/grub/themes/ventoy/background.png b/INSTALL/grub/themes/ventoy/background.png index b0190fc6..8a4ac943 100644 Binary files a/INSTALL/grub/themes/ventoy/background.png and b/INSTALL/grub/themes/ventoy/background.png differ diff --git a/INSTALL/grub/themes/ventoy/theme.txt b/INSTALL/grub/themes/ventoy/theme.txt index dda7f27f..f8815065 100644 --- a/INSTALL/grub/themes/ventoy/theme.txt +++ b/INSTALL/grub/themes/ventoy/theme.txt @@ -70,6 +70,22 @@ terminal-box: "terminal_box_*.png" } ++ hbox{ + left = 30%+200 + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_GRUB2_MODE@" color = "red" align = "left"} +} + ++ hbox{ + left = 30%+200 + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_WIMBOOT_MODE@" color = "red" align = "left"} +} + + hbox{ left = 90% top = 55 diff --git a/INSTALL/grub/x86_64-efi/adler32.mod b/INSTALL/grub/x86_64-efi/adler32.mod new file mode 100644 index 00000000..8df78d18 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/adler32.mod differ diff --git a/INSTALL/grub/x86_64-efi/affs.mod b/INSTALL/grub/x86_64-efi/affs.mod new file mode 100644 index 00000000..8c67092e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/affs.mod differ diff --git a/INSTALL/grub/x86_64-efi/afs.mod b/INSTALL/grub/x86_64-efi/afs.mod new file mode 100644 index 00000000..98157773 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/afs.mod differ diff --git a/INSTALL/grub/x86_64-efi/ahci.mod b/INSTALL/grub/x86_64-efi/ahci.mod new file mode 100644 index 00000000..86b274d8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ahci.mod differ diff --git a/INSTALL/grub/x86_64-efi/aout.mod b/INSTALL/grub/x86_64-efi/aout.mod new file mode 100644 index 00000000..db8ab3ea Binary files /dev/null and b/INSTALL/grub/x86_64-efi/aout.mod differ diff --git a/INSTALL/grub/x86_64-efi/appleldr.mod b/INSTALL/grub/x86_64-efi/appleldr.mod new file mode 100644 index 00000000..a4505c39 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/appleldr.mod differ diff --git a/INSTALL/grub/x86_64-efi/archelp.mod b/INSTALL/grub/x86_64-efi/archelp.mod new file mode 100644 index 00000000..62463eec Binary files /dev/null and b/INSTALL/grub/x86_64-efi/archelp.mod differ diff --git a/INSTALL/grub/x86_64-efi/ata.mod b/INSTALL/grub/x86_64-efi/ata.mod new file mode 100644 index 00000000..825e4944 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ata.mod differ diff --git a/INSTALL/grub/x86_64-efi/backtrace.mod b/INSTALL/grub/x86_64-efi/backtrace.mod new file mode 100644 index 00000000..29f9fef5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/backtrace.mod differ diff --git a/INSTALL/grub/x86_64-efi/bfs.mod b/INSTALL/grub/x86_64-efi/bfs.mod new file mode 100644 index 00000000..3065049f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/blscfg.mod b/INSTALL/grub/x86_64-efi/blscfg.mod new file mode 100644 index 00000000..01c54792 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/blscfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/bsd.mod b/INSTALL/grub/x86_64-efi/bsd.mod new file mode 100644 index 00000000..9f5235b0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bsd.mod differ diff --git a/INSTALL/grub/x86_64-efi/bswap_test.mod b/INSTALL/grub/x86_64-efi/bswap_test.mod new file mode 100644 index 00000000..b80415a9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/bswap_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/btrfs.mod b/INSTALL/grub/x86_64-efi/btrfs.mod new file mode 100644 index 00000000..af470c3d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/btrfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbfs.mod b/INSTALL/grub/x86_64-efi/cbfs.mod new file mode 100644 index 00000000..385069bb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbls.mod b/INSTALL/grub/x86_64-efi/cbls.mod new file mode 100644 index 00000000..325251ee Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbls.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbmemc.mod b/INSTALL/grub/x86_64-efi/cbmemc.mod new file mode 100644 index 00000000..1245aacf Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbmemc.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbtable.mod b/INSTALL/grub/x86_64-efi/cbtable.mod new file mode 100644 index 00000000..f46fe4f7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbtable.mod differ diff --git a/INSTALL/grub/x86_64-efi/cbtime.mod b/INSTALL/grub/x86_64-efi/cbtime.mod new file mode 100644 index 00000000..f685e5e7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cbtime.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod b/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod new file mode 100644 index 00000000..57c7bbe7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmdline_cat_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmp.mod b/INSTALL/grub/x86_64-efi/cmp.mod new file mode 100644 index 00000000..29dbd130 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmp.mod differ diff --git a/INSTALL/grub/x86_64-efi/cmp_test.mod b/INSTALL/grub/x86_64-efi/cmp_test.mod new file mode 100644 index 00000000..e750bdb6 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cmp_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/command.lst b/INSTALL/grub/x86_64-efi/command.lst new file mode 100644 index 00000000..b9743610 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/command.lst @@ -0,0 +1,200 @@ +*acpi: acpi +*all_functional_test: functional_test +*background_image: gfxterm_background +*bls_import: blscfg +*blscfg: blscfg +*cat: cat +*cpuid: cpuid +*crc: hashsum +*cryptomount: cryptodisk +*echo: echo +*extract_syslinux_entries_configfile: syslinuxcfg +*extract_syslinux_entries_source: syslinuxcfg +*file: file +*functional_test: functional_test +*gettext: gettext +*hashsum: hashsum +*hdparm: hdparm +*hello: hello +*help: help +*hexdump: hexdump +*inb: iorw +*inl: iorw +*inw: iorw +*keystatus: keystatus +*kfreebsd: bsd +*knetbsd: bsd +*kopenbsd: bsd +*list_env: loadenv +*load_env: loadenv +*loopback: loopback +*ls: ls +*lsacpi: lsacpi +*lspci: lspci +*md5sum: hashsum +*menuentry: normal +*pcidump: pcidump +*probe: probe +*rdmsr: rdmsr +*read_byte: memrw +*read_dword: memrw +*read_word: memrw +*regexp: regexp +*save_env: loadenv +*search: search +*serial: serial +*set_keyboard_layout: setkey +*setkey: setkey +*setpci: setpci +*sha1sum: hashsum +*sha256sum: hashsum +*sha512sum: hashsum +*sleep: sleep +*submenu: normal +*syslinux_configfile: syslinuxcfg +*syslinux_source: syslinuxcfg +*terminfo: terminfo +*test_blockarg: test_blockarg +*testspeed: testspeed +*tr: tr +*trust: pgp +*verify_detached: pgp +*xnu_splash: xnu +*zfskey: zfscrypt +.: configfile +[: test +appleloader: appleldr +authenticate: normal +background_color: gfxterm_background +backtrace: backtrace +badram: mmap +blocklist: blocklist +boot: boot +break: normal +cat: minicmd +cbmemc: cbmemc +chainloader: chain +clear: normal +cmp: cmp +configfile: configfile +continue: normal +coreboot_boottime: cbtime +cutmem: mmap +date: date +distrust: pgp +dump: minicmd +eval: eval +exit: minicmd +export: normal +extract_entries_configfile: configfile +extract_entries_source: configfile +extract_legacy_entries_configfile: legacycfg +extract_legacy_entries_source: legacycfg +fakebios: loadbios +false: true +fix_video: fixvideo +fwsetup: efifwsetup +gptsync: gptsync +halt: halt +help: minicmd +hexdump_random: random +initrd16: linux16 +initrd: linux +initrdefi: linux +keymap: keylayouts +kfreebsd_loadenv: bsd +kfreebsd_module: bsd +kfreebsd_module_elf: bsd +knetbsd_module: bsd +knetbsd_module_elf: bsd +kopenbsd_ramdisk: bsd +legacy_check_password: legacycfg +legacy_configfile: legacycfg +legacy_initrd: legacycfg +legacy_initrd_nounzip: legacycfg +legacy_kernel: legacycfg +legacy_password: legacycfg +legacy_source: legacycfg +linux16: linux16 +linux: linux +linuxefi: linux +list_trusted: pgp +loadbios: loadbios +loadfont: font +lscoreboot: cbls +lsefi: lsefi +lsefimmap: lsefimmap +lsefisystab: lsefisystab +lsfonts: font +lsmmap: lsmmap +lsmod: minicmd +lssal: lssal +macppcbless: macbless +mactelbless: macbless +module2: multiboot2 +module: multiboot +multiboot2: multiboot2 +multiboot: multiboot +nativedisk: nativedisk +net_add_addr: net +net_add_dns: net +net_add_route: net +net_bootp: net +net_del_addr: net +net_del_dns: net +net_del_route: net +net_dhcp: net +net_get_dhcp_option: net +net_ipv6_autoconf: net +net_ls_addr: net +net_ls_cards: net +net_ls_dns: net +net_ls_routes: net +net_nslookup: net +normal: normal +normal_exit: normal +outb: iorw +outl: iorw +outw: iorw +parttool: parttool +password: password +password_pbkdf2: password_pbkdf2 +play: play +read: read +reboot: reboot +return: normal +rmmod: minicmd +search.file: search_fs_file +search.fs_label: search_label +search.fs_uuid: search_fs_uuid +setparams: normal +shift: normal +source: configfile +terminal_input: terminal +terminal_output: terminal +test: test +testload: testload +time: time +true: true +usb: usbtest +videoinfo: videoinfo +videotest: videotest +vt_img_extra_initrd_append: linux +vt_img_extra_initrd_reset: linux +vt_set_boot_opt: linux +vt_unset_boot_opt: linux +write_byte: memrw +write_dword: memrw +write_word: memrw +wrmsr: wrmsr +xnu_devprop_load: xnu +xnu_kernel64: xnu +xnu_kernel: xnu +xnu_kext: xnu +xnu_kextdir: xnu +xnu_mkext: xnu +xnu_ramdisk: xnu +xnu_resume: xnu +xnu_uuid: xnu_uuid +zfs-bootfs: zfsinfo +zfsinfo: zfsinfo diff --git a/INSTALL/grub/x86_64-efi/cpio.mod b/INSTALL/grub/x86_64-efi/cpio.mod new file mode 100644 index 00000000..e774c231 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpio.mod differ diff --git a/INSTALL/grub/x86_64-efi/cpio_be.mod b/INSTALL/grub/x86_64-efi/cpio_be.mod new file mode 100644 index 00000000..621213fd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpio_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/cpuid.mod b/INSTALL/grub/x86_64-efi/cpuid.mod new file mode 100644 index 00000000..03e93898 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cpuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/crc64.mod b/INSTALL/grub/x86_64-efi/crc64.mod new file mode 100644 index 00000000..ec5e9c0a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/crc64.mod differ diff --git a/INSTALL/grub/x86_64-efi/crypto.lst b/INSTALL/grub/x86_64-efi/crypto.lst new file mode 100644 index 00000000..77d9efc0 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/crypto.lst @@ -0,0 +1,45 @@ +RIJNDAEL: gcry_rijndael +RIJNDAEL192: gcry_rijndael +RIJNDAEL256: gcry_rijndael +AES128: gcry_rijndael +AES-128: gcry_rijndael +AES-192: gcry_rijndael +AES-256: gcry_rijndael +ADLER32: adler32 +CRC64: crc64 +ARCFOUR: gcry_arcfour +BLOWFISH: gcry_blowfish +CAMELLIA128: gcry_camellia +CAMELLIA192: gcry_camellia +CAMELLIA256: gcry_camellia +CAST5: gcry_cast5 +CRC32: gcry_crc +CRC32RFC1510: gcry_crc +CRC24RFC2440: gcry_crc +DES: gcry_des +3DES: gcry_des +DSA: gcry_dsa +IDEA: gcry_idea +MD4: gcry_md4 +MD5: gcry_md5 +RFC2268_40: gcry_rfc2268 +AES: gcry_rijndael +AES192: gcry_rijndael +AES256: gcry_rijndael +RIPEMD160: gcry_rmd160 +RSA: gcry_rsa +SEED: gcry_seed +SERPENT128: gcry_serpent +SERPENT192: gcry_serpent +SERPENT256: gcry_serpent +SHA1: gcry_sha1 +SHA224: gcry_sha256 +SHA256: gcry_sha256 +SHA512: gcry_sha512 +SHA384: gcry_sha512 +TIGER192: gcry_tiger +TIGER: gcry_tiger +TIGER2: gcry_tiger +TWOFISH: gcry_twofish +TWOFISH128: gcry_twofish +WHIRLPOOL: gcry_whirlpool diff --git a/INSTALL/grub/x86_64-efi/cryptodisk.mod b/INSTALL/grub/x86_64-efi/cryptodisk.mod new file mode 100644 index 00000000..c56ebf5c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cryptodisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/cs5536.mod b/INSTALL/grub/x86_64-efi/cs5536.mod new file mode 100644 index 00000000..b52ab088 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/cs5536.mod differ diff --git a/INSTALL/grub/x86_64-efi/ctz_test.mod b/INSTALL/grub/x86_64-efi/ctz_test.mod new file mode 100644 index 00000000..e602fd1a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ctz_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/date.mod b/INSTALL/grub/x86_64-efi/date.mod new file mode 100644 index 00000000..5fec5bbe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/date.mod differ diff --git a/INSTALL/grub/x86_64-efi/datehook.mod b/INSTALL/grub/x86_64-efi/datehook.mod new file mode 100644 index 00000000..f398c92f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/datehook.mod differ diff --git a/INSTALL/grub/x86_64-efi/disk.mod b/INSTALL/grub/x86_64-efi/disk.mod new file mode 100644 index 00000000..aab241b1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/disk.mod differ diff --git a/INSTALL/grub/x86_64-efi/div.mod b/INSTALL/grub/x86_64-efi/div.mod new file mode 100644 index 00000000..374129fe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/div.mod differ diff --git a/INSTALL/grub/x86_64-efi/div_test.mod b/INSTALL/grub/x86_64-efi/div_test.mod new file mode 100644 index 00000000..ede46a09 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/div_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/dm_nv.mod b/INSTALL/grub/x86_64-efi/dm_nv.mod new file mode 100644 index 00000000..19a46086 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/dm_nv.mod differ diff --git a/INSTALL/grub/x86_64-efi/efinet.mod b/INSTALL/grub/x86_64-efi/efinet.mod new file mode 100644 index 00000000..6cef7b1b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/efinet.mod differ diff --git a/INSTALL/grub/x86_64-efi/ehci.mod b/INSTALL/grub/x86_64-efi/ehci.mod new file mode 100644 index 00000000..841296f8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ehci.mod differ diff --git a/INSTALL/grub/x86_64-efi/elf.mod b/INSTALL/grub/x86_64-efi/elf.mod new file mode 100644 index 00000000..d4811f86 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/elf.mod differ diff --git a/INSTALL/grub/x86_64-efi/eval.mod b/INSTALL/grub/x86_64-efi/eval.mod new file mode 100644 index 00000000..4c401f84 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/eval.mod differ diff --git a/INSTALL/grub/x86_64-efi/exfctest.mod b/INSTALL/grub/x86_64-efi/exfctest.mod new file mode 100644 index 00000000..fc8d158b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/exfctest.mod differ diff --git a/INSTALL/grub/x86_64-efi/f2fs.mod b/INSTALL/grub/x86_64-efi/f2fs.mod new file mode 100644 index 00000000..4d9e530c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/f2fs.mod differ diff --git a/INSTALL/grub/x86_64-efi/fdt.lst b/INSTALL/grub/x86_64-efi/fdt.lst new file mode 100644 index 00000000..e69de29b diff --git a/INSTALL/grub/x86_64-efi/fixvideo.mod b/INSTALL/grub/x86_64-efi/fixvideo.mod new file mode 100644 index 00000000..625c52e3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/fixvideo.mod differ diff --git a/INSTALL/grub/x86_64-efi/fs.lst b/INSTALL/grub/x86_64-efi/fs.lst new file mode 100644 index 00000000..0acd240b --- /dev/null +++ b/INSTALL/grub/x86_64-efi/fs.lst @@ -0,0 +1,37 @@ +affs +afs +bfs +btrfs +cbfs +cpio +cpio_be +exfat +ext2 +f2fs +fat +hfs +hfsplus +iso9660 +jfs +minix +minix2 +minix2_be +minix3 +minix3_be +minix_be +newc +nilfs2 +ntfs +odc +procfs +reiserfs +romfs +sfs +squash4 +tar +udf +ufs1 +ufs1_be +ufs2 +xfs +zfs diff --git a/INSTALL/grub/x86_64-efi/functional_test.mod b/INSTALL/grub/x86_64-efi/functional_test.mod new file mode 100644 index 00000000..0b2d1469 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/functional_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_arcfour.mod b/INSTALL/grub/x86_64-efi/gcry_arcfour.mod new file mode 100644 index 00000000..97568f76 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_arcfour.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_blowfish.mod b/INSTALL/grub/x86_64-efi/gcry_blowfish.mod new file mode 100644 index 00000000..5d962f43 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_blowfish.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_camellia.mod b/INSTALL/grub/x86_64-efi/gcry_camellia.mod new file mode 100644 index 00000000..b44663b0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_camellia.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_cast5.mod b/INSTALL/grub/x86_64-efi/gcry_cast5.mod new file mode 100644 index 00000000..8a264bf2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_cast5.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_crc.mod b/INSTALL/grub/x86_64-efi/gcry_crc.mod new file mode 100644 index 00000000..7f71a65f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_crc.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_des.mod b/INSTALL/grub/x86_64-efi/gcry_des.mod new file mode 100644 index 00000000..919d2c33 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_des.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_dsa.mod b/INSTALL/grub/x86_64-efi/gcry_dsa.mod new file mode 100644 index 00000000..14134411 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_dsa.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_idea.mod b/INSTALL/grub/x86_64-efi/gcry_idea.mod new file mode 100644 index 00000000..b3043204 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_idea.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_md4.mod b/INSTALL/grub/x86_64-efi/gcry_md4.mod new file mode 100644 index 00000000..b4e2e603 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_md4.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod b/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod new file mode 100644 index 00000000..fed34c01 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rfc2268.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rijndael.mod b/INSTALL/grub/x86_64-efi/gcry_rijndael.mod new file mode 100644 index 00000000..29ac30eb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rijndael.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rmd160.mod b/INSTALL/grub/x86_64-efi/gcry_rmd160.mod new file mode 100644 index 00000000..b8c35dc7 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rmd160.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_rsa.mod b/INSTALL/grub/x86_64-efi/gcry_rsa.mod new file mode 100644 index 00000000..e3a58997 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_rsa.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_seed.mod b/INSTALL/grub/x86_64-efi/gcry_seed.mod new file mode 100644 index 00000000..1fa8178d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_seed.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_serpent.mod b/INSTALL/grub/x86_64-efi/gcry_serpent.mod new file mode 100644 index 00000000..fd12f884 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_serpent.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_sha1.mod b/INSTALL/grub/x86_64-efi/gcry_sha1.mod new file mode 100644 index 00000000..9c6a843c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_sha1.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_sha256.mod b/INSTALL/grub/x86_64-efi/gcry_sha256.mod new file mode 100644 index 00000000..973d7652 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_sha256.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_tiger.mod b/INSTALL/grub/x86_64-efi/gcry_tiger.mod new file mode 100644 index 00000000..686e70bd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_tiger.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_twofish.mod b/INSTALL/grub/x86_64-efi/gcry_twofish.mod new file mode 100644 index 00000000..013c91ff Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_twofish.mod differ diff --git a/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod b/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod new file mode 100644 index 00000000..e10c7859 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gcry_whirlpool.mod differ diff --git a/INSTALL/grub/x86_64-efi/geli.mod b/INSTALL/grub/x86_64-efi/geli.mod new file mode 100644 index 00000000..c5db6467 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/geli.mod differ diff --git a/INSTALL/grub/x86_64-efi/gfxterm_menu.mod b/INSTALL/grub/x86_64-efi/gfxterm_menu.mod new file mode 100644 index 00000000..6783e078 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gfxterm_menu.mod differ diff --git a/INSTALL/grub/x86_64-efi/gptsync.mod b/INSTALL/grub/x86_64-efi/gptsync.mod new file mode 100644 index 00000000..86ecbbfb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/gptsync.mod differ diff --git a/INSTALL/grub/x86_64-efi/hdparm.mod b/INSTALL/grub/x86_64-efi/hdparm.mod new file mode 100644 index 00000000..bd19f3f4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hdparm.mod differ diff --git a/INSTALL/grub/x86_64-efi/hello.mod b/INSTALL/grub/x86_64-efi/hello.mod new file mode 100644 index 00000000..56921863 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hello.mod differ diff --git a/INSTALL/grub/x86_64-efi/help.mod b/INSTALL/grub/x86_64-efi/help.mod new file mode 100644 index 00000000..9c27d63d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/help.mod differ diff --git a/INSTALL/grub/x86_64-efi/hexdump.mod b/INSTALL/grub/x86_64-efi/hexdump.mod new file mode 100644 index 00000000..05c5722a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hexdump.mod differ diff --git a/INSTALL/grub/x86_64-efi/hfs.mod b/INSTALL/grub/x86_64-efi/hfs.mod new file mode 100644 index 00000000..d04180a9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/hfspluscomp.mod b/INSTALL/grub/x86_64-efi/hfspluscomp.mod new file mode 100644 index 00000000..e206005f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/hfspluscomp.mod differ diff --git a/INSTALL/grub/x86_64-efi/iorw.mod b/INSTALL/grub/x86_64-efi/iorw.mod new file mode 100644 index 00000000..707b405b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/iorw.mod differ diff --git a/INSTALL/grub/x86_64-efi/jfs.mod b/INSTALL/grub/x86_64-efi/jfs.mod new file mode 100644 index 00000000..776a758e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/jfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/keylayouts.mod b/INSTALL/grub/x86_64-efi/keylayouts.mod new file mode 100644 index 00000000..2c2f9e7f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/keylayouts.mod differ diff --git a/INSTALL/grub/x86_64-efi/keystatus.mod b/INSTALL/grub/x86_64-efi/keystatus.mod new file mode 100644 index 00000000..3cd5d7cc Binary files /dev/null and b/INSTALL/grub/x86_64-efi/keystatus.mod differ diff --git a/INSTALL/grub/x86_64-efi/ldm.mod b/INSTALL/grub/x86_64-efi/ldm.mod new file mode 100644 index 00000000..baa88e76 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ldm.mod differ diff --git a/INSTALL/grub/x86_64-efi/legacy_password_test.mod b/INSTALL/grub/x86_64-efi/legacy_password_test.mod new file mode 100644 index 00000000..225082ac Binary files /dev/null and b/INSTALL/grub/x86_64-efi/legacy_password_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/legacycfg.mod b/INSTALL/grub/x86_64-efi/legacycfg.mod new file mode 100644 index 00000000..91afa239 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/legacycfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/linux16.mod b/INSTALL/grub/x86_64-efi/linux16.mod new file mode 100644 index 00000000..1aa94eff Binary files /dev/null and b/INSTALL/grub/x86_64-efi/linux16.mod differ diff --git a/INSTALL/grub/x86_64-efi/loadbios.mod b/INSTALL/grub/x86_64-efi/loadbios.mod new file mode 100644 index 00000000..9dae5686 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/loadbios.mod differ diff --git a/INSTALL/grub/x86_64-efi/loadenv.mod b/INSTALL/grub/x86_64-efi/loadenv.mod new file mode 100644 index 00000000..6bfde6bb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/loadenv.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsacpi.mod b/INSTALL/grub/x86_64-efi/lsacpi.mod new file mode 100644 index 00000000..5bda6c1e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsacpi.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefi.mod b/INSTALL/grub/x86_64-efi/lsefi.mod new file mode 100644 index 00000000..23e76746 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefi.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefimmap.mod b/INSTALL/grub/x86_64-efi/lsefimmap.mod new file mode 100644 index 00000000..3cef1a2e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefimmap.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsefisystab.mod b/INSTALL/grub/x86_64-efi/lsefisystab.mod new file mode 100644 index 00000000..ebc59dfb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsefisystab.mod differ diff --git a/INSTALL/grub/x86_64-efi/lsmmap.mod b/INSTALL/grub/x86_64-efi/lsmmap.mod new file mode 100644 index 00000000..b02fe98f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lsmmap.mod differ diff --git a/INSTALL/grub/x86_64-efi/lspci.mod b/INSTALL/grub/x86_64-efi/lspci.mod new file mode 100644 index 00000000..39ef1bee Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lspci.mod differ diff --git a/INSTALL/grub/x86_64-efi/lssal.mod b/INSTALL/grub/x86_64-efi/lssal.mod new file mode 100644 index 00000000..7cfb71c2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lssal.mod differ diff --git a/INSTALL/grub/x86_64-efi/luks.mod b/INSTALL/grub/x86_64-efi/luks.mod new file mode 100644 index 00000000..e0d290f9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/luks.mod differ diff --git a/INSTALL/grub/x86_64-efi/lvm.mod b/INSTALL/grub/x86_64-efi/lvm.mod new file mode 100644 index 00000000..68a81529 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/lvm.mod differ diff --git a/INSTALL/grub/x86_64-efi/macbless.mod b/INSTALL/grub/x86_64-efi/macbless.mod new file mode 100644 index 00000000..4631c364 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/macbless.mod differ diff --git a/INSTALL/grub/x86_64-efi/macho.mod b/INSTALL/grub/x86_64-efi/macho.mod new file mode 100644 index 00000000..d8d73442 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/macho.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid09.mod b/INSTALL/grub/x86_64-efi/mdraid09.mod new file mode 100644 index 00000000..b6768460 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid09.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid09_be.mod b/INSTALL/grub/x86_64-efi/mdraid09_be.mod new file mode 100644 index 00000000..c47e089e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid09_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/mdraid1x.mod b/INSTALL/grub/x86_64-efi/mdraid1x.mod new file mode 100644 index 00000000..8cc64181 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mdraid1x.mod differ diff --git a/INSTALL/grub/x86_64-efi/memdisk.mod b/INSTALL/grub/x86_64-efi/memdisk.mod new file mode 100644 index 00000000..41c1270a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/memdisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/memrw.mod b/INSTALL/grub/x86_64-efi/memrw.mod new file mode 100644 index 00000000..8d9893e1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/memrw.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix.mod b/INSTALL/grub/x86_64-efi/minix.mod new file mode 100644 index 00000000..21548278 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix2.mod b/INSTALL/grub/x86_64-efi/minix2.mod new file mode 100644 index 00000000..402eb731 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix2.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix2_be.mod b/INSTALL/grub/x86_64-efi/minix2_be.mod new file mode 100644 index 00000000..1fd15f37 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix2_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix3.mod b/INSTALL/grub/x86_64-efi/minix3.mod new file mode 100644 index 00000000..b6312831 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix3.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix3_be.mod b/INSTALL/grub/x86_64-efi/minix3_be.mod new file mode 100644 index 00000000..2d24bad4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix3_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/minix_be.mod b/INSTALL/grub/x86_64-efi/minix_be.mod new file mode 100644 index 00000000..a039b6da Binary files /dev/null and b/INSTALL/grub/x86_64-efi/minix_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/moddep.lst b/INSTALL/grub/x86_64-efi/moddep.lst new file mode 100644 index 00000000..2f7f9af5 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/moddep.lst @@ -0,0 +1,267 @@ +videotest: font video gfxmenu +odc: archelp +loopback: extcmd +setkey: extcmd +macho: +gcry_des: crypto +memrw: extcmd +terminfo: extcmd +f2fs: fshelp +part_gpt: +romfs: fshelp +read: +lsefimmap: +aout: +gcry_arcfour: crypto +tftp: net priority_queue +newc: archelp +minix2_be: +elf: +videotest_checksum: font functional_test video_fb +password_pbkdf2: crypto gcry_sha512 pbkdf2 normal +gcry_seed: crypto +pcidump: extcmd +bsd: elf serial crypto gcry_md5 verifiers extcmd aout video boot cpuid relocator mmap +sfs: fshelp +reiserfs: fshelp +part_sunpc: +zstd: +gfxmenu: trig video_colors bitmap_scale gfxterm font normal bitmap video +backtrace: +jfs: +help: extcmd normal +configfile: normal +cbls: cbtable +gfxterm_menu: font functional_test procfs normal video_fb +gcry_idea: crypto +tr: extcmd +shift_test: functional_test +ohci: cs5536 usb boot +afs: fshelp +spkmodem: terminfo +usb_keyboard: keylayouts usb +xzio: crypto +syslinuxcfg: extcmd normal +search_fs_file: +wrmsr: +usbms: scsi usb +test_blockarg: extcmd normal +true: +affs: fshelp +iso9660: fshelp +exfat: fshelp +setjmp_test: setjmp functional_test +gfxterm: font video +efinet: net +disk: +appleldr: boot +xfs: fshelp +testspeed: extcmd normal +cpio_be: archelp +functional_test: btrfs extcmd video video_fb +bswap_test: functional_test +sleep: extcmd normal +memdisk: +gcry_rijndael: crypto +mdraid09_be: diskfilter +gettext: +gcry_sha1: crypto +hfspluscomp: gzio hfsplus +cmp: +random: hexdump +offsetio: +file: elf macho extcmd offsetio +usbserial_usbdebug: serial usb usbserial_common +video_colors: +morse: +hashsum: crypto extcmd normal +usb: +halt: acpi +gfxterm_background: video_colors bitmap_scale gfxterm extcmd video bitmap +search_fs_uuid: +gcry_dsa: pgp mpi +keystatus: extcmd +linux: ventoy verifiers video boot relocator mmap +geli: cryptodisk crypto gcry_sha512 pbkdf2 gcry_sha256 +cmdline_cat_test: font functional_test normal procfs video_fb +rdmsr: extcmd +part_sun: +cbtable: +pbkdf2_test: functional_test pbkdf2 gcry_sha1 +video_bochs: video video_fb +verifiers: +bufio: +usbserial_ftdi: serial usb usbserial_common +legacy_password_test: functional_test legacycfg +cpuid: extcmd +blscfg: extcmd normal +hdparm: extcmd hexdump +bfs: fshelp +gcry_blowfish: crypto +test: +nilfs2: fshelp +gcry_rsa: pgp mpi +cryptodisk: crypto extcmd procfs +nativedisk: +minicmd: +signature_test: functional_test procfs +ata: scsi +udf: fshelp +gzio: gcry_crc +xnu_uuid: gcry_md5 +uhci: usb +pata: ata +mul_test: functional_test +adler32: crypto +terminal: +shim_lock: verifiers +div: +ehci: cs5536 usb boot +crypto: +part_bsd: part_msdos +cs5536: +ventoy: elf fshelp ext2 btrfs font crypto gcry_md5 exfat udf extcmd datetime div normal video gcry_sha1 iso9660 +gcry_sha512: crypto +password: crypto normal +fshelp: +sleep_test: functional_test datetime +iorw: extcmd +xnu: macho bitmap_scale random verifiers extcmd boot video bitmap relocator mmap +mmap: +exfctest: functional_test +zfsinfo: zfs +ldm: part_gpt diskfilter part_msdos +eval: normal +part_dvh: +lssal: +blocklist: +ext2: fshelp +net: priority_queue bufio datetime boot +part_acorn: +videoinfo: video +btrfs: zstd lzopio raid6rec gzio +lsmmap: mmap +strtoull_test: functional_test +bitmap: +ntfs: fshelp +multiboot: net linux video boot relocator mmap +tpm: verifiers +gcry_crc: crypto +png: bufio bitmap +jpeg: bufio bitmap +macbless: disk +div_test: functional_test div +regexp: extcmd normal +parttool: normal +usbserial_pl2303: serial usb usbserial_common +cpio: archelp +gcry_rmd160: crypto +fat: fshelp +ufs1_be: +archelp: +http: net +zfs: gzio +raid6rec: diskfilter +lsefisystab: +minix2: +lsacpi: extcmd acpi +datehook: datetime normal +loadenv: disk extcmd +bitmap_scale: bitmap +probe: extcmd +minix3: +tar: archelp +loadbios: +hfs: fshelp +procfs: archelp +boot: +keylayouts: +progress: normal +kernel: +usbtest: usb +relocator: mmap +acpi: extcmd mmap +tga: bufio bitmap +reboot: +serial: extcmd terminfo +zfscrypt: crypto pbkdf2 extcmd zfs gcry_sha1 gcry_rijndael +efi_uga: video video_fb +dm_nv: diskfilter +cmp_test: functional_test +luks: cryptodisk crypto pbkdf2 +font: bufio video +raid5rec: diskfilter +crc64: crypto +datetime: +efifwsetup: +ctz_test: functional_test +video: +cbmemc: cbtable normal terminfo +hfsplus: fshelp +gcry_cast5: crypto +extcmd: +squash4: fshelp lzopio xzio gzio +part_plan: +minix_be: +gcry_whirlpool: crypto +gcry_tiger: crypto +fixvideo: +search: search_fs_uuid search_fs_file extcmd search_label +lspci: extcmd +cbtime: cbtable +video_fb: +minix3_be: +trig: +msdospart: disk parttool +priority_queue: +gcry_twofish: crypto +part_dfly: +xnu_uuid_test: functional_test +diskfilter: +testload: +part_apple: +hexdump: extcmd +date: datetime normal +pbkdf2: crypto +gcry_sha256: crypto +ls: extcmd normal +usbserial_common: serial usb +ntfscomp: ntfs +lzopio: crypto +video_cirrus: video video_fb +hello: extcmd +scsi: +linux16: linux boot video relocator mmap +cat: extcmd +ahci: ata boot +pgp: crypto verifiers extcmd mpi gcry_sha1 +normal: terminal crypto verifiers bufio extcmd boot gettext +ufs1: +mdraid09: diskfilter +lvm: diskfilter +chain: net efinet boot +cbfs: archelp +ufs2: +time: +setpci: extcmd +gptsync: disk +search_label: +setjmp: +multiboot2: linux net video boot relocator acpi mmap +gcry_rfc2268: crypto +mdraid1x: diskfilter +mpi: crypto +legacycfg: crypto password gcry_md5 normal +play: +part_amiga: +efi_gop: video video_fb +minix: +echo: extcmd +lsefi: +gcry_serpent: crypto +gcry_md4: crypto +gcry_md5: crypto +part_msdos: +gcry_camellia: crypto +at_keyboard: keylayouts boot +all_video: efi_gop efi_uga video_bochs video_cirrus diff --git a/INSTALL/grub/x86_64-efi/morse.mod b/INSTALL/grub/x86_64-efi/morse.mod new file mode 100644 index 00000000..123c9f46 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/morse.mod differ diff --git a/INSTALL/grub/x86_64-efi/mpi.mod b/INSTALL/grub/x86_64-efi/mpi.mod new file mode 100644 index 00000000..54689554 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mpi.mod differ diff --git a/INSTALL/grub/x86_64-efi/msdospart.mod b/INSTALL/grub/x86_64-efi/msdospart.mod new file mode 100644 index 00000000..96e3e8e5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/msdospart.mod differ diff --git a/INSTALL/grub/x86_64-efi/mul_test.mod b/INSTALL/grub/x86_64-efi/mul_test.mod new file mode 100644 index 00000000..4a37424b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/mul_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/multiboot.mod b/INSTALL/grub/x86_64-efi/multiboot.mod new file mode 100644 index 00000000..9a827f20 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/multiboot.mod differ diff --git a/INSTALL/grub/x86_64-efi/multiboot2.mod b/INSTALL/grub/x86_64-efi/multiboot2.mod new file mode 100644 index 00000000..057693d9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/multiboot2.mod differ diff --git a/INSTALL/grub/x86_64-efi/nativedisk.mod b/INSTALL/grub/x86_64-efi/nativedisk.mod new file mode 100644 index 00000000..3061804f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/nativedisk.mod differ diff --git a/INSTALL/grub/x86_64-efi/nilfs2.mod b/INSTALL/grub/x86_64-efi/nilfs2.mod new file mode 100644 index 00000000..2aa661da Binary files /dev/null and b/INSTALL/grub/x86_64-efi/nilfs2.mod differ diff --git a/INSTALL/grub/x86_64-efi/normal.mod b/INSTALL/grub/x86_64-efi/normal.mod index 2acecccc..76065454 100644 Binary files a/INSTALL/grub/x86_64-efi/normal.mod and b/INSTALL/grub/x86_64-efi/normal.mod differ diff --git a/INSTALL/grub/x86_64-efi/ntfscomp.mod b/INSTALL/grub/x86_64-efi/ntfscomp.mod new file mode 100644 index 00000000..9f35f838 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ntfscomp.mod differ diff --git a/INSTALL/grub/x86_64-efi/odc.mod b/INSTALL/grub/x86_64-efi/odc.mod new file mode 100644 index 00000000..512d7e70 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/odc.mod differ diff --git a/INSTALL/grub/x86_64-efi/offsetio.mod b/INSTALL/grub/x86_64-efi/offsetio.mod new file mode 100644 index 00000000..99c12779 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/offsetio.mod differ diff --git a/INSTALL/grub/x86_64-efi/ohci.mod b/INSTALL/grub/x86_64-efi/ohci.mod new file mode 100644 index 00000000..de29f2bb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ohci.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_acorn.mod b/INSTALL/grub/x86_64-efi/part_acorn.mod new file mode 100644 index 00000000..323854af Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_acorn.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_amiga.mod b/INSTALL/grub/x86_64-efi/part_amiga.mod new file mode 100644 index 00000000..b16590fe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_amiga.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_bsd.mod b/INSTALL/grub/x86_64-efi/part_bsd.mod new file mode 100644 index 00000000..d4bf05e2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_bsd.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_dfly.mod b/INSTALL/grub/x86_64-efi/part_dfly.mod new file mode 100644 index 00000000..d7b1d8e4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_dfly.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_dvh.mod b/INSTALL/grub/x86_64-efi/part_dvh.mod new file mode 100644 index 00000000..509c3a6e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_dvh.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_plan.mod b/INSTALL/grub/x86_64-efi/part_plan.mod new file mode 100644 index 00000000..826f54dc Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_plan.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_sun.mod b/INSTALL/grub/x86_64-efi/part_sun.mod new file mode 100644 index 00000000..d054e878 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_sun.mod differ diff --git a/INSTALL/grub/x86_64-efi/part_sunpc.mod b/INSTALL/grub/x86_64-efi/part_sunpc.mod new file mode 100644 index 00000000..b17db009 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/part_sunpc.mod differ diff --git a/INSTALL/grub/x86_64-efi/partmap.lst b/INSTALL/grub/x86_64-efi/partmap.lst new file mode 100644 index 00000000..761233aa --- /dev/null +++ b/INSTALL/grub/x86_64-efi/partmap.lst @@ -0,0 +1,11 @@ +part_acorn +part_amiga +part_apple +part_bsd +part_dfly +part_dvh +part_gpt +part_msdos +part_plan +part_sun +part_sunpc diff --git a/INSTALL/grub/x86_64-efi/parttool.lst b/INSTALL/grub/x86_64-efi/parttool.lst new file mode 100644 index 00000000..68b4b5c4 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/parttool.lst @@ -0,0 +1 @@ +msdos: msdospart diff --git a/INSTALL/grub/x86_64-efi/parttool.mod b/INSTALL/grub/x86_64-efi/parttool.mod new file mode 100644 index 00000000..fd631c01 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/parttool.mod differ diff --git a/INSTALL/grub/x86_64-efi/password.mod b/INSTALL/grub/x86_64-efi/password.mod new file mode 100644 index 00000000..a2dd92d5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/password.mod differ diff --git a/INSTALL/grub/x86_64-efi/pata.mod b/INSTALL/grub/x86_64-efi/pata.mod new file mode 100644 index 00000000..d61ef8d0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pata.mod differ diff --git a/INSTALL/grub/x86_64-efi/pbkdf2_test.mod b/INSTALL/grub/x86_64-efi/pbkdf2_test.mod new file mode 100644 index 00000000..80c9e525 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pbkdf2_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/pcidump.mod b/INSTALL/grub/x86_64-efi/pcidump.mod new file mode 100644 index 00000000..1cecc623 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pcidump.mod differ diff --git a/INSTALL/grub/x86_64-efi/pgp.mod b/INSTALL/grub/x86_64-efi/pgp.mod new file mode 100644 index 00000000..309f6135 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/pgp.mod differ diff --git a/INSTALL/grub/x86_64-efi/play.mod b/INSTALL/grub/x86_64-efi/play.mod new file mode 100644 index 00000000..e101c82c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/play.mod differ diff --git a/INSTALL/grub/x86_64-efi/probe.mod b/INSTALL/grub/x86_64-efi/probe.mod new file mode 100644 index 00000000..af846021 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/probe.mod differ diff --git a/INSTALL/grub/x86_64-efi/procfs.mod b/INSTALL/grub/x86_64-efi/procfs.mod new file mode 100644 index 00000000..01d42e95 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/procfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/progress.mod b/INSTALL/grub/x86_64-efi/progress.mod new file mode 100644 index 00000000..e8448364 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/progress.mod differ diff --git a/INSTALL/grub/x86_64-efi/raid5rec.mod b/INSTALL/grub/x86_64-efi/raid5rec.mod new file mode 100644 index 00000000..b4786b29 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/raid5rec.mod differ diff --git a/INSTALL/grub/x86_64-efi/raid6rec.mod b/INSTALL/grub/x86_64-efi/raid6rec.mod new file mode 100644 index 00000000..bfd0d1b2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/raid6rec.mod differ diff --git a/INSTALL/grub/x86_64-efi/random.mod b/INSTALL/grub/x86_64-efi/random.mod new file mode 100644 index 00000000..83a6c80e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/random.mod differ diff --git a/INSTALL/grub/x86_64-efi/rdmsr.mod b/INSTALL/grub/x86_64-efi/rdmsr.mod new file mode 100644 index 00000000..9bf3269a Binary files /dev/null and b/INSTALL/grub/x86_64-efi/rdmsr.mod differ diff --git a/INSTALL/grub/x86_64-efi/reiserfs.mod b/INSTALL/grub/x86_64-efi/reiserfs.mod new file mode 100644 index 00000000..542ae3ce Binary files /dev/null and b/INSTALL/grub/x86_64-efi/reiserfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/romfs.mod b/INSTALL/grub/x86_64-efi/romfs.mod new file mode 100644 index 00000000..c42d9c7e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/romfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/scsi.mod b/INSTALL/grub/x86_64-efi/scsi.mod new file mode 100644 index 00000000..a5e5e859 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/scsi.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_fs_file.mod b/INSTALL/grub/x86_64-efi/search_fs_file.mod new file mode 100644 index 00000000..d02316d5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_fs_file.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_fs_uuid.mod b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod new file mode 100644 index 00000000..bd5f5558 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_fs_uuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/search_label.mod b/INSTALL/grub/x86_64-efi/search_label.mod new file mode 100644 index 00000000..68ce50dd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/search_label.mod differ diff --git a/INSTALL/grub/x86_64-efi/setjmp.mod b/INSTALL/grub/x86_64-efi/setjmp.mod new file mode 100644 index 00000000..a0b4e571 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setjmp.mod differ diff --git a/INSTALL/grub/x86_64-efi/setjmp_test.mod b/INSTALL/grub/x86_64-efi/setjmp_test.mod new file mode 100644 index 00000000..291d9870 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setjmp_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/setpci.mod b/INSTALL/grub/x86_64-efi/setpci.mod new file mode 100644 index 00000000..908a3ad2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/setpci.mod differ diff --git a/INSTALL/grub/x86_64-efi/sfs.mod b/INSTALL/grub/x86_64-efi/sfs.mod new file mode 100644 index 00000000..2e3a2142 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/sfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/shift_test.mod b/INSTALL/grub/x86_64-efi/shift_test.mod new file mode 100644 index 00000000..5a1321a9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/shift_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/shim_lock.mod b/INSTALL/grub/x86_64-efi/shim_lock.mod new file mode 100644 index 00000000..3e4123a2 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/shim_lock.mod differ diff --git a/INSTALL/grub/x86_64-efi/signature_test.mod b/INSTALL/grub/x86_64-efi/signature_test.mod new file mode 100644 index 00000000..54a3545b Binary files /dev/null and b/INSTALL/grub/x86_64-efi/signature_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/sleep_test.mod b/INSTALL/grub/x86_64-efi/sleep_test.mod new file mode 100644 index 00000000..2722f351 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/sleep_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/spkmodem.mod b/INSTALL/grub/x86_64-efi/spkmodem.mod new file mode 100644 index 00000000..eac5b905 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/spkmodem.mod differ diff --git a/INSTALL/grub/x86_64-efi/strtoull_test.mod b/INSTALL/grub/x86_64-efi/strtoull_test.mod new file mode 100644 index 00000000..24b4245f Binary files /dev/null and b/INSTALL/grub/x86_64-efi/strtoull_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/syslinuxcfg.mod b/INSTALL/grub/x86_64-efi/syslinuxcfg.mod new file mode 100644 index 00000000..971c2094 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/syslinuxcfg.mod differ diff --git a/INSTALL/grub/x86_64-efi/terminal.lst b/INSTALL/grub/x86_64-efi/terminal.lst new file mode 100644 index 00000000..3c9a5a34 --- /dev/null +++ b/INSTALL/grub/x86_64-efi/terminal.lst @@ -0,0 +1,9 @@ +iat_keyboard: at_keyboard +iserial: serial +iserial_*: serial +oaudio: morse +ocbmemc: cbmemc +ogfxterm: gfxterm +oserial: serial +oserial_*: serial +ospkmodem: spkmodem diff --git a/INSTALL/grub/x86_64-efi/test_blockarg.mod b/INSTALL/grub/x86_64-efi/test_blockarg.mod new file mode 100644 index 00000000..742a4806 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/test_blockarg.mod differ diff --git a/INSTALL/grub/x86_64-efi/testload.mod b/INSTALL/grub/x86_64-efi/testload.mod new file mode 100644 index 00000000..1b58c210 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/testload.mod differ diff --git a/INSTALL/grub/x86_64-efi/testspeed.mod b/INSTALL/grub/x86_64-efi/testspeed.mod new file mode 100644 index 00000000..609b3a5d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/testspeed.mod differ diff --git a/INSTALL/grub/x86_64-efi/tga.mod b/INSTALL/grub/x86_64-efi/tga.mod new file mode 100644 index 00000000..02ce149e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tga.mod differ diff --git a/INSTALL/grub/x86_64-efi/time.mod b/INSTALL/grub/x86_64-efi/time.mod new file mode 100644 index 00000000..7112f0cb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/time.mod differ diff --git a/INSTALL/grub/x86_64-efi/tpm.mod b/INSTALL/grub/x86_64-efi/tpm.mod new file mode 100644 index 00000000..811b7ce4 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tpm.mod differ diff --git a/INSTALL/grub/x86_64-efi/tr.mod b/INSTALL/grub/x86_64-efi/tr.mod new file mode 100644 index 00000000..cc015283 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/tr.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs1.mod b/INSTALL/grub/x86_64-efi/ufs1.mod new file mode 100644 index 00000000..ab79b219 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs1.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs1_be.mod b/INSTALL/grub/x86_64-efi/ufs1_be.mod new file mode 100644 index 00000000..296c2fcb Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs1_be.mod differ diff --git a/INSTALL/grub/x86_64-efi/ufs2.mod b/INSTALL/grub/x86_64-efi/ufs2.mod new file mode 100644 index 00000000..c84e55a5 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/ufs2.mod differ diff --git a/INSTALL/grub/x86_64-efi/uhci.mod b/INSTALL/grub/x86_64-efi/uhci.mod new file mode 100644 index 00000000..a9a490c1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/uhci.mod differ diff --git a/INSTALL/grub/x86_64-efi/usb.mod b/INSTALL/grub/x86_64-efi/usb.mod new file mode 100644 index 00000000..423a4632 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usb.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbms.mod b/INSTALL/grub/x86_64-efi/usbms.mod new file mode 100644 index 00000000..ab5848d8 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbms.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_common.mod b/INSTALL/grub/x86_64-efi/usbserial_common.mod new file mode 100644 index 00000000..5a33d89e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_common.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod b/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod new file mode 100644 index 00000000..35cc7afe Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_ftdi.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod b/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod new file mode 100644 index 00000000..1b93dec0 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_pl2303.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod b/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod new file mode 100644 index 00000000..6fd988aa Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbserial_usbdebug.mod differ diff --git a/INSTALL/grub/x86_64-efi/usbtest.mod b/INSTALL/grub/x86_64-efi/usbtest.mod new file mode 100644 index 00000000..b2cc7666 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/usbtest.mod differ diff --git a/INSTALL/grub/x86_64-efi/verifiers.mod b/INSTALL/grub/x86_64-efi/verifiers.mod new file mode 100644 index 00000000..6cb24d3c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/verifiers.mod differ diff --git a/INSTALL/grub/x86_64-efi/video.lst b/INSTALL/grub/x86_64-efi/video.lst new file mode 100644 index 00000000..ae9ba23e --- /dev/null +++ b/INSTALL/grub/x86_64-efi/video.lst @@ -0,0 +1,4 @@ +efi_gop +efi_uga +video_bochs +video_cirrus diff --git a/INSTALL/grub/x86_64-efi/videoinfo.mod b/INSTALL/grub/x86_64-efi/videoinfo.mod new file mode 100644 index 00000000..d30ab126 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videoinfo.mod differ diff --git a/INSTALL/grub/x86_64-efi/videotest.mod b/INSTALL/grub/x86_64-efi/videotest.mod new file mode 100644 index 00000000..9cd7cc55 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videotest.mod differ diff --git a/INSTALL/grub/x86_64-efi/videotest_checksum.mod b/INSTALL/grub/x86_64-efi/videotest_checksum.mod new file mode 100644 index 00000000..afba542d Binary files /dev/null and b/INSTALL/grub/x86_64-efi/videotest_checksum.mod differ diff --git a/INSTALL/grub/x86_64-efi/wrmsr.mod b/INSTALL/grub/x86_64-efi/wrmsr.mod new file mode 100644 index 00000000..66241828 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/wrmsr.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu.mod b/INSTALL/grub/x86_64-efi/xnu.mod new file mode 100644 index 00000000..ad4d811c Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu_uuid.mod b/INSTALL/grub/x86_64-efi/xnu_uuid.mod new file mode 100644 index 00000000..f5cc67f3 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu_uuid.mod differ diff --git a/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod b/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod new file mode 100644 index 00000000..d39261e9 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/xnu_uuid_test.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfs.mod b/INSTALL/grub/x86_64-efi/zfs.mod new file mode 100644 index 00000000..70f1d917 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfs.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfscrypt.mod b/INSTALL/grub/x86_64-efi/zfscrypt.mod new file mode 100644 index 00000000..cb2e7f8e Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfscrypt.mod differ diff --git a/INSTALL/grub/x86_64-efi/zfsinfo.mod b/INSTALL/grub/x86_64-efi/zfsinfo.mod new file mode 100644 index 00000000..7a3af4cd Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zfsinfo.mod differ diff --git a/INSTALL/grub/x86_64-efi/zstd.mod b/INSTALL/grub/x86_64-efi/zstd.mod new file mode 100644 index 00000000..9ba950f1 Binary files /dev/null and b/INSTALL/grub/x86_64-efi/zstd.mod differ diff --git a/INSTALL/plugin/ventoy/theme/background.png b/INSTALL/plugin/ventoy/theme/background.png new file mode 100644 index 00000000..5a5c7710 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/background.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/deepin.png b/INSTALL/plugin/ventoy/theme/icons/deepin.png new file mode 100644 index 00000000..a071b753 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/deepin.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/red-hat.png b/INSTALL/plugin/ventoy/theme/icons/red-hat.png new file mode 100644 index 00000000..df19452a Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/red-hat.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/ubuntu.png b/INSTALL/plugin/ventoy/theme/icons/ubuntu.png new file mode 100644 index 00000000..a8ad2835 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/ubuntu.png differ diff --git a/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png b/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png new file mode 100644 index 00000000..b4e80772 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/icons/vtoyiso.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_c.png b/INSTALL/plugin/ventoy/theme/menu_c.png new file mode 100644 index 00000000..75c165b2 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_e.png b/INSTALL/plugin/ventoy/theme/menu_e.png new file mode 100644 index 00000000..d4c7421b Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_e.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_n.png b/INSTALL/plugin/ventoy/theme/menu_n.png new file mode 100644 index 00000000..5af34692 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_ne.png b/INSTALL/plugin/ventoy/theme/menu_ne.png new file mode 100644 index 00000000..87578685 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_ne.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_nw.png b/INSTALL/plugin/ventoy/theme/menu_nw.png new file mode 100644 index 00000000..87578685 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_nw.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_s.png b/INSTALL/plugin/ventoy/theme/menu_s.png new file mode 100644 index 00000000..6ba27343 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_se.png b/INSTALL/plugin/ventoy/theme/menu_se.png new file mode 100644 index 00000000..959b6091 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_se.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_sw.png b/INSTALL/plugin/ventoy/theme/menu_sw.png new file mode 100644 index 00000000..959b6091 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_sw.png differ diff --git a/INSTALL/plugin/ventoy/theme/menu_w.png b/INSTALL/plugin/ventoy/theme/menu_w.png new file mode 100644 index 00000000..d4c7421b Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/menu_w.png differ diff --git a/INSTALL/plugin/ventoy/theme/select_c.png b/INSTALL/plugin/ventoy/theme/select_c.png new file mode 100644 index 00000000..245259aa Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/select_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_c.png b/INSTALL/plugin/ventoy/theme/slider_c.png new file mode 100644 index 00000000..7d630fdf Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_n.png b/INSTALL/plugin/ventoy/theme/slider_n.png new file mode 100644 index 00000000..41482c90 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/slider_s.png b/INSTALL/plugin/ventoy/theme/slider_s.png new file mode 100644 index 00000000..17adc2ab Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/slider_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_c.png b/INSTALL/plugin/ventoy/theme/terminal_box_c.png new file mode 100644 index 00000000..d0dd52a2 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_c.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_e.png b/INSTALL/plugin/ventoy/theme/terminal_box_e.png new file mode 100644 index 00000000..394cbe4f Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_e.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_n.png b/INSTALL/plugin/ventoy/theme/terminal_box_n.png new file mode 100644 index 00000000..476f8bc6 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_n.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_ne.png b/INSTALL/plugin/ventoy/theme/terminal_box_ne.png new file mode 100644 index 00000000..9e26959b Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_ne.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_nw.png b/INSTALL/plugin/ventoy/theme/terminal_box_nw.png new file mode 100644 index 00000000..5c3cba87 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_nw.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_s.png b/INSTALL/plugin/ventoy/theme/terminal_box_s.png new file mode 100644 index 00000000..85a8901d Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_s.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_se.png b/INSTALL/plugin/ventoy/theme/terminal_box_se.png new file mode 100644 index 00000000..d8627ee5 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_se.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_sw.png b/INSTALL/plugin/ventoy/theme/terminal_box_sw.png new file mode 100644 index 00000000..67c600c8 Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_sw.png differ diff --git a/INSTALL/plugin/ventoy/theme/terminal_box_w.png b/INSTALL/plugin/ventoy/theme/terminal_box_w.png new file mode 100644 index 00000000..d066e2db Binary files /dev/null and b/INSTALL/plugin/ventoy/theme/terminal_box_w.png differ diff --git a/INSTALL/plugin/ventoy/theme/theme.txt b/INSTALL/plugin/ventoy/theme/theme.txt new file mode 100644 index 00000000..f8815065 --- /dev/null +++ b/INSTALL/plugin/ventoy/theme/theme.txt @@ -0,0 +1,96 @@ + +desktop-image: "background.png" +title-text: " " +title-color: "#ffffff" +message-color: "#f2f2f2" + +terminal-box: "terminal_box_*.png" + ++ boot_menu { + left = 10% + width = 80% + top = 30% + height = 50% + + menu_pixmap_style = "menu_*.png" + + item_color = "#ffffff" + item_height = 30 + + item_spacing = 1 + item_padding = 1 + + selected_item_color= "#f2f2f2" + selected_item_pixmap_style = "select_*.png" + + item_icon_space = 0 + + scrollbar = true + scrollbar_width = 10 + scrollbar_thumb = "slider_*.png" +} + ++ progress_bar { + id = "__timeout__" + text = "@TIMEOUT_NOTIFICATION_SHORT@" + + left = 20% + width = 60% + top = 85% + + text_color = "red" + bar_style = "*" + highlight_style = "*" +} + ++ hbox{ + left = 30% + top = 95% + width = 10% + height = 25 + + label {text = "@VTOY_HOTKEY_TIP@" color = "blue" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_MEM_DISK@" color = "red" align = "left"} +} + + ++ hbox{ + left = 30% + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_RAW@" color = "red" align = "left"} +} + + ++ hbox{ + left = 30%+200 + top = 95%-50 + width = 10% + height = 25 + + label {text = "@VTOY_GRUB2_MODE@" color = "red" align = "left"} +} + ++ hbox{ + left = 30%+200 + top = 95%-25 + width = 10% + height = 25 + + label {text = "@VTOY_WIMBOOT_MODE@" color = "red" align = "left"} +} + ++ hbox{ + left = 90% + top = 55 + width = 10% + height = 25 + + label {text = "@VTOY_ISO_UEFI_DRV@" color = "red" align = "left"} +} + diff --git a/INSTALL/plugin/ventoy/ventoy.json b/INSTALL/plugin/ventoy/ventoy.json new file mode 100644 index 00000000..0452aaba --- /dev/null +++ b/INSTALL/plugin/ventoy/ventoy.json @@ -0,0 +1,60 @@ +{ + "control": [ + { "VTOY_DEFAULT_MENU_MODE": "1" }, + { "VTOY_FILT_DOT_UNDERSCORE_FILE": "1" } + ], + + "theme": { + "file": "/ventoy/theme/theme.txt", + "display_mode": "GUI", + "ventoy_left": "5%", + "ventoy_top": "95%", + "ventoy_color": "#0000ff" + }, + + + "menu_class": [ + { + "key": "ubuntu", + "class": "ubuntu" + }, + { + "key": "deepin", + "class": "deepin" + }, + { + "dir": "rhel", + "class": "red-hat" + } + ], + + "menu_alias": [ + { + "image": "/ISO/MX-19.1_x64.iso", + "alias": "MX 19.1 ISO file For me" + }, + { + "image": "/cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso", + "alias": "我的 Windows 10 系统" + } + ], + + "auto_install": [ + { + "image": "/ISO/cn_windows_10.iso", + "template": "/ventoy/script/windows_unattended.cfg" + }, + { + "image": "/ISO/cn_windows_server_2012_r2_vl_x64_dvd_2979220.iso", + "template": [ + "/ventoy/script/windows_unattended1.xml", + "/ventoy/script/windows_unattended2.xml", + "/ventoy/script/windows_unattended3.xml", + "/ventoy/script/windows_unattended4.xml", + "/ventoy/script/windows_unattended5.xml", + "/ventoy/script/windows_unattended6.xml" + ] + } + ] + +} diff --git a/INSTALL/plugin/ventoy/ventoy_grub.cfg b/INSTALL/plugin/ventoy/ventoy_grub.cfg new file mode 100644 index 00000000..f736fb99 --- /dev/null +++ b/INSTALL/plugin/ventoy/ventoy_grub.cfg @@ -0,0 +1,19 @@ +menuentry "My Custom Menu" --class=custom { + echo 'This is custom menu ... ' + sleep 1 +} + +submenu 'My Custom SubMenu -->' --class=customsub { + menuentry "My Custom Menu2" --class=custom2 { + echo 'This is custom menu2 ... ' + sleep 1 + } + + menuentry '<-- Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' + } +} + +menuentry '<-- Return to previous menu [Esc]' --class=vtoyret VTOY_RET { + echo 'Return ...' +} diff --git a/INSTALL/tool/VentoyWorker.sh b/INSTALL/tool/VentoyWorker.sh index 9c6967b9..543ac697 100644 --- a/INSTALL/tool/VentoyWorker.sh +++ b/INSTALL/tool/VentoyWorker.sh @@ -3,19 +3,24 @@ . ./tool/ventoy_lib.sh print_usage() { + echo 'Usage: Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX' echo ' CMD:' - echo ' -i install ventoy to sdX (fail if disk already installed with ventoy)' - echo ' -u update ventoy in sdX' - echo ' -I force install ventoy to sdX (no matter installed or not)' + echo ' -i install Ventoy to sdX (fails if disk already installed with Ventoy)' + echo ' -I force install Ventoy to sdX (no matter installed or not)' + echo ' -u update Ventoy in sdX' + echo ' -l list Ventoy information in sdX' echo '' echo ' OPTION: (optional)' echo ' -r SIZE_MB preserve some space at the bottom of the disk (only for install)' - echo ' -s enable secure boot support (default is disabled)' + echo ' -s/-S enable/disable secure boot support (default is disabled)' + echo ' -g use GPT partition style, default is MBR (only for install)' + echo ' -L Label of the 1st exfat partition (default is Ventoy)' echo '' - } + +VTNEW_LABEL='Ventoy' RESERVE_SIZE_MB=0 while [ -n "$1" ]; do if [ "$1" = "-i" ]; then @@ -25,12 +30,26 @@ while [ -n "$1" ]; do FORCE="Y" elif [ "$1" = "-u" ]; then MODE="update" + elif [ "$1" = "-l" ]; then + MODE="list" elif [ "$1" = "-s" ]; then SECUREBOOT="YES" + elif [ "$1" = "-S" ]; then + SECUREBOOT="NO" + elif [ "$1" = "-g" ]; then + VTGPT="YES" + elif [ "$1" = "-L" ]; then + shift + VTNEW_LABEL=$1 elif [ "$1" = "-r" ]; then RESERVE_SPACE="YES" shift RESERVE_SIZE_MB=$1 + elif [ "$1" = "-V" ] || [ "$1" = "--version" ]; then + exit 0 + elif [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + print_usage + exit 0 else if ! [ -b "$1" ]; then vterr "$1 is NOT a valid device" @@ -54,11 +73,15 @@ if ! [ -b "$DISK" ]; then fi if [ -e /sys/class/block/${DISK#/dev/}/start ]; then - vterr "$DISK is a partition, please use the whole disk" + vterr "$DISK is a partition, please use the whole disk." + echo "For example:" + vterr " sudo sh Ventoy2Disk.sh -i /dev/sdb1 <=== This is wrong" + vtinfo " sudo sh Ventoy2Disk.sh -i /dev/sdb <=== This is right" + echo "" exit 1 fi -if [ -n "$RESERVE_SPACE" ]; then +if [ -n "$RESERVE_SPACE" -a "$MODE" = "install" ]; then if echo $RESERVE_SIZE_MB | grep -q '^[0-9][0-9]*$'; then vtdebug "User will reserve $RESERVE_SIZE_MB MB disk space" else @@ -67,6 +90,57 @@ if [ -n "$RESERVE_SPACE" ]; then fi fi +vtdebug "MODE=$MODE FORCE=$FORCE RESERVE_SPACE=$RESERVE_SPACE RESERVE_SIZE_MB=$RESERVE_SIZE_MB" + +#check tools +if check_tool_work_ok; then + vtdebug "check tool work ok" +else + vterr "Some tools can not run on current system. Please check log.txt for details." + exit 1 +fi + +if [ "$MODE" = "list" ]; then + version=$(get_disk_ventoy_version $DISK) + if [ $? -eq 0 ]; then + echo "Ventoy Version in Disk: $version" + + vtPart1Type=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + if [ "$vtPart1Type" = "EE" ]; then + echo "Disk Partition Style : GPT" + else + echo "Disk Partition Style : MBR" + fi + + if check_disk_secure_boot $DISK; then + echo "Secure Boot Support : YES" + else + echo "Secure Boot Support : NO" + fi + else + echo "Ventoy Version: NA" + fi + echo "" + exit 0 +fi + +#check mountpoint +check_umount_disk "$DISK" + +if grep "$DISK" /proc/mounts; then + vterr "$DISK is already mounted, please umount it first!" + exit 1 +fi + +#check swap partition +if swapon --help 2>&1 | grep -q '^ \-s,'; then + if swapon -s | grep -q "^${DISK}[0-9]"; then + vterr "$DISK is used as swap, please swapoff it first!" + exit 1 + fi +fi + +#check access if dd if="$DISK" of=/dev/null bs=1 count=1 >/dev/null 2>&1; then vtdebug "root permission check ok ..." else @@ -75,48 +149,39 @@ else exit 1 fi -vtdebug "MODE=$MODE FORCE=$FORCE RESERVE_SPACE=$RESERVE_SPACE RESERVE_SIZE_MB=$RESERVE_SIZE_MB" -if ! check_tool_work_ok; then - vterr "Some tools can not run in current system. Please check log.txt for detail." - exit 1 -fi - -grep "^$DISK" /proc/mounts | while read mtline; do - mtpnt=$(echo $mtline | awk '{print $2}') - vtdebug "Trying to umount $mtpnt ..." - umount $mtpnt >/dev/null 2>&1 -done - -if swapon -s | grep -q "^${DISK}[0-9]"; then - swapon -s | grep "^${DISK}[0-9]" | awk '{print $1}' | while read line; do - vtdebug "Trying to swapoff $line ..." - swapoff $line - done -fi - - -if grep "$DISK" /proc/mounts; then - vterr "$DISK is already mounted, please umount it first!" - exit 1 -fi - -if swapon -s | grep -q "^${DISK}[0-9]"; then - vterr "$DISK is used as swap, please swapoff it first!" - exit 1 +#check tmp_mnt directory +if [ -d ./tmp_mnt ]; then + vtdebug "There is a tmp_mnt directory, now delete it." + umount ./tmp_mnt >/dev/null 2>&1 + rm -rf ./tmp_mnt + if [ -d ./tmp_mnt ]; then + vterr "tmp_mnt directory exits, please delete it first." + exit 1 + fi fi if [ "$MODE" = "install" ]; then - vtdebug "install ventoy ..." + vtdebug "install Ventoy ..." - if parted -v > /dev/null 2>&1; then - PARTTOOL='parted' - elif fdisk -v >/dev/null 2>&1; then - PARTTOOL='fdisk' + if [ -n "$VTGPT" ]; then + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + else + vterr "parted is not found in the system, Ventoy can't create new partitions without it." + vterr "You should install \"GNU parted\" first." + exit 1 + fi else - vterr "Both parted and fdisk are not found in the sysstem, Ventoy can't create new partition." - exit 1 + if parted -v > /dev/null 2>&1; then + PARTTOOL='parted' + elif fdisk -v >/dev/null 2>&1; then + PARTTOOL='fdisk' + else + vterr "Both parted and fdisk are not found in the system, Ventoy can't create new partitions." + exit 1 + fi fi version=$(get_disk_ventoy_version $DISK) @@ -124,7 +189,7 @@ if [ "$MODE" = "install" ]; then if [ -z "$FORCE" ]; then vtwarn "$DISK already contains a Ventoy with version $version" vtwarn "Use -u option to do a safe upgrade operation." - vtwarn "OR if you really want to reinstall ventoy to $DISK, please use -I option." + vtwarn "OR if you really want to reinstall Ventoy to $DISK, please use -I option." vtwarn "" exit 1 fi @@ -133,7 +198,7 @@ if [ "$MODE" = "install" ]; then disk_sector_num=$(cat /sys/block/${DISK#/dev/}/size) disk_size_gb=$(expr $disk_sector_num / 2097152) - if [ $disk_sector_num -gt 4294967296 ]; then + if [ $disk_sector_num -gt 4294967296 ] && [ -z "$VTGPT" ]; then vterr "$DISK is over 2TB size, MBR will not work on it." exit 1 fi @@ -148,11 +213,15 @@ if [ "$MODE" = "install" ]; then fi fi - #Print disk info echo "Disk : $DISK" parted -s $DISK p 2>&1 | grep Model - echo "Size : $disk_size_gb GB" + echo "Size : $disk_size_gb GB" + if [ -n "$VTGPT" ]; then + echo "Style: GPT" + else + echo "Style: MBR" + fi echo '' if [ -n "$RESERVE_SPACE" ]; then @@ -165,7 +234,7 @@ if [ "$MODE" = "install" ]; then vtwarn "All the data on the disk $DISK will be lost!!!" echo "" - read -p 'Continue? (y/n)' Answer + read -p 'Continue? (y/n) ' Answer if [ "$Answer" != "y" ]; then if [ "$Answer" != "Y" ]; then exit 0 @@ -174,14 +243,13 @@ if [ "$MODE" = "install" ]; then echo "" vtwarn "All the data on the disk $DISK will be lost!!!" - read -p 'Double-check. Continue? (y/n)' Answer + read -p 'Double-check. Continue? (y/n) ' Answer if [ "$Answer" != "y" ]; then if [ "$Answer" != "Y" ]; then exit 0 fi fi - if [ $disk_sector_num -le $VENTOY_SECTOR_NUM ]; then vterr "No enough space in disk $DISK" exit 1 @@ -192,16 +260,15 @@ if [ "$MODE" = "install" ]; then exit 1 fi - format_ventoy_disk $RESERVE_SIZE_MB $DISK $PARTTOOL - - # format part1 - if ventoy_is_linux64; then - cmd=./tool/mkexfatfs_64 + if [ -n "$VTGPT" ]; then + vtdebug "format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_gpt $RESERVE_SIZE_MB $DISK $PARTTOOL else - cmd=./tool/mkexfatfs_32 + vtdebug "format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL ..." + format_ventoy_disk_mbr $RESERVE_SIZE_MB $DISK $PARTTOOL fi - chmod +x ./tool/* + # format part1 # DiskSize > 32GB Cluster Size use 128KB # DiskSize < 32GB Cluster Size use 32KB @@ -211,20 +278,37 @@ if [ "$MODE" = "install" ]; then cluster_sectors=64 fi - $cmd -n ventoy -s $cluster_sectors ${DISK}1 + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) - chmod +x ./tool/vtoy_gen_uuid + mkexfatfs -n "$VTNEW_LABEL" -s $cluster_sectors ${PART1} vtinfo "writing data to disk ..." + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=446 - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 - ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector + + if [ -n "$VTGPT" ]; then + echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92 + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 + fi + + # check and umount + check_umount_disk "$DISK" + + xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start_sector + + #test UUID + testUUIDStr=$(vtoy_gen_uuid | hexdump -C) + vtdebug "test uuid: $testUUIDStr" #disk uuid - ./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16 + vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} seek=384 bs=1 count=16 #disk signature - ./tool/vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4 + vtoy_gen_uuid | dd status=none conv=fsync of=${DISK} skip=12 seek=440 bs=1 count=4 vtinfo "sync data ..." sync @@ -232,36 +316,44 @@ if [ "$MODE" = "install" ]; then vtinfo "esp partition processing ..." sleep 1 - mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') - if [ -n "$mtpnt" ]; then - umount $mtpnt >/dev/null 2>&1 - fi + check_umount_disk "$DISK" - if [ "$SECUREBOOT" != "YES" ]; then + if [ "$SECUREBOOT" != "YES" ]; then mkdir ./tmp_mnt vtdebug "mounting part2 ...." - for tt in 1 2 3; do - if mount ${DISK}2 ./tmp_mnt; then + for tt in 1 2 3 4 5; do + if mount ${PART2} ./tmp_mnt > /dev/null 2>&1; then vtdebug "mounting part2 success" break fi - mtpnt=$(grep "^${DISK}2" /proc/mounts | awk '{print $2}') - if [ -n "$mtpnt" ]; then - umount $mtpnt >/dev/null 2>&1 - fi + check_umount_disk "$DISK" sleep 2 done - + rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi + rm -f ./tmp_mnt/EFI/BOOT/BOOTIA32.EFI + rm -f ./tmp_mnt/EFI/BOOT/grubia32.efi rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi + rm -f ./tmp_mnt/EFI/BOOT/mmia32.efi rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI + mv ./tmp_mnt/EFI/BOOT/grubia32_real.efi ./tmp_mnt/EFI/BOOT/BOOTIA32.EFI - umount ./tmp_mnt - rm -rf ./tmp_mnt + sync + + for tt in 1 2 3; do + if umount ./tmp_mnt; then + vtdebug "umount part2 success" + rm -rf ./tmp_mnt + break + else + vtdebug "umount part2 failed, now retry..." + sleep 1 + fi + done fi echo "" @@ -269,15 +361,28 @@ if [ "$MODE" = "install" ]; then echo "" else - vtdebug "update ventoy ..." + vtdebug "update Ventoy ..." oldver=$(get_disk_ventoy_version $DISK) if [ $? -ne 0 ]; then - vtwarn "$DISK does not contain ventoy or data corupted" - echo "" - vtwarn "Please use -i option if you want to install ventoy to $DISK" - echo "" - exit 1 + if is_disk_contains_ventoy $DISK; then + oldver="Unknown" + else + vtwarn "$DISK does not contain Ventoy or data corrupted" + echo "" + vtwarn "Please use -i option if you want to install ventoy to $DISK" + echo "" + exit 1 + fi + fi + + #reserve secure boot option + if [ -z "$SECUREBOOT" ]; then + if check_disk_secure_boot $DISK; then + SECUREBOOT="YES" + else + SECUREBOOT="NO" + fi fi curver=$(cat ./ventoy/version) @@ -296,47 +401,91 @@ else SHORT_PART2=${PART2#/dev/} part2_start=$(cat /sys/class/block/$SHORT_PART2/start) + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + + #reserve disk uuid + rm -f ./diskuuid.bin + dd status=none conv=fsync if=${DISK} skip=384 bs=1 count=16 of=./diskuuid.bin + dd status=none conv=fsync if=./boot/boot.img of=$DISK bs=1 count=440 + dd status=none conv=fsync if=./diskuuid.bin of=$DISK bs=1 count=16 seek=384 + rm -f ./diskuuid.bin + + #reserve data + rm -f ./rsvdata.bin + dd status=none conv=fsync if=${DISK} skip=2040 bs=512 count=8 of=./rsvdata.bin + + if [ "$PART1_TYPE" = "EE" ]; then + vtdebug "This is GPT partition style ..." + echo -en '\x22' | dd status=none of=$DISK conv=fsync bs=1 count=1 seek=92 + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2014 seek=34 + echo -en '\x23' | dd of=$DISK conv=fsync bs=1 count=1 seek=17908 status=none + else + vtdebug "This is MBR partition style ..." - PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - - vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE" - if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then - vtdebug "change 1st partition active, 2nd partition inactive ..." - echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none - echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none + PART1_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=446 status=none | hexdump -n1 -e '1/1 "%02X"') + PART2_ACTIVE=$(dd if=$DISK bs=1 count=1 skip=462 status=none | hexdump -n1 -e '1/1 "%02X"') + + vtdebug "PART1_ACTIVE=$PART1_ACTIVE PART2_ACTIVE=$PART2_ACTIVE" + if [ "$PART1_ACTIVE" = "00" ] && [ "$PART2_ACTIVE" = "80" ]; then + vtdebug "change 1st partition active, 2nd partition inactive ..." + echo -en '\x80' | dd of=$DISK conv=fsync bs=1 count=1 seek=446 status=none + echo -en '\x00' | dd of=$DISK conv=fsync bs=1 count=1 seek=462 status=none + fi + xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 fi + + dd status=none conv=fsync if=./rsvdata.bin seek=2040 bs=512 count=8 of=${DISK} + rm -f ./rsvdata.bin + + check_umount_disk "$DISK" - ./tool/xzcat ./boot/core.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=2047 seek=1 - ./tool/xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start + xzcat ./ventoy/ventoy.disk.img.xz | dd status=none conv=fsync of=$DISK bs=512 count=$VENTOY_SECTOR_NUM seek=$part2_start sync - + if [ "$SECUREBOOT" != "YES" ]; then mkdir ./tmp_mnt - vtdebug "mounting part2 ...." - for tt in 1 2 3; do - if mount ${DISK}2 ./tmp_mnt; then + vtdebug "mounting part2 ...." + for tt in 1 2 3 4 5; do + check_umount_disk "$DISK" + + if mount ${PART2} ./tmp_mnt > /dev/null 2>&1; then vtdebug "mounting part2 success" break + else + vtdebug "mounting part2 failed, now wait and retry..." fi - sleep 2 + sleep 2 done - + rm -f ./tmp_mnt/EFI/BOOT/BOOTX64.EFI rm -f ./tmp_mnt/EFI/BOOT/grubx64.efi + rm -f ./tmp_mnt/EFI/BOOT/BOOTIA32.EFI + rm -f ./tmp_mnt/EFI/BOOT/grubia32.efi rm -f ./tmp_mnt/EFI/BOOT/MokManager.efi + rm -f ./tmp_mnt/EFI/BOOT/mmia32.efi rm -f ./tmp_mnt/ENROLL_THIS_KEY_IN_MOKMANAGER.cer mv ./tmp_mnt/EFI/BOOT/grubx64_real.efi ./tmp_mnt/EFI/BOOT/BOOTX64.EFI + mv ./tmp_mnt/EFI/BOOT/grubia32_real.efi ./tmp_mnt/EFI/BOOT/BOOTIA32.EFI - umount ./tmp_mnt - rm -rf ./tmp_mnt + sync + + for tt in 1 2 3; do + if umount ./tmp_mnt > /dev/null 2>&1; then + vtdebug "umount part2 success" + rm -rf ./tmp_mnt + break + else + vtdebug "umount part2 failed, now retry..." + sleep 1 + fi + done fi echo "" - vtinfo "Update Ventoy to $DISK successfully finished." + vtinfo "Update Ventoy on $DISK successfully finished." echo "" fi diff --git a/INSTALL/tool/aarch64/V2DServer b/INSTALL/tool/aarch64/V2DServer new file mode 100644 index 00000000..6663ab58 Binary files /dev/null and b/INSTALL/tool/aarch64/V2DServer differ diff --git a/INSTALL/tool/aarch64/ash b/INSTALL/tool/aarch64/ash new file mode 100644 index 00000000..55eb1455 Binary files /dev/null and b/INSTALL/tool/aarch64/ash differ diff --git a/INSTALL/tool/aarch64/hexdump b/INSTALL/tool/aarch64/hexdump new file mode 100644 index 00000000..0f4e6c2b Binary files /dev/null and b/INSTALL/tool/aarch64/hexdump differ diff --git a/INSTALL/tool/aarch64/mkexfatfs b/INSTALL/tool/aarch64/mkexfatfs new file mode 100644 index 00000000..e22e9f11 Binary files /dev/null and b/INSTALL/tool/aarch64/mkexfatfs differ diff --git a/INSTALL/tool/aarch64/mount.exfat-fuse b/INSTALL/tool/aarch64/mount.exfat-fuse new file mode 100644 index 00000000..0cf851b5 Binary files /dev/null and b/INSTALL/tool/aarch64/mount.exfat-fuse differ diff --git a/INSTALL/tool/aarch64/vtoyfat b/INSTALL/tool/aarch64/vtoyfat new file mode 100644 index 00000000..f1ff7485 Binary files /dev/null and b/INSTALL/tool/aarch64/vtoyfat differ diff --git a/INSTALL/tool/aarch64/vtoygpt b/INSTALL/tool/aarch64/vtoygpt new file mode 100644 index 00000000..420aefca Binary files /dev/null and b/INSTALL/tool/aarch64/vtoygpt differ diff --git a/INSTALL/tool/aarch64/xzcat b/INSTALL/tool/aarch64/xzcat new file mode 100644 index 00000000..4064856a Binary files /dev/null and b/INSTALL/tool/aarch64/xzcat differ diff --git a/INSTALL/tool/i386/V2DServer b/INSTALL/tool/i386/V2DServer new file mode 100644 index 00000000..02f1e5ef Binary files /dev/null and b/INSTALL/tool/i386/V2DServer differ diff --git a/INSTALL/tool/ash b/INSTALL/tool/i386/ash similarity index 100% rename from INSTALL/tool/ash rename to INSTALL/tool/i386/ash diff --git a/INSTALL/tool/hexdump b/INSTALL/tool/i386/hexdump similarity index 100% rename from INSTALL/tool/hexdump rename to INSTALL/tool/i386/hexdump diff --git a/INSTALL/tool/mkexfatfs_32 b/INSTALL/tool/i386/mkexfatfs similarity index 100% rename from INSTALL/tool/mkexfatfs_32 rename to INSTALL/tool/i386/mkexfatfs diff --git a/INSTALL/tool/mount.exfat-fuse_32 b/INSTALL/tool/i386/mount.exfat-fuse similarity index 100% rename from INSTALL/tool/mount.exfat-fuse_32 rename to INSTALL/tool/i386/mount.exfat-fuse diff --git a/INSTALL/tool/vtoyfat_32 b/INSTALL/tool/i386/vtoyfat similarity index 54% rename from INSTALL/tool/vtoyfat_32 rename to INSTALL/tool/i386/vtoyfat index 9ff79668..b372e626 100644 Binary files a/INSTALL/tool/vtoyfat_32 and b/INSTALL/tool/i386/vtoyfat differ diff --git a/INSTALL/tool/i386/vtoygpt b/INSTALL/tool/i386/vtoygpt new file mode 100644 index 00000000..127f080c Binary files /dev/null and b/INSTALL/tool/i386/vtoygpt differ diff --git a/INSTALL/tool/xzcat b/INSTALL/tool/i386/xzcat similarity index 100% rename from INSTALL/tool/xzcat rename to INSTALL/tool/i386/xzcat diff --git a/INSTALL/tool/mips64el/V2DServer b/INSTALL/tool/mips64el/V2DServer new file mode 100644 index 00000000..bb9f481c Binary files /dev/null and b/INSTALL/tool/mips64el/V2DServer differ diff --git a/INSTALL/tool/mips64el/ash b/INSTALL/tool/mips64el/ash new file mode 100644 index 00000000..039e82a6 Binary files /dev/null and b/INSTALL/tool/mips64el/ash differ diff --git a/INSTALL/tool/mips64el/hexdump b/INSTALL/tool/mips64el/hexdump new file mode 100644 index 00000000..dc0d52fb Binary files /dev/null and b/INSTALL/tool/mips64el/hexdump differ diff --git a/INSTALL/tool/mips64el/mkexfatfs b/INSTALL/tool/mips64el/mkexfatfs new file mode 100644 index 00000000..281ab2a1 Binary files /dev/null and b/INSTALL/tool/mips64el/mkexfatfs differ diff --git a/INSTALL/tool/mips64el/mount.exfat-fuse b/INSTALL/tool/mips64el/mount.exfat-fuse new file mode 100644 index 00000000..2702c582 Binary files /dev/null and b/INSTALL/tool/mips64el/mount.exfat-fuse differ diff --git a/INSTALL/tool/mips64el/vtoyfat b/INSTALL/tool/mips64el/vtoyfat new file mode 100644 index 00000000..2ff2eaf8 Binary files /dev/null and b/INSTALL/tool/mips64el/vtoyfat differ diff --git a/INSTALL/tool/mips64el/vtoygpt b/INSTALL/tool/mips64el/vtoygpt new file mode 100644 index 00000000..074d6f09 Binary files /dev/null and b/INSTALL/tool/mips64el/vtoygpt differ diff --git a/INSTALL/tool/mips64el/xzcat b/INSTALL/tool/mips64el/xzcat new file mode 100644 index 00000000..910c74c1 Binary files /dev/null and b/INSTALL/tool/mips64el/xzcat differ diff --git a/INSTALL/tool/ventoy_lib.sh b/INSTALL/tool/ventoy_lib.sh index 6fa869ae..709ce2c0 100644 --- a/INSTALL/tool/ventoy_lib.sh +++ b/INSTALL/tool/ventoy_lib.sh @@ -14,14 +14,6 @@ ventoy_true() { [ "1" = "1" ] } -ventoy_is_linux64() { - if uname -a | egrep -q 'x86_64|amd64'; then - ventoy_true - return - fi - - ventoy_false -} vtinfo() { echo -e "\033[32m$*\033[0m" @@ -40,19 +32,27 @@ vtdebug() { echo "$*" >> ./log.txt } +vtoy_gen_uuid() { + if uuid -F BIN > /dev/null 2>&1; then + uuid -F BIN + elif uuidgen -V > /dev/null 2>&1; then + a=$(uuidgen | sed 's/-//g') + echo -en "\x${a:0:2}\x${a:2:2}\x${a:4:2}\x${a:6:2}\x${a:8:2}\x${a:10:2}\x${a:12:2}\x${a:14:2}\x${a:16:2}\x${a:18:2}\x${a:20:2}\x${a:22:2}\x${a:24:2}\x${a:26:2}\x${a:28:2}\x${a:30:2}" + elif python -V > /dev/null 2>&1; then + a=$(python -c 'import sys,uuid; sys.stdout.write(uuid.uuid4().hex)') + echo -en "\x${a:0:2}\x${a:2:2}\x${a:4:2}\x${a:6:2}\x${a:8:2}\x${a:10:2}\x${a:12:2}\x${a:14:2}\x${a:16:2}\x${a:18:2}\x${a:20:2}\x${a:22:2}\x${a:24:2}\x${a:26:2}\x${a:28:2}\x${a:30:2}" + elif [ -e /dev/urandom ]; then + dd if=/dev/urandom bs=1 count=16 status=none + else + datestr=$(date +%N%N%N%N%N) + a=${datestr:0:32} + echo -en "\x${a:0:2}\x${a:2:2}\x${a:4:2}\x${a:6:2}\x${a:8:2}\x${a:10:2}\x${a:12:2}\x${a:14:2}\x${a:16:2}\x${a:18:2}\x${a:20:2}\x${a:22:2}\x${a:24:2}\x${a:26:2}\x${a:28:2}\x${a:30:2}" + fi +} + check_tool_work_ok() { - if ventoy_is_linux64; then - vtdebug "This is linux 64" - mkexfatfs=mkexfatfs_64 - vtoyfat=vtoyfat_64 - else - vtdebug "This is linux 32" - mkexfatfs=mkexfatfs_32 - vtoyfat=vtoyfat_32 - fi - - if echo 1 | ./tool/hexdump > /dev/null; then + if echo 1 | hexdump > /dev/null; then vtdebug "hexdump test ok ..." else vtdebug "hexdump test fail ..." @@ -60,18 +60,18 @@ check_tool_work_ok() { return fi - if ./tool/$mkexfatfs -V > /dev/null; then - vtdebug "$mkexfatfs test ok ..." + if mkexfatfs -V > /dev/null; then + vtdebug "mkexfatfs test ok ..." else - vtdebug "$mkexfatfs test fail ..." + vtdebug "mkexfatfs test fail ..." ventoy_false return fi - if ./tool/$vtoyfat -T; then - vtdebug "$vtoyfat test ok ..." + if vtoyfat -T; then + vtdebug "vtoyfat test ok ..." else - vtdebug "$vtoyfat test fail ..." + vtdebug "vtoyfat test fail ..." ventoy_false return fi @@ -88,11 +88,23 @@ get_disk_part_name() { echo ${DISK}p${2} elif echo $DISK | grep -q "/dev/nvme[0-9][0-9]*n[0-9]"; then echo ${DISK}p${2} + elif echo $DISK | grep -q "/dev/mmcblk[0-9]"; then + echo ${DISK}p${2} + elif echo $DISK | grep -q "/dev/nbd[0-9]"; then + echo ${DISK}p${2} else echo ${DISK}${2} fi } +check_umount_disk() { + DiskOrPart="$1" + grep "^${DiskOrPart}" /proc/mounts | while read mtline; do + mtpnt=$(echo $mtline | awk '{print $2}') + vtdebug "Trying to umount $mtpnt ..." + umount $mtpnt >/dev/null 2>&1 + done +} get_ventoy_version_from_cfg() { if grep -q 'set.*VENTOY_VERSION=' $1; then @@ -103,7 +115,7 @@ get_ventoy_version_from_cfg() { } is_disk_contains_ventoy() { - DISK=$1 + DISK=$1 PART1=$(get_disk_part_name $1 1) PART2=$(get_disk_part_name $1 2) @@ -126,14 +138,18 @@ is_disk_contains_ventoy() { return fi - PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') - if [ "$PART2_TYPE" != "EF" ]; then - vtdebug "part2 type is $PART2_TYPE not EF" - ventoy_false - return - fi + PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') + PART2_TYPE=$(dd if=$DISK bs=1 count=1 skip=466 status=none | hexdump -n1 -e '1/1 "%02X"') - # PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | ./tool/hexdump -n1 -e '1/1 "%02X"') + # if [ "$PART1_TYPE" != "EE" ]; then + # if [ "$PART2_TYPE" != "EF" ]; then + # vtdebug "part2 type is $PART2_TYPE not EF" + # ventoy_false + # return + # fi + # fi + + # PART1_TYPE=$(dd if=$DISK bs=1 count=1 skip=450 status=none | hexdump -n1 -e '1/1 "%02X"') # if [ "$PART1_TYPE" != "07" ]; then # vtdebug "part1 type is $PART2_TYPE not 07" # ventoy_false @@ -159,6 +175,17 @@ is_disk_contains_ventoy() { ventoy_true } +check_disk_secure_boot() { + if ! is_disk_contains_ventoy $1; then + ventoy_false + return + fi + + PART2=$(get_disk_part_name $1 2) + + vtoyfat -s $PART2 +} + get_disk_ventoy_version() { if ! is_disk_contains_ventoy $1; then @@ -168,13 +195,7 @@ get_disk_ventoy_version() { PART2=$(get_disk_part_name $1 2) - if ventoy_is_linux64; then - cmd=./tool/vtoyfat_64 - else - cmd=./tool/vtoyfat_32 - fi - - ParseVer=$($cmd $PART2) + ParseVer=$(vtoyfat $PART2) if [ $? -eq 0 ]; then vtdebug "Ventoy version in $PART2 is $ParseVer" echo $ParseVer @@ -185,7 +206,7 @@ get_disk_ventoy_version() { ventoy_false } -format_ventoy_disk() { +format_ventoy_disk_mbr() { reserve_mb=$1 DISK=$2 PARTTOOL=$3 @@ -205,6 +226,14 @@ format_ventoy_disk() { fi part2_start_sector=$(expr $part1_end_sector + 1) + + modsector=$(expr $part2_start_sector % 8) + if [ $modsector -gt 0 ]; then + vtdebug "modsector:$modsector need to be aligned with 4KB" + part1_end_sector=$(expr $part1_end_sector - $modsector) + part2_start_sector=$(expr $part1_end_sector + 1) + fi + part2_end_sector=$(expr $part2_start_sector + $VENTOY_SECTOR_NUM - 1) export part2_start_sector @@ -218,7 +247,7 @@ format_ventoy_disk() { fi echo "" - echo "Create partitions on $DISK by $PARTTOOL ..." + echo "Create partitions on $DISK by $PARTTOOL in MBR style ..." if [ "$PARTTOOL" = "parted" ]; then vtdebug "format disk by parted ..." @@ -259,7 +288,7 @@ w EOF fi - udevadm trigger >/dev/null 2>&1 + udevadm trigger --name-match=$DISK >/dev/null 2>&1 partprobe >/dev/null 2>&1 sleep 3 echo "Done" @@ -289,6 +318,115 @@ EOF echo "create efi fat fs $PART2 ..." for i in 0 1 2 3 4 5 6 7 8 9; do + check_umount_disk "$PART2" + + if mkfs.vfat -F 16 -n VTOYEFI -s 1 $PART2; then + echo 'success' + break + else + echo "$? retry ..." + sleep 2 + fi + done +} + + +format_ventoy_disk_gpt() { + reserve_mb=$1 + DISK=$2 + PARTTOOL=$3 + + PART1=$(get_disk_part_name $DISK 1) + PART2=$(get_disk_part_name $DISK 2) + + sector_num=$(cat /sys/block/${DISK#/dev/}/size) + + part1_start_sector=2048 + + if [ $reserve_mb -gt 0 ]; then + reserve_sector_num=$(expr $reserve_mb \* 2048 + 33) + part1_end_sector=$(expr $sector_num - $reserve_sector_num - $VENTOY_SECTOR_NUM - 1) + else + part1_end_sector=$(expr $sector_num - $VENTOY_SECTOR_NUM - 34) + fi + + part2_start_sector=$(expr $part1_end_sector + 1) + + modsector=$(expr $part2_start_sector % 8) + if [ $modsector -gt 0 ]; then + vtdebug "modsector:$modsector need to be aligned with 4KB" + part1_end_sector=$(expr $part1_end_sector - $modsector) + part2_start_sector=$(expr $part1_end_sector + 1) + fi + + part2_end_sector=$(expr $part2_start_sector + $VENTOY_SECTOR_NUM - 1) + + export part2_start_sector + + vtdebug "part1_start_sector=$part1_start_sector part1_end_sector=$part1_end_sector" + vtdebug "part2_start_sector=$part2_start_sector part2_end_sector=$part2_end_sector" + + if [ -e $PART2 ]; then + echo "delete $PART2" + rm -f $PART2 + fi + + echo "" + echo "Create partitions on $DISK by $PARTTOOL in GPT style ..." + + vtdebug "format disk by parted ..." + + if [ "$TOOLDIR" != "aarch64" ]; then + vt_set_efi_type="set 2 msftdata on" + fi + + parted -a none --script $DISK \ + mklabel gpt \ + unit s \ + mkpart Ventoy ntfs $part1_start_sector $part1_end_sector \ + mkpart VTOYEFI fat16 $part2_start_sector $part2_end_sector \ + $vt_set_efi_type \ + set 2 hidden on \ + quit + + sync + + vtoygpt -f $DISK + sync + + udevadm trigger --name-match=$DISK >/dev/null 2>&1 + partprobe >/dev/null 2>&1 + sleep 3 + echo "Done" + + echo 'mkfs on disk partitions ...' + for i in 1 2 3 4 5 6 7; do + if [ -b $PART2 ]; then + break + else + echo "wait $PART2 ..." + sleep 1 + fi + done + + + if ! [ -b $PART2 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART2#/dev/}/dev) + echo "mknod -m 0660 $PART2 b $MajorMinor ..." + mknod -m 0660 $PART2 b $MajorMinor + + if ! [ -b $PART1 ]; then + MajorMinor=$(sed "s/:/ /" /sys/class/block/${PART1#/dev/}/dev) + echo "mknod -m 0660 $PART1 b $MajorMinor ..." + mknod -m 0660 $PART1 b $MajorMinor + fi + fi + + echo "create efi fat fs $PART2 ..." + + for i in 0 1 2 3 4 5 6 7 8 9; do + check_umount_disk "$PART2" + if mkfs.vfat -F 16 -n VTOYEFI $PART2; then echo 'success' break @@ -302,3 +440,4 @@ EOF + diff --git a/INSTALL/tool/vtoy_gen_uuid b/INSTALL/tool/vtoy_gen_uuid deleted file mode 100644 index 8fc29eba..00000000 Binary files a/INSTALL/tool/vtoy_gen_uuid and /dev/null differ diff --git a/INSTALL/tool/vtoyfat_64 b/INSTALL/tool/vtoyfat_64 deleted file mode 100644 index 83c9e02b..00000000 Binary files a/INSTALL/tool/vtoyfat_64 and /dev/null differ diff --git a/INSTALL/tool/x86_64/V2DServer b/INSTALL/tool/x86_64/V2DServer new file mode 100644 index 00000000..9b9d8710 Binary files /dev/null and b/INSTALL/tool/x86_64/V2DServer differ diff --git a/INSTALL/tool/x86_64/ash b/INSTALL/tool/x86_64/ash new file mode 100644 index 00000000..a137ff35 Binary files /dev/null and b/INSTALL/tool/x86_64/ash differ diff --git a/INSTALL/tool/x86_64/hexdump b/INSTALL/tool/x86_64/hexdump new file mode 100644 index 00000000..c6ce5823 Binary files /dev/null and b/INSTALL/tool/x86_64/hexdump differ diff --git a/INSTALL/tool/mkexfatfs_64 b/INSTALL/tool/x86_64/mkexfatfs similarity index 100% rename from INSTALL/tool/mkexfatfs_64 rename to INSTALL/tool/x86_64/mkexfatfs diff --git a/INSTALL/tool/mount.exfat-fuse_64 b/INSTALL/tool/x86_64/mount.exfat-fuse similarity index 100% rename from INSTALL/tool/mount.exfat-fuse_64 rename to INSTALL/tool/x86_64/mount.exfat-fuse diff --git a/INSTALL/tool/x86_64/vtoyfat b/INSTALL/tool/x86_64/vtoyfat new file mode 100644 index 00000000..26e020c6 Binary files /dev/null and b/INSTALL/tool/x86_64/vtoyfat differ diff --git a/INSTALL/tool/x86_64/vtoygpt b/INSTALL/tool/x86_64/vtoygpt new file mode 100644 index 00000000..068aaf6e Binary files /dev/null and b/INSTALL/tool/x86_64/vtoygpt differ diff --git a/INSTALL/tool/x86_64/xzcat b/INSTALL/tool/x86_64/xzcat new file mode 100644 index 00000000..210f9609 Binary files /dev/null and b/INSTALL/tool/x86_64/xzcat differ diff --git a/INSTALL/ventoy/7z/32/7za.exe b/INSTALL/ventoy/7z/32/7za.exe new file mode 100644 index 00000000..2bdd57d2 Binary files /dev/null and b/INSTALL/ventoy/7z/32/7za.exe differ diff --git a/INSTALL/ventoy/7z/64/7za.exe b/INSTALL/ventoy/7z/64/7za.exe new file mode 100644 index 00000000..9f27b20e Binary files /dev/null and b/INSTALL/ventoy/7z/64/7za.exe differ diff --git a/INSTALL/ventoy/dragonfly.mfs.xz b/INSTALL/ventoy/dragonfly.mfs.xz new file mode 100644 index 00000000..6c71a87a Binary files /dev/null and b/INSTALL/ventoy/dragonfly.mfs.xz differ diff --git a/INSTALL/ventoy/ipxe.krn b/INSTALL/ventoy/ipxe.krn index 3815916b..aebf3bbd 100644 Binary files a/INSTALL/ventoy/ipxe.krn and b/INSTALL/ventoy/ipxe.krn differ diff --git a/INSTALL/ventoy/iso9660_aa64.efi b/INSTALL/ventoy/iso9660_aa64.efi new file mode 100644 index 00000000..6d9b8037 Binary files /dev/null and b/INSTALL/ventoy/iso9660_aa64.efi differ diff --git a/INSTALL/ventoy/iso9660_ia32.efi b/INSTALL/ventoy/iso9660_ia32.efi new file mode 100644 index 00000000..81238998 Binary files /dev/null and b/INSTALL/ventoy/iso9660_ia32.efi differ diff --git a/INSTALL/ventoy/udf_aa64.efi b/INSTALL/ventoy/udf_aa64.efi new file mode 100644 index 00000000..bed2b014 Binary files /dev/null and b/INSTALL/ventoy/udf_aa64.efi differ diff --git a/INSTALL/ventoy/udf_ia32.efi b/INSTALL/ventoy/udf_ia32.efi new file mode 100644 index 00000000..ba4ed35f Binary files /dev/null and b/INSTALL/ventoy/udf_ia32.efi differ diff --git a/INSTALL/ventoy/udf_x64.efi b/INSTALL/ventoy/udf_x64.efi new file mode 100644 index 00000000..0f327fbe Binary files /dev/null and b/INSTALL/ventoy/udf_x64.efi differ diff --git a/INSTALL/ventoy/ventoy.cpio b/INSTALL/ventoy/ventoy.cpio index 96816e8d..2545928a 100644 Binary files a/INSTALL/ventoy/ventoy.cpio and b/INSTALL/ventoy/ventoy.cpio differ diff --git a/INSTALL/ventoy/ventoy_aa64.efi b/INSTALL/ventoy/ventoy_aa64.efi new file mode 100644 index 00000000..506a49e1 Binary files /dev/null and b/INSTALL/ventoy/ventoy_aa64.efi differ diff --git a/INSTALL/ventoy/ventoy_arm64.cpio b/INSTALL/ventoy/ventoy_arm64.cpio new file mode 100644 index 00000000..c4ea7af2 Binary files /dev/null and b/INSTALL/ventoy/ventoy_arm64.cpio differ diff --git a/INSTALL/ventoy/ventoy_efiboot.img.xz b/INSTALL/ventoy/ventoy_efiboot.img.xz new file mode 100644 index 00000000..121ef3d1 Binary files /dev/null and b/INSTALL/ventoy/ventoy_efiboot.img.xz differ diff --git a/INSTALL/ventoy/ventoy_ia32.efi b/INSTALL/ventoy/ventoy_ia32.efi new file mode 100644 index 00000000..a891aef8 Binary files /dev/null and b/INSTALL/ventoy/ventoy_ia32.efi differ diff --git a/INSTALL/ventoy/ventoy_mips64.cpio b/INSTALL/ventoy/ventoy_mips64.cpio new file mode 100644 index 00000000..7967349b Binary files /dev/null and b/INSTALL/ventoy/ventoy_mips64.cpio differ diff --git a/INSTALL/ventoy/ventoy_unix.cpio b/INSTALL/ventoy/ventoy_unix.cpio new file mode 100644 index 00000000..f888ffb6 Binary files /dev/null and b/INSTALL/ventoy/ventoy_unix.cpio differ diff --git a/INSTALL/ventoy/ventoy_x64.efi b/INSTALL/ventoy/ventoy_x64.efi index d9709732..1ad45154 100644 Binary files a/INSTALL/ventoy/ventoy_x64.efi and b/INSTALL/ventoy/ventoy_x64.efi differ diff --git a/INSTALL/ventoy/ventoy_x86.cpio b/INSTALL/ventoy/ventoy_x86.cpio new file mode 100644 index 00000000..920f4f50 Binary files /dev/null and b/INSTALL/ventoy/ventoy_x86.cpio differ diff --git a/INSTALL/ventoy/vtloopex.cpio b/INSTALL/ventoy/vtloopex.cpio new file mode 100644 index 00000000..48d2faab Binary files /dev/null and b/INSTALL/ventoy/vtloopex.cpio differ diff --git a/INSTALL/ventoy/vtoyjump32.exe b/INSTALL/ventoy/vtoyjump32.exe index cc54475c..82fe2ed1 100644 Binary files a/INSTALL/ventoy/vtoyjump32.exe and b/INSTALL/ventoy/vtoyjump32.exe differ diff --git a/INSTALL/ventoy/vtoyjump64.exe b/INSTALL/ventoy/vtoyjump64.exe index 9273282e..63659aa7 100644 Binary files a/INSTALL/ventoy/vtoyjump64.exe and b/INSTALL/ventoy/vtoyjump64.exe differ diff --git a/INSTALL/ventoy/vtoyutil_aa64.efi b/INSTALL/ventoy/vtoyutil_aa64.efi new file mode 100644 index 00000000..5dafe9b4 Binary files /dev/null and b/INSTALL/ventoy/vtoyutil_aa64.efi differ diff --git a/INSTALL/ventoy/vtoyutil_ia32.efi b/INSTALL/ventoy/vtoyutil_ia32.efi new file mode 100644 index 00000000..47e40c46 Binary files /dev/null and b/INSTALL/ventoy/vtoyutil_ia32.efi differ diff --git a/INSTALL/ventoy/vtoyutil_x64.efi b/INSTALL/ventoy/vtoyutil_x64.efi new file mode 100644 index 00000000..8cfe7a81 Binary files /dev/null and b/INSTALL/ventoy/vtoyutil_x64.efi differ diff --git a/INSTALL/ventoy/wimboot.i386.efi.xz b/INSTALL/ventoy/wimboot.i386.efi.xz new file mode 100644 index 00000000..42abe44d Binary files /dev/null and b/INSTALL/ventoy/wimboot.i386.efi.xz differ diff --git a/INSTALL/ventoy/wimboot.x86_64.xz b/INSTALL/ventoy/wimboot.x86_64.xz new file mode 100644 index 00000000..3f628676 Binary files /dev/null and b/INSTALL/ventoy/wimboot.x86_64.xz differ diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh index 9e3b4841..8d47fe74 100644 --- a/INSTALL/ventoy_pack.sh +++ b/INSTALL/ventoy_pack.sh @@ -1,8 +1,15 @@ #!/bin/sh +if [ "$1" = "CI" ]; then + OPT='-dR' +else + OPT='-a' +fi + dos2unix -q ./tool/ventoy_lib.sh dos2unix -q ./tool/VentoyWorker.sh + . ./tool/ventoy_lib.sh GRUB_DIR=../GRUB2/INSTALL @@ -16,6 +23,16 @@ fi cd ../IMG sh mkcpio.sh +sh mkloopex.sh +cd - + +cd ../Unix +sh pack_unix.sh +cd - + +cd ../LinuxGUI +sh language.sh || exit 1 +sh build.sh cd - @@ -31,7 +48,7 @@ while ! grep -q 524288 /sys/block/${LOOP#/dev/}/size 2>/dev/null; do sleep 1 done -format_ventoy_disk $LOOP fdisk +format_ventoy_disk_mbr 0 $LOOP fdisk $GRUB_DIR/sbin/grub-bios-setup --skip-fs-probe --directory="./grub/i386-pc" $LOOP @@ -48,21 +65,28 @@ mount ${LOOP}p2 $tmpmnt mkdir -p $tmpmnt/grub # First copy grub.cfg file, to make it locate at front of the part2 -cp -a ./grub/grub.cfg $tmpmnt/grub/ +cp $OPT ./grub/grub.cfg $tmpmnt/grub/ ls -1 ./grub/ | grep -v 'grub\.cfg' | while read line; do - cp -a ./grub/$line $tmpmnt/grub/ + cp $OPT ./grub/$line $tmpmnt/grub/ done -cp -a ./ventoy $tmpmnt/ -cp -a ./EFI $tmpmnt/ -cp -a ./tool/ENROLL_THIS_KEY_IN_MOKMANAGER.cer $tmpmnt/ +cp $OPT ./ventoy $tmpmnt/ +cp $OPT ./EFI $tmpmnt/ +cp $OPT ./tool/ENROLL_THIS_KEY_IN_MOKMANAGER.cer $tmpmnt/ mkdir -p $tmpmnt/tool -cp -a ./tool/mount* $tmpmnt/tool/ +# cp $OPT ./tool/i386/mount.exfat-fuse $tmpmnt/tool/mount.exfat-fuse_i386 +# cp $OPT ./tool/x86_64/mount.exfat-fuse $tmpmnt/tool/mount.exfat-fuse_x86_64 +# cp $OPT ./tool/aarch64/mount.exfat-fuse $tmpmnt/tool/mount.exfat-fuse_aarch64 +# to save space +cp $OPT ./tool/i386/vtoygpt $tmpmnt/tool/mount.exfat-fuse_i386 +cp $OPT ./tool/x86_64/vtoygpt $tmpmnt/tool/mount.exfat-fuse_x86_64 +cp $OPT ./tool/aarch64/vtoygpt $tmpmnt/tool/mount.exfat-fuse_aarch64 -rm -f $tmpmnt/grub/i386-pc/* + +rm -f $tmpmnt/grub/i386-pc/*.img umount $tmpmnt && rm -rf $tmpmnt @@ -76,11 +100,25 @@ dd if=$LOOP of=$tmpdir/boot/boot.img bs=1 count=512 status=none dd if=$LOOP of=$tmpdir/boot/core.img bs=512 count=2047 skip=1 status=none xz --check=crc32 $tmpdir/boot/core.img -cp -a ./tool $tmpdir/ -cp -a Ventoy2Disk.sh $tmpdir/ -cp -a CreatePersistentImg.sh $tmpdir/ +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 Ventoy.desktop $tmpdir/ +cp $OPT README $tmpdir/ +cp $OPT plugin $tmpdir/ +cp $OPT CreatePersistentImg.sh $tmpdir/ +cp $OPT ExtendPersistentImg.sh $tmpdir/ dos2unix -q $tmpdir/Ventoy2Disk.sh +dos2unix -q $tmpdir/VentoyWeb.sh + +#dos2unix -q $tmpdir/Ventoy.desktop dos2unix -q $tmpdir/CreatePersistentImg.sh +dos2unix -q $tmpdir/ExtendPersistentImg.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 @@ -92,28 +130,51 @@ rm -f ventoy-${curver}-linux.tar.gz CurDir=$PWD -cd $tmpdir/tool -for file in $(ls); do - if [ "$file" != "xzcat" ] && [ "$file" != "ventoy_lib.sh" ]; then - xz --check=crc32 $file - fi +for d in i386 x86_64 aarch64; do + cd $tmpdir/tool/$d + for file in $(ls); do + if [ "$file" != "xzcat" ]; then + xz --check=crc32 $file + fi + done + cd $CurDir done -cd $CurDir +#chmod +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/Ventoy.desktop +chmod +x $tmpdir/CreatePersistentImg.sh +chmod +x $tmpdir/ExtendPersistentImg.sh + tar -czvf ventoy-${curver}-linux.tar.gz $tmpdir + + rm -f ventoy-${curver}-windows.zip -cp -a Ventoy2Disk.exe $tmpdir/ -cp -a $LANG_DIR/languages.ini $tmpdir/ventoy/ +cp $OPT Ventoy2Disk*.exe $tmpdir/ +cp $OPT $LANG_DIR/languages.json $tmpdir/ventoy/ rm -rf $tmpdir/tool rm -f $tmpdir/*.sh +rm -rf $tmpdir/WebUI +rm -f $tmpdir/README zip -r ventoy-${curver}-windows.zip $tmpdir/ rm -rf $tmpdir +echo "=============== run livecd.sh ===============" +cd ../LiveCD +sh livecd.sh $1 +cd $CurDir + +mv ../LiveCD/ventoy*.iso ./ + if [ -e ventoy-${curver}-windows.zip ] && [ -e ventoy-${curver}-linux.tar.gz ]; then echo -e "\n ============= SUCCESS =================\n" else diff --git a/IPXE/buildipxe.sh b/IPXE/buildipxe.sh index 27bbdee7..ce8e789d 100644 --- a/IPXE/buildipxe.sh +++ b/IPXE/buildipxe.sh @@ -2,7 +2,7 @@ rm -rf ipxe-3fe683e -tar -xvf ipxe_org_code/ipxe-3fe683e.tar.bz2 -C ./ +tar -xf ipxe_org_code/ipxe-3fe683e.tar.bz2 -C ./ rm -rf ./ipxe-3fe683e/src/bin rm -rf ./ipxe-3fe683e/src/drivers @@ -11,6 +11,7 @@ rm -rf ./ipxe-3fe683e/src/drivers cd ipxe-3fe683e/src +echo '========= build IPXE ==========' sh build.sh cd ../../ diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c index d3ccb2b4..074f1afe 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/core/ventoy_vdisk.c @@ -25,6 +25,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include int g_debug = 0; +int g_hddmode = 0; +int g_bios_disk80 = 0; char *g_cmdline_copy; void *g_initrd_addr; size_t g_initrd_len; @@ -55,6 +57,40 @@ uint64 g_fixup_iso9660_secover_tot_secs = 0; static struct int13_disk_address __bss16 ( ventoy_address ); #define ventoy_address __use_data16 ( ventoy_address ) +static uint64_t ventoy_remap_lba_hdd(uint64_t lba, uint32_t *count) +{ + uint32_t i; + uint32_t max_sectors; + ventoy_img_chunk *cur; + + if ((NULL == g_cur_chunk) || (lba < g_cur_chunk->img_start_sector) || + (lba > g_cur_chunk->img_end_sector)) + { + g_cur_chunk = NULL; + for (i = 0; i < g_img_chunk_num; i++) + { + cur = g_chunk + i; + if (lba >= cur->img_start_sector && lba <= cur->img_end_sector) + { + g_cur_chunk = cur; + break; + } + } + } + + if (g_cur_chunk) + { + max_sectors = g_cur_chunk->img_end_sector - lba + 1; + if (*count > max_sectors) + { + *count = max_sectors; + } + + return g_cur_chunk->disk_start_sector + (lba - g_cur_chunk->img_start_sector); + } + return lba; +} + static uint64_t ventoy_remap_lba(uint64_t lba, uint32_t *count) { uint32_t i; @@ -92,6 +128,72 @@ static uint64_t ventoy_remap_lba(uint64_t lba, uint32_t *count) return lba; } +static int ventoy_vdisk_read_real_hdd(uint64_t lba, unsigned int count, unsigned long buffer) +{ + uint32_t left = 0; + uint32_t readcount = 0; + uint32_t tmpcount = 0; + uint16_t status = 0; + uint64_t curlba = 0; + uint64_t maplba = 0; + unsigned long phyaddr; + + curlba = lba; + left = count; + +#if VTOY_DEBUG + printf("ventoy_vdisk_read_real_hdd: %llu %u\n", lba, count); +#endif + + while (left > 0) + { + readcount = left; + maplba = ventoy_remap_lba_hdd(curlba, &readcount); + + tmpcount = readcount; + + phyaddr = user_to_phys(buffer, 0); + + while (tmpcount > 0) + { + /* Use INT 13, 42 to read the data from real disk */ + ventoy_address.lba = maplba; + ventoy_address.buffer.segment = (uint16_t)(phyaddr >> 4); + ventoy_address.buffer.offset = (uint16_t)(phyaddr & 0x0F); + + if (tmpcount >= 64) /* max sectors per transmit */ + { + ventoy_address.count = 64; + tmpcount -= 64; + maplba += 64; + phyaddr += 32768; + } + else + { + ventoy_address.count = tmpcount; + tmpcount = 0; + } + + __asm__ __volatile__ ( REAL_CODE ( "stc\n\t" + "sti\n\t" + "int $0x13\n\t" + "sti\n\t" /* BIOS bugs */ + "jc 1f\n\t" + "xorw %%ax, %%ax\n\t" + "\n1:\n\t" ) + : "=a" ( status ) + : "a" ( 0x4200 ), "d" ( VENTOY_BIOS_FAKE_DRIVE ), + "S" ( __from_data16 ( &ventoy_address ) ) ); + } + + curlba += readcount; + left -= readcount; + buffer += (readcount * 512); + } + + return 0; +} + static int ventoy_vdisk_read_real(uint64_t lba, unsigned int count, unsigned long buffer) { uint32_t i = 0; @@ -284,6 +386,7 @@ int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int coun uint32_t lbacount = 0; unsigned long lastbuffer; uint64_t readend; + uint64_t VirtSec; ventoy_virt_chunk *node; ventoy_sector_flag *cur_flag; ventoy_sector_flag *sector_flag = g_sector_flag; @@ -297,6 +400,26 @@ int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int coun ix86 = (struct i386_all_regs *)sandev->x86_regptr; + if (g_hddmode) + { + #if 0 + /* need to check ?? */ + lastlba = g_chain->virt_img_size_in_bytes / 512; + if (lba < lastlba) + { + if (lba + count > lastlba) + { + count = lastlba - lba; + } + ventoy_vdisk_read_real_hdd(lba, count, buffer); + } + #endif + + ventoy_vdisk_read_real_hdd(lba, count, buffer); + ix86->regs.dl = sandev->drive; + return 0; + } + /* Workaround for SSTR PE loader error */ if (g_fixup_iso9660_secover_start) { @@ -310,6 +433,33 @@ int ventoy_vdisk_read(struct san_device *sandev, uint64_t lba, unsigned int coun ix86->regs.dl = sandev->drive; return 0; } + else if ((lba * 2048) < g_chain->real_img_size_in_bytes) + { + /* fix for grub4dos Inconsistent data read from error */ + memset((void *)(buffer + (count - 1) * 2048), 0, 2048); + + count = (g_chain->real_img_size_in_bytes / 2048) - lba; + ventoy_vdisk_read_real(lba, count, buffer); + ix86->regs.dl = sandev->drive; + + lba += count; + buffer += count * 2048; + count = (readend - g_chain->real_img_size_in_bytes) / 2048; + } + + VirtSec = g_chain->virt_img_size_in_bytes / 2048; + if (lba >= VirtSec) + { + /* fix for grub4dos Inconsistent data read from error */ + memset((void *)(buffer + (count - 1) * 2048), 0, 2048); + + ix86->regs.dl = sandev->drive; + return 0; + } + else if (lba + count > VirtSec) + { + count = VirtSec - lba; + } if (count > sizeof(g_sector_flag)) { @@ -441,9 +591,12 @@ static void ventoy_dump_chain(ventoy_chain_head *chain) uint32_t i = 0; uint8_t chksum = 0; uint8_t *guid; + uint8_t *sig; uint8_t *vtoy_reserve; guid = chain->os_param.vtoy_disk_guid; + sig = chain->os_param.vtoy_disk_signature; + for (i = 0; i < sizeof(ventoy_os_param); i++) { chksum += *((uint8_t *)(&(chain->os_param)) + i); @@ -457,6 +610,7 @@ static void ventoy_dump_chain(ventoy_chain_head *chain) printf("os_param->chksum=0x%x (%s)\n", chain->os_param.chksum, chksum ? "FAILED" : "SUCCESS"); printf("os_param->vtoy_disk_guid=%02x%02x%02x%02x\n", guid[0], guid[1], guid[2], guid[3]); + printf("os_param->vtoy_disk_signature=%02x%02x%02x%02x\n", sig[0], sig[1], sig[2], sig[3]); printf("os_param->vtoy_disk_size=%llu\n", chain->os_param.vtoy_disk_size); printf("os_param->vtoy_disk_part_id=%u\n", chain->os_param.vtoy_disk_part_id); printf("os_param->vtoy_disk_part_type=%u\n", chain->os_param.vtoy_disk_part_type); @@ -530,19 +684,33 @@ static int ventoy_update_image_location(ventoy_os_param *param) } memcpy(&location->guid, ¶m->guid, sizeof(ventoy_guid)); - location->image_sector_size = 2048; + location->image_sector_size = g_hddmode ? 512 : 2048; location->disk_sector_size = g_chain->disk_sector_size; location->region_count = g_img_chunk_num; region = location->regions; - for (i = 0; i < g_img_chunk_num; i++) + if (g_hddmode) { - region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; - region->image_start_sector = chunk->img_start_sector; - region->disk_start_sector = chunk->disk_start_sector; - region++; - chunk++; + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->disk_end_sector - chunk->disk_start_sector + 1; + region->image_start_sector = chunk->img_start_sector * 4; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } + } + else + { + for (i = 0; i < g_img_chunk_num; i++) + { + region->image_sector_count = chunk->img_end_sector - chunk->img_start_sector + 1; + region->image_start_sector = chunk->img_start_sector; + region->disk_start_sector = chunk->disk_start_sector; + region++; + chunk++; + } } return 0; @@ -553,6 +721,7 @@ int ventoy_boot_vdisk(void *data) uint8_t chksum = 0; unsigned int i; unsigned int drive; + ventoy_img_chunk *cur; (void)data; @@ -562,8 +731,19 @@ int ventoy_boot_vdisk(void *data) { g_debug = 1; printf("### ventoy chain boot begin... ###\n"); + printf("cmdline: <%s>\n", g_cmdline_copy); ventoy_debug_pause(); } + + if (strstr(g_cmdline_copy, "sector512")) + { + g_hddmode = 1; + } + + if (strstr(g_cmdline_copy, "bios80")) + { + g_bios_disk80 = 1; + } g_chain = (ventoy_chain_head *)g_initrd_addr; g_chunk = (ventoy_img_chunk *)((char *)g_chain + g_chain->img_chunk_offset); @@ -574,7 +754,7 @@ int ventoy_boot_vdisk(void *data) g_os_param_reserved = (uint8_t *)(g_chain->os_param.vtoy_reserved); /* Workaround for Windows & ISO9660 */ - if (g_os_param_reserved[2] == 1 && g_os_param_reserved[3] == 0) + if (g_os_param_reserved[2] == ventoy_chain_windows && g_os_param_reserved[3] == 0) { g_fixup_iso9660_secover_enable = 1; } @@ -601,6 +781,16 @@ int ventoy_boot_vdisk(void *data) ventoy_dump_chain(g_chain); } + if (g_hddmode) + { + for (i = 0; i < g_img_chunk_num; i++) + { + cur = g_chunk + i; + cur->img_start_sector *= 4; + cur->img_end_sector = cur->img_end_sector * 4 + 3; + } + } + drive = ventoy_int13_hook(g_chain); if (g_debug) diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.c b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.c index 9f61c473..2671761d 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.c +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/arch/x86/interface/pcbios/ventoy_int13.c @@ -1051,6 +1051,10 @@ static __asmcall void int13 ( struct i386_all_regs *ix86 ) { /* We simulate a cdrom, so no need to sync hd drive number */ //int13_check_num_drives(); + #if VTOY_DEBUG + printf("int13 0x%x 0x%x\n", bios_drive, command); sleep(1); + #endif + if (bios_drive == VENTOY_BIOS_FAKE_DRIVE) { ix86->regs.dl = g_sandev->exdrive; @@ -1255,39 +1259,15 @@ static void int13_hook_vector ( void ) { * @ret rc Return status code */ static int int13_load_mbr ( unsigned int drive, struct segoff *address ) { - uint16_t status; - int discard_b, discard_c, discard_d; uint16_t magic; - /* Use INT 13, 02 to read the MBR */ - address->segment = 0; - address->offset = 0x7c00; - __asm__ __volatile__ ( REAL_CODE ( "pushw %%es\n\t" - "pushl %%ebx\n\t" - "popw %%bx\n\t" - "popw %%es\n\t" - "stc\n\t" - "sti\n\t" - "int $0x13\n\t" - "sti\n\t" /* BIOS bugs */ - "jc 1f\n\t" - "xorw %%ax, %%ax\n\t" - "\n1:\n\t" - "popw %%es\n\t" ) - : "=a" ( status ), "=b" ( discard_b ), - "=c" ( discard_c ), "=d" ( discard_d ) - : "a" ( 0x0201 ), "b" ( *address ), - "c" ( 1 ), "d" ( drive ) ); - if ( status ) { - DBG ( "INT13 drive %02x could not read MBR (status %04x)\n", - drive, status ); - return -EIO; - } + address->segment = 0; + address->offset = 0x7c00; + copy_to_real(address->segment, address->offset, g_sandev->boot_catalog_sector, 512); /* Check magic signature */ - get_real ( magic, address->segment, - ( address->offset + - offsetof ( struct master_boot_record, magic ) ) ); + get_real ( magic, address->segment, (address->offset + offsetof ( struct master_boot_record, magic ) ) ); + if ( magic != INT13_MBR_MAGIC ) { DBG ( "INT13 drive %02x does not contain a valid MBR\n", drive ); @@ -1374,6 +1354,15 @@ static int int13_load_eltorito ( unsigned int drive, struct segoff *address ) { DBG ( "INT13 drive %02x El Torito boot image loads at %04x:%04x\n", drive, address->segment, address->offset ); + if (catalog.boot.length > 256) + { + if (g_debug) + { + printf("trim length from %d to 4\n", catalog.boot.length); + } + catalog.boot.length = 4; + } + /* Use INT 13, 42 to read the boot image */ eltorito_address.bufsize = offsetof ( typeof ( eltorito_address ), buffer_phys ); @@ -1443,8 +1432,14 @@ unsigned int ventoy_int13_hook (ventoy_chain_head *chain) /* hook will copy num_drives to dl when int13 08 was called, so must initialize it's value */ get_real(num_drives, BDA_SEG, BDA_NUM_DRIVES); - //natural_drive = num_drives | 0x80; - natural_drive = 0xE0; /* just set a cdrom drive number 224 */ + if (g_hddmode) + { + natural_drive = g_bios_disk80 ? 0x80 : (num_drives | 0x80); + } + else + { + natural_drive = 0xE0; /* just set a cdrom drive number 224 */ + } if (chain->disk_drive >= 0x80 && chain->drive_map >= 0x80) { @@ -1456,8 +1451,8 @@ unsigned int ventoy_int13_hook (ventoy_chain_head *chain) g_sandev = zalloc(sizeof(struct san_device) + sizeof(struct int13_data)); g_sandev->priv = int13 = (struct int13_data *)(g_sandev + 1); g_sandev->drive = int13->natural_drive = natural_drive; - g_sandev->is_cdrom = 1; - g_sandev->blksize_shift = 2; + g_sandev->is_cdrom = g_hddmode ? 0 : 1; + g_sandev->blksize_shift = g_hddmode ? 0 : 2; g_sandev->capacity.blksize = 512; g_sandev->capacity.blocks = chain->virt_img_size_in_bytes / 512; g_sandev->exdrive = chain->disk_drive; @@ -1521,9 +1516,20 @@ int ventoy_int13_boot ( unsigned int drive, void *imginfo, const char *cmdline) struct ibft_table *ibft = NULL; /* Look for a usable boot sector */ - if ( ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) && - ( ( rc = int13_load_mbr ( drive, &address ) ) != 0 )) + if (g_hddmode) + { + if ((rc = int13_load_mbr(drive, &address)) != 0) + { + printf("int13_load_mbr %d\n", rc); + return rc; + } + } + else + { + if ( ( ( rc = int13_load_eltorito ( drive, &address ) ) != 0 ) && + ( ( rc = int13_load_mbr ( drive, &address ) ) != 0 )) return rc; + } if (imginfo) { diff --git a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h index 1898d7ac..b10534d4 100644 --- a/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h +++ b/IPXE/ipxe_mod_code/ipxe-3fe683e/src/include/ventoy.h @@ -4,6 +4,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); +//#define VTOY_DEBUG 1 + #define grub_uint64_t uint64_t #define grub_uint32_t uint32_t #define grub_uint16_t uint16_t @@ -13,6 +15,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #define VENTOY_GUID { 0x77772020, 0x2e77, 0x6576, { 0x6e, 0x74, 0x6f, 0x79, 0x2e, 0x6e, 0x65, 0x74 }} +typedef enum ventoy_chain_type +{ + ventoy_chain_linux = 0, /* 0: linux */ + ventoy_chain_windows, /* 1: windows */ + ventoy_chain_wim, /* 2: wim */ + + ventoy_chain_max +}ventoy_chain_type; + #pragma pack(1) typedef struct ventoy_guid @@ -34,7 +45,7 @@ typedef struct ventoy_image_location { ventoy_guid guid; - /* image sector size, currently this value is always 2048 */ + /* image sector size, 2048/512 */ grub_uint32_t image_sector_size; /* disk sector size, normally the value is 512 */ @@ -77,7 +88,9 @@ typedef struct ventoy_os_param grub_uint64_t vtoy_reserved[4]; // Internal use by ventoy - grub_uint8_t reserved[31]; + grub_uint8_t vtoy_disk_signature[4]; + + grub_uint8_t reserved[27]; }ventoy_os_param; typedef struct ventoy_iso9660_override @@ -173,6 +186,8 @@ typedef struct ventoy_sector_flag #define VENTOY_BOOT_FIXBIN_DRIVE 0xFD extern int g_debug; +extern int g_hddmode; +extern int g_bios_disk80; extern char *g_cmdline_copy; extern void *g_initrd_addr; extern size_t g_initrd_len; diff --git a/KBD/cfg/KBD_AZERTY.cfg b/KBD/cfg/KBD_AZERTY.cfg new file mode 100644 index 00000000..6c6c7fc0 --- /dev/null +++ b/KBD/cfg/KBD_AZERTY.cfg @@ -0,0 +1,65 @@ +# set AZERTY keyboard generic +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey a q +setkey A Q +setkey z w +setkey Z W +setkey q a +setkey Q A +setkey m semicolon +setkey M colon +setkey w z +setkey W Z +setkey comma m +setkey question M +setkey semicolon comma +setkey period less +setkey colon period +setkey slash greater +setkey exclam slash +setkey dollar bracketright +setkey asterisk backslash +setkey percent doublequote +setkey ampersand 1 +setkey 1 exclam +setkey tilde 2 +setkey 2 at +setkey doublequote 3 +setkey 3 numbersign +setkey quote 4 +setkey 4 dollar +setkey parenleft 5 +setkey 5 percent +setkey minus 6 +setkey 6 caret +setkey backquote 7 +setkey 7 ampersand +setkey underscore 8 +setkey 8 asterisk +setkey caret 9 +setkey 9 parenleft +setkey at 0 +setkey 0 parenright +setkey parenright minus +setkey less backquote +setkey greater tilde +setkey numbersign braceright +setkey backslash question +setkey bracketright braceleft +setkey braceleft quote +setkey braceright underscore + +setkey -e +if [ "${quiet}" = "" ]; then + echo AZERTY KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_CZECH_QWERTY.cfg b/KBD/cfg/KBD_CZECH_QWERTY.cfg new file mode 100644 index 00000000..e5934f75 --- /dev/null +++ b/KBD/cfg/KBD_CZECH_QWERTY.cfg @@ -0,0 +1,75 @@ +#QWERTY CZECH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey semicolon backquote +setkey plus 1 +setkey equal minus +setkey quote equal +setkey parenright bracketright +setkey doublequote backslash +setkey minus slash +#shift +setkey 1 exclam +setkey 2 at +setkey 3 numbersign +setkey 4 dollar +setkey 5 percent +setkey 6 caret +setkey 7 ampersand +setkey 8 asterisk +setkey 9 parenleft +setkey 0 parenright +setkey percent underscore +setkey slash braceleft +setkey parenleft braceright +setkey doublequote colon +setkey exclam doublequote +setkey quote bar +setkey question less +setkey colon greater +setkey underscore question +#Alt +setkey backquote Abackquote +setkey exclam A1 +setkey at A2 +setkey numbersign A3 +setkey dollar A4 +setkey percent A5 +setkey caret A6 +setkey ampersand A7 +setkey asterisk A8 +setkey parenleft A9 +setkey parenright A0 +setkey minus Aminus +setkey equal Aequal +setkey bracketleft Abracketleft +setkey bracketright Abracketright +setkey semicolon Asemicolon +setkey backslash Abackslash +setkey less Acomma +setkey greater Aperiod +setkey slash Aslash +setkey tilde Atilde +setkey underscore Aunderscore +setkey plus Aplus +setkey braceleft Abraceleft +setkey braceright Abraceright +setkey caret Adoublequote +setkey colon Acolon +setkey question Aquestion + +setkey bar Abar + +setkey -e +if [ "${quiet}" = "" ]; then + echo CZECH QWERTY KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_CZECH_QWERTZ.cfg b/KBD/cfg/KBD_CZECH_QWERTZ.cfg new file mode 100644 index 00000000..be8938e9 --- /dev/null +++ b/KBD/cfg/KBD_CZECH_QWERTZ.cfg @@ -0,0 +1,64 @@ +#QWERTZ CZECH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey y z +setkey z y +setkey Y Z +setkey Z Y +setkey semicolon backquote +setkey plus 1 +setkey equal minus +setkey quote equal +setkey parenright bracketright +setkey doublequote backslash +setkey minus slash +#shift +setkey 1 exclam +setkey 2 at +setkey 3 numbersign +setkey 4 dollar +setkey 5 percent +setkey 6 caret +setkey 7 ampersand +setkey 8 asterisk +setkey 9 parenleft +setkey 0 parenright +setkey percent underscore +setkey slash braceleft +setkey parenleft braceright +setkey doublequote colon +setkey exclam doublequote +setkey quote bar +setkey question less +setkey colon greater +setkey underscore question +#Alt +setkey tilde A1 +setkey caret A3 +setkey backslash Aq +setkey bar Aw +setkey bracketleft Af +setkey bracketright Ag +setkey dollar Asemicolon +setkey numbersign Ax +setkey ampersand Ac +setkey at Av +setkey braceleft Ab +setkey braceright An +setkey less Acomma +setkey greater Aperiod +setkey asterisk Aslash + +setkey -e +if [ "${quiet}" = "" ]; then + echo CZECH QWERTZ KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_DANISH.cfg b/KBD/cfg/KBD_DANISH.cfg new file mode 100644 index 00000000..1e599025 --- /dev/null +++ b/KBD/cfg/KBD_DANISH.cfg @@ -0,0 +1,56 @@ +#DANISH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey plus minus +setkey quote equal +setkey doublequote bracketright +setkey quote backslash +setkey minus slash + +#shifted +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey caret braceright +setkey asterisk bar +setkey backquote plus +setkey semicolon less +setkey colon greater +setkey underscore question + +#use top-left key for oem102 codes +setkey bar Atilde +setkey backslash Abackquote +setkey greater tilde + +#AltGr +setkey at A2 +setkey dollar A4 +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey backslash Aminus + +setkey less quote +setkey greater doublequote +setkey tilde Abracketright + +setkey -e +if [ "${quiet}" = "" ]; then + echo "DANISH KBD a=< A=>" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_DVORAK_USA.cfg b/KBD/cfg/KBD_DVORAK_USA.cfg new file mode 100644 index 00000000..9e4b6087 --- /dev/null +++ b/KBD/cfg/KBD_DVORAK_USA.cfg @@ -0,0 +1,104 @@ +# Author: Alex Roper +# set DVORAK keyboard +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey [ minus +setkey braceleft underscore +setkey quote q +setkey doublequote Q +setkey comma w +setkey less W +setkey s semicolon +setkey S colon +setkey semicolon z +setkey colon Z +setkey w comma +setkey W less +setkey v period +setkey z greater +setkey z slash +setkey equal bracketright +setkey backslash backslash +setkey underscore doublequote +setkey quote q +setkey doublequote Q +setkey comma w +setkey less W +setkey period e +setkey greater E +setkey p r +setkey P R +setkey y t +setkey Y T +setkey f y +setkey F Y +setkey g u +setkey G U +setkey c c +setkey C I +setkey r o +setkey R O +setkey l p +setkey L P +setkey bracketright equal +setkey braceright plus +setkey a a +setkey A A +setkey o s +setkey O S +setkey e d +setkey E D +setkey u f +setkey U F +setkey i g +setkey I G +setkey d h +setkey D H +setkey h j +setkey H J +setkey t k +setkey T K +setkey n l +setkey N L +setkey s semicolon +setkey S colon +setkey minus quote +setkey underscore doublequote +setkey semicolon z +setkey colon Z +setkey q x +setkey Q X +setkey j c +setkey J C +setkey k v +setkey K V +setkey x b +setkey X B +setkey b n +setkey B N +#setkey m m +#setkey M M +setkey w comma +setkey W less +setkey v period +setkey V greater +setkey z slash +setkey Z question +setkey slash bracketleft +setkey question braceleft +setkey equal bracketright +setkey plus braceright + +setkey -e +if [ "${quiet}" = "" ]; then + echo DVORAK KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_FRENCH.cfg b/KBD/cfg/KBD_FRENCH.cfg new file mode 100644 index 00000000..edc04301 --- /dev/null +++ b/KBD/cfg/KBD_FRENCH.cfg @@ -0,0 +1,80 @@ +#FRENCH AZERTY +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey less backquote +setkey greater tilde +setkey ampersand 1 +setkey 1 exclam +setkey tilde 2 +setkey 2 at +setkey doublequote 3 +setkey 3 numbersign +setkey quote 4 +setkey 4 dollar +setkey parenleft 5 +setkey 5 percent +setkey minus 6 +setkey 6 caret +setkey backquote 7 +setkey 7 ampersand +setkey underscore 8 +setkey 8 asterisk +setkey backslash 9 +setkey 9 parenleft +setkey at 0 +setkey 0 parenright +setkey parenright minus +setkey numbersign underscore +# no change for equal +# no change for plus +setkey a q +setkey A Q +setkey z w +setkey Z W +setkey caret bracketleft +# no equivalent for diaresis => we keep the US braceleft +setkey dollar bracketright +# no equivalent for pound => we keep the US braceright +setkey q a +setkey Q A +setkey m semicolon +setkey M colon +setkey bracketleft quote +setkey percent doublequote +setkey asterisk backslash +setkey bracketright bar +setkey w z +setkey W Z +setkey comma m +setkey question M +setkey semicolon comma +setkey period less +setkey colon period +setkey slash greater +setkey exclam slash +setkey bar question + +setkey tilde A2 +setkey numbersign A3 +setkey braceleft A4 +setkey bracketleft A5 +setkey bar A6 +setkey quote A7 +setkey backslash A8 +setkey caret A9 +setkey at A0 +setkey bracketright Aminus +setkey braceright Aequal +setkey -e +if [ "${quiet}" = "" ]; then + echo FRENCH KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_GERMAN.cfg b/KBD/cfg/KBD_GERMAN.cfg new file mode 100644 index 00000000..1265fcd0 --- /dev/null +++ b/KBD/cfg/KBD_GERMAN.cfg @@ -0,0 +1,56 @@ +#GERMAN +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey backslash minus +setkey z y +setkey Z Y +setkey y z +setkey Y Z +setkey plus bracketright +setkey asterisk braceright +setkey semicolon less +setkey colon greater +setkey minus slash +setkey backslash Aminus +setkey underscore question +setkey caret backquote +setkey quote equal +setkey backquote plus +setkey braceright doublequote +setkey bar bracketleft +setkey at braceleft +setkey numbersign backslash +setkey at Aq +setkey less backquote +setkey greater tilde +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey tilde Abracketright +setkey backslash Aminus +setkey quote bar +setkey greater semicolon +setkey less colon +setkey bar quote + +setkey -e +if [ "${quiet}" = "" ]; then + echo GERMAN KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_ITALIANO.cfg b/KBD/cfg/KBD_ITALIANO.cfg new file mode 100644 index 00000000..21846ec0 --- /dev/null +++ b/KBD/cfg/KBD_ITALIANO.cfg @@ -0,0 +1,52 @@ +# Italian +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey backslash backquote +setkey bar tilde +setkey doublequote at +setkey tilde numbersign +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey quote minus +setkey question underscore +setkey caret plus +setkey bracketleft bracketleft +setkey bracketright braceleft +setkey plus bracketright +setkey asterisk braceright +setkey at semicolon +setkey braceleft colon +setkey numbersign quote +setkey braceright doublequote +setkey less backslash +setkey greater bar +setkey minus slash +setkey underscore question +setkey semicolon less +setkey colon greater + +setkey bracketleft Abracketleft +setkey bracketright Abracketright +setkey at Asemicolon +setkey numbersign Aquote +setkey braceright Abraceright +setkey braceleft Abraceleft + +setkey -e + +if [ "${quiet}" = "" ]; then + echo ITALIAN KBD +fi + + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_JAPAN_106.cfg b/KBD/cfg/KBD_JAPAN_106.cfg new file mode 100644 index 00000000..42c7fd9e --- /dev/null +++ b/KBD/cfg/KBD_JAPAN_106.cfg @@ -0,0 +1,37 @@ +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +# Jp106 keypad +setkey at bracketleft +setkey doublequote at +setkey ampersand caret +setkey quote ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey underscore parenright +setkey equal underscore +setkey plus colon +setkey colon quote +setkey asterisk doublequote +setkey bracketleft bracketright +setkey braceleft braceright +setkey bracketright backslash +setkey braceright bar +setkey backslash backquote +setkey tilde plus +setkey caret equal +setkey backquote braceleft +setkey bar tilde + +setkey -e +if [ "${quiet}" = "" ]; then + echo JAPANESE 106 KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_LATIN_USA.cfg b/KBD/cfg/KBD_LATIN_USA.cfg new file mode 100644 index 00000000..f50b4187 --- /dev/null +++ b/KBD/cfg/KBD_LATIN_USA.cfg @@ -0,0 +1,53 @@ +#LATIN AMERCICAN KBD +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey bar backquote +setkey quote minus +setkey question underscore +setkey backquote bracketleft +setkey plus bracketright +setkey braceleft quote +setkey braceright backslash +setkey minus slash +setkey ampersand caret +setkey doublequote at +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey asterisk braceright +setkey bracketleft doublequote +setkey bracketright bar +setkey semicolon less +setkey colon greater +setkey underscore question + +setkey caret Aquote +setkey doublequote braceleft +setkey at Aq +setkey backquote Abackslash + +setkey backslash Aminus + +setkey greater plus +setkey less equal + +setkey backslash Aminus +setkey backquote Abackslash +setkey tilde Abracketright +setkey caret Aquote + +setkey -e +if [ "${quiet}" = "" ]; then + echo "LATIN AMERICAN KBD shift+top-right '>' top-right '<'" + sleep 3 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_PORTU_BRAZIL.cfg b/KBD/cfg/KBD_PORTU_BRAZIL.cfg new file mode 100644 index 00000000..c0878a85 --- /dev/null +++ b/KBD/cfg/KBD_PORTU_BRAZIL.cfg @@ -0,0 +1,41 @@ +#PORTUGUESE-BRAZIL +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey quote backquote +setkey quote bracketleft +setkey bracketleft bracketright +setkey tilde quote +setkey bracketright backslash +setkey semicolon slash +setkey bar colon + +#shifted +setkey doublequote tilde +setkey backquote braceleft +setkey braceleft braceright +setkey caret doublequote +setkey braceright bar +setkey colon question +setkey backslash semicolon + + +#AltGr +setkey bar Atilde +setkey backslash Abackquote +setkey slash Aq +setkey question Aw + +setkey -e +if [ "${quiet}" = "" ]; then + echo "PORTUGUESE-BRAZIL KBD c+' -> \"|\" C -> \"\\\"" + sleep 3 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTY_UK.cfg b/KBD/cfg/KBD_QWERTY_UK.cfg new file mode 100644 index 00000000..01cc9d0b --- /dev/null +++ b/KBD/cfg/KBD_QWERTY_UK.cfg @@ -0,0 +1,27 @@ +#QWERTY UK +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +#change key map for UK keyboard +setkey at doublequote +setkey doublequote at +setkey tilde bar +setkey numbersign backslash +setkey backslash numbersign +setkey bar tilde +setkey backslash Atilde +setkey backslash Abackquote + +setkey -e +if [ "${quiet}" = "" ]; then + echo "UK KBD use [Shift+3] for \\ and [Shift+top-left] for |" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTZ.cfg b/KBD/cfg/KBD_QWERTZ.cfg new file mode 100644 index 00000000..0bacacce --- /dev/null +++ b/KBD/cfg/KBD_QWERTZ.cfg @@ -0,0 +1,44 @@ +#QWERTZ generic +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey doublequote at +setkey ampersand percent +setkey slash ampersand + +setkey equal parenright +setkey question underscore +setkey backslash minus +setkey z y +setkey Z Y +setkey y z +setkey Y Z +setkey plus bracketright +setkey asterisk braceright +setkey semicolon less +setkey colon greater +setkey minus slash + +setkey underscore question +setkey caret backquote + +setkey backquote equal +setkey numbersign backslash +setkey parenright parenleft +setkey parenleft asterisk +setkey percent caret +setkey less numbersign +setkey greater bar + +setkey -e +if [ "${quiet}" = "" ]; then + echo QWERTZ KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTZ_HUN.cfg b/KBD/cfg/KBD_QWERTZ_HUN.cfg new file mode 100644 index 00000000..f7263b3d --- /dev/null +++ b/KBD/cfg/KBD_QWERTZ_HUN.cfg @@ -0,0 +1,69 @@ +#QWERTZ Hungarian +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey y z +setkey z y +setkey Y Z +setkey Z Y +setkey 0 backquote +setkey quote exclam +setkey doublequote at +setkey plus numbersign +setkey exclam dollar +setkey slash caret +setkey equal ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey backslash Aq +setkey bar Aw +setkey bracketleft Af +setkey bracketright Ag +#setkey greater Aoem102 - Aoem102 not supported +#this is a y key in hungarian keyboard +setkey greater Az +setkey numbersign Ax +setkey ampersand Ac +setkey at Av +setkey braceleft Ab +setkey braceright An +setkey less Am +#use É (USA=:) for $ +setkey dollar colon +setkey question less +setkey colon greater +setkey minus slash +setkey underscore question +setkey at doublequote +setkey tilde A1 +setkey caret A3 +setkey backquote A7 + +#use Ö for asterisk +setkey asterisk 0 + +setkey dollar Asemicolon +setkey semicolon Acomma +setkey greater Aperiod +setkey asterisk Aslash +#semicolon use é key +#Hun AltGR chars: less greater numbersign ampersand at braceleft braceright semicolon asterisk backslash bar tilde caret quote doublequote bracketleft bracketright + +setkey backquote A9 +setkey doublequote A0 + + + +setkey -e +if [ "${quiet}" = "" ]; then + echo "QWERTZ_HUN KBD e ';'" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_QWERTZ_SLOV_CROAT.cfg b/KBD/cfg/KBD_QWERTZ_SLOV_CROAT.cfg new file mode 100644 index 00000000..30b20eae --- /dev/null +++ b/KBD/cfg/KBD_QWERTZ_SLOV_CROAT.cfg @@ -0,0 +1,48 @@ +#QWERTZ Croatian\Slovenian +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey quote minus +setkey plus equal +setkey y z +setkey minus slash +#shifted +setkey doublequote tilde +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey asterisk plus +setkey Y Z +setkey semicolon less +setkey colon greater +setkey underscore question +#AltGr +setkey tilde A1 +setkey caret A3 +setkey backquote A7 +setkey backslash Aq +setkey bar Aw +setkey bracketleft Af +setkey bracketright Ag +setkey at Av +setkey braceleft Ab +setkey braceright An +setkey less Acomma +setkey greater Aperiod + +setkey -e +if [ "${quiet}" = "" ]; then + echo QWERTZ_SLOV_CROAT KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_SPANISH.cfg b/KBD/cfg/KBD_SPANISH.cfg new file mode 100644 index 00000000..fb9cc3b2 --- /dev/null +++ b/KBD/cfg/KBD_SPANISH.cfg @@ -0,0 +1,54 @@ +#Espanol - SPANISH CHARACTER - USA KBD CHARACTER +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey slash ampersand +setkey ampersand caret +setkey caret braceleft +setkey asterisk braceright +setkey parenleft asterisk +setkey parenright parenleft +setkey minus slash +setkey equal parenright +setkey quote minus +setkey underscore question +setkey question underscore +#setkey braceleft quote +#setkey braceright backslash +setkey colon greater +setkey greater bar +setkey doublequote at +setkey backslash backquote +setkey less backslash +setkey semicolon less +setkey backquote bracketleft +setkey plus bracketright +setkey plus colon +setkey at semicolon + +setkey bar A1 +setkey at A2 +setkey numbersign A3 +setkey tilde A4 +setkey bracketleft Abracketleft +setkey bracketright Abracketright +setkey braceleft Aquote +setkey braceright Abackslash + +setkey greater bar +setkey less backslash +setkey backslash Abackquote + +setkey -e +if [ "${quiet}" = "" ]; then + echo "SPANISH KBD MAP SET c=< C=>" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_SWEDISH.cfg b/KBD/cfg/KBD_SWEDISH.cfg new file mode 100644 index 00000000..6d17d152 --- /dev/null +++ b/KBD/cfg/KBD_SWEDISH.cfg @@ -0,0 +1,56 @@ +#SWEDISH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey plus minus +setkey quote equal +setkey doublequote bracketright +setkey quote backslash +setkey minus slash + +#shifted +setkey doublequote at +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey caret braceright +setkey asterisk bar +setkey backquote plus +setkey semicolon less +setkey colon greater +setkey underscore question + +#use top-left key for oem102 codes +setkey bar Atilde +setkey backslash Abackquote +setkey greater tilde + +#AltGr +setkey at A2 +setkey dollar A4 +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey backslash Aminus + +setkey less quote +setkey greater doublequote +setkey tilde Abracketright + +setkey -e +if [ "${quiet}" = "" ]; then + echo "SWEDISH KBD a=< A=>" + sleep 2 +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_TURKISH_Q.cfg b/KBD/cfg/KBD_TURKISH_Q.cfg new file mode 100644 index 00000000..4a02fe61 --- /dev/null +++ b/KBD/cfg/KBD_TURKISH_Q.cfg @@ -0,0 +1,49 @@ +#QWERTY TURKISH +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey doublequote backquote +setkey asterisk minus +setkey minus equal +setkey comma backslash +setkey period slash +#shift +setkey quote at +setkey caret numbersign +setkey plus dollar +setkey ampersand caret +setkey slash ampersand +setkey parenleft asterisk +setkey parenright parenleft +setkey equal parenright +setkey question underscore +setkey underscore plus +setkey semicolon bar +setkey colon question +#altgr +setkey less Abackquote +setkey greater A1 +setkey numbersign A3 +setkey dollar A4 +setkey braceleft A7 +setkey bracketleft A8 +setkey bracketright A9 +setkey braceright A0 +setkey backslash Aminus +setkey bar Aequal +setkey at Aq +setkey doublequote Abracketleft +setkey tilde Abracketright + +setkey -e +if [ "${quiet}" = "" ]; then + echo TURKISH QWERTY KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/cfg/KBD_VIETNAMESE.cfg b/KBD/cfg/KBD_VIETNAMESE.cfg new file mode 100644 index 00000000..2d818673 --- /dev/null +++ b/KBD/cfg/KBD_VIETNAMESE.cfg @@ -0,0 +1,52 @@ +#VIETNAMESE +#clear all settings +setkey -r +#setkey [new character] [QWERTY-USA character] +setkey exclam A1 +setkey at A2 +setkey numbersign A3 +setkey dollar A4 +setkey percent A5 +setkey caret A6 +setkey ampersand A7 +setkey asterisk A8 +setkey parenleft A9 +setkey parenright A0 +setkey plus Aplus +setkey equal Aequal +setkey braceleft Abraceleft +setkey braceright Abraceright +setkey colon Acolon +setkey semicolon Asemicolon +setkey quote Aquote +setkey backslash Abackslash +setkey less Aless +setkey greater Agreater +setkey comma Acomma +setkey period Aperiod +setkey question Aquestion +setkey slash Aslash +setkey tilde Atilde +setkey backquote Abackquote +setkey bracketright Abracketright +setkey bracketleft Abracketleft +setkey bar Abar +setkey doublequote Adoublequote +setkey colon Acolon +setkey minus Aminus +setkey underscore Aunderscore + +#for top row, use unshifted and shifted keys +setkey -e + +if [ "${quiet}" = "" ]; then + echo VIETNAMESE KBD +fi + +#key names +#escape, exclam (!), at (@), numbersign (#), dollar ($), parenright ()), caret (^), ampersand (&), asterisk (*), plus (+), percent (%) +#minus (-), underscore (_), equal (=), parenleft [(], backspace (backspace), tab (Tab), bracketleft ([), braceleft ({), bracketright (]) +#braceright (}), enter (carriage return), semicolon (;), colon (:), quote (') , doublequote ("), slash (/), backquote (`), tilde (~) +#backslash (\), bar (|), comma (,), less (<) period (.) , greater (>), question (?) +#space, home, uparrow, pageup, leftarrow, center, rightarrow, end, downarrow, pagedown, insert, delete, F1-F12, shiftF1-shiftF12, ctrlF1-ctrlF12 +#Use prefix A for Alt+, e.g. Aequal, Aq, Aslash, A0, etc. \ No newline at end of file diff --git a/KBD/keyboard_layout.c b/KBD/keyboard_layout.c new file mode 100644 index 00000000..8d139b5f --- /dev/null +++ b/KBD/keyboard_layout.c @@ -0,0 +1,795 @@ + +#define ventoy_keyboard_set_layout(name) if (grub_strcmp(layout, #name) == 0) return ventoy_keyboard_layout_##name() + +static void ventoy_keyboard_layout_QWERTY_USA(void) { + grub_keymap_reset(); + grub_keymap_disable(); +} +static void ventoy_keyboard_layout_AZERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("caret", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("numbersign", "braceright"); +grub_keymap_add_by_string("backslash", "question"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "underscore"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTY(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("caret", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_CZECH_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("semicolon", "backquote"); +grub_keymap_add_by_string("plus", "1"); +grub_keymap_add_by_string("equal", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("parenright", "bracketright"); +grub_keymap_add_by_string("doublequote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("percent", "underscore"); +grub_keymap_add_by_string("slash", "braceleft"); +grub_keymap_add_by_string("parenleft", "braceright"); +grub_keymap_add_by_string("doublequote", "colon"); +grub_keymap_add_by_string("exclam", "doublequote"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_DVORAK_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("[", "minus"); +grub_keymap_add_by_string("braceleft", "underscore"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("z", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("backslash", "backslash"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("quote", "q"); +grub_keymap_add_by_string("doublequote", "Q"); +grub_keymap_add_by_string("comma", "w"); +grub_keymap_add_by_string("less", "W"); +grub_keymap_add_by_string("period", "e"); +grub_keymap_add_by_string("greater", "E"); +grub_keymap_add_by_string("p", "r"); +grub_keymap_add_by_string("P", "R"); +grub_keymap_add_by_string("y", "t"); +grub_keymap_add_by_string("Y", "T"); +grub_keymap_add_by_string("f", "y"); +grub_keymap_add_by_string("F", "Y"); +grub_keymap_add_by_string("g", "u"); +grub_keymap_add_by_string("G", "U"); +grub_keymap_add_by_string("c", "c"); +grub_keymap_add_by_string("C", "I"); +grub_keymap_add_by_string("r", "o"); +grub_keymap_add_by_string("R", "O"); +grub_keymap_add_by_string("l", "p"); +grub_keymap_add_by_string("L", "P"); +grub_keymap_add_by_string("bracketright", "equal"); +grub_keymap_add_by_string("braceright", "plus"); +grub_keymap_add_by_string("a", "a"); +grub_keymap_add_by_string("A", "A"); +grub_keymap_add_by_string("o", "s"); +grub_keymap_add_by_string("O", "S"); +grub_keymap_add_by_string("e", "d"); +grub_keymap_add_by_string("E", "D"); +grub_keymap_add_by_string("u", "f"); +grub_keymap_add_by_string("U", "F"); +grub_keymap_add_by_string("i", "g"); +grub_keymap_add_by_string("I", "G"); +grub_keymap_add_by_string("d", "h"); +grub_keymap_add_by_string("D", "H"); +grub_keymap_add_by_string("h", "j"); +grub_keymap_add_by_string("H", "J"); +grub_keymap_add_by_string("t", "k"); +grub_keymap_add_by_string("T", "K"); +grub_keymap_add_by_string("n", "l"); +grub_keymap_add_by_string("N", "L"); +grub_keymap_add_by_string("s", "semicolon"); +grub_keymap_add_by_string("S", "colon"); +grub_keymap_add_by_string("minus", "quote"); +grub_keymap_add_by_string("underscore", "doublequote"); +grub_keymap_add_by_string("semicolon", "z"); +grub_keymap_add_by_string("colon", "Z"); +grub_keymap_add_by_string("q", "x"); +grub_keymap_add_by_string("Q", "X"); +grub_keymap_add_by_string("j", "c"); +grub_keymap_add_by_string("J", "C"); +grub_keymap_add_by_string("k", "v"); +grub_keymap_add_by_string("K", "V"); +grub_keymap_add_by_string("x", "b"); +grub_keymap_add_by_string("X", "B"); +grub_keymap_add_by_string("b", "n"); +grub_keymap_add_by_string("B", "N"); +grub_keymap_add_by_string("w", "comma"); +grub_keymap_add_by_string("W", "less"); +grub_keymap_add_by_string("v", "period"); +grub_keymap_add_by_string("V", "greater"); +grub_keymap_add_by_string("z", "slash"); +grub_keymap_add_by_string("Z", "question"); +grub_keymap_add_by_string("slash", "bracketleft"); +grub_keymap_add_by_string("question", "braceleft"); +grub_keymap_add_by_string("equal", "bracketright"); +grub_keymap_add_by_string("plus", "braceright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_FRENCH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("ampersand", "1"); +grub_keymap_add_by_string("1", "exclam"); +grub_keymap_add_by_string("tilde", "2"); +grub_keymap_add_by_string("2", "at"); +grub_keymap_add_by_string("doublequote", "3"); +grub_keymap_add_by_string("3", "numbersign"); +grub_keymap_add_by_string("quote", "4"); +grub_keymap_add_by_string("4", "dollar"); +grub_keymap_add_by_string("parenleft", "5"); +grub_keymap_add_by_string("5", "percent"); +grub_keymap_add_by_string("minus", "6"); +grub_keymap_add_by_string("6", "caret"); +grub_keymap_add_by_string("backquote", "7"); +grub_keymap_add_by_string("7", "ampersand"); +grub_keymap_add_by_string("underscore", "8"); +grub_keymap_add_by_string("8", "asterisk"); +grub_keymap_add_by_string("backslash", "9"); +grub_keymap_add_by_string("9", "parenleft"); +grub_keymap_add_by_string("at", "0"); +grub_keymap_add_by_string("0", "parenright"); +grub_keymap_add_by_string("parenright", "minus"); +grub_keymap_add_by_string("numbersign", "underscore"); +grub_keymap_add_by_string("a", "q"); +grub_keymap_add_by_string("A", "Q"); +grub_keymap_add_by_string("z", "w"); +grub_keymap_add_by_string("Z", "W"); +grub_keymap_add_by_string("caret", "bracketleft"); +grub_keymap_add_by_string("dollar", "bracketright"); +grub_keymap_add_by_string("q", "a"); +grub_keymap_add_by_string("Q", "A"); +grub_keymap_add_by_string("m", "semicolon"); +grub_keymap_add_by_string("M", "colon"); +grub_keymap_add_by_string("bracketleft", "quote"); +grub_keymap_add_by_string("percent", "doublequote"); +grub_keymap_add_by_string("asterisk", "backslash"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("w", "z"); +grub_keymap_add_by_string("W", "Z"); +grub_keymap_add_by_string("comma", "m"); +grub_keymap_add_by_string("question", "M"); +grub_keymap_add_by_string("semicolon", "comma"); +grub_keymap_add_by_string("period", "less"); +grub_keymap_add_by_string("colon", "period"); +grub_keymap_add_by_string("slash", "greater"); +grub_keymap_add_by_string("exclam", "slash"); +grub_keymap_add_by_string("bar", "question"); +grub_keymap_add_by_string("tilde", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("braceleft", "A4"); +grub_keymap_add_by_string("bracketleft", "A5"); +grub_keymap_add_by_string("bar", "A6"); +grub_keymap_add_by_string("quote", "A7"); +grub_keymap_add_by_string("backslash", "A8"); +grub_keymap_add_by_string("caret", "A9"); +grub_keymap_add_by_string("at", "A0"); +grub_keymap_add_by_string("bracketright", "Aminus"); +grub_keymap_add_by_string("braceright", "Aequal"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_GERMAN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("bar", "bracketleft"); +grub_keymap_add_by_string("at", "braceleft"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("less", "backquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("quote", "bar"); +grub_keymap_add_by_string("greater", "semicolon"); +grub_keymap_add_by_string("less", "colon"); +grub_keymap_add_by_string("bar", "quote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_ITALIANO(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "numbersign"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "plus"); +grub_keymap_add_by_string("bracketleft", "bracketleft"); +grub_keymap_add_by_string("bracketright", "braceleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("braceleft", "colon"); +grub_keymap_add_by_string("numbersign", "quote"); +grub_keymap_add_by_string("braceright", "doublequote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("at", "Asemicolon"); +grub_keymap_add_by_string("numbersign", "Aquote"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_JAPAN_106(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "bracketleft"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("quote", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("underscore", "parenright"); +grub_keymap_add_by_string("equal", "underscore"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("colon", "quote"); +grub_keymap_add_by_string("asterisk", "doublequote"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("tilde", "plus"); +grub_keymap_add_by_string("caret", "equal"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_LATIN_USA(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("bar", "backquote"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("braceleft", "quote"); +grub_keymap_add_by_string("braceright", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("bracketleft", "doublequote"); +grub_keymap_add_by_string("bracketright", "bar"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_add_by_string("doublequote", "braceleft"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("greater", "plus"); +grub_keymap_add_by_string("less", "equal"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("backquote", "Abackslash"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_add_by_string("caret", "Aquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_PORTU_BRAZIL(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "backquote"); +grub_keymap_add_by_string("quote", "bracketleft"); +grub_keymap_add_by_string("bracketleft", "bracketright"); +grub_keymap_add_by_string("tilde", "quote"); +grub_keymap_add_by_string("bracketright", "backslash"); +grub_keymap_add_by_string("semicolon", "slash"); +grub_keymap_add_by_string("bar", "colon"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("backquote", "braceleft"); +grub_keymap_add_by_string("braceleft", "braceright"); +grub_keymap_add_by_string("caret", "doublequote"); +grub_keymap_add_by_string("braceright", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("backslash", "semicolon"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("slash", "Aq"); +grub_keymap_add_by_string("question", "Aw"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTY_UK(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("tilde", "bar"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("backslash", "numbersign"); +grub_keymap_add_by_string("bar", "tilde"); +grub_keymap_add_by_string("backslash", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "percent"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("backslash", "minus"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("caret", "backquote"); +grub_keymap_add_by_string("backquote", "equal"); +grub_keymap_add_by_string("numbersign", "backslash"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("percent", "caret"); +grub_keymap_add_by_string("less", "numbersign"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_HUN(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("z", "y"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("Z", "Y"); +grub_keymap_add_by_string("0", "backquote"); +grub_keymap_add_by_string("quote", "exclam"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("plus", "numbersign"); +grub_keymap_add_by_string("exclam", "dollar"); +grub_keymap_add_by_string("slash", "caret"); +grub_keymap_add_by_string("equal", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("greater", "Az"); +grub_keymap_add_by_string("numbersign", "Ax"); +grub_keymap_add_by_string("ampersand", "Ac"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Am"); +grub_keymap_add_by_string("dollar", "colon"); +grub_keymap_add_by_string("question", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("at", "doublequote"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("asterisk", "0"); +grub_keymap_add_by_string("dollar", "Asemicolon"); +grub_keymap_add_by_string("semicolon", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_add_by_string("asterisk", "Aslash"); +grub_keymap_add_by_string("backquote", "A9"); +grub_keymap_add_by_string("doublequote", "A0"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_QWERTZ_SLOV_CROAT(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("plus", "equal"); +grub_keymap_add_by_string("y", "z"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "tilde"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("asterisk", "plus"); +grub_keymap_add_by_string("Y", "Z"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("tilde", "A1"); +grub_keymap_add_by_string("caret", "A3"); +grub_keymap_add_by_string("backquote", "A7"); +grub_keymap_add_by_string("backslash", "Aq"); +grub_keymap_add_by_string("bar", "Aw"); +grub_keymap_add_by_string("bracketleft", "Af"); +grub_keymap_add_by_string("bracketright", "Ag"); +grub_keymap_add_by_string("at", "Av"); +grub_keymap_add_by_string("braceleft", "Ab"); +grub_keymap_add_by_string("braceright", "An"); +grub_keymap_add_by_string("less", "Acomma"); +grub_keymap_add_by_string("greater", "Aperiod"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SPANISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("caret", "braceleft"); +grub_keymap_add_by_string("asterisk", "braceright"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("quote", "minus"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("backslash", "backquote"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("backquote", "bracketleft"); +grub_keymap_add_by_string("plus", "bracketright"); +grub_keymap_add_by_string("plus", "colon"); +grub_keymap_add_by_string("at", "semicolon"); +grub_keymap_add_by_string("bar", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("tilde", "A4"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("braceleft", "Aquote"); +grub_keymap_add_by_string("braceright", "Abackslash"); +grub_keymap_add_by_string("greater", "bar"); +grub_keymap_add_by_string("less", "backslash"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_SWEDISH(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("plus", "minus"); +grub_keymap_add_by_string("quote", "equal"); +grub_keymap_add_by_string("doublequote", "bracketright"); +grub_keymap_add_by_string("quote", "backslash"); +grub_keymap_add_by_string("minus", "slash"); +grub_keymap_add_by_string("doublequote", "at"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("caret", "braceright"); +grub_keymap_add_by_string("asterisk", "bar"); +grub_keymap_add_by_string("backquote", "plus"); +grub_keymap_add_by_string("semicolon", "less"); +grub_keymap_add_by_string("colon", "greater"); +grub_keymap_add_by_string("underscore", "question"); +grub_keymap_add_by_string("bar", "Atilde"); +grub_keymap_add_by_string("backslash", "Abackquote"); +grub_keymap_add_by_string("greater", "tilde"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("less", "quote"); +grub_keymap_add_by_string("greater", "doublequote"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_TURKISH_Q(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("doublequote", "backquote"); +grub_keymap_add_by_string("asterisk", "minus"); +grub_keymap_add_by_string("minus", "equal"); +grub_keymap_add_by_string("comma", "backslash"); +grub_keymap_add_by_string("period", "slash"); +grub_keymap_add_by_string("quote", "at"); +grub_keymap_add_by_string("caret", "numbersign"); +grub_keymap_add_by_string("plus", "dollar"); +grub_keymap_add_by_string("ampersand", "caret"); +grub_keymap_add_by_string("slash", "ampersand"); +grub_keymap_add_by_string("parenleft", "asterisk"); +grub_keymap_add_by_string("parenright", "parenleft"); +grub_keymap_add_by_string("equal", "parenright"); +grub_keymap_add_by_string("question", "underscore"); +grub_keymap_add_by_string("underscore", "plus"); +grub_keymap_add_by_string("semicolon", "bar"); +grub_keymap_add_by_string("colon", "question"); +grub_keymap_add_by_string("less", "Abackquote"); +grub_keymap_add_by_string("greater", "A1"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("braceleft", "A7"); +grub_keymap_add_by_string("bracketleft", "A8"); +grub_keymap_add_by_string("bracketright", "A9"); +grub_keymap_add_by_string("braceright", "A0"); +grub_keymap_add_by_string("backslash", "Aminus"); +grub_keymap_add_by_string("bar", "Aequal"); +grub_keymap_add_by_string("at", "Aq"); +grub_keymap_add_by_string("doublequote", "Abracketleft"); +grub_keymap_add_by_string("tilde", "Abracketright"); +grub_keymap_enable(); +} +static void ventoy_keyboard_layout_VIETNAMESE(void) { +grub_keymap_reset(); +grub_keymap_add_by_string("exclam", "A1"); +grub_keymap_add_by_string("at", "A2"); +grub_keymap_add_by_string("numbersign", "A3"); +grub_keymap_add_by_string("dollar", "A4"); +grub_keymap_add_by_string("percent", "A5"); +grub_keymap_add_by_string("caret", "A6"); +grub_keymap_add_by_string("ampersand", "A7"); +grub_keymap_add_by_string("asterisk", "A8"); +grub_keymap_add_by_string("parenleft", "A9"); +grub_keymap_add_by_string("parenright", "A0"); +grub_keymap_add_by_string("plus", "Aplus"); +grub_keymap_add_by_string("equal", "Aequal"); +grub_keymap_add_by_string("braceleft", "Abraceleft"); +grub_keymap_add_by_string("braceright", "Abraceright"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("semicolon", "Asemicolon"); +grub_keymap_add_by_string("quote", "Aquote"); +grub_keymap_add_by_string("backslash", "Abackslash"); +grub_keymap_add_by_string("less", "Aless"); +grub_keymap_add_by_string("greater", "Agreater"); +grub_keymap_add_by_string("comma", "Acomma"); +grub_keymap_add_by_string("period", "Aperiod"); +grub_keymap_add_by_string("question", "Aquestion"); +grub_keymap_add_by_string("slash", "Aslash"); +grub_keymap_add_by_string("tilde", "Atilde"); +grub_keymap_add_by_string("backquote", "Abackquote"); +grub_keymap_add_by_string("bracketright", "Abracketright"); +grub_keymap_add_by_string("bracketleft", "Abracketleft"); +grub_keymap_add_by_string("bar", "Abar"); +grub_keymap_add_by_string("doublequote", "Adoublequote"); +grub_keymap_add_by_string("colon", "Acolon"); +grub_keymap_add_by_string("minus", "Aminus"); +grub_keymap_add_by_string("underscore", "Aunderscore"); +grub_keymap_enable(); +} +void ventoy_set_keyboard_layout(const char *layout); +void ventoy_set_keyboard_layout(const char *layout) { +ventoy_keyboard_set_layout(QWERTY_USA); +ventoy_keyboard_set_layout(AZERTY); +ventoy_keyboard_set_layout(CZECH_QWERTY); +ventoy_keyboard_set_layout(CZECH_QWERTZ); +ventoy_keyboard_set_layout(DANISH); +ventoy_keyboard_set_layout(DVORAK_USA); +ventoy_keyboard_set_layout(FRENCH); +ventoy_keyboard_set_layout(GERMAN); +ventoy_keyboard_set_layout(ITALIANO); +ventoy_keyboard_set_layout(JAPAN_106); +ventoy_keyboard_set_layout(LATIN_USA); +ventoy_keyboard_set_layout(PORTU_BRAZIL); +ventoy_keyboard_set_layout(QWERTY_UK); +ventoy_keyboard_set_layout(QWERTZ); +ventoy_keyboard_set_layout(QWERTZ_HUN); +ventoy_keyboard_set_layout(QWERTZ_SLOV_CROAT); +ventoy_keyboard_set_layout(SPANISH); +ventoy_keyboard_set_layout(SWEDISH); +ventoy_keyboard_set_layout(TURKISH_Q); +ventoy_keyboard_set_layout(VIETNAMESE); +} diff --git a/KBD/mkconfig.sh b/KBD/mkconfig.sh new file mode 100644 index 00000000..0e09792c --- /dev/null +++ b/KBD/mkconfig.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# +# Configfiles are from grubfilemanager project +# + +cfgfile=keyboard_layout.c +rm -f ${cfgfile} + +cat >>$cfgfile << EOF + +#define ventoy_keyboard_set_layout(name) if (grub_strcmp(layout, #name) == 0) return ventoy_keyboard_layout_##name() + +menuentry QWERTY_USA --class=debug_kbd { + setkey -r + setkey -d +} +EOF + +ls -1 cfg | while read line; do + kbd=${line%.cfg} + name=${kbd#KBD_} + + echo "menuentry $name --class=debug_kbd {" >> $cfgfile + grep '^setkey' cfg/$line >>$cfgfile + echo "}" >> $cfgfile +done + +dos2unix $cfgfile +sed 's/menuentry \([^ ]*\) .*/static void ventoy_keyboard_layout_\1(void) {/g' -i $cfgfile +sed 's/setkey *-r/grub_keymap_reset();/g' -i $cfgfile +sed 's/setkey *-d/grub_keymap_disable();/g' -i $cfgfile +sed 's/setkey *-e/grub_keymap_enable();/g' -i $cfgfile +sed 's/^setkey *\([^ ]*\) *\([^ ]*\)/grub_keymap_add_by_string("\1", "\2");/g' -i $cfgfile + +rm -f .tmpfunc +echo "void ventoy_set_keyboard_layout(const char *layout);" >> .tmpfunc +echo "void ventoy_set_keyboard_layout(const char *layout) {" >> .tmpfunc +grep 'void *ventoy_keyboard_layout_' $cfgfile | while read line; do + name=$(echo $line | sed 's/.*ventoy_keyboard_layout_\(.*\)(.*/\1/g') + echo "ventoy_keyboard_set_layout($name);" >> .tmpfunc +done + +echo "}" >> .tmpfunc + +cat .tmpfunc >> $cfgfile +rm -f .tmpfunc + +rm -f ../GRUB2/SRC/grub-2.04/grub-core/term/$cfgfile +cp -a $cfgfile ../GRUB2/SRC/grub-2.04/grub-core/term/$cfgfile + + + + + +############ +# +# cfg +############# + +cfgfile=../INSTALL/grub/keyboard.cfg +rm -f ${cfgfile} + +echo "submenu \"Keyboard Layouts\" --class=debug_krdlayout {" >>$cfgfile + +cat >>$cfgfile << EOF + menuentry QWERTY_USA --class=debug_kbd { + set_keyboard_layout QWERTY_USA + } +EOF + +ls -1 cfg | while read line; do + kbd=${line%.cfg} + name=${kbd#KBD_} + + echo " menuentry $name --class=debug_kbd {" >> $cfgfile + echo " set_keyboard_layout $name" >> $cfgfile + echo " }" >> $cfgfile +done + +echo "}" >>$cfgfile + + + diff --git a/LANGUAGES/README b/LANGUAGES/README new file mode 100644 index 00000000..7a5b4f25 --- /dev/null +++ b/LANGUAGES/README @@ -0,0 +1,17 @@ + +File encoding: UTF-8 + +language name must in the format: "Language-XXX (YYY)" + 1. Language- fixed 9 characters + 2. XXX: name in English + 3. a space (ASCII: 0x20) + 4. a left brace (ASCII: 0x28) + 5. YYY: name in the specified language + 6. a right brace (ASCII: 0x29) + +string translation: + all the String Define + #@ will be replaced with \r\n + +All the languages will be sorted by the name + diff --git a/LANGUAGES/check.sh b/LANGUAGES/check.sh new file mode 100644 index 00000000..a18c1a8d --- /dev/null +++ b/LANGUAGES/check.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +VTOY_PATH=$1 + +if [ ! -f $VTOY_PATH/LANGUAGES/languages.json ]; then + exit 1 +fi + +gcc -DFOR_VTOY_JSON_CHECK $VTOY_PATH/Ventoy2Disk/Ventoy2Disk/VentoyJson.c -I $VTOY_PATH/Ventoy2Disk/Ventoy2Disk/ -o checkjson + +./checkjson $VTOY_PATH/LANGUAGES/languages.json +ret=$? + +rm -f ./checkjson +[ $ret -eq 0 ] + + diff --git a/LANGUAGES/languages.ini b/LANGUAGES/languages.ini deleted file mode 100644 index a1a528ae..00000000 Binary files a/LANGUAGES/languages.ini and /dev/null differ diff --git a/LANGUAGES/languages.json b/LANGUAGES/languages.json new file mode 100644 index 00000000..a16175e3 --- /dev/null +++ b/LANGUAGES/languages.json @@ -0,0 +1,1991 @@ +[ + { + "name":"Arabic (العربية)", + "FontFamily":"Courier New", + "FontSize":20, + "Author":"Omar Namis Mostafa", + + "STR_ERROR":"خطأ", + "STR_WARNING":"تحذير", + "STR_INFO":"معلومات", + "STR_INCORRECT_DIR":"يرجى التشغيل من المسار الصحيح!", + "STR_INCORRECT_TREE_DIR":"لا تقم بالتشغيل من هنا، يرجى تحميل حزمة التثبيت، وتشغيلها من هناك.", + "STR_DEVICE":"الجهاز", + "STR_LOCAL_VER":"ÙÙŠ الحزمة Ventoy", + "STR_DISK_VER":"ÙÙŠ الجهاز Ventoy", + "STR_STATUS":"الحالة - جاهز", + "STR_INSTALL":"تثبيت", + "STR_UPDATE":"تحديث", + "STR_UPDATE_TIP":"عملية التحديث آمنة, لن يتم عمل تغييرات على ملÙات الـISO.#@استمرار؟", + "STR_INSTALL_TIP":"سو٠يتم تهيئة القرص وسيتم حذ٠جميع البيانات.#@المواصلة؟", + "STR_INSTALL_TIP2":"سو٠يتم تهيئة القرص وسيتم حذ٠جميع البيانات.#@المواصلة؟ (التحقق مرة أخرى)", + "STR_INSTALL_SUCCESS":"مبروك!#@تم تثبيت Ventoy بنجاح على الجهاز.", + "STR_INSTALL_FAILED":"حدث خطأ أثناء التثبيت. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تÙقّد log.txt للتÙاصيل.", + "STR_UPDATE_SUCCESS":"مبروك!#@تم تحديث Ventoy بنجاح على الجهاز.", + "STR_UPDATE_FAILED":"حدث خطأ أثناء التحديث. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تÙقّد log.txt للتÙاصيل.", + "STR_WAIT_PROCESS":"هناك عملية نشطة، يرجى الانتظار...", + "STR_MENU_OPTION":"خيارات", + "STR_MENU_SECURE_BOOT":"تمهيد آمن", + "STR_MENU_PART_CFG":"تكوين التقسيم", + "STR_BTN_OK":"مواÙÙ‚", + "STR_BTN_CANCEL":"إلغاء", + "STR_PRESERVE_SPACE":"الحÙاظ على بعض المساحة ÙÙŠ الجزء السÙلي من القرص", + "STR_SPACE_VAL_INVALID":"قيمة غير صالحة للمساحة المحجوزة", + "STR_MENU_CLEAR":"إزالة Ventoy", + "STR_CLEAR_SUCCESS":"تمت إزالة Ventoy من الجهاز بنجاح.", + "STR_CLEAR_FAILED":"حدث خطأ عند إزالة Ventoy من القرص. يمكنك إعادة توصيل الـUSB والمحاولة مرة أخرى. تÙقد log.txt للتÙاصيل.", + "STR_MENU_PART_STYLE":"أسلوب التقسيم", + "STR_DISK_2TB_MBR_ERROR":"يرجى اختيار GPT للأقراص الأكبر من 2 تيرابايت", + "STR_SHOW_ALL_DEV":"عرض كاÙØ© الأجهزة", + "STR_PART_ALIGN_4KB":"محاذاة الأقسام مع 4KB", + "STR_WEB_COMMUNICATION_ERR":"خطأ ÙÙŠ الاتصال:", + "STR_WEB_REMOTE_ABNORMAL":"خطأ ÙÙŠ الاتصال: بعيد غير طبيعي", + "STR_WEB_REQUEST_TIMEOUT":"خطأ ÙÙŠ الاتصال: انتهت مهلة الطلب", + "STR_WEB_SERVICE_UNAVAILABLE":"خطأ ÙÙŠ الاتصال: الخدمة غير متوÙرة", + "STR_WEB_TOKEN_MISMATCH":"تم تحديث حالة البرنامج الخÙÙŠ ØŒ يرجى إعادة المحاولة لاحقًا.", + "STR_WEB_SERVICE_BUSY":"الخدمة مشغولة ØŒ يرجى إعادة المحاولة لاحقًا.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Korean (한국어)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"VenusGirl", + + "STR_ERROR":"오류", + "STR_WARNING":"경고", + "STR_INFO":"ì •ë³´", + "STR_INCORRECT_DIR":"올바른 디렉토리ì—ì„œ 실행하십시오!", + "STR_INCORRECT_TREE_DIR":"여기서 실행하지 ë§ê³ , ì¶œì‹œëœ ì„¤ì¹˜ 패키지를 다운로드한 ë‹¤ìŒ ê±°ê¸°ì„œ 실행하십시오.", + "STR_DEVICE":"장치", + "STR_LOCAL_VER":"íŒ¨í‚¤ì§€ì˜ Ventoy 버전", + "STR_DISK_VER":"장치 ë‚´ë¶€ì˜ Ventoy 버전", + "STR_STATUS":"ìƒíƒœ - 준비 완료", + "STR_INSTALL":"설치", + "STR_UPDATE":"ì—…ë°ì´íŠ¸", + "STR_UPDATE_TIP":"업그레ì´ë“œ ìž‘ì—…ì€ ì•ˆì „í•˜ë©° ISO 파ì¼ì€ 변경ë˜ì§€ 않습니다.#@계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", + "STR_INSTALL_TIP":"디스í¬ê°€ í¬ë§·ë˜ê³  모든 ë°ì´í„°ê°€ ì†ì‹¤ë©ë‹ˆë‹¤.#@계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", + "STR_INSTALL_TIP2":"디스í¬ê°€ í¬ë§·ë˜ê³  모든 ë°ì´í„°ê°€ ì†ì‹¤ë©ë‹ˆë‹¤.#@계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ? (다시 확ì¸)", + "STR_INSTALL_SUCCESS":"축하합니다!#@Ventoyê°€ ìž¥ì¹˜ì— ì„±ê³µì ìœ¼ë¡œ 설치ë˜ì—ˆìŠµë‹ˆë‹¤.", + "STR_INSTALL_FAILED":"설치 중 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. USB를 다시 연결하고 다시 ì‹œë„í•  수 있습니다. ìžì„¸í•œ ë‚´ìš©ì€ log.txt를 확ì¸í•˜ì‹­ì‹œì˜¤.", + "STR_UPDATE_SUCCESS":"축하합니다!#@Ventoyê°€ ìž¥ì¹˜ì— ì„±ê³µì ìœ¼ë¡œ ì—…ë°ì´íŠ¸ë˜ì—ˆìŠµë‹ˆë‹¤.", + "STR_UPDATE_FAILED":"ì—…ë°ì´íŠ¸ ì¤‘ì— ì˜¤ë¥˜ê°€ ë°œìƒí–ˆìŠµë‹ˆë‹¤. USB를 다시 연결하고 다시 ì‹œë„í•  수 있습니다. ìžì„¸í•œ ë‚´ìš©ì€ log.txt를 확ì¸í•˜ì‹­ì‹œì˜¤.", + "STR_WAIT_PROCESS":"현재 ìž‘ì—…ì´ ì‹¤í–‰ 중입니다. 기다려 주십시오...", + "STR_MENU_OPTION":"옵션", + "STR_MENU_SECURE_BOOT":"보안 부트 (Secure Boot) 지ì›", + "STR_MENU_PART_CFG":"파티션 구성", + "STR_BTN_OK":"확ì¸", + "STR_BTN_CANCEL":"취소", + "STR_PRESERVE_SPACE":"디스í¬ì˜ ëì— ì˜ˆì•½ëœ ê³µê°„ 확보", + "STR_SPACE_VAL_INVALID":"ì˜ˆì•½ëœ ê³µê°„ì˜ ê°’ì´ ìž˜ëª»ë˜ì—ˆìŠµë‹ˆë‹¤", + "STR_MENU_CLEAR":"Ventoy 제거", + "STR_CLEAR_SUCCESS":"Ventoyê°€ 장치ì—ì„œ 성공ì ìœ¼ë¡œ 제거ë˜ì—ˆìŠµë‹ˆë‹¤.", + "STR_CLEAR_FAILED":"디스í¬ì—ì„œ Ventoy를 지울 ë•Œ 오류가 ë°œìƒí–ˆìŠµë‹ˆë‹¤. USB를 다시 연결하고 다시 ì‹œë„í•  수 있습니다. ìžì„¸í•œ ë‚´ìš©ì€ log.txt를 확ì¸í•˜ì‹­ì‹œì˜¤.", + "STR_MENU_PART_STYLE":"파티션 유형", + "STR_DISK_2TB_MBR_ERROR":"2TB ì´ìƒì˜ 디스í¬ëŠ” GPT를 ì„ íƒí•˜ì‹­ì‹œì˜¤", + "STR_SHOW_ALL_DEV":"모든 장치 표시", + "STR_PART_ALIGN_4KB":"íŒŒí‹°ì…˜ì„ 4KBë¡œ ì •ë ¬", + "STR_WEB_COMMUNICATION_ERR":"통신 오류:", + "STR_WEB_REMOTE_ABNORMAL":"통신 오류: ì›ê²© ì´ìƒ", + "STR_WEB_REQUEST_TIMEOUT":"통신 오류: ìš”ì²­ì´ ì‹œê°„ 초과ë¨", + "STR_WEB_SERVICE_UNAVAILABLE":"통신 오류: 서비스를 사용할 수 ì—†ìŒ", + "STR_WEB_TOKEN_MISMATCH":"ë°ëª¬ ìƒíƒœê°€ ì—…ë°ì´íŠ¸ë˜ì—ˆìŠµë‹ˆë‹¤. ë‚˜ì¤‘ì— ë‹¤ì‹œ ì‹œë„하십시오.", + "STR_WEB_SERVICE_BUSY":"서비스가 사용 중입니다. ë‚˜ì¤‘ì— ë‹¤ì‹œ ì‹œë„하십시오.", + "STR_MENU_VTSI_CREATE":"VTSI íŒŒì¼ ìƒì„±", + "STR_VTSI_CREATE_TIP":"ì´ë²ˆì—는 ìž¥ì¹˜ì— ì“°ì§€ ì•Šê³  VTSI 파ì¼#@만 ìƒì„±í•©ë‹ˆë‹¤.#@계ì†í•˜ì‹œê² ìŠµë‹ˆê¹Œ?", + "STR_VTSI_CREATE_SUCCESS":"VTSI 파ì¼ì´ 성공ì ìœ¼ë¡œ ìƒì„±ë˜ì—ˆìŠµë‹ˆë‹¤!#@Rufus(3.15+)를 사용하여 ìž¥ì¹˜ì— ê¸°ë¡í•˜ì—¬ Ventoy 설치를 완료할 수 있습니다.", + "STR_VTSI_CREATE_FAILED":"VTSI 파ì¼ì„ ìƒì„±í•˜ì§€ 못했습니다.", + "STRXXX":"" + }, + { + "name":"Chinese Simplified (简体中文)", + "FontFamily":"宋体", + "FontSize":14, + "Author":"longpanda", + + "STR_ERROR":"错误", + "STR_WARNING":"警告", + "STR_INFO":"æ醒", + "STR_INCORRECT_DIR":"请在正确的目录下è¿è¡Œ!", + "STR_INCORRECT_TREE_DIR":"请ä¸è¦åœ¨ä»£ç æ ‘下è¿è¡Œæ­¤ç¨‹åº(INSTALL目录),请下载安装包,解压åŽåœ¨é‚£é‡Œè¿è¡Œã€‚", + "STR_DEVICE":"设备", + "STR_LOCAL_VER":"安装包内 Ventoy 版本", + "STR_DISK_VER":"设备内部 Ventoy 版本", + "STR_STATUS":"çŠ¶æ€ - 准备就绪", + "STR_INSTALL":"安装", + "STR_UPDATE":"å‡çº§", + "STR_UPDATE_TIP":"å‡çº§æ“作是安全的, ISO文件ä¸ä¼šä¸¢å¤±#@是å¦ç»§ç»­ï¼Ÿ", + "STR_INSTALL_TIP":"ç£ç›˜ä¼šè¢«æ ¼å¼åŒ–, 所有数æ®éƒ½ä¼šä¸¢å¤±!#@是å¦ç»§ç»­ï¼Ÿ", + "STR_INSTALL_TIP2":"ç£ç›˜ä¼šè¢«æ ¼å¼åŒ–, 所有数æ®éƒ½ä¼šä¸¢å¤±!#@å†æ¬¡ç¡®è®¤æ˜¯å¦ç»§ç»­ï¼Ÿ", + "STR_INSTALL_SUCCESS":"æ­å–œä½ ! Ventoy å·²ç»æˆåŠŸå®‰è£…到此设备中.", + "STR_INSTALL_FAILED":"安装 Ventoy 过程中å‘生错误. ä½ å¯ä»¥é‡æ–°æ‹”æ’一下U盘然åŽé‡è¯•ä¸€æ¬¡, 详细信æ¯è¯·æŸ¥é˜… log.txt 文件.", + "STR_UPDATE_SUCCESS":"æ­å–œä½ ! 新版本的 Ventoy å·²ç»æˆåŠŸæ›´æ–°åˆ°æ­¤è®¾å¤‡ä¸­.", + "STR_UPDATE_FAILED":"æ›´æ–° Ventoy 过程中é‡åˆ°é”™è¯¯. ä½ å¯ä»¥é‡æ–°æ‹”æ’一下U盘然åŽé‡è¯•ä¸€æ¬¡, 详细信æ¯è¯·æŸ¥é˜… log.txt 文件.", + "STR_WAIT_PROCESS":"当å‰æœ‰ä»»åŠ¡æ­£åœ¨è¿è¡Œ, 请等待...", + "STR_MENU_OPTION":"é…置选项", + "STR_MENU_SECURE_BOOT":"安全å¯åŠ¨æ”¯æŒ", + "STR_MENU_PART_CFG":"分区设置", + "STR_BTN_OK":"确定", + "STR_BTN_CANCEL":"å–消", + "STR_PRESERVE_SPACE":"在ç£ç›˜æœ€åŽä¿ç•™ä¸€æ®µç©ºé—´", + "STR_SPACE_VAL_INVALID":"ä¿ç•™ç©ºé—´çš„数值éžæ³•", + "STR_MENU_CLEAR":"清除 Ventoy", + "STR_CLEAR_SUCCESS":"Ventoyå·²ç»æˆåŠŸä»Žæ­¤è®¾å¤‡ä¸­æ¸…除.", + "STR_CLEAR_FAILED":"清除 Ventoy 过程中é‡åˆ°é”™è¯¯. ä½ å¯ä»¥é‡æ–°æ‹”æ’一下U盘然åŽé‡è¯•ä¸€æ¬¡, 详细信æ¯è¯·æŸ¥é˜… log.txt 文件.", + "STR_MENU_PART_STYLE":"分区类型", + "STR_DISK_2TB_MBR_ERROR":"ç£ç›˜å®¹é‡è¶…过2TB,请选择GPT分区格å¼", + "STR_SHOW_ALL_DEV":"显示所有设备", + "STR_PART_ALIGN_4KB":"分区按照 4KB 对é½", + "STR_WEB_COMMUNICATION_ERR":"通信失败:", + "STR_WEB_REMOTE_ABNORMAL":"通信失败:æœåŠ¡ç«¯å¼‚常", + "STR_WEB_REQUEST_TIMEOUT":"通信失败:请求超时", + "STR_WEB_SERVICE_UNAVAILABLE":"通信失败:æœåŠ¡ä¸å¯ç”¨", + "STR_WEB_TOKEN_MISMATCH":"åŽå°æœåŠ¡çŠ¶æ€æ›´æ–°ï¼Œè¯·ç¨åŽé‡è¯•", + "STR_WEB_SERVICE_BUSY":"åŽå°æœåŠ¡æ­£å¿™ï¼Œè¯·ç¨åŽé‡è¯•", + "STR_MENU_VTSI_CREATE":"创建 VTSI 文件", + "STR_VTSI_CREATE_TIP":"本æ“作ä¸ä¼šå‘设备中写入数æ®ï¼Œè€Œåªä¼šç”Ÿæˆä¸€ä¸ª VTSI 文件#@是å¦ç»§ç»­ï¼Ÿ", + "STR_VTSI_CREATE_SUCCESS":"VTSI 文件创建æˆåŠŸï¼Œä½ å¯ä»¥ä½¿ç”¨Rufus(3.15+)将其写入对应设备,从而完æˆVentoy的安装", + "STR_VTSI_CREATE_FAILED":"VTSI 文件创建失败", + "STRXXX":"" + }, + { + "name":"English (English)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"longpanda", + + "STR_ERROR":"Error", + "STR_WARNING":"Warning", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Please run under the correct directory!", + "STR_INCORRECT_TREE_DIR":"Don't run me here, please download the released install package, and run there.", + "STR_DEVICE":"Device", + "STR_LOCAL_VER":"Ventoy In Package", + "STR_DISK_VER":"Ventoy In Device", + "STR_STATUS":"Status - READY", + "STR_INSTALL":"Install", + "STR_UPDATE":"Update", + "STR_UPDATE_TIP":"Upgrade operation is safe, ISO files will be unchanged.#@Continue?", + "STR_INSTALL_TIP":"The disk will be formatted and all the data will be lost.#@Continue?", + "STR_INSTALL_TIP2":"The disk will be formatted and all the data will be lost.#@Continue? (Double Check)", + "STR_INSTALL_SUCCESS":"Congratulations!#@Ventoy has been successfully installed to the device.", + "STR_INSTALL_FAILED":"An error occurred during the installation. You can replug the USB and try again. Check log.txt for detail.", + "STR_UPDATE_SUCCESS":"Congratulations!#@Ventoy has been successfully updated to the device.", + "STR_UPDATE_FAILED":"An error occurred during the update. You can replug the USB and try again. Check log.txt for detail.", + "STR_WAIT_PROCESS":"A thread is running, please wait...", + "STR_MENU_OPTION":"Option", + "STR_MENU_SECURE_BOOT":"Secure Boot Support", + "STR_MENU_PART_CFG":"Partition Configuration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancel", + "STR_PRESERVE_SPACE":"Preserve some space at the end of the disk", + "STR_SPACE_VAL_INVALID":"Invalid value for reserved space", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clearing Ventoy from disk. You can replug the USB and try again. Check log.txt for details.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Persian (Ùارسی)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"ivadham", + + "STR_ERROR":"خطا", + "STR_WARNING":"هشدار", + "STR_INFO":"توضیحات", + "STR_INCORRECT_DIR":".لطÙاً در پوشه‌دان صحیح اجرا کنید", + "STR_INCORRECT_TREE_DIR":".این‌جا اجرا نکنید، لطÙاً بستهٔ نصب را دانلود Ùˆ آن‌جا اجرا کنید", + "STR_DEVICE":"حاÙظهٔ قابل حمل", + "STR_LOCAL_VER":"آمادهٔ نصب Ventoy", + "STR_DISK_VER":"نصب‌شده روی حاÙظه Ventoy", + "STR_STATUS":"وضعیت - آماده", + "STR_INSTALL":"Ùرمت Ùˆ نصب", + "STR_UPDATE":"به‌روزرسانی", + "STR_UPDATE_TIP":"عملیات به‌روزرسانی بی‌خطر است Ùˆ داده‌های روی حاÙظهٔ قابل حمل سالم باقی خواهند ماند. ادامه؟", + "STR_INSTALL_TIP":"حاÙظهٔ قابل حمل Ùرمت Ùˆ تمامی داده‌های آن پاک خواهد شد. ادامه؟", + "STR_INSTALL_TIP2":"توجه: این عملیات غیرقابل بازگشت است. ادامه؟", + "STR_INSTALL_SUCCESS":".تبریک! عملیات نصب بر روی حاÙظهٔ قابل حمل با موÙقیت پایان یاÙت", + "STR_INSTALL_FAILED":".خطا در عملیات نصب! یو‌اس‌بی را از نو متصل Ùˆ دوباره تلاش کنید", + "STR_UPDATE_SUCCESS":".تبریک! نرم‌اÙزار با موÙقیت بر روی حاÙظهٔ قابل حمل به‌روزرسانی شد", + "STR_UPDATE_FAILED":".خطا در به‌روزرسانی! یو‌اس‌بی را از نو متصل Ùˆ دوباره تلاش کنید", + "STR_WAIT_PROCESS":"...پروسه‌ای در حال اجرا است، لطÙاً صبر کنید", + "STR_MENU_OPTION":"تنظیمات", + "STR_MENU_SECURE_BOOT":"(Secure Boot) بوت امن", + "STR_MENU_PART_CFG":"پیکربندی پارتیشن", + "STR_BTN_OK":"تأیید", + "STR_BTN_CANCEL":"انصراÙ", + "STR_PRESERVE_SPACE":"اختصاص مقداری Ùضا به انتهای حاÙظهٔ قابل حمل", + "STR_SPACE_VAL_INVALID":".این مقدار Ùضا برای اختصاص‌یاÙتن نامعتبر است", + "STR_MENU_CLEAR":"Ventoy را پاک کنید", + "STR_CLEAR_SUCCESS":"Ventoy با موÙقیت از دستگاه برداشته شد.", + "STR_CLEAR_FAILED":"هنگام پاک کردن Ventoy از روی دیسک خطایی روی داد. Ù…ÛŒ توانید USB را دوباره از برق جدا کنید Ùˆ دوباره امتحان کنید. log.txt را برای جزئیات بررسی کنید.", + "STR_MENU_PART_STYLE":"سبک پارتیشن بندی", + "STR_DISK_2TB_MBR_ERROR":"لطÙاً GPT را برای دیسک بیش از 2 ترابایت انتخاب کنید", + "STR_SHOW_ALL_DEV":"نمایش همه دستگاه ها", + "STR_PART_ALIGN_4KB":"پارتیشن ها را با 4KB تراز کنید", + "STR_WEB_COMMUNICATION_ERR":"خطای ارتباطی:", + "STR_WEB_REMOTE_ABNORMAL":"خطای ارتباطی: از راه دور غیر طبیعی است", + "STR_WEB_REQUEST_TIMEOUT":"خطای ارتباطی: زمان درخواست به پایان رسیده است", + "STR_WEB_SERVICE_UNAVAILABLE":"خطای ارتباطی: سرویس موجود نیست", + "STR_WEB_TOKEN_MISMATCH":"وضعیت Daemon به روز شد ØŒ لطÙاً بعداً دوباره امتحان کنید.", + "STR_WEB_SERVICE_BUSY":"سرویس شلوغ است ØŒ لطÙاً بعداً دوباره امتحان کنید.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Polish (Polski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"B.O.S.S", + + "STR_ERROR":"BÅ‚Ä…d", + "STR_WARNING":"Ostrzeżenie", + "STR_INFO":"Informacja", + "STR_INCORRECT_DIR":"ProszÄ™ uruchom w odpowiednim katalogu!", + "STR_INCORRECT_TREE_DIR":"Nie uruchamiaj mnie tutaj, pobierz pakiet instalacyjny i uruchom go.", + "STR_DEVICE":"UrzÄ…dzenie", + "STR_LOCAL_VER":"Ventoy w programie", + "STR_DISK_VER":"Ventoy na urzÄ…dzeniu", + "STR_STATUS":"Status - GOTOWY", + "STR_INSTALL":"Zainstaluj", + "STR_UPDATE":"Zaktualizuj", + "STR_UPDATE_TIP":"Operacja aktualizacji jest bezpieczna, pliki ISO pozostanÄ… niezmienione.#@Kontynuować?", + "STR_INSTALL_TIP":"Dysk zostanie sformatowany, a wszystkie dane zostanÄ… utracone.#@Kontynuować?", + "STR_INSTALL_TIP2":"Dysk zostanie sformatowany, a wszystkie dane zostanÄ… utracone.#@Kontynuować? (Podwójne sprawdzenie)", + "STR_INSTALL_SUCCESS":"Gratulacje!#@Ventoy zostaÅ‚ pomyÅ›lnie zainstalowany na urzÄ…dzeniu.", + "STR_INSTALL_FAILED":"WystÄ…piÅ‚ bÅ‚Ä…d podczas instalacji. Możesz ponownie podÅ‚Ä…czyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_UPDATE_SUCCESS":"Gratulacje!#@Ventoy zostaÅ‚o pomyÅ›lnie zaktualizowane na urzÄ…dzeniu.", + "STR_UPDATE_FAILED":"WystÄ…piÅ‚ bÅ‚Ä…d podczas aktualizacji. Możesz ponownie podÅ‚Ä…czyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_WAIT_PROCESS":"WÄ…tek jest uruchomiony, proszÄ™ czekać...", + "STR_MENU_OPTION":"Opcje", + "STR_MENU_SECURE_BOOT":"Bezpieczny rozruch/Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracja partycji", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Anuluj", + "STR_PRESERVE_SPACE":"Zachowaj trochÄ™ miejsca na dole dysku", + "STR_SPACE_VAL_INVALID":"NieprawidÅ‚owa wartość zarezerwowanego miejsca", + "STR_MENU_CLEAR":"Wyczyść Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy zostaÅ‚ pomyÅ›lnie usuniÄ™ty z urzÄ…dzenia.", + "STR_CLEAR_FAILED":"WystÄ…piÅ‚ bÅ‚Ä…d podczas usuwania Ventoy z dysku. Możesz podÅ‚Ä…czyć USB i spróbować jeszcze raz. Szczegóły w log.txt.", + "STR_MENU_PART_STYLE":"Schemat partycji", + "STR_DISK_2TB_MBR_ERROR":"Wybierz GPT dla dysku powyżej 2TB", + "STR_SHOW_ALL_DEV":"Pokaż wszystkie urzÄ…dzenia", + "STR_PART_ALIGN_4KB":"Wyrównaj partycje z 4KB", + "STR_WEB_COMMUNICATION_ERR":"BÅ‚Ä…d komunikacji:", + "STR_WEB_REMOTE_ABNORMAL":"BÅ‚Ä…d komunikacji: nieprawidÅ‚owy serwer", + "STR_WEB_REQUEST_TIMEOUT":"BÅ‚Ä…d komunikacji: przekroczono limit czasu żądania", + "STR_WEB_SERVICE_UNAVAILABLE":"BÅ‚Ä…d komunikacji: usÅ‚uga niedostÄ™pna", + "STR_WEB_TOKEN_MISMATCH":"Stan daemona zostaÅ‚ zaktualizowany, spróbuj ponownie później.", + "STR_WEB_SERVICE_BUSY":"UsÅ‚uga jest zajÄ™ta, spróbuj ponownie później.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Portuguese Brazilian (Português do Brasil)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"EstevaoCostaG3, David BrazSan", + + "STR_ERROR":"Erro", + "STR_WARNING":"Atenção", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Por favor, execute no diretório correto!", + "STR_INCORRECT_TREE_DIR":"Não me execute aqui, por favor baixe o pacote de instalação lançado, e me execute lá.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy em pacote", + "STR_DISK_VER":"Ventoy em dispositivo", + "STR_STATUS":"Status - PRONTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Atualizar", + "STR_UPDATE_TIP":"A operação de atualização é segura, os arquivos ISO não serão alterados.#@Continuar?", + "STR_INSTALL_TIP":"O disco será formatado e todos os dados serão perdidos.#@Continuar?", + "STR_INSTALL_TIP2":"O disco será formatado e todos os dados serão perdidos.#@Continuar? (Verificação dupla)", + "STR_INSTALL_SUCCESS":"Parabéns!#@Ventoy foi instalado com sucesso no dispositivo.", + "STR_INSTALL_FAILED":"Um erro ocorreu durante a instalação. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o arquivo log.txt para mais detalhes.", + "STR_UPDATE_SUCCESS":"Parabéns!#@Ventoy foi atualizado com sucesso no dispositivo.", + "STR_UPDATE_FAILED":"Um erro ocorreu durante a atualização. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o arquivo log.txt para mais detalhes.", + "STR_WAIT_PROCESS":"Uma thread está em execução, por favor espere...", + "STR_MENU_OPTION":"Opção", + "STR_MENU_SECURE_BOOT":"Boot seguro", + "STR_MENU_PART_CFG":"Configuração de Partição", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algum espaço no final do disco", + "STR_SPACE_VAL_INVALID":"Valor invalido para o espaço reservado", + "STR_MENU_CLEAR":"Remover o Ventoy", + "STR_CLEAR_SUCCESS":"O Ventoy foi removido deste dispositivo com sucesso.", + "STR_CLEAR_FAILED":"Um erro ocorreu ao remover o Ventoy do disco. Você pode reconectar o dispositivo USB e tentar novamente. Verifique o Arquivo log.txt para mais detalhes.", + "STR_MENU_PART_STYLE":"Estilo de Partição", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecione GPT para discos maiores que 2TB", + "STR_SHOW_ALL_DEV":"Mostrar Todos os Dispositivos", + "STR_PART_ALIGN_4KB":"Alinhar partições com 4KB", + "STR_WEB_COMMUNICATION_ERR":"Erro de comunicação:", + "STR_WEB_REMOTE_ABNORMAL":"Erro de comunicação: remoto anormal", + "STR_WEB_REQUEST_TIMEOUT":"Erro de comunicação: Solicitação cronometrado", + "STR_WEB_SERVICE_UNAVAILABLE":"Erro de comunicação: Serviço indisponível", + "STR_WEB_TOKEN_MISMATCH":"Status daemon atualizado, por favor, tente novamente mais tarde.", + "STR_WEB_SERVICE_BUSY":"O serviço está ocupado, por favor, tente novamente mais tarde.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Turkish (Türkçe)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Erhan Kültür/crasadure", + + "STR_ERROR":"Hata", + "STR_WARNING":"Uyarı", + "STR_INFO":"Bilgi", + "STR_INCORRECT_DIR":"Lütfen doÄŸru dizin altında çalıştırın!", + "STR_INCORRECT_TREE_DIR":"Dosyayı burada çalıştırma, lütfen yayınlanan en son kurulum paketini indirin ve oradan çalıştırın.", + "STR_DEVICE":"Aygıt", + "STR_LOCAL_VER":"Ventoy GÃœNCEL Sürüm", + "STR_DISK_VER":"Cihazdaki Ventoy Sürümü", + "STR_STATUS":"Durum - HAZIR", + "STR_INSTALL":"Kur", + "STR_UPDATE":"Güncelle", + "STR_UPDATE_TIP":"Ventoyun versiyon bilgisi güncellenecek, ISO dosyalarınız bundan etkilenmiyecek.#@Devam edilsinmi?", + "STR_INSTALL_TIP":"Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsinmi?", + "STR_INSTALL_TIP2":"Disk biçimlendirilecek ve tüm veriler kaybolacak.#@Devam edilsinmi? (Son UYARI!)", + "STR_INSTALL_SUCCESS":"Tebrikler!#@ventoy cihaza baÅŸarıyla kuruldu.", + "STR_INSTALL_FAILED":"Yükleme sırasında bir hata oluÅŸtu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.", + "STR_UPDATE_SUCCESS":"Tebrikler!#@ventoy cihazda baÅŸarıyla güncellendi.", + "STR_UPDATE_FAILED":"Güncelleme sırasında bir hata oluÅŸtu. USB'yi yeniden takıp tekrar deneyebilirsiniz. Ayrıntılar için log.txt dosyasına bakın.", + "STR_WAIT_PROCESS":"Mevcut iÅŸlem çalışıyor, lütfen bekleyiniz ...", + "STR_MENU_OPTION":"Seçenek", + "STR_MENU_SECURE_BOOT":"Güvenli Önyükleme", + "STR_MENU_PART_CFG":"Partisyon Yapılandırması", + "STR_BTN_OK":"Tamam", + "STR_BTN_CANCEL":"Ä°ptal et", + "STR_PRESERVE_SPACE":"Diskin sonunda ayrılmış disk partisyonu oluÅŸtur", + "STR_SPACE_VAL_INVALID":"Ayrılmış alan için geçersiz deÄŸer girdiniz", + "STR_MENU_CLEAR":"Ventoyu USB Diskten Sil", + "STR_CLEAR_SUCCESS":"Ventoy baÅŸarılı bir ÅŸekilde diskten silindi", + "STR_CLEAR_FAILED":"Ventoy USB diskten temizlenirken bir hata oluÅŸtu.Lütfen USB Diski tekrar takın ve tekrar deneyin.Hatanın detayları için Log.txt dosyasını okuyun", + "STR_MENU_PART_STYLE":"Partisyon Yapısı", + "STR_DISK_2TB_MBR_ERROR":"2TB üstündeki diskler için lütfen GPT disk yapısını seçiniz.", + "STR_SHOW_ALL_DEV":"Tüm Cihazları Göster", + "STR_PART_ALIGN_4KB":"Tüm Partisyonları 4KB düzeninde hizala", + "STR_WEB_COMMUNICATION_ERR":"IletiÅŸim Hatası:", + "STR_WEB_REMOTE_ABNORMAL":"IletiÅŸim Hatası:Uzaktan eriÅŸim hizmeti anormal durumda", + "STR_WEB_REQUEST_TIMEOUT":"IletiÅŸim hatası: Uzaktan eriÅŸim isteÄŸi zaman aşımına uÄŸradı", + "STR_WEB_SERVICE_UNAVAILABLE":"IletiÅŸim hatası: Uzaktan web eriÅŸim hizmeti eriÅŸilemez durumda", + "STR_WEB_TOKEN_MISMATCH":"Daemon durumu güncellendi,lütfen daha sonra tekrar deneyiniz.", + "STR_WEB_SERVICE_BUSY":"Hizmet meÅŸgul, lütfen daha sonra tekrar deneyin.", + "STR_MENU_VTSI_CREATE":"VTSI dosyası oluÅŸtur", + "STR_VTSI_CREATE_TIP":"Åžu an cihaza yazılmayacak,sadece bir VTSI dosyası oluÅŸturulacak#@Devam edilsin mi?", + "STR_VTSI_CREATE_SUCCESS":"VTSI dosyası baÅŸarılı bi ÅŸekilde oluÅŸturuldu!#@Ventoy un cihaza kurulumunu tamamlamak için Rufus(3.15+) programını kullanabilirsiniz.", + "STR_VTSI_CREATE_FAILED":"VTSI dosyası oluÅŸturma BaÅŸarısız!", + "STRXXX":"" + }, + { + "name":"German (Deutsch)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"luzea & u!^DEV", + + "STR_ERROR":"Fehler", + "STR_WARNING":"Warnung", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Bitte im richtigen Verzeichnis ausführen!", + "STR_INCORRECT_TREE_DIR":"Bitte nicht hier ausführen. Laden Sie das Installationspaket herunter und von dort aus ausführen.", + "STR_DEVICE":"Gerät", + "STR_LOCAL_VER":"Ventoy (lokal)", + "STR_DISK_VER":"Ventoy (Gerät)", + "STR_STATUS":"Status - BEREIT", + "STR_INSTALL":"Installieren", + "STR_UPDATE":"Aktualisieren", + "STR_UPDATE_TIP":"Die Durchführung der Aktualisierung ist sicher, ISO-Dateien bleiben unverändert.#@Fortfahren?", + "STR_INSTALL_TIP":"Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren?", + "STR_INSTALL_TIP2":"Das Gerät wird formatiert und alle Daten gehen verloren.#@Fortfahren? (erneute Ãœberprüfung)", + "STR_INSTALL_SUCCESS":"Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät installiert.", + "STR_INSTALL_FAILED":"Während der Installation ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Ãœberprüfen Sie die log.txt auf Details.", + "STR_UPDATE_SUCCESS":"Herzlichen Glückwunsch!#@Ventoy wurde erfolgreich auf dem Gerät aktualisiert.", + "STR_UPDATE_FAILED":"Während der Aktualisierung ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Ãœberprüfen Sie die log.txt auf Details.", + "STR_WAIT_PROCESS":"Ein anderer Thread läuft, bitte warten...", + "STR_MENU_OPTION":"Optionen", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Partitionskonfiguration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Abbrechen", + "STR_PRESERVE_SPACE":"Etwas Speicher am Ende des Datenträgers reservieren.", + "STR_SPACE_VAL_INVALID":"Ungültiger Wert für reservierten Speicherplatz!", + "STR_MENU_CLEAR":"Ventoy entfernen", + "STR_CLEAR_SUCCESS":"Ventoy wurde erfolgreich vom Gerät entfernt.", + "STR_CLEAR_FAILED":"Beim Versuch, Ventoy zu entfernen, ist ein Fehler aufgetreten. Stecken Sie das Gerät neu ein und versuchen Sie es erneut. Ãœberprüfen Sie die log.txt auf Details.", + "STR_MENU_PART_STYLE":"Partitionsstil", + "STR_DISK_2TB_MBR_ERROR":"Wählen Sie GPT für Geräte > 2TB aus.", + "STR_SHOW_ALL_DEV":"Alle Geräte anzeigen", + "STR_PART_ALIGN_4KB":"Richten Sie Partitionen mit 4KB aus", + "STR_WEB_COMMUNICATION_ERR":"Kommunikationsfehler:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikationsfehler: unnormales Verhalten", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfehler: Zeitüberschreitung der Anforderung", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfehler: Dienst nicht verfügbar", + "STR_WEB_TOKEN_MISMATCH":"Daemon-Status aktualisiert, bitte später erneut versuchen.", + "STR_WEB_SERVICE_BUSY":"Dienst ist ausgelastet, bitte später erneut versuchen.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Occitan (Occitan)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"quentin", + + "STR_ERROR":"Error", + "STR_WARNING":"Avertiment", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Aqueste programa deu s’executar dins lo bon repertòri !", + "STR_INCORRECT_TREE_DIR":"Lancetz pas aquò, mercés de telecargar lo programa d’installacion e relançatz-lo.", + "STR_DEVICE":"Periferic", + "STR_LOCAL_VER":"Ventoy en local", + "STR_DISK_VER":"Ventoy sul periferic", + "STR_STATUS":"Estat - prèst", + "STR_INSTALL":"Installacion", + "STR_UPDATE":"Mesa a jorn", + "STR_UPDATE_TIP":"La mesa a jorn es segura, los fichièrs ISO seràn pas modificats.#@Continhar ?", + "STR_INSTALL_TIP":"Lo disc serà formatat e totas sas donadas seràn perdudas.#@Contunhar ?", + "STR_INSTALL_TIP2":"Lo disc serà formatat e totas sas donadas seràn perdudas.#@Contunhar ? (confirmacion)", + "STR_INSTALL_SUCCESS":"Felicitacion  !#@Ventoy es estat corrèctament installat sul periferic.", + "STR_INSTALL_FAILED":"Una error s’es producha pendent l’installacion. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.", + "STR_UPDATE_SUCCESS":"Felicitacions !#@Ventoy es estat corrèctament mes a jorn sul periferic.", + "STR_UPDATE_FAILED":"Una error s’es producha pendent la mesa a jorn. Podètz tornar brancar lo periferic USB e tornar ensajar. Agachatz lo fichièr log.txt per ne saber mai.", + "STR_WAIT_PROCESS":"Una operacion es en cors, esperatz...", + "STR_MENU_OPTION":"Opcion", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Configuracion de particion", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Anullar", + "STR_PRESERVE_SPACE":"Servar d’espaci a la fin del disc", + "STR_SPACE_VAL_INVALID":"Valor invalida per l’espaci reservat", + "STR_MENU_CLEAR":"Escafar Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy es estat corrèctament tirat del periferic.", + "STR_CLEAR_FAILED":"Una error s’es producha pendent l’esfaçament de Ventoy del disc. Podètz tornar brancar l’USB e tornar ensajar. Vejatz log.txt pels detalhs.", + "STR_MENU_PART_STYLE":"Estil de particion", + "STR_DISK_2TB_MBR_ERROR":"Pels disques de mai de 2 To seleccionatz GPT", + "STR_SHOW_ALL_DEV":"Mostrar totes los periferics", + "STR_PART_ALIGN_4KB":"Alinhar las particions sus 4 Ko", + "STR_WEB_COMMUNICATION_ERR":"Error de comunicacion :", + "STR_WEB_REMOTE_ABNORMAL":"Error de comunicacion : remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Error de comunicacion : requèsta tardièra", + "STR_WEB_SERVICE_UNAVAILABLE":"Error de comunicacion : servici pas disponible", + "STR_WEB_TOKEN_MISMATCH":"Estat del Daemon actualizat, tornatz ensajar mai tard.", + "STR_WEB_SERVICE_BUSY":"Lo servici es ocupat, tornatz ensajar mai tard.", + "STR_MENU_VTSI_CREATE":"Generar lo fichièr VTSI", + "STR_VTSI_CREATE_TIP":"Aqueste còp cap d’escritura al disc, generacion del fichiet VTSI sonque#@Contunhar ?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"Fracàs de la creacion del fichièr VTSI.", + "STRXXX":"" + }, + { + "name":"French (Français)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"vboucard, Silejonu", + + "STR_ERROR":"Erreur", + "STR_WARNING":"Avertissement", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Ce programme doit s'exécuter dans le bon répertoire !", + "STR_INCORRECT_TREE_DIR":"Ne me lancez pas d'ici, veuillez télécharger le programme d'installation et relancez-le.", + "STR_DEVICE":"Périphérique", + "STR_LOCAL_VER":"Ventoy en local", + "STR_DISK_VER":"Ventoy sur le périphérique", + "STR_STATUS":"État - prêt", + "STR_INSTALL":"Installation", + "STR_UPDATE":"Mise à jour", + "STR_UPDATE_TIP":"La mise à jour est sûre, les fichiers ISO ne seront pas modifiés.#@Continuer ?", + "STR_INSTALL_TIP":"Le disque va être formaté et toutes ses données seront perdues.#@Continuer ?", + "STR_INSTALL_TIP2":"Le disque va être formaté et toutes ses données seront perdues.#@Continuer ? (Confirmation)", + "STR_INSTALL_SUCCESS":"Félicitations !#@Ventoy a été correctement installé sur le périphérique.", + "STR_INSTALL_FAILED":"Une erreur est survenue durant l'installation. Vous pouvez rebrancher le périphérique et réessayer. Consultez le fichier log.txt pour plus de détails.", + "STR_UPDATE_SUCCESS":"Félicitations !#@Ventoy a été correctement mis à jour sur le périphérique.", + "STR_UPDATE_FAILED":"Une erreur est survenue durant la mise à jour. Vous pouvez rebrancher le périphérique et réessayer. Consultez le fichier log.txt pour plus de détails.", + "STR_WAIT_PROCESS":"Une opération est en cours, veuillez patienter...", + "STR_MENU_OPTION":"Option", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Configuration des partitions", + "STR_BTN_OK":"Valider", + "STR_BTN_CANCEL":"Annuler", + "STR_PRESERVE_SPACE":"Réservez de l'espace à la fin du disque", + "STR_SPACE_VAL_INVALID":"Valeur de l'espace réservé invalide", + "STR_MENU_CLEAR":"Effacer Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy a été retiré du périphérique avec succès.", + "STR_CLEAR_FAILED":"Une erreur est survenue pendant la suppression de Ventoy. Vous pouvez rebrancher le périphérique et réessayer. Consultez le fichier log.txt pour plus de détails.", + "STR_MENU_PART_STYLE":"Type de partition", + "STR_DISK_2TB_MBR_ERROR":"Sélectionnez le type GPT pour les disques de plus de 2 To", + "STR_SHOW_ALL_DEV":"Afficher tous les périphériques", + "STR_PART_ALIGN_4KB":"Alignez les partitions sur 4 ko", + "STR_WEB_COMMUNICATION_ERR":"Erreur de communication :", + "STR_WEB_REMOTE_ABNORMAL":"Erreur de communication : anomalie sur le serveur", + "STR_WEB_REQUEST_TIMEOUT":"Erreur de communication : délai d'attente dépassé", + "STR_WEB_SERVICE_UNAVAILABLE":"Erreur de communication : service inaccessible", + "STR_WEB_TOKEN_MISMATCH":"Statut du démon mis à jour, veuillez réessayer plus tard.", + "STR_WEB_SERVICE_BUSY":"Service surchargé, veuillez réessayer plus tard.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Czech (ÄŒeÅ¡tina)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"vavanade", + + "STR_ERROR":"Chyba", + "STR_WARNING":"Varování", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"SpusÅ¥te prosím ve správném adresáři!", + "STR_INCORRECT_TREE_DIR":"NespouÅ¡tÄ›jte mÄ› zde, stáhnÄ›te si prosím vydaný instalaÄní balík a spusÅ¥te v nÄ›m.", + "STR_DEVICE":"Zařízení", + "STR_LOCAL_VER":"Ventoy v balíÄku", + "STR_DISK_VER":"Ventoy v zařízení", + "STR_STATUS":"Status - PŘIPRAVENO", + "STR_INSTALL":"Instalovat", + "STR_UPDATE":"Aktualizovat", + "STR_UPDATE_TIP":"Operace aktualizace je bezpeÄná, ISO soubory nebudou zmÄ›nÄ›ny.#@PokraÄovat?", + "STR_INSTALL_TIP":"Disk bude zformátován a vÅ¡echna data budou ztracena!#@PokraÄovat?", + "STR_INSTALL_TIP2":"Disk bude zformátován a vÅ¡echna data budou ztracena!#@PokraÄovat? (druhá kontrola)", + "STR_INSTALL_SUCCESS":"Gratulujeme!#@Ventoy byla na zařízení úspěšnÄ› nainstalována.", + "STR_INSTALL_FAILED":"V průbÄ›hu instalace se vyskytla chyba. Můžete vyjmout a znovu zastrÄit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_UPDATE_SUCCESS":"Gratulujeme!#@Ventoy byla na zařízení úspěšnÄ› aktualizována.", + "STR_UPDATE_FAILED":"V průbÄ›hu aktualizace se vyskytla chyba. Můžete vyjmout a znovu zastrÄit USB zařízení a zkusit to znovu. Pro podrobnosti se podívejte do souboru log.txt.", + "STR_WAIT_PROCESS":"Vlákno běží, prosíme vyÄkejte...", + "STR_MENU_OPTION":"Možnosti", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Konfigurace oddílu", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"zruÅ¡ení", + "STR_PRESERVE_SPACE":"Zachovejte místo na spodní stranÄ› disku", + "STR_SPACE_VAL_INVALID":"Neplatná hodnota pro vyhrazený prostor", + "STR_MENU_CLEAR":"Vymazat Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Styl oddílu", + "STR_DISK_2TB_MBR_ERROR":"Vyberte GPT pro disk pÅ™es 2TB", + "STR_SHOW_ALL_DEV":"Zobrazit vÅ¡echna zařízení", + "STR_PART_ALIGN_4KB":"Zarovnejte oddíly s 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Spanish (Español)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Carlos Sánchez, MELERIX", + + "STR_ERROR":"Error", + "STR_WARNING":"Advertencia", + "STR_INFO":"Información", + "STR_INCORRECT_DIR":"¡Por favor, ejecuta bajo el directorio correcto!", + "STR_INCORRECT_TREE_DIR":"No me ejecute aquí, por favor descarga el paquete de instalación lanzado, y ejecútalo allí.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy En Paquete", + "STR_DISK_VER":"Ventoy En Dispositivo", + "STR_STATUS":"Estado - LISTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Actualizar", + "STR_UPDATE_TIP":"La operación de actualización es segura, Los archivo ISO no se modificarán.#@¿Continuar?", + "STR_INSTALL_TIP":"El dispositivo será formateado y todos los datos se perderán.#@¿Continuar?", + "STR_INSTALL_TIP2":"El dispositivo será formateado y todos los datos se perderán.#@¿Continuar? (Doble Comprobación)", + "STR_INSTALL_SUCCESS":"¡Felicitaciones!#@Ventoy ha sido instalado exitosamente en el dispositivo.", + "STR_INSTALL_FAILED":"Ocurrió un error durante la instalación. Puedes reconectar el USB e intentar de nuevo. Comprueba log.txt para detalle.", + "STR_UPDATE_SUCCESS":"¡Felicitaciones!#@Ventoy ha sido actualizado exitosamente en el dispositivo.", + "STR_UPDATE_FAILED":"Ocurrió un error durante la actualización. Puedes reconectar el USB e intentar de nuevo. Comprueba log.txt para detalle.", + "STR_WAIT_PROCESS":"Un hilo está ejecutándose, por favor espera...", + "STR_MENU_OPTION":"Opción", + "STR_MENU_SECURE_BOOT":"Soporte De Arranque Seguro", + "STR_MENU_PART_CFG":"Configuración De Partición", + "STR_BTN_OK":"Aceptar", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algo de espacio al final del dispositivo", + "STR_SPACE_VAL_INVALID":"Valor inválido para espacio reservado", + "STR_MENU_CLEAR":"Limpiar Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy ha sido removido exitosamente desde el dispositivo.", + "STR_CLEAR_FAILED":"Ocurrió un error al limpiar Ventoy desde el dispositivo. Puedes reconectar el USB e intentar de nuevo. Comprueba log.txt para detalle.", + "STR_MENU_PART_STYLE":"Estilo De Partición", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecciona GPT para dispositivos sobre 2TB", + "STR_SHOW_ALL_DEV":"Mostrar Todos Los Dispositivos", + "STR_PART_ALIGN_4KB":"Alinear particiones con 4KB", + "STR_WEB_COMMUNICATION_ERR":"Error de comunicación:", + "STR_WEB_REMOTE_ABNORMAL":"Error de comunicación: anormal remoto", + "STR_WEB_REQUEST_TIMEOUT":"Error de comunicación: Tiempo de espera agotado", + "STR_WEB_SERVICE_UNAVAILABLE":"Error de comunicación: Servicio No Disponible", + "STR_WEB_TOKEN_MISMATCH":" Estado del daemon actualizado, por favor reintenta más tarde.", + "STR_WEB_SERVICE_BUSY":" El servicio está ocupado, por favor reintenta más tarde.", + "STR_MENU_VTSI_CREATE":"Generar Archivo VTSI", + "STR_VTSI_CREATE_TIP":"Esta vez no se escribirá al dispositivo, pero solo generará un archivo VTSI#@¿Continuar?", + "STR_VTSI_CREATE_SUCCESS":"¡Archivo VTSI creado exitosamente!#@Puedes usar Rufus(3.15+) para escribirlo al dispositivo a fin de completar la instalación de Ventoy.", + "STR_VTSI_CREATE_FAILED":"Fallo en el archivo VTSI creado.", + "STRXXX":"" + }, + { + "name":"Russian (PуÑÑкий)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R", + + "STR_ERROR":"Ошибка", + "STR_WARNING":"Предупреждение", + "STR_INFO":"ИнформациÑ", + "STR_INCORRECT_DIR":"ПожалуйÑта, запуÑтите в другом каталоге!", + "STR_INCORRECT_TREE_DIR":"Ðе запуÑкайте Ð¼ÐµÐ½Ñ Ð·Ð´ÐµÑÑŒ, пожалуйÑта, загрузите выпущенный уÑтановочный пакет и запуÑтите его в другом меÑте.", + "STR_DEVICE":"УÑтройÑтво", + "STR_LOCAL_VER":"Ventoy в пакете", + "STR_DISK_VER":"Ventoy на уÑтройÑтве", + "STR_STATUS":"Ð¡Ñ‚Ð°Ñ‚ÑƒÑ - ГОТОВ", + "STR_INSTALL":"УÑтановить", + "STR_UPDATE":"Обновить", + "STR_UPDATE_TIP":"Обновление безопаÑно, ISO-файлы оÑтанутÑÑ Ð±ÐµÐ· изменений.#@Продолжить?", + "STR_INSTALL_TIP":"ДиÑк будет отформатирован и вÑе данные будут потерÑны.#@Продолжить?", + "STR_INSTALL_TIP2":"ДиÑк будет отформатирован и вÑе данные будут потерÑны.#@Ð’Ñ‹ ДЕЙСТВИТЕЛЬÐО хотите продолжить?", + "STR_INSTALL_SUCCESS":"ПоздравлÑем!#@Ventoy был уÑпешно уÑтановлен на уÑтройÑтво.", + "STR_INSTALL_FAILED":"Во Ð²Ñ€ÐµÐ¼Ñ ÑƒÑтановки Ventoy произошла ошибка. Переподключите уÑтройÑтво и попробуйте Ñнова. Проверьте log.txt на ошибки.", + "STR_UPDATE_SUCCESS":"ПоздравлÑем!#@Ventoy был уÑпешно обновлен на уÑтройÑтве.", + "STR_UPDATE_FAILED":"Во Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ Ventoy произошла ошибка. Переподключите уÑтройÑтво и попробуйте Ñнова. Проверьте log.txt на ошибки.", + "STR_WAIT_PROCESS":"ПроцеÑÑ Ð·Ð°Ð¿ÑƒÑ‰ÐµÐ½, пожалуйÑта подождите...", + "STR_MENU_OPTION":"Опции", + "STR_MENU_SECURE_BOOT":"Поддержка Secure Boot", + "STR_MENU_PART_CFG":"Дополнительный раздел", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Отмена", + "STR_PRESERVE_SPACE":"Создать дополнительный раздел в конце диÑка", + "STR_SPACE_VAL_INVALID":"Ðеверное значение размера раздела", + "STR_MENU_CLEAR":"Удалить Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy был уÑпешно удалён Ñ ÑƒÑтройÑтва.", + "STR_CLEAR_FAILED":"Во Ð²Ñ€ÐµÐ¼Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ Ventoy произошла ошибка. Переподключите уÑтройÑтво и попробуйте Ñнова. Проверьте log.txt на ошибки.", + "STR_MENU_PART_STYLE":"Стиль разметки разделов", + "STR_DISK_2TB_MBR_ERROR":"ПожалуйÑта, выберите GPT Ð´Ð»Ñ Ð´Ð¸Ñков более 2ТБ", + "STR_SHOW_ALL_DEV":"Показать вÑе уÑтройÑтва", + "STR_PART_ALIGN_4KB":"ВыровнÑÑ‚ÑŒ разделы Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€Ð¾Ð¼ 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Ошибка ÑвÑзи:", + "STR_WEB_REMOTE_ABNORMAL":"Ошибка ÑвÑзи: Удаленное Ñоединение недейÑтвительно", + "STR_WEB_REQUEST_TIMEOUT":"Ошибка ÑвÑзи: ИÑтекло Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð¶Ð¸Ð´Ð°Ð½Ð¸Ñ Ð·Ð°Ð¿Ñ€Ð¾Ñа", + "STR_WEB_SERVICE_UNAVAILABLE":"Ошибка ÑвÑзи: Служба недоÑтупна", + "STR_WEB_TOKEN_MISMATCH":"Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð´ÐµÐ¼Ð¾Ð½Ð° обновлен. Повторите попытку позже.", + "STR_WEB_SERVICE_BUSY":"Служба занÑта, повторите попытку позже.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Bengali (বাংলা)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R", + + "STR_ERROR":"তà§à¦°à§à¦Ÿà¦¿", + "STR_WARNING":"সতরà§à¦•à¦¤à¦¾", + "STR_INFO":"তথà§à¦¯", + "STR_INCORRECT_DIR":"দয়া করে সঠিক ডিরেকà§à¦Ÿà¦°à¦¿à¦¤à§‡ চালান!", + "STR_INCORRECT_TREE_DIR":"আমাকে à¦à¦–ানে চালাবেন না, দয়া করে পà§à¦°à¦•à¦¾à¦¶à¦¿à¦¤ ইনসà§à¦Ÿà¦² পà§à¦¯à¦¾à¦•à§‡à¦œà¦Ÿà¦¿ ডাউনলোড করà§à¦¨ à¦à¦¬à¦‚ সেখানে চালান।", + "STR_DEVICE":"ডিভাইস", + "STR_LOCAL_VER":"Ventoy পà§à¦¯à¦¾à¦•à§‡à¦œà§‡ আছে", + "STR_DISK_VER":"Ventoy ডিভাইসে আছে", + "STR_STATUS":"সà§à¦¥à¦¿à¦¤à¦¿ - পà§à¦°à¦¸à§à¦¤à§à¦¤", + "STR_INSTALL":"ইনসà§à¦Ÿà¦² করà§à¦¨", + "STR_UPDATE":"আপডেট করà§à¦¨", + "STR_UPDATE_TIP":"আপগà§à¦°à§‡à¦¡ অপারেশন নিরাপদ, ISO ফাইলগà§à¦²à¦¿ অপরিবরà§à¦¤à¦¿à¦¤ থাকবে।#@চালিয়ে যাবেন?", + "STR_INSTALL_TIP":"ডিসà§à¦•à¦Ÿà¦¿ ফরà§à¦®à§à¦¯à¦¾à¦Ÿ করা হবে à¦à¦¬à¦‚ সমসà§à¦¤ ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন?", + "STR_INSTALL_TIP2":"ডিসà§à¦•à¦Ÿà¦¿ ফরà§à¦®à§à¦¯à¦¾à¦Ÿ করা হবে à¦à¦¬à¦‚ সমসà§à¦¤ ডেটা হারিয়ে যাবে।#@চালিয়ে যাবেন? (পà§à¦¨à¦ƒà¦¨à¦¿à¦°à§€à¦•à§à¦·à¦£)", + "STR_INSTALL_SUCCESS":"অভিননà§à¦¦à¦¨! #@Ventoy সফলভাবে ডিভাইসে ইনসà§à¦Ÿà¦² করা হয়েছে।", + "STR_INSTALL_FAILED":"ইনসà§à¦Ÿà¦²à§‡à¦¶à¦¨ চলাকালীন à¦à¦•à¦Ÿà¦¿ তà§à¦°à§à¦Ÿà¦¿ ঘটেছে। আপনি USB পà§à¦¨à¦°à¦¾à¦¯à¦¼ পà§à¦²à¦¾à¦— করতে পারেন à¦à¦¬à¦‚ আবার চেষà§à¦Ÿà¦¾ করতে পারেন। বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ জানার জনà§à¦¯ log.txt পরীকà§à¦·à¦¾ করà§à¦¨à¥¤", + "STR_UPDATE_SUCCESS":"অভিননà§à¦¦à¦¨! #@Ventoy সফলভাবে ডিভাইসে আপডেট করা হয়েছে।", + "STR_UPDATE_FAILED":"আপডেটের সময় à¦à¦•à¦Ÿà¦¿ তà§à¦°à§à¦Ÿà¦¿ ঘটেছে। আপনি USB পà§à¦¨à¦°à¦¾à¦¯à¦¼ পà§à¦²à¦¾à¦— করতে পারেন à¦à¦¬à¦‚ আবার চেষà§à¦Ÿà¦¾ করতে পারেন। বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ জানার জনà§à¦¯ log.txt পরীকà§à¦·à¦¾ করà§à¦¨à¥¤", + "STR_WAIT_PROCESS":"à¦à¦•à¦Ÿà¦¿ থà§à¦°à§‡à¦¡ চলছে, দয়া করে অপেকà§à¦·à¦¾ করà§à¦¨ ...", + "STR_MENU_OPTION":"অপসন", + "STR_MENU_SECURE_BOOT":"নিরাপদ বà§à¦Ÿ", + "STR_MENU_PART_CFG":"পারà§à¦Ÿà¦¿à¦¶à¦¨ কনফিগারেশন", + "STR_BTN_OK":"ঠিক আছে", + "STR_BTN_CANCEL":"বাতিল", + "STR_PRESERVE_SPACE":"ডিসà§à¦•à§‡à¦° নীচে কিছৠসà§à¦¥à¦¾à¦¨ সংরকà§à¦·à¦£ করà§à¦¨", + "STR_SPACE_VAL_INVALID":"সংরকà§à¦·à¦¿à¦¤ জায়গার জনà§à¦¯ অবৈধ মান", + "STR_MENU_CLEAR":"Ventoy সাফ", + "STR_CLEAR_SUCCESS":"Ventoy সফলভাবে ডিভাইস থেকে সরানো হয়েছে।", + "STR_CLEAR_FAILED":"ডিসà§à¦• থেকে Ventoy সাফ করার সময় à¦à¦•à¦Ÿà¦¿ তà§à¦°à§à¦Ÿà¦¿ ঘটেছে। আপনি USB পà§à¦¨à¦°à¦¾à¦¯à¦¼ পà§à¦²à¦¾à¦— করতে পারেন à¦à¦¬à¦‚ আবার চেষà§à¦Ÿà¦¾ করতে পারেন। বিসà§à¦¤à¦¾à¦°à¦¿à¦¤ জানার জনà§à¦¯ log.txt পরীকà§à¦·à¦¾ করà§à¦¨à¥¤", + "STR_MENU_PART_STYLE":"পারà§à¦Ÿà¦¿à¦¶à¦¨ সà§à¦Ÿà¦¾à¦‡à¦²", + "STR_DISK_2TB_MBR_ERROR":"2TB à¦à¦° বেশি ডিসà§à¦•à§‡à¦° জনà§à¦¯ দয়া করে GPT নিরà§à¦¬à¦¾à¦šà¦¨ করà§à¦¨", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Hindi (हिनà¥à¤¦à¥€)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"BL4CKH47H4CK3R", + + "STR_ERROR":"तà¥à¤°à¥à¤Ÿà¤¿", + "STR_WARNING":"चेतावनी", + "STR_INFO":"जानकारी", + "STR_INCORRECT_DIR":"कृपया सही निरà¥à¤¦à¥‡à¤¶à¤¿à¤•à¤¾ के तहत चलाà¤à¤‚!", + "STR_INCORRECT_TREE_DIR":"मà¥à¤à¥‡ यहां न चलाà¤à¤‚, कृपया जारी किठगठइंसà¥à¤Ÿà¥‰à¤² पैकेज को डाउनलोड करें, और वहां चलाà¤à¤‚।", + "STR_DEVICE":"डिवाइस", + "STR_LOCAL_VER":"पैकेज में Ventoy", + "STR_DISK_VER":"डिवाइस में Ventoy", + "STR_STATUS":"सà¥à¤¥à¤¿à¤¤à¤¿ - तैयार", + "STR_INSTALL":"इंसà¥à¤Ÿà¥‰à¤²", + "STR_UPDATE":"अपडेट करें", + "STR_UPDATE_TIP":"नवीनीकरण ऑपरेशन सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ है, ISO फाइल अपरिवरà¥à¤¤à¤¿à¤¤ रहेंगी।#@जारी रखें?", + "STR_INSTALL_TIP":"डिसà¥à¤• को सà¥à¤µà¤°à¥‚पित किया जाà¤à¤—ा और सभी डेटा खो जाà¤à¤—ा।#@जारी रखें?", + "STR_INSTALL_TIP2":"डिसà¥à¤• को सà¥à¤µà¤°à¥‚पित किया जाà¤à¤—ा और सभी डेटा खो जाà¤à¤—ा।#@जारी रखें? (दोहरी जाà¤à¤š)", + "STR_INSTALL_SUCCESS":"बधाई! #@Ventoy डिवाइस में सफलतापूरà¥à¤µà¤• सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ किया गया है।", + "STR_INSTALL_FAILED":"सà¥à¤¥à¤¾à¤ªà¤¨à¤¾ के दौरान à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆà¥¤ आप USB को पà¥à¤¨: सà¥à¤¥à¤¾à¤ªà¤¿à¤¤ कर सकते हैं और पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ कर सकते हैं। विसà¥à¤¤à¤¾à¤° के लिठlog.txt की जाà¤à¤š करें।", + "STR_UPDATE_SUCCESS":"बधाई! #@Ventoy डिवाइस में सफलतापूरà¥à¤µà¤• अपडेट हो गई है।", + "STR_UPDATE_FAILED":"अपडेट के दौरान à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆà¥¤ आप USB को पà¥à¤¨: भर सकते हैं और पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ कर सकते हैं। विसà¥à¤¤à¤¾à¤° के लिठlog.txt की जाà¤à¤š करें।", + "STR_WAIT_PROCESS":"à¤à¤• धागा चल रहा है, कृपया पà¥à¤°à¤¤à¥€à¤•à¥à¤·à¤¾ करें ...", + "STR_MENU_OPTION":"विकलà¥à¤ª", + "STR_MENU_SECURE_BOOT":"सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ बूट", + "STR_MENU_PART_CFG":"विभाजन विनà¥à¤¯à¤¾à¤¸", + "STR_BTN_OK":"ठीक है", + "STR_BTN_CANCEL":"रदà¥à¤¦ करना", + "STR_PRESERVE_SPACE":"डिसà¥à¤• के निचले भाग में कà¥à¤› सà¥à¤¥à¤¾à¤¨ सà¥à¤°à¤•à¥à¤·à¤¿à¤¤ रखें", + "STR_SPACE_VAL_INVALID":"आरकà¥à¤·à¤¿à¤¤ सà¥à¤¥à¤¾à¤¨ के लिठअमानà¥à¤¯ मान", + "STR_MENU_CLEAR":"Ventoy को हटा दें", + "STR_CLEAR_SUCCESS":"डिवाइस से Ventoy को सफलतापूरà¥à¤µà¤• हटा दिया गया है।", + "STR_CLEAR_FAILED":"डिसà¥à¤• से Ventoy को साफ़ करते समय à¤à¤• तà¥à¤°à¥à¤Ÿà¤¿ हà¥à¤ˆà¥¤ आप USB को पà¥à¤¨: भर सकते हैं और पà¥à¤¨à¤ƒ पà¥à¤°à¤¯à¤¾à¤¸ कर सकते हैं। विसà¥à¤¤à¤¾à¤° के लिठlog.txt की जाà¤à¤š करें।", + "STR_MENU_PART_STYLE":"विभाजन शैली", + "STR_DISK_2TB_MBR_ERROR":"कृपया 2TB से अधिक डिसà¥à¤• के लिठGPT का चयन करें", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Dutch (Nederlands)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"UmitCanbolat", + + "STR_ERROR":"Fout", + "STR_WARNING":"Waarschuwing", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Voer Ventoy uit in de juiste map!", + "STR_INCORRECT_TREE_DIR":"Ventoy kan hier niet worden uitgevoerd. Download het installatiepakket en probeer Ventoy daarmee te starten.", + "STR_DEVICE":"Apparaat", + "STR_LOCAL_VER":"Ventoy in pakket", + "STR_DISK_VER":"Ventoy op apparaat", + "STR_STATUS":"Status - KLAAR", + "STR_INSTALL":"Installeren", + "STR_UPDATE":"Bijwerken", + "STR_UPDATE_TIP":"Upgraden is veilig: ISO-bestanden blijven ongewijzigd.#@Doorgaan?", + "STR_INSTALL_TIP":"De schijf wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan?", + "STR_INSTALL_TIP2":"De schijf wordt geformatteerd en alle gegevens gaan verloren.#@Doorgaan? (Dubbelcheck)", + "STR_INSTALL_SUCCESS":"Gefeliciteerd!#@Ventoy is met succes op het apparaat geïnstalleerd.", + "STR_INSTALL_FAILED":"Er is een fout opgetreden tijdens de installatie. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.", + "STR_UPDATE_SUCCESS":"Gefeliciteerd!#@Ventoy is met succes bijgewerkt op het apparaat.", + "STR_UPDATE_FAILED":"Er is een fout opgetreden tijdens de update. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.", + "STR_WAIT_PROCESS":"Ventoy is nog bezig, even geduld...", + "STR_MENU_OPTION":"Opties", + "STR_MENU_SECURE_BOOT":"Ondersteuning voor Secure Boot", + "STR_MENU_PART_CFG":"Partitieconfiguratie", + "STR_BTN_OK":"Ok", + "STR_BTN_CANCEL":"Annuleren", + "STR_PRESERVE_SPACE":"Ruimte aan het einde van de schijf reserveren", + "STR_SPACE_VAL_INVALID":"Ongeldige waarde voor gereserveerde ruimte", + "STR_MENU_CLEAR":"Ventoy verwijderen", + "STR_CLEAR_SUCCESS":"Ventoy is met succes verwijderd van het apparaat.", + "STR_CLEAR_FAILED":"Er is een fout opgetreden bij het verwijderen van Ventoy. U kunt het apparaat opnieuw aansluiten en het nogmaals proberen. Controleer log.txt voor details.", + "STR_MENU_PART_STYLE":"Partitietabel", + "STR_DISK_2TB_MBR_ERROR":"Selecteer GPT als partitietabel voor schijven groter dan 2 TB", + "STR_SHOW_ALL_DEV":"Alle apparaten weergeven", + "STR_PART_ALIGN_4KB":"Partities uitlijnen met 4 KB", + "STR_WEB_COMMUNICATION_ERR":"Communicatiefout:", + "STR_WEB_REMOTE_ABNORMAL":"Communicatiefout: extern abnormaal", + "STR_WEB_REQUEST_TIMEOUT":"Communicatiefout: time-out van verzoek", + "STR_WEB_SERVICE_UNAVAILABLE":"Communicatiefout: service niet beschikbaar", + "STR_WEB_TOKEN_MISMATCH":"Daemon-status bijgewerkt, probeer het later opnieuw.", + "STR_WEB_SERVICE_BUSY":"Service is bezet, probeer het later opnieuw.", + "STR_MENU_VTSI_CREATE":"VTSI-bestand genereren", + "STR_VTSI_CREATE_TIP":"Deze keer wordt er niet naar het apparaat geschreven, maar wordt er alleen een VTSI-bestand gegenereerd#@Doorgaan?", + "STR_VTSI_CREATE_SUCCESS":"VTSI-bestand met succes aangemaakt!#@U kunt Rufus(3.15+) gebruiken om het bestand naar het apparaat te schrijven om de installatie van Ventoy te voltooien.", + "STR_VTSI_CREATE_FAILED":"Aanmaken van VTSI-bestand mislukt.", + "STRXXX":"" + }, + { + "name":"Romanian (Română)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"DorinMol", + + "STR_ERROR":"Eroare", + "STR_WARNING":"Avertisment", + "STR_INFO":"Informare", + "STR_INCORRECT_DIR":"Vă rugăm executaÈ›i în directorul corect!", + "STR_INCORRECT_TREE_DIR":"Nu rulaÈ›i aici, vă rugăm să descărcaÈ›i pachetul de instalare È™i executati acolo.", + "STR_DEVICE":"Dispozitiv", + "STR_LOCAL_VER":"Ventoy ÃŽn Pachet", + "STR_DISK_VER":"Ventoy ÃŽn Dispozitiv", + "STR_STATUS":"Stare - PREGÄ‚TIT", + "STR_INSTALL":"Instalare", + "STR_UPDATE":"Actualizare", + "STR_UPDATE_TIP":"OperaÈ›ia de actualizare este sigură, fiÈ™ierele ISO nu vor fi alterate / modificate.#@ContinuaÈ›i?", + "STR_INSTALL_TIP":"Unitatea disc va fi formatată È™i toate datele vor fi pierdute.#@ContinuaÈ›i?", + "STR_INSTALL_TIP2":"Unitatea disc va fi formatată È™i toate datele vor fi pierdute.#@ContinuaÈ›i? (Verificare Dublă)", + "STR_INSTALL_SUCCESS":"Felicitări!#@Ventoy a fost instalat cu succes pe dispozitiv.", + "STR_INSTALL_FAILED":"A apărut o eroare în timpul instalării. ReintroduceÈ›i dispozitivul USB È™i încercaÈ›i din nou. VerificaÈ›i log.txt pentru detalii.", + "STR_UPDATE_SUCCESS":"Felicitări!#@Ventoy a fost actualizat cu succes pe dispozitiv.", + "STR_UPDATE_FAILED":"A apărut o eroare în timpul actualizării. ReintroduceÈ›i dispozitivul USB È™i încercaÈ›i din nou. VerificaÈ›i log.txt pentru detalii.", + "STR_WAIT_PROCESS":"Rulează un fir de execuÈ›ie, vă rugăm aÈ™teptaÈ›i...", + "STR_MENU_OPTION":"OpÈ›iune", + "STR_MENU_SECURE_BOOT":"ÃŽncărcare Sigură", + "STR_MENU_PART_CFG":"Configurare partiÈ›ie", + "STR_BTN_OK":"O.K", + "STR_BTN_CANCEL":"Anulare", + "STR_PRESERVE_SPACE":"PăstraÈ›i puÈ›in spaÈ›iu în partea de jos a discului", + "STR_SPACE_VAL_INVALID":"Valoare nevalidă pentru spaÈ›iul rezervat", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Japanese (日本語)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"taichi eto,Bentnand", + + "STR_ERROR":"エラー", + "STR_WARNING":"警告", + "STR_INFO":"情報", + "STR_INCORRECT_DIR":"æ­£ã—ã„ディレクトリーã§å®Ÿè¡Œã—ã¦ãã ã•ã„", + "STR_INCORRECT_TREE_DIR":"ã“ã“ã§å®Ÿè¡Œã™ã‚‹ã«ã¯ã€ãƒ‘ッケージをインストールã—ã¦ãã ã•ã„。.", + "STR_DEVICE":"デãƒã‚¤ã‚¹", + "STR_LOCAL_VER":"Ventoy In Package", + "STR_DISK_VER":"Ventoy In Device", + "STR_STATUS":"Status - 準備完了", + "STR_INSTALL":"インストール", + "STR_UPDATE":"æ›´æ–°", + "STR_UPDATE_TIP":"アップグレードå¯èƒ½ã§ã™ã€ISOファイルã¯æ”¹å¤‰ã•ã‚Œã¾ã›ã‚“。.#@続行?", + "STR_INSTALL_TIP":"é¸æŠžã•ã‚ŒãŸãƒ‡ã‚£ã‚¹ã‚¯ã¯å®Œå…¨ã«åˆæœŸåŒ–ã•ã‚Œã€ä¿å­˜ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ã¯äºŒåº¦ã¨å¾©å…ƒã§ãã¾ã›ã‚“。#@続行?", + "STR_INSTALL_TIP2":"é¸æŠžã•ã‚ŒãŸãƒ‡ã‚£ã‚¹ã‚¯ã¯å®Œå…¨ã«åˆæœŸåŒ–ã•ã‚Œã€ä¿å­˜ã•ã‚ŒãŸãƒ‡ãƒ¼ã‚¿ã¯äºŒåº¦ã¨å¾©å…ƒã§ãã¾ã›ã‚“。#@続行? (å†ç¢ºèª)", + "STR_INSTALL_SUCCESS":"Congratulations!#@Ventoy ã¯æ­£å¸¸ã«ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¾ã—ãŸ", + "STR_INSTALL_FAILED":"インストール中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚デãƒã‚¤ã‚¹ã‚’å†æŽ¥ç¶šã—ã¦ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。 詳細ログ log.txt ", + "STR_UPDATE_SUCCESS":"Congratulations!#@Ventoy ã¯æ­£å¸¸ã«ã‚¢ãƒƒãƒ—デートã•ã‚Œã¾ã—ãŸ.", + "STR_UPDATE_FAILED":"更新中ã«ã‚¨ãƒ©ãƒ¼ãŒç™ºç”Ÿã—ã¾ã—ãŸã€‚デãƒã‚¤ã‚¹ã‚’å†æŽ¥ç¶šã—ã¦ã‚‚ã†ä¸€åº¦ã‚„ã‚Šç›´ã—ã¦ãã ã•ã„。. 詳細ログ log.txt", + "STR_WAIT_PROCESS":"処ç†ä¸­...", + "STR_MENU_OPTION":"設定", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"パーティション構æˆ", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"キャンセル", + "STR_PRESERVE_SPACE":"ディスクã®ä¸‹éƒ¨ã«ã‚る程度ã®ã‚¹ãƒšãƒ¼ã‚¹ã‚’確ä¿ã™ã‚‹", + "STR_SPACE_VAL_INVALID":"予約スペースã®ç„¡åŠ¹ãªå€¤", + "STR_MENU_CLEAR":"Ventoyを削除", + "STR_CLEAR_SUCCESS":"VentoyãŒãƒ‡ã‚£ã‚¹ã‚¯ã‹ã‚‰å‰Šé™¤ã•ã‚Œã¾ã—ãŸã€‚", + "STR_CLEAR_FAILED":"Ventoyをディスクã‹ã‚‰å‰Šé™¤ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚USBã‚’å†æŒ¿å…¥ã—ã¦ã¿ã¦ãã ã•ã„。 詳細ログ log.txt", + "STR_MENU_PART_STYLE":"パーティションスタイル", + "STR_DISK_2TB_MBR_ERROR":"2TB以上ã®ãƒ‡ã‚£ã‚¹ã‚¯ã«ã¯GPTを使用ã—ã¦ãã ã•ã„。", + "STR_SHOW_ALL_DEV":"ã™ã¹ã¦ã®ãƒ‡ãƒã‚¤ã‚¹ã‚’表示", + "STR_PART_ALIGN_4KB":"パーティションを4KBã«æƒãˆã‚‹", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"デーモンã®ã‚¹ãƒ†ãƒ¼ã‚¿ã‚¹ãŒæ›´æ–°ã•ã‚Œã¾ã—ãŸã€‚ã—ã°ã‚‰ãã—ã¦ã‹ã‚‰å†è©¦è¡Œã—ã¦ãã ã•ã„。", + "STR_WEB_SERVICE_BUSY":"サービスãŒãƒ“ジーã§ã™ã€‚後ã§å†è©¦è¡Œã—ã¦ãã ã•ã„。", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Italian (Italiano)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"AverageUser2", + + "STR_ERROR":"Errore", + "STR_WARNING":"Attenzione", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Si prega di eseguire nella cartella corretta", + "STR_INCORRECT_TREE_DIR":"Non eseguire qui, scarica il pacchetto di installazione ed avvialo", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Versione Ventoy locale", + "STR_DISK_VER":"Ventoy nel dispositivo", + "STR_STATUS":"Stato - PRONTO", + "STR_INSTALL":"Installa", + "STR_UPDATE":"Aggiorna", + "STR_UPDATE_TIP":"L'aggiornamento è sicuro, i file presenti nel dispositivo rimarranno invariati.#@Continue?", + "STR_INSTALL_TIP":"Il disco verrà formattato e tutti i dati saranno persi.#@Continue?", + "STR_INSTALL_TIP2":"Il disco verrà formattato e tutti i dati saranno persi.#@Continue?' (Seconda Verifica)", + "STR_INSTALL_SUCCESS":"Congratulazioni!#@Ventoy è stato installato con successo nel dispositivo", + "STR_INSTALL_FAILED":"Si è verificato un errore durante l'installazione. Reinserisci il dispostivo e riprova. Controlla il file log.txt per i dettagli.", + "STR_UPDATE_SUCCESS":"Congratulazioni!#@Ventoy è stato aggiornato con successo nel dispositivo", + "STR_UPDATE_FAILED":"Si è verificato un errore durante l'aggiornamento. Reinserisci il dispostivo e riprova. Controlla il file log.txt per i dettagli.", + "STR_WAIT_PROCESS":"Un processo è in esecuzione, attendere prego...", + "STR_MENU_OPTION":"Opzioni", + "STR_MENU_SECURE_BOOT":"Avvio protetto (secure boot)", + "STR_MENU_PART_CFG":"Configurazione della partizione", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Annulla", + "STR_PRESERVE_SPACE":"Conserva spazio nella parte finale del disco", + "STR_SPACE_VAL_INVALID":"Quantità di spazio da riservare non valida", + "STR_MENU_CLEAR":"Rimuovi Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy è stato rimosso con successo dal dispositivo.", + "STR_CLEAR_FAILED":"Si è verificato un errore durante la rimozione di Ventoy dal dispositivo. Reinserisci il dispositivo e riprova. Controlla il file log.txt per maggiori dettagli", + "STR_MENU_PART_STYLE":"Stile Tabella delle partizioni", + "STR_DISK_2TB_MBR_ERROR":"Seleziona GPT per dischi con dimensioni maggiori di 2TB", + "STR_SHOW_ALL_DEV":"Mostra tutti i dispositivi", + "STR_PART_ALIGN_4KB":"Allinea le partizioni con 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Croatian (Hrvatski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Valnjes", + + "STR_ERROR":"PogreÅ¡ka", + "STR_WARNING":"Upozorenje", + "STR_INFO":"Informacija", + "STR_INCORRECT_DIR":"Molim vas pokrenite unutar pravog direktorija!", + "STR_INCORRECT_TREE_DIR":"Ne pokrećite me ovdje, molim vas downloadajte poslijednju verziju, te ponovno pokrenite!", + "STR_DEVICE":"UreÄ‘aj", + "STR_LOCAL_VER":"Ventoy (lokalni)", + "STR_DISK_VER":"Ventoy (na ureÄ‘aju)", + "STR_STATUS":"Status - SPREMAN", + "STR_INSTALL":"Instaliraj", + "STR_UPDATE":"Ažuriraj", + "STR_UPDATE_TIP":"Nadogradnja je sigurna, ISO datoteke neće biti promjenjene.#@Nastaviti?", + "STR_INSTALL_TIP":"USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti?", + "STR_INSTALL_TIP2":"USB disk će biti formatiran i svi podatci će biti izgubljeni!#@Nastaviti? (Dodatna provjera)", + "STR_INSTALL_SUCCESS":"ÄŒestitam!#@Ventoy je uspjeÅ¡no instaliran na vaÅ¡ ureÄ‘aj.", + "STR_INSTALL_FAILED":"Dogodila se pogreÅ¡ka tokom instalacije. PokuÅ¡ajte ponovno spojiti USB i pokuÅ¡ati ponovno. Provjerite log.txt za viÅ¡e detalja o nastaloj pogreÅ¡ci.", + "STR_UPDATE_SUCCESS":"ÄŒestitam!#@Ventoy je uspjeÅ¡no ažuriran na vaÅ¡em ureÄ‘aju.", + "STR_UPDATE_FAILED":"Dogodila se pogreÅ¡ka tokom ažuriranja. PokuÅ¡ajte ponovno spojiti USB i pokuÅ¡ati ponovno. Provjerite log.txt za viÅ¡e detalja o nastaloj pogreÅ¡ci.", + "STR_WAIT_PROCESS":"Instanca je vec pokrenuta, molimo vas priÄekajte...", + "STR_MENU_OPTION":"Opcije", + "STR_MENU_SECURE_BOOT":"Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracija particije", + "STR_BTN_OK":"u redu", + "STR_BTN_CANCEL":"Otkazati", + "STR_PRESERVE_SPACE":"SaÄuvajte malo prostora na dnu diska", + "STR_SPACE_VAL_INVALID":"Nevažeća vrijednost rezerviranog prostora", + "STR_MENU_CLEAR":"ObriÅ¡i Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je uspesno obrisan sa ureÄ‘aja", + "STR_CLEAR_FAILED":"Dogodila se greÅ¡ka tokom brisanja Ventoy sa diska. MožeÅ¡ ponovo ubacit USB i pokuÅ¡ati opet. Pogledaj log.txt za joÅ¡ detalja.", + "STR_MENU_PART_STYLE":"Stil particija", + "STR_DISK_2TB_MBR_ERROR":"Molim te, koristi GPT za diskove preko 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Hungarian (Magyar)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bitfarago", + + "STR_ERROR":"Hiba", + "STR_WARNING":"Figyelem", + "STR_INFO":"Infó", + "STR_INCORRECT_DIR":"Kérjük, futtasd a megfelelÅ‘ könyvtárból!", + "STR_INCORRECT_TREE_DIR":"Ne futtasd innen. Töltsd le a kiadott telepítÅ‘csomagot és onnan futtasd.", + "STR_DEVICE":"Eszköz", + "STR_LOCAL_VER":"Ventoy a csomagban", + "STR_DISK_VER":"Ventoy az eszközön", + "STR_STATUS":"Ãllapot - KÉSZ", + "STR_INSTALL":"Telepítés", + "STR_UPDATE":"Frissítés", + "STR_UPDATE_TIP":"A frissítés biztonságos, az ISO fájlok nem változnak.#@Folytatod?", + "STR_INSTALL_TIP":"A meghajtó formázva lesz és minden rajta lévÅ‘ adat elveszik.#@Folytatod?", + "STR_INSTALL_TIP2":"A meghajtó formázva lesz és minden rajta lévÅ‘ adat elveszik.#@Folytatod? (Második jóváhagyás)", + "STR_INSTALL_SUCCESS":"Gratulálunk!#@A Ventoy sikeresen telepítve lett az eszközön.", + "STR_INSTALL_FAILED":"Hiba történt a telepítés során. Csatlakoztasd újra az USB eszközt, és próbáld újra.#@A részleteket lásd a log.txt fájlban.", + "STR_UPDATE_SUCCESS":"Gratulálunk!#@A Ventoy sikeresen frissítve lett az eszközön.", + "STR_UPDATE_FAILED":"Hiba történt a frissítés során. Csatlakoztasd újra az USB eszközt, és próbáld újra.#@A részleteket lásd a log.txt fájlban.", + "STR_WAIT_PROCESS":"A feldolgozás még folyamatban van, kérlek várj...", + "STR_MENU_OPTION":"Opció", + "STR_MENU_SECURE_BOOT":"Biztonsági mód (Secure Boot)", + "STR_MENU_PART_CFG":"Partíciókonfiguráció", + "STR_BTN_OK":"rendben", + "STR_BTN_CANCEL":"Megszünteti", + "STR_PRESERVE_SPACE":"Tartson szabad helyet a lemez alján", + "STR_SPACE_VAL_INVALID":"A fenntartott hely érvénytelen értéke", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Chinese Traditional (ç¹é«”中文)", + "FontFamily":"新細明體", + "FontSize":14, + "Author":"penut85420", + + "STR_ERROR":"錯誤", + "STR_WARNING":"警告", + "STR_INFO":"æ醒", + "STR_INCORRECT_DIR":"請在正確的資料夾下開啟ï¼", + "STR_INCORRECT_TREE_DIR":"請下載並使用發行版本的安è£åŒ…", + "STR_DEVICE":"è£ç½®", + "STR_LOCAL_VER":"ç•¶å‰ Ventoy 版本", + "STR_DISK_VER":"è£ç½®å…§éƒ¨çš„ Ventoy 版本", + "STR_STATUS":"狀態 - 準備就緒", + "STR_INSTALL":"安è£", + "STR_UPDATE":"å‡ç´š", + "STR_UPDATE_TIP":"å‡ç´šæ“作是安全的,ç£ç¢Ÿå…§çš„ ISO 文件ä¸æœƒè¢«æ¸…除#@是å¦ç¹¼çºŒï¼Ÿ", + "STR_INSTALL_TIP":"ç£ç¢Ÿå°‡æœƒè¢«æ ¼å¼åŒ–,所有內容將會被清除ï¼#@是å¦ç¹¼çºŒï¼Ÿ", + "STR_INSTALL_TIP2":"ç£ç¢Ÿå°‡æœƒè¢«æ ¼å¼åŒ–,所有內容將會被清除ï¼#@å†æ¬¡ç¢ºèªæ˜¯å¦ç¹¼çºŒï¼Ÿ", + "STR_INSTALL_SUCCESS":"æ­å–œï¼ŒVentoy 已經æˆåŠŸå®‰è£åˆ°æ­¤è£ç½®ä¸­ï¼", + "STR_INSTALL_FAILED":"å®‰è£ Ventoy çš„éŽç¨‹ä¸­ç™¼ç”ŸéŒ¯èª¤ï¼Œè«‹é‡æ–°æ’å…¥ç£ç¢Ÿä¸¦é‡è©¦ä¸€æ¬¡ï¼Œè©³ç´°è¨Šæ¯è«‹èª¿é–± log.txt 文件。", + "STR_UPDATE_SUCCESS":"æ­å–œï¼Œæ–°ç‰ˆæœ¬çš„ Ventoy 已經æˆåŠŸæ›´æ–°åˆ°æ­¤è£ç½®ä¸­ï¼", + "STR_UPDATE_FAILED":"æ›´æ–° Ventoy çš„éŽç¨‹ä¸­ç™¼ç”ŸéŒ¯èª¤ï¼Œè«‹é‡æ–°æ’å…¥ç£ç¢Ÿä¸¦é‡è©¦ä¸€æ¬¡ï¼Œè©³ç´°è¨Šæ¯è«‹èª¿é–± log.txt 文件。", + "STR_WAIT_PROCESS":"ç›®å‰æœ‰åŸ·è¡Œç·’正在é‹ä½œä¸­ï¼Œè«‹ç¨å€™", + "STR_MENU_OPTION":"é¸é …", + "STR_MENU_SECURE_BOOT":"æ”¯æ´ Secure Boot", + "STR_MENU_PART_CFG":"分å€é…ç½®", + "STR_BTN_OK":"確定", + "STR_BTN_CANCEL":"å–消", + "STR_PRESERVE_SPACE":"在ç£ç›¤æœ€å¾Œä¿ç•™ä¸€éƒ¨åˆ†ç©ºé–“", + "STR_SPACE_VAL_INVALID":"ä¿ç•™ç©ºé–“的大å°ä¸åˆæ³•", + "STR_MENU_CLEAR":"清除Ventoy", + "STR_CLEAR_SUCCESS":"Ventoyå·²æˆåŠŸå¾žè¨­å‚™ä¸­æ¸…除", + "STR_CLEAR_FAILED":"清除 Ventoy çš„éŽç¨‹ä¸­ç™¼ç”ŸéŒ¯èª¤ï¼Œè«‹é‡æ–°æ’å…¥ç£ç¢Ÿä¸¦é‡è©¦ä¸€æ¬¡ï¼Œè©³ç´°è¨Šæ¯è«‹èª¿é–± log.txt 文件。", + "STR_MENU_PART_STYLE":"分å€æ ¼å¼", + "STR_DISK_2TB_MBR_ERROR":"å°æ–¼è¶…éŽ2TBçš„ç£ç‰‡è«‹é¸æ“‡GPT分å€æ ¼å¼", + "STR_SHOW_ALL_DEV":"顯示所有設備", + "STR_PART_ALIGN_4KB":"分å€æŒ‰ç…§4KBå°é½Š", + "STR_WEB_COMMUNICATION_ERR":"通信錯誤:", + "STR_WEB_REMOTE_ABNORMAL":"通信錯誤: æœå‹™ç«¯ç•°å¸¸", + "STR_WEB_REQUEST_TIMEOUT":"通信錯誤: 請求超時", + "STR_WEB_SERVICE_UNAVAILABLE":"通信錯誤: æœå‹™ä¸å¯ç”¨", + "STR_WEB_TOKEN_MISMATCH":"æœå‹™ç‹€æ…‹å·²æ›´æ–°", + "STR_WEB_SERVICE_BUSY":"æœå‹™æ­£å¿™ï¼Œè«‹ç¨å¾Œé‡è©¦", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Serbian Latin (Srpski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bojan Maksimović, panickingkernel, Zoran Jankov", + + "STR_ERROR":"GreÅ¡ka", + "STR_WARNING":"Upozorenje", + "STR_INFO":"Informacija", + "STR_INCORRECT_DIR":"Molim Vas, pokrenite ме u pravom direktorijumu!", + "STR_INCORRECT_TREE_DIR":"Nemojте me pokretati ovde, molim Vas preuzmite objavljeni instalacioni paket i pokrenite me tamo.", + "STR_DEVICE":"UreÄ‘aj", + "STR_LOCAL_VER":"Ventoy u paketu", + "STR_DISK_VER":"Ventoy u ureÄ‘aju", + "STR_STATUS":"Status - SPREMAN", + "STR_INSTALL":"Instaliraj", + "STR_UPDATE":"Nadogradi", + "STR_UPDATE_TIP":"Nadogradnja je sigurna, ISO fajlovi neće biti promenjeni.#@Nastavi?", + "STR_INSTALL_TIP":"Disk će biti formatiran i svi podaci će biti izgubljeni.#@Nastavi?", + "STR_INSTALL_TIP2":"Disk će biti formatiran i svi podaci će biti izgubljeni.#@Nastavi? (Dvostruka provera)", + "STR_INSTALL_SUCCESS":"ÄŒestitam!#@Ventoy je uspeÅ¡no instaliran na ovom ureÄ‘aju.", + "STR_INSTALL_FAILED":"Dogodila se greÅ¡ka tokom instalacije. Možete izvaditi i ponovo ubaciti USB, pa pokuÅ¡ati opet. Pogledajte log.txt za joÅ¡ detalja.", + "STR_UPDATE_SUCCESS":"ÄŒestitam!#@Ventoy je uspeÅ¡no nadograÄ‘en na ovom ureÄ‘aju.", + "STR_UPDATE_FAILED":"Dogodila se greÅ¡ka prilikom nadogradnje. Možeте izvaditi i ponovo ubaciti USB, pa pokuÅ¡ati opet. Pogledajte log.txt za joÅ¡ detalja.", + "STR_WAIT_PROCESS":"Odvija se operacija, molim Vas saÄekajte...", + "STR_MENU_OPTION":"Opcije", + "STR_MENU_SECURE_BOOT":"Sigurno ukljuÄivanje je podržano", + "STR_MENU_PART_CFG":"Konfiguracija particija", + "STR_BTN_OK":"U redu", + "STR_BTN_CANCEL":"Otkaži", + "STR_PRESERVE_SPACE":"SaÄuvaj neÅ¡to prostora na kraju diska", + "STR_SPACE_VAL_INVALID":"Neispravna vrednost za prezervirani prostor", + "STR_MENU_CLEAR":"ObriÅ¡i Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je uspeÅ¡no obrisan sa ureÄ‘aja", + "STR_CLEAR_FAILED":"Dogodila se greÅ¡ka tokom brisanja Ventoy sa diska. Možete ponovo ubaciti USB i pokuÅ¡ati opet. Pogledajte log.txt za joÅ¡ detalja.", + "STR_MENU_PART_STYLE":"Stil particija", + "STR_DISK_2TB_MBR_ERROR":"Molim Vas, izaberite GPT za diskove preko 2TB", + "STR_SHOW_ALL_DEV":"Pokaži sve ureÄ‘aje", + "STR_PART_ALIGN_4KB":"Poravnajte sve particije sa 4KB", + "STR_WEB_COMMUNICATION_ERR":"GreÅ¡ka u komunikaciji:", + "STR_WEB_REMOTE_ABNORMAL":"GreÅ¡ka u komunikaciji: nenormalno daljinsko upravljanje", + "STR_WEB_REQUEST_TIMEOUT":"GreÅ¡ka u komunikaciji: Zahtev je istekao", + "STR_WEB_SERVICE_UNAVAILABLE":"GreÅ¡ka u komunikaciji: Servis nije dostupan", + "STR_WEB_TOKEN_MISMATCH":"Status demona ažuriran, pokuÅ¡ajte ponovo kasnije.", + "STR_WEB_SERVICE_BUSY":"Servis je zauzet, pokuÅ¡ajte ponovo kasnije.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Serbian Cyrillic (СрпÑки)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Bojan Maksimović, panickingkernel, Zoran Jankov", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Упозорење", + "STR_INFO":"Информација", + "STR_INCORRECT_DIR":"Молим ВаÑ, покрените ме у правом директоријуму!", + "STR_INCORRECT_TREE_DIR":"Ðемојте ме покретати овде, молим Ð’Ð°Ñ Ð¿Ñ€ÐµÑƒÐ·Ð¼Ð¸Ñ‚Ðµ објављени инÑталациони пакет и покрените ме тамо.", + "STR_DEVICE":"Уређај", + "STR_LOCAL_VER":"Ventoy у пакету", + "STR_DISK_VER":"Ventoy у уређају", + "STR_STATUS":"Ð¡Ñ‚Ð°Ñ‚ÑƒÑ - СПРЕМÐÐ", + "STR_INSTALL":"ИнÑталирај", + "STR_UPDATE":"Ðадогради", + "STR_UPDATE_TIP":"Ðадоградња је Ñигурна, ISO фајлови неће бити промењени.#@ÐаÑтави?", + "STR_INSTALL_TIP":"ДиÑк ће бити форматиран и Ñви подаци ће бити изгубљени.#@ÐаÑтави?", + "STR_INSTALL_TIP2":"ДиÑк ће бити форматиран и Ñви подаци ће бити изгубљени.#@ÐаÑтави? (ДвоÑтрука провера)", + "STR_INSTALL_SUCCESS":"ЧеÑтитам!#@Ventoy је уÑпешно инÑталиран на овом уређају.", + "STR_INSTALL_FAILED":"Догодила Ñе грешка током инÑталације. Можете извадити и поново убацити USB, па покушати опет. Погледајте log.txt за још детаља.", + "STR_UPDATE_SUCCESS":"ЧеÑтитам!#@Ventoy је био уÑпешно надограђен на овом уређају.", + "STR_UPDATE_FAILED":"Догодила Ñе грешка током надоградње. Можете извадити и поново убацити USB, па покушати опет. Погледајте log.txt за још детаља.", + "STR_WAIT_PROCESS":"Одвија Ñе операција, молим Ð’Ð°Ñ Ñачекајте...", + "STR_MENU_OPTION":"Опције", + "STR_MENU_SECURE_BOOT":"Сигурно уклјучиванје је подржано", + "STR_MENU_PART_CFG":"Конфигурација партиција", + "STR_BTN_OK":"У реду", + "STR_BTN_CANCEL":"Откажи", + "STR_PRESERVE_SPACE":"Саћувај нешто проÑтора на крају диÑка", + "STR_SPACE_VAL_INVALID":"ÐеиÑправна вредноÑÑ‚ за презервирани проÑтор", + "STR_MENU_CLEAR":"Обриши Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy је уÑпешно обриÑан Ñа уређаја", + "STR_CLEAR_FAILED":"Можете поново убацити USB и покушати опет. Погледајте log.txt за још детаља.", + "STR_MENU_PART_STYLE":"Стил партиција", + "STR_DISK_2TB_MBR_ERROR":"Молим ВаÑ, изаберите GPT за диÑкове преко 2ТB", + "STR_SHOW_ALL_DEV":"Прикажи Ñве уређаје", + "STR_PART_ALIGN_4KB":"Поравнајте партиције Ñа 4KB", + "STR_WEB_COMMUNICATION_ERR":"Комуникациона грешка:", + "STR_WEB_REMOTE_ABNORMAL":"Комуникациона грешка: ненормално даљинÑко управљање", + "STR_WEB_REQUEST_TIMEOUT":"Комуникациона грешка: Захтев је иÑтекао", + "STR_WEB_SERVICE_UNAVAILABLE":"Комуникациона грешка: Ð¡ÐµÑ€Ð²Ð¸Ñ Ñ˜Ðµ недоÑтупан", + "STR_WEB_TOKEN_MISMATCH":"Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð´ÐµÐ¼Ð¾Ð½Ð° ажуриран, покушајте поново каÑније.", + "STR_WEB_SERVICE_BUSY":"Ð¡ÐµÐ²Ð¸Ñ Ñ˜Ðµ заузет, покушајте поново каÑније.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Thai (ไทย)", + "FontFamily":"Courier New", + "FontSize":17, + "Author":"longpanda", + + "STR_ERROR":"ผิดพลาด", + "STR_WARNING":"คำเตือน", + "STR_INFO":"ข้อมูล", + "STR_INCORRECT_DIR":"à¸à¸£à¸¸à¸“าเรียà¸à¹ƒà¸Šà¹‰à¹ƒà¸™à¸­à¸¸à¸›à¸à¸£à¸“์ที่ถูà¸à¸•à¹‰à¸­à¸‡!", + "STR_INCORRECT_TREE_DIR":"อย่าติดตั้งในนี้, โปรดดาวน์โหลดà¹à¸¥à¸°à¹ƒà¸Šà¹‰à¹à¸žà¹‡à¸„เà¸à¸ˆà¸à¸²à¸£à¸•à¸´à¸”ตั้งของรุ่นที่วางจำหน่าย", + "STR_DEVICE":"อุปà¸à¸£à¸“์", + "STR_LOCAL_VER":"เวอร์ชั่น Ventoy ", + "STR_DISK_VER":"ลง Ventoy ในอุปà¸à¸£à¸“์", + "STR_STATUS":"สถานะ - พร้อม", + "STR_INSTALL":"ติดตั้ง", + "STR_UPDATE":"ปรับปรุง", + "STR_UPDATE_TIP":"à¸à¸²à¸£à¸”ำเนินà¸à¸²à¸£à¸­à¸±à¸›à¹€à¸à¸£à¸”ปลอดภัย, ไฟล์ ISO จะไม่มีà¸à¸²à¸£à¹€à¸›à¸¥à¸µà¹ˆà¸¢à¸™à¹à¸›à¸¥à¸‡.#@ต่อเนื่อง?", + "STR_INSTALL_TIP":"ดิสà¸à¹Œà¸ˆà¸°à¸–ูà¸à¸Ÿà¸­à¸£à¹Œà¹à¸¡à¸•à¹à¸¥à¸°à¸‚้อมูลทั้งหมดจะสูà¸à¸«à¸²à¸¢.#@ต่อเนื่อง?", + "STR_INSTALL_TIP2":"ดิสà¸à¹Œà¸ˆà¸°à¸–ูà¸à¸Ÿà¸­à¸£à¹Œà¹à¸¡à¸•à¹à¸¥à¸°à¸‚้อมูลทั้งหมดจะสูà¸à¸«à¸²à¸¢#@ต่อเนื่อง? (ตรวจสอบอีà¸à¸„รั้ง)", + "STR_INSTALL_SUCCESS":"ขอà¹à¸ªà¸”งความยินดี!#@Ventoy ติดตั้งไปยังอุปà¸à¸£à¸“์สำเร็จà¹à¸¥à¹‰à¸§", + "STR_INSTALL_FAILED":"เà¸à¸´à¸”ข้อผิดพลาดระหว่างà¸à¸²à¸£à¸•à¸´à¸”ตั้ง. คุณสามารถถอด USB à¹à¸¥à¸°à¸¥à¸­à¸‡à¸­à¸µà¸à¸„รั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.", + "STR_UPDATE_SUCCESS":"ขอà¹à¸ªà¸”งความยินดี!#@Ventoy อัปเดตไปยังอุปà¸à¸£à¸“์สำเร็จà¹à¸¥à¹‰à¸§.", + "STR_UPDATE_FAILED":"เà¸à¸´à¸”ข้อผิดพลาดระหว่างà¸à¸²à¸£à¸­à¸±à¸žà¹€à¸”ต. คุณสามารถถอด USB à¹à¸¥à¸°à¸¥à¸­à¸‡à¸­à¸µà¸à¸„รั้ง. ตรวจสอบรายละเอียดได้ที่ log.txt.", + "STR_WAIT_PROCESS":"CPU à¸à¸³à¸¥à¸±à¸‡à¸—ำงานอยู่,ได้โปรดรอ...", + "STR_MENU_OPTION":"ตัวเลือà¸", + "STR_MENU_SECURE_BOOT":"สนับสนุนà¸à¸²à¸£à¸šà¸¹à¸•à¸—ี่ปลอดภัย", + "STR_MENU_PART_CFG":"à¸à¸³à¸«à¸™à¸”ค่าพาร์ติชัน", + "STR_BTN_OK":"ตà¸à¸¥à¸‡", + "STR_BTN_CANCEL":"ยà¸à¹€à¸¥à¸´à¸", + "STR_PRESERVE_SPACE":"เà¸à¹‡à¸šà¸žà¸·à¹‰à¸™à¸—ี่บางส่วนของอุปà¸à¸£à¸“์ไว้", + "STR_SPACE_VAL_INVALID":"มีปัà¸à¸«à¸²à¸ªà¸³à¸«à¸£à¸±à¸šà¸žà¸·à¹‰à¸™à¸—ี่ที่สงวนไว้(à¸à¸£à¸¸à¸“า ฟอร์à¹à¸¡à¸• à¹à¸¥à¸°à¸•à¸´à¸”ตั้งใหม่)", + "STR_MENU_CLEAR":"Clear Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy has been successfully removed from the device.", + "STR_CLEAR_FAILED":"An error occurred when clear Ventoy from disk. You can replug the USB and try again. Check log.txt for detail.", + "STR_MENU_PART_STYLE":"Partition Style", + "STR_DISK_2TB_MBR_ERROR":"Please select GPT for disk over 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Norwegian (Norsk)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Stein-Ove Bøthun", + + "STR_ERROR":"Feil", + "STR_WARNING":"Advarsel", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Vennligst kjør fra den riktige mappen!", + "STR_INCORRECT_TREE_DIR":"Ikke kjør meg her, vennligst last ned den utgitte installasjonspakken og kjør den der.", + "STR_DEVICE":"Enhet", + "STR_LOCAL_VER":"Ventoy i Pakken", + "STR_DISK_VER":"Ventoy pÃ¥ Enheten", + "STR_STATUS":"Status - KLAR", + "STR_INSTALL":"Installer", + "STR_UPDATE":"Oppdater", + "STR_UPDATE_TIP":"Oppgraderingen er trygg, ISO-filene vil være uendret.#@Fortsette?", + "STR_INSTALL_TIP":"Disken blir formatert og alle dataene vil gÃ¥ tapt.#@Fortsette?", + "STR_INSTALL_TIP2":"Disken blir formatert og alle dataene vil gÃ¥ tapt.#@Fortsette? (Dobbelsjekk)", + "STR_INSTALL_SUCCESS":"Gratulerer!#@Ventoy er blitt installert pÃ¥ enheten.", + "STR_INSTALL_FAILED":"Det oppstod en feil under installasjonen. Du kan koble til USB-en pÃ¥ nytt og prøve igjen. Check log.txt for flere detaljer.", + "STR_UPDATE_SUCCESS":"Gratulerer!#@Ventoy har blitt oppdatert pÃ¥ enheten.", + "STR_UPDATE_FAILED":"Det oppstod en feil under oppdateringen. Du kan koble til USB-en pÃ¥ nytt og prøve igjen. Se log.txt for flere detaljer.", + "STR_WAIT_PROCESS":"En prosess kjører, vennligst vent...", + "STR_MENU_OPTION":"Alternativ", + "STR_MENU_SECURE_BOOT":"Støtte for sikker oppstart", + "STR_MENU_PART_CFG":"Partisjonskonfigirasjon", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Avbryt", + "STR_PRESERVE_SPACE":"Bevar litt plass pÃ¥ bunnen av disken", + "STR_SPACE_VAL_INVALID":"Ugyldig verdi for reservert plass", + "STR_MENU_CLEAR":"Fjern Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy er blitt fjernet fra enheten.", + "STR_CLEAR_FAILED":"Det oppstod en feil da Ventoy bler fjernet fra disken. Du kan koble til USB-en pÃ¥ nytt og prøve igjen. Sjekk log.txt for flere detaljer.", + "STR_MENU_PART_STYLE":"Partisjonsstil", + "STR_DISK_2TB_MBR_ERROR":"Velg GPT for disker over 2 TB", + "STR_SHOW_ALL_DEV":"Vis alle enheter", + "STR_PART_ALIGN_4KB":"Juster partisjoner med 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kommunikasjonsfeil:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunokasjonsfeil: unormalt fjerntliggende", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikasjonsfeil: Forespørselen ble tidsavbrutt", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikasjonsfeil: Tjeneste utilgjengelig", + "STR_WEB_TOKEN_MISMATCH":"Daemon status er oppdatert, vennligst prøv igjen senere.", + "STR_WEB_SERVICE_BUSY":"Tjenesten er opptatt, vennligst prøv igjen senere.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Vietnamese (Tiếng Việt)", + "FontFamily":"Tahoma", + "FontSize":14, + "Author":"Nguyen Quoc Hoang - cuumay.com", + + "STR_ERROR":"Lá»—i", + "STR_WARNING":"Cảnh báo", + "STR_INFO":"Thông tin", + "STR_INCORRECT_DIR":"Vui lòng chạy Ventoy2Disk tại đúng thÆ° mục của nó !", + "STR_INCORRECT_TREE_DIR":"Không được chạy Ventoy2Disk ở đây, vui lòng tải gói cài đặt đã phát hành và chạy ở đó.", + "STR_DEVICE":"Thiết bị", + "STR_LOCAL_VER":"Phiên bản Ventoy", + "STR_DISK_VER":"Phiên bản Ventoy ở thiết bị", + "STR_STATUS":"Trạng thái - SẴN SÀNG", + "STR_INSTALL":"Cài đặt", + "STR_UPDATE":"Cập nhật", + "STR_UPDATE_TIP":"Việc cập nhật Ventoy là an toàn, các tập tin ISO của bạn sẽ được giữ nguyên trạng.#@Bạn thật sá»± muốn tiếp tục?", + "STR_INSTALL_TIP":"Thiết bị sẽ được định dạng và do đó TẤT CẢ Dá»® LIỆU trên thiết bị sẽ bị mất.#@Bạn thật sá»± muốn tiếp tục?", + "STR_INSTALL_TIP2":"Thiết bị sẽ được định dạng và do đó TẤT CẢ Dá»® LIỆU trên thiết bị sẽ bị mất.#@Bạn thật sá»± muốn tiếp tục? (Xác nhận lần hai)", + "STR_INSTALL_SUCCESS":"Chúc mừng bạn !.#@Thiết bị đã được cài Ventoy thành công.", + "STR_INSTALL_FAILED":"Äã xảy ra lá»—i trong quá trình cài đặt Ventoy. Bạn có thể rút thiết bị ra và thá»­ lại. Xem chi tiết ở tệp log.txt.", + "STR_UPDATE_SUCCESS":"Chúc mừng bạn !.#@Thiết bị đã được cập nhật Ventoy thành công.", + "STR_UPDATE_FAILED":"Äã xảy ra lá»—i trong quá trình cập nhật Ventoy. Bạn có thể rút thiết bị ra và thá»­ lại. Xem chi tiết ở tệp log.txt.", + "STR_WAIT_PROCESS":"Má»™t luồng xá»­ lý Ä‘ang chạy, vui lòng chá»...", + "STR_MENU_OPTION":"Tùy chá»n", + "STR_MENU_SECURE_BOOT":"Bật há»— trợ Secure Boot", + "STR_MENU_PART_CFG":"Cấu hình phân vùng", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Hủy", + "STR_PRESERVE_SPACE":"Giữ lại phần dung lượng ở cuối thiết bị", + "STR_SPACE_VAL_INVALID":"Giá trị dung lượng giữ lại không hợp lệ.", + "STR_MENU_CLEAR":"Gỡ bá» Ventoy", + "STR_CLEAR_SUCCESS":"Chúc mừng bạn !.#@Thiết bị đã được gỡ bá» Ventoy thành công.", + "STR_CLEAR_FAILED":"Äã xảy ra lá»—i trong quá trình gỡ bá» Ventoy. Bạn có thể rút thiết bị ra và thá»­ lại. Xem chi tiết ở tệp log.txt.", + "STR_MENU_PART_STYLE":"Kiểu phân vùng", + "STR_DISK_2TB_MBR_ERROR":"Thiết bị có dung lượng lá»›n hÆ¡n 2TB. Vui lòng chá»n Kiểu phân vùng là GPT.", + "STR_SHOW_ALL_DEV":"Hiện tất cả Thiết bị", + "STR_PART_ALIGN_4KB":"Căn chỉnh phân vùng vá»›i 4KB", + "STR_WEB_COMMUNICATION_ERR":"Lá»—i giao tiếp:", + "STR_WEB_REMOTE_ABNORMAL":"Lá»—i giao tiếp: Remote bất thÆ°á»ng", + "STR_WEB_REQUEST_TIMEOUT":"Lá»—i giao tiếp: Yêu cầu đã hết thá»i gian chá»", + "STR_WEB_SERVICE_UNAVAILABLE":"Lá»—i giao tiếp: Dịch vụ không sẵn có", + "STR_WEB_TOKEN_MISMATCH":"Äã cập nhật trạng thái Daemon, vui lòng thá»­ lại sau.", + "STR_WEB_SERVICE_BUSY":"Dịch vụ bận, vui lòng thá»­ lại sau.", + "STR_MENU_VTSI_CREATE":"Tạo tệp VTSI", + "STR_VTSI_CREATE_TIP":"Lần này sẽ không ghi vào thiết bị, chỉ tạo má»™t tệp VTSI#@Bạn muốn tiếp tục?", + "STR_VTSI_CREATE_SUCCESS":"Tạo tệp VTSI thành công!#@Äể hoàn thành cài đặt Ventoy, bạn có thể dùng Rufus (3.15+) để ghi tệp này vào thiết bị.", + "STR_VTSI_CREATE_FAILED":"Tạo tệp VTSI đã gặp lá»—i.", + "STRXXX":"" + }, + { + "name":"Lithuanian (Lietuvių)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"r0manas", + + "STR_ERROR ":"Klaida", + "STR_WARNING ":"Ä®spÄ—jimas", + "STR_INFO ":"Informacija", + "STR_INCORRECT_DIR ":"PraÅ¡ome paleisti teisingame kataloge!", + "STR_INCORRECT_TREE_DIR ":"Nepaleiskite manÄ™s Äia, atsisiųskite iÅ¡leistÄ… diegimo paketÄ… ir paleiskite ten.", + "STR_DEVICE ":"Ä®renginys", + "STR_LOCAL_VER ":"„Ventoy“ versija pakuotÄ—je", + "STR_DISK_VER ":"„Ventoy“ versija įrenginyje", + "STR_STATUS ":"BÅ«sena - PASIRENGĘS", + "STR_INSTALL ":"Ä®diegti", + "STR_UPDATE ":"Atnaujinti", + "STR_UPDATE_TIP ":"Atnaujinti - saugu, ISO failai liks nepažeisti.#@TÄ™sti?", + "STR_INSTALL_TIP ":"Ä®renginys bus suformatuotas ir visi duomenys bus prarasti.#@TÄ™sti?", + "STR_INSTALL_TIP2 ":"Ä®renginys bus suformatuotas ir visi duomenys bus prarasti.#@TÄ™sti? (TIKRAI TĘSTI?)", + "STR_INSTALL_SUCCESS ":"Sveikinu!#@Ventoy sÄ—kmingai įdiegtas įrenginyje.", + "STR_INSTALL_FAILED ":"Diegimo metu įvyko klaida. Galite iÅ¡ naujo prijungti USB ir bandyti dar kartÄ…. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_UPDATE_SUCCESS ":"Sveikinu!#@Ventoy sÄ—kmingai atnaujintas įrenginyje.", + "STR_UPDATE_FAILED ":"Atnaujinant įvyko klaida. Galite iÅ¡ naujo prijungti USB ir bandyti dar kartÄ…. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_WAIT_PROCESS ":"PradÄ—tas procesas, palaukite ...", + "STR_MENU_OPTION ":"Nustatymai", + "STR_MENU_SECURE_BOOT ":"Secure Boot palaikymas", + "STR_MENU_PART_CFG ":"Skirsnio konfigÅ«racija", + "STR_BTN_OK ":"Gerai", + "STR_BTN_CANCEL ":"AtÅ¡aukti", + "STR_PRESERVE_SPACE ":"Rezervuoti vietos įrenginyje", + "STR_SPACE_VAL_INVALID ":"Neteisinga rezervuotos vietos vertÄ—", + "STR_MENU_CLEAR ":"PaÅ¡alinti „Ventoy“", + "STR_CLEAR_SUCCESS ":"„Ventoy“ sÄ—kmingai paÅ¡alintas iÅ¡ įrenginio.", + "STR_CLEAR_FAILED ":"Ä®vyko klaida paÅ¡alinant „Ventoy“ iÅ¡ įrenginio. USB ir bandyti dar kartÄ…. Patikrinkite log.txt, jei norite sužinoti daugiau.", + "STR_MENU_PART_STYLE ":"Skirsnio formatas", + "STR_DISK_2TB_MBR_ERROR ":"PraÅ¡ome pasirinkti GPT, jei įrenginys didesnis nei 2 TB.", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Macedonian (МакедонÑки)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Влатко Стојанов", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Предупредување", + "STR_INFO":"Инфо", + "STR_INCORRECT_DIR":"Ве молам покренете ме коректната папка!", + "STR_INCORRECT_TREE_DIR":"Ðе покренувајте ме овде, ве молам превземете ја поÑледната верзија и покренете ме таму.", + "STR_DEVICE":"Уред", + "STR_LOCAL_VER":"Ventoy во пакетот", + "STR_DISK_VER":"Ventoy на уредот", + "STR_STATUS":"Ð¡Ñ‚Ð°Ñ‚ÑƒÑ - Спремен", + "STR_INSTALL":"ИнÑталирај", + "STR_UPDATE":"Ðжурирај", + "STR_UPDATE_TIP":"Операцијата ажурирање е безбедна, ISO датотеките нема да бидат променети.#@Продолжи?", + "STR_INSTALL_TIP":"УСБ уредот ќе биде форматиран и Ñите податоци ќе бидат уништени.#@Продолжи?", + "STR_INSTALL_TIP2":"УСБ уредот ќе биде форматиран и Ñите податоци ќе бидат уништени.#@Продолжи? (Двојна проверка)", + "STR_INSTALL_SUCCESS":"ЧеÑтитки!#@Ventoy е уÑпешно инÑталиран на уредот.", + "STR_INSTALL_FAILED":"Се појави грешка при инÑталацијата. ОтÑтранете го УСБ уредот и пробајте повторно. Проверете го log.txt за детали.", + "STR_UPDATE_SUCCESS":"ЧеÑтитки!#@Ventoy е уÑпешно ажуриран на уредот.", + "STR_UPDATE_FAILED":"Се појави грешка при ажурирањето. ОтÑтранете го УСБ уредот и пробајте повторно. Проверете го log.txt за детали.", + "STR_WAIT_PROCESS":"ПроцеÑот е вклучен, ве молиме почекајте...", + "STR_MENU_OPTION":"Опции", + "STR_MENU_SECURE_BOOT":"Secure Boot Поддршка", + "STR_MENU_PART_CFG":"Конфигурирање на партиции", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Излез", + "STR_PRESERVE_SPACE":"Резервирај меÑто на крајот на диÑкот", + "STR_SPACE_VAL_INVALID":"Ðевалидна вредноÑÑ‚ за резервираното меÑто", + "STR_MENU_CLEAR":"ОтÑтрани го Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy е уÑпешно отÑтранет од уредот.", + "STR_CLEAR_FAILED":"Се појави грешка при отÑтранувањето на Ventoy од уредот. ОтÑтранете го УСБ уредот и пробајте повторно. Проверете го log.txt за детали.", + "STR_MENU_PART_STYLE":"Тип на партиција", + "STR_DISK_2TB_MBR_ERROR":"Ве молиме изберете GPT за уредот поголеми од 2TB", + "STR_SHOW_ALL_DEV":"Прикажи ги Ñите уреди", + "STR_PART_ALIGN_4KB":"Порамнете ги партициите Ñо 4KB", + "STR_WEB_COMMUNICATION_ERR":"КомуникациÑка грешка:", + "STR_WEB_REMOTE_ABNORMAL":"КомуникациÑка грешка: Ðбнормално далечинÑко управување", + "STR_WEB_REQUEST_TIMEOUT":"КомуникациÑка грешка: Барањето е иÑтечено", + "STR_WEB_SERVICE_UNAVAILABLE":"КомуникациÑка грешка: ÐедоÑтапен ÑервиÑ", + "STR_WEB_TOKEN_MISMATCH":"Ðжуриран ÑÑ‚Ð°Ñ‚ÑƒÑ Ð½Ð° даемонот, молиме обидете Ñе подоцна.", + "STR_WEB_SERVICE_BUSY":"СервиÑот е зафатен, молиме обидете Ñе подоцна.", + "STR_MENU_VTSI_CREATE":"Генерирај VTSI датотека", + "STR_VTSI_CREATE_TIP":"Овој пат ништо нема да Ñе запише на уредот туку Ñамо ќе Ñе генерира VTSI датотека#@Продолжи?", + "STR_VTSI_CREATE_SUCCESS":"УÑпешно креирана VTSI датотека!#@Можете да го кориÑтите Rufus(3.15+) за да ја запишете на уредот како и да ја комплетирате инÑталацијата на Ventoy.", + "STR_VTSI_CREATE_FAILED":"Креирањето на VTSI датотека е неуÑпешно.", + "STRXXX":"" + }, + { + "name":"Hebrew (עברית)", + "FontFamily":"tahoma", + "FontSize":16, + "Author":"chaim-chv", + + "STR_ERROR":"תקלה", + "STR_WARNING":"×זהרה", + "STR_INFO":"מידע", + "STR_INCORRECT_DIR":"הרץ בבקשה בתיקייה הנכונה!", + "STR_INCORRECT_TREE_DIR":"×ל תריץ ×ותי ×›×ן. בבקשה הורד ×ת חבילת ההתקנה ששוחררה, ותריץ ×ותי ש×.", + "STR_DEVICE":"התקן", + "STR_LOCAL_VER":"גרסת Ventoy מקומית", + "STR_DISK_VER":"גרסת Ventoy בהתקן", + "STR_STATUS":"סטטוס - מוכן", + "STR_INSTALL":"התקנה", + "STR_UPDATE":"עדכון", + "STR_UPDATE_TIP":"×ופציית העדכון ×”×™× ×‘×˜×•×—×” לשימוש. קבצי ×”-ISO ×œ× ×™×™×¤×’×¢×•.#@להמשיך?", + "STR_INSTALL_TIP":"הדיסק יפורמט וכל המידע שבו ייעל×.#@להמשיך?", + "STR_INSTALL_TIP2":"הדיסק יפורמט וכל המידע שבו ייעלפ ויימחק לחלוטין.#@להמשיך? (בדיקה לווידו×)", + "STR_INSTALL_SUCCESS":"הצלחה!#@Ventoy הותקנה בהצלחה על הדיסק הנבחר", + "STR_INSTALL_FAILED":"×ירעה תקלה בניסיון ההתקנה. ×פשר לנסות לחבר ×ת הדיסק מחדש ולבצע ניסיון התקנה נוסף. עיין בקובץ ×”-log.txt ×œ×¤×¨×˜×™× × ×•×¡×¤×™×.", + "STR_UPDATE_SUCCESS":"הצלחה!#@Ventoy הותקנה בהצלחה על הדיסק הנבחר", + "STR_UPDATE_FAILED":"×ירעה תקלה בניסיון העדכון. ×פשר לנסות לחבר ×ת הדיסק מחדש ולבצע ניסיון נוסף לעדכון. עיין בקובץ ×”-log.txt ×œ×¤×¨×˜×™× × ×•×¡×¤×™×.", + "STR_WAIT_PROCESS":"עובד... × × ×”×ž×ª×Ÿ", + "STR_MENU_OPTION":"×פשרויות", + "STR_MENU_SECURE_BOOT":"תמיכה ב-Secure Boot", + "STR_MENU_PART_CFG":"הגדרת מחיצות", + "STR_BTN_OK":"×ישור", + "STR_BTN_CANCEL":"ביטול", + "STR_PRESERVE_SPACE":"הגדר ×ž×§×•× ×œ×©×ž×™×¨×” בדיסק", + "STR_SPACE_VAL_INVALID":"ערך ×œ× ×—×•×§×™ עבור שטח לשמירה", + "STR_MENU_CLEAR":"נקה ×ת Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy נמחקה בהצלחה מהדיסק הנבחר.", + "STR_CLEAR_FAILED":"×ירעה תקלה בניסיון למחוק ×ת Ventoy מהדיסק הנבחר. ×פשר לנסות לחבר ×ת הדיסק מחדש ולבצע שוב מחיקה. עיין בקובץ ×”-log.txt ×œ×¤×¨×˜×™× × ×•×¡×¤×™×.", + "STR_MENU_PART_STYLE":"סוג מחיצה", + "STR_DISK_2TB_MBR_ERROR":"בחר ב-GPT עבור דיסק שגדול מ-2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Portuguese (Português de Portugal)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Eskiso", + + "STR_ERROR":"Erro", + "STR_WARNING":"Aviso", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Por favor, execute na pasta correta!", + "STR_INCORRECT_TREE_DIR":"Não me execute aqui, por favor transfira o pacote de instalação, e execute lá.", + "STR_DEVICE":"Dispositivo", + "STR_LOCAL_VER":"Ventoy em pacote", + "STR_DISK_VER":"Ventoy no dispositivo", + "STR_STATUS":"Estado - PRONTO", + "STR_INSTALL":"Instalar", + "STR_UPDATE":"Atualizar", + "STR_UPDATE_TIP":"A operação de atualização é segura, os ficheiros ISO não serão alterados.#@Continuar?", + "STR_INSTALL_TIP":"O disco será formatado e todos os dados serão perdidos.#@Continuar?", + "STR_INSTALL_TIP2":"O disco será formatado e todos os dados serão perdidos.#@Continuar? (Confirmação)", + "STR_INSTALL_SUCCESS":"Parabéns!#@Ventoy foi instalado com sucesso no dispositivo.", + "STR_INSTALL_FAILED":"Um erro ocorreu durante a instalação. Pode reconectar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_UPDATE_SUCCESS":"Parabéns!#@Ventoy foi atualizado com sucesso no dispositivo.", + "STR_UPDATE_FAILED":"Um erro ocorreu durante a atualização. Pode reconectar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_WAIT_PROCESS":"Uma thread está em execução, por favor espere...", + "STR_MENU_OPTION":"Opção", + "STR_MENU_SECURE_BOOT":"Boot seguro", + "STR_MENU_PART_CFG":"Configuração da Partição", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Cancelar", + "STR_PRESERVE_SPACE":"Preservar algum espaço no final do disco", + "STR_SPACE_VAL_INVALID":"Valor invalido para o espaço reservado", + "STR_MENU_CLEAR":"Remover o Ventoy", + "STR_CLEAR_SUCCESS":"O Ventoy foi removido deste dispositivo com sucesso.", + "STR_CLEAR_FAILED":"Um erro ocorreu ao remover o Ventoy do disco. Pode reconectar o dispositivo USB e tentar novamente. Verifique o ficheiro log.txt para mais detalhes.", + "STR_MENU_PART_STYLE":"Estilo de Partição", + "STR_DISK_2TB_MBR_ERROR":"Por favor selecione GPT para discos maiores que 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Align partitions with 4KB", + "STR_WEB_COMMUNICATION_ERR":"Communication error:", + "STR_WEB_REMOTE_ABNORMAL":"Communication error: remote abnormal", + "STR_WEB_REQUEST_TIMEOUT":"Communication error: Request timed out", + "STR_WEB_SERVICE_UNAVAILABLE":"Communication error: Service Unavailable", + "STR_WEB_TOKEN_MISMATCH":"Daemon status updated, please retry later.", + "STR_WEB_SERVICE_BUSY":"Service is busy, please retry later.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Indonesian (Bahasa Indonesia)", + "FontFamily":"Comic Sans MS", + "FontSize":16, + "Author":"Ida Bagus Anom Sanjaya", + + "STR_ERROR":"Kesalahan", + "STR_WARNING":"Peringatan", + "STR_INFO":"Informasi", + "STR_INCORRECT_DIR":"Silakan jalankan pada direktori yang benar!", + "STR_INCORRECT_TREE_DIR":"Jangan jalankan di sini, silakan unduh paket pemasangan yang diliris, dan jalankan di sana.", + "STR_DEVICE":"Perangkat", + "STR_LOCAL_VER":"Ventoy pada Paket", + "STR_DISK_VER":"Ventoy pada Perangkat", + "STR_STATUS":"Status - SIAP", + "STR_INSTALL":"Pasang", + "STR_UPDATE":"Perbarui", + "STR_UPDATE_TIP":"Operasi pembaruan ini aman, Tidak akan ada perubahan berkas ISO.#@Lanjutkan?", + "STR_INSTALL_TIP":"Disk akan di-format dan semua data akan hilang.#@Lanjutkan?", + "STR_INSTALL_TIP2":"Disk akan di-format dan semua data akan hilang.#@Lanjutkan? (YAKIN)", + "STR_INSTALL_SUCCESS":"Selamat!#@Ventoy telah berhasil terpasang di perangkat ini.", + "STR_INSTALL_FAILED":"Terjadi kesalahan ketika pemasangan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_UPDATE_SUCCESS":"Selamat!#@Ventoy telah berhasil diperbarui di perangkat ini.", + "STR_UPDATE_FAILED":"Terjadi kesalahan ketika pembaruan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_WAIT_PROCESS":"Tugas sedang berjalan, silakan tunggu...", + "STR_MENU_OPTION":"Pilihan", + "STR_MENU_SECURE_BOOT":"Dukungan Secure Boot", + "STR_MENU_PART_CFG":"Konfigurasi Partisi", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Batal", + "STR_PRESERVE_SPACE":"Mempertahankan sejumlah ruang penyimpanan pada disk di bawah ini", + "STR_SPACE_VAL_INVALID":"Nilai menpertahankan ruang tidak valid", + "STR_MENU_CLEAR":"Bersihkan Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy telah berhasil dihapus pada perangkat ini.", + "STR_CLEAR_FAILED":"Terjadi kesalahan ketika penghapusan berlangsung. Anda perlu mencabut-pasang ulang USB dan coba lagi. Cek log.txt untuk detil.", + "STR_MENU_PART_STYLE":"Gaya Partisi", + "STR_DISK_2TB_MBR_ERROR":"Silakan pilih GPT untuk disk yang lebih dari 2TB", + "STR_SHOW_ALL_DEV":"Show All Devices", + "STR_PART_ALIGN_4KB":"Meluruskan dengan partisi 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kesalahan komunikasi:", + "STR_WEB_REMOTE_ABNORMAL":"Kesalahan komunikasi: tidak normalnya kendali", + "STR_WEB_REQUEST_TIMEOUT":"Kesalahan komunikasi: Waktu permintaan habis", + "STR_WEB_SERVICE_UNAVAILABLE":"Kesalahan komunikasi: Layanan tidak tersedia", + "STR_WEB_TOKEN_MISMATCH":"Status daemon diperbarui, silakan coba lagi nanti.", + "STR_WEB_SERVICE_BUSY":"Layanan sedang sibuk, silakan coba lagi nanti.", + "STR_MENU_VTSI_CREATE":"Membuat berkas VTSI", + "STR_VTSI_CREATE_TIP":"Saat ini tidak akan menuliskan di perangkat, tetapi hanya membuat berkas VTSI #@Lanjutkan?", + "STR_VTSI_CREATE_SUCCESS":"Berkas VTSI berhasil dibuat#@Anda bisa menggunakan Rufus(3.15+) untuk menulisnya ke perangkat untuk menyelesaikan instalasi Ventoy.", + "STR_VTSI_CREATE_FAILED":"Berkas VTSI gagal dibuat.", + "STRXXX":"" + }, + { + "name":"Ukrainian (УкраїнÑька)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Teraskull", + + "STR_ERROR":"Помилка", + "STR_WARNING":"ПопередженнÑ", + "STR_INFO":"ІнформаціÑ", + "STR_INCORRECT_DIR":"Будь лаÑка, запуÑÑ‚Ñ–Ñ‚ÑŒ у правильному каталозі!", + "STR_INCORRECT_TREE_DIR":"Ðе запуÑкайте мене тут, завантажте реліз інÑталÑційного пакету Ñ– запуÑÑ‚Ñ–Ñ‚ÑŒ там.", + "STR_DEVICE":"ПриÑтрій", + "STR_LOCAL_VER":"Ventoy в пакеті", + "STR_DISK_VER":"Ventoy на приÑтрої", + "STR_STATUS":"Стан - ГОТОВИЙ", + "STR_INSTALL":"Ð’Ñтановити", + "STR_UPDATE":"Оновити", + "STR_UPDATE_TIP":"ÐŸÑ€Ð¾Ñ†ÐµÑ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ Ð±ÐµÐ·Ð¿ÐµÑ‡Ð½Ð¸Ð¹, файли ISO залишатьÑÑ Ð½ÐµÐ·Ð¼Ñ–Ð½Ð½Ð¸Ð¼Ð¸.#@Продовжити?", + "STR_INSTALL_TIP":"ДиÑк буде відформатовано, Ñ– вÑÑ– дані будуть втрачені.#@Продовжити?", + "STR_INSTALL_TIP2":"ДиÑк буде відформатовано, Ñ– вÑÑ– дані будуть втрачені.#@Продовжити? (Подвійна перевірка)", + "STR_INSTALL_SUCCESS":"Вітаємо!#@Ventoy уÑпішно вÑтановлено на приÑтрій.", + "STR_INSTALL_FAILED":"Під Ñ‡Ð°Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Ви можете ще раз підключити USB Ñ– повторити Ñпробу. Перевірте log.txt Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÐµÐ¹.", + "STR_UPDATE_SUCCESS":"Вітаємо!#@Ventoy на приÑтрої уÑпішно оновлено.", + "STR_UPDATE_FAILED":"Під Ñ‡Ð°Ñ Ð¾Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Ви можете ще раз підключити USB Ñ– повторити Ñпробу. Перевірте log.txt Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÐµÐ¹.", + "STR_WAIT_PROCESS":"Потік запущено, зачекайте...", + "STR_MENU_OPTION":"Опції", + "STR_MENU_SECURE_BOOT":"Підтримка Secure Boot", + "STR_MENU_PART_CFG":"ÐšÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ Ñ€Ð¾Ð·Ð´Ñ–Ð»Ñ–Ð²", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"СкаÑувати", + "STR_PRESERVE_SPACE":"Зарезервувати проÑÑ‚Ñ–Ñ€ в кінці диÑка", + "STR_SPACE_VAL_INVALID":"ÐедійÑне Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð·Ð°Ñ€ÐµÐ·ÐµÑ€Ð²Ð¾Ð²Ð°Ð½Ð¾Ð³Ð¾ проÑтору", + "STR_MENU_CLEAR":"Видалити Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy уÑпішно видалено з приÑтрою.", + "STR_CLEAR_FAILED":"Під Ñ‡Ð°Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ Ventoy ÑталаÑÑ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°. Ви можете ще раз підключити USB Ñ– повторити Ñпробу. Перевірте log.txt Ð´Ð»Ñ Ð´ÐµÑ‚Ð°Ð»ÐµÐ¹.", + "STR_MENU_PART_STYLE":"Стиль розмітки розділів", + "STR_DISK_2TB_MBR_ERROR":"Будь лаÑка, виберіть GPT Ð´Ð»Ñ Ð´Ð¸Ñків понад 2TB", + "STR_SHOW_ALL_DEV":"Показати вÑÑ– приÑтрої", + "STR_PART_ALIGN_4KB":"ВирівнÑти розділи з розміром 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Помилка зв'Ñзку: ", + "STR_WEB_REMOTE_ABNORMAL":"Помилка зв'Ñзку: віддалене з'Ñ”Ð´Ð½Ð°Ð½Ð½Ñ Ð½ÐµÐ´Ñ–Ð¹Ñне", + "STR_WEB_REQUEST_TIMEOUT":"Помилка зв'Ñзку: Ð§Ð°Ñ Ð¾Ñ‡Ñ–ÐºÑƒÐ²Ð°Ð½Ð½Ñ Ð·Ð°Ð¿Ð¸Ñ‚Ñƒ минув", + "STR_WEB_SERVICE_UNAVAILABLE":"Помилка зв'Ñзку: Служба недоÑтупна", + "STR_WEB_TOKEN_MISMATCH":"Ð¡Ñ‚Ð°Ñ‚ÑƒÑ Ð´ÐµÐ¼Ð¾Ð½Ð° оновлено. Повторіть Ñпробу пізніше.", + "STR_WEB_SERVICE_BUSY":"Служба зайнÑта, повторіть Ñпробу пізніше.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Greek (Ελληνικά)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"grmasa, Vasilis Kosmidis", + + "STR_ERROR":"Σφάλμα", + "STR_WARNING":"ΠÏοειδοποίηση", + "STR_INFO":"ΠληÏοφοÏίες", + "STR_INCORRECT_DIR":"ΠαÏακαλώ εκτελέστε στον σωστό κατάλογο!", + "STR_INCORRECT_TREE_DIR":"Μην με εκτελείτε εδώ, κατεβάστε το πακέτο εγκατάστασης και εκτελέστε εκεί.", + "STR_DEVICE":"Συσκευή", + "STR_LOCAL_VER":"Ventoy στο Ï€ÏόγÏαμμα", + "STR_DISK_VER":"Ventoy στη συσκευή", + "STR_STATUS":"Κατάσταση - ΕΤΟΙΜΟ", + "STR_INSTALL":"Εγκατάσταση", + "STR_UPDATE":"Αναβάθμιση", + "STR_UPDATE_TIP":"Η λειτουÏγία αναβάθμισης είναι ασφαλής, τα αÏχεία ISO δεν θα αλλάξουν.#@Συνέχεια;", + "STR_INSTALL_TIP":"Ο δίσκος θα μοÏφοποιηθεί και όλα τα δεδομένα θα χαθοÏν.#@Συνέχεια;", + "STR_INSTALL_TIP2":"Ο δίσκος θα μοÏφοποιηθεί και όλα τα δεδομένα θα χαθοÏν.#@Συνέχεια; (Επανελέγξτε)", + "STR_INSTALL_SUCCESS":"ΣυγχαÏητήÏια!#Το @Ventoy έχει εγκατασταθεί με επιτυχία στη συσκευή.", + "STR_INSTALL_FAILED":"ΠαÏουσιάστηκε σφάλμα κατά την εγκατάσταση. ΜποÏείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αÏχείο log.txt για λεπτομέÏειες.", + "STR_UPDATE_SUCCESS":"ΣυγχαÏητήÏια!#Το @Ventoy ενημεÏώθηκε με επιτυχία στη συσκευή.", + "STR_UPDATE_FAILED":"ΠαÏουσιάστηκε σφάλμα κατά την ενημέÏωση. ΜποÏείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αÏχείο log.txt για λεπτομέÏειες.", + "STR_WAIT_PROCESS":"Ένα νήμα εκτελείται, παÏακαλώ πεÏιμένετε...", + "STR_MENU_OPTION":"Επιλογές", + "STR_MENU_SECURE_BOOT":"ΥποστήÏιξη ασφαλοÏÏ‚ εκκίνησης (Secure Boot)", + "STR_MENU_PART_CFG":"ΔιαμόÏφωση κατατμήσεων", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"ΑκÏÏωση", + "STR_PRESERVE_SPACE":"ΔιατηÏήστε λίγο χώÏο στο κάτω μέÏος του δίσκου", + "STR_SPACE_VAL_INVALID":"Μη έγκυÏη τιμή για τον δεσμευμένο χώÏο", + "STR_MENU_CLEAR":"Απεγκατάσταση του Ventoy", + "STR_CLEAR_SUCCESS":"Το Ventoy καταÏγήθηκε με επιτυχία από τη συσκευή.", + "STR_CLEAR_FAILED":"ΠαÏουσιάστηκε σφάλμα κατά την εκκαθάÏιση του Ventoy από το δίσκο. ΜποÏείτε να επανασυνδέσετε το USB και να δοκιμάσετε ξανά. Ελέγξτε το αÏχείο log.txt για λεπτομέÏειες.", + "STR_MENU_PART_STYLE":"Στυλ κατατμήσεων", + "STR_DISK_2TB_MBR_ERROR":"ΠαÏακαλώ επιλέξτε GPT για δίσκο άνω των 2 TB", + "STR_SHOW_ALL_DEV":"ΠÏοβολή όλων των συσκευών", + "STR_PART_ALIGN_4KB":"ΕυθυγÏάμμιση κατατμήσεων με 4KB", + "STR_WEB_COMMUNICATION_ERR":"Σφάλμα επικοινωνίας:", + "STR_WEB_REMOTE_ABNORMAL":"Σφάλμα επικοινωνίας: απομακÏυσμένη ανωμαλία", + "STR_WEB_REQUEST_TIMEOUT":"Σφάλμα επικοινωνίας: χÏονική λήξη αιτήματος", + "STR_WEB_SERVICE_UNAVAILABLE":"Σφάλμα επικοινωνίας: υπηÏεσία μη διαθέσιμη", + "STR_WEB_TOKEN_MISMATCH":"Η κατάσταση του δαίμονα επικαιÏοποιήθηκε. ΠαÏακαλώ δοκιμάστε αÏγότεÏα.", + "STR_WEB_SERVICE_BUSY":"Η υπηÏεσία είναι απασχολημένη. ΠαÏακαλώ δοκιμάστε αÏγότεÏα.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Swedish (Svenska)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Sopor", + + "STR_ERROR":"Fel", + "STR_WARNING":"Varning", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Kör programmet frÃ¥n korrekt katalog!", + "STR_INCORRECT_TREE_DIR":"Kör inte programmet här. Ladda ner installationspaketet och kör programmet där.", + "STR_DEVICE":"Enhet", + "STR_LOCAL_VER":"Ventoy i paketet", + "STR_DISK_VER":"Ventoy pÃ¥ enheten", + "STR_STATUS":"Status - REDO", + "STR_INSTALL":"Installera", + "STR_UPDATE":"Uppdatera", + "STR_UPDATE_TIP":"Uppdateringen är säker, ISO-filerna kommer att vara oförändrade.#@Fortsätta?", + "STR_INSTALL_TIP":"Enheten kommer att formateras och all data kommer att gÃ¥ förlorad.#@Fortsätta?", + "STR_INSTALL_TIP2":"Enheten kommer att formateras och all data kommer att gÃ¥ förlorad.#@Fortsätta? (Sista varningen!)", + "STR_INSTALL_SUCCESS":"Gratulerar!#@Ventoy har installerats pÃ¥ enheten.", + "STR_INSTALL_FAILED":"Ett fel inträffade under installationen. Prova att Ã¥teransluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_UPDATE_SUCCESS":"Gratulerar!#@Ventoy har uppdaterats pÃ¥ enheten.", + "STR_UPDATE_FAILED":"Ett fel inträffade under uppdateringen. Prova att Ã¥teransluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_WAIT_PROCESS":"En trÃ¥d körs redan, vänta...", + "STR_MENU_OPTION":"Alternativ", + "STR_MENU_SECURE_BOOT":"Stöd för säker start", + "STR_MENU_PART_CFG":"Partitionskonfiguration", + "STR_BTN_OK":"OK", + "STR_BTN_CANCEL":"Avbryt", + "STR_PRESERVE_SPACE":"Spara lite utrymme i slutet av enheten", + "STR_SPACE_VAL_INVALID":"Ogiltigt värde för reserverat utrymme", + "STR_MENU_CLEAR":"Ta bort Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy har tagits bort frÃ¥n enheten.", + "STR_CLEAR_FAILED":"Ett fel inträffade när Ventoy skulle tas bort frÃ¥n enheten. Prova att Ã¥teransluta USB-enheten och försök igen. Läs i log.txt för mer information.", + "STR_MENU_PART_STYLE":"Partitionsstil", + "STR_DISK_2TB_MBR_ERROR":"Välj GPT för enhet över 2 TB", + "STR_SHOW_ALL_DEV":"Visa alla enheter", + "STR_PART_ALIGN_4KB":"Justera partitioner med 4KB", + "STR_WEB_COMMUNICATION_ERR":"Kommunikationsfel:", + "STR_WEB_REMOTE_ABNORMAL":"Kommunikationsfel: onormal fjärr", + "STR_WEB_REQUEST_TIMEOUT":"Kommunikationsfel: Begäran tog för lÃ¥ng tid", + "STR_WEB_SERVICE_UNAVAILABLE":"Kommunikationsfel: Tjänsten är inte tillgänglig", + "STR_WEB_TOKEN_MISMATCH":"Daemon-status uppdaterad. Försök igen senare.", + "STR_WEB_SERVICE_BUSY":"Tjänster är upptagen. Försök igen senare.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Slovenian (Slovenski)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Urajmal", + + "STR_ERROR":"Napaka", + "STR_WARNING":"Opozorilo", + "STR_INFO":"Info", + "STR_INCORRECT_DIR":"Prosim izberite pravilno pot!", + "STR_INCORRECT_TREE_DIR":"Ne zaganjajte tukaj. Prosim prenesite posodobljeno verzijo in jo zaženite.", + "STR_DEVICE":"Naprava", + "STR_LOCAL_VER":"Ventoy verzija", + "STR_DISK_VER":"Ventoy na napravi", + "STR_STATUS":"Status - PRIPRAVLJEN", + "STR_INSTALL":"Namesti", + "STR_UPDATE":"Nadgradi", + "STR_UPDATE_TIP":"Varna nadgradnja. ISO datoteke ne bodo spremenjene.#@Nadaljujem?", + "STR_INSTALL_TIP":"Ta disk bo formatiran in vsi podatki bodo izbrisani.#@Nadaljujem?", + "STR_INSTALL_TIP2":"Ta disk bo formatiran in vsi podatki bodo izbrisani.#@Nadaljujem? (Druga potrditev)", + "STR_INSTALL_SUCCESS":"ÄŒestitamo!#@ventoy je bil uspeÅ¡no nameÅ¡Äen na napravo.", + "STR_INSTALL_FAILED":"Med namestitvijo je priÅ¡lo do napake. Iztaknite in ponovno priklopite USB. Preverite log.txt za podrobnosti.", + "STR_UPDATE_SUCCESS":"ÄŒestitamo!#@ventoy na napravi je bil uspeÅ¡no posodobljen.", + "STR_UPDATE_FAILED":"PriÅ¡lo je do napake med nadgradnjo. Iztaknite in ponovno priklopite USB. Preverite log.txt za podrobnosti.", + "STR_WAIT_PROCESS":"Proces teÄe, prosimo poÄakajte, ...", + "STR_MENU_OPTION":"Nastavitve", + "STR_MENU_SECURE_BOOT":"Podpora Secure Boot", + "STR_MENU_PART_CFG":"Konfiguracija particij", + "STR_BTN_OK":"V redu", + "STR_BTN_CANCEL":"PrekliÄi", + "STR_PRESERVE_SPACE":"Ohrani nekaj prostora na koncu particije", + "STR_SPACE_VAL_INVALID":"Nepravilna vrednost za rezerviran prostor", + "STR_MENU_CLEAR":"Odstrani Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy je bil uspeÅ¡no odstranjen.", + "STR_CLEAR_FAILED":"PriÅ¡lo je do napake pri odstranjevanju Ventoy-a iz diska. Iztaknite in ponovno priklopite USB. Preverite log.txt za podrobnosti.", + "STR_MENU_PART_STYLE":"Vrsta particije", + "STR_DISK_2TB_MBR_ERROR":"Prosim izberite GPT za particije nad 2TB", + "STR_SHOW_ALL_DEV":"Pokaži vse naprave", + "STR_PART_ALIGN_4KB":"Poravnaj particije na 4KB", + "STR_WEB_COMMUNICATION_ERR":"Napaka v komunikaciji:", + "STR_WEB_REMOTE_ABNORMAL":"Napaka v komunikaciji: oddaljena težava", + "STR_WEB_REQUEST_TIMEOUT":"Napaka v komunikaciji: Äas je potekel", + "STR_WEB_SERVICE_UNAVAILABLE":"Napaka v komunikaciji: storitev ni na voljo", + "STR_WEB_TOKEN_MISMATCH":"Zahteva storitve je potekla, prosim poskusite kasneje.", + "STR_WEB_SERVICE_BUSY":"Storitev je zasedena, prosim poskusite kasneje.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"This time will not write to the device, but only generate a VTSI file#@Continue?", + "STR_VTSI_CREATE_SUCCESS":"VTSI file created successfully!#@You can use Rufus(3.15+) to write it to the device so as to complete the installation of Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI file created failed.", + "STRXXX":"" + }, + { + "name":"Bulgarian (БългарÑки)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"jekovcar", + + "STR_ERROR":"Грешка", + "STR_WARNING":"Предупреждение", + "STR_INFO":"ИнформациÑ", + "STR_INCORRECT_DIR":"МолÑ, Ñтартирайте в друга директориÑ!", + "STR_INCORRECT_TREE_DIR":"Ðе ме Ñтартирайте оттук, молÑ, изтеглете инÑталационен пакет и го Ñтартирайте в друго мÑÑто.", + "STR_DEVICE":"УÑтройÑтво", + "STR_LOCAL_VER":"Ventoy в пакета", + "STR_DISK_VER":"Ventoy на уÑтройÑтвото", + "STR_STATUS":"Ð¡Ñ‚Ð°Ñ‚ÑƒÑ - ГОТОВ", + "STR_INSTALL":"ИнÑталирай", + "STR_UPDATE":"Обнови", + "STR_UPDATE_TIP":"ОбновÑването е безопаÑно, ISO-файловете нÑма да Ñе променÑÑ‚.#@Продължаваме?", + "STR_INSTALL_TIP":"ДиÑка ще Ñе форматира и вÑички данни изтриÑÑ‚.#@Продължаваме?", + "STR_INSTALL_TIP2":"ДиÑка ще Ñе форматира и вÑички данни изтриÑÑ‚..#@ДЕЙСТВИТЕЛÐО ще продължите?", + "STR_INSTALL_SUCCESS":"Поздрави!#@Ventoy бе уÑпешно инÑталиран на уÑтройÑтвото.", + "STR_INSTALL_FAILED":"По време на инÑталирането на Ventoy възникна грешка. ПодÑъединете уÑтройÑтвото и опитайте отново. Проверете log.txt за грешки.", + "STR_UPDATE_SUCCESS":"Поздрави!#@Ventoy бе уÑпешно обновен на уÑтройÑтвото.", + "STR_UPDATE_FAILED":"По време на обновÑването на Ventoy възникна грешка. ПодÑъединете уÑтройÑтвото и опитайте отново. Проверете log.txt за грешки.", + "STR_WAIT_PROCESS":"ПроцеÑа е Ñтартиран, Ð¼Ð¾Ð»Ñ Ð¸Ð·Ñ‡Ð°ÐºÐ°Ð¹Ñ‚Ðµ...", + "STR_MENU_OPTION":"Опции", + "STR_MENU_SECURE_BOOT":"Поддръжка на Secure Boot", + "STR_MENU_PART_CFG":"Допълнителен дÑл", + "STR_BTN_OK":"ОК", + "STR_BTN_CANCEL":"Отказ", + "STR_PRESERVE_SPACE":"Създай Допълнителен дÑл в ÐºÑ€Ð°Ñ Ð½Ð° диÑка", + "STR_SPACE_VAL_INVALID":"Ðеправилен размер на дÑла", + "STR_MENU_CLEAR":"Изтрий Ventoy", + "STR_CLEAR_SUCCESS":"Ventoy бе уÑпешно изтрит от уÑтройÑтвото.", + "STR_CLEAR_FAILED":"По време на изтриването на Ventoy възникна грешка. ПодÑъединете уÑтройÑтвото и опитайте отново. Проверете log.txt за грешки.", + "STR_MENU_PART_STYLE":"Стил на оразмерÑване на дÑловете", + "STR_DISK_2TB_MBR_ERROR":"МолÑ, изберете GPT за диÑкове по-големи от 2ТБ", + "STR_SHOW_ALL_DEV":"Покажи вÑички уÑтройÑтва", + "STR_PART_ALIGN_4KB":"Подравни дÑловете Ñ Ñ€Ð°Ð·Ð¼ÐµÑ€ 4КБ", + "STR_WEB_COMMUNICATION_ERR":"Грешка при Ñвързване:", + "STR_WEB_REMOTE_ABNORMAL":"Грешка при Ñвързване: Отдалечената връзка е недейÑтвителна", + "STR_WEB_REQUEST_TIMEOUT":"Грешка при Ñвързване: Изтекло време за изчакване на заÑвката", + "STR_WEB_SERVICE_UNAVAILABLE":"Грешка при Ñвързване: Службата е недоÑтъпна", + "STR_WEB_TOKEN_MISMATCH":"СтатуÑа на агента е обновен. Повторете по-къÑно.", + "STR_WEB_SERVICE_BUSY":"Службата е заета, Повторете по-къÑно.", + "STR_MENU_VTSI_CREATE":"Generate VTSI File", + "STR_VTSI_CREATE_TIP":"Сега нÑма да Ñе запиÑва на диÑка, Ñамо ще Ñе генерира VTSI файл#@Продължаваме?", + "STR_VTSI_CREATE_SUCCESS":"VTSI файла бе Ñъздаден уÑпешно!#@Може да използвате Rufus(3.15+) да го запишете на уÑтройÑтвото за инÑталациÑта Ñ Ventoy.", + "STR_VTSI_CREATE_FAILED":"VTSI файла Ñъздаване Ñе провали.", + "STRXXX":"" + }, + { + "name":"Armenian (Õ€Õ¡ÕµÕ¥Ö€Õ¥Õ¶)", + "FontFamily":"Courier New", + "FontSize":16, + "Author":"Egho", + + "STR_ERROR":"ÕÕ­Õ¡Õ¬", + "STR_WARNING":"Ô¶Õ£Õ¸Ö‚Õ·Õ¡ÖÕ¸Ö‚Õ´", + "STR_INFO":"ÕÕ¥Õ²Õ¥Õ¯Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶", + "STR_INCORRECT_DIR":"Ô½Õ¶Õ¤Ö€Õ¸Ö‚Õ´ Õ¥Õ¶Ö„ Õ£Õ¸Ö€Õ®Õ¡Ö€Õ¯Õ¥Õ¬ Õ³Õ«Õ·Õ¿ Õ©Õ²Õ©Õ¡Õ­Õ¡Õ¶Õ¡Õ¯Õ¸Ö‚Õ´!", + "STR_INCORRECT_TREE_DIR":"Õ‰Õ£Õ¸Ö€Õ®Õ¡Ö€Õ¯Õ¥Õ¬ Õ¡ÕµÕ½Õ¿Õ¥Õ², Õ­Õ¶Õ¤Ö€Õ¸Ö‚Õ´ Õ¥Õ´ Õ¶Õ¥Ö€Õ¢Õ¥Õ¼Õ¶Õ¥Ö„ Õ©Õ¸Õ²Õ¡Ö€Õ¯Õ¾Õ¡Õ® Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ´Õ¡Õ¶ ÖƒÕ¡Õ©Õ¥Õ©Õ¨ Ö‡ Õ£Õ¸Ö€Õ®Õ¡Ö€Õ¯Õ¥Õ¬ Õ¡ÕµÕ¶Õ¿Õ¥Õ²:", + "STR_DEVICE":"Ô¿Ö€Õ«Õ¹Õ¨", + "STR_LOCAL_VER":"Ventoy-Õ¨ ÖƒÕ¡Õ©Õ¥Õ©Õ¸Ö‚Õ´", + "STR_DISK_VER":"Ventoy-Õ¨ Õ¯Ö€Õ«Õ¹Õ¸Ö‚Õ´", + "STR_STATUS":"Ô¿Õ¡Ö€Õ£Õ¡Õ¾Õ«Õ³Õ¡Õ¯ - ÕŠÔ±ÕÕÔ±ÕÕ", + "STR_INSTALL":"ÕÕ¥Õ²Õ¡Õ¤Ö€Õ¥Õ¬", + "STR_UPDATE":"Ô¹Õ¡Ö€Õ´Õ¡ÖÕ¶Õ¥Õ¬", + "STR_UPDATE_TIP":"Ô¹Õ¡Ö€Õ´Õ¡ÖÕ´Õ¡Õ¶ Õ£Õ¸Ö€Õ®Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¡Õ¶Õ¾Õ¿Õ¡Õ¶Õ£ Õ§, ISO Ö†Õ¡ÕµÕ¬Õ¥Ö€Õ¨ Õ¯Õ´Õ¶Õ¡Õ¶ Õ¡Õ¶ÖƒÕ¸ÖƒÕ¸Õ­.#@Õ‡Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥Õ¬?", + "STR_INSTALL_TIP":"ÕÕ¯Õ¡Õ¾Õ¡Õ¼Õ¡Õ¯Õ¨ Õ¯Õ±Ö‡Õ¡Õ¹Õ¡ÖƒÕ¾Õ« Ö‡ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¨ Õ¯Õ¯Õ¸Ö€Õ¹Õ¥Õ¶.#@Õ‡Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥Õ¬?", + "STR_INSTALL_TIP2":"ÕÕ¯Õ¡Õ¾Õ¡Õ¼Õ¡Õ¯Õ¨ Õ¯Õ±Ö‡Õ¡Õ¹Õ¡ÖƒÕ¾Õ« Ö‡ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¿Õ¾ÕµÕ¡Õ¬Õ¶Õ¥Ö€Õ¨ Õ¯Õ¯Õ¸Ö€Õ¹Õ¥Õ¶:#@Ô´Õ¸Ö‚Ö„ Õ°Õ¡Õ´Õ¸Õ¦Õ¾Õ¡Õ® Õ¥Ö„, Õ´Õ¡Ö„Ö€Õ¥Õ¬ Õ¯Ö€Õ«Õ¹Õ¨? (Double Check)", + "STR_INSTALL_SUCCESS":"Õ‡Õ¶Õ¸Ö€Õ°Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´ Õ¥Õ¶Ö„!#@Ventoy- Õ¨ Õ°Õ¡Õ»Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¾Õ¥Õ¬ Õ§ Õ¯Ö€Õ«Õ¹Õ¸Ö‚Õ´:", + "STR_INSTALL_FAILED":"ÕÕ¥Õ²Õ¡Õ¤Ö€Õ´Õ¡Õ¶ Õ¨Õ¶Õ©Õ¡ÖÖ„Õ¸Ö‚Õ´ Õ¿Õ¥Õ²Õ« Õ¸Ö‚Õ¶Õ¥ÖÕ¡Õ¾ Õ½Õ­Õ¡Õ¬: Ô¿Õ¡Ö€Õ¸Õ² Õ¥Ö„ Õ¶Õ¸Ö€Õ«Ö Õ´Õ«Õ¡ÖÕ¶Õ¥Õ¬ USB- Õ¯Ö€Õ«Õ¹Õ¨ Ö‡ Õ¯Ö€Õ¯Õ«Õ¶ ÖƒÕ¸Ö€Õ±Õ¥Õ¬: Õ„Õ¡Õ¶Ö€Õ¡Õ´Õ¡Õ½Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ½Õ¿Õ¸Ö‚Õ£Õ¥Õ¬ log.txt-Õ¨ ", + "STR_UPDATE_SUCCESS":"Õ‡Õ¶Õ¸Ö€Õ°Õ¡Õ¾Õ¸Ö€Õ¸Ö‚Õ´ Õ¥Õ¶Ö„!#@Ventoy-Õ¨ Õ°Õ¡Õ»Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ©Õ¡Ö€Õ´Õ¡ÖÕ¾Õ¥Ö Õ¯Ö€Õ«Õ¹Õ¸Ö‚Õ´:", + "STR_UPDATE_FAILED":"Ô¹Õ¡Ö€Õ´Õ¡ÖÕ´Õ¡Õ¶ Õ¨Õ¶Õ©Õ¡ÖÖ„Õ¸Ö‚Õ´ Õ¿Õ¥Õ²Õ« Õ¸Ö‚Õ¶Õ¥ÖÕ¡Õ¾ Õ½Õ­Õ¡Õ¬: Ô¿Õ¡Ö€Õ¸Õ² Õ¥Ö„ Õ¶Õ¸Ö€Õ«Ö Õ´Õ«Õ¡ÖÕ¶Õ¥Õ¬ USB- Õ¯Ö€Õ«Õ¹Õ¨ Ö‡ Õ¯Ö€Õ¯Õ«Õ¶ ÖƒÕ¸Ö€Õ±Õ¥Õ¬: Õ„Õ¡Õ¶Ö€Õ¡Õ´Õ¡Õ½Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ½Õ¿Õ¸Ö‚Õ£Õ¥Õ¬ log.txt-Õ¨ ", + "STR_WAIT_PROCESS":"Ô±Õ·Õ­Õ¡Õ¿Õ¡Õ¶Ö„Õ¶ Õ¨Õ¶Õ©Õ¡Õ¶Õ¸Ö‚Õ´, Õ­Õ¶Õ¤Ö€Õ¸Ö‚Õ´ Õ¥Õ¶Ö„ Õ½ÕºÕ¡Õ½Õ¥Õ¬...", + "STR_MENU_OPTION":"Ô¸Õ¶Õ¿Ö€Õ¡Õ¶Ö„Õ¶Õ¥Ö€", + "STR_MENU_SECURE_BOOT":"Secure Boot Õ¡Õ»Õ¡Õ¯ÖÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶", + "STR_MENU_PART_CFG":"Partition Õ¯Õ¡Õ¦Õ´Õ¡Õ±Ö‡Õ¸Ö‚Õ´", + "STR_BTN_OK":"Ô±ÕµÕ¸", + "STR_BTN_CANCEL":"Õ‰Õ¥Õ²Õ¡Ö€Õ¯Õ¥Õ¬", + "STR_PRESERVE_SPACE":"ÕŠÕ¡Õ°ÕºÕ¡Õ¶Õ¥Ö„ Õ¸Ö€Õ¸Õ·Õ¡Õ¯Õ« Õ¿Õ¡Ö€Õ¡Õ®Ö„ Õ¯Ö€Õ«Õ¹Õ« Õ¾Õ¥Ö€Õ»Õ¸Ö‚Õ´", + "STR_SPACE_VAL_INVALID":"ÕŠÕ¡Õ°Õ¾Õ¡Õ® Õ¿Õ¡Ö€Õ¡Õ®Ö„Õ« Õ¡Õ¶Õ¾Õ¡Õ¾Õ¥Ö€ Õ¡Ö€ÕªÕ¥Ö„", + "STR_MENU_CLEAR":"Õ„Õ¡Ö„Ö€Õ¥Õ¬ Ventoy-Õ¨", + "STR_CLEAR_SUCCESS":"Ventoy-Õ¨ Õ°Õ¡Õ»Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ°Õ¥Õ¼Õ¡ÖÕ¾Õ¡Õ® Õ§ Õ¯Ö€Õ«Õ¹Õ«Ö:", + "STR_CLEAR_FAILED":"Ventoy-Õ¨ Õ¯Ö€Õ«Õ¹Õ«Ö Õ´Õ¡Ö„Ö€Õ¥Õ¬Õ«Õ½ Õ¿Õ¥Õ²Õ« Õ¸Ö‚Õ¶Õ¥ÖÕ¡Õ¾ Õ½Õ­Õ¡Õ¬: Ô¿Õ¡Ö€Õ¸Õ² Õ¥Ö„ Õ¶Õ¸Ö€Õ«Ö Õ´Õ«Õ¡ÖÕ¶Õ¥Õ¬ USB-Õ¯Ö€Õ«Õ¹Õ¨ Ö‡ Õ¯Ö€Õ¯Õ«Õ¶ ÖƒÕ¸Ö€Õ±Õ¥Õ¬: Õ„Õ¡Õ¶Ö€Õ¡Õ´Õ¡Õ½Õ¶Õ¥Ö€Õ« Õ°Õ¡Õ´Õ¡Ö€ Õ½Õ¿Õ¸Ö‚Õ£Õ¥Õ¬ log.txt-Õ¨", + "STR_MENU_PART_STYLE":"Partition-Õ« Õ¿Õ¥Õ½Õ¡Õ¯Õ¨", + "STR_DISK_2TB_MBR_ERROR":"Ô½Õ¶Õ¤Ö€Õ¸Ö‚Õ´ Õ¥Õ¶Ö„ Õ¨Õ¶Õ¿Ö€Õ¥Õ¬ GPT 2TB-Õ«Ö Õ´Õ¥Õ® Õ¯Ö€Õ«Õ¹Õ« Õ¤Õ¥ÕºÖ„Õ¸Ö‚Õ´", + "STR_SHOW_ALL_DEV":"Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ¢Õ¸Õ¬Õ¸Ö€ Õ¯Ö€Õ«Õ¹Õ¶Õ¥Ö€Õ¨", + "STR_PART_ALIGN_4KB":"partition-Õ¥Ö€Õ¨ Õ£Õ®Õ¡Õ¶Õ·Õ¥Õ¬ 4KB-Õ¸Õ¾", + "STR_WEB_COMMUNICATION_ERR":"Õ€Õ¡Õ´Õ¡Õ¯ÖÕ´Õ¡Õ¶ սխալ․", + "STR_WEB_REMOTE_ABNORMAL":"Õ€Õ¡Õ´Õ¡Õ¯ÖÕ´Õ¡Õ¶ սխալ․ Õ€Õ¥Õ¼Õ¡Õ°Õ¡Ö€ Õ°Õ¡Õ´Õ¡Õ¯ÖÕ¸Ö‚Õ´Õ¶ Õ¹Õ½Õ¿Õ¡ÖÕ¾Õ¥Ö", + "STR_WEB_REQUEST_TIMEOUT":"Õ€Õ¡Õ´Õ¡Õ¯ÖÕ´Õ¡Õ¶ սխալ․: ÕÕºÕ¡Õ½Õ´Õ¡Õ¶ ÕªÕ¡Õ´Õ¡Õ¶Õ¡Õ¯Õ¨ Õ½ÕºÕ¡Õ¼Õ¾Õ¥Ö", + "STR_WEB_SERVICE_UNAVAILABLE":"Õ€Õ¡Õ´Õ¡Õ¯ÖÕ´Õ¡Õ¶ սխալ․: Ô¾Õ¡Õ¼Õ¡ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¡Õ¶Õ°Õ¡Õ½Õ¡Õ¶Õ¥Õ¬Õ« Õ§", + "STR_WEB_TOKEN_MISMATCH":"Ô¹Õ¡Ö€Õ´Õ¡ÖÕ¾Õ¥Õ¬ Õ§ Demon-Õ« Õ¯Õ¡Ö€Õ£Õ¡Õ¾Õ«Õ³Õ¡Õ¯Õ¨, Õ­Õ¶Õ¤Ö€Õ¸Ö‚Õ´ Õ¥Õ´ Õ¶Õ¸Ö€Õ«Ö ÖƒÕ¸Ö€Õ±Õ¥Õ¬ Õ¡Õ¾Õ¥Õ¬Õ« Õ¸Ö‚Õ·:", + "STR_WEB_SERVICE_BUSY":"Ô¾Õ¡Õ¼Õ¡ÕµÕ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨ Õ¦Õ¢Õ¡Õ²Õ¾Õ¡Õ® Õ§, Õ­Õ¶Õ¤Ö€Õ¸Ö‚Õ´ Õ¥Õ´ Õ¶Õ¸Ö€Õ«Ö ÖƒÕ¸Ö€Õ±Õ¥Õ¬ Õ¡Õ¾Õ¥Õ¬Õ« Õ¸Ö‚Õ·:", + "STR_MENU_VTSI_CREATE":"ÕÕ¿Õ¥Õ²Õ®Õ¥Õ¬ VTSI Ö†Õ¡ÕµÕ¬", + "STR_VTSI_CREATE_TIP":"Ô±ÕµÕ½ Õ¡Õ¶Õ£Õ¡Õ´ Õ¹Õ« Õ£Ö€Õ¾Õ« Õ¯Ö€Õ«Õ¹Õ« Õ¾Ö€Õ¡, Õ¡ÕµÕ¬ Õ´Õ«Õ¡ÕµÕ¶ Õ¯Õ½Õ¿Õ¥Õ²Õ®Õ¾Õ« VTSI Ö†Õ¡ÕµÕ¬#@Õ‡Õ¡Ö€Õ¸Ö‚Õ¶Õ¡Õ¯Õ¥Õ¬?", + "STR_VTSI_CREATE_SUCCESS":"VTSI Ö†Õ¡ÕµÕ¬Õ¨ Õ°Õ¡Õ»Õ¸Õ²Õ¸Ö‚Õ©ÕµÕ¡Õ´Õ¢ Õ½Õ¿Õ¥Õ²Õ®Õ¾Õ¥Ö!#@Ô´Õ¸Ö‚Ö„ Õ¯Õ¡Ö€Õ¸Õ² Õ¥Ö„ Ö…Õ£Õ¿Õ¡Õ£Õ¸Ö€Õ®Õ¥Õ¬ Rufus (3.15+) Õ¯Ö€Õ«Õ¹Õ¸Ö‚Õ´ Õ±Õ¡ÕµÕ¶Õ¡Õ£Ö€Õ¥Õ¬Õ¸Ö‚ Õ°Õ¡Õ´Õ¡Ö€, Õ¸Ö€ÕºÕ¥Õ½Õ¦Õ« Õ¡Õ¾Õ¡Ö€Õ¿Õ¥Ö„ Ventoy-Õ« Õ¿Õ¥Õ²Õ¡Õ¤Ö€Õ¸Ö‚Õ´Õ¨:", + "STR_VTSI_CREATE_FAILED":"VTSI Ö†Õ¡ÕµÕ¬Õ« Õ½Õ¿Õ¥Õ²Õ®Õ¸Ö‚Õ´Õ¨ Õ±Õ¡Õ­Õ¸Õ²Õ¾Õ¥ÖÖ‰", + "STRXXX":"" + } +] diff --git a/LZIP/lunzip-1.11.tar.gz b/LZIP/lunzip-1.11.tar.gz new file mode 100644 index 00000000..3ef326f9 Binary files /dev/null and b/LZIP/lunzip-1.11.tar.gz differ diff --git a/LZIP/lunzip32 b/LZIP/lunzip32 new file mode 100644 index 00000000..a422baf0 Binary files /dev/null and b/LZIP/lunzip32 differ diff --git a/LZIP/lunzip64 b/LZIP/lunzip64 new file mode 100644 index 00000000..f5ab4dfd Binary files /dev/null and b/LZIP/lunzip64 differ diff --git a/LZIP/lunzipaa64 b/LZIP/lunzipaa64 new file mode 100644 index 00000000..72efbab9 Binary files /dev/null and b/LZIP/lunzipaa64 differ diff --git a/LZIP/lz4cat64 b/LZIP/lz4cat64 new file mode 100644 index 00000000..2790fa9f Binary files /dev/null and b/LZIP/lz4cat64 differ diff --git a/LZIP/lz4cataa64 b/LZIP/lz4cataa64 new file mode 100644 index 00000000..7e025d4d Binary files /dev/null and b/LZIP/lz4cataa64 differ diff --git a/LZIP/lz4catm64e b/LZIP/lz4catm64e new file mode 100644 index 00000000..3d803307 Binary files /dev/null and b/LZIP/lz4catm64e differ diff --git a/LZIP/smallz4cat.c b/LZIP/smallz4cat.c new file mode 100644 index 00000000..db3778b3 --- /dev/null +++ b/LZIP/smallz4cat.c @@ -0,0 +1,417 @@ +// ////////////////////////////////////////////////////////// +// smallz4cat.c +// Copyright (c) 2016-2019 Stephan Brumme. All rights reserved. +// see https://create.stephan-brumme.com/smallz4/ +// +// "MIT License": +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This program is a shorter, more readable, albeit slower re-implementation of lz4cat ( https://github.com/Cyan4973/xxHash ) + +// compile: gcc smallz4cat.c -O3 -o smallz4cat -Wall -pedantic -std=c99 -s +// The static 8k binary was compiled using Clang and dietlibc (see https://www.fefe.de/dietlibc/ ) + +// Limitations: +// - skippable frames and legacy frames are not implemented (and most likely never will) +// - checksums are not verified (see https://create.stephan-brumme.com/xxhash/ for a simple implementation) + +// Replace getByteFromIn() and sendToOut() by your own code if you need in-memory LZ4 decompression. +// Corrupted data causes a call to unlz4error(). + +// suppress warnings when compiled by Visual C++ +#define _CRT_SECURE_NO_WARNINGS + +#include // stdin/stdout/stderr, fopen, ... +#include // exit() +#include // memcpy + +#ifndef FALSE +#define FALSE 0 +#define TRUE 1 +#endif + +/// error handler +static void unlz4error(const char* msg) +{ + // smaller static binary than fprintf(stderr, "ERROR: %s\n", msg); + fputs("ERROR: ", stderr); + fputs(msg, stderr); + fputc('\n', stderr); + exit(1); +} + + +// ==================== I/O INTERFACE ==================== + + +// read one byte from input, see getByteFromIn() for a basic implementation +typedef unsigned char (*GET_BYTE) (void* userPtr); +// write several bytes, see sendBytesToOut() for a basic implementation +typedef void (*SEND_BYTES)(const unsigned char*, unsigned int, void* userPtr); + +struct UserPtr +{ + // file handles + FILE* in; + FILE* out; + // modify input buffer size as you like ... for most use cases, bigger buffer aren't faster anymore - and even reducing to 1 byte works ! +#define READ_BUFFER_SIZE 4*1024 + unsigned char readBuffer[READ_BUFFER_SIZE]; + unsigned int pos; + unsigned int available; +}; + +/// read a single byte (with simple buffering) +static unsigned char getByteFromIn(void* userPtr) // parameter "userPtr" not needed +{ + /// cast user-specific data + struct UserPtr* user = (struct UserPtr*)userPtr; + + // refill buffer + if (user->pos == user->available) + { + user->pos = 0; + user->available = fread(user->readBuffer, 1, READ_BUFFER_SIZE, user->in); + if (user->available == 0) + unlz4error("out of data"); + } + + // return a byte + return user->readBuffer[user->pos++]; +} + +/// write a block of bytes +static void sendBytesToOut(const unsigned char* data, unsigned int numBytes, void* userPtr) +{ + /// cast user-specific data + struct UserPtr* user = (struct UserPtr*)userPtr; + if (data != NULL && numBytes > 0) + fwrite(data, 1, numBytes, user->out); +} + + +// ==================== LZ4 DECOMPRESSOR ==================== + + +/// decompress everything in input stream (accessed via getByte) and write to output stream (via sendBytes) +void unlz4_userPtr(GET_BYTE getByte, SEND_BYTES sendBytes, const char* dictionary, void* userPtr) +{ + // signature + unsigned char signature1 = getByte(userPtr); + unsigned char signature2 = getByte(userPtr); + unsigned char signature3 = getByte(userPtr); + unsigned char signature4 = getByte(userPtr); + unsigned int signature = (signature4 << 24) | (signature3 << 16) | (signature2 << 8) | signature1; + unsigned char isModern = (signature == 0x184D2204); + unsigned char isLegacy = (signature == 0x184C2102); + if (!isModern && !isLegacy) + unlz4error("invalid signature"); + + unsigned char hasBlockChecksum = FALSE; + unsigned char hasContentSize = FALSE; + unsigned char hasContentChecksum = FALSE; + unsigned char hasDictionaryID = FALSE; + if (isModern) + { + // flags + unsigned char flags = getByte(userPtr); + hasBlockChecksum = flags & 16; + hasContentSize = flags & 8; + hasContentChecksum = flags & 4; + hasDictionaryID = flags & 1; + + // only version 1 file format + unsigned char version = flags >> 6; + if (version != 1) + unlz4error("only LZ4 file format version 1 supported"); + + // ignore blocksize + char numIgnore = 1; + + // ignore, skip 8 bytes + if (hasContentSize) + numIgnore += 8; + // ignore, skip 4 bytes + if (hasDictionaryID) + numIgnore += 4; + + // ignore header checksum (xxhash32 of everything up this point & 0xFF) + numIgnore++; + + // skip all those ignored bytes + while (numIgnore--) + getByte(userPtr); + } + + // don't lower this value, backreferences can be 64kb far away +#define HISTORY_SIZE 64*1024 + // contains the latest decoded data + unsigned char history[HISTORY_SIZE]; + // next free position in history[] + unsigned int pos = 0; + + // dictionary compression is a recently introduced feature, just move its contents to the buffer + if (dictionary != NULL) + { + // open dictionary + FILE* dict = fopen(dictionary, "rb"); + if (!dict) + unlz4error("cannot open dictionary"); + + // get dictionary's filesize + fseek(dict, 0, SEEK_END); + long dictSize = ftell(dict); + // only the last 64k are relevant + long relevant = dictSize < 65536 ? 0 : dictSize - 65536; + fseek(dict, relevant, SEEK_SET); + if (dictSize > 65536) + dictSize = 65536; + // read it and store it at the end of the buffer + fread(history + HISTORY_SIZE - dictSize, 1, dictSize, dict); + fclose(dict); + } + + // parse all blocks until blockSize == 0 + while (1) + { + // block size + unsigned int blockSize = getByte(userPtr); + blockSize |= (unsigned int)getByte(userPtr) << 8; + blockSize |= (unsigned int)getByte(userPtr) << 16; + blockSize |= (unsigned int)getByte(userPtr) << 24; + + // highest bit set ? + unsigned char isCompressed = isLegacy || (blockSize & 0x80000000) == 0; + if (isModern) + blockSize &= 0x7FFFFFFF; + + // stop after last block + if (blockSize == 0) + break; + + if (isCompressed) + { + // decompress block + unsigned int blockOffset = 0; + unsigned int numWritten = 0; + while (blockOffset < blockSize) + { + // get a token + unsigned char token = getByte(userPtr); + blockOffset++; + + // determine number of literals + unsigned int numLiterals = token >> 4; + if (numLiterals == 15) + { + // number of literals length encoded in more than 1 byte + unsigned char current; + do + { + current = getByte(userPtr); + numLiterals += current; + blockOffset++; + } while (current == 255); + } + + blockOffset += numLiterals; + + // copy all those literals + if (pos + numLiterals < HISTORY_SIZE) + { + // fast loop + while (numLiterals-- > 0) + history[pos++] = getByte(userPtr); + } + else + { + // slow loop + while (numLiterals-- > 0) + { + history[pos++] = getByte(userPtr); + + // flush output buffer + if (pos == HISTORY_SIZE) + { + sendBytes(history, HISTORY_SIZE, userPtr); + numWritten += HISTORY_SIZE; + pos = 0; + } + } + } + + // last token has only literals + if (blockOffset == blockSize) + break; + + // match distance is encoded in two bytes (little endian) + unsigned int delta = getByte(userPtr); + delta |= (unsigned int)getByte(userPtr) << 8; + // zero isn't allowed + if (delta == 0) + unlz4error("invalid offset"); + blockOffset += 2; + + // match length (always >= 4, therefore length is stored minus 4) + unsigned int matchLength = 4 + (token & 0x0F); + if (matchLength == 4 + 0x0F) + { + unsigned char current; + do // match length encoded in more than 1 byte + { + current = getByte(userPtr); + matchLength += current; + blockOffset++; + } while (current == 255); + } + + // copy match + unsigned int referencePos = (pos >= delta) ? (pos - delta) : (HISTORY_SIZE + pos - delta); + // start and end within the current 64k block ? + if (pos + matchLength < HISTORY_SIZE && referencePos + matchLength < HISTORY_SIZE) + { + // read/write continuous block (no wrap-around at the end of history[]) + // fast copy + if (pos >= referencePos + matchLength || referencePos >= pos + matchLength) + { + // non-overlapping + memcpy(history + pos, history + referencePos, matchLength); + pos += matchLength; + } + else + { + // overlapping, slower byte-wise copy + while (matchLength-- > 0) + history[pos++] = history[referencePos++]; + } + } + else + { + // either read or write wraps around at the end of history[] + while (matchLength-- > 0) + { + // copy single byte + history[pos++] = history[referencePos++]; + + // cannot write anymore ? => wrap around + if (pos == HISTORY_SIZE) + { + // flush output buffer + sendBytes(history, HISTORY_SIZE, userPtr); + numWritten += HISTORY_SIZE; + pos = 0; + } + // wrap-around of read location + referencePos %= HISTORY_SIZE; + } + } + } + + // all legacy blocks must be completely filled - except for the last one + if (isLegacy && numWritten + pos < 8*1024*1024) + break; + } + else + { + // copy uncompressed data and add to history, too (if next block is compressed and some matches refer to this block) + while (blockSize-- > 0) + { + // copy a byte ... + history[pos++] = getByte(userPtr); + // ... until buffer is full => send to output + if (pos == HISTORY_SIZE) + { + sendBytes(history, HISTORY_SIZE, userPtr); + pos = 0; + } + } + } + + if (hasBlockChecksum) + { + // ignore checksum, skip 4 bytes + getByte(userPtr); getByte(userPtr); getByte(userPtr); getByte(userPtr); + } + } + + if (hasContentChecksum) + { + // ignore checksum, skip 4 bytes + getByte(userPtr); getByte(userPtr); getByte(userPtr); getByte(userPtr); + } + + // flush output buffer + sendBytes(history, pos, userPtr); +} + +/// old interface where getByte and sendBytes use global file handles +void unlz4(GET_BYTE getByte, SEND_BYTES sendBytes, const char* dictionary) +{ + unlz4_userPtr(getByte, sendBytes, dictionary, NULL); +} + + +// ==================== COMMAND-LINE HANDLING ==================== + + +/// parse command-line +int main(int argc, const char* argv[]) +{ + // default input/output streams + struct UserPtr user = + { + .in = stdin, + .out = stdout, + .pos = 0, // initial input buffer is empty + .available = 0 + }; + + const char* dictionary = NULL; + + // first command-line parameter is our input filename / but ignore "-" which stands for STDIN + int parameter; + for (parameter = 1; parameter < argc; parameter++) + { + const char* current = argv[parameter]; + // dictionary + if (current[0] == '-' && current[1] == 'D') + { + if (parameter + 1 >= argc) + unlz4error("no dictionary filename found"); + dictionary = argv[++parameter]; + continue; + } + + // filename + // read from STDIN, default behavior + if (current[0] != '-' && current[1] != '\0') + { + // already have a filename - at most one filename is allowed (except for dictionary) ? + if (user.in != stdin) + unlz4error("can only decompress one file at a time"); + // get handle + user.in = fopen(argv[1], "rb"); + if (!user.in) + unlz4error("file not found"); + } + } + + // and go ! + unlz4_userPtr(getByteFromIn, sendBytesToOut, dictionary, &user); + return 0; +} diff --git a/License/lgpl-3.0.txt b/License/lgpl-3.0.txt new file mode 100644 index 00000000..80d241e1 --- /dev/null +++ b/License/lgpl-3.0.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/License/license-7z.txt b/License/license-7z.txt new file mode 100644 index 00000000..41cc0322 --- /dev/null +++ b/License/license-7z.txt @@ -0,0 +1,37 @@ + +imdisk follows LGPL license (see lgpl-3.0.txt) + +Ventoy only use its binaries 7za.exe + +========7zip License Information=============== + 7-Zip Extra + ~~~~~~~~~~~ + License for use and distribution + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Copyright (C) 1999-2019 Igor Pavlov. + + 7-Zip Extra files are under the GNU LGPL license. + + + Notes: + You can use 7-Zip Extra on any computer, including a computer in a commercial + organization. You don't need to register or pay for 7-Zip. + + + GNU LGPL information + -------------------- + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You can receive a copy of the GNU Lesser General Public License from + http://www.gnu.org/ + diff --git a/License/license-AdminLTE.txt b/License/license-AdminLTE.txt new file mode 100644 index 00000000..a751318d --- /dev/null +++ b/License/license-AdminLTE.txt @@ -0,0 +1 @@ +AdminLTE follows the MIT License (see MIT.txt) diff --git a/License/license-bootstrap.txt b/License/license-bootstrap.txt new file mode 100644 index 00000000..3dc9e9d0 --- /dev/null +++ b/License/license-bootstrap.txt @@ -0,0 +1 @@ +bootstrap follows the MIT License (see MIT.txt) diff --git a/License/license-jquery.txt b/License/license-jquery.txt new file mode 100644 index 00000000..8b0fac00 --- /dev/null +++ b/License/license-jquery.txt @@ -0,0 +1 @@ +jquery follows the MIT License (see MIT.txt) diff --git a/License/license-libhttp.txt b/License/license-libhttp.txt new file mode 100644 index 00000000..828f85d7 --- /dev/null +++ b/License/license-libhttp.txt @@ -0,0 +1,3 @@ +libhttp follows the MIT License (see MIT.txt) + +Ventoy does not modify its source code, only its header file and lib is used. diff --git a/License/license-lunzip.txt b/License/license-lunzip.txt new file mode 100644 index 00000000..8b4f5d0f --- /dev/null +++ b/License/license-lunzip.txt @@ -0,0 +1,3 @@ +lunzip follows GPLv2+ license (see gpl-2.0.txt) + +Ventoy does not modify its source code, only its binary is used. diff --git a/License/license-mini_gzip.txt b/License/license-mini_gzip.txt new file mode 100644 index 00000000..296be622 --- /dev/null +++ b/License/license-mini_gzip.txt @@ -0,0 +1,13 @@ + +https://github.com/wkoszek/mini_gzip + +Ventoy modify its source code, these code modified by Ventoy follow the same license as mini_gzip. + +=====================================License================================================= +Copyright (c) 2015, Wojciech Adam Koszek wojciech@koszek.com All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/License/license-tinycore.txt b/License/license-tinycore.txt new file mode 100644 index 00000000..4b8650a9 --- /dev/null +++ b/License/license-tinycore.txt @@ -0,0 +1,4 @@ +tinycore follows the GPL-v2 License (see gpl-2.0.txt) + +Ventoy does not modify its source code, only its binraries are used. + diff --git a/License/license-wimboot.txt b/License/license-wimboot.txt index 9179d035..8ab4754e 100644 --- a/License/license-wimboot.txt +++ b/License/license-wimboot.txt @@ -1,5 +1,4 @@ wimboot follows GPLv2+ license (see gpl-2.0.txt) -Ventoy use the lzx decompress file from wimboot. These code follow the same license as wimboot. - +Ventoy modified the code and follow the same license as wimboot. diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c new file mode 100644 index 00000000..9f80c61b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c @@ -0,0 +1,299 @@ +/****************************************************************************** + * crc32.c ---- ventoy crc32 + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#include +#include +#include +#include +#include +#include + +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; +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_define.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_define.h new file mode 100644 index 00000000..14b2cf41 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_define.h @@ -0,0 +1,192 @@ +/****************************************************************************** + * ventoy_define.h + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#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__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c new file mode 100644 index 00000000..04eb7f48 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c @@ -0,0 +1,751 @@ +/****************************************************************************** + * ventoy_disk.c ---- ventoy disk + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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/zramX */ + if (name[0] == 'z' && name[1] == 'r' && name[2] == 'a' && name[3] == 'm') + { + return 0; + } + + /* /dev/loopX */ + if (name[0] == 'l' && name[1] == 'o' && name[2] == 'o' && name[3] == 'p') + { + return 0; + } + + /* /dev/dm-X */ + if (name[0] == 'd' && name[1] == 'm' && name[2] == '-' && isdigit(name[3])) + { + return 0; + } + + /* /dev/srX */ + if (name[0] == 's' && name[1] == 'r' && isdigit(name[2])) + { + return 0; + } + + return 1; +} + +uint64_t ventoy_get_disk_size_in_byte(const char *disk) +{ + int fd; + int rc; + unsigned long long size = 0; + char diskpath[256] = {0}; + char sizebuf[64] = {0}; + + // Try 1: get size from sysfs + 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) + { + vlog("/EFI/BOOT/grubx64_real.efi find, secure boot in enabled\n"); + fl_fclose(flfile); + return 1; + } + else + { + vlog("/EFI/BOOT/grubx64_real.efi not exist\n"); + } + + return 0; +} + +static int fatlib_get_ventoy_version(char *verbuf, int bufsize) +{ + int rc = 1; + int size = 0; + char *buf = NULL; + char *pos = NULL; + char *end = NULL; + void *flfile = NULL; + + flfile = fl_fopen("/grub/grub.cfg", "rb"); + if (flfile) + { + fl_fseek(flfile, 0, SEEK_END); + size = (int)fl_ftell(flfile); + + fl_fseek(flfile, 0, SEEK_SET); + + buf = malloc(size + 1); + if (buf) + { + fl_fread(buf, 1, size, flfile); + buf[size] = 0; + + pos = strstr(buf, "VENTOY_VERSION="); + if (pos) + { + pos += strlen("VENTOY_VERSION="); + if (*pos == '"') + { + pos++; + } + + end = pos; + while (*end != 0 && *end != '"' && *end != '\r' && *end != '\n') + { + end++; + } + + *end = 0; + + 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("ventoy partition layout check OK: [%llu %llu] [%llu %llu]\n", + part1_start_sector, part1_sector_count, part2_start_sector, part2_sector_count); + + vtoy->ventoy_valid = 1; + + vdebug("now check secure boot for %s ...\n", info->disk_path); + + g_fatlib_media_fd = fd; + g_fatlib_media_offset = part2_start_sector; + fl_init(); + + if (0 == fl_attach_media(fatlib_media_sector_read, NULL)) + { + ret = fatlib_get_ventoy_version(vtoy->ventoy_ver, sizeof(vtoy->ventoy_ver)); + if (ret == 0 && vtoy->ventoy_ver[0]) + { + vtoy->secure_boot_flag = fatlib_is_secure_boot_enable(); + } + else + { + vdebug("fatlib_get_ventoy_version failed %d\n", ret); + } + } + else + { + vdebug("fl_attach_media failed\n"); + } + + fl_shutdown(); + g_fatlib_media_fd = -1; + g_fatlib_media_offset = 0; + + if (vtoy->ventoy_ver[0] == 0) + { + vtoy->ventoy_ver[0] = '?'; + } + + if (0 == vtoy->ventoy_valid) + { + goto end; + } + + lseek(fd, 2040 * 512, SEEK_SET); + read(fd, vtoy->rsvdata, sizeof(vtoy->rsvdata)); + + vtoy->preserved_space = preserved_space; + vtoy->partition_style = part_style; + vtoy->part2_start_sector = part2_start_sector; + + rc = 0; +end: + vtoy_safe_close_fd(fd); + return rc; +} + +int ventoy_get_disk_info(const char *name, ventoy_disk *info) +{ + char vendor[64] = {0}; + char model[128] = {0}; + + vdebug("get disk info %s\n", name); + + strlcpy(info->disk_name, name); + scnprintf(info->disk_path, "/dev/%s", name); + + if (strstr(name, "nvme") || strstr(name, "mmc") || strstr(name, "nbd")) + { + scnprintf(info->part1_name, "%sp1", name); + scnprintf(info->part1_path, "/dev/%sp1", name); + scnprintf(info->part2_name, "%sp2", name); + scnprintf(info->part2_path, "/dev/%sp2", name); + } + else + { + scnprintf(info->part1_name, "%s1", name); + scnprintf(info->part1_path, "/dev/%s1", name); + scnprintf(info->part2_name, "%s2", name); + scnprintf(info->part2_path, "/dev/%s2", name); + } + + info->size_in_byte = ventoy_get_disk_size_in_byte(name); + + ventoy_get_disk_devnum(name, &info->major, &info->minor); + info->type = ventoy_get_dev_type(name, info->major, info->minor); + ventoy_get_disk_vendor(name, vendor, sizeof(vendor)); + ventoy_get_disk_model(name, model, sizeof(model)); + + scnprintf(info->human_readable_size, "%llu GB", (_ull)ventoy_get_human_readable_gb(info->size_in_byte)); + scnprintf(info->disk_model, "%s %s (%s)", vendor, model, ventoy_get_dev_type_name(info->type)); + + ventoy_get_vtoy_data(info, &(info->partstyle)); + + vdebug("disk:<%s %d:%d> model:<%s> size:%llu (%s)\n", + info->disk_path, info->major, info->minor, info->disk_model, info->size_in_byte, info->human_readable_size); + + if (info->vtoydata.ventoy_valid) + { + vdebug("%s Ventoy:<%s> %s secureboot:%d preserve:%llu\n", info->disk_path, info->vtoydata.ventoy_ver, + info->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT", + info->vtoydata.secure_boot_flag, (_ull)(info->vtoydata.preserved_space)); + } + else + { + vdebug("%s NO Ventoy detected\n", info->disk_path); + } + + return 0; +} + +static int ventoy_disk_compare(const ventoy_disk *disk1, const ventoy_disk *disk2) +{ + if (disk1->type == VTOY_DEVICE_USB && disk2->type == VTOY_DEVICE_USB) + { + return strcmp(disk1->disk_name, disk2->disk_name); + } + else if (disk1->type == VTOY_DEVICE_USB) + { + return -1; + } + else if (disk2->type == VTOY_DEVICE_USB) + { + return 1; + } + else + { + return strcmp(disk1->disk_name, disk2->disk_name); + } +} + +static int ventoy_disk_sort(void) +{ + int i, j; + ventoy_disk *tmp; + + tmp = malloc(sizeof(ventoy_disk)); + if (!tmp) + { + return 1; + } + + for (i = 0; i < g_disk_num; i++) + for (j = i + 1; j < g_disk_num; j++) + { + if (ventoy_disk_compare(g_disk_list + i, g_disk_list + j) > 0) + { + memcpy(tmp, g_disk_list + i, sizeof(ventoy_disk)); + memcpy(g_disk_list + i, g_disk_list + j, sizeof(ventoy_disk)); + memcpy(g_disk_list + j, tmp, sizeof(ventoy_disk)); + } + } + + free(tmp); + return 0; +} + +int ventoy_disk_enumerate_all(void) +{ + int rc = 0; + DIR* dir = NULL; + struct dirent* p = NULL; + + vdebug("ventoy_disk_enumerate_all\n"); + + dir = opendir("/sys/block"); + if (!dir) + { + vlog("Failed to open /sys/block %d\n", errno); + return 1; + } + + while (((p = readdir(dir)) != NULL) && (g_disk_num < MAX_DISK_NUM)) + { + if (ventoy_is_possible_blkdev(p->d_name)) + { + memset(g_disk_list + g_disk_num, 0, sizeof(ventoy_disk)); + if (0 == ventoy_get_disk_info(p->d_name, g_disk_list + g_disk_num)) + { + g_disk_num++; + } + } + } + closedir(dir); + + ventoy_disk_sort(); + + return rc; +} + +void ventoy_disk_dump(ventoy_disk *cur) +{ + if (cur->vtoydata.ventoy_valid) + { + vdebug("%s [%s] %s\tVentoy: %s %s secureboot:%d preserve:%llu\n", + cur->disk_path, cur->human_readable_size, cur->disk_model, + cur->vtoydata.ventoy_ver, cur->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT", + cur->vtoydata.secure_boot_flag, (_ull)(cur->vtoydata.preserved_space)); + } + else + { + vdebug("%s [%s] %s\tVentoy: NA\n", cur->disk_path, cur->human_readable_size, cur->disk_model); + } +} + +void ventoy_disk_dump_all(void) +{ + int i; + + vdebug("============= DISK DUMP ============\n"); + for (i = 0; i < g_disk_num; i++) + { + ventoy_disk_dump(g_disk_list + i); + } +} + +int ventoy_disk_install(ventoy_disk *disk, void *efipartimg) +{ + return 0; +} + + +int ventoy_disk_init(void) +{ + g_disk_list = malloc(sizeof(ventoy_disk) * MAX_DISK_NUM); + + ventoy_disk_enumerate_all(); + ventoy_disk_dump_all(); + + return 0; +} + +void ventoy_disk_exit(void) +{ + check_free(g_disk_list); + g_disk_list = NULL; + g_disk_num = 0; +} + + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h new file mode 100644 index 00000000..50618dce --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h @@ -0,0 +1,145 @@ +/****************************************************************************** + * ventoy_disk.h + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#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 */ +#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__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_json.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.c new file mode 100644 index 00000000..f65a4583 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.c @@ -0,0 +1,716 @@ +/****************************************************************************** + * ventoy_json.c + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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; +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_json.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.h new file mode 100644 index 00000000..12e6f192 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_json.h @@ -0,0 +1,267 @@ +/****************************************************************************** + * ventoy_json.h + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#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__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_log.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_log.c new file mode 100644 index 00000000..6e788c2f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_log.c @@ -0,0 +1,143 @@ +/****************************************************************************** + * ventoy_log.c ---- ventoy log + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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_printf(const char *Fmt, ...) +{ + char log[512]; + va_list arg; + time_t stamp; + struct tm ttm; + FILE *fp; + + time(&stamp); + localtime_r(&stamp, &ttm); + + va_start(arg, Fmt); + 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); +} + +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); +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c new file mode 100644 index 00000000..ba79d545 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c @@ -0,0 +1,167 @@ +/****************************************************************************** + * ventoy_md5.c ---- ventoy md5 + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#include +#include +#include +#include +#include +#include + +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); +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_util.c b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.c new file mode 100644 index 00000000..38ac8d59 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.c @@ -0,0 +1,550 @@ +/****************************************************************************** + * ventoy_util.c ---- ventoy util + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 ModSectorCount = 0; + 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; + } + + Part1SectorCount = DiskSectorCount - ReservedSector - (VTOYEFI_PART_BYTES / 512) - 2048; + + ModSectorCount = (Part1SectorCount % 8); + if (ModSectorCount) + { + vlog("Part1SectorCount:%llu is not aligned by 4KB (%llu)\n", (_ull)Part1SectorCount, (_ull)ModSectorCount); + } + + // check aligned with 4KB + if (align4k) + { + if (ModSectorCount) + { + vdebug("Disk need to align with 4KB %u\n", (uint32_t)ModSectorCount); + Part1SectorCount -= ModSectorCount; + } + else + { + vdebug("no need to align with 4KB\n"); + } + } + + 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 = 0xC000000000000001ULL; + 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, 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); + } + + // 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); + } + else + { + vdebug("no need to align with 4KB\n"); + } + } + + 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; +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h new file mode 100644 index 00000000..72cec62d --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h @@ -0,0 +1,52 @@ +/****************************************************************************** + * ventoy_util.h + * + * Copyright (c) 2021, longpanda + * + * 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 . + * + */ +#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, MBR_HEAD *pMBR); + +#endif /* __VENTOY_UTIL_H__ */ + diff --git a/GenUUID/vtoy_gen_uuid.c b/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h similarity index 56% rename from GenUUID/vtoy_gen_uuid.c rename to LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h index 6e37750f..32f452cb 100644 --- a/GenUUID/vtoy_gen_uuid.c +++ b/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h @@ -1,7 +1,7 @@ /****************************************************************************** - * vtoy_gen_uuid.c + * Ventoy2Disk.h * - * Copyright (c) 2020, longpanda + * Copyright (c) 2021, longpanda * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,34 +17,10 @@ * along with this program; if not, see . * */ +#ifndef __VENTOY2DISK_H__ +#define __VENTOY2DISK_H__ -#include -#include -#include -#include -#include -#include -int main() -{ - int i; - int fd; - unsigned char uuid[16]; - - fd = open("/dev/random", O_RDONLY); - if (fd < 0) - { - srand(time(NULL)); - for (i = 0; i < 16; i++) - { - uuid[i] = (unsigned char)(rand()); - } - } - else - { - read(fd, uuid, 16); - } - - fwrite(uuid, 1, 16, stdout); - return 0; -} + +#endif /* __VENTOY2DISK_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh b/LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh new file mode 100644 index 00000000..00a83c64 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh @@ -0,0 +1,30 @@ +#!/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"/g' -i src/mkfs/mkexfat_main.c +sed 's//"exfat.h"/g' -i src/mkfs/mkexfat.h +sed 's/int main/int mkexfat_main/g' -i src/mkfs/mkexfat_main.c + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip b/LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip new file mode 100644 index 00000000..aa1d5f39 Binary files /dev/null and b/LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip differ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h new file mode 100644 index 00000000..ba544109 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h @@ -0,0 +1,68 @@ +/* + 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 +#include + +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 */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c new file mode 100644 index 00000000..15cd9aa3 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c @@ -0,0 +1,491 @@ +/* + 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 +#include +#include + +/* + * 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; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h new file mode 100644 index 00000000..7eb686c7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h @@ -0,0 +1,66 @@ +/* + 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 */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h new file mode 100644 index 00000000..73059a72 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h @@ -0,0 +1,40 @@ +/* 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 */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h new file mode 100644 index 00000000..b3ff78da --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h @@ -0,0 +1,255 @@ +/* + exfat.h (29.08.09) + Definitions of structures and constants used in exFAT file system + implementation. + + 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 EXFAT_H_INCLUDED +#define EXFAT_H_INCLUDED + +#ifndef ANDROID +/* Android.bp is used instead of autotools when targeting Android */ +#include "config.h" +#endif +#include "compiler.h" +#include "exfatfs.h" +#include +#include +#include +#include +#include +#include + +#define EXFAT_NAME_MAX 255 +/* UTF-16 encodes code points up to U+FFFF as single 16-bit code units. + UTF-8 uses up to 3 bytes (i.e. 8-bit code units) to encode code points + up to U+FFFF. One additional character is for null terminator. */ +#define EXFAT_UTF8_NAME_BUFFER_MAX (EXFAT_NAME_MAX * 3 + 1) +#define EXFAT_UTF8_ENAME_BUFFER_MAX (EXFAT_ENAME_MAX * 3 + 1) + +#define SECTOR_SIZE(sb) (1 << (sb).sector_bits) +#define CLUSTER_SIZE(sb) (SECTOR_SIZE(sb) << (sb).spc_bits) +#define CLUSTER_INVALID(sb, c) ((c) < EXFAT_FIRST_DATA_CLUSTER || \ + (c) - EXFAT_FIRST_DATA_CLUSTER >= le32_to_cpu((sb).cluster_count)) + +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define DIV_ROUND_UP(x, d) (((x) + (d) - 1) / (d)) +#define ROUND_UP(x, d) (DIV_ROUND_UP(x, d) * (d)) + +#define BMAP_SIZE(count) (ROUND_UP(count, sizeof(bitmap_t) * 8) / 8) +#define BMAP_BLOCK(index) ((index) / sizeof(bitmap_t) / 8) +#define BMAP_MASK(index) ((bitmap_t) 1 << ((index) % (sizeof(bitmap_t) * 8))) +#define BMAP_GET(bitmap, index) \ + ((bitmap)[BMAP_BLOCK(index)] & BMAP_MASK(index)) +#define BMAP_SET(bitmap, index) \ + ((bitmap)[BMAP_BLOCK(index)] |= BMAP_MASK(index)) +#define BMAP_CLR(bitmap, index) \ + ((bitmap)[BMAP_BLOCK(index)] &= ~BMAP_MASK(index)) + +#define EXFAT_REPAIR(hook, ef, ...) \ + (exfat_ask_to_fix(ef) && exfat_fix_ ## hook(ef, __VA_ARGS__)) + +/* The size of off_t type must be 64 bits. File systems larger than 2 GB will + be corrupted with 32-bit off_t. */ +STATIC_ASSERT(sizeof(off_t) == 8); + +struct exfat_node +{ + struct exfat_node* parent; + struct exfat_node* child; + struct exfat_node* next; + struct exfat_node* prev; + + int references; + uint32_t fptr_index; + cluster_t fptr_cluster; + off_t entry_offset; + cluster_t start_cluster; + uint16_t attrib; + uint8_t continuations; + bool is_contiguous : 1; + bool is_cached : 1; + bool is_dirty : 1; + bool is_unlinked : 1; + uint64_t size; + time_t mtime, atime; + le16_t name[EXFAT_NAME_MAX + 1]; +}; + +enum exfat_mode +{ + EXFAT_MODE_RO, + EXFAT_MODE_RW, + EXFAT_MODE_ANY, +}; + +struct exfat_dev; + +struct exfat +{ + struct exfat_dev* dev; + struct exfat_super_block* sb; + uint16_t* upcase; + struct exfat_node* root; + struct + { + cluster_t start_cluster; + uint32_t size; /* in bits */ + bitmap_t* chunk; + uint32_t chunk_size; /* in bits */ + bool dirty; + } + cmap; + char label[EXFAT_UTF8_ENAME_BUFFER_MAX]; + void* zero_cluster; + int dmask, fmask; + uid_t uid; + gid_t gid; + int ro; + bool noatime; + enum { EXFAT_REPAIR_NO, EXFAT_REPAIR_ASK, EXFAT_REPAIR_YES } repair; +}; + +/* in-core nodes iterator */ +struct exfat_iterator +{ + struct exfat_node* parent; + struct exfat_node* current; +}; + +struct exfat_human_bytes +{ + uint64_t value; + const char* unit; +}; + +extern int exfat_errors; +extern int exfat_errors_fixed; + +#define VLOG_LOG 1 +#define VLOG_DEBUG 2 +void ventoy_syslog_newline(int level, const char *Fmt, ...); +#define exfat_bug(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_error(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_error(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_warn(fmt, args...) ventoy_syslog_newline(VLOG_LOG, fmt, ##args) +#define exfat_debug(fmt, args...) ventoy_syslog_newline(VLOG_DEBUG, fmt, ##args) + +#if 0 +void exfat_bug(const char* format, ...) PRINTF NORETURN; +void exfat_error(const char* format, ...) PRINTF; +void exfat_warn(const char* format, ...) PRINTF; +void exfat_debug(const char* format, ...) PRINTF; +#endif /* #if 0 */ + +struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode); +int exfat_close(struct exfat_dev* dev); +int exfat_fsync(struct exfat_dev* dev); +enum exfat_mode exfat_get_mode(const struct exfat_dev* dev); +off_t exfat_get_size(const struct exfat_dev* dev); +off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence); +ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size); +ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size); +ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size, + off_t offset); +ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size, + off_t offset); +ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, + void* buffer, size_t size, off_t offset); +ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, + const void* buffer, size_t size, off_t offset); + +int exfat_opendir(struct exfat* ef, struct exfat_node* dir, + struct exfat_iterator* it); +void exfat_closedir(struct exfat* ef, struct exfat_iterator* it); +struct exfat_node* exfat_readdir(struct exfat_iterator* it); +int exfat_lookup(struct exfat* ef, struct exfat_node** node, + const char* path); +int exfat_split(struct exfat* ef, struct exfat_node** parent, + struct exfat_node** node, le16_t* name, const char* path); + +off_t exfat_c2o(const struct exfat* ef, cluster_t cluster); +cluster_t exfat_next_cluster(const struct exfat* ef, + const struct exfat_node* node, cluster_t cluster); +cluster_t exfat_advance_cluster(const struct exfat* ef, + struct exfat_node* node, uint32_t count); +int exfat_flush_nodes(struct exfat* ef); +int exfat_flush(struct exfat* ef); +int exfat_truncate(struct exfat* ef, struct exfat_node* node, uint64_t size, + bool erase); +uint32_t exfat_count_free_clusters(const struct exfat* ef); +int exfat_find_used_sectors(const struct exfat* ef, off_t* a, off_t* b); + +void exfat_stat(const struct exfat* ef, const struct exfat_node* node, + struct stat* stbuf); +void exfat_get_name(const struct exfat_node* node, + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]); +uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry); +uint16_t exfat_add_checksum(const void* entry, uint16_t sum); +le16_t exfat_calc_checksum(const struct exfat_entry* entries, int n); +uint32_t exfat_vbr_start_checksum(const void* sector, size_t size); +uint32_t exfat_vbr_add_checksum(const void* sector, size_t size, uint32_t sum); +le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name, + size_t length); +void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb); +void exfat_print_info(const struct exfat_super_block* sb, + uint32_t free_clusters); + +int utf16_to_utf8(char* output, const le16_t* input, size_t outsize, + size_t insize); +int utf8_to_utf16(le16_t* output, const char* input, size_t outsize, + size_t insize); +size_t utf16_length(const le16_t* str); + +struct exfat_node* exfat_get_node(struct exfat_node* node); +void exfat_put_node(struct exfat* ef, struct exfat_node* node); +int exfat_cleanup_node(struct exfat* ef, struct exfat_node* node); +int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir); +void exfat_reset_cache(struct exfat* ef); +int exfat_flush_node(struct exfat* ef, struct exfat_node* node); +int exfat_unlink(struct exfat* ef, struct exfat_node* node); +int exfat_rmdir(struct exfat* ef, struct exfat_node* node); +int exfat_mknod(struct exfat* ef, const char* path); +int exfat_mkdir(struct exfat* ef, const char* path); +int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path); +void exfat_utimes(struct exfat_node* node, const struct timespec tv[2]); +void exfat_update_atime(struct exfat_node* node); +void exfat_update_mtime(struct exfat_node* node); +const char* exfat_get_label(struct exfat* ef); +int exfat_set_label(struct exfat* ef, const char* label); + +int exfat_mount(struct exfat* ef, const char* spec, const char* options); +void exfat_unmount(struct exfat* ef); + +time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec); +void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time, + uint8_t* centisec); +void exfat_tzset(void); + +bool exfat_ask_to_fix(const struct exfat* ef); +bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector, + uint32_t vbr_checksum); +bool exfat_fix_invalid_node_checksum(const struct exfat* ef, + struct exfat_node* node); +bool exfat_fix_unknown_entry(struct exfat* ef, struct exfat_node* dir, + const struct exfat_entry* entry, off_t offset); + +#endif /* ifndef EXFAT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h new file mode 100644 index 00000000..b7b6cac5 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h @@ -0,0 +1,180 @@ +/* + exfatfs.h (29.08.09) + Definitions of structures and constants used in exFAT file system. + + 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 EXFATFS_H_INCLUDED +#define EXFATFS_H_INCLUDED + +#include "byteorder.h" +#include "compiler.h" + +typedef uint32_t cluster_t; /* cluster number */ + +#define EXFAT_FIRST_DATA_CLUSTER 2 +#define EXFAT_LAST_DATA_CLUSTER 0xfffffff6 + +#define EXFAT_CLUSTER_FREE 0 /* free cluster */ +#define EXFAT_CLUSTER_BAD 0xfffffff7 /* cluster contains bad sector */ +#define EXFAT_CLUSTER_END 0xffffffff /* final cluster of file or directory */ + +#define EXFAT_STATE_MOUNTED 2 + +struct exfat_super_block +{ + uint8_t jump[3]; /* 0x00 jmp and nop instructions */ + uint8_t oem_name[8]; /* 0x03 "EXFAT " */ + uint8_t __unused1[53]; /* 0x0B always 0 */ + le64_t sector_start; /* 0x40 partition first sector */ + le64_t sector_count; /* 0x48 partition sectors count */ + le32_t fat_sector_start; /* 0x50 FAT first sector */ + le32_t fat_sector_count; /* 0x54 FAT sectors count */ + le32_t cluster_sector_start; /* 0x58 first cluster sector */ + le32_t cluster_count; /* 0x5C total clusters count */ + le32_t rootdir_cluster; /* 0x60 first cluster of the root dir */ + le32_t volume_serial; /* 0x64 volume serial number */ + struct /* 0x68 FS version */ + { + uint8_t minor; + uint8_t major; + } + version; + le16_t volume_state; /* 0x6A volume state flags */ + uint8_t sector_bits; /* 0x6C sector size as (1 << n) */ + uint8_t spc_bits; /* 0x6D sectors per cluster as (1 << n) */ + uint8_t fat_count; /* 0x6E always 1 */ + uint8_t drive_no; /* 0x6F always 0x80 */ + uint8_t allocated_percent; /* 0x70 percentage of allocated space */ + uint8_t __unused2[397]; /* 0x71 always 0 */ + le16_t boot_signature; /* the value of 0xAA55 */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_super_block) == 512); + +#define EXFAT_ENTRY_VALID 0x80 +#define EXFAT_ENTRY_CONTINUED 0x40 +#define EXFAT_ENTRY_OPTIONAL 0x20 + +#define EXFAT_ENTRY_BITMAP (0x01 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_UPCASE (0x02 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_LABEL (0x03 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_FILE (0x05 | EXFAT_ENTRY_VALID) +#define EXFAT_ENTRY_FILE_INFO (0x00 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED) +#define EXFAT_ENTRY_FILE_NAME (0x01 | EXFAT_ENTRY_VALID | EXFAT_ENTRY_CONTINUED) +#define EXFAT_ENTRY_FILE_TAIL (0x00 | EXFAT_ENTRY_VALID \ + | EXFAT_ENTRY_CONTINUED \ + | EXFAT_ENTRY_OPTIONAL) + +struct exfat_entry /* common container for all entries */ +{ + uint8_t type; /* any of EXFAT_ENTRY_xxx */ + uint8_t data[31]; +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry) == 32); + +#define EXFAT_ENAME_MAX 15 + +struct exfat_entry_bitmap /* allocated clusters bitmap */ +{ + uint8_t type; /* EXFAT_ENTRY_BITMAP */ + uint8_t __unknown1[19]; + le32_t start_cluster; + le64_t size; /* in bytes */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_bitmap) == 32); + +#define EXFAT_UPCASE_CHARS 0x10000 + +struct exfat_entry_upcase /* upper case translation table */ +{ + uint8_t type; /* EXFAT_ENTRY_UPCASE */ + uint8_t __unknown1[3]; + le32_t checksum; + uint8_t __unknown2[12]; + le32_t start_cluster; + le64_t size; /* in bytes */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_upcase) == 32); + +struct exfat_entry_label /* volume label */ +{ + uint8_t type; /* EXFAT_ENTRY_LABEL */ + uint8_t length; /* number of characters */ + le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_label) == 32); + +#define EXFAT_ATTRIB_RO 0x01 +#define EXFAT_ATTRIB_HIDDEN 0x02 +#define EXFAT_ATTRIB_SYSTEM 0x04 +#define EXFAT_ATTRIB_VOLUME 0x08 +#define EXFAT_ATTRIB_DIR 0x10 +#define EXFAT_ATTRIB_ARCH 0x20 + +struct exfat_entry_meta1 /* file or directory info (part 1) */ +{ + uint8_t type; /* EXFAT_ENTRY_FILE */ + uint8_t continuations; + le16_t checksum; + le16_t attrib; /* combination of EXFAT_ATTRIB_xxx */ + le16_t __unknown1; + le16_t crtime, crdate; /* creation date and time */ + le16_t mtime, mdate; /* latest modification date and time */ + le16_t atime, adate; /* latest access date and time */ + uint8_t crtime_cs; /* creation time in cs (centiseconds) */ + uint8_t mtime_cs; /* latest modification time in cs */ + uint8_t __unknown2[10]; +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_meta1) == 32); + +#define EXFAT_FLAG_ALWAYS1 (1u << 0) +#define EXFAT_FLAG_CONTIGUOUS (1u << 1) + +struct exfat_entry_meta2 /* file or directory info (part 2) */ +{ + uint8_t type; /* EXFAT_ENTRY_FILE_INFO */ + uint8_t flags; /* combination of EXFAT_FLAG_xxx */ + uint8_t __unknown1; + uint8_t name_length; + le16_t name_hash; + le16_t __unknown2; + le64_t valid_size; /* in bytes, less or equal to size */ + uint8_t __unknown3[4]; + le32_t start_cluster; + le64_t size; /* in bytes */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_meta2) == 32); + +struct exfat_entry_name /* file or directory name */ +{ + uint8_t type; /* EXFAT_ENTRY_FILE_NAME */ + uint8_t __unknown; + le16_t name[EXFAT_ENAME_MAX]; /* in UTF-16LE */ +} +PACKED; +STATIC_ASSERT(sizeof(struct exfat_entry_name) == 32); + +#endif /* ifndef EXFATFS_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c new file mode 100644 index 00000000..4dee5365 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c @@ -0,0 +1,511 @@ +/* + io.c (02.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 +#include +#include +#include +#include +#include +#include +#if defined(__APPLE__) +#include +#elif defined(__OpenBSD__) +#include +#include +#include +#include +#elif __linux__ +#include +#endif +#ifdef USE_UBLIO +#include +#include +#endif + +struct exfat_dev +{ + int fd; + enum exfat_mode mode; + off_t size; /* in bytes */ +#ifdef USE_UBLIO + off_t pos; + ublio_filehandle_t ufh; +#endif +}; + +int g_vtoy_exfat_disk_fd = -1; +uint64_t g_vtoy_exfat_part_size = 0; + +static bool is_open(int fd) +{ + return fcntl(fd, F_GETFD) != -1; +} + +static int open_ro(const char* spec) +{ + return open(spec, O_RDONLY); +} + +static int open_rw(const char* spec) +{ + int fd = open(spec, O_RDWR); +#ifdef __linux__ + int ro = 0; + + /* + This ioctl is needed because after "blockdev --setro" kernel still + allows to open the device in read-write mode but fails writes. + */ + if (fd != -1 && ioctl(fd, BLKROGET, &ro) == 0 && ro) + { + close(fd); + errno = EROFS; + return -1; + } +#endif + return fd; +} + +struct exfat_dev* exfat_open(const char* spec, enum exfat_mode mode) +{ + struct exfat_dev* dev; + struct stat stbuf; +#ifdef USE_UBLIO + struct ublio_param up; +#endif + + /* The system allocates file descriptors sequentially. If we have been + started with stdin (0), stdout (1) or stderr (2) closed, the system + will give us descriptor 0, 1 or 2 later when we open block device, + FUSE communication pipe, etc. As a result, functions using stdin, + stdout or stderr will actually work with a different thing and can + corrupt it. Protect descriptors 0, 1 and 2 from such misuse. */ + while (!is_open(STDIN_FILENO) + || !is_open(STDOUT_FILENO) + || !is_open(STDERR_FILENO)) + { + /* we don't need those descriptors, let them leak */ + if (open("/dev/null", O_RDWR) == -1) + { + exfat_error("failed to open /dev/null"); + return NULL; + } + } + + dev = malloc(sizeof(struct exfat_dev)); + if (dev == NULL) + { + exfat_error("failed to allocate memory for device structure"); + return NULL; + } + + switch (mode) + { + case EXFAT_MODE_RO: + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_ro(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd == -1) + { + free(dev); + exfat_error("failed to open '%s' in read-only mode: %s", spec, + strerror(errno)); + return NULL; + } + dev->mode = EXFAT_MODE_RO; + break; + case EXFAT_MODE_RW: + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_rw(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd == -1) + { + free(dev); + exfat_error("failed to open '%s' in read-write mode: %s", spec, + strerror(errno)); + return NULL; + } + dev->mode = EXFAT_MODE_RW; + break; + case EXFAT_MODE_ANY: + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_rw(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd != -1) + { + dev->mode = EXFAT_MODE_RW; + break; + } + dev->fd = g_vtoy_exfat_disk_fd < 0 ? open_ro(spec) : g_vtoy_exfat_disk_fd; + if (dev->fd != -1) + { + dev->mode = EXFAT_MODE_RO; + exfat_warn("'%s' is write-protected, mounting read-only", spec); + break; + } + free(dev); + exfat_error("failed to open '%s': %s", spec, strerror(errno)); + return NULL; + } + + if (fstat(dev->fd, &stbuf) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to fstat '%s'", spec); + return NULL; + } + if (!S_ISBLK(stbuf.st_mode) && + !S_ISCHR(stbuf.st_mode) && + !S_ISREG(stbuf.st_mode)) + { + close(dev->fd); + free(dev); + exfat_error("'%s' is neither a device, nor a regular file", spec); + return NULL; + } + +#if defined(__APPLE__) + if (!S_ISREG(stbuf.st_mode)) + { + uint32_t block_size = 0; + uint64_t blocks = 0; + + if (ioctl(dev->fd, DKIOCGETBLOCKSIZE, &block_size) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get block size"); + return NULL; + } + if (ioctl(dev->fd, DKIOCGETBLOCKCOUNT, &blocks) != 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get blocks count"); + return NULL; + } + dev->size = blocks * block_size; + } + else +#elif defined(__OpenBSD__) + if (!S_ISREG(stbuf.st_mode)) + { + struct disklabel lab; + struct partition* pp; + char* partition; + + if (ioctl(dev->fd, DIOCGDINFO, &lab) == -1) + { + close(dev->fd); + free(dev); + exfat_error("failed to get disklabel"); + return NULL; + } + + /* Don't need to check that partition letter is valid as we won't get + this far otherwise. */ + partition = strchr(spec, '\0') - 1; + pp = &(lab.d_partitions[*partition - 'a']); + dev->size = DL_GETPSIZE(pp) * lab.d_secsize; + + if (pp->p_fstype != FS_NTFS) + exfat_warn("partition type is not 0x07 (NTFS/exFAT); " + "you can fix this with fdisk(8)"); + } + else +#endif + { + /* works for Linux, FreeBSD, Solaris */ + dev->size = exfat_seek(dev, 0, SEEK_END); + if (dev->size <= 0) + { + close(dev->fd); + free(dev); + exfat_error("failed to get size of '%s'", spec); + return NULL; + } + if (exfat_seek(dev, 0, SEEK_SET) == -1) + { + close(dev->fd); + free(dev); + exfat_error("failed to seek to the beginning of '%s'", spec); + return NULL; + } + } + +#ifdef USE_UBLIO + memset(&up, 0, sizeof(struct ublio_param)); + up.up_blocksize = 256 * 1024; + up.up_items = 64; + up.up_grace = 32; + up.up_priv = &dev->fd; + + dev->pos = 0; + dev->ufh = ublio_open(&up); + if (dev->ufh == NULL) + { + close(dev->fd); + free(dev); + exfat_error("failed to initialize ublio"); + return NULL; + } +#endif + + return dev; +} + +int exfat_close(struct exfat_dev* dev) +{ + int rc = 0; + +#ifdef USE_UBLIO + if (ublio_close(dev->ufh) != 0) + { + exfat_error("failed to close ublio"); + rc = -EIO; + } +#endif + if (dev->fd != g_vtoy_exfat_disk_fd) + { + if (close(dev->fd) != 0) + { + exfat_error("failed to close device: %s", strerror(errno)); + rc = -EIO; + } + } + + free(dev); + return rc; +} + +int exfat_fsync(struct exfat_dev* dev) +{ + int rc = 0; + +#ifdef USE_UBLIO + if (ublio_fsync(dev->ufh) != 0) + { + exfat_error("ublio fsync failed"); + rc = -EIO; + } +#endif + if (fsync(dev->fd) != 0) + { + exfat_error("fsync failed: %s", strerror(errno)); + rc = -EIO; + } + return rc; +} + +enum exfat_mode exfat_get_mode(const struct exfat_dev* dev) +{ + return dev->mode; +} + + +off_t exfat_get_size(const struct exfat_dev* dev) +{ + return dev->size; +} + +off_t exfat_seek(struct exfat_dev* dev, off_t offset, int whence) +{ +#ifdef USE_UBLIO + /* XXX SEEK_CUR will be handled incorrectly */ + return dev->pos = lseek(dev->fd, offset, whence); +#else + + if (SEEK_SET == whence) + { + if (offset > g_vtoy_exfat_part_size) + { + return -1; + } + + lseek(dev->fd, 512 * 2048 + offset, SEEK_SET); + return offset; + } + else if (SEEK_END == whence) + { + if (offset == 0) + { + offset = 512 * 2048 + g_vtoy_exfat_part_size; + lseek(dev->fd, offset, SEEK_SET); + return (off_t)g_vtoy_exfat_part_size; + } + else + { + exfat_error("Invalid SEEK_END offset %llu", (unsigned long long)offset); + return -1; + } + } + else + { + exfat_error("Invalid seek whence %d", whence); + return lseek(dev->fd, offset, whence); + } +#endif +} + +ssize_t exfat_read(struct exfat_dev* dev, void* buffer, size_t size) +{ +#ifdef USE_UBLIO + ssize_t result = ublio_pread(dev->ufh, buffer, size, dev->pos); + if (result >= 0) + dev->pos += size; + return result; +#else + return read(dev->fd, buffer, size); +#endif +} + +ssize_t exfat_write(struct exfat_dev* dev, const void* buffer, size_t size) +{ +#ifdef USE_UBLIO + ssize_t result = ublio_pwrite(dev->ufh, buffer, size, dev->pos); + if (result >= 0) + dev->pos += size; + return result; +#else + return write(dev->fd, buffer, size); +#endif +} + +ssize_t exfat_pread(struct exfat_dev* dev, void* buffer, size_t size, + off_t offset) +{ +#ifdef USE_UBLIO + return ublio_pread(dev->ufh, buffer, size, offset); +#else + return pread(dev->fd, buffer, size, offset); +#endif +} + +ssize_t exfat_pwrite(struct exfat_dev* dev, const void* buffer, size_t size, + off_t offset) +{ +#ifdef USE_UBLIO + return ublio_pwrite(dev->ufh, buffer, size, offset); +#else + return pwrite(dev->fd, buffer, size, offset); +#endif +} + +ssize_t exfat_generic_pread(const struct exfat* ef, struct exfat_node* node, + void* buffer, size_t size, off_t offset) +{ + cluster_t cluster; + char* bufp = buffer; + off_t lsize, loffset, remainder; + + if (offset >= node->size) + return 0; + if (size == 0) + return 0; + + cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb)); + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while reading", cluster); + return -EIO; + } + + loffset = offset % CLUSTER_SIZE(*ef->sb); + remainder = MIN(size, node->size - offset); + while (remainder > 0) + { + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while reading", cluster); + return -EIO; + } + lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder); + if (exfat_pread(ef->dev, bufp, lsize, + exfat_c2o(ef, cluster) + loffset) < 0) + { + exfat_error("failed to read cluster %#x", cluster); + return -EIO; + } + bufp += lsize; + loffset = 0; + remainder -= lsize; + cluster = exfat_next_cluster(ef, node, cluster); + } + if (!(node->attrib & EXFAT_ATTRIB_DIR) && !ef->ro && !ef->noatime) + exfat_update_atime(node); + return MIN(size, node->size - offset) - remainder; +} + +ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, + const void* buffer, size_t size, off_t offset) +{ + int rc; + cluster_t cluster; + const char* bufp = buffer; + off_t lsize, loffset, remainder; + + if (offset > node->size) + { + rc = exfat_truncate(ef, node, offset, true); + if (rc != 0) + return rc; + } + if (offset + size > node->size) + { + rc = exfat_truncate(ef, node, offset + size, false); + if (rc != 0) + return rc; + } + if (size == 0) + return 0; + + cluster = exfat_advance_cluster(ef, node, offset / CLUSTER_SIZE(*ef->sb)); + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while writing", cluster); + return -EIO; + } + + loffset = offset % CLUSTER_SIZE(*ef->sb); + remainder = size; + while (remainder > 0) + { + if (CLUSTER_INVALID(*ef->sb, cluster)) + { + exfat_error("invalid cluster 0x%x while writing", cluster); + return -EIO; + } + lsize = MIN(CLUSTER_SIZE(*ef->sb) - loffset, remainder); + if (exfat_pwrite(ef->dev, bufp, lsize, + exfat_c2o(ef, cluster) + loffset) < 0) + { + exfat_error("failed to write cluster %#x", cluster); + return -EIO; + } + bufp += lsize; + loffset = 0; + remainder -= lsize; + cluster = exfat_next_cluster(ef, node, cluster); + } + if (!(node->attrib & EXFAT_ATTRIB_DIR)) + /* directory's mtime should be updated by the caller only when it + creates or removes something in this directory */ + exfat_update_mtime(node); + return size - remainder; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c new file mode 100644 index 00000000..8fa8e0f3 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c @@ -0,0 +1,224 @@ +/* + lookup.c (02.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 +#include +#include + +int exfat_opendir(struct exfat* ef, struct exfat_node* dir, + struct exfat_iterator* it) +{ + int rc; + + exfat_get_node(dir); + it->parent = dir; + it->current = NULL; + rc = exfat_cache_directory(ef, dir); + if (rc != 0) + exfat_put_node(ef, dir); + return rc; +} + +void exfat_closedir(struct exfat* ef, struct exfat_iterator* it) +{ + exfat_put_node(ef, it->parent); + it->parent = NULL; + it->current = NULL; +} + +struct exfat_node* exfat_readdir(struct exfat_iterator* it) +{ + if (it->current == NULL) + it->current = it->parent->child; + else + it->current = it->current->next; + + if (it->current != NULL) + return exfat_get_node(it->current); + else + return NULL; +} + +static int compare_char(struct exfat* ef, uint16_t a, uint16_t b) +{ + return (int) ef->upcase[a] - (int) ef->upcase[b]; +} + +static int compare_name(struct exfat* ef, const le16_t* a, const le16_t* b) +{ + while (le16_to_cpu(*a) && le16_to_cpu(*b)) + { + int rc = compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b)); + if (rc != 0) + return rc; + a++; + b++; + } + return compare_char(ef, le16_to_cpu(*a), le16_to_cpu(*b)); +} + +static int lookup_name(struct exfat* ef, struct exfat_node* parent, + struct exfat_node** node, const char* name, size_t n) +{ + struct exfat_iterator it; + le16_t buffer[EXFAT_NAME_MAX + 1]; + int rc; + + *node = NULL; + + rc = utf8_to_utf16(buffer, name, EXFAT_NAME_MAX + 1, n); + if (rc != 0) + return rc; + + rc = exfat_opendir(ef, parent, &it); + if (rc != 0) + return rc; + while ((*node = exfat_readdir(&it))) + { + if (compare_name(ef, buffer, (*node)->name) == 0) + { + exfat_closedir(ef, &it); + return 0; + } + exfat_put_node(ef, *node); + } + exfat_closedir(ef, &it); + return -ENOENT; +} + +static size_t get_comp(const char* path, const char** comp) +{ + const char* end; + + *comp = path + strspn(path, "/"); /* skip leading slashes */ + end = strchr(*comp, '/'); + if (end == NULL) + return strlen(*comp); + else + return end - *comp; +} + +int exfat_lookup(struct exfat* ef, struct exfat_node** node, + const char* path) +{ + struct exfat_node* parent; + const char* p; + size_t n; + int rc; + + /* start from the root directory */ + parent = *node = exfat_get_node(ef->root); + for (p = path; (n = get_comp(p, &p)); p += n) + { + if (n == 1 && *p == '.') /* skip "." component */ + continue; + rc = lookup_name(ef, parent, node, p, n); + if (rc != 0) + { + exfat_put_node(ef, parent); + return rc; + } + exfat_put_node(ef, parent); + parent = *node; + } + return 0; +} + +static bool is_last_comp(const char* comp, size_t length) +{ + const char* p = comp + length; + + return get_comp(p, &p) == 0; +} + +static bool is_allowed(const char* comp, size_t length) +{ + size_t i; + + for (i = 0; i < length; i++) + switch (comp[i]) + { + case 0x01 ... 0x1f: + case '/': + case '\\': + case ':': + case '*': + case '?': + case '"': + case '<': + case '>': + case '|': + return false; + } + return true; +} + +int exfat_split(struct exfat* ef, struct exfat_node** parent, + struct exfat_node** node, le16_t* name, const char* path) +{ + const char* p; + size_t n; + int rc; + + memset(name, 0, (EXFAT_NAME_MAX + 1) * sizeof(le16_t)); + *parent = *node = exfat_get_node(ef->root); + for (p = path; (n = get_comp(p, &p)); p += n) + { + if (n == 1 && *p == '.') + continue; + if (is_last_comp(p, n)) + { + if (!is_allowed(p, n)) + { + /* contains characters that are not allowed */ + exfat_put_node(ef, *parent); + return -ENOENT; + } + rc = utf8_to_utf16(name, p, EXFAT_NAME_MAX + 1, n); + if (rc != 0) + { + exfat_put_node(ef, *parent); + return rc; + } + + rc = lookup_name(ef, *parent, node, p, n); + if (rc != 0 && rc != -ENOENT) + { + exfat_put_node(ef, *parent); + return rc; + } + return 0; + } + rc = lookup_name(ef, *parent, node, p, n); + if (rc != 0) + { + exfat_put_node(ef, *parent); + return rc; + } + exfat_put_node(ef, *parent); + *parent = *node; + } + exfat_bug("impossible"); + + return 1; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c new file mode 100644 index 00000000..4284aee6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c @@ -0,0 +1,389 @@ +/* + mount.c (22.10.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 +#include +#include +#include +#include +#include + +static uint64_t rootdir_size(const struct exfat* ef) +{ + uint32_t clusters = 0; + uint32_t clusters_max = le32_to_cpu(ef->sb->cluster_count); + cluster_t rootdir_cluster = le32_to_cpu(ef->sb->rootdir_cluster); + + /* Iterate all clusters of the root directory to calculate its size. + It can't be contiguous because there is no flag to indicate this. */ + do + { + if (clusters == clusters_max) /* infinite loop detected */ + { + exfat_error("root directory cannot occupy all %d clusters", + clusters); + return 0; + } + if (CLUSTER_INVALID(*ef->sb, rootdir_cluster)) + { + exfat_error("bad cluster %#x while reading root directory", + rootdir_cluster); + return 0; + } + rootdir_cluster = exfat_next_cluster(ef, ef->root, rootdir_cluster); + clusters++; + } + while (rootdir_cluster != EXFAT_CLUSTER_END); + + return (uint64_t) clusters * CLUSTER_SIZE(*ef->sb); +} + +static const char* get_option(const char* options, const char* option_name) +{ + const char* p; + size_t length = strlen(option_name); + + for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name)) + if ((p == options || p[-1] == ',') && p[length] == '=') + return p + length + 1; + return NULL; +} + +static int get_int_option(const char* options, const char* option_name, + int base, int default_value) +{ + const char* p = get_option(options, option_name); + + if (p == NULL) + return default_value; + return strtol(p, NULL, base); +} + +static bool match_option(const char* options, const char* option_name) +{ + const char* p; + size_t length = strlen(option_name); + + for (p = strstr(options, option_name); p; p = strstr(p + 1, option_name)) + if ((p == options || p[-1] == ',') && + (p[length] == ',' || p[length] == '\0')) + return true; + return false; +} + +static void parse_options(struct exfat* ef, const char* options) +{ + int opt_umask; + + opt_umask = get_int_option(options, "umask", 8, 0); + ef->dmask = get_int_option(options, "dmask", 8, opt_umask); + ef->fmask = get_int_option(options, "fmask", 8, opt_umask); + + ef->uid = get_int_option(options, "uid", 10, geteuid()); + ef->gid = get_int_option(options, "gid", 10, getegid()); + + ef->noatime = match_option(options, "noatime"); + + switch (get_int_option(options, "repair", 10, 0)) + { + case 1: + ef->repair = EXFAT_REPAIR_ASK; + break; + case 2: + ef->repair = EXFAT_REPAIR_YES; + break; + default: + ef->repair = EXFAT_REPAIR_NO; + break; + } +} + +static bool verify_vbr_checksum(const struct exfat* ef, void* sector) +{ + off_t sector_size = SECTOR_SIZE(*ef->sb); + uint32_t vbr_checksum; + int i; + + if (exfat_pread(ef->dev, sector, sector_size, 0) < 0) + { + exfat_error("failed to read boot sector"); + return false; + } + vbr_checksum = exfat_vbr_start_checksum(sector, sector_size); + for (i = 1; i < 11; i++) + { + if (exfat_pread(ef->dev, sector, sector_size, i * sector_size) < 0) + { + exfat_error("failed to read VBR sector"); + return false; + } + vbr_checksum = exfat_vbr_add_checksum(sector, sector_size, + vbr_checksum); + } + if (exfat_pread(ef->dev, sector, sector_size, i * sector_size) < 0) + { + exfat_error("failed to read VBR checksum sector"); + return false; + } + for (i = 0; i < sector_size / sizeof(vbr_checksum); i++) + if (le32_to_cpu(((const le32_t*) sector)[i]) != vbr_checksum) + { + exfat_error("invalid VBR checksum 0x%x (expected 0x%x)", + le32_to_cpu(((const le32_t*) sector)[i]), vbr_checksum); + if (!EXFAT_REPAIR(invalid_vbr_checksum, ef, sector, vbr_checksum)) + return false; + } + return true; +} + +static int commit_super_block(const struct exfat* ef) +{ + if (exfat_pwrite(ef->dev, ef->sb, sizeof(struct exfat_super_block), 0) < 0) + { + exfat_error("failed to write super block"); + return 1; + } + return exfat_fsync(ef->dev); +} + +static int prepare_super_block(const struct exfat* ef) +{ + if (le16_to_cpu(ef->sb->volume_state) & EXFAT_STATE_MOUNTED) + exfat_warn("volume was not unmounted cleanly"); + + if (ef->ro) + return 0; + + ef->sb->volume_state = cpu_to_le16( + le16_to_cpu(ef->sb->volume_state) | EXFAT_STATE_MOUNTED); + return commit_super_block(ef); +} + +static void exfat_free(struct exfat* ef) +{ + exfat_close(ef->dev); /* first of all, close the descriptor */ + ef->dev = NULL; /* struct exfat_dev is freed by exfat_close() */ + free(ef->root); + ef->root = NULL; + free(ef->zero_cluster); + ef->zero_cluster = NULL; + free(ef->cmap.chunk); + ef->cmap.chunk = NULL; + free(ef->upcase); + ef->upcase = NULL; + free(ef->sb); + ef->sb = NULL; +} + +int exfat_mount(struct exfat* ef, const char* spec, const char* options) +{ + int rc; + enum exfat_mode mode; + + exfat_tzset(); + memset(ef, 0, sizeof(struct exfat)); + + parse_options(ef, options); + + if (match_option(options, "ro")) + mode = EXFAT_MODE_RO; + else if (match_option(options, "ro_fallback")) + mode = EXFAT_MODE_ANY; + else + mode = EXFAT_MODE_RW; + ef->dev = exfat_open(spec, mode); + if (ef->dev == NULL) + return -EIO; + if (exfat_get_mode(ef->dev) == EXFAT_MODE_RO) + { + if (mode == EXFAT_MODE_ANY) + ef->ro = -1; + else + ef->ro = 1; + } + + ef->sb = malloc(sizeof(struct exfat_super_block)); + if (ef->sb == NULL) + { + exfat_error("failed to allocate memory for the super block"); + exfat_free(ef); + return -ENOMEM; + } + memset(ef->sb, 0, sizeof(struct exfat_super_block)); + + if (exfat_pread(ef->dev, ef->sb, sizeof(struct exfat_super_block), 0) < 0) + { + exfat_error("failed to read boot sector"); + exfat_free(ef); + return -EIO; + } + if (memcmp(ef->sb->oem_name, "EXFAT ", 8) != 0) + { + exfat_error("exFAT file system is not found"); + exfat_free(ef); + return -EIO; + } + /* sector cannot be smaller than 512 bytes */ + if (ef->sb->sector_bits < 9) + { + exfat_error("too small sector size: 2^%hhd", ef->sb->sector_bits); + exfat_free(ef); + return -EIO; + } + /* officially exFAT supports cluster size up to 32 MB */ + if ((int) ef->sb->sector_bits + (int) ef->sb->spc_bits > 25) + { + exfat_error("too big cluster size: 2^(%hhd+%hhd)", + ef->sb->sector_bits, ef->sb->spc_bits); + exfat_free(ef); + return -EIO; + } + ef->zero_cluster = malloc(CLUSTER_SIZE(*ef->sb)); + if (ef->zero_cluster == NULL) + { + exfat_error("failed to allocate zero sector"); + exfat_free(ef); + return -ENOMEM; + } + /* use zero_cluster as a temporary buffer for VBR checksum verification */ + if (!verify_vbr_checksum(ef, ef->zero_cluster)) + { + exfat_free(ef); + return -EIO; + } + memset(ef->zero_cluster, 0, CLUSTER_SIZE(*ef->sb)); + if (ef->sb->version.major != 1 || ef->sb->version.minor != 0) + { + exfat_error("unsupported exFAT version: %hhu.%hhu", + ef->sb->version.major, ef->sb->version.minor); + exfat_free(ef); + return -EIO; + } + if (ef->sb->fat_count != 1) + { + exfat_error("unsupported FAT count: %hhu", ef->sb->fat_count); + exfat_free(ef); + return -EIO; + } + if (le64_to_cpu(ef->sb->sector_count) * SECTOR_SIZE(*ef->sb) > + exfat_get_size(ef->dev)) + { + /* this can cause I/O errors later but we don't fail mounting to let + user rescue data */ + exfat_warn("file system in sectors is larger than device: " + "%"PRIu64" * %d > %"PRIu64, + le64_to_cpu(ef->sb->sector_count), SECTOR_SIZE(*ef->sb), + exfat_get_size(ef->dev)); + } + if ((off_t) le32_to_cpu(ef->sb->cluster_count) * CLUSTER_SIZE(*ef->sb) > + exfat_get_size(ef->dev)) + { + exfat_error("file system in clusters is larger than device: " + "%u * %d > %"PRIu64, + le32_to_cpu(ef->sb->cluster_count), CLUSTER_SIZE(*ef->sb), + exfat_get_size(ef->dev)); + exfat_free(ef); + return -EIO; + } + + ef->root = malloc(sizeof(struct exfat_node)); + if (ef->root == NULL) + { + exfat_error("failed to allocate root node"); + exfat_free(ef); + return -ENOMEM; + } + memset(ef->root, 0, sizeof(struct exfat_node)); + ef->root->attrib = EXFAT_ATTRIB_DIR; + ef->root->start_cluster = le32_to_cpu(ef->sb->rootdir_cluster); + ef->root->fptr_cluster = ef->root->start_cluster; + ef->root->name[0] = cpu_to_le16('\0'); + ef->root->size = rootdir_size(ef); + if (ef->root->size == 0) + { + exfat_free(ef); + return -EIO; + } + /* exFAT does not have time attributes for the root directory */ + ef->root->mtime = 0; + ef->root->atime = 0; + /* always keep at least 1 reference to the root node */ + exfat_get_node(ef->root); + + rc = exfat_cache_directory(ef, ef->root); + if (rc != 0) + goto error; + if (ef->upcase == NULL) + { + exfat_error("upcase table is not found"); + goto error; + } + if (ef->cmap.chunk == NULL) + { + exfat_error("clusters bitmap is not found"); + goto error; + } + + if (prepare_super_block(ef) != 0) + goto error; + + return 0; + +error: + exfat_put_node(ef, ef->root); + exfat_reset_cache(ef); + exfat_free(ef); + return -EIO; +} + +static void finalize_super_block(struct exfat* ef) +{ + if (ef->ro) + return; + + ef->sb->volume_state = cpu_to_le16( + le16_to_cpu(ef->sb->volume_state) & ~EXFAT_STATE_MOUNTED); + + /* Some implementations set the percentage of allocated space to 0xff + on FS creation and never update it. In this case leave it as is. */ + if (ef->sb->allocated_percent != 0xff) + { + uint32_t free, total; + + free = exfat_count_free_clusters(ef); + total = le32_to_cpu(ef->sb->cluster_count); + ef->sb->allocated_percent = ((total - free) * 100 + total / 2) / total; + } + + commit_super_block(ef); /* ignore return code */ +} + +void exfat_unmount(struct exfat* ef) +{ + exfat_flush_nodes(ef); /* ignore return code */ + exfat_flush(ef); /* ignore return code */ + exfat_put_node(ef, ef->root); + exfat_reset_cache(ef); + finalize_super_block(ef); + exfat_free(ef); /* will close the descriptor */ +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c new file mode 100644 index 00000000..ab1d7d6d --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c @@ -0,0 +1,1226 @@ +/* + node.c (09.10.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 +#include +#include + +#define EXFAT_ENTRY_NONE (-1) + +struct exfat_node* exfat_get_node(struct exfat_node* node) +{ + /* if we switch to multi-threaded mode we will need atomic + increment here and atomic decrement in exfat_put_node() */ + node->references++; + return node; +} + +void exfat_put_node(struct exfat* ef, struct exfat_node* node) +{ + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]; + + --node->references; + if (node->references < 0) + { + exfat_get_name(node, buffer); + exfat_bug("reference counter of '%s' is below zero", buffer); + } + else if (node->references == 0 && node != ef->root) + { + if (node->is_dirty) + { + exfat_get_name(node, buffer); + exfat_warn("dirty node '%s' with zero references", buffer); + } + } +} + +/** + * This function must be called on rmdir and unlink (after the last + * exfat_put_node()) to free clusters. + */ +int exfat_cleanup_node(struct exfat* ef, struct exfat_node* node) +{ + int rc = 0; + + if (node->references != 0) + exfat_bug("unable to cleanup a node with %d references", + node->references); + + if (node->is_unlinked) + { + /* free all clusters and node structure itself */ + rc = exfat_truncate(ef, node, 0, true); + /* free the node even in case of error or its memory will be lost */ + free(node); + } + return rc; +} + +static int read_entries(struct exfat* ef, struct exfat_node* dir, + struct exfat_entry* entries, int n, off_t offset) +{ + ssize_t size; + + if (!(dir->attrib & EXFAT_ATTRIB_DIR)) + exfat_bug("attempted to read entries from a file"); + + size = exfat_generic_pread(ef, dir, entries, + sizeof(struct exfat_entry[n]), offset); + if (size == sizeof(struct exfat_entry[n])) + return 0; /* success */ + if (size == 0) + return -ENOENT; + if (size < 0) + return -EIO; + exfat_error("read %zd bytes instead of %zu bytes", size, + sizeof(struct exfat_entry[n])); + return -EIO; +} + +static int write_entries(struct exfat* ef, struct exfat_node* dir, + const struct exfat_entry* entries, int n, off_t offset) +{ + ssize_t size; + + if (!(dir->attrib & EXFAT_ATTRIB_DIR)) + exfat_bug("attempted to write entries into a file"); + + size = exfat_generic_pwrite(ef, dir, entries, + sizeof(struct exfat_entry[n]), offset); + if (size == sizeof(struct exfat_entry[n])) + return 0; /* success */ + if (size < 0) + return -EIO; + exfat_error("wrote %zd bytes instead of %zu bytes", size, + sizeof(struct exfat_entry[n])); + return -EIO; +} + +static struct exfat_node* allocate_node(void) +{ + struct exfat_node* node = malloc(sizeof(struct exfat_node)); + if (node == NULL) + { + exfat_error("failed to allocate node"); + return NULL; + } + memset(node, 0, sizeof(struct exfat_node)); + return node; +} + +static void init_node_meta1(struct exfat_node* node, + const struct exfat_entry_meta1* meta1) +{ + node->attrib = le16_to_cpu(meta1->attrib); + node->continuations = meta1->continuations; + node->mtime = exfat_exfat2unix(meta1->mdate, meta1->mtime, + meta1->mtime_cs); + /* there is no centiseconds field for atime */ + node->atime = exfat_exfat2unix(meta1->adate, meta1->atime, 0); +} + +static void init_node_meta2(struct exfat_node* node, + const struct exfat_entry_meta2* meta2) +{ + node->size = le64_to_cpu(meta2->size); + node->start_cluster = le32_to_cpu(meta2->start_cluster); + node->fptr_cluster = node->start_cluster; + node->is_contiguous = ((meta2->flags & EXFAT_FLAG_CONTIGUOUS) != 0); +} + +static void init_node_name(struct exfat_node* node, + const struct exfat_entry* entries, int n) +{ + int i; + + for (i = 0; i < n; i++) + memcpy(node->name + i * EXFAT_ENAME_MAX, + ((const struct exfat_entry_name*) &entries[i])->name, + EXFAT_ENAME_MAX * sizeof(le16_t)); +} + +static bool check_entries(const struct exfat_entry* entry, int n) +{ + int previous = EXFAT_ENTRY_NONE; + int current; + int i; + + /* check transitions between entries types */ + for (i = 0; i < n + 1; previous = current, i++) + { + bool valid = false; + + current = (i < n) ? entry[i].type : EXFAT_ENTRY_NONE; + switch (previous) + { + case EXFAT_ENTRY_NONE: + valid = (current == EXFAT_ENTRY_FILE); + break; + case EXFAT_ENTRY_FILE: + valid = (current == EXFAT_ENTRY_FILE_INFO); + break; + case EXFAT_ENTRY_FILE_INFO: + valid = (current == EXFAT_ENTRY_FILE_NAME); + break; + case EXFAT_ENTRY_FILE_NAME: + valid = (current == EXFAT_ENTRY_FILE_NAME || + current == EXFAT_ENTRY_NONE || + current >= EXFAT_ENTRY_FILE_TAIL); + break; + case EXFAT_ENTRY_FILE_TAIL ... 0xff: + valid = (current >= EXFAT_ENTRY_FILE_TAIL || + current == EXFAT_ENTRY_NONE); + break; + } + + if (!valid) + { + exfat_error("unexpected entry type %#x after %#x at %d/%d", + current, previous, i, n); + return false; + } + } + return true; +} + +static bool check_node(const struct exfat* ef, struct exfat_node* node, + le16_t actual_checksum, const struct exfat_entry_meta1* meta1, + const struct exfat_entry_meta2* meta2) +{ + int cluster_size = CLUSTER_SIZE(*ef->sb); + uint64_t clusters_heap_size = + (uint64_t) le32_to_cpu(ef->sb->cluster_count) * cluster_size; + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]; + bool ret = true; + + /* + Validate checksum first. If it's invalid all other fields probably + contain just garbage. + */ + if (le16_to_cpu(actual_checksum) != le16_to_cpu(meta1->checksum)) + { + exfat_get_name(node, buffer); + exfat_error("'%s' has invalid checksum (%#hx != %#hx)", buffer, + le16_to_cpu(actual_checksum), le16_to_cpu(meta1->checksum)); + if (!EXFAT_REPAIR(invalid_node_checksum, ef, node)) + ret = false; + } + + /* + exFAT does not support sparse files but allows files with uninitialized + clusters. For such files valid_size means initialized data size and + cannot be greater than file size. See SetFileValidData() function + description in MSDN. + */ + if (le64_to_cpu(meta2->valid_size) > node->size) + { + exfat_get_name(node, buffer); + exfat_error("'%s' has valid size (%"PRIu64") greater than size " + "(%"PRIu64")", buffer, le64_to_cpu(meta2->valid_size), + node->size); + ret = false; + } + + /* + Empty file must have zero start cluster. Non-empty file must start + with a valid cluster. Directories cannot be empty (i.e. must always + have a valid start cluster), but we will check this later while + reading that directory to give user a chance to read this directory. + */ + if (node->size == 0 && node->start_cluster != EXFAT_CLUSTER_FREE) + { + exfat_get_name(node, buffer); + exfat_error("'%s' is empty but start cluster is %#x", buffer, + node->start_cluster); + ret = false; + } + if (node->size > 0 && CLUSTER_INVALID(*ef->sb, node->start_cluster)) + { + exfat_get_name(node, buffer); + exfat_error("'%s' points to invalid cluster %#x", buffer, + node->start_cluster); + ret = false; + } + + /* File or directory cannot be larger than clusters heap. */ + if (node->size > clusters_heap_size) + { + exfat_get_name(node, buffer); + exfat_error("'%s' is larger than clusters heap: %"PRIu64" > %"PRIu64, + buffer, node->size, clusters_heap_size); + ret = false; + } + + /* Empty file or directory must be marked as non-contiguous. */ + if (node->size == 0 && node->is_contiguous) + { + exfat_get_name(node, buffer); + exfat_error("'%s' is empty but marked as contiguous (%#hx)", buffer, + node->attrib); + ret = false; + } + + /* Directory size must be aligned on at cluster boundary. */ + if ((node->attrib & EXFAT_ATTRIB_DIR) && node->size % cluster_size != 0) + { + exfat_get_name(node, buffer); + exfat_error("'%s' directory size %"PRIu64" is not divisible by %d", buffer, + node->size, cluster_size); + ret = false; + } + + return ret; +} + +static int parse_file_entries(struct exfat* ef, struct exfat_node* node, + const struct exfat_entry* entries, int n) +{ + const struct exfat_entry_meta1* meta1; + const struct exfat_entry_meta2* meta2; + int mandatory_entries; + + if (!check_entries(entries, n)) + return -EIO; + + meta1 = (const struct exfat_entry_meta1*) &entries[0]; + if (meta1->continuations < 2) + { + exfat_error("too few continuations (%hhu)", meta1->continuations); + return -EIO; + } + meta2 = (const struct exfat_entry_meta2*) &entries[1]; + if (meta2->flags & ~(EXFAT_FLAG_ALWAYS1 | EXFAT_FLAG_CONTIGUOUS)) + { + exfat_error("unknown flags in meta2 (%#hhx)", meta2->flags); + return -EIO; + } + mandatory_entries = 2 + DIV_ROUND_UP(meta2->name_length, EXFAT_ENAME_MAX); + if (meta1->continuations < mandatory_entries - 1) + { + exfat_error("too few continuations (%hhu < %d)", + meta1->continuations, mandatory_entries - 1); + return -EIO; + } + + init_node_meta1(node, meta1); + init_node_meta2(node, meta2); + init_node_name(node, entries + 2, mandatory_entries - 2); + + if (!check_node(ef, node, exfat_calc_checksum(entries, n), meta1, meta2)) + return -EIO; + + return 0; +} + +static int parse_file_entry(struct exfat* ef, struct exfat_node* parent, + struct exfat_node** node, off_t* offset, int n) +{ + struct exfat_entry entries[n]; + int rc; + + rc = read_entries(ef, parent, entries, n, *offset); + if (rc != 0) + return rc; + + /* a new node has zero references */ + *node = allocate_node(); + if (*node == NULL) + return -ENOMEM; + (*node)->entry_offset = *offset; + + rc = parse_file_entries(ef, *node, entries, n); + if (rc != 0) + { + free(*node); + return rc; + } + + *offset += sizeof(struct exfat_entry[n]); + return 0; +} + +static void decompress_upcase(uint16_t* output, const le16_t* source, + size_t size) +{ + size_t si; + size_t oi; + + for (oi = 0; oi < EXFAT_UPCASE_CHARS; oi++) + output[oi] = oi; + + for (si = 0, oi = 0; si < size && oi < EXFAT_UPCASE_CHARS; si++) + { + uint16_t ch = le16_to_cpu(source[si]); + + if (ch == 0xffff && si + 1 < size) /* indicates a run */ + oi += le16_to_cpu(source[++si]); + else + output[oi++] = ch; + } +} + +/* + * Read one entry in a directory at offset position and build a new node + * structure. + */ +static int readdir(struct exfat* ef, struct exfat_node* parent, + struct exfat_node** node, off_t* offset) +{ + int rc; + struct exfat_entry entry; + const struct exfat_entry_meta1* meta1; + const struct exfat_entry_upcase* upcase; + const struct exfat_entry_bitmap* bitmap; + const struct exfat_entry_label* label; + uint64_t upcase_size = 0; + le16_t* upcase_comp = NULL; + + for (;;) + { + rc = read_entries(ef, parent, &entry, 1, *offset); + if (rc != 0) + return rc; + + switch (entry.type) + { + case EXFAT_ENTRY_FILE: + meta1 = (const struct exfat_entry_meta1*) &entry; + return parse_file_entry(ef, parent, node, offset, + 1 + meta1->continuations); + + case EXFAT_ENTRY_UPCASE: + if (ef->upcase != NULL) + break; + upcase = (const struct exfat_entry_upcase*) &entry; + if (CLUSTER_INVALID(*ef->sb, le32_to_cpu(upcase->start_cluster))) + { + exfat_error("invalid cluster 0x%x in upcase table", + le32_to_cpu(upcase->start_cluster)); + return -EIO; + } + upcase_size = le64_to_cpu(upcase->size); + if (upcase_size == 0 || + upcase_size > EXFAT_UPCASE_CHARS * sizeof(uint16_t) || + upcase_size % sizeof(uint16_t) != 0) + { + exfat_error("bad upcase table size (%"PRIu64" bytes)", + upcase_size); + return -EIO; + } + upcase_comp = malloc(upcase_size); + if (upcase_comp == NULL) + { + exfat_error("failed to allocate upcase table (%"PRIu64" bytes)", + upcase_size); + return -ENOMEM; + } + + /* read compressed upcase table */ + if (exfat_pread(ef->dev, upcase_comp, upcase_size, + exfat_c2o(ef, le32_to_cpu(upcase->start_cluster))) < 0) + { + free(upcase_comp); + exfat_error("failed to read upper case table " + "(%"PRIu64" bytes starting at cluster %#x)", + upcase_size, + le32_to_cpu(upcase->start_cluster)); + return -EIO; + } + + /* decompress upcase table */ + ef->upcase = calloc(EXFAT_UPCASE_CHARS, sizeof(uint16_t)); + if (ef->upcase == NULL) + { + free(upcase_comp); + exfat_error("failed to allocate decompressed upcase table"); + return -ENOMEM; + } + decompress_upcase(ef->upcase, upcase_comp, + upcase_size / sizeof(uint16_t)); + free(upcase_comp); + break; + + case EXFAT_ENTRY_BITMAP: + bitmap = (const struct exfat_entry_bitmap*) &entry; + ef->cmap.start_cluster = le32_to_cpu(bitmap->start_cluster); + if (CLUSTER_INVALID(*ef->sb, ef->cmap.start_cluster)) + { + exfat_error("invalid cluster 0x%x in clusters bitmap", + ef->cmap.start_cluster); + return -EIO; + } + ef->cmap.size = le32_to_cpu(ef->sb->cluster_count); + if (le64_to_cpu(bitmap->size) < DIV_ROUND_UP(ef->cmap.size, 8)) + { + exfat_error("invalid clusters bitmap size: %"PRIu64 + " (expected at least %u)", + le64_to_cpu(bitmap->size), + DIV_ROUND_UP(ef->cmap.size, 8)); + return -EIO; + } + /* FIXME bitmap can be rather big, up to 512 MB */ + ef->cmap.chunk_size = ef->cmap.size; + ef->cmap.chunk = malloc(BMAP_SIZE(ef->cmap.chunk_size)); + if (ef->cmap.chunk == NULL) + { + exfat_error("failed to allocate clusters bitmap chunk " + "(%"PRIu64" bytes)", le64_to_cpu(bitmap->size)); + return -ENOMEM; + } + + if (exfat_pread(ef->dev, ef->cmap.chunk, + BMAP_SIZE(ef->cmap.chunk_size), + exfat_c2o(ef, ef->cmap.start_cluster)) < 0) + { + exfat_error("failed to read clusters bitmap " + "(%"PRIu64" bytes starting at cluster %#x)", + le64_to_cpu(bitmap->size), ef->cmap.start_cluster); + return -EIO; + } + break; + + case EXFAT_ENTRY_LABEL: + label = (const struct exfat_entry_label*) &entry; + if (label->length > EXFAT_ENAME_MAX) + { + exfat_error("too long label (%hhu chars)", label->length); + return -EIO; + } + if (utf16_to_utf8(ef->label, label->name, + sizeof(ef->label), EXFAT_ENAME_MAX) != 0) + return -EIO; + break; + + default: + if (!(entry.type & EXFAT_ENTRY_VALID)) + break; /* deleted entry, ignore it */ + + exfat_error("unknown entry type %#hhx", entry.type); + if (!EXFAT_REPAIR(unknown_entry, ef, parent, &entry, *offset)) + return -EIO; + } + *offset += sizeof(entry); + } + /* we never reach here */ +} + +int exfat_cache_directory(struct exfat* ef, struct exfat_node* dir) +{ + off_t offset = 0; + int rc; + struct exfat_node* node; + struct exfat_node* current = NULL; + + if (dir->is_cached) + return 0; /* already cached */ + + while ((rc = readdir(ef, dir, &node, &offset)) == 0) + { + node->parent = dir; + if (current != NULL) + { + current->next = node; + node->prev = current; + } + else + dir->child = node; + + current = node; + } + + if (rc != -ENOENT) + { + /* rollback */ + for (current = dir->child; current; current = node) + { + node = current->next; + free(current); + } + dir->child = NULL; + return rc; + } + + dir->is_cached = true; + return 0; +} + +static void tree_attach(struct exfat_node* dir, struct exfat_node* node) +{ + node->parent = dir; + if (dir->child) + { + dir->child->prev = node; + node->next = dir->child; + } + dir->child = node; +} + +static void tree_detach(struct exfat_node* node) +{ + if (node->prev) + node->prev->next = node->next; + else /* this is the first node in the list */ + node->parent->child = node->next; + if (node->next) + node->next->prev = node->prev; + node->parent = NULL; + node->prev = NULL; + node->next = NULL; +} + +static void reset_cache(struct exfat* ef, struct exfat_node* node) +{ + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]; + + while (node->child) + { + struct exfat_node* p = node->child; + reset_cache(ef, p); + tree_detach(p); + free(p); + } + node->is_cached = false; + if (node->references != 0) + { + exfat_get_name(node, buffer); + exfat_warn("non-zero reference counter (%d) for '%s'", + node->references, buffer); + } + if (node != ef->root && node->is_dirty) + { + exfat_get_name(node, buffer); + exfat_bug("node '%s' is dirty", buffer); + } + while (node->references) + exfat_put_node(ef, node); +} + +void exfat_reset_cache(struct exfat* ef) +{ + reset_cache(ef, ef->root); +} + +int exfat_flush_node(struct exfat* ef, struct exfat_node* node) +{ + struct exfat_entry entries[1 + node->continuations]; + struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; + struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; + int rc; + + if (!node->is_dirty) + return 0; /* no need to flush */ + + if (ef->ro) + exfat_bug("unable to flush node to read-only FS"); + + if (node->parent == NULL) + return 0; /* do not flush unlinked node */ + + rc = read_entries(ef, node->parent, entries, 1 + node->continuations, + node->entry_offset); + if (rc != 0) + return rc; + if (!check_entries(entries, 1 + node->continuations)) + return -EIO; + + meta1->attrib = cpu_to_le16(node->attrib); + exfat_unix2exfat(node->mtime, &meta1->mdate, &meta1->mtime, + &meta1->mtime_cs); + exfat_unix2exfat(node->atime, &meta1->adate, &meta1->atime, NULL); + meta2->size = meta2->valid_size = cpu_to_le64(node->size); + meta2->start_cluster = cpu_to_le32(node->start_cluster); + meta2->flags = EXFAT_FLAG_ALWAYS1; + /* empty files must not be marked as contiguous */ + if (node->size != 0 && node->is_contiguous) + meta2->flags |= EXFAT_FLAG_CONTIGUOUS; + /* name hash remains unchanged, no need to recalculate it */ + + meta1->checksum = exfat_calc_checksum(entries, 1 + node->continuations); + rc = write_entries(ef, node->parent, entries, 1 + node->continuations, + node->entry_offset); + if (rc != 0) + return rc; + + node->is_dirty = false; + return exfat_flush(ef); +} + +static int erase_entries(struct exfat* ef, struct exfat_node* dir, int n, + off_t offset) +{ + struct exfat_entry entries[n]; + int rc; + int i; + + rc = read_entries(ef, dir, entries, n, offset); + if (rc != 0) + return rc; + for (i = 0; i < n; i++) + entries[i].type &= ~EXFAT_ENTRY_VALID; + return write_entries(ef, dir, entries, n, offset); +} + +static int erase_node(struct exfat* ef, struct exfat_node* node) +{ + int rc; + + exfat_get_node(node->parent); + rc = erase_entries(ef, node->parent, 1 + node->continuations, + node->entry_offset); + if (rc != 0) + { + exfat_put_node(ef, node->parent); + return rc; + } + rc = exfat_flush_node(ef, node->parent); + exfat_put_node(ef, node->parent); + return rc; +} + +static int shrink_directory(struct exfat* ef, struct exfat_node* dir, + off_t deleted_offset) +{ + const struct exfat_node* node; + const struct exfat_node* last_node; + uint64_t entries = 0; + uint64_t new_size; + + if (!(dir->attrib & EXFAT_ATTRIB_DIR)) + exfat_bug("attempted to shrink a file"); + if (!dir->is_cached) + exfat_bug("attempted to shrink uncached directory"); + + for (last_node = node = dir->child; node; node = node->next) + { + if (deleted_offset < node->entry_offset) + { + /* there are other entries after the removed one, no way to shrink + this directory */ + return 0; + } + if (last_node->entry_offset < node->entry_offset) + last_node = node; + } + + if (last_node) + { + /* offset of the last entry */ + entries += last_node->entry_offset / sizeof(struct exfat_entry); + /* two subentries with meta info */ + entries += 2; + /* subentries with file name */ + entries += DIV_ROUND_UP(utf16_length(last_node->name), + EXFAT_ENAME_MAX); + } + + new_size = DIV_ROUND_UP(entries * sizeof(struct exfat_entry), + CLUSTER_SIZE(*ef->sb)) * CLUSTER_SIZE(*ef->sb); + if (new_size == 0) /* directory always has at least 1 cluster */ + new_size = CLUSTER_SIZE(*ef->sb); + if (new_size == dir->size) + return 0; + return exfat_truncate(ef, dir, new_size, true); +} + +static int delete(struct exfat* ef, struct exfat_node* node) +{ + struct exfat_node* parent = node->parent; + off_t deleted_offset = node->entry_offset; + int rc; + + exfat_get_node(parent); + rc = erase_node(ef, node); + if (rc != 0) + { + exfat_put_node(ef, parent); + return rc; + } + tree_detach(node); + rc = shrink_directory(ef, parent, deleted_offset); + node->is_unlinked = true; + if (rc != 0) + { + exfat_flush_node(ef, parent); + exfat_put_node(ef, parent); + return rc; + } + exfat_update_mtime(parent); + rc = exfat_flush_node(ef, parent); + exfat_put_node(ef, parent); + return rc; +} + +int exfat_unlink(struct exfat* ef, struct exfat_node* node) +{ + if (node->attrib & EXFAT_ATTRIB_DIR) + return -EISDIR; + return delete(ef, node); +} + +int exfat_rmdir(struct exfat* ef, struct exfat_node* node) +{ + int rc; + + if (!(node->attrib & EXFAT_ATTRIB_DIR)) + return -ENOTDIR; + /* check that directory is empty */ + rc = exfat_cache_directory(ef, node); + if (rc != 0) + return rc; + if (node->child) + return -ENOTEMPTY; + return delete(ef, node); +} + +static int check_slot(struct exfat* ef, struct exfat_node* dir, off_t offset, + int n) +{ + struct exfat_entry entries[n]; + int rc; + size_t i; + + /* Root directory contains entries, that don't have any nodes associated + with them (clusters bitmap, upper case table, label). We need to be + careful not to overwrite them. */ + if (dir != ef->root) + return 0; + + rc = read_entries(ef, dir, entries, n, offset); + if (rc != 0) + return rc; + for (i = 0; i < n; i++) + if (entries[i].type & EXFAT_ENTRY_VALID) + return -EINVAL; + return 0; +} + +static int find_slot(struct exfat* ef, struct exfat_node* dir, + off_t* offset, int n) +{ + bitmap_t* dmap; + struct exfat_node* p; + size_t i; + int contiguous = 0; + + if (!dir->is_cached) + exfat_bug("directory is not cached"); + + /* build a bitmap of valid entries in the directory */ + dmap = calloc(BMAP_SIZE(dir->size / sizeof(struct exfat_entry)), + sizeof(bitmap_t)); + if (dmap == NULL) + { + exfat_error("failed to allocate directory bitmap (%"PRIu64")", + dir->size / sizeof(struct exfat_entry)); + return -ENOMEM; + } + for (p = dir->child; p != NULL; p = p->next) + for (i = 0; i < 1 + p->continuations; i++) + BMAP_SET(dmap, p->entry_offset / sizeof(struct exfat_entry) + i); + + /* find a slot in the directory entries bitmap */ + for (i = 0; i < dir->size / sizeof(struct exfat_entry); i++) + { + if (BMAP_GET(dmap, i) == 0) + { + if (contiguous++ == 0) + *offset = (off_t) i * sizeof(struct exfat_entry); + if (contiguous == n) + /* suitable slot is found, check that it's not occupied */ + switch (check_slot(ef, dir, *offset, n)) + { + case 0: + free(dmap); + return 0; + case -EIO: + free(dmap); + return -EIO; + case -EINVAL: + /* slot at (i-n) is occupied, go back and check (i-n+1) */ + i -= contiguous - 1; + contiguous = 0; + break; + } + } + else + contiguous = 0; + } + free(dmap); + + /* no suitable slots found, extend the directory */ + if (contiguous == 0) + *offset = dir->size; + return exfat_truncate(ef, dir, + ROUND_UP(dir->size + sizeof(struct exfat_entry[n - contiguous]), + CLUSTER_SIZE(*ef->sb)), + true); +} + +static int commit_entry(struct exfat* ef, struct exfat_node* dir, + const le16_t* name, off_t offset, uint16_t attrib) +{ + struct exfat_node* node; + const size_t name_length = utf16_length(name); + const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX); + struct exfat_entry entries[2 + name_entries]; + struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; + struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; + int i; + int rc; + + memset(entries, 0, sizeof(struct exfat_entry[2])); + + meta1->type = EXFAT_ENTRY_FILE; + meta1->continuations = 1 + name_entries; + meta1->attrib = cpu_to_le16(attrib); + exfat_unix2exfat(time(NULL), &meta1->crdate, &meta1->crtime, + &meta1->crtime_cs); + meta1->adate = meta1->mdate = meta1->crdate; + meta1->atime = meta1->mtime = meta1->crtime; + meta1->mtime_cs = meta1->crtime_cs; /* there is no atime_cs */ + + meta2->type = EXFAT_ENTRY_FILE_INFO; + meta2->flags = EXFAT_FLAG_ALWAYS1; + meta2->name_length = name_length; + meta2->name_hash = exfat_calc_name_hash(ef, name, name_length); + meta2->start_cluster = cpu_to_le32(EXFAT_CLUSTER_FREE); + + for (i = 0; i < name_entries; i++) + { + struct exfat_entry_name* name_entry; + + name_entry = (struct exfat_entry_name*) &entries[2 + i]; + name_entry->type = EXFAT_ENTRY_FILE_NAME; + name_entry->__unknown = 0; + memcpy(name_entry->name, name + i * EXFAT_ENAME_MAX, + EXFAT_ENAME_MAX * sizeof(le16_t)); + } + + meta1->checksum = exfat_calc_checksum(entries, 2 + name_entries); + rc = write_entries(ef, dir, entries, 2 + name_entries, offset); + if (rc != 0) + return rc; + + node = allocate_node(); + if (node == NULL) + return -ENOMEM; + node->entry_offset = offset; + memcpy(node->name, name, name_length * sizeof(le16_t)); + init_node_meta1(node, meta1); + init_node_meta2(node, meta2); + + tree_attach(dir, node); + return 0; +} + +static int create(struct exfat* ef, const char* path, uint16_t attrib) +{ + struct exfat_node* dir; + struct exfat_node* existing; + off_t offset = -1; + le16_t name[EXFAT_NAME_MAX + 1]; + int rc; + + rc = exfat_split(ef, &dir, &existing, name, path); + if (rc != 0) + return rc; + if (existing != NULL) + { + exfat_put_node(ef, existing); + exfat_put_node(ef, dir); + return -EEXIST; + } + + rc = find_slot(ef, dir, &offset, + 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX)); + if (rc != 0) + { + exfat_put_node(ef, dir); + return rc; + } + rc = commit_entry(ef, dir, name, offset, attrib); + if (rc != 0) + { + exfat_put_node(ef, dir); + return rc; + } + exfat_update_mtime(dir); + rc = exfat_flush_node(ef, dir); + exfat_put_node(ef, dir); + return rc; +} + +int exfat_mknod(struct exfat* ef, const char* path) +{ + return create(ef, path, EXFAT_ATTRIB_ARCH); +} + +int exfat_mkdir(struct exfat* ef, const char* path) +{ + int rc; + struct exfat_node* node; + + rc = create(ef, path, EXFAT_ATTRIB_DIR); + if (rc != 0) + return rc; + rc = exfat_lookup(ef, &node, path); + if (rc != 0) + return 0; + /* directories always have at least one cluster */ + rc = exfat_truncate(ef, node, CLUSTER_SIZE(*ef->sb), true); + if (rc != 0) + { + delete(ef, node); + exfat_put_node(ef, node); + return rc; + } + rc = exfat_flush_node(ef, node); + if (rc != 0) + { + delete(ef, node); + exfat_put_node(ef, node); + return rc; + } + exfat_put_node(ef, node); + return 0; +} + +static int rename_entry(struct exfat* ef, struct exfat_node* dir, + struct exfat_node* node, const le16_t* name, off_t new_offset) +{ + const size_t name_length = utf16_length(name); + const int name_entries = DIV_ROUND_UP(name_length, EXFAT_ENAME_MAX); + struct exfat_entry entries[2 + name_entries]; + struct exfat_entry_meta1* meta1 = (struct exfat_entry_meta1*) &entries[0]; + struct exfat_entry_meta2* meta2 = (struct exfat_entry_meta2*) &entries[1]; + int rc; + int i; + + rc = read_entries(ef, node->parent, entries, 2, node->entry_offset); + if (rc != 0) + return rc; + + meta1->continuations = 1 + name_entries; + meta2->name_length = name_length; + meta2->name_hash = exfat_calc_name_hash(ef, name, name_length); + + rc = erase_node(ef, node); + if (rc != 0) + return rc; + + node->entry_offset = new_offset; + node->continuations = 1 + name_entries; + + for (i = 0; i < name_entries; i++) + { + struct exfat_entry_name* name_entry; + + name_entry = (struct exfat_entry_name*) &entries[2 + i]; + name_entry->type = EXFAT_ENTRY_FILE_NAME; + name_entry->__unknown = 0; + memcpy(name_entry->name, name + i * EXFAT_ENAME_MAX, + EXFAT_ENAME_MAX * sizeof(le16_t)); + } + + meta1->checksum = exfat_calc_checksum(entries, 2 + name_entries); + rc = write_entries(ef, dir, entries, 2 + name_entries, new_offset); + if (rc != 0) + return rc; + + memcpy(node->name, name, (EXFAT_NAME_MAX + 1) * sizeof(le16_t)); + tree_detach(node); + tree_attach(dir, node); + return 0; +} + +int exfat_rename(struct exfat* ef, const char* old_path, const char* new_path) +{ + struct exfat_node* node; + struct exfat_node* existing; + struct exfat_node* dir; + off_t offset = -1; + le16_t name[EXFAT_NAME_MAX + 1]; + int rc; + + rc = exfat_lookup(ef, &node, old_path); + if (rc != 0) + return rc; + + rc = exfat_split(ef, &dir, &existing, name, new_path); + if (rc != 0) + { + exfat_put_node(ef, node); + return rc; + } + + /* check that target is not a subdirectory of the source */ + if (node->attrib & EXFAT_ATTRIB_DIR) + { + struct exfat_node* p; + + for (p = dir; p; p = p->parent) + if (node == p) + { + if (existing != NULL) + exfat_put_node(ef, existing); + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return -EINVAL; + } + } + + if (existing != NULL) + { + /* remove target if it's not the same node as source */ + if (existing != node) + { + if (existing->attrib & EXFAT_ATTRIB_DIR) + { + if (node->attrib & EXFAT_ATTRIB_DIR) + rc = exfat_rmdir(ef, existing); + else + rc = -ENOTDIR; + } + else + { + if (!(node->attrib & EXFAT_ATTRIB_DIR)) + rc = exfat_unlink(ef, existing); + else + rc = -EISDIR; + } + exfat_put_node(ef, existing); + if (rc != 0) + { + /* free clusters even if something went wrong; overwise they + will be just lost */ + exfat_cleanup_node(ef, existing); + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + rc = exfat_cleanup_node(ef, existing); + if (rc != 0) + { + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + } + else + exfat_put_node(ef, existing); + } + + rc = find_slot(ef, dir, &offset, + 2 + DIV_ROUND_UP(utf16_length(name), EXFAT_ENAME_MAX)); + if (rc != 0) + { + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + rc = rename_entry(ef, dir, node, name, offset); + if (rc != 0) + { + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + return rc; + } + rc = exfat_flush_node(ef, dir); + exfat_put_node(ef, dir); + exfat_put_node(ef, node); + /* node itself is not marked as dirty, no need to flush it */ + return rc; +} + +void exfat_utimes(struct exfat_node* node, const struct timespec tv[2]) +{ + node->atime = tv[0].tv_sec; + node->mtime = tv[1].tv_sec; + node->is_dirty = true; +} + +void exfat_update_atime(struct exfat_node* node) +{ + node->atime = time(NULL); + node->is_dirty = true; +} + +void exfat_update_mtime(struct exfat_node* node) +{ + node->mtime = time(NULL); + node->is_dirty = true; +} + +const char* exfat_get_label(struct exfat* ef) +{ + return ef->label; +} + +static int find_label(struct exfat* ef, off_t* offset) +{ + struct exfat_entry entry; + int rc; + + for (*offset = 0; ; *offset += sizeof(entry)) + { + rc = read_entries(ef, ef->root, &entry, 1, *offset); + if (rc != 0) + return rc; + + if (entry.type == EXFAT_ENTRY_LABEL) + return 0; + } +} + +int exfat_set_label(struct exfat* ef, const char* label) +{ + le16_t label_utf16[EXFAT_ENAME_MAX + 1]; + int rc; + off_t offset; + struct exfat_entry_label entry; + + memset(label_utf16, 0, sizeof(label_utf16)); + rc = utf8_to_utf16(label_utf16, label, EXFAT_ENAME_MAX + 1, strlen(label)); + if (rc != 0) + return rc; + + rc = find_label(ef, &offset); + if (rc == -ENOENT) + rc = find_slot(ef, ef->root, &offset, 1); + if (rc != 0) + return rc; + + entry.type = EXFAT_ENTRY_LABEL; + entry.length = utf16_length(label_utf16); + memcpy(entry.name, label_utf16, sizeof(entry.name)); + if (entry.length == 0) + entry.type ^= EXFAT_ENTRY_VALID; + + rc = write_entries(ef, ef->root, (struct exfat_entry*) &entry, 1, offset); + if (rc != 0) + return rc; + + strcpy(ef->label, label); + return 0; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h new file mode 100644 index 00000000..9ab3155d --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h @@ -0,0 +1,63 @@ +/* + platform.h (14.05.13) + OS-specific code (libc-specific in fact). Note that systems with the + same kernel can use different libc implementations. + + 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 PLATFORM_H_INCLUDED +#define PLATFORM_H_INCLUDED + +#if defined(__linux__) || defined(__GLIBC__) || defined(__GNU__) + +#include +#include +#define exfat_bswap16(x) bswap_16(x) +#define exfat_bswap32(x) bswap_32(x) +#define exfat_bswap64(x) bswap_64(x) +#define EXFAT_BYTE_ORDER __BYTE_ORDER +#define EXFAT_LITTLE_ENDIAN __LITTLE_ENDIAN +#define EXFAT_BIG_ENDIAN __BIG_ENDIAN + +#elif defined(__APPLE__) + +#include +#include +#define exfat_bswap16(x) OSSwapInt16(x) +#define exfat_bswap32(x) OSSwapInt32(x) +#define exfat_bswap64(x) OSSwapInt64(x) +#define EXFAT_BYTE_ORDER BYTE_ORDER +#define EXFAT_LITTLE_ENDIAN LITTLE_ENDIAN +#define EXFAT_BIG_ENDIAN BIG_ENDIAN + +#elif defined(__FreeBSD__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__) + +#include +#define exfat_bswap16(x) bswap16(x) +#define exfat_bswap32(x) bswap32(x) +#define exfat_bswap64(x) bswap64(x) +#define EXFAT_BYTE_ORDER _BYTE_ORDER +#define EXFAT_LITTLE_ENDIAN _LITTLE_ENDIAN +#define EXFAT_BIG_ENDIAN _BIG_ENDIAN + +#else +#error Unknown platform +#endif + +#endif /* ifndef PLATFORM_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c new file mode 100644 index 00000000..620ad52b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c @@ -0,0 +1,103 @@ +/* + repair.c (09.03.17) + 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 + +int exfat_errors_fixed; + +bool exfat_ask_to_fix(const struct exfat* ef) +{ + const char* question = "Fix (Y/N)?"; + char answer[8]; + bool yeah, nope; + + switch (ef->repair) + { + case EXFAT_REPAIR_NO: + return false; + case EXFAT_REPAIR_YES: + printf("%s %s", question, "Y\n"); + return true; + case EXFAT_REPAIR_ASK: + do + { + printf("%s ", question); + fflush(stdout); + if (fgets(answer, sizeof(answer), stdin)) + { + yeah = strcasecmp(answer, "Y\n") == 0; + nope = strcasecmp(answer, "N\n") == 0; + } + else + { + yeah = false; + nope = true; + } + } + while (!yeah && !nope); + return yeah; + } + exfat_bug("invalid repair option value: %d", ef->repair); + return false; +} + +bool exfat_fix_invalid_vbr_checksum(const struct exfat* ef, void* sector, + uint32_t vbr_checksum) +{ + size_t i; + off_t sector_size = SECTOR_SIZE(*ef->sb); + + for (i = 0; i < sector_size / sizeof(vbr_checksum); i++) + ((le32_t*) sector)[i] = cpu_to_le32(vbr_checksum); + if (exfat_pwrite(ef->dev, sector, sector_size, 11 * sector_size) < 0) + { + exfat_error("failed to write correct VBR checksum"); + return false; + } + exfat_errors_fixed++; + return true; +} + +bool exfat_fix_invalid_node_checksum(const struct exfat* ef, + struct exfat_node* node) +{ + /* checksum will be rewritten by exfat_flush_node() */ + node->is_dirty = true; + + exfat_errors_fixed++; + return true; +} + +bool exfat_fix_unknown_entry(struct exfat* ef, struct exfat_node* dir, + const struct exfat_entry* entry, off_t offset) +{ + struct exfat_entry deleted = *entry; + + deleted.type &= ~EXFAT_ENTRY_VALID; + if (exfat_generic_pwrite(ef, dir, &deleted, sizeof(struct exfat_entry), + offset) != sizeof(struct exfat_entry)) + return false; + + exfat_errors_fixed++; + return true; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c new file mode 100644 index 00000000..31ae5a26 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c @@ -0,0 +1,164 @@ +/* + time.c (03.02.12) + 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" + +/* timezone offset from UTC in seconds; positive for western timezones, + negative for eastern ones */ +static long exfat_timezone; + +#define SEC_IN_MIN 60ll +#define SEC_IN_HOUR (60 * SEC_IN_MIN) +#define SEC_IN_DAY (24 * SEC_IN_HOUR) +#define SEC_IN_YEAR (365 * SEC_IN_DAY) /* not leap year */ +/* Unix epoch started at 0:00:00 UTC 1 January 1970 */ +#define UNIX_EPOCH_YEAR 1970 +/* exFAT epoch started at 0:00:00 UTC 1 January 1980 */ +#define EXFAT_EPOCH_YEAR 1980 +/* number of years from Unix epoch to exFAT epoch */ +#define EPOCH_DIFF_YEAR (EXFAT_EPOCH_YEAR - UNIX_EPOCH_YEAR) +/* number of days from Unix epoch to exFAT epoch (considering leap days) */ +#define EPOCH_DIFF_DAYS (EPOCH_DIFF_YEAR * 365 + EPOCH_DIFF_YEAR / 4) +/* number of seconds from Unix epoch to exFAT epoch (considering leap days) */ +#define EPOCH_DIFF_SEC (EPOCH_DIFF_DAYS * SEC_IN_DAY) +/* number of leap years passed from exFAT epoch to the specified year + (excluding the specified year itself) */ +#define LEAP_YEARS(year) ((EXFAT_EPOCH_YEAR + (year) - 1) / 4 \ + - (EXFAT_EPOCH_YEAR - 1) / 4) +/* checks whether the specified year is leap */ +#define IS_LEAP_YEAR(year) ((EXFAT_EPOCH_YEAR + (year)) % 4 == 0) + +static const time_t days_in_year[] = +{ + /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ + 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 +}; + +time_t exfat_exfat2unix(le16_t date, le16_t time, uint8_t centisec) +{ + time_t unix_time = EPOCH_DIFF_SEC; + uint16_t ndate = le16_to_cpu(date); + uint16_t ntime = le16_to_cpu(time); + + uint16_t day = ndate & 0x1f; /* 5 bits, 1-31 */ + uint16_t month = ndate >> 5 & 0xf; /* 4 bits, 1-12 */ + uint16_t year = ndate >> 9; /* 7 bits, 1-127 (+1980) */ + + uint16_t twosec = ntime & 0x1f; /* 5 bits, 0-29 (2 sec granularity) */ + uint16_t min = ntime >> 5 & 0x3f; /* 6 bits, 0-59 */ + uint16_t hour = ntime >> 11; /* 5 bits, 0-23 */ + + if (day == 0 || month == 0 || month > 12) + { + exfat_error("bad date %u-%02hu-%02hu", + year + EXFAT_EPOCH_YEAR, month, day); + return 0; + } + if (hour > 23 || min > 59 || twosec > 29) + { + exfat_error("bad time %hu:%02hu:%02u", + hour, min, twosec * 2); + return 0; + } + if (centisec > 199) + { + exfat_error("bad centiseconds count %hhu", centisec); + return 0; + } + + /* every 4th year between 1904 and 2096 is leap */ + unix_time += year * SEC_IN_YEAR + LEAP_YEARS(year) * SEC_IN_DAY; + unix_time += days_in_year[month] * SEC_IN_DAY; + /* if it's leap year and February has passed we should add 1 day */ + if ((EXFAT_EPOCH_YEAR + year) % 4 == 0 && month > 2) + unix_time += SEC_IN_DAY; + unix_time += (day - 1) * SEC_IN_DAY; + + unix_time += hour * SEC_IN_HOUR; + unix_time += min * SEC_IN_MIN; + /* exFAT represents time with 2 sec granularity */ + unix_time += twosec * 2; + unix_time += centisec / 100; + + /* exFAT stores timestamps in local time, so we correct it to UTC */ + unix_time += exfat_timezone; + + return unix_time; +} + +void exfat_unix2exfat(time_t unix_time, le16_t* date, le16_t* time, + uint8_t* centisec) +{ + time_t shift = EPOCH_DIFF_SEC + exfat_timezone; + uint16_t day, month, year; + uint16_t twosec, min, hour; + int days; + int i; + + /* time before exFAT epoch cannot be represented */ + if (unix_time < shift) + unix_time = shift; + + unix_time -= shift; + + days = unix_time / SEC_IN_DAY; + year = (4 * days) / (4 * 365 + 1); + days -= year * 365 + LEAP_YEARS(year); + month = 0; + for (i = 1; i <= 12; i++) + { + int leap_day = (IS_LEAP_YEAR(year) && i == 2); + int leap_sub = (IS_LEAP_YEAR(year) && i >= 3); + + if (i == 12 || days - leap_sub < days_in_year[i + 1] + leap_day) + { + month = i; + days -= days_in_year[i] + leap_sub; + break; + } + } + day = days + 1; + + hour = (unix_time % SEC_IN_DAY) / SEC_IN_HOUR; + min = (unix_time % SEC_IN_HOUR) / SEC_IN_MIN; + twosec = (unix_time % SEC_IN_MIN) / 2; + + *date = cpu_to_le16(day | (month << 5) | (year << 9)); + *time = cpu_to_le16(twosec | (min << 5) | (hour << 11)); + if (centisec) + *centisec = (unix_time % 2) * 100; +} + +void exfat_tzset(void) +{ + time_t now; + struct tm* utc; + + tzset(); + now = time(NULL); + utc = gmtime(&now); + /* gmtime() always sets tm_isdst to 0 because daylight savings never + affect UTC. Setting tm_isdst to -1 makes mktime() to determine whether + summer time is in effect. */ + utc->tm_isdst = -1; + exfat_timezone = mktime(utc) - now; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c new file mode 100644 index 00000000..0d0018c0 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c @@ -0,0 +1,245 @@ +/* + utf.c (13.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 + +static char* wchar_to_utf8(char* output, wchar_t wc, size_t outsize) +{ + if (wc <= 0x7f) + { + if (outsize < 1) + return NULL; + *output++ = (char) wc; + } + else if (wc <= 0x7ff) + { + if (outsize < 2) + return NULL; + *output++ = 0xc0 | (wc >> 6); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0xffff) + { + if (outsize < 3) + return NULL; + *output++ = 0xe0 | (wc >> 12); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0x1fffff) + { + if (outsize < 4) + return NULL; + *output++ = 0xf0 | (wc >> 18); + *output++ = 0x80 | ((wc >> 12) & 0x3f); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0x3ffffff) + { + if (outsize < 5) + return NULL; + *output++ = 0xf8 | (wc >> 24); + *output++ = 0x80 | ((wc >> 18) & 0x3f); + *output++ = 0x80 | ((wc >> 12) & 0x3f); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else if (wc <= 0x7fffffff) + { + if (outsize < 6) + return NULL; + *output++ = 0xfc | (wc >> 30); + *output++ = 0x80 | ((wc >> 24) & 0x3f); + *output++ = 0x80 | ((wc >> 18) & 0x3f); + *output++ = 0x80 | ((wc >> 12) & 0x3f); + *output++ = 0x80 | ((wc >> 6) & 0x3f); + *output++ = 0x80 | (wc & 0x3f); + } + else + return NULL; + + return output; +} + +static const le16_t* utf16_to_wchar(const le16_t* input, wchar_t* wc, + size_t insize) +{ + if ((le16_to_cpu(input[0]) & 0xfc00) == 0xd800) + { + if (insize < 2 || (le16_to_cpu(input[1]) & 0xfc00) != 0xdc00) + return NULL; + *wc = ((wchar_t) (le16_to_cpu(input[0]) & 0x3ff) << 10); + *wc |= (le16_to_cpu(input[1]) & 0x3ff); + *wc += 0x10000; + return input + 2; + } + else + { + *wc = le16_to_cpu(*input); + return input + 1; + } +} + +int utf16_to_utf8(char* output, const le16_t* input, size_t outsize, + size_t insize) +{ + const le16_t* inp = input; + char* outp = output; + wchar_t wc; + + while (inp - input < insize) + { + inp = utf16_to_wchar(inp, &wc, insize - (inp - input)); + if (inp == NULL) + { + exfat_error("illegal UTF-16 sequence"); + return -EILSEQ; + } + outp = wchar_to_utf8(outp, wc, outsize - (outp - output)); + if (outp == NULL) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + if (wc == 0) + return 0; + } + if (outp - output >= outsize) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + *outp = '\0'; + return 0; +} + +static const char* utf8_to_wchar(const char* input, wchar_t* wc, + size_t insize) +{ + if ((input[0] & 0x80) == 0 && insize >= 1) + { + *wc = (wchar_t) input[0]; + return input + 1; + } + if ((input[0] & 0xe0) == 0xc0 && insize >= 2) + { + *wc = (((wchar_t) input[0] & 0x1f) << 6) | + ((wchar_t) input[1] & 0x3f); + return input + 2; + } + if ((input[0] & 0xf0) == 0xe0 && insize >= 3) + { + *wc = (((wchar_t) input[0] & 0x0f) << 12) | + (((wchar_t) input[1] & 0x3f) << 6) | + ((wchar_t) input[2] & 0x3f); + return input + 3; + } + if ((input[0] & 0xf8) == 0xf0 && insize >= 4) + { + *wc = (((wchar_t) input[0] & 0x07) << 18) | + (((wchar_t) input[1] & 0x3f) << 12) | + (((wchar_t) input[2] & 0x3f) << 6) | + ((wchar_t) input[3] & 0x3f); + return input + 4; + } + if ((input[0] & 0xfc) == 0xf8 && insize >= 5) + { + *wc = (((wchar_t) input[0] & 0x03) << 24) | + (((wchar_t) input[1] & 0x3f) << 18) | + (((wchar_t) input[2] & 0x3f) << 12) | + (((wchar_t) input[3] & 0x3f) << 6) | + ((wchar_t) input[4] & 0x3f); + return input + 5; + } + if ((input[0] & 0xfe) == 0xfc && insize >= 6) + { + *wc = (((wchar_t) input[0] & 0x01) << 30) | + (((wchar_t) input[1] & 0x3f) << 24) | + (((wchar_t) input[2] & 0x3f) << 18) | + (((wchar_t) input[3] & 0x3f) << 12) | + (((wchar_t) input[4] & 0x3f) << 6) | + ((wchar_t) input[5] & 0x3f); + return input + 6; + } + return NULL; +} + +static le16_t* wchar_to_utf16(le16_t* output, wchar_t wc, size_t outsize) +{ + if (wc <= 0xffff) /* if character is from BMP */ + { + if (outsize == 0) + return NULL; + output[0] = cpu_to_le16(wc); + return output + 1; + } + if (outsize < 2) + return NULL; + wc -= 0x10000; + output[0] = cpu_to_le16(0xd800 | ((wc >> 10) & 0x3ff)); + output[1] = cpu_to_le16(0xdc00 | (wc & 0x3ff)); + return output + 2; +} + +int utf8_to_utf16(le16_t* output, const char* input, size_t outsize, + size_t insize) +{ + const char* inp = input; + le16_t* outp = output; + wchar_t wc; + + while (inp - input < insize) + { + inp = utf8_to_wchar(inp, &wc, insize - (inp - input)); + if (inp == NULL) + { + exfat_error("illegal UTF-8 sequence"); + return -EILSEQ; + } + outp = wchar_to_utf16(outp, wc, outsize - (outp - output)); + if (outp == NULL) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + if (wc == 0) + break; + } + if (outp - output >= outsize) + { + exfat_error("name is too long"); + return -ENAMETOOLONG; + } + *outp = cpu_to_le16(0); + return 0; +} + +size_t utf16_length(const le16_t* str) +{ + size_t i = 0; + + while (le16_to_cpu(str[i])) + i++; + return i; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c new file mode 100644 index 00000000..7baa6631 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c @@ -0,0 +1,180 @@ +/* + utils.c (04.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 +#include +#include + +void exfat_stat(const struct exfat* ef, const struct exfat_node* node, + struct stat* stbuf) +{ + memset(stbuf, 0, sizeof(struct stat)); + if (node->attrib & EXFAT_ATTRIB_DIR) + stbuf->st_mode = S_IFDIR | (0777 & ~ef->dmask); + else + stbuf->st_mode = S_IFREG | (0777 & ~ef->fmask); + stbuf->st_nlink = 1; + stbuf->st_uid = ef->uid; + stbuf->st_gid = ef->gid; + stbuf->st_size = node->size; + stbuf->st_blocks = ROUND_UP(node->size, CLUSTER_SIZE(*ef->sb)) / 512; + stbuf->st_mtime = node->mtime; + stbuf->st_atime = node->atime; + /* set ctime to mtime to ensure we don't break programs that rely on ctime + (e.g. rsync) */ + stbuf->st_ctime = node->mtime; +} + +void exfat_get_name(const struct exfat_node* node, + char buffer[EXFAT_UTF8_NAME_BUFFER_MAX]) +{ + if (utf16_to_utf8(buffer, node->name, EXFAT_UTF8_NAME_BUFFER_MAX, + EXFAT_NAME_MAX) != 0) + exfat_bug("failed to convert name to UTF-8"); +} + +static uint16_t add_checksum_byte(uint16_t sum, uint8_t byte) +{ + return ((sum << 15) | (sum >> 1)) + byte; +} + +static uint16_t add_checksum_bytes(uint16_t sum, const void* buffer, size_t n) +{ + int i; + + for (i = 0; i < n; i++) + sum = add_checksum_byte(sum, ((const uint8_t*) buffer)[i]); + return sum; +} + +uint16_t exfat_start_checksum(const struct exfat_entry_meta1* entry) +{ + uint16_t sum = 0; + int i; + + for (i = 0; i < sizeof(struct exfat_entry); i++) + if (i != 2 && i != 3) /* skip checksum field itself */ + sum = add_checksum_byte(sum, ((const uint8_t*) entry)[i]); + return sum; +} + +uint16_t exfat_add_checksum(const void* entry, uint16_t sum) +{ + return add_checksum_bytes(sum, entry, sizeof(struct exfat_entry)); +} + +le16_t exfat_calc_checksum(const struct exfat_entry* entries, int n) +{ + uint16_t checksum; + int i; + + checksum = exfat_start_checksum((const struct exfat_entry_meta1*) entries); + for (i = 1; i < n; i++) + checksum = exfat_add_checksum(entries + i, checksum); + return cpu_to_le16(checksum); +} + +uint32_t exfat_vbr_start_checksum(const void* sector, size_t size) +{ + size_t i; + uint32_t sum = 0; + + for (i = 0; i < size; i++) + /* skip volume_state and allocated_percent fields */ + if (i != 0x6a && i != 0x6b && i != 0x70) + sum = ((sum << 31) | (sum >> 1)) + ((const uint8_t*) sector)[i]; + return sum; +} + +uint32_t exfat_vbr_add_checksum(const void* sector, size_t size, uint32_t sum) +{ + size_t i; + + for (i = 0; i < size; i++) + sum = ((sum << 31) | (sum >> 1)) + ((const uint8_t*) sector)[i]; + return sum; +} + +le16_t exfat_calc_name_hash(const struct exfat* ef, const le16_t* name, + size_t length) +{ + size_t i; + uint16_t hash = 0; + + for (i = 0; i < length; i++) + { + uint16_t c = le16_to_cpu(name[i]); + + /* convert to upper case */ + c = ef->upcase[c]; + + hash = ((hash << 15) | (hash >> 1)) + (c & 0xff); + hash = ((hash << 15) | (hash >> 1)) + (c >> 8); + } + return cpu_to_le16(hash); +} + +void exfat_humanize_bytes(uint64_t value, struct exfat_human_bytes* hb) +{ + size_t i; + /* 16 EB (minus 1 byte) is the largest size that can be represented by + uint64_t */ + const char* units[] = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB"}; + uint64_t divisor = 1; + uint64_t temp = 0; + + for (i = 0; ; i++, divisor *= 1024) + { + temp = (value + divisor / 2) / divisor; + + if (temp == 0) + break; + if (temp / 1024 * 1024 == temp) + continue; + if (temp < 10240) + break; + } + hb->value = temp; + hb->unit = units[i]; +} + +void exfat_print_info(const struct exfat_super_block* sb, + uint32_t free_clusters) +{ + struct exfat_human_bytes hb; + off_t total_space = le64_to_cpu(sb->sector_count) * SECTOR_SIZE(*sb); + off_t avail_space = (off_t) free_clusters * CLUSTER_SIZE(*sb); + + printf("File system version %hhu.%hhu\n", + sb->version.major, sb->version.minor); + exfat_humanize_bytes(SECTOR_SIZE(*sb), &hb); + printf("Sector size %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(CLUSTER_SIZE(*sb), &hb); + printf("Cluster size %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(total_space, &hb); + printf("Volume size %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(total_space - avail_space, &hb); + printf("Used space %10"PRIu64" %s\n", hb.value, hb.unit); + exfat_humanize_bytes(avail_space, &hb); + printf("Available space %10"PRIu64" %s\n", hb.value, hb.unit); +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c new file mode 100644 index 00000000..ad5accc2 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c @@ -0,0 +1,79 @@ +/* + cbm.c (09.11.10) + Clusters Bitmap creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 "cbm.h" +#include "fat.h" +#include "uct.h" +#include "rootdir.h" +#include +#include + +static off_t cbm_alignment(void) +{ + return get_cluster_size(); +} + +static off_t cbm_size(void) +{ + return DIV_ROUND_UP( + (get_volume_size() - get_position(&cbm)) / get_cluster_size(), + CHAR_BIT); +} + +static int cbm_write(struct exfat_dev* dev) +{ + uint32_t allocated_clusters = + DIV_ROUND_UP(cbm.get_size(), get_cluster_size()) + + DIV_ROUND_UP(uct.get_size(), get_cluster_size()) + + DIV_ROUND_UP(rootdir.get_size(), get_cluster_size()); + size_t bitmap_size = ROUND_UP(allocated_clusters, CHAR_BIT); + bitmap_t* bitmap = malloc(BMAP_SIZE(bitmap_size)); + size_t i; + + if (bitmap == NULL) + { + exfat_error("failed to allocate bitmap of %zu bytes", + BMAP_SIZE(bitmap_size)); + return 1; + } + memset(bitmap, 0, BMAP_SIZE(bitmap_size)); + + for (i = 0; i < bitmap_size; i++) + if (i < allocated_clusters) + BMAP_SET(bitmap, i); + if (exfat_write(dev, bitmap, bitmap_size / CHAR_BIT) < 0) + { + free(bitmap); + exfat_error("failed to write bitmap of %zu bytes", + bitmap_size / CHAR_BIT); + return 1; + } + free(bitmap); + return 0; +} + +const struct fs_object cbm = +{ + .get_alignment = cbm_alignment, + .get_size = cbm_size, + .write = cbm_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h new file mode 100644 index 00000000..3803b792 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h @@ -0,0 +1,30 @@ +/* + cbm.h (09.11.10) + Clusters Bitmap creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 MKFS_CBM_H_INCLUDED +#define MKFS_CBM_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object cbm; + +#endif /* ifndef MKFS_CBM_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c new file mode 100644 index 00000000..c5174a7a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c @@ -0,0 +1,88 @@ +/* + fat.c (09.11.10) + File Allocation Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 "fat.h" +#include "cbm.h" +#include "uct.h" +#include "rootdir.h" +#include + +static off_t fat_alignment(void) +{ + return (off_t) 128 * get_sector_size(); +} + +static off_t fat_size(void) +{ + return get_volume_size() / get_cluster_size() * sizeof(cluster_t); +} + +static cluster_t fat_write_entry(struct exfat_dev* dev, cluster_t cluster, + cluster_t value) +{ + le32_t fat_entry = cpu_to_le32(value); + if (exfat_write(dev, &fat_entry, sizeof(fat_entry)) < 0) + { + exfat_error("failed to write FAT entry 0x%x", value); + return 0; + } + return cluster + 1; +} + +static cluster_t fat_write_entries(struct exfat_dev* dev, cluster_t cluster, + uint64_t length) +{ + cluster_t end = cluster + DIV_ROUND_UP(length, get_cluster_size()); + + while (cluster < end - 1) + { + cluster = fat_write_entry(dev, cluster, cluster + 1); + if (cluster == 0) + return 0; + } + return fat_write_entry(dev, cluster, EXFAT_CLUSTER_END); +} + +static int fat_write(struct exfat_dev* dev) +{ + cluster_t c = 0; + + if (!(c = fat_write_entry(dev, c, 0xfffffff8))) /* media type */ + return 1; + if (!(c = fat_write_entry(dev, c, 0xffffffff))) /* some weird constant */ + return 1; + if (!(c = fat_write_entries(dev, c, cbm.get_size()))) + return 1; + if (!(c = fat_write_entries(dev, c, uct.get_size()))) + return 1; + if (!(c = fat_write_entries(dev, c, rootdir.get_size()))) + return 1; + + return 0; +} + +const struct fs_object fat = +{ + .get_alignment = fat_alignment, + .get_size = fat_size, + .write = fat_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h new file mode 100644 index 00000000..fbecaa22 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h @@ -0,0 +1,30 @@ +/* + fat.h (09.11.10) + File Allocation Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 MKFS_FAT_H_INCLUDED +#define MKFS_FAT_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object fat; + +#endif /* ifndef MKFS_FAT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c new file mode 100644 index 00000000..10ecf23a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c @@ -0,0 +1,167 @@ +/* + mkexfat.c (22.04.12) + FS creation engine. + + Free exFAT implementation. + Copyright (C) 2011-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 "mkexfat.h" +#include +#include +#include +#include +#include + +static int check_size(off_t volume_size) +{ + const struct fs_object** pp; + off_t position = 0; + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + position += (*pp)->get_size(); + } + + if (position > volume_size) + { + struct exfat_human_bytes vhb; + + exfat_humanize_bytes(volume_size, &vhb); + exfat_error("too small device (%"PRIu64" %s)", vhb.value, vhb.unit); + return 1; + } + + return 0; + +} + +static int erase_object(struct exfat_dev* dev, const void* block, + size_t block_size, off_t start, off_t size) +{ + const off_t block_count = DIV_ROUND_UP(size, block_size); + off_t i; + + if (exfat_seek(dev, start, SEEK_SET) == (off_t) -1) + { + exfat_error("seek to 0x%"PRIx64" failed", start); + return 1; + } + for (i = 0; i < size; i += block_size) + { + if (exfat_write(dev, block, MIN(size - i, block_size)) < 0) + { + exfat_error("failed to erase block %"PRIu64"/%"PRIu64 + " at 0x%"PRIx64, i + 1, block_count, start); + return 1; + } + } + return 0; +} + +static int erase(struct exfat_dev* dev) +{ + const struct fs_object** pp; + off_t position = 0; + const size_t block_size = 1024 * 1024; + void* block = malloc(block_size); + + if (block == NULL) + { + exfat_error("failed to allocate erase block of %zu bytes", block_size); + return 1; + } + memset(block, 0, block_size); + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + if (erase_object(dev, block, block_size, position, + (*pp)->get_size()) != 0) + { + free(block); + return 1; + } + position += (*pp)->get_size(); + } + + free(block); + return 0; +} + +static int create(struct exfat_dev* dev) +{ + const struct fs_object** pp; + off_t position = 0; + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + if (exfat_seek(dev, position, SEEK_SET) == (off_t) -1) + { + exfat_error("seek to 0x%"PRIx64" failed", position); + return 1; + } + if ((*pp)->write(dev) != 0) + return 1; + position += (*pp)->get_size(); + } + return 0; +} + +int mkfs(struct exfat_dev* dev, off_t volume_size) +{ + if (check_size(volume_size) != 0) + return 1; + + exfat_debug("Creating... "); + //fputs("Creating... ", stdout); + //fflush(stdout); + if (erase(dev) != 0) + return 1; + if (create(dev) != 0) + return 1; + //puts("done."); + + //fputs("Flushing... ", stdout); + //fflush(stdout); + exfat_debug("Flushing... "); + if (exfat_fsync(dev) != 0) + return 1; + //puts("done."); + + return 0; +} + +off_t get_position(const struct fs_object* object) +{ + const struct fs_object** pp; + off_t position = 0; + + for (pp = objects; *pp; pp++) + { + position = ROUND_UP(position, (*pp)->get_alignment()); + if (*pp == object) + return position; + position += (*pp)->get_size(); + } + exfat_bug("unknown object"); + + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h new file mode 100644 index 00000000..54816afe --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h @@ -0,0 +1,49 @@ +/* + mkexfat.h (09.11.10) + FS creation engine. + + Free exFAT implementation. + Copyright (C) 2011-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 MKFS_MKEXFAT_H_INCLUDED +#define MKFS_MKEXFAT_H_INCLUDED + +#include "exfat.h" + +struct fs_object +{ + off_t (*get_alignment)(void); + off_t (*get_size)(void); + int (*write)(struct exfat_dev* dev); +}; + +extern const struct fs_object* objects[]; + +int get_sector_bits(void); +int get_spc_bits(void); +off_t get_volume_size(void); +const le16_t* get_volume_label(void); +uint32_t get_volume_serial(void); +uint64_t get_first_sector(void); +int get_sector_size(void); +int get_cluster_size(void); + +int mkfs(struct exfat_dev* dev, off_t volume_size); +off_t get_position(const struct fs_object* object); + +#endif /* ifndef MKFS_MKEXFAT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c new file mode 100644 index 00000000..c65035fa --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c @@ -0,0 +1,268 @@ +/* + main.c (15.08.10) + Creates exFAT file system. + + Free exFAT implementation. + Copyright (C) 2011-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 "mkexfat.h" +#include "vbr.h" +#include "fat.h" +#include "cbm.h" +#include "uct.h" +#include "rootdir.h" +#include "exfat.h" +#include +#include +#include +#include +#include +#include +#include + +const struct fs_object* objects[] = +{ + &vbr, + &vbr, + &fat, + /* clusters heap */ + &cbm, + &uct, + &rootdir, + NULL, +}; + +static struct +{ + int sector_bits; + int spc_bits; + off_t volume_size; + le16_t volume_label[EXFAT_ENAME_MAX + 1]; + uint32_t volume_serial; + uint64_t first_sector; +} +param; + +extern int g_vtoy_exfat_disk_fd; +extern uint64_t g_vtoy_exfat_part_size; + +int get_sector_bits(void) +{ + return param.sector_bits; +} + +int get_spc_bits(void) +{ + return param.spc_bits; +} + +off_t get_volume_size(void) +{ + return param.volume_size; +} + +const le16_t* get_volume_label(void) +{ + return param.volume_label; +} + +uint32_t get_volume_serial(void) +{ + return param.volume_serial; +} + +uint64_t get_first_sector(void) +{ + return param.first_sector; +} + +int get_sector_size(void) +{ + return 1 << get_sector_bits(); +} + +int get_cluster_size(void) +{ + return get_sector_size() << get_spc_bits(); +} + +static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size) +{ + int i; + + if (user_defined != -1) + { + off_t cluster_size = 1 << sector_bits << user_defined; + if (volume_size / cluster_size > EXFAT_LAST_DATA_CLUSTER) + { + struct exfat_human_bytes chb, vhb; + + exfat_humanize_bytes(cluster_size, &chb); + exfat_humanize_bytes(volume_size, &vhb); + exfat_error("cluster size %"PRIu64" %s is too small for " + "%"PRIu64" %s volume, try -s %d", + chb.value, chb.unit, + vhb.value, vhb.unit, + 1 << setup_spc_bits(sector_bits, -1, volume_size)); + return -1; + } + return user_defined; + } + + if (volume_size < 256ull * 1024 * 1024) + return MAX(0, 12 - sector_bits); /* 4 KB */ + if (volume_size < 32ull * 1024 * 1024 * 1024) + return MAX(0, 15 - sector_bits); /* 32 KB */ + + for (i = 17; ; i++) /* 128 KB or more */ + if (DIV_ROUND_UP(volume_size, 1 << i) <= EXFAT_LAST_DATA_CLUSTER) + return MAX(0, i - sector_bits); +} + +static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s) +{ + memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t)); + if (s == NULL) + return 0; + return utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s)); +} + +static uint32_t setup_volume_serial(uint32_t user_defined) +{ + struct timeval now; + + if (user_defined != 0) + return user_defined; + + if (gettimeofday(&now, NULL) != 0) + { + exfat_error("failed to form volume id"); + return 0; + } + return (now.tv_sec << 20) | now.tv_usec; +} + +static int setup(struct exfat_dev* dev, int sector_bits, int spc_bits, + const char* volume_label, uint32_t volume_serial, + uint64_t first_sector) +{ + param.sector_bits = sector_bits; + param.first_sector = first_sector; + param.volume_size = exfat_get_size(dev); + + param.spc_bits = setup_spc_bits(sector_bits, spc_bits, param.volume_size); + if (param.spc_bits == -1) + return 1; + + if (setup_volume_label(param.volume_label, volume_label) != 0) + return 1; + + param.volume_serial = setup_volume_serial(volume_serial); + if (param.volume_serial == 0) + return 1; + + return mkfs(dev, param.volume_size); +} + +static int logarithm2(int n) +{ + int i; + + for (i = 0; i < sizeof(int) * CHAR_BIT - 1; i++) + if ((1 << i) == n) + return i; + return -1; +} + +static void usage(const char* prog) +{ + fprintf(stderr, "Usage: %s [-i volume-id] [-n label] " + "[-p partition-first-sector] " + "[-s sectors-per-cluster] [-V] \n", prog); + exit(1); +} + +int mkexfat_main(const char *devpath, int fd, uint64_t part_sector_count) +{ + int spc_bits = -1; + uint32_t volume_serial = 0; + uint64_t first_sector = 0; + struct exfat_dev* dev; + +#if 0 + while ((opt = getopt(argc, argv, "i:n:p:s:V")) != -1) + { + switch (opt) + { + case 'i': + volume_serial = strtol(optarg, NULL, 16); + break; + case 'n': + volume_label = optarg; + break; + case 'p': + first_sector = strtoll(optarg, NULL, 10); + break; + case 's': + spc_bits = logarithm2(atoi(optarg)); + if (spc_bits < 0) + { + exfat_error("invalid option value: '%s'", optarg); + return 1; + } + break; + case 'V': + puts("Copyright (C) 2011-2018 Andrew Nayenko"); + return 0; + default: + usage(argv[0]); + break; + } + } +#endif /* #if 0 */ + + /* + * DiskSize > 32GB Cluster Size use 128KB + * DiskSize < 32GB Cluster Size use 32KB + */ + if ((part_sector_count / 2097152) > 32) + { + spc_bits = logarithm2(256); + } + else + { + spc_bits = logarithm2(64); + } + + g_vtoy_exfat_disk_fd = fd; + g_vtoy_exfat_part_size = part_sector_count * 512; + + dev = exfat_open(devpath, EXFAT_MODE_RW); + if (dev == NULL) + return 1; + if (setup(dev, 9, spc_bits, "Ventoy", volume_serial, first_sector) != 0) + { + exfat_close(dev); + return 1; + } + if (exfat_close(dev) != 0) + return 1; + + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c new file mode 100644 index 00000000..323da8aa --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c @@ -0,0 +1,102 @@ +/* + rootdir.c (09.11.10) + Root directory creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 "rootdir.h" +#include "uct.h" +#include "cbm.h" +#include "uctc.h" +#include + +static off_t rootdir_alignment(void) +{ + return get_cluster_size(); +} + +static off_t rootdir_size(void) +{ + return get_cluster_size(); +} + +static void init_label_entry(struct exfat_entry_label* label_entry) +{ + memset(label_entry, 0, sizeof(struct exfat_entry_label)); + label_entry->type = EXFAT_ENTRY_LABEL ^ EXFAT_ENTRY_VALID; + + if (utf16_length(get_volume_label()) == 0) + return; + + memcpy(label_entry->name, get_volume_label(), + EXFAT_ENAME_MAX * sizeof(le16_t)); + label_entry->length = utf16_length(get_volume_label()); + label_entry->type |= EXFAT_ENTRY_VALID; +} + +static void init_bitmap_entry(struct exfat_entry_bitmap* bitmap_entry) +{ + memset(bitmap_entry, 0, sizeof(struct exfat_entry_bitmap)); + bitmap_entry->type = EXFAT_ENTRY_BITMAP; + bitmap_entry->start_cluster = cpu_to_le32(EXFAT_FIRST_DATA_CLUSTER); + bitmap_entry->size = cpu_to_le64(cbm.get_size()); +} + +static void init_upcase_entry(struct exfat_entry_upcase* upcase_entry) +{ + size_t i; + uint32_t sum = 0; + + for (i = 0; i < sizeof(upcase_table); i++) + sum = ((sum << 31) | (sum >> 1)) + upcase_table[i]; + + memset(upcase_entry, 0, sizeof(struct exfat_entry_upcase)); + upcase_entry->type = EXFAT_ENTRY_UPCASE; + upcase_entry->checksum = cpu_to_le32(sum); + upcase_entry->start_cluster = cpu_to_le32( + (get_position(&uct) - get_position(&cbm)) / get_cluster_size() + + EXFAT_FIRST_DATA_CLUSTER); + upcase_entry->size = cpu_to_le64(sizeof(upcase_table)); +} + +static int rootdir_write(struct exfat_dev* dev) +{ + struct exfat_entry_label label_entry; + struct exfat_entry_bitmap bitmap_entry; + struct exfat_entry_upcase upcase_entry; + + init_label_entry(&label_entry); + init_bitmap_entry(&bitmap_entry); + init_upcase_entry(&upcase_entry); + + if (exfat_write(dev, &label_entry, sizeof(struct exfat_entry)) < 0) + return 1; + if (exfat_write(dev, &bitmap_entry, sizeof(struct exfat_entry)) < 0) + return 1; + if (exfat_write(dev, &upcase_entry, sizeof(struct exfat_entry)) < 0) + return 1; + return 0; +} + +const struct fs_object rootdir = +{ + .get_alignment = rootdir_alignment, + .get_size = rootdir_size, + .write = rootdir_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h new file mode 100644 index 00000000..87f437f1 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h @@ -0,0 +1,30 @@ +/* + rootdir.h (09.11.10) + Root directory creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 MKFS_ROOTDIR_H_INCLUDED +#define MKFS_ROOTDIR_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object rootdir; + +#endif /* ifndef MKFS_ROOTDIR_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c new file mode 100644 index 00000000..98cdce8f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c @@ -0,0 +1,52 @@ +/* + uct.c (09.11.10) + Upper Case Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 "uct.h" +#include "uctc.h" + +static off_t uct_alignment(void) +{ + return get_cluster_size(); +} + +static off_t uct_size(void) +{ + return sizeof(upcase_table); +} + +static int uct_write(struct exfat_dev* dev) +{ + if (exfat_write(dev, upcase_table, sizeof(upcase_table)) < 0) + { + exfat_error("failed to write upcase table of %zu bytes", + sizeof(upcase_table)); + return 1; + } + return 0; +} + +const struct fs_object uct = +{ + .get_alignment = uct_alignment, + .get_size = uct_size, + .write = uct_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h new file mode 100644 index 00000000..ce619ecf --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h @@ -0,0 +1,30 @@ +/* + uct.h (09.11.10) + Upper Case Table creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 MKFS_UCT_H_INCLUDED +#define MKFS_UCT_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object uct; + +#endif /* ifndef MKFS_UCT_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c new file mode 100644 index 00000000..518219cd --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c @@ -0,0 +1,757 @@ +/* + uctc.c (30.04.12) + Upper Case Table contents. + + Free exFAT implementation. + Copyright (C) 2011-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 "uctc.h" + +uint8_t upcase_table[5836] = +{ + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, + 0x08, 0x00, 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x00, + 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, + 0x10, 0x00, 0x11, 0x00, 0x12, 0x00, 0x13, 0x00, + 0x14, 0x00, 0x15, 0x00, 0x16, 0x00, 0x17, 0x00, + 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, + 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, + 0x20, 0x00, 0x21, 0x00, 0x22, 0x00, 0x23, 0x00, + 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, + 0x28, 0x00, 0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, + 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00, 0x2f, 0x00, + 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, + 0x34, 0x00, 0x35, 0x00, 0x36, 0x00, 0x37, 0x00, + 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00, 0x3b, 0x00, + 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, + 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, + 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, + 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, + 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00, 0x5f, 0x00, + 0x60, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, 0x00, + 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, 0x00, + 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, + 0x4c, 0x00, 0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, + 0x50, 0x00, 0x51, 0x00, 0x52, 0x00, 0x53, 0x00, + 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, + 0x58, 0x00, 0x59, 0x00, 0x5a, 0x00, 0x7b, 0x00, + 0x7c, 0x00, 0x7d, 0x00, 0x7e, 0x00, 0x7f, 0x00, + 0x80, 0x00, 0x81, 0x00, 0x82, 0x00, 0x83, 0x00, + 0x84, 0x00, 0x85, 0x00, 0x86, 0x00, 0x87, 0x00, + 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x8b, 0x00, + 0x8c, 0x00, 0x8d, 0x00, 0x8e, 0x00, 0x8f, 0x00, + 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, 0x00, + 0x94, 0x00, 0x95, 0x00, 0x96, 0x00, 0x97, 0x00, + 0x98, 0x00, 0x99, 0x00, 0x9a, 0x00, 0x9b, 0x00, + 0x9c, 0x00, 0x9d, 0x00, 0x9e, 0x00, 0x9f, 0x00, + 0xa0, 0x00, 0xa1, 0x00, 0xa2, 0x00, 0xa3, 0x00, + 0xa4, 0x00, 0xa5, 0x00, 0xa6, 0x00, 0xa7, 0x00, + 0xa8, 0x00, 0xa9, 0x00, 0xaa, 0x00, 0xab, 0x00, + 0xac, 0x00, 0xad, 0x00, 0xae, 0x00, 0xaf, 0x00, + 0xb0, 0x00, 0xb1, 0x00, 0xb2, 0x00, 0xb3, 0x00, + 0xb4, 0x00, 0xb5, 0x00, 0xb6, 0x00, 0xb7, 0x00, + 0xb8, 0x00, 0xb9, 0x00, 0xba, 0x00, 0xbb, 0x00, + 0xbc, 0x00, 0xbd, 0x00, 0xbe, 0x00, 0xbf, 0x00, + 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 0x00, + 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, + 0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00, + 0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xcf, 0x00, + 0xd0, 0x00, 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, + 0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xd7, 0x00, + 0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdb, 0x00, + 0xdc, 0x00, 0xdd, 0x00, 0xde, 0x00, 0xdf, 0x00, + 0xc0, 0x00, 0xc1, 0x00, 0xc2, 0x00, 0xc3, 0x00, + 0xc4, 0x00, 0xc5, 0x00, 0xc6, 0x00, 0xc7, 0x00, + 0xc8, 0x00, 0xc9, 0x00, 0xca, 0x00, 0xcb, 0x00, + 0xcc, 0x00, 0xcd, 0x00, 0xce, 0x00, 0xcf, 0x00, + 0xd0, 0x00, 0xd1, 0x00, 0xd2, 0x00, 0xd3, 0x00, + 0xd4, 0x00, 0xd5, 0x00, 0xd6, 0x00, 0xf7, 0x00, + 0xd8, 0x00, 0xd9, 0x00, 0xda, 0x00, 0xdb, 0x00, + 0xdc, 0x00, 0xdd, 0x00, 0xde, 0x00, 0x78, 0x01, + 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, + 0x04, 0x01, 0x04, 0x01, 0x06, 0x01, 0x06, 0x01, + 0x08, 0x01, 0x08, 0x01, 0x0a, 0x01, 0x0a, 0x01, + 0x0c, 0x01, 0x0c, 0x01, 0x0e, 0x01, 0x0e, 0x01, + 0x10, 0x01, 0x10, 0x01, 0x12, 0x01, 0x12, 0x01, + 0x14, 0x01, 0x14, 0x01, 0x16, 0x01, 0x16, 0x01, + 0x18, 0x01, 0x18, 0x01, 0x1a, 0x01, 0x1a, 0x01, + 0x1c, 0x01, 0x1c, 0x01, 0x1e, 0x01, 0x1e, 0x01, + 0x20, 0x01, 0x20, 0x01, 0x22, 0x01, 0x22, 0x01, + 0x24, 0x01, 0x24, 0x01, 0x26, 0x01, 0x26, 0x01, + 0x28, 0x01, 0x28, 0x01, 0x2a, 0x01, 0x2a, 0x01, + 0x2c, 0x01, 0x2c, 0x01, 0x2e, 0x01, 0x2e, 0x01, + 0x30, 0x01, 0x31, 0x01, 0x32, 0x01, 0x32, 0x01, + 0x34, 0x01, 0x34, 0x01, 0x36, 0x01, 0x36, 0x01, + 0x38, 0x01, 0x39, 0x01, 0x39, 0x01, 0x3b, 0x01, + 0x3b, 0x01, 0x3d, 0x01, 0x3d, 0x01, 0x3f, 0x01, + 0x3f, 0x01, 0x41, 0x01, 0x41, 0x01, 0x43, 0x01, + 0x43, 0x01, 0x45, 0x01, 0x45, 0x01, 0x47, 0x01, + 0x47, 0x01, 0x49, 0x01, 0x4a, 0x01, 0x4a, 0x01, + 0x4c, 0x01, 0x4c, 0x01, 0x4e, 0x01, 0x4e, 0x01, + 0x50, 0x01, 0x50, 0x01, 0x52, 0x01, 0x52, 0x01, + 0x54, 0x01, 0x54, 0x01, 0x56, 0x01, 0x56, 0x01, + 0x58, 0x01, 0x58, 0x01, 0x5a, 0x01, 0x5a, 0x01, + 0x5c, 0x01, 0x5c, 0x01, 0x5e, 0x01, 0x5e, 0x01, + 0x60, 0x01, 0x60, 0x01, 0x62, 0x01, 0x62, 0x01, + 0x64, 0x01, 0x64, 0x01, 0x66, 0x01, 0x66, 0x01, + 0x68, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x6a, 0x01, + 0x6c, 0x01, 0x6c, 0x01, 0x6e, 0x01, 0x6e, 0x01, + 0x70, 0x01, 0x70, 0x01, 0x72, 0x01, 0x72, 0x01, + 0x74, 0x01, 0x74, 0x01, 0x76, 0x01, 0x76, 0x01, + 0x78, 0x01, 0x79, 0x01, 0x79, 0x01, 0x7b, 0x01, + 0x7b, 0x01, 0x7d, 0x01, 0x7d, 0x01, 0x7f, 0x01, + 0x43, 0x02, 0x81, 0x01, 0x82, 0x01, 0x82, 0x01, + 0x84, 0x01, 0x84, 0x01, 0x86, 0x01, 0x87, 0x01, + 0x87, 0x01, 0x89, 0x01, 0x8a, 0x01, 0x8b, 0x01, + 0x8b, 0x01, 0x8d, 0x01, 0x8e, 0x01, 0x8f, 0x01, + 0x90, 0x01, 0x91, 0x01, 0x91, 0x01, 0x93, 0x01, + 0x94, 0x01, 0xf6, 0x01, 0x96, 0x01, 0x97, 0x01, + 0x98, 0x01, 0x98, 0x01, 0x3d, 0x02, 0x9b, 0x01, + 0x9c, 0x01, 0x9d, 0x01, 0x20, 0x02, 0x9f, 0x01, + 0xa0, 0x01, 0xa0, 0x01, 0xa2, 0x01, 0xa2, 0x01, + 0xa4, 0x01, 0xa4, 0x01, 0xa6, 0x01, 0xa7, 0x01, + 0xa7, 0x01, 0xa9, 0x01, 0xaa, 0x01, 0xab, 0x01, + 0xac, 0x01, 0xac, 0x01, 0xae, 0x01, 0xaf, 0x01, + 0xaf, 0x01, 0xb1, 0x01, 0xb2, 0x01, 0xb3, 0x01, + 0xb3, 0x01, 0xb5, 0x01, 0xb5, 0x01, 0xb7, 0x01, + 0xb8, 0x01, 0xb8, 0x01, 0xba, 0x01, 0xbb, 0x01, + 0xbc, 0x01, 0xbc, 0x01, 0xbe, 0x01, 0xf7, 0x01, + 0xc0, 0x01, 0xc1, 0x01, 0xc2, 0x01, 0xc3, 0x01, + 0xc4, 0x01, 0xc5, 0x01, 0xc4, 0x01, 0xc7, 0x01, + 0xc8, 0x01, 0xc7, 0x01, 0xca, 0x01, 0xcb, 0x01, + 0xca, 0x01, 0xcd, 0x01, 0xcd, 0x01, 0xcf, 0x01, + 0xcf, 0x01, 0xd1, 0x01, 0xd1, 0x01, 0xd3, 0x01, + 0xd3, 0x01, 0xd5, 0x01, 0xd5, 0x01, 0xd7, 0x01, + 0xd7, 0x01, 0xd9, 0x01, 0xd9, 0x01, 0xdb, 0x01, + 0xdb, 0x01, 0x8e, 0x01, 0xde, 0x01, 0xde, 0x01, + 0xe0, 0x01, 0xe0, 0x01, 0xe2, 0x01, 0xe2, 0x01, + 0xe4, 0x01, 0xe4, 0x01, 0xe6, 0x01, 0xe6, 0x01, + 0xe8, 0x01, 0xe8, 0x01, 0xea, 0x01, 0xea, 0x01, + 0xec, 0x01, 0xec, 0x01, 0xee, 0x01, 0xee, 0x01, + 0xf0, 0x01, 0xf1, 0x01, 0xf2, 0x01, 0xf1, 0x01, + 0xf4, 0x01, 0xf4, 0x01, 0xf6, 0x01, 0xf7, 0x01, + 0xf8, 0x01, 0xf8, 0x01, 0xfa, 0x01, 0xfa, 0x01, + 0xfc, 0x01, 0xfc, 0x01, 0xfe, 0x01, 0xfe, 0x01, + 0x00, 0x02, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x04, 0x02, 0x04, 0x02, 0x06, 0x02, 0x06, 0x02, + 0x08, 0x02, 0x08, 0x02, 0x0a, 0x02, 0x0a, 0x02, + 0x0c, 0x02, 0x0c, 0x02, 0x0e, 0x02, 0x0e, 0x02, + 0x10, 0x02, 0x10, 0x02, 0x12, 0x02, 0x12, 0x02, + 0x14, 0x02, 0x14, 0x02, 0x16, 0x02, 0x16, 0x02, + 0x18, 0x02, 0x18, 0x02, 0x1a, 0x02, 0x1a, 0x02, + 0x1c, 0x02, 0x1c, 0x02, 0x1e, 0x02, 0x1e, 0x02, + 0x20, 0x02, 0x21, 0x02, 0x22, 0x02, 0x22, 0x02, + 0x24, 0x02, 0x24, 0x02, 0x26, 0x02, 0x26, 0x02, + 0x28, 0x02, 0x28, 0x02, 0x2a, 0x02, 0x2a, 0x02, + 0x2c, 0x02, 0x2c, 0x02, 0x2e, 0x02, 0x2e, 0x02, + 0x30, 0x02, 0x30, 0x02, 0x32, 0x02, 0x32, 0x02, + 0x34, 0x02, 0x35, 0x02, 0x36, 0x02, 0x37, 0x02, + 0x38, 0x02, 0x39, 0x02, 0x65, 0x2c, 0x3b, 0x02, + 0x3b, 0x02, 0x3d, 0x02, 0x66, 0x2c, 0x3f, 0x02, + 0x40, 0x02, 0x41, 0x02, 0x41, 0x02, 0x43, 0x02, + 0x44, 0x02, 0x45, 0x02, 0x46, 0x02, 0x46, 0x02, + 0x48, 0x02, 0x48, 0x02, 0x4a, 0x02, 0x4a, 0x02, + 0x4c, 0x02, 0x4c, 0x02, 0x4e, 0x02, 0x4e, 0x02, + 0x50, 0x02, 0x51, 0x02, 0x52, 0x02, 0x81, 0x01, + 0x86, 0x01, 0x55, 0x02, 0x89, 0x01, 0x8a, 0x01, + 0x58, 0x02, 0x8f, 0x01, 0x5a, 0x02, 0x90, 0x01, + 0x5c, 0x02, 0x5d, 0x02, 0x5e, 0x02, 0x5f, 0x02, + 0x93, 0x01, 0x61, 0x02, 0x62, 0x02, 0x94, 0x01, + 0x64, 0x02, 0x65, 0x02, 0x66, 0x02, 0x67, 0x02, + 0x97, 0x01, 0x96, 0x01, 0x6a, 0x02, 0x62, 0x2c, + 0x6c, 0x02, 0x6d, 0x02, 0x6e, 0x02, 0x9c, 0x01, + 0x70, 0x02, 0x71, 0x02, 0x9d, 0x01, 0x73, 0x02, + 0x74, 0x02, 0x9f, 0x01, 0x76, 0x02, 0x77, 0x02, + 0x78, 0x02, 0x79, 0x02, 0x7a, 0x02, 0x7b, 0x02, + 0x7c, 0x02, 0x64, 0x2c, 0x7e, 0x02, 0x7f, 0x02, + 0xa6, 0x01, 0x81, 0x02, 0x82, 0x02, 0xa9, 0x01, + 0x84, 0x02, 0x85, 0x02, 0x86, 0x02, 0x87, 0x02, + 0xae, 0x01, 0x44, 0x02, 0xb1, 0x01, 0xb2, 0x01, + 0x45, 0x02, 0x8d, 0x02, 0x8e, 0x02, 0x8f, 0x02, + 0x90, 0x02, 0x91, 0x02, 0xb7, 0x01, 0x93, 0x02, + 0x94, 0x02, 0x95, 0x02, 0x96, 0x02, 0x97, 0x02, + 0x98, 0x02, 0x99, 0x02, 0x9a, 0x02, 0x9b, 0x02, + 0x9c, 0x02, 0x9d, 0x02, 0x9e, 0x02, 0x9f, 0x02, + 0xa0, 0x02, 0xa1, 0x02, 0xa2, 0x02, 0xa3, 0x02, + 0xa4, 0x02, 0xa5, 0x02, 0xa6, 0x02, 0xa7, 0x02, + 0xa8, 0x02, 0xa9, 0x02, 0xaa, 0x02, 0xab, 0x02, + 0xac, 0x02, 0xad, 0x02, 0xae, 0x02, 0xaf, 0x02, + 0xb0, 0x02, 0xb1, 0x02, 0xb2, 0x02, 0xb3, 0x02, + 0xb4, 0x02, 0xb5, 0x02, 0xb6, 0x02, 0xb7, 0x02, + 0xb8, 0x02, 0xb9, 0x02, 0xba, 0x02, 0xbb, 0x02, + 0xbc, 0x02, 0xbd, 0x02, 0xbe, 0x02, 0xbf, 0x02, + 0xc0, 0x02, 0xc1, 0x02, 0xc2, 0x02, 0xc3, 0x02, + 0xc4, 0x02, 0xc5, 0x02, 0xc6, 0x02, 0xc7, 0x02, + 0xc8, 0x02, 0xc9, 0x02, 0xca, 0x02, 0xcb, 0x02, + 0xcc, 0x02, 0xcd, 0x02, 0xce, 0x02, 0xcf, 0x02, + 0xd0, 0x02, 0xd1, 0x02, 0xd2, 0x02, 0xd3, 0x02, + 0xd4, 0x02, 0xd5, 0x02, 0xd6, 0x02, 0xd7, 0x02, + 0xd8, 0x02, 0xd9, 0x02, 0xda, 0x02, 0xdb, 0x02, + 0xdc, 0x02, 0xdd, 0x02, 0xde, 0x02, 0xdf, 0x02, + 0xe0, 0x02, 0xe1, 0x02, 0xe2, 0x02, 0xe3, 0x02, + 0xe4, 0x02, 0xe5, 0x02, 0xe6, 0x02, 0xe7, 0x02, + 0xe8, 0x02, 0xe9, 0x02, 0xea, 0x02, 0xeb, 0x02, + 0xec, 0x02, 0xed, 0x02, 0xee, 0x02, 0xef, 0x02, + 0xf0, 0x02, 0xf1, 0x02, 0xf2, 0x02, 0xf3, 0x02, + 0xf4, 0x02, 0xf5, 0x02, 0xf6, 0x02, 0xf7, 0x02, + 0xf8, 0x02, 0xf9, 0x02, 0xfa, 0x02, 0xfb, 0x02, + 0xfc, 0x02, 0xfd, 0x02, 0xfe, 0x02, 0xff, 0x02, + 0x00, 0x03, 0x01, 0x03, 0x02, 0x03, 0x03, 0x03, + 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x07, 0x03, + 0x08, 0x03, 0x09, 0x03, 0x0a, 0x03, 0x0b, 0x03, + 0x0c, 0x03, 0x0d, 0x03, 0x0e, 0x03, 0x0f, 0x03, + 0x10, 0x03, 0x11, 0x03, 0x12, 0x03, 0x13, 0x03, + 0x14, 0x03, 0x15, 0x03, 0x16, 0x03, 0x17, 0x03, + 0x18, 0x03, 0x19, 0x03, 0x1a, 0x03, 0x1b, 0x03, + 0x1c, 0x03, 0x1d, 0x03, 0x1e, 0x03, 0x1f, 0x03, + 0x20, 0x03, 0x21, 0x03, 0x22, 0x03, 0x23, 0x03, + 0x24, 0x03, 0x25, 0x03, 0x26, 0x03, 0x27, 0x03, + 0x28, 0x03, 0x29, 0x03, 0x2a, 0x03, 0x2b, 0x03, + 0x2c, 0x03, 0x2d, 0x03, 0x2e, 0x03, 0x2f, 0x03, + 0x30, 0x03, 0x31, 0x03, 0x32, 0x03, 0x33, 0x03, + 0x34, 0x03, 0x35, 0x03, 0x36, 0x03, 0x37, 0x03, + 0x38, 0x03, 0x39, 0x03, 0x3a, 0x03, 0x3b, 0x03, + 0x3c, 0x03, 0x3d, 0x03, 0x3e, 0x03, 0x3f, 0x03, + 0x40, 0x03, 0x41, 0x03, 0x42, 0x03, 0x43, 0x03, + 0x44, 0x03, 0x45, 0x03, 0x46, 0x03, 0x47, 0x03, + 0x48, 0x03, 0x49, 0x03, 0x4a, 0x03, 0x4b, 0x03, + 0x4c, 0x03, 0x4d, 0x03, 0x4e, 0x03, 0x4f, 0x03, + 0x50, 0x03, 0x51, 0x03, 0x52, 0x03, 0x53, 0x03, + 0x54, 0x03, 0x55, 0x03, 0x56, 0x03, 0x57, 0x03, + 0x58, 0x03, 0x59, 0x03, 0x5a, 0x03, 0x5b, 0x03, + 0x5c, 0x03, 0x5d, 0x03, 0x5e, 0x03, 0x5f, 0x03, + 0x60, 0x03, 0x61, 0x03, 0x62, 0x03, 0x63, 0x03, + 0x64, 0x03, 0x65, 0x03, 0x66, 0x03, 0x67, 0x03, + 0x68, 0x03, 0x69, 0x03, 0x6a, 0x03, 0x6b, 0x03, + 0x6c, 0x03, 0x6d, 0x03, 0x6e, 0x03, 0x6f, 0x03, + 0x70, 0x03, 0x71, 0x03, 0x72, 0x03, 0x73, 0x03, + 0x74, 0x03, 0x75, 0x03, 0x76, 0x03, 0x77, 0x03, + 0x78, 0x03, 0x79, 0x03, 0x7a, 0x03, 0xfd, 0x03, + 0xfe, 0x03, 0xff, 0x03, 0x7e, 0x03, 0x7f, 0x03, + 0x80, 0x03, 0x81, 0x03, 0x82, 0x03, 0x83, 0x03, + 0x84, 0x03, 0x85, 0x03, 0x86, 0x03, 0x87, 0x03, + 0x88, 0x03, 0x89, 0x03, 0x8a, 0x03, 0x8b, 0x03, + 0x8c, 0x03, 0x8d, 0x03, 0x8e, 0x03, 0x8f, 0x03, + 0x90, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, + 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9a, 0x03, 0x9b, 0x03, + 0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03, + 0xa0, 0x03, 0xa1, 0x03, 0xa2, 0x03, 0xa3, 0x03, + 0xa4, 0x03, 0xa5, 0x03, 0xa6, 0x03, 0xa7, 0x03, + 0xa8, 0x03, 0xa9, 0x03, 0xaa, 0x03, 0xab, 0x03, + 0x86, 0x03, 0x88, 0x03, 0x89, 0x03, 0x8a, 0x03, + 0xb0, 0x03, 0x91, 0x03, 0x92, 0x03, 0x93, 0x03, + 0x94, 0x03, 0x95, 0x03, 0x96, 0x03, 0x97, 0x03, + 0x98, 0x03, 0x99, 0x03, 0x9a, 0x03, 0x9b, 0x03, + 0x9c, 0x03, 0x9d, 0x03, 0x9e, 0x03, 0x9f, 0x03, + 0xa0, 0x03, 0xa1, 0x03, 0xa3, 0x03, 0xa3, 0x03, + 0xa4, 0x03, 0xa5, 0x03, 0xa6, 0x03, 0xa7, 0x03, + 0xa8, 0x03, 0xa9, 0x03, 0xaa, 0x03, 0xab, 0x03, + 0x8c, 0x03, 0x8e, 0x03, 0x8f, 0x03, 0xcf, 0x03, + 0xd0, 0x03, 0xd1, 0x03, 0xd2, 0x03, 0xd3, 0x03, + 0xd4, 0x03, 0xd5, 0x03, 0xd6, 0x03, 0xd7, 0x03, + 0xd8, 0x03, 0xd8, 0x03, 0xda, 0x03, 0xda, 0x03, + 0xdc, 0x03, 0xdc, 0x03, 0xde, 0x03, 0xde, 0x03, + 0xe0, 0x03, 0xe0, 0x03, 0xe2, 0x03, 0xe2, 0x03, + 0xe4, 0x03, 0xe4, 0x03, 0xe6, 0x03, 0xe6, 0x03, + 0xe8, 0x03, 0xe8, 0x03, 0xea, 0x03, 0xea, 0x03, + 0xec, 0x03, 0xec, 0x03, 0xee, 0x03, 0xee, 0x03, + 0xf0, 0x03, 0xf1, 0x03, 0xf9, 0x03, 0xf3, 0x03, + 0xf4, 0x03, 0xf5, 0x03, 0xf6, 0x03, 0xf7, 0x03, + 0xf7, 0x03, 0xf9, 0x03, 0xfa, 0x03, 0xfa, 0x03, + 0xfc, 0x03, 0xfd, 0x03, 0xfe, 0x03, 0xff, 0x03, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04, + 0x0c, 0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, + 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, 0x04, + 0x1c, 0x04, 0x1d, 0x04, 0x1e, 0x04, 0x1f, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, + 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2a, 0x04, 0x2b, 0x04, + 0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, 0x04, + 0x10, 0x04, 0x11, 0x04, 0x12, 0x04, 0x13, 0x04, + 0x14, 0x04, 0x15, 0x04, 0x16, 0x04, 0x17, 0x04, + 0x18, 0x04, 0x19, 0x04, 0x1a, 0x04, 0x1b, 0x04, + 0x1c, 0x04, 0x1d, 0x04, 0x1e, 0x04, 0x1f, 0x04, + 0x20, 0x04, 0x21, 0x04, 0x22, 0x04, 0x23, 0x04, + 0x24, 0x04, 0x25, 0x04, 0x26, 0x04, 0x27, 0x04, + 0x28, 0x04, 0x29, 0x04, 0x2a, 0x04, 0x2b, 0x04, + 0x2c, 0x04, 0x2d, 0x04, 0x2e, 0x04, 0x2f, 0x04, + 0x00, 0x04, 0x01, 0x04, 0x02, 0x04, 0x03, 0x04, + 0x04, 0x04, 0x05, 0x04, 0x06, 0x04, 0x07, 0x04, + 0x08, 0x04, 0x09, 0x04, 0x0a, 0x04, 0x0b, 0x04, + 0x0c, 0x04, 0x0d, 0x04, 0x0e, 0x04, 0x0f, 0x04, + 0x60, 0x04, 0x60, 0x04, 0x62, 0x04, 0x62, 0x04, + 0x64, 0x04, 0x64, 0x04, 0x66, 0x04, 0x66, 0x04, + 0x68, 0x04, 0x68, 0x04, 0x6a, 0x04, 0x6a, 0x04, + 0x6c, 0x04, 0x6c, 0x04, 0x6e, 0x04, 0x6e, 0x04, + 0x70, 0x04, 0x70, 0x04, 0x72, 0x04, 0x72, 0x04, + 0x74, 0x04, 0x74, 0x04, 0x76, 0x04, 0x76, 0x04, + 0x78, 0x04, 0x78, 0x04, 0x7a, 0x04, 0x7a, 0x04, + 0x7c, 0x04, 0x7c, 0x04, 0x7e, 0x04, 0x7e, 0x04, + 0x80, 0x04, 0x80, 0x04, 0x82, 0x04, 0x83, 0x04, + 0x84, 0x04, 0x85, 0x04, 0x86, 0x04, 0x87, 0x04, + 0x88, 0x04, 0x89, 0x04, 0x8a, 0x04, 0x8a, 0x04, + 0x8c, 0x04, 0x8c, 0x04, 0x8e, 0x04, 0x8e, 0x04, + 0x90, 0x04, 0x90, 0x04, 0x92, 0x04, 0x92, 0x04, + 0x94, 0x04, 0x94, 0x04, 0x96, 0x04, 0x96, 0x04, + 0x98, 0x04, 0x98, 0x04, 0x9a, 0x04, 0x9a, 0x04, + 0x9c, 0x04, 0x9c, 0x04, 0x9e, 0x04, 0x9e, 0x04, + 0xa0, 0x04, 0xa0, 0x04, 0xa2, 0x04, 0xa2, 0x04, + 0xa4, 0x04, 0xa4, 0x04, 0xa6, 0x04, 0xa6, 0x04, + 0xa8, 0x04, 0xa8, 0x04, 0xaa, 0x04, 0xaa, 0x04, + 0xac, 0x04, 0xac, 0x04, 0xae, 0x04, 0xae, 0x04, + 0xb0, 0x04, 0xb0, 0x04, 0xb2, 0x04, 0xb2, 0x04, + 0xb4, 0x04, 0xb4, 0x04, 0xb6, 0x04, 0xb6, 0x04, + 0xb8, 0x04, 0xb8, 0x04, 0xba, 0x04, 0xba, 0x04, + 0xbc, 0x04, 0xbc, 0x04, 0xbe, 0x04, 0xbe, 0x04, + 0xc0, 0x04, 0xc1, 0x04, 0xc1, 0x04, 0xc3, 0x04, + 0xc3, 0x04, 0xc5, 0x04, 0xc5, 0x04, 0xc7, 0x04, + 0xc7, 0x04, 0xc9, 0x04, 0xc9, 0x04, 0xcb, 0x04, + 0xcb, 0x04, 0xcd, 0x04, 0xcd, 0x04, 0xc0, 0x04, + 0xd0, 0x04, 0xd0, 0x04, 0xd2, 0x04, 0xd2, 0x04, + 0xd4, 0x04, 0xd4, 0x04, 0xd6, 0x04, 0xd6, 0x04, + 0xd8, 0x04, 0xd8, 0x04, 0xda, 0x04, 0xda, 0x04, + 0xdc, 0x04, 0xdc, 0x04, 0xde, 0x04, 0xde, 0x04, + 0xe0, 0x04, 0xe0, 0x04, 0xe2, 0x04, 0xe2, 0x04, + 0xe4, 0x04, 0xe4, 0x04, 0xe6, 0x04, 0xe6, 0x04, + 0xe8, 0x04, 0xe8, 0x04, 0xea, 0x04, 0xea, 0x04, + 0xec, 0x04, 0xec, 0x04, 0xee, 0x04, 0xee, 0x04, + 0xf0, 0x04, 0xf0, 0x04, 0xf2, 0x04, 0xf2, 0x04, + 0xf4, 0x04, 0xf4, 0x04, 0xf6, 0x04, 0xf6, 0x04, + 0xf8, 0x04, 0xf8, 0x04, 0xfa, 0x04, 0xfa, 0x04, + 0xfc, 0x04, 0xfc, 0x04, 0xfe, 0x04, 0xfe, 0x04, + 0x00, 0x05, 0x00, 0x05, 0x02, 0x05, 0x02, 0x05, + 0x04, 0x05, 0x04, 0x05, 0x06, 0x05, 0x06, 0x05, + 0x08, 0x05, 0x08, 0x05, 0x0a, 0x05, 0x0a, 0x05, + 0x0c, 0x05, 0x0c, 0x05, 0x0e, 0x05, 0x0e, 0x05, + 0x10, 0x05, 0x10, 0x05, 0x12, 0x05, 0x12, 0x05, + 0x14, 0x05, 0x15, 0x05, 0x16, 0x05, 0x17, 0x05, + 0x18, 0x05, 0x19, 0x05, 0x1a, 0x05, 0x1b, 0x05, + 0x1c, 0x05, 0x1d, 0x05, 0x1e, 0x05, 0x1f, 0x05, + 0x20, 0x05, 0x21, 0x05, 0x22, 0x05, 0x23, 0x05, + 0x24, 0x05, 0x25, 0x05, 0x26, 0x05, 0x27, 0x05, + 0x28, 0x05, 0x29, 0x05, 0x2a, 0x05, 0x2b, 0x05, + 0x2c, 0x05, 0x2d, 0x05, 0x2e, 0x05, 0x2f, 0x05, + 0x30, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, + 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3a, 0x05, 0x3b, 0x05, + 0x3c, 0x05, 0x3d, 0x05, 0x3e, 0x05, 0x3f, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, + 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4a, 0x05, 0x4b, 0x05, + 0x4c, 0x05, 0x4d, 0x05, 0x4e, 0x05, 0x4f, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, + 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0x57, 0x05, + 0x58, 0x05, 0x59, 0x05, 0x5a, 0x05, 0x5b, 0x05, + 0x5c, 0x05, 0x5d, 0x05, 0x5e, 0x05, 0x5f, 0x05, + 0x60, 0x05, 0x31, 0x05, 0x32, 0x05, 0x33, 0x05, + 0x34, 0x05, 0x35, 0x05, 0x36, 0x05, 0x37, 0x05, + 0x38, 0x05, 0x39, 0x05, 0x3a, 0x05, 0x3b, 0x05, + 0x3c, 0x05, 0x3d, 0x05, 0x3e, 0x05, 0x3f, 0x05, + 0x40, 0x05, 0x41, 0x05, 0x42, 0x05, 0x43, 0x05, + 0x44, 0x05, 0x45, 0x05, 0x46, 0x05, 0x47, 0x05, + 0x48, 0x05, 0x49, 0x05, 0x4a, 0x05, 0x4b, 0x05, + 0x4c, 0x05, 0x4d, 0x05, 0x4e, 0x05, 0x4f, 0x05, + 0x50, 0x05, 0x51, 0x05, 0x52, 0x05, 0x53, 0x05, + 0x54, 0x05, 0x55, 0x05, 0x56, 0x05, 0xff, 0xff, + 0xf6, 0x17, 0x63, 0x2c, 0x7e, 0x1d, 0x7f, 0x1d, + 0x80, 0x1d, 0x81, 0x1d, 0x82, 0x1d, 0x83, 0x1d, + 0x84, 0x1d, 0x85, 0x1d, 0x86, 0x1d, 0x87, 0x1d, + 0x88, 0x1d, 0x89, 0x1d, 0x8a, 0x1d, 0x8b, 0x1d, + 0x8c, 0x1d, 0x8d, 0x1d, 0x8e, 0x1d, 0x8f, 0x1d, + 0x90, 0x1d, 0x91, 0x1d, 0x92, 0x1d, 0x93, 0x1d, + 0x94, 0x1d, 0x95, 0x1d, 0x96, 0x1d, 0x97, 0x1d, + 0x98, 0x1d, 0x99, 0x1d, 0x9a, 0x1d, 0x9b, 0x1d, + 0x9c, 0x1d, 0x9d, 0x1d, 0x9e, 0x1d, 0x9f, 0x1d, + 0xa0, 0x1d, 0xa1, 0x1d, 0xa2, 0x1d, 0xa3, 0x1d, + 0xa4, 0x1d, 0xa5, 0x1d, 0xa6, 0x1d, 0xa7, 0x1d, + 0xa8, 0x1d, 0xa9, 0x1d, 0xaa, 0x1d, 0xab, 0x1d, + 0xac, 0x1d, 0xad, 0x1d, 0xae, 0x1d, 0xaf, 0x1d, + 0xb0, 0x1d, 0xb1, 0x1d, 0xb2, 0x1d, 0xb3, 0x1d, + 0xb4, 0x1d, 0xb5, 0x1d, 0xb6, 0x1d, 0xb7, 0x1d, + 0xb8, 0x1d, 0xb9, 0x1d, 0xba, 0x1d, 0xbb, 0x1d, + 0xbc, 0x1d, 0xbd, 0x1d, 0xbe, 0x1d, 0xbf, 0x1d, + 0xc0, 0x1d, 0xc1, 0x1d, 0xc2, 0x1d, 0xc3, 0x1d, + 0xc4, 0x1d, 0xc5, 0x1d, 0xc6, 0x1d, 0xc7, 0x1d, + 0xc8, 0x1d, 0xc9, 0x1d, 0xca, 0x1d, 0xcb, 0x1d, + 0xcc, 0x1d, 0xcd, 0x1d, 0xce, 0x1d, 0xcf, 0x1d, + 0xd0, 0x1d, 0xd1, 0x1d, 0xd2, 0x1d, 0xd3, 0x1d, + 0xd4, 0x1d, 0xd5, 0x1d, 0xd6, 0x1d, 0xd7, 0x1d, + 0xd8, 0x1d, 0xd9, 0x1d, 0xda, 0x1d, 0xdb, 0x1d, + 0xdc, 0x1d, 0xdd, 0x1d, 0xde, 0x1d, 0xdf, 0x1d, + 0xe0, 0x1d, 0xe1, 0x1d, 0xe2, 0x1d, 0xe3, 0x1d, + 0xe4, 0x1d, 0xe5, 0x1d, 0xe6, 0x1d, 0xe7, 0x1d, + 0xe8, 0x1d, 0xe9, 0x1d, 0xea, 0x1d, 0xeb, 0x1d, + 0xec, 0x1d, 0xed, 0x1d, 0xee, 0x1d, 0xef, 0x1d, + 0xf0, 0x1d, 0xf1, 0x1d, 0xf2, 0x1d, 0xf3, 0x1d, + 0xf4, 0x1d, 0xf5, 0x1d, 0xf6, 0x1d, 0xf7, 0x1d, + 0xf8, 0x1d, 0xf9, 0x1d, 0xfa, 0x1d, 0xfb, 0x1d, + 0xfc, 0x1d, 0xfd, 0x1d, 0xfe, 0x1d, 0xff, 0x1d, + 0x00, 0x1e, 0x00, 0x1e, 0x02, 0x1e, 0x02, 0x1e, + 0x04, 0x1e, 0x04, 0x1e, 0x06, 0x1e, 0x06, 0x1e, + 0x08, 0x1e, 0x08, 0x1e, 0x0a, 0x1e, 0x0a, 0x1e, + 0x0c, 0x1e, 0x0c, 0x1e, 0x0e, 0x1e, 0x0e, 0x1e, + 0x10, 0x1e, 0x10, 0x1e, 0x12, 0x1e, 0x12, 0x1e, + 0x14, 0x1e, 0x14, 0x1e, 0x16, 0x1e, 0x16, 0x1e, + 0x18, 0x1e, 0x18, 0x1e, 0x1a, 0x1e, 0x1a, 0x1e, + 0x1c, 0x1e, 0x1c, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, + 0x20, 0x1e, 0x20, 0x1e, 0x22, 0x1e, 0x22, 0x1e, + 0x24, 0x1e, 0x24, 0x1e, 0x26, 0x1e, 0x26, 0x1e, + 0x28, 0x1e, 0x28, 0x1e, 0x2a, 0x1e, 0x2a, 0x1e, + 0x2c, 0x1e, 0x2c, 0x1e, 0x2e, 0x1e, 0x2e, 0x1e, + 0x30, 0x1e, 0x30, 0x1e, 0x32, 0x1e, 0x32, 0x1e, + 0x34, 0x1e, 0x34, 0x1e, 0x36, 0x1e, 0x36, 0x1e, + 0x38, 0x1e, 0x38, 0x1e, 0x3a, 0x1e, 0x3a, 0x1e, + 0x3c, 0x1e, 0x3c, 0x1e, 0x3e, 0x1e, 0x3e, 0x1e, + 0x40, 0x1e, 0x40, 0x1e, 0x42, 0x1e, 0x42, 0x1e, + 0x44, 0x1e, 0x44, 0x1e, 0x46, 0x1e, 0x46, 0x1e, + 0x48, 0x1e, 0x48, 0x1e, 0x4a, 0x1e, 0x4a, 0x1e, + 0x4c, 0x1e, 0x4c, 0x1e, 0x4e, 0x1e, 0x4e, 0x1e, + 0x50, 0x1e, 0x50, 0x1e, 0x52, 0x1e, 0x52, 0x1e, + 0x54, 0x1e, 0x54, 0x1e, 0x56, 0x1e, 0x56, 0x1e, + 0x58, 0x1e, 0x58, 0x1e, 0x5a, 0x1e, 0x5a, 0x1e, + 0x5c, 0x1e, 0x5c, 0x1e, 0x5e, 0x1e, 0x5e, 0x1e, + 0x60, 0x1e, 0x60, 0x1e, 0x62, 0x1e, 0x62, 0x1e, + 0x64, 0x1e, 0x64, 0x1e, 0x66, 0x1e, 0x66, 0x1e, + 0x68, 0x1e, 0x68, 0x1e, 0x6a, 0x1e, 0x6a, 0x1e, + 0x6c, 0x1e, 0x6c, 0x1e, 0x6e, 0x1e, 0x6e, 0x1e, + 0x70, 0x1e, 0x70, 0x1e, 0x72, 0x1e, 0x72, 0x1e, + 0x74, 0x1e, 0x74, 0x1e, 0x76, 0x1e, 0x76, 0x1e, + 0x78, 0x1e, 0x78, 0x1e, 0x7a, 0x1e, 0x7a, 0x1e, + 0x7c, 0x1e, 0x7c, 0x1e, 0x7e, 0x1e, 0x7e, 0x1e, + 0x80, 0x1e, 0x80, 0x1e, 0x82, 0x1e, 0x82, 0x1e, + 0x84, 0x1e, 0x84, 0x1e, 0x86, 0x1e, 0x86, 0x1e, + 0x88, 0x1e, 0x88, 0x1e, 0x8a, 0x1e, 0x8a, 0x1e, + 0x8c, 0x1e, 0x8c, 0x1e, 0x8e, 0x1e, 0x8e, 0x1e, + 0x90, 0x1e, 0x90, 0x1e, 0x92, 0x1e, 0x92, 0x1e, + 0x94, 0x1e, 0x94, 0x1e, 0x96, 0x1e, 0x97, 0x1e, + 0x98, 0x1e, 0x99, 0x1e, 0x9a, 0x1e, 0x9b, 0x1e, + 0x9c, 0x1e, 0x9d, 0x1e, 0x9e, 0x1e, 0x9f, 0x1e, + 0xa0, 0x1e, 0xa0, 0x1e, 0xa2, 0x1e, 0xa2, 0x1e, + 0xa4, 0x1e, 0xa4, 0x1e, 0xa6, 0x1e, 0xa6, 0x1e, + 0xa8, 0x1e, 0xa8, 0x1e, 0xaa, 0x1e, 0xaa, 0x1e, + 0xac, 0x1e, 0xac, 0x1e, 0xae, 0x1e, 0xae, 0x1e, + 0xb0, 0x1e, 0xb0, 0x1e, 0xb2, 0x1e, 0xb2, 0x1e, + 0xb4, 0x1e, 0xb4, 0x1e, 0xb6, 0x1e, 0xb6, 0x1e, + 0xb8, 0x1e, 0xb8, 0x1e, 0xba, 0x1e, 0xba, 0x1e, + 0xbc, 0x1e, 0xbc, 0x1e, 0xbe, 0x1e, 0xbe, 0x1e, + 0xc0, 0x1e, 0xc0, 0x1e, 0xc2, 0x1e, 0xc2, 0x1e, + 0xc4, 0x1e, 0xc4, 0x1e, 0xc6, 0x1e, 0xc6, 0x1e, + 0xc8, 0x1e, 0xc8, 0x1e, 0xca, 0x1e, 0xca, 0x1e, + 0xcc, 0x1e, 0xcc, 0x1e, 0xce, 0x1e, 0xce, 0x1e, + 0xd0, 0x1e, 0xd0, 0x1e, 0xd2, 0x1e, 0xd2, 0x1e, + 0xd4, 0x1e, 0xd4, 0x1e, 0xd6, 0x1e, 0xd6, 0x1e, + 0xd8, 0x1e, 0xd8, 0x1e, 0xda, 0x1e, 0xda, 0x1e, + 0xdc, 0x1e, 0xdc, 0x1e, 0xde, 0x1e, 0xde, 0x1e, + 0xe0, 0x1e, 0xe0, 0x1e, 0xe2, 0x1e, 0xe2, 0x1e, + 0xe4, 0x1e, 0xe4, 0x1e, 0xe6, 0x1e, 0xe6, 0x1e, + 0xe8, 0x1e, 0xe8, 0x1e, 0xea, 0x1e, 0xea, 0x1e, + 0xec, 0x1e, 0xec, 0x1e, 0xee, 0x1e, 0xee, 0x1e, + 0xf0, 0x1e, 0xf0, 0x1e, 0xf2, 0x1e, 0xf2, 0x1e, + 0xf4, 0x1e, 0xf4, 0x1e, 0xf6, 0x1e, 0xf6, 0x1e, + 0xf8, 0x1e, 0xf8, 0x1e, 0xfa, 0x1e, 0xfb, 0x1e, + 0xfc, 0x1e, 0xfd, 0x1e, 0xfe, 0x1e, 0xff, 0x1e, + 0x08, 0x1f, 0x09, 0x1f, 0x0a, 0x1f, 0x0b, 0x1f, + 0x0c, 0x1f, 0x0d, 0x1f, 0x0e, 0x1f, 0x0f, 0x1f, + 0x08, 0x1f, 0x09, 0x1f, 0x0a, 0x1f, 0x0b, 0x1f, + 0x0c, 0x1f, 0x0d, 0x1f, 0x0e, 0x1f, 0x0f, 0x1f, + 0x18, 0x1f, 0x19, 0x1f, 0x1a, 0x1f, 0x1b, 0x1f, + 0x1c, 0x1f, 0x1d, 0x1f, 0x16, 0x1f, 0x17, 0x1f, + 0x18, 0x1f, 0x19, 0x1f, 0x1a, 0x1f, 0x1b, 0x1f, + 0x1c, 0x1f, 0x1d, 0x1f, 0x1e, 0x1f, 0x1f, 0x1f, + 0x28, 0x1f, 0x29, 0x1f, 0x2a, 0x1f, 0x2b, 0x1f, + 0x2c, 0x1f, 0x2d, 0x1f, 0x2e, 0x1f, 0x2f, 0x1f, + 0x28, 0x1f, 0x29, 0x1f, 0x2a, 0x1f, 0x2b, 0x1f, + 0x2c, 0x1f, 0x2d, 0x1f, 0x2e, 0x1f, 0x2f, 0x1f, + 0x38, 0x1f, 0x39, 0x1f, 0x3a, 0x1f, 0x3b, 0x1f, + 0x3c, 0x1f, 0x3d, 0x1f, 0x3e, 0x1f, 0x3f, 0x1f, + 0x38, 0x1f, 0x39, 0x1f, 0x3a, 0x1f, 0x3b, 0x1f, + 0x3c, 0x1f, 0x3d, 0x1f, 0x3e, 0x1f, 0x3f, 0x1f, + 0x48, 0x1f, 0x49, 0x1f, 0x4a, 0x1f, 0x4b, 0x1f, + 0x4c, 0x1f, 0x4d, 0x1f, 0x46, 0x1f, 0x47, 0x1f, + 0x48, 0x1f, 0x49, 0x1f, 0x4a, 0x1f, 0x4b, 0x1f, + 0x4c, 0x1f, 0x4d, 0x1f, 0x4e, 0x1f, 0x4f, 0x1f, + 0x50, 0x1f, 0x59, 0x1f, 0x52, 0x1f, 0x5b, 0x1f, + 0x54, 0x1f, 0x5d, 0x1f, 0x56, 0x1f, 0x5f, 0x1f, + 0x58, 0x1f, 0x59, 0x1f, 0x5a, 0x1f, 0x5b, 0x1f, + 0x5c, 0x1f, 0x5d, 0x1f, 0x5e, 0x1f, 0x5f, 0x1f, + 0x68, 0x1f, 0x69, 0x1f, 0x6a, 0x1f, 0x6b, 0x1f, + 0x6c, 0x1f, 0x6d, 0x1f, 0x6e, 0x1f, 0x6f, 0x1f, + 0x68, 0x1f, 0x69, 0x1f, 0x6a, 0x1f, 0x6b, 0x1f, + 0x6c, 0x1f, 0x6d, 0x1f, 0x6e, 0x1f, 0x6f, 0x1f, + 0xba, 0x1f, 0xbb, 0x1f, 0xc8, 0x1f, 0xc9, 0x1f, + 0xca, 0x1f, 0xcb, 0x1f, 0xda, 0x1f, 0xdb, 0x1f, + 0xf8, 0x1f, 0xf9, 0x1f, 0xea, 0x1f, 0xeb, 0x1f, + 0xfa, 0x1f, 0xfb, 0x1f, 0x7e, 0x1f, 0x7f, 0x1f, + 0x88, 0x1f, 0x89, 0x1f, 0x8a, 0x1f, 0x8b, 0x1f, + 0x8c, 0x1f, 0x8d, 0x1f, 0x8e, 0x1f, 0x8f, 0x1f, + 0x88, 0x1f, 0x89, 0x1f, 0x8a, 0x1f, 0x8b, 0x1f, + 0x8c, 0x1f, 0x8d, 0x1f, 0x8e, 0x1f, 0x8f, 0x1f, + 0x98, 0x1f, 0x99, 0x1f, 0x9a, 0x1f, 0x9b, 0x1f, + 0x9c, 0x1f, 0x9d, 0x1f, 0x9e, 0x1f, 0x9f, 0x1f, + 0x98, 0x1f, 0x99, 0x1f, 0x9a, 0x1f, 0x9b, 0x1f, + 0x9c, 0x1f, 0x9d, 0x1f, 0x9e, 0x1f, 0x9f, 0x1f, + 0xa8, 0x1f, 0xa9, 0x1f, 0xaa, 0x1f, 0xab, 0x1f, + 0xac, 0x1f, 0xad, 0x1f, 0xae, 0x1f, 0xaf, 0x1f, + 0xa8, 0x1f, 0xa9, 0x1f, 0xaa, 0x1f, 0xab, 0x1f, + 0xac, 0x1f, 0xad, 0x1f, 0xae, 0x1f, 0xaf, 0x1f, + 0xb8, 0x1f, 0xb9, 0x1f, 0xb2, 0x1f, 0xbc, 0x1f, + 0xb4, 0x1f, 0xb5, 0x1f, 0xb6, 0x1f, 0xb7, 0x1f, + 0xb8, 0x1f, 0xb9, 0x1f, 0xba, 0x1f, 0xbb, 0x1f, + 0xbc, 0x1f, 0xbd, 0x1f, 0xbe, 0x1f, 0xbf, 0x1f, + 0xc0, 0x1f, 0xc1, 0x1f, 0xc2, 0x1f, 0xc3, 0x1f, + 0xc4, 0x1f, 0xc5, 0x1f, 0xc6, 0x1f, 0xc7, 0x1f, + 0xc8, 0x1f, 0xc9, 0x1f, 0xca, 0x1f, 0xcb, 0x1f, + 0xc3, 0x1f, 0xcd, 0x1f, 0xce, 0x1f, 0xcf, 0x1f, + 0xd8, 0x1f, 0xd9, 0x1f, 0xd2, 0x1f, 0xd3, 0x1f, + 0xd4, 0x1f, 0xd5, 0x1f, 0xd6, 0x1f, 0xd7, 0x1f, + 0xd8, 0x1f, 0xd9, 0x1f, 0xda, 0x1f, 0xdb, 0x1f, + 0xdc, 0x1f, 0xdd, 0x1f, 0xde, 0x1f, 0xdf, 0x1f, + 0xe8, 0x1f, 0xe9, 0x1f, 0xe2, 0x1f, 0xe3, 0x1f, + 0xe4, 0x1f, 0xec, 0x1f, 0xe6, 0x1f, 0xe7, 0x1f, + 0xe8, 0x1f, 0xe9, 0x1f, 0xea, 0x1f, 0xeb, 0x1f, + 0xec, 0x1f, 0xed, 0x1f, 0xee, 0x1f, 0xef, 0x1f, + 0xf0, 0x1f, 0xf1, 0x1f, 0xf2, 0x1f, 0xf3, 0x1f, + 0xf4, 0x1f, 0xf5, 0x1f, 0xf6, 0x1f, 0xf7, 0x1f, + 0xf8, 0x1f, 0xf9, 0x1f, 0xfa, 0x1f, 0xfb, 0x1f, + 0xf3, 0x1f, 0xfd, 0x1f, 0xfe, 0x1f, 0xff, 0x1f, + 0x00, 0x20, 0x01, 0x20, 0x02, 0x20, 0x03, 0x20, + 0x04, 0x20, 0x05, 0x20, 0x06, 0x20, 0x07, 0x20, + 0x08, 0x20, 0x09, 0x20, 0x0a, 0x20, 0x0b, 0x20, + 0x0c, 0x20, 0x0d, 0x20, 0x0e, 0x20, 0x0f, 0x20, + 0x10, 0x20, 0x11, 0x20, 0x12, 0x20, 0x13, 0x20, + 0x14, 0x20, 0x15, 0x20, 0x16, 0x20, 0x17, 0x20, + 0x18, 0x20, 0x19, 0x20, 0x1a, 0x20, 0x1b, 0x20, + 0x1c, 0x20, 0x1d, 0x20, 0x1e, 0x20, 0x1f, 0x20, + 0x20, 0x20, 0x21, 0x20, 0x22, 0x20, 0x23, 0x20, + 0x24, 0x20, 0x25, 0x20, 0x26, 0x20, 0x27, 0x20, + 0x28, 0x20, 0x29, 0x20, 0x2a, 0x20, 0x2b, 0x20, + 0x2c, 0x20, 0x2d, 0x20, 0x2e, 0x20, 0x2f, 0x20, + 0x30, 0x20, 0x31, 0x20, 0x32, 0x20, 0x33, 0x20, + 0x34, 0x20, 0x35, 0x20, 0x36, 0x20, 0x37, 0x20, + 0x38, 0x20, 0x39, 0x20, 0x3a, 0x20, 0x3b, 0x20, + 0x3c, 0x20, 0x3d, 0x20, 0x3e, 0x20, 0x3f, 0x20, + 0x40, 0x20, 0x41, 0x20, 0x42, 0x20, 0x43, 0x20, + 0x44, 0x20, 0x45, 0x20, 0x46, 0x20, 0x47, 0x20, + 0x48, 0x20, 0x49, 0x20, 0x4a, 0x20, 0x4b, 0x20, + 0x4c, 0x20, 0x4d, 0x20, 0x4e, 0x20, 0x4f, 0x20, + 0x50, 0x20, 0x51, 0x20, 0x52, 0x20, 0x53, 0x20, + 0x54, 0x20, 0x55, 0x20, 0x56, 0x20, 0x57, 0x20, + 0x58, 0x20, 0x59, 0x20, 0x5a, 0x20, 0x5b, 0x20, + 0x5c, 0x20, 0x5d, 0x20, 0x5e, 0x20, 0x5f, 0x20, + 0x60, 0x20, 0x61, 0x20, 0x62, 0x20, 0x63, 0x20, + 0x64, 0x20, 0x65, 0x20, 0x66, 0x20, 0x67, 0x20, + 0x68, 0x20, 0x69, 0x20, 0x6a, 0x20, 0x6b, 0x20, + 0x6c, 0x20, 0x6d, 0x20, 0x6e, 0x20, 0x6f, 0x20, + 0x70, 0x20, 0x71, 0x20, 0x72, 0x20, 0x73, 0x20, + 0x74, 0x20, 0x75, 0x20, 0x76, 0x20, 0x77, 0x20, + 0x78, 0x20, 0x79, 0x20, 0x7a, 0x20, 0x7b, 0x20, + 0x7c, 0x20, 0x7d, 0x20, 0x7e, 0x20, 0x7f, 0x20, + 0x80, 0x20, 0x81, 0x20, 0x82, 0x20, 0x83, 0x20, + 0x84, 0x20, 0x85, 0x20, 0x86, 0x20, 0x87, 0x20, + 0x88, 0x20, 0x89, 0x20, 0x8a, 0x20, 0x8b, 0x20, + 0x8c, 0x20, 0x8d, 0x20, 0x8e, 0x20, 0x8f, 0x20, + 0x90, 0x20, 0x91, 0x20, 0x92, 0x20, 0x93, 0x20, + 0x94, 0x20, 0x95, 0x20, 0x96, 0x20, 0x97, 0x20, + 0x98, 0x20, 0x99, 0x20, 0x9a, 0x20, 0x9b, 0x20, + 0x9c, 0x20, 0x9d, 0x20, 0x9e, 0x20, 0x9f, 0x20, + 0xa0, 0x20, 0xa1, 0x20, 0xa2, 0x20, 0xa3, 0x20, + 0xa4, 0x20, 0xa5, 0x20, 0xa6, 0x20, 0xa7, 0x20, + 0xa8, 0x20, 0xa9, 0x20, 0xaa, 0x20, 0xab, 0x20, + 0xac, 0x20, 0xad, 0x20, 0xae, 0x20, 0xaf, 0x20, + 0xb0, 0x20, 0xb1, 0x20, 0xb2, 0x20, 0xb3, 0x20, + 0xb4, 0x20, 0xb5, 0x20, 0xb6, 0x20, 0xb7, 0x20, + 0xb8, 0x20, 0xb9, 0x20, 0xba, 0x20, 0xbb, 0x20, + 0xbc, 0x20, 0xbd, 0x20, 0xbe, 0x20, 0xbf, 0x20, + 0xc0, 0x20, 0xc1, 0x20, 0xc2, 0x20, 0xc3, 0x20, + 0xc4, 0x20, 0xc5, 0x20, 0xc6, 0x20, 0xc7, 0x20, + 0xc8, 0x20, 0xc9, 0x20, 0xca, 0x20, 0xcb, 0x20, + 0xcc, 0x20, 0xcd, 0x20, 0xce, 0x20, 0xcf, 0x20, + 0xd0, 0x20, 0xd1, 0x20, 0xd2, 0x20, 0xd3, 0x20, + 0xd4, 0x20, 0xd5, 0x20, 0xd6, 0x20, 0xd7, 0x20, + 0xd8, 0x20, 0xd9, 0x20, 0xda, 0x20, 0xdb, 0x20, + 0xdc, 0x20, 0xdd, 0x20, 0xde, 0x20, 0xdf, 0x20, + 0xe0, 0x20, 0xe1, 0x20, 0xe2, 0x20, 0xe3, 0x20, + 0xe4, 0x20, 0xe5, 0x20, 0xe6, 0x20, 0xe7, 0x20, + 0xe8, 0x20, 0xe9, 0x20, 0xea, 0x20, 0xeb, 0x20, + 0xec, 0x20, 0xed, 0x20, 0xee, 0x20, 0xef, 0x20, + 0xf0, 0x20, 0xf1, 0x20, 0xf2, 0x20, 0xf3, 0x20, + 0xf4, 0x20, 0xf5, 0x20, 0xf6, 0x20, 0xf7, 0x20, + 0xf8, 0x20, 0xf9, 0x20, 0xfa, 0x20, 0xfb, 0x20, + 0xfc, 0x20, 0xfd, 0x20, 0xfe, 0x20, 0xff, 0x20, + 0x00, 0x21, 0x01, 0x21, 0x02, 0x21, 0x03, 0x21, + 0x04, 0x21, 0x05, 0x21, 0x06, 0x21, 0x07, 0x21, + 0x08, 0x21, 0x09, 0x21, 0x0a, 0x21, 0x0b, 0x21, + 0x0c, 0x21, 0x0d, 0x21, 0x0e, 0x21, 0x0f, 0x21, + 0x10, 0x21, 0x11, 0x21, 0x12, 0x21, 0x13, 0x21, + 0x14, 0x21, 0x15, 0x21, 0x16, 0x21, 0x17, 0x21, + 0x18, 0x21, 0x19, 0x21, 0x1a, 0x21, 0x1b, 0x21, + 0x1c, 0x21, 0x1d, 0x21, 0x1e, 0x21, 0x1f, 0x21, + 0x20, 0x21, 0x21, 0x21, 0x22, 0x21, 0x23, 0x21, + 0x24, 0x21, 0x25, 0x21, 0x26, 0x21, 0x27, 0x21, + 0x28, 0x21, 0x29, 0x21, 0x2a, 0x21, 0x2b, 0x21, + 0x2c, 0x21, 0x2d, 0x21, 0x2e, 0x21, 0x2f, 0x21, + 0x30, 0x21, 0x31, 0x21, 0x32, 0x21, 0x33, 0x21, + 0x34, 0x21, 0x35, 0x21, 0x36, 0x21, 0x37, 0x21, + 0x38, 0x21, 0x39, 0x21, 0x3a, 0x21, 0x3b, 0x21, + 0x3c, 0x21, 0x3d, 0x21, 0x3e, 0x21, 0x3f, 0x21, + 0x40, 0x21, 0x41, 0x21, 0x42, 0x21, 0x43, 0x21, + 0x44, 0x21, 0x45, 0x21, 0x46, 0x21, 0x47, 0x21, + 0x48, 0x21, 0x49, 0x21, 0x4a, 0x21, 0x4b, 0x21, + 0x4c, 0x21, 0x4d, 0x21, 0x32, 0x21, 0x4f, 0x21, + 0x50, 0x21, 0x51, 0x21, 0x52, 0x21, 0x53, 0x21, + 0x54, 0x21, 0x55, 0x21, 0x56, 0x21, 0x57, 0x21, + 0x58, 0x21, 0x59, 0x21, 0x5a, 0x21, 0x5b, 0x21, + 0x5c, 0x21, 0x5d, 0x21, 0x5e, 0x21, 0x5f, 0x21, + 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, + 0x68, 0x21, 0x69, 0x21, 0x6a, 0x21, 0x6b, 0x21, + 0x6c, 0x21, 0x6d, 0x21, 0x6e, 0x21, 0x6f, 0x21, + 0x60, 0x21, 0x61, 0x21, 0x62, 0x21, 0x63, 0x21, + 0x64, 0x21, 0x65, 0x21, 0x66, 0x21, 0x67, 0x21, + 0x68, 0x21, 0x69, 0x21, 0x6a, 0x21, 0x6b, 0x21, + 0x6c, 0x21, 0x6d, 0x21, 0x6e, 0x21, 0x6f, 0x21, + 0x80, 0x21, 0x81, 0x21, 0x82, 0x21, 0x83, 0x21, + 0x83, 0x21, 0xff, 0xff, 0x4b, 0x03, 0xb6, 0x24, + 0xb7, 0x24, 0xb8, 0x24, 0xb9, 0x24, 0xba, 0x24, + 0xbb, 0x24, 0xbc, 0x24, 0xbd, 0x24, 0xbe, 0x24, + 0xbf, 0x24, 0xc0, 0x24, 0xc1, 0x24, 0xc2, 0x24, + 0xc3, 0x24, 0xc4, 0x24, 0xc5, 0x24, 0xc6, 0x24, + 0xc7, 0x24, 0xc8, 0x24, 0xc9, 0x24, 0xca, 0x24, + 0xcb, 0x24, 0xcc, 0x24, 0xcd, 0x24, 0xce, 0x24, + 0xcf, 0x24, 0xff, 0xff, 0x46, 0x07, 0x00, 0x2c, + 0x01, 0x2c, 0x02, 0x2c, 0x03, 0x2c, 0x04, 0x2c, + 0x05, 0x2c, 0x06, 0x2c, 0x07, 0x2c, 0x08, 0x2c, + 0x09, 0x2c, 0x0a, 0x2c, 0x0b, 0x2c, 0x0c, 0x2c, + 0x0d, 0x2c, 0x0e, 0x2c, 0x0f, 0x2c, 0x10, 0x2c, + 0x11, 0x2c, 0x12, 0x2c, 0x13, 0x2c, 0x14, 0x2c, + 0x15, 0x2c, 0x16, 0x2c, 0x17, 0x2c, 0x18, 0x2c, + 0x19, 0x2c, 0x1a, 0x2c, 0x1b, 0x2c, 0x1c, 0x2c, + 0x1d, 0x2c, 0x1e, 0x2c, 0x1f, 0x2c, 0x20, 0x2c, + 0x21, 0x2c, 0x22, 0x2c, 0x23, 0x2c, 0x24, 0x2c, + 0x25, 0x2c, 0x26, 0x2c, 0x27, 0x2c, 0x28, 0x2c, + 0x29, 0x2c, 0x2a, 0x2c, 0x2b, 0x2c, 0x2c, 0x2c, + 0x2d, 0x2c, 0x2e, 0x2c, 0x5f, 0x2c, 0x60, 0x2c, + 0x60, 0x2c, 0x62, 0x2c, 0x63, 0x2c, 0x64, 0x2c, + 0x65, 0x2c, 0x66, 0x2c, 0x67, 0x2c, 0x67, 0x2c, + 0x69, 0x2c, 0x69, 0x2c, 0x6b, 0x2c, 0x6b, 0x2c, + 0x6d, 0x2c, 0x6e, 0x2c, 0x6f, 0x2c, 0x70, 0x2c, + 0x71, 0x2c, 0x72, 0x2c, 0x73, 0x2c, 0x74, 0x2c, + 0x75, 0x2c, 0x75, 0x2c, 0x77, 0x2c, 0x78, 0x2c, + 0x79, 0x2c, 0x7a, 0x2c, 0x7b, 0x2c, 0x7c, 0x2c, + 0x7d, 0x2c, 0x7e, 0x2c, 0x7f, 0x2c, 0x80, 0x2c, + 0x80, 0x2c, 0x82, 0x2c, 0x82, 0x2c, 0x84, 0x2c, + 0x84, 0x2c, 0x86, 0x2c, 0x86, 0x2c, 0x88, 0x2c, + 0x88, 0x2c, 0x8a, 0x2c, 0x8a, 0x2c, 0x8c, 0x2c, + 0x8c, 0x2c, 0x8e, 0x2c, 0x8e, 0x2c, 0x90, 0x2c, + 0x90, 0x2c, 0x92, 0x2c, 0x92, 0x2c, 0x94, 0x2c, + 0x94, 0x2c, 0x96, 0x2c, 0x96, 0x2c, 0x98, 0x2c, + 0x98, 0x2c, 0x9a, 0x2c, 0x9a, 0x2c, 0x9c, 0x2c, + 0x9c, 0x2c, 0x9e, 0x2c, 0x9e, 0x2c, 0xa0, 0x2c, + 0xa0, 0x2c, 0xa2, 0x2c, 0xa2, 0x2c, 0xa4, 0x2c, + 0xa4, 0x2c, 0xa6, 0x2c, 0xa6, 0x2c, 0xa8, 0x2c, + 0xa8, 0x2c, 0xaa, 0x2c, 0xaa, 0x2c, 0xac, 0x2c, + 0xac, 0x2c, 0xae, 0x2c, 0xae, 0x2c, 0xb0, 0x2c, + 0xb0, 0x2c, 0xb2, 0x2c, 0xb2, 0x2c, 0xb4, 0x2c, + 0xb4, 0x2c, 0xb6, 0x2c, 0xb6, 0x2c, 0xb8, 0x2c, + 0xb8, 0x2c, 0xba, 0x2c, 0xba, 0x2c, 0xbc, 0x2c, + 0xbc, 0x2c, 0xbe, 0x2c, 0xbe, 0x2c, 0xc0, 0x2c, + 0xc0, 0x2c, 0xc2, 0x2c, 0xc2, 0x2c, 0xc4, 0x2c, + 0xc4, 0x2c, 0xc6, 0x2c, 0xc6, 0x2c, 0xc8, 0x2c, + 0xc8, 0x2c, 0xca, 0x2c, 0xca, 0x2c, 0xcc, 0x2c, + 0xcc, 0x2c, 0xce, 0x2c, 0xce, 0x2c, 0xd0, 0x2c, + 0xd0, 0x2c, 0xd2, 0x2c, 0xd2, 0x2c, 0xd4, 0x2c, + 0xd4, 0x2c, 0xd6, 0x2c, 0xd6, 0x2c, 0xd8, 0x2c, + 0xd8, 0x2c, 0xda, 0x2c, 0xda, 0x2c, 0xdc, 0x2c, + 0xdc, 0x2c, 0xde, 0x2c, 0xde, 0x2c, 0xe0, 0x2c, + 0xe0, 0x2c, 0xe2, 0x2c, 0xe2, 0x2c, 0xe4, 0x2c, + 0xe5, 0x2c, 0xe6, 0x2c, 0xe7, 0x2c, 0xe8, 0x2c, + 0xe9, 0x2c, 0xea, 0x2c, 0xeb, 0x2c, 0xec, 0x2c, + 0xed, 0x2c, 0xee, 0x2c, 0xef, 0x2c, 0xf0, 0x2c, + 0xf1, 0x2c, 0xf2, 0x2c, 0xf3, 0x2c, 0xf4, 0x2c, + 0xf5, 0x2c, 0xf6, 0x2c, 0xf7, 0x2c, 0xf8, 0x2c, + 0xf9, 0x2c, 0xfa, 0x2c, 0xfb, 0x2c, 0xfc, 0x2c, + 0xfd, 0x2c, 0xfe, 0x2c, 0xff, 0x2c, 0xa0, 0x10, + 0xa1, 0x10, 0xa2, 0x10, 0xa3, 0x10, 0xa4, 0x10, + 0xa5, 0x10, 0xa6, 0x10, 0xa7, 0x10, 0xa8, 0x10, + 0xa9, 0x10, 0xaa, 0x10, 0xab, 0x10, 0xac, 0x10, + 0xad, 0x10, 0xae, 0x10, 0xaf, 0x10, 0xb0, 0x10, + 0xb1, 0x10, 0xb2, 0x10, 0xb3, 0x10, 0xb4, 0x10, + 0xb5, 0x10, 0xb6, 0x10, 0xb7, 0x10, 0xb8, 0x10, + 0xb9, 0x10, 0xba, 0x10, 0xbb, 0x10, 0xbc, 0x10, + 0xbd, 0x10, 0xbe, 0x10, 0xbf, 0x10, 0xc0, 0x10, + 0xc1, 0x10, 0xc2, 0x10, 0xc3, 0x10, 0xc4, 0x10, + 0xc5, 0x10, 0xff, 0xff, 0x1b, 0xd2, 0x21, 0xff, + 0x22, 0xff, 0x23, 0xff, 0x24, 0xff, 0x25, 0xff, + 0x26, 0xff, 0x27, 0xff, 0x28, 0xff, 0x29, 0xff, + 0x2a, 0xff, 0x2b, 0xff, 0x2c, 0xff, 0x2d, 0xff, + 0x2e, 0xff, 0x2f, 0xff, 0x30, 0xff, 0x31, 0xff, + 0x32, 0xff, 0x33, 0xff, 0x34, 0xff, 0x35, 0xff, + 0x36, 0xff, 0x37, 0xff, 0x38, 0xff, 0x39, 0xff, + 0x3a, 0xff, 0x5b, 0xff, 0x5c, 0xff, 0x5d, 0xff, + 0x5e, 0xff, 0x5f, 0xff, 0x60, 0xff, 0x61, 0xff, + 0x62, 0xff, 0x63, 0xff, 0x64, 0xff, 0x65, 0xff, + 0x66, 0xff, 0x67, 0xff, 0x68, 0xff, 0x69, 0xff, + 0x6a, 0xff, 0x6b, 0xff, 0x6c, 0xff, 0x6d, 0xff, + 0x6e, 0xff, 0x6f, 0xff, 0x70, 0xff, 0x71, 0xff, + 0x72, 0xff, 0x73, 0xff, 0x74, 0xff, 0x75, 0xff, + 0x76, 0xff, 0x77, 0xff, 0x78, 0xff, 0x79, 0xff, + 0x7a, 0xff, 0x7b, 0xff, 0x7c, 0xff, 0x7d, 0xff, + 0x7e, 0xff, 0x7f, 0xff, 0x80, 0xff, 0x81, 0xff, + 0x82, 0xff, 0x83, 0xff, 0x84, 0xff, 0x85, 0xff, + 0x86, 0xff, 0x87, 0xff, 0x88, 0xff, 0x89, 0xff, + 0x8a, 0xff, 0x8b, 0xff, 0x8c, 0xff, 0x8d, 0xff, + 0x8e, 0xff, 0x8f, 0xff, 0x90, 0xff, 0x91, 0xff, + 0x92, 0xff, 0x93, 0xff, 0x94, 0xff, 0x95, 0xff, + 0x96, 0xff, 0x97, 0xff, 0x98, 0xff, 0x99, 0xff, + 0x9a, 0xff, 0x9b, 0xff, 0x9c, 0xff, 0x9d, 0xff, + 0x9e, 0xff, 0x9f, 0xff, 0xa0, 0xff, 0xa1, 0xff, + 0xa2, 0xff, 0xa3, 0xff, 0xa4, 0xff, 0xa5, 0xff, + 0xa6, 0xff, 0xa7, 0xff, 0xa8, 0xff, 0xa9, 0xff, + 0xaa, 0xff, 0xab, 0xff, 0xac, 0xff, 0xad, 0xff, + 0xae, 0xff, 0xaf, 0xff, 0xb0, 0xff, 0xb1, 0xff, + 0xb2, 0xff, 0xb3, 0xff, 0xb4, 0xff, 0xb5, 0xff, + 0xb6, 0xff, 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xff, + 0xba, 0xff, 0xbb, 0xff, 0xbc, 0xff, 0xbd, 0xff, + 0xbe, 0xff, 0xbf, 0xff, 0xc0, 0xff, 0xc1, 0xff, + 0xc2, 0xff, 0xc3, 0xff, 0xc4, 0xff, 0xc5, 0xff, + 0xc6, 0xff, 0xc7, 0xff, 0xc8, 0xff, 0xc9, 0xff, + 0xca, 0xff, 0xcb, 0xff, 0xcc, 0xff, 0xcd, 0xff, + 0xce, 0xff, 0xcf, 0xff, 0xd0, 0xff, 0xd1, 0xff, + 0xd2, 0xff, 0xd3, 0xff, 0xd4, 0xff, 0xd5, 0xff, + 0xd6, 0xff, 0xd7, 0xff, 0xd8, 0xff, 0xd9, 0xff, + 0xda, 0xff, 0xdb, 0xff, 0xdc, 0xff, 0xdd, 0xff, + 0xde, 0xff, 0xdf, 0xff, 0xe0, 0xff, 0xe1, 0xff, + 0xe2, 0xff, 0xe3, 0xff, 0xe4, 0xff, 0xe5, 0xff, + 0xe6, 0xff, 0xe7, 0xff, 0xe8, 0xff, 0xe9, 0xff, + 0xea, 0xff, 0xeb, 0xff, 0xec, 0xff, 0xed, 0xff, + 0xee, 0xff, 0xef, 0xff, 0xf0, 0xff, 0xf1, 0xff, + 0xf2, 0xff, 0xf3, 0xff, 0xf4, 0xff, 0xf5, 0xff, + 0xf6, 0xff, 0xf7, 0xff, 0xf8, 0xff, 0xf9, 0xff, + 0xfa, 0xff, 0xfb, 0xff, 0xfc, 0xff, 0xfd, 0xff, + 0xfe, 0xff, 0xff, 0xff +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h new file mode 100644 index 00000000..bd5ebb29 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h @@ -0,0 +1,30 @@ +/* + uctc.h (30.10.10) + Upper Case Table declaration. + + Free exFAT implementation. + Copyright (C) 2011-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 MKFS_UCTC_H_INCLUDED +#define MKFS_UCTC_H_INCLUDED + +#include + +extern uint8_t upcase_table[5836]; + +#endif /* ifndef MKFS_UCTC_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c new file mode 100644 index 00000000..e40081fa --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c @@ -0,0 +1,148 @@ +/* + vbr.c (09.11.10) + Volume Boot Record creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 "vbr.h" +#include "fat.h" +#include "cbm.h" +#include "uct.h" +#include "rootdir.h" +#include + +static off_t vbr_alignment(void) +{ + return get_sector_size(); +} + +static off_t vbr_size(void) +{ + return 12 * get_sector_size(); +} + +static void init_sb(struct exfat_super_block* sb) +{ + uint32_t clusters_max; + uint32_t fat_sectors; + + clusters_max = get_volume_size() / get_cluster_size(); + fat_sectors = DIV_ROUND_UP((off_t) clusters_max * sizeof(cluster_t), + get_sector_size()); + + memset(sb, 0, sizeof(struct exfat_super_block)); + sb->jump[0] = 0xeb; + sb->jump[1] = 0x76; + sb->jump[2] = 0x90; + memcpy(sb->oem_name, "EXFAT ", sizeof(sb->oem_name)); + sb->sector_start = cpu_to_le64(get_first_sector()); + sb->sector_count = cpu_to_le64(get_volume_size() / get_sector_size()); + sb->fat_sector_start = cpu_to_le32( + fat.get_alignment() / get_sector_size()); + sb->fat_sector_count = cpu_to_le32(ROUND_UP( + le32_to_cpu(sb->fat_sector_start) + fat_sectors, + 1 << get_spc_bits()) - + le32_to_cpu(sb->fat_sector_start)); + sb->cluster_sector_start = cpu_to_le32( + get_position(&cbm) / get_sector_size()); + sb->cluster_count = cpu_to_le32(clusters_max - + ((le32_to_cpu(sb->fat_sector_start) + + le32_to_cpu(sb->fat_sector_count)) >> get_spc_bits())); + sb->rootdir_cluster = cpu_to_le32( + (get_position(&rootdir) - get_position(&cbm)) / get_cluster_size() + + EXFAT_FIRST_DATA_CLUSTER); + sb->volume_serial = cpu_to_le32(get_volume_serial()); + sb->version.major = 1; + sb->version.minor = 0; + sb->volume_state = cpu_to_le16(0); + sb->sector_bits = get_sector_bits(); + sb->spc_bits = get_spc_bits(); + sb->fat_count = 1; + sb->drive_no = 0x80; + sb->allocated_percent = 0; + sb->boot_signature = cpu_to_le16(0xaa55); +} + +static int vbr_write(struct exfat_dev* dev) +{ + struct exfat_super_block sb; + uint32_t checksum; + le32_t* sector = malloc(get_sector_size()); + size_t i; + + if (sector == NULL) + { + exfat_error("failed to allocate sector-sized block of memory"); + return 1; + } + + init_sb(&sb); + if (exfat_write(dev, &sb, sizeof(struct exfat_super_block)) < 0) + { + free(sector); + exfat_error("failed to write super block sector"); + return 1; + } + checksum = exfat_vbr_start_checksum(&sb, sizeof(struct exfat_super_block)); + + memset(sector, 0, get_sector_size()); + sector[get_sector_size() / sizeof(sector[0]) - 1] = + cpu_to_le32(0xaa550000); + for (i = 0; i < 8; i++) + { + if (exfat_write(dev, sector, get_sector_size()) < 0) + { + free(sector); + exfat_error("failed to write a sector with boot signature"); + return 1; + } + checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum); + } + + memset(sector, 0, get_sector_size()); + for (i = 0; i < 2; i++) + { + if (exfat_write(dev, sector, get_sector_size()) < 0) + { + free(sector); + exfat_error("failed to write an empty sector"); + return 1; + } + checksum = exfat_vbr_add_checksum(sector, get_sector_size(), checksum); + } + + for (i = 0; i < get_sector_size() / sizeof(sector[0]); i++) + sector[i] = cpu_to_le32(checksum); + if (exfat_write(dev, sector, get_sector_size()) < 0) + { + free(sector); + exfat_error("failed to write checksum sector"); + return 1; + } + + free(sector); + return 0; +} + +const struct fs_object vbr = +{ + .get_alignment = vbr_alignment, + .get_size = vbr_size, + .write = vbr_write, +}; diff --git a/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h new file mode 100644 index 00000000..c1f59a60 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h @@ -0,0 +1,30 @@ +/* + vbr.h (09.11.10) + Volume Boot Record creation code. + + Free exFAT implementation. + Copyright (C) 2011-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 MKFS_VBR_H_INCLUDED +#define MKFS_VBR_H_INCLUDED + +#include "mkexfat.h" + +extern const struct fs_object vbr; + +#endif /* ifndef MKFS_VBR_H_INCLUDED */ diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/API.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/API.txt new file mode 100644 index 00000000..61fc1647 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/API.txt @@ -0,0 +1,22 @@ +File IO Lib API +-=-=-=-=-=-=-=-=- + +void fl_init(void) + + Called to initialize FAT IO library. + This should be called prior to any other functions. + +void fl_attach_locks(void (*lock)(void), void (*unlock)(void)) + + [Optional] File system thread safety locking functions. + For thread safe operation, you should provide lock() and unlock() functions. + Note that locking primitive used must support recursive locking, i.e lock() called within an already ‘locked’ region. + +int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr) + + This function is used to attach system specific disk/media access functions. + This should be done subsequent to calling fl_init() and fl_attach_locks() (if locking required). + +void fl_shutdown(void) + + Shutdown the FAT IO library. This purges any un-saved data back to disk. diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/COPYRIGHT.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/COPYRIGHT.txt new file mode 100644 index 00000000..4335f7fb --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/COPYRIGHT.txt @@ -0,0 +1,345 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Configuration.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Configuration.txt new file mode 100644 index 00000000..9ec576e4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Configuration.txt @@ -0,0 +1,53 @@ +File IO Lib Options +-=-=-=-=-=-=-=-=-=- + +See defines in fat_opts.h: + +FATFS_IS_LITTLE_ENDIAN [1/0] + Which endian is your system? Set to 1 for little endian, 0 for big endian. + +FATFS_MAX_LONG_FILENAME [260] + By default, 260 characters (max LFN length). Increase this to support greater path depths. + +FATFS_MAX_OPEN_FILES + The more files you wish to have concurrently open, the greater this number should be. + This increases the number of FL_FILE file structures in the library, each of these is around 1K in size (assuming 512 byte sectors). + +FAT_BUFFER_SECTORS + Minimum is 1, more increases performance. + This defines how many FAT sectors can be buffered per FAT_BUFFER entry. + +FAT_BUFFERS + Minimum is 1, more increases performance. + This defines how many FAT buffer entries are available. + Memory usage is FAT_BUFFERS * FAT_BUFFER_SECTORS * FAT_SECTOR_SIZE + +FATFS_INC_WRITE_SUPPORT + Support file write functionality. + +FAT_SECTOR_SIZE + Sector size used by buffers. Most likely to be 512 bytes (standard for ATA/IDE). + +FAT_PRINTF + A define that allows the File IO library to print to console/stdout. + Provide your own printf function if printf not available. + +FAT_CLUSTER_CACHE_ENTRIES + Size of cluster chain cache (can be undefined if not required). + Mem used = FAT_CLUSTER_CACHE_ENTRIES * 4 * 2 + Improves access speed considerably. + +FATFS_INC_LFN_SUPPORT [1/0] + Enable/Disable support for long filenames. + +FATFS_DIR_LIST_SUPPORT [1/0] + Include support for directory listing. + +FATFS_INC_TIME_DATE_SUPPORT [1/0] + Use time/date functions provided by time.h to update creation & modification timestamps. + +FATFS_INC_FORMAT_SUPPORT + Include support for formatting disks (FAT16 only). + +FAT_PRINTF_NOINC_STDIO + Disable use of printf & inclusion of stdio.h diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/History.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/History.txt new file mode 100644 index 00000000..58958f41 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/History.txt @@ -0,0 +1,24 @@ +Revision History +-=-=-=-=-=-=-=-=- +v2.6.11 - Fix compilation with GCC on 64-bit machines +v2.6.10 - Added support for FAT32 format. +V2.6.9 - Added support for time & date handling. +V2.6.8 - Fixed error with FSINFO sector write. +V2.6.7 - Added fgets(). + Fixed C warnings, removed dependancy on some string.h functions. +V2.6.6 – Massive read + write performance improvements. +V2.6.5 – Bug fixes for big endian systems. +V2.6.4 – Further bug fixes and performance improvements for write operations. +V2.6.3 – Peformance improvements, FAT16 formatting support. Various bug fixes. +V2.6 - Basic support for FAT16 added (18-04-10). +V2.5 - Code cleaned up. Many bugs fixed. Thread safety functions added. +V2.x - Write support added as well as better stdio like API. +V1.0 - Rewrite of all code to enable multiple files to be opened and provides a + better file API. + Also better string matching, and generally better C code than origonal + version. +V0.1c - Fetch_ID_Max_LBA() function added to retrieve Drive infomation and stoping + the drive reads from addressing a sector that is out of range. +V0.1b - fopen(), fgetc(), fopenDIR() using new software stack for IDE and FAT32 + access. +V0.1a - First release (27/12/03); fopen(), fgetc() unbuffered reads. diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/License.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/License.txt new file mode 100644 index 00000000..c7fb0cc7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/License.txt @@ -0,0 +1,10 @@ +FAT File IO Library License +-=-=-=-=-=-=-=-=-=-=-=-=-=- + +This versions license: GPL + +If you include GPL software in your project, you must release the source code of that project too. + +If you would like a version with a more permissive license for use in closed source commercial applications please contact me for details. + +Email: admin@ultra-embedded.com diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Media Access API.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Media Access API.txt new file mode 100644 index 00000000..45eede0f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/Media Access API.txt @@ -0,0 +1,40 @@ +Media Access API +-=-=-=-=-=-=-=-=- + +int media_read(uint32 sector, uint8 *buffer, uint32 sector_count) + +Params: + Sector: 32-bit sector number + Buffer: Target buffer to read n sectors of data into. + Sector_count: Number of sectors to read. + +Return: + int, 1 = success, 0 = failure. + +Description: + Application/target specific disk/media read function. + Sector number (sectors are usually 512 byte pages) to read. + +Media Write API + +int media_write(uint32 sector, uint8 *buffer, uint32 sector_count) + +Params: + Sector: 32-bit sector number + Buffer: Target buffer to write n sectors of data from. + Sector_count: Number of sectors to write. + +Return: + int, 1 = success, 0 = failure. + +Description: + Application/target specific disk/media write function. + Sector number (sectors are usually 512 byte pages) to write to. + +File IO Library Linkage + Use the following API to attach the media IO functions to the File IO library. + + int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr) + + + diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.c new file mode 100644 index 00000000..f55bd59b --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.c @@ -0,0 +1,904 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_string.h" +#include "fat_misc.h" + +//----------------------------------------------------------------------------- +// fatfs_init: Load FAT Parameters +//----------------------------------------------------------------------------- +int fatfs_init(struct fatfs *fs) +{ + uint8 num_of_fats; + uint16 reserved_sectors; + uint32 FATSz; + uint32 root_dir_sectors; + uint32 total_sectors; + uint32 data_sectors; + uint32 count_of_clusters; + uint8 valid_partition = 0; + + fs->currentsector.address = FAT32_INVALID_CLUSTER; + fs->currentsector.dirty = 0; + + fs->next_free_cluster = 0; // Invalid + + fatfs_fat_init(fs); + + // Make sure we have a read function (write function is optional) + if (!fs->disk_io.read_media) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // MBR: Sector 0 on the disk + // NOTE: Some removeable media does not have this. + + // Load MBR (LBA 0) into the 512 byte buffer + if (!fs->disk_io.read_media(0, fs->currentsector.sector, 1)) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Make Sure 0x55 and 0xAA are at end of sector + // (this should be the case regardless of the MBR or boot sector) + if (fs->currentsector.sector[SIGNATURE_POSITION] != 0x55 || fs->currentsector.sector[SIGNATURE_POSITION+1] != 0xAA) + return FAT_INIT_INVALID_SIGNATURE; + + // Now check again using the access function to prove endian conversion function + if (GET_16BIT_WORD(fs->currentsector.sector, SIGNATURE_POSITION) != SIGNATURE_VALUE) + return FAT_INIT_ENDIAN_ERROR; + + // Verify packed structures + if (sizeof(struct fat_dir_entry) != FAT_DIR_ENTRY_SIZE) + return FAT_INIT_STRUCT_PACKING; + + // Check the partition type code + switch(fs->currentsector.sector[PARTITION1_TYPECODE_LOCATION]) + { + case 0x0B: + case 0x06: + case 0x0C: + case 0x0E: + case 0x0F: + case 0x05: + valid_partition = 1; + break; + case 0x00: + valid_partition = 0; + break; + default: + if (fs->currentsector.sector[PARTITION1_TYPECODE_LOCATION] <= 0x06) + valid_partition = 1; + break; + } + + // Read LBA Begin for the file system + if (valid_partition) + fs->lba_begin = GET_32BIT_WORD(fs->currentsector.sector, PARTITION1_LBA_BEGIN_LOCATION); + // Else possibly MBR less disk + else + fs->lba_begin = 0; + + // Load Volume 1 table into sector buffer + // (We may already have this in the buffer if MBR less drive!) + if (!fs->disk_io.read_media(fs->lba_begin, fs->currentsector.sector, 1)) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Make sure there are 512 bytes per cluster + if (GET_16BIT_WORD(fs->currentsector.sector, 0x0B) != FAT_SECTOR_SIZE) + return FAT_INIT_INVALID_SECTOR_SIZE; + + // Load Parameters of FAT partition + fs->sectors_per_cluster = fs->currentsector.sector[BPB_SECPERCLUS]; + reserved_sectors = GET_16BIT_WORD(fs->currentsector.sector, BPB_RSVDSECCNT); + num_of_fats = fs->currentsector.sector[BPB_NUMFATS]; + fs->root_entry_count = GET_16BIT_WORD(fs->currentsector.sector, BPB_ROOTENTCNT); + + if(GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16) != 0) + fs->fat_sectors = GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16); + else + fs->fat_sectors = GET_32BIT_WORD(fs->currentsector.sector, BPB_FAT32_FATSZ32); + + // For FAT32 (which this may be) + fs->rootdir_first_cluster = GET_32BIT_WORD(fs->currentsector.sector, BPB_FAT32_ROOTCLUS); + fs->fs_info_sector = GET_16BIT_WORD(fs->currentsector.sector, BPB_FAT32_FSINFO); + + // For FAT16 (which this may be), rootdir_first_cluster is actuall rootdir_first_sector + fs->rootdir_first_sector = reserved_sectors + (num_of_fats * fs->fat_sectors); + fs->rootdir_sectors = ((fs->root_entry_count * 32) + (FAT_SECTOR_SIZE - 1)) / FAT_SECTOR_SIZE; + + // First FAT LBA address + fs->fat_begin_lba = fs->lba_begin + reserved_sectors; + + // The address of the first data cluster on this volume + fs->cluster_begin_lba = fs->fat_begin_lba + (num_of_fats * fs->fat_sectors); + + if (GET_16BIT_WORD(fs->currentsector.sector, 0x1FE) != 0xAA55) // This signature should be AA55 + return FAT_INIT_INVALID_SIGNATURE; + + // Calculate the root dir sectors + root_dir_sectors = ((GET_16BIT_WORD(fs->currentsector.sector, BPB_ROOTENTCNT) * 32) + (GET_16BIT_WORD(fs->currentsector.sector, BPB_BYTSPERSEC) - 1)) / GET_16BIT_WORD(fs->currentsector.sector, BPB_BYTSPERSEC); + + if(GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16) != 0) + FATSz = GET_16BIT_WORD(fs->currentsector.sector, BPB_FATSZ16); + else + FATSz = GET_32BIT_WORD(fs->currentsector.sector, BPB_FAT32_FATSZ32); + + if(GET_16BIT_WORD(fs->currentsector.sector, BPB_TOTSEC16) != 0) + total_sectors = GET_16BIT_WORD(fs->currentsector.sector, BPB_TOTSEC16); + else + total_sectors = GET_32BIT_WORD(fs->currentsector.sector, BPB_TOTSEC32); + + data_sectors = total_sectors - (GET_16BIT_WORD(fs->currentsector.sector, BPB_RSVDSECCNT) + (fs->currentsector.sector[BPB_NUMFATS] * FATSz) + root_dir_sectors); + + // Find out which version of FAT this is... + if (fs->sectors_per_cluster != 0) + { + count_of_clusters = data_sectors / fs->sectors_per_cluster; + + if(count_of_clusters < 4085) + // Volume is FAT12 + return FAT_INIT_WRONG_FILESYS_TYPE; + else if(count_of_clusters < 65525) + { + // Clear this FAT32 specific param + fs->rootdir_first_cluster = 0; + + // Volume is FAT16 + fs->fat_type = FAT_TYPE_16; + return FAT_INIT_OK; + } + else + { + // Volume is FAT32 + fs->fat_type = FAT_TYPE_32; + return FAT_INIT_OK; + } + } + else + return FAT_INIT_WRONG_FILESYS_TYPE; +} +//----------------------------------------------------------------------------- +// fatfs_lba_of_cluster: This function converts a cluster number into a sector / +// LBA number. +//----------------------------------------------------------------------------- +uint32 fatfs_lba_of_cluster(struct fatfs *fs, uint32 Cluster_Number) +{ + if (fs->fat_type == FAT_TYPE_16) + return (fs->cluster_begin_lba + (fs->root_entry_count * 32 / FAT_SECTOR_SIZE) + ((Cluster_Number-2) * fs->sectors_per_cluster)); + else + return ((fs->cluster_begin_lba + ((Cluster_Number-2)*fs->sectors_per_cluster))); +} +//----------------------------------------------------------------------------- +// fatfs_sector_read: +//----------------------------------------------------------------------------- +int fatfs_sector_read(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count) +{ + return fs->disk_io.read_media(lba, target, count); +} +//----------------------------------------------------------------------------- +// fatfs_sector_write: +//----------------------------------------------------------------------------- +int fatfs_sector_write(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count) +{ + return fs->disk_io.write_media(lba, target, count); +} +//----------------------------------------------------------------------------- +// fatfs_sector_reader: From the provided startcluster and sector offset +// Returns True if success, returns False if not (including if read out of range) +//----------------------------------------------------------------------------- +int fatfs_sector_reader(struct fatfs *fs, uint32 start_cluster, uint32 offset, uint8 *target) +{ + uint32 sector_to_read = 0; + uint32 cluster_to_read = 0; + uint32 cluster_chain = 0; + uint32 i; + uint32 lba; + + // FAT16 Root directory + if (fs->fat_type == FAT_TYPE_16 && start_cluster == 0) + { + if (offset < fs->rootdir_sectors) + lba = fs->lba_begin + fs->rootdir_first_sector + offset; + else + return 0; + } + // FAT16/32 Other + else + { + // Set start of cluster chain to initial value + cluster_chain = start_cluster; + + // Find parameters + cluster_to_read = offset / fs->sectors_per_cluster; + sector_to_read = offset - (cluster_to_read*fs->sectors_per_cluster); + + // Follow chain to find cluster to read + for (i=0; idisk_io.read_media(lba, target, 1); + // Else read sector if not already loaded + else if (lba != fs->currentsector.address) + { + fs->currentsector.address = lba; + return fs->disk_io.read_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + else + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_read_sector: Read from the provided cluster and sector offset +// Returns True if success, returns False if not +//----------------------------------------------------------------------------- +int fatfs_read_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target) +{ + // FAT16 Root directory + if (fs->fat_type == FAT_TYPE_16 && cluster == 0) + { + uint32 lba; + + // In FAT16, there are a limited amount of sectors in root dir! + if (sector < fs->rootdir_sectors) + lba = fs->lba_begin + fs->rootdir_first_sector + sector; + else + return 0; + + // User target buffer passed in + if (target) + { + // Read from disk + return fs->disk_io.read_media(lba, target, 1); + } + else + { + // Calculate read address + fs->currentsector.address = lba; + + // Read from disk + return fs->disk_io.read_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + // FAT16/32 Other + else + { + // User target buffer passed in + if (target) + { + // Calculate read address + uint32 lba = fatfs_lba_of_cluster(fs, cluster) + sector; + + // Read from disk + return fs->disk_io.read_media(lba, target, 1); + } + else + { + // Calculate write address + fs->currentsector.address = fatfs_lba_of_cluster(fs, cluster)+sector; + + // Read from disk + return fs->disk_io.read_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } +} +//----------------------------------------------------------------------------- +// fatfs_write_sector: Write to the provided cluster and sector offset +// Returns True if success, returns False if not +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_write_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target) +{ + // No write access? + if (!fs->disk_io.write_media) + return 0; + + // FAT16 Root directory + if (fs->fat_type == FAT_TYPE_16 && cluster == 0) + { + uint32 lba; + + // In FAT16 we cannot extend the root dir! + if (sector < fs->rootdir_sectors) + lba = fs->lba_begin + fs->rootdir_first_sector + sector; + else + return 0; + + // User target buffer passed in + if (target) + { + // Write to disk + return fs->disk_io.write_media(lba, target, 1); + } + else + { + // Calculate write address + fs->currentsector.address = lba; + + // Write to disk + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + // FAT16/32 Other + else + { + // User target buffer passed in + if (target) + { + // Calculate write address + uint32 lba = fatfs_lba_of_cluster(fs, cluster) + sector; + + // Write to disk + return fs->disk_io.write_media(lba, target, 1); + } + else + { + // Calculate write address + fs->currentsector.address = fatfs_lba_of_cluster(fs, cluster)+sector; + + // Write to disk + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } +} +#endif +//----------------------------------------------------------------------------- +// fatfs_show_details: Show the details about the filesystem +//----------------------------------------------------------------------------- +void fatfs_show_details(struct fatfs *fs) +{ + FAT_PRINTF(("FAT details:\r\n")); + FAT_PRINTF((" Type =%s", (fs->fat_type == FAT_TYPE_32) ? "FAT32": "FAT16")); + FAT_PRINTF((" Root Dir First Cluster = %x\r\n", fs->rootdir_first_cluster)); + FAT_PRINTF((" FAT Begin LBA = 0x%x\r\n",fs->fat_begin_lba)); + FAT_PRINTF((" Cluster Begin LBA = 0x%x\r\n",fs->cluster_begin_lba)); + FAT_PRINTF((" Sectors Per Cluster = %d\r\n", fs->sectors_per_cluster)); +} +//----------------------------------------------------------------------------- +// fatfs_get_root_cluster: Get the root dir cluster +//----------------------------------------------------------------------------- +uint32 fatfs_get_root_cluster(struct fatfs *fs) +{ + // NOTE: On FAT16 this will be 0 which has a special meaning... + return fs->rootdir_first_cluster; +} +//------------------------------------------------------------- +// fatfs_get_file_entry: Find the file entry for a filename +//------------------------------------------------------------- +uint32 fatfs_get_file_entry(struct fatfs *fs, uint32 Cluster, char *name_to_find, struct fat_dir_entry *sfEntry) +{ + uint8 item=0; + uint16 recordoffset = 0; + uint8 i=0; + int x=0; + char *long_filename = NULL; + char short_filename[13]; + struct lfn_cache lfn; + int dotRequired = 0; + struct fat_dir_entry *directoryEntry; + + fatfs_lfn_cache_init(&lfn, 1); + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + fatfs_lfn_cache_entry(&lfn, fs->currentsector.sector+recordoffset); + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + fatfs_lfn_cache_init(&lfn, 0); + + // Normal SFN Entry and Long text exists + else if (fatfs_entry_lfn_exists(&lfn, directoryEntry) ) + { + long_filename = fatfs_lfn_cache_get(&lfn); + + // Compare names to see if they match + if (fatfs_compare_names(long_filename, name_to_find)) + { + memcpy(sfEntry,directoryEntry,sizeof(struct fat_dir_entry)); + return 1; + } + + fatfs_lfn_cache_init(&lfn, 0); + } + else +#endif + // Normal Entry, only 8.3 Text + if (fatfs_entry_sfn_only(directoryEntry) ) + { + memset(short_filename, 0, sizeof(short_filename)); + + // Copy name to string + for (i=0; i<8; i++) + short_filename[i] = directoryEntry->Name[i]; + + // Extension + dotRequired = 0; + for (i=8; i<11; i++) + { + short_filename[i+1] = directoryEntry->Name[i]; + if (directoryEntry->Name[i] != ' ') + dotRequired = 1; + } + + // Dot only required if extension present + if (dotRequired) + { + // If not . or .. entry + if (short_filename[0]!='.') + short_filename[8] = '.'; + else + short_filename[8] = ' '; + } + else + short_filename[8] = ' '; + + // Compare names to see if they match + if (fatfs_compare_names(short_filename, name_to_find)) + { + memcpy(sfEntry,directoryEntry,sizeof(struct fat_dir_entry)); + return 1; + } + + fatfs_lfn_cache_init(&lfn, 0); + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +//------------------------------------------------------------- +// fatfs_sfn_exists: Check if a short filename exists. +// NOTE: shortname is XXXXXXXXYYY not XXXXXXXX.YYY +//------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_sfn_exists(struct fatfs *fs, uint32 Cluster, char *shortname) +{ + uint8 item=0; + uint16 recordoffset = 0; + int x=0; + struct fat_dir_entry *directoryEntry; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + ; + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + ; + else +#endif + // Normal Entry, only 8.3 Text + if (fatfs_entry_sfn_only(directoryEntry) ) + { + if (strncmp((const char*)directoryEntry->Name, shortname, 11)==0) + return 1; + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +#endif +//------------------------------------------------------------- +// fatfs_update_timestamps: Update date/time details +//------------------------------------------------------------- +#if FATFS_INC_TIME_DATE_SUPPORT +int fatfs_update_timestamps(struct fat_dir_entry *directoryEntry, int create, int modify, int access) +{ + time_t time_now; + struct tm * time_info; + uint16 fat_time; + uint16 fat_date; + + // Get system time + time(&time_now); + + // Convert to local time + time_info = localtime(&time_now); + + // Convert time to FAT format + fat_time = fatfs_convert_to_fat_time(time_info->tm_hour, time_info->tm_min, time_info->tm_sec); + + // Convert date to FAT format + fat_date = fatfs_convert_to_fat_date(time_info->tm_mday, time_info->tm_mon + 1, time_info->tm_year + 1900); + + // Update requested fields + if (create) + { + directoryEntry->CrtTime[1] = fat_time >> 8; + directoryEntry->CrtTime[0] = fat_time >> 0; + directoryEntry->CrtDate[1] = fat_date >> 8; + directoryEntry->CrtDate[0] = fat_date >> 0; + } + + if (modify) + { + directoryEntry->WrtTime[1] = fat_time >> 8; + directoryEntry->WrtTime[0] = fat_time >> 0; + directoryEntry->WrtDate[1] = fat_date >> 8; + directoryEntry->WrtDate[0] = fat_date >> 0; + } + + if (access) + { + directoryEntry->LstAccDate[1] = fat_time >> 8; + directoryEntry->LstAccDate[0] = fat_time >> 0; + directoryEntry->LstAccDate[1] = fat_date >> 8; + directoryEntry->LstAccDate[0] = fat_date >> 0; + } + + return 1; +} +#endif +//------------------------------------------------------------- +// fatfs_update_file_length: Find a SFN entry and update it +// NOTE: shortname is XXXXXXXXYYY not XXXXXXXX.YYY +//------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_update_file_length(struct fatfs *fs, uint32 Cluster, char *shortname, uint32 fileLength) +{ + uint8 item=0; + uint16 recordoffset = 0; + int x=0; + struct fat_dir_entry *directoryEntry; + + // No write access? + if (!fs->disk_io.write_media) + return 0; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + ; + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + ; + + // Normal Entry, only 8.3 Text + else +#endif + if (fatfs_entry_sfn_only(directoryEntry) ) + { + if (strncmp((const char*)directoryEntry->Name, shortname, 11)==0) + { + directoryEntry->FileSize = FAT_HTONL(fileLength); + +#if FATFS_INC_TIME_DATE_SUPPORT + // Update access / modify time & date + fatfs_update_timestamps(directoryEntry, 0, 1, 1); +#endif + + // Update sfn entry + memcpy((uint8*)(fs->currentsector.sector+recordoffset), (uint8*)directoryEntry, sizeof(struct fat_dir_entry)); + + // Write sector back + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +#endif +//------------------------------------------------------------- +// fatfs_mark_file_deleted: Find a SFN entry and mark if as deleted +// NOTE: shortname is XXXXXXXXYYY not XXXXXXXX.YYY +//------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_mark_file_deleted(struct fatfs *fs, uint32 Cluster, char *shortname) +{ + uint8 item=0; + uint16 recordoffset = 0; + int x=0; + struct fat_dir_entry *directoryEntry; + + // No write access? + if (!fs->disk_io.write_media) + return 0; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, Cluster, x++, 0)) // If sector read was successfull + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if (fatfs_entry_lfn_text(directoryEntry) ) + ; + + // If Invalid record found delete any long file name information collated + else if (fatfs_entry_lfn_invalid(directoryEntry) ) + ; + + // Normal Entry, only 8.3 Text + else +#endif + if (fatfs_entry_sfn_only(directoryEntry) ) + { + if (strncmp((const char *)directoryEntry->Name, shortname, 11)==0) + { + // Mark as deleted + directoryEntry->Name[0] = FILE_HEADER_DELETED; + +#if FATFS_INC_TIME_DATE_SUPPORT + // Update access / modify time & date + fatfs_update_timestamps(directoryEntry, 0, 1, 1); +#endif + + // Update sfn entry + memcpy((uint8*)(fs->currentsector.sector+recordoffset), (uint8*)directoryEntry, sizeof(struct fat_dir_entry)); + + // Write sector back + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } + } + } // End of if + } + else + break; + } // End of while loop + + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_list_directory_start: Initialise a directory listing procedure +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +void fatfs_list_directory_start(struct fatfs *fs, struct fs_dir_list_status *dirls, uint32 StartCluster) +{ + dirls->cluster = StartCluster; + dirls->sector = 0; + dirls->offset = 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_list_directory_next: Get the next entry in the directory. +// Returns: 1 = found, 0 = end of listing +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fatfs_list_directory_next(struct fatfs *fs, struct fs_dir_list_status *dirls, struct fs_dir_ent *entry) +{ + uint8 i,item; + uint16 recordoffset; + struct fat_dir_entry *directoryEntry; + char *long_filename = NULL; + char short_filename[13]; + struct lfn_cache lfn; + int dotRequired = 0; + int result = 0; + + // Initialise LFN cache first + fatfs_lfn_cache_init(&lfn, 0); + + while (1) + { + // If data read OK + if (fatfs_sector_reader(fs, dirls->cluster, dirls->sector, 0)) + { + // Maximum of 16 directory entries + for (item = dirls->offset; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Increase directory offset + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + +#if FATFS_INC_LFN_SUPPORT + // Long File Name Text Found + if ( fatfs_entry_lfn_text(directoryEntry) ) + fatfs_lfn_cache_entry(&lfn, fs->currentsector.sector+recordoffset); + + // If Invalid record found delete any long file name information collated + else if ( fatfs_entry_lfn_invalid(directoryEntry) ) + fatfs_lfn_cache_init(&lfn, 0); + + // Normal SFN Entry and Long text exists + else if (fatfs_entry_lfn_exists(&lfn, directoryEntry) ) + { + // Get text + long_filename = fatfs_lfn_cache_get(&lfn); + strncpy(entry->filename, long_filename, FATFS_MAX_LONG_FILENAME-1); + + if (fatfs_entry_is_dir(directoryEntry)) + entry->is_dir = 1; + else + entry->is_dir = 0; + +#if FATFS_INC_TIME_DATE_SUPPORT + // Get time / dates + entry->create_time = ((uint16)directoryEntry->CrtTime[1] << 8) | directoryEntry->CrtTime[0]; + entry->create_date = ((uint16)directoryEntry->CrtDate[1] << 8) | directoryEntry->CrtDate[0]; + entry->access_date = ((uint16)directoryEntry->LstAccDate[1] << 8) | directoryEntry->LstAccDate[0]; + entry->write_time = ((uint16)directoryEntry->WrtTime[1] << 8) | directoryEntry->WrtTime[0]; + entry->write_date = ((uint16)directoryEntry->WrtDate[1] << 8) | directoryEntry->WrtDate[0]; +#endif + + entry->size = FAT_HTONL(directoryEntry->FileSize); + entry->cluster = (FAT_HTONS(directoryEntry->FstClusHI)<<16) | FAT_HTONS(directoryEntry->FstClusLO); + + // Next starting position + dirls->offset = item + 1; + result = 1; + return 1; + } + // Normal Entry, only 8.3 Text + else +#endif + if ( fatfs_entry_sfn_only(directoryEntry) ) + { + fatfs_lfn_cache_init(&lfn, 0); + + memset(short_filename, 0, sizeof(short_filename)); + + // Copy name to string + for (i=0; i<8; i++) + short_filename[i] = directoryEntry->Name[i]; + + // Extension + dotRequired = 0; + for (i=8; i<11; i++) + { + short_filename[i+1] = directoryEntry->Name[i]; + if (directoryEntry->Name[i] != ' ') + dotRequired = 1; + } + + // Dot only required if extension present + if (dotRequired) + { + // If not . or .. entry + if (short_filename[0]!='.') + short_filename[8] = '.'; + else + short_filename[8] = ' '; + } + else + short_filename[8] = ' '; + + fatfs_get_sfn_display_name(entry->filename, short_filename); + + if (fatfs_entry_is_dir(directoryEntry)) + entry->is_dir = 1; + else + entry->is_dir = 0; + +#if FATFS_INC_TIME_DATE_SUPPORT + // Get time / dates + entry->create_time = ((uint16)directoryEntry->CrtTime[1] << 8) | directoryEntry->CrtTime[0]; + entry->create_date = ((uint16)directoryEntry->CrtDate[1] << 8) | directoryEntry->CrtDate[0]; + entry->access_date = ((uint16)directoryEntry->LstAccDate[1] << 8) | directoryEntry->LstAccDate[0]; + entry->write_time = ((uint16)directoryEntry->WrtTime[1] << 8) | directoryEntry->WrtTime[0]; + entry->write_date = ((uint16)directoryEntry->WrtDate[1] << 8) | directoryEntry->WrtDate[0]; +#endif + + entry->size = FAT_HTONL(directoryEntry->FileSize); + entry->cluster = (FAT_HTONS(directoryEntry->FstClusHI)<<16) | FAT_HTONS(directoryEntry->FstClusLO); + + // Next starting position + dirls->offset = item + 1; + result = 1; + return 1; + } + }// end of for + + // If reached end of the dir move onto next sector + dirls->sector++; + dirls->offset = 0; + } + else + break; + } + + return result; +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.h new file mode 100644 index 00000000..17523878 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_access.h @@ -0,0 +1,133 @@ +#ifndef __FAT_ACCESS_H__ +#define __FAT_ACCESS_H__ + +#include "fat_defs.h" +#include "fat_opts.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#define FAT_INIT_OK 0 +#define FAT_INIT_MEDIA_ACCESS_ERROR (-1) +#define FAT_INIT_INVALID_SECTOR_SIZE (-2) +#define FAT_INIT_INVALID_SIGNATURE (-3) +#define FAT_INIT_ENDIAN_ERROR (-4) +#define FAT_INIT_WRONG_FILESYS_TYPE (-5) +#define FAT_INIT_WRONG_PARTITION_TYPE (-6) +#define FAT_INIT_STRUCT_PACKING (-7) + +#define FAT_DIR_ENTRIES_PER_SECTOR (FAT_SECTOR_SIZE / FAT_DIR_ENTRY_SIZE) + +//----------------------------------------------------------------------------- +// Function Pointers +//----------------------------------------------------------------------------- +typedef int (*fn_diskio_read) (uint32 sector, uint8 *buffer, uint32 sector_count); +typedef int (*fn_diskio_write)(uint32 sector, uint8 *buffer, uint32 sector_count); + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct disk_if +{ + // User supplied function pointers for disk IO + fn_diskio_read read_media; + fn_diskio_write write_media; +}; + +// Forward declaration +struct fat_buffer; + +struct fat_buffer +{ + uint8 sector[FAT_SECTOR_SIZE * FAT_BUFFER_SECTORS]; + uint32 address; + int dirty; + uint8 * ptr; + + // Next in chain of sector buffers + struct fat_buffer *next; +}; + +typedef enum eFatType +{ + FAT_TYPE_16, + FAT_TYPE_32 +} tFatType; + +struct fatfs +{ + // Filesystem globals + uint8 sectors_per_cluster; + uint32 cluster_begin_lba; + uint32 rootdir_first_cluster; + uint32 rootdir_first_sector; + uint32 rootdir_sectors; + uint32 fat_begin_lba; + uint16 fs_info_sector; + uint32 lba_begin; + uint32 fat_sectors; + uint32 next_free_cluster; + uint16 root_entry_count; + uint16 reserved_sectors; + uint8 num_of_fats; + tFatType fat_type; + + // Disk/Media API + struct disk_if disk_io; + + // [Optional] Thread Safety + void (*fl_lock)(void); + void (*fl_unlock)(void); + + // Working buffer + struct fat_buffer currentsector; + + // FAT Buffer + struct fat_buffer *fat_buffer_head; + struct fat_buffer fat_buffers[FAT_BUFFERS]; +}; + +struct fs_dir_list_status +{ + uint32 sector; + uint32 cluster; + uint8 offset; +}; + +struct fs_dir_ent +{ + char filename[FATFS_MAX_LONG_FILENAME]; + uint8 is_dir; + uint32 cluster; + uint32 size; + +#if FATFS_INC_TIME_DATE_SUPPORT + uint16 access_date; + uint16 write_time; + uint16 write_date; + uint16 create_date; + uint16 create_time; +#endif +}; + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_init(struct fatfs *fs); +uint32 fatfs_lba_of_cluster(struct fatfs *fs, uint32 Cluster_Number); +int fatfs_sector_reader(struct fatfs *fs, uint32 Startcluster, uint32 offset, uint8 *target); +int fatfs_sector_read(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count); +int fatfs_sector_write(struct fatfs *fs, uint32 lba, uint8 *target, uint32 count); +int fatfs_read_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target); +int fatfs_write_sector(struct fatfs *fs, uint32 cluster, uint32 sector, uint8 *target); +void fatfs_show_details(struct fatfs *fs); +uint32 fatfs_get_root_cluster(struct fatfs *fs); +uint32 fatfs_get_file_entry(struct fatfs *fs, uint32 Cluster, char *nametofind, struct fat_dir_entry *sfEntry); +int fatfs_sfn_exists(struct fatfs *fs, uint32 Cluster, char *shortname); +int fatfs_update_file_length(struct fatfs *fs, uint32 Cluster, char *shortname, uint32 fileLength); +int fatfs_mark_file_deleted(struct fatfs *fs, uint32 Cluster, char *shortname); +void fatfs_list_directory_start(struct fatfs *fs, struct fs_dir_list_status *dirls, uint32 StartCluster); +int fatfs_list_directory_next(struct fatfs *fs, struct fs_dir_list_status *dirls, struct fs_dir_ent *entry); +int fatfs_update_timestamps(struct fat_dir_entry *directoryEntry, int create, int modify, int access); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.c new file mode 100644 index 00000000..de77e6a0 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.c @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_cache.h" + +// Per file cluster chain caching used to improve performance. +// This does not have to be enabled for architectures with low +// memory space. + +//----------------------------------------------------------------------------- +// fatfs_cache_init: +//----------------------------------------------------------------------------- +int fatfs_cache_init(struct fatfs *fs, FL_FILE *file) +{ +#ifdef FAT_CLUSTER_CACHE_ENTRIES + int i; + + for (i=0;icluster_cache_idx[i] = 0xFFFFFFFF; // Not used + file->cluster_cache_data[i] = 0; + } +#endif + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_cache_get_next_cluster: +//----------------------------------------------------------------------------- +int fatfs_cache_get_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 *pNextCluster) +{ +#ifdef FAT_CLUSTER_CACHE_ENTRIES + uint32 slot = clusterIdx % FAT_CLUSTER_CACHE_ENTRIES; + + if (file->cluster_cache_idx[slot] == clusterIdx) + { + *pNextCluster = file->cluster_cache_data[slot]; + return 1; + } +#endif + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_cache_set_next_cluster: +//----------------------------------------------------------------------------- +int fatfs_cache_set_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 nextCluster) +{ +#ifdef FAT_CLUSTER_CACHE_ENTRIES + uint32 slot = clusterIdx % FAT_CLUSTER_CACHE_ENTRIES; + + if (file->cluster_cache_idx[slot] == clusterIdx) + file->cluster_cache_data[slot] = nextCluster; + else + { + file->cluster_cache_idx[slot] = clusterIdx; + file->cluster_cache_data[slot] = nextCluster; + } +#endif + + return 1; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.h new file mode 100644 index 00000000..348d5d38 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_cache.h @@ -0,0 +1,13 @@ +#ifndef __FAT_CACHE_H__ +#define __FAT_CACHE_H__ + +#include "fat_filelib.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_cache_init(struct fatfs *fs, FL_FILE *file); +int fatfs_cache_get_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 *pNextCluster); +int fatfs_cache_set_next_cluster(struct fatfs *fs, FL_FILE *file, uint32 clusterIdx, uint32 nextCluster); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_defs.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_defs.h new file mode 100644 index 00000000..5fe8d6a4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_defs.h @@ -0,0 +1,128 @@ +#ifndef __FAT_DEFS_H__ +#define __FAT_DEFS_H__ + +#include "fat_opts.h" +#include "fat_types.h" + +//----------------------------------------------------------------------------- +// FAT32 Offsets +// Name Offset +//----------------------------------------------------------------------------- + +// Boot Sector +#define BS_JMPBOOT 0 // Length = 3 +#define BS_OEMNAME 3 // Length = 8 +#define BPB_BYTSPERSEC 11 // Length = 2 +#define BPB_SECPERCLUS 13 // Length = 1 +#define BPB_RSVDSECCNT 14 // Length = 2 +#define BPB_NUMFATS 16 // Length = 1 +#define BPB_ROOTENTCNT 17 // Length = 2 +#define BPB_TOTSEC16 19 // Length = 2 +#define BPB_MEDIA 21 // Length = 1 +#define BPB_FATSZ16 22 // Length = 2 +#define BPB_SECPERTRK 24 // Length = 2 +#define BPB_NUMHEADS 26 // Length = 2 +#define BPB_HIDDSEC 28 // Length = 4 +#define BPB_TOTSEC32 32 // Length = 4 + +// FAT 12/16 +#define BS_FAT_DRVNUM 36 // Length = 1 +#define BS_FAT_BOOTSIG 38 // Length = 1 +#define BS_FAT_VOLID 39 // Length = 4 +#define BS_FAT_VOLLAB 43 // Length = 11 +#define BS_FAT_FILSYSTYPE 54 // Length = 8 + +// FAT 32 +#define BPB_FAT32_FATSZ32 36 // Length = 4 +#define BPB_FAT32_EXTFLAGS 40 // Length = 2 +#define BPB_FAT32_FSVER 42 // Length = 2 +#define BPB_FAT32_ROOTCLUS 44 // Length = 4 +#define BPB_FAT32_FSINFO 48 // Length = 2 +#define BPB_FAT32_BKBOOTSEC 50 // Length = 2 +#define BS_FAT32_DRVNUM 64 // Length = 1 +#define BS_FAT32_BOOTSIG 66 // Length = 1 +#define BS_FAT32_VOLID 67 // Length = 4 +#define BS_FAT32_VOLLAB 71 // Length = 11 +#define BS_FAT32_FILSYSTYPE 82 // Length = 8 + +//----------------------------------------------------------------------------- +// FAT Types +//----------------------------------------------------------------------------- +#define FAT_TYPE_FAT12 1 +#define FAT_TYPE_FAT16 2 +#define FAT_TYPE_FAT32 3 + +//----------------------------------------------------------------------------- +// FAT32 Specific Statics +//----------------------------------------------------------------------------- +#define SIGNATURE_POSITION 510 +#define SIGNATURE_VALUE 0xAA55 +#define PARTITION1_TYPECODE_LOCATION 450 +#define FAT32_TYPECODE1 0x0B +#define FAT32_TYPECODE2 0x0C +#define PARTITION1_LBA_BEGIN_LOCATION 454 +#define PARTITION1_SIZE_LOCATION 458 + +#define FAT_DIR_ENTRY_SIZE 32 +#define FAT_SFN_SIZE_FULL 11 +#define FAT_SFN_SIZE_PARTIAL 8 + +//----------------------------------------------------------------------------- +// FAT32 File Attributes and Types +//----------------------------------------------------------------------------- +#define FILE_ATTR_READ_ONLY 0x01 +#define FILE_ATTR_HIDDEN 0x02 +#define FILE_ATTR_SYSTEM 0x04 +#define FILE_ATTR_SYSHID 0x06 +#define FILE_ATTR_VOLUME_ID 0x08 +#define FILE_ATTR_DIRECTORY 0x10 +#define FILE_ATTR_ARCHIVE 0x20 +#define FILE_ATTR_LFN_TEXT 0x0F +#define FILE_HEADER_BLANK 0x00 +#define FILE_HEADER_DELETED 0xE5 +#define FILE_TYPE_DIR 0x10 +#define FILE_TYPE_FILE 0x20 + +//----------------------------------------------------------------------------- +// Time / Date details +//----------------------------------------------------------------------------- +#define FAT_TIME_HOURS_SHIFT 11 +#define FAT_TIME_HOURS_MASK 0x1F +#define FAT_TIME_MINUTES_SHIFT 5 +#define FAT_TIME_MINUTES_MASK 0x3F +#define FAT_TIME_SECONDS_SHIFT 0 +#define FAT_TIME_SECONDS_MASK 0x1F +#define FAT_TIME_SECONDS_SCALE 2 +#define FAT_DATE_YEAR_SHIFT 9 +#define FAT_DATE_YEAR_MASK 0x7F +#define FAT_DATE_MONTH_SHIFT 5 +#define FAT_DATE_MONTH_MASK 0xF +#define FAT_DATE_DAY_SHIFT 0 +#define FAT_DATE_DAY_MASK 0x1F +#define FAT_DATE_YEAR_OFFSET 1980 + +//----------------------------------------------------------------------------- +// Other Defines +//----------------------------------------------------------------------------- +#define FAT32_LAST_CLUSTER 0xFFFFFFFF +#define FAT32_INVALID_CLUSTER 0xFFFFFFFF + +STRUCT_PACK_BEGIN +struct fat_dir_entry STRUCT_PACK +{ + uint8 Name[11]; + uint8 Attr; + uint8 NTRes; + uint8 CrtTimeTenth; + uint8 CrtTime[2]; + uint8 CrtDate[2]; + uint8 LstAccDate[2]; + uint16 FstClusHI; + uint8 WrtTime[2]; + uint8 WrtDate[2]; + uint16 FstClusLO; + uint32 FileSize; +} STRUCT_PACKED; +STRUCT_PACK_END + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c new file mode 100644 index 00000000..2c4a236f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.c @@ -0,0 +1,1603 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_misc.h" +#include "fat_string.h" +#include "fat_filelib.h" +#include "fat_cache.h" + +//----------------------------------------------------------------------------- +// Locals +//----------------------------------------------------------------------------- +static FL_FILE _files[FATFS_MAX_OPEN_FILES]; +static int _filelib_init = 0; +static int _filelib_valid = 0; +static struct fatfs _fs; +static struct fat_list _open_file_list; +static struct fat_list _free_file_list; + +//----------------------------------------------------------------------------- +// Macros +//----------------------------------------------------------------------------- + +// Macro for checking if file lib is initialised +#define CHECK_FL_INIT() { if (_filelib_init==0) fl_init(); } + +#define FL_LOCK(a) do { if ((a)->fl_lock) (a)->fl_lock(); } while (0) +#define FL_UNLOCK(a) do { if ((a)->fl_unlock) (a)->fl_unlock(); } while (0) + +//----------------------------------------------------------------------------- +// Local Functions +//----------------------------------------------------------------------------- +static void _fl_init(); + +//----------------------------------------------------------------------------- +// _allocate_file: Find a slot in the open files buffer for a new file +//----------------------------------------------------------------------------- +static FL_FILE* _allocate_file(void) +{ + // Allocate free file + struct fat_node *node = fat_list_pop_head(&_free_file_list); + + // Add to open list + if (node) + fat_list_insert_last(&_open_file_list, node); + + return fat_list_entry(node, FL_FILE, list_node); +} +//----------------------------------------------------------------------------- +// _check_file_open: Returns true if the file is already open +//----------------------------------------------------------------------------- +static int _check_file_open(FL_FILE* file) +{ + struct fat_node *node; + + // Compare open files + fat_list_for_each(&_open_file_list, node) + { + FL_FILE* openFile = fat_list_entry(node, FL_FILE, list_node); + + // If not the current file + if (openFile != file) + { + // Compare path and name + if ( (fatfs_compare_names(openFile->path,file->path)) && (fatfs_compare_names(openFile->filename,file->filename)) ) + return 1; + } + } + + return 0; +} +//----------------------------------------------------------------------------- +// _free_file: Free open file handle +//----------------------------------------------------------------------------- +static void _free_file(FL_FILE* file) +{ + // Remove from open list + fat_list_remove(&_open_file_list, &file->list_node); + + // Add to free list + fat_list_insert_last(&_free_file_list, &file->list_node); +} + +//----------------------------------------------------------------------------- +// Low Level +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// _open_directory: Cycle through path string to find the start cluster +// address of the highest subdir. +//----------------------------------------------------------------------------- +static int _open_directory(char *path, uint32 *pathCluster) +{ + int levels; + int sublevel; + char currentfolder[FATFS_MAX_LONG_FILENAME]; + struct fat_dir_entry sfEntry; + uint32 startcluster; + + // Set starting cluster to root cluster + startcluster = fatfs_get_root_cluster(&_fs); + + // Find number of levels + levels = fatfs_total_path_levels(path); + + // Cycle through each level and get the start sector + for (sublevel=0;sublevel<(levels+1);sublevel++) + { + if (fatfs_get_substring(path, sublevel, currentfolder, sizeof(currentfolder)) == -1) + return 0; + + // Find clusteraddress for folder (currentfolder) + if (fatfs_get_file_entry(&_fs, startcluster, currentfolder,&sfEntry)) + { + // Check entry is folder + if (fatfs_entry_is_dir(&sfEntry)) + startcluster = ((FAT_HTONS((uint32)sfEntry.FstClusHI))<<16) + FAT_HTONS(sfEntry.FstClusLO); + else + return 0; + } + else + return 0; + } + + *pathCluster = startcluster; + return 1; +} +//----------------------------------------------------------------------------- +// _create_directory: Cycle through path string and create the end directory +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +static int _create_directory(char *path) +{ + FL_FILE* file; + struct fat_dir_entry sfEntry; + char shortFilename[FAT_SFN_SIZE_FULL]; + int tailNum = 0; + int i; + + // Allocate a new file handle + file = _allocate_file(); + if (!file) + return 0; + + // Clear filename + memset(file->path, '\0', sizeof(file->path)); + memset(file->filename, '\0', sizeof(file->filename)); + + // Split full path into filename and directory path + if (fatfs_split_path((char*)path, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) + { + _free_file(file); + return 0; + } + + // Check if file already open + if (_check_file_open(file)) + { + _free_file(file); + return 0; + } + + // If file is in the root dir + if (file->path[0] == 0) + file->parentcluster = fatfs_get_root_cluster(&_fs); + else + { + // Find parent directory start cluster + if (!_open_directory(file->path, &file->parentcluster)) + { + _free_file(file); + return 0; + } + } + + // Check if same filename exists in directory + if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry) == 1) + { + _free_file(file); + return 0; + } + + file->startcluster = 0; + + // Create the file space for the folder (at least one clusters worth!) + if (!fatfs_allocate_free_space(&_fs, 1, &file->startcluster, 1)) + { + _free_file(file); + return 0; + } + + // Erase new directory cluster + memset(file->file_data_sector, 0x00, FAT_SECTOR_SIZE); + for (i=0;i<_fs.sectors_per_cluster;i++) + { + if (!fatfs_write_sector(&_fs, file->startcluster, i, file->file_data_sector)) + { + _free_file(file); + return 0; + } + } + +#if FATFS_INC_LFN_SUPPORT + + // Generate a short filename & tail + tailNum = 0; + do + { + // Create a standard short filename (without tail) + fatfs_lfn_create_sfn(shortFilename, file->filename); + + // If second hit or more, generate a ~n tail + if (tailNum != 0) + fatfs_lfn_generate_tail((char*)file->shortfilename, shortFilename, tailNum); + // Try with no tail if first entry + else + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already or not + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename) == 0) + break; + + tailNum++; + } + while (tailNum < 9999); + + // We reached the max number of duplicate short file names (unlikely!) + if (tailNum == 9999) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } +#else + // Create a standard short filename (without tail) + if (!fatfs_lfn_create_sfn(shortFilename, file->filename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } + + // Copy to SFN space + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } +#endif + + // Add file to disk + if (!fatfs_add_file_entry(&_fs, file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, 0, 1)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return 0; + } + + // General + file->filelength = 0; + file->bytenum = 0; + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Quick lookup for next link in the chain + file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; + file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; + + fatfs_fat_purge(&_fs); + + _free_file(file); + return 1; +} +#endif +//----------------------------------------------------------------------------- +// _open_file: Open a file for reading +//----------------------------------------------------------------------------- +static FL_FILE* _open_file(const char *path) +{ + FL_FILE* file; + struct fat_dir_entry sfEntry; + + // Allocate a new file handle + file = _allocate_file(); + if (!file) + return NULL; + + // Clear filename + memset(file->path, '\0', sizeof(file->path)); + memset(file->filename, '\0', sizeof(file->filename)); + + // Split full path into filename and directory path + if (fatfs_split_path((char*)path, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) + { + _free_file(file); + return NULL; + } + + // Check if file already open + if (_check_file_open(file)) + { + _free_file(file); + return NULL; + } + + // If file is in the root dir + if (file->path[0]==0) + file->parentcluster = fatfs_get_root_cluster(&_fs); + else + { + // Find parent directory start cluster + if (!_open_directory(file->path, &file->parentcluster)) + { + _free_file(file); + return NULL; + } + } + + // Using dir cluster address search for filename + if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry)) + // Make sure entry is file not dir! + if (fatfs_entry_is_file(&sfEntry)) + { + // Initialise file details + memcpy(file->shortfilename, sfEntry.Name, FAT_SFN_SIZE_FULL); + file->filelength = FAT_HTONL(sfEntry.FileSize); + file->bytenum = 0; + file->startcluster = ((FAT_HTONS((uint32)sfEntry.FstClusHI))<<16) + FAT_HTONS(sfEntry.FstClusLO); + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Quick lookup for next link in the chain + file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; + file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; + + fatfs_cache_init(&_fs, file); + + fatfs_fat_purge(&_fs); + + return file; + } + + _free_file(file); + return NULL; +} +//----------------------------------------------------------------------------- +// _create_file: Create a new file +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +static FL_FILE* _create_file(const char *filename) +{ + FL_FILE* file; + struct fat_dir_entry sfEntry; + char shortFilename[FAT_SFN_SIZE_FULL]; + int tailNum = 0; + + // No write access? + if (!_fs.disk_io.write_media) + return NULL; + + // Allocate a new file handle + file = _allocate_file(); + if (!file) + return NULL; + + // Clear filename + memset(file->path, '\0', sizeof(file->path)); + memset(file->filename, '\0', sizeof(file->filename)); + + // Split full path into filename and directory path + if (fatfs_split_path((char*)filename, file->path, sizeof(file->path), file->filename, sizeof(file->filename)) == -1) + { + _free_file(file); + return NULL; + } + + // Check if file already open + if (_check_file_open(file)) + { + _free_file(file); + return NULL; + } + + // If file is in the root dir + if (file->path[0] == 0) + file->parentcluster = fatfs_get_root_cluster(&_fs); + else + { + // Find parent directory start cluster + if (!_open_directory(file->path, &file->parentcluster)) + { + _free_file(file); + return NULL; + } + } + + // Check if same filename exists in directory + if (fatfs_get_file_entry(&_fs, file->parentcluster, file->filename,&sfEntry) == 1) + { + _free_file(file); + return NULL; + } + + file->startcluster = 0; + + // Create the file space for the file (at least one clusters worth!) + if (!fatfs_allocate_free_space(&_fs, 1, &file->startcluster, 1)) + { + _free_file(file); + return NULL; + } + +#if FATFS_INC_LFN_SUPPORT + // Generate a short filename & tail + tailNum = 0; + do + { + // Create a standard short filename (without tail) + fatfs_lfn_create_sfn(shortFilename, file->filename); + + // If second hit or more, generate a ~n tail + if (tailNum != 0) + fatfs_lfn_generate_tail((char*)file->shortfilename, shortFilename, tailNum); + // Try with no tail if first entry + else + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already or not + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename) == 0) + break; + + tailNum++; + } + while (tailNum < 9999); + + // We reached the max number of duplicate short file names (unlikely!) + if (tailNum == 9999) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } +#else + // Create a standard short filename (without tail) + if (!fatfs_lfn_create_sfn(shortFilename, file->filename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } + + // Copy to SFN space + memcpy(file->shortfilename, shortFilename, FAT_SFN_SIZE_FULL); + + // Check if entry exists already + if (fatfs_sfn_exists(&_fs, file->parentcluster, (char*)file->shortfilename)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } +#endif + + // Add file to disk + if (!fatfs_add_file_entry(&_fs, file->parentcluster, (char*)file->filename, (char*)file->shortfilename, file->startcluster, 0, 0)) + { + // Delete allocated space + fatfs_free_cluster_chain(&_fs, file->startcluster); + + _free_file(file); + return NULL; + } + + // General + file->filelength = 0; + file->bytenum = 0; + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Quick lookup for next link in the chain + file->last_fat_lookup.ClusterIdx = 0xFFFFFFFF; + file->last_fat_lookup.CurrentCluster = 0xFFFFFFFF; + + fatfs_cache_init(&_fs, file); + + fatfs_fat_purge(&_fs); + + return file; +} +#endif +//----------------------------------------------------------------------------- +// _read_sectors: Read sector(s) from disk to file +//----------------------------------------------------------------------------- +static uint32 _read_sectors(FL_FILE* file, uint32 offset, uint8 *buffer, uint32 count) +{ + uint32 Sector = 0; + uint32 ClusterIdx = 0; + uint32 Cluster = 0; + uint32 i; + uint32 lba; + + // Find cluster index within file & sector with cluster + ClusterIdx = offset / _fs.sectors_per_cluster; + Sector = offset - (ClusterIdx * _fs.sectors_per_cluster); + + // Limit number of sectors read to the number remaining in this cluster + if ((Sector + count) > _fs.sectors_per_cluster) + count = _fs.sectors_per_cluster - Sector; + + // Quick lookup for next link in the chain + if (ClusterIdx == file->last_fat_lookup.ClusterIdx) + Cluster = file->last_fat_lookup.CurrentCluster; + // Else walk the chain + else + { + // Starting from last recorded cluster? + if (ClusterIdx && ClusterIdx == file->last_fat_lookup.ClusterIdx + 1) + { + i = file->last_fat_lookup.ClusterIdx; + Cluster = file->last_fat_lookup.CurrentCluster; + } + // Start searching from the beginning.. + else + { + // Set start of cluster chain to initial value + i = 0; + Cluster = file->startcluster; + } + + // Follow chain to find cluster to read + for ( ;ilast_fat_lookup.CurrentCluster = Cluster; + file->last_fat_lookup.ClusterIdx = ClusterIdx; + } + } + + // If end of cluster chain then return false + if (Cluster == FAT32_LAST_CLUSTER) + return 0; + + // Calculate sector address + lba = fatfs_lba_of_cluster(&_fs, Cluster) + Sector; + + // Read sector of file + if (fatfs_sector_read(&_fs, lba, buffer, count)) + return count; + else + return 0; +} + +//----------------------------------------------------------------------------- +// External API +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// fl_init: Initialise library +//----------------------------------------------------------------------------- +void fl_init(void) +{ + int i; + + fat_list_init(&_free_file_list); + fat_list_init(&_open_file_list); + + // Add all file objects to free list + for (i=0;iflags = flags; + + FL_UNLOCK(&_fs); + return file; +} +//----------------------------------------------------------------------------- +// _write_sectors: Write sector(s) to disk +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +static uint32 _write_sectors(FL_FILE* file, uint32 offset, uint8 *buf, uint32 count) +{ + uint32 SectorNumber = 0; + uint32 ClusterIdx = 0; + uint32 Cluster = 0; + uint32 LastCluster = FAT32_LAST_CLUSTER; + uint32 i; + uint32 lba; + uint32 TotalWriteCount = count; + + // Find values for Cluster index & sector within cluster + ClusterIdx = offset / _fs.sectors_per_cluster; + SectorNumber = offset - (ClusterIdx * _fs.sectors_per_cluster); + + // Limit number of sectors written to the number remaining in this cluster + if ((SectorNumber + count) > _fs.sectors_per_cluster) + count = _fs.sectors_per_cluster - SectorNumber; + + // Quick lookup for next link in the chain + if (ClusterIdx == file->last_fat_lookup.ClusterIdx) + Cluster = file->last_fat_lookup.CurrentCluster; + // Else walk the chain + else + { + // Starting from last recorded cluster? + if (ClusterIdx && ClusterIdx == file->last_fat_lookup.ClusterIdx + 1) + { + i = file->last_fat_lookup.ClusterIdx; + Cluster = file->last_fat_lookup.CurrentCluster; + } + // Start searching from the beginning.. + else + { + // Set start of cluster chain to initial value + i = 0; + Cluster = file->startcluster; + } + + // Follow chain to find cluster to read + for ( ;ilast_fat_lookup.CurrentCluster = Cluster; + file->last_fat_lookup.ClusterIdx = ClusterIdx; + } + + // Calculate write address + lba = fatfs_lba_of_cluster(&_fs, Cluster) + SectorNumber; + + if (fatfs_sector_write(&_fs, lba, buf, count)) + return count; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fl_fflush: Flush un-written data to the file +//----------------------------------------------------------------------------- +int fl_fflush(void *f) +{ +#if FATFS_INC_WRITE_SUPPORT + FL_FILE *file = (FL_FILE *)f; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (file) + { + FL_LOCK(&_fs); + + // If some write data still in buffer + if (file->file_data_dirty) + { + // Write back current sector before loading next + if (_write_sectors(file, file->file_data_address, file->file_data_sector, 1)) + file->file_data_dirty = 0; + } + + FL_UNLOCK(&_fs); + } +#endif + return 0; +} +//----------------------------------------------------------------------------- +// fl_fclose: Close an open file +//----------------------------------------------------------------------------- +void fl_fclose(void *f) +{ + FL_FILE *file = (FL_FILE *)f; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (file) + { + FL_LOCK(&_fs); + + // Flush un-written data to file + fl_fflush(f); + + // File size changed? + if (file->filelength_changed) + { +#if FATFS_INC_WRITE_SUPPORT + // Update filesize in directory + fatfs_update_file_length(&_fs, file->parentcluster, (char*)file->shortfilename, file->filelength); +#endif + file->filelength_changed = 0; + } + + file->bytenum = 0; + file->filelength = 0; + file->startcluster = 0; + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + file->filelength_changed = 0; + + // Free file handle + _free_file(file); + + fatfs_fat_purge(&_fs); + + FL_UNLOCK(&_fs); + } +} +//----------------------------------------------------------------------------- +// fl_fgetc: Get a character in the stream +//----------------------------------------------------------------------------- +int fl_fgetc(void *f) +{ + int res; + uint8 data = 0; + + res = fl_fread(&data, 1, 1, f); + if (res == 1) + return (int)data; + else + return res; +} +//----------------------------------------------------------------------------- +// fl_fgets: Get a string from a stream +//----------------------------------------------------------------------------- +char *fl_fgets(char *s, int n, void *f) +{ + int idx = 0; + + // Space for null terminator? + if (n > 0) + { + // While space (+space for null terminator) + while (idx < (n-1)) + { + int ch = fl_fgetc(f); + + // EOF / Error? + if (ch < 0) + break; + + // Store character read from stream + s[idx++] = (char)ch; + + // End of line? + if (ch == '\n') + break; + } + + if (idx > 0) + s[idx] = '\0'; + } + + return (idx > 0) ? s : 0; +} +//----------------------------------------------------------------------------- +// fl_fread: Read a block of data from the file +//----------------------------------------------------------------------------- +int fl_fread(void * buffer, int size, int length, void *f ) +{ + uint32 sector; + uint32 offset; + int copyCount; + int count = size * length; + int bytesRead = 0; + + FL_FILE *file = (FL_FILE *)f; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (buffer==NULL || file==NULL) + return -1; + + // No read permissions + if (!(file->flags & FILE_READ)) + return -1; + + // Nothing to be done + if (!count) + return 0; + + // Check if read starts past end of file + if (file->bytenum >= file->filelength) + return -1; + + // Limit to file size + if ( (file->bytenum + count) > file->filelength ) + count = file->filelength - file->bytenum; + + // Calculate start sector + sector = file->bytenum / FAT_SECTOR_SIZE; + + // Offset to start copying data from first sector + offset = file->bytenum % FAT_SECTOR_SIZE; + + while (bytesRead < count) + { + // Read whole sector, read from media directly into target buffer + if ((offset == 0) && ((count - bytesRead) >= FAT_SECTOR_SIZE)) + { + // Read as many sectors as possible into target buffer + uint32 sectorsRead = _read_sectors(file, sector, (uint8*)((uint8*)buffer + bytesRead), (count - bytesRead) / FAT_SECTOR_SIZE); + if (sectorsRead) + { + // We have upto one sector to copy + copyCount = FAT_SECTOR_SIZE * sectorsRead; + + // Move onto next sector and reset copy offset + sector+= sectorsRead; + offset = 0; + } + else + break; + } + else + { + // Do we need to re-read the sector? + if (file->file_data_address != sector) + { + // Flush un-written data to file + if (file->file_data_dirty) + fl_fflush(file); + + // Get LBA of sector offset within file + if (!_read_sectors(file, sector, file->file_data_sector, 1)) + // Read failed - out of range (probably) + break; + + file->file_data_address = sector; + file->file_data_dirty = 0; + } + + // We have upto one sector to copy + copyCount = FAT_SECTOR_SIZE - offset; + + // Only require some of this sector? + if (copyCount > (count - bytesRead)) + copyCount = (count - bytesRead); + + // Copy to application buffer + memcpy( (uint8*)((uint8*)buffer + bytesRead), (uint8*)(file->file_data_sector + offset), copyCount); + + // Move onto next sector and reset copy offset + sector++; + offset = 0; + } + + // Increase total read count + bytesRead += copyCount; + + // Increment file pointer + file->bytenum += copyCount; + } + + return bytesRead; +} +//----------------------------------------------------------------------------- +// fl_fseek: Seek to a specific place in the file +//----------------------------------------------------------------------------- +int fl_fseek( void *f, long offset, int origin ) +{ + FL_FILE *file = (FL_FILE *)f; + int res = -1; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (!file) + return -1; + + if (origin == SEEK_END && offset != 0) + return -1; + + FL_LOCK(&_fs); + + // Invalidate file buffer + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + + if (origin == SEEK_SET) + { + file->bytenum = (uint32)offset; + + if (file->bytenum > file->filelength) + file->bytenum = file->filelength; + + res = 0; + } + else if (origin == SEEK_CUR) + { + // Positive shift + if (offset >= 0) + { + file->bytenum += offset; + + if (file->bytenum > file->filelength) + file->bytenum = file->filelength; + } + // Negative shift + else + { + // Make shift positive + offset = -offset; + + // Limit to negative shift to start of file + if ((uint32)offset > file->bytenum) + file->bytenum = 0; + else + file->bytenum-= offset; + } + + res = 0; + } + else if (origin == SEEK_END) + { + file->bytenum = file->filelength; + res = 0; + } + else + res = -1; + + FL_UNLOCK(&_fs); + + return res; +} +//----------------------------------------------------------------------------- +// fl_fgetpos: Get the current file position +//----------------------------------------------------------------------------- +int fl_fgetpos(void *f , uint32 * position) +{ + FL_FILE *file = (FL_FILE *)f; + + if (!file) + return -1; + + FL_LOCK(&_fs); + + // Get position + *position = file->bytenum; + + FL_UNLOCK(&_fs); + + return 0; +} +//----------------------------------------------------------------------------- +// fl_ftell: Get the current file position +//----------------------------------------------------------------------------- +long fl_ftell(void *f) +{ + uint32 pos = 0; + + fl_fgetpos(f, &pos); + + return (long)pos; +} +//----------------------------------------------------------------------------- +// fl_feof: Is the file pointer at the end of the stream? +//----------------------------------------------------------------------------- +int fl_feof(void *f) +{ + FL_FILE *file = (FL_FILE *)f; + int res; + + if (!file) + return -1; + + FL_LOCK(&_fs); + + if (file->bytenum == file->filelength) + res = EOF; + else + res = 0; + + FL_UNLOCK(&_fs); + + return res; +} +//----------------------------------------------------------------------------- +// fl_fputc: Write a character to the stream +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_fputc(int c, void *f) +{ + uint8 data = (uint8)c; + int res; + + res = fl_fwrite(&data, 1, 1, f); + if (res == 1) + return c; + else + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_fwrite: Write a block of data to the stream +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_fwrite(const void * data, int size, int count, void *f ) +{ + FL_FILE *file = (FL_FILE *)f; + uint32 sector; + uint32 offset; + uint32 length = (size*count); + uint8 *buffer = (uint8 *)data; + uint32 bytesWritten = 0; + uint32 copyCount; + + // If first call to library, initialise + CHECK_FL_INIT(); + + if (!file) + return -1; + + FL_LOCK(&_fs); + + // No write permissions + if (!(file->flags & FILE_WRITE)) + { + FL_UNLOCK(&_fs); + return -1; + } + + // Append writes to end of file + if (file->flags & FILE_APPEND) + file->bytenum = file->filelength; + // Else write to current position + + // Calculate start sector + sector = file->bytenum / FAT_SECTOR_SIZE; + + // Offset to start copying data from first sector + offset = file->bytenum % FAT_SECTOR_SIZE; + + while (bytesWritten < length) + { + // Whole sector or more to be written? + if ((offset == 0) && ((length - bytesWritten) >= FAT_SECTOR_SIZE)) + { + uint32 sectorsWrote; + + // Buffered sector, flush back to disk + if (file->file_data_address != 0xFFFFFFFF) + { + // Flush un-written data to file + if (file->file_data_dirty) + fl_fflush(file); + + file->file_data_address = 0xFFFFFFFF; + file->file_data_dirty = 0; + } + + // Write as many sectors as possible + sectorsWrote = _write_sectors(file, sector, (uint8*)(buffer + bytesWritten), (length - bytesWritten) / FAT_SECTOR_SIZE); + copyCount = FAT_SECTOR_SIZE * sectorsWrote; + + // Increase total read count + bytesWritten += copyCount; + + // Increment file pointer + file->bytenum += copyCount; + + // Move onto next sector and reset copy offset + sector+= sectorsWrote; + offset = 0; + + if (!sectorsWrote) + break; + } + else + { + // We have upto one sector to copy + copyCount = FAT_SECTOR_SIZE - offset; + + // Only require some of this sector? + if (copyCount > (length - bytesWritten)) + copyCount = (length - bytesWritten); + + // Do we need to read a new sector? + if (file->file_data_address != sector) + { + // Flush un-written data to file + if (file->file_data_dirty) + fl_fflush(file); + + // If we plan to overwrite the whole sector, we don't need to read it first! + if (copyCount != FAT_SECTOR_SIZE) + { + // NOTE: This does not have succeed; if last sector of file + // reached, no valid data will be read in, but write will + // allocate some more space for new data. + + // Get LBA of sector offset within file + if (!_read_sectors(file, sector, file->file_data_sector, 1)) + memset(file->file_data_sector, 0x00, FAT_SECTOR_SIZE); + } + + file->file_data_address = sector; + file->file_data_dirty = 0; + } + + // Copy from application buffer into sector buffer + memcpy((uint8*)(file->file_data_sector + offset), (uint8*)(buffer + bytesWritten), copyCount); + + // Mark buffer as dirty + file->file_data_dirty = 1; + + // Increase total read count + bytesWritten += copyCount; + + // Increment file pointer + file->bytenum += copyCount; + + // Move onto next sector and reset copy offset + sector++; + offset = 0; + } + } + + // Write increased extent of the file? + if (file->bytenum > file->filelength) + { + // Increase file size to new point + file->filelength = file->bytenum; + + // We are changing the file length and this + // will need to be writen back at some point + file->filelength_changed = 1; + } + +#if FATFS_INC_TIME_DATE_SUPPORT + // If time & date support is enabled, always force directory entry to be + // written in-order to update file modify / access time & date. + file->filelength_changed = 1; +#endif + + FL_UNLOCK(&_fs); + + return (size*count); +} +#endif +//----------------------------------------------------------------------------- +// fl_fputs: Write a character string to the stream +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_fputs(const char * str, void *f) +{ + int len = (int)strlen(str); + int res = fl_fwrite(str, 1, len, f); + + if (res == len) + return len; + else + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_remove: Remove a file from the filesystem +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_remove( const char * filename ) +{ + FL_FILE* file; + int res = -1; + + FL_LOCK(&_fs); + + // Use read_file as this will check if the file is already open! + file = fl_fopen((char*)filename, "r"); + if (file) + { + // Delete allocated space + if (fatfs_free_cluster_chain(&_fs, file->startcluster)) + { + // Remove directory entries + if (fatfs_mark_file_deleted(&_fs, file->parentcluster, (char*)file->shortfilename)) + { + // Close the file handle (this should not write anything to the file + // as we have not changed the file since opening it!) + fl_fclose(file); + + res = 0; + } + } + } + + FL_UNLOCK(&_fs); + + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_createdirectory: Create a directory based on a path +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fl_createdirectory(const char *path) +{ + int res; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + res =_create_directory((char*)path); + FL_UNLOCK(&_fs); + + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_listdirectory: List a directory based on a path +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +void fl_listdirectory(const char *path) +{ + FL_DIR dirstat; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + + FAT_PRINTF(("\r\nDirectory %s\r\n", path)); + + if (fl_opendir(path, &dirstat)) + { + struct fs_dir_ent dirent; + + while (fl_readdir(&dirstat, &dirent) == 0) + { +#if FATFS_INC_TIME_DATE_SUPPORT + int d,m,y,h,mn,s; + fatfs_convert_from_fat_time(dirent.write_time, &h,&m,&s); + fatfs_convert_from_fat_date(dirent.write_date, &d,&mn,&y); + FAT_PRINTF(("%02d/%02d/%04d %02d:%02d ", d,mn,y,h,m)); +#endif + + if (dirent.is_dir) + { + FAT_PRINTF(("%s \r\n", dirent.filename)); + } + else + { + FAT_PRINTF(("%s [%d bytes]\r\n", dirent.filename, dirent.size)); + } + } + + fl_closedir(&dirstat); + } + + FL_UNLOCK(&_fs); +} +#endif +//----------------------------------------------------------------------------- +// fl_opendir: Opens a directory for listing +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +FL_DIR* fl_opendir(const char* path, FL_DIR *dir) +{ + int levels; + int res = 1; + uint32 cluster = FAT32_INVALID_CLUSTER; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + + levels = fatfs_total_path_levels((char*)path) + 1; + + // If path is in the root dir + if (levels == 0) + cluster = fatfs_get_root_cluster(&_fs); + // Find parent directory start cluster + else + res = _open_directory((char*)path, &cluster); + + if (res) + fatfs_list_directory_start(&_fs, dir, cluster); + + FL_UNLOCK(&_fs); + + return cluster != FAT32_INVALID_CLUSTER ? dir : 0; +} +#endif +//----------------------------------------------------------------------------- +// fl_readdir: Get next item in directory +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fl_readdir(FL_DIR *dirls, fl_dirent *entry) +{ + int res = 0; + + // If first call to library, initialise + CHECK_FL_INIT(); + + FL_LOCK(&_fs); + + res = fatfs_list_directory_next(&_fs, dirls, entry); + + FL_UNLOCK(&_fs); + + return res ? 0 : -1; +} +#endif +//----------------------------------------------------------------------------- +// fl_closedir: Close directory after listing +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fl_closedir(FL_DIR* dir) +{ + // Not used + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fl_is_dir: Is this a directory? +//----------------------------------------------------------------------------- +#if FATFS_DIR_LIST_SUPPORT +int fl_is_dir(const char *path) +{ + int res = 0; + FL_DIR dir; + + if (fl_opendir(path, &dir)) + { + res = 1; + fl_closedir(&dir); + } + + return res; +} +#endif +//----------------------------------------------------------------------------- +// fl_format: Format a partition with either FAT16 or FAT32 based on size +//----------------------------------------------------------------------------- +#if FATFS_INC_FORMAT_SUPPORT +int fl_format(uint32 volume_sectors, const char *name) +{ + return fatfs_format(&_fs, volume_sectors, name); +} +#endif /*FATFS_INC_FORMAT_SUPPORT*/ +//----------------------------------------------------------------------------- +// fl_get_fs: +//----------------------------------------------------------------------------- +#ifdef FATFS_INC_TEST_HOOKS +struct fatfs* fl_get_fs(void) +{ + return &_fs; +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h new file mode 100644 index 00000000..a40a28ff --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_filelib.h @@ -0,0 +1,146 @@ +#ifndef __FAT_FILELIB_H__ +#define __FAT_FILELIB_H__ + +#include "fat_opts.h" +#include "fat_access.h" +#include "fat_list.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#ifndef SEEK_CUR + #define SEEK_CUR 1 +#endif + +#ifndef SEEK_END + #define SEEK_END 2 +#endif + +#ifndef SEEK_SET + #define SEEK_SET 0 +#endif + +#ifndef EOF + #define EOF (-1) +#endif + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct sFL_FILE; + +struct cluster_lookup +{ + uint32 ClusterIdx; + uint32 CurrentCluster; +}; + +typedef struct sFL_FILE +{ + uint32 parentcluster; + uint32 startcluster; + uint32 bytenum; + uint32 filelength; + int filelength_changed; + char path[FATFS_MAX_LONG_FILENAME]; + char filename[FATFS_MAX_LONG_FILENAME]; + uint8 shortfilename[11]; + +#ifdef FAT_CLUSTER_CACHE_ENTRIES + uint32 cluster_cache_idx[FAT_CLUSTER_CACHE_ENTRIES]; + uint32 cluster_cache_data[FAT_CLUSTER_CACHE_ENTRIES]; +#endif + + // Cluster Lookup + struct cluster_lookup last_fat_lookup; + + // Read/Write sector buffer + uint8 file_data_sector[FAT_SECTOR_SIZE]; + uint32 file_data_address; + int file_data_dirty; + + // File fopen flags + uint8 flags; +#define FILE_READ (1 << 0) +#define FILE_WRITE (1 << 1) +#define FILE_APPEND (1 << 2) +#define FILE_BINARY (1 << 3) +#define FILE_ERASE (1 << 4) +#define FILE_CREATE (1 << 5) + + struct fat_node list_node; +} FL_FILE; + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- + +// External +void fl_init(void); +void fl_attach_locks(void (*lock)(void), void (*unlock)(void)); +int fl_attach_media(fn_diskio_read rd, fn_diskio_write wr); +void fl_shutdown(void); + +// Standard API +void* fl_fopen(const char *path, const char *modifiers); +void fl_fclose(void *file); +int fl_fflush(void *file); +int fl_fgetc(void *file); +char * fl_fgets(char *s, int n, void *f); +int fl_fputc(int c, void *file); +int fl_fputs(const char * str, void *file); +int fl_fwrite(const void * data, int size, int count, void *file ); +int fl_fread(void * data, int size, int count, void *file ); +int fl_fseek(void *file , long offset , int origin ); +int fl_fgetpos(void *file , uint32 * position); +long fl_ftell(void *f); +int fl_feof(void *f); +int fl_remove(const char * filename); + +// Equivelant dirent.h +typedef struct fs_dir_list_status FL_DIR; +typedef struct fs_dir_ent fl_dirent; + +FL_DIR* fl_opendir(const char* path, FL_DIR *dir); +int fl_readdir(FL_DIR *dirls, fl_dirent *entry); +int fl_closedir(FL_DIR* dir); + +// Extensions +void fl_listdirectory(const char *path); +int fl_createdirectory(const char *path); +int fl_is_dir(const char *path); + +int fl_format(uint32 volume_sectors, const char *name); + +// Test hooks +#ifdef FATFS_INC_TEST_HOOKS +struct fatfs* fl_get_fs(void); +#endif + +//----------------------------------------------------------------------------- +// Stdio file I/O names +//----------------------------------------------------------------------------- +#ifdef USE_FILELIB_STDIO_COMPAT_NAMES + +#define FILE FL_FILE + +#define fopen(a,b) fl_fopen(a, b) +#define fclose(a) fl_fclose(a) +#define fflush(a) fl_fflush(a) +#define fgetc(a) fl_fgetc(a) +#define fgets(a,b,c) fl_fgets(a, b, c) +#define fputc(a,b) fl_fputc(a, b) +#define fputs(a,b) fl_fputs(a, b) +#define fwrite(a,b,c,d) fl_fwrite(a, b, c, d) +#define fread(a,b,c,d) fl_fread(a, b, c, d) +#define fseek(a,b,c) fl_fseek(a, b, c) +#define fgetpos(a,b) fl_fgetpos(a, b) +#define ftell(a) fl_ftell(a) +#define feof(a) fl_feof(a) +#define remove(a) fl_remove(a) +#define mkdir(a) fl_createdirectory(a) +#define rmdir(a) 0 + +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.c new file mode 100644 index 00000000..d067f377 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.c @@ -0,0 +1,532 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_string.h" +#include "fat_misc.h" +#include "fat_format.h" + +#if FATFS_INC_FORMAT_SUPPORT + +//----------------------------------------------------------------------------- +// Tables +//----------------------------------------------------------------------------- +struct sec_per_clus_table +{ + uint32 sectors; + uint8 sectors_per_cluster; +}; + +struct sec_per_clus_table _cluster_size_table16[] = +{ + { 32680, 2}, // 16MB - 1K + { 262144, 4}, // 128MB - 2K + { 524288, 8}, // 256MB - 4K + { 1048576, 16}, // 512MB - 8K + { 2097152, 32}, // 1GB - 16K + { 4194304, 64}, // 2GB - 32K + { 8388608, 128},// 2GB - 64K [Warning only supported by Windows XP onwards] + { 0 , 0 } // Invalid +}; + +struct sec_per_clus_table _cluster_size_table32[] = +{ + { 532480, 1}, // 260MB - 512b + { 16777216, 8}, // 8GB - 4K + { 33554432, 16}, // 16GB - 8K + { 67108864, 32}, // 32GB - 16K + { 0xFFFFFFFF, 64},// >32GB - 32K + { 0 , 0 } // Invalid +}; + +//----------------------------------------------------------------------------- +// fatfs_calc_cluster_size: Calculate what cluster size should be used +//----------------------------------------------------------------------------- +static uint8 fatfs_calc_cluster_size(uint32 sectors, int is_fat32) +{ + int i; + + if (!is_fat32) + { + for (i=0; _cluster_size_table16[i].sectors_per_cluster != 0;i++) + if (sectors <= _cluster_size_table16[i].sectors) + return _cluster_size_table16[i].sectors_per_cluster; + } + else + { + for (i=0; _cluster_size_table32[i].sectors_per_cluster != 0;i++) + if (sectors <= _cluster_size_table32[i].sectors) + return _cluster_size_table32[i].sectors_per_cluster; + } + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_erase_sectors: Erase a number of sectors +//----------------------------------------------------------------------------- +static int fatfs_erase_sectors(struct fatfs *fs, uint32 lba, int count) +{ + int i; + + // Zero sector first + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + for (i=0;idisk_io.write_media(lba + i, fs->currentsector.sector, 1)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_create_boot_sector: Create the boot sector +//----------------------------------------------------------------------------- +static int fatfs_create_boot_sector(struct fatfs *fs, uint32 boot_sector_lba, uint32 vol_sectors, const char *name, int is_fat32) +{ + uint32 total_clusters; + int i; + + // Zero sector initially + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + // OEM Name & Jump Code + fs->currentsector.sector[0] = 0xEB; + fs->currentsector.sector[1] = 0x3C; + fs->currentsector.sector[2] = 0x90; + fs->currentsector.sector[3] = 0x4D; + fs->currentsector.sector[4] = 0x53; + fs->currentsector.sector[5] = 0x44; + fs->currentsector.sector[6] = 0x4F; + fs->currentsector.sector[7] = 0x53; + fs->currentsector.sector[8] = 0x35; + fs->currentsector.sector[9] = 0x2E; + fs->currentsector.sector[10] = 0x30; + + // Bytes per sector + fs->currentsector.sector[11] = (FAT_SECTOR_SIZE >> 0) & 0xFF; + fs->currentsector.sector[12] = (FAT_SECTOR_SIZE >> 8) & 0xFF; + + // Get sectors per cluster size for the disk + fs->sectors_per_cluster = fatfs_calc_cluster_size(vol_sectors, is_fat32); + if (!fs->sectors_per_cluster) + return 0; // Invalid disk size + + // Sectors per cluster + fs->currentsector.sector[13] = fs->sectors_per_cluster; + + // Reserved Sectors + if (!is_fat32) + fs->reserved_sectors = 8; + else + fs->reserved_sectors = 32; + fs->currentsector.sector[14] = (fs->reserved_sectors >> 0) & 0xFF; + fs->currentsector.sector[15] = (fs->reserved_sectors >> 8) & 0xFF; + + // Number of FATS + fs->num_of_fats = 2; + fs->currentsector.sector[16] = fs->num_of_fats; + + // Max entries in root dir (FAT16 only) + if (!is_fat32) + { + fs->root_entry_count = 512; + fs->currentsector.sector[17] = (fs->root_entry_count >> 0) & 0xFF; + fs->currentsector.sector[18] = (fs->root_entry_count >> 8) & 0xFF; + } + else + { + fs->root_entry_count = 0; + fs->currentsector.sector[17] = 0; + fs->currentsector.sector[18] = 0; + } + + // [FAT16] Total sectors (use FAT32 count instead) + fs->currentsector.sector[19] = 0x00; + fs->currentsector.sector[20] = 0x00; + + // Media type + fs->currentsector.sector[21] = 0xF8; + + + // FAT16 BS Details + if (!is_fat32) + { + // Count of sectors used by the FAT table (FAT16 only) + total_clusters = (vol_sectors / fs->sectors_per_cluster) + 1; + fs->fat_sectors = (total_clusters/(FAT_SECTOR_SIZE/2)) + 1; + fs->currentsector.sector[22] = (uint8)((fs->fat_sectors >> 0) & 0xFF); + fs->currentsector.sector[23] = (uint8)((fs->fat_sectors >> 8) & 0xFF); + + // Sectors per track + fs->currentsector.sector[24] = 0x00; + fs->currentsector.sector[25] = 0x00; + + // Heads + fs->currentsector.sector[26] = 0x00; + fs->currentsector.sector[27] = 0x00; + + // Hidden sectors + fs->currentsector.sector[28] = 0x20; + fs->currentsector.sector[29] = 0x00; + fs->currentsector.sector[30] = 0x00; + fs->currentsector.sector[31] = 0x00; + + // Total sectors for this volume + fs->currentsector.sector[32] = (uint8)((vol_sectors>>0)&0xFF); + fs->currentsector.sector[33] = (uint8)((vol_sectors>>8)&0xFF); + fs->currentsector.sector[34] = (uint8)((vol_sectors>>16)&0xFF); + fs->currentsector.sector[35] = (uint8)((vol_sectors>>24)&0xFF); + + // Drive number + fs->currentsector.sector[36] = 0x00; + + // Reserved + fs->currentsector.sector[37] = 0x00; + + // Boot signature + fs->currentsector.sector[38] = 0x29; + + // Volume ID + fs->currentsector.sector[39] = 0x12; + fs->currentsector.sector[40] = 0x34; + fs->currentsector.sector[41] = 0x56; + fs->currentsector.sector[42] = 0x78; + + // Volume name + for (i=0;i<11;i++) + { + if (i < (int)strlen(name)) + fs->currentsector.sector[i+43] = name[i]; + else + fs->currentsector.sector[i+43] = ' '; + } + + // File sys type + fs->currentsector.sector[54] = 'F'; + fs->currentsector.sector[55] = 'A'; + fs->currentsector.sector[56] = 'T'; + fs->currentsector.sector[57] = '1'; + fs->currentsector.sector[58] = '6'; + fs->currentsector.sector[59] = ' '; + fs->currentsector.sector[60] = ' '; + fs->currentsector.sector[61] = ' '; + + // Signature + fs->currentsector.sector[510] = 0x55; + fs->currentsector.sector[511] = 0xAA; + } + // FAT32 BS Details + else + { + // Count of sectors used by the FAT table (FAT16 only) + fs->currentsector.sector[22] = 0; + fs->currentsector.sector[23] = 0; + + // Sectors per track (default) + fs->currentsector.sector[24] = 0x3F; + fs->currentsector.sector[25] = 0x00; + + // Heads (default) + fs->currentsector.sector[26] = 0xFF; + fs->currentsector.sector[27] = 0x00; + + // Hidden sectors + fs->currentsector.sector[28] = 0x00; + fs->currentsector.sector[29] = 0x00; + fs->currentsector.sector[30] = 0x00; + fs->currentsector.sector[31] = 0x00; + + // Total sectors for this volume + fs->currentsector.sector[32] = (uint8)((vol_sectors>>0)&0xFF); + fs->currentsector.sector[33] = (uint8)((vol_sectors>>8)&0xFF); + fs->currentsector.sector[34] = (uint8)((vol_sectors>>16)&0xFF); + fs->currentsector.sector[35] = (uint8)((vol_sectors>>24)&0xFF); + + total_clusters = (vol_sectors / fs->sectors_per_cluster) + 1; + fs->fat_sectors = (total_clusters/(FAT_SECTOR_SIZE/4)) + 1; + + // BPB_FATSz32 + fs->currentsector.sector[36] = (uint8)((fs->fat_sectors>>0)&0xFF); + fs->currentsector.sector[37] = (uint8)((fs->fat_sectors>>8)&0xFF); + fs->currentsector.sector[38] = (uint8)((fs->fat_sectors>>16)&0xFF); + fs->currentsector.sector[39] = (uint8)((fs->fat_sectors>>24)&0xFF); + + // BPB_ExtFlags + fs->currentsector.sector[40] = 0; + fs->currentsector.sector[41] = 0; + + // BPB_FSVer + fs->currentsector.sector[42] = 0; + fs->currentsector.sector[43] = 0; + + // BPB_RootClus + fs->currentsector.sector[44] = (uint8)((fs->rootdir_first_cluster>>0)&0xFF); + fs->currentsector.sector[45] = (uint8)((fs->rootdir_first_cluster>>8)&0xFF); + fs->currentsector.sector[46] = (uint8)((fs->rootdir_first_cluster>>16)&0xFF); + fs->currentsector.sector[47] = (uint8)((fs->rootdir_first_cluster>>24)&0xFF); + + // BPB_FSInfo + fs->currentsector.sector[48] = (uint8)((fs->fs_info_sector>>0)&0xFF); + fs->currentsector.sector[49] = (uint8)((fs->fs_info_sector>>8)&0xFF); + + // BPB_BkBootSec + fs->currentsector.sector[50] = 6; + fs->currentsector.sector[51] = 0; + + // Drive number + fs->currentsector.sector[64] = 0x00; + + // Boot signature + fs->currentsector.sector[66] = 0x29; + + // Volume ID + fs->currentsector.sector[67] = 0x12; + fs->currentsector.sector[68] = 0x34; + fs->currentsector.sector[69] = 0x56; + fs->currentsector.sector[70] = 0x78; + + // Volume name + for (i=0;i<11;i++) + { + if (i < (int)strlen(name)) + fs->currentsector.sector[i+71] = name[i]; + else + fs->currentsector.sector[i+71] = ' '; + } + + // File sys type + fs->currentsector.sector[82] = 'F'; + fs->currentsector.sector[83] = 'A'; + fs->currentsector.sector[84] = 'T'; + fs->currentsector.sector[85] = '3'; + fs->currentsector.sector[86] = '2'; + fs->currentsector.sector[87] = ' '; + fs->currentsector.sector[88] = ' '; + fs->currentsector.sector[89] = ' '; + + // Signature + fs->currentsector.sector[510] = 0x55; + fs->currentsector.sector[511] = 0xAA; + } + + if (fs->disk_io.write_media(boot_sector_lba, fs->currentsector.sector, 1)) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_create_fsinfo_sector: Create the FSInfo sector (FAT32) +//----------------------------------------------------------------------------- +static int fatfs_create_fsinfo_sector(struct fatfs *fs, uint32 sector_lba) +{ + // Zero sector initially + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + // FSI_LeadSig + fs->currentsector.sector[0] = 0x52; + fs->currentsector.sector[1] = 0x52; + fs->currentsector.sector[2] = 0x61; + fs->currentsector.sector[3] = 0x41; + + // FSI_StrucSig + fs->currentsector.sector[484] = 0x72; + fs->currentsector.sector[485] = 0x72; + fs->currentsector.sector[486] = 0x41; + fs->currentsector.sector[487] = 0x61; + + // FSI_Free_Count + fs->currentsector.sector[488] = 0xFF; + fs->currentsector.sector[489] = 0xFF; + fs->currentsector.sector[490] = 0xFF; + fs->currentsector.sector[491] = 0xFF; + + // FSI_Nxt_Free + fs->currentsector.sector[492] = 0xFF; + fs->currentsector.sector[493] = 0xFF; + fs->currentsector.sector[494] = 0xFF; + fs->currentsector.sector[495] = 0xFF; + + // Signature + fs->currentsector.sector[510] = 0x55; + fs->currentsector.sector[511] = 0xAA; + + if (fs->disk_io.write_media(sector_lba, fs->currentsector.sector, 1)) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_erase_fat: Erase FAT table using fs details in fs struct +//----------------------------------------------------------------------------- +static int fatfs_erase_fat(struct fatfs *fs, int is_fat32) +{ + uint32 i; + + // Zero sector initially + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + + // Initialise default allocate / reserved clusters + if (!is_fat32) + { + SET_16BIT_WORD(fs->currentsector.sector, 0, 0xFFF8); + SET_16BIT_WORD(fs->currentsector.sector, 2, 0xFFFF); + } + else + { + SET_32BIT_WORD(fs->currentsector.sector, 0, 0x0FFFFFF8); + SET_32BIT_WORD(fs->currentsector.sector, 4, 0xFFFFFFFF); + SET_32BIT_WORD(fs->currentsector.sector, 8, 0x0FFFFFFF); + } + + if (!fs->disk_io.write_media(fs->fat_begin_lba + 0, fs->currentsector.sector, 1)) + return 0; + + // Zero remaining FAT sectors + memset(fs->currentsector.sector, 0, FAT_SECTOR_SIZE); + for (i=1;ifat_sectors*fs->num_of_fats;i++) + if (!fs->disk_io.write_media(fs->fat_begin_lba + i, fs->currentsector.sector, 1)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_format_fat16: Format a FAT16 partition +//----------------------------------------------------------------------------- +int fatfs_format_fat16(struct fatfs *fs, uint32 volume_sectors, const char *name) +{ + fs->currentsector.address = FAT32_INVALID_CLUSTER; + fs->currentsector.dirty = 0; + + fs->next_free_cluster = 0; // Invalid + + fatfs_fat_init(fs); + + // Make sure we have read + write functions + if (!fs->disk_io.read_media || !fs->disk_io.write_media) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Volume is FAT16 + fs->fat_type = FAT_TYPE_16; + + // Not valid for FAT16 + fs->fs_info_sector = 0; + fs->rootdir_first_cluster = 0; + + // Sector 0: Boot sector + // NOTE: We don't need an MBR, it is a waste of a good sector! + fs->lba_begin = 0; + if (!fatfs_create_boot_sector(fs, fs->lba_begin, volume_sectors, name, 0)) + return 0; + + // For FAT16 (which this may be), rootdir_first_cluster is actuall rootdir_first_sector + fs->rootdir_first_sector = fs->reserved_sectors + (fs->num_of_fats * fs->fat_sectors); + fs->rootdir_sectors = ((fs->root_entry_count * 32) + (FAT_SECTOR_SIZE - 1)) / FAT_SECTOR_SIZE; + + // First FAT LBA address + fs->fat_begin_lba = fs->lba_begin + fs->reserved_sectors; + + // The address of the first data cluster on this volume + fs->cluster_begin_lba = fs->fat_begin_lba + (fs->num_of_fats * fs->fat_sectors); + + // Initialise FAT sectors + if (!fatfs_erase_fat(fs, 0)) + return 0; + + // Erase Root directory + if (!fatfs_erase_sectors(fs, fs->lba_begin + fs->rootdir_first_sector, fs->rootdir_sectors)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_format_fat32: Format a FAT32 partition +//----------------------------------------------------------------------------- +int fatfs_format_fat32(struct fatfs *fs, uint32 volume_sectors, const char *name) +{ + fs->currentsector.address = FAT32_INVALID_CLUSTER; + fs->currentsector.dirty = 0; + + fs->next_free_cluster = 0; // Invalid + + fatfs_fat_init(fs); + + // Make sure we have read + write functions + if (!fs->disk_io.read_media || !fs->disk_io.write_media) + return FAT_INIT_MEDIA_ACCESS_ERROR; + + // Volume is FAT32 + fs->fat_type = FAT_TYPE_32; + + // Basic defaults for normal FAT32 partitions + fs->fs_info_sector = 1; + fs->rootdir_first_cluster = 2; + + // Sector 0: Boot sector + // NOTE: We don't need an MBR, it is a waste of a good sector! + fs->lba_begin = 0; + if (!fatfs_create_boot_sector(fs, fs->lba_begin, volume_sectors, name, 1)) + return 0; + + // First FAT LBA address + fs->fat_begin_lba = fs->lba_begin + fs->reserved_sectors; + + // The address of the first data cluster on this volume + fs->cluster_begin_lba = fs->fat_begin_lba + (fs->num_of_fats * fs->fat_sectors); + + // Initialise FSInfo sector + if (!fatfs_create_fsinfo_sector(fs, fs->fs_info_sector)) + return 0; + + // Initialise FAT sectors + if (!fatfs_erase_fat(fs, 1)) + return 0; + + // Erase Root directory + if (!fatfs_erase_sectors(fs, fatfs_lba_of_cluster(fs, fs->rootdir_first_cluster), fs->sectors_per_cluster)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_format: Format a partition with either FAT16 or FAT32 based on size +//----------------------------------------------------------------------------- +int fatfs_format(struct fatfs *fs, uint32 volume_sectors, const char *name) +{ + // 2GB - 32K limit for safe behaviour for FAT16 + if (volume_sectors <= 4194304) + return fatfs_format_fat16(fs, volume_sectors, name); + else + return fatfs_format_fat32(fs, volume_sectors, name); +} +#endif /*FATFS_INC_FORMAT_SUPPORT*/ diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.h new file mode 100644 index 00000000..a8a6bbaf --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_format.h @@ -0,0 +1,15 @@ +#ifndef __FAT_FORMAT_H__ +#define __FAT_FORMAT_H__ + +#include "fat_defs.h" +#include "fat_opts.h" +#include "fat_access.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_format(struct fatfs *fs, uint32 volume_sectors, const char *name); +int fatfs_format_fat16(struct fatfs *fs, uint32 volume_sectors, const char *name); +int fatfs_format_fat32(struct fatfs *fs, uint32 volume_sectors, const char *name); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_list.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_list.h new file mode 100644 index 00000000..bd386ef6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_list.h @@ -0,0 +1,161 @@ +#ifndef __FAT_LIST_H__ +#define __FAT_LIST_H__ + +#ifndef FAT_ASSERT + #define FAT_ASSERT(x) +#endif + +#ifndef FAT_INLINE + #define FAT_INLINE +#endif + +//----------------------------------------------------------------- +// Types +//----------------------------------------------------------------- +struct fat_list; + +struct fat_node +{ + struct fat_node *previous; + struct fat_node *next; +}; + +struct fat_list +{ + struct fat_node *head; + struct fat_node *tail; +}; + +//----------------------------------------------------------------- +// Macros +//----------------------------------------------------------------- +#define fat_list_entry(p, t, m) p ? ((t *)((char *)(p)-(char*)(&((t *)0)->m))) : 0 +#define fat_list_next(l, p) (p)->next +#define fat_list_prev(l, p) (p)->previous +#define fat_list_first(l) (l)->head +#define fat_list_last(l) (l)->tail +#define fat_list_for_each(l, p) for ((p) = (l)->head; (p); (p) = (p)->next) + +//----------------------------------------------------------------- +// Inline Functions +//----------------------------------------------------------------- + +//----------------------------------------------------------------- +// fat_list_init: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_init(struct fat_list *list) +{ + FAT_ASSERT(list); + + list->head = list->tail = 0; +} +//----------------------------------------------------------------- +// fat_list_remove: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_remove(struct fat_list *list, struct fat_node *node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + + if(!node->previous) + list->head = node->next; + else + node->previous->next = node->next; + + if(!node->next) + list->tail = node->previous; + else + node->next->previous = node->previous; +} +//----------------------------------------------------------------- +// fat_list_insert_after: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_after(struct fat_list *list, struct fat_node *node, struct fat_node *new_node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + FAT_ASSERT(new_node); + + new_node->previous = node; + new_node->next = node->next; + if (!node->next) + list->tail = new_node; + else + node->next->previous = new_node; + node->next = new_node; +} +//----------------------------------------------------------------- +// fat_list_insert_before: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_before(struct fat_list *list, struct fat_node *node, struct fat_node *new_node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + FAT_ASSERT(new_node); + + new_node->previous = node->previous; + new_node->next = node; + if (!node->previous) + list->head = new_node; + else + node->previous->next = new_node; + node->previous = new_node; +} +//----------------------------------------------------------------- +// fat_list_insert_first: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_first(struct fat_list *list, struct fat_node *node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + + if (!list->head) + { + list->head = node; + list->tail = node; + node->previous = 0; + node->next = 0; + } + else + fat_list_insert_before(list, list->head, node); +} +//----------------------------------------------------------------- +// fat_list_insert_last: +//----------------------------------------------------------------- +static FAT_INLINE void fat_list_insert_last(struct fat_list *list, struct fat_node *node) +{ + FAT_ASSERT(list); + FAT_ASSERT(node); + + if (!list->tail) + fat_list_insert_first(list, node); + else + fat_list_insert_after(list, list->tail, node); +} +//----------------------------------------------------------------- +// fat_list_is_empty: +//----------------------------------------------------------------- +static FAT_INLINE int fat_list_is_empty(struct fat_list *list) +{ + FAT_ASSERT(list); + + return !list->head; +} +//----------------------------------------------------------------- +// fat_list_pop_head: +//----------------------------------------------------------------- +static FAT_INLINE struct fat_node * fat_list_pop_head(struct fat_list *list) +{ + struct fat_node * node; + + FAT_ASSERT(list); + + node = fat_list_first(list); + if (node) + fat_list_remove(list, node); + + return node; +} + +#endif + diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.c new file mode 100644 index 00000000..cbf6f08d --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.c @@ -0,0 +1,505 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include +#include "fat_misc.h" + +//----------------------------------------------------------------------------- +// fatfs_lfn_cache_init: Clear long file name cache +//----------------------------------------------------------------------------- +void fatfs_lfn_cache_init(struct lfn_cache *lfn, int wipeTable) +{ + int i = 0; + + lfn->no_of_strings = 0; + +#if FATFS_INC_LFN_SUPPORT + + // Zero out buffer also + if (wipeTable) + for (i=0;iString[i], 0x00, MAX_LFN_ENTRY_LENGTH); +#endif +} +//----------------------------------------------------------------------------- +// fatfs_lfn_cache_entry - Function extracts long file name text from sector +// at a specific offset +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +void fatfs_lfn_cache_entry(struct lfn_cache *lfn, uint8 *entryBuffer) +{ + uint8 LFNIndex, i; + LFNIndex = entryBuffer[0] & 0x1F; + + // Limit file name to cache size! + if (LFNIndex > MAX_LONGFILENAME_ENTRIES) + return ; + + // This is an error condition + if (LFNIndex == 0) + return ; + + if (lfn->no_of_strings == 0) + lfn->no_of_strings = LFNIndex; + + lfn->String[LFNIndex-1][0] = entryBuffer[1]; + lfn->String[LFNIndex-1][1] = entryBuffer[3]; + lfn->String[LFNIndex-1][2] = entryBuffer[5]; + lfn->String[LFNIndex-1][3] = entryBuffer[7]; + lfn->String[LFNIndex-1][4] = entryBuffer[9]; + lfn->String[LFNIndex-1][5] = entryBuffer[0x0E]; + lfn->String[LFNIndex-1][6] = entryBuffer[0x10]; + lfn->String[LFNIndex-1][7] = entryBuffer[0x12]; + lfn->String[LFNIndex-1][8] = entryBuffer[0x14]; + lfn->String[LFNIndex-1][9] = entryBuffer[0x16]; + lfn->String[LFNIndex-1][10] = entryBuffer[0x18]; + lfn->String[LFNIndex-1][11] = entryBuffer[0x1C]; + lfn->String[LFNIndex-1][12] = entryBuffer[0x1E]; + + for (i=0; iString[LFNIndex-1][i]==0xFF) + lfn->String[LFNIndex-1][i] = 0x20; // Replace with spaces +} +#endif +//----------------------------------------------------------------------------- +// fatfs_lfn_cache_get: Get a reference to the long filename +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +char* fatfs_lfn_cache_get(struct lfn_cache *lfn) +{ + // Null terminate long filename + if (lfn->no_of_strings == MAX_LONGFILENAME_ENTRIES) + lfn->Null = '\0'; + else if (lfn->no_of_strings) + lfn->String[lfn->no_of_strings][0] = '\0'; + else + lfn->String[0][0] = '\0'; + + return (char*)&lfn->String[0][0]; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_lfn_text: If LFN text entry found +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_entry_lfn_text(struct fat_dir_entry *entry) +{ + if ((entry->Attr & FILE_ATTR_LFN_TEXT) == FILE_ATTR_LFN_TEXT) + return 1; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_lfn_invalid: If SFN found not relating to LFN +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_entry_lfn_invalid(struct fat_dir_entry *entry) +{ + if ( (entry->Name[0]==FILE_HEADER_BLANK) || + (entry->Name[0]==FILE_HEADER_DELETED)|| + (entry->Attr==FILE_ATTR_VOLUME_ID) || + (entry->Attr & FILE_ATTR_SYSHID) ) + return 1; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_lfn_exists: If LFN exists and correlation SFN found +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_entry_lfn_exists(struct lfn_cache *lfn, struct fat_dir_entry *entry) +{ + if ( (entry->Attr!=FILE_ATTR_LFN_TEXT) && + (entry->Name[0]!=FILE_HEADER_BLANK) && + (entry->Name[0]!=FILE_HEADER_DELETED) && + (entry->Attr!=FILE_ATTR_VOLUME_ID) && + (!(entry->Attr&FILE_ATTR_SYSHID)) && + (lfn->no_of_strings) ) + return 1; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_entry_sfn_only: If SFN only exists +//----------------------------------------------------------------------------- +int fatfs_entry_sfn_only(struct fat_dir_entry *entry) +{ + if ( (entry->Attr!=FILE_ATTR_LFN_TEXT) && + (entry->Name[0]!=FILE_HEADER_BLANK) && + (entry->Name[0]!=FILE_HEADER_DELETED) && + (entry->Attr!=FILE_ATTR_VOLUME_ID) && + (!(entry->Attr&FILE_ATTR_SYSHID)) ) + return 1; + else + return 0; +} +// TODO: FILE_ATTR_SYSHID ?!?!??! +//----------------------------------------------------------------------------- +// fatfs_entry_is_dir: Returns 1 if a directory +//----------------------------------------------------------------------------- +int fatfs_entry_is_dir(struct fat_dir_entry *entry) +{ + if (entry->Attr & FILE_TYPE_DIR) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_entry_is_file: Returns 1 is a file entry +//----------------------------------------------------------------------------- +int fatfs_entry_is_file(struct fat_dir_entry *entry) +{ + if (entry->Attr & FILE_TYPE_FILE) + return 1; + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_lfn_entries_required: Calculate number of 13 characters entries +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +int fatfs_lfn_entries_required(char *filename) +{ + int length = (int)strlen(filename); + + if (length) + return (length + MAX_LFN_ENTRY_LENGTH - 1) / MAX_LFN_ENTRY_LENGTH; + else + return 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_filename_to_lfn: +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +void fatfs_filename_to_lfn(char *filename, uint8 *buffer, int entry, uint8 sfnChk) +{ + int i; + int nameIndexes[MAX_LFN_ENTRY_LENGTH] = {1,3,5,7,9,0x0E,0x10,0x12,0x14,0x16,0x18,0x1C,0x1E}; + + // 13 characters entries + int length = (int)strlen(filename); + int entriesRequired = fatfs_lfn_entries_required(filename); + + // Filename offset + int start = entry * MAX_LFN_ENTRY_LENGTH; + + // Initialise to zeros + memset(buffer, 0x00, FAT_DIR_ENTRY_SIZE); + + // LFN entry number + buffer[0] = (uint8)(((entriesRequired-1)==entry)?(0x40|(entry+1)):(entry+1)); + + // LFN flag + buffer[11] = 0x0F; + + // Checksum of short filename + buffer[13] = sfnChk; + + // Copy to buffer + for (i=0;iName[i] = shortfilename[i]; + + // Unless we have a RTC we might as well set these to 1980 + entry->CrtTimeTenth = 0x00; + entry->CrtTime[1] = entry->CrtTime[0] = 0x00; + entry->CrtDate[1] = 0x00; + entry->CrtDate[0] = 0x20; + entry->LstAccDate[1] = 0x00; + entry->LstAccDate[0] = 0x20; + entry->WrtTime[1] = entry->WrtTime[0] = 0x00; + entry->WrtDate[1] = 0x00; + entry->WrtDate[0] = 0x20; + + if (!dir) + entry->Attr = FILE_TYPE_FILE; + else + entry->Attr = FILE_TYPE_DIR; + + entry->NTRes = 0x00; + + entry->FstClusHI = FAT_HTONS((uint16)((startCluster>>16) & 0xFFFF)); + entry->FstClusLO = FAT_HTONS((uint16)((startCluster>>0) & 0xFFFF)); + entry->FileSize = FAT_HTONL(size); +} +#endif +//----------------------------------------------------------------------------- +// fatfs_lfn_create_sfn: Create a padded SFN +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_lfn_create_sfn(char *sfn_output, char *filename) +{ + int i; + int dotPos = -1; + char ext[3]; + int pos; + int len = (int)strlen(filename); + + // Invalid to start with . + if (filename[0]=='.') + return 0; + + memset(sfn_output, ' ', FAT_SFN_SIZE_FULL); + memset(ext, ' ', 3); + + // Find dot seperator + for (i = 0; i< len; i++) + { + if (filename[i]=='.') + dotPos = i; + } + + // Extract extensions + if (dotPos!=-1) + { + // Copy first three chars of extension + for (i = (dotPos+1); i < (dotPos+1+3); i++) + if (i= 'a' && filename[i] <= 'z') + sfn_output[pos++] = filename[i] - 'a' + 'A'; + else + sfn_output[pos++] = filename[i]; + } + + // Fill upto 8 characters + if (pos==FAT_SFN_SIZE_PARTIAL) + break; + } + + // Add extension part + for (i=FAT_SFN_SIZE_PARTIAL;i= 'a' && ext[i-FAT_SFN_SIZE_PARTIAL] <= 'z') + sfn_output[i] = ext[i-FAT_SFN_SIZE_PARTIAL] - 'a' + 'A'; + else + sfn_output[i] = ext[i-FAT_SFN_SIZE_PARTIAL]; + } + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_itoa: +//----------------------------------------------------------------------------- +static void fatfs_itoa(uint32 num, char *s) +{ + char* cp; + char outbuf[12]; + const char digits[] = "0123456789ABCDEF"; + + // Build string backwards + cp = outbuf; + do + { + *cp++ = digits[(int)(num % 10)]; + } + while ((num /= 10) > 0); + + *cp-- = 0; + + // Copy in forwards + while (cp >= outbuf) + *s++ = *cp--; + + *s = 0; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_lfn_generate_tail: +// sfn_input = Input short filename, spaced format & in upper case +// sfn_output = Output short filename with tail +//----------------------------------------------------------------------------- +#if FATFS_INC_LFN_SUPPORT +#if FATFS_INC_WRITE_SUPPORT +int fatfs_lfn_generate_tail(char *sfn_output, char *sfn_input, uint32 tailNum) +{ + int tail_chars; + char tail_str[12]; + + if (tailNum > 99999) + return 0; + + // Convert to number + memset(tail_str, 0x00, sizeof(tail_str)); + tail_str[0] = '~'; + fatfs_itoa(tailNum, tail_str+1); + + // Copy in base filename + memcpy(sfn_output, sfn_input, FAT_SFN_SIZE_FULL); + + // Overwrite with tail + tail_chars = (int)strlen(tail_str); + memcpy(sfn_output+(FAT_SFN_SIZE_PARTIAL-tail_chars), tail_str, tail_chars); + + return 1; +} +#endif +#endif +//----------------------------------------------------------------------------- +// fatfs_convert_from_fat_time: Convert FAT time to h/m/s +//----------------------------------------------------------------------------- +#if FATFS_INC_TIME_DATE_SUPPORT +void fatfs_convert_from_fat_time(uint16 fat_time, int *hours, int *minutes, int *seconds) +{ + *hours = (fat_time >> FAT_TIME_HOURS_SHIFT) & FAT_TIME_HOURS_MASK; + *minutes = (fat_time >> FAT_TIME_MINUTES_SHIFT) & FAT_TIME_MINUTES_MASK; + *seconds = (fat_time >> FAT_TIME_SECONDS_SHIFT) & FAT_TIME_SECONDS_MASK; + *seconds = *seconds * FAT_TIME_SECONDS_SCALE; +} +//----------------------------------------------------------------------------- +// fatfs_convert_from_fat_date: Convert FAT date to d/m/y +//----------------------------------------------------------------------------- +void fatfs_convert_from_fat_date(uint16 fat_date, int *day, int *month, int *year) +{ + *day = (fat_date >> FAT_DATE_DAY_SHIFT) & FAT_DATE_DAY_MASK; + *month = (fat_date >> FAT_DATE_MONTH_SHIFT) & FAT_DATE_MONTH_MASK; + *year = (fat_date >> FAT_DATE_YEAR_SHIFT) & FAT_DATE_YEAR_MASK; + *year = *year + FAT_DATE_YEAR_OFFSET; +} +//----------------------------------------------------------------------------- +// fatfs_convert_to_fat_time: Convert h/m/s to FAT time +//----------------------------------------------------------------------------- +uint16 fatfs_convert_to_fat_time(int hours, int minutes, int seconds) +{ + uint16 fat_time = 0; + + // Most FAT times are to a resolution of 2 seconds + seconds /= FAT_TIME_SECONDS_SCALE; + + fat_time = (hours & FAT_TIME_HOURS_MASK) << FAT_TIME_HOURS_SHIFT; + fat_time|= (minutes & FAT_TIME_MINUTES_MASK) << FAT_TIME_MINUTES_SHIFT; + fat_time|= (seconds & FAT_TIME_SECONDS_MASK) << FAT_TIME_SECONDS_SHIFT; + + return fat_time; +} +//----------------------------------------------------------------------------- +// fatfs_convert_to_fat_date: Convert d/m/y to FAT date +//----------------------------------------------------------------------------- +uint16 fatfs_convert_to_fat_date(int day, int month, int year) +{ + uint16 fat_date = 0; + + // FAT dates are relative to 1980 + if (year >= FAT_DATE_YEAR_OFFSET) + year -= FAT_DATE_YEAR_OFFSET; + + fat_date = (day & FAT_DATE_DAY_MASK) << FAT_DATE_DAY_SHIFT; + fat_date|= (month & FAT_DATE_MONTH_MASK) << FAT_DATE_MONTH_SHIFT; + fat_date|= (year & FAT_DATE_YEAR_MASK) << FAT_DATE_YEAR_SHIFT; + + return fat_date; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_print_sector: +//----------------------------------------------------------------------------- +#ifdef FATFS_DEBUG +void fatfs_print_sector(uint32 sector, uint8 *data) +{ + int i; + int j; + + FAT_PRINTF(("Sector %d:\n", sector)); + + for (i=0;i 31 && ch < 127) + { + FAT_PRINTF(("%c", ch)); + } + else + { + FAT_PRINTF((".")); + } + } + + FAT_PRINTF(("\n")); + } + } +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.h new file mode 100644 index 00000000..0c026343 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_misc.h @@ -0,0 +1,63 @@ +#ifndef __FAT_MISC_H__ +#define __FAT_MISC_H__ + +#include "fat_defs.h" +#include "fat_opts.h" + +//----------------------------------------------------------------------------- +// Defines +//----------------------------------------------------------------------------- +#define MAX_LONGFILENAME_ENTRIES 20 +#define MAX_LFN_ENTRY_LENGTH 13 + +//----------------------------------------------------------------------------- +// Macros +//----------------------------------------------------------------------------- +#define GET_32BIT_WORD(buffer, location) ( ((uint32)buffer[location+3]<<24) + ((uint32)buffer[location+2]<<16) + ((uint32)buffer[location+1]<<8) + (uint32)buffer[location+0] ) +#define GET_16BIT_WORD(buffer, location) ( ((uint16)buffer[location+1]<<8) + (uint16)buffer[location+0] ) + +#define SET_32BIT_WORD(buffer, location, value) { buffer[location+0] = (uint8)((value)&0xFF); \ + buffer[location+1] = (uint8)((value>>8)&0xFF); \ + buffer[location+2] = (uint8)((value>>16)&0xFF); \ + buffer[location+3] = (uint8)((value>>24)&0xFF); } + +#define SET_16BIT_WORD(buffer, location, value) { buffer[location+0] = (uint8)((value)&0xFF); \ + buffer[location+1] = (uint8)((value>>8)&0xFF); } + +//----------------------------------------------------------------------------- +// Structures +//----------------------------------------------------------------------------- +struct lfn_cache +{ +#if FATFS_INC_LFN_SUPPORT + // Long File Name Structure (max 260 LFN length) + uint8 String[MAX_LONGFILENAME_ENTRIES][MAX_LFN_ENTRY_LENGTH]; + uint8 Null; +#endif + uint8 no_of_strings; +}; + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +void fatfs_lfn_cache_init(struct lfn_cache *lfn, int wipeTable); +void fatfs_lfn_cache_entry(struct lfn_cache *lfn, uint8 *entryBuffer); +char* fatfs_lfn_cache_get(struct lfn_cache *lfn); +int fatfs_entry_lfn_text(struct fat_dir_entry *entry); +int fatfs_entry_lfn_invalid(struct fat_dir_entry *entry); +int fatfs_entry_lfn_exists(struct lfn_cache *lfn, struct fat_dir_entry *entry); +int fatfs_entry_sfn_only(struct fat_dir_entry *entry); +int fatfs_entry_is_dir(struct fat_dir_entry *entry); +int fatfs_entry_is_file(struct fat_dir_entry *entry); +int fatfs_lfn_entries_required(char *filename); +void fatfs_filename_to_lfn(char *filename, uint8 *buffer, int entry, uint8 sfnChk); +void fatfs_sfn_create_entry(char *shortfilename, uint32 size, uint32 startCluster, struct fat_dir_entry *entry, int dir); +int fatfs_lfn_create_sfn(char *sfn_output, char *filename); +int fatfs_lfn_generate_tail(char *sfn_output, char *sfn_input, uint32 tailNum); +void fatfs_convert_from_fat_time(uint16 fat_time, int *hours, int *minutes, int *seconds); +void fatfs_convert_from_fat_date(uint16 fat_date, int *day, int *month, int *year); +uint16 fatfs_convert_to_fat_time(int hours, int minutes, int seconds); +uint16 fatfs_convert_to_fat_date(int day, int month, int year); +void fatfs_print_sector(uint32 sector, uint8 *data); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_opts.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_opts.h new file mode 100644 index 00000000..6db158c4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_opts.h @@ -0,0 +1,83 @@ +#ifndef __FAT_OPTS_H__ +#define __FAT_OPTS_H__ + +#ifdef FATFS_USE_CUSTOM_OPTS_FILE + #include "fat_custom.h" +#endif + +//------------------------------------------------------------- +// Configuration +//------------------------------------------------------------- + +// Is the processor little endian (1) or big endian (0) +#ifndef FATFS_IS_LITTLE_ENDIAN + #define FATFS_IS_LITTLE_ENDIAN 1 +#endif + +// Max filename Length +#ifndef FATFS_MAX_LONG_FILENAME + #define FATFS_MAX_LONG_FILENAME 260 +#endif + +// Max open files (reduce to lower memory requirements) +#ifndef FATFS_MAX_OPEN_FILES + #define FATFS_MAX_OPEN_FILES 2 +#endif + +// Number of sectors per FAT_BUFFER (min 1) +#ifndef FAT_BUFFER_SECTORS + #define FAT_BUFFER_SECTORS 1 +#endif + +// Max FAT sectors to buffer (min 1) +// (mem used is FAT_BUFFERS * FAT_BUFFER_SECTORS * FAT_SECTOR_SIZE) +#ifndef FAT_BUFFERS + #define FAT_BUFFERS 1 +#endif + +// Size of cluster chain cache (can be undefined) +// Mem used = FAT_CLUSTER_CACHE_ENTRIES * 4 * 2 +// Improves access speed considerably +//#define FAT_CLUSTER_CACHE_ENTRIES 128 + +// Include support for writing files (1 / 0)? +#ifndef FATFS_INC_WRITE_SUPPORT + #define FATFS_INC_WRITE_SUPPORT 1 +#endif + +// Support long filenames (1 / 0)? +// (if not (0) only 8.3 format is supported) +#ifndef FATFS_INC_LFN_SUPPORT + #define FATFS_INC_LFN_SUPPORT 1 +#endif + +// Support directory listing (1 / 0)? +#ifndef FATFS_DIR_LIST_SUPPORT + #define FATFS_DIR_LIST_SUPPORT 1 +#endif + +// Support time/date (1 / 0)? +#ifndef FATFS_INC_TIME_DATE_SUPPORT + #define FATFS_INC_TIME_DATE_SUPPORT 0 +#endif + +// Include support for formatting disks (1 / 0)? +#ifndef FATFS_INC_FORMAT_SUPPORT + #define FATFS_INC_FORMAT_SUPPORT 0 +#endif + +// Sector size used +#define FAT_SECTOR_SIZE 512 + +// Printf output (directory listing / debug) +#ifndef FAT_PRINTF + void ventoy_syslog_printf(const char *Fmt, ...); + #define FAT_PRINTF(a) ventoy_syslog_printf a +#endif + +// Time/Date support requires time.h +#if FATFS_INC_TIME_DATE_SUPPORT + #include +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.c new file mode 100644 index 00000000..f7206ce7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.c @@ -0,0 +1,514 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include +#include "fat_string.h" + +//----------------------------------------------------------------------------- +// fatfs_total_path_levels: Take a filename and path and count the sub levels +// of folders. E.g. C:\folder\file.zip = 1 level +// Acceptable input formats are: +// c:\folder\file.zip +// /dev/etc/samba.conf +// Returns: -1 = Error, 0 or more = Ok +//----------------------------------------------------------------------------- +int fatfs_total_path_levels(char *path) +{ + int levels = 0; + char expectedchar; + + if (!path) + return -1; + + // Acceptable formats: + // c:\folder\file.zip + // /dev/etc/samba.conf + if (*path == '/') + { + expectedchar = '/'; + path++; + } + else if (path[1] == ':' || path[2] == '\\') + { + expectedchar = '\\'; + path += 3; + } + else + return -1; + + // Count levels in path string + while (*path) + { + // Fast forward through actual subdir text to next slash + for (; *path; ) + { + // If slash detected escape from for loop + if (*path == expectedchar) { path++; break; } + path++; + } + + // Increase number of subdirs founds + levels++; + } + + // Subtract the file itself + return levels-1; +} +//----------------------------------------------------------------------------- +// fatfs_get_substring: Get a substring from 'path' which contains the folder +// (or file) at the specified level. +// E.g. C:\folder\file.zip : Level 0 = C:\folder, Level 1 = file.zip +// Returns: -1 = Error, 0 = Ok +//----------------------------------------------------------------------------- +int fatfs_get_substring(char *path, int levelreq, char *output, int max_len) +{ + int i; + int pathlen=0; + int levels=0; + int copypnt=0; + char expectedchar; + + if (!path || max_len <= 0) + return -1; + + // Acceptable formats: + // c:\folder\file.zip + // /dev/etc/samba.conf + if (*path == '/') + { + expectedchar = '/'; + path++; + } + else if (path[1] == ':' || path[2] == '\\') + { + expectedchar = '\\'; + path += 3; + } + else + return -1; + + // Get string length of path + pathlen = (int)strlen (path); + + // Loop through the number of times as characters in 'path' + for (i = 0; i path = C:\folder filename = file.zip +// E.g. C:\file.zip -> path = [blank] filename = file.zip +//----------------------------------------------------------------------------- +int fatfs_split_path(char *full_path, char *path, int max_path, char *filename, int max_filename) +{ + int strindex; + + // Count the levels to the filepath + int levels = fatfs_total_path_levels(full_path); + if (levels == -1) + return -1; + + // Get filename part of string + if (fatfs_get_substring(full_path, levels, filename, max_filename) != 0) + return -1; + + // If root file + if (levels == 0) + path[0] = '\0'; + else + { + strindex = (int)strlen(full_path) - (int)strlen(filename); + if (strindex > max_path) + strindex = max_path; + + memcpy(path, full_path, strindex); + path[strindex-1] = '\0'; + } + + return 0; +} +//----------------------------------------------------------------------------- +// FileString_StrCmpNoCase: Compare two strings case with case sensitivity +//----------------------------------------------------------------------------- +static int FileString_StrCmpNoCase(char *s1, char *s2, int n) +{ + int diff; + char a,b; + + while (n--) + { + a = *s1; + b = *s2; + + // Make lower case if uppercase + if ((a>='A') && (a<='Z')) + a+= 32; + if ((b>='A') && (b<='Z')) + b+= 32; + + diff = a - b; + + // If different + if (diff) + return diff; + + // If run out of strings + if ( (*s1 == 0) || (*s2 == 0) ) + break; + + s1++; + s2++; + } + return 0; +} +//----------------------------------------------------------------------------- +// FileString_GetExtension: Get index to extension within filename +// Returns -1 if not found or index otherwise +//----------------------------------------------------------------------------- +static int FileString_GetExtension(char *str) +{ + int dotPos = -1; + char *strSrc = str; + + // Find last '.' in string (if at all) + while (*strSrc) + { + if (*strSrc=='.') + dotPos = (int)(strSrc-str); + + strSrc++; + } + + return dotPos; +} +//----------------------------------------------------------------------------- +// FileString_TrimLength: Get length of string excluding trailing spaces +// Returns -1 if not found or index otherwise +//----------------------------------------------------------------------------- +static int FileString_TrimLength(char *str, int strLen) +{ + int length = strLen; + char *strSrc = str+strLen-1; + + // Find last non white space + while (strLen != 0) + { + if (*strSrc == ' ') + length = (int)(strSrc - str); + else + break; + + strSrc--; + strLen--; + } + + return length; +} +//----------------------------------------------------------------------------- +// fatfs_compare_names: Compare two filenames (without copying or changing origonals) +// Returns 1 if match, 0 if not +//----------------------------------------------------------------------------- +int fatfs_compare_names(char* strA, char* strB) +{ + char *ext1 = NULL; + char *ext2 = NULL; + int ext1Pos, ext2Pos; + int file1Len, file2Len; + + // Get both files extension + ext1Pos = FileString_GetExtension(strA); + ext2Pos = FileString_GetExtension(strB); + + // NOTE: Extension position can be different for matching + // filename if trailing space are present before it! + // Check that if one has an extension, so does the other + if ((ext1Pos==-1) && (ext2Pos!=-1)) + return 0; + if ((ext2Pos==-1) && (ext1Pos!=-1)) + return 0; + + // If they both have extensions, compare them + if (ext1Pos!=-1) + { + // Set pointer to start of extension + ext1 = strA+ext1Pos+1; + ext2 = strB+ext2Pos+1; + + // Verify that the file extension lengths match! + if (strlen(ext1) != strlen(ext2)) + return 0; + + // If they dont match + if (FileString_StrCmpNoCase(ext1, ext2, (int)strlen(ext1))!=0) + return 0; + + // Filelength is upto extensions + file1Len = ext1Pos; + file2Len = ext2Pos; + } + // No extensions + else + { + // Filelength is actual filelength + file1Len = (int)strlen(strA); + file2Len = (int)strlen(strB); + } + + // Find length without trailing spaces (before ext) + file1Len = FileString_TrimLength(strA, file1Len); + file2Len = FileString_TrimLength(strB, file2Len); + + // Check the file lengths match + if (file1Len!=file2Len) + return 0; + + // Compare main part of filenames + if (FileString_StrCmpNoCase(strA, strB, file1Len)!=0) + return 0; + else + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_string_ends_with_slash: Does the string end with a slash (\ or /) +//----------------------------------------------------------------------------- +int fatfs_string_ends_with_slash(char *path) +{ + if (path) + { + while (*path) + { + // Last character? + if (!(*(path+1))) + { + if (*path == '\\' || *path == '/') + return 1; + } + + path++; + } + } + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_get_sfn_display_name: Get display name for SFN entry +//----------------------------------------------------------------------------- +int fatfs_get_sfn_display_name(char* out, char* in) +{ + int len = 0; + while (*in && len <= 11) + { + char a = *in++; + + if (a == ' ') + continue; + // Make lower case if uppercase + else if ((a>='A') && (a<='Z')) + a+= 32; + + *out++ = a; + len++; + } + + *out = '\0'; + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_get_extension: Get extension of filename passed in 'filename'. +// Returned extension is always lower case. +// Returns: 1 if ok, 0 if not. +//----------------------------------------------------------------------------- +int fatfs_get_extension(char* filename, char* out, int maxlen) +{ + int len = 0; + + // Get files extension offset + int ext_pos = FileString_GetExtension(filename); + + if (ext_pos > 0 && out && maxlen) + { + filename += ext_pos + 1; + + while (*filename && len < (maxlen-1)) + { + char a = *filename++; + + // Make lowercase if uppercase + if ((a>='A') && (a<='Z')) + a+= 32; + + *out++ = a; + len++; + } + + *out = '\0'; + return 1; + } + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_create_path_string: Append path & filename to create file path string. +// Returns: 1 if ok, 0 if not. +//----------------------------------------------------------------------------- +int fatfs_create_path_string(char* path, char *filename, char* out, int maxlen) +{ + int len = 0; + char last = 0; + char seperator = '/'; + + if (path && filename && out && maxlen > 0) + { + while (*path && len < (maxlen-2)) + { + last = *path++; + if (last == '\\') + seperator = '\\'; + *out++ = last; + len++; + } + + // Add a seperator if trailing one not found + if (last != '\\' && last != '/') + *out++ = seperator; + + while (*filename && len < (maxlen-1)) + { + *out++ = *filename++; + len++; + } + + *out = '\0'; + + return 1; + } + + return 0; +} +//----------------------------------------------------------------------------- +// Test Bench +//----------------------------------------------------------------------------- +#ifdef FAT_STRING_TESTBENCH +void main(void) +{ + char output[255]; + char output2[255]; + + assert(fatfs_total_path_levels("C:\\folder\\file.zip") == 1); + assert(fatfs_total_path_levels("C:\\file.zip") == 0); + assert(fatfs_total_path_levels("C:\\folder\\folder2\\file.zip") == 2); + assert(fatfs_total_path_levels("C:\\") == -1); + assert(fatfs_total_path_levels("") == -1); + assert(fatfs_total_path_levels("/dev/etc/file.zip") == 2); + assert(fatfs_total_path_levels("/dev/file.zip") == 1); + + assert(fatfs_get_substring("C:\\folder\\file.zip", 0, output, sizeof(output)) == 0); + assert(strcmp(output, "folder") == 0); + + assert(fatfs_get_substring("C:\\folder\\file.zip", 1, output, sizeof(output)) == 0); + assert(strcmp(output, "file.zip") == 0); + + assert(fatfs_get_substring("/dev/etc/file.zip", 0, output, sizeof(output)) == 0); + assert(strcmp(output, "dev") == 0); + + assert(fatfs_get_substring("/dev/etc/file.zip", 1, output, sizeof(output)) == 0); + assert(strcmp(output, "etc") == 0); + + assert(fatfs_get_substring("/dev/etc/file.zip", 2, output, sizeof(output)) == 0); + assert(strcmp(output, "file.zip") == 0); + + assert(fatfs_split_path("C:\\folder\\file.zip", output, sizeof(output), output2, sizeof(output2)) == 0); + assert(strcmp(output, "C:\\folder") == 0); + assert(strcmp(output2, "file.zip") == 0); + + assert(fatfs_split_path("C:\\file.zip", output, sizeof(output), output2, sizeof(output2)) == 0); + assert(output[0] == 0); + assert(strcmp(output2, "file.zip") == 0); + + assert(fatfs_split_path("/dev/etc/file.zip", output, sizeof(output), output2, sizeof(output2)) == 0); + assert(strcmp(output, "/dev/etc") == 0); + assert(strcmp(output2, "file.zip") == 0); + + assert(FileString_GetExtension("C:\\file.zip") == strlen("C:\\file")); + assert(FileString_GetExtension("C:\\file.zip.ext") == strlen("C:\\file.zip")); + assert(FileString_GetExtension("C:\\file.zip.") == strlen("C:\\file.zip")); + + assert(FileString_TrimLength("C:\\file.zip", strlen("C:\\file.zip")) == strlen("C:\\file.zip")); + assert(FileString_TrimLength("C:\\file.zip ", strlen("C:\\file.zip ")) == strlen("C:\\file.zip")); + assert(FileString_TrimLength(" ", strlen(" ")) == 0); + + assert(fatfs_compare_names("C:\\file.ext", "C:\\file.ext") == 1); + assert(fatfs_compare_names("C:\\file2.ext", "C:\\file.ext") == 0); + assert(fatfs_compare_names("C:\\file .ext", "C:\\file.ext") == 1); + assert(fatfs_compare_names("C:\\file .ext", "C:\\file2.ext") == 0); + + assert(fatfs_string_ends_with_slash("C:\\folder") == 0); + assert(fatfs_string_ends_with_slash("C:\\folder\\") == 1); + assert(fatfs_string_ends_with_slash("/path") == 0); + assert(fatfs_string_ends_with_slash("/path/a") == 0); + assert(fatfs_string_ends_with_slash("/path/") == 1); + + assert(fatfs_get_extension("/mypath/file.wav", output, 4) == 1); + assert(strcmp(output, "wav") == 0); + assert(fatfs_get_extension("/mypath/file.WAV", output, 4) == 1); + assert(strcmp(output, "wav") == 0); + assert(fatfs_get_extension("/mypath/file.zip", output, 4) == 1); + assert(strcmp(output, "ext") != 0); + + assert(fatfs_create_path_string("/mydir1", "myfile.txt", output, sizeof(output)) == 1); + assert(strcmp(output, "/mydir1/myfile.txt") == 0); + assert(fatfs_create_path_string("/mydir2/", "myfile2.txt", output, sizeof(output)) == 1); + assert(strcmp(output, "/mydir2/myfile2.txt") == 0); + assert(fatfs_create_path_string("C:\\mydir3", "myfile3.txt", output, sizeof(output)) == 1); + assert(strcmp(output, "C:\\mydir3\\myfile3.txt") == 0); +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.h new file mode 100644 index 00000000..90ca8e05 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_string.h @@ -0,0 +1,20 @@ +#ifndef __FILESTRING_H__ +#define __FILESTRING_H__ + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_total_path_levels(char *path); +int fatfs_get_substring(char *Path, int levelreq, char *output, int max_len); +int fatfs_split_path(char *FullPath, char *Path, int max_path, char *FileName, int max_filename); +int fatfs_compare_names(char* strA, char* strB); +int fatfs_string_ends_with_slash(char *path); +int fatfs_get_sfn_display_name(char* out, char* in); +int fatfs_get_extension(char* filename, char* out, int maxlen); +int fatfs_create_path_string(char* path, char *filename, char* out, int maxlen); + +#ifndef NULL + #define NULL 0 +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.c new file mode 100644 index 00000000..8d05d3bf --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.c @@ -0,0 +1,478 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" + +#ifndef FAT_BUFFERS + #define FAT_BUFFERS 1 +#endif + +#ifndef FAT_BUFFER_SECTORS + #define FAT_BUFFER_SECTORS 1 +#endif + +#if FAT_BUFFERS < 1 || FAT_BUFFER_SECTORS < 1 + #error "FAT_BUFFERS & FAT_BUFFER_SECTORS must be at least 1" +#endif + +//----------------------------------------------------------------------------- +// FAT Sector Buffer +//----------------------------------------------------------------------------- +#define FAT32_GET_32BIT_WORD(pbuf, location) ( GET_32BIT_WORD(pbuf->ptr, location) ) +#define FAT32_SET_32BIT_WORD(pbuf, location, value) { SET_32BIT_WORD(pbuf->ptr, location, value); pbuf->dirty = 1; } +#define FAT16_GET_16BIT_WORD(pbuf, location) ( GET_16BIT_WORD(pbuf->ptr, location) ) +#define FAT16_SET_16BIT_WORD(pbuf, location, value) { SET_16BIT_WORD(pbuf->ptr, location, value); pbuf->dirty = 1; } + +//----------------------------------------------------------------------------- +// fatfs_fat_init: +//----------------------------------------------------------------------------- +void fatfs_fat_init(struct fatfs *fs) +{ + int i; + + // FAT buffer chain head + fs->fat_buffer_head = NULL; + + for (i=0;ifat_buffers[i].address = FAT32_INVALID_CLUSTER; + fs->fat_buffers[i].dirty = 0; + memset(fs->fat_buffers[i].sector, 0x00, sizeof(fs->fat_buffers[i].sector)); + fs->fat_buffers[i].ptr = NULL; + + // Add to head of queue + fs->fat_buffers[i].next = fs->fat_buffer_head; + fs->fat_buffer_head = &fs->fat_buffers[i]; + } +} +//----------------------------------------------------------------------------- +// fatfs_fat_writeback: Writeback 'dirty' FAT sectors to disk +//----------------------------------------------------------------------------- +static int fatfs_fat_writeback(struct fatfs *fs, struct fat_buffer *pcur) +{ + if (pcur) + { + // Writeback sector if changed + if (pcur->dirty) + { + if (fs->disk_io.write_media) + { + uint32 sectors = FAT_BUFFER_SECTORS; + uint32 offset = pcur->address - fs->fat_begin_lba; + + // Limit to sectors used for the FAT + if ((offset + FAT_BUFFER_SECTORS) <= fs->fat_sectors) + sectors = FAT_BUFFER_SECTORS; + else + sectors = fs->fat_sectors - offset; + + if (!fs->disk_io.write_media(pcur->address, pcur->sector, sectors)) + return 0; + } + + pcur->dirty = 0; + } + + return 1; + } + else + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_fat_read_sector: Read a FAT sector +//----------------------------------------------------------------------------- +static struct fat_buffer *fatfs_fat_read_sector(struct fatfs *fs, uint32 sector) +{ + struct fat_buffer *last = NULL; + struct fat_buffer *pcur = fs->fat_buffer_head; + + // Itterate through sector buffer list + while (pcur) + { + // Sector within this buffer? + if ((sector >= pcur->address) && (sector < (pcur->address + FAT_BUFFER_SECTORS))) + break; + + // End of list? + if (pcur->next == NULL) + { + // Remove buffer from list + if (last) + last->next = NULL; + // We the first and last buffer in the chain? + else + fs->fat_buffer_head = NULL; + } + + last = pcur; + pcur = pcur->next; + } + + // We found the sector already in FAT buffer chain + if (pcur) + { + pcur->ptr = (uint8 *)(pcur->sector + ((sector - pcur->address) * FAT_SECTOR_SIZE)); + return pcur; + } + + // Else, we removed the last item from the list + pcur = last; + + // Add to start of sector buffer list (now newest sector) + pcur->next = fs->fat_buffer_head; + fs->fat_buffer_head = pcur; + + // Writeback sector if changed + if (pcur->dirty) + if (!fatfs_fat_writeback(fs, pcur)) + return 0; + + // Address is now new sector + pcur->address = sector; + + // Read next sector + if (!fs->disk_io.read_media(pcur->address, pcur->sector, FAT_BUFFER_SECTORS)) + { + // Read failed, invalidate buffer address + pcur->address = FAT32_INVALID_CLUSTER; + return NULL; + } + + pcur->ptr = pcur->sector; + return pcur; +} +//----------------------------------------------------------------------------- +// fatfs_fat_purge: Purge 'dirty' FAT sectors to disk +//----------------------------------------------------------------------------- +int fatfs_fat_purge(struct fatfs *fs) +{ + struct fat_buffer *pcur = fs->fat_buffer_head; + + // Itterate through sector buffer list + while (pcur) + { + // Writeback sector if changed + if (pcur->dirty) + if (!fatfs_fat_writeback(fs, pcur)) + return 0; + + pcur = pcur->next; + } + + return 1; +} + +//----------------------------------------------------------------------------- +// General FAT Table Operations +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// fatfs_find_next_cluster: Return cluster number of next cluster in chain by +// reading FAT table and traversing it. Return 0xffffffff for end of chain. +//----------------------------------------------------------------------------- +uint32 fatfs_find_next_cluster(struct fatfs *fs, uint32 current_cluster) +{ + uint32 fat_sector_offset, position; + uint32 nextcluster; + struct fat_buffer *pbuf; + + // Why is '..' labelled with cluster 0 when it should be 2 ?? + if (current_cluster == 0) + current_cluster = 2; + + // Find which sector of FAT table to read + if (fs->fat_type == FAT_TYPE_16) + fat_sector_offset = current_cluster / 256; + else + fat_sector_offset = current_cluster / 128; + + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); + if (!pbuf) + return (FAT32_LAST_CLUSTER); + + if (fs->fat_type == FAT_TYPE_16) + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 256)) * 2; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT16_GET_16BIT_WORD(pbuf, (uint16)position); + + // If end of chain found + if (nextcluster >= 0xFFF8 && nextcluster <= 0xFFFF) + return (FAT32_LAST_CLUSTER); + } + else + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 128)) * 4; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT32_GET_32BIT_WORD(pbuf, (uint16)position); + + // Mask out MS 4 bits (its 28bit addressing) + nextcluster = nextcluster & 0x0FFFFFFF; + + // If end of chain found + if (nextcluster >= 0x0FFFFFF8 && nextcluster <= 0x0FFFFFFF) + return (FAT32_LAST_CLUSTER); + } + + // Else return next cluster + return (nextcluster); +} +//----------------------------------------------------------------------------- +// fatfs_set_fs_info_next_free_cluster: Write the next free cluster to the FSINFO table +//----------------------------------------------------------------------------- +void fatfs_set_fs_info_next_free_cluster(struct fatfs *fs, uint32 newValue) +{ + if (fs->fat_type == FAT_TYPE_16) + ; + else + { + // Load sector to change it + struct fat_buffer *pbuf = fatfs_fat_read_sector(fs, fs->lba_begin+fs->fs_info_sector); + if (!pbuf) + return ; + + // Change + FAT32_SET_32BIT_WORD(pbuf, 492, newValue); + fs->next_free_cluster = newValue; + + // Write back FSINFO sector to disk + if (fs->disk_io.write_media) + fs->disk_io.write_media(pbuf->address, pbuf->sector, 1); + + // Invalidate cache entry + pbuf->address = FAT32_INVALID_CLUSTER; + pbuf->dirty = 0; + } +} +//----------------------------------------------------------------------------- +// fatfs_find_blank_cluster: Find a free cluster entry by reading the FAT +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_find_blank_cluster(struct fatfs *fs, uint32 start_cluster, uint32 *free_cluster) +{ + uint32 fat_sector_offset, position; + uint32 nextcluster; + uint32 current_cluster = start_cluster; + struct fat_buffer *pbuf; + + do + { + // Find which sector of FAT table to read + if (fs->fat_type == FAT_TYPE_16) + fat_sector_offset = current_cluster / 256; + else + fat_sector_offset = current_cluster / 128; + + if ( fat_sector_offset < fs->fat_sectors) + { + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); + if (!pbuf) + return 0; + + if (fs->fat_type == FAT_TYPE_16) + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 256)) * 2; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT16_GET_16BIT_WORD(pbuf, (uint16)position); + } + else + { + // Find 32 bit entry of current sector relating to cluster number + position = (current_cluster - (fat_sector_offset * 128)) * 4; + + // Read Next Clusters value from Sector Buffer + nextcluster = FAT32_GET_32BIT_WORD(pbuf, (uint16)position); + + // Mask out MS 4 bits (its 28bit addressing) + nextcluster = nextcluster & 0x0FFFFFFF; + } + + if (nextcluster !=0 ) + current_cluster++; + } + else + // Otherwise, run out of FAT sectors to check... + return 0; + } + while (nextcluster != 0x0); + + // Found blank entry + *free_cluster = current_cluster; + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_fat_set_cluster: Set a cluster link in the chain. NOTE: Immediate +// write (slow). +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_fat_set_cluster(struct fatfs *fs, uint32 cluster, uint32 next_cluster) +{ + struct fat_buffer *pbuf; + uint32 fat_sector_offset, position; + + // Find which sector of FAT table to read + if (fs->fat_type == FAT_TYPE_16) + fat_sector_offset = cluster / 256; + else + fat_sector_offset = cluster / 128; + + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba+fat_sector_offset); + if (!pbuf) + return 0; + + if (fs->fat_type == FAT_TYPE_16) + { + // Find 16 bit entry of current sector relating to cluster number + position = (cluster - (fat_sector_offset * 256)) * 2; + + // Write Next Clusters value to Sector Buffer + FAT16_SET_16BIT_WORD(pbuf, (uint16)position, ((uint16)next_cluster)); + } + else + { + // Find 32 bit entry of current sector relating to cluster number + position = (cluster - (fat_sector_offset * 128)) * 4; + + // Write Next Clusters value to Sector Buffer + FAT32_SET_32BIT_WORD(pbuf, (uint16)position, next_cluster); + } + + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_free_cluster_chain: Follow a chain marking each element as free +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_free_cluster_chain(struct fatfs *fs, uint32 start_cluster) +{ + uint32 last_cluster; + uint32 next_cluster = start_cluster; + + // Loop until end of chain + while ( (next_cluster != FAT32_LAST_CLUSTER) && (next_cluster != 0x00000000) ) + { + last_cluster = next_cluster; + + // Find next link + next_cluster = fatfs_find_next_cluster(fs, next_cluster); + + // Clear last link + fatfs_fat_set_cluster(fs, last_cluster, 0x00000000); + } + + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_fat_add_cluster_to_chain: Follow a chain marking and then add a new entry +// to the current tail. +//----------------------------------------------------------------------------- +#if FATFS_INC_WRITE_SUPPORT +int fatfs_fat_add_cluster_to_chain(struct fatfs *fs, uint32 start_cluster, uint32 newEntry) +{ + uint32 last_cluster = FAT32_LAST_CLUSTER; + uint32 next_cluster = start_cluster; + + if (start_cluster == FAT32_LAST_CLUSTER) + return 0; + + // Loop until end of chain + while ( next_cluster != FAT32_LAST_CLUSTER ) + { + last_cluster = next_cluster; + + // Find next link + next_cluster = fatfs_find_next_cluster(fs, next_cluster); + if (!next_cluster) + return 0; + } + + // Add link in for new cluster + fatfs_fat_set_cluster(fs, last_cluster, newEntry); + + // Mark new cluster as end of chain + fatfs_fat_set_cluster(fs, newEntry, FAT32_LAST_CLUSTER); + + return 1; +} +#endif +//----------------------------------------------------------------------------- +// fatfs_count_free_clusters: +//----------------------------------------------------------------------------- +uint32 fatfs_count_free_clusters(struct fatfs *fs) +{ + uint32 i,j; + uint32 count = 0; + struct fat_buffer *pbuf; + + for (i = 0; i < fs->fat_sectors; i++) + { + // Read FAT sector into buffer + pbuf = fatfs_fat_read_sector(fs, fs->fat_begin_lba + i); + if (!pbuf) + break; + + for (j = 0; j < FAT_SECTOR_SIZE; ) + { + if (fs->fat_type == FAT_TYPE_16) + { + if (FAT16_GET_16BIT_WORD(pbuf, (uint16)j) == 0) + count++; + + j += 2; + } + else + { + if (FAT32_GET_32BIT_WORD(pbuf, (uint16)j) == 0) + count++; + + j += 4; + } + } + } + + return count; +} diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.h new file mode 100644 index 00000000..ead75f32 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_table.h @@ -0,0 +1,20 @@ +#ifndef __FAT_TABLE_H__ +#define __FAT_TABLE_H__ + +#include "fat_opts.h" +#include "fat_misc.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +void fatfs_fat_init(struct fatfs *fs); +int fatfs_fat_purge(struct fatfs *fs); +uint32 fatfs_find_next_cluster(struct fatfs *fs, uint32 current_cluster); +void fatfs_set_fs_info_next_free_cluster(struct fatfs *fs, uint32 newValue); +int fatfs_find_blank_cluster(struct fatfs *fs, uint32 start_cluster, uint32 *free_cluster); +int fatfs_fat_set_cluster(struct fatfs *fs, uint32 cluster, uint32 next_cluster); +int fatfs_fat_add_cluster_to_chain(struct fatfs *fs, uint32 start_cluster, uint32 newEntry); +int fatfs_free_cluster_chain(struct fatfs *fs, uint32 start_cluster); +uint32 fatfs_count_free_clusters(struct fatfs *fs); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_types.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_types.h new file mode 100644 index 00000000..5e2cca8a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_types.h @@ -0,0 +1,69 @@ +#ifndef __FAT_TYPES_H__ +#define __FAT_TYPES_H__ + +// Detect 64-bit compilation on GCC +#if defined(__GNUC__) && defined(__SIZEOF_LONG__) + #if __SIZEOF_LONG__ == 8 + #define FATFS_DEF_UINT32_AS_INT + #endif +#endif + +//------------------------------------------------------------- +// System specific types +//------------------------------------------------------------- +#ifndef FATFS_NO_DEF_TYPES + typedef unsigned char uint8; + typedef unsigned short uint16; + + // If compiling on a 64-bit machine, use int as 32-bits + #ifdef FATFS_DEF_UINT32_AS_INT + typedef unsigned int uint32; + // Else for 32-bit machines & embedded systems, use long... + #else + typedef unsigned long uint32; + #endif +#endif + +#ifndef NULL + #define NULL 0 +#endif + +//------------------------------------------------------------- +// Endian Macros +//------------------------------------------------------------- +// FAT is little endian so big endian systems need to swap words + +// Little Endian - No swap required +#if FATFS_IS_LITTLE_ENDIAN == 1 + + #define FAT_HTONS(n) (n) + #define FAT_HTONL(n) (n) + +// Big Endian - Swap required +#else + + #define FAT_HTONS(n) ((((uint16)((n) & 0xff)) << 8) | (((n) & 0xff00) >> 8)) + #define FAT_HTONL(n) (((((uint32)(n) & 0xFF)) << 24) | \ + ((((uint32)(n) & 0xFF00)) << 8) | \ + ((((uint32)(n) & 0xFF0000)) >> 8) | \ + ((((uint32)(n) & 0xFF000000)) >> 24)) + +#endif + +//------------------------------------------------------------- +// Structure Packing Compile Options +//------------------------------------------------------------- +#ifdef __GNUC__ + #define STRUCT_PACK + #define STRUCT_PACK_BEGIN + #define STRUCT_PACK_END + #define STRUCT_PACKED __attribute__ ((packed)) +#else + // Other compilers may require other methods of packing structures + #define STRUCT_PACK + #define STRUCT_PACK_BEGIN + #define STRUCT_PACK_END + #define STRUCT_PACKED +#endif + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.c new file mode 100644 index 00000000..0718cb13 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.c @@ -0,0 +1,373 @@ +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// FAT16/32 File IO Library +// V2.6 +// Ultra-Embedded.com +// Copyright 2003 - 2012 +// +// Email: admin@ultra-embedded.com +// +// License: GPL +// If you would like a version with a more permissive license for use in +// closed source commercial applications please contact me for details. +//----------------------------------------------------------------------------- +// +// This file is part of FAT File IO Library. +// +// FAT File IO Library 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. +// +// FAT File IO Library 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 FAT File IO Library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +#include +#include "fat_defs.h" +#include "fat_access.h" +#include "fat_table.h" +#include "fat_write.h" +#include "fat_string.h" +#include "fat_misc.h" + +#if FATFS_INC_WRITE_SUPPORT +//----------------------------------------------------------------------------- +// fatfs_add_free_space: Allocate another cluster of free space to the end +// of a files cluster chain. +//----------------------------------------------------------------------------- +int fatfs_add_free_space(struct fatfs *fs, uint32 *startCluster, uint32 clusters) +{ + uint32 i; + uint32 nextcluster; + uint32 start = *startCluster; + + // Set the next free cluster hint to unknown + if (fs->next_free_cluster != FAT32_LAST_CLUSTER) + fatfs_set_fs_info_next_free_cluster(fs, FAT32_LAST_CLUSTER); + + for (i=0;irootdir_first_cluster, &nextcluster)) + { + // Point last to this + fatfs_fat_set_cluster(fs, start, nextcluster); + + // Point this to end of file + fatfs_fat_set_cluster(fs, nextcluster, FAT32_LAST_CLUSTER); + + // Adjust argument reference + start = nextcluster; + if (i == 0) + *startCluster = nextcluster; + } + else + return 0; + } + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_allocate_free_space: Add an ammount of free space to a file either from +// 'startCluster' if newFile = false, or allocating a new start to the chain if +// newFile = true. +//----------------------------------------------------------------------------- +int fatfs_allocate_free_space(struct fatfs *fs, int newFile, uint32 *startCluster, uint32 size) +{ + uint32 clusterSize; + uint32 clusterCount; + uint32 nextcluster; + + if (size==0) + return 0; + + // Set the next free cluster hint to unknown + if (fs->next_free_cluster != FAT32_LAST_CLUSTER) + fatfs_set_fs_info_next_free_cluster(fs, FAT32_LAST_CLUSTER); + + // Work out size and clusters + clusterSize = fs->sectors_per_cluster * FAT_SECTOR_SIZE; + clusterCount = (size / clusterSize); + + // If any left over + if (size-(clusterSize*clusterCount)) + clusterCount++; + + // Allocated first link in the chain if a new file + if (newFile) + { + if (!fatfs_find_blank_cluster(fs, fs->rootdir_first_cluster, &nextcluster)) + return 0; + + // If this is all that is needed then all done + if (clusterCount==1) + { + fatfs_fat_set_cluster(fs, nextcluster, FAT32_LAST_CLUSTER); + *startCluster = nextcluster; + return 1; + } + } + // Allocate from end of current chain (startCluster is end of chain) + else + nextcluster = *startCluster; + + if (!fatfs_add_free_space(fs, &nextcluster, clusterCount)) + return 0; + + return 1; +} +//----------------------------------------------------------------------------- +// fatfs_find_free_dir_offset: Find a free space in the directory for a new entry +// which takes up 'entryCount' blocks (or allocate some more) +//----------------------------------------------------------------------------- +static int fatfs_find_free_dir_offset(struct fatfs *fs, uint32 dirCluster, int entryCount, uint32 *pSector, uint8 *pOffset) +{ + struct fat_dir_entry *directoryEntry; + uint8 item=0; + uint16 recordoffset = 0; + uint8 i=0; + int x=0; + int possible_spaces = 0; + int start_recorded = 0; + + // No entries required? + if (entryCount == 0) + return 0; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, dirCluster, x++, 0)) + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // Overlay directory entry over buffer + directoryEntry = (struct fat_dir_entry*)(fs->currentsector.sector+recordoffset); + + // LFN Entry + if (fatfs_entry_lfn_text(directoryEntry)) + { + // First entry? + if (possible_spaces == 0) + { + // Store start + *pSector = x-1; + *pOffset = item; + start_recorded = 1; + } + + // Increment the count in-case the file turns + // out to be deleted... + possible_spaces++; + } + // SFN Entry + else + { + // Has file been deleted? + if (fs->currentsector.sector[recordoffset] == FILE_HEADER_DELETED) + { + // First entry? + if (possible_spaces == 0) + { + // Store start + *pSector = x-1; + *pOffset = item; + start_recorded = 1; + } + + possible_spaces++; + + // We have found enough space? + if (possible_spaces >= entryCount) + return 1; + + // Else continue counting until we find a valid entry! + } + // Is the file entry empty? + else if (fs->currentsector.sector[recordoffset] == FILE_HEADER_BLANK) + { + // First entry? + if (possible_spaces == 0) + { + // Store start + *pSector = x-1; + *pOffset = item; + start_recorded = 1; + } + + // Increment the blank entries count + possible_spaces++; + + // We have found enough space? + if (possible_spaces >= entryCount) + return 1; + } + // File entry is valid + else + { + // Reset all flags + possible_spaces = 0; + start_recorded = 0; + } + } + } // End of for + } // End of if + // Run out of free space in the directory, allocate some more + else + { + uint32 newCluster; + + // Get a new cluster for directory + if (!fatfs_find_blank_cluster(fs, fs->rootdir_first_cluster, &newCluster)) + return 0; + + // Add cluster to end of directory tree + if (!fatfs_fat_add_cluster_to_chain(fs, dirCluster, newCluster)) + return 0; + + // Erase new directory cluster + memset(fs->currentsector.sector, 0x00, FAT_SECTOR_SIZE); + for (i=0;isectors_per_cluster;i++) + { + if (!fatfs_write_sector(fs, newCluster, i, 0)) + return 0; + } + + // If non of the name fitted on previous sectors + if (!start_recorded) + { + // Store start + *pSector = (x-1); + *pOffset = 0; + start_recorded = 1; + } + + return 1; + } + } // End of while loop + + return 0; +} +//----------------------------------------------------------------------------- +// fatfs_add_file_entry: Add a directory entry to a location found by FindFreeOffset +//----------------------------------------------------------------------------- +int fatfs_add_file_entry(struct fatfs *fs, uint32 dirCluster, char *filename, char *shortfilename, uint32 startCluster, uint32 size, int dir) +{ + uint8 item=0; + uint16 recordoffset = 0; + uint8 i=0; + uint32 x=0; + int entryCount; + struct fat_dir_entry shortEntry; + int dirtySector = 0; + + uint32 dirSector = 0; + uint8 dirOffset = 0; + int foundEnd = 0; + + uint8 checksum; + uint8 *pSname; + + // No write access? + if (!fs->disk_io.write_media) + return 0; + +#if FATFS_INC_LFN_SUPPORT + // How many LFN entries are required? + // NOTE: We always request one LFN even if it would fit in a SFN! + entryCount = fatfs_lfn_entries_required(filename); + if (!entryCount) + return 0; +#else + entryCount = 0; +#endif + + // Find space in the directory for this filename (or allocate some more) + // NOTE: We need to find space for at least the LFN + SFN (or just the SFN if LFNs not supported). + if (!fatfs_find_free_dir_offset(fs, dirCluster, entryCount + 1, &dirSector, &dirOffset)) + return 0; + + // Generate checksum of short filename + pSname = (uint8*)shortfilename; + checksum = 0; + for (i=11; i!=0; i--) checksum = ((checksum & 1) ? 0x80 : 0) + (checksum >> 1) + *pSname++; + + // Start from current sector where space was found! + x = dirSector; + + // Main cluster following loop + while (1) + { + // Read sector + if (fatfs_sector_reader(fs, dirCluster, x++, 0)) + { + // Analyse Sector + for (item = 0; item < FAT_DIR_ENTRIES_PER_SECTOR; item++) + { + // Create the multiplier for sector access + recordoffset = FAT_DIR_ENTRY_SIZE * item; + + // If the start position for the entry has been found + if (foundEnd==0) + if ( (dirSector==(x-1)) && (dirOffset==item) ) + foundEnd = 1; + + // Start adding filename + if (foundEnd) + { + if (entryCount==0) + { + // Short filename + fatfs_sfn_create_entry(shortfilename, size, startCluster, &shortEntry, dir); + +#if FATFS_INC_TIME_DATE_SUPPORT + // Update create, access & modify time & date + fatfs_update_timestamps(&shortEntry, 1, 1, 1); +#endif + + memcpy(&fs->currentsector.sector[recordoffset], &shortEntry, sizeof(shortEntry)); + + // Writeback + return fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1); + } +#if FATFS_INC_LFN_SUPPORT + else + { + entryCount--; + + // Copy entry to directory buffer + fatfs_filename_to_lfn(filename, &fs->currentsector.sector[recordoffset], entryCount, checksum); + dirtySector = 1; + } +#endif + } + } // End of if + + // Write back to disk before loading another sector + if (dirtySector) + { + if (!fs->disk_io.write_media(fs->currentsector.address, fs->currentsector.sector, 1)) + return 0; + + dirtySector = 0; + } + } + else + return 0; + } // End of while loop + + return 0; +} +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.h new file mode 100644 index 00000000..5558a86e --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/fat_write.h @@ -0,0 +1,14 @@ +#ifndef __FAT_WRITE_H__ +#define __FAT_WRITE_H__ + +#include "fat_defs.h" +#include "fat_opts.h" + +//----------------------------------------------------------------------------- +// Prototypes +//----------------------------------------------------------------------------- +int fatfs_add_file_entry(struct fatfs *fs, uint32 dirCluster, char *filename, char *shortfilename, uint32 startCluster, uint32 size, int dir); +int fatfs_add_free_space(struct fatfs *fs, uint32 *startCluster, uint32 clusters); +int fatfs_allocate_free_space(struct fatfs *fs, int newFile, uint32 *startCluster, uint32 size); + +#endif diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/version.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/version.txt new file mode 100644 index 00000000..5a00a98c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/version.txt @@ -0,0 +1 @@ +2.6.11 diff --git a/LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh b/LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh new file mode 100644 index 00000000..07c542f4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# https://github.com/lammertb/libhttp/archive/v1.8.tar.gz + + +# rm -rf include +# rm -rf lib +# mkdir include +# mkdir lib + +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# cp -a include/civetweb.h ../include/ + + +# cd .. +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# make lib COPT="-DNDEBUG -DNO_CGI -DNO_CACHING -DNO_SSL -DSQLITE_DISABLE_LFS -DSSL_ALREADY_INITIALIZED" +# cp -a libcivetweb.a ../lib/libcivetweb_64.a + + + +# cd .. +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# make lib COPT="-m32 -DNDEBUG -DNO_CGI -DNO_CACHING -DNO_SSL -DSQLITE_DISABLE_LFS -DSSL_ALREADY_INITIALIZED" +# cp -a libcivetweb.a ../lib/libcivetweb_32.a + + + +# cd .. +# rm -rf libhttp-1.8 +# tar xf libhttp-1.8.tar.gz +# cd libhttp-1.8 +# make lib CC=aarch64-linux-gnu-gcc COPT="-DNDEBUG -DNO_CGI -DNO_CACHING -DNO_SSL -DSQLITE_DISABLE_LFS -DSSL_ALREADY_INITIALIZED" +# cp -a libcivetweb.a ../lib/libcivetweb_aa64.a + + +# cd .. +# rm -rf libhttp-1.8 + + diff --git a/LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.c b/LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.c new file mode 100644 index 00000000..98130f53 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.c @@ -0,0 +1,13145 @@ +/* Copyright (c) 2013-2016 the Civetweb developers + * Copyright (c) 2004-2013 Sergey Lyubka + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#if defined(_WIN32) +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS /* Disable deprecation warning in VS2005 */ +#endif +#ifndef _WIN32_WINNT /* defined for tdm-gcc so we can use getnameinfo */ +#define _WIN32_WINNT 0x0501 +#endif +#else +#if defined(__GNUC__) && !defined(_GNU_SOURCE) +#define _GNU_SOURCE /* for setgroups() */ +#endif +#if defined(__linux__) && !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 /* For flockfile() on Linux */ +#endif +#ifndef _LARGEFILE_SOURCE +#define _LARGEFILE_SOURCE /* For fseeko(), ftello() */ +#endif +#ifndef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 64 /* Use 64-bit file offsets by default */ +#endif +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS /* wants this for C++ */ +#endif +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS /* C++ wants that for INT64_MAX */ +#endif +#ifdef __sun +#define __EXTENSIONS__ /* to expose flockfile and friends in stdio.h */ +#define __inline inline /* not recognized on older compiler versions */ +#endif +#endif + +#if defined(USE_LUA) && defined(USE_WEBSOCKET) +#define USE_TIMERS +#endif + +#if defined(_MSC_VER) +/* 'type cast' : conversion from 'int' to 'HANDLE' of greater size */ +#pragma warning(disable : 4306) +/* conditional expression is constant: introduced by FD_SET(..) */ +#pragma warning(disable : 4127) +/* non-constant aggregate initializer: issued due to missing C99 support */ +#pragma warning(disable : 4204) +/* padding added after data member */ +#pragma warning(disable : 4820) +/* not defined as a preprocessor macro, replacing with '0' for '#if/#elif' */ +#pragma warning(disable : 4668) +/* no function prototype given: converting '()' to '(void)' */ +#pragma warning(disable : 4255) +/* function has been selected for automatic inline expansion */ +#pragma warning(disable : 4711) +#endif + + +/* This code uses static_assert to check some conditions. + * Unfortunately some compilers still do not support it, so we have a + * replacement function here. */ +#if defined(_MSC_VER) && (_MSC_VER >= 1600) +#define mg_static_assert static_assert +#elif defined(__cplusplus) && (__cplusplus >= 201103L) +#define mg_static_assert static_assert +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) +#define mg_static_assert _Static_assert +#else +char static_assert_replacement[1]; +#define mg_static_assert(cond, txt) \ + extern char static_assert_replacement[(cond) ? 1 : -1] +#endif + +mg_static_assert(sizeof(int) == 4 || sizeof(int) == 8, + "int data type size check"); +mg_static_assert(sizeof(void *) == 4 || sizeof(void *) == 8, + "pointer data type size check"); +mg_static_assert(sizeof(void *) >= sizeof(int), "data type size check"); +/* mg_static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t data + * type size check"); */ + +/* DTL -- including winsock2.h works better if lean and mean */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#if defined(__SYMBIAN32__) +#define NO_SSL /* SSL is not supported */ +#define NO_CGI /* CGI is not supported */ +#define PATH_MAX FILENAME_MAX +#endif /* __SYMBIAN32__ */ + + +/* Include the header file here, so the CivetWeb interface is defined for the + * entire implementation, including the following forward definitions. */ +#include "civetweb.h" + + +#ifndef IGNORE_UNUSED_RESULT +#define IGNORE_UNUSED_RESULT(a) ((void)((a) && 1)) +#endif + +#ifndef _WIN32_WCE /* Some ANSI #includes are not available on Windows CE */ +#include +#include +#include +#include +#include +#endif /* !_WIN32_WCE */ + +#ifdef __MACH__ + +#define CLOCK_MONOTONIC (1) +#define CLOCK_REALTIME (2) + +#include +#include +#include +#include +#include + + +/* clock_gettime is not implemented on OSX */ +int clock_gettime(int clk_id, struct timespec *t); + +int +clock_gettime(int clk_id, struct timespec *t) +{ + memset(t, 0, sizeof(*t)); + if (clk_id == CLOCK_REALTIME) { + struct timeval now; + int rv = gettimeofday(&now, NULL); + if (rv) { + return rv; + } + t->tv_sec = now.tv_sec; + t->tv_nsec = now.tv_usec * 1000; + return 0; + + } else if (clk_id == CLOCK_MONOTONIC) { + static uint64_t clock_start_time = 0; + static mach_timebase_info_data_t timebase_ifo = {0, 0}; + + uint64_t now = mach_absolute_time(); + + if (clock_start_time == 0) { + kern_return_t mach_status = mach_timebase_info(&timebase_ifo); +#if defined(DEBUG) + assert(mach_status == KERN_SUCCESS); +#else + /* appease "unused variable" warning for release builds */ + (void)mach_status; +#endif + clock_start_time = now; + } + + now = (uint64_t)((double)(now - clock_start_time) + * (double)timebase_ifo.numer + / (double)timebase_ifo.denom); + + t->tv_sec = now / 1000000000; + t->tv_nsec = now % 1000000000; + return 0; + } + return -1; /* EINVAL - Clock ID is unknown */ +} +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef MAX_WORKER_THREADS +#define MAX_WORKER_THREADS (1024 * 64) +#endif +#ifndef SOCKET_TIMEOUT_QUANTUM +#define SOCKET_TIMEOUT_QUANTUM (10000) +#endif + +mg_static_assert(MAX_WORKER_THREADS >= 1, + "worker threads must be a positive number"); + +#if defined(_WIN32) \ + && !defined(__SYMBIAN32__) /* WINDOWS / UNIX include block */ +#include +#include /* DTL add for SO_EXCLUSIVE */ +#include + +typedef const char *SOCK_OPT_TYPE; + +#if !defined(PATH_MAX) +#define PATH_MAX (MAX_PATH) +#endif + +#if !defined(PATH_MAX) +#define PATH_MAX (4096) +#endif + +mg_static_assert(PATH_MAX >= 1, "path length must be a positive number"); + +#ifndef _IN_PORT_T +#ifndef in_port_t +#define in_port_t u_short +#endif +#endif + +#ifndef _WIN32_WCE +#include +#include +#include +#else /* _WIN32_WCE */ +#define NO_CGI /* WinCE has no pipes */ + +typedef long off_t; + +#define errno ((int)(GetLastError())) +#define strerror(x) (_ultoa(x, (char *)_alloca(sizeof(x) * 3), 10)) +#endif /* _WIN32_WCE */ + +#define MAKEUQUAD(lo, hi) \ + ((uint64_t)(((uint32_t)(lo)) | ((uint64_t)((uint32_t)(hi))) << 32)) +#define RATE_DIFF (10000000) /* 100 nsecs */ +#define EPOCH_DIFF (MAKEUQUAD(0xd53e8000, 0x019db1de)) +#define SYS2UNIX_TIME(lo, hi) \ + ((time_t)((MAKEUQUAD((lo), (hi)) - EPOCH_DIFF) / RATE_DIFF)) + +/* Visual Studio 6 does not know __func__ or __FUNCTION__ + * The rest of MS compilers use __FUNCTION__, not C99 __func__ + * Also use _strtoui64 on modern M$ compilers */ +#if defined(_MSC_VER) +#if (_MSC_VER < 1300) +#define STRX(x) #x +#define STR(x) STRX(x) +#define __func__ __FILE__ ":" STR(__LINE__) +#define strtoull(x, y, z) ((unsigned __int64)_atoi64(x)) +#define strtoll(x, y, z) (_atoi64(x)) +#else +#define __func__ __FUNCTION__ +#define strtoull(x, y, z) (_strtoui64(x, y, z)) +#define strtoll(x, y, z) (_strtoi64(x, y, z)) +#endif +#endif /* _MSC_VER */ + +#define ERRNO ((int)(GetLastError())) +#define NO_SOCKLEN_T + +#if defined(_WIN64) || defined(__MINGW64__) +#define SSL_LIB "ssleay64.dll" +#define CRYPTO_LIB "libeay64.dll" +#else +#define SSL_LIB "ssleay32.dll" +#define CRYPTO_LIB "libeay32.dll" +#endif + +#define O_NONBLOCK (0) +#ifndef W_OK +#define W_OK (2) /* http://msdn.microsoft.com/en-us/library/1w06ktdy.aspx */ +#endif +#if !defined(EWOULDBLOCK) +#define EWOULDBLOCK WSAEWOULDBLOCK +#endif /* !EWOULDBLOCK */ +#define _POSIX_ +#define INT64_FMT "I64d" +#define UINT64_FMT "I64u" + +#define WINCDECL __cdecl +#define SHUT_RD (0) +#define SHUT_WR (1) +#define SHUT_BOTH (2) +#define vsnprintf_impl _vsnprintf +#define access _access +#define mg_sleep(x) (Sleep(x)) + +#define pipe(x) _pipe(x, MG_BUF_LEN, _O_BINARY) +#ifndef popen +#define popen(x, y) (_popen(x, y)) +#endif +#ifndef pclose +#define pclose(x) (_pclose(x)) +#endif +#define close(x) (_close(x)) +#define dlsym(x, y) (GetProcAddress((HINSTANCE)(x), (y))) +#define RTLD_LAZY (0) +#define fseeko(x, y, z) (_lseeki64(_fileno(x), (y), (z)) == -1 ? -1 : 0) +#define fdopen(x, y) (_fdopen((x), (y))) +#define write(x, y, z) (_write((x), (y), (unsigned)z)) +#define read(x, y, z) (_read((x), (y), (unsigned)z)) +#define flockfile(x) (EnterCriticalSection(&global_log_file_lock)) +#define funlockfile(x) (LeaveCriticalSection(&global_log_file_lock)) +#define sleep(x) (Sleep((x)*1000)) +#define rmdir(x) (_rmdir(x)) +#define timegm(x) (_mkgmtime(x)) + +#if !defined(fileno) +#define fileno(x) (_fileno(x)) +#endif /* !fileno MINGW #defines fileno */ + +typedef HANDLE pthread_mutex_t; +typedef DWORD pthread_key_t; +typedef HANDLE pthread_t; +typedef struct { + CRITICAL_SECTION threadIdSec; + int waitingthreadcount; /* The number of threads queued. */ + pthread_t *waitingthreadhdls; /* The thread handles. */ +} pthread_cond_t; + +#ifndef __clockid_t_defined +typedef DWORD clockid_t; +#endif +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC (1) +#endif +#ifndef CLOCK_REALTIME +#define CLOCK_REALTIME (2) +#endif + +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +#define _TIMESPEC_DEFINED +#endif +#ifndef _TIMESPEC_DEFINED +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* nanoseconds */ +}; +#endif + +#define pid_t HANDLE /* MINGW typedefs pid_t to int. Using #define here. */ + +static int pthread_mutex_lock(pthread_mutex_t *); +static int pthread_mutex_unlock(pthread_mutex_t *); +static void path_to_unicode(const struct mg_connection *conn, + const char *path, + wchar_t *wbuf, + size_t wbuf_len); +struct file; +static const char * +mg_fgets(char *buf, size_t size, struct file *filep, char **p); + + +#if defined(HAVE_STDINT) +#include +#else +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned __int64 uint64_t; +typedef __int64 int64_t; +#define INT64_MAX (9223372036854775807) +#endif /* HAVE_STDINT */ + +/* POSIX dirent interface */ +struct dirent { + char d_name[PATH_MAX]; +}; + +typedef struct DIR { + HANDLE handle; + WIN32_FIND_DATAW info; + struct dirent result; +} DIR; + +#if defined(_WIN32) && !defined(POLLIN) +#ifndef HAVE_POLL +struct pollfd { + SOCKET fd; + short events; + short revents; +}; +#define POLLIN (0x0300) +#endif +#endif + +/* Mark required libraries */ +#if defined(_MSC_VER) +#pragma comment(lib, "Ws2_32.lib") +#endif + +#else /* defined(_WIN32) && !defined(__SYMBIAN32__) - WINDOWS / UNIX include \ + block */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +typedef const void *SOCK_OPT_TYPE; + +#if defined(ANDROID) +typedef unsigned short int in_port_t; +#endif + +#include +#include +#include +#include +#define vsnprintf_impl vsnprintf + +#if !defined(NO_SSL_DL) && !defined(NO_SSL) +#include +#endif +#include +#if defined(__MACH__) +#define SSL_LIB "libssl.dylib" +#define CRYPTO_LIB "libcrypto.dylib" +#else +#if !defined(SSL_LIB) +#define SSL_LIB "libssl.so" +#endif +#if !defined(CRYPTO_LIB) +#define CRYPTO_LIB "libcrypto.so" +#endif +#endif +#ifndef O_BINARY +#define O_BINARY (0) +#endif /* O_BINARY */ +#define closesocket(a) (close(a)) +#define mg_mkdir(conn, path, mode) (mkdir(path, mode)) +#define mg_remove(conn, x) (remove(x)) +#define mg_sleep(x) (usleep((x)*1000)) +#define mg_opendir(conn, x) (opendir(x)) +#define mg_closedir(x) (closedir(x)) +#define mg_readdir(x) (readdir(x)) +#define ERRNO (errno) +#define INVALID_SOCKET (-1) +#define INT64_FMT PRId64 +#define UINT64_FMT PRIu64 +typedef int SOCKET; +#define WINCDECL + +#if defined(__hpux) +/* HPUX 11 does not have monotonic, fall back to realtime */ +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC CLOCK_REALTIME +#endif + +/* HPUX defines socklen_t incorrectly as size_t which is 64bit on + * Itanium. Without defining _XOPEN_SOURCE or _XOPEN_SOURCE_EXTENDED + * the prototypes use int* rather than socklen_t* which matches the + * actual library expectation. When called with the wrong size arg + * accept() returns a zero client inet addr and check_acl() always + * fails. Since socklen_t is widely used below, just force replace + * their typedef with int. - DTL + */ +#define socklen_t int +#endif /* hpux */ + +#endif /* defined(_WIN32) && !defined(__SYMBIAN32__) - WINDOWS / UNIX include \ + block */ + +/* va_copy should always be a macro, C99 and C++11 - DTL */ +#ifndef va_copy +#define va_copy(x, y) ((x) = (y)) +#endif + +#ifdef _WIN32 +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static CRITICAL_SECTION global_log_file_lock; +static DWORD +pthread_self(void) +{ + return GetCurrentThreadId(); +} + + +static int +pthread_key_create( + pthread_key_t *key, + void (*_ignored)(void *) /* destructor not supported for Windows */ + ) +{ + (void)_ignored; + + if ((key != 0)) { + *key = TlsAlloc(); + return (*key != TLS_OUT_OF_INDEXES) ? 0 : -1; + } + return -2; +} + + +static int +pthread_key_delete(pthread_key_t key) +{ + return TlsFree(key) ? 0 : 1; +} + + +static int +pthread_setspecific(pthread_key_t key, void *value) +{ + return TlsSetValue(key, value) ? 0 : 1; +} + + +static void * +pthread_getspecific(pthread_key_t key) +{ + return TlsGetValue(key); +} + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + +static struct pthread_mutex_undefined_struct *pthread_mutex_attr = NULL; +#else +static pthread_mutexattr_t pthread_mutex_attr; +#endif /* _WIN32 */ + + +#define PASSWORDS_FILE_NAME ".htpasswd" +#define CGI_ENVIRONMENT_SIZE (4096) +#define MAX_CGI_ENVIR_VARS (256) +#define MG_BUF_LEN (8192) + +#ifndef MAX_REQUEST_SIZE +#define MAX_REQUEST_SIZE (16384) +#endif + +mg_static_assert(MAX_REQUEST_SIZE >= 256, + "request size length must be a positive number"); + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) + +#if !defined(DEBUG_TRACE) +#if defined(DEBUG) + + +static void DEBUG_TRACE_FUNC(const char *func, + unsigned line, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(3, 4); + +static void +DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...) +{ + va_list args; + flockfile(stdout); + printf("*** %lu.%p.%s.%u: ", + (unsigned long)time(NULL), + (void *)pthread_self(), + func, + line); + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + putchar('\n'); + fflush(stdout); + funlockfile(stdout); +} + +#define DEBUG_TRACE(fmt, ...) \ + DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__) + +#else +#define DEBUG_TRACE(fmt, ...) \ + do { \ + } while (0) +#endif /* DEBUG */ +#endif /* DEBUG_TRACE */ + +#if defined(MEMORY_DEBUGGING) +unsigned long mg_memory_debug_blockCount = 0; +unsigned long mg_memory_debug_totalMemUsed = 0; + + +static void * +mg_malloc_ex(size_t size, const char *file, unsigned line) +{ + void *data = malloc(size + sizeof(size_t)); + void *memory = 0; + char mallocStr[256]; + + if (data) { + *(size_t *)data = size; + mg_memory_debug_totalMemUsed += size; + mg_memory_debug_blockCount++; + memory = (void *)(((char *)data) + sizeof(size_t)); + } + + sprintf(mallocStr, + "MEM: %p %5lu alloc %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)size, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + + return memory; +} + + +static void * +mg_calloc_ex(size_t count, size_t size, const char *file, unsigned line) +{ + void *data = mg_malloc_ex(size * count, file, line); + if (data) { + memset(data, 0, size); + } + return data; +} + + +static void +mg_free_ex(void *memory, const char *file, unsigned line) +{ + char mallocStr[256]; + void *data = (void *)(((char *)memory) - sizeof(size_t)); + size_t size; + + if (memory) { + size = *(size_t *)data; + mg_memory_debug_totalMemUsed -= size; + mg_memory_debug_blockCount--; + sprintf(mallocStr, + "MEM: %p %5lu free %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)size, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + + free(data); + } +} + + +static void * +mg_realloc_ex(void *memory, size_t newsize, const char *file, unsigned line) +{ + char mallocStr[256]; + void *data; + void *_realloc; + size_t oldsize; + + if (newsize) { + if (memory) { + data = (void *)(((char *)memory) - sizeof(size_t)); + oldsize = *(size_t *)data; + _realloc = realloc(data, newsize + sizeof(size_t)); + if (_realloc) { + data = _realloc; + mg_memory_debug_totalMemUsed -= oldsize; + sprintf(mallocStr, + "MEM: %p %5lu r-free %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)oldsize, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + mg_memory_debug_totalMemUsed += newsize; + sprintf(mallocStr, + "MEM: %p %5lu r-alloc %7lu %4lu --- %s:%u\n", + memory, + (unsigned long)newsize, + mg_memory_debug_totalMemUsed, + mg_memory_debug_blockCount, + file, + line); +#if defined(_WIN32) + OutputDebugStringA(mallocStr); +#else + DEBUG_TRACE("%s", mallocStr); +#endif + *(size_t *)data = newsize; + data = (void *)(((char *)data) + sizeof(size_t)); + } else { +#if defined(_WIN32) + OutputDebugStringA("MEM: realloc failed\n"); +#else + DEBUG_TRACE("%s", "MEM: realloc failed\n"); +#endif + return _realloc; + } + } else { + data = mg_malloc_ex(newsize, file, line); + } + } else { + data = 0; + mg_free_ex(memory, file, line); + } + + return data; +} + +#define mg_malloc(a) mg_malloc_ex(a, __FILE__, __LINE__) +#define mg_calloc(a, b) mg_calloc_ex(a, b, __FILE__, __LINE__) +#define mg_realloc(a, b) mg_realloc_ex(a, b, __FILE__, __LINE__) +#define mg_free(a) mg_free_ex(a, __FILE__, __LINE__) + +#else + +static __inline void * +mg_malloc(size_t a) +{ + return malloc(a); +} + +static __inline void * +mg_calloc(size_t a, size_t b) +{ + return calloc(a, b); +} + +static __inline void * +mg_realloc(void *a, size_t b) +{ + return realloc(a, b); +} + +static __inline void +mg_free(void *a) +{ + free(a); +} + +#endif + + +static void mg_vsnprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + const char *fmt, + va_list ap); + +static void mg_snprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(5, 6); + +/* This following lines are just meant as a reminder to use the mg-functions + * for memory management */ +#ifdef malloc +#undef malloc +#endif +#ifdef calloc +#undef calloc +#endif +#ifdef realloc +#undef realloc +#endif +#ifdef free +#undef free +#endif +#ifdef snprintf +#undef snprintf +#endif +#ifdef vsnprintf +#undef vsnprintf +#endif +#define malloc DO_NOT_USE_THIS_FUNCTION__USE_mg_malloc +#define calloc DO_NOT_USE_THIS_FUNCTION__USE_mg_calloc +#define realloc DO_NOT_USE_THIS_FUNCTION__USE_mg_realloc +#define free DO_NOT_USE_THIS_FUNCTION__USE_mg_free +#define snprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_snprintf +#ifdef _WIN32 /* vsnprintf must not be used in any system, * \ + * but this define only works well for Windows. */ +#define vsnprintf DO_NOT_USE_THIS_FUNCTION__USE_mg_vsnprintf +#endif + +#define MD5_STATIC static +#include "md5.inl" + +/* Darwin prior to 7.0 and Win32 do not have socklen_t */ +#ifdef NO_SOCKLEN_T +typedef int socklen_t; +#endif /* NO_SOCKLEN_T */ +#define _DARWIN_UNLIMITED_SELECT + +#define IP_ADDR_STR_LEN (50) /* IPv6 hex string is 46 chars */ + +#if !defined(MSG_NOSIGNAL) +#define MSG_NOSIGNAL (0) +#endif + +#if !defined(SOMAXCONN) +#define SOMAXCONN (100) +#endif + +/* Size of the accepted socket queue */ +#if !defined(MGSQLEN) +#define MGSQLEN (20) +#endif + +#if defined(NO_SSL_DL) +#include +#include +#include +#include +#include +#else +/* SSL loaded dynamically from DLL. + * I put the prototypes here to be independent from OpenSSL source + * installation. */ + +typedef struct ssl_st SSL; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_ctx_st SSL_CTX; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +#define SSL_CTRL_OPTIONS (32) +#define SSL_CTRL_CLEAR_OPTIONS (77) +#define SSL_CTRL_SET_ECDH_AUTO (94) + +#define SSL_VERIFY_NONE (0) +#define SSL_VERIFY_PEER (1) +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT (2) +#define SSL_VERIFY_CLIENT_ONCE (4) +#define SSL_OP_ALL ((long)(0x80000BFFUL)) +#define SSL_OP_NO_SSLv2 (0x01000000L) +#define SSL_OP_NO_SSLv3 (0x02000000L) +#define SSL_OP_NO_TLSv1 (0x04000000L) +#define SSL_OP_NO_TLSv1_2 (0x08000000L) +#define SSL_OP_NO_TLSv1_1 (0x10000000L) +#define SSL_OP_SINGLE_DH_USE (0x00100000L) + +struct ssl_func { + const char *name; /* SSL function name */ + void (*ptr)(void); /* Function pointer */ +}; + +#define SSL_free (*(void (*)(SSL *))ssl_sw[0].ptr) +#define SSL_accept (*(int (*)(SSL *))ssl_sw[1].ptr) +#define SSL_connect (*(int (*)(SSL *))ssl_sw[2].ptr) +#define SSL_read (*(int (*)(SSL *, void *, int))ssl_sw[3].ptr) +#define SSL_write (*(int (*)(SSL *, const void *, int))ssl_sw[4].ptr) +#define SSL_get_error (*(int (*)(SSL *, int))ssl_sw[5].ptr) +#define SSL_set_fd (*(int (*)(SSL *, SOCKET))ssl_sw[6].ptr) +#define SSL_new (*(SSL * (*)(SSL_CTX *))ssl_sw[7].ptr) +#define SSL_CTX_new (*(SSL_CTX * (*)(SSL_METHOD *))ssl_sw[8].ptr) +#define SSLv23_server_method (*(SSL_METHOD * (*)(void))ssl_sw[9].ptr) +#define SSL_library_init (*(int (*)(void))ssl_sw[10].ptr) +#define SSL_CTX_use_PrivateKey_file \ + (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[11].ptr) +#define SSL_CTX_use_certificate_file \ + (*(int (*)(SSL_CTX *, const char *, int))ssl_sw[12].ptr) +#define SSL_CTX_set_default_passwd_cb \ + (*(void (*)(SSL_CTX *, mg_callback_t))ssl_sw[13].ptr) +#define SSL_CTX_free (*(void (*)(SSL_CTX *))ssl_sw[14].ptr) +#define SSL_load_error_strings (*(void (*)(void))ssl_sw[15].ptr) +#define SSL_CTX_use_certificate_chain_file \ + (*(int (*)(SSL_CTX *, const char *))ssl_sw[16].ptr) +#define SSLv23_client_method (*(SSL_METHOD * (*)(void))ssl_sw[17].ptr) +#define SSL_pending (*(int (*)(SSL *))ssl_sw[18].ptr) +#define SSL_CTX_set_verify \ + (*(void (*)(SSL_CTX *, \ + int, \ + int (*verify_callback)(int, X509_STORE_CTX *)))ssl_sw[19].ptr) +#define SSL_shutdown (*(int (*)(SSL *))ssl_sw[20].ptr) +#define SSL_CTX_load_verify_locations \ + (*(int (*)(SSL_CTX *, const char *, const char *))ssl_sw[21].ptr) +#define SSL_CTX_set_default_verify_paths (*(int (*)(SSL_CTX *))ssl_sw[22].ptr) +#define SSL_CTX_set_verify_depth (*(void (*)(SSL_CTX *, int))ssl_sw[23].ptr) +#define SSL_get_peer_certificate (*(X509 * (*)(SSL *))ssl_sw[24].ptr) +#define SSL_get_version (*(const char *(*)(SSL *))ssl_sw[25].ptr) +#define SSL_get_current_cipher (*(SSL_CIPHER * (*)(SSL *))ssl_sw[26].ptr) +#define SSL_CIPHER_get_name \ + (*(const char *(*)(const SSL_CIPHER *))ssl_sw[27].ptr) +#define SSL_CTX_check_private_key (*(int (*)(SSL_CTX *))ssl_sw[28].ptr) +#define SSL_CTX_set_session_id_context \ + (*(int (*)(SSL_CTX *, const unsigned char *, unsigned int))ssl_sw[29].ptr) +#define SSL_CTX_ctrl (*(long (*)(SSL_CTX *, int, long, void *))ssl_sw[30].ptr) +#define SSL_CTX_set_cipher_list \ + (*(int (*)(SSL_CTX *, const char *))ssl_sw[31].ptr) +#define SSL_CTX_set_options(ctx, op) \ + SSL_CTX_ctrl((ctx), SSL_CTRL_OPTIONS, (op), NULL) +#define SSL_CTX_clear_options(ctx, op) \ + SSL_CTX_ctrl((ctx), SSL_CTRL_CLEAR_OPTIONS, (op), NULL) +#define SSL_CTX_set_ecdh_auto(ctx, onoff) \ + SSL_CTX_ctrl(ctx, SSL_CTRL_SET_ECDH_AUTO, onoff, NULL) + +#define CRYPTO_num_locks (*(int (*)(void))crypto_sw[0].ptr) +#define CRYPTO_set_locking_callback \ + (*(void (*)(void (*)(int, int, const char *, int)))crypto_sw[1].ptr) +#define CRYPTO_set_id_callback \ + (*(void (*)(unsigned long (*)(void)))crypto_sw[2].ptr) +#define ERR_get_error (*(unsigned long (*)(void))crypto_sw[3].ptr) +#define ERR_error_string (*(char *(*)(unsigned long, char *))crypto_sw[4].ptr) +#define ERR_remove_state (*(void (*)(unsigned long))crypto_sw[5].ptr) +#define ERR_free_strings (*(void (*)(void))crypto_sw[6].ptr) +#define ENGINE_cleanup (*(void (*)(void))crypto_sw[7].ptr) +#define CONF_modules_unload (*(void (*)(int))crypto_sw[8].ptr) +#define CRYPTO_cleanup_all_ex_data (*(void (*)(void))crypto_sw[9].ptr) +#define EVP_cleanup (*(void (*)(void))crypto_sw[10].ptr) + + +/* set_ssl_option() function updates this array. + * It loads SSL library dynamically and changes NULLs to the actual addresses + * of respective functions. The macros above (like SSL_connect()) are really + * just calling these functions indirectly via the pointer. */ +static struct ssl_func ssl_sw[] = {{"SSL_free", NULL}, + {"SSL_accept", NULL}, + {"SSL_connect", NULL}, + {"SSL_read", NULL}, + {"SSL_write", NULL}, + {"SSL_get_error", NULL}, + {"SSL_set_fd", NULL}, + {"SSL_new", NULL}, + {"SSL_CTX_new", NULL}, + {"SSLv23_server_method", NULL}, + {"SSL_library_init", NULL}, + {"SSL_CTX_use_PrivateKey_file", NULL}, + {"SSL_CTX_use_certificate_file", NULL}, + {"SSL_CTX_set_default_passwd_cb", NULL}, + {"SSL_CTX_free", NULL}, + {"SSL_load_error_strings", NULL}, + {"SSL_CTX_use_certificate_chain_file", NULL}, + {"SSLv23_client_method", NULL}, + {"SSL_pending", NULL}, + {"SSL_CTX_set_verify", NULL}, + {"SSL_shutdown", NULL}, + {"SSL_CTX_load_verify_locations", NULL}, + {"SSL_CTX_set_default_verify_paths", NULL}, + {"SSL_CTX_set_verify_depth", NULL}, + {"SSL_get_peer_certificate", NULL}, + {"SSL_get_version", NULL}, + {"SSL_get_current_cipher", NULL}, + {"SSL_CIPHER_get_name", NULL}, + {"SSL_CTX_check_private_key", NULL}, + {"SSL_CTX_set_session_id_context", NULL}, + {"SSL_CTX_ctrl", NULL}, + {"SSL_CTX_set_cipher_list", NULL}, + {NULL, NULL}}; + + +/* Similar array as ssl_sw. These functions could be located in different + * lib. */ +#if !defined(NO_SSL) +static struct ssl_func crypto_sw[] = {{"CRYPTO_num_locks", NULL}, + {"CRYPTO_set_locking_callback", NULL}, + {"CRYPTO_set_id_callback", NULL}, + {"ERR_get_error", NULL}, + {"ERR_error_string", NULL}, + {"ERR_remove_state", NULL}, + {"ERR_free_strings", NULL}, + {"ENGINE_cleanup", NULL}, + {"CONF_modules_unload", NULL}, + {"CRYPTO_cleanup_all_ex_data", NULL}, + {"EVP_cleanup", NULL}, + {NULL, NULL}}; +#endif /* NO_SSL */ +#endif /* NO_SSL_DL */ + + +#if !defined(NO_CACHING) +static const char *month_names[] = {"Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec"}; +#endif /* !NO_CACHING */ + +/* Unified socket address. For IPv6 support, add IPv6 address structure in the + * union u. */ +union usa { + struct sockaddr sa; + struct sockaddr_in sin; +#if defined(USE_IPV6) + struct sockaddr_in6 sin6; +#endif +}; + +/* Describes a string (chunk of memory). */ +struct vec { + const char *ptr; + size_t len; +}; + +struct file { + uint64_t size; + time_t last_modified; + FILE *fp; + const char *membuf; /* Non-NULL if file data is in memory */ + int is_directory; + int gzipped; /* set to 1 if the content is gzipped + * in which case we need a content-encoding: gzip header */ +}; + +#define STRUCT_FILE_INITIALIZER \ + { \ + (uint64_t)0, (time_t)0, (FILE *)NULL, (const char *)NULL, 0, 0 \ + } + +/* Describes listening socket, or socket which was accept()-ed by the master + * thread and queued for future handling by the worker thread. */ +struct socket { + SOCKET sock; /* Listening socket */ + union usa lsa; /* Local socket address */ + union usa rsa; /* Remote socket address */ + unsigned char is_ssl; /* Is port SSL-ed */ + unsigned char ssl_redir; /* Is port supposed to redirect everything to SSL + * port */ +}; + +/* NOTE(lsm): this enum shoulds be in sync with the config_options below. */ +enum { + CGI_EXTENSIONS, + CGI_ENVIRONMENT, + PUT_DELETE_PASSWORDS_FILE, + CGI_INTERPRETER, + PROTECT_URI, + AUTHENTICATION_DOMAIN, + SSI_EXTENSIONS, + THROTTLE, + ACCESS_LOG_FILE, + ENABLE_DIRECTORY_LISTING, + ERROR_LOG_FILE, + GLOBAL_PASSWORDS_FILE, + INDEX_FILES, + ENABLE_KEEP_ALIVE, + ACCESS_CONTROL_LIST, + EXTRA_MIME_TYPES, + LISTENING_PORTS, + DOCUMENT_ROOT, + SSL_CERTIFICATE, + NUM_THREADS, + RUN_AS_USER, + REWRITE, + HIDE_FILES, + REQUEST_TIMEOUT, + SSL_DO_VERIFY_PEER, + SSL_CA_PATH, + SSL_CA_FILE, + SSL_VERIFY_DEPTH, + SSL_DEFAULT_VERIFY_PATHS, + SSL_CIPHER_LIST, + SSL_PROTOCOL_VERSION, + SSL_SHORT_TRUST, +#if defined(USE_WEBSOCKET) + WEBSOCKET_TIMEOUT, +#endif + DECODE_URL, + +#if defined(USE_LUA) + LUA_PRELOAD_FILE, + LUA_SCRIPT_EXTENSIONS, + LUA_SERVER_PAGE_EXTENSIONS, +#endif +#if defined(USE_DUKTAPE) + DUKTAPE_SCRIPT_EXTENSIONS, +#endif + +#if defined(USE_WEBSOCKET) + WEBSOCKET_ROOT, +#endif +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + LUA_WEBSOCKET_EXTENSIONS, +#endif + ACCESS_CONTROL_ALLOW_ORIGIN, + ERROR_PAGES, + CONFIG_TCP_NODELAY, /* Prepended CONFIG_ to avoid conflict with the + * socket option typedef TCP_NODELAY. */ +#if !defined(NO_CACHING) + STATIC_FILE_MAX_AGE, +#endif + + NUM_OPTIONS +}; + + +/* Config option name, config types, default value */ +static struct mg_option config_options[] = { + {"cgi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.cgi$|**.pl$|**.php$"}, + {"cgi_environment", CONFIG_TYPE_STRING, NULL}, + {"put_delete_auth_file", CONFIG_TYPE_FILE, NULL}, + {"cgi_interpreter", CONFIG_TYPE_FILE, NULL}, + {"protect_uri", CONFIG_TYPE_STRING, NULL}, + {"authentication_domain", CONFIG_TYPE_STRING, "mydomain.com"}, + {"ssi_pattern", CONFIG_TYPE_EXT_PATTERN, "**.shtml$|**.shtm$"}, + {"throttle", CONFIG_TYPE_STRING, NULL}, + {"access_log_file", CONFIG_TYPE_FILE, NULL}, + {"enable_directory_listing", CONFIG_TYPE_BOOLEAN, "yes"}, + {"error_log_file", CONFIG_TYPE_FILE, NULL}, + {"global_auth_file", CONFIG_TYPE_FILE, NULL}, + {"index_files", + CONFIG_TYPE_STRING, +#ifdef USE_LUA + "index.xhtml,index.html,index.htm,index.lp,index.lsp,index.lua,index.cgi," + "index.shtml,index.php"}, +#else + "index.xhtml,index.html,index.htm,index.cgi,index.shtml,index.php"}, +#endif + {"enable_keep_alive", CONFIG_TYPE_BOOLEAN, "no"}, + {"access_control_list", CONFIG_TYPE_STRING, NULL}, + {"extra_mime_types", CONFIG_TYPE_STRING, NULL}, + {"listening_ports", CONFIG_TYPE_STRING, "8080"}, + {"document_root", CONFIG_TYPE_DIRECTORY, NULL}, + {"ssl_certificate", CONFIG_TYPE_FILE, NULL}, + {"num_threads", CONFIG_TYPE_NUMBER, "50"}, + {"run_as_user", CONFIG_TYPE_STRING, NULL}, + {"url_rewrite_patterns", CONFIG_TYPE_STRING, NULL}, + {"hide_files_patterns", CONFIG_TYPE_EXT_PATTERN, NULL}, + {"request_timeout_ms", CONFIG_TYPE_NUMBER, "30000"}, + {"ssl_verify_peer", CONFIG_TYPE_BOOLEAN, "no"}, + {"ssl_ca_path", CONFIG_TYPE_DIRECTORY, NULL}, + {"ssl_ca_file", CONFIG_TYPE_FILE, NULL}, + {"ssl_verify_depth", CONFIG_TYPE_NUMBER, "9"}, + {"ssl_default_verify_paths", CONFIG_TYPE_BOOLEAN, "yes"}, + {"ssl_cipher_list", CONFIG_TYPE_STRING, NULL}, + {"ssl_protocol_version", CONFIG_TYPE_NUMBER, "0"}, + {"ssl_short_trust", CONFIG_TYPE_BOOLEAN, "no"}, +#if defined(USE_WEBSOCKET) + {"websocket_timeout_ms", CONFIG_TYPE_NUMBER, "30000"}, +#endif + {"decode_url", CONFIG_TYPE_BOOLEAN, "yes"}, + +#if defined(USE_LUA) + {"lua_preload_file", CONFIG_TYPE_FILE, NULL}, + {"lua_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"}, + {"lua_server_page_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lp$|**.lsp$"}, +#endif +#if defined(USE_DUKTAPE) + /* The support for duktape is still in alpha version state. + * The name of this config option might change. */ + {"duktape_script_pattern", CONFIG_TYPE_EXT_PATTERN, "**.ssjs$"}, +#endif + +#if defined(USE_WEBSOCKET) + {"websocket_root", CONFIG_TYPE_DIRECTORY, NULL}, +#endif +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + {"lua_websocket_pattern", CONFIG_TYPE_EXT_PATTERN, "**.lua$"}, +#endif + {"access_control_allow_origin", CONFIG_TYPE_STRING, "*"}, + {"error_pages", CONFIG_TYPE_DIRECTORY, NULL}, + {"tcp_nodelay", CONFIG_TYPE_NUMBER, "0"}, +#if !defined(NO_CACHING) + {"static_file_max_age", CONFIG_TYPE_NUMBER, "3600"}, +#endif + + {NULL, CONFIG_TYPE_UNKNOWN, NULL}}; + +/* Check if the config_options and the corresponding enum have compatible + * sizes. */ +mg_static_assert((sizeof(config_options) / sizeof(config_options[0])) + == (NUM_OPTIONS + 1), + "config_options and enum not sync"); + +enum { REQUEST_HANDLER, WEBSOCKET_HANDLER, AUTH_HANDLER }; + +struct mg_handler_info { + /* Name/Pattern of the URI. */ + char *uri; + size_t uri_len; + + /* handler type */ + int handler_type; + + /* Handler for http/https or authorization requests. */ + mg_request_handler handler; + + /* Handler for ws/wss (websocket) requests. */ + mg_websocket_connect_handler connect_handler; + mg_websocket_ready_handler ready_handler; + mg_websocket_data_handler data_handler; + mg_websocket_close_handler close_handler; + + /* Handler for authorization requests */ + mg_authorization_handler auth_handler; + + /* User supplied argument for the handler function. */ + void *cbdata; + + /* next handler in a linked list */ + struct mg_handler_info *next; +}; + +struct mg_context { + volatile int stop_flag; /* Should we stop event loop */ + SSL_CTX *ssl_ctx; /* SSL context */ + char *config[NUM_OPTIONS]; /* Civetweb configuration parameters */ + struct mg_callbacks callbacks; /* User-defined callback function */ + void *user_data; /* User-defined data */ + int context_type; /* 1 = server context, 2 = client context */ + + struct socket *listening_sockets; + in_port_t *listening_ports; + unsigned int num_listening_sockets; + + volatile int + running_worker_threads; /* Number of currently running worker threads */ + pthread_mutex_t thread_mutex; /* Protects (max|num)_threads */ + pthread_cond_t thread_cond; /* Condvar for tracking workers terminations */ + + struct socket queue[MGSQLEN]; /* Accepted sockets */ + volatile int sq_head; /* Head of the socket queue */ + volatile int sq_tail; /* Tail of the socket queue */ + pthread_cond_t sq_full; /* Signaled when socket is produced */ + pthread_cond_t sq_empty; /* Signaled when socket is consumed */ + pthread_t masterthreadid; /* The master thread ID */ + unsigned int + cfg_worker_threads; /* The number of configured worker threads. */ + pthread_t *workerthreadids; /* The worker thread IDs */ + + time_t start_time; /* Server start time, used for authentication */ + uint64_t auth_nonce_mask; /* Mask for all nonce values */ + pthread_mutex_t nonce_mutex; /* Protects nonce_count */ + unsigned long nonce_count; /* Used nonces, used for authentication */ + + char *systemName; /* What operating system is running */ + + /* linked list of uri handlers */ + struct mg_handler_info *handlers; + +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + /* linked list of shared lua websockets */ + struct mg_shared_lua_websocket_list *shared_lua_websockets; +#endif + +#ifdef USE_TIMERS + struct ttimers *timers; +#endif +}; + + +struct mg_connection { + struct mg_request_info request_info; + struct mg_context *ctx; + SSL *ssl; /* SSL descriptor */ + SSL_CTX *client_ssl_ctx; /* SSL context for client connections */ + struct socket client; /* Connected client */ + time_t conn_birth_time; /* Time (wall clock) when connection was + * established */ + struct timespec req_time; /* Time (since system start) when the request + * was received */ + int64_t num_bytes_sent; /* Total bytes sent to client */ + int64_t content_len; /* Content-Length header value */ + int64_t consumed_content; /* How many bytes of content have been read */ + int is_chunked; /* Transfer-Encoding is chunked: 0=no, 1=yes: + * data available, 2: all data read */ + size_t chunk_remainder; /* Unread data from the last chunk */ + char *buf; /* Buffer for received data */ + char *path_info; /* PATH_INFO part of the URL */ + + int must_close; /* 1 if connection must be closed */ + int in_error_handler; /* 1 if in handler for user defined error + * pages */ + int internal_error; /* 1 if an error occured while processing the + * request */ + + int buf_size; /* Buffer size */ + int request_len; /* Size of the request + headers in a buffer */ + int data_len; /* Total size of data in a buffer */ + int status_code; /* HTTP reply status code, e.g. 200 */ + int throttle; /* Throttling, bytes/sec. <= 0 means no + * throttle */ + time_t last_throttle_time; /* Last time throttled data was sent */ + int64_t last_throttle_bytes; /* Bytes sent this second */ + pthread_mutex_t mutex; /* Used by mg_(un)lock_connection to ensure + * atomic transmissions for websockets */ +#if defined(USE_LUA) && defined(USE_WEBSOCKET) + void *lua_websocket_state; /* Lua_State for a websocket connection */ +#endif +}; + + +static pthread_key_t sTlsKey; /* Thread local storage index */ +static int sTlsInit = 0; +static int thread_idx_max = 0; + + +struct mg_workerTLS { + int is_master; + unsigned long thread_idx; +#if defined(_WIN32) && !defined(__SYMBIAN32__) + HANDLE pthread_cond_helper_mutex; +#endif +}; + +/* Directory entry */ +struct de { + struct mg_connection *conn; + char *file_name; + struct file file; +}; + + +#if defined(USE_WEBSOCKET) +static int is_websocket_protocol(const struct mg_connection *conn); +#else +#define is_websocket_protocol(conn) (0) +#endif + + +static int +mg_atomic_inc(volatile int *addr) +{ + int ret; +#if defined(_WIN32) && !defined(__SYMBIAN32__) + /* Depending on the SDK, this function uses either + * (volatile unsigned int *) or (volatile LONG *), + * so whatever you use, the other SDK is likely to raise a warning. */ + ret = InterlockedIncrement((volatile long *)addr); +#elif defined(__GNUC__) \ + && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) + ret = __sync_add_and_fetch(addr, 1); +#else + ret = (++(*addr)); +#endif + return ret; +} + + +static int +mg_atomic_dec(volatile int *addr) +{ + int ret; +#if defined(_WIN32) && !defined(__SYMBIAN32__) + /* Depending on the SDK, this function uses either + * (volatile unsigned int *) or (volatile LONG *), + * so whatever you use, the other SDK is likely to raise a warning. */ + ret = InterlockedDecrement((volatile long *)addr); +#elif defined(__GNUC__) \ + && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 0))) + ret = __sync_sub_and_fetch(addr, 1); +#else + ret = (--(*addr)); +#endif + return ret; +} + +#if !defined(NO_THREAD_NAME) +#if defined(_WIN32) && defined(_MSC_VER) +/* Set the thread name for debugging purposes in Visual Studio + * http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + */ +#pragma pack(push, 8) +typedef struct tagTHREADNAME_INFO { + DWORD dwType; /* Must be 0x1000. */ + LPCSTR szName; /* Pointer to name (in user addr space). */ + DWORD dwThreadID; /* Thread ID (-1=caller thread). */ + DWORD dwFlags; /* Reserved for future use, must be zero. */ +} THREADNAME_INFO; +#pragma pack(pop) +#elif defined(__linux__) +#include +#include +#endif + + +static void +mg_set_thread_name(const char *name) +{ + char threadName[16 + 1]; /* 16 = Max. thread length in Linux/OSX/.. */ + + mg_snprintf( + NULL, NULL, threadName, sizeof(threadName), "civetweb-%s", name); + +#if defined(_WIN32) +#if defined(_MSC_VER) + /* Windows and Visual Studio Compiler */ + __try + { + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = ~0U; + info.dwFlags = 0; + + RaiseException(0x406D1388, + 0, + sizeof(info) / sizeof(ULONG_PTR), + (ULONG_PTR *)&info); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + } +#elif defined(__MINGW32__) +/* No option known to set thread name for MinGW */ +#endif +#elif defined(__GLIBC__) \ + && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12))) + /* pthread_setname_np first appeared in glibc in version 2.12*/ + (void)pthread_setname_np(pthread_self(), threadName); +#elif defined(__linux__) + /* on linux we can use the old prctl function */ + (void)prctl(PR_SET_NAME, threadName, 0, 0, 0); +#endif +} +#else /* !defined(NO_THREAD_NAME) */ +void +mg_set_thread_name(const char *threadName) +{ +} +#endif + + +#if defined(MG_LEGACY_INTERFACE) +const char ** +mg_get_valid_option_names(void) +{ + /* This function is deprecated. Use mg_get_valid_options instead. */ + static const char * + data[2 * sizeof(config_options) / sizeof(config_options[0])] = {0}; + int i; + + for (i = 0; config_options[i].name != NULL; i++) { + data[i * 2] = config_options[i].name; + data[i * 2 + 1] = config_options[i].default_value; + } + + return data; +} +#endif + + +const struct mg_option * +mg_get_valid_options(void) +{ + return config_options; +} + + +static int +is_file_in_memory(const struct mg_connection *conn, + const char *path, + struct file *filep) +{ + size_t size = 0; + if (!conn || !filep) { + return 0; + } + + if (conn->ctx->callbacks.open_file) { + filep->membuf = conn->ctx->callbacks.open_file(conn, path, &size); + if (filep->membuf != NULL) { + /* NOTE: override filep->size only on success. Otherwise, it might + * break constructs like if (!mg_stat() || !mg_fopen()) ... */ + filep->size = size; + } + } + + return filep->membuf != NULL; +} + + +static int +is_file_opened(const struct file *filep) +{ + if (!filep) { + return 0; + } + + return filep->membuf != NULL || filep->fp != NULL; +} + + +/* mg_fopen will open a file either in memory or on the disk. + * The input parameter path is a string in UTF-8 encoding. + * The input parameter mode is the same as for fopen. + * Either fp or membuf will be set in the output struct filep. + * The function returns 1 on success, 0 on error. */ +static int +mg_fopen(const struct mg_connection *conn, + const char *path, + const char *mode, + struct file *filep) +{ + struct stat st; + + if (!filep) { + return 0; + } + + /* TODO (high): mg_fopen should only open a file, while mg_stat should + * only get the file status. They should not work on different members of + * the same structure (bad cohesion). */ + memset(filep, 0, sizeof(*filep)); + + if (stat(path, &st) == 0) { + filep->size = (uint64_t)(st.st_size); + } + + if (!is_file_in_memory(conn, path, filep)) { +#ifdef _WIN32 + wchar_t wbuf[PATH_MAX], wmode[20]; + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + MultiByteToWideChar(CP_UTF8, 0, mode, -1, wmode, ARRAY_SIZE(wmode)); + filep->fp = _wfopen(wbuf, wmode); +#else + /* Linux et al already use unicode. No need to convert. */ + filep->fp = fopen(path, mode); +#endif + } + + return is_file_opened(filep); +} + + +static void +mg_fclose(struct file *filep) +{ + if (filep != NULL && filep->fp != NULL) { + fclose(filep->fp); + } +} + + +static void +mg_strlcpy(register char *dst, register const char *src, size_t n) +{ + for (; *src != '\0' && n > 1; n--) { + *dst++ = *src++; + } + *dst = '\0'; +} + + +static int +lowercase(const char *s) +{ + return tolower(*(const unsigned char *)s); +} + + +int +mg_strncasecmp(const char *s1, const char *s2, size_t len) +{ + int diff = 0; + + if (len > 0) { + do { + diff = lowercase(s1++) - lowercase(s2++); + } while (diff == 0 && s1[-1] != '\0' && --len > 0); + } + + return diff; +} + + +int +mg_strcasecmp(const char *s1, const char *s2) +{ + int diff; + + do { + diff = lowercase(s1++) - lowercase(s2++); + } while (diff == 0 && s1[-1] != '\0'); + + return diff; +} + + +static char * +mg_strndup(const char *ptr, size_t len) +{ + char *p; + + if ((p = (char *)mg_malloc(len + 1)) != NULL) { + mg_strlcpy(p, ptr, len + 1); + } + + return p; +} + + +static char * +mg_strdup(const char *str) +{ + return mg_strndup(str, strlen(str)); +} + + +static const char * +mg_strcasestr(const char *big_str, const char *small_str) +{ + size_t i, big_len = strlen(big_str), small_len = strlen(small_str); + + if (big_len >= small_len) { + for (i = 0; i <= (big_len - small_len); i++) { + if (mg_strncasecmp(big_str + i, small_str, small_len) == 0) { + return big_str + i; + } + } + } + + return NULL; +} + + +/* Return null terminated string of given maximum length. + * Report errors if length is exceeded. */ +static void +mg_vsnprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + const char *fmt, + va_list ap) +{ + int n, ok; + + if (buflen == 0) { + return; + } + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wformat-nonliteral" +/* Using fmt as a non-literal is intended here, since it is mostly called + * indirectly by mg_snprintf */ +#endif + + n = (int)vsnprintf_impl(buf, buflen, fmt, ap); + ok = (n >= 0) && ((size_t)n < buflen); + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + + if (ok) { + if (truncated) { + *truncated = 0; + } + } else { + if (truncated) { + *truncated = 1; + } + mg_cry(conn, + "truncating vsnprintf buffer: [%.*s]", + (int)((buflen > 200) ? 200 : (buflen - 1)), + buf); + n = (int)buflen - 1; + } + buf[n] = '\0'; +} + + +static void +mg_snprintf(const struct mg_connection *conn, + int *truncated, + char *buf, + size_t buflen, + const char *fmt, + ...) +{ + va_list ap; + + va_start(ap, fmt); + mg_vsnprintf(conn, truncated, buf, buflen, fmt, ap); + va_end(ap); +} + + +static int +get_option_index(const char *name) +{ + int i; + + for (i = 0; config_options[i].name != NULL; i++) { + if (strcmp(config_options[i].name, name) == 0) { + return i; + } + } + return -1; +} + + +const char * +mg_get_option(const struct mg_context *ctx, const char *name) +{ + int i; + if ((i = get_option_index(name)) == -1) { + return NULL; + } else if (!ctx || ctx->config[i] == NULL) { + return ""; + } else { + return ctx->config[i]; + } +} + + +struct mg_context * +mg_get_context(const struct mg_connection *conn) +{ + return (conn == NULL) ? (struct mg_context *)NULL : (conn->ctx); +} + + +void * +mg_get_user_data(const struct mg_context *ctx) +{ + return (ctx == NULL) ? NULL : ctx->user_data; +} + + +void +mg_set_user_connection_data(struct mg_connection *conn, void *data) +{ + if (conn != NULL) { + conn->request_info.conn_data = data; + } +} + + +void * +mg_get_user_connection_data(const struct mg_connection *conn) +{ + if (conn != NULL) { + return conn->request_info.conn_data; + } + return NULL; +} + + +size_t +mg_get_ports(const struct mg_context *ctx, size_t size, int *ports, int *ssl) +{ + size_t i; + if (!ctx) { + return 0; + } + for (i = 0; i < size && i < ctx->num_listening_sockets; i++) { + ssl[i] = ctx->listening_sockets[i].is_ssl; + ports[i] = ctx->listening_ports[i]; + } + return i; +} + + +int +mg_get_server_ports(const struct mg_context *ctx, + int size, + struct mg_server_ports *ports) +{ + int i, cnt = 0; + + if (size <= 0) { + return -1; + } + memset(ports, 0, sizeof(*ports) * (size_t)size); + if (!ctx) { + return -1; + } + if (!ctx->listening_sockets || !ctx->listening_ports) { + return -1; + } + + for (i = 0; (i < size) && (i < (int)ctx->num_listening_sockets); i++) { + + ports[cnt].port = ctx->listening_ports[i]; + ports[cnt].is_ssl = ctx->listening_sockets[i].is_ssl; + ports[cnt].is_redirect = ctx->listening_sockets[i].ssl_redir; + + if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET) { + /* IPv4 */ + ports[cnt].protocol = 1; + cnt++; + } else if (ctx->listening_sockets[i].lsa.sa.sa_family == AF_INET6) { + /* IPv6 */ + ports[cnt].protocol = 3; + cnt++; + } + } + + return cnt; +} + + +static void +sockaddr_to_string(char *buf, size_t len, const union usa *usa) +{ + buf[0] = '\0'; + + if (!usa) { + return; + } + + if (usa->sa.sa_family == AF_INET) { + getnameinfo(&usa->sa, + sizeof(usa->sin), + buf, + (unsigned)len, + NULL, + 0, + NI_NUMERICHOST); + } +#if defined(USE_IPV6) + else if (usa->sa.sa_family == AF_INET6) { + getnameinfo(&usa->sa, + sizeof(usa->sin6), + buf, + (unsigned)len, + NULL, + 0, + NI_NUMERICHOST); + } +#endif +} + + +/* Convert time_t to a string. According to RFC2616, Sec 14.18, this must be + * included in all responses other than 100, 101, 5xx. */ +static void +gmt_time_string(char *buf, size_t buf_len, time_t *t) +{ + struct tm *tm; + + tm = ((t != NULL) ? gmtime(t) : NULL); + if (tm != NULL) { + strftime(buf, buf_len, "%a, %d %b %Y %H:%M:%S GMT", tm); + } else { + mg_strlcpy(buf, "Thu, 01 Jan 1970 00:00:00 GMT", buf_len); + buf[buf_len - 1] = '\0'; + } +} + + +/* difftime for struct timespec. Return value is in seconds. */ +static double +mg_difftimespec(const struct timespec *ts_now, const struct timespec *ts_before) +{ + return (double)(ts_now->tv_nsec - ts_before->tv_nsec) * 1.0E-9 + + (double)(ts_now->tv_sec - ts_before->tv_sec); +} + + +/* Print error message to the opened error log stream. */ +void +mg_cry(const struct mg_connection *conn, const char *fmt, ...) +{ + char buf[MG_BUF_LEN], src_addr[IP_ADDR_STR_LEN]; + va_list ap; + struct file fi; + time_t timestamp; + + va_start(ap, fmt); + IGNORE_UNUSED_RESULT(vsnprintf_impl(buf, sizeof(buf), fmt, ap)); + va_end(ap); + buf[sizeof(buf) - 1] = 0; + + if (!conn) { + puts(buf); + return; + } + + /* Do not lock when getting the callback value, here and below. + * I suppose this is fine, since function cannot disappear in the + * same way string option can. */ + if ((conn->ctx->callbacks.log_message == NULL) + || (conn->ctx->callbacks.log_message(conn, buf) == 0)) { + + if (conn->ctx->config[ERROR_LOG_FILE] != NULL) { + if (mg_fopen(conn, conn->ctx->config[ERROR_LOG_FILE], "a+", &fi) + == 0) { + fi.fp = NULL; + } + } else { + fi.fp = NULL; + } + + if (fi.fp != NULL) { + flockfile(fi.fp); + timestamp = time(NULL); + + sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa); + fprintf(fi.fp, + "[%010lu] [error] [client %s] ", + (unsigned long)timestamp, + src_addr); + + if (conn->request_info.request_method != NULL) { + fprintf(fi.fp, + "%s %s: ", + conn->request_info.request_method, + conn->request_info.request_uri); + } + + fprintf(fi.fp, "%s", buf); + fputc('\n', fi.fp); + fflush(fi.fp); + funlockfile(fi.fp); + mg_fclose(&fi); + } + } +} + + +/* Return fake connection structure. Used for logging, if connection + * is not applicable at the moment of logging. */ +static struct mg_connection * +fc(struct mg_context *ctx) +{ + static struct mg_connection fake_connection; + fake_connection.ctx = ctx; + return &fake_connection; +} + + +const char * +mg_version(void) +{ + return CIVETWEB_VERSION; +} + + +const struct mg_request_info * +mg_get_request_info(const struct mg_connection *conn) +{ + if (!conn) { + return NULL; + } + return &conn->request_info; +} + + +/* Skip the characters until one of the delimiters characters found. + * 0-terminate resulting word. Skip the delimiter and following whitespaces. + * Advance pointer to buffer to the next word. Return found 0-terminated word. + * Delimiters can be quoted with quotechar. */ +static char * +skip_quoted(char **buf, + const char *delimiters, + const char *whitespace, + char quotechar) +{ + char *p, *begin_word, *end_word, *end_whitespace; + + begin_word = *buf; + end_word = begin_word + strcspn(begin_word, delimiters); + + /* Check for quotechar */ + if (end_word > begin_word) { + p = end_word - 1; + while (*p == quotechar) { + /* While the delimiter is quoted, look for the next delimiter. */ + /* This happens, e.g., in calls from parse_auth_header, + * if the user name contains a " character. */ + + /* If there is anything beyond end_word, copy it. */ + if (*end_word != '\0') { + size_t end_off = strcspn(end_word + 1, delimiters); + memmove(p, end_word, end_off + 1); + p += end_off; /* p must correspond to end_word - 1 */ + end_word += end_off + 1; + } else { + *p = '\0'; + break; + } + } + for (p++; p < end_word; p++) { + *p = '\0'; + } + } + + if (*end_word == '\0') { + *buf = end_word; + } else { + end_whitespace = end_word + 1 + strspn(end_word + 1, whitespace); + + for (p = end_word; p < end_whitespace; p++) { + *p = '\0'; + } + + *buf = end_whitespace; + } + + return begin_word; +} + + +/* Simplified version of skip_quoted without quote char + * and whitespace == delimiters */ +static char * +skip(char **buf, const char *delimiters) +{ + return skip_quoted(buf, delimiters, delimiters, 0); +} + + +/* Return HTTP header value, or NULL if not found. */ +static const char * +get_header(const struct mg_request_info *ri, const char *name) +{ + int i; + if (ri) { + for (i = 0; i < ri->num_headers; i++) { + if (!mg_strcasecmp(name, ri->http_headers[i].name)) { + return ri->http_headers[i].value; + } + } + } + + return NULL; +} + + +const char * +mg_get_header(const struct mg_connection *conn, const char *name) +{ + if (!conn) { + return NULL; + } + + return get_header(&conn->request_info, name); +} + + +/* A helper function for traversing a comma separated list of values. + * It returns a list pointer shifted to the next value, or NULL if the end + * of the list found. + * Value is stored in val vector. If value has form "x=y", then eq_val + * vector is initialized to point to the "y" part, and val vector length + * is adjusted to point only to "x". */ +static const char * +next_option(const char *list, struct vec *val, struct vec *eq_val) +{ + int end; + +reparse: + if (val == NULL || list == NULL || *list == '\0') { + /* End of the list */ + list = NULL; + } else { + /* Skip over leading LWS */ + while (*list == ' ' || *list == '\t') + list++; + + val->ptr = list; + if ((list = strchr(val->ptr, ',')) != NULL) { + /* Comma found. Store length and shift the list ptr */ + val->len = ((size_t)(list - val->ptr)); + list++; + } else { + /* This value is the last one */ + list = val->ptr + strlen(val->ptr); + val->len = ((size_t)(list - val->ptr)); + } + + /* Adjust length for trailing LWS */ + end = (int)val->len - 1; + while (end >= 0 && (val->ptr[end] == ' ' || val->ptr[end] == '\t')) + end--; + val->len = (size_t)(end + 1); + + if (val->len == 0) { + /* Ignore any empty entries. */ + goto reparse; + } + + if (eq_val != NULL) { + /* Value has form "x=y", adjust pointers and lengths + * so that val points to "x", and eq_val points to "y". */ + eq_val->len = 0; + eq_val->ptr = (const char *)memchr(val->ptr, '=', val->len); + if (eq_val->ptr != NULL) { + eq_val->ptr++; /* Skip over '=' character */ + eq_val->len = ((size_t)(val->ptr - eq_val->ptr)) + val->len; + val->len = ((size_t)(eq_val->ptr - val->ptr)) - 1; + } + } + } + + return list; +} + +/* A helper function for checking if a comma separated list of values contains + * the given option (case insensitvely). + * 'header' can be NULL, in which case false is returned. */ +static int +header_has_option(const char *header, const char *option) +{ + struct vec opt_vec; + struct vec eq_vec; + + assert(option != NULL); + assert(option[0] != '\0'); + + while ((header = next_option(header, &opt_vec, &eq_vec)) != NULL) { + if (mg_strncasecmp(option, opt_vec.ptr, opt_vec.len) == 0) + return 1; + } + + return 0; +} + +/* Perform case-insensitive match of string against pattern */ +static int +match_prefix(const char *pattern, size_t pattern_len, const char *str) +{ + const char *or_str; + size_t i; + int j, len, res; + + if ((or_str = (const char *)memchr(pattern, '|', pattern_len)) != NULL) { + res = match_prefix(pattern, (size_t)(or_str - pattern), str); + return res > 0 ? res : match_prefix(or_str + 1, + (size_t)((pattern + pattern_len) + - (or_str + 1)), + str); + } + + for (i = 0, j = 0; i < pattern_len; i++, j++) { + if (pattern[i] == '?' && str[j] != '\0') { + continue; + } else if (pattern[i] == '$') { + return str[j] == '\0' ? j : -1; + } else if (pattern[i] == '*') { + i++; + if (pattern[i] == '*') { + i++; + len = (int)strlen(str + j); + } else { + len = (int)strcspn(str + j, "/"); + } + if (i == pattern_len) { + return j + len; + } + do { + res = match_prefix(pattern + i, pattern_len - i, str + j + len); + } while (res == -1 && len-- > 0); + return res == -1 ? -1 : j + res + len; + } else if (lowercase(&pattern[i]) != lowercase(&str[j])) { + return -1; + } + } + return j; +} + + +/* HTTP 1.1 assumes keep alive if "Connection:" header is not set + * This function must tolerate situations when connection info is not + * set up, for example if request parsing failed. */ +static int +should_keep_alive(const struct mg_connection *conn) +{ + if (conn != NULL) { + const char *http_version = conn->request_info.http_version; + const char *header = mg_get_header(conn, "Connection"); + if (conn->must_close || conn->internal_error || conn->status_code == 401 + || mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 + || (header != NULL && !header_has_option(header, "keep-alive")) + || (header == NULL && http_version + && 0 != strcmp(http_version, "1.1"))) { + return 0; + } + return 1; + } + return 0; +} + + +static int +should_decode_url(const struct mg_connection *conn) +{ + if (!conn || !conn->ctx) { + return 0; + } + + return (mg_strcasecmp(conn->ctx->config[DECODE_URL], "yes") == 0); +} + + +static const char * +suggest_connection_header(const struct mg_connection *conn) +{ + return should_keep_alive(conn) ? "keep-alive" : "close"; +} + + +static int +send_no_cache_header(struct mg_connection *conn) +{ + /* Send all current and obsolete cache opt-out directives. */ + return mg_printf(conn, + "Cache-Control: no-cache, no-store, " + "must-revalidate, private, max-age=0\r\n" + "Pragma: no-cache\r\n" + "Expires: 0\r\n"); +} + + +static int +send_static_cache_header(struct mg_connection *conn) +{ +#if !defined(NO_CACHING) + /* Read the server config to check how long a file may be cached. + * The configuration is in seconds. */ + int max_age = atoi(conn->ctx->config[STATIC_FILE_MAX_AGE]); + if (max_age <= 0) { + /* 0 means "do not cache". All values <0 are reserved + * and may be used differently in the future. */ + /* If a file should not be cached, do not only send + * max-age=0, but also pragmas and Expires headers. */ + return send_no_cache_header(conn); + } + + /* Use "Cache-Control: max-age" instead of "Expires" header. + * Reason: see https://www.mnot.net/blog/2007/05/15/expires_max-age */ + /* See also https://www.mnot.net/cache_docs/ */ + /* According to RFC 2616, Section 14.21, caching times should not exceed + * one year. A year with 365 days corresponds to 31536000 seconds, a leap + * year to 31622400 seconds. For the moment, we just send whatever has + * been configured, still the behavior for >1 year should be considered + * as undefined. */ + return mg_printf(conn, "Cache-Control: max-age=%u\r\n", (unsigned)max_age); +#else /* NO_CACHING */ + return send_no_cache_header(conn); +#endif /* !NO_CACHING */ +} + + +static void handle_file_based_request(struct mg_connection *conn, + const char *path, + struct file *filep); + +static int +mg_stat(struct mg_connection *conn, const char *path, struct file *filep); + + +const char * +mg_get_response_code_text(struct mg_connection *conn, int response_code) +{ + /* See IANA HTTP status code assignment: + * http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml + */ + + switch (response_code) { + /* RFC2616 Section 10.1 - Informational 1xx */ + case 100: + return "Continue"; /* RFC2616 Section 10.1.1 */ + case 101: + return "Switching Protocols"; /* RFC2616 Section 10.1.2 */ + case 102: + return "Processing"; /* RFC2518 Section 10.1 */ + + /* RFC2616 Section 10.2 - Successful 2xx */ + case 200: + return "OK"; /* RFC2616 Section 10.2.1 */ + case 201: + return "Created"; /* RFC2616 Section 10.2.2 */ + case 202: + return "Accepted"; /* RFC2616 Section 10.2.3 */ + case 203: + return "Non-Authoritative Information"; /* RFC2616 Section 10.2.4 */ + case 204: + return "No Content"; /* RFC2616 Section 10.2.5 */ + case 205: + return "Reset Content"; /* RFC2616 Section 10.2.6 */ + case 206: + return "Partial Content"; /* RFC2616 Section 10.2.7 */ + case 207: + return "Multi-Status"; /* RFC2518 Section 10.2, RFC4918 Section 11.1 */ + case 208: + return "Already Reported"; /* RFC5842 Section 7.1 */ + + case 226: + return "IM used"; /* RFC3229 Section 10.4.1 */ + + /* RFC2616 Section 10.3 - Redirection 3xx */ + case 300: + return "Multiple Choices"; /* RFC2616 Section 10.3.1 */ + case 301: + return "Moved Permanently"; /* RFC2616 Section 10.3.2 */ + case 302: + return "Found"; /* RFC2616 Section 10.3.3 */ + case 303: + return "See Other"; /* RFC2616 Section 10.3.4 */ + case 304: + return "Not Modified"; /* RFC2616 Section 10.3.5 */ + case 305: + return "Use Proxy"; /* RFC2616 Section 10.3.6 */ + case 307: + return "Temporary Redirect"; /* RFC2616 Section 10.3.8 */ + case 308: + return "Permanent Redirect"; /* RFC7238 Section 3 */ + + /* RFC2616 Section 10.4 - Client Error 4xx */ + case 400: + return "Bad Request"; /* RFC2616 Section 10.4.1 */ + case 401: + return "Unauthorized"; /* RFC2616 Section 10.4.2 */ + case 402: + return "Payment Required"; /* RFC2616 Section 10.4.3 */ + case 403: + return "Forbidden"; /* RFC2616 Section 10.4.4 */ + case 404: + return "Not Found"; /* RFC2616 Section 10.4.5 */ + case 405: + return "Method Not Allowed"; /* RFC2616 Section 10.4.6 */ + case 406: + return "Not Acceptable"; /* RFC2616 Section 10.4.7 */ + case 407: + return "Proxy Authentication Required"; /* RFC2616 Section 10.4.8 */ + case 408: + return "Request Time-out"; /* RFC2616 Section 10.4.9 */ + case 409: + return "Conflict"; /* RFC2616 Section 10.4.10 */ + case 410: + return "Gone"; /* RFC2616 Section 10.4.11 */ + case 411: + return "Length Required"; /* RFC2616 Section 10.4.12 */ + case 412: + return "Precondition Failed"; /* RFC2616 Section 10.4.13 */ + case 413: + return "Request Entity Too Large"; /* RFC2616 Section 10.4.14 */ + case 414: + return "Request-URI Too Large"; /* RFC2616 Section 10.4.15 */ + case 415: + return "Unsupported Media Type"; /* RFC2616 Section 10.4.16 */ + case 416: + return "Requested range not satisfiable"; /* RFC2616 Section 10.4.17 */ + case 417: + return "Expectation Failed"; /* RFC2616 Section 10.4.18 */ + + case 421: + return "Misdirected Request"; /* RFC7540 Section 9.1.2 */ + case 422: + return "Unproccessable entity"; /* RFC2518 Section 10.3, RFC4918 + * Section 11.2 */ + case 423: + return "Locked"; /* RFC2518 Section 10.4, RFC4918 Section 11.3 */ + case 424: + return "Failed Dependency"; /* RFC2518 Section 10.5, RFC4918 + * Section 11.4 */ + + case 426: + return "Upgrade Required"; /* RFC 2817 Section 4 */ + + case 428: + return "Precondition Required"; /* RFC 6585, Section 3 */ + case 429: + return "Too Many Requests"; /* RFC 6585, Section 4 */ + + case 431: + return "Request Header Fields Too Large"; /* RFC 6585, Section 5 */ + + case 451: + return "Unavailable For Legal Reasons"; /* draft-tbray-http-legally-restricted-status-05, + * Section 3 */ + + /* RFC2616 Section 10.5 - Server Error 5xx */ + case 500: + return "Internal Server Error"; /* RFC2616 Section 10.5.1 */ + case 501: + return "Not Implemented"; /* RFC2616 Section 10.5.2 */ + case 502: + return "Bad Gateway"; /* RFC2616 Section 10.5.3 */ + case 503: + return "Service Unavailable"; /* RFC2616 Section 10.5.4 */ + case 504: + return "Gateway Time-out"; /* RFC2616 Section 10.5.5 */ + case 505: + return "HTTP Version not supported"; /* RFC2616 Section 10.5.6 */ + case 506: + return "Variant Also Negotiates"; /* RFC 2295, Section 8.1 */ + case 507: + return "Insufficient Storage"; /* RFC2518 Section 10.6, RFC4918 + * Section 11.5 */ + case 508: + return "Loop Detected"; /* RFC5842 Section 7.1 */ + + case 510: + return "Not Extended"; /* RFC 2774, Section 7 */ + case 511: + return "Network Authentication Required"; /* RFC 6585, Section 6 */ + + /* Other status codes, not shown in the IANA HTTP status code assignment. + * E.g., "de facto" standards due to common use, ... */ + case 418: + return "I am a teapot"; /* RFC2324 Section 2.3.2 */ + case 419: + return "Authentication Timeout"; /* common use */ + case 420: + return "Enhance Your Calm"; /* common use */ + case 440: + return "Login Timeout"; /* common use */ + case 509: + return "Bandwidth Limit Exceeded"; /* common use */ + + default: + /* This error code is unknown. This should not happen. */ + if (conn) { + mg_cry(conn, "Unknown HTTP response code: %u", response_code); + } + + /* Return at least a category according to RFC 2616 Section 10. */ + if (response_code >= 100 && response_code < 200) { + /* Unknown informational status code */ + return "Information"; + } + if (response_code >= 200 && response_code < 300) { + /* Unknown success code */ + return "Success"; + } + if (response_code >= 300 && response_code < 400) { + /* Unknown redirection code */ + return "Redirection"; + } + if (response_code >= 400 && response_code < 500) { + /* Unknown request error code */ + return "Client Error"; + } + if (response_code >= 500 && response_code < 600) { + /* Unknown server error code */ + return "Server Error"; + } + + /* Response code not even within reasonable range */ + return ""; + } +} + + +static void send_http_error(struct mg_connection *, + int, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(3, 4); + +static void +send_http_error(struct mg_connection *conn, int status, const char *fmt, ...) +{ + char buf[MG_BUF_LEN]; + va_list ap; + int len, i, page_handler_found, scope, truncated; + char date[64]; + time_t curtime = time(NULL); + const char *error_handler = NULL; + struct file error_page_file = STRUCT_FILE_INITIALIZER; + const char *error_page_file_ext, *tstr; + + const char *status_text = mg_get_response_code_text(conn, status); + + if (conn == NULL) { + return; + } + + conn->status_code = status; + if (conn->in_error_handler || conn->ctx->callbacks.http_error == NULL + || conn->ctx->callbacks.http_error(conn, status)) { + if (!conn->in_error_handler) { + /* Send user defined error pages, if defined */ + error_handler = conn->ctx->config[ERROR_PAGES]; + error_page_file_ext = conn->ctx->config[INDEX_FILES]; + page_handler_found = 0; + if (error_handler != NULL) { + for (scope = 1; (scope <= 3) && !page_handler_found; scope++) { + switch (scope) { + case 1: /* Handler for specific error, e.g. 404 error */ + mg_snprintf(conn, + &truncated, + buf, + sizeof(buf) - 32, + "%serror%03u.", + error_handler, + status); + break; + case 2: /* Handler for error group, e.g., 5xx error handler + * for all server errors (500-599) */ + mg_snprintf(conn, + &truncated, + buf, + sizeof(buf) - 32, + "%serror%01uxx.", + error_handler, + status / 100); + break; + default: /* Handler for all errors */ + mg_snprintf(conn, + &truncated, + buf, + sizeof(buf) - 32, + "%serror.", + error_handler); + break; + } + + /* String truncation in buf may only occur if error_handler + * is too long. This string is from the config, not from a + * client. */ + (void)truncated; + + len = (int)strlen(buf); + + tstr = strchr(error_page_file_ext, '.'); + + while (tstr) { + for (i = 1; i < 32 && tstr[i] != 0 && tstr[i] != ','; + i++) + buf[len + i - 1] = tstr[i]; + buf[len + i - 1] = 0; + if (mg_stat(conn, buf, &error_page_file)) { + page_handler_found = 1; + break; + } + tstr = strchr(tstr + i, '.'); + } + } + } + + if (page_handler_found) { + conn->in_error_handler = 1; + handle_file_based_request(conn, buf, &error_page_file); + conn->in_error_handler = 0; + return; + } + } + + /* No custom error page. Send default error page. */ + gmt_time_string(date, sizeof(date), &curtime); + + conn->must_close = 1; + mg_printf(conn, "HTTP/1.1 %d %s\r\n", status, status_text); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Connection: close\r\n\r\n", + date); + + /* Errors 1xx, 204 and 304 MUST NOT send a body */ + if (status > 199 && status != 204 && status != 304) { + + mg_printf(conn, "Error %d: %s\n", status, status_text); + + if (fmt != NULL) { + va_start(ap, fmt); + mg_vsnprintf(conn, NULL, buf, sizeof(buf), fmt, ap); + va_end(ap); + mg_write(conn, buf, strlen(buf)); + DEBUG_TRACE("Error %i - [%s]", status, buf); + } + + } else { + /* No body allowed. Close the connection. */ + DEBUG_TRACE("Error %i", status); + } + } +} + +#if defined(_WIN32) && !defined(__SYMBIAN32__) +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static int +pthread_mutex_init(pthread_mutex_t *mutex, void *unused) +{ + (void)unused; + *mutex = CreateMutex(NULL, FALSE, NULL); + return *mutex == NULL ? -1 : 0; +} + + +static int +pthread_mutex_destroy(pthread_mutex_t *mutex) +{ + return CloseHandle(*mutex) == 0 ? -1 : 0; +} + + +static int +pthread_mutex_lock(pthread_mutex_t *mutex) +{ + return WaitForSingleObject(*mutex, INFINITE) == WAIT_OBJECT_0 ? 0 : -1; +} + + +#ifdef ENABLE_UNUSED_PTHREAD_FUNCTIONS +static int +pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + switch (WaitForSingleObject(*mutex, 0)) { + case WAIT_OBJECT_0: + return 0; + case WAIT_TIMEOUT: + return -2; /* EBUSY */ + } + return -1; +} +#endif + + +static int +pthread_mutex_unlock(pthread_mutex_t *mutex) +{ + return ReleaseMutex(*mutex) == 0 ? -1 : 0; +} + + +#ifndef WIN_PTHREADS_TIME_H +static int +clock_gettime(clockid_t clk_id, struct timespec *tp) +{ + FILETIME ft; + ULARGE_INTEGER li; + BOOL ok = FALSE; + double d; + static double perfcnt_per_sec = 0.0; + + if (tp) { + memset(tp, 0, sizeof(*tp)); + if (clk_id == CLOCK_REALTIME) { + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + li.QuadPart -= 116444736000000000; /* 1.1.1970 in filedate */ + tp->tv_sec = (time_t)(li.QuadPart / 10000000); + tp->tv_nsec = (long)(li.QuadPart % 10000000) * 100; + ok = TRUE; + } else if (clk_id == CLOCK_MONOTONIC) { + if (perfcnt_per_sec == 0.0) { + QueryPerformanceFrequency((LARGE_INTEGER *)&li); + perfcnt_per_sec = 1.0 / li.QuadPart; + } + if (perfcnt_per_sec != 0.0) { + QueryPerformanceCounter((LARGE_INTEGER *)&li); + d = li.QuadPart * perfcnt_per_sec; + tp->tv_sec = (time_t)d; + d -= tp->tv_sec; + tp->tv_nsec = (long)(d * 1.0E9); + ok = TRUE; + } + } + } + + return ok ? 0 : -1; +} +#endif + + +static int +pthread_cond_init(pthread_cond_t *cv, const void *unused) +{ + (void)unused; + InitializeCriticalSection(&cv->threadIdSec); + cv->waitingthreadcount = 0; + cv->waitingthreadhdls = + (pthread_t *)mg_calloc(MAX_WORKER_THREADS, sizeof(pthread_t)); + return (cv->waitingthreadhdls != NULL) ? 0 : -1; +} + + +static int +pthread_cond_timedwait(pthread_cond_t *cv, + pthread_mutex_t *mutex, + const struct timespec *abstime) +{ + struct mg_workerTLS *tls = + (struct mg_workerTLS *)pthread_getspecific(sTlsKey); + int ok; + struct timespec tsnow; + int64_t nsnow, nswaitabs, nswaitrel; + DWORD mswaitrel; + + EnterCriticalSection(&cv->threadIdSec); + assert(cv->waitingthreadcount < MAX_WORKER_THREADS); + cv->waitingthreadhdls[cv->waitingthreadcount] = + tls->pthread_cond_helper_mutex; + cv->waitingthreadcount++; + LeaveCriticalSection(&cv->threadIdSec); + + if (abstime) { + clock_gettime(CLOCK_REALTIME, &tsnow); + nsnow = (((int64_t)tsnow.tv_sec) * 1000000000) + tsnow.tv_nsec; + nswaitabs = + (((int64_t)abstime->tv_sec) * 1000000000) + abstime->tv_nsec; + nswaitrel = nswaitabs - nsnow; + if (nswaitrel < 0) { + nswaitrel = 0; + } + mswaitrel = (DWORD)(nswaitrel / 1000000); + } else { + mswaitrel = INFINITE; + } + + pthread_mutex_unlock(mutex); + ok = (WAIT_OBJECT_0 + == WaitForSingleObject(tls->pthread_cond_helper_mutex, mswaitrel)); + pthread_mutex_lock(mutex); + + return ok ? 0 : -1; +} + + +static int +pthread_cond_wait(pthread_cond_t *cv, pthread_mutex_t *mutex) +{ + return pthread_cond_timedwait(cv, mutex, NULL); +} + + +static int +pthread_cond_signal(pthread_cond_t *cv) +{ + int i; + HANDLE wkup = NULL; + BOOL ok = FALSE; + + EnterCriticalSection(&cv->threadIdSec); + if (cv->waitingthreadcount) { + wkup = cv->waitingthreadhdls[0]; + ok = SetEvent(wkup); + + for (i = 1; i < cv->waitingthreadcount; i++) { + cv->waitingthreadhdls[i - 1] = cv->waitingthreadhdls[i]; + } + cv->waitingthreadcount--; + + assert(ok); + } + LeaveCriticalSection(&cv->threadIdSec); + + return ok ? 0 : 1; +} + + +static int +pthread_cond_broadcast(pthread_cond_t *cv) +{ + EnterCriticalSection(&cv->threadIdSec); + while (cv->waitingthreadcount) { + pthread_cond_signal(cv); + } + LeaveCriticalSection(&cv->threadIdSec); + + return 0; +} + + +static int +pthread_cond_destroy(pthread_cond_t *cv) +{ + EnterCriticalSection(&cv->threadIdSec); + assert(cv->waitingthreadcount == 0); + mg_free(cv->waitingthreadhdls); + cv->waitingthreadhdls = 0; + LeaveCriticalSection(&cv->threadIdSec); + DeleteCriticalSection(&cv->threadIdSec); + + return 0; +} + + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + + +/* For Windows, change all slashes to backslashes in path names. */ +static void +change_slashes_to_backslashes(char *path) +{ + int i; + + for (i = 0; path[i] != '\0'; i++) { + if (path[i] == '/') { + path[i] = '\\'; + } + + /* remove double backslash (check i > 0 to preserve UNC paths, + * like \\server\file.txt) */ + if ((path[i] == '\\') && (i > 0)) { + while (path[i + 1] == '\\' || path[i + 1] == '/') { + (void)memmove(path + i + 1, path + i + 2, strlen(path + i + 1)); + } + } + } +} + + +static int +mg_wcscasecmp(const wchar_t *s1, const wchar_t *s2) +{ + int diff; + + do { + diff = tolower(*s1) - tolower(*s2); + s1++; + s2++; + } while (diff == 0 && s1[-1] != '\0'); + + return diff; +} + + +/* Encode 'path' which is assumed UTF-8 string, into UNICODE string. + * wbuf and wbuf_len is a target buffer and its length. */ +static void +path_to_unicode(const struct mg_connection *conn, + const char *path, + wchar_t *wbuf, + size_t wbuf_len) +{ + char buf[PATH_MAX], buf2[PATH_MAX]; + wchar_t wbuf2[MAX_PATH + 1]; + DWORD long_len, err; + int (*fcompare)(const wchar_t *, const wchar_t *) = mg_wcscasecmp; + + mg_strlcpy(buf, path, sizeof(buf)); + change_slashes_to_backslashes(buf); + + /* Convert to Unicode and back. If doubly-converted string does not + * match the original, something is fishy, reject. */ + memset(wbuf, 0, wbuf_len * sizeof(wchar_t)); + MultiByteToWideChar(CP_UTF8, 0, buf, -1, wbuf, (int)wbuf_len); + WideCharToMultiByte( + CP_UTF8, 0, wbuf, (int)wbuf_len, buf2, sizeof(buf2), NULL, NULL); + if (strcmp(buf, buf2) != 0) { + wbuf[0] = L'\0'; + } + + /* TODO: Add a configuration to switch between case sensitive and + * case insensitive URIs for Windows server. */ + /* + if (conn) { + if (conn->ctx->config[WINDOWS_CASE_SENSITIVE]) { + fcompare = wcscmp; + } + } + */ + (void)conn; /* conn is currently unused */ + + /* Only accept a full file path, not a Windows short (8.3) path. */ + memset(wbuf2, 0, ARRAY_SIZE(wbuf2) * sizeof(wchar_t)); + long_len = GetLongPathNameW(wbuf, wbuf2, ARRAY_SIZE(wbuf2) - 1); + if (long_len == 0) { + err = GetLastError(); + if (err == ERROR_FILE_NOT_FOUND) { + /* File does not exist. This is not always a problem here. */ + return; + } + } + if ((long_len >= ARRAY_SIZE(wbuf2)) || (fcompare(wbuf, wbuf2) != 0)) { + /* Short name is used. */ + wbuf[0] = L'\0'; + } +} + + +#if defined(_WIN32_WCE) +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static time_t +time(time_t *ptime) +{ + time_t t; + SYSTEMTIME st; + FILETIME ft; + + GetSystemTime(&st); + SystemTimeToFileTime(&st, &ft); + t = SYS2UNIX_TIME(ft.dwLowDateTime, ft.dwHighDateTime); + + if (ptime != NULL) { + *ptime = t; + } + + return t; +} + + +static struct tm * +localtime(const time_t *ptime, struct tm *ptm) +{ + int64_t t = ((int64_t)*ptime) * RATE_DIFF + EPOCH_DIFF; + FILETIME ft, lft; + SYSTEMTIME st; + TIME_ZONE_INFORMATION tzinfo; + + if (ptm == NULL) { + return NULL; + } + + *(int64_t *)&ft = t; + FileTimeToLocalFileTime(&ft, &lft); + FileTimeToSystemTime(&lft, &st); + ptm->tm_year = st.wYear - 1900; + ptm->tm_mon = st.wMonth - 1; + ptm->tm_wday = st.wDayOfWeek; + ptm->tm_mday = st.wDay; + ptm->tm_hour = st.wHour; + ptm->tm_min = st.wMinute; + ptm->tm_sec = st.wSecond; + ptm->tm_yday = 0; /* hope nobody uses this */ + ptm->tm_isdst = + GetTimeZoneInformation(&tzinfo) == TIME_ZONE_ID_DAYLIGHT ? 1 : 0; + + return ptm; +} + + +static struct tm * +gmtime(const time_t *ptime, struct tm *ptm) +{ + /* FIXME(lsm): fix this. */ + return localtime(ptime, ptm); +} + + +static size_t +strftime(char *dst, size_t dst_size, const char *fmt, const struct tm *tm) +{ + (void)mg_snprintf(NULL, dst, dst_size, "implement strftime() for WinCE"); + return 0; +} + + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + +#endif + + +/* Windows happily opens files with some garbage at the end of file name. + * For example, fopen("a.cgi ", "r") on Windows successfully opens + * "a.cgi", despite one would expect an error back. + * This function returns non-0 if path ends with some garbage. */ +static int +path_cannot_disclose_cgi(const char *path) +{ + static const char *allowed_last_characters = "_-"; + int last = path[strlen(path) - 1]; + return isalnum(last) || strchr(allowed_last_characters, last) != NULL; +} + + +static int +mg_stat(struct mg_connection *conn, const char *path, struct file *filep) +{ + wchar_t wbuf[PATH_MAX]; + WIN32_FILE_ATTRIBUTE_DATA info; + time_t creation_time; + + if (!filep) { + return 0; + } + memset(filep, 0, sizeof(*filep)); + + if (conn && is_file_in_memory(conn, path, filep)) { + /* filep->is_directory = 0; filep->gzipped = 0; .. already done by + * memset */ + filep->last_modified = time(NULL); + /* last_modified = now ... assumes the file may change during runtime, + * so every mg_fopen call may return different data */ + /* last_modified = conn->ctx.start_time; + * May be used it the data does not change during runtime. This allows + * browser caching. Since we do not know, we have to assume the file + * in memory may change. */ + return 1; + } + + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + if (GetFileAttributesExW(wbuf, GetFileExInfoStandard, &info) != 0) { + filep->size = MAKEUQUAD(info.nFileSizeLow, info.nFileSizeHigh); + filep->last_modified = + SYS2UNIX_TIME(info.ftLastWriteTime.dwLowDateTime, + info.ftLastWriteTime.dwHighDateTime); + + /* On Windows, the file creation time can be higher than the + * modification time, e.g. when a file is copied. + * Since the Last-Modified timestamp is used for caching + * it should be based on the most recent timestamp. */ + creation_time = SYS2UNIX_TIME(info.ftCreationTime.dwLowDateTime, + info.ftCreationTime.dwHighDateTime); + if (creation_time > filep->last_modified) { + filep->last_modified = creation_time; + } + + filep->is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; + /* If file name is fishy, reset the file structure and return + * error. + * Note it is important to reset, not just return the error, cause + * functions like is_file_opened() check the struct. */ + if (!filep->is_directory && !path_cannot_disclose_cgi(path)) { + memset(filep, 0, sizeof(*filep)); + return 0; + } + + return 1; + } + + return 0; +} + + +static int +mg_remove(const struct mg_connection *conn, const char *path) +{ + wchar_t wbuf[PATH_MAX]; + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + return DeleteFileW(wbuf) ? 0 : -1; +} + + +static int +mg_mkdir(const struct mg_connection *conn, const char *path, int mode) +{ + wchar_t wbuf[PATH_MAX]; + (void)mode; + path_to_unicode(conn, path, wbuf, ARRAY_SIZE(wbuf)); + return CreateDirectoryW(wbuf, NULL) ? 0 : -1; +} + + +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +/* Implementation of POSIX opendir/closedir/readdir for Windows. */ +static DIR * +mg_opendir(const struct mg_connection *conn, const char *name) +{ + DIR *dir = NULL; + wchar_t wpath[PATH_MAX]; + DWORD attrs; + + if (name == NULL) { + SetLastError(ERROR_BAD_ARGUMENTS); + } else if ((dir = (DIR *)mg_malloc(sizeof(*dir))) == NULL) { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + } else { + path_to_unicode(conn, name, wpath, ARRAY_SIZE(wpath)); + attrs = GetFileAttributesW(wpath); + if (attrs != 0xFFFFFFFF && ((attrs & FILE_ATTRIBUTE_DIRECTORY) + == FILE_ATTRIBUTE_DIRECTORY)) { + (void)wcscat(wpath, L"\\*"); + dir->handle = FindFirstFileW(wpath, &dir->info); + dir->result.d_name[0] = '\0'; + } else { + mg_free(dir); + dir = NULL; + } + } + + return dir; +} + + +static int +mg_closedir(DIR *dir) +{ + int result = 0; + + if (dir != NULL) { + if (dir->handle != INVALID_HANDLE_VALUE) + result = FindClose(dir->handle) ? 0 : -1; + + mg_free(dir); + } else { + result = -1; + SetLastError(ERROR_BAD_ARGUMENTS); + } + + return result; +} + + +static struct dirent * +mg_readdir(DIR *dir) +{ + struct dirent *result = 0; + + if (dir) { + if (dir->handle != INVALID_HANDLE_VALUE) { + result = &dir->result; + (void)WideCharToMultiByte(CP_UTF8, + 0, + dir->info.cFileName, + -1, + result->d_name, + sizeof(result->d_name), + NULL, + NULL); + + if (!FindNextFileW(dir->handle, &dir->info)) { + (void)FindClose(dir->handle); + dir->handle = INVALID_HANDLE_VALUE; + } + + } else { + SetLastError(ERROR_FILE_NOT_FOUND); + } + } else { + SetLastError(ERROR_BAD_ARGUMENTS); + } + + return result; +} + + +#ifndef HAVE_POLL +static int +poll(struct pollfd *pfd, unsigned int n, int milliseconds) +{ + struct timeval tv; + fd_set set; + unsigned int i; + int result; + SOCKET maxfd = 0; + + memset(&tv, 0, sizeof(tv)); + tv.tv_sec = milliseconds / 1000; + tv.tv_usec = (milliseconds % 1000) * 1000; + FD_ZERO(&set); + + for (i = 0; i < n; i++) { + FD_SET((SOCKET)pfd[i].fd, &set); + pfd[i].revents = 0; + + if (pfd[i].fd > maxfd) { + maxfd = pfd[i].fd; + } + } + + if ((result = select((int)maxfd + 1, &set, NULL, NULL, &tv)) > 0) { + for (i = 0; i < n; i++) { + if (FD_ISSET(pfd[i].fd, &set)) { + pfd[i].revents = POLLIN; + } + } + } + + return result; +} +#endif /* HAVE_POLL */ + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + + +static void +set_close_on_exec(SOCKET sock, struct mg_connection *conn /* may be null */) +{ + (void)conn; /* Unused. */ + (void)SetHandleInformation((HANDLE)(intptr_t)sock, HANDLE_FLAG_INHERIT, 0); +} + + +int +mg_start_thread(mg_thread_func_t f, void *p) +{ +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) + /* Compile-time option to control stack size, e.g. -DUSE_STACK_SIZE=16384 + */ + return ((_beginthread((void(__cdecl *)(void *))f, USE_STACK_SIZE, p) + == ((uintptr_t)(-1L))) + ? -1 + : 0); +#else + return ( + (_beginthread((void(__cdecl *)(void *))f, 0, p) == ((uintptr_t)(-1L))) + ? -1 + : 0); +#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */ +} + + +/* Start a thread storing the thread context. */ +static int +mg_start_thread_with_id(unsigned(__stdcall *f)(void *), + void *p, + pthread_t *threadidptr) +{ + uintptr_t uip; + HANDLE threadhandle; + int result = -1; + + uip = _beginthreadex(NULL, 0, (unsigned(__stdcall *)(void *))f, p, 0, NULL); + threadhandle = (HANDLE)uip; + if ((uip != (uintptr_t)(-1L)) && (threadidptr != NULL)) { + *threadidptr = threadhandle; + result = 0; + } + + return result; +} + + +/* Wait for a thread to finish. */ +static int +mg_join_thread(pthread_t threadid) +{ + int result; + DWORD dwevent; + + result = -1; + dwevent = WaitForSingleObject(threadid, INFINITE); + if (dwevent == WAIT_FAILED) { + DEBUG_TRACE("WaitForSingleObject() failed, error %d", ERRNO); + } else { + if (dwevent == WAIT_OBJECT_0) { + CloseHandle(threadid); + result = 0; + } + } + + return result; +} + +#if !defined(NO_SSL_DL) +/* Create substitutes for POSIX functions in Win32. */ + +#if defined(__MINGW32__) +/* Show no warning in case system functions are not used. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +#endif + + +static HANDLE +dlopen(const char *dll_name, int flags) +{ + wchar_t wbuf[PATH_MAX]; + (void)flags; + path_to_unicode(NULL, dll_name, wbuf, ARRAY_SIZE(wbuf)); + return LoadLibraryW(wbuf); +} + + +static int +dlclose(void *handle) +{ + int result; + + if (FreeLibrary((HMODULE)handle) != 0) { + result = 0; + } else { + result = -1; + } + + return result; +} + + +#if defined(__MINGW32__) +/* Enable unused function warning again */ +#pragma GCC diagnostic pop +#endif + +#endif + + +#if !defined(NO_CGI) +#define SIGKILL (0) + +static int +kill(pid_t pid, int sig_num) +{ + (void)TerminateProcess((HANDLE)pid, (UINT)sig_num); + (void)CloseHandle((HANDLE)pid); + return 0; +} + + +static void +trim_trailing_whitespaces(char *s) +{ + char *e = s + strlen(s) - 1; + while (e > s && isspace(*(unsigned char *)e)) { + *e-- = '\0'; + } +} + + +static pid_t +spawn_process(struct mg_connection *conn, + const char *prog, + char *envblk, + char *envp[], + int fdin[2], + int fdout[2], + int fderr[2], + const char *dir) +{ + HANDLE me; + char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX], + cmdline[PATH_MAX], buf[PATH_MAX]; + int truncated; + struct file file = STRUCT_FILE_INITIALIZER; + STARTUPINFOA si; + PROCESS_INFORMATION pi = {0}; + + (void)envp; + + memset(&si, 0, sizeof(si)); + si.cb = sizeof(si); + + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = SW_HIDE; + + me = GetCurrentProcess(); + DuplicateHandle(me, + (HANDLE)_get_osfhandle(fdin[0]), + me, + &si.hStdInput, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + DuplicateHandle(me, + (HANDLE)_get_osfhandle(fdout[1]), + me, + &si.hStdOutput, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + DuplicateHandle(me, + (HANDLE)_get_osfhandle(fderr[1]), + me, + &si.hStdError, + 0, + TRUE, + DUPLICATE_SAME_ACCESS); + + /* Mark handles that should not be inherited. See + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499%28v=vs.85%29.aspx + */ + SetHandleInformation((HANDLE)_get_osfhandle(fdin[1]), + HANDLE_FLAG_INHERIT, + 0); + SetHandleInformation((HANDLE)_get_osfhandle(fdout[0]), + HANDLE_FLAG_INHERIT, + 0); + SetHandleInformation((HANDLE)_get_osfhandle(fderr[0]), + HANDLE_FLAG_INHERIT, + 0); + + /* If CGI file is a script, try to read the interpreter line */ + interp = conn->ctx->config[CGI_INTERPRETER]; + if (interp == NULL) { + buf[0] = buf[1] = '\0'; + + /* Read the first line of the script into the buffer */ + mg_snprintf( + conn, &truncated, cmdline, sizeof(cmdline), "%s/%s", dir, prog); + + if (truncated) { + pi.hProcess = (pid_t)-1; + goto spawn_cleanup; + } + + if (mg_fopen(conn, cmdline, "r", &file)) { + p = (char *)file.membuf; + mg_fgets(buf, sizeof(buf), &file, &p); + mg_fclose(&file); + buf[sizeof(buf) - 1] = '\0'; + } + + if (buf[0] == '#' && buf[1] == '!') { + trim_trailing_whitespaces(buf + 2); + } else { + buf[2] = '\0'; + } + interp = buf + 2; + } + + if (interp[0] != '\0') { + GetFullPathNameA(interp, sizeof(full_interp), full_interp, NULL); + interp = full_interp; + } + GetFullPathNameA(dir, sizeof(full_dir), full_dir, NULL); + + if (interp[0] != '\0') { + mg_snprintf(conn, + &truncated, + cmdline, + sizeof(cmdline), + "\"%s\" \"%s\\%s\"", + interp, + full_dir, + prog); + } else { + mg_snprintf(conn, + &truncated, + cmdline, + sizeof(cmdline), + "\"%s\\%s\"", + full_dir, + prog); + } + + if (truncated) { + pi.hProcess = (pid_t)-1; + goto spawn_cleanup; + } + + DEBUG_TRACE("Running [%s]", cmdline); + if (CreateProcessA(NULL, + cmdline, + NULL, + NULL, + TRUE, + CREATE_NEW_PROCESS_GROUP, + envblk, + NULL, + &si, + &pi) == 0) { + mg_cry( + conn, "%s: CreateProcess(%s): %ld", __func__, cmdline, (long)ERRNO); + pi.hProcess = (pid_t)-1; + /* goto spawn_cleanup; */ + } + +spawn_cleanup: + (void)CloseHandle(si.hStdOutput); + (void)CloseHandle(si.hStdError); + (void)CloseHandle(si.hStdInput); + if (pi.hThread != NULL) { + (void)CloseHandle(pi.hThread); + } + + return (pid_t)pi.hProcess; +} +#endif /* !NO_CGI */ + + +static int +set_non_blocking_mode(SOCKET sock) +{ + unsigned long on = 1; + return ioctlsocket(sock, (long)FIONBIO, &on); +} + +#else + +static int +mg_stat(struct mg_connection *conn, const char *path, struct file *filep) +{ + struct stat st; + if (!filep) { + return 0; + } + memset(filep, 0, sizeof(*filep)); + + if (conn && is_file_in_memory(conn, path, filep)) { + return 1; + } + + if (0 == stat(path, &st)) { + filep->size = (uint64_t)(st.st_size); + filep->last_modified = st.st_mtime; + filep->is_directory = S_ISDIR(st.st_mode); + return 1; + } + + return 0; +} + + +static void +set_close_on_exec(SOCKET fd, struct mg_connection *conn /* may be null */) +{ + if (fcntl(fd, F_SETFD, FD_CLOEXEC) != 0) { + if (conn) { + mg_cry(conn, + "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", + __func__, + strerror(ERRNO)); + } + } +} + + +int +mg_start_thread(mg_thread_func_t func, void *param) +{ + pthread_t thread_id; + pthread_attr_t attr; + int result; + + (void)pthread_attr_init(&attr); + (void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) + /* Compile-time option to control stack size, + * e.g. -DUSE_STACK_SIZE=16384 */ + (void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE); +#endif /* defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) */ + + result = pthread_create(&thread_id, &attr, func, param); + pthread_attr_destroy(&attr); + + return result; +} + + +/* Start a thread storing the thread context. */ +static int +mg_start_thread_with_id(mg_thread_func_t func, + void *param, + pthread_t *threadidptr) +{ + pthread_t thread_id; + pthread_attr_t attr; + int result; + + (void)pthread_attr_init(&attr); + +#if defined(USE_STACK_SIZE) && (USE_STACK_SIZE > 1) + /* Compile-time option to control stack size, + * e.g. -DUSE_STACK_SIZE=16384 */ + (void)pthread_attr_setstacksize(&attr, USE_STACK_SIZE); +#endif /* defined(USE_STACK_SIZE) && USE_STACK_SIZE > 1 */ + + result = pthread_create(&thread_id, &attr, func, param); + pthread_attr_destroy(&attr); + if ((result == 0) && (threadidptr != NULL)) { + *threadidptr = thread_id; + } + return result; +} + + +/* Wait for a thread to finish. */ +static int +mg_join_thread(pthread_t threadid) +{ + int result; + + result = pthread_join(threadid, NULL); + return result; +} + + +#ifndef NO_CGI +static pid_t +spawn_process(struct mg_connection *conn, + const char *prog, + char *envblk, + char *envp[], + int fdin[2], + int fdout[2], + int fderr[2], + const char *dir) +{ + pid_t pid; + const char *interp; + + (void)envblk; + + if (conn == NULL) { + return 0; + } + + if ((pid = fork()) == -1) { + /* Parent */ + send_http_error(conn, + 500, + "Error: Creating CGI process\nfork(): %s", + strerror(ERRNO)); + } else if (pid == 0) { + /* Child */ + if (chdir(dir) != 0) { + mg_cry(conn, "%s: chdir(%s): %s", __func__, dir, strerror(ERRNO)); + } else if (dup2(fdin[0], 0) == -1) { + mg_cry(conn, + "%s: dup2(%d, 0): %s", + __func__, + fdin[0], + strerror(ERRNO)); + } else if (dup2(fdout[1], 1) == -1) { + mg_cry(conn, + "%s: dup2(%d, 1): %s", + __func__, + fdout[1], + strerror(ERRNO)); + } else if (dup2(fderr[1], 2) == -1) { + mg_cry(conn, + "%s: dup2(%d, 2): %s", + __func__, + fderr[1], + strerror(ERRNO)); + } else { + /* Keep stderr and stdout in two different pipes. + * Stdout will be sent back to the client, + * stderr should go into a server error log. */ + (void)close(fdin[0]); + (void)close(fdout[1]); + (void)close(fderr[1]); + + /* Close write end fdin and read end fdout and fderr */ + (void)close(fdin[1]); + (void)close(fdout[0]); + (void)close(fderr[0]); + + /* After exec, all signal handlers are restored to their default + * values, with one exception of SIGCHLD. According to + * POSIX.1-2001 and Linux's implementation, SIGCHLD's handler will + * leave unchanged after exec if it was set to be ignored. Restore + * it to default action. */ + signal(SIGCHLD, SIG_DFL); + + interp = conn->ctx->config[CGI_INTERPRETER]; + if (interp == NULL) { + (void)execle(prog, prog, NULL, envp); + mg_cry(conn, + "%s: execle(%s): %s", + __func__, + prog, + strerror(ERRNO)); + } else { + (void)execle(interp, interp, prog, NULL, envp); + mg_cry(conn, + "%s: execle(%s %s): %s", + __func__, + interp, + prog, + strerror(ERRNO)); + } + } + exit(EXIT_FAILURE); + } + + return pid; +} +#endif /* !NO_CGI */ + + +static int +set_non_blocking_mode(SOCKET sock) +{ + int flags; + + flags = fcntl(sock, F_GETFL, 0); + (void)fcntl(sock, F_SETFL, flags | O_NONBLOCK); + + return 0; +} +#endif /* _WIN32 */ +/* End of initial operating system specific define block. */ + + +/* Get a random number (independent of C rand function) */ +static uint64_t +get_random(void) +{ + static uint64_t lfsr = 0; /* Linear feedback shift register */ + static uint64_t lcg = 0; /* Linear congruential generator */ + struct timespec now; + + memset(&now, 0, sizeof(now)); + clock_gettime(CLOCK_MONOTONIC, &now); + + if (lfsr == 0) { + /* lfsr will be only 0 if has not been initialized, + * so this code is called only once. */ + lfsr = (((uint64_t)now.tv_sec) << 21) ^ ((uint64_t)now.tv_nsec) + ^ ((uint64_t)(ptrdiff_t)&now) ^ (((uint64_t)time(NULL)) << 33); + lcg = (((uint64_t)now.tv_sec) << 25) + (uint64_t)now.tv_nsec + + (uint64_t)(ptrdiff_t)&now; + } else { + /* Get the next step of both random number generators. */ + lfsr = (lfsr >> 1) + | ((((lfsr >> 0) ^ (lfsr >> 1) ^ (lfsr >> 3) ^ (lfsr >> 4)) & 1) + << 63); + lcg = lcg * 6364136223846793005 + 1442695040888963407; + } + + /* Combining two pseudo-random number generators and a high resolution part + * of the current server time will make it hard (impossible?) to guess the + * next number. */ + return (lfsr ^ lcg ^ (uint64_t)now.tv_nsec); +} + + +/* Write data to the IO channel - opened file descriptor, socket or SSL + * descriptor. Return number of bytes written. */ +static int +push(struct mg_context *ctx, + FILE *fp, + SOCKET sock, + SSL *ssl, + const char *buf, + int len, + double timeout) +{ + struct timespec start, now; + int n, err; + +#ifdef _WIN32 + typedef int len_t; +#else + typedef size_t len_t; +#endif + + if (timeout > 0) { + memset(&start, 0, sizeof(start)); + memset(&now, 0, sizeof(now)); + clock_gettime(CLOCK_MONOTONIC, &start); + } + + if (ctx == NULL) { + return -1; + } + +#ifdef NO_SSL + if (ssl) { + return -1; + } +#endif + + do { + +#ifndef NO_SSL + if (ssl != NULL) { + n = SSL_write(ssl, buf, len); + if (n <= 0) { + err = SSL_get_error(ssl, n); + if ((err == 5 /* SSL_ERROR_SYSCALL */) && (n == -1)) { + err = ERRNO; + } else { + DEBUG_TRACE("SSL_write() failed, error %d", err); + return -1; + } + } else { + err = 0; + } + } else +#endif + if (fp != NULL) { + n = (int)fwrite(buf, 1, (size_t)len, fp); + if (ferror(fp)) { + n = -1; + err = ERRNO; + } else { + err = 0; + } + } else { + n = (int)send(sock, buf, (len_t)len, MSG_NOSIGNAL); + err = (n < 0) ? ERRNO : 0; + } + + if (ctx->stop_flag) { + return -1; + } + + if ((n > 0) || (n == 0 && len == 0)) { + /* some data has been read, or no data was requested */ + return n; + } + if (n == 0) { + /* shutdown of the socket at client side */ + return -1; + } + if (n < 0) { + /* socket error - check errno */ + DEBUG_TRACE("send() failed, error %d", err); + + /* TODO: error handling depending on the error code. + * These codes are different between Windows and Linux. + */ + return -1; + } + + /* This code is not reached in the moment. + * ==> Fix the TODOs above first. */ + + if (timeout > 0) { + clock_gettime(CLOCK_MONOTONIC, &now); + } + + } while ((timeout <= 0) || (mg_difftimespec(&now, &start) <= timeout)); + + (void)err; /* Avoid unused warning if NO_SSL is set and DEBUG_TRACE is not + used */ + + return -1; +} + + +static int64_t +push_all(struct mg_context *ctx, + FILE *fp, + SOCKET sock, + SSL *ssl, + const char *buf, + int64_t len) +{ + double timeout = -1.0; + int64_t n, nwritten = 0; + + if (ctx == NULL) { + return -1; + } + + if (ctx->config[REQUEST_TIMEOUT]) { + timeout = atoi(ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } + + while (len > 0 && ctx->stop_flag == 0) { + n = push(ctx, fp, sock, ssl, buf + nwritten, (int)len, timeout); + if (n < 0) { + if (nwritten == 0) { + nwritten = n; /* Propagate the error */ + } + break; + } else if (n == 0) { + break; /* No more data to write */ + } else { + nwritten += n; + len -= n; + } + } + + return nwritten; +} + + +/* Read from IO channel - opened file descriptor, socket, or SSL descriptor. + * Return negative value on error, or number of bytes read on success. */ +static int +pull(FILE *fp, struct mg_connection *conn, char *buf, int len, double timeout) +{ + int nread, err; + struct timespec start, now; + +#ifdef _WIN32 + typedef int len_t; +#else + typedef size_t len_t; +#endif + + if (timeout > 0) { + memset(&start, 0, sizeof(start)); + memset(&now, 0, sizeof(now)); + clock_gettime(CLOCK_MONOTONIC, &start); + } + + do { + if (fp != NULL) { + /* Use read() instead of fread(), because if we're reading from the + * CGI pipe, fread() may block until IO buffer is filled up. We + * cannot afford to block and must pass all read bytes immediately + * to the client. */ + nread = (int)read(fileno(fp), buf, (size_t)len); + err = (nread < 0) ? ERRNO : 0; + +#ifndef NO_SSL + } else if (conn->ssl != NULL) { + nread = SSL_read(conn->ssl, buf, len); + if (nread <= 0) { + err = SSL_get_error(conn->ssl, nread); + if ((err == 5 /* SSL_ERROR_SYSCALL */) && (nread == -1)) { + err = ERRNO; + } else { + DEBUG_TRACE("SSL_read() failed, error %d", err); + return -1; + } + } else { + err = 0; + } +#endif + + } else { + nread = (int)recv(conn->client.sock, buf, (len_t)len, 0); + err = (nread < 0) ? ERRNO : 0; + } + + if (conn->ctx->stop_flag) { + return -1; + } + + if ((nread > 0) || (nread == 0 && len == 0)) { + /* some data has been read, or no data was requested */ + return nread; + } + if (nread == 0) { + /* shutdown of the socket at client side */ + return -1; + } + if (nread < 0) { +/* socket error - check errno */ +#ifdef _WIN32 + if (err == WSAEWOULDBLOCK) { + /* standard case if called from close_socket_gracefully */ + return -1; + } else if (err == WSAETIMEDOUT) { + /* timeout is handled by the while loop */ + } else { + DEBUG_TRACE("recv() failed, error %d", err); + return -1; + } +#else + /* TODO: POSIX returns either EAGAIN or EWOULDBLOCK in both cases, + * if the timeout is reached and if the socket was set to non- + * blocking in close_socket_gracefully, so we can not distinguish + * here. We have to wait for the timeout in both cases for now. + */ + if (err == EAGAIN || err == EWOULDBLOCK || err == EINTR) { + /* EAGAIN/EWOULDBLOCK: + * standard case if called from close_socket_gracefully + * => should return -1 */ + /* or timeout occured + * => the code must stay in the while loop */ + + /* EINTR can be generated on a socket with a timeout set even + * when SA_RESTART is effective for all relevant signals + * (see signal(7)). + * => stay in the while loop */ + } else { + DEBUG_TRACE("recv() failed, error %d", err); + return -1; + } +#endif + } + if (timeout > 0) { + clock_gettime(CLOCK_MONOTONIC, &now); + } + } while ((timeout <= 0) || (mg_difftimespec(&now, &start) <= timeout)); + + /* Timeout occured, but no data available. */ + return -1; +} + + +static int +pull_all(FILE *fp, struct mg_connection *conn, char *buf, int len) +{ + int n, nread = 0; + double timeout = -1.0; + + if (conn->ctx->config[REQUEST_TIMEOUT]) { + timeout = atoi(conn->ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } + + while (len > 0 && conn->ctx->stop_flag == 0) { + n = pull(fp, conn, buf + nread, len, timeout); + if (n < 0) { + if (nread == 0) { + nread = n; /* Propagate the error */ + } + break; + } else if (n == 0) { + break; /* No more data to read */ + } else { + conn->consumed_content += n; + nread += n; + len -= n; + } + } + + return nread; +} + + +static void +discard_unread_request_data(struct mg_connection *conn) +{ + char buf[MG_BUF_LEN]; + size_t to_read; + int nread; + + if (conn == NULL) { + return; + } + + to_read = sizeof(buf); + + if (conn->is_chunked) { + /* Chunked encoding: 1=chunk not read completely, 2=chunk read + * completely */ + while (conn->is_chunked == 1) { + nread = mg_read(conn, buf, to_read); + if (nread <= 0) { + break; + } + } + + } else { + /* Not chunked: content length is known */ + while (conn->consumed_content < conn->content_len) { + if (to_read + > (size_t)(conn->content_len - conn->consumed_content)) { + to_read = (size_t)(conn->content_len - conn->consumed_content); + } + + nread = mg_read(conn, buf, to_read); + if (nread <= 0) { + break; + } + } + } +} + + +static int +mg_read_inner(struct mg_connection *conn, void *buf, size_t len) +{ + int64_t n, buffered_len, nread; + int64_t len64 = + (int64_t)(len > INT_MAX ? INT_MAX : len); /* since the return value is + * int, we may not read more + * bytes */ + const char *body; + + if (conn == NULL) { + return 0; + } + + /* If Content-Length is not set for a PUT or POST request, read until + * socket is closed */ + if (conn->consumed_content == 0 && conn->content_len == -1) { + conn->content_len = INT64_MAX; + conn->must_close = 1; + } + + nread = 0; + if (conn->consumed_content < conn->content_len) { + /* Adjust number of bytes to read. */ + int64_t left_to_read = conn->content_len - conn->consumed_content; + if (left_to_read < len64) { + /* Do not read more than the total content length of the request. + */ + len64 = left_to_read; + } + + /* Return buffered data */ + buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len + - conn->consumed_content; + if (buffered_len > 0) { + if (len64 < buffered_len) { + buffered_len = len64; + } + body = conn->buf + conn->request_len + conn->consumed_content; + memcpy(buf, body, (size_t)buffered_len); + len64 -= buffered_len; + conn->consumed_content += buffered_len; + nread += buffered_len; + buf = (char *)buf + buffered_len; + } + + /* We have returned all buffered data. Read new data from the remote + * socket. + */ + if ((n = pull_all(NULL, conn, (char *)buf, (int)len64)) >= 0) { + nread += n; + } else { + nread = (nread > 0 ? nread : n); + } + } + return (int)nread; +} + + +static char +mg_getc(struct mg_connection *conn) +{ + char c; + if (conn == NULL) { + return 0; + } + conn->content_len++; + if (mg_read_inner(conn, &c, 1) <= 0) { + return (char)0; + } + return c; +} + + +int +mg_read(struct mg_connection *conn, void *buf, size_t len) +{ + if (len > INT_MAX) { + len = INT_MAX; + } + + if (conn == NULL) { + return 0; + } + + if (conn->is_chunked) { + size_t all_read = 0; + + while (len > 0) { + + if (conn->is_chunked == 2) { + /* No more data left to read */ + return 0; + } + + if (conn->chunk_remainder) { + /* copy from the remainder of the last received chunk */ + long read_ret; + size_t read_now = + ((conn->chunk_remainder > len) ? (len) + : (conn->chunk_remainder)); + + conn->content_len += (int)read_now; + read_ret = + mg_read_inner(conn, (char *)buf + all_read, read_now); + all_read += (size_t)read_ret; + + conn->chunk_remainder -= read_now; + len -= read_now; + + if (conn->chunk_remainder == 0) { + /* the rest of the data in the current chunk has been read + */ + if ((mg_getc(conn) != '\r') || (mg_getc(conn) != '\n')) { + /* Protocol violation */ + return -1; + } + } + + } else { + /* fetch a new chunk */ + int i = 0; + char lenbuf[64]; + char *end = 0; + unsigned long chunkSize = 0; + + for (i = 0; i < ((int)sizeof(lenbuf) - 1); i++) { + lenbuf[i] = mg_getc(conn); + if (i > 0 && lenbuf[i] == '\r' && lenbuf[i - 1] != '\r') { + continue; + } + if (i > 1 && lenbuf[i] == '\n' && lenbuf[i - 1] == '\r') { + lenbuf[i + 1] = 0; + chunkSize = strtoul(lenbuf, &end, 16); + if (chunkSize == 0) { + /* regular end of content */ + conn->is_chunked = 2; + } + break; + } + if (!isalnum(lenbuf[i])) { + /* illegal character for chunk length */ + return -1; + } + } + if ((end == NULL) || (*end != '\r')) { + /* chunksize not set correctly */ + return -1; + } + if (chunkSize == 0) { + break; + } + + conn->chunk_remainder = chunkSize; + } + } + + return (int)all_read; + } + return mg_read_inner(conn, buf, len); +} + + +int +mg_write(struct mg_connection *conn, const void *buf, size_t len) +{ + time_t now; + int64_t n, total, allowed; + + if (conn == NULL) { + return 0; + } + + if (conn->throttle > 0) { + if ((now = time(NULL)) != conn->last_throttle_time) { + conn->last_throttle_time = now; + conn->last_throttle_bytes = 0; + } + allowed = conn->throttle - conn->last_throttle_bytes; + if (allowed > (int64_t)len) { + allowed = (int64_t)len; + } + if ((total = push_all(conn->ctx, + NULL, + conn->client.sock, + conn->ssl, + (const char *)buf, + (int64_t)allowed)) == allowed) { + buf = (const char *)buf + total; + conn->last_throttle_bytes += total; + while (total < (int64_t)len && conn->ctx->stop_flag == 0) { + allowed = conn->throttle > (int64_t)len - total + ? (int64_t)len - total + : conn->throttle; + if ((n = push_all(conn->ctx, + NULL, + conn->client.sock, + conn->ssl, + (const char *)buf, + (int64_t)allowed)) != allowed) { + break; + } + sleep(1); + conn->last_throttle_bytes = allowed; + conn->last_throttle_time = time(NULL); + buf = (const char *)buf + n; + total += n; + } + } + } else { + total = push_all(conn->ctx, + NULL, + conn->client.sock, + conn->ssl, + (const char *)buf, + (int64_t)len); + } + return (int)total; +} + + +/* Alternative alloc_vprintf() for non-compliant C runtimes */ +static int +alloc_vprintf2(char **buf, const char *fmt, va_list ap) +{ + va_list ap_copy; + size_t size = MG_BUF_LEN / 4; + int len = -1; + + *buf = NULL; + while (len < 0) { + if (*buf) { + mg_free(*buf); + } + + size *= 4; + *buf = (char *)mg_malloc(size); + if (!*buf) { + break; + } + + va_copy(ap_copy, ap); + len = vsnprintf_impl(*buf, size - 1, fmt, ap_copy); + va_end(ap_copy); + (*buf)[size - 1] = 0; + } + + return len; +} + + +/* Print message to buffer. If buffer is large enough to hold the message, + * return buffer. If buffer is to small, allocate large enough buffer on heap, + * and return allocated buffer. */ +static int +alloc_vprintf(char **out_buf, + char *prealloc_buf, + size_t prealloc_size, + const char *fmt, + va_list ap) +{ + va_list ap_copy; + int len; + + /* Windows is not standard-compliant, and vsnprintf() returns -1 if + * buffer is too small. Also, older versions of msvcrt.dll do not have + * _vscprintf(). However, if size is 0, vsnprintf() behaves correctly. + * Therefore, we make two passes: on first pass, get required message + * length. + * On second pass, actually print the message. */ + va_copy(ap_copy, ap); + len = vsnprintf_impl(NULL, 0, fmt, ap_copy); + va_end(ap_copy); + + if (len < 0) { + /* C runtime is not standard compliant, vsnprintf() returned -1. + * Switch to alternative code path that uses incremental allocations. + */ + va_copy(ap_copy, ap); + len = alloc_vprintf2(out_buf, fmt, ap); + va_end(ap_copy); + + } else if ((size_t)(len) >= prealloc_size) { + /* The pre-allocated buffer not large enough. */ + /* Allocate a new buffer. */ + *out_buf = (char *)mg_malloc((size_t)(len) + 1); + if (!*out_buf) { + /* Allocation failed. Return -1 as "out of memory" error. */ + return -1; + } + /* Buffer allocation successful. Store the string there. */ + va_copy(ap_copy, ap); + IGNORE_UNUSED_RESULT( + vsnprintf_impl(*out_buf, (size_t)(len) + 1, fmt, ap_copy)); + va_end(ap_copy); + + } else { + /* The pre-allocated buffer is large enough. + * Use it to store the string and return the address. */ + va_copy(ap_copy, ap); + IGNORE_UNUSED_RESULT( + vsnprintf_impl(prealloc_buf, prealloc_size, fmt, ap_copy)); + va_end(ap_copy); + *out_buf = prealloc_buf; + } + + return len; +} + + +static int +mg_vprintf(struct mg_connection *conn, const char *fmt, va_list ap) +{ + char mem[MG_BUF_LEN]; + char *buf = NULL; + int len; + + if ((len = alloc_vprintf(&buf, mem, sizeof(mem), fmt, ap)) > 0) { + len = mg_write(conn, buf, (size_t)len); + } + if (buf != mem && buf != NULL) { + mg_free(buf); + } + + return len; +} + + +int +mg_printf(struct mg_connection *conn, const char *fmt, ...) +{ + va_list ap; + int result; + + va_start(ap, fmt); + result = mg_vprintf(conn, fmt, ap); + va_end(ap); + + return result; +} + + +int +mg_url_decode(const char *src, + int src_len, + char *dst, + int dst_len, + int is_form_url_encoded) +{ + int i, j, a, b; +#define HEXTOI(x) (isdigit(x) ? x - '0' : x - 'W') + + for (i = j = 0; i < src_len && j < dst_len - 1; i++, j++) { + if (i < src_len - 2 && src[i] == '%' + && isxdigit(*(const unsigned char *)(src + i + 1)) + && isxdigit(*(const unsigned char *)(src + i + 2))) { + a = tolower(*(const unsigned char *)(src + i + 1)); + b = tolower(*(const unsigned char *)(src + i + 2)); + dst[j] = (char)((HEXTOI(a) << 4) | HEXTOI(b)); + i += 2; + } else if (is_form_url_encoded && src[i] == '+') { + dst[j] = ' '; + } else { + dst[j] = src[i]; + } + } + + dst[j] = '\0'; /* Null-terminate the destination */ + + return i >= src_len ? j : -1; +} + + +int +mg_get_var(const char *data, + size_t data_len, + const char *name, + char *dst, + size_t dst_len) +{ + return mg_get_var2(data, data_len, name, dst, dst_len, 0); +} + + +int +mg_get_var2(const char *data, + size_t data_len, + const char *name, + char *dst, + size_t dst_len, + size_t occurrence) +{ + const char *p, *e, *s; + size_t name_len; + int len; + + if (dst == NULL || dst_len == 0) { + len = -2; + } else if (data == NULL || name == NULL || data_len == 0) { + len = -1; + dst[0] = '\0'; + } else { + name_len = strlen(name); + e = data + data_len; + len = -1; + dst[0] = '\0'; + + /* data is "var1=val1&var2=val2...". Find variable first */ + for (p = data; p + name_len < e; p++) { + if ((p == data || p[-1] == '&') && p[name_len] == '=' + && !mg_strncasecmp(name, p, name_len) && 0 == occurrence--) { + /* Point p to variable value */ + p += name_len + 1; + + /* Point s to the end of the value */ + s = (const char *)memchr(p, '&', (size_t)(e - p)); + if (s == NULL) { + s = e; + } + /* assert(s >= p); */ + if (s < p) { + return -3; + } + + /* Decode variable into destination buffer */ + len = mg_url_decode(p, (int)(s - p), dst, (int)dst_len, 1); + + /* Redirect error code from -1 to -2 (destination buffer too + * small). */ + if (len == -1) { + len = -2; + } + break; + } + } + } + + return len; +} + + +int +mg_get_cookie(const char *cookie_header, + const char *var_name, + char *dst, + size_t dst_size) +{ + const char *s, *p, *end; + int name_len, len = -1; + + if (dst == NULL || dst_size == 0) { + len = -2; + } else if (var_name == NULL || (s = cookie_header) == NULL) { + len = -1; + dst[0] = '\0'; + } else { + name_len = (int)strlen(var_name); + end = s + strlen(s); + dst[0] = '\0'; + + for (; (s = mg_strcasestr(s, var_name)) != NULL; s += name_len) { + if (s[name_len] == '=') { + s += name_len + 1; + if ((p = strchr(s, ' ')) == NULL) { + p = end; + } + if (p[-1] == ';') { + p--; + } + if (*s == '"' && p[-1] == '"' && p > s + 1) { + s++; + p--; + } + if ((size_t)(p - s) < dst_size) { + len = (int)(p - s); + mg_strlcpy(dst, s, (size_t)len + 1); + } else { + len = -3; + } + break; + } + } + } + return len; +} + + +#if defined(USE_WEBSOCKET) || defined(USE_LUA) +static void +base64_encode(const unsigned char *src, int src_len, char *dst) +{ + static const char *b64 = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + int i, j, a, b, c; + + for (i = j = 0; i < src_len; i += 3) { + a = src[i]; + b = i + 1 >= src_len ? 0 : src[i + 1]; + c = i + 2 >= src_len ? 0 : src[i + 2]; + + dst[j++] = b64[a >> 2]; + dst[j++] = b64[((a & 3) << 4) | (b >> 4)]; + if (i + 1 < src_len) { + dst[j++] = b64[(b & 15) << 2 | (c >> 6)]; + } + if (i + 2 < src_len) { + dst[j++] = b64[c & 63]; + } + } + while (j % 4 != 0) { + dst[j++] = '='; + } + dst[j++] = '\0'; +} +#endif + + +#if defined(USE_LUA) +static unsigned char +b64reverse(char letter) +{ + if (letter >= 'A' && letter <= 'Z') { + return letter - 'A'; + } + if (letter >= 'a' && letter <= 'z') { + return letter - 'a' + 26; + } + if (letter >= '0' && letter <= '9') { + return letter - '0' + 52; + } + if (letter == '+') { + return 62; + } + if (letter == '/') { + return 63; + } + if (letter == '=') { + return 255; /* normal end */ + } + return 254; /* error */ +} + + +static int +base64_decode(const unsigned char *src, int src_len, char *dst, size_t *dst_len) +{ + int i; + unsigned char a, b, c, d; + + *dst_len = 0; + + for (i = 0; i < src_len; i += 4) { + a = b64reverse(src[i]); + if (a >= 254) { + return i; + } + + b = b64reverse(i + 1 >= src_len ? 0 : src[i + 1]); + if (b >= 254) { + return i + 1; + } + + c = b64reverse(i + 2 >= src_len ? 0 : src[i + 2]); + if (c == 254) { + return i + 2; + } + + d = b64reverse(i + 3 >= src_len ? 0 : src[i + 3]); + if (d == 254) { + return i + 3; + } + + dst[(*dst_len)++] = (a << 2) + (b >> 4); + if (c != 255) { + dst[(*dst_len)++] = (b << 4) + (c >> 2); + if (d != 255) { + dst[(*dst_len)++] = (c << 6) + d; + } + } + } + return -1; +} +#endif + + +static int +is_put_or_delete_method(const struct mg_connection *conn) +{ + if (conn) { + const char *s = conn->request_info.request_method; + return s != NULL && (!strcmp(s, "PUT") || !strcmp(s, "DELETE") + || !strcmp(s, "MKCOL") || !strcmp(s, "PATCH")); + } + return 0; +} + + +static void +interpret_uri(struct mg_connection *conn, /* in: request (must be valid) */ + char *filename, /* out: filename */ + size_t filename_buf_len, /* in: size of filename buffer */ + struct file *filep, /* out: file structure */ + int *is_found, /* out: file is found (directly) */ + int *is_script_resource, /* out: handled by a script? */ + int *is_websocket_request, /* out: websocket connetion? */ + int *is_put_or_delete_request /* out: put/delete a file? */ + ) +{ +/* TODO (high): Restructure this function */ + +#if !defined(NO_FILES) + const char *uri = conn->request_info.local_uri; + const char *root = conn->ctx->config[DOCUMENT_ROOT]; + const char *rewrite; + struct vec a, b; + int match_len; + char gz_path[PATH_MAX]; + char const *accept_encoding; + int truncated; +#if !defined(NO_CGI) || defined(USE_LUA) + char *p; +#endif +#else + (void)filename_buf_len; /* unused if NO_FILES is defined */ +#endif + + memset(filep, 0, sizeof(*filep)); + *filename = 0; + *is_found = 0; + *is_script_resource = 0; + *is_put_or_delete_request = is_put_or_delete_method(conn); + +#if defined(USE_WEBSOCKET) + *is_websocket_request = is_websocket_protocol(conn); +#if !defined(NO_FILES) + if (*is_websocket_request && conn->ctx->config[WEBSOCKET_ROOT]) { + root = conn->ctx->config[WEBSOCKET_ROOT]; + } +#endif /* !NO_FILES */ +#else /* USE_WEBSOCKET */ + *is_websocket_request = 0; +#endif /* USE_WEBSOCKET */ + +#if !defined(NO_FILES) + /* Note that root == NULL is a regular use case here. This occurs, + * if all requests are handled by callbacks, so the WEBSOCKET_ROOT + * config is not required. */ + if (root == NULL) { + /* all file related outputs have already been set to 0, just return + */ + return; + } + + /* Using buf_len - 1 because memmove() for PATH_INFO may shift part + * of the path one byte on the right. + * If document_root is NULL, leave the file empty. */ + mg_snprintf( + conn, &truncated, filename, filename_buf_len - 1, "%s%s", root, uri); + + if (truncated) { + goto interpret_cleanup; + } + + rewrite = conn->ctx->config[REWRITE]; + while ((rewrite = next_option(rewrite, &a, &b)) != NULL) { + if ((match_len = match_prefix(a.ptr, a.len, uri)) > 0) { + mg_snprintf(conn, + &truncated, + filename, + filename_buf_len - 1, + "%.*s%s", + (int)b.len, + b.ptr, + uri + match_len); + break; + } + } + + if (truncated) { + goto interpret_cleanup; + } + + /* Local file path and name, corresponding to requested URI + * is now stored in "filename" variable. */ + if (mg_stat(conn, filename, filep)) { +#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) + /* File exists. Check if it is a script type. */ + if (0 +#if !defined(NO_CGI) + || match_prefix(conn->ctx->config[CGI_EXTENSIONS], + strlen(conn->ctx->config[CGI_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_LUA) + || match_prefix(conn->ctx->config[LUA_SCRIPT_EXTENSIONS], + strlen(conn->ctx->config[LUA_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_DUKTAPE) + || match_prefix(conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS], + strlen( + conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif + ) { + /* The request addresses a CGI script or a Lua script. The URI + * corresponds to the script itself (like /path/script.cgi), + * and there is no additional resource path + * (like /path/script.cgi/something). + * Requests that modify (replace or delete) a resource, like + * PUT and DELETE requests, should replace/delete the script + * file. + * Requests that read or write from/to a resource, like GET and + * POST requests, should call the script and return the + * generated response. */ + *is_script_resource = !*is_put_or_delete_request; + } +#endif /* !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) */ + *is_found = 1; + return; + } + + /* If we can't find the actual file, look for the file + * with the same name but a .gz extension. If we find it, + * use that and set the gzipped flag in the file struct + * to indicate that the response need to have the content- + * encoding: gzip header. + * We can only do this if the browser declares support. */ + if ((accept_encoding = mg_get_header(conn, "Accept-Encoding")) != NULL) { + if (strstr(accept_encoding, "gzip") != NULL) { + mg_snprintf( + conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", filename); + + if (truncated) { + goto interpret_cleanup; + } + + if (mg_stat(conn, gz_path, filep)) { + if (filep) { + filep->gzipped = 1; + *is_found = 1; + } + /* Currently gz files can not be scripts. */ + return; + } + } + } + +#if !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) + /* Support PATH_INFO for CGI scripts. */ + for (p = filename + strlen(filename); p > filename + 1; p--) { + if (*p == '/') { + *p = '\0'; + if ((0 +#if !defined(NO_CGI) + || match_prefix(conn->ctx->config[CGI_EXTENSIONS], + strlen(conn->ctx->config[CGI_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_LUA) + || match_prefix(conn->ctx->config[LUA_SCRIPT_EXTENSIONS], + strlen( + conn->ctx->config[LUA_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif +#if defined(USE_DUKTAPE) + || match_prefix( + conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS], + strlen(conn->ctx->config[DUKTAPE_SCRIPT_EXTENSIONS]), + filename) > 0 +#endif + ) && mg_stat(conn, filename, filep)) { + /* Shift PATH_INFO block one character right, e.g. + * "/x.cgi/foo/bar\x00" => "/x.cgi\x00/foo/bar\x00" + * conn->path_info is pointing to the local variable "path" + * declared in handle_request(), so PATH_INFO is not valid + * after handle_request returns. */ + conn->path_info = p + 1; + memmove(p + 2, p + 1, strlen(p + 1) + 1); /* +1 is for + * trailing \0 */ + p[1] = '/'; + *is_script_resource = 1; + break; + } else { + *p = '/'; + } + } + } +#endif /* !defined(NO_CGI) || defined(USE_LUA) || defined(USE_DUKTAPE) */ +#endif /* !defined(NO_FILES) */ + return; + +#if !defined(NO_FILES) +/* Reset all outputs */ +interpret_cleanup: + memset(filep, 0, sizeof(*filep)); + *filename = 0; + *is_found = 0; + *is_script_resource = 0; + *is_websocket_request = 0; + *is_put_or_delete_request = 0; +#endif /* !defined(NO_FILES) */ +} + + +/* Check whether full request is buffered. Return: + * -1 if request is malformed + * 0 if request is not yet fully buffered + * >0 actual request length, including last \r\n\r\n */ +static int +get_request_len(const char *buf, int buflen) +{ + const char *s, *e; + int len = 0; + + for (s = buf, e = s + buflen - 1; len <= 0 && s < e; s++) + /* Control characters are not allowed but >=128 is. */ + if (!isprint(*(const unsigned char *)s) && *s != '\r' && *s != '\n' + && *(const unsigned char *)s < 128) { + len = -1; + break; /* [i_a] abort scan as soon as one malformed character is + * found; */ + /* don't let subsequent \r\n\r\n win us over anyhow */ + } else if (s[0] == '\n' && s[1] == '\n') { + len = (int)(s - buf) + 2; + } else if (s[0] == '\n' && &s[1] < e && s[1] == '\r' && s[2] == '\n') { + len = (int)(s - buf) + 3; + } + + return len; +} + + +#if !defined(NO_CACHING) +/* Convert month to the month number. Return -1 on error, or month number */ +static int +get_month_index(const char *s) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(month_names); i++) { + if (!strcmp(s, month_names[i])) { + return (int)i; + } + } + + return -1; +} + + +/* Parse UTC date-time string, and return the corresponding time_t value. */ +static time_t +parse_date_string(const char *datetime) +{ + char month_str[32] = {0}; + int second, minute, hour, day, month, year; + time_t result = (time_t)0; + struct tm tm; + + if ((sscanf(datetime, + "%d/%3s/%d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6) || (sscanf(datetime, + "%d %3s %d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6) + || (sscanf(datetime, + "%*3s, %d %3s %d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6) || (sscanf(datetime, + "%d-%3s-%d %d:%d:%d", + &day, + month_str, + &year, + &hour, + &minute, + &second) == 6)) { + month = get_month_index(month_str); + if ((month >= 0) && (year >= 1970)) { + memset(&tm, 0, sizeof(tm)); + tm.tm_year = year - 1900; + tm.tm_mon = month; + tm.tm_mday = day; + tm.tm_hour = hour; + tm.tm_min = minute; + tm.tm_sec = second; + result = timegm(&tm); + } + } + + return result; +} +#endif /* !NO_CACHING */ + + +/* Protect against directory disclosure attack by removing '..', + * excessive '/' and '\' characters */ +static void +remove_double_dots_and_double_slashes(char *s) +{ + char *p = s; + + while (*s != '\0') { + *p++ = *s++; + if (s[-1] == '/' || s[-1] == '\\') { + /* Skip all following slashes, backslashes and double-dots */ + while (s[0] != '\0') { + if (s[0] == '/' || s[0] == '\\') { + s++; + } else if (s[0] == '.' && s[1] == '.') { + s += 2; + } else { + break; + } + } + } + } + *p = '\0'; +} + + +static const struct { + const char *extension; + size_t ext_len; + const char *mime_type; +} builtin_mime_types[] = { + /* IANA registered MIME types (http://www.iana.org/assignments/media-types) + * application types */ + {".doc", 4, "application/msword"}, + {".eps", 4, "application/postscript"}, + {".exe", 4, "application/octet-stream"}, + {".js", 3, "application/javascript"}, + {".json", 5, "application/json"}, + {".pdf", 4, "application/pdf"}, + {".ps", 3, "application/postscript"}, + {".rtf", 4, "application/rtf"}, + {".xhtml", 6, "application/xhtml+xml"}, + {".xsl", 4, "application/xml"}, + {".xslt", 5, "application/xml"}, + + /* fonts */ + {".ttf", 4, "application/font-sfnt"}, + {".cff", 4, "application/font-sfnt"}, + {".otf", 4, "application/font-sfnt"}, + {".aat", 4, "application/font-sfnt"}, + {".sil", 4, "application/font-sfnt"}, + {".pfr", 4, "application/font-tdpfr"}, + {".woff", 5, "application/font-woff"}, + + /* audio */ + {".mp3", 4, "audio/mpeg"}, + {".oga", 4, "audio/ogg"}, + {".ogg", 4, "audio/ogg"}, + + /* image */ + {".gif", 4, "image/gif"}, + {".ief", 4, "image/ief"}, + {".jpeg", 5, "image/jpeg"}, + {".jpg", 4, "image/jpeg"}, + {".jpm", 4, "image/jpm"}, + {".jpx", 4, "image/jpx"}, + {".png", 4, "image/png"}, + {".svg", 4, "image/svg+xml"}, + {".tif", 4, "image/tiff"}, + {".tiff", 5, "image/tiff"}, + + /* model */ + {".wrl", 4, "model/vrml"}, + + /* text */ + {".css", 4, "text/css"}, + {".csv", 4, "text/csv"}, + {".htm", 4, "text/html"}, + {".html", 5, "text/html"}, + {".sgm", 4, "text/sgml"}, + {".shtm", 5, "text/html"}, + {".shtml", 6, "text/html"}, + {".txt", 4, "text/plain"}, + {".xml", 4, "text/xml"}, + + /* video */ + {".mov", 4, "video/quicktime"}, + {".mp4", 4, "video/mp4"}, + {".mpeg", 5, "video/mpeg"}, + {".mpg", 4, "video/mpeg"}, + {".ogv", 4, "video/ogg"}, + {".qt", 3, "video/quicktime"}, + + /* not registered types + * (http://reference.sitepoint.com/html/mime-types-full, + * http://www.hansenb.pdx.edu/DMKB/dict/tutorials/mime_typ.php, ..) */ + {".arj", 4, "application/x-arj-compressed"}, + {".gz", 3, "application/x-gunzip"}, + {".rar", 4, "application/x-arj-compressed"}, + {".swf", 4, "application/x-shockwave-flash"}, + {".tar", 4, "application/x-tar"}, + {".tgz", 4, "application/x-tar-gz"}, + {".torrent", 8, "application/x-bittorrent"}, + {".ppt", 4, "application/x-mspowerpoint"}, + {".xls", 4, "application/x-msexcel"}, + {".zip", 4, "application/x-zip-compressed"}, + {".aac", + 4, + "audio/aac"}, /* http://en.wikipedia.org/wiki/Advanced_Audio_Coding */ + {".aif", 4, "audio/x-aif"}, + {".m3u", 4, "audio/x-mpegurl"}, + {".mid", 4, "audio/x-midi"}, + {".ra", 3, "audio/x-pn-realaudio"}, + {".ram", 4, "audio/x-pn-realaudio"}, + {".wav", 4, "audio/x-wav"}, + {".bmp", 4, "image/bmp"}, + {".ico", 4, "image/x-icon"}, + {".pct", 4, "image/x-pct"}, + {".pict", 5, "image/pict"}, + {".rgb", 4, "image/x-rgb"}, + {".webm", 5, "video/webm"}, /* http://en.wikipedia.org/wiki/WebM */ + {".asf", 4, "video/x-ms-asf"}, + {".avi", 4, "video/x-msvideo"}, + {".m4v", 4, "video/x-m4v"}, + {NULL, 0, NULL}}; + + +const char * +mg_get_builtin_mime_type(const char *path) +{ + const char *ext; + size_t i, path_len; + + path_len = strlen(path); + + for (i = 0; builtin_mime_types[i].extension != NULL; i++) { + ext = path + (path_len - builtin_mime_types[i].ext_len); + if (path_len > builtin_mime_types[i].ext_len + && mg_strcasecmp(ext, builtin_mime_types[i].extension) == 0) { + return builtin_mime_types[i].mime_type; + } + } + + return "text/plain"; +} + + +/* Look at the "path" extension and figure what mime type it has. + * Store mime type in the vector. */ +static void +get_mime_type(struct mg_context *ctx, const char *path, struct vec *vec) +{ + struct vec ext_vec, mime_vec; + const char *list, *ext; + size_t path_len; + + path_len = strlen(path); + + if (ctx == NULL || vec == NULL) { + return; + } + + /* Scan user-defined mime types first, in case user wants to + * override default mime types. */ + list = ctx->config[EXTRA_MIME_TYPES]; + while ((list = next_option(list, &ext_vec, &mime_vec)) != NULL) { + /* ext now points to the path suffix */ + ext = path + path_len - ext_vec.len; + if (mg_strncasecmp(ext, ext_vec.ptr, ext_vec.len) == 0) { + *vec = mime_vec; + return; + } + } + + vec->ptr = mg_get_builtin_mime_type(path); + vec->len = strlen(vec->ptr); +} + + +/* Stringify binary data. Output buffer must be twice as big as input, + * because each byte takes 2 bytes in string representation */ +static void +bin2str(char *to, const unsigned char *p, size_t len) +{ + static const char *hex = "0123456789abcdef"; + + for (; len--; p++) { + *to++ = hex[p[0] >> 4]; + *to++ = hex[p[0] & 0x0f]; + } + *to = '\0'; +} + + +/* Return stringified MD5 hash for list of strings. Buffer must be 33 bytes. */ +char * +mg_md5(char buf[33], ...) +{ + md5_byte_t hash[16]; + const char *p; + va_list ap; + md5_state_t ctx; + + md5_init(&ctx); + + va_start(ap, buf); + while ((p = va_arg(ap, const char *)) != NULL) { + md5_append(&ctx, (const md5_byte_t *)p, strlen(p)); + } + va_end(ap); + + md5_finish(&ctx, hash); + bin2str(buf, hash, sizeof(hash)); + return buf; +} + + +/* Check the user's password, return 1 if OK */ +static int +check_password(const char *method, + const char *ha1, + const char *uri, + const char *nonce, + const char *nc, + const char *cnonce, + const char *qop, + const char *response) +{ + char ha2[32 + 1], expected_response[32 + 1]; + + /* Some of the parameters may be NULL */ + if (method == NULL || nonce == NULL || nc == NULL || cnonce == NULL + || qop == NULL + || response == NULL) { + return 0; + } + + /* NOTE(lsm): due to a bug in MSIE, we do not compare the URI */ + if (strlen(response) != 32) { + return 0; + } + + mg_md5(ha2, method, ":", uri, NULL); + mg_md5(expected_response, + ha1, + ":", + nonce, + ":", + nc, + ":", + cnonce, + ":", + qop, + ":", + ha2, + NULL); + + return mg_strcasecmp(response, expected_response) == 0; +} + + +/* Use the global passwords file, if specified by auth_gpass option, + * or search for .htpasswd in the requested directory. */ +static void +open_auth_file(struct mg_connection *conn, const char *path, struct file *filep) +{ + if (conn != NULL && conn->ctx != NULL) { + char name[PATH_MAX]; + const char *p, *e, *gpass = conn->ctx->config[GLOBAL_PASSWORDS_FILE]; + struct file file = STRUCT_FILE_INITIALIZER; + int truncated; + + if (gpass != NULL) { + /* Use global passwords file */ + if (!mg_fopen(conn, gpass, "r", filep)) { +#ifdef DEBUG + mg_cry(conn, "fopen(%s): %s", gpass, strerror(ERRNO)); +#endif + } + /* Important: using local struct file to test path for is_directory + * flag. If filep is used, mg_stat() makes it appear as if auth file + * was opened. */ + } else if (mg_stat(conn, path, &file) && file.is_directory) { + mg_snprintf(conn, + &truncated, + name, + sizeof(name), + "%s/%s", + path, + PASSWORDS_FILE_NAME); + + if (truncated || !mg_fopen(conn, name, "r", filep)) { +#ifdef DEBUG + mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO)); +#endif + } + } else { + /* Try to find .htpasswd in requested directory. */ + for (p = path, e = p + strlen(p) - 1; e > p; e--) { + if (e[0] == '/') { + break; + } + } + mg_snprintf(conn, + &truncated, + name, + sizeof(name), + "%.*s/%s", + (int)(e - p), + p, + PASSWORDS_FILE_NAME); + + if (truncated || !mg_fopen(conn, name, "r", filep)) { +#ifdef DEBUG + mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO)); +#endif + } + } + } +} + + +/* Parsed Authorization header */ +struct ah { + char *user, *uri, *cnonce, *response, *qop, *nc, *nonce; +}; + + +/* Return 1 on success. Always initializes the ah structure. */ +static int +parse_auth_header(struct mg_connection *conn, + char *buf, + size_t buf_size, + struct ah *ah) +{ + char *name, *value, *s; + const char *auth_header; + uint64_t nonce; + + if (!ah || !conn) { + return 0; + } + + (void)memset(ah, 0, sizeof(*ah)); + if ((auth_header = mg_get_header(conn, "Authorization")) == NULL + || mg_strncasecmp(auth_header, "Digest ", 7) != 0) { + return 0; + } + + /* Make modifiable copy of the auth header */ + (void)mg_strlcpy(buf, auth_header + 7, buf_size); + s = buf; + + /* Parse authorization header */ + for (;;) { + /* Gobble initial spaces */ + while (isspace(*(unsigned char *)s)) { + s++; + } + name = skip_quoted(&s, "=", " ", 0); + /* Value is either quote-delimited, or ends at first comma or space. */ + if (s[0] == '\"') { + s++; + value = skip_quoted(&s, "\"", " ", '\\'); + if (s[0] == ',') { + s++; + } + } else { + value = skip_quoted(&s, ", ", " ", 0); /* IE uses commas, FF uses + * spaces */ + } + if (*name == '\0') { + break; + } + + if (!strcmp(name, "username")) { + ah->user = value; + } else if (!strcmp(name, "cnonce")) { + ah->cnonce = value; + } else if (!strcmp(name, "response")) { + ah->response = value; + } else if (!strcmp(name, "uri")) { + ah->uri = value; + } else if (!strcmp(name, "qop")) { + ah->qop = value; + } else if (!strcmp(name, "nc")) { + ah->nc = value; + } else if (!strcmp(name, "nonce")) { + ah->nonce = value; + } + } + +#ifndef NO_NONCE_CHECK + /* Read the nonce from the response. */ + if (ah->nonce == NULL) { + return 0; + } + s = NULL; + nonce = strtoull(ah->nonce, &s, 10); + if ((s == NULL) || (*s != 0)) { + return 0; + } + + /* Convert the nonce from the client to a number. */ + nonce ^= conn->ctx->auth_nonce_mask; + + /* The converted number corresponds to the time the nounce has been + * created. This should not be earlier than the server start. */ + /* Server side nonce check is valuable in all situations but one: + * if the server restarts frequently, but the client should not see + * that, so the server should accept nonces from previous starts. */ + /* However, the reasonable default is to not accept a nonce from a + * previous start, so if anyone changed the access rights between + * two restarts, a new login is required. */ + if (nonce < (uint64_t)conn->ctx->start_time) { + /* nonce is from a previous start of the server and no longer valid + * (replay attack?) */ + return 0; + } + /* Check if the nonce is too high, so it has not (yet) been used by the + * server. */ + if (nonce >= ((uint64_t)conn->ctx->start_time + conn->ctx->nonce_count)) { + return 0; + } +#endif + + /* CGI needs it as REMOTE_USER */ + if (ah->user != NULL) { + conn->request_info.remote_user = mg_strdup(ah->user); + } else { + return 0; + } + + return 1; +} + + +static const char * +mg_fgets(char *buf, size_t size, struct file *filep, char **p) +{ + const char *eof; + size_t len; + const char *memend; + + if (!filep) { + return NULL; + } + + if (filep->membuf != NULL && *p != NULL) { + memend = (const char *)&filep->membuf[filep->size]; + /* Search for \n from p till the end of stream */ + eof = (char *)memchr(*p, '\n', (size_t)(memend - *p)); + if (eof != NULL) { + eof += 1; /* Include \n */ + } else { + eof = memend; /* Copy remaining data */ + } + len = (size_t)(eof - *p) > size - 1 ? size - 1 : (size_t)(eof - *p); + memcpy(buf, *p, len); + buf[len] = '\0'; + *p += len; + return len ? eof : NULL; + } else if (filep->fp != NULL) { + return fgets(buf, (int)size, filep->fp); + } else { + return NULL; + } +} + +struct read_auth_file_struct { + struct mg_connection *conn; + struct ah ah; + char *domain; + char buf[256 + 256 + 40]; + char *f_user; + char *f_domain; + char *f_ha1; +}; + + +static int +read_auth_file(struct file *filep, struct read_auth_file_struct *workdata) +{ + char *p; + int is_authorized = 0; + struct file fp; + size_t l; + + if (!filep || !workdata) { + return 0; + } + + /* Loop over passwords file */ + p = (char *)filep->membuf; + while (mg_fgets(workdata->buf, sizeof(workdata->buf), filep, &p) != NULL) { + l = strlen(workdata->buf); + while (l > 0) { + if (isspace(workdata->buf[l - 1]) + || iscntrl(workdata->buf[l - 1])) { + l--; + workdata->buf[l] = 0; + } else + break; + } + if (l < 1) { + continue; + } + + workdata->f_user = workdata->buf; + + if (workdata->f_user[0] == ':') { + /* user names may not contain a ':' and may not be empty, + * so lines starting with ':' may be used for a special purpose */ + if (workdata->f_user[1] == '#') { + /* :# is a comment */ + continue; + } else if (!strncmp(workdata->f_user + 1, "include=", 8)) { + if (mg_fopen(workdata->conn, workdata->f_user + 9, "r", &fp)) { + is_authorized = read_auth_file(&fp, workdata); + mg_fclose(&fp); + } else { + mg_cry(workdata->conn, + "%s: cannot open authorization file: %s", + __func__, + workdata->buf); + } + continue; + } + /* everything is invalid for the moment (might change in the + * future) */ + mg_cry(workdata->conn, + "%s: syntax error in authorization file: %s", + __func__, + workdata->buf); + continue; + } + + workdata->f_domain = strchr(workdata->f_user, ':'); + if (workdata->f_domain == NULL) { + mg_cry(workdata->conn, + "%s: syntax error in authorization file: %s", + __func__, + workdata->buf); + continue; + } + *(workdata->f_domain) = 0; + (workdata->f_domain)++; + + workdata->f_ha1 = strchr(workdata->f_domain, ':'); + if (workdata->f_ha1 == NULL) { + mg_cry(workdata->conn, + "%s: syntax error in authorization file: %s", + __func__, + workdata->buf); + continue; + } + *(workdata->f_ha1) = 0; + (workdata->f_ha1)++; + + if (!strcmp(workdata->ah.user, workdata->f_user) + && !strcmp(workdata->domain, workdata->f_domain)) { + return check_password(workdata->conn->request_info.request_method, + workdata->f_ha1, + workdata->ah.uri, + workdata->ah.nonce, + workdata->ah.nc, + workdata->ah.cnonce, + workdata->ah.qop, + workdata->ah.response); + } + } + + return is_authorized; +} + + +/* Authorize against the opened passwords file. Return 1 if authorized. */ +static int +authorize(struct mg_connection *conn, struct file *filep) +{ + struct read_auth_file_struct workdata; + char buf[MG_BUF_LEN]; + + if (!conn || !conn->ctx) { + return 0; + } + + memset(&workdata, 0, sizeof(workdata)); + workdata.conn = conn; + + if (!parse_auth_header(conn, buf, sizeof(buf), &workdata.ah)) { + return 0; + } + workdata.domain = conn->ctx->config[AUTHENTICATION_DOMAIN]; + + return read_auth_file(filep, &workdata); +} + + +/* Return 1 if request is authorised, 0 otherwise. */ +static int +check_authorization(struct mg_connection *conn, const char *path) +{ + char fname[PATH_MAX]; + struct vec uri_vec, filename_vec; + const char *list; + struct file file = STRUCT_FILE_INITIALIZER; + int authorized = 1, truncated; + + if (!conn || !conn->ctx) { + return 0; + } + + list = conn->ctx->config[PROTECT_URI]; + while ((list = next_option(list, &uri_vec, &filename_vec)) != NULL) { + if (!memcmp(conn->request_info.local_uri, uri_vec.ptr, uri_vec.len)) { + mg_snprintf(conn, + &truncated, + fname, + sizeof(fname), + "%.*s", + (int)filename_vec.len, + filename_vec.ptr); + + if (truncated || !mg_fopen(conn, fname, "r", &file)) { + mg_cry(conn, + "%s: cannot open %s: %s", + __func__, + fname, + strerror(errno)); + } + break; + } + } + + if (!is_file_opened(&file)) { + open_auth_file(conn, path, &file); + } + + if (is_file_opened(&file)) { + authorized = authorize(conn, &file); + mg_fclose(&file); + } + + return authorized; +} + + +static void +send_authorization_request(struct mg_connection *conn) +{ + char date[64]; + time_t curtime = time(NULL); + + if (conn && conn->ctx) { + uint64_t nonce = (uint64_t)(conn->ctx->start_time); + + (void)pthread_mutex_lock(&conn->ctx->nonce_mutex); + nonce += conn->ctx->nonce_count; + ++conn->ctx->nonce_count; + (void)pthread_mutex_unlock(&conn->ctx->nonce_mutex); + + nonce ^= conn->ctx->auth_nonce_mask; + conn->status_code = 401; + conn->must_close = 1; + + gmt_time_string(date, sizeof(date), &curtime); + + mg_printf(conn, "HTTP/1.1 401 Unauthorized\r\n"); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Connection: %s\r\n" + "Content-Length: 0\r\n" + "WWW-Authenticate: Digest qop=\"auth\", realm=\"%s\", " + "nonce=\"%" UINT64_FMT "\"\r\n\r\n", + date, + suggest_connection_header(conn), + conn->ctx->config[AUTHENTICATION_DOMAIN], + nonce); + } +} + + +#if !defined(NO_FILES) +static int +is_authorized_for_put(struct mg_connection *conn) +{ + if (conn) { + struct file file = STRUCT_FILE_INITIALIZER; + const char *passfile = conn->ctx->config[PUT_DELETE_PASSWORDS_FILE]; + int ret = 0; + + if (passfile != NULL && mg_fopen(conn, passfile, "r", &file)) { + ret = authorize(conn, &file); + mg_fclose(&file); + } + + return ret; + } + return 0; +} +#endif + + +int +mg_modify_passwords_file(const char *fname, + const char *domain, + const char *user, + const char *pass) +{ + int found, i; + char line[512], u[512] = "", d[512] = "", ha1[33], tmp[PATH_MAX + 8]; + FILE *fp, *fp2; + + found = 0; + fp = fp2 = NULL; + + /* Regard empty password as no password - remove user record. */ + if (pass != NULL && pass[0] == '\0') { + pass = NULL; + } + + /* Other arguments must not be empty */ + if (fname == NULL || domain == NULL || user == NULL) { + return 0; + } + + /* Using the given file format, user name and domain must not contain ':' + */ + if (strchr(user, ':') != NULL) { + return 0; + } + if (strchr(domain, ':') != NULL) { + return 0; + } + + /* Do not allow control characters like newline in user name and domain. + * Do not allow excessively long names either. */ + for (i = 0; i < 255 && user[i] != 0; i++) { + if (iscntrl(user[i])) { + return 0; + } + } + if (user[i]) { + return 0; + } + for (i = 0; i < 255 && domain[i] != 0; i++) { + if (iscntrl(domain[i])) { + return 0; + } + } + if (domain[i]) { + return 0; + } + + /* The maximum length of the path to the password file is limited */ + if ((strlen(fname) + 4) >= PATH_MAX) { + return 0; + } + + /* Create a temporary file name. Length has been checked before. */ + strcpy(tmp, fname); + strcat(tmp, ".tmp"); + + /* Create the file if does not exist */ + /* Use of fopen here is OK, since fname is only ASCII */ + if ((fp = fopen(fname, "a+")) != NULL) { + (void)fclose(fp); + } + + /* Open the given file and temporary file */ + if ((fp = fopen(fname, "r")) == NULL) { + return 0; + } else if ((fp2 = fopen(tmp, "w+")) == NULL) { + fclose(fp); + return 0; + } + + /* Copy the stuff to temporary file */ + while (fgets(line, sizeof(line), fp) != NULL) { + if (sscanf(line, "%255[^:]:%255[^:]:%*s", u, d) != 2) { + continue; + } + u[255] = 0; + d[255] = 0; + + if (!strcmp(u, user) && !strcmp(d, domain)) { + found++; + if (pass != NULL) { + mg_md5(ha1, user, ":", domain, ":", pass, NULL); + fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); + } + } else { + fprintf(fp2, "%s", line); + } + } + + /* If new user, just add it */ + if (!found && pass != NULL) { + mg_md5(ha1, user, ":", domain, ":", pass, NULL); + fprintf(fp2, "%s:%s:%s\n", user, domain, ha1); + } + + /* Close files */ + fclose(fp); + fclose(fp2); + + /* Put the temp file in place of real file */ + IGNORE_UNUSED_RESULT(remove(fname)); + IGNORE_UNUSED_RESULT(rename(tmp, fname)); + + return 1; +} + + +static int +is_valid_port(unsigned long port) +{ + return port < 0xffff; +} + + +static int +mg_inet_pton(int af, const char *src, void *dst, size_t dstlen) +{ + struct addrinfo hints, *res, *ressave; + int func_ret = 0; + int gai_ret; + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = af; + + gai_ret = getaddrinfo(src, NULL, &hints, &res); + if (gai_ret != 0) { + /* gai_strerror could be used to convert gai_ret to a string */ + /* POSIX return values: see + * http://pubs.opengroup.org/onlinepubs/9699919799/functions/freeaddrinfo.html + */ + /* Windows return values: see + * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520%28v=vs.85%29.aspx + */ + return 0; + } + + ressave = res; + + while (res) { + if (dstlen >= res->ai_addrlen) { + memcpy(dst, res->ai_addr, res->ai_addrlen); + func_ret = 1; + } + res = res->ai_next; + } + + freeaddrinfo(ressave); + return func_ret; +} + + +static int +connect_socket(struct mg_context *ctx /* may be NULL */, + const char *host, + int port, + int use_ssl, + char *ebuf, + size_t ebuf_len, + SOCKET *sock /* output: socket, must not be NULL */, + union usa *sa /* output: socket address, must not be NULL */ + ) +{ + int ip_ver = 0; + *sock = INVALID_SOCKET; + memset(sa, 0, sizeof(*sa)); + + if (ebuf_len > 0) { + *ebuf = 0; + } + + if (host == NULL) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "NULL host"); + return 0; + } + + if (port < 0 || !is_valid_port((unsigned)port)) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "invalid port"); + return 0; + } + + if (use_ssl && (SSLv23_client_method == NULL)) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "SSL is not initialized"); + return 0; + } + + if (mg_inet_pton(AF_INET, host, &sa->sin, sizeof(sa->sin))) { + sa->sin.sin_port = htons((uint16_t)port); + ip_ver = 4; +#ifdef USE_IPV6 + } else if (mg_inet_pton(AF_INET6, host, &sa->sin6, sizeof(sa->sin6))) { + sa->sin6.sin6_port = htons((uint16_t)port); + ip_ver = 6; + } else if (host[0] == '[') { + /* While getaddrinfo on Windows will work with [::1], + * getaddrinfo on Linux only works with ::1 (without []). */ + size_t l = strlen(host + 1); + char *h = l > 1 ? mg_strdup(host + 1) : NULL; + if (h) { + h[l - 1] = 0; + if (mg_inet_pton(AF_INET6, h, &sa->sin6, sizeof(sa->sin6))) { + sa->sin6.sin6_port = htons((uint16_t)port); + ip_ver = 6; + } + mg_free(h); + } +#endif + } + + if (ip_ver == 0) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "%s", + "host not found"); + return 0; + } + + if (ip_ver == 4) { + *sock = socket(PF_INET, SOCK_STREAM, 0); + } +#ifdef USE_IPV6 + else if (ip_ver == 6) { + *sock = socket(PF_INET6, SOCK_STREAM, 0); + } +#endif + + if (*sock == INVALID_SOCKET) { + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "socket(): %s", + strerror(ERRNO)); + return 0; + } + + set_close_on_exec(*sock, fc(ctx)); + + if ((ip_ver == 4) + && (connect(*sock, (struct sockaddr *)&sa->sin, sizeof(sa->sin)) + == 0)) { + /* connected with IPv4 */ + return 1; + } + +#ifdef USE_IPV6 + if ((ip_ver == 6) + && (connect(*sock, (struct sockaddr *)&sa->sin6, sizeof(sa->sin6)) + == 0)) { + /* connected with IPv6 */ + return 1; + } +#endif + + /* Not connected */ + mg_snprintf(NULL, + NULL, /* No truncation check for ebuf */ + ebuf, + ebuf_len, + "connect(%s:%d): %s", + host, + port, + strerror(ERRNO)); + closesocket(*sock); + *sock = INVALID_SOCKET; + return 0; +} + + +int +mg_url_encode(const char *src, char *dst, size_t dst_len) +{ + static const char *dont_escape = "._-$,;~()"; + static const char *hex = "0123456789abcdef"; + char *pos = dst; + const char *end = dst + dst_len - 1; + + for (; *src != '\0' && pos < end; src++, pos++) { + if (isalnum(*(const unsigned char *)src) + || strchr(dont_escape, *(const unsigned char *)src) != NULL) { + *pos = *src; + } else if (pos + 2 < end) { + pos[0] = '%'; + pos[1] = hex[(*(const unsigned char *)src) >> 4]; + pos[2] = hex[(*(const unsigned char *)src) & 0xf]; + pos += 2; + } else { + break; + } + } + + *pos = '\0'; + return (*src == '\0') ? (int)(pos - dst) : -1; +} + + +static void +print_dir_entry(struct de *de) +{ + char size[64], mod[64], href[PATH_MAX]; + struct tm *tm; + + if (de->file.is_directory) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%s", + "[DIRECTORY]"); + } else { + /* We use (signed) cast below because MSVC 6 compiler cannot + * convert unsigned __int64 to double. Sigh. */ + if (de->file.size < 1024) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%d", + (int)de->file.size); + } else if (de->file.size < 0x100000) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%.1fk", + (double)de->file.size / 1024.0); + } else if (de->file.size < 0x40000000) { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%.1fM", + (double)de->file.size / 1048576); + } else { + mg_snprintf(de->conn, + NULL, /* Buffer is big enough */ + size, + sizeof(size), + "%.1fG", + (double)de->file.size / 1073741824); + } + } + + /* Note: mg_snprintf will not cause a buffer overflow above. + * So, string truncation checks are not required here. */ + + tm = localtime(&de->file.last_modified); + if (tm != NULL) { + strftime(mod, sizeof(mod), "%d-%b-%Y %H:%M", tm); + } else { + mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod)); + mod[sizeof(mod) - 1] = '\0'; + } + mg_url_encode(de->file_name, href, sizeof(href)); + de->conn->num_bytes_sent += + mg_printf(de->conn, + "%s%s" + " %s  %s\n", + de->conn->request_info.local_uri, + href, + de->file.is_directory ? "/" : "", + de->file_name, + de->file.is_directory ? "/" : "", + mod, + size); +} + + +/* This function is called from send_directory() and used for + * sorting directory entries by size, or name, or modification time. + * On windows, __cdecl specification is needed in case if project is built + * with __stdcall convention. qsort always requires __cdels callback. */ +static int WINCDECL +compare_dir_entries(const void *p1, const void *p2) +{ + if (p1 && p2) { + const struct de *a = (const struct de *)p1, *b = (const struct de *)p2; + const char *query_string = a->conn->request_info.query_string; + int cmp_result = 0; + + if (query_string == NULL) { + query_string = "na"; + } + + if (a->file.is_directory && !b->file.is_directory) { + return -1; /* Always put directories on top */ + } else if (!a->file.is_directory && b->file.is_directory) { + return 1; /* Always put directories on top */ + } else if (*query_string == 'n') { + cmp_result = strcmp(a->file_name, b->file_name); + } else if (*query_string == 's') { + cmp_result = a->file.size == b->file.size + ? 0 + : a->file.size > b->file.size ? 1 : -1; + } else if (*query_string == 'd') { + cmp_result = + (a->file.last_modified == b->file.last_modified) + ? 0 + : ((a->file.last_modified > b->file.last_modified) ? 1 + : -1); + } + + return query_string[1] == 'd' ? -cmp_result : cmp_result; + } + return 0; +} + + +static int +must_hide_file(struct mg_connection *conn, const char *path) +{ + if (conn && conn->ctx) { + const char *pw_pattern = "**" PASSWORDS_FILE_NAME "$"; + const char *pattern = conn->ctx->config[HIDE_FILES]; + return match_prefix(pw_pattern, strlen(pw_pattern), path) > 0 + || (pattern != NULL + && match_prefix(pattern, strlen(pattern), path) > 0); + } + return 0; +} + + +static int +scan_directory(struct mg_connection *conn, + const char *dir, + void *data, + void (*cb)(struct de *, void *)) +{ + char path[PATH_MAX]; + struct dirent *dp; + DIR *dirp; + struct de de; + int truncated; + + if ((dirp = mg_opendir(conn, dir)) == NULL) { + return 0; + } else { + de.conn = conn; + + while ((dp = mg_readdir(dirp)) != NULL) { + /* Do not show current dir and hidden files */ + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..") + || must_hide_file(conn, dp->d_name)) { + continue; + } + + mg_snprintf( + conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name); + + /* If we don't memset stat structure to zero, mtime will have + * garbage and strftime() will segfault later on in + * print_dir_entry(). memset is required only if mg_stat() + * fails. For more details, see + * http://code.google.com/p/mongoose/issues/detail?id=79 */ + memset(&de.file, 0, sizeof(de.file)); + + if (truncated) { + /* If the path is not complete, skip processing. */ + continue; + } + + if (!mg_stat(conn, path, &de.file)) { + mg_cry(conn, + "%s: mg_stat(%s) failed: %s", + __func__, + path, + strerror(ERRNO)); + } + de.file_name = dp->d_name; + cb(&de, data); + } + (void)mg_closedir(dirp); + } + return 1; +} + + +#if !defined(NO_FILES) +static int +remove_directory(struct mg_connection *conn, const char *dir) +{ + char path[PATH_MAX]; + struct dirent *dp; + DIR *dirp; + struct de de; + int truncated; + int ok = 1; + + if ((dirp = mg_opendir(conn, dir)) == NULL) { + return 0; + } else { + de.conn = conn; + + while ((dp = mg_readdir(dirp)) != NULL) { + /* Do not show current dir (but show hidden files as they will + * also be removed) */ + if (!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")) { + continue; + } + + mg_snprintf( + conn, &truncated, path, sizeof(path), "%s/%s", dir, dp->d_name); + + /* If we don't memset stat structure to zero, mtime will have + * garbage and strftime() will segfault later on in + * print_dir_entry(). memset is required only if mg_stat() + * fails. For more details, see + * http://code.google.com/p/mongoose/issues/detail?id=79 */ + memset(&de.file, 0, sizeof(de.file)); + + if (truncated) { + /* Do not delete anything shorter */ + ok = 0; + continue; + } + + if (!mg_stat(conn, path, &de.file)) { + mg_cry(conn, + "%s: mg_stat(%s) failed: %s", + __func__, + path, + strerror(ERRNO)); + ok = 0; + } + if (de.file.membuf == NULL) { + /* file is not in memory */ + if (de.file.is_directory) { + if (remove_directory(conn, path) == 0) { + ok = 0; + } + } else { + if (mg_remove(conn, path) == 0) { + ok = 0; + } + } + } else { + /* file is in memory. It can not be deleted. */ + ok = 0; + } + } + (void)mg_closedir(dirp); + + IGNORE_UNUSED_RESULT(rmdir(dir)); + } + + return ok; +} +#endif + + +struct dir_scan_data { + struct de *entries; + unsigned int num_entries; + unsigned int arr_size; +}; + + +/* Behaves like realloc(), but frees original pointer on failure */ +static void * +realloc2(void *ptr, size_t size) +{ + void *new_ptr = mg_realloc(ptr, size); + if (new_ptr == NULL) { + mg_free(ptr); + } + return new_ptr; +} + + +static void +dir_scan_callback(struct de *de, void *data) +{ + struct dir_scan_data *dsd = (struct dir_scan_data *)data; + + if (dsd->entries == NULL || dsd->num_entries >= dsd->arr_size) { + dsd->arr_size *= 2; + dsd->entries = + (struct de *)realloc2(dsd->entries, + dsd->arr_size * sizeof(dsd->entries[0])); + } + if (dsd->entries == NULL) { + /* TODO(lsm, low): propagate an error to the caller */ + dsd->num_entries = 0; + } else { + dsd->entries[dsd->num_entries].file_name = mg_strdup(de->file_name); + dsd->entries[dsd->num_entries].file = de->file; + dsd->entries[dsd->num_entries].conn = de->conn; + dsd->num_entries++; + } +} + + +static void +handle_directory_request(struct mg_connection *conn, const char *dir) +{ + unsigned int i; + int sort_direction; + struct dir_scan_data data = {NULL, 0, 128}; + char date[64]; + time_t curtime = time(NULL); + + if (!scan_directory(conn, dir, &data, dir_scan_callback)) { + send_http_error(conn, + 500, + "Error: Cannot open directory\nopendir(%s): %s", + dir, + strerror(ERRNO)); + return; + } + + gmt_time_string(date, sizeof(date), &curtime); + + if (!conn) { + return; + } + + sort_direction = conn->request_info.query_string != NULL + && conn->request_info.query_string[1] == 'd' + ? 'a' + : 'd'; + + conn->must_close = 1; + mg_printf(conn, "HTTP/1.1 200 OK\r\n"); + send_static_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Connection: close\r\n" + "Content-Type: text/html; charset=utf-8\r\n\r\n", + date); + + conn->num_bytes_sent += + mg_printf(conn, + "Index of %s" + "" + "

Index of %s

"
+	              ""
+	              ""
+	              ""
+	              "",
+	              conn->request_info.local_uri,
+	              conn->request_info.local_uri,
+	              sort_direction,
+	              sort_direction,
+	              sort_direction);
+
+	/* Print first entry - link to a parent directory */
+	conn->num_bytes_sent +=
+	    mg_printf(conn,
+	              ""
+	              "\n",
+	              conn->request_info.local_uri,
+	              "..",
+	              "Parent directory",
+	              "-",
+	              "-");
+
+	/* Sort and print directory entries */
+	if (data.entries != NULL) {
+		qsort(data.entries,
+		      (size_t)data.num_entries,
+		      sizeof(data.entries[0]),
+		      compare_dir_entries);
+		for (i = 0; i < data.num_entries; i++) {
+			print_dir_entry(&data.entries[i]);
+			mg_free(data.entries[i].file_name);
+		}
+		mg_free(data.entries);
+	}
+
+	conn->num_bytes_sent += mg_printf(conn, "%s", "
NameModifiedSize

%s %s  %s
"); + conn->status_code = 200; +} + + +/* Send len bytes from the opened file to the client. */ +static void +send_file_data(struct mg_connection *conn, + struct file *filep, + int64_t offset, + int64_t len) +{ + char buf[MG_BUF_LEN]; + int to_read, num_read, num_written; + int64_t size; + + if (!filep || !conn) { + return; + } + + /* Sanity check the offset */ + size = filep->size > INT64_MAX ? INT64_MAX : (int64_t)(filep->size); + offset = offset < 0 ? 0 : offset > size ? size : offset; + + if (len > 0 && filep->membuf != NULL && size > 0) { + /* file stored in memory */ + if (len > size - offset) { + len = size - offset; + } + mg_write(conn, filep->membuf + offset, (size_t)len); + } else if (len > 0 && filep->fp != NULL) { +/* file stored on disk */ +#if defined(__linux__) + /* sendfile is only available for Linux */ + if (conn->throttle == 0 && conn->ssl == 0) { + off_t sf_offs = (off_t)offset; + ssize_t sf_sent; + int sf_file = fileno(filep->fp); + int loop_cnt = 0; + + do { + /* 2147479552 (0x7FFFF000) is a limit found by experiment on + * 64 bit Linux (2^31 minus one memory page of 4k?). */ + size_t sf_tosend = + (size_t)((len < 0x7FFFF000) ? len : 0x7FFFF000); + sf_sent = + sendfile(conn->client.sock, sf_file, &sf_offs, sf_tosend); + if (sf_sent > 0) { + conn->num_bytes_sent += sf_sent; + len -= sf_sent; + offset += sf_sent; + } else if (loop_cnt == 0) { + /* This file can not be sent using sendfile. + * This might be the case for pseudo-files in the + * /sys/ and /proc/ file system. + * Use the regular user mode copy code instead. */ + break; + } else if (sf_sent == 0) { + /* No error, but 0 bytes sent. May be EOF? */ + return; + } + loop_cnt++; + + } while ((len > 0) && (sf_sent >= 0)); + + if (sf_sent > 0) { + return; /* OK */ + } + + /* sf_sent<0 means error, thus fall back to the classic way */ + /* This is always the case, if sf_file is not a "normal" file, + * e.g., for sending data from the output of a CGI process. */ + offset = (int64_t)sf_offs; + } +#endif + if ((offset > 0) && (fseeko(filep->fp, offset, SEEK_SET) != 0)) { + mg_cry(conn, "%s: fseeko() failed: %s", __func__, strerror(ERRNO)); + send_http_error( + conn, + 500, + "%s", + "Error: Unable to access file at requested position."); + } else { + while (len > 0) { + /* Calculate how much to read from the file in the buffer */ + to_read = sizeof(buf); + if ((int64_t)to_read > len) { + to_read = (int)len; + } + + /* Read from file, exit the loop on error */ + if ((num_read = (int)fread(buf, 1, (size_t)to_read, filep->fp)) + <= 0) { + break; + } + + /* Send read bytes to the client, exit the loop on error */ + if ((num_written = mg_write(conn, buf, (size_t)num_read)) + != num_read) { + break; + } + + /* Both read and were successful, adjust counters */ + conn->num_bytes_sent += num_written; + len -= num_written; + } + } + } +} + + +static int +parse_range_header(const char *header, int64_t *a, int64_t *b) +{ + return sscanf(header, "bytes=%" INT64_FMT "-%" INT64_FMT, a, b); +} + + +static void +construct_etag(char *buf, size_t buf_len, const struct file *filep) +{ + if (filep != NULL && buf != NULL) { + mg_snprintf(NULL, + NULL, /* All calls to construct_etag use 64 byte buffer */ + buf, + buf_len, + "\"%lx.%" INT64_FMT "\"", + (unsigned long)filep->last_modified, + filep->size); + } +} + + +static void +fclose_on_exec(struct file *filep, struct mg_connection *conn) +{ + if (filep != NULL && filep->fp != NULL) { +#ifdef _WIN32 + (void)conn; /* Unused. */ +#else + if (fcntl(fileno(filep->fp), F_SETFD, FD_CLOEXEC) != 0) { + mg_cry(conn, + "%s: fcntl(F_SETFD FD_CLOEXEC) failed: %s", + __func__, + strerror(ERRNO)); + } +#endif + } +} + + +static void +handle_static_file_request(struct mg_connection *conn, + const char *path, + struct file *filep, + const char *mime_type) +{ + char date[64], lm[64], etag[64]; + char range[128]; /* large enough, so there will be no overflow */ + const char *msg = "OK", *hdr; + time_t curtime = time(NULL); + int64_t cl, r1, r2; + struct vec mime_vec; + int n, truncated; + char gz_path[PATH_MAX]; + const char *encoding = ""; + const char *cors1, *cors2, *cors3; + + if (conn == NULL || conn->ctx == NULL || filep == NULL) { + return; + } + + if (mime_type == NULL) { + get_mime_type(conn->ctx, path, &mime_vec); + } else { + mime_vec.ptr = mime_type; + mime_vec.len = strlen(mime_type); + } + if (filep->size > INT64_MAX) { + send_http_error(conn, + 500, + "Error: File size is too large to send\n%" INT64_FMT, + filep->size); + } + cl = (int64_t)filep->size; + conn->status_code = 200; + range[0] = '\0'; + + /* if this file is in fact a pre-gzipped file, rewrite its filename + * it's important to rewrite the filename after resolving + * the mime type from it, to preserve the actual file's type */ + if (filep->gzipped) { + mg_snprintf(conn, &truncated, gz_path, sizeof(gz_path), "%s.gz", path); + + if (truncated) { + send_http_error(conn, + 500, + "Error: Path of zipped file too long (%s)", + path); + return; + } + + path = gz_path; + encoding = "Content-Encoding: gzip\r\n"; + } + + if (!mg_fopen(conn, path, "rb", filep)) { + send_http_error(conn, + 500, + "Error: Cannot open file\nfopen(%s): %s", + path, + strerror(ERRNO)); + return; + } + + fclose_on_exec(filep, conn); + + /* If Range: header specified, act accordingly */ + r1 = r2 = 0; + hdr = mg_get_header(conn, "Range"); + if (hdr != NULL && (n = parse_range_header(hdr, &r1, &r2)) > 0 && r1 >= 0 + && r2 >= 0) { + /* actually, range requests don't play well with a pre-gzipped + * file (since the range is specified in the uncompressed space) */ + if (filep->gzipped) { + send_http_error( + conn, + 501, + "%s", + "Error: Range requests in gzipped files are not supported"); + mg_fclose(filep); + return; + } + conn->status_code = 206; + cl = n == 2 ? (r2 > cl ? cl : r2) - r1 + 1 : cl - r1; + mg_snprintf(conn, + NULL, /* range buffer is big enough */ + range, + sizeof(range), + "Content-Range: bytes " + "%" INT64_FMT "-%" INT64_FMT "/%" INT64_FMT "\r\n", + r1, + r1 + cl - 1, + filep->size); + msg = "Partial Content"; + } + + hdr = mg_get_header(conn, "Origin"); + if (hdr) { + /* Cross-origin resource sharing (CORS), see + * http://www.html5rocks.com/en/tutorials/cors/, + * http://www.html5rocks.com/static/images/cors_server_flowchart.png - + * preflight is not supported for files. */ + cors1 = "Access-Control-Allow-Origin: "; + cors2 = conn->ctx->config[ACCESS_CONTROL_ALLOW_ORIGIN]; + cors3 = "\r\n"; + } else { + cors1 = cors2 = cors3 = ""; + } + + /* Prepare Etag, Date, Last-Modified headers. Must be in UTC, according to + * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3 */ + gmt_time_string(date, sizeof(date), &curtime); + gmt_time_string(lm, sizeof(lm), &filep->last_modified); + construct_etag(etag, sizeof(etag), filep); + + (void)mg_printf(conn, + "HTTP/1.1 %d %s\r\n" + "%s%s%s" + "Date: %s\r\n", + conn->status_code, + msg, + cors1, + cors2, + cors3, + date); + send_static_cache_header(conn); + (void)mg_printf(conn, + "Last-Modified: %s\r\n" + "Etag: %s\r\n" + "Content-Type: %.*s\r\n" + "Content-Length: %" INT64_FMT "\r\n" + "Connection: %s\r\n" + "Accept-Ranges: bytes\r\n" + "%s%s\r\n", + lm, + etag, + (int)mime_vec.len, + mime_vec.ptr, + cl, + suggest_connection_header(conn), + range, + encoding); + + if (strcmp(conn->request_info.request_method, "HEAD") != 0) { + send_file_data(conn, filep, r1, cl); + } + mg_fclose(filep); +} + + +void +mg_send_file(struct mg_connection *conn, const char *path) +{ + mg_send_mime_file(conn, path, NULL); +} + + +void +mg_send_mime_file(struct mg_connection *conn, + const char *path, + const char *mime_type) +{ + struct file file = STRUCT_FILE_INITIALIZER; + if (mg_stat(conn, path, &file)) { + if (file.is_directory) { + if (!conn) { + return; + } + if (!mg_strcasecmp(conn->ctx->config[ENABLE_DIRECTORY_LISTING], + "yes")) { + handle_directory_request(conn, path); + } else { + send_http_error(conn, + 403, + "%s", + "Error: Directory listing denied"); + } + } else { + handle_static_file_request(conn, path, &file, mime_type); + } + } else { + send_http_error(conn, 404, "%s", "Error: File not found"); + } +} + + +/* For a given PUT path, create all intermediate subdirectories. + * Return 0 if the path itself is a directory. + * Return 1 if the path leads to a file. + * Return -1 for if the path is too long. + * Return -2 if path can not be created. +*/ +static int +put_dir(struct mg_connection *conn, const char *path) +{ + char buf[PATH_MAX]; + const char *s, *p; + struct file file = STRUCT_FILE_INITIALIZER; + size_t len; + int res = 1; + + for (s = p = path + 2; (p = strchr(s, '/')) != NULL; s = ++p) { + len = (size_t)(p - path); + if (len >= sizeof(buf)) { + /* path too long */ + res = -1; + break; + } + memcpy(buf, path, len); + buf[len] = '\0'; + + /* Try to create intermediate directory */ + DEBUG_TRACE("mkdir(%s)", buf); + if (!mg_stat(conn, buf, &file) && mg_mkdir(conn, buf, 0755) != 0) { + /* path does not exixt and can not be created */ + res = -2; + break; + } + + /* Is path itself a directory? */ + if (p[1] == '\0') { + res = 0; + } + } + + return res; +} + + +static void +remove_bad_file(const struct mg_connection *conn, const char *path) +{ + int r = mg_remove(conn, path); + if (r != 0) { + mg_cry(conn, "%s: Cannot remove invalid file %s", __func__, path); + } +} + + +long long +mg_store_body(struct mg_connection *conn, const char *path) +{ + char buf[MG_BUF_LEN]; + long long len = 0; + int ret, n; + struct file fi; + + if (conn->consumed_content != 0) { + mg_cry(conn, "%s: Contents already consumed", __func__); + return -11; + } + + ret = put_dir(conn, path); + if (ret < 0) { + /* -1 for path too long, + * -2 for path can not be created. */ + return ret; + } + if (ret != 1) { + /* Return 0 means, path itself is a directory. */ + return 0; + } + + if (mg_fopen(conn, path, "w", &fi) == 0) { + return -12; + } + + ret = mg_read(conn, buf, sizeof(buf)); + while (ret > 0) { + n = (int)fwrite(buf, 1, (size_t)ret, fi.fp); + if (n != ret) { + mg_fclose(&fi); + remove_bad_file(conn, path); + return -13; + } + ret = mg_read(conn, buf, sizeof(buf)); + } + + /* TODO: mg_fclose should return an error, + * and every caller should check and handle it. */ + if (fclose(fi.fp) != 0) { + remove_bad_file(conn, path); + return -14; + } + + return len; +} + + +/* Parse HTTP headers from the given buffer, advance buffer to the point + * where parsing stopped. */ +static void +parse_http_headers(char **buf, struct mg_request_info *ri) +{ + int i; + + if (!ri) { + return; + } + + ri->num_headers = 0; + + for (i = 0; i < (int)ARRAY_SIZE(ri->http_headers); i++) { + char *dp = *buf; + while ((*dp != ':') && (*dp != '\r') && (*dp != 0)) { + dp++; + } + if (!*dp) { + /* neither : nor \r\n. This is not a valid field. */ + break; + } + if (*dp == '\r') { + if (dp[1] == '\n') { + /* \r\n */ + ri->http_headers[i].name = *buf; + ri->http_headers[i].value = 0; + *buf = dp; + } else { + /* stray \r. This is not valid. */ + break; + } + } else { + /* (*dp == ':') */ + *dp = 0; + ri->http_headers[i].name = *buf; + do { + dp++; + } while (*dp == ' '); + + ri->http_headers[i].value = dp; + *buf = strstr(dp, "\r\n"); + } + + ri->num_headers = i + 1; + if (*buf) { + (*buf)[0] = 0; + (*buf)[1] = 0; + *buf += 2; + } else { + *buf = dp; + break; + } + + if (*buf[0] == '\r') { + /* This is the end of the header */ + break; + } + } +} + + +static int +is_valid_http_method(const char *method) +{ + return !strcmp(method, "GET") /* HTTP (RFC 2616) */ + || !strcmp(method, "POST") /* HTTP (RFC 2616) */ + || !strcmp(method, "HEAD") /* HTTP (RFC 2616) */ + || !strcmp(method, "PUT") /* HTTP (RFC 2616) */ + || !strcmp(method, "DELETE") /* HTTP (RFC 2616) */ + || !strcmp(method, "OPTIONS") /* HTTP (RFC 2616) */ + /* TRACE method (RFC 2616) is not supported for security reasons */ + || !strcmp(method, "CONNECT") /* HTTP (RFC 2616) */ + + || !strcmp(method, "PROPFIND") /* WEBDAV (RFC 2518) */ + || !strcmp(method, "MKCOL") /* WEBDAV (RFC 2518) */ + + /* Unsupported WEBDAV Methods: */ + /* PROPPATCH, COPY, MOVE, LOCK, UNLOCK (RFC 2518) */ + /* + 11 methods from RFC 3253 */ + /* ORDERPATCH (RFC 3648) */ + /* ACL (RFC 3744) */ + /* SEARCH (RFC 5323) */ + /* + MicroSoft extensions + * https://msdn.microsoft.com/en-us/library/aa142917.aspx */ + + /* PATCH method only allowed for CGI/Lua/LSP and callbacks. */ + || !strcmp(method, "PATCH"); /* PATCH method (RFC 5789) */ +} + + +/* Parse HTTP request, fill in mg_request_info structure. + * This function modifies the buffer by NUL-terminating + * HTTP request components, header names and header values. */ +static int +parse_http_message(char *buf, int len, struct mg_request_info *ri) +{ + int is_request, request_length; + + if (!ri) { + return 0; + } + + request_length = get_request_len(buf, len); + + if (request_length > 0) { + /* Reset attributes. DO NOT TOUCH is_ssl, remote_ip, remote_addr, + * remote_port */ + ri->remote_user = ri->request_method = ri->request_uri = + ri->http_version = NULL; + ri->num_headers = 0; + + buf[request_length - 1] = '\0'; + + /* RFC says that all initial whitespaces should be ingored */ + while (*buf != '\0' && isspace(*(unsigned char *)buf)) { + buf++; + } + ri->request_method = skip(&buf, " "); + ri->request_uri = skip(&buf, " "); + ri->http_version = skip(&buf, "\r\n"); + + /* HTTP message could be either HTTP request or HTTP response, e.g. + * "GET / HTTP/1.0 ...." or "HTTP/1.0 200 OK ..." */ + is_request = is_valid_http_method(ri->request_method); + if ((is_request && memcmp(ri->http_version, "HTTP/", 5) != 0) + || (!is_request && memcmp(ri->request_method, "HTTP/", 5) != 0)) { + request_length = -1; + } else { + if (is_request) { + ri->http_version += 5; + } + parse_http_headers(&buf, ri); + } + } + return request_length; +} + + +/* Keep reading the input (either opened file descriptor fd, or socket sock, + * or SSL descriptor ssl) into buffer buf, until \r\n\r\n appears in the + * buffer (which marks the end of HTTP request). Buffer buf may already + * have some data. The length of the data is stored in nread. + * Upon every read operation, increase nread by the number of bytes read. */ +static int +read_request(FILE *fp, + struct mg_connection *conn, + char *buf, + int bufsiz, + int *nread) +{ + int request_len, n = 0; + struct timespec last_action_time; + double request_timeout; + + if (!conn) { + return 0; + } + + memset(&last_action_time, 0, sizeof(last_action_time)); + + if (conn->ctx->config[REQUEST_TIMEOUT]) { + /* value of request_timeout is in seconds, config in milliseconds */ + request_timeout = atof(conn->ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } else { + request_timeout = -1.0; + } + + request_len = get_request_len(buf, *nread); + + /* first time reading from this connection */ + clock_gettime(CLOCK_MONOTONIC, &last_action_time); + + while ( + (conn->ctx->stop_flag == 0) && (*nread < bufsiz) && (request_len == 0) + && ((mg_difftimespec(&last_action_time, &(conn->req_time)) + <= request_timeout) || (request_timeout < 0)) + && ((n = pull(fp, conn, buf + *nread, bufsiz - *nread, request_timeout)) + > 0)) { + *nread += n; + /* assert(*nread <= bufsiz); */ + if (*nread > bufsiz) { + return -2; + } + request_len = get_request_len(buf, *nread); + if (request_timeout > 0.0) { + clock_gettime(CLOCK_MONOTONIC, &last_action_time); + } + } + + return (request_len <= 0 && n <= 0) ? -1 : request_len; +} + +#if !defined(NO_FILES) +/* For given directory path, substitute it to valid index file. + * Return 1 if index file has been found, 0 if not found. + * If the file is found, it's stats is returned in stp. */ +static int +substitute_index_file(struct mg_connection *conn, + char *path, + size_t path_len, + struct file *filep) +{ + if (conn && conn->ctx) { + const char *list = conn->ctx->config[INDEX_FILES]; + struct file file = STRUCT_FILE_INITIALIZER; + struct vec filename_vec; + size_t n = strlen(path); + int found = 0; + + /* The 'path' given to us points to the directory. Remove all trailing + * directory separator characters from the end of the path, and + * then append single directory separator character. */ + while (n > 0 && path[n - 1] == '/') { + n--; + } + path[n] = '/'; + + /* Traverse index files list. For each entry, append it to the given + * path and see if the file exists. If it exists, break the loop */ + while ((list = next_option(list, &filename_vec, NULL)) != NULL) { + /* Ignore too long entries that may overflow path buffer */ + if (filename_vec.len > path_len - (n + 2)) { + continue; + } + + /* Prepare full path to the index file */ + mg_strlcpy(path + n + 1, filename_vec.ptr, filename_vec.len + 1); + + /* Does it exist? */ + if (mg_stat(conn, path, &file)) { + /* Yes it does, break the loop */ + *filep = file; + found = 1; + break; + } + } + + /* If no index file exists, restore directory path */ + if (!found) { + path[n] = '\0'; + } + + return found; + } + return 0; +} +#endif + + +#if !defined(NO_CACHING) +/* Return True if we should reply 304 Not Modified. */ +static int +is_not_modified(const struct mg_connection *conn, const struct file *filep) +{ + char etag[64]; + const char *ims = mg_get_header(conn, "If-Modified-Since"); + const char *inm = mg_get_header(conn, "If-None-Match"); + construct_etag(etag, sizeof(etag), filep); + if (!filep) { + return 0; + } + return (inm != NULL && !mg_strcasecmp(etag, inm)) + || (ims != NULL && (filep->last_modified <= parse_date_string(ims))); +} +#endif /* !NO_CACHING */ + + +#if !defined(NO_CGI) || !defined(NO_FILES) +static int +forward_body_data(struct mg_connection *conn, FILE *fp, SOCKET sock, SSL *ssl) +{ + const char *expect, *body; + char buf[MG_BUF_LEN]; + int to_read, nread, success = 0; + int64_t buffered_len; + double timeout = -1.0; + + if (!conn) { + return 0; + } + if (conn->ctx->config[REQUEST_TIMEOUT]) { + timeout = atoi(conn->ctx->config[REQUEST_TIMEOUT]) / 1000.0; + } + + expect = mg_get_header(conn, "Expect"); + /* assert(fp != NULL); */ + if (!fp) { + send_http_error(conn, 500, "%s", "Error: NULL File"); + return 0; + } + + if (conn->content_len == -1 && !conn->is_chunked) { + /* Content length is not specified by the client. */ + send_http_error(conn, + 411, + "%s", + "Error: Client did not specify content length"); + } else if ((expect != NULL) + && (mg_strcasecmp(expect, "100-continue") != 0)) { + /* Client sent an "Expect: xyz" header and xyz is not 100-continue. */ + send_http_error(conn, + 417, + "Error: Can not fulfill expectation %s", + expect); + } else { + if (expect != NULL) { + (void)mg_printf(conn, "%s", "HTTP/1.1 100 Continue\r\n\r\n"); + conn->status_code = 100; + } else { + conn->status_code = 200; + } + + buffered_len = (int64_t)(conn->data_len) - (int64_t)conn->request_len + - conn->consumed_content; + + /* assert(buffered_len >= 0); */ + /* assert(conn->consumed_content == 0); */ + + if ((buffered_len < 0) || (conn->consumed_content != 0)) { + send_http_error(conn, 500, "%s", "Error: Size mismatch"); + return 0; + } + + if (buffered_len > 0) { + if ((int64_t)buffered_len > conn->content_len) { + buffered_len = (int)conn->content_len; + } + body = conn->buf + conn->request_len + conn->consumed_content; + push_all(conn->ctx, fp, sock, ssl, body, (int64_t)buffered_len); + conn->consumed_content += buffered_len; + } + + nread = 0; + while (conn->consumed_content < conn->content_len) { + to_read = sizeof(buf); + if ((int64_t)to_read > conn->content_len - conn->consumed_content) { + to_read = (int)(conn->content_len - conn->consumed_content); + } + nread = pull(NULL, conn, buf, to_read, timeout); + if (nread <= 0 + || push_all(conn->ctx, fp, sock, ssl, buf, nread) != nread) { + break; + } + conn->consumed_content += nread; + } + + if (conn->consumed_content == conn->content_len) { + success = (nread >= 0); + } + + /* Each error code path in this function must send an error */ + if (!success) { + /* NOTE: Maybe some data has already been sent. */ + /* TODO (low): If some data has been sent, a correct error + * reply can no longer be sent, so just close the connection */ + send_http_error(conn, 500, "%s", ""); + } + } + + return success; +} +#endif + +#if !defined(NO_CGI) +/* This structure helps to create an environment for the spawned CGI program. + * Environment is an array of "VARIABLE=VALUE\0" ASCIIZ strings, + * last element must be NULL. + * However, on Windows there is a requirement that all these VARIABLE=VALUE\0 + * strings must reside in a contiguous buffer. The end of the buffer is + * marked by two '\0' characters. + * We satisfy both worlds: we create an envp array (which is vars), all + * entries are actually pointers inside buf. */ +struct cgi_environment { + struct mg_connection *conn; + /* Data block */ + char *buf; /* Environment buffer */ + size_t buflen; /* Space available in buf */ + size_t bufused; /* Space taken in buf */ + /* Index block */ + char **var; /* char **envp */ + size_t varlen; /* Number of variables available in var */ + size_t varused; /* Number of variables stored in var */ +}; + + +static void addenv(struct cgi_environment *env, + PRINTF_FORMAT_STRING(const char *fmt), + ...) PRINTF_ARGS(2, 3); + +/* Append VARIABLE=VALUE\0 string to the buffer, and add a respective + * pointer into the vars array. Assumes env != NULL and fmt != NULL. */ +static void +addenv(struct cgi_environment *env, const char *fmt, ...) +{ + size_t n, space; + int truncated; + char *added; + va_list ap; + + /* Calculate how much space is left in the buffer */ + space = (env->buflen - env->bufused); + + /* Calculate an estimate for the required space */ + n = strlen(fmt) + 2 + 128; + + do { + if (space <= n) { + /* Allocate new buffer */ + n = env->buflen + CGI_ENVIRONMENT_SIZE; + added = (char *)mg_realloc(env->buf, n); + if (!added) { + /* Out of memory */ + mg_cry(env->conn, + "%s: Cannot allocate memory for CGI variable [%s]", + __func__, + fmt); + return; + } + env->buf = added; + env->buflen = n; + space = (env->buflen - env->bufused); + } + + /* Make a pointer to the free space int the buffer */ + added = env->buf + env->bufused; + + /* Copy VARIABLE=VALUE\0 string into the free space */ + va_start(ap, fmt); + mg_vsnprintf(env->conn, &truncated, added, (size_t)space, fmt, ap); + va_end(ap); + + /* Do not add truncated strings to the environment */ + if (truncated) { + /* Reallocate the buffer */ + space = 0; + n = 1; + } + } while (truncated); + + /* Calculate number of bytes added to the environment */ + n = strlen(added) + 1; + env->bufused += n; + + /* Now update the variable index */ + space = (env->varlen - env->varused); + if (space < 2) { + mg_cry(env->conn, + "%s: Cannot register CGI variable [%s]", + __func__, + fmt); + return; + } + + /* Append a pointer to the added string into the envp array */ + env->var[env->varused] = added; + env->varused++; +} + + +static void +prepare_cgi_environment(struct mg_connection *conn, + const char *prog, + struct cgi_environment *env) +{ + const char *s; + struct vec var_vec; + char *p, src_addr[IP_ADDR_STR_LEN], http_var_name[128]; + int i, truncated; + + if (conn == NULL || prog == NULL || env == NULL) { + return; + } + + env->conn = conn; + env->buflen = CGI_ENVIRONMENT_SIZE; + env->bufused = 0; + env->buf = (char *)mg_malloc(env->buflen); + env->varlen = MAX_CGI_ENVIR_VARS; + env->varused = 0; + env->var = (char **)mg_malloc(env->buflen * sizeof(char *)); + + addenv(env, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]); + addenv(env, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]); + addenv(env, "DOCUMENT_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]); + addenv(env, "SERVER_SOFTWARE=%s/%s", "Civetweb", mg_version()); + + /* Prepare the environment block */ + addenv(env, "%s", "GATEWAY_INTERFACE=CGI/1.1"); + addenv(env, "%s", "SERVER_PROTOCOL=HTTP/1.1"); + addenv(env, "%s", "REDIRECT_STATUS=200"); /* For PHP */ + +#if defined(USE_IPV6) + if (conn->client.lsa.sa.sa_family == AF_INET6) { + addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin6.sin6_port)); + } else +#endif + { + addenv(env, "SERVER_PORT=%d", ntohs(conn->client.lsa.sin.sin_port)); + } + + sockaddr_to_string(src_addr, sizeof(src_addr), &conn->client.rsa); + addenv(env, "REMOTE_ADDR=%s", src_addr); + + addenv(env, "REQUEST_METHOD=%s", conn->request_info.request_method); + addenv(env, "REMOTE_PORT=%d", conn->request_info.remote_port); + + addenv(env, "REQUEST_URI=%s", conn->request_info.request_uri); + addenv(env, "LOCAL_URI=%s", conn->request_info.local_uri); + + /* SCRIPT_NAME */ + addenv(env, + "SCRIPT_NAME=%.*s", + (int)strlen(conn->request_info.local_uri) + - ((conn->path_info == NULL) ? 0 : (int)strlen(conn->path_info)), + conn->request_info.local_uri); + + addenv(env, "SCRIPT_FILENAME=%s", prog); + if (conn->path_info == NULL) { + addenv(env, "PATH_TRANSLATED=%s", conn->ctx->config[DOCUMENT_ROOT]); + } else { + addenv(env, + "PATH_TRANSLATED=%s%s", + conn->ctx->config[DOCUMENT_ROOT], + conn->path_info); + } + + addenv(env, "HTTPS=%s", conn->ssl == NULL ? "off" : "on"); + + if ((s = mg_get_header(conn, "Content-Type")) != NULL) { + addenv(env, "CONTENT_TYPE=%s", s); + } + if (conn->request_info.query_string != NULL) { + addenv(env, "QUERY_STRING=%s", conn->request_info.query_string); + } + if ((s = mg_get_header(conn, "Content-Length")) != NULL) { + addenv(env, "CONTENT_LENGTH=%s", s); + } + if ((s = getenv("PATH")) != NULL) { + addenv(env, "PATH=%s", s); + } + if (conn->path_info != NULL) { + addenv(env, "PATH_INFO=%s", conn->path_info); + } + + if (conn->status_code > 0) { + /* CGI error handler should show the status code */ + addenv(env, "STATUS=%d", conn->status_code); + } + +#if defined(_WIN32) + if ((s = getenv("COMSPEC")) != NULL) { + addenv(env, "COMSPEC=%s", s); + } + if ((s = getenv("SYSTEMROOT")) != NULL) { + addenv(env, "SYSTEMROOT=%s", s); + } + if ((s = getenv("SystemDrive")) != NULL) { + addenv(env, "SystemDrive=%s", s); + } + if ((s = getenv("ProgramFiles")) != NULL) { + addenv(env, "ProgramFiles=%s", s); + } + if ((s = getenv("ProgramFiles(x86)")) != NULL) { + addenv(env, "ProgramFiles(x86)=%s", s); + } +#else + if ((s = getenv("LD_LIBRARY_PATH")) != NULL) { + addenv(env, "LD_LIBRARY_PATH=%s", s); + } +#endif /* _WIN32 */ + + if ((s = getenv("PERLLIB")) != NULL) { + addenv(env, "PERLLIB=%s", s); + } + + if (conn->request_info.remote_user != NULL) { + addenv(env, "REMOTE_USER=%s", conn->request_info.remote_user); + addenv(env, "%s", "AUTH_TYPE=Digest"); + } + + /* Add all headers as HTTP_* variables */ + for (i = 0; i < conn->request_info.num_headers; i++) { + + (void)mg_snprintf(conn, + &truncated, + http_var_name, + sizeof(http_var_name), + "HTTP_%s", + conn->request_info.http_headers[i].name); + + if (truncated) { + mg_cry(conn, + "%s: HTTP header variable too long [%s]", + __func__, + conn->request_info.http_headers[i].name); + continue; + } + + /* Convert variable name into uppercase, and change - to _ */ + for (p = http_var_name; *p != '\0'; p++) { + if (*p == '-') { + *p = '_'; + } + *p = (char)toupper(*(unsigned char *)p); + } + + addenv(env, + "%s=%s", + http_var_name, + conn->request_info.http_headers[i].value); + } + + /* Add user-specified variables */ + s = conn->ctx->config[CGI_ENVIRONMENT]; + while ((s = next_option(s, &var_vec, NULL)) != NULL) { + addenv(env, "%.*s", (int)var_vec.len, var_vec.ptr); + } + + env->var[env->varused] = NULL; + env->buf[env->bufused] = '\0'; +} + + +static void +handle_cgi_request(struct mg_connection *conn, const char *prog) +{ + char *buf; + size_t buflen; + int headers_len, data_len, i, truncated; + int fdin[2] = {-1, -1}, fdout[2] = {-1, -1}, fderr[2] = {-1, -1}; + const char *status, *status_text, *connection_state; + char *pbuf, dir[PATH_MAX], *p; + struct mg_request_info ri; + struct cgi_environment blk; + FILE *in = NULL, *out = NULL, *err = NULL; + struct file fout = STRUCT_FILE_INITIALIZER; + pid_t pid = (pid_t)-1; + + if (conn == NULL) { + return; + } + + buf = NULL; + buflen = 16384; + prepare_cgi_environment(conn, prog, &blk); + + /* CGI must be executed in its own directory. 'dir' must point to the + * directory containing executable program, 'p' must point to the + * executable program name relative to 'dir'. */ + (void)mg_snprintf(conn, &truncated, dir, sizeof(dir), "%s", prog); + + if (truncated) { + mg_cry(conn, "Error: CGI program \"%s\": Path too long", prog); + send_http_error(conn, 500, "Error: %s", "CGI path too long"); + goto done; + } + + if ((p = strrchr(dir, '/')) != NULL) { + *p++ = '\0'; + } else { + dir[0] = '.', dir[1] = '\0'; + p = (char *)prog; + } + + if (pipe(fdin) != 0 || pipe(fdout) != 0 || pipe(fderr) != 0) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not create CGI pipes: %s", + prog, + status); + send_http_error(conn, 500, "Error: Cannot create CGI pipe: %s", status); + goto done; + } + + pid = spawn_process(conn, p, blk.buf, blk.var, fdin, fdout, fderr, dir); + + if (pid == (pid_t)-1) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not spawn CGI process: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: Cannot spawn CGI process [%s]: %s", + prog, + status); + goto done; + } + + /* Make sure child closes all pipe descriptors. It must dup them to 0,1 */ + set_close_on_exec((SOCKET)fdin[0], conn); /* stdin read */ + set_close_on_exec((SOCKET)fdout[1], conn); /* stdout write */ + set_close_on_exec((SOCKET)fderr[1], conn); /* stderr write */ + set_close_on_exec((SOCKET)fdin[1], conn); /* stdin write */ + set_close_on_exec((SOCKET)fdout[0], conn); /* stdout read */ + set_close_on_exec((SOCKET)fderr[0], conn); /* stderr read */ + + /* Parent closes only one side of the pipes. + * If we don't mark them as closed, close() attempt before + * return from this function throws an exception on Windows. + * Windows does not like when closed descriptor is closed again. */ + (void)close(fdin[0]); + (void)close(fdout[1]); + (void)close(fderr[1]); + fdin[0] = fdout[1] = fderr[1] = -1; + + if ((in = fdopen(fdin[1], "wb")) == NULL) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not open stdin: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: CGI can not open fdin\nfopen: %s", + status); + goto done; + } + + if ((out = fdopen(fdout[0], "rb")) == NULL) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not open stdout: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: CGI can not open fdout\nfopen: %s", + status); + goto done; + } + + if ((err = fdopen(fderr[0], "rb")) == NULL) { + status = strerror(ERRNO); + mg_cry(conn, + "Error: CGI program \"%s\": Can not open stderr: %s", + prog, + status); + send_http_error(conn, + 500, + "Error: CGI can not open fdout\nfopen: %s", + status); + goto done; + } + + setbuf(in, NULL); + setbuf(out, NULL); + setbuf(err, NULL); + fout.fp = out; + + if ((conn->request_info.content_length > 0) || conn->is_chunked) { + /* This is a POST/PUT request, or another request with body data. */ + if (!forward_body_data(conn, in, INVALID_SOCKET, NULL)) { + /* Error sending the body data */ + mg_cry(conn, + "Error: CGI program \"%s\": Forward body data failed", + prog); + goto done; + } + } + + /* Close so child gets an EOF. */ + fclose(in); + in = NULL; + fdin[1] = -1; + + /* Now read CGI reply into a buffer. We need to set correct + * status code, thus we need to see all HTTP headers first. + * Do not send anything back to client, until we buffer in all + * HTTP headers. */ + data_len = 0; + buf = (char *)mg_malloc(buflen); + if (buf == NULL) { + send_http_error(conn, + 500, + "Error: Not enough memory for CGI buffer (%u bytes)", + (unsigned int)buflen); + mg_cry(conn, + "Error: CGI program \"%s\": Not enough memory for buffer (%u " + "bytes)", + prog, + (unsigned int)buflen); + goto done; + } + headers_len = read_request(out, conn, buf, (int)buflen, &data_len); + if (headers_len <= 0) { + + /* Could not parse the CGI response. Check if some error message on + * stderr. */ + i = pull_all(err, conn, buf, (int)buflen); + if (i > 0) { + mg_cry(conn, + "Error: CGI program \"%s\" sent error " + "message: [%.*s]", + prog, + i, + buf); + send_http_error(conn, + 500, + "Error: CGI program \"%s\" sent error " + "message: [%.*s]", + prog, + i, + buf); + } else { + mg_cry(conn, + "Error: CGI program sent malformed or too big " + "(>%u bytes) HTTP headers: [%.*s]", + (unsigned)buflen, + data_len, + buf); + + send_http_error(conn, + 500, + "Error: CGI program sent malformed or too big " + "(>%u bytes) HTTP headers: [%.*s]", + (unsigned)buflen, + data_len, + buf); + } + + goto done; + } + pbuf = buf; + buf[headers_len - 1] = '\0'; + parse_http_headers(&pbuf, &ri); + + /* Make up and send the status line */ + status_text = "OK"; + if ((status = get_header(&ri, "Status")) != NULL) { + conn->status_code = atoi(status); + status_text = status; + while (isdigit(*(const unsigned char *)status_text) + || *status_text == ' ') { + status_text++; + } + } else if (get_header(&ri, "Location") != NULL) { + conn->status_code = 302; + } else { + conn->status_code = 200; + } + connection_state = get_header(&ri, "Connection"); + if (!header_has_option(connection_state, "keep-alive")) { + conn->must_close = 1; + } + (void)mg_printf(conn, "HTTP/1.1 %d %s\r\n", conn->status_code, status_text); + + /* Send headers */ + for (i = 0; i < ri.num_headers; i++) { + mg_printf(conn, + "%s: %s\r\n", + ri.http_headers[i].name, + ri.http_headers[i].value); + } + mg_write(conn, "\r\n", 2); + + /* Send chunk of data that may have been read after the headers */ + conn->num_bytes_sent += + mg_write(conn, buf + headers_len, (size_t)(data_len - headers_len)); + + /* Read the rest of CGI output and send to the client */ + send_file_data(conn, &fout, 0, INT64_MAX); + +done: + mg_free(blk.var); + mg_free(blk.buf); + + if (pid != (pid_t)-1) { + kill(pid, SIGKILL); +#if !defined(_WIN32) + { + int st; + while (waitpid(pid, &st, 0) != -1) + ; /* clean zombies */ + } +#endif + } + if (fdin[0] != -1) { + close(fdin[0]); + } + if (fdout[1] != -1) { + close(fdout[1]); + } + + if (in != NULL) { + fclose(in); + } else if (fdin[1] != -1) { + close(fdin[1]); + } + + if (out != NULL) { + fclose(out); + } else if (fdout[0] != -1) { + close(fdout[0]); + } + + if (err != NULL) { + fclose(err); + } else if (fderr[0] != -1) { + close(fderr[0]); + } + + if (buf != NULL) { + mg_free(buf); + } +} +#endif /* !NO_CGI */ + + +#if !defined(NO_FILES) +static void +mkcol(struct mg_connection *conn, const char *path) +{ + int rc, body_len; + struct de de; + char date[64]; + time_t curtime = time(NULL); + + if (conn == NULL) { + return; + } + + /* TODO (mid): Check the send_http_error situations in this function */ + + memset(&de.file, 0, sizeof(de.file)); + if (!mg_stat(conn, path, &de.file)) { + mg_cry(conn, + "%s: mg_stat(%s) failed: %s", + __func__, + path, + strerror(ERRNO)); + } + + if (de.file.last_modified) { + /* TODO (high): This check does not seem to make any sense ! */ + send_http_error( + conn, 405, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + return; + } + + body_len = conn->data_len - conn->request_len; + if (body_len > 0) { + send_http_error( + conn, 415, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + return; + } + + rc = mg_mkdir(conn, path, 0755); + + if (rc == 0) { + conn->status_code = 201; + gmt_time_string(date, sizeof(date), &curtime); + mg_printf(conn, + "HTTP/1.1 %d Created\r\n" + "Date: %s\r\n", + conn->status_code, + date); + send_static_cache_header(conn); + mg_printf(conn, + "Content-Length: 0\r\n" + "Connection: %s\r\n\r\n", + suggest_connection_header(conn)); + } else if (rc == -1) { + if (errno == EEXIST) { + send_http_error( + conn, 405, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + } else if (errno == EACCES) { + send_http_error( + conn, 403, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + } else if (errno == ENOENT) { + send_http_error( + conn, 409, "Error: mkcol(%s): %s", path, strerror(ERRNO)); + } else { + send_http_error(conn, 500, "fopen(%s): %s", path, strerror(ERRNO)); + } + } +} + + +static void +put_file(struct mg_connection *conn, const char *path) +{ + struct file file = STRUCT_FILE_INITIALIZER; + const char *range; + int64_t r1, r2; + int rc; + char date[64]; + time_t curtime = time(NULL); + + if (conn == NULL) { + return; + } + + if (mg_stat(conn, path, &file)) { + /* File already exists */ + conn->status_code = 200; + + if (file.is_directory) { + /* This is an already existing directory, + * so there is nothing to do for the server. */ + rc = 0; + + } else { + /* File exists and is not a directory. */ + /* Can it be replaced? */ + + if (file.membuf != NULL) { + /* This is an "in-memory" file, that can not be replaced */ + send_http_error( + conn, + 405, + "Error: Put not possible\nReplacing %s is not supported", + path); + return; + } + + /* Check if the server may write this file */ + if (access(path, W_OK) == 0) { + /* Access granted */ + conn->status_code = 200; + rc = 1; + } else { + send_http_error( + conn, + 403, + "Error: Put not possible\nReplacing %s is not allowed", + path); + return; + } + } + } else { + /* File should be created */ + conn->status_code = 201; + rc = put_dir(conn, path); + } + + if (rc == 0) { + /* put_dir returns 0 if path is a directory */ + gmt_time_string(date, sizeof(date), &curtime); + mg_printf(conn, + "HTTP/1.1 %d %s\r\n", + conn->status_code, + mg_get_response_code_text(NULL, conn->status_code)); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Content-Length: 0\r\n" + "Connection: %s\r\n\r\n", + date, + suggest_connection_header(conn)); + + /* Request to create a directory has been fulfilled successfully. + * No need to put a file. */ + return; + } + + if (rc == -1) { + /* put_dir returns -1 if the path is too long */ + send_http_error(conn, + 414, + "Error: Path too long\nput_dir(%s): %s", + path, + strerror(ERRNO)); + return; + } + + if (rc == -2) { + /* put_dir returns -2 if the directory can not be created */ + send_http_error(conn, + 500, + "Error: Can not create directory\nput_dir(%s): %s", + path, + strerror(ERRNO)); + return; + } + + /* A file should be created or overwritten. */ + if (!mg_fopen(conn, path, "wb+", &file) || file.fp == NULL) { + mg_fclose(&file); + send_http_error(conn, + 500, + "Error: Can not create file\nfopen(%s): %s", + path, + strerror(ERRNO)); + return; + } + + fclose_on_exec(&file, conn); + range = mg_get_header(conn, "Content-Range"); + r1 = r2 = 0; + if (range != NULL && parse_range_header(range, &r1, &r2) > 0) { + conn->status_code = 206; /* Partial content */ + fseeko(file.fp, r1, SEEK_SET); + } + + if (!forward_body_data(conn, file.fp, INVALID_SOCKET, NULL)) { + /* forward_body_data failed. + * The error code has already been sent to the client, + * and conn->status_code is already set. */ + mg_fclose(&file); + return; + } + + gmt_time_string(date, sizeof(date), &curtime); + mg_printf(conn, + "HTTP/1.1 %d %s\r\n", + conn->status_code, + mg_get_response_code_text(NULL, conn->status_code)); + send_no_cache_header(conn); + mg_printf(conn, + "Date: %s\r\n" + "Content-Length: 0\r\n" + "Connection: %s\r\n\r\n", + date, + suggest_connection_header(conn)); + + mg_fclose(&file); +} + + +static void +delete_file(struct mg_connection *conn, const char *path) +{ + struct de de; + memset(&de.file, 0, sizeof(de.file)); + if (!mg_stat(conn, path, &de.file)) { + /* mg_stat returns 0 if the file does not exist */ + send_http_error(conn, + 404, + "Error: Cannot delete file\nFile %s not found", + path); + return; + } + + if (de.file.membuf != NULL) { + /* the file is cached in memory */ + send_http_error( + conn, + 405, + "Error: Delete not possible\nDeleting %s is not supported", + path); + return; + } + + if (de.file.is_directory) { + if (remove_directory(conn, path)) { + /* Delete is successful: Return 204 without content. */ + send_http_error(conn, 204, "%s", ""); + } else { + /* Delete is not successful: Return 500 (Server error). */ + send_http_error(conn, 500, "Error: Could not delete %s", path); + } + return; + } + + /* This is an existing file (not a directory). + * Check if write permission is granted. */ + if (access(path, W_OK) != 0) { + /* File is read only */ + send_http_error( + conn, + 403, + "Error: Delete not possible\nDeleting %s is not allowed", + path); + return; + } + + /* Try to delete it. */ + if (mg_remove(conn, path) == 0) { + /* Delete was successful: Return 204 without content. */ + send_http_error(conn, 204, "%s", ""); + } else { + /* Delete not successful (file locked). */ + send_http_error(conn, + 423, + "Error: Cannot delete file\nremove(%s): %s", + path, + strerror(ERRNO)); + } +} +#endif /* !NO_FILES */ + + +static void +send_ssi_file(struct mg_connection *, const char *, struct file *, int); + + +static void +do_ssi_include(struct mg_connection *conn, + const char *ssi, + char *tag, + int include_level) +{ + char file_name[MG_BUF_LEN], path[512], *p; + struct file file = STRUCT_FILE_INITIALIZER; + size_t len; + int truncated = 0; + + if (conn == NULL) { + return; + } + + /* sscanf() is safe here, since send_ssi_file() also uses buffer + * of size MG_BUF_LEN to get the tag. So strlen(tag) is + * always < MG_BUF_LEN. */ + if (sscanf(tag, " virtual=\"%511[^\"]\"", file_name) == 1) { + /* File name is relative to the webserver root */ + file_name[511] = 0; + (void)mg_snprintf(conn, + &truncated, + path, + sizeof(path), + "%s/%s", + conn->ctx->config[DOCUMENT_ROOT], + file_name); + + } else if (sscanf(tag, " abspath=\"%511[^\"]\"", file_name) == 1) { + /* File name is relative to the webserver working directory + * or it is absolute system path */ + file_name[511] = 0; + (void) + mg_snprintf(conn, &truncated, path, sizeof(path), "%s", file_name); + + } else if (sscanf(tag, " file=\"%511[^\"]\"", file_name) == 1 + || sscanf(tag, " \"%511[^\"]\"", file_name) == 1) { + /* File name is relative to the currect document */ + file_name[511] = 0; + (void)mg_snprintf(conn, &truncated, path, sizeof(path), "%s", ssi); + + if (!truncated) { + if ((p = strrchr(path, '/')) != NULL) { + p[1] = '\0'; + } + len = strlen(path); + (void)mg_snprintf(conn, + &truncated, + path + len, + sizeof(path) - len, + "%s", + file_name); + } + + } else { + mg_cry(conn, "Bad SSI #include: [%s]", tag); + return; + } + + if (truncated) { + mg_cry(conn, "SSI #include path length overflow: [%s]", tag); + return; + } + + if (!mg_fopen(conn, path, "rb", &file)) { + mg_cry(conn, + "Cannot open SSI #include: [%s]: fopen(%s): %s", + tag, + path, + strerror(ERRNO)); + } else { + fclose_on_exec(&file, conn); + if (match_prefix(conn->ctx->config[SSI_EXTENSIONS], + strlen(conn->ctx->config[SSI_EXTENSIONS]), + path) > 0) { + send_ssi_file(conn, path, &file, include_level + 1); + } else { + send_file_data(conn, &file, 0, INT64_MAX); + } + mg_fclose(&file); + } +} + + +#if !defined(NO_POPEN) +static void +do_ssi_exec(struct mg_connection *conn, char *tag) +{ + char cmd[1024] = ""; + struct file file = STRUCT_FILE_INITIALIZER; + + if (sscanf(tag, " \"%1023[^\"]\"", cmd) != 1) { + mg_cry(conn, "Bad SSI #exec: [%s]", tag); + } else { + cmd[1023] = 0; + if ((file.fp = popen(cmd, "r")) == NULL) { + mg_cry(conn, "Cannot SSI #exec: [%s]: %s", cmd, strerror(ERRNO)); + } else { + send_file_data(conn, &file, 0, INT64_MAX); + pclose(file.fp); + } + } +} +#endif /* !NO_POPEN */ + + +static int +mg_fgetc(struct file *filep, int offset) +{ + if (filep == NULL) { + return EOF; + } + if (filep->membuf != NULL && offset >= 0 + && ((unsigned int)(offset)) < filep->size) { + return ((const unsigned char *)filep->membuf)[offset]; + } else if (filep->fp != NULL) { + return fgetc(filep->fp); + } else { + return EOF; + } +} + + +static void +send_ssi_file(struct mg_connection *conn, + const char *path, + struct file *filep, + int include_level) +{ + char buf[MG_BUF_LEN]; + int ch, offset, len, in_ssi_tag; + + if (include_level > 10) { + mg_cry(conn, "SSI #include level is too deep (%s)", path); + return; + } + + in_ssi_tag = len = offset = 0; + while ((ch = mg_fgetc(filep, offset)) != EOF) { + if (in_ssi_tag && ch == '>') { + in_ssi_tag = 0; + buf[len++] = (char)ch; + buf[len] = '\0'; + /* assert(len <= (int) sizeof(buf)); */ + if (len > (int)sizeof(buf)) { + break; + } + if (len < 6 || memcmp(buf, " + + + + Ventoy2Disk + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + +
+
+ + +
+
+
+ 设备 +
+ +
+ +
+ +
+ +
+
+ +
+
+
+

安装包内 Ventoy 版本

+
+
+ + + +
+
+ +
+
+

设备内部 Ventoy 版本

+
+
+ + + +
+
+
+ +
+ çŠ¶æ€ - 准备就绪 +
+
+
+
+
+ +
+ + +
+
+ + + + + + + +
+
+ +
+ + +
+ + + + + diff --git a/LinuxGUI/WebUI/static/AdminLTE/css/AdminLTE.min.css b/LinuxGUI/WebUI/static/AdminLTE/css/AdminLTE.min.css new file mode 100644 index 00000000..fd35437f --- /dev/null +++ b/LinuxGUI/WebUI/static/AdminLTE/css/AdminLTE.min.css @@ -0,0 +1,8 @@ +/**@import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic); **/ +/*! + * AdminLTE v2.3.0 + * Author: Almsaeed Studio + * Website: Almsaeed Studio + * License: Open source - MIT + * Please visit http://opensource.org/licenses/MIT for more information +!*/html,body{/*min-height:100%*/}.layout-boxed html,.layout-boxed body{height:100%}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:'Arial','Microsoft YaHei','ºÚÌå','ËÎÌå',sans-serif;font-weight:400;overflow-x:hidden;overflow-y:auto}.wrapper{min-height:100%;position:static;overflow:hidden}.wrapper:before,.wrapper:after{content:" ";display:table}.wrapper:after{clear:both}.layout-boxed .wrapper{max-width:1250px;margin:0 auto;min-height:100%;box-shadow:0 0 8px rgba(0,0,0,0.5);position:relative}.layout-boxed{background:url('../img/boxed-bg.jpg') repeat fixed}.content-wrapper,.right-side,.main-footer{-webkit-transition:-webkit-transform .3s ease-in-out,margin .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,margin .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,margin .3s ease-in-out;transition:transform .3s ease-in-out,margin .3s ease-in-out;margin-left:230px;z-index:820}.layout-top-nav .content-wrapper,.layout-top-nav .right-side,.layout-top-nav .main-footer{margin-left:0}@media (max-width:767px){.content-wrapper,.right-side,.main-footer{margin-left:0}}@media (min-width:768px){.sidebar-collapse .content-wrapper,.sidebar-collapse .right-side,.sidebar-collapse .main-footer{margin-left:0}}@media (max-width:767px){.sidebar-open .content-wrapper,.sidebar-open .right-side,.sidebar-open .main-footer{-webkit-transform:translate(230px, 0);-ms-transform:translate(230px, 0);-o-transform:translate(230px, 0);transform:translate(230px, 0)}}.content-wrapper,.right-side{min-height:100%;background-color:#ecf0f5;z-index:800}.main-footer{background:#fff;padding:15px;color:#444;border-top:1px solid #d2d6de}.fixed .main-header,.fixed .main-sidebar,.fixed .left-side{position:fixed}.fixed .main-header{top:0;right:0;left:0}.fixed .content-wrapper,.fixed .right-side{padding-top:50px}@media (max-width:767px){.fixed .content-wrapper,.fixed .right-side{padding-top:100px}}.fixed.layout-boxed .wrapper{max-width:100%}body.hold-transition .content-wrapper,body.hold-transition .right-side,body.hold-transition .main-footer,body.hold-transition .main-sidebar,body.hold-transition .left-side,body.hold-transition .main-header>.navbar,body.hold-transition .main-header .logo{-webkit-transition:none;-o-transition:none;transition:none}.content{min-height:250px;padding:15px;margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:'Arial','Microsoft YaHei','ºÚÌå','ËÎÌå',sans-serif}a{color:#3c8dbc}a:hover,a:active,a:focus{outline:none;text-decoration:none;color:#72afd2}.page-header{margin:10px 0 20px 0;font-size:22px}.page-header>small{color:#666;display:block;margin-top:5px}.main-header{position:relative;max-height:100px;z-index:1030}.main-header>.navbar{-webkit-transition:margin-left .3s ease-in-out;-o-transition:margin-left .3s ease-in-out;transition:margin-left .3s ease-in-out;margin-bottom:0;margin-left:230px;border:none;min-height:50px;border-radius:0}.layout-top-nav .main-header>.navbar{margin-left:0}.main-header #navbar-search-input.form-control{background:rgba(255,255,255,0.2);border-color:transparent}.main-header #navbar-search-input.form-control:focus,.main-header #navbar-search-input.form-control:active{border-color:rgba(0,0,0,0.1);background:rgba(255,255,255,0.9)}.main-header #navbar-search-input.form-control::-moz-placeholder{color:#ccc;opacity:1}.main-header #navbar-search-input.form-control:-ms-input-placeholder{color:#ccc}.main-header #navbar-search-input.form-control::-webkit-input-placeholder{color:#ccc}.main-header .navbar-custom-menu,.main-header .navbar-right{float:right}@media (max-width:991px){.main-header .navbar-custom-menu a,.main-header .navbar-right a{color:inherit;background:transparent}}@media (max-width:767px){.main-header .navbar-right{float:none}.navbar-collapse .main-header .navbar-right{margin:7.5px -15px}.main-header .navbar-right>li{color:inherit;border:0}}.main-header .sidebar-toggle{float:left;background-color:transparent;background-image:none;padding:15px 15px;font-family:fontAwesome}.main-header .sidebar-toggle:before{content:"\f0c9"}.main-header .sidebar-toggle:hover{color:#fff}.main-header .sidebar-toggle:focus,.main-header .sidebar-toggle:active{background:transparent}.main-header .sidebar-toggle .icon-bar{display:none}.main-header .navbar .nav>li.user>a>.fa,.main-header .navbar .nav>li.user>a>.glyphicon,.main-header .navbar .nav>li.user>a>.ion{margin-right:5px}.main-header .navbar .nav>li>a>.label{position:absolute;top:9px;right:7px;text-align:center;font-size:9px;padding:2px 3px;line-height:.9}.main-header .logo{-webkit-transition:width .3s ease-in-out;-o-transition:width .3s ease-in-out;transition:width .3s ease-in-out;display:block;float:left;height:50px;font-size:20px;line-height:50px;text-align:center;width:230px;font-family:'Arial','Microsoft YaHei','ºÚÌå','ËÎÌå',sans-serif;padding:0 15px;font-weight:300;overflow:hidden}.main-header .logo .logo-lg{display:block}.main-header .logo .logo-mini{display:none}.main-header .navbar-brand{color:#fff}.content-header{position:relative;padding:15px 15px 0 15px}.content-header>h1{margin:0;font-size:24px}.content-header>h1>small{font-size:15px;display:inline-block;padding-left:4px;font-weight:300}.content-header>.breadcrumb{float:right;background:transparent;margin-top:0;margin-bottom:0;font-size:12px;padding:7px 5px;position:absolute;top:15px;right:10px;border-radius:2px}.content-header>.breadcrumb>li>a{color:#444;text-decoration:none;display:inline-block}.content-header>.breadcrumb>li>a>.fa,.content-header>.breadcrumb>li>a>.glyphicon,.content-header>.breadcrumb>li>a>.ion{margin-right:5px}.content-header>.breadcrumb>li+li:before{content:'>\00a0'}@media (max-width:991px){.content-header>.breadcrumb{position:relative;margin-top:5px;top:0;right:0;float:none;background:#d2d6de;padding-left:10px}.content-header>.breadcrumb li:before{color:#97a0b3}}.navbar-toggle{color:#fff;border:0;margin:0;padding:15px 15px}@media (max-width:991px){.navbar-custom-menu .navbar-nav>li{float:left}.navbar-custom-menu .navbar-nav{margin:0;float:left}.navbar-custom-menu .navbar-nav>li>a{padding-top:15px;padding-bottom:15px;line-height:20px}}@media (max-width:767px){.main-header{position:relative}.main-header .logo,.main-header .navbar{width:100%;float:none}.main-header .navbar{margin:0}.main-header .navbar-custom-menu{float:right}}@media (max-width:991px){.navbar-collapse.pull-left{float:none!important}.navbar-collapse.pull-left+.navbar-custom-menu{display:block;position:absolute;top:0;right:40px}}.main-sidebar,.left-side{position:absolute;top:0;left:0;padding-top:50px;min-height:100%;width:230px;z-index:810;-webkit-transition:-webkit-transform .3s ease-in-out,width .3s ease-in-out;-moz-transition:-moz-transform .3s ease-in-out,width .3s ease-in-out;-o-transition:-o-transform .3s ease-in-out,width .3s ease-in-out;transition:transform .3s ease-in-out,width .3s ease-in-out}@media (max-width:767px){.main-sidebar,.left-side{padding-top:100px}}@media (max-width:767px){.main-sidebar,.left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (min-width:768px){.sidebar-collapse .main-sidebar,.sidebar-collapse .left-side{-webkit-transform:translate(-230px, 0);-ms-transform:translate(-230px, 0);-o-transform:translate(-230px, 0);transform:translate(-230px, 0)}}@media (max-width:767px){.sidebar-open .main-sidebar,.sidebar-open .left-side{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}}.sidebar{padding-bottom:10px}.sidebar-form input:focus{border-color:transparent}.user-panel{position:relative;width:100%;padding:10px;overflow:hidden}.user-panel:before,.user-panel:after{content:" ";display:table}.user-panel:after{clear:both}.user-panel>.image>img{width:100%;max-width:45px;height:auto}.user-panel>.info{padding:5px 5px 5px 15px;line-height:1;position:absolute;left:55px}.user-panel>.info>p{font-weight:600;margin-bottom:9px}.user-panel>.info>a{text-decoration:none;padding-right:5px;margin-top:3px;font-size:11px}.user-panel>.info>a>.fa,.user-panel>.info>a>.ion,.user-panel>.info>a>.glyphicon{margin-right:3px}.sidebar-menu{list-style:none;margin:0;padding:0}.sidebar-menu>li{position:relative;margin:0;padding:0}.sidebar-menu>li>a{padding:12px 5px 12px 15px;display:block}.sidebar-menu>li>a>.fa,.sidebar-menu>li>a>.glyphicon,.sidebar-menu>li>a>.ion{width:20px}.sidebar-menu>li .label,.sidebar-menu>li .badge{margin-top:3px;margin-right:5px}.sidebar-menu li.header{padding:10px 25px 10px 15px;font-size:12px}.sidebar-menu li>a>.fa-angle-left{width:auto;height:auto;padding:0;margin-right:10px;margin-top:3px}.sidebar-menu li.active>a>.fa-angle-left{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg)}.sidebar-menu li.active>.treeview-menu{display:block}.sidebar-menu .treeview-menu{display:none;list-style:none;padding:0;margin:0;padding-left:5px}.sidebar-menu .treeview-menu .treeview-menu{padding-left:20px}.sidebar-menu .treeview-menu>li{margin:0}.sidebar-menu .treeview-menu>li>a{padding:5px 5px 5px 15px;display:block;font-size:14px}.sidebar-menu .treeview-menu>li>a>.fa,.sidebar-menu .treeview-menu>li>a>.glyphicon,.sidebar-menu .treeview-menu>li>a>.ion{width:20px}.sidebar-menu .treeview-menu>li>a>.fa-angle-left,.sidebar-menu .treeview-menu>li>a>.fa-angle-down{width:auto}@media (min-width:768px){.sidebar-mini.sidebar-collapse .content-wrapper,.sidebar-mini.sidebar-collapse .right-side,.sidebar-mini.sidebar-collapse .main-footer{margin-left:50px!important;z-index:840}.sidebar-mini.sidebar-collapse .main-sidebar{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);width:50px!important;z-index:850}.sidebar-mini.sidebar-collapse .sidebar-menu>li{position:relative}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a{margin-right:0}.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span{border-top-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:not(.treeview)>a>span{border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu{padding-top:5px;padding-bottom:5px;border-bottom-right-radius:4px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span:not(.pull-right),.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{display:block!important;position:absolute;width:180px;left:50px}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>a>span{top:0;margin-left:-3px;padding:12px 5px 12px 20px;background-color:inherit}.sidebar-mini.sidebar-collapse .sidebar-menu>li:hover>.treeview-menu{top:44px;margin-left:0}.sidebar-mini.sidebar-collapse .main-sidebar .user-panel>.info,.sidebar-mini.sidebar-collapse .sidebar-form,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>span,.sidebar-mini.sidebar-collapse .sidebar-menu>li>.treeview-menu,.sidebar-mini.sidebar-collapse .sidebar-menu>li>a>.pull-right,.sidebar-mini.sidebar-collapse .sidebar-menu li.header{display:none!important;-webkit-transform:translateZ(0)}.sidebar-mini.sidebar-collapse .main-header .logo{width:50px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-mini{display:block;margin-left:-15px;margin-right:-15px;font-size:18px}.sidebar-mini.sidebar-collapse .main-header .logo>.logo-lg{display:none}.sidebar-mini.sidebar-collapse .main-header .navbar{margin-left:50px}}.sidebar-menu,.main-sidebar .user-panel,.sidebar-menu>li.header{white-space:nowrap;overflow:hidden}.sidebar-menu:hover{overflow:visible}.sidebar-form,.sidebar-menu>li.header{overflow:hidden;text-overflow:clip}.sidebar-menu li>a{position:relative}.sidebar-menu li>a>.pull-right{position:absolute;top:50%;right:10px;margin-top:-7px}.control-sidebar-bg{position:fixed;z-index:1000;bottom:0}.control-sidebar-bg,.control-sidebar{top:0;right:-230px;width:230px;-webkit-transition:right .3s ease-in-out;-o-transition:right .3s ease-in-out;transition:right .3s ease-in-out}.control-sidebar{position:absolute;padding-top:50px;z-index:1010}@media (max-width:768px){.control-sidebar{padding-top:100px}}.control-sidebar>.tab-content{padding:10px 15px}.control-sidebar.control-sidebar-open,.control-sidebar.control-sidebar-open+.control-sidebar-bg{right:0}.control-sidebar-open .control-sidebar-bg,.control-sidebar-open .control-sidebar{right:0}@media (min-width:768px){.control-sidebar-open .content-wrapper,.control-sidebar-open .right-side,.control-sidebar-open .main-footer{margin-right:230px}}.nav-tabs.control-sidebar-tabs>li:first-of-type>a,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:hover,.nav-tabs.control-sidebar-tabs>li:first-of-type>a:focus{border-left-width:0}.nav-tabs.control-sidebar-tabs>li>a{border-radius:0}.nav-tabs.control-sidebar-tabs>li>a,.nav-tabs.control-sidebar-tabs>li>a:hover{border-top:none;border-right:none;border-left:1px solid transparent;border-bottom:1px solid transparent}.nav-tabs.control-sidebar-tabs>li>a .icon{font-size:16px}.nav-tabs.control-sidebar-tabs>li.active>a,.nav-tabs.control-sidebar-tabs>li.active>a:hover,.nav-tabs.control-sidebar-tabs>li.active>a:focus,.nav-tabs.control-sidebar-tabs>li.active>a:active{border-top:none;border-right:none;border-bottom:none}@media (max-width:768px){.nav-tabs.control-sidebar-tabs{display:table}.nav-tabs.control-sidebar-tabs>li{display:table-cell}}.control-sidebar-heading{font-weight:400;font-size:16px;padding:10px 0;margin-bottom:10px}.control-sidebar-subheading{display:block;font-weight:400;font-size:14px}.control-sidebar-menu{list-style:none;padding:0;margin:0 -15px}.control-sidebar-menu>li>a{display:block;padding:10px 15px}.control-sidebar-menu>li>a:before,.control-sidebar-menu>li>a:after{content:" ";display:table}.control-sidebar-menu>li>a:after{clear:both}.control-sidebar-menu>li>a>.control-sidebar-subheading{margin-top:0}.control-sidebar-menu .menu-icon{float:left;width:35px;height:35px;border-radius:50%;text-align:center;line-height:35px}.control-sidebar-menu .menu-info{margin-left:45px;margin-top:3px}.control-sidebar-menu .menu-info>.control-sidebar-subheading{margin:0}.control-sidebar-menu .menu-info>p{margin:0;font-size:11px}.control-sidebar-menu .progress{margin:0}.control-sidebar-dark{color:#b8c7ce}.control-sidebar-dark,.control-sidebar-dark+.control-sidebar-bg{background:#222d32}.control-sidebar-dark .nav-tabs.control-sidebar-tabs{border-bottom:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a{background:#181f23;color:#b8c7ce}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#141a1d;border-bottom-color:#141a1d}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:active{background:#1c2529}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li>a:hover{color:#fff}.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-dark .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#222d32;color:#fff}.control-sidebar-dark .control-sidebar-heading,.control-sidebar-dark .control-sidebar-subheading{color:#fff}.control-sidebar-dark .control-sidebar-menu>li>a:hover{background:#1e282c}.control-sidebar-dark .control-sidebar-menu>li>a .menu-info>p{color:#b8c7ce}.control-sidebar-light{color:#5e5e5e}.control-sidebar-light,.control-sidebar-light+.control-sidebar-bg{background:#f9fafc;border-left:1px solid #d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs{border-bottom:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a{background:#e8ecf4;color:#444}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus{border-left-color:#d2d6de;border-bottom-color:#d2d6de}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li>a:active{background:#eff1f7}.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:hover,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:focus,.control-sidebar-light .nav-tabs.control-sidebar-tabs>li.active>a:active{background:#f9fafc;color:#111}.control-sidebar-light .control-sidebar-heading,.control-sidebar-light .control-sidebar-subheading{color:#111}.control-sidebar-light .control-sidebar-menu{margin-left:-14px}.control-sidebar-light .control-sidebar-menu>li>a:hover{background:#f4f4f5}.control-sidebar-light .control-sidebar-menu>li>a .menu-info>p{color:#5e5e5e}.dropdown-menu{box-shadow:none;border-color:#eee}.dropdown-menu>li>a{color:#777}.dropdown-menu>li>a>.glyphicon,.dropdown-menu>li>a>.fa,.dropdown-menu>li>a>.ion{margin-right:10px}.dropdown-menu>li>a:hover{background-color:#e1e3e9;color:#333}.dropdown-menu>.divider{background-color:#eee}.navbar-nav>.notifications-menu>.dropdown-menu,.navbar-nav>.messages-menu>.dropdown-menu,.navbar-nav>.tasks-menu>.dropdown-menu{width:280px;padding:0 0 0 0;margin:0;top:100%}.navbar-nav>.notifications-menu>.dropdown-menu>li,.navbar-nav>.messages-menu>.dropdown-menu>li,.navbar-nav>.tasks-menu>.dropdown-menu>li{position:relative}.navbar-nav>.notifications-menu>.dropdown-menu>li.header,.navbar-nav>.messages-menu>.dropdown-menu>li.header,.navbar-nav>.tasks-menu>.dropdown-menu>li.header{border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0;background-color:#ffffff;padding:7px 10px;border-bottom:1px solid #f4f4f4;color:#444444;font-size:14px}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px;font-size:12px;background-color:#fff;padding:7px 10px;border-bottom:1px solid #eeeeee;color:#444!important;text-align:center}@media (max-width:991px){.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a{background:#fff!important;color:#444!important}}.navbar-nav>.notifications-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li.footer>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li.footer>a:hover{text-decoration:none;font-weight:normal}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu,.navbar-nav>.messages-menu>.dropdown-menu>li .menu,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu{max-height:200px;margin:0;padding:0;list-style:none;overflow-x:hidden}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{display:block;white-space:nowrap;border-bottom:1px solid #f4f4f4}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:hover,.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a:hover{background:#f4f4f4;text-decoration:none}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a{color:#444444;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;padding:10px}.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.glyphicon,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.fa,.navbar-nav>.notifications-menu>.dropdown-menu>li .menu>li>a>.ion{width:20px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a{margin:0;padding:10px 10px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>div>img{margin:auto 10px auto auto;width:40px;height:40px}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4{padding:0;margin:0 0 0 45px;color:#444444;font-size:15px;position:relative}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>h4>small{color:#999999;font-size:10px;position:absolute;top:0;right:0}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a>p{margin:0 0 0 45px;font-size:12px;color:#888888}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:before,.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{content:" ";display:table}.navbar-nav>.messages-menu>.dropdown-menu>li .menu>li>a:after{clear:both}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a{padding:10px}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>h3{font-size:14px;padding:0;margin:0 0 10px 0;color:#666666}.navbar-nav>.tasks-menu>.dropdown-menu>li .menu>li>a>.progress{padding:0;margin:0}.navbar-nav>.user-menu>.dropdown-menu{border-top-right-radius:0;border-top-left-radius:0;padding:1px 0 0 0;border-top-width:0;width:280px}.navbar-nav>.user-menu>.dropdown-menu,.navbar-nav>.user-menu>.dropdown-menu>.user-body{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header{height:175px;padding:10px;text-align:center}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>img{z-index:5;height:90px;width:90px;border:3px solid;border-color:transparent;border-color:rgba(255,255,255,0.2)}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p{z-index:5;color:#fff;color:rgba(255,255,255,0.8);font-size:17px;margin-top:10px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p>small{display:block;font-size:12px}.navbar-nav>.user-menu>.dropdown-menu>.user-body{padding:15px;border-bottom:1px solid #f4f4f4;border-top:1px solid #dddddd}.navbar-nav>.user-menu>.dropdown-menu>.user-body:before,.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-body a{color:#444 !important}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-body a{background:#fff !important;color:#444 !important}}.navbar-nav>.user-menu>.dropdown-menu>.user-footer{background-color:#f9f9f9;padding:10px}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:before,.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{content:" ";display:table}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{clear:both}.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default{color:#666666}@media (max-width:991px){.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default:hover{background-color:#f9f9f9}}.navbar-nav>.user-menu .user-image{float:left;width:25px;height:25px;border-radius:50%;margin-right:10px;margin-top:-2px}@media (max-width:767px){.navbar-nav>.user-menu .user-image{float:none;margin-right:0;margin-top:-8px;line-height:10px}}.open:not(.dropup)>.animated-dropdown-menu{backface-visibility:visible !important;-webkit-animation:flipInX .7s both;-o-animation:flipInX .7s both;animation:flipInX .7s both}@keyframes flipInX{0%{transform:perspective(400px) rotate3d(1, 0, 0, 90deg);transition-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotate3d(1, 0, 0, -20deg);transition-timing-function:ease-in}60%{transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{transform:perspective(400px)}}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 90deg);-webkit-transition-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -20deg);-webkit-transition-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, 10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotate3d(1, 0, 0, -5deg)}100%{-webkit-transform:perspective(400px)}}.navbar-custom-menu>.navbar-nav>li{position:relative}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:0;left:auto}@media (max-width:991px){.navbar-custom-menu>.navbar-nav{float:right}.navbar-custom-menu>.navbar-nav>li{position:static}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:5%;left:auto;border:1px solid #ddd;background:#fff}}.form-control{border-radius:0;box-shadow:none;border-color:#d2d6de}.form-control:focus{border-color:#3c8dbc;box-shadow:none}.form-control::-moz-placeholder,.form-control:-ms-input-placeholder,.form-control::-webkit-input-placeholder{color:#bbb;opacity:1}.form-control:not(select){-webkit-appearance:none;-moz-appearance:none;appearance:none}.form-group.has-success label{color:#00a65a}.form-group.has-success .form-control{border-color:#00a65a;box-shadow:none}.form-group.has-warning label{color:#f39c12}.form-group.has-warning .form-control{border-color:#f39c12;box-shadow:none}.form-group.has-error label{color:#dd4b39}.form-group.has-error .form-control{border-color:#dd4b39;box-shadow:none}.input-group .input-group-addon{border-radius:0;border-color:#d2d6de;background-color:#fff}.btn-group-vertical .btn.btn-flat:first-of-type,.btn-group-vertical .btn.btn-flat:last-of-type{border-radius:0}.icheck>label{padding-left:0}.form-control-feedback.fa{line-height:34px}.input-lg+.form-control-feedback.fa,.input-group-lg+.form-control-feedback.fa,.form-group-lg .form-control+.form-control-feedback.fa{line-height:46px}.input-sm+.form-control-feedback.fa,.input-group-sm+.form-control-feedback.fa,.form-group-sm .form-control+.form-control-feedback.fa{line-height:30px}.progress,.progress>.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress,.progress>.progress-bar,.progress .progress-bar,.progress>.progress-bar .progress-bar{border-radius:1px}.progress.sm,.progress-sm{height:10px}.progress.sm,.progress-sm,.progress.sm .progress-bar,.progress-sm .progress-bar{border-radius:1px}.progress.xs,.progress-xs{height:7px}.progress.xs,.progress-xs,.progress.xs .progress-bar,.progress-xs .progress-bar{border-radius:1px}.progress.xxs,.progress-xxs{height:3px}.progress.xxs,.progress-xxs,.progress.xxs .progress-bar,.progress-xxs .progress-bar{border-radius:1px}.progress.vertical{position:relative;width:30px;height:200px;display:inline-block;margin-right:10px}.progress.vertical>.progress-bar{width:100%;position:absolute;bottom:0}.progress.vertical.sm,.progress.vertical.progress-sm{width:20px}.progress.vertical.xs,.progress.vertical.progress-xs{width:10px}.progress.vertical.xxs,.progress.vertical.progress-xxs{width:3px}.progress-group .progress-text{font-weight:600}.progress-group .progress-number{float:right}.table tr>td .progress{margin:0}.progress-bar-light-blue,.progress-bar-primary{background-color:#3c8dbc}.progress-striped .progress-bar-light-blue,.progress-striped .progress-bar-primary{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-green,.progress-bar-success{background-color:#00a65a}.progress-striped .progress-bar-green,.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-aqua,.progress-bar-info{background-color:#00c0ef}.progress-striped .progress-bar-aqua,.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-yellow,.progress-bar-warning{background-color:#f39c12}.progress-striped .progress-bar-yellow,.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-red,.progress-bar-danger{background-color:#dd4b39}.progress-striped .progress-bar-red,.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.small-box{border-radius:2px;position:relative;display:block;margin-bottom:20px;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.small-box>.inner{padding:10px}.small-box>.small-box-footer{position:relative;text-align:center;padding:3px 0;color:#fff;color:rgba(255,255,255,0.8);display:block;z-index:10;background:rgba(0,0,0,0.1);text-decoration:none}.small-box>.small-box-footer:hover{color:#fff;background:rgba(0,0,0,0.15)}.small-box h3{font-size:38px;font-weight:bold;margin:0 0 10px 0;white-space:nowrap;padding:0}.small-box p{font-size:15px}.small-box p>small{display:block;color:#f9f9f9;font-size:13px;margin-top:5px}.small-box h3,.small-box p{z-index:5px}.small-box .icon{-webkit-transition:all .3s linear;-o-transition:all .3s linear;transition:all .3s linear;position:absolute;top:-10px;right:10px;z-index:0;font-size:90px;color:rgba(0,0,0,0.15)}.small-box:hover{text-decoration:none;color:#f9f9f9}.small-box:hover .icon{font-size:95px}@media (max-width:767px){.small-box{text-align:center}.small-box .icon{display:none}.small-box p{font-size:12px}}.box{position:relative;border-radius:3px;background:#ffffff;border-top:3px solid #d2d6de;margin-bottom:20px;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1)}.box.box-primary{border-top-color:#3c8dbc}.box.box-info{border-top-color:#00c0ef}.box.box-danger{border-top-color:#dd4b39}.box.box-warning{border-top-color:#f39c12}.box.box-success{border-top-color:#00a65a}.box.box-default{border-top-color:#d2d6de}.box.collapsed-box .box-body,.box.collapsed-box .box-footer{display:none}.box .nav-stacked>li{border-bottom:1px solid #f4f4f4;margin:0}.box .nav-stacked>li:last-of-type{border-bottom:none}.box.height-control .box-body{max-height:300px;overflow:auto}.box .border-right{border-right:1px solid #f4f4f4}.box .border-left{border-left:1px solid #f4f4f4}.box.box-solid{border-top:0}.box.box-solid>.box-header .btn.btn-default{background:transparent}.box.box-solid>.box-header .btn:hover,.box.box-solid>.box-header a:hover{background:rgba(0,0,0,0.1)}.box.box-solid.box-default{border:1px solid #d2d6de}.box.box-solid.box-default>.box-header{color:#444;background:#d2d6de;background-color:#d2d6de}.box.box-solid.box-default>.box-header a,.box.box-solid.box-default>.box-header .btn{color:#444}.box.box-solid.box-primary{border:1px solid #3c8dbc}.box.box-solid.box-primary>.box-header{color:#fff;background:#3c8dbc;background-color:#3c8dbc}.box.box-solid.box-primary>.box-header a,.box.box-solid.box-primary>.box-header .btn{color:#fff}.box.box-solid.box-info{border:1px solid #00c0ef}.box.box-solid.box-info>.box-header{color:#fff;background:#00c0ef;background-color:#00c0ef}.box.box-solid.box-info>.box-header a,.box.box-solid.box-info>.box-header .btn{color:#fff}.box.box-solid.box-danger{border:1px solid #dd4b39}.box.box-solid.box-danger>.box-header{color:#fff;background:#dd4b39;background-color:#dd4b39}.box.box-solid.box-danger>.box-header a,.box.box-solid.box-danger>.box-header .btn{color:#fff}.box.box-solid.box-warning{border:1px solid #f39c12}.box.box-solid.box-warning>.box-header{color:#fff;background:#f39c12;background-color:#f39c12}.box.box-solid.box-warning>.box-header a,.box.box-solid.box-warning>.box-header .btn{color:#fff}.box.box-solid.box-success{border:1px solid #00a65a}.box.box-solid.box-success>.box-header{color:#fff;background:#00a65a;background-color:#00a65a}.box.box-solid.box-success>.box-header a,.box.box-solid.box-success>.box-header .btn{color:#fff}.box.box-solid>.box-header>.box-tools .btn{border:0;box-shadow:none}.box.box-solid[class*='bg']>.box-header{color:#fff}.box .box-group>.box{margin-bottom:5px}.box .knob-label{text-align:center;color:#333;font-weight:100;font-size:12px;margin-bottom:0.3em}.box>.overlay,.overlay-wrapper>.overlay,.box>.loading-img,.overlay-wrapper>.loading-img{position:absolute;top:0;left:0;width:100%;height:100%}.box .overlay,.overlay-wrapper .overlay{z-index:50;background:rgba(255,255,255,0.7);border-radius:3px}.box .overlay>.fa,.overlay-wrapper .overlay>.fa{position:absolute;top:50%;left:50%;margin-left:-15px;margin-top:-15px;color:#000;font-size:30px}.box .overlay.dark,.overlay-wrapper .overlay.dark{background:rgba(0,0,0,0.5)}.box-header:before,.box-body:before,.box-footer:before,.box-header:after,.box-body:after,.box-footer:after{content:" ";display:table}.box-header:after,.box-body:after,.box-footer:after{clear:both}.box-header{color:#444;display:block;padding:10px;position:relative}.box-header.with-border{border-bottom:1px solid #f4f4f4}.collapsed-box .box-header.with-border{border-bottom:none}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion,.box-header .box-title{display:inline-block;font-size:18px;margin:0;line-height:1}.box-header>.fa,.box-header>.glyphicon,.box-header>.ion{margin-right:5px}.box-header>.box-tools{position:absolute;right:10px;top:5px}.box-header>.box-tools [data-toggle="tooltip"]{position:relative}.box-header>.box-tools.pull-right .dropdown-menu{right:0;left:auto}.btn-box-tool{padding:5px;font-size:12px;background:transparent;color:#97a0b3}.open .btn-box-tool,.btn-box-tool:hover{color:#606c84}.btn-box-tool.btn:active{box-shadow:none}.box-body{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;padding:10px}.no-header .box-body{border-top-right-radius:3px;border-top-left-radius:3px}.box-body>.table{margin-bottom:0}.box-body .fc{margin-top:5px}.box-body .full-width-chart{margin:-19px}.box-body.no-padding .full-width-chart{margin:-9px}.box-body .box-pane{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:3px}.box-body .box-pane-right{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:0}.box-footer{border-top-left-radius:0;border-top-right-radius:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px;border-top:1px solid #f4f4f4;padding:10px;background-color:#fff}.chart-legend{margin:10px 0}@media (max-width:991px){.chart-legend>li{float:left;margin-right:10px}}.box-comments{background:#f7f7f7}.box-comments .box-comment{padding:8px 0;border-bottom:1px solid #eee}.box-comments .box-comment:before,.box-comments .box-comment:after{content:" ";display:table}.box-comments .box-comment:after{clear:both}.box-comments .box-comment:last-of-type{border-bottom:0}.box-comments .box-comment:first-of-type{padding-top:0}.box-comments .box-comment img{float:left}.box-comments .comment-text{margin-left:40px;color:#555}.box-comments .username{color:#444;display:block;font-weight:600}.box-comments .text-muted{font-weight:400;font-size:12px}.todo-list{margin:0;padding:0;list-style:none;overflow:auto}.todo-list>li{border-radius:2px;padding:10px;background:#f4f4f4;margin-bottom:2px;border-left:2px solid #e6e7e8;color:#444}.todo-list>li:last-of-type{margin-bottom:0}.todo-list>li>input[type='checkbox']{margin:0 10px 0 5px}.todo-list>li .text{display:inline-block;margin-left:5px;font-weight:600}.todo-list>li .label{margin-left:10px;font-size:9px}.todo-list>li .tools{display:none;float:right;color:#dd4b39}.todo-list>li .tools>.fa,.todo-list>li .tools>.glyphicon,.todo-list>li .tools>.ion{margin-right:5px;cursor:pointer}.todo-list>li:hover .tools{display:inline-block}.todo-list>li.done{color:#999}.todo-list>li.done .text{text-decoration:line-through;font-weight:500}.todo-list>li.done .label{background:#d2d6de !important}.todo-list .danger{border-left-color:#dd4b39}.todo-list .warning{border-left-color:#f39c12}.todo-list .info{border-left-color:#00c0ef}.todo-list .success{border-left-color:#00a65a}.todo-list .primary{border-left-color:#3c8dbc}.todo-list .handle{display:inline-block;cursor:move;margin:0 5px}.chat{padding:5px 20px 5px 10px}.chat .item{margin-bottom:10px}.chat .item:before,.chat .item:after{content:" ";display:table}.chat .item:after{clear:both}.chat .item>img{width:40px;height:40px;border:2px solid transparent;border-radius:50%}.chat .item>.online{border:2px solid #00a65a}.chat .item>.offline{border:2px solid #dd4b39}.chat .item>.message{margin-left:55px;margin-top:-40px}.chat .item>.message>.name{display:block;font-weight:600}.chat .item>.attachment{border-radius:3px;background:#f4f4f4;margin-left:65px;margin-right:15px;padding:10px}.chat .item>.attachment>h4{margin:0 0 5px 0;font-weight:600;font-size:14px}.chat .item>.attachment>p,.chat .item>.attachment>.filename{font-weight:600;font-size:13px;font-style:italic;margin:0}.chat .item>.attachment:before,.chat .item>.attachment:after{content:" ";display:table}.chat .item>.attachment:after{clear:both}.box-input{max-width:200px}.modal .panel-body{color:#444}.info-box{display:block;min-height:90px;background:#fff;width:100%;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:2px;margin-bottom:15px}.info-box small{font-size:14px}.info-box .progress{background:rgba(0,0,0,0.2);margin:5px -10px 5px -10px;height:2px}.info-box .progress,.info-box .progress .progress-bar{border-radius:0}.info-box .progress .progress-bar{background:#fff}.info-box-icon{border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px;display:block;float:left;height:90px;width:90px;text-align:center;font-size:45px;line-height:90px;background:rgba(0,0,0,0.2)}.info-box-icon>img{max-width:100%}.info-box-content{padding:5px 10px;margin-left:90px}.info-box-number{display:block;font-weight:bold;font-size:18px}.progress-description,.info-box-text{display:block;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.info-box-text{text-transform:uppercase}.info-box-more{display:block}.progress-description{margin:0}.timeline{position:relative;margin:0 0 30px 0;padding:0;list-style:none}.timeline:before{content:'';position:absolute;top:0;bottom:0;width:4px;background:#ddd;left:31px;margin:0;border-radius:2px}.timeline>li{position:relative;margin-right:10px;margin-bottom:15px}.timeline>li:before,.timeline>li:after{content:" ";display:table}.timeline>li:after{clear:both}.timeline>li>.timeline-item{-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;margin-top:0;background:#fff;color:#444;margin-left:60px;margin-right:15px;padding:0;position:relative}.timeline>li>.timeline-item>.time{color:#999;float:right;padding:10px;font-size:12px}.timeline>li>.timeline-item>.timeline-header{margin:0;color:#555;border-bottom:1px solid #f4f4f4;padding:10px;font-size:16px;line-height:1.1}.timeline>li>.timeline-item>.timeline-header>a{font-weight:600}.timeline>li>.timeline-item>.timeline-body,.timeline>li>.timeline-item>.timeline-footer{padding:10px}.timeline>li>.fa,.timeline>li>.glyphicon,.timeline>li>.ion{width:30px;height:30px;font-size:15px;line-height:30px;position:absolute;color:#666;background:#d2d6de;border-radius:50%;text-align:center;left:18px;top:0}.timeline>.time-label>span{font-weight:600;padding:5px;display:inline-block;background-color:#fff;border-radius:4px}.timeline-inverse>li>.timeline-item{background:#f0f0f0;border:1px solid #ddd;-webkit-box-shadow:none;box-shadow:none}.timeline-inverse>li>.timeline-item>.timeline-header{border-bottom-color:#ddd}.btn{border-radius:3px;-webkit-box-shadow:none;box-shadow:none;border:1px solid transparent}.btn.uppercase{text-transform:uppercase}.btn.btn-flat{border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;border-width:1px}.btn:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn:focus{outline:none}.btn.btn-file{position:relative;overflow:hidden}.btn.btn-file>input[type='file']{position:absolute;top:0;right:0;min-width:100%;min-height:100%;font-size:100px;text-align:right;opacity:0;filter:alpha(opacity=0);outline:none;background:white;cursor:inherit;display:block}.btn-default{background-color:#f4f4f4;color:#444;border-color:#ddd}.btn-default:hover,.btn-default:active,.btn-default.hover{background-color:#e7e7e7}.btn-primary{background-color:#3c8dbc;border-color:#367fa9}.btn-primary:hover,.btn-primary:active,.btn-primary.hover{background-color:#367fa9}.btn-success{background-color:#00a65a;border-color:#008d4c}.btn-success:hover,.btn-success:active,.btn-success.hover{background-color:#008d4c}.btn-info{background-color:#00c0ef;border-color:#00acd6}.btn-info:hover,.btn-info:active,.btn-info.hover{background-color:#00acd6}.btn-danger{background-color:#dd4b39;border-color:#d73925}.btn-danger:hover,.btn-danger:active,.btn-danger.hover{background-color:#d73925}.btn-warning{background-color:#f39c12;border-color:#e08e0b}.btn-warning:hover,.btn-warning:active,.btn-warning.hover{background-color:#e08e0b}.btn-outline{border:1px solid #fff;background:transparent;color:#fff}.btn-outline:hover,.btn-outline:focus,.btn-outline:active{color:rgba(255,255,255,0.7);border-color:rgba(255,255,255,0.7)}.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn[class*='bg-']:hover{-webkit-box-shadow:inset 0 0 100px rgba(0,0,0,0.2);box-shadow:inset 0 0 100px rgba(0,0,0,0.2)}.btn-app{border-radius:3px;position:relative;padding:15px 5px;margin:0 0 10px 10px;min-width:80px;height:60px;text-align:center;color:#666;border:1px solid #ddd;background-color:#f4f4f4;font-size:12px}.btn-app>.fa,.btn-app>.glyphicon,.btn-app>.ion{font-size:20px;display:block}.btn-app:hover{background:#f4f4f4;color:#444;border-color:#aaa}.btn-app:active,.btn-app:focus{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);-moz-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-app>.badge{position:absolute;top:-3px;right:-10px;font-size:10px;font-weight:400}.callout{border-radius:3px;margin:0 0 20px 0;padding:15px 30px 15px 15px;border-left:5px solid #eee}.callout a{color:#fff;text-decoration:underline}.callout a:hover{color:#eee}.callout h4{margin-top:0;font-weight:600}.callout p:last-child{margin-bottom:0}.callout code,.callout .highlight{background-color:#fff}.callout.callout-danger{border-color:#c23321}.callout.callout-warning{border-color:#c87f0a}.callout.callout-info{border-color:#0097bc}.callout.callout-success{border-color:#00733e}.alert{border-radius:3px}.alert h4{font-weight:600}.alert .icon{margin-right:10px}.alert .close{color:#000;opacity:.2;filter:alpha(opacity=20)}.alert .close:hover{opacity:.5;filter:alpha(opacity=50)}.alert a{color:#fff;text-decoration:underline}.alert-success{border-color:#008d4c}.alert-danger,.alert-error{border-color:#d73925}.alert-warning{border-color:#e08e0b}.alert-info{border-color:#00acd6}.nav>li>a:hover,.nav>li>a:active,.nav>li>a:focus{color:#444;background:#f7f7f7}.nav-pills>li>a{border-radius:0;border-top:3px solid transparent;color:#444}.nav-pills>li>a>.fa,.nav-pills>li>a>.glyphicon,.nav-pills>li>a>.ion{margin-right:5px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{border-top-color:#3c8dbc}.nav-pills>li.active>a{font-weight:600}.nav-stacked>li>a{border-radius:0;border-top:0;border-left:3px solid transparent;color:#444}.nav-stacked>li.active>a,.nav-stacked>li.active>a:hover{background:transparent;color:#444;border-top:0;border-left-color:#3c8dbc}.nav-stacked>li.header{border-bottom:1px solid #ddd;color:#777;margin-bottom:10px;padding:5px 10px;text-transform:uppercase}.nav-tabs-custom{margin-bottom:20px;background:#fff;box-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px}.nav-tabs-custom>.nav-tabs{margin:0;/* border-bottom-color: #3C8DBC /*#f4f4f4*/; */border-top-right-radius:3px;border-top-left-radius:3px}.nav-tabs-custom>.nav-tabs>li{border-top:3px solid transparent;/*margin-bottom:-2px;*/margin-right:5px}.nav-tabs-custom>.nav-tabs>li>a{color:#444;border-radius:0}.nav-tabs-custom>.nav-tabs>li>a.text-muted{color:#999}.nav-tabs-custom>.nav-tabs>li>a,.nav-tabs-custom>.nav-tabs>li>a:hover{background:transparent;margin:0}.nav-tabs-custom>.nav-tabs>li>a:hover{color:#999}.nav-tabs-custom>.nav-tabs>li:not(.active)>a:hover,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:focus,.nav-tabs-custom>.nav-tabs>li:not(.active)>a:active{border-color:transparent}.nav-tabs-custom>.nav-tabs>li.active{border-top-color:#3c8dbc}.nav-tabs-custom>.nav-tabs>li.active>a,.nav-tabs-custom>.nav-tabs>li.active:hover>a{background-color:#fff;color:#444}.nav-tabs-custom>.nav-tabs>li.active>a{border-top:1px solid #3C8DBC;border-left:1px solid #3C8DBC;border-right:1px solid #3C8DBC;}.nav-tabs-custom>.nav-tabs>li:first-of-type{margin-left:0}.nav-tabs-custom>.nav-tabs>li:first-of-type.active>a{border-left-color:transparent}.nav-tabs-custom>.nav-tabs.pull-right{float:none!important}.nav-tabs-custom>.nav-tabs.pull-right>li{float:right}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type{margin-right:0}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type>a{border-left-width:1px}.nav-tabs-custom>.nav-tabs.pull-right>li:first-of-type.active>a{border-left-color:#f4f4f4;border-right-color:transparent}.nav-tabs-custom>.nav-tabs>li.header{line-height:35px;padding:0 10px;font-size:20px;color:#444}.nav-tabs-custom>.nav-tabs>li.header>.fa,.nav-tabs-custom>.nav-tabs>li.header>.glyphicon,.nav-tabs-custom>.nav-tabs>li.header>.ion{margin-right:5px}.nav-tabs-custom>.tab-content{background:#fff;padding:10px;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.nav-tabs-custom .dropdown.open>a:active,.nav-tabs-custom .dropdown.open>a:focus{background:transparent;color:#999}.pagination>li>a{background:#fafafa;color:#666}.pagination.pagination-flat>li>a{border-radius:0 !important}.products-list{list-style:none;margin:0;padding:0}.products-list>.item{border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.1);box-shadow:0 1px 1px rgba(0,0,0,0.1);padding:10px 0;background:#fff}.products-list>.item:before,.products-list>.item:after{content:" ";display:table}.products-list>.item:after{clear:both}.products-list .product-img{float:left}.products-list .product-img img{width:50px;height:50px}.products-list .product-info{margin-left:60px}.products-list .product-title{font-weight:600}.products-list .product-description{display:block;color:#999;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.product-list-in-box>.item{-webkit-box-shadow:none;box-shadow:none;border-radius:0;border-bottom:1px solid #f4f4f4}.product-list-in-box>.item:last-of-type{border-bottom-width:0}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{border-top:1px solid #f4f4f4}.table>thead>tr>th{border-bottom:2px solid #f4f4f4}.table tr td .progress{margin-top:5px}.table-bordered{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #f4f4f4}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table.no-border,.table.no-border td,.table.no-border th{border:0}table.text-center,table.text-center td,table.text-center th{text-align:center}.table.align th{text-align:left}.table.align td{text-align:right}.label-default{background-color:#d2d6de;color:#444}.direct-chat .box-body{border-bottom-right-radius:0;border-bottom-left-radius:0;position:relative;overflow-x:hidden;padding:0}.direct-chat.chat-pane-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-messages{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0);padding:10px;height:250px;overflow:auto}.direct-chat-msg,.direct-chat-text{display:block}.direct-chat-msg{margin-bottom:10px}.direct-chat-msg:before,.direct-chat-msg:after{content:" ";display:table}.direct-chat-msg:after{clear:both}.direct-chat-messages,.direct-chat-contacts{-webkit-transition:-webkit-transform .5s ease-in-out;-moz-transition:-moz-transform .5s ease-in-out;-o-transition:-o-transform .5s ease-in-out;transition:transform .5s ease-in-out}.direct-chat-text{border-radius:5px;position:relative;padding:5px 10px;background:#d2d6de;border:1px solid #d2d6de;margin:5px 0 0 50px;color:#444}.direct-chat-text:after,.direct-chat-text:before{position:absolute;right:100%;top:15px;border:solid transparent;border-right-color:#d2d6de;content:' ';height:0;width:0;pointer-events:none}.direct-chat-text:after{border-width:5px;margin-top:-5px}.direct-chat-text:before{border-width:6px;margin-top:-6px}.right .direct-chat-text{margin-right:50px;margin-left:0}.right .direct-chat-text:after,.right .direct-chat-text:before{right:auto;left:100%;border-right-color:transparent;border-left-color:#d2d6de}.direct-chat-img{border-radius:50%;float:left;width:40px;height:40px}.right .direct-chat-img{float:right}.direct-chat-info{display:block;margin-bottom:2px;font-size:12px}.direct-chat-name{font-weight:600}.direct-chat-timestamp{color:#999}.direct-chat-contacts-open .direct-chat-contacts{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.direct-chat-contacts{-webkit-transform:translate(101%, 0);-ms-transform:translate(101%, 0);-o-transform:translate(101%, 0);transform:translate(101%, 0);position:absolute;top:0;bottom:0;height:250px;width:100%;background:#222d32;color:#fff;overflow:auto}.contacts-list>li{border-bottom:1px solid rgba(0,0,0,0.2);padding:10px;margin:0}.contacts-list>li:before,.contacts-list>li:after{content:" ";display:table}.contacts-list>li:after{clear:both}.contacts-list>li:last-of-type{border-bottom:none}.contacts-list-img{border-radius:50%;width:40px;float:left}.contacts-list-info{margin-left:45px;color:#fff}.contacts-list-name,.contacts-list-status{display:block}.contacts-list-name{font-weight:600}.contacts-list-status{font-size:12px}.contacts-list-date{color:#aaa;font-weight:normal}.contacts-list-msg{color:#999}.direct-chat-danger .right>.direct-chat-text{background:#dd4b39;border-color:#dd4b39;color:#fff}.direct-chat-danger .right>.direct-chat-text:after,.direct-chat-danger .right>.direct-chat-text:before{border-left-color:#dd4b39}.direct-chat-primary .right>.direct-chat-text{background:#3c8dbc;border-color:#3c8dbc;color:#fff}.direct-chat-primary .right>.direct-chat-text:after,.direct-chat-primary .right>.direct-chat-text:before{border-left-color:#3c8dbc}.direct-chat-warning .right>.direct-chat-text{background:#f39c12;border-color:#f39c12;color:#fff}.direct-chat-warning .right>.direct-chat-text:after,.direct-chat-warning .right>.direct-chat-text:before{border-left-color:#f39c12}.direct-chat-info .right>.direct-chat-text{background:#00c0ef;border-color:#00c0ef;color:#fff}.direct-chat-info .right>.direct-chat-text:after,.direct-chat-info .right>.direct-chat-text:before{border-left-color:#00c0ef}.direct-chat-success .right>.direct-chat-text{background:#00a65a;border-color:#00a65a;color:#fff}.direct-chat-success .right>.direct-chat-text:after,.direct-chat-success .right>.direct-chat-text:before{border-left-color:#00a65a}.users-list>li{width:25%;float:left;padding:10px;text-align:center}.users-list>li img{border-radius:50%;max-width:100%;height:auto}.users-list>li>a:hover,.users-list>li>a:hover .users-list-name{color:#999}.users-list-name,.users-list-date{display:block}.users-list-name{font-weight:600;color:#444;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.users-list-date{color:#999;font-size:12px}.carousel-control.left,.carousel-control.right{background-image:none}.carousel-control>.fa{font-size:40px;position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-20px}.modal{background:rgba(0,0,0,0.3)}.modal-content{border-radius:0;-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125);border:0}@media (min-width:768px){.modal-content{-webkit-box-shadow:0 2px 3px rgba(0,0,0,0.125);box-shadow:0 2px 3px rgba(0,0,0,0.125)}}.modal-header{border-bottom-color:#f4f4f4}.modal-footer{border-top-color:#f4f4f4}.modal-primary .modal-header,.modal-primary .modal-footer{border-color:#307095}.modal-warning .modal-header,.modal-warning .modal-footer{border-color:#c87f0a}.modal-info .modal-header,.modal-info .modal-footer{border-color:#0097bc}.modal-success .modal-header,.modal-success .modal-footer{border-color:#00733e}.modal-danger .modal-header,.modal-danger .modal-footer{border-color:#c23321}.box-widget{border:none;position:relative}.widget-user .widget-user-header{padding:20px;height:120px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user .widget-user-username{margin-top:0;margin-bottom:5px;font-size:25px;font-weight:300;text-shadow:0 1px 1px rgba(0,0,0,0.2)}.widget-user .widget-user-desc{margin-top:0}.widget-user .widget-user-image{position:absolute;top:65px;left:50%;margin-left:-45px}.widget-user .widget-user-image>img{width:90px;height:auto;border:3px solid #fff}.widget-user .box-footer{padding-top:30px}.widget-user-2 .widget-user-header{padding:20px;border-top-right-radius:3px;border-top-left-radius:3px}.widget-user-2 .widget-user-username{margin-top:5px;margin-bottom:5px;font-size:25px;font-weight:300}.widget-user-2 .widget-user-desc{margin-top:0}.widget-user-2 .widget-user-username,.widget-user-2 .widget-user-desc{margin-left:75px}.widget-user-2 .widget-user-image>img{width:65px;height:auto;float:left}.mailbox-messages>.table{margin:0}.mailbox-controls{padding:5px}.mailbox-controls.with-border{border-bottom:1px solid #f4f4f4}.mailbox-read-info{border-bottom:1px solid #f4f4f4;padding:10px}.mailbox-read-info h3{font-size:20px;margin:0}.mailbox-read-info h5{margin:0;padding:5px 0 0 0}.mailbox-read-time{color:#999;font-size:13px}.mailbox-read-message{padding:10px}.mailbox-attachments li{float:left;width:200px;border:1px solid #eee;margin-bottom:10px;margin-right:10px}.mailbox-attachment-name{font-weight:bold;color:#666}.mailbox-attachment-icon,.mailbox-attachment-info,.mailbox-attachment-size{display:block}.mailbox-attachment-info{padding:10px;background:#f4f4f4}.mailbox-attachment-size{color:#999;font-size:12px}.mailbox-attachment-icon{text-align:center;font-size:65px;color:#666;padding:20px 10px}.mailbox-attachment-icon.has-img{padding:0}.mailbox-attachment-icon.has-img>img{max-width:100%;height:auto}.lockscreen{background:#d2d6de}.lockscreen-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.lockscreen-logo a{color:#444}.lockscreen-wrapper{max-width:400px;margin:0 auto;margin-top:10%}.lockscreen .lockscreen-name{text-align:center;font-weight:600}.lockscreen-item{border-radius:4px;padding:0;background:#fff;position:relative;margin:10px auto 30px auto;width:290px}.lockscreen-image{border-radius:50%;position:absolute;left:-10px;top:-25px;background:#fff;padding:5px;z-index:10}.lockscreen-image>img{border-radius:50%;width:70px;height:70px}.lockscreen-credentials{margin-left:70px}.lockscreen-credentials .form-control{border:0}.lockscreen-credentials .btn{background-color:#fff;border:0;padding:0 10px}.lockscreen-footer{margin-top:10px}.login-logo,.register-logo{font-size:35px;text-align:center;margin-bottom:25px;font-weight:300}.login-logo a,.register-logo a{color:#444}.login-page,.register-page{background:#d2d6de}.login-box,.register-box{width:360px;margin:7% auto}@media (max-width:768px){.login-box,.register-box{width:90%;margin-top:20px}}.login-box-body,.register-box-body{background:#fff;padding:20px;border-top:0;color:#666}.login-box-body .form-control-feedback,.register-box-body .form-control-feedback{color:#777}.login-box-msg,.register-box-msg{margin:0;text-align:center;padding:0 20px 20px 20px}.social-auth-links{margin:10px 0}.error-page{width:600px;margin:20px auto 0 auto}@media (max-width:991px){.error-page{width:100%}}.error-page>.headline{float:left;font-size:100px;font-weight:300}@media (max-width:991px){.error-page>.headline{float:none;text-align:center}}.error-page>.error-content{margin-left:190px;display:block}@media (max-width:991px){.error-page>.error-content{margin-left:0}}.error-page>.error-content>h3{font-weight:300;font-size:25px}@media (max-width:991px){.error-page>.error-content>h3{text-align:center}}.invoice{position:relative;background:#fff;border:1px solid #f4f4f4;padding:20px;margin:10px 25px}.invoice-title{margin-top:0}.profile-user-img{margin:0 auto;width:100px;padding:3px;border:3px solid #d2d6de}.profile-username{font-size:21px;margin-top:5px}.post{border-bottom:1px solid #d2d6de;margin-bottom:15px;padding-bottom:15px;color:#666}.post:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.post .user-block{margin-bottom:15px}.btn-social{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.btn-social>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social.btn-lg{padding-left:61px}.btn-social.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social.btn-sm{padding-left:38px}.btn-social.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social.btn-xs{padding-left:30px}.btn-social.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon{position:relative;padding-left:44px;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;height:34px;width:34px;padding:0}.btn-social-icon>:first-child{position:absolute;left:0;top:0;bottom:0;width:32px;line-height:34px;font-size:1.6em;text-align:center;border-right:1px solid rgba(0,0,0,0.2)}.btn-social-icon.btn-lg{padding-left:61px}.btn-social-icon.btn-lg>:first-child{line-height:45px;width:45px;font-size:1.8em}.btn-social-icon.btn-sm{padding-left:38px}.btn-social-icon.btn-sm>:first-child{line-height:28px;width:28px;font-size:1.4em}.btn-social-icon.btn-xs{padding-left:30px}.btn-social-icon.btn-xs>:first-child{line-height:20px;width:20px;font-size:1.2em}.btn-social-icon>:first-child{border:none;text-align:center;width:100%}.btn-social-icon.btn-lg{height:45px;width:45px;padding-left:0;padding-right:0}.btn-social-icon.btn-sm{height:30px;width:30px;padding-left:0;padding-right:0}.btn-social-icon.btn-xs{height:22px;width:22px;padding-left:0;padding-right:0}.btn-adn{color:#fff;background-color:#d87a68;border-color:rgba(0,0,0,0.2)}.btn-adn:hover,.btn-adn:focus,.btn-adn.focus,.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{color:#fff;background-color:#ce563f;border-color:rgba(0,0,0,0.2)}.btn-adn:active,.btn-adn.active,.open>.dropdown-toggle.btn-adn{background-image:none}.btn-adn .badge{color:#d87a68;background-color:#fff}.btn-bitbucket{color:#fff;background-color:#205081;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:hover,.btn-bitbucket:focus,.btn-bitbucket.focus,.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{color:#fff;background-color:#163758;border-color:rgba(0,0,0,0.2)}.btn-bitbucket:active,.btn-bitbucket.active,.open>.dropdown-toggle.btn-bitbucket{background-image:none}.btn-bitbucket .badge{color:#205081;background-color:#fff}.btn-dropbox{color:#fff;background-color:#1087dd;border-color:rgba(0,0,0,0.2)}.btn-dropbox:hover,.btn-dropbox:focus,.btn-dropbox.focus,.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{color:#fff;background-color:#0d6aad;border-color:rgba(0,0,0,0.2)}.btn-dropbox:active,.btn-dropbox.active,.open>.dropdown-toggle.btn-dropbox{background-image:none}.btn-dropbox .badge{color:#1087dd;background-color:#fff}.btn-facebook{color:#fff;background-color:#3b5998;border-color:rgba(0,0,0,0.2)}.btn-facebook:hover,.btn-facebook:focus,.btn-facebook.focus,.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{color:#fff;background-color:#2d4373;border-color:rgba(0,0,0,0.2)}.btn-facebook:active,.btn-facebook.active,.open>.dropdown-toggle.btn-facebook{background-image:none}.btn-facebook .badge{color:#3b5998;background-color:#fff}.btn-flickr{color:#fff;background-color:#ff0084;border-color:rgba(0,0,0,0.2)}.btn-flickr:hover,.btn-flickr:focus,.btn-flickr.focus,.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{color:#fff;background-color:#cc006a;border-color:rgba(0,0,0,0.2)}.btn-flickr:active,.btn-flickr.active,.open>.dropdown-toggle.btn-flickr{background-image:none}.btn-flickr .badge{color:#ff0084;background-color:#fff}.btn-foursquare{color:#fff;background-color:#f94877;border-color:rgba(0,0,0,0.2)}.btn-foursquare:hover,.btn-foursquare:focus,.btn-foursquare.focus,.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{color:#fff;background-color:#f71752;border-color:rgba(0,0,0,0.2)}.btn-foursquare:active,.btn-foursquare.active,.open>.dropdown-toggle.btn-foursquare{background-image:none}.btn-foursquare .badge{color:#f94877;background-color:#fff}.btn-github{color:#fff;background-color:#444;border-color:rgba(0,0,0,0.2)}.btn-github:hover,.btn-github:focus,.btn-github.focus,.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{color:#fff;background-color:#2b2b2b;border-color:rgba(0,0,0,0.2)}.btn-github:active,.btn-github.active,.open>.dropdown-toggle.btn-github{background-image:none}.btn-github .badge{color:#444;background-color:#fff}.btn-google{color:#fff;background-color:#dd4b39;border-color:rgba(0,0,0,0.2)}.btn-google:hover,.btn-google:focus,.btn-google.focus,.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{color:#fff;background-color:#c23321;border-color:rgba(0,0,0,0.2)}.btn-google:active,.btn-google.active,.open>.dropdown-toggle.btn-google{background-image:none}.btn-google .badge{color:#dd4b39;background-color:#fff}.btn-instagram{color:#fff;background-color:#3f729b;border-color:rgba(0,0,0,0.2)}.btn-instagram:hover,.btn-instagram:focus,.btn-instagram.focus,.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{color:#fff;background-color:#305777;border-color:rgba(0,0,0,0.2)}.btn-instagram:active,.btn-instagram.active,.open>.dropdown-toggle.btn-instagram{background-image:none}.btn-instagram .badge{color:#3f729b;background-color:#fff}.btn-linkedin{color:#fff;background-color:#007bb6;border-color:rgba(0,0,0,0.2)}.btn-linkedin:hover,.btn-linkedin:focus,.btn-linkedin.focus,.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{color:#fff;background-color:#005983;border-color:rgba(0,0,0,0.2)}.btn-linkedin:active,.btn-linkedin.active,.open>.dropdown-toggle.btn-linkedin{background-image:none}.btn-linkedin .badge{color:#007bb6;background-color:#fff}.btn-microsoft{color:#fff;background-color:#2672ec;border-color:rgba(0,0,0,0.2)}.btn-microsoft:hover,.btn-microsoft:focus,.btn-microsoft.focus,.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{color:#fff;background-color:#125acd;border-color:rgba(0,0,0,0.2)}.btn-microsoft:active,.btn-microsoft.active,.open>.dropdown-toggle.btn-microsoft{background-image:none}.btn-microsoft .badge{color:#2672ec;background-color:#fff}.btn-openid{color:#fff;background-color:#f7931e;border-color:rgba(0,0,0,0.2)}.btn-openid:hover,.btn-openid:focus,.btn-openid.focus,.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{color:#fff;background-color:#da7908;border-color:rgba(0,0,0,0.2)}.btn-openid:active,.btn-openid.active,.open>.dropdown-toggle.btn-openid{background-image:none}.btn-openid .badge{color:#f7931e;background-color:#fff}.btn-pinterest{color:#fff;background-color:#cb2027;border-color:rgba(0,0,0,0.2)}.btn-pinterest:hover,.btn-pinterest:focus,.btn-pinterest.focus,.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{color:#fff;background-color:#9f191f;border-color:rgba(0,0,0,0.2)}.btn-pinterest:active,.btn-pinterest.active,.open>.dropdown-toggle.btn-pinterest{background-image:none}.btn-pinterest .badge{color:#cb2027;background-color:#fff}.btn-reddit{color:#000;background-color:#eff7ff;border-color:rgba(0,0,0,0.2)}.btn-reddit:hover,.btn-reddit:focus,.btn-reddit.focus,.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{color:#000;background-color:#bcddff;border-color:rgba(0,0,0,0.2)}.btn-reddit:active,.btn-reddit.active,.open>.dropdown-toggle.btn-reddit{background-image:none}.btn-reddit .badge{color:#eff7ff;background-color:#000}.btn-soundcloud{color:#fff;background-color:#f50;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:hover,.btn-soundcloud:focus,.btn-soundcloud.focus,.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{color:#fff;background-color:#c40;border-color:rgba(0,0,0,0.2)}.btn-soundcloud:active,.btn-soundcloud.active,.open>.dropdown-toggle.btn-soundcloud{background-image:none}.btn-soundcloud .badge{color:#f50;background-color:#fff}.btn-tumblr{color:#fff;background-color:#2c4762;border-color:rgba(0,0,0,0.2)}.btn-tumblr:hover,.btn-tumblr:focus,.btn-tumblr.focus,.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{color:#fff;background-color:#1c2d3f;border-color:rgba(0,0,0,0.2)}.btn-tumblr:active,.btn-tumblr.active,.open>.dropdown-toggle.btn-tumblr{background-image:none}.btn-tumblr .badge{color:#2c4762;background-color:#fff}.btn-twitter{color:#fff;background-color:#55acee;border-color:rgba(0,0,0,0.2)}.btn-twitter:hover,.btn-twitter:focus,.btn-twitter.focus,.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{color:#fff;background-color:#2795e9;border-color:rgba(0,0,0,0.2)}.btn-twitter:active,.btn-twitter.active,.open>.dropdown-toggle.btn-twitter{background-image:none}.btn-twitter .badge{color:#55acee;background-color:#fff}.btn-vimeo{color:#fff;background-color:#1ab7ea;border-color:rgba(0,0,0,0.2)}.btn-vimeo:hover,.btn-vimeo:focus,.btn-vimeo.focus,.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{color:#fff;background-color:#1295bf;border-color:rgba(0,0,0,0.2)}.btn-vimeo:active,.btn-vimeo.active,.open>.dropdown-toggle.btn-vimeo{background-image:none}.btn-vimeo .badge{color:#1ab7ea;background-color:#fff}.btn-vk{color:#fff;background-color:#587ea3;border-color:rgba(0,0,0,0.2)}.btn-vk:hover,.btn-vk:focus,.btn-vk.focus,.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{color:#fff;background-color:#466482;border-color:rgba(0,0,0,0.2)}.btn-vk:active,.btn-vk.active,.open>.dropdown-toggle.btn-vk{background-image:none}.btn-vk .badge{color:#587ea3;background-color:#fff}.btn-yahoo{color:#fff;background-color:#720e9e;border-color:rgba(0,0,0,0.2)}.btn-yahoo:hover,.btn-yahoo:focus,.btn-yahoo.focus,.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{color:#fff;background-color:#500a6f;border-color:rgba(0,0,0,0.2)}.btn-yahoo:active,.btn-yahoo.active,.open>.dropdown-toggle.btn-yahoo{background-image:none}.btn-yahoo .badge{color:#720e9e;background-color:#fff}.fc-button{background:#f4f4f4;background-image:none;color:#444;border-color:#ddd;border-bottom-color:#ddd}.fc-button:hover,.fc-button:active,.fc-button.hover{background-color:#e9e9e9}.fc-header-title h2{font-size:15px;line-height:1.6em;color:#666;margin-left:10px}.fc-header-right{padding-right:10px}.fc-header-left{padding-left:10px}.fc-widget-header{background:#fafafa}.fc-grid{width:100%;border:0}.fc-widget-header:first-of-type,.fc-widget-content:first-of-type{border-left:0;border-right:0}.fc-widget-header:last-of-type,.fc-widget-content:last-of-type{border-right:0}.fc-toolbar{padding:10px;margin:0}.fc-day-number{font-size:20px;font-weight:300;padding-right:10px}.fc-color-picker{list-style:none;margin:0;padding:0}.fc-color-picker>li{float:left;font-size:30px;margin-right:5px;line-height:30px}.fc-color-picker>li .fa{-webkit-transition:-webkit-transform linear .3s;-moz-transition:-moz-transform linear .3s;-o-transition:-o-transform linear .3s;transition:transform linear .3s}.fc-color-picker>li .fa:hover{-webkit-transform:rotate(30deg);-ms-transform:rotate(30deg);-o-transform:rotate(30deg);transform:rotate(30deg)}#add-new-event{-webkit-transition:all linear .3s;-o-transition:all linear .3s;transition:all linear .3s}.external-event{padding:5px 10px;font-weight:bold;margin-bottom:4px;box-shadow:0 1px 1px rgba(0,0,0,0.1);text-shadow:0 1px 1px rgba(0,0,0,0.1);border-radius:3px;cursor:move}.external-event:hover{box-shadow:inset 0 0 90px rgba(0,0,0,0.2)}.select2-container--default.select2-container--focus,.select2-selection.select2-container--focus,.select2-container--default:focus,.select2-selection:focus,.select2-container--default:active,.select2-selection:active{outline:none}.select2-container--default .select2-selection--single,.select2-selection .select2-selection--single{border:1px solid #d2d6de;border-radius:0;padding:6px 12px;height:34px}.select2-container--default.select2-container--open{border-color:#3c8dbc}.select2-dropdown{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#3c8dbc;color:white}.select2-results__option{padding:6px 12px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{padding-left:0;padding-right:0;height:auto;margin-top:-4px}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:6px;padding-left:20px}.select2-container--default .select2-selection--single .select2-selection__arrow{height:28px;right:3px}.select2-container--default .select2-selection--single .select2-selection__arrow b{margin-top:0}.select2-dropdown .select2-search__field,.select2-search--inline .select2-search__field{border:1px solid #d2d6de}.select2-dropdown .select2-search__field:focus,.select2-search--inline .select2-search__field:focus{outline:none;border:1px solid #3c8dbc}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option[aria-selected=true],.select2-container--default .select2-results__option[aria-selected=true]:hover{color:#444}.select2-container--default .select2-selection--multiple{border:1px solid #d2d6de;border-radius:0}.select2-container--default .select2-selection--multiple:focus{border-color:#3c8dbc}.select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#d2d6de}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc;border-color:#367fa9;padding:1px 10px;color:#fff}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{margin-right:5px;color:rgba(255,255,255,0.7)}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container .select2-selection--single .select2-selection__rendered{padding-right:10px}.pad{padding:10px}.margin{margin:10px}.margin-bottom{margin-bottom:20px}.margin-bottom-none{margin-bottom:0}.margin-r-5{margin-right:5px}.inline{display:inline}.description-block{display:block;margin:10px 0;text-align:center}.description-block.margin-bottom{margin-bottom:25px}.description-block>.description-header{margin:0;padding:0;font-weight:600;font-size:16px}.description-block>.description-text{text-transform:uppercase}.bg-red,.bg-yellow,.bg-aqua,.bg-blue,.bg-light-blue,.bg-green,.bg-navy,.bg-teal,.bg-olive,.bg-lime,.bg-orange,.bg-fuchsia,.bg-purple,.bg-maroon,.bg-black,.bg-red-active,.bg-yellow-active,.bg-aqua-active,.bg-blue-active,.bg-light-blue-active,.bg-green-active,.bg-navy-active,.bg-teal-active,.bg-olive-active,.bg-lime-active,.bg-orange-active,.bg-fuchsia-active,.bg-purple-active,.bg-maroon-active,.bg-black-active,.callout.callout-danger,.callout.callout-warning,.callout.callout-info,.callout.callout-success,.alert-success,.alert-danger,.alert-error,.alert-warning,.alert-info,.label-danger,.label-info,.label-warning,.label-primary,.label-success,.modal-primary .modal-body,.modal-primary .modal-header,.modal-primary .modal-footer,.modal-warning .modal-body,.modal-warning .modal-header,.modal-warning .modal-footer,.modal-info .modal-body,.modal-info .modal-header,.modal-info .modal-footer,.modal-success .modal-body,.modal-success .modal-header,.modal-success .modal-footer,.modal-danger .modal-body,.modal-danger .modal-header,.modal-danger .modal-footer{color:#fff !important}.bg-gray{color:#000;background-color:#d2d6de !important}.bg-gray-light{background-color:#f7f7f7}.bg-black{background-color:#111 !important}.bg-red,.callout.callout-danger,.alert-danger,.alert-error,.label-danger,.modal-danger .modal-body{background-color:#dd4b39 !important}.bg-yellow,.callout.callout-warning,.alert-warning,.label-warning,.modal-warning .modal-body{background-color:#f39c12 !important}.bg-aqua,.callout.callout-info,.alert-info,.label-info,.modal-info .modal-body{background-color:#00c0ef !important}.bg-blue{background-color:#0073b7 !important}.bg-light-blue,.label-primary,.modal-primary .modal-body{background-color:#3c8dbc !important}.bg-green,.callout.callout-success,.alert-success,.label-success,.modal-success .modal-body{background-color:#00a65a !important}.bg-navy{background-color:#001f3f !important}.bg-teal{background-color:#39cccc !important}.bg-olive{background-color:#3d9970 !important}.bg-lime{background-color:#01ff70 !important}.bg-orange{background-color:#ff851b !important}.bg-fuchsia{background-color:#f012be !important}.bg-purple{background-color:#605ca8 !important}.bg-maroon{background-color:#d81b60 !important}.bg-gray-active{color:#000;background-color:#b5bbc8 !important}.bg-black-active{background-color:#000 !important}.bg-red-active,.modal-danger .modal-header,.modal-danger .modal-footer{background-color:#d33724 !important}.bg-yellow-active,.modal-warning .modal-header,.modal-warning .modal-footer{background-color:#db8b0b !important}.bg-aqua-active,.modal-info .modal-header,.modal-info .modal-footer{background-color:#00a7d0 !important}.bg-blue-active{background-color:#005384 !important}.bg-light-blue-active,.modal-primary .modal-header,.modal-primary .modal-footer{background-color:#357ca5 !important}.bg-green-active,.modal-success .modal-header,.modal-success .modal-footer{background-color:#008d4c !important}.bg-navy-active{background-color:#001a35 !important}.bg-teal-active{background-color:#30bbbb !important}.bg-olive-active{background-color:#368763 !important}.bg-lime-active{background-color:#00e765 !important}.bg-orange-active{background-color:#ff7701 !important}.bg-fuchsia-active{background-color:#db0ead !important}.bg-purple-active{background-color:#555299 !important}.bg-maroon-active{background-color:#ca195a !important}[class^="bg-"].disabled{opacity:.65;filter:alpha(opacity=65)}.text-red{color:#dd4b39 !important}.text-yellow{color:#f39c12 !important}.text-aqua{color:#00c0ef !important}.text-blue{color:#0073b7 !important}.text-black{color:#111 !important}.text-light-blue{color:#3c8dbc !important}.text-green{color:#00a65a !important}.text-gray{color:#d2d6de !important}.text-navy{color:#001f3f !important}.text-teal{color:#39cccc !important}.text-olive{color:#3d9970 !important}.text-lime{color:#01ff70 !important}.text-orange{color:#ff851b !important}.text-fuchsia{color:#f012be !important}.text-purple{color:#605ca8 !important}.text-maroon{color:#d81b60 !important}.link-muted{color:#7a869d}.link-muted:hover,.link-muted:focus{color:#606c84}.link-black{color:#666}.link-black:hover,.link-black:focus{color:#999}.hide{display:none !important}.no-border{border:0 !important}.no-padding{padding:0 !important}.no-margin{margin:0 !important}.no-shadow{box-shadow:none!important}.list-unstyled,.chart-legend,.contacts-list,.users-list,.mailbox-attachments{list-style:none;margin:0;padding:0}.list-group-unbordered>.list-group-item{border-left:0;border-right:0;border-radius:0;padding-left:0;padding-right:0}.flat{border-radius:0 !important}.text-bold,.text-bold.table td,.text-bold.table th{font-weight:700}.text-sm{font-size:12px}.jqstooltip{padding:5px!important;width:auto!important;height:auto!important}.bg-teal-gradient{background:#39cccc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;background:-ms-linear-gradient(bottom, #39cccc, #7adddd) !important;background:-moz-linear-gradient(center bottom, #39cccc 0, #7adddd 100%) !important;background:-o-linear-gradient(#7adddd, #39cccc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important;color:#fff}.bg-light-blue-gradient{background:#3c8dbc !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;background:-ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;background:-moz-linear-gradient(center bottom, #3c8dbc 0, #67a8ce 100%) !important;background:-o-linear-gradient(#67a8ce, #3c8dbc) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;color:#fff}.bg-blue-gradient{background:#0073b7 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;background:-ms-linear-gradient(bottom, #0073b7, #0089db) !important;background:-moz-linear-gradient(center bottom, #0073b7 0, #0089db 100%) !important;background:-o-linear-gradient(#0089db, #0073b7) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;color:#fff}.bg-aqua-gradient{background:#00c0ef !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important;background:-ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important;background:-moz-linear-gradient(center bottom, #00c0ef 0, #14d1ff 100%) !important;background:-o-linear-gradient(#14d1ff, #00c0ef) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important;color:#fff}.bg-yellow-gradient{background:#f39c12 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important;background:-ms-linear-gradient(bottom, #f39c12, #f7bc60) !important;background:-moz-linear-gradient(center bottom, #f39c12 0, #f7bc60 100%) !important;background:-o-linear-gradient(#f7bc60, #f39c12) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important;color:#fff}.bg-purple-gradient{background:#605ca8 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #605ca8), color-stop(1, #9491c4)) !important;background:-ms-linear-gradient(bottom, #605ca8, #9491c4) !important;background:-moz-linear-gradient(center bottom, #605ca8 0, #9491c4 100%) !important;background:-o-linear-gradient(#9491c4, #605ca8) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#9491c4', endColorstr='#605ca8', GradientType=0) !important;color:#fff}.bg-green-gradient{background:#00a65a !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important;background:-ms-linear-gradient(bottom, #00a65a, #00ca6d) !important;background:-moz-linear-gradient(center bottom, #00a65a 0, #00ca6d 100%) !important;background:-o-linear-gradient(#00ca6d, #00a65a) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important;color:#fff}.bg-red-gradient{background:#dd4b39 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #dd4b39), color-stop(1, #e47365)) !important;background:-ms-linear-gradient(bottom, #dd4b39, #e47365) !important;background:-moz-linear-gradient(center bottom, #dd4b39 0, #e47365 100%) !important;background:-o-linear-gradient(#e47365, #dd4b39) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e47365', endColorstr='#dd4b39', GradientType=0) !important;color:#fff}.bg-black-gradient{background:#111 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #111), color-stop(1, #2b2b2b)) !important;background:-ms-linear-gradient(bottom, #111, #2b2b2b) !important;background:-moz-linear-gradient(center bottom, #111 0, #2b2b2b 100%) !important;background:-o-linear-gradient(#2b2b2b, #111) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#2b2b2b', endColorstr='#111111', GradientType=0) !important;color:#fff}.bg-maroon-gradient{background:#d81b60 !important;background:-webkit-gradient(linear, left bottom, left top, color-stop(0, #d81b60), color-stop(1, #e73f7c)) !important;background:-ms-linear-gradient(bottom, #d81b60, #e73f7c) !important;background:-moz-linear-gradient(center bottom, #d81b60 0, #e73f7c 100%) !important;background:-o-linear-gradient(#e73f7c, #d81b60) !important;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#e73f7c', endColorstr='#d81b60', GradientType=0) !important;color:#fff}.description-block .description-icon{font-size:16px}.no-pad-top{padding-top:0}.position-static{position:static!important}.list-header{font-size:15px;padding:10px 4px;font-weight:bold;color:#666}.list-seperator{height:1px;background:#f4f4f4;margin:15px 0 9px 0}.list-link>a{padding:4px;color:#777}.list-link>a:hover{color:#222}.font-light{font-weight:300}.user-block:before,.user-block:after{content:" ";display:table}.user-block:after{clear:both}.user-block img{width:40px;height:40px;float:left}.user-block .username,.user-block .description,.user-block .comment{display:block;margin-left:50px}.user-block .username{font-size:16px;font-weight:600}.user-block .description{color:#999;font-size:13px}.user-block.user-block-sm .username,.user-block.user-block-sm .description,.user-block.user-block-sm .comment{margin-left:40px}.user-block.user-block-sm .username{font-size:14px}.img-sm,.img-md,.img-lg,.box-comments .box-comment img,.user-block.user-block-sm img{float:left}.img-sm,.box-comments .box-comment img,.user-block.user-block-sm img{width:30px!important;height:30px!important}.img-sm+.img-push{margin-left:40px}.img-md{width:60px;height:60px}.img-md+.img-push{margin-left:70px}.img-lg{width:100px;height:100px}.img-lg+.img-push{margin-left:110px}.img-bordered{border:3px solid #d2d6de;padding:3px}.img-bordered-sm{border:2px solid #d2d6de;padding:2px}.attachment-block{border:1px solid #f4f4f4;padding:5px;margin-bottom:10px;background:#f7f7f7}.attachment-block .attachment-img{max-width:100px;max-height:100px;height:auto;float:left}.attachment-block .attachment-pushed{margin-left:110px}.attachment-block .attachment-heading{margin:0}.attachment-block .attachment-text{color:#555}.connectedSortable{min-height:100px}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sort-highlight{background:#f4f4f4;border:1px dashed #ddd;margin-bottom:10px}.full-opacity-hover{opacity:.65;filter:alpha(opacity=65)}.full-opacity-hover:hover{opacity:1;filter:alpha(opacity=100)}.chart{position:relative;overflow:hidden;width:100%}.chart svg,.chart canvas{width:100%!important}@media print{.no-print,.main-sidebar,.left-side,.main-header,.content-header{display:none!important}.content-wrapper,.right-side,.main-footer{margin-left:0!important;min-height:0!important;-webkit-transform:translate(0, 0) !important;-ms-transform:translate(0, 0) !important;-o-transform:translate(0, 0) !important;transform:translate(0, 0) !important}.fixed .content-wrapper,.fixed .right-side{padding-top:0!important}.invoice{width:100%;border:0;margin:0;padding:0}.invoice-col{float:left;width:33.3333333%}.table-responsive{overflow:auto}.table-responsive>.table tr th,.table-responsive>.table tr td{white-space:normal!important}} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/AdminLTE/css/skins/skin-blue.min.css b/LinuxGUI/WebUI/static/AdminLTE/css/skins/skin-blue.min.css new file mode 100644 index 00000000..123c04f4 --- /dev/null +++ b/LinuxGUI/WebUI/static/AdminLTE/css/skins/skin-blue.min.css @@ -0,0 +1 @@ +.skin-blue .main-header .navbar{background-color:#3c8dbc}.skin-blue .main-header .navbar .nav>li>a{color:#fff}.skin-blue .main-header .navbar .nav>li>a:hover,.skin-blue .main-header .navbar .nav>li>a:active,.skin-blue .main-header .navbar .nav>li>a:focus,.skin-blue .main-header .navbar .nav .open>a,.skin-blue .main-header .navbar .nav .open>a:hover,.skin-blue .main-header .navbar .nav .open>a:focus,.skin-blue .main-header .navbar .nav>.active>a{background:rgba(0,0,0,0.1);color:#f6f6f6}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{color:#f6f6f6;background:rgba(0,0,0,0.1)}.skin-blue .main-header .navbar .sidebar-toggle{color:#fff}.skin-blue .main-header .navbar .sidebar-toggle:hover{background-color:#367fa9}@media (max-width:767px){.skin-blue .main-header .navbar .dropdown-menu li.divider{background-color:rgba(255,255,255,0.1)}.skin-blue .main-header .navbar .dropdown-menu li a{color:#fff}.skin-blue .main-header .navbar .dropdown-menu li a:hover{background:#367fa9}}.skin-blue .main-header .logo{background-color:#367fa9;color:#fff;border-bottom:0 solid transparent}.skin-blue .main-header .logo:hover{background-color:#357ca5}.skin-blue .main-header li.user-header{background-color:#3c8dbc}.skin-blue .content-header{background:transparent}.skin-blue .wrapper,.skin-blue .main-sidebar,.skin-blue .left-side{background-color:#222d32}.skin-blue .user-panel>.info,.skin-blue .user-panel>.info>a{color:#fff}.skin-blue .sidebar-menu>li.header{color:#4b646f;background:#1a2226}.skin-blue .sidebar-menu>li>a{border-left:3px solid transparent}.skin-blue .sidebar-menu>li:hover>a,.skin-blue .sidebar-menu>li.active>a{color:#fff;background:#1e282c;border-left-color:#3c8dbc}.skin-blue .sidebar-menu>li>.treeview-menu{margin:0 1px;background:#2c3b41}.skin-blue .sidebar a{color:#b8c7ce}.skin-blue .sidebar a:hover{text-decoration:none}.skin-blue .treeview-menu>li>a{color:#8aa4af}.skin-blue .treeview-menu>li.active>a,.skin-blue .treeview-menu>li>a:hover{color:#fff}.skin-blue .sidebar-form{border-radius:3px;border:1px solid #374850;margin:10px 10px}.skin-blue .sidebar-form input[type="text"],.skin-blue .sidebar-form .btn{box-shadow:none;background-color:#374850;border:1px solid transparent;height:35px;-webkit-transition:all .3s ease-in-out;-o-transition:all .3s ease-in-out;transition:all .3s ease-in-out}.skin-blue .sidebar-form input[type="text"]{color:#666;border-top-left-radius:2px;border-top-right-radius:0;border-bottom-right-radius:0;border-bottom-left-radius:2px}.skin-blue .sidebar-form input[type="text"]:focus,.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{background-color:#fff;color:#666}.skin-blue .sidebar-form input[type="text"]:focus+.input-group-btn .btn{border-left-color:#fff}.skin-blue .sidebar-form .btn{color:#999;border-top-left-radius:0;border-top-right-radius:2px;border-bottom-right-radius:2px;border-bottom-left-radius:0}.skin-blue.layout-top-nav .main-header>.logo{background-color:#3c8dbc;color:#fff;border-bottom:0 solid transparent}.skin-blue.layout-top-nav .main-header>.logo:hover{background-color:#3b8ab8} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/AdminLTE/js/app.min.js b/LinuxGUI/WebUI/static/AdminLTE/js/app.min.js new file mode 100644 index 00000000..679f18f1 --- /dev/null +++ b/LinuxGUI/WebUI/static/AdminLTE/js/app.min.js @@ -0,0 +1,13 @@ +/*! AdminLTE app.js + * ================ + * Main JS application file for AdminLTE v2. This file + * should be included in all pages. It controls some layout + * options and implements exclusive AdminLTE plugins. + * + * @Author Almsaeed Studio + * @Support + * @Email + * @version 2.3.0 + * @license MIT + */ +function _init(){"use strict";$.AdminLTE.layout={activate:function(){var a=this;a.fix(),a.fixSidebar(),$(window,".wrapper").resize(function(){a.fix(),a.fixSidebar()})},fix:function(){var a=$(".main-header").outerHeight()+$(".main-footer").outerHeight(),b=$(window).height(),c=$(".sidebar").height();if($("body").hasClass("fixed"))$(".content-wrapper, .right-side").css("min-height",b-$(".main-footer").outerHeight());else{var d;b>=c?($(".content-wrapper, .right-side").css("min-height",b-a),d=b-a):($(".content-wrapper, .right-side").css("min-height",c),d=c);var e=$($.AdminLTE.options.controlSidebarOptions.selector);"undefined"!=typeof e&&e.height()>d&&$(".content-wrapper, .right-side").css("min-height",e.height())}},fixSidebar:function(){return $("body").hasClass("fixed")?("undefined"==typeof $.fn.slimScroll&&window.console&&window.console.error("Error: the fixed layout requires the slimscroll plugin!"),void($.AdminLTE.options.sidebarSlimScroll&&"undefined"!=typeof $.fn.slimScroll&&($(".sidebar").slimScroll({destroy:!0}).height("auto"),$(".sidebar").slimscroll({height:$(window).height()-$(".main-header").height()+"px",color:"rgba(0,0,0,0.2)",size:"3px"})))):void("undefined"!=typeof $.fn.slimScroll&&$(".sidebar").slimScroll({destroy:!0}).height("auto"))}},$.AdminLTE.pushMenu={activate:function(a){var b=$.AdminLTE.options.screenSizes;$(a).on("click",function(a){a.preventDefault(),$(window).width()>b.sm-1?$("body").hasClass("sidebar-collapse")?$("body").removeClass("sidebar-collapse").trigger("expanded.pushMenu"):$("body").addClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").hasClass("sidebar-open")?$("body").removeClass("sidebar-open").removeClass("sidebar-collapse").trigger("collapsed.pushMenu"):$("body").addClass("sidebar-open").trigger("expanded.pushMenu")}),$(".content-wrapper").click(function(){$(window).width()<=b.sm-1&&$("body").hasClass("sidebar-open")&&$("body").removeClass("sidebar-open")}),($.AdminLTE.options.sidebarExpandOnHover||$("body").hasClass("fixed")&&$("body").hasClass("sidebar-mini"))&&this.expandOnHover()},expandOnHover:function(){var a=this,b=$.AdminLTE.options.screenSizes.sm-1;$(".main-sidebar").hover(function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-collapse")&&$(window).width()>b&&a.expand()},function(){$("body").hasClass("sidebar-mini")&&$("body").hasClass("sidebar-expanded-on-hover")&&$(window).width()>b&&a.collapse()})},expand:function(){$("body").removeClass("sidebar-collapse").addClass("sidebar-expanded-on-hover")},collapse:function(){$("body").hasClass("sidebar-expanded-on-hover")&&$("body").removeClass("sidebar-expanded-on-hover").addClass("sidebar-collapse")}},$.AdminLTE.tree=function(a){var b=this,c=$.AdminLTE.options.animationSpeed;$(document).on("click",a+" li a",function(a){var d=$(this),e=d.next();if(e.is(".treeview-menu")&&e.is(":visible"))e.slideUp(c,function(){e.removeClass("menu-open")}),e.parent("li").removeClass("active");else if(e.is(".treeview-menu")&&!e.is(":visible")){var f=d.parents("ul").first(),g=f.find("ul:visible").slideUp(c);g.removeClass("menu-open");var h=d.parent("li");e.slideDown(c,function(){e.addClass("menu-open"),f.find("li.active").removeClass("active"),h.addClass("active"),b.layout.fix()})}e.is(".treeview-menu")&&a.preventDefault()})},$.AdminLTE.controlSidebar={activate:function(){var a=this,b=$.AdminLTE.options.controlSidebarOptions,c=$(b.selector),d=$(b.toggleBtnSelector);d.on("click",function(d){d.preventDefault(),c.hasClass("control-sidebar-open")||$("body").hasClass("control-sidebar-open")?a.close(c,b.slide):a.open(c,b.slide)});var e=$(".control-sidebar-bg");a._fix(e),$("body").hasClass("fixed")?a._fixForFixed(c):$(".content-wrapper, .right-side").height() .box-body, > .box-footer, > form >.box-body, > form > .box-footer");c.hasClass("collapsed-box")?(a.children(":first").removeClass(b.icons.open).addClass(b.icons.collapse),d.slideDown(b.animationSpeed,function(){c.removeClass("collapsed-box")})):(a.children(":first").removeClass(b.icons.collapse).addClass(b.icons.open),d.slideUp(b.animationSpeed,function(){c.addClass("collapsed-box")}))},remove:function(a){var b=a.parents(".box").first();b.slideUp(this.animationSpeed)}}}if("undefined"==typeof jQuery)throw new Error("AdminLTE requires jQuery");$.AdminLTE={},$.AdminLTE.options={navbarMenuSlimscroll:!0,navbarMenuSlimscrollWidth:"3px",navbarMenuHeight:"200px",animationSpeed:500,sidebarToggleSelector:"[data-toggle='offcanvas']",sidebarPushMenu:!0,sidebarSlimScroll:!0,sidebarExpandOnHover:!1,enableBoxRefresh:!0,enableBSToppltip:!0,BSTooltipSelector:"[data-toggle='tooltip']",enableFastclick:!0,enableControlSidebar:!0,controlSidebarOptions:{toggleBtnSelector:"[data-toggle='control-sidebar']",selector:".control-sidebar",slide:!0},enableBoxWidget:!0,boxWidgetOptions:{boxWidgetIcons:{collapse:"fa-minus",open:"fa-plus",remove:"fa-times"},boxWidgetSelectors:{remove:'[data-widget="remove"]',collapse:'[data-widget="collapse"]'}},directChat:{enable:!0,contactToggleSelector:'[data-widget="chat-pane-toggle"]'},colors:{lightBlue:"#3c8dbc",red:"#f56954",green:"#00a65a",aqua:"#00c0ef",yellow:"#f39c12",blue:"#0073b7",navy:"#001F3F",teal:"#39CCCC",olive:"#3D9970",lime:"#01FF70",orange:"#FF851B",fuchsia:"#F012BE",purple:"#8E24AA",maroon:"#D81B60",black:"#222222",gray:"#d2d6de"},screenSizes:{xs:480,sm:768,md:992,lg:1200}},$(function(){"use strict";$("body").removeClass("hold-transition"),"undefined"!=typeof AdminLTEOptions&&$.extend(!0,$.AdminLTE.options,AdminLTEOptions);var a=$.AdminLTE.options;_init(),$.AdminLTE.layout.activate(),$.AdminLTE.tree(".sidebar"),a.enableControlSidebar&&$.AdminLTE.controlSidebar.activate(),a.navbarMenuSlimscroll&&"undefined"!=typeof $.fn.slimscroll&&$(".navbar .menu").slimscroll({height:a.navbarMenuHeight,alwaysVisible:!1,size:a.navbarMenuSlimscrollWidth}).css("width","100%"),a.sidebarPushMenu&&$.AdminLTE.pushMenu.activate(a.sidebarToggleSelector),a.enableBSToppltip&&$("body").tooltip({selector:a.BSTooltipSelector}),a.enableBoxWidget&&$.AdminLTE.boxWidget.activate(),a.enableFastclick&&"undefined"!=typeof FastClick&&FastClick.attach(document.body),a.directChat.enable&&$(document).on("click",a.directChat.contactToggleSelector,function(){var a=$(this).parents(".direct-chat").first();a.toggleClass("direct-chat-contacts-open")}),$('.btn-group[data-toggle="btn-toggle"]').each(function(){var a=$(this);$(this).find(".btn").on("click",function(b){a.find(".btn.active").removeClass("active"),$(this).addClass("active"),b.preventDefault()})})}),function(a){"use strict";a.fn.boxRefresh=function(b){function c(a){a.append(f),e.onLoadStart.call(a)}function d(a){a.find(f).remove(),e.onLoadDone.call(a)}var e=a.extend({trigger:".refresh-btn",source:"",onLoadStart:function(a){return a},onLoadDone:function(a){return a}},b),f=a('
');return this.each(function(){if(""===e.source)return void(window.console&&window.console.log("Please specify a source first - boxRefresh()"));var b=a(this),f=b.find(e.trigger).first();f.on("click",function(a){a.preventDefault(),c(b),b.find(".box-body").load(e.source,function(){d(b)})})})}}(jQuery),function(a){"use strict";a.fn.activateBox=function(){a.AdminLTE.boxWidget.activate(this)}}(jQuery),function(a){"use strict";a.fn.todolist=function(b){var c=a.extend({onCheck:function(a){return a},onUncheck:function(a){return a}},b);return this.each(function(){"undefined"!=typeof a.fn.iCheck?(a("input",this).on("ifChecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onCheck.call(b)}),a("input",this).on("ifUnchecked",function(){var b=a(this).parents("li").first();b.toggleClass("done"),c.onUncheck.call(b)})):a("input",this).on("change",function(){var b=a(this).parents("li").first();b.toggleClass("done"),a("input",b).is(":checked")?c.onCheck.call(b):c.onUncheck.call(b)})})}}(jQuery); \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/css/bootstrap-theme.min.css b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap-theme.min.css new file mode 100644 index 00000000..61358b13 --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap-theme.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */.btn-danger,.btn-default,.btn-info,.btn-primary,.btn-success,.btn-warning{text-shadow:0 -1px 0 rgba(0,0,0,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 1px rgba(0,0,0,.075)}.btn-danger.active,.btn-danger:active,.btn-default.active,.btn-default:active,.btn-info.active,.btn-info:active,.btn-primary.active,.btn-primary:active,.btn-success.active,.btn-success:active,.btn-warning.active,.btn-warning:active{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-danger.disabled,.btn-danger[disabled],.btn-default.disabled,.btn-default[disabled],.btn-info.disabled,.btn-info[disabled],.btn-primary.disabled,.btn-primary[disabled],.btn-success.disabled,.btn-success[disabled],.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-danger,fieldset[disabled] .btn-default,fieldset[disabled] .btn-info,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-success,fieldset[disabled] .btn-warning{-webkit-box-shadow:none;box-shadow:none}.btn-danger .badge,.btn-default .badge,.btn-info .badge,.btn-primary .badge,.btn-success .badge,.btn-warning .badge{text-shadow:none}.btn.active,.btn:active{background-image:none}.btn-default{text-shadow:0 1px 0 #fff;background-image:-webkit-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-o-linear-gradient(top,#fff 0,#e0e0e0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e0e0e0));background-image:linear-gradient(to bottom,#fff 0,#e0e0e0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#dbdbdb;border-color:#ccc}.btn-default:focus,.btn-default:hover{background-color:#e0e0e0;background-position:0 -15px}.btn-default.active,.btn-default:active{background-color:#e0e0e0;border-color:#dbdbdb}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#e0e0e0;background-image:none}.btn-primary{background-image:-webkit-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-o-linear-gradient(top,#337ab7 0,#265a88 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#265a88));background-image:linear-gradient(to bottom,#337ab7 0,#265a88 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#245580}.btn-primary:focus,.btn-primary:hover{background-color:#265a88;background-position:0 -15px}.btn-primary.active,.btn-primary:active{background-color:#265a88;border-color:#245580}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#265a88;background-image:none}.btn-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#419641 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#419641));background-image:linear-gradient(to bottom,#5cb85c 0,#419641 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#3e8f3e}.btn-success:focus,.btn-success:hover{background-color:#419641;background-position:0 -15px}.btn-success.active,.btn-success:active{background-color:#419641;border-color:#3e8f3e}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#419641;background-image:none}.btn-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#2aabd2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#2aabd2));background-image:linear-gradient(to bottom,#5bc0de 0,#2aabd2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#28a4c9}.btn-info:focus,.btn-info:hover{background-color:#2aabd2;background-position:0 -15px}.btn-info.active,.btn-info:active{background-color:#2aabd2;border-color:#28a4c9}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#2aabd2;background-image:none}.btn-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#eb9316 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#eb9316));background-image:linear-gradient(to bottom,#f0ad4e 0,#eb9316 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#e38d13}.btn-warning:focus,.btn-warning:hover{background-color:#eb9316;background-position:0 -15px}.btn-warning.active,.btn-warning:active{background-color:#eb9316;border-color:#e38d13}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#eb9316;background-image:none}.btn-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c12e2a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c12e2a));background-image:linear-gradient(to bottom,#d9534f 0,#c12e2a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-color:#b92c28}.btn-danger:focus,.btn-danger:hover{background-color:#c12e2a;background-position:0 -15px}.btn-danger.active,.btn-danger:active{background-color:#c12e2a;border-color:#b92c28}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#c12e2a;background-image:none}.img-thumbnail,.thumbnail{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{background-color:#e8e8e8;background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{background-color:#2e6da4;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.navbar-default{background-image:-webkit-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-o-linear-gradient(top,#fff 0,#f8f8f8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#f8f8f8));background-image:linear-gradient(to bottom,#fff 0,#f8f8f8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.15),0 1px 5px rgba(0,0,0,.075)}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-o-linear-gradient(top,#dbdbdb 0,#e2e2e2 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dbdbdb),to(#e2e2e2));background-image:linear-gradient(to bottom,#dbdbdb 0,#e2e2e2 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.075);box-shadow:inset 0 3px 9px rgba(0,0,0,.075)}.navbar-brand,.navbar-nav>li>a{text-shadow:0 1px 0 rgba(255,255,255,.25)}.navbar-inverse{background-image:-webkit-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-o-linear-gradient(top,#3c3c3c 0,#222 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#3c3c3c),to(#222));background-image:linear-gradient(to bottom,#3c3c3c 0,#222 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background-repeat:repeat-x;border-radius:4px}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.open>a{background-image:-webkit-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-o-linear-gradient(top,#080808 0,#0f0f0f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#080808),to(#0f0f0f));background-image:linear-gradient(to bottom,#080808 0,#0f0f0f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);background-repeat:repeat-x;-webkit-box-shadow:inset 0 3px 9px rgba(0,0,0,.25);box-shadow:inset 0 3px 9px rgba(0,0,0,.25)}.navbar-inverse .navbar-brand,.navbar-inverse .navbar-nav>li>a{text-shadow:0 -1px 0 rgba(0,0,0,.25)}.navbar-fixed-bottom,.navbar-fixed-top,.navbar-static-top{border-radius:0}@media (max-width:767px){.navbar .navbar-nav .open .dropdown-menu>.active>a,.navbar .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}}.alert{text-shadow:0 1px 0 rgba(255,255,255,.2);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 2px rgba(0,0,0,.05)}.alert-success{background-image:-webkit-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#c8e5bc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#c8e5bc));background-image:linear-gradient(to bottom,#dff0d8 0,#c8e5bc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);background-repeat:repeat-x;border-color:#b2dba1}.alert-info{background-image:-webkit-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#b9def0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#b9def0));background-image:linear-gradient(to bottom,#d9edf7 0,#b9def0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);background-repeat:repeat-x;border-color:#9acfea}.alert-warning{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#f8efc0 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#f8efc0));background-image:linear-gradient(to bottom,#fcf8e3 0,#f8efc0 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);background-repeat:repeat-x;border-color:#f5e79e}.alert-danger{background-image:-webkit-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-o-linear-gradient(top,#f2dede 0,#e7c3c3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#e7c3c3));background-image:linear-gradient(to bottom,#f2dede 0,#e7c3c3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);background-repeat:repeat-x;border-color:#dca7a7}.progress{background-image:-webkit-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#ebebeb 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#f5f5f5));background-image:linear-gradient(to bottom,#ebebeb 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x}.progress-bar{background-image:-webkit-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-o-linear-gradient(top,#337ab7 0,#286090 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#286090));background-image:linear-gradient(to bottom,#337ab7 0,#286090 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);background-repeat:repeat-x}.progress-bar-success{background-image:-webkit-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-o-linear-gradient(top,#5cb85c 0,#449d44 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5cb85c),to(#449d44));background-image:linear-gradient(to bottom,#5cb85c 0,#449d44 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);background-repeat:repeat-x}.progress-bar-info{background-image:-webkit-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-o-linear-gradient(top,#5bc0de 0,#31b0d5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#5bc0de),to(#31b0d5));background-image:linear-gradient(to bottom,#5bc0de 0,#31b0d5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);background-repeat:repeat-x}.progress-bar-warning{background-image:-webkit-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-o-linear-gradient(top,#f0ad4e 0,#ec971f 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f0ad4e),to(#ec971f));background-image:linear-gradient(to bottom,#f0ad4e 0,#ec971f 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);background-repeat:repeat-x}.progress-bar-danger{background-image:-webkit-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-o-linear-gradient(top,#d9534f 0,#c9302c 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9534f),to(#c9302c));background-image:linear-gradient(to bottom,#d9534f 0,#c9302c 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);background-repeat:repeat-x}.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.list-group{border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.075);box-shadow:0 1px 2px rgba(0,0,0,.075)}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{text-shadow:0 -1px 0 #286090;background-image:-webkit-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2b669a 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2b669a));background-image:linear-gradient(to bottom,#337ab7 0,#2b669a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);background-repeat:repeat-x;border-color:#2b669a}.list-group-item.active .badge,.list-group-item.active:focus .badge,.list-group-item.active:hover .badge{text-shadow:none}.panel{-webkit-box-shadow:0 1px 2px rgba(0,0,0,.05);box-shadow:0 1px 2px rgba(0,0,0,.05)}.panel-default>.panel-heading{background-image:-webkit-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-o-linear-gradient(top,#f5f5f5 0,#e8e8e8 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#e8e8e8));background-image:linear-gradient(to bottom,#f5f5f5 0,#e8e8e8 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);background-repeat:repeat-x}.panel-primary>.panel-heading{background-image:-webkit-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-o-linear-gradient(top,#337ab7 0,#2e6da4 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#337ab7),to(#2e6da4));background-image:linear-gradient(to bottom,#337ab7 0,#2e6da4 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);background-repeat:repeat-x}.panel-success>.panel-heading{background-image:-webkit-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-o-linear-gradient(top,#dff0d8 0,#d0e9c6 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#dff0d8),to(#d0e9c6));background-image:linear-gradient(to bottom,#dff0d8 0,#d0e9c6 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);background-repeat:repeat-x}.panel-info>.panel-heading{background-image:-webkit-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-o-linear-gradient(top,#d9edf7 0,#c4e3f3 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#d9edf7),to(#c4e3f3));background-image:linear-gradient(to bottom,#d9edf7 0,#c4e3f3 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);background-repeat:repeat-x}.panel-warning>.panel-heading{background-image:-webkit-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-o-linear-gradient(top,#fcf8e3 0,#faf2cc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#fcf8e3),to(#faf2cc));background-image:linear-gradient(to bottom,#fcf8e3 0,#faf2cc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);background-repeat:repeat-x}.panel-danger>.panel-heading{background-image:-webkit-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-o-linear-gradient(top,#f2dede 0,#ebcccc 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#f2dede),to(#ebcccc));background-image:linear-gradient(to bottom,#f2dede 0,#ebcccc 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);background-repeat:repeat-x}.well{background-image:-webkit-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-o-linear-gradient(top,#e8e8e8 0,#f5f5f5 100%);background-image:-webkit-gradient(linear,left top,left bottom,from(#e8e8e8),to(#f5f5f5));background-image:linear-gradient(to bottom,#e8e8e8 0,#f5f5f5 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);background-repeat:repeat-x;border-color:#dcdcdc;-webkit-box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 3px rgba(0,0,0,.05),0 1px 0 rgba(255,255,255,.1)} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/css/bootstrap.min.css b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap.min.css new file mode 100644 index 00000000..be11b9ff --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/css/bootstrap.min.css @@ -0,0 +1,5 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,:after,:before{color:#000!important;text-shadow:none!important;background:0 0!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}img{max-width:100%!important}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff2) format('woff2'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-eur:before,.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}.glyphicon-cd:before{content:"\e201"}.glyphicon-save-file:before{content:"\e202"}.glyphicon-open-file:before{content:"\e203"}.glyphicon-level-up:before{content:"\e204"}.glyphicon-copy:before{content:"\e205"}.glyphicon-paste:before{content:"\e206"}.glyphicon-alert:before{content:"\e209"}.glyphicon-equalizer:before{content:"\e210"}.glyphicon-king:before{content:"\e211"}.glyphicon-queen:before{content:"\e212"}.glyphicon-pawn:before{content:"\e213"}.glyphicon-bishop:before{content:"\e214"}.glyphicon-knight:before{content:"\e215"}.glyphicon-baby-formula:before{content:"\e216"}.glyphicon-tent:before{content:"\26fa"}.glyphicon-blackboard:before{content:"\e218"}.glyphicon-bed:before{content:"\e219"}.glyphicon-apple:before{content:"\f8ff"}.glyphicon-erase:before{content:"\e221"}.glyphicon-hourglass:before{content:"\231b"}.glyphicon-lamp:before{content:"\e223"}.glyphicon-duplicate:before{content:"\e224"}.glyphicon-piggy-bank:before{content:"\e225"}.glyphicon-scissors:before{content:"\e226"}.glyphicon-bitcoin:before{content:"\e227"}.glyphicon-btc:before{content:"\e227"}.glyphicon-xbt:before{content:"\e227"}.glyphicon-yen:before{content:"\00a5"}.glyphicon-jpy:before{content:"\00a5"}.glyphicon-ruble:before{content:"\20bd"}.glyphicon-rub:before{content:"\20bd"}.glyphicon-scale:before{content:"\e230"}.glyphicon-ice-lolly:before{content:"\e231"}.glyphicon-ice-lolly-tasted:before{content:"\e232"}.glyphicon-education:before{content:"\e233"}.glyphicon-option-horizontal:before{content:"\e234"}.glyphicon-option-vertical:before{content:"\e235"}.glyphicon-menu-hamburger:before{content:"\e236"}.glyphicon-modal-window:before{content:"\e237"}.glyphicon-oil:before{content:"\e238"}.glyphicon-grain:before{content:"\e239"}.glyphicon-sunglasses:before{content:"\e240"}.glyphicon-text-size:before{content:"\e241"}.glyphicon-text-color:before{content:"\e242"}.glyphicon-text-background:before{content:"\e243"}.glyphicon-object-align-top:before{content:"\e244"}.glyphicon-object-align-bottom:before{content:"\e245"}.glyphicon-object-align-horizontal:before{content:"\e246"}.glyphicon-object-align-left:before{content:"\e247"}.glyphicon-object-align-vertical:before{content:"\e248"}.glyphicon-object-align-right:before{content:"\e249"}.glyphicon-triangle-right:before{content:"\e250"}.glyphicon-triangle-left:before{content:"\e251"}.glyphicon-triangle-bottom:before{content:"\e252"}.glyphicon-triangle-top:before{content:"\e253"}.glyphicon-console:before{content:"\e254"}.glyphicon-superscript:before{content:"\e255"}.glyphicon-subscript:before{content:"\e256"}.glyphicon-menu-left:before{content:"\e257"}.glyphicon-menu-right:before{content:"\e258"}.glyphicon-menu-down:before{content:"\e259"}.glyphicon-menu-up:before{content:"\e260"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}button,input,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#337ab7;text-decoration:none}a:focus,a:hover{color:#23527c;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.carousel-inner>.item>a>img,.carousel-inner>.item>img,.img-responsive,.thumbnail a>img,.thumbnail>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}[role=button]{cursor:pointer}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-weight:400;line-height:1;color:#777}.h1,.h2,.h3,h1,h2,h3{margin-top:20px;margin-bottom:10px}.h1 .small,.h1 small,.h2 .small,.h2 small,.h3 .small,.h3 small,h1 .small,h1 small,h2 .small,h2 small,h3 .small,h3 small{font-size:65%}.h4,.h5,.h6,h4,h5,h6{margin-top:10px;margin-bottom:10px}.h4 .small,.h4 small,.h5 .small,.h5 small,.h6 .small,.h6 small,h4 .small,h4 small,h5 .small,h5 small,h6 .small,h6 small{font-size:75%}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}.small,small{font-size:85%}.mark,mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#337ab7}a.text-primary:focus,a.text-primary:hover{color:#286090}.text-success{color:#3c763d}a.text-success:focus,a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:focus,a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:focus,a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:focus,a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#337ab7}a.bg-primary:focus,a.bg-primary:hover{background-color:#286090}.bg-success{background-color:#dff0d8}a.bg-success:focus,a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:focus,a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:focus,a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:focus,a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:10px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dd,dt{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[data-original-title],abbr[title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote ol:last-child,blockquote p:last-child,blockquote ul:last-child{margin-bottom:0}blockquote .small,blockquote footer,blockquote small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote .small:before,blockquote footer:before,blockquote small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse .small:before,.blockquote-reverse footer:before,.blockquote-reverse small:before,blockquote.pull-right .small:before,blockquote.pull-right footer:before,blockquote.pull-right small:before{content:''}.blockquote-reverse .small:after,.blockquote-reverse footer:after,.blockquote-reverse small:after,blockquote.pull-right .small:after,blockquote.pull-right footer:after,blockquote.pull-right small:after{content:'\00A0 \2014'}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-10,.col-xs-11,.col-xs-12,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#777;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px;font-size:14px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>td,.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>td,.table>thead:first-child>tr:first-child>th{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>tbody>tr>td,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>td,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>thead>tr>th{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>tbody>tr>td,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>td,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border:1px solid #ddd}.table-bordered>thead>tr>td,.table-bordered>thead>tr>th{border-bottom-width:2px}.table-striped>tbody>tr:nth-of-type(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>tbody>tr.active>td,.table>tbody>tr.active>th,.table>tbody>tr>td.active,.table>tbody>tr>th.active,.table>tfoot>tr.active>td,.table>tfoot>tr.active>th,.table>tfoot>tr>td.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>thead>tr.active>th,.table>thead>tr>td.active,.table>thead>tr>th.active{background-color:#f5f5f5}.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr.active:hover>th,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover{background-color:#e8e8e8}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:#dff0d8}.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr.success:hover>th,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover{background-color:#d0e9c6}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:#d9edf7}.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr.info:hover>th,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover{background-color:#c4e3f3}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:#fcf8e3}.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr.warning:hover>th,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover{background-color:#faf2cc}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:#f2dede}.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr.danger:hover>th,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover{background-color:#ebcccc}.table-responsive{min-height:.01%;overflow-x:auto}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>td,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>thead>tr>th{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=checkbox],input[type=radio]{margin:4px 0 0;margin-top:1px\9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=checkbox]:focus,input[type=radio]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#999;opacity:1}.form-control:-ms-input-placeholder{color:#999}.form-control::-webkit-input-placeholder{color:#999}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{background-color:#eee;opacity:1}.form-control[disabled],fieldset[disabled] .form-control{cursor:not-allowed}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type=date].form-control,input[type=time].form-control,input[type=datetime-local].form-control,input[type=month].form-control{line-height:34px}.input-group-sm input[type=date],.input-group-sm input[type=time],.input-group-sm input[type=datetime-local],.input-group-sm input[type=month],input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}.input-group-lg input[type=date],.input-group-lg input[type=time],.input-group-lg input[type=datetime-local],.input-group-lg input[type=month],input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}}.form-group{margin-bottom:15px}.checkbox,.radio{position:relative;display:block;margin-top:10px;margin-bottom:10px}.checkbox label,.radio label{min-height:20px;padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox],.radio input[type=radio],.radio-inline input[type=radio]{position:absolute;margin-top:4px\9;margin-left:-20px}.checkbox+.checkbox,.radio+.radio{margin-top:-5px}.checkbox-inline,.radio-inline{position:relative;display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.checkbox-inline+.checkbox-inline,.radio-inline+.radio-inline{margin-top:0;margin-left:10px}fieldset[disabled] input[type=checkbox],fieldset[disabled] input[type=radio],input[type=checkbox].disabled,input[type=checkbox][disabled],input[type=radio].disabled,input[type=radio][disabled]{cursor:not-allowed}.checkbox-inline.disabled,.radio-inline.disabled,fieldset[disabled] .checkbox-inline,fieldset[disabled] .radio-inline{cursor:not-allowed}.checkbox.disabled label,.radio.disabled label,fieldset[disabled] .checkbox label,fieldset[disabled] .radio label{cursor:not-allowed}.form-control-static{min-height:34px;padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}select[multiple].input-sm,textarea.input-sm{height:auto}.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.form-group-sm select.form-control{height:30px;line-height:30px}.form-group-sm select[multiple].form-control,.form-group-sm textarea.form-control{height:auto}.form-group-sm .form-control-static{height:30px;min-height:32px;padding:6px 10px;font-size:12px;line-height:1.5}.input-lg{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-lg{height:46px;line-height:46px}select[multiple].input-lg,textarea.input-lg{height:auto}.form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.form-group-lg select.form-control{height:46px;line-height:46px}.form-group-lg select[multiple].form-control,.form-group-lg textarea.form-control{height:auto}.form-group-lg .form-control-static{height:46px;min-height:38px;padding:11px 16px;font-size:18px;line-height:1.3333333}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center;pointer-events:none}.form-group-lg .form-control+.form-control-feedback,.input-group-lg+.form-control-feedback,.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.form-group-sm .form-control+.form-control-feedback,.input-group-sm+.form-control-feedback,.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .checkbox,.has-success .checkbox-inline,.has-success .control-label,.has-success .help-block,.has-success .radio,.has-success .radio-inline,.has-success.checkbox label,.has-success.checkbox-inline label,.has-success.radio label,.has-success.radio-inline label{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .checkbox,.has-warning .checkbox-inline,.has-warning .control-label,.has-warning .help-block,.has-warning .radio,.has-warning .radio-inline,.has-warning.checkbox label,.has-warning.checkbox-inline label,.has-warning.radio label,.has-warning.radio-inline label{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .checkbox,.has-error .checkbox-inline,.has-error .control-label,.has-error .help-block,.has-error .radio,.has-error .radio-inline,.has-error.checkbox label,.has-error.checkbox-inline label,.has-error.radio label,.has-error.radio-inline label{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label~.form-control-feedback{top:25px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .form-control,.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .checkbox,.form-inline .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .checkbox label,.form-inline .radio label{padding-left:0}.form-inline .checkbox input[type=checkbox],.form-inline .radio input[type=radio]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .checkbox,.form-horizontal .checkbox-inline,.form-horizontal .radio,.form-horizontal .radio-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .checkbox,.form-horizontal .radio{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.33px;font-size:18px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px;font-size:12px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn.active.focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn:active:focus,.btn:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn.focus,.btn:focus,.btn:hover{color:#333;text-decoration:none}.btn.active,.btn:active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default.focus,.btn-default:focus{color:#333;background-color:#e6e6e6;border-color:#8c8c8c}.btn-default:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default.active.focus,.btn-default.active:focus,.btn-default.active:hover,.btn-default:active.focus,.btn-default:active:focus,.btn-default:active:hover,.open>.dropdown-toggle.btn-default.focus,.open>.dropdown-toggle.btn-default:focus,.open>.dropdown-toggle.btn-default:hover{color:#333;background-color:#d4d4d4;border-color:#8c8c8c}.btn-default.active,.btn-default:active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default.disabled.active,.btn-default.disabled.focus,.btn-default.disabled:active,.btn-default.disabled:focus,.btn-default.disabled:hover,.btn-default[disabled],.btn-default[disabled].active,.btn-default[disabled].focus,.btn-default[disabled]:active,.btn-default[disabled]:focus,.btn-default[disabled]:hover,fieldset[disabled] .btn-default,fieldset[disabled] .btn-default.active,fieldset[disabled] .btn-default.focus,fieldset[disabled] .btn-default:active,fieldset[disabled] .btn-default:focus,fieldset[disabled] .btn-default:hover{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#337ab7;border-color:#2e6da4}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#286090;border-color:#122b40}.btn-primary:hover{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#286090;border-color:#204d74}.btn-primary.active.focus,.btn-primary.active:focus,.btn-primary.active:hover,.btn-primary:active.focus,.btn-primary:active:focus,.btn-primary:active:hover,.open>.dropdown-toggle.btn-primary.focus,.open>.dropdown-toggle.btn-primary:focus,.open>.dropdown-toggle.btn-primary:hover{color:#fff;background-color:#204d74;border-color:#122b40}.btn-primary.active,.btn-primary:active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary.disabled.active,.btn-primary.disabled.focus,.btn-primary.disabled:active,.btn-primary.disabled:focus,.btn-primary.disabled:hover,.btn-primary[disabled],.btn-primary[disabled].active,.btn-primary[disabled].focus,.btn-primary[disabled]:active,.btn-primary[disabled]:focus,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary,fieldset[disabled] .btn-primary.active,fieldset[disabled] .btn-primary.focus,fieldset[disabled] .btn-primary:active,fieldset[disabled] .btn-primary:focus,fieldset[disabled] .btn-primary:hover{background-color:#337ab7;border-color:#2e6da4}.btn-primary .badge{color:#337ab7;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#449d44;border-color:#255625}.btn-success:hover{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success.active.focus,.btn-success.active:focus,.btn-success.active:hover,.btn-success:active.focus,.btn-success:active:focus,.btn-success:active:hover,.open>.dropdown-toggle.btn-success.focus,.open>.dropdown-toggle.btn-success:focus,.open>.dropdown-toggle.btn-success:hover{color:#fff;background-color:#398439;border-color:#255625}.btn-success.active,.btn-success:active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success.disabled.active,.btn-success.disabled.focus,.btn-success.disabled:active,.btn-success.disabled:focus,.btn-success.disabled:hover,.btn-success[disabled],.btn-success[disabled].active,.btn-success[disabled].focus,.btn-success[disabled]:active,.btn-success[disabled]:focus,.btn-success[disabled]:hover,fieldset[disabled] .btn-success,fieldset[disabled] .btn-success.active,fieldset[disabled] .btn-success.focus,fieldset[disabled] .btn-success:active,fieldset[disabled] .btn-success:focus,fieldset[disabled] .btn-success:hover{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#31b0d5;border-color:#1b6d85}.btn-info:hover{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info.active.focus,.btn-info.active:focus,.btn-info.active:hover,.btn-info:active.focus,.btn-info:active:focus,.btn-info:active:hover,.open>.dropdown-toggle.btn-info.focus,.open>.dropdown-toggle.btn-info:focus,.open>.dropdown-toggle.btn-info:hover{color:#fff;background-color:#269abc;border-color:#1b6d85}.btn-info.active,.btn-info:active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info.disabled.active,.btn-info.disabled.focus,.btn-info.disabled:active,.btn-info.disabled:focus,.btn-info.disabled:hover,.btn-info[disabled],.btn-info[disabled].active,.btn-info[disabled].focus,.btn-info[disabled]:active,.btn-info[disabled]:focus,.btn-info[disabled]:hover,fieldset[disabled] .btn-info,fieldset[disabled] .btn-info.active,fieldset[disabled] .btn-info.focus,fieldset[disabled] .btn-info:active,fieldset[disabled] .btn-info:focus,fieldset[disabled] .btn-info:hover{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning.focus,.btn-warning:focus{color:#fff;background-color:#ec971f;border-color:#985f0d}.btn-warning:hover{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning.active.focus,.btn-warning.active:focus,.btn-warning.active:hover,.btn-warning:active.focus,.btn-warning:active:focus,.btn-warning:active:hover,.open>.dropdown-toggle.btn-warning.focus,.open>.dropdown-toggle.btn-warning:focus,.open>.dropdown-toggle.btn-warning:hover{color:#fff;background-color:#d58512;border-color:#985f0d}.btn-warning.active,.btn-warning:active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning.disabled.active,.btn-warning.disabled.focus,.btn-warning.disabled:active,.btn-warning.disabled:focus,.btn-warning.disabled:hover,.btn-warning[disabled],.btn-warning[disabled].active,.btn-warning[disabled].focus,.btn-warning[disabled]:active,.btn-warning[disabled]:focus,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning,fieldset[disabled] .btn-warning.active,fieldset[disabled] .btn-warning.focus,fieldset[disabled] .btn-warning:active,fieldset[disabled] .btn-warning:focus,fieldset[disabled] .btn-warning:hover{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c9302c;border-color:#761c19}.btn-danger:hover{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger.active.focus,.btn-danger.active:focus,.btn-danger.active:hover,.btn-danger:active.focus,.btn-danger:active:focus,.btn-danger:active:hover,.open>.dropdown-toggle.btn-danger.focus,.open>.dropdown-toggle.btn-danger:focus,.open>.dropdown-toggle.btn-danger:hover{color:#fff;background-color:#ac2925;border-color:#761c19}.btn-danger.active,.btn-danger:active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger.disabled.active,.btn-danger.disabled.focus,.btn-danger.disabled:active,.btn-danger.disabled:focus,.btn-danger.disabled:hover,.btn-danger[disabled],.btn-danger[disabled].active,.btn-danger[disabled].focus,.btn-danger[disabled]:active,.btn-danger[disabled]:focus,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger,fieldset[disabled] .btn-danger.active,fieldset[disabled] .btn-danger.focus,fieldset[disabled] .btn-danger:active,fieldset[disabled] .btn-danger:focus,fieldset[disabled] .btn-danger:hover{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#337ab7;border-radius:0}.btn-link,.btn-link.active,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:active,.btn-link:focus,.btn-link:hover{border-color:transparent}.btn-link:focus,.btn-link:hover{color:#23527c;text-decoration:underline;background-color:transparent}.btn-link[disabled]:focus,.btn-link[disabled]:hover,fieldset[disabled] .btn-link:focus,fieldset[disabled] .btn-link:hover{color:#777;text-decoration:none}.btn-group-lg>.btn,.btn-lg{padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}.btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease;-webkit-transition-duration:.35s;-o-transition-duration:.35s;transition-duration:.35s;-webkit-transition-property:height,visibility;-o-transition-property:height,visibility;transition-property:height,visibility}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px dashed;border-top:4px solid\9;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown,.dropup{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:focus,.dropdown-menu>li>a:hover{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:focus,.dropdown-menu>.active>a:hover{color:#fff;text-decoration:none;background-color:#337ab7;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{color:#777}.dropdown-menu>.disabled>a:focus,.dropdown-menu>.disabled>a:hover{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px dashed;border-bottom:4px solid\9}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:2px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;float:left}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn,.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn input[type=checkbox],[data-toggle=buttons]>.btn input[type=radio],[data-toggle=buttons]>.btn-group>.btn input[type=checkbox],[data-toggle=buttons]>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.3333333;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn,textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn,textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn{height:auto}.input-group .form-control,.input-group-addon,.input-group-btn{display:table-cell}.input-group .form-control:not(:first-child):not(:last-child),.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=checkbox],.input-group-addon input[type=radio]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn-group:not(:last-child)>.btn,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:first-child>.btn-group:not(:first-child)>.btn,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:active,.input-group-btn>.btn:focus,.input-group-btn>.btn:hover{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{z-index:2;margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:focus,.nav>li>a:hover{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:focus,.nav>li.disabled>a:hover{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:focus,.nav .open>a:hover{background-color:#eee;border-color:#337ab7}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:focus,.nav-tabs>li.active>a:hover{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:focus,.nav-tabs.nav-justified>.active>a:hover{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{color:#fff;background-color:#337ab7}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:focus,.nav-tabs-justified>.active>a:hover{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-bottom .navbar-collapse,.navbar-fixed-top .navbar-collapse{max-height:200px}}.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container-fluid>.navbar-collapse,.container-fluid>.navbar-header,.container>.navbar-collapse,.container>.navbar-header{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-bottom,.navbar-fixed-top{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-bottom,.navbar-fixed-top{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu .dropdown-header,.navbar-nav .open .dropdown-menu>li>a{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:focus,.navbar-nav .open .dropdown-menu>li>a:hover{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .form-control,.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .checkbox,.navbar-form .radio{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .checkbox label,.navbar-form .radio label{padding-left:0}.navbar-form .checkbox input[type=checkbox],.navbar-form .radio input[type=radio]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{margin-bottom:0;border-top-left-radius:4px;border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:focus,.navbar-default .navbar-brand:hover{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:focus,.navbar-default .navbar-nav>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:focus,.navbar-default .navbar-nav>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:focus,.navbar-default .navbar-nav>.disabled>a:hover{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:focus,.navbar-default .navbar-toggle:hover{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:focus,.navbar-default .navbar-nav>.open>a:hover{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:focus,.navbar-default .btn-link:hover{color:#333}.navbar-default .btn-link[disabled]:focus,.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:focus,fieldset[disabled] .navbar-default .btn-link:hover{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#9d9d9d}.navbar-inverse .navbar-brand:focus,.navbar-inverse .navbar-brand:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav>li>a:focus,.navbar-inverse .navbar-nav>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:focus,.navbar-inverse .navbar-nav>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:focus,.navbar-inverse .navbar-nav>.disabled>a:hover{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:focus,.navbar-inverse .navbar-toggle:hover{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:focus,.navbar-inverse .navbar-nav>.open>a:hover{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#9d9d9d}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#9d9d9d}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#9d9d9d}.navbar-inverse .btn-link:focus,.navbar-inverse .btn-link:hover{color:#fff}.navbar-inverse .btn-link[disabled]:focus,.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:focus,fieldset[disabled] .navbar-inverse .btn-link:hover{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#337ab7;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{z-index:3;color:#23527c;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{z-index:2;color:#fff;cursor:default;background-color:#337ab7;border-color:#337ab7}.pagination>.disabled>a,.pagination>.disabled>a:focus,.pagination>.disabled>a:hover,.pagination>.disabled>span,.pagination>.disabled>span:focus,.pagination>.disabled>span:hover{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px;line-height:1.3333333}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px;line-height:1.5}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:focus,.pager li>a:hover{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:focus,a.label:hover{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:focus,.label-default[href]:hover{background-color:#5e5e5e}.label-primary{background-color:#337ab7}.label-primary[href]:focus,.label-primary[href]:hover{background-color:#286090}.label-success{background-color:#5cb85c}.label-success[href]:focus,.label-success[href]:hover{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:focus,.label-info[href]:hover{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:focus,.label-warning[href]:hover{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:focus,.label-danger[href]:hover{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:middle;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-group-xs>.btn .badge,.btn-xs .badge{top:0;padding:1px 5px}a.badge:focus,a.badge:hover{color:#fff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#337ab7;background-color:#fff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding-top:30px;padding-bottom:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron .h1,.jumbotron h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron,.container-fluid .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron,.container-fluid .jumbotron{padding-right:60px;padding-left:60px}.jumbotron .h1,.jumbotron h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail a>img,.thumbnail>img{margin-right:auto;margin-left:auto}a.thumbnail.active,a.thumbnail:focus,a.thumbnail:hover{border-color:#337ab7}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#337ab7;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-bar-striped,.progress-striped .progress-bar{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress-bar.active,.progress.active .progress-bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media,.media-body{overflow:hidden;zoom:1}.media-body{width:10000px}.media-object{display:block}.media-object.img-thumbnail{max-width:none}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-body,.media-left,.media-right{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}a.list-group-item,button.list-group-item{color:#555}a.list-group-item .list-group-item-heading,button.list-group-item .list-group-item-heading{color:#333}a.list-group-item:focus,a.list-group-item:hover,button.list-group-item:focus,button.list-group-item:hover{color:#555;text-decoration:none;background-color:#f5f5f5}button.list-group-item{width:100%;text-align:left}.list-group-item.disabled,.list-group-item.disabled:focus,.list-group-item.disabled:hover{color:#777;cursor:not-allowed;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:focus,.list-group-item.active:hover{z-index:2;color:#fff;background-color:#337ab7;border-color:#337ab7}.list-group-item.active .list-group-item-heading,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:focus .list-group-item-text,.list-group-item.active:hover .list-group-item-text{color:#c7ddef}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success,button.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading,button.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:focus,a.list-group-item-success:hover,button.list-group-item-success:focus,button.list-group-item-success:hover{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:focus,a.list-group-item-success.active:hover,button.list-group-item-success.active,button.list-group-item-success.active:focus,button.list-group-item-success.active:hover{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info,button.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading,button.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:focus,a.list-group-item-info:hover,button.list-group-item-info:focus,button.list-group-item-info:hover{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:focus,a.list-group-item-info.active:hover,button.list-group-item-info.active,button.list-group-item-info.active:focus,button.list-group-item-info.active:hover{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning,button.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading,button.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:focus,a.list-group-item-warning:hover,button.list-group-item-warning:focus,button.list-group-item-warning:hover{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:focus,a.list-group-item-warning.active:hover,button.list-group-item-warning.active,button.list-group-item-warning.active:focus,button.list-group-item-warning.active:hover{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger,button.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading,button.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:focus,a.list-group-item-danger:hover,button.list-group-item-danger:focus,button.list-group-item-danger:hover{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:focus,a.list-group-item-danger.active:hover,button.list-group-item-danger.active,button.list-group-item-danger.active:focus,button.list-group-item-danger.active:hover{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>.small,.panel-title>.small>a,.panel-title>a,.panel-title>small,.panel-title>small>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.panel-heading+.panel-collapse>.list-group .list-group-item:first-child{border-top-left-radius:0;border-top-right-radius:0}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.panel-collapse>.table,.panel>.table,.panel>.table-responsive>.table{margin-bottom:0}.panel>.panel-collapse>.table caption,.panel>.table caption,.panel>.table-responsive>.table caption{padding-right:15px;padding-left:15px}.panel>.table-responsive:first-child>.table:first-child,.panel>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table:first-child>thead:first-child>tr:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table-responsive:last-child>.table:last-child,.panel>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child td,.panel>.table>tbody:first-child>tr:first-child th{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child{border-left:0}.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child{border-right:0}.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.list-group,.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#337ab7}.panel-primary>.panel-heading{color:#fff;background-color:#337ab7;border-color:#337ab7}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#337ab7}.panel-primary>.panel-heading .badge{color:#337ab7;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#337ab7}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:focus,.close:hover{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate(0,-25%);-ms-transform:translate(0,-25%);-o-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.in .modal-dialog{-webkit-transform:translate(0,0);-ms-transform:translate(0,0);-o-transform:translate(0,0);transform:translate(0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;filter:alpha(opacity=0);opacity:0;line-break:auto}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{right:5px;bottom:0;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;font-style:normal;font-weight:400;line-height:1.42857143;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;word-wrap:normal;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);line-break:auto}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>a>img,.carousel-inner>.item>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-inner>.item.active.right,.carousel-inner>.item.next{left:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}.carousel-inner>.item.active.left,.carousel-inner>.item.prev{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.carousel-inner>.item.active,.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right{left:0;-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:focus,.carousel-control:hover{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{position:absolute;top:50%;z-index:5;display:inline-block;margin-top:-10px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{left:50%;margin-left:-10px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{right:50%;margin-right:-10px}.carousel-control .icon-next,.carousel-control .icon-prev{width:20px;height:20px;font-family:serif;line-height:1}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000\9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next,.carousel-control .icon-prev{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.btn-group-vertical>.btn-group:after,.btn-group-vertical>.btn-group:before,.btn-toolbar:after,.btn-toolbar:before,.clearfix:after,.clearfix:before,.container-fluid:after,.container-fluid:before,.container:after,.container:before,.dl-horizontal dd:after,.dl-horizontal dd:before,.form-horizontal .form-group:after,.form-horizontal .form-group:before,.modal-footer:after,.modal-footer:before,.nav:after,.nav:before,.navbar-collapse:after,.navbar-collapse:before,.navbar-header:after,.navbar-header:before,.navbar:after,.navbar:before,.pager:after,.pager:before,.panel-body:after,.panel-body:before,.row:after,.row:before{display:table;content:" "}.btn-group-vertical>.btn-group:after,.btn-toolbar:after,.clearfix:after,.container-fluid:after,.container:after,.dl-horizontal dd:after,.form-horizontal .form-group:after,.modal-footer:after,.nav:after,.navbar-collapse:after,.navbar-header:after,.navbar:after,.pager:after,.panel-body:after,.row:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-lg,.visible-md,.visible-sm,.visible-xs{display:none!important}.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table!important}tr.visible-xs{display:table-row!important}td.visible-xs,th.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table!important}tr.visible-sm{display:table-row!important}td.visible-sm,th.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table!important}tr.visible-md{display:table-row!important}td.visible-md,th.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table!important}tr.visible-lg{display:table-row!important}td.visible-lg,th.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table!important}tr.visible-print{display:table-row!important}td.visible-print,th.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.eot b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.eot new file mode 100644 index 00000000..b93a4953 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.eot differ diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.svg b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.svg new file mode 100644 index 00000000..94fb5490 --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.svg @@ -0,0 +1,288 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.ttf b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 00000000..1413fc60 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.ttf differ diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 00000000..9e612858 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff differ diff --git a/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 00000000..64539b54 Binary files /dev/null and b/LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/LinuxGUI/WebUI/static/bootstrap/js/bootstrap.min.js b/LinuxGUI/WebUI/static/bootstrap/js/bootstrap.min.js new file mode 100644 index 00000000..133aeecb --- /dev/null +++ b/LinuxGUI/WebUI/static/bootstrap/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v3.3.5 (http://getbootstrap.com) + * Copyright 2011-2015 Twitter, Inc. + * Licensed under the MIT license + */ +if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery");+function(a){"use strict";var b=a.fn.jquery.split(" ")[0].split(".");if(b[0]<2&&b[1]<9||1==b[0]&&9==b[1]&&b[2]<1)throw new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher")}(jQuery),+function(a){"use strict";function b(){var a=document.createElement("bootstrap"),b={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var c in b)if(void 0!==a.style[c])return{end:b[c]};return!1}a.fn.emulateTransitionEnd=function(b){var c=!1,d=this;a(this).one("bsTransitionEnd",function(){c=!0});var e=function(){c||a(d).trigger(a.support.transition.end)};return setTimeout(e,b),this},a(function(){a.support.transition=b(),a.support.transition&&(a.event.special.bsTransitionEnd={bindType:a.support.transition.end,delegateType:a.support.transition.end,handle:function(b){return a(b.target).is(this)?b.handleObj.handler.apply(this,arguments):void 0}})})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var c=a(this),e=c.data("bs.alert");e||c.data("bs.alert",e=new d(this)),"string"==typeof b&&e[b].call(c)})}var c='[data-dismiss="alert"]',d=function(b){a(b).on("click",c,this.close)};d.VERSION="3.3.5",d.TRANSITION_DURATION=150,d.prototype.close=function(b){function c(){g.detach().trigger("closed.bs.alert").remove()}var e=a(this),f=e.attr("data-target");f||(f=e.attr("href"),f=f&&f.replace(/.*(?=#[^\s]*$)/,""));var g=a(f);b&&b.preventDefault(),g.length||(g=e.closest(".alert")),g.trigger(b=a.Event("close.bs.alert")),b.isDefaultPrevented()||(g.removeClass("in"),a.support.transition&&g.hasClass("fade")?g.one("bsTransitionEnd",c).emulateTransitionEnd(d.TRANSITION_DURATION):c())};var e=a.fn.alert;a.fn.alert=b,a.fn.alert.Constructor=d,a.fn.alert.noConflict=function(){return a.fn.alert=e,this},a(document).on("click.bs.alert.data-api",c,d.prototype.close)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.button"),f="object"==typeof b&&b;e||d.data("bs.button",e=new c(this,f)),"toggle"==b?e.toggle():b&&e.setState(b)})}var c=function(b,d){this.$element=a(b),this.options=a.extend({},c.DEFAULTS,d),this.isLoading=!1};c.VERSION="3.3.5",c.DEFAULTS={loadingText:"loading..."},c.prototype.setState=function(b){var c="disabled",d=this.$element,e=d.is("input")?"val":"html",f=d.data();b+="Text",null==f.resetText&&d.data("resetText",d[e]()),setTimeout(a.proxy(function(){d[e](null==f[b]?this.options[b]:f[b]),"loadingText"==b?(this.isLoading=!0,d.addClass(c).attr(c,c)):this.isLoading&&(this.isLoading=!1,d.removeClass(c).removeAttr(c))},this),0)},c.prototype.toggle=function(){var a=!0,b=this.$element.closest('[data-toggle="buttons"]');if(b.length){var c=this.$element.find("input");"radio"==c.prop("type")?(c.prop("checked")&&(a=!1),b.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==c.prop("type")&&(c.prop("checked")!==this.$element.hasClass("active")&&(a=!1),this.$element.toggleClass("active")),c.prop("checked",this.$element.hasClass("active")),a&&c.trigger("change")}else this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active")};var d=a.fn.button;a.fn.button=b,a.fn.button.Constructor=c,a.fn.button.noConflict=function(){return a.fn.button=d,this},a(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(c){var d=a(c.target);d.hasClass("btn")||(d=d.closest(".btn")),b.call(d,"toggle"),a(c.target).is('input[type="radio"]')||a(c.target).is('input[type="checkbox"]')||c.preventDefault()}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(b){a(b.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(b.type))})}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.carousel"),f=a.extend({},c.DEFAULTS,d.data(),"object"==typeof b&&b),g="string"==typeof b?b:f.slide;e||d.data("bs.carousel",e=new c(this,f)),"number"==typeof b?e.to(b):g?e[g]():f.interval&&e.pause().cycle()})}var c=function(b,c){this.$element=a(b),this.$indicators=this.$element.find(".carousel-indicators"),this.options=c,this.paused=null,this.sliding=null,this.interval=null,this.$active=null,this.$items=null,this.options.keyboard&&this.$element.on("keydown.bs.carousel",a.proxy(this.keydown,this)),"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",a.proxy(this.pause,this)).on("mouseleave.bs.carousel",a.proxy(this.cycle,this))};c.VERSION="3.3.5",c.TRANSITION_DURATION=600,c.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0},c.prototype.keydown=function(a){if(!/input|textarea/i.test(a.target.tagName)){switch(a.which){case 37:this.prev();break;case 39:this.next();break;default:return}a.preventDefault()}},c.prototype.cycle=function(b){return b||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(a.proxy(this.next,this),this.options.interval)),this},c.prototype.getItemIndex=function(a){return this.$items=a.parent().children(".item"),this.$items.index(a||this.$active)},c.prototype.getItemForDirection=function(a,b){var c=this.getItemIndex(b),d="prev"==a&&0===c||"next"==a&&c==this.$items.length-1;if(d&&!this.options.wrap)return b;var e="prev"==a?-1:1,f=(c+e)%this.$items.length;return this.$items.eq(f)},c.prototype.to=function(a){var b=this,c=this.getItemIndex(this.$active=this.$element.find(".item.active"));return a>this.$items.length-1||0>a?void 0:this.sliding?this.$element.one("slid.bs.carousel",function(){b.to(a)}):c==a?this.pause().cycle():this.slide(a>c?"next":"prev",this.$items.eq(a))},c.prototype.pause=function(b){return b||(this.paused=!0),this.$element.find(".next, .prev").length&&a.support.transition&&(this.$element.trigger(a.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this},c.prototype.next=function(){return this.sliding?void 0:this.slide("next")},c.prototype.prev=function(){return this.sliding?void 0:this.slide("prev")},c.prototype.slide=function(b,d){var e=this.$element.find(".item.active"),f=d||this.getItemForDirection(b,e),g=this.interval,h="next"==b?"left":"right",i=this;if(f.hasClass("active"))return this.sliding=!1;var j=f[0],k=a.Event("slide.bs.carousel",{relatedTarget:j,direction:h});if(this.$element.trigger(k),!k.isDefaultPrevented()){if(this.sliding=!0,g&&this.pause(),this.$indicators.length){this.$indicators.find(".active").removeClass("active");var l=a(this.$indicators.children()[this.getItemIndex(f)]);l&&l.addClass("active")}var m=a.Event("slid.bs.carousel",{relatedTarget:j,direction:h});return a.support.transition&&this.$element.hasClass("slide")?(f.addClass(b),f[0].offsetWidth,e.addClass(h),f.addClass(h),e.one("bsTransitionEnd",function(){f.removeClass([b,h].join(" ")).addClass("active"),e.removeClass(["active",h].join(" ")),i.sliding=!1,setTimeout(function(){i.$element.trigger(m)},0)}).emulateTransitionEnd(c.TRANSITION_DURATION)):(e.removeClass("active"),f.addClass("active"),this.sliding=!1,this.$element.trigger(m)),g&&this.cycle(),this}};var d=a.fn.carousel;a.fn.carousel=b,a.fn.carousel.Constructor=c,a.fn.carousel.noConflict=function(){return a.fn.carousel=d,this};var e=function(c){var d,e=a(this),f=a(e.attr("data-target")||(d=e.attr("href"))&&d.replace(/.*(?=#[^\s]+$)/,""));if(f.hasClass("carousel")){var g=a.extend({},f.data(),e.data()),h=e.attr("data-slide-to");h&&(g.interval=!1),b.call(f,g),h&&f.data("bs.carousel").to(h),c.preventDefault()}};a(document).on("click.bs.carousel.data-api","[data-slide]",e).on("click.bs.carousel.data-api","[data-slide-to]",e),a(window).on("load",function(){a('[data-ride="carousel"]').each(function(){var c=a(this);b.call(c,c.data())})})}(jQuery),+function(a){"use strict";function b(b){var c,d=b.attr("data-target")||(c=b.attr("href"))&&c.replace(/.*(?=#[^\s]+$)/,"");return a(d)}function c(b){return this.each(function(){var c=a(this),e=c.data("bs.collapse"),f=a.extend({},d.DEFAULTS,c.data(),"object"==typeof b&&b);!e&&f.toggle&&/show|hide/.test(b)&&(f.toggle=!1),e||c.data("bs.collapse",e=new d(this,f)),"string"==typeof b&&e[b]()})}var d=function(b,c){this.$element=a(b),this.options=a.extend({},d.DEFAULTS,c),this.$trigger=a('[data-toggle="collapse"][href="#'+b.id+'"],[data-toggle="collapse"][data-target="#'+b.id+'"]'),this.transitioning=null,this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger),this.options.toggle&&this.toggle()};d.VERSION="3.3.5",d.TRANSITION_DURATION=350,d.DEFAULTS={toggle:!0},d.prototype.dimension=function(){var a=this.$element.hasClass("width");return a?"width":"height"},d.prototype.show=function(){if(!this.transitioning&&!this.$element.hasClass("in")){var b,e=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing");if(!(e&&e.length&&(b=e.data("bs.collapse"),b&&b.transitioning))){var f=a.Event("show.bs.collapse");if(this.$element.trigger(f),!f.isDefaultPrevented()){e&&e.length&&(c.call(e,"hide"),b||e.data("bs.collapse",null));var g=this.dimension();this.$element.removeClass("collapse").addClass("collapsing")[g](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1;var h=function(){this.$element.removeClass("collapsing").addClass("collapse in")[g](""),this.transitioning=0,this.$element.trigger("shown.bs.collapse")};if(!a.support.transition)return h.call(this);var i=a.camelCase(["scroll",g].join("-"));this.$element.one("bsTransitionEnd",a.proxy(h,this)).emulateTransitionEnd(d.TRANSITION_DURATION)[g](this.$element[0][i])}}}},d.prototype.hide=function(){if(!this.transitioning&&this.$element.hasClass("in")){var b=a.Event("hide.bs.collapse");if(this.$element.trigger(b),!b.isDefaultPrevented()){var c=this.dimension();this.$element[c](this.$element[c]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1;var e=function(){this.transitioning=0,this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")};return a.support.transition?void this.$element[c](0).one("bsTransitionEnd",a.proxy(e,this)).emulateTransitionEnd(d.TRANSITION_DURATION):e.call(this)}}},d.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()},d.prototype.getParent=function(){return a(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(a.proxy(function(c,d){var e=a(d);this.addAriaAndCollapsedClass(b(e),e)},this)).end()},d.prototype.addAriaAndCollapsedClass=function(a,b){var c=a.hasClass("in");a.attr("aria-expanded",c),b.toggleClass("collapsed",!c).attr("aria-expanded",c)};var e=a.fn.collapse;a.fn.collapse=c,a.fn.collapse.Constructor=d,a.fn.collapse.noConflict=function(){return a.fn.collapse=e,this},a(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(d){var e=a(this);e.attr("data-target")||d.preventDefault();var f=b(e),g=f.data("bs.collapse"),h=g?"toggle":e.data();c.call(f,h)})}(jQuery),+function(a){"use strict";function b(b){var c=b.attr("data-target");c||(c=b.attr("href"),c=c&&/#[A-Za-z]/.test(c)&&c.replace(/.*(?=#[^\s]*$)/,""));var d=c&&a(c);return d&&d.length?d:b.parent()}function c(c){c&&3===c.which||(a(e).remove(),a(f).each(function(){var d=a(this),e=b(d),f={relatedTarget:this};e.hasClass("open")&&(c&&"click"==c.type&&/input|textarea/i.test(c.target.tagName)&&a.contains(e[0],c.target)||(e.trigger(c=a.Event("hide.bs.dropdown",f)),c.isDefaultPrevented()||(d.attr("aria-expanded","false"),e.removeClass("open").trigger("hidden.bs.dropdown",f))))}))}function d(b){return this.each(function(){var c=a(this),d=c.data("bs.dropdown");d||c.data("bs.dropdown",d=new g(this)),"string"==typeof b&&d[b].call(c)})}var e=".dropdown-backdrop",f='[data-toggle="dropdown"]',g=function(b){a(b).on("click.bs.dropdown",this.toggle)};g.VERSION="3.3.5",g.prototype.toggle=function(d){var e=a(this);if(!e.is(".disabled, :disabled")){var f=b(e),g=f.hasClass("open");if(c(),!g){"ontouchstart"in document.documentElement&&!f.closest(".navbar-nav").length&&a(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(a(this)).on("click",c);var h={relatedTarget:this};if(f.trigger(d=a.Event("show.bs.dropdown",h)),d.isDefaultPrevented())return;e.trigger("focus").attr("aria-expanded","true"),f.toggleClass("open").trigger("shown.bs.dropdown",h)}return!1}},g.prototype.keydown=function(c){if(/(38|40|27|32)/.test(c.which)&&!/input|textarea/i.test(c.target.tagName)){var d=a(this);if(c.preventDefault(),c.stopPropagation(),!d.is(".disabled, :disabled")){var e=b(d),g=e.hasClass("open");if(!g&&27!=c.which||g&&27==c.which)return 27==c.which&&e.find(f).trigger("focus"),d.trigger("click");var h=" li:not(.disabled):visible a",i=e.find(".dropdown-menu"+h);if(i.length){var j=i.index(c.target);38==c.which&&j>0&&j--,40==c.which&&jdocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&a?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!a?this.scrollbarWidth:""})},c.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})},c.prototype.checkScrollbar=function(){var a=window.innerWidth;if(!a){var b=document.documentElement.getBoundingClientRect();a=b.right-Math.abs(b.left)}this.bodyIsOverflowing=document.body.clientWidth
',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}},c.prototype.init=function(b,c,d){if(this.enabled=!0,this.type=b,this.$element=a(c),this.options=this.getOptions(d),this.$viewport=this.options.viewport&&a(a.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(var e=this.options.trigger.split(" "),f=e.length;f--;){var g=e[f];if("click"==g)this.$element.on("click."+this.type,this.options.selector,a.proxy(this.toggle,this));else if("manual"!=g){var h="hover"==g?"mouseenter":"focusin",i="hover"==g?"mouseleave":"focusout";this.$element.on(h+"."+this.type,this.options.selector,a.proxy(this.enter,this)),this.$element.on(i+"."+this.type,this.options.selector,a.proxy(this.leave,this))}}this.options.selector?this._options=a.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.getOptions=function(b){return b=a.extend({},this.getDefaults(),this.$element.data(),b),b.delay&&"number"==typeof b.delay&&(b.delay={show:b.delay,hide:b.delay}),b},c.prototype.getDelegateOptions=function(){var b={},c=this.getDefaults();return this._options&&a.each(this._options,function(a,d){c[a]!=d&&(b[a]=d)}),b},c.prototype.enter=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusin"==b.type?"focus":"hover"]=!0),c.tip().hasClass("in")||"in"==c.hoverState?void(c.hoverState="in"):(clearTimeout(c.timeout),c.hoverState="in",c.options.delay&&c.options.delay.show?void(c.timeout=setTimeout(function(){"in"==c.hoverState&&c.show()},c.options.delay.show)):c.show())},c.prototype.isInStateTrue=function(){for(var a in this.inState)if(this.inState[a])return!0;return!1},c.prototype.leave=function(b){var c=b instanceof this.constructor?b:a(b.currentTarget).data("bs."+this.type);return c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c)),b instanceof a.Event&&(c.inState["focusout"==b.type?"focus":"hover"]=!1),c.isInStateTrue()?void 0:(clearTimeout(c.timeout),c.hoverState="out",c.options.delay&&c.options.delay.hide?void(c.timeout=setTimeout(function(){"out"==c.hoverState&&c.hide()},c.options.delay.hide)):c.hide())},c.prototype.show=function(){var b=a.Event("show.bs."+this.type);if(this.hasContent()&&this.enabled){this.$element.trigger(b);var d=a.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]);if(b.isDefaultPrevented()||!d)return;var e=this,f=this.tip(),g=this.getUID(this.type);this.setContent(),f.attr("id",g),this.$element.attr("aria-describedby",g),this.options.animation&&f.addClass("fade");var h="function"==typeof this.options.placement?this.options.placement.call(this,f[0],this.$element[0]):this.options.placement,i=/\s?auto?\s?/i,j=i.test(h);j&&(h=h.replace(i,"")||"top"),f.detach().css({top:0,left:0,display:"block"}).addClass(h).data("bs."+this.type,this),this.options.container?f.appendTo(this.options.container):f.insertAfter(this.$element),this.$element.trigger("inserted.bs."+this.type);var k=this.getPosition(),l=f[0].offsetWidth,m=f[0].offsetHeight;if(j){var n=h,o=this.getPosition(this.$viewport);h="bottom"==h&&k.bottom+m>o.bottom?"top":"top"==h&&k.top-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.right&&(e.left=g.left+g.width-k)}return e},c.prototype.getTitle=function(){var a,b=this.$element,c=this.options;return a=b.attr("data-original-title")||("function"==typeof c.title?c.title.call(b[0]):c.title)},c.prototype.getUID=function(a){do a+=~~(1e6*Math.random());while(document.getElementById(a));return a},c.prototype.tip=function(){if(!this.$tip&&(this.$tip=a(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")},c.prototype.enable=function(){this.enabled=!0},c.prototype.disable=function(){this.enabled=!1},c.prototype.toggleEnabled=function(){this.enabled=!this.enabled},c.prototype.toggle=function(b){var c=this;b&&(c=a(b.currentTarget).data("bs."+this.type),c||(c=new this.constructor(b.currentTarget,this.getDelegateOptions()),a(b.currentTarget).data("bs."+this.type,c))),b?(c.inState.click=!c.inState.click,c.isInStateTrue()?c.enter(c):c.leave(c)):c.tip().hasClass("in")?c.leave(c):c.enter(c)},c.prototype.destroy=function(){var a=this;clearTimeout(this.timeout),this.hide(function(){a.$element.off("."+a.type).removeData("bs."+a.type),a.$tip&&a.$tip.detach(),a.$tip=null,a.$arrow=null,a.$viewport=null})};var d=a.fn.tooltip;a.fn.tooltip=b,a.fn.tooltip.Constructor=c,a.fn.tooltip.noConflict=function(){return a.fn.tooltip=d,this}}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.popover"),f="object"==typeof b&&b;(e||!/destroy|hide/.test(b))&&(e||d.data("bs.popover",e=new c(this,f)),"string"==typeof b&&e[b]())})}var c=function(a,b){this.init("popover",a,b)};if(!a.fn.tooltip)throw new Error("Popover requires tooltip.js");c.VERSION="3.3.5",c.DEFAULTS=a.extend({},a.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:''}),c.prototype=a.extend({},a.fn.tooltip.Constructor.prototype),c.prototype.constructor=c,c.prototype.getDefaults=function(){return c.DEFAULTS},c.prototype.setContent=function(){var a=this.tip(),b=this.getTitle(),c=this.getContent();a.find(".popover-title")[this.options.html?"html":"text"](b),a.find(".popover-content").children().detach().end()[this.options.html?"string"==typeof c?"html":"append":"text"](c),a.removeClass("fade top bottom left right in"),a.find(".popover-title").html()||a.find(".popover-title").hide()},c.prototype.hasContent=function(){return this.getTitle()||this.getContent()},c.prototype.getContent=function(){var a=this.$element,b=this.options;return a.attr("data-content")||("function"==typeof b.content?b.content.call(a[0]):b.content)},c.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".arrow")};var d=a.fn.popover;a.fn.popover=b,a.fn.popover.Constructor=c,a.fn.popover.noConflict=function(){return a.fn.popover=d,this}}(jQuery),+function(a){"use strict";function b(c,d){this.$body=a(document.body),this.$scrollElement=a(a(c).is(document.body)?window:c),this.options=a.extend({},b.DEFAULTS,d),this.selector=(this.options.target||"")+" .nav li > a",this.offsets=[],this.targets=[],this.activeTarget=null,this.scrollHeight=0,this.$scrollElement.on("scroll.bs.scrollspy",a.proxy(this.process,this)),this.refresh(),this.process()}function c(c){return this.each(function(){var d=a(this),e=d.data("bs.scrollspy"),f="object"==typeof c&&c;e||d.data("bs.scrollspy",e=new b(this,f)),"string"==typeof c&&e[c]()})}b.VERSION="3.3.5",b.DEFAULTS={offset:10},b.prototype.getScrollHeight=function(){return this.$scrollElement[0].scrollHeight||Math.max(this.$body[0].scrollHeight,document.documentElement.scrollHeight)},b.prototype.refresh=function(){var b=this,c="offset",d=0;this.offsets=[],this.targets=[],this.scrollHeight=this.getScrollHeight(),a.isWindow(this.$scrollElement[0])||(c="position",d=this.$scrollElement.scrollTop()),this.$body.find(this.selector).map(function(){var b=a(this),e=b.data("target")||b.attr("href"),f=/^#./.test(e)&&a(e);return f&&f.length&&f.is(":visible")&&[[f[c]().top+d,e]]||null}).sort(function(a,b){return a[0]-b[0]}).each(function(){b.offsets.push(this[0]),b.targets.push(this[1])})},b.prototype.process=function(){var a,b=this.$scrollElement.scrollTop()+this.options.offset,c=this.getScrollHeight(),d=this.options.offset+c-this.$scrollElement.height(),e=this.offsets,f=this.targets,g=this.activeTarget;if(this.scrollHeight!=c&&this.refresh(),b>=d)return g!=(a=f[f.length-1])&&this.activate(a);if(g&&b=e[a]&&(void 0===e[a+1]||b .dropdown-menu > .active").removeClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!1),b.addClass("active").find('[data-toggle="tab"]').attr("aria-expanded",!0),h?(b[0].offsetWidth,b.addClass("in")):b.removeClass("fade"),b.parent(".dropdown-menu").length&&b.closest("li.dropdown").addClass("active").end().find('[data-toggle="tab"]').attr("aria-expanded",!0),e&&e()}var g=d.find("> .active"),h=e&&a.support.transition&&(g.length&&g.hasClass("fade")||!!d.find("> .fade").length);g.length&&h?g.one("bsTransitionEnd",f).emulateTransitionEnd(c.TRANSITION_DURATION):f(),g.removeClass("in")};var d=a.fn.tab;a.fn.tab=b,a.fn.tab.Constructor=c,a.fn.tab.noConflict=function(){return a.fn.tab=d,this};var e=function(c){c.preventDefault(),b.call(a(this),"show")};a(document).on("click.bs.tab.data-api",'[data-toggle="tab"]',e).on("click.bs.tab.data-api",'[data-toggle="pill"]',e)}(jQuery),+function(a){"use strict";function b(b){return this.each(function(){var d=a(this),e=d.data("bs.affix"),f="object"==typeof b&&b;e||d.data("bs.affix",e=new c(this,f)),"string"==typeof b&&e[b]()})}var c=function(b,d){this.options=a.extend({},c.DEFAULTS,d),this.$target=a(this.options.target).on("scroll.bs.affix.data-api",a.proxy(this.checkPosition,this)).on("click.bs.affix.data-api",a.proxy(this.checkPositionWithEventLoop,this)),this.$element=a(b),this.affixed=null,this.unpin=null,this.pinnedOffset=null,this.checkPosition()};c.VERSION="3.3.5",c.RESET="affix affix-top affix-bottom",c.DEFAULTS={offset:0,target:window},c.prototype.getState=function(a,b,c,d){var e=this.$target.scrollTop(),f=this.$element.offset(),g=this.$target.height();if(null!=c&&"top"==this.affixed)return c>e?"top":!1;if("bottom"==this.affixed)return null!=c?e+this.unpin<=f.top?!1:"bottom":a-d>=e+g?!1:"bottom";var h=null==this.affixed,i=h?e:f.top,j=h?g:b;return null!=c&&c>=e?"top":null!=d&&i+j>=a-d?"bottom":!1},c.prototype.getPinnedOffset=function(){if(this.pinnedOffset)return this.pinnedOffset;this.$element.removeClass(c.RESET).addClass("affix");var a=this.$target.scrollTop(),b=this.$element.offset();return this.pinnedOffset=b.top-a},c.prototype.checkPositionWithEventLoop=function(){setTimeout(a.proxy(this.checkPosition,this),1)},c.prototype.checkPosition=function(){if(this.$element.is(":visible")){var b=this.$element.height(),d=this.options.offset,e=d.top,f=d.bottom,g=Math.max(a(document).height(),a(document.body).height());"object"!=typeof d&&(f=e=d),"function"==typeof e&&(e=d.top(this.$element)),"function"==typeof f&&(f=d.bottom(this.$element));var h=this.getState(g,b,e,f);if(this.affixed!=h){null!=this.unpin&&this.$element.css("top","");var i="affix"+(h?"-"+h:""),j=a.Event(i+".bs.affix");if(this.$element.trigger(j),j.isDefaultPrevented())return;this.affixed=h,this.unpin="bottom"==h?this.getPinnedOffset():null,this.$element.removeClass(c.RESET).addClass(i).trigger(i.replace("affix","affixed")+".bs.affix")}"bottom"==h&&this.$element.offset({top:g-b-f})}};var d=a.fn.affix;a.fn.affix=b,a.fn.affix.Constructor=c,a.fn.affix.noConflict=function(){return a.fn.affix=d,this},a(window).on("load",function(){a('[data-spy="affix"]').each(function(){var c=a(this),d=c.data();d.offset=d.offset||{},null!=d.offsetBottom&&(d.offset.bottom=d.offsetBottom),null!=d.offsetTop&&(d.offset.top=d.offsetTop),b.call(c,d)})})}(jQuery); \ No newline at end of file diff --git a/LinuxGUI/WebUI/static/css/font-awesome.min.css b/LinuxGUI/WebUI/static/css/font-awesome.min.css new file mode 100644 index 00000000..aae88c41 --- /dev/null +++ b/LinuxGUI/WebUI/static/css/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.4.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.4.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.4.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.4.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.4.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.4.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.4.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1);-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1);-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"} diff --git a/LinuxGUI/WebUI/static/css/ionicons.min.css b/LinuxGUI/WebUI/static/css/ionicons.min.css new file mode 100644 index 00000000..e4bd1ef2 --- /dev/null +++ b/LinuxGUI/WebUI/static/css/ionicons.min.css @@ -0,0 +1,11 @@ +@charset "UTF-8";/*! + Ionicons, v2.0.1 + Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ + https://twitter.com/benjsperry https://twitter.com/ionicframework + MIT License: https://github.com/driftyco/ionicons + + Android-style icons originally built by Google’s + Material Design Icons: https://github.com/google/material-design-icons + used under CC BY http://creativecommons.org/licenses/by/4.0/ + Modified icons to fit ionicon’s grid from original. +*/@font-face{font-family:"Ionicons";src:url("../fonts/ionicons.eot?v=2.0.1");src:url("../fonts/ionicons.eot?v=2.0.1#iefix") format("embedded-opentype"),url("../fonts/ionicons.ttf?v=2.0.1") format("truetype"),url("../fonts/ionicons.woff?v=2.0.1") format("woff"),url("../fonts/ionicons.svg?v=2.0.1#Ionicons") format("svg");font-weight:normal;font-style:normal}.ion,.ionicons,.ion-alert:before,.ion-alert-circled:before,.ion-android-add:before,.ion-android-add-circle:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done:before,.ion-android-done-all:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite:before,.ion-android-favorite-outline:before,.ion-android-film:before,.ion-android-folder:before,.ion-android-folder-open:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone:before,.ion-android-microphone-off:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person:before,.ion-android-person-add:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove:before,.ion-android-remove-circle:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share:before,.ion-android-share-alt:before,.ion-android-star:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace:before,.ion-backspace-outline:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox:before,.ion-chatbox-working:before,.ion-chatboxes:before,.ion-chatbubble:before,.ion-chatbubble-working:before,.ion-chatbubbles:before,.ion-checkmark:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close:before,.ion-close-circled:before,.ion-close-round:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code:before,.ion-code-download:before,.ion-code-working:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document:before,.ion-document-text:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email:before,.ion-email-unread:before,.ion-erlenmeyer-flask:before,.ion-erlenmeyer-flask-bubbles:before,.ion-eye:before,.ion-eye-disabled:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash:before,.ion-flash-off:before,.ion-folder:before,.ion-fork:before,.ion-fork-repo:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy:before,.ion-happy-outline:before,.ion-headphone:before,.ion-heart:before,.ion-heart-broken:before,.ion-help:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information:before,.ion-information-circled:before,.ion-ionic:before,.ion-ios-alarm:before,.ion-ios-alarm-outline:before,.ion-ios-albums:before,.ion-ios-albums-outline:before,.ion-ios-americanfootball:before,.ion-ios-americanfootball-outline:before,.ion-ios-analytics:before,.ion-ios-analytics-outline:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at:before,.ion-ios-at-outline:before,.ion-ios-barcode:before,.ion-ios-barcode-outline:before,.ion-ios-baseball:before,.ion-ios-baseball-outline:before,.ion-ios-basketball:before,.ion-ios-basketball-outline:before,.ion-ios-bell:before,.ion-ios-bell-outline:before,.ion-ios-body:before,.ion-ios-body-outline:before,.ion-ios-bolt:before,.ion-ios-bolt-outline:before,.ion-ios-book:before,.ion-ios-book-outline:before,.ion-ios-bookmarks:before,.ion-ios-bookmarks-outline:before,.ion-ios-box:before,.ion-ios-box-outline:before,.ion-ios-briefcase:before,.ion-ios-briefcase-outline:before,.ion-ios-browsers:before,.ion-ios-browsers-outline:before,.ion-ios-calculator:before,.ion-ios-calculator-outline:before,.ion-ios-calendar:before,.ion-ios-calendar-outline:before,.ion-ios-camera:before,.ion-ios-camera-outline:before,.ion-ios-cart:before,.ion-ios-cart-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatbubble:before,.ion-ios-chatbubble-outline:before,.ion-ios-checkmark:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock:before,.ion-ios-clock-outline:before,.ion-ios-close:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-cloud:before,.ion-ios-cloud-download:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloudy:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-outline:before,.ion-ios-cog:before,.ion-ios-cog-outline:before,.ion-ios-color-filter:before,.ion-ios-color-filter-outline:before,.ion-ios-color-wand:before,.ion-ios-color-wand-outline:before,.ion-ios-compose:before,.ion-ios-compose-outline:before,.ion-ios-contact:before,.ion-ios-contact-outline:before,.ion-ios-copy:before,.ion-ios-copy-outline:before,.ion-ios-crop:before,.ion-ios-crop-strong:before,.ion-ios-download:before,.ion-ios-download-outline:before,.ion-ios-drag:before,.ion-ios-email:before,.ion-ios-email-outline:before,.ion-ios-eye:before,.ion-ios-eye-outline:before,.ion-ios-fastforward:before,.ion-ios-fastforward-outline:before,.ion-ios-filing:before,.ion-ios-filing-outline:before,.ion-ios-film:before,.ion-ios-film-outline:before,.ion-ios-flag:before,.ion-ios-flag-outline:before,.ion-ios-flame:before,.ion-ios-flame-outline:before,.ion-ios-flask:before,.ion-ios-flask-outline:before,.ion-ios-flower:before,.ion-ios-flower-outline:before,.ion-ios-folder:before,.ion-ios-folder-outline:before,.ion-ios-football:before,.ion-ios-football-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-b:before,.ion-ios-game-controller-b-outline:before,.ion-ios-gear:before,.ion-ios-gear-outline:before,.ion-ios-glasses:before,.ion-ios-glasses-outline:before,.ion-ios-grid-view:before,.ion-ios-grid-view-outline:before,.ion-ios-heart:before,.ion-ios-heart-outline:before,.ion-ios-help:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-home:before,.ion-ios-home-outline:before,.ion-ios-infinite:before,.ion-ios-infinite-outline:before,.ion-ios-information:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-ionic-outline:before,.ion-ios-keypad:before,.ion-ios-keypad-outline:before,.ion-ios-lightbulb:before,.ion-ios-lightbulb-outline:before,.ion-ios-list:before,.ion-ios-list-outline:before,.ion-ios-location:before,.ion-ios-location-outline:before,.ion-ios-locked:before,.ion-ios-locked-outline:before,.ion-ios-loop:before,.ion-ios-loop-strong:before,.ion-ios-medical:before,.ion-ios-medical-outline:before,.ion-ios-medkit:before,.ion-ios-medkit-outline:before,.ion-ios-mic:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-minus:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-monitor:before,.ion-ios-monitor-outline:before,.ion-ios-moon:before,.ion-ios-moon-outline:before,.ion-ios-more:before,.ion-ios-more-outline:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate:before,.ion-ios-navigate-outline:before,.ion-ios-nutrition:before,.ion-ios-nutrition-outline:before,.ion-ios-paper:before,.ion-ios-paper-outline:before,.ion-ios-paperplane:before,.ion-ios-paperplane-outline:before,.ion-ios-partlysunny:before,.ion-ios-partlysunny-outline:before,.ion-ios-pause:before,.ion-ios-pause-outline:before,.ion-ios-paw:before,.ion-ios-paw-outline:before,.ion-ios-people:before,.ion-ios-people-outline:before,.ion-ios-person:before,.ion-ios-person-outline:before,.ion-ios-personadd:before,.ion-ios-personadd-outline:before,.ion-ios-photos:before,.ion-ios-photos-outline:before,.ion-ios-pie:before,.ion-ios-pie-outline:before,.ion-ios-pint:before,.ion-ios-pint-outline:before,.ion-ios-play:before,.ion-ios-play-outline:before,.ion-ios-plus:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetags:before,.ion-ios-pricetags-outline:before,.ion-ios-printer:before,.ion-ios-printer-outline:before,.ion-ios-pulse:before,.ion-ios-pulse-strong:before,.ion-ios-rainy:before,.ion-ios-rainy-outline:before,.ion-ios-recording:before,.ion-ios-recording-outline:before,.ion-ios-redo:before,.ion-ios-redo-outline:before,.ion-ios-refresh:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-reload:before,.ion-ios-reverse-camera:before,.ion-ios-reverse-camera-outline:before,.ion-ios-rewind:before,.ion-ios-rewind-outline:before,.ion-ios-rose:before,.ion-ios-rose-outline:before,.ion-ios-search:before,.ion-ios-search-strong:before,.ion-ios-settings:before,.ion-ios-settings-strong:before,.ion-ios-shuffle:before,.ion-ios-shuffle-strong:before,.ion-ios-skipbackward:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipforward:before,.ion-ios-skipforward-outline:before,.ion-ios-snowy:before,.ion-ios-speedometer:before,.ion-ios-speedometer-outline:before,.ion-ios-star:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-stopwatch:before,.ion-ios-stopwatch-outline:before,.ion-ios-sunny:before,.ion-ios-sunny-outline:before,.ion-ios-telephone:before,.ion-ios-telephone-outline:before,.ion-ios-tennisball:before,.ion-ios-tennisball-outline:before,.ion-ios-thunderstorm:before,.ion-ios-thunderstorm-outline:before,.ion-ios-time:before,.ion-ios-time-outline:before,.ion-ios-timer:before,.ion-ios-timer-outline:before,.ion-ios-toggle:before,.ion-ios-toggle-outline:before,.ion-ios-trash:before,.ion-ios-trash-outline:before,.ion-ios-undo:before,.ion-ios-undo-outline:before,.ion-ios-unlocked:before,.ion-ios-unlocked-outline:before,.ion-ios-upload:before,.ion-ios-upload-outline:before,.ion-ios-videocam:before,.ion-ios-videocam-outline:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass:before,.ion-ios-wineglass-outline:before,.ion-ios-world:before,.ion-ios-world-outline:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon:before,.ion-navicon-round:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person:before,.ion-person-add:before,.ion-person-stalker:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply:before,.ion-reply-all:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad:before,.ion-sad-outline:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android:before,.ion-social-android-outline:before,.ion-social-angular:before,.ion-social-angular-outline:before,.ion-social-apple:before,.ion-social-apple-outline:before,.ion-social-bitcoin:before,.ion-social-bitcoin-outline:before,.ion-social-buffer:before,.ion-social-buffer-outline:before,.ion-social-chrome:before,.ion-social-chrome-outline:before,.ion-social-codepen:before,.ion-social-codepen-outline:before,.ion-social-css3:before,.ion-social-css3-outline:before,.ion-social-designernews:before,.ion-social-designernews-outline:before,.ion-social-dribbble:before,.ion-social-dribbble-outline:before,.ion-social-dropbox:before,.ion-social-dropbox-outline:before,.ion-social-euro:before,.ion-social-euro-outline:before,.ion-social-facebook:before,.ion-social-facebook-outline:before,.ion-social-foursquare:before,.ion-social-foursquare-outline:before,.ion-social-freebsd-devil:before,.ion-social-github:before,.ion-social-github-outline:before,.ion-social-google:before,.ion-social-google-outline:before,.ion-social-googleplus:before,.ion-social-googleplus-outline:before,.ion-social-hackernews:before,.ion-social-hackernews-outline:before,.ion-social-html5:before,.ion-social-html5-outline:before,.ion-social-instagram:before,.ion-social-instagram-outline:before,.ion-social-javascript:before,.ion-social-javascript-outline:before,.ion-social-linkedin:before,.ion-social-linkedin-outline:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest:before,.ion-social-pinterest-outline:before,.ion-social-python:before,.ion-social-reddit:before,.ion-social-reddit-outline:before,.ion-social-rss:before,.ion-social-rss-outline:before,.ion-social-sass:before,.ion-social-skype:before,.ion-social-skype-outline:before,.ion-social-snapchat:before,.ion-social-snapchat-outline:before,.ion-social-tumblr:before,.ion-social-tumblr-outline:before,.ion-social-tux:before,.ion-social-twitch:before,.ion-social-twitch-outline:before,.ion-social-twitter:before,.ion-social-twitter-outline:before,.ion-social-usd:before,.ion-social-usd-outline:before,.ion-social-vimeo:before,.ion-social-vimeo-outline:before,.ion-social-whatsapp:before,.ion-social-whatsapp-outline:before,.ion-social-windows:before,.ion-social-windows-outline:before,.ion-social-wordpress:before,.ion-social-wordpress-outline:before,.ion-social-yahoo:before,.ion-social-yahoo-outline:before,.ion-social-yen:before,.ion-social-yen-outline:before,.ion-social-youtube:before,.ion-social-youtube-outline:before,.ion-soup-can:before,.ion-soup-can-outline:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle:before,.ion-toggle-filled:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt:before,.ion-tshirt-outline:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before{display:inline-block;font-family:"Ionicons";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} diff --git a/LinuxGUI/WebUI/static/css/vtoy.css b/LinuxGUI/WebUI/static/css/vtoy.css new file mode 100644 index 00000000..f9fcf4e1 --- /dev/null +++ b/LinuxGUI/WebUI/static/css/vtoy.css @@ -0,0 +1,357 @@ +/*loading ¶¯»­*/ +.loading { + width: 100%; + height: 100%; + position: fixed; + top:0; + left:0; + z-index: 999999; + background-color: rgba(0, 0, 0, 0); +} +.loading .title { + width: 300px; + text-align: center; + margin: 250px auto 0px; + color: #2F7095; + font-weight: 900; + font-size: 24px; +} +.loading .rectbox { + width: 150px; + height: 40px; + margin: 10px auto; +} +.loading .rectbox .title { + font-size: 14px; + font-family: 'Microsoft YaHei'; + font-weight: 900; + text-align: center; + color: rgba(68, 149, 57, 1); +} +.loading .rectbox .rect { + width: 25px; + height: 25px; + background-color: rgba(68, 149, 57, 1); + margin: 0 2px auto 3px; + float: left; + -webkit-animation: loading 0.48s infinite ease-in-out; + -o-animation: loading 0.48s infinite ease-in-out; + animation: loading 0.48s infinite ease-in-out; +} +.loading .rectbox .rect1 { + -webkit-animation-delay: 0s; + -moz-animation-delay: 0s; + -o-animation-delay: 0s; + animation-delay: 0s; +} +.loading .rectbox .rect2 { + -webkit-animation-delay: 0.12s; + -moz-animation-delay: 0.12s; + -o-animation-delay: 0.12s; + animation-delay: 0.12s; + background-color: rgba(68, 149, 57, 0.2); +} +.loading .rectbox .rect3 { + -webkit-animation-delay: 0.24s; + -moz-animation-delay: 0.24s; + -o-animation-delay: 0.24s; + animation-delay: 0.24s; + background-color: rgba(68, 149, 57, 0.4); +} +.loading .rectbox .rect4 { + -webkit-animation-delay: 0.36s; + -moz-animation-delay: 0.36s; + -o-animation-delay: 0.36s; + animation-delay: 0.36s; + background-color: rgba(68, 149, 57, 0.6); +} +.loading .rectbox .rect5 { + -webkit-animation-delay: 0.48s; + -moz-animation-delay: 0.48s; + -o-animation-delay: 0.48s; + animation-delay: 0.48s; + background-color: rgba(68, 149, 57, 0.8); +} +@keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-moz-keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-ms-keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-webkit-keyframes loading { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} + +/*vtoy server is running*/ +#vtoy-main .loading { + width: 100%; + position: relative; + top:0; + left:0; + background-color: rgba(0, 0, 0, 0); +} +#vtoy-main .loading .title { + width: 300px; + text-align: center; + margin: 250px auto 0px; + color: #449539; + font-weight: 900; + font-size: 24px; +} +#vtoy-main .loading .rectbox { + width: 120px; + height: 40px; + margin: 10px auto; +} +#vtoy-main .loading .rectbox .title { + font-size: 14px; + font-family: 'Microsoft YaHei'; + font-weight: 900; + text-align: center; + color: rgba(68, 149, 57, 1); +} +#vtoy-main .loading .rectbox .rect { + width: 25px; + height: 25px; + background-color: rgba(68, 149, 57, 1); + margin: 0 2px auto 3px; + float: left; + -webkit-animation: loading 1.44s infinite ease-in-out; + -o-animation: loading 0.48s infinite ease-in-out; + animation: loading 0.48s infinite ease-in-out; +} +#vtoy-main .loading .rectbox .rect1 { + -webkit-animation-delay: 0s; + -moz-animation-delay: 0s; + -o-animation-delay: 0s; + animation-delay: 0s; +} +#vtoy-main .loading .rectbox .rect2 { + -webkit-animation-delay: 0.36s; + -moz-animation-delay: 0.12s; + -o-animation-delay: 0.12s; + animation-delay: 0.12s; + background-color: rgba(68, 149, 57, 0.2); +} +#vtoy-main .loading .rectbox .rect3 { + -webkit-animation-delay: 0.72s; + -moz-animation-delay: 0.24s; + -o-animation-delay: 0.24s; + animation-delay: 0.24s; + background-color: rgba(68, 149, 57, 0.4); +} +#vtoy-main .loading .rectbox .rect4 { + -webkit-animation-delay: 1.08s; + -moz-animation-delay: 0.36s; + -o-animation-delay: 0.36s; + animation-delay: 0.36s; + background-color: rgba(68, 149, 57, 0.6); +} +#vtoy-main .loading .rectbox .rect5 { + -webkit-animation-delay: 1.44s; + -moz-animation-delay: 0.48s; + -o-animation-delay: 0.48s; + animation-delay: 0.48s; + background-color: rgba(68, 149, 57, 0.8); +} +@keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-moz-keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-ms-keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} +@-webkit-keyframes running { + 0% { + background-color: rgba(68, 149, 57, 1); + } + 25% { + background-color: rgba(68, 149, 57, 0.8); + } + 50% { + background-color: rgba(68, 149, 57, 0.6); + } + 75% { + background-color: rgba(68, 149, 57, 0.4); + } + 100% { + background-color: rgba(68, 149, 57, 0.2); + } +} + + + +.loadEffect{ + width: 110px; + height: 110px; + position: relative; + margin: 0 auto; + margin-top:0 auto; +} +.loadEffect span{ + display: inline-block; + width: 20px; + height: 20px; + border-radius: 50%; + background: lightgreen; + position: absolute; + -webkit-animation: load 1.04s ease infinite; +} +@-webkit-keyframes load{ + 0%{ + opacity: 1; + } + 100%{ + opacity: 0.2; + } +} + + + + +.loadEffect span:nth-child(1){ + left: 40%; + top: -130%; + -webkit-animation-delay:0.13s; +} +.loadEffect span:nth-child(2){ + left: 90%; + top: 8%; + margin-top:-120%; + -webkit-animation-delay:0.26s; +} +.loadEffect span:nth-child(3){ + left: 110%; + top: -80%; + margin-left: %-100; + -webkit-animation-delay:0.39s; +} +.loadEffect span:nth-child(4){ + top: -40%; + left:110%; + -webkit-animation-delay:0.52s; +} +.loadEffect span:nth-child(5){ + left: 40%; + top: 0; + margin-top:10%; + -webkit-animation-delay:0.65s; +} +.loadEffect span:nth-child(6){ + left: -20%; + bottom:120%; + -webkit-animation-delay:0.78s; +} +.loadEffect span:nth-child(7){ + bottom: 160%; + left: -20%; + -webkit-animation-delay:0.91s; +} +.loadEffect span:nth-child(8){ + bottom: 200%; + left: -10%; + -webkit-animation-delay:1.04s; +} diff --git a/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.ttf b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..d7994e13 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.ttf differ diff --git a/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..6fd4ede0 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff differ diff --git a/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff2 b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..5560193c Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff2 differ diff --git a/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.ttf b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.ttf new file mode 100644 index 00000000..1413fc60 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.ttf differ diff --git a/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff new file mode 100644 index 00000000..9e612858 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff differ diff --git a/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff2 b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff2 new file mode 100644 index 00000000..64539b54 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff2 differ diff --git a/LinuxGUI/WebUI/static/fonts/ionicons.eot b/LinuxGUI/WebUI/static/fonts/ionicons.eot new file mode 100644 index 00000000..9caa3489 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/ionicons.eot differ diff --git a/LinuxGUI/WebUI/static/fonts/ionicons.ttf b/LinuxGUI/WebUI/static/fonts/ionicons.ttf new file mode 100644 index 00000000..180ce515 Binary files /dev/null and b/LinuxGUI/WebUI/static/fonts/ionicons.ttf differ diff --git a/LinuxGUI/WebUI/static/img/VentoyLogo.png b/LinuxGUI/WebUI/static/img/VentoyLogo.png new file mode 100644 index 00000000..a13884a4 Binary files /dev/null and b/LinuxGUI/WebUI/static/img/VentoyLogo.png differ diff --git a/LinuxGUI/WebUI/static/img/dropdown.png b/LinuxGUI/WebUI/static/img/dropdown.png new file mode 100644 index 00000000..201a4ca9 Binary files /dev/null and b/LinuxGUI/WebUI/static/img/dropdown.png differ diff --git a/LinuxGUI/WebUI/static/img/refresh.ico b/LinuxGUI/WebUI/static/img/refresh.ico new file mode 100644 index 00000000..c2bc3388 Binary files /dev/null and b/LinuxGUI/WebUI/static/img/refresh.ico differ diff --git a/LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js b/LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js new file mode 100644 index 00000000..49990d6e --- /dev/null +++ b/LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js @@ -0,0 +1,4 @@ +/*! jQuery v2.1.4 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b="length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){ +return M.access(a,b,c)},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,ba=/<([\w:]+)/,ca=/<|&#?\w+;/,da=/<(?:script|style|link)/i,ea=/checked\s*(?:[^=]|=\s*.checked.)/i,fa=/^$|\/(?:java|ecma)script/i,ga=/^true\/(.*)/,ha=/^\s*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ia.optgroup=ia.option,ia.tbody=ia.tfoot=ia.colgroup=ia.caption=ia.thead,ia.th=ia.td;function ja(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function ka(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function la(a){var b=ga.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function ma(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function na(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function oa(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pa(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=oa(h),f=oa(a),d=0,e=f.length;e>d;d++)pa(f[d],g[d]);if(b)if(c)for(f=f||oa(a),g=g||oa(h),d=0,e=f.length;e>d;d++)na(f[d],g[d]);else na(a,h);return g=oa(h,"script"),g.length>0&&ma(g,!i&&oa(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(ca.test(e)){f=f||k.appendChild(b.createElement("div")),g=(ba.exec(e)||["",""])[1].toLowerCase(),h=ia[g]||ia._default,f.innerHTML=h[1]+e.replace(aa,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=oa(k.appendChild(e),"script"),i&&ma(f),c)){j=0;while(e=f[j++])fa.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=ja(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(oa(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&ma(oa(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(oa(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!da.test(a)&&!ia[(ba.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(aa,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(oa(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(oa(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&ea.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(oa(c,"script"),ka),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,oa(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,la),j=0;g>j;j++)h=f[j],fa.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(ha,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qa,ra={};function sa(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function ta(a){var b=l,c=ra[a];return c||(c=sa(a,b),"none"!==c&&c||(qa=(qa||n("