From 43e8ec57857e3786b40eb4208729e9fcf9826000 Mon Sep 17 00:00:00 2001 From: longpanda Date: Fri, 26 Feb 2021 21:36:53 +0800 Subject: [PATCH] Experimental Linux GUI based on web browser --- INSTALL/README | 4 + INSTALL/VentoyWeb.sh | 182 + INSTALL/ventoy_pack.sh | 12 + LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c | 299 + LinuxGUI/Ventoy2Disk/Core/ventoy_define.h | 192 + LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c | 735 + LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h | 145 + LinuxGUI/Ventoy2Disk/Core/ventoy_json.c | 716 + LinuxGUI/Ventoy2Disk/Core/ventoy_json.h | 267 + LinuxGUI/Ventoy2Disk/Core/ventoy_log.c | 115 + LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c | 167 + LinuxGUI/Ventoy2Disk/Core/ventoy_util.c | 541 + LinuxGUI/Ventoy2Disk/Core/ventoy_util.h | 52 + LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h | 26 + LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh | 30 + .../Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip | Bin 0 -> 90929 bytes .../Lib/exfat/src/libexfat/byteorder.h | 68 + .../Lib/exfat/src/libexfat/cluster.c | 491 + .../Lib/exfat/src/libexfat/compiler.h | 66 + .../Lib/exfat/src/libexfat/config.h | 40 + .../Lib/exfat/src/libexfat/exfat.h | 255 + .../Lib/exfat/src/libexfat/exfatfs.h | 180 + .../Ventoy2Disk/Lib/exfat/src/libexfat/io.c | 511 + .../Lib/exfat/src/libexfat/lookup.c | 224 + .../Lib/exfat/src/libexfat/mount.c | 389 + .../Ventoy2Disk/Lib/exfat/src/libexfat/node.c | 1226 ++ .../Lib/exfat/src/libexfat/platform.h | 63 + .../Lib/exfat/src/libexfat/repair.c | 103 + .../Ventoy2Disk/Lib/exfat/src/libexfat/time.c | 164 + .../Ventoy2Disk/Lib/exfat/src/libexfat/utf.c | 245 + .../Lib/exfat/src/libexfat/utils.c | 180 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c | 79 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h | 30 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c | 88 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h | 30 + .../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c | 167 + .../Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h | 49 + .../Lib/exfat/src/mkfs/mkexfat_main.c | 268 + .../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c | 102 + .../Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h | 30 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c | 52 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h | 30 + .../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c | 757 + .../Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h | 30 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c | 148 + LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h | 30 + .../Ventoy2Disk/Lib/fat_io_lib/buildlib.sh | 30 + .../Lib/fat_io_lib/include/fat_access.h | 133 + .../Lib/fat_io_lib/include/fat_cache.h | 13 + .../Lib/fat_io_lib/include/fat_defs.h | 128 + .../Lib/fat_io_lib/include/fat_filelib.h | 146 + .../Lib/fat_io_lib/include/fat_format.h | 15 + .../Lib/fat_io_lib/include/fat_list.h | 161 + .../Lib/fat_io_lib/include/fat_misc.h | 63 + .../Lib/fat_io_lib/include/fat_opts.h | 90 + .../Lib/fat_io_lib/include/fat_string.h | 20 + .../Lib/fat_io_lib/include/fat_table.h | 20 + .../Lib/fat_io_lib/include/fat_types.h | 69 + .../Lib/fat_io_lib/include/fat_write.h | 14 + .../Lib/fat_io_lib/lib/libfat_io_32.a | Bin 0 -> 45670 bytes .../Lib/fat_io_lib/lib/libfat_io_64.a | Bin 0 -> 58226 bytes .../Lib/fat_io_lib/lib/libfat_io_aa64.a | Bin 0 -> 47506 bytes .../Lib/fat_io_lib/release/API.txt | 22 + .../Lib/fat_io_lib/release/COPYRIGHT.txt | 345 + .../Lib/fat_io_lib/release/Configuration.txt | 53 + .../Lib/fat_io_lib/release/History.txt | 24 + .../Lib/fat_io_lib/release/License.txt | 10 + .../fat_io_lib/release/Media Access API.txt | 40 + .../Lib/fat_io_lib/release/example.c | 87 + .../Lib/fat_io_lib/release/fat_access.c | 904 ++ .../Lib/fat_io_lib/release/fat_access.h | 133 + .../Lib/fat_io_lib/release/fat_cache.c | 91 + .../Lib/fat_io_lib/release/fat_cache.h | 13 + .../Lib/fat_io_lib/release/fat_defs.h | 128 + .../Lib/fat_io_lib/release/fat_filelib.c | 1603 ++ .../Lib/fat_io_lib/release/fat_filelib.h | 146 + .../Lib/fat_io_lib/release/fat_format.c | 532 + .../Lib/fat_io_lib/release/fat_format.h | 15 + .../Lib/fat_io_lib/release/fat_list.h | 161 + .../Lib/fat_io_lib/release/fat_misc.c | 505 + .../Lib/fat_io_lib/release/fat_misc.h | 63 + .../Lib/fat_io_lib/release/fat_opts.h | 90 + .../Lib/fat_io_lib/release/fat_string.c | 514 + .../Lib/fat_io_lib/release/fat_string.h | 20 + .../Lib/fat_io_lib/release/fat_table.c | 478 + .../Lib/fat_io_lib/release/fat_table.h | 20 + .../Lib/fat_io_lib/release/fat_types.h | 69 + .../Lib/fat_io_lib/release/fat_write.c | 373 + .../Lib/fat_io_lib/release/fat_write.h | 14 + .../Lib/fat_io_lib/release/version.txt | 1 + LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh | 46 + .../Lib/libhttp/include/civetweb.c | 13145 ++++++++++++++++ .../Lib/libhttp/include/civetweb.h | 1024 ++ .../Lib/libhttp/include/handle_form.inl | 793 + .../Ventoy2Disk/Lib/libhttp/include/md5.inl | 468 + .../Lib/libhttp/include/mod_duktape.inl | 250 + .../Lib/libhttp/include/mod_lua.inl | 1840 +++ .../Ventoy2Disk/Lib/libhttp/include/timer.inl | 150 + .../Lib/libhttp/libhttp-1.8.tar.gz | Bin 0 -> 6848604 bytes LinuxGUI/Ventoy2Disk/Lib/xz-embedded/COPYING | 10 + LinuxGUI/Ventoy2Disk/Lib/xz-embedded/README | 163 + .../xz-embedded/linux/Documentation/xz.txt | 122 + .../linux/include/linux/decompress/unxz.h | 19 + .../Lib/xz-embedded/linux/include/linux/xz.h | 304 + .../xz-embedded/linux/lib/decompress_unxz.c | 397 + .../Lib/xz-embedded/linux/lib/xz/Kconfig | 57 + .../Lib/xz-embedded/linux/lib/xz/Makefile | 5 + .../Lib/xz-embedded/linux/lib/xz/xz_crc32.c | 59 + .../Lib/xz-embedded/linux/lib/xz/xz_crc64.c | 50 + .../Lib/xz-embedded/linux/lib/xz/xz_dec_bcj.c | 574 + .../xz-embedded/linux/lib/xz/xz_dec_lzma2.c | 1171 ++ .../xz-embedded/linux/lib/xz/xz_dec_stream.c | 847 + .../xz-embedded/linux/lib/xz/xz_dec_syms.c | 26 + .../xz-embedded/linux/lib/xz/xz_dec_test.c | 220 + .../Lib/xz-embedded/linux/lib/xz/xz_lzma2.h | 204 + .../Lib/xz-embedded/linux/lib/xz/xz_private.h | 156 + .../Lib/xz-embedded/linux/lib/xz/xz_stream.h | 62 + .../Lib/xz-embedded/linux/scripts/xz_wrap.sh | 23 + .../Lib/xz-embedded/userspace/boottest.c | 96 + .../Lib/xz-embedded/userspace/buftest.c | 48 + .../Lib/xz-embedded/userspace/bytetest.c | 135 + .../Lib/xz-embedded/userspace/xz_config.h | 124 + .../Lib/xz-embedded/userspace/xzminidec.c | 135 + LinuxGUI/Ventoy2Disk/Web/ventoy_http.c | 1481 ++ LinuxGUI/Ventoy2Disk/Web/ventoy_http.h | 82 + LinuxGUI/Ventoy2Disk/main.c | 81 + LinuxGUI/WebUI/favicon.ico | Bin 0 -> 9662 bytes LinuxGUI/WebUI/index.html | 1062 ++ .../static/AdminLTE/css/AdminLTE.min.css | 8 + .../AdminLTE/css/skins/skin-blue.min.css | 1 + LinuxGUI/WebUI/static/AdminLTE/js/app.min.js | 13 + .../bootstrap/css/bootstrap-theme.min.css | 5 + .../static/bootstrap/css/bootstrap.min.css | 5 + .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../static/bootstrap/js/bootstrap.min.js | 7 + .../WebUI/static/css/font-awesome.min.css | 4 + LinuxGUI/WebUI/static/css/ionicons.min.css | 11 + LinuxGUI/WebUI/static/css/vtoy.css | 357 + .../static/fonts/fontawesome-webfont.ttf | Bin 0 -> 138204 bytes .../static/fonts/fontawesome-webfont.woff | Bin 0 -> 81284 bytes .../static/fonts/fontawesome-webfont.woff2 | Bin 0 -> 64464 bytes .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes LinuxGUI/WebUI/static/fonts/ionicons.eot | Bin 0 -> 120724 bytes LinuxGUI/WebUI/static/fonts/ionicons.ttf | Bin 0 -> 188508 bytes LinuxGUI/WebUI/static/img/dropdown.png | Bin 0 -> 422 bytes LinuxGUI/WebUI/static/img/refresh.ico | Bin 0 -> 4286 bytes LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js | 4 + .../WebUI/static/js/jquery.validate.min.js | 4 + LinuxGUI/WebUI/static/js/jquery.vtoy.alert.js | 223 + LinuxGUI/WebUI/static/js/vtoy.js | 279 + LinuxGUI/build.sh | 61 + LinuxGUI/language.sh | 37 + 158 files changed, 43670 insertions(+) create mode 100644 INSTALL/VentoyWeb.sh create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_crc32.c create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_define.h create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_disk.h create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_json.c create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_json.h create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_log.c create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_md5.c create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_util.c create mode 100644 LinuxGUI/Ventoy2Disk/Core/ventoy_util.h create mode 100644 LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/buidexfat.sh create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/exfat-1.3.0.zip create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/byteorder.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/cluster.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/compiler.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/config.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfat.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/exfatfs.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/io.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/lookup.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/mount.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/node.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/platform.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/repair.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/time.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utf.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/libexfat/utils.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/cbm.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/fat.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/mkexfat_main.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/rootdir.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uct.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/uctc.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/exfat/src/mkfs/vbr.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/buildlib.sh create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_access.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_cache.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_defs.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_filelib.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_format.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_list.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_misc.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_opts.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_string.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_table.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_types.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_write.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_32.a create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_64.a create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_aa64.a create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/API.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/COPYRIGHT.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/Configuration.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/History.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/License.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/Media Access API.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/example.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_access.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_access.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_cache.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_cache.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_defs.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_filelib.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_filelib.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_format.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_format.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_list.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_misc.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_misc.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_opts.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_string.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_string.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_table.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_table.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_types.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_write.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_write.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/version.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/buildlib.sh create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/include/civetweb.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/include/handle_form.inl create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/include/md5.inl create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/include/mod_duktape.inl create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/include/mod_lua.inl create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/include/timer.inl create mode 100644 LinuxGUI/Ventoy2Disk/Lib/libhttp/libhttp-1.8.tar.gz create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/COPYING create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/README create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/Documentation/xz.txt create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/include/linux/decompress/unxz.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/include/linux/xz.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/decompress_unxz.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/Kconfig create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/Makefile create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_crc32.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_crc64.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_bcj.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_stream.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_syms.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_dec_test.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_lzma2.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_private.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/lib/xz/xz_stream.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/linux/scripts/xz_wrap.sh create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/userspace/boottest.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/userspace/buftest.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/userspace/bytetest.c create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/userspace/xz_config.h create mode 100644 LinuxGUI/Ventoy2Disk/Lib/xz-embedded/userspace/xzminidec.c create mode 100644 LinuxGUI/Ventoy2Disk/Web/ventoy_http.c create mode 100644 LinuxGUI/Ventoy2Disk/Web/ventoy_http.h create mode 100644 LinuxGUI/Ventoy2Disk/main.c create mode 100644 LinuxGUI/WebUI/favicon.ico create mode 100644 LinuxGUI/WebUI/index.html create mode 100644 LinuxGUI/WebUI/static/AdminLTE/css/AdminLTE.min.css create mode 100644 LinuxGUI/WebUI/static/AdminLTE/css/skins/skin-blue.min.css create mode 100644 LinuxGUI/WebUI/static/AdminLTE/js/app.min.js create mode 100644 LinuxGUI/WebUI/static/bootstrap/css/bootstrap-theme.min.css create mode 100644 LinuxGUI/WebUI/static/bootstrap/css/bootstrap.min.css create mode 100644 LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.eot create mode 100644 LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.svg create mode 100644 LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.ttf create mode 100644 LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff create mode 100644 LinuxGUI/WebUI/static/bootstrap/fonts/glyphicons-halflings-regular.woff2 create mode 100644 LinuxGUI/WebUI/static/bootstrap/js/bootstrap.min.js create mode 100644 LinuxGUI/WebUI/static/css/font-awesome.min.css create mode 100644 LinuxGUI/WebUI/static/css/ionicons.min.css create mode 100644 LinuxGUI/WebUI/static/css/vtoy.css create mode 100644 LinuxGUI/WebUI/static/fonts/fontawesome-webfont.ttf create mode 100644 LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff create mode 100644 LinuxGUI/WebUI/static/fonts/fontawesome-webfont.woff2 create mode 100644 LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.ttf create mode 100644 LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff create mode 100644 LinuxGUI/WebUI/static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 LinuxGUI/WebUI/static/fonts/ionicons.eot create mode 100644 LinuxGUI/WebUI/static/fonts/ionicons.ttf create mode 100644 LinuxGUI/WebUI/static/img/dropdown.png create mode 100644 LinuxGUI/WebUI/static/img/refresh.ico create mode 100644 LinuxGUI/WebUI/static/js/jQuery-2.1.4.min.js create mode 100644 LinuxGUI/WebUI/static/js/jquery.validate.min.js create mode 100644 LinuxGUI/WebUI/static/js/jquery.vtoy.alert.js create mode 100644 LinuxGUI/WebUI/static/js/vtoy.js create mode 100644 LinuxGUI/build.sh create mode 100644 LinuxGUI/language.sh diff --git a/INSTALL/README b/INSTALL/README index 61f28d56..2535f490 100644 --- a/INSTALL/README +++ b/INSTALL/README @@ -17,6 +17,10 @@ Ventoy2Disk.sh CMD [ OPTION ] /dev/sdX Please refer https://www.ventoy.net/en/doc_start.html for details. +========== VentoyWeb.sh =============== +sudo sh VentoyWeb.sh +Normally, it will popup a web browser window. +If not you can open your browser and visit http://127.0.0.1:24680 diff --git a/INSTALL/VentoyWeb.sh b/INSTALL/VentoyWeb.sh new file mode 100644 index 00000000..3bc9469e --- /dev/null +++ b/INSTALL/VentoyWeb.sh @@ -0,0 +1,182 @@ +#!/bin/sh + +print_usage() { + echo 'Usage: VentoyWeb.sh [ OPTION ]' + echo ' OPTION: (optional)' + echo ' -H x.x.x.x http server IP address (default is 127.0.0.1)' + echo ' -p PORT http server PORT (default is 24680)' + echo " -n don't start web browser" + echo ' -h print this help' + echo '' +} + +print_err() { + echo "" + echo "$*" + echo "" +} + +check_option() { + app="$1" + $app --help 2>&1 | grep -q "$2" +} + +get_user() { + name=$(logname) + if [ -n "$name" -a "$name" != "root" ]; then + echo $name; return + fi + + name=${HOME#/home/} + if [ -n "$name" -a "$name" != "root" ]; then + echo $name; return + fi +} + +chromium_proc() { + app="$1" + + url="http://${HOST}:${PORT}/index.html" + + if check_option "$app" '[-][-]app='; then + su $VUSER -c "$app --app=$url >> $LOGFILE 2>&1" + elif check_option "$app" '[-][-]new[-]window='; then + su $VUSER -c "$app --new-window $url >> $LOGFILE 2>&1" + else + su $VUSER -c "$app $url >> $LOGFILE 2>&1" + fi +} + +uid=$(id -u) +if [ $uid -ne 0 ]; then + print_err "Please use sudo or run the script as root." + exit 1 +fi + +OLDDIR=$(pwd) + +if uname -a | egrep -q 'aarch64|arm64'; then + TOOLDIR=aarch64 +elif uname -a | egrep -q 'x86_64|amd64'; then + TOOLDIR=x86_64 +else + TOOLDIR=i386 +fi + +if [ ! -f ./tool/$TOOLDIR/V2DServer ]; then + if [ -f ${0%VentoyWeb.sh}/tool/$TOOLDIR/V2DServer ]; then + cd ${0%VentoyWeb.sh} + fi +fi + +PATH=./tool/$TOOLDIR:$PATH + +if [ ! -f ./boot/boot.img ]; then + if [ -d ./grub ]; then + echo "Don't run VentoyWeb.sh here, please download the released install package, and run the script in it." + else + echo "Please run under the correct directory!" + fi + exit 1 +fi + +HOST="127.0.0.1" +PORT=24680 + +while [ -n "$1" ]; do + if [ "$1" = "-h" ] || [ "$1" = "--help" ]; then + print_usage + exit 0 + elif [ "$1" = "-n" ]; then + NOWEB=1 + elif [ "$1" = "-H" ]; then + shift + if echo $1 | grep -q '[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*'; then + HOST="$1" + else + print_err "Invalid host $1" + exit 1 + fi + elif [ "$1" = "-p" ]; then + shift + if [ $1 -gt 0 -a $1 -le 65535 ]; then + PORT="$1" + else + print_err "Invalid port $1" + exit 1 + fi + fi + + shift +done + + +if ps -ef | grep "V2DServer.*$HOST.*$PORT" | grep -q -v grep; then + print_err "Another ventoy server is running now, please close it first." + exit 1 +fi + +VUSER=$(get_user) +LOGFILE=log.txt +#delete the log.txt if it's more than 8MB +if [ -f $LOGFILE ]; then + logsize=$(stat -c '%s' $LOGFILE) + if [ $logsize -gt 8388608 ]; then + rm -f $LOGFILE + su $VUSER -c "touch $LOGFILE" + fi +else + su $VUSER -c "touch $LOGFILE" +fi + + + +if [ -f ./tool/$TOOLDIR/V2DServer.xz ]; then + xz -d ./tool/$TOOLDIR/V2DServer.xz + chmod +x ./tool/$TOOLDIR/V2DServer +fi + +V2DServer "$HOST" "$PORT" & + +vtVer=$(cat ventoy/version) +echo "" +echo "==================================================================" +echo " Ventoy Server $vtVer is running at http://${HOST}:${PORT} ..." +echo "==================================================================" +echo "" +echo "################ Press Ctrl + C to exit ######################" +echo "" + +if [ "$NOWEB" = "1" ]; then + echo "Please open your web browser and visit http://${HOST}:${PORT}" +else + if which -a google-chrome-stable >> $LOGFILE 2>&1; then + chromium_proc google-chrome-stable + elif which -a google-chrome >> $LOGFILE 2>&1; then + chromium_proc google-chrome + elif which -a chrome >> $LOGFILE 2>&1; then + chromium_proc chrome + elif which -a browser >> $LOGFILE 2>&1; then + chromium_proc browser + elif which -a firefox >> $LOGFILE 2>&1; then + su $VUSER -c "firefox --no-remote \"http://${HOST}:${PORT}/index.html\"" + else + echo "Please open your web browser and visit http://${HOST}:${PORT}" + fi +fi + +if ps -ef | grep "V2DServer.*$HOST.*$PORT" | grep -q -v grep; then + echo "" +else + print_err "Ventoy Server Error! Please check log.txt." +fi + +wait $! + + +if [ -n "$OLDDIR" ]; then + CURDIR=$(pwd) + if [ "$CURDIR" != "$OLDDIR" ]; then + cd "$OLDDIR" + fi +fi diff --git a/INSTALL/ventoy_pack.sh b/INSTALL/ventoy_pack.sh index e9cfe9e9..8c2655c3 100644 --- a/INSTALL/ventoy_pack.sh +++ b/INSTALL/ventoy_pack.sh @@ -25,6 +25,11 @@ sh mkcpio.sh sh mkloopex.sh cd - +cd ../LinuxGUI +sh language.sh || exit 1 +sh build.sh +cd - + LOOP=$(losetup -f) @@ -88,12 +93,17 @@ xz --check=crc32 $tmpdir/boot/core.img cp $OPT ./tool $tmpdir/ rm -f $tmpdir/ENROLL_THIS_KEY_IN_MOKMANAGER.cer cp $OPT Ventoy2Disk.sh $tmpdir/ +cp $OPT VentoyWeb.sh $tmpdir/ cp $OPT README $tmpdir/ cp $OPT plugin $tmpdir/ cp $OPT CreatePersistentImg.sh $tmpdir/ dos2unix -q $tmpdir/Ventoy2Disk.sh +dos2unix -q $tmpdir/VentoyWeb.sh dos2unix -q $tmpdir/CreatePersistentImg.sh +cp $OPT ../LinuxGUI/WebUI $tmpdir/ +sed 's/.*SCRIPT_DEL_THIS \(.*\)/\1/g' -i $tmpdir/WebUI/index.html + #32MB disk img dd status=none if=$LOOP of=$tmpdir/ventoy/ventoy.disk.img bs=512 count=$VENTOY_SECTOR_NUM skip=$part2_start_sector xz --check=crc32 $tmpdir/ventoy/ventoy.disk.img @@ -119,6 +129,7 @@ done find $tmpdir/ -type d -exec chmod 755 "{}" + find $tmpdir/ -type f -exec chmod 644 "{}" + chmod +x $tmpdir/Ventoy2Disk.sh +chmod +x $tmpdir/VentoyWeb.sh chmod +x $tmpdir/CreatePersistentImg.sh tar -czvf ventoy-${curver}-linux.tar.gz $tmpdir @@ -130,6 +141,7 @@ cp $OPT Ventoy2Disk*.exe $tmpdir/ cp $OPT $LANG_DIR/languages.ini $tmpdir/ventoy/ rm -rf $tmpdir/tool rm -f $tmpdir/*.sh +rm -rf $tmpdir/WebUI rm -f $tmpdir/README 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..4d0871b8 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_disk.c @@ -0,0 +1,735 @@ +/****************************************************************************** + * 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/loopX */ + if (name[0] == 'l' && name[1] == 'o' && name[2] == 'o' && name[3] == 'p') + { + return 0; + } + + /* /dev/dm-X */ + if (name[0] == 'd' && name[1] == 'm' && name[2] == '-' && isdigit(name[3])) + { + return 0; + } + + /* /dev/srX */ + if (name[0] == 's' && name[1] == 'r' && isdigit(name[2])) + { + return 0; + } + + return 1; +} + +uint64_t ventoy_get_disk_size_in_byte(const char *disk) +{ + int fd; + int rc; + unsigned long long size = 0; + char diskpath[256] = {0}; + char sizebuf[64] = {0}; + + // Try 1: get size from sysfs + snprintf(diskpath, sizeof(diskpath) - 1, "/sys/block/%s/size", disk); + if (access(diskpath, F_OK) >= 0) + { + vdebug("get disk size from sysfs for %s\n", disk); + + fd = open(diskpath, O_RDONLY | O_BINARY); + if (fd >= 0) + { + read(fd, sizebuf, sizeof(sizebuf)); + size = strtoull(sizebuf, NULL, 10); + close(fd); + return (uint64_t)(size * 512); + } + } + else + { + vdebug("%s not exist \n", diskpath); + } + + // Try 2: get size from ioctl + snprintf(diskpath, sizeof(diskpath) - 1, "/dev/%s", disk); + fd = open(diskpath, O_RDONLY); + if (fd >= 0) + { + vdebug("get disk size from ioctl for %s\n", disk); + rc = ioctl(fd, BLKGETSIZE64, &size); + if (rc == -1) + { + size = 0; + vdebug("failed to ioctl %d\n", rc); + } + close(fd); + } + else + { + vdebug("failed to open %s %d\n", diskpath, errno); + } + + vdebug("disk %s size %llu bytes\n", disk, size); + return size; +} + +int ventoy_get_disk_vendor(const char *name, char *vendorbuf, int bufsize) +{ + return ventoy_get_sys_file_line(vendorbuf, bufsize, "/sys/block/%s/device/vendor", name); +} + +int ventoy_get_disk_model(const char *name, char *modelbuf, int bufsize) +{ + return ventoy_get_sys_file_line(modelbuf, bufsize, "/sys/block/%s/device/model", name); +} + +static int fatlib_media_sector_read(uint32 sector, uint8 *buffer, uint32 sector_count) +{ + lseek(g_fatlib_media_fd, (sector + g_fatlib_media_offset) * 512ULL, SEEK_SET); + read(g_fatlib_media_fd, buffer, sector_count * 512); + + return 1; +} + +static int fatlib_is_secure_boot_enable(void) +{ + void *flfile = NULL; + + flfile = fl_fopen("/EFI/BOOT/grubx64_real.efi", "rb"); + if (flfile) + { + fl_fclose(flfile); + return 1; + } + else + { + vlog("/EFI/BOOT/grubx64_real.efi not exist\n"); + } + + return 0; +} + +static int fatlib_get_ventoy_version(char *verbuf, int bufsize) +{ + int rc = 1; + int size = 0; + char *buf = NULL; + char *pos = NULL; + char *end = NULL; + void *flfile = NULL; + + flfile = fl_fopen("/grub/grub.cfg", "rb"); + if (flfile) + { + fl_fseek(flfile, 0, SEEK_END); + size = (int)fl_ftell(flfile); + + fl_fseek(flfile, 0, SEEK_SET); + + buf = malloc(size + 1); + if (buf) + { + fl_fread(buf, 1, size, flfile); + buf[size] = 0; + + pos = strstr(buf, "VENTOY_VERSION="); + if (pos) + { + pos += strlen("VENTOY_VERSION="); + if (*pos == '"') + { + pos++; + } + + end = pos; + while (*end != 0 && *end != '"' && *end != '\r' && *end != '\n') + { + end++; + } + + *end = 0; + + snprintf(verbuf, bufsize - 1, "%s", pos); + rc = 0; + } + free(buf); + } + + fl_fclose(flfile); + } + else + { + vdebug("No grub.cfg found\n"); + } + + return rc; +} + +int ventoy_get_vtoy_data(ventoy_disk *info, int *ppartstyle) +{ + int i; + int fd; + int len; + int rc = 1; + int ret = 1; + int part_style; + uint64_t part1_start_sector; + uint64_t part1_sector_count; + uint64_t part2_start_sector; + uint64_t part2_sector_count; + uint64_t preserved_space; + char name[64] = {0}; + disk_ventoy_data *vtoy = NULL; + VTOY_GPT_INFO *gpt = NULL; + + vtoy = &(info->vtoydata); + gpt = &(vtoy->gptinfo); + memset(vtoy, 0, sizeof(disk_ventoy_data)); + + vdebug("ventoy_get_vtoy_data %s\n", info->disk_path); + + if (info->size_in_byte < (2 * VTOYEFI_PART_BYTES)) + { + vdebug("disk %s is too small %llu\n", info->disk_path, (_ull)info->size_in_byte); + return 1; + } + + fd = open(info->disk_path, O_RDONLY | O_BINARY); + if (fd < 0) + { + vdebug("failed to open %s %d\n", info->disk_path, errno); + return 1; + } + + len = (int)read(fd, &(vtoy->gptinfo), sizeof(VTOY_GPT_INFO)); + if (len != sizeof(VTOY_GPT_INFO)) + { + vdebug("failed to read %s %d\n", info->disk_path, errno); + goto end; + } + + if (gpt->MBR.Byte55 != 0x55 || gpt->MBR.ByteAA != 0xAA) + { + vdebug("Invalid mbr magic 0x%x 0x%x\n", gpt->MBR.Byte55, gpt->MBR.ByteAA); + goto end; + } + + if (gpt->MBR.PartTbl[0].FsFlag == 0xEE && strncmp(gpt->Head.Signature, "EFI PART", 8) == 0) + { + part_style = GPT_PART_STYLE; + if (ppartstyle) + { + *ppartstyle = part_style; + } + + if (gpt->PartTbl[0].StartLBA == 0 || gpt->PartTbl[1].StartLBA == 0) + { + vdebug("NO ventoy efi part layout <%llu %llu>\n", + (_ull)gpt->PartTbl[0].StartLBA, + (_ull)gpt->PartTbl[1].StartLBA); + goto end; + } + + for (i = 0; i < 36; i++) + { + name[i] = (char)(gpt->PartTbl[1].Name[i]); + } + if (strcmp(name, "VTOYEFI")) + { + vdebug("Invalid efi part2 name <%s>\n", name); + goto end; + } + + part1_start_sector = gpt->PartTbl[0].StartLBA; + part1_sector_count = gpt->PartTbl[0].LastLBA - part1_start_sector + 1; + part2_start_sector = gpt->PartTbl[1].StartLBA; + part2_sector_count = gpt->PartTbl[1].LastLBA - part2_start_sector + 1; + + preserved_space = info->size_in_byte - (part2_start_sector + part2_sector_count + 33) * 512; + } + else + { + part_style = MBR_PART_STYLE; + if (ppartstyle) + { + *ppartstyle = part_style; + } + + part1_start_sector = gpt->MBR.PartTbl[0].StartSectorId; + part1_sector_count = gpt->MBR.PartTbl[0].SectorCount; + part2_start_sector = gpt->MBR.PartTbl[1].StartSectorId; + part2_sector_count = gpt->MBR.PartTbl[1].SectorCount; + + preserved_space = info->size_in_byte - (part2_start_sector + part2_sector_count) * 512; + } + + if (part1_start_sector != VTOYIMG_PART_START_SECTOR || + part2_sector_count != VTOYEFI_PART_SECTORS || + (part1_start_sector + part1_sector_count) != part2_start_sector) + { + vdebug("Not valid ventoy partition layout [%llu %llu] [%llu %llu]\n", + part1_start_sector, part1_sector_count, part2_start_sector, part2_sector_count); + goto end; + } + + vdebug("now check secure boot ...\n"); + + g_fatlib_media_fd = fd; + g_fatlib_media_offset = part2_start_sector; + fl_init(); + + if (0 == fl_attach_media(fatlib_media_sector_read, NULL)) + { + ret = fatlib_get_ventoy_version(vtoy->ventoy_ver, sizeof(vtoy->ventoy_ver)); + if (ret == 0 && vtoy->ventoy_ver[0]) + { + vtoy->secure_boot_flag = fatlib_is_secure_boot_enable(); + vtoy->ventoy_valid = 1; + } + else + { + vdebug("fatlib_get_ventoy_version failed %d\n", ret); + } + } + else + { + vdebug("fl_attach_media failed\n"); + } + + fl_shutdown(); + g_fatlib_media_fd = -1; + g_fatlib_media_offset = 0; + + if (0 == vtoy->ventoy_valid) + { + goto end; + } + + lseek(fd, 2040 * 512, SEEK_SET); + read(fd, vtoy->rsvdata, sizeof(vtoy->rsvdata)); + + vtoy->preserved_space = preserved_space; + vtoy->partition_style = part_style; + vtoy->part2_start_sector = part2_start_sector; + + rc = 0; +end: + close(fd); + return rc; +} + +int ventoy_get_disk_info(const char *name, ventoy_disk *info) +{ + char vendor[64] = {0}; + char model[128] = {0}; + + vdebug("get disk info %s\n", name); + + strlcpy(info->disk_name, name); + scnprintf(info->disk_path, "/dev/%s", name); + + if (strstr(name, "nvme") || strstr(name, "mmc") || strstr(name, "nbd")) + { + scnprintf(info->part1_name, "%sp1", name); + scnprintf(info->part1_path, "/dev/%sp1", name); + scnprintf(info->part2_name, "%sp2", name); + scnprintf(info->part2_path, "/dev/%sp2", name); + } + else + { + scnprintf(info->part1_name, "%s1", name); + scnprintf(info->part1_path, "/dev/%s1", name); + scnprintf(info->part2_name, "%s2", name); + scnprintf(info->part2_path, "/dev/%s2", name); + } + + info->size_in_byte = ventoy_get_disk_size_in_byte(name); + + ventoy_get_disk_devnum(name, &info->major, &info->minor); + info->type = ventoy_get_dev_type(name, info->major, info->minor); + ventoy_get_disk_vendor(name, vendor, sizeof(vendor)); + ventoy_get_disk_model(name, model, sizeof(model)); + + scnprintf(info->human_readable_size, "%llu GB", (_ull)ventoy_get_human_readable_gb(info->size_in_byte)); + scnprintf(info->disk_model, "%s %s (%s)", vendor, model, ventoy_get_dev_type_name(info->type)); + + ventoy_get_vtoy_data(info, &(info->partstyle)); + + vdebug("disk:<%s %d:%d> model:<%s> size:%llu (%s)\n", + info->disk_path, info->major, info->minor, info->disk_model, info->size_in_byte, info->human_readable_size); + + if (info->vtoydata.ventoy_valid) + { + vdebug("%s Ventoy:<%s> %s secureboot:%d preserve:%llu\n", info->disk_path, info->vtoydata.ventoy_ver, + info->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT", + info->vtoydata.secure_boot_flag, (_ull)(info->vtoydata.preserved_space)); + } + else + { + vdebug("%s NO Ventoy detected\n", info->disk_path); + } + + return 0; +} + +static int ventoy_disk_compare(const ventoy_disk *disk1, const ventoy_disk *disk2) +{ + if (disk1->type == VTOY_DEVICE_USB && disk2->type == VTOY_DEVICE_USB) + { + return strcmp(disk1->disk_name, disk2->disk_name); + } + else if (disk1->type == VTOY_DEVICE_USB) + { + return -1; + } + else if (disk2->type == VTOY_DEVICE_USB) + { + return 1; + } + else + { + return strcmp(disk1->disk_name, disk2->disk_name); + } +} + +static int ventoy_disk_sort(void) +{ + int i, j; + ventoy_disk *tmp; + + tmp = malloc(sizeof(ventoy_disk)); + if (!tmp) + { + return 1; + } + + for (i = 0; i < g_disk_num; i++) + for (j = i + 1; j < g_disk_num; j++) + { + if (ventoy_disk_compare(g_disk_list + i, g_disk_list + j) > 0) + { + memcpy(tmp, g_disk_list + i, sizeof(ventoy_disk)); + memcpy(g_disk_list + i, g_disk_list + j, sizeof(ventoy_disk)); + memcpy(g_disk_list + j, tmp, sizeof(ventoy_disk)); + } + } + + free(tmp); + return 0; +} + +int ventoy_disk_enumerate_all(void) +{ + int rc = 0; + DIR* dir = NULL; + struct dirent* p = NULL; + + vdebug("ventoy_disk_enumerate_all\n"); + + dir = opendir("/sys/block"); + if (!dir) + { + vlog("Failed to open /sys/block %d\n", errno); + return 1; + } + + while (((p = readdir(dir)) != NULL) && (g_disk_num < MAX_DISK_NUM)) + { + if (ventoy_is_possible_blkdev(p->d_name)) + { + memset(g_disk_list + g_disk_num, 0, sizeof(ventoy_disk)); + if (0 == ventoy_get_disk_info(p->d_name, g_disk_list + g_disk_num)) + { + g_disk_num++; + } + } + } + closedir(dir); + + ventoy_disk_sort(); + + return rc; +} + +void ventoy_disk_dump(ventoy_disk *cur) +{ + if (cur->vtoydata.ventoy_valid) + { + vdebug("%s [%s] %s\tVentoy: %s %s secureboot:%d preserve:%llu\n", + cur->disk_path, cur->human_readable_size, cur->disk_model, + cur->vtoydata.ventoy_ver, cur->vtoydata.partition_style == MBR_PART_STYLE ? "MBR" : "GPT", + cur->vtoydata.secure_boot_flag, (_ull)(cur->vtoydata.preserved_space)); + } + else + { + vdebug("%s [%s] %s\tVentoy: NA\n", cur->disk_path, cur->human_readable_size, cur->disk_model); + } +} + +void ventoy_disk_dump_all(void) +{ + int i; + + vdebug("============= DISK DUMP ============\n"); + for (i = 0; i < g_disk_num; i++) + { + ventoy_disk_dump(g_disk_list + i); + } +} + +int ventoy_disk_install(ventoy_disk *disk, void *efipartimg) +{ + return 0; +} + + +int ventoy_disk_init(void) +{ + g_disk_list = malloc(sizeof(ventoy_disk) * MAX_DISK_NUM); + + ventoy_disk_enumerate_all(); + ventoy_disk_dump_all(); + + return 0; +} + +void ventoy_disk_exit(void) +{ + check_free(g_disk_list); + g_disk_list = NULL; + g_disk_num = 0; +} + + 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..469f843e --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_log.c @@ -0,0 +1,115 @@ +/****************************************************************************** + * 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(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..562c3a09 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.c @@ -0,0 +1,541 @@ +/****************************************************************************** + * 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 Part1SectorCount = 0; + uint64_t DiskSectorCount = size / 512; + VTOY_GPT_HDR *Head = &gpt->Head; + VTOY_GPT_PART_TBL *Table = gpt->PartTbl; + ventoy_guid WindowsDataPartType = { 0xebd0a0a2, 0xb9e5, 0x4433, { 0x87, 0xc0, 0x68, 0xb6, 0xb7, 0x26, 0x99, 0xc7 } }; + //ventoy_guid EspPartType = { 0xc12a7328, 0xf81f, 0x11d2, { 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b } }; + //ventoy_guid BiosGrubPartType = { 0x21686148, 0x6449, 0x6e6f, { 0x74, 0x4e, 0x65, 0x65, 0x64, 0x45, 0x46, 0x49 } }; + + VentoyFillProtectMBR(size, &gpt->MBR); + + if (reserve > 0) + { + ReservedSector += reserve / 512; + } + + // check aligned with 4KB + if (align4k) + { + if (DiskSectorCount % 8) + { + vdebug("Disk need to align with 4KB %u\n", (uint32_t)(DiskSectorCount % 8)); + ReservedSector += (DiskSectorCount % 8); + } + } + + Part1SectorCount = DiskSectorCount - ReservedSector - (VTOYEFI_PART_BYTES / 512) - 2048; + + memcpy(Head->Signature, "EFI PART", 8); + Head->Version[2] = 0x01; + Head->Length = 92; + Head->Crc = 0; + Head->EfiStartLBA = 1; + Head->EfiBackupLBA = DiskSectorCount - 1; + Head->PartAreaStartLBA = 34; + Head->PartAreaEndLBA = DiskSectorCount - 34; + ventoy_gen_preudo_uuid(&Head->DiskGuid); + Head->PartTblStartLBA = 2; + Head->PartTblTotNum = 128; + Head->PartTblEntryLen = 128; + + + memcpy(&(Table[0].PartType), &WindowsDataPartType, sizeof(ventoy_guid)); + ventoy_gen_preudo_uuid(&(Table[0].PartGuid)); + Table[0].StartLBA = 2048; + Table[0].LastLBA = 2048 + Part1SectorCount - 1; + Table[0].Attr = 0; + ventoy_fill_gpt_partname(Table[0].Name, "Ventoy"); + + // to fix windows issue + //memcpy(&(Table[1].PartType), &EspPartType, sizeof(GUID)); + memcpy(&(Table[1].PartType), &WindowsDataPartType, sizeof(ventoy_guid)); + ventoy_gen_preudo_uuid(&(Table[1].PartGuid)); + Table[1].StartLBA = Table[0].LastLBA + 1; + Table[1].LastLBA = Table[1].StartLBA + VTOYEFI_PART_BYTES / 512 - 1; + Table[1].Attr = 0x8000000000000001ULL; + ventoy_fill_gpt_partname(Table[1].Name, "VTOYEFI"); + +#if 0 + memcpy(&(Table[2].PartType), &BiosGrubPartType, sizeof(ventoy_guid)); + ventoy_gen_preudo_uuid(&(Table[2].PartGuid)); + Table[2].StartLBA = 34; + Table[2].LastLBA = 2047; + Table[2].Attr = 0; +#endif + + //Update CRC + Head->PartTblCrc = ventoy_crc32(Table, sizeof(gpt->PartTbl)); + Head->Crc = ventoy_crc32(Head, Head->Length); + + return 0; +} + +int VentoyFillMBRLocation(uint64_t DiskSizeInBytes, uint32_t StartSectorId, uint32_t SectorCount, PART_TABLE *Table) +{ + uint8_t Head; + uint8_t Sector; + uint8_t nSector = 63; + uint8_t nHead = 8; + uint32_t Cylinder; + uint32_t EndSectorId; + + while (nHead != 0 && (DiskSizeInBytes / 512 / nSector / nHead) > 1024) + { + nHead = (uint8_t)nHead * 2; + } + + if (nHead == 0) + { + nHead = 255; + } + + Cylinder = StartSectorId / nSector / nHead; + Head = StartSectorId / nSector % nHead; + Sector = StartSectorId % nSector + 1; + + Table->StartHead = Head; + Table->StartSector = Sector; + Table->StartCylinder = Cylinder; + + EndSectorId = StartSectorId + SectorCount - 1; + Cylinder = EndSectorId / nSector / nHead; + Head = EndSectorId / nSector % nHead; + Sector = EndSectorId % nSector + 1; + + Table->EndHead = Head; + Table->EndSector = Sector; + Table->EndCylinder = Cylinder; + + Table->StartSectorId = StartSectorId; + Table->SectorCount = SectorCount; + + return 0; +} + +int ventoy_fill_mbr(uint64_t size, uint64_t reserve, int align4k, int PartStyle, MBR_HEAD *pMBR) +{ + ventoy_guid Guid; + uint32_t DiskSignature; + uint32_t DiskSectorCount; + uint32_t PartSectorCount; + uint32_t PartStartSector; + uint32_t ReservedSector; + + VentoyGetLocalBootImg(pMBR); + + ventoy_gen_preudo_uuid(&Guid); + + memcpy(&DiskSignature, &Guid, sizeof(uint32_t)); + + vdebug("Disk signature: 0x%08x\n", DiskSignature); + + memcpy(pMBR->BootCode + 0x1B8, &DiskSignature, 4); + + if (size / 512 > 0xFFFFFFFF) + { + DiskSectorCount = 0xFFFFFFFF; + } + else + { + DiskSectorCount = (uint32_t)(size / 512); + } + + if (reserve <= 0) + { + ReservedSector = 0; + } + else + { + ReservedSector = (uint32_t)(reserve / 512); + } + + if (PartStyle) + { + ReservedSector += 33; // backup GPT part table + } + + // check aligned with 4KB + if (align4k) + { + uint64_t sectors = size / 512; + if (sectors % 8) + { + vlog("Disk need to align with 4KB %u\n", (uint32_t)(sectors % 8)); + ReservedSector += (uint32_t)(sectors % 8); + } + } + + vlog("ReservedSector: %u\n", ReservedSector); + + + //Part1 + PartStartSector = VTOYIMG_PART_START_SECTOR; + PartSectorCount = DiskSectorCount - ReservedSector - VTOYEFI_PART_BYTES / 512 - PartStartSector; + VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl); + + pMBR->PartTbl[0].Active = 0x80; // bootable + pMBR->PartTbl[0].FsFlag = 0x07; // exFAT/NTFS/HPFS + + //Part2 + PartStartSector += PartSectorCount; + PartSectorCount = VTOYEFI_PART_BYTES / 512; + VentoyFillMBRLocation(size, PartStartSector, PartSectorCount, pMBR->PartTbl + 1); + + pMBR->PartTbl[1].Active = 0x00; + pMBR->PartTbl[1].FsFlag = 0xEF; // EFI System Partition + + pMBR->Byte55 = 0x55; + pMBR->ByteAA = 0xAA; + + return 0; +} + diff --git a/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h b/LinuxGUI/Ventoy2Disk/Core/ventoy_util.h new file mode 100644 index 00000000..eb093106 --- /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, int PartStyle, MBR_HEAD *pMBR); + +#endif /* __VENTOY_UTIL_H__ */ + diff --git a/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h b/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h new file mode 100644 index 00000000..32f452cb --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Include/Ventoy2Disk.h @@ -0,0 +1,26 @@ +/****************************************************************************** + * Ventoy2Disk.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 __VENTOY2DISK_H__ +#define __VENTOY2DISK_H__ + + + +#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 0000000000000000000000000000000000000000..aa1d5f39014fe13e7803605fad0cdf42088dd022 GIT binary patch literal 90929 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%0A|YcOifthU*)sS787@G7(_K2M)3 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 literal 0 HcmV?d00001 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/buildlib.sh b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/buildlib.sh new file mode 100644 index 00000000..dec432f7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/buildlib.sh @@ -0,0 +1,30 @@ +#!/bin/sh + +rm -rf include +rm -rf lib + +cd release +gcc -O2 -D_FILE_OFFSET_BITS=64 fat*.c -c +ar -rc libfat_io_64.a *.o +rm -f *.o + + +gcc -m32 -O2 -D_FILE_OFFSET_BITS=64 fat*.c -c +ar -rc libfat_io_32.a *.o +rm -f *.o + + +aarch64-linux-gnu-gcc -O2 -D_FILE_OFFSET_BITS=64 fat*.c -c +ar -rc libfat_io_aa64.a *.o +rm -f *.o + + +cd - + + +mkdir lib +mkdir include + +mv release/*.a lib/ +cp -a release/*.h include/ + diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_access.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_access.h new file mode 100644 index 00000000..17523878 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_cache.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_cache.h new file mode 100644 index 00000000..348d5d38 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_defs.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_defs.h new file mode 100644 index 00000000..5fe8d6a4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_filelib.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_filelib.h new file mode 100644 index 00000000..a40a28ff --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_format.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_format.h new file mode 100644 index 00000000..a8a6bbaf --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_list.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_list.h new file mode 100644 index 00000000..bd386ef6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_misc.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_misc.h new file mode 100644 index 00000000..0c026343 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_opts.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_opts.h new file mode 100644 index 00000000..ac4dc860 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_opts.h @@ -0,0 +1,90 @@ +#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 1 +#endif + +// Sector size used +#define FAT_SECTOR_SIZE 512 + +// Printf output (directory listing / debug) +#ifndef FAT_PRINTF + // Don't include stdio, but there is a printf function available + #ifdef FAT_PRINTF_NOINC_STDIO + extern int printf(const char* ctrl1, ... ); + #define FAT_PRINTF(a) printf a + // Include stdio to use printf + #else + #include + #define FAT_PRINTF(a) printf a + #endif +#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/include/fat_string.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_string.h new file mode 100644 index 00000000..90ca8e05 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_table.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_table.h new file mode 100644 index 00000000..ead75f32 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_types.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_types.h new file mode 100644 index 00000000..5e2cca8a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/include/fat_write.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/fat_write.h new file mode 100644 index 00000000..5558a86e --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/include/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/lib/libfat_io_32.a b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_32.a new file mode 100644 index 0000000000000000000000000000000000000000..e68fa3865044193a9c77cdde9634650b9a512eba GIT binary patch literal 45670 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 literal 0 HcmV?d00001 diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_64.a b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_64.a new file mode 100644 index 0000000000000000000000000000000000000000..8598a87c74e5b726f4b3a04750741feee31c6799 GIT binary patch literal 58226 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 literal 0 HcmV?d00001 diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_aa64.a b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/lib/libfat_io_aa64.a new file mode 100644 index 0000000000000000000000000000000000000000..7b9b66c608a86043260797b4376ecd67a37f10f0 GIT binary patch literal 47506 zcmd^o4R}@6neN*A96}(dAqfxyH79^pqNM>6$g#HB38*NxgCXs8T4!=jPJ#&uKgkIS z!k804hmm$Jk&HiWXE*_DNv5}#E1~67rvznMXU3VUXst7k_Zq-fr#c-4RH9(+`>ws# z$;##&MeoylJNNE9CwuRAul22Oed}A_Uf=rLMc0MfB8^`f|M|e^WA1{v^B2sUS2lNH zAW$M7ng0WUx#bJyxiLcHg%H(3jJ^NU|E~O@5c+rZZXtfxztxut;r;!|V?unI-?#1* z;-h}weL#qh`~CG-gm8Z=!tE=fwN0y=+J$@BQWvgWv!XWAvM$=*(5Ap>L!^C8TWwoI zxPCNpS6fqi!)S&8~0WQ@^Jv~kT{we=0{;ii_T3Uxj-QKoAr@LZxZNvJeXuFQQZf$+Iy}=FG(y;oD_C^(QRk*F$h3gwy8rmClW?B%r zw!W!N=5j-Av_0IG6vyaCs~gtqCy{WZvB8v_3y?*I@^J1xj9&1tMNw#}4Y#+0Vr|Qs zNHa2$ykFH&-xTJ3v~gW~{hGU0^LoXawGHmY3X~JF2Po3ACW@lKm0L`>051`V;6l<| z5p8H_*2vm5F4o@A(ju{jH7n#<6)FgXFv+NT*c7GQWvXl1R)w`}SIC=MXyn`ls_aIf`SV6WLQA?f+H`kAZF{(`r2#=w zph;RS(3lH~Zv-@zYXpT1Rl4$dEuXZHsKW@@wEE6)OOw{E5qy-6x^NUU)~s&Pn(TsF zCbDKGA*#JfpD7b>YKTJ6t?N(*IyHt`9bN@7tRaIc0+VseYgEONd6UIhix39!I~rCu zw6O}YN-Dg4O?$Ydc5S#FD%x;o!>F1XT~`+cJFD-|>8)*PYL{UZ5LvToZMdzWmaIXK zWX{|eV5mM?dsh?4Mq9#EW%-b`h+Nk_96dy8fT}ya%v-bfKA%W2*)TB@wX$&`M z-pLaxiw@3`GapCRtXmCcjP$ht8A;;Nwc&`)QMd&LL|Q+_81;m~M{Fl^Q5%j#8lurT zYxp)!zJV8vegn@fDOpfj8VD>5&P~37JFdUw2HUdmB6bf;{8)_KX;g@-rjJ}Z^3oAm zV!ZGPCs>pzZngbRLM(GO6lMCR1+ty20blKlg#q6$&Tsr_@9_@jvGYFBbvjE7o%V^o z!dW6=U1JS_On2mRXUI26^!HyThT7|_t{EbR7D24~xG%3SBr0AMd7?D@!^IooH~&R- zg%Hg}xuPcY$2SG*zJ62C35cvhVKrA0Te&1ySRz^*CyJWFYeeglmxvm1i6|qjj>|=Y z>5#Uj>r51-p$961;Xkho1|*%#)-d9R`znL0zE>G+_^Zm`9pA1Du6VFA7%#H2B0sGR zit9v9-A^imuLs6tt*}Kf^NS)UR4q2t@2(711$#AdxZKtmRl%>!xHPK;dCRi0 zveqJhvp;4=aOp?^XsIPgMpZ*JUpcg+!KJWM|pJ&I&yS?1u;w z5LXvjqNedTxc)7$Usnd3PE;bF*~>*(WX&w{WeMTS+8nc|{R%SZ5mr{Eu$E?IiqfLY zpA}R*ThZD(R@B5k+$GCuwqMi~LFWCJIVkH`b$FggoX&EF&To8jAN9k^6Sr3QMQf8l zndOVteW!+N>NYP4hVEMu4BxXP7`b~%unN37;58hukhYZ-LRo%mczDW6aZ%Wp)l@VNvceB#unXaI+8yIXqQjehxk~@su$%sGhie8A#}Tm{#{0!c{G4OB z4k`S<<2sP6>Amao^#z0|9`uXSgSlep zP@x!l*miSpx)&|{!Die^(vYnCbI4w_le@ec5ZWcc(~>O$^~UHcfg18 zo983~wkX{U8m!x~4BQKQ+QI*sKkZPVGZeQ)*1=q7=xaXFf7~~@Zwu)ltX zde3h>x-W$MFs-v64nK5?GRkqFr*`u==vU{ZP9jFVM|le9-*54p^hjHP25D(Jlv(H3 zs}ijH0mLO9`?{Uzgsm{s)oBJ0|1Hq_HDqH$Hm^cfzk-~fL_Ii;JkcIej(Z@-=fK+@ zq_xK{`nRGysF$vd@bwJ{k;O7$89u7YFpe@@WV>O#;Y2p`m(e`VM*b!sf76}By`bsl zF(WI2csfoTbhqG{Oyf2?LA*0$bx~%_Kl7}gF&v+hHytKs#33z~YbNw&8_L6*@7JIk zyWPB(X&!Gfc+~vOL|o0EurAEE&)}cDF^uN*{Kmslrhfu?-eHOU^Ba#SIgXWbWLTXa zo!3+t;}K_mbUEpFh7e*0eqH!=N1&fJ?yGQ*ch!y#*pMPz7m3Z^Hp7L-Q^!W)g(rLN zq1U6HL*IE%8-;ThWsY+m`4O2;V!&7X;`xpHWL{4%w|etJqzUg5I5j{AmN@CoReQ!97;jG=HqxCt}A=_$H(NPc0twP3c2A-2@M<@V`#(aoZ3m!12@0LpF^whQ^CE0QDxP8=440i=UfIjCe&-uiz3)X9^$s;J?)@NoJ?i;O(vE8$ z2HzhpJv>i9hOuLZZ83BhHaEO7RNk{PP%iwUt1uwm?u4xgUFihtW;nrcu@fweiPqge zw}SD1u!24R9cSb(zNa!+cu2G|uRnRp3X=ap-y}EBNTcpjr+4#ZqBj7Z>MpIswbe@= z)A3hYvFk^Ff}eht$s@yju!jThirW5IRTwKJ6>$)A^uIICu|y+I&z)j)UF+>^AHB zQ!|_)mdysdyO}@g&-smiE8h{!TPoR7?}SGlIv!=hXFU5L51*0;>Cm>PmB~yoM43<) zQz4TRzR~4LS)BGw9VG|Uqfadd#}~^9p`D02-bXnw@01PYqGd8Plkc66mPJU(f?-GN z$KOi*(6V4TR%D9V6#)^XY+O6qm(-JYd{!Uz<6YwyY zjiy~Xfco0;CDFPB@@T(&s^&on=$mysOt%G=9vkf3^8}wUW z52D^Mth7Z)o8cLTaTzcC;c$(Yk1D^IxZ4(q!!u}KM7Op}y3U{9_@a~r+xI#@p|K*F zX5fQiw8vnFRbCH&Rt)vbw7L#22hHV{v{{tbX4tD4jic>V4EAaZ^1oTxt35ZuPA#>9 zyZ^un4x;TEpXu5wI8HSKu-)-RR*?2v+8fxr4%nUJ$diEG=QC|Tv^)xhXr(*`$L=Z^ z$nggQ;Ip&X*|2$mvjJ_K#8a1AiAu*RJ~G})96wueYov*q8ZHj=sbZyjYup5w< zxS_HJT`BU6&J%eKsE)d8FTs7FX2aTsz!$HG;+jXG8hv(w#Z7I28=Bgp?SVyZFJj<} zfh*QuG9J%CFi_QSN7L%SEmf6(OV-N=$$%-INxI8r*IYEPtf4I#7DVew^u|Stt_@su zOVjFb+nNAw0t@Gqer{gL+~Ay&d9!&lXKnzu<#XrFoger{iwyTUBTS&J;m#&@CIreB zG(;AxSWp)XMj~?;EL^doBrj0?~b zAUQ}kpq{*CyBA-;DO+LY>1Nz8e74H+EcLKf;pGa?Q+TVwmwE853U5?+i4w`fz*D8W zUxj~IiS$j}^LP?J^0Q5e;u(nw@e76Drn3A^g};t-D*FGH20x?dysqeEDmq!Af* z3LHIVG6!9q?Q=@REZr$d30KinISS zgGe9I&+W3S1_LB-Yd0u0N0*{|OhbK`ph27uDLY7wa2h@XZPk4<#tZ?!5+-!q%8~A68@Nomb+`#u4INH0(;|T*d`G48K zP5v`8-KflOAW21t76UiwpEYokPQH3Sk&c<)Sq5(Ax5U8BbQc@=41=F14BSk2(7?@f z-!yPD-LnR6raM8sN6EjLZjFJP={}tXf8D@Me$E)U$q#z|(O@&e6|r@%!zJTg%NX{+uPi8qrPfuXbI1eZ{<0dP7xM!>Y`CG zr)>>y7<}%Waxn+**;RN^i8-s+v^UJT@he~b941dhn$0Bscdi47jI0Y~#*(BQb+uRJ zOFvN6R^Q4x%BH@PMBIy*dZ{f@gc*3Z z#2q64*fH|C^GeDwl#U}b{$j_-*Bg0oBrA>>2T8C$$LzCA-v6HUcTi@ZysyK^^oaOT zRu`6*tLom8aU-Sb)8La-eI~Te^cnS`b*)I@`d**Eq;PH5HBSFPDTUzzUND`=1=zm7 z_}O3|WsWbf#J?-k%c?;srL(!ZZX$?0l5$b^lqchROY%1L+SxEb-j+L&ffS`Z_X2HX{wV}@8jkL&0P@W^q@~<^VU|3FyY8c2ljuw;J6z2*`eqC z%oonkPK+`4|I+Gx2mRAO!u*BF%S6|dkiQH1kr&NyhL&TDx!s=l9Oo45vM0TP@v|Dt z2I>M?j&+t|?5!_W=a=^}jG@tva;&!hmzBLgQu7XIXZ5{M&-FN(J08+2$3xD5k4fO~ zpe?%Iog#(~R*9~&m^Z<(w6ho|(c_JnYmpr98}Of9sOM7rc$yf(*hw*7e;B9DE8c^# zgx!0rE*&p`F^)Je@;-n$82yhs8-_90BK~t{L!OhDbv4EbF*fjquD#Thz_ITGhL{!)&0@HwC5`9y-UNEPP%#)Ql-=Zna^z2@tM ze(vydJ{HD;-v4)hFVe_)zPKv!0mg;SeO?S<%(^(4se+;VeA8mSsabc6 zsY^RB5990ezgy5@PiclvTC)&i$}eE7i1SOBzov1bhI3FRfj(u5I+528S{&c#U*jZp zWr(?h$UDQvFjwdVWU%Le)x|Q`vP0QoEISW!cgK8BLe2~qUn3G`IMO9e(k5NX492F5 zb4h&Qee+n%y}^AI<}CG~Y=nbr)uECd~mfGI)Ji@ zA%6=p2MS)gPfV*5`RIPmU&{G43rn`3Y$i7kLbeMq{`I&jn^z$3UX0ywo?R(uccX03 zMUHwWCO!@s@;PK;l*c6G&mFrPl;trE<>B6sE)O>x=}@kuLwZM07Mw%XF&1-*FfR5Z z6BvDaXro_=N??mI^fFGExXCh zN6ungA7%D4$dYHKi!t?@S8>mJkNJs1b(ov72ME^KZZx#-il44m$*z1Wr$~8vzAp2Er#9Gb7Zy%r#AvV zLZA}^4Bi6BhOO zm`>l1c=t|N+;Lh3N+%(b6d50R)_2T@-A0^-aEThe!HH3K~ zLy!sQM^FangDQp5-c9?0{C_}#c7H7n&k6?WN z*Z5t5Yue&VU{Cj~tSj%h-D({iBWhm9eAo`Z)#|`DzmEHkABfgY%pZ7utXL4W3+Hhj z1m-z(G43s}UF4x?8d^Y(=nC7`cpLRs1e_uCZ@xWW>?}aJ_B)WrMqA|U%n%Dh_Ou+n zBM*$dY9Z#h9AllpT+X4;XI!}*fP5Z@?Ii!4OTzZT`Hg=s^|fQ0)rxmz&1~@8@wC+n zyHwNhvenx8!EjB~_7{^c^7qe>X-B5j8t3yRc>X@0i+TF_b9}zlYUR5$YFo*8uvJr{ z_GgmeevbPCRwnX2CK={QV3cVO&U_F23U!?CK8zXmA2^X6?XRe>uLjdOFIp5brV07mGjTwku!G z5d9~7(~Em>uk+Ibdx&|3$+QMCMCmSHLGu9ShJSag=;GX1ttY2{`}qZ0Zt>p^_b*p+ z3*ee^`w`mST0WE;(>SEs-x|LdxrN`wylUk28=(Iq*htRvy$yU&N2!N=X6je(rkn$q133sgejM}D=nZ^N@5W1bZA zF@t&Z(0Tmia9JE}qR`3V(vFP6w!lfsV`|^$l)U37hNXVzfu63TQ*cdsmm2gwI6quE zUg4RBEWZHUuW;MIPXbHYRb}VHkQr=wUjTMapbgy4wg@m`*w@&C#R=5^GTPY??1!W5 zF5ZQ54x4H7sZX8r7AL63o1e^t9_IC(q?};$cP;QI{vFS$w;#m^%c%x!BrhNO9UH^k z@wkn-TqsNOw5v*-rTyRaq&OQxc{1El)=9iqsUOMrfqFj)Ij>rD=baxuXuh*LQI1S= z3+AJ5Mt#%u_t#QxkN2X#S^BT^3(wLH2`53n@eJnlmTj`9!O<-(#JgcD-VJfA{fM1d z77S&H1z#N}N@JkOI`kmsAirXZ<`Z0-VNcGY-f+#z6ft=zgf{fvyuT>;=X=I2AGSs7 zi!(&dzh%1b7|u~-{a=8!6_j5LGX6H?TPUVB(>Ak=;%FC9?rb-^^N92Mehb+TLPsB& z=TA`nr|n5gg@bnp(u3~=+bNnWeb)BqF}%&5D%*b0&dtJPwTX52I6Eo382BBwCpG7a z+^n6Lzxyq`4^Dyx=Qwwq8{7JicppTtuEa)Mo#t~$(?Po-_qHj^(Z0_j4bnB~ya|7R z`JjHYek3pl6#8AvdhhzQZo5gB`QM`q$j?5U=^t?ZD`k>^y!>6Mti1!Z3A>;v|fVtX0m-N>r3od zaxN*#t;{cO#hQyg^!MZq_|7gISUJDEoxbB$a{gYI16j=gkKh;OVHd|MFuxFUY0vm_ zi}~zu1?L%xZl-PF{T{EV3^G3Hz<=r@9pbP2eJOaIjJcX>PBYr6x?PDncno$z&dHWO zk>}Y+JLhj?JBL0#+f!J7AnU!G9}8_AyEw%56?6qW^g~DAju%wjEg%Ed3DX|1-m#t? zL>a@5whHJU^dSfHyIXsxi_mrI2j0_(agYtm|3Ulgk0*=CS$y^&aMpo+ZoF#N;V|q< zCG1K7?HA-#wk4UL^BbR%?Gei9Ur?T;c^c<;eUtxzH2w_jC8o6tIMAu+=Ngd#{gY&y9JcNq^ijz6p0aIhD}}&!9PjNIcpLQCym#QckMI_&{y?T3%Ndck zyRL+O5!>|xu&Ydy{HRcN*?Q0Q+ZaDVe-zt1 zzkpsITIdYD58XHiJCW1vxUz?XnWC)2&TK{5)wp(X zTGB4=`(XH?`1ldK$o?d@r9!^x+o@|?P!_NS)wEkN*v+WzllG7H>=oF07!E_&^ywSFdfoJ*N z#e42MsB3Z1rF~rl`PiUKyLbumuoHY*u(R+1TIVYpebBbD$mc-LSMQ!pS%A-9g08lu ztPlG75Uyn#2mMlPFr$575ao zpu_q=d7gxvP9Q$(Q4#W^-}iVX*YTJ(fp$^1hl-R<7_muteHNY-SxQ~ia`(2S`0k@kartxegz!1H{3x*bB> z#rE3(+8-#RQMS4cI>L0xFX}_T+0Q=GW_SBpM(*8quq_L;^{40uv+P`b zfiGS>2)$-|0Dad(yWmfiAuQVl0{vt$=~KC3$;T_u2i?}&E9Ek|kG#75-A|x9I+o+@ zgL2=?qHj-yNU&Zz&~xg9SI>1lqizn+4xe`G%y736_y*v@bK>!h7vJEIeHX$xr|VyG)I+?#DV_H`m| zvLCJoHdp&i2-{Da$oDn*)8k`3KC3I)hYH#5&b>ZJjPbCpwv@b>VK`Ptd$0SS9M$G= z`TvD0^FOFexHMcFs@AD=zo6s_eX3^LO56D!)E%b7zAvtm(QOy>o$rXiMxTJL$UauL zyz;O-rS^v9*9NX{Yg^M6z}5>b^#ROm3bd>V*UPmlYVk|psw?Ve7jf~4d$g(ZCF8O7 z#oa|Fa7A?F`4!Q?b&GGR{*p#;|BWl^19cnP8=`;od$@+hLViB^oDN7e#gS?*hCBU- zsf<22t;bxy(yboPRQSW{{w;N$ukdY(6nq7FR4Kefv2?q_mnnP)UIaW^+>^lAhMO)1 zw|H!FPof=X@`E}dj~az{DEuXbH!Aw~%jb%?3d_^C@UtLMePpYPzf`!s*L?LTJg%bX z=l@ON`xPEnlLy!VNczjvyfB^8&lFzc!2zRLqL}B6I$ZuQ#QFG>tOxo9!fT!tX?gnB zG&q<~89qM^{<$=`lLoIzgSV!^|11suy)^jaY4B&$;3w1I@1()crNJ>)kWy|%Y4CYz z@G9V(8-@0nJeIg8akIj=DO{K7*A@P-!gak|nT9^vzA5?Kr0A3=J+4>jZqxJ?{+3ec zt~7KWPJ=&|2LE{)9PPrCd~!XT&bwk!p2onwq{1%;PI+!q^=_+*bd|!h)%?r-3ZIvT z&QcYAK!ra9J>XH3Cj2*4`1OjZayPiBSNMK~Kcnzf3Xe@xfTDk=#??GaZ6`Yw{+7Z+ zD%$-DUxtPN4;}sig%2qFcF2*(cNHF(?A|->Nj$3XkiywW;PFF+KdkV*E-cr(q>}%$ zD!jv17mh)dF8cUVmKVmOWqAeEB=MteG+{ySQqi9doaOtv3LjJ9Kbt0er3&9T%?8;Ia?8XOEpB)CU|laIk{`w z$mVyV)?6DF6>=vxwRlW!JXI?<%WGO4ZD?z+#g1L=qIP7@Deh6`?n%W&g-csrVlmvv zouq+)ATKwtVhD}lk}yt~fadPqmAo_eRZF$Pi?c0LEK>WZt;=N6a;ep*6=|dPV3Uiq zJX@T7#L^j2)iWo5Eh zFxe0LoLw+^6|mkX?P515l!W9;N4;(^)s}@=H-HW56mKJX!pz#IN(N;K$woMClJPk`!~{ua1X9K)Yn9` zt-9QU-=e}#13pz<^K^R}e6Pa2^!F)zl863LgO0f#=vf0-CR!rr3|yI9iDZH<5AtcQ z?jpl{z^}vmmxotAj>0eCCk_6z!oBi&$-o0LCHEitP2|Dw zrhM|1vU=0KO5qGY)1Y&mfnQ>GXUuDq8+!%R~ z&)Ek4s(}|9xKRF&mmj~vz5Gm2IO&`ANBdn~I*ZfLxn1Gja?yU8m(DlS(D{MFz2Wz# z39r}Pdh_*+3eSAaG34`>fnROlXVTF3s|K)_PM*TaC;AtYN4~i@h(pOO+MEu+#7zc5&lXys{G%d27kuDKWl`4GY$Q-MtHNn__N%|UVicwPX5jM zUT)y*Gt>v>-N=LCwXaE_-N4J-AoBlK17Bd^`xNfw=Vc?jDW5mf;Qk3NQSxKT=Qaa3 z)2&yyH{F;Kexb>yft&VizkwGU;omZF-Iu_}-Kt;1tG5p;+{@1o(%?ta;Cg+nR}ZJF zeh_cE0fl?hElq(A62-{m+r@X zLE)bPpR`LF$NUg^kpC|lbgokkYj3_58@S2m!v=nxK__4J2a%46e^cR_PaS24!oBi; zA`L!W^&fe|I|^sICZF93_on-B8an&a;1g6ol$TDn!oBzbOs=Od2}R zrU`#04gP~XwzZ#Kfm74A*{!Jsi*{+zNIvu?9OBBw0neBwd z23}_HS!3V}47}aI%ME;=ft%s`74GHdStI;HgU&evH{VkwDwAIQDOI?a{<1W9y}~I6 zv!4XBg5}|*vp)^~ghA&Pga4yx!ark#SC=x@%LZY!)Y5GC?4ScD={~-_k+tjlG z4}Fav^@ML!;r0F+lqdPo_zOn5UpCTx)4)wW&l{x4f=VxHrG025y#1je(nT zXjHhjyjm3QO?Q*R`JP&C zH1f=QWq##5h`8#8<0E+tc+%B4!v;Nn6Q1j9Gw6RYJC%(G-mtt^U8+VXA@-~IgQ}l}?mk}) zntv^S;$GR2(2gtkUx*H~k%N10`fT2(il1G<*h2iFdrJQI#^*SbJ8*Du-=LYVx0?6_ z`|G@}d{{E!NKPCv9y{!CPOpu5$ef4AId_w=w>RgiWBwrKsSC{Gp4khSzcz?@ zhmjdr7x{IO;ChV^z6-!LULmYS2w?uT0Op;WE5uLTICa>A0COE>oZ+5R;W=W6G?MYL z?uqGlpfn>zBu8CVms+r3|KBK4}SXxYft)o>ia(-d^=PjYp#*H3wx3Cn=RxS-)-4IzWE&=uGPbR0>zK%g<^+;xqm%BySKXjFaPwI zl@V|AKh}FHj54af|LId!wiA4{={KhqA#Od&De{073}e1xmB2m}w%z=%$g2nlxqrXC z)j33r@@G8k%Yd~6@>>SgoWm;fh&hdVFOk^zBL(BIe}ASEtG-FZPjT%+rWJ3yNerC2 z@1D%%0{fNUdr$WAt@q?FzZvO^O_|HbiQ!Yk$NC43U48xT>McLJzuLYGdVzF8GejaE zYlj<)MIsYnS3V|!;Rmf?Q(eZ{&`+#j<4>*N9oOO;Nhhpeo`@Y=@oOvC@Ea>w|642A zd=I{FWLq2R#@oRRlw*8ldwDnJ1_vhC!CiC2+Ya)ibunz`ZKwXdiFHQhc+PMPV__eP zBUf!Z<{Z2~r?dEbr$RsUZ#a^1^b~c#^1pg2d?NF#z%}P957-qi!hpzn!nFjcrw2@5y80%Ysw-SBGGWaHM<_) zG|IwSc7b(`;rlCRGkyg7pofK(#Wn62FKgu-&~#~oPq`j!C+Z2WyVRW0PpX$_@VL4N zz5GvVEpY&OVp-pY^Lps#ozT+|^wXxELO+>j+(S>@dC=>jbJWu+=&2(tsjJk}2=vvb zbd~xRfxe!Eu127zmDEwkNz|g8_P|b{>nP9urmLS#)X$O;{iN)XNARS+4dBtyOZ>58 z8UA?nm!YF?j*TCig|IWP-(0<2>FE8?(LaNZeg(MLG*W~*p$C~wbIvB(ASm|8D~3wD>i6dZHBI{gswJ0S3{?u z%kM&$-?xG*K76mg!vA+>IbK6EC@vWobU~{e5XXD4V_d>9+)O=cl^|F zX%W+gK69;g0QdYx4ev?&IOcxW*=~LL7M^?coa>Fjdk**fxmR6p!MQ>#YrP420vhZk z%G=kW+Y)}^zV-^x=b+QG63NtS3gf_wHWnQSQ|~YTDGu*G7{c4JBDQziHGQrjdZj z&yuE`v!$lTB){@_5#K6R`MFA+>C(%c=^%aX7KVKSK+<<>{YmzpEuQ91aG>H zs)~5&>%F*%YuzKGnaYQvZ?A@3B>#FWpSa;-U;zA+?y38`+R0I}DFQfwMJ&-CeK_hi zTjftbRkmB-ruFgl9?<(q90$qpQpe9Hh~rB9h?_b=e3?pjEpLoN$JbC=AK$~b4zJkJ zx3d49n6?}G!GMbYaX$LBh~TA38f9Ka6=82!-m9viLb#`L6@O4g;4SO7CadK)4wzSV zq>w+J|AqKF_muqaO+THFuJ@?EIT_Qv@W!XzTh$bes4Z|mb`RY7!G#L~^0@dtaJLy1 z$dPO~s8d;@FwY+>Lc7+=_TxKnzF(kiGlUNKuEPC=hYH^+EXTX*jWB!=uKD8g8Nvxx zWs97}*mGeE_WJ3#MaVV|pZoF_2cN>)w#}QIosU|v>Z|-t&<9#K`t9xaZo1+-8EBi{ zm^pU4Eyis3i?Q1yIA=C~wmdMw3C8>)7|6pp6X)qTPr!K=&e=GZ+RINyfzESy6)Uxo8poUg%oJEy@jF#~(q(wbkHNppSN7uP zHDB^R@A~Au-Zu}b)NPlbFXGSs5_@Z5->jE<+qlPB<))(V6rHQvS+r?0x_vv7a^e03 zc%AIn3cqWlAHwRp{~8B<6?X5oS?IGszsP;lt9rk;YfNuv3HEk@Jnn?9_5D|0@4oN* zdwa0IB-8yh+T}Ld-N<7pjF04j>02u8z^2$zen)pNbTN+p5=#`!>$pes?!Cu9O@Q8E z^eYtMd;-s{?9KxEPmi9&9&2+%F!toE?RPE^@DbrZ-eckOxv?DB_dKhyt~|VQX1Ua# zQt@^S^4+t3_n}UtQ-SY{hHc;WH{ioN!0%Auux24xi?Bz4kMzm7`y_TC%)deJu&!6` zBbCwEP`;w^it8DeX-AAaNYvz{&xs81cxZy~l7grM(t zJSz^Z$hOv_P6ivU!uO9u)}gvmu^~KNBy>6Iz9{y?q3;QOQ2ZvDCHAYQ_$^Nkr()u1~Fdg4k>(;^;_GyWUTe%0BKl{eJL2Tuf<%a|AUM>QCM3yDC&xqBQFGAc(6_4SIN;VgC>ThGB40O2#z=Q5z zV>z>1?BAoLvWlDYHdmzFJ9SRSmbTD16jnCRax z=au>TU9Q)4U(ZbC!XuS$>9&(q1KblO)%WAv@UUPh4qviGH2Ptx^{6aE8eDy_?a1S^ z_z~A_z(ImIzK9=j{k<{${8oiKiWK#N#|r!y{x*e|N>qq@6s~>dB?|uwg}B(a-?rc`=pO{h0`ZCYtMRx(OspV(J+zd!T)_8ppAOd%s@rc9X8bmQbpREN$>t~BKP z2qI0!=X;39mG}|&`hnl{q|2~87}h*!2g%c?jXxK0NmHp0uG~YfqtNz91eq{=(v>pqOQ63lpD zwB?$AU4Cq5cx4Yryu}ANYCOz&Ze<^Fs`vr*;t0EBlK;K&X_jHHnpWT88E0P@2$V=) z-Tgneq+|g<<}knflYhr1qGn3%}+@y~J1wr&-!U&HSy;8i8}7Vz0H@JPvh1=ydzxf7y$1?~O4@Ef_0 zKlYw3W;+&b@@np{&bICV_TNJ9anME@7JUAWC*VWC|EYLgw8kj&72@7Hrb#v$zebrwFx5XxWDfws?iee-!x8X{ zvOMUgyFa&!bKZg8M+^HIasSi44tr`d$HJq>9w~@o&r|FJ*muCrm3~IYslxID@V79> zpg8%x0qhl~_uf2giy)tIPsUWwiQ}6EIovyn`br;6_dV!+M43m_s$fX&n>M+RdoIqv z9+rjlhoO(lv9EUw`WQz!4PswJ&b`2Re-7!*5R;POYDBjT*MVD?I83Sv^chC z?4{}YOW3PxF8hpF=Jf@Y*V51YF}^3kxN+?HeHY}Az;`De#(4-jQ-FP<|Jk0poqL@B z#4fBYh8U`T^vZ`HW-VW~OVD z8_H)A_U@Y^%lbW}&vMO&uDzEbp35IAo;zYs*&es^x1Yv7)=#dytGqTQS}ReP>QOgd z_08&=CH&jbgvp!vR&99)p7lTu*n72a27Jz1;g|hx^C4f1jg%UodHg=gH-KxF%U|Of-vYs2lJ2)F zevEP3(0jvWlmq3$Z;711-uEm==KH^@aoy7>57O$!bL{7uH%#Z`0F}?e#2VWmO=DaEY5cB*8PIm3#<4r6=c8h%)uKqYd_IoUb zOCzVa&<~3~ zi9V!}b07Tn4(Ra~=<(l*dkZi&T?U);Hv0l;*IOXlLD)OSeH3L3y0C3ywhQz{Ik3^S zes@07;!JTX-ygoUk~0c!Mz{(!Ft}(j!e<|kJzif34FW;*;0PnV4wNE z3xJnbeHq1zkuL2zW%FA0wt@`uV2x?cK%R-SOtzv-j=)CG0^Or1yAW*pVe~_-1dR}A z3o(Xz))f%6?e05?bZ5!@h&Q%^7I+NKl6mk;xoLiG1kU#qza#T|)`cM~7>M6xAI8Ow zzi$E``bgDR!Dp%ZJZ1x@ZyjR*95MM{h)SG^%M9Xr2{Vf0tN5kzp>GGy@On-Es|<_- z{g5fcw*zPR5-1uE9d8@1iLY0_n!|@U9>tINA%)*2Q6UBtuGebsSNIDGA3y_w$4l-B zogpKQO6l$203Ud{Y-HBrv}o1ZudG>wF?Z$ke$*x`(d6bTqnv7E?-IS~hIG+WZT;f5 zZsDcZM{DnDYHzHKVsDy8mA2f#1-^KF6G(%JG_s+ljtcN^iyOT_*60|Phdn?AdVzifmz$MerAJ@E2l z`uHZDTks;|;SGO#8vH-n__p4o%+2M9Z>I03;euIpG@#CzN=SPC4P8a5fY-OXQsGMM zDmLl~BcwQ#8YQ1xgDcYfwDIR6E@^swW1arT`NrwSx4*123fku3<)8OT70qB`nTr3k ziojde15Nhhd}BSn{coeFCe3IPoro*1?D#NS`J*={L%J7U{%OYW>Eo6LHNc(x-eEf5 zc;Vc6(q#@@{P?!)6i|FP@~r2eyZgWU0+@#>$6BnuEoir0A*vE~o|EtgIL~iP@or%+ zy&i3b%{U(x{^qK!y9z?0;>8e_qXqDu@5rzd9PiNkn~o{39J+UmyO%xMGIEZ)OMgrs zWQB1Ve0vJ*-8#Dp^F^)ZZD?aH2K`;QhMlOX8(%quahZcBu?H)@+cU)bI^5HLlfVlBOJPv*wUS2(;0*KF0n0-83fk{ea)HIyYQKoMGrc zvJK1qV10w*x?aWna@#TGq38Mg`s%-A520wfL&!r%l|9sPgN-s7k*TJm$Hj6XSca4gx%bI2AT`R$SGmnelpRld3 z$Aaw=XM%T-)8KH|IO>94v%tNo0FRC>?zQOMFK zEclnX+h?FIQKm7-l=2*eKX4Fp1vGu8#Wc-yUOxvvj5_66U-1{V`@K&uUXQXL(-_^E&7ij&s*?KFdO-`*!P0`bL|7yJt0DQ5+31V(0 z{4@3$aeWNK!Tz9M$^Bj-uWia-_BFX!2>k|(_jmA-55T4b@cazwzP8sD?5~2|)%vCN zoie3y;Ij{Cry&)x4;OiqSpy58~^X)v=6^4*b( zcTq0+or}I7QpgYLbCbx;k^M~00+AB(cZ#7CizdqTb}%+5HpY%$r+W>J*w**Vopy zgjYA~ndkZe5+Q*|%erWL1NL&1p0!CqZ<6UgKyYrWse*HuJJJ|#N_xy|)~yCJ+{ROd zh)PN6`4C>;@>wN+;->HVs)3t&bDfgEH~j4eZid(U#4)^y|3~v((ceGn(7uxf)A_Ce zyt#Soa8Gis6RW033_hRj_dAM<##c@tF$;5>${c( zKe6w+P4U8fIsAwJ?)vG+a@%G6{*l{`D?}Tb^R0E;EERw0XnzgsU7>?{Y{#+9)&p7fLsl3+O41L(Z@{=+ zYbDxABl33Bjzivq$T!*H;0Ou=C9c9#)oR3YZ5$1r|LEROHSk(RuE$VrfvrduecH{XJB@OXtYG!;DfuEE^a zJg2YgZLg2zWsD7u%Io>{|_#k|9j(f^+)9CfR?tBDSzZk~*{Ev|?b!9iweH6NfxgXL7J&N)R zp&n8GyZ3+}gyD1Y#AmT{!=;CS+2}i>Un8GI@O>lb7Q+bW24r8#uq^K$&^UoIU>xcv z!}EKo)G3y^ri*V9mohHDN7xA2W3E6ebtsy%tDqIU{=WGy;9Kw=_PZRXOXtHd?N8#9 zu-(VDyFOl47gyjss!gcyFQmcInUXU6df=o#h%=9DmDB^cCjOSXZ&wY3?=uVodX6V? zp9+654gN+N9P0&A(&60SRP-07!M~ISr;FgaH**Z1C*@ZQ7&3)(kDgQsCu8A8>w&Zv-aov7p&=%bD@P^-K;3j>{MM#D>`Gnm|;^z8ZbDYy$ zH~Xp)-qcHeqlO3hF~c78deUWDJd_%_H~62< zhrHPM>3m2X|I_-AQ&rzWl2LWx<)8OTrAGw~sQB6HA?2oj45;NtF)I}(oILb5v2OJw U=($bnL+U-RZ%$HlFTC;p7bxv^zyJUM literal 0 HcmV?d00001 diff --git a/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/API.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/API.txt new file mode 100644 index 00000000..61fc1647 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/COPYRIGHT.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/COPYRIGHT.txt new file mode 100644 index 00000000..4335f7fb --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/Configuration.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/Configuration.txt new file mode 100644 index 00000000..9ec576e4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/History.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/History.txt new file mode 100644 index 00000000..58958f41 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/License.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/License.txt new file mode 100644 index 00000000..c7fb0cc7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/Media Access API.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/Media Access API.txt new file mode 100644 index 00000000..45eede0f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/example.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/example.c new file mode 100644 index 00000000..5d30e5b6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/example.c @@ -0,0 +1,87 @@ +#include +#include "fat_filelib.h" + +int media_init() +{ + // ... + return 1; +} + +int media_read(unsigned long sector, unsigned char *buffer, unsigned long sector_count) +{ + unsigned long i; + + for (i=0;i +#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/release/fat_access.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_access.h new file mode 100644 index 00000000..17523878 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_cache.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_cache.c new file mode 100644 index 00000000..de77e6a0 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_cache.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_cache.h new file mode 100644 index 00000000..348d5d38 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_defs.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_defs.h new file mode 100644 index 00000000..5fe8d6a4 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_filelib.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_filelib.c new file mode 100644 index 00000000..2c4a236f --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_filelib.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_filelib.h new file mode 100644 index 00000000..a40a28ff --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_format.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_format.c new file mode 100644 index 00000000..d067f377 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_format.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_format.h new file mode 100644 index 00000000..a8a6bbaf --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_list.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_list.h new file mode 100644 index 00000000..bd386ef6 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_misc.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_misc.c new file mode 100644 index 00000000..cbf6f08d --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_misc.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_misc.h new file mode 100644 index 00000000..0c026343 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_opts.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_opts.h new file mode 100644 index 00000000..ac4dc860 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_opts.h @@ -0,0 +1,90 @@ +#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 1 +#endif + +// Sector size used +#define FAT_SECTOR_SIZE 512 + +// Printf output (directory listing / debug) +#ifndef FAT_PRINTF + // Don't include stdio, but there is a printf function available + #ifdef FAT_PRINTF_NOINC_STDIO + extern int printf(const char* ctrl1, ... ); + #define FAT_PRINTF(a) printf a + // Include stdio to use printf + #else + #include + #define FAT_PRINTF(a) printf a + #endif +#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/release/fat_string.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_string.c new file mode 100644 index 00000000..f7206ce7 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_string.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_string.h new file mode 100644 index 00000000..90ca8e05 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_table.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_table.c new file mode 100644 index 00000000..8d05d3bf --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_table.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_table.h new file mode 100644 index 00000000..ead75f32 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_types.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_types.h new file mode 100644 index 00000000..5e2cca8a --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_write.c b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_write.c new file mode 100644 index 00000000..0718cb13 --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/fat_write.h b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/fat_write.h new file mode 100644 index 00000000..5558a86e --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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/release/version.txt b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/version.txt new file mode 100644 index 00000000..5a00a98c --- /dev/null +++ b/LinuxGUI/Ventoy2Disk/Lib/fat_io_lib/release/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, "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

&n-xzCu$IA=Msy(UqqM#xb=%h2|m- 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

?fB~=OSpgmg=^RcEjm{k3U7XkUi9|# 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

%VY# zbs32%r%tY}d7WgAupGTUu`1YY|3(F$ceuO_HZ7Ald!xoad$&2h9ILj|^0PlBYR8V~ zX?}y9E}>*fslGx^OfF<7ycMbM@#<2=g^`z8uU z<&jF4<}$D17GnkJJTWb!0;zv}Kb_%jnKh2$*DMdBdv|-lAImQ$DD_{OO!{a7QUq?W ztFPf__NV9$Rj9ezbL`vggun>uy$u_U)e^j@=a~R+^=OUWDwcO}o4_@RRoQw#s>`6A za69u=!W1(_+;O7p)0C_jo}OQadk7{?G;HEMda(g$glpUBTA zY4l%p+4R%N#9QcNrFcZu=K%^$2=w+yn#xHNQqJ+)(W~fy>C3X&M-a$NHd7O2=wg+- zW9Yr-CXG)38e-)bO;KY|x@XE(*Oy;Sj5*hQnq;U;1&fV^&KwIqB}4<;trPUQ<5;jf zH-!Pb(qzGBgN%_{76RI*aQ{@@rS|b7C{ze(;7R15(tEN`BIMWun$|KEr3u4qu10sEXTw{XZOsf_xgoM4+e zX+?c_41IHyq>*vp`m~-(rSA2TbyUU_+!7n+kOxIDDL^R9qiWuAU4&X5Syo&%3!wG$(}Rb}j`lha=z)^d;H~amlUV)6*!~Bo%CHZir7@NwBNxs znv`f3{ekU0b0fWux~^@HsR&bEM+n-sdOHSY!|OHZ$HM{@N;3l8EoQn^2SbpTY7`^@ zDvRlZ#qmzrr$j>CZVT9XE2YKwWF?bsh4hc!$% ziEir=h25nTKK4?rp>Y@zJA(S^Ee-~}h7lrHtfprQ#=7nFJhc9_-DmYccehWHxT_s? z9~E$rx+Gh1uu;@oB~(Rm{Y<3JG7L9y2A`P9V%>mAZv9MvvszyJa<3~}QM-KDJU9MW z4@_u@+(Y(W9GS4*YFL=DW!Wq(kA7{eQ+#*u299!jRbCV7RV$^v|4vX*Sl^*sx8v|} zd+?r4=&Rs-3YpHYS5XghuP@EM&);4GowO(h9x9|D350Gf{VJdqc99XD{(ZwPl|_@F z=-p9jqvkmpsj+Jl)0s(bWca+r1gVf$&fJ>kC2rjf^ynFqJ9l+k%Gav*b^tEvU(CR( z3(#vTr0@5iVw1V7y`$sfz`+&)gwH|-Ts_D7E@WoWPPDmLr~Pxdhox}x_XeH5RAJ^F z7D(l<#{P!3rPo=cp&jlQjW(%ds>rcAELs#qTX)cKBUr;g=+umkR2QFqKRG2R{Ys?+5cCUVLz##2%MVl(z1b_ zLRP=+iUp_(9xUqju_Z)0W^yhjpM`@YE8+o>j3UmCd%sP08CEVhn)mAsoVQFibXtF5=C2j(f}tRj%h?yp+vLMqUBi%sii2H7l^Pe z6~nqEEUC2_>%6X5tr;!p+!CM&Ebes^kF1n_~o(3`)#=PHOc4^`4D zmPG1&r0+x;T+ibOoS2yWiJm~6^RR>)-1@Qnr9f1DPab8IHMq2e!Vs=e&2&@hgma7J zN@2OO8i;`C&Kc;-@~1`@!`xvwyx&Bx87y#)?0TCfU_3$>4B!W=TcSmQ_GWk0&MKID zDj}StQymZwE=ML^aXI@oxPkBg6bV_hfLTtCPb9i)5g_L^vroW%)GC2AX zLv6!W6p+5!hm!JNn#5X_|C->{zM^;2qr%IRTBf|s>#B4w79othV0EYh#m{lna>I|g zZ0icX_bw#Ta@2hs0{SpX>8B)p#rK60ANuF+E`!49{6>=~lP}Hc1_gOmf}S*eIIKO7 zri_M*sRHR02UkHw%Pk$LW%5IoIf1WCQSN%Y;bmNIM(RsWA7~Qlp6QtvhatuK_mATN zHg*X2cyn+?t@#X#km-`6TuchvJn=@x2B|yr|B3r@Oq!lGKr?Uxq~J9bahE(5PL*a7-ZyAkdJ_+&kM}}Ni^?Z8$Voe{m8&0* zrl&4+X~ocmTvF5b8Cx}1)}xWo`(o+xjongSkpt_wK0{oy2KwaopSc2JKt+SY1u1Rl z04-(iyt>U>xZ(`gd*|jha>^l?w(LZNrV#p5raud4VOcNKA8-Y++3n-Z^?R~6k9A^P;Q-h@tt6~gpsdJ1W$zVeTPNu`>#8Pyp-mY+^n z`)|6~`tf8EYGa1$>>@C*6a^1n0cfn#?CB03!h^7KVSAfH{mUl%1c<(84eDl#pteUb@%*KE9!J4UBKzeQkrXuR7!m`j+)9vQq}2SOWQt zleFhOXvXw*W#jfqo&kxc7^n34{Ujt|Xg<=JVpOD5>ciE0bl0>4nT=8!UpA8?W!aQV z0T626{-Ed<(SDUA_Uaf-cy|zod^|OJ2WTMC$4;(}8yh^)502S4zi3qjMVR3|5U20L zsA$K;PHzJWtThKl8XAs5)HKg_1W^`0dPD$6EhAr(!4L0xl;P`DZagt_>KTkf!||57 zt~x|)mPBv;a;IPU*ribyUV=Xq&hCsRIAu5qi1wnLAGT#o3R9x_*(AXJYZG6eM308x z;P7X8OE=E@)~xcI9uDgFq=nnD^wInK9xsQ3u&g8QEv)QwmpJS=83bL4%JlxFBOIs( zl-q#V>uvImJvGCb7=_F@kgR!3TeHXqC6-`l4o*C>j<`Dk<{5Y#K$p>K;Agt< z*TM*K5$l4w-|r22U-B$t^Z5i)38AP@^$x4bOaS5Cnor3=UR%%!Pw_g59sq%K$4`kqx~?Pix2#nm(wGoI^!6h(xI+b z$4o}|cK0q<6XnWDfsATMEV6JBN3=0PmYiz$yXE^V%;*nIuNlH?4m3+&=$EZOPe80S zZOB}(JVmEb$=i8F4IL`(D7sq;D(0XgI|ypf9|T=c-^NTMV*EiXytC9Xku$p)IEF4MiV{S{4w(E;>`X27GGG8`x?re957TsX!AV-1!_p zRfj@3aE$bJnv|02XgrKcA~G>7~VkZUY6Oi8Sv z4vNz*3P&+{8gq9md;7d2o27vGe3Ge3&)Tio(j?MC`w ziCQIc8#Lz8-ChsP-ysgs%#nY{DLC1MEM|IeG9Drv> z;OT{nQ&Jq_J(O=OV6A|_W*?YjPrlvb@OkVbt;3Td1+B823-zwNwzPjWl^+IcXD{-5 zY+&YCmXZfZ#@b<-AolsK#c&q{aetP)t4uiA7#VX(>fN}{=2`5dJP>B~cI5HTnNnqs zy03(&Rm+?)3Au=kCjE7Qaoq6Yt1S2zUS|N6Q{1W?RSU;~H5MCm6Wv9!&#^LEK5UjN z8Qg22&+4Nc9$6Eus=26ZhEBwmUg3c$77BOoo8A^oig*;+~fl+AtuRF$4iQip-70Vj9 z?KpPoP7)VS%be$VW`Y@E8t?JCb=c^&EN67NAfEvv>O}V#j}d~hY1A_T%m!JFbi#9B z?n0J?V89JU!MCeux4Q@E!>yzkrbm173>*NJsL)H*;sG~N4FIt$Wc71hR#vIz_jo4#fzv0`O1*Nl@fnX&G>T%*X;%d@3YF~VUQXO*OaWA%P zlzTFoR5Pb^xc$bnSj*JN;MyjIX1f4rcG;aH_e|m+w1Q1R;uV~UqIErO|96=6O0+DCK0R*%t+Dg?@%DU8?EhIZxkgZOqgan zekwnngw}uCh1L)2C-N}FkUj?&DSC(s4LA4Z^P0YL->huuqM*Wv7)+sr!OP5i7=BTd zRn$h7Ai@Qdmfo9_b<5Jk^llgWE;B$UE8ZI+Fu(Jtr)O|6^OwPJ2)SXxiSCq!stXfy zu1%mUE)$*-HrE)F3$&?7C=wNO)%nI-pRwQ0XjY}r5tyD@IU9x3qKF>u?X!vrKeeWl z1m}%DA;sFB>a4)lPz%TB>!cnHq%m;kH$2IUQ$e#Eox5#N!SPNZS9`YX`DUr2i*h0% z-Qq|MWT2tyD(OpZN6GzdpB9pn1?SgAKlC-U%=tmV#%m|?V!17P&7veDX73E+;Rg>K z{Y&sT(mQ5knL$n1GH+PlV~^$Y?KU>oTo}=^G^9yhI9uHBG@W5)2LF^VwBYY zX_#or9$~IqqnEXr!Our>x9gwhH7$<83GBA(J|>1Si#QSmfF?I_Vg07XDd8H@Tfw8e z$aIw8CLZ)gM~k&JgNWZt!hfY@HMJFwzPVnMOd>I`-}4A%BudJu9}uUSHByd10a#z`L$)?o50w!<8Qbx7eZ{&47WeZ zs99@>Y4_i@oiv1H@??7Bel^H-XdmsQtA=eVpJ!KRF9XT$p*j0q(ivLixfbrvK~>27 zfGsJrD3ijCCMJPdktA1eY_MV(Q($^yQZ#EZ{ToppZvAd`5f1Q>w(0H6$90jsM&4N; zXw)ctM^gr8I=cYpt$c=*>J}7VvumG9O1Kq-%aesx5ZIgp%Zctpbne%N0c?W{%QktR z9|vO4)xV42gn{$qV^3wWzN@$7j`(~f`Vly$t$#ROcoEuy3?a)7y9|?rms(hb2 zZTT1|!}Xk;`G|Q(a}4_(pZIPxVGjsk3xd$CBrN`!M2v!1CpY&6V6K2#?j94 z=?g}e@mjKblOv(=_@#Gvx234$rL6OQTiO*OnGsLm%Zl~n()*A<(dsiYXuWf1(LN|( z1M#UM%89SLnUAxc4qKY6F!yAQ)aGrg+nc{hcnn^~g0Bz4GfgX1u`TIBWDJ8wmde>Y z&AF04(#>5^)wN?gkGODHv5-6H2^n>oYpce1y7v(pki9d65ZSyD*GV(^zVo?q?t#2V z`Eb+z)g4-w!^yReK1Bu%+=Lq^tKCfRzOZj*tJ?H<6IiSA-*u7o{rWxOq#R&)Th(3e z2(LbrhbFbO%Z_@$dKE%R)%v5*B70`GzHCBMGK2%9VK3%_a9KU)h0(}jY@V2os8vu> zGb+*}-0h)pwrcq2v&R6pB*53p4*EW?8N)Lm_t%HT-53&r#zCKL&->Z*Vos~5&Ry}1 zL<fR`#5%9MOJWMDDwD3+4q-DZHiT-G_p1M1@nYnw9{@v7P*6Zo$?7<5T% z$VRNj^Tj9CUBUoywbcL>^CPxG>}EBZNr~=T zem3%7iZygy0Nb?Z#pV`}SEc}2*Uue$ec!PcwK?;3>I`lz#t;D0OVEM@p*CMICN3{1L!jF4(#c;>P?` zjsSdg+pa%ghX7?M=g;U;)I5p)rXgjZp_}BgWS3{bZsy2bs)o#BQx`+4kAQOqkh!^H!b)fF0ywXFb6dnn=lKo(3j~dl(gPevIL}XVMf4DMa zjk?AzAK&=urko7xzNpK2=nOfg2ad13HlU1x`?d~0nO0lPqpEq26$aaMJ4PN>eY>jn z@~Db`E^F$3Kn;TQ_st}?P3e>P4x{XI`Qap^{`)SmK8Yp~U~Q;1hxzvGr8zciMyp25 zDoUaRkTxEA4qKDcQnI@^FWRO)0&~q>yNjr$62x{95Bo>Zi>3|xZ9Z93yPSDBTCMI; z^*%4Tm{EG+DEJ8U!-GgVpTI>DXf%)=mdCd7Y%p0Os|IYkoOr2bo+ ztG0`T00-B|VoU>})zjwzQ|0NW#oaJzuHuq19R^I}19%X(L)q3`R8Uc)ZKA}(NE9_@ zHTr&u1ziagl>|c2o6rW>k<}N6 z+Rf8D`^phz!MMwe)sUsJvFM2HVEb7)@?hPW;liP<;T#_@2#Nj~Y?E)g0#9lv9-`+O z-|q&xx|P&Fz+R0KMUC8zag7fRq5Gs6qvU=^U&s$8iSs{n(e=Fvfw3r0t^;r#W(H3v z_F*wgLRGMvQ@KE9&};Tfb*pJ*<_UAHzQT=IU46KDT+E>HaE`%Ra;5KkbimBVBF?uIFO^z7_`S_jWBXn2tejWM6EO;M zi_v)VBruAM2m>htuspaTY+W+~qUJ%JIG@J_9ZMzxERK_$Dq>H9gx7GIpJnkCiI(C` zYYyFw^+DFCt{d4>p1T3)wTTZBI^yjTiX|d5G7EQgtCsMI&{F2LqZ($j?dI#KQSut?Pdm-A?!#*`EXDTsC5}QU zz#WjRxMM4~DD{@+i1gT^2Z};vrc^+@7IOjVO_h;TP7)9Ww)K8_Btzk5yE2h>UNY62 zFon)d%HUb-M9^2NZ8~)Mt&|c?CN-1P4ar&`nzUNti?SDlm+pSt| z6$$cd5<=Td7fArbaA?0@U-o2`r<5P)Lu5>_J{vPVhTw?T)u~DgLwtf`F zu7_#jYlm2{ir1R>VI?p{=a)#YRHO?p6*Q6PAC7?hdKn^yF@k99ob*e@c&Ya7s?Fzj z@&Haywb7-L2Spo*+<{oPQ*Xk((`H&ksG4c0mRE$WKADdFxFtq{x|_ovSukvh^fM8gY~aYjd`(#9rAGhLQSgm3Yk)#*+BtB4OoxFi z0t-go)`5pGYFcThM6(4|8r)}kJ;urPjU$N5U^Lz3_QhR&#{_$|SX>enIx;IV$=(C( z3zUSoh7Ub5J}$53D#!6qo7;9-p9^ zO-IYAmx%Z`IA7k>+M(Wep@1PfJP1&zAbeS5*lmV1DU4`p(q@*$?4#91tU|6J`Q>u^)psYVcG_&oxYPzrzUl8A+SUPrZB!cL(^8{%$c z?9{t+Hv^H&VL{Eg`QY)X6pso98I6$@&Gx7dz`FuJzb$H?wR@B3!ds=WOG798Hufnj zGFQw4Sanln01)onF}HL(J~f%QjX%aa;iSa^;~qj^4k+$!fwQ3=;P77)10R7$Y_Ys; z+-L-Ia;{f(qdo>9();}kS|H-d5fg7j8ke-{Eout^q=+Hm1m-$aC4As+S>F!c8lCkZ zAAm++D0)$R&}Hy(kVr4)O_hKM+l~#K0`Gn-IW zkNf((nxDbqMJ^jPjB$Y; zV@|rvT9yCNq}E4XMIJ5s8Ra(4e5C?Vp+>0!sLsuq#xe<-%{CKa_ZG+qo+sm)djr9w znThe#KplO|Rq01C`N1>Sp5E@qn|bUAs4!+IU-wQO4j_wiXtCN=JF&;FcbwuPKp4G+ z$3O;U$s_FfTFrIl%_?ognT|+^Z~t2W8K<4{zh{7 z0GhfTSmTxmpmd+1z<_!S{(}G(29(=LUO1^+_}rxNraQO^+Qu!bU>m)x&fgheWWHNR z9?GT{T$Et7QMYD9Tmh|uh)r~f8pBymj%SEQM=!{I6}}b7)*v(M4ME3_|2oMQxMmdV zt5chVXR-}J7f0BUSv!Lz22DoJ^!itsA*yQL&{*eL4(jX#wrT7J#y%q4xTr{lAwlBnX-z})X?@IQC=F3%~M zXtQc?_|v!xcNaoUuThfRkP`y9E-FJ>CAWw6M0jQnP6C*C%G{1O&ApR-+7HbztRIN& zn_s&^P7^_Ll@HZ|RA%mAJ{TV_herT79<5C4-%ukT{Y(8?Ib*hkoyLK@r&ycg5G-l24;k@uIx(P@A}`7#NIXxwd0 z6;_!v?K+ngc^nTRd{q&gS_vd%jhEO}2~jZIf*R8{LJR4UVx#H1;o^O_%qbU88Wi!6 zC;~&`z8X#-Vip&(B*(lpz46{cFLS?7?#?yKETO-VlOiYzEd*v5Pt~*-?oIFJ^7P^% z#BVnjcx;jH6)JX6ao|hgShAVK@)RZ`EH){&LthmRsu_T?#jGNhr1_ZeYUPK`JtHiU zURkD^rgv0ncJERg%|y$7p--2vKuhziP0v7JxJ53N7>fKBRb87z3;v~-z5>}!uD2{Z zykFZSwU$gCe=_%)&Wi~2mu3zTo@QK_>i0}YOYJ*MxnAAaJ}dd_W6ubx;i$CaP)`2Z zi2kZ^Kz%dGv;WbhnHxUdo2#D%dGU|pdT>XfhkdcWT=+tG%?5EMz!oFIT{7BdxO{;- zmFMh(A#b|aAG`Vushqfzfg0)m<-QS73|AF6TQ{{sHK|Mr*6xDdcoo~C@GY7;&?_?U zn%8LdyT!cw{(aaY5$Qd&yVVGk;gz=to|w-q00Xb+X_BON_S69PHvi?$t29jvb{kI1 zSe1vuqO_(SegzK!A5E!{=5)lu$>T=Si(M*Rj;t#<*%~^a_RLotYDiKC;@6$9gC^Q z$tw6cez1^?DvZR&Iq`GU9@Oi{5)Ad*5TsrhrmbDw-BmaV+Ii@DsI$zdVy$0>@$@Ej z?|cZY+0OVzzBft5|BqJyeHZT1mWuBn7So8uD=(oVTD9e!t}V|33l11!%p8wEGCT{z zy56$ZV@~hrAJe}#l{5N0eAb)&m?wuS1h{|R&^^LWQS@o+L(4H}-F`TOi$5k4+E`C&-1t^zZJe&L=nJ#r@Ts_L_T&$uuRBJ6&9P14bxM36XQo91 zjkcE6uuB)&3IG?qL0GR4E~hSwiNgC`<;1;JN-m4sE)%Sj+ZCD?6kxZ;;42}K8EE!w zP2nW)F{7T7OOpag9lPSu2emi4AbiV55v}*GnSlzGVNpsAUW=ryT@UP-Ei*5;@m9Hj zvj*?YLejmhO`5@;{Lb{PC$wVrFR?j#H(C=7+d+*$7MBdM*I6e>{ z3gfZj^WQbqzaQFzpqzB)gCBFOYES(=jO!jqwi{OC#mw3*;+{_OxB1t+{TS}Q(TP5u zuX0vBYv1(eaZh11({*-;OLV3*WO7$^PC$kGdbvxqGwGnmRB}nyLM}Wc^*N}n<*gMv3*ouVpI$MVv$6fWC-vG96UTp53fsAYy zPh$G4UP|-f|Ia4FzAXnX8noo6hEb@mH{A`=NmsR3$Nguf%;I={>cOq(ugC7WUt0$J zGf&t8^rh9#;t{otx|o(tD}m6x!BSo9DKXq`iCCwrv6Y7U3Vch;zVo>C67nmKoAn6f zTG9eQR&o*I3&Jx5RbYRaZf`{kaIAciqQw)gmfhR z6&hSim2#+C?N>4yw>sanlVMeLa6?4EOhS@ZEWT(wQtL8U5&@kD&Dt?jBZEZF>*m_dXr5B&=Lj*@ck>1W#PDF)IoN+ zzUekW!2N0pOp0#CmPKU1xZXWBq7l3 zuHW_441(ddt4VUx)A&*YzqC(n#f{P->gQeQOrp8c$z6fsQiROn+m7Pc->)6(8FCTA z5dz)bNWwc#>FaQ4>m(@a}-K{lk*~Jj&))T?4 zw~p(3_WT2M{&(|oZkG^B6Hw_AZfD%O_jP9E-cjViuOTw9q&DKq#=@AjIPd9M^*Kt?sg>1&#<8mXdrjNknD# z4Tb0mN>CvTlW7b7&aH>eg3<%p+vhxZEqMPX%5p86#24)`OS!JRD{@~{-kU5tbV;2Hv@R(T6%ReD9yZ9a~W~kR=#B z7_DU_rhgD1osOfhZU5F8eNufl6ktye3J^UevOdlx4`KNc!;jwVF^go|j+iLpf zWubN@jCKa7assw2bx=Mh@#Jw+_Il%wh#PAn?f+{6?ORfj^Ws0^0LHMHYswpYn5Pt` zjC;M!Pl#lZGH~*8zG8lVDSf`PU3NqUP#=LvyInOlw-e|+jyv9>LvG?%)5%6PF1zeHk#IKbqC54>PX>A054`T3X3Xr5^@qOP%`)s*R3Da5 zz7z;oHCfDx=Jk&Bf-OMWE;hG6!xkMKKn7C%D&3oi(&0n<_)1e)}N-LqwW}gbo}IcV)N&SGHEI&ePPLBt?=G_YtHBI+$z{z*1DK zHaVsTDc52tW|^w3Fg-w+%Zj?_#~*(K|1PBjwBP5B-?Bi|5K1s1n} z(B0Qhl}2L07Jv)VcGjHts%~oB)TMlP0%U*B?aOcXasi=wG?ndCF46~4&!pR-^;6o0 z<9tDQMSh*Ck+L8tZY$!NRewA6NMu{+1-uOyU)vYeL0QlM8B*Mnf=1VY30ou7<|;9J zW|D$PRj<}!vbdR{tDeT+wy!h$oQnNkK zGPUhA^FDXn&bn_C`E+Qtv|VJ{(SxC4T0(cepSd}#9J6!?I15V#nq`h%w=L9ne+#0# zWNnnuSp4jR6xfV(38ua7V%*6foYQNnw$Sn50Ds%b-?H zeqy}A@of|bSX-WcB`U24g<7-fnKgc+HI0G8gviqDSNlvOZ+8P{QVY4_hG@C!4F)`7 zrTV0~DQW0hY^kJ$bjAqG*2f4w3ZJr6p~&|!ryMR^)e>MsL?YjxlLq0C z9aRrqqu&9OUb!J!_n;U|y=@I=!e9`Xe$c=rjvnPzKN?D(%mDYm6uydSvbl9Rk#ou#?z7XJ`RZXWrgs$(?>RUv?o)+%m6IILKY`s zq78_qFZ&V7Gc+q|VyGvKXbe zg3~TVLDQ1SkrMgcw{ab_e`zq$E&v&IPG2MM-3RcQzwe+1DJ;sZw-bXnqyafp?WZ~< z4iOiu!+OLsiFsYBQc52KS^6oCY}JOcrvl z))%CG{VprqLf-Lc+nA$}a|bI%1;~X!SBxt{qkNZ6ZaO@7EZLbgOE4BJK4{TPc_>cgGTR)3k^jDEK1 ziF+1a12X*z-33sY?1dKmF4O@*YDC`r-ElzCONVA5umj2k_HgyJmH_l;!A5YZ*dtLDg}sBwc7^Y$d7>Va z&=C`@UdcD7h5cV$oZ(TP=Ot4-2}%LGiTR(D2u{4YY8DDJVbgC^fv1c>ew^Af1}KxE zX`g8d4v9^@sR2G6Iq7$G5iWTx*?v$=6qIPqUk4EzNQ@Is?-i}SxDU_EK@YsscrMecdr=hSy=Q+60t*u{p;}T=Mfx@I6b4RL9fs}Xp z{n;h?g4L{+EG1XQ3?<^%l~&@;0%u(VVLJsKI)XbP)Ueax@BRA0c{#&2&@_?M44A_% zR!13wq)}roY~)iiqaiQjTMBPQHvJn^I?LARLzs;1#CNK|5cZNuB!$2UhH>OJoIGxj z65#Pnfd46RaKY4h#vY)+y3RBf4oeDGTu^r>*`v_*`fzASUv0)(=Q!nv8{vi34yBzD zcS-15@5VLtQuDBD@5QQSF5T+&Ajddi=rT}#CyRCJcV`mhP?;pUa^41IpU1YDE;rm| zlK!?fDAqM9ut<2E!7J(`}bUnAu4j~pa zcJ~16CK<9*)fmAysiSxDNjP(=S{6OZrj`D#-gAd1ic%I$Ghmqx)$up5G9etxxMI~; zGVbWmK3yZ7WgIQCoMZlZeM_9QLl=!^5Xngr?p(7r?V+WYA8EIMrf6>3A57VOYNU4p z%^C&f5dGz!KPlc^20M2pe<6@oA4<4G9K`m0v5Y0%59KR2$Gd)SO)yGiO)kkR5WRY3 zjxBjTdzc4|6XGcrJwubuT<Ezpr^KUhxjGpo)6{O9^sC`#|-PMUM>K zP0n298@OW{(QM~O<|RrpE9B*x;gtnQ1)}xPAmVIVH02X-752*51fw3Oiz27oVW{!-1#T+Na{n%p5?BDjM-g43qHKlYx zZY+=}A#I9lGpC$VW6ai}GyYN?B>$o&GQh##_EVNRh=m$!1fB}m;_Z+k6JOKLY^@xi zm}PTQb)pS>ZZ%UhTJv~mLhjP@*OqyP4SFRV!`dgsQAS`=%y&{_A3#6&tT>j7yD zbrVm_tWlflVh2COWR0DD=Uw>bq8vck+FFYdJ3elT#t>L>B}IxVLi+8m#|$Cc zmC7{)?Xvsdif>k#Wa{*aPV5ks;p+g+c_Wb$Dqt;i!050H@<1&723 z3}ojCw>S$W=Xu2joSYF$>#XZMGX6iy7@`>R9Np4gY{`DXH{P&5M6=mqXltIu2!WR$ zQM>2Y?u~FqvnA$UTfT$c@l$Um7Xm%q6;2ORLyzl}RuSUH>R-v9Pm=2&d9UhsWE1CdX$vtyx1s>-YzYVrwWVH-`W=M@KgTg`o(aSTu?u+jsUV90Wg0h2z z2r`_vl%wn2aY5eE3{pkXbYQ-dtxqnHS_kh!&IwnS?1&q3PCbH%G27;AFf|5qt(wGU zTH)IFE|_XphLAnQ+ajt%@qQJ;H1rxN>Rp_VR+)HA9&QKFQJP6$eflj5htEI~JeIi}SgBKI1`mZaL%(8uj3gXdAZE{XGF+%95)FCBa;WmE|o;($5j3s?Q? zpd=Kq4h+&=t6u5ky$?uJ@+}?|E2X)$E55DH7Zkm{*0%J0b z);7)GQHzZjBM6xB>sdk4oM6p-9lT=MSOnkY^ltRR#cDmqEuo9iCW`ioC;coH(H+C1p| zUBbAbEutBDJ80E&lKUS55qvE<1HNs-9$gyT7KM=i&Cp{m{(}mN$34~Fx{^PeuKAA* znte<+c}fdr)>eU9Fz1_%3%fHNNHJ11)njR>1UzM55NpeKbgJuD)IUZpn*;!|+5@gwSN7aQ zb-^oZ&EY$|hh1ta&}Y=l&;P`wj+%+~K^jY7xBtlSnL|1CR)%|kVP1Rn*j+$wO`0v! zO4=ZGs!eT*^|pdeKpnxfPB<=83y8C1YlW1jEEyL$V+J8*@2}EcFR50hfv`aoE}T2+ z6ieu@e8@4Mcyv(2CszX%U}Sf@$Q2UBP67C8pum;*hKZxgWd+Z#-wm)#_#Nb` zJ$elN4BW{U#JOu@thA2ZI8nE(xZODYc_lTswyC{0PLZJRNNzj=4PTjO!Tc4?-OzE^ zpUFQ;6TD%jVfv9MA|N;TLzeYpRoK?9i^(;kdCH{F7)m1fZI0OS`el5d&tt%<_9Ehh zFP1c@(pxR3X3DCtvdE;IfcC0Qtz*B+xM8ll))NL(oZ~*WFc(wVhn`QnFL(;sUr*pW z*??r;O8AT5#uyvF#&brUutgJ;uJ$D-K|Nr9oH_z`eK0{uKt`34K1MV-q21B0v8n-R zr4F=hq;@_pH=MJ09Lxd)CMLf%KIvsQ?Xud`&W~D?f^2tr1#Ukp#L<$vui|N|z7KDJ z-ia^5tX4!w%JiG})>)oM-8Zgh-(_)15gC{?ZY${9Pm{O>0uAZ&Rcv||Dw|)f`jl_J(y`eI$?N9|Cj*HY*!J^d`)^6VkO%9n1~; z&bCZCSMsORb^eLlklzdSEa(UbvPp^gP$9C0&Zt!SvaM7=wDfBOrA;iS*xZ5mI_zmp zZa>#j)@zOj=*b@%aaZk;cx>Htx|yyrl)8bLofg1^u`Tm*sgU(mOC}rJ!Rw%lM795h zwsgyANT`g9#RK>Bh}`+pNkhjNr_p$>3-t0W8AGC(W6}{}5SRVV-vV2v#w&9Rr&x=K(N16ul>{1v(Tk?w!(-+N@RM% z{xRsK-wWt9($Z*fkqV(tZ2m$g?NR~0pyX$kjKfnUrJSTs?FwTKk1|@a@=~ro!UbQ_ zQ0z8K<^>-fOGy}_4+WauOY7n5w5G~xpj^H8O4T}|%~V@R5)(>RzITPNS7;HResg2~ zfnvxDYPEHE{Zk2x@jmd2WlDOQr%*~jQl32MXr&D zfH0*VGpd+ZaOuAfyZ9*80*EhlQKO|^#l~q)*lnY$V&iwV(mP8mfcwJ*U2b^b54=me zG*%RGC$Z4>-TRe^nr(XQ!FBQnVS?UrHjt$h9~LX(6#*AxV)7*AWUoP^$==(B-2pqzG~3(_bT7#j z%|6?j@3QY9z}7*S9rqaR8E+C&%zYdiT9m79&h8nT`B_zJ4fJ*UnTLW1>(qvzM-I&6xQ$he$=*e@^F`|`3 z-Q`mL!vqfgsoRL8<{83vmxCAN?`%O-KlY;foqLyTF?kw`{-#d1k6nOimRkWVbaVk8 z7Ji%rx#-+p0l8$%fwB$T3E-WvfOq`P*}0>$BhkN9o}a|#o%_2t(HbZ0Tm)D24k}E_ zxjBp3X=;%r(M(u?`maa#sIZC(pYeVdgi1y#nEPM~THZiYQrKyAfHJE9^luG{*@XEn zBI2|p~Q%V_34mTSx0&STL3u&`=ZsqHa4FWaw7t9Yx zkeDusSj1W0(-L)_%^TEKZj16=*(EE`O2mPU!IC#)?!7CagpnWR7Dt%#7C++f9n>=MI4b{|CO`uy*{?x*B8!l4~qsA zyI`1W?R?ftOY|z1OHXOl*TQX@HY)lMjMC+JN*;X>tcFzWK|Ay_1JfV%Qr^hw;uH65 zeLM-P01|{`3wgCrt6{x z3%Z|PKO=97)5N{5z#w$*I=*5P3dYGcw0Yt1M_lN-?k(WhV>A=Ax|DkHeb0aRc(M|Y z)3(LH0WMxnUM(kH15V-AIuFd4M9j0$4FQ~4K@G_#k_j$bZ9%F_Cxwbo;3zBn<~!1g7F^F{U71Vb_va`& z(G&O_GL1rVJO6DBW|?)HRsukmgNZh(h*U&PuSo!xv1$P&vg|8Z$|PDDO~R5=(Fn=h zt40<%4k8)hboj|u{SHwf%RVkWa#wfaRbZwcpN1gtrv%~x)oU-kpqA!^zn0y_4?MA6 z5f_*;<^EA(JrLJT+cl3_L}IFw(PwxTlgyXh%5{X$)%tWWCrJdDA!vXw!IFb3x5Bprmzq2+hhMuYB3x<) z%>)wSX~0c^=zJ^ExJcA2x~WSIBdS`#WB8Ea&rUZ|Z)IzPgm-nGvA?a(%a$RjqPf0-PI$bL&+?JsEv=K(w;+zJ5N(nroXlbU;m#wDK6zk?qA5o z^xu!HP`d%JgCJP#fA_S6mY9s;X23MlsuY*Zt6V!mDkuW1JML;h`B_1#Z0TDDc*;sb74taUZ@v7-mfqv*E#8G0a?-%<3M3I zZK5&IvQTpJn9XPlkr>C-{5?@=jA-L&0p+ycjZiaCe-yOujT4{pLs{|AiNDu!QP;A) z_@Q^lQ6%<$AlxjKE6%)ShXh!xD$uVWRy2@fWijA+4yEg18&}9PQ*cQ?s^hE1mXKjC z$Oz~jx{gG2pg@p+YlI-ky>b53oz1?^k@1Hs>U)CU-n?!U!aMU+oqA3I+?RUN$Ke=) zWqoLpX&s{3qhJ_Svvr5aIWv3z-JoI7U;s$XOEr|mdRZeB#5*J}og%841#Bd!?C`>& z+4wNu53h{&ae~t?Rln4@V65S*HhW1;@QSez&eD>=)KVIJ`+X9u4)Bn(`~ue0mD`)-(&ABBUWY4)lmzRx@WBkJAd}u*`!@wYIg7qR)a$S zw`W2z^*pVu?cBR&24ovh#Z<2kij{bi)Wi-`sGK5L(i4S5oGnRPrT8Yl?lvU$L+=#* z@$|tbTJDFK@ukTb7e@v5HR-nko(idy!#vTlI=9+BU{!T**mFG8mpS#@?;~-B68FaF z>e~UjuE=EA$)g%Tru*}`fst!!u7||EG>g=0mEU8bgR^`4Lw~Ll;()z1Ke2;0xBB+N zA7Ypar)XdJ8W_=`anPP>5uT8F3Xx;tk5X6@0o}82sv8d4oJJCbRkPArZHDvoutG)`p4&}&_nG$^{Qy8Q^{l%f8@ zd*_fjzBbekuFQ0_W|@!?ks_gGIbnBCc_|;T{LbowB<9QUeFzmxic1h7tK7=Ayb4Dj zLZ-ce$?zQzM2T|@Ppu^jg@O>}wU|$M)8@;vn5;waIs7jyD+;nQ{je+9$-#xJFMcu! zFKrtA(PT!Bu}2(EZ6mgbUSkKjl#wYv6BCOgLfynd?yGR+H22`YGgpRyrPT#93;Ody zhc-5ugw=1lUO_yzT0pRfpAN8<;g^{Eq z_NVu<_n!w2L;xjJH@@|Dh-0R=LOx_43~c3E*IY(%S#1_;mFRsBo<9P)v-G4KXkwgw z{jCI&$Bix3{k4fQVW&IR<~mxNZm2UcJOKH*D#DH2)u`iOb4wq)XUo6K^^Pes>~a!Z z57hrP{r6M(doH^Y+~`ile)_Gqef2z&jIe-Uxdjz_v{IIcFlDbwc9F4VW~?~#gYlW) zcdj5uj09D8b!R8oTH)dYoAK64WmcA>3MG=LmM_#P#OpphcT8Fml?fvJFY$|+ChE&I ziPnrC8Yev-eG*EP^pI9vk^N!;fuv+Q8wR4I0%404GW;K~u>qDes$Aob+=2V1iw^Fw z{(R&@TQN=X2Z+!1lZPLrLSdiS^0f~(&bbl^K+ady4e z1)|V6PIwpxYlrQOoM#!I`1DSp2LbSM>ef|%IXecg_hH{Kw+Z@h=rHbns`ISglLS)< zXdTh6I^|c%nb}KG4<9Cia^F=sG0T4zcRR zbgLJC>C+vXfv9!YCXR&#?w0n~d|dk&k#4n%Vb!9^qtgK7XG9adC$z7I0yCn}+ng06 zadl_!l~bfOxM8w8HXv1`puo^$e_Cwpq0`Yh7nFX$WngjkUR|=+!Q;Xyts!?Y4NNR5 zB`!L^)Yzr_9SBlE#~QY22_wzN(12qe5ewU9YXVhj5}pJSs{)~I@OqP;^9>_{23$jbu%4QN^ z`!2v>Bz`P+v3KwQ+py9t#nr8I7sv%^^cGZznWI?)FZ6+xeLL&8y|aXt$jU8sSkRu@CQ{<${@BhokIm5}W{&o3b_Xl|_;aAXDL zUK-;Zg%>P^h#mUEg`84;J((5I>aA@?$Zjck!l$GA?2{i$%GTO~+Zg zi=WsS+GY*DAk4!*`y}X(A(i3Sr%7}ndRbw(K}rREVwSbZC19)dLdCIj>fCFp*L|hJ zs?~^cNpAavyH`E)t$%iV)!^?6?av$lj!KmZbyX2^q_ZDYMFS%yQ-dIgd1{C*#)1cx{tyF<7TWE-e39of#B zitYQKGL2>{6xu3QkedS^yI(4a#L19wC>F4)mi^!{J0K61q&7e%bl{cSq`a;zSuP<8 zJ({RDvB`%2__|=W0kb?yI6Ya$LHKU+zQwfkls$~5BUpCUY(bS_bIkgegUq28s}K>Ji;fPmiUpze+Q7z1uYENr zT1G>n!LK2Y3$5xoQEn`A10;$@I*xVP`pMgswK+xr%k( z%(D_(e@5hyEn{kk*5#-np}sR);U4`zl*&i@y~OhSS`F?W7LeU}-yqh#3+XwhyBJd4@&izMd49X5|Blq36;B(l#KSZg~CyJ$yrvic=LNh{y?eZb4=?2r%pRvUu zk|M?^JoU`kv+r!=h>Mk7kB5#|6q4tb=M@?x_YT{c18==3uP3}0(do#q!6k{^P-S><`Z&L(w zv4u7g@{D*x@2s@i9>^o-RIWu*L*#+^!exT9D|-%>b8|KPVz$HmY;_NlRJ5&XC1Up* z?WgFj|D8FN6cO55KEcLU6{^07$8o_NDtx;jYQPSTuzzfIQQKV{&iMYBKd#P_d#U)z z{8>J-*Fls-4?u$kV?&Ejth&|QGKkAza%E9Rb&b3|b+_-cK1WmaWT9QdD|G$Fiw#-W4R~!Q z8}TFS8~9-_^eL$efGt$?;HN2g>!CM9kU9+k8ZBz}^g^JeSz{0V9~HP{j@s1D_1^UPAT}`W6;o9J>)OwCqH7Ht z*k}URj5X;7&XCjg{wPfgs-cB`&@%wky+@KMvE>Q$trKp}{*2fz%f&!rY*wx7404bi z=W%CQC%hGtpaO#0Lq&e{iP6~QO)Ms)i@)w>)z*h zFRXq-RS-#@+=?7{L@Q%ZO#}^dU~q(c>!$6B`IjT+k@S3-zkbOAF8xrGjG5z+d5KC- z^t7Glw$=jTJdmXyK$cPa_d&sg){M~(JTIj5%I}48!N!dwUXkUb_+gz}bH{I)F-Lc45R#O;1;TtW_qJ zBeN2zS29U0StpG37HJ7WSw5LmDg?TC6AMi?gozNj#4fAn^|Yp@-EFe4s_^Nb^C~6SK(}BO zHJF3fYg(R8M8k*nojgc%#Nwv*4^D?f;5duM z)e#&R`#un&_7)HxCFb5+4_x)_t(Ctzva%A&uU`^R*H{z?Qv2(c>J|PMhIg;;ZO)ag zw3d%>9}~0^CTJn|d+N18D<7XJyjscT;$BaA{~md>qFJDOcE@3<>r^IXm6^5p;FU6l z04b@^9Yp3J%jR$yg^{f-39W1?_B(u!7QGgacvGtV*$@4Bt`F4A>6={3d`Kf1P z#pK0~jDF~Pj)gjB&AvWQGyCOJf=v5 z+-inINuxMaX^(kq+E&69@_fcF1}BKtbais?_}SOizGjpWop!6|Wa$a0s2@Y_3=pw8 zdCtBmzmS&>4Y!b)++u8Jps!(_<_yC|s2Tc?oqZii4gO!h)zL_EznFF~@5Tq}2Dipw z%t4~zLLU2VjQ1QkE0k_+QS>pMFiK~@e}4iA+@Op(F9k8tPXn?0b}Gc$^>J7xY&P}B zg5X`2@Y@7_6G{=Fgo;2^tvAx@bQEAkH|FowkKr@kz-{Yjv$K`;I@lp08)$NRuX%5z za2SZew*AWfHEhw`|;es)> ztvj+}K#rr>0x@UiiUcSPH1568tb>Gb+hNG+0BJ4KGB!cf9_zV3%{vQT4t0%%)KGwD z@^m-zOUz@lKIGhU-JuLRyIh74CUW+^ra{&oqp$(hU3QLhE}H$u!Ie+(6!_h{1j%?SdK-5b}zxSNdgGdLFin z@z8dFqU3Z>++_wCo)C-A-Ri1JBBZ7lZHes#SSqOYZNf)Ci$NQ1i;(sUKCCE&g>7r2 zAWC)3J-^pS26~M6_TGXhsbhmhJgd!em?PCXKD1Qm&yuhB6z3u7pbJ^eVdrSP#@(#6 z?+Bh0UwSbYg~kbE%Z4@E_yv?{9*gNy2TX{RQ%8JlOHvSh0|*k#A#&2=T{&_6XQ7H= z(HFXj3Z7O|3jNToP;hl?`>aCXD#V>TvChJEU0oqN5d&Usb6EeRz>6VTRCr%;mZ6{W15s5w#M&O> zX-YC-_?A!bxE*NSZ6Hg_3J;_=V*aOQ60VBFEtkC9Kpqy#kO8i%bcFii9T|oh`JFpL z!TpSKiph;~A+m;`*Jv{wwQ7C+pI}9(twM*c!EZ-;_nJ#p;Z4%y+AVece3sFU-uLq) zYw#M@dQK#d!9-5S9i0|4Q3$6Pq|i8=2|_md^s z?k)&k;%j)q+PSyAzfg6;y>v0cJ52~KoBI}t>IyhRB0KU35UUfowRbJ1i=gnZOrF=2 z5V!W;TqT|-g_%fa-H&g88{XPY!t17+iN9@#>m#Y&+%XUrYM|K$G^+Pm z^LLc_VJ%4>+e7-61uKgwN<3RigdGf#%35w><%5>V<5RWvmX@WxUOJ4a8dI=^R0Iay zZT>FRB}+|H?IPQy(2a*80pMj>!TQ4>HT1cAL6FWur?HSbIR4B5u>t z+o38vIsgcFUCmK>tqw{F!AsSy%GO>>sQ0t=*j_LUF~-ZZKb3yS>8M{Hydk(%E(5^y zmjWDMwV_y&E;V~%=XxP5`^cpj6fg%YDyN9tY9pck+-dRO5X{ph6HR<=s2u)+|pqB&o;qI4xfSHO4%0)!i%e%f6HoweM9hFUnXNM_^fZ-aH$0WdhTHql zV_ka`vhutU%D#uNk5ki>fw-pu;h2<7z2Of#c9pu%*n{LAQ{16j7vYWGg?fgoJj{fH zT=&1Vc6UO3B$7`1kMkB*Dauz>&-q!L2B2yVw{m2rMF?GzM;RpLm3C`%mwgr8sq6g`Or9#i zy{gvkCE(R>6w{9hI8>8?&}Vu-CuCHZlI|^x^_?FG32k$-+yU;Antm|_gIW(*=H^6Q z+1Pj5vahbA_jbv7rUM=7EvE+{9pE>TV}Lz)Urw>;C5#&GXr_K$tP{n-3oTdXC&+dCczseX@!pnQ^- z(u?ZqvRrwCb$$pU&6w(r`>u7R`dplF^(Mv;sQIxe3o}ZSPOC{e9c#PM_P_lksD9f~ z)%_3+R_jt2zE&f}s5`s(mDW3(>ax+$DVS$7}Sa*+>6d&_Auq_Tb zHtVIk)6r+IbXy3A96Cy0*%KR)gkOs<;-)F*L^>2K?9j`ejR6#zM~M1Cfvft297`+p ztP8NT59)M09sO4Q=?kx-ubQYEF64#wH=F)E;HQVf;E_2gZLb;?ey2@cYa3lE5EP!| zGV*xL%3zDI{eLYi8r+CkMH{@5Wd!Ad?Xf5B7suB1OYY_l5Whyl6+n=f%X`b*Y)HcuR_b^^I--P^Ax z18-IS*?^hGw6v_%^sh}v=jK9D&?LBzEvb%Vq>(-(FO<;V4mKiwlVy8&WYz!$KibK=t zc2+worw?weg9?uiID)KaQN)CzhFz85O&Pmht%}Dke_tZ1{{SM-VW}H#E}SMbil$*^beJAg=zbDMHKl#%{+@>nt;|s)SKY{K>d5{R2^&t=|EhWbINAOu zpzcoC_w_a(6y!E~>~97Ln1Vc6nt6u|XqKQOT3*UKJ1lirS0|q8W}Ia_&&-1ghu{Vy z6_=z?lrajeZ`?AseA^}=FiOylikz|AI|%ig#)D|0vriQMf2{!??c{Wl;Ya91P6SE# z>NxlyNOGsz?3sz85N4rve8Xs5WN0$sn6>BU;plkEv@*ntI$fDTmdXSq zU?-H_AoEzYDeqE+R;x7INWHxfB-G==;GB#LxN?x@HifAPkd!-rhG;tU$b$au*-*1x zi|A&RD0N(G?%E!aN2j}`Xr(U3jbnUzZfg%_@s2NBl(Hjp;KrhI52+9MbilXLJan{Q znbky&_{vjKBKElSLKcxwn5h>E2Skko74QhA>+yi5}(9 z=wF-{a1MyBSmu-B!fnF)^1E)HTg2_4uQuAi1?l=oZaiuQ=AreYj#}pc$q={u;$kgu4k6-B)%&Zsqsn zei2C73Pur^gAytFW`y+w)amTV(eMUWfEy+&p~0$AjqQIl%s|X#=*?}?) z3TJ_tv8G=7w;;So%{Vfhy{dk$AR<_9F!$P`FS$nfS0DIlK@VxS$G$cgg0Yz8V$FVR zVb-FZw0&MiU+%v!Tl|!ti%j;#U%Q*l1ajV7{AB_;2PucEF9>4WU-2EPE+(J@yBxh^ zj2W(u`}vvH!va;PL}$Z=;^=z|GA1?MY|!Ha$?}z68%L?9$8YEiD%x5?td(maFv%5tVjgR-P`dmIWw9F zbOPR5zZ%XX60Lu89R-R{dzA(}bzI|$$2bGqeOn|j>-L>ig?H4@+YeDraWm}xL(@09 z#VJHuczwsbQS@${q}J=^SKivtm)}mv2CH|&bG`3_;vSN`DSeuNTXWl#6mgz5yZUoG zk8zG}TFcuc%V2y;B@I0OYOdgxAx&;!{{Z?B-LRyV5yxO_(8MX}Ba{2?NM>iqY4_z7 z3;nUey@q}7^2cSAcn}M2bI8A4{hNVjLV5BJk>9OLSFD$u%3!k34b+?Ab1nZu)MtGL z+DQ*?eRg~2&z3K8PYQXFueG}ZYa=!eAI2u=!fgDyoGS}}70`a@F>$SL}B0=k4lWwk1V$Nc0@KhCc#_u6qmFQe|L-KlKWuLnFRRUza4~BaF72 zRMDF*Uv@M5=|efEbt3<#gC$QP44;C-`(kybH5Mzjn!7H|L@L&CT?em8;*zmOU;Wi} zX&J+rvhRVl!FSVsU+UT>vsS+}B(V~`9+bKcK&^0Qh#!jGH@6MJz8WRnfS+z6Y-3ee zM%t+95|>;W;@O1Pru|-~CCZ~tb*YcE#pRIPHw2-s<@2U;emJR{`$ZUHw9`Dv7GQh1 zZetbw(cF?S!r2mWxS=H>n?o?hWnzg_{m<}gbDve0(Lb{ZVt{K2fG&Fv$Bj75jK40;M`gV+GnEp=OQ2~jO z%OoG`QwAVA4Y&aKUf82S;uZ;#90$1PnrAmmc|3G-325Ue9ILydoEH7?{j3ra<<$jR z#X`O-7B{tdpq1p)8h}^Im0Zf7UHse)qn!bEh>Z=nU41=7w%2{}-x*Bpq{5STJJ1e; zZ^ryWz}z5B7scwzwj`2)eMWB$d^{mhHrn=+t#!QzFWi(Gy*5Gvy)ZWyKzfkGX{cG^ zhvjgTQu|Zp4$-4_7;LnLJej$wO}>Z6yBi;=a-;87yQHY_Um6^&iyO12dOnFwe)p~0 z)PE8+c_l(@$NGhnIsDKz4+aWP>qZK;2QS^TvDe6a@57-bo7Xe9XI`(H-UCj1e-A(+DC|Q0 zeRxm5yc6+W!me>!hfm^vo3T_7UFxXi(yb=^8-b-a3NWv;NYo83mg?E>BSuG#fgo(% z`QWz7{@SgnwVe=|%{qZ3b-lB6G$2pKRBe32giuUmOmDm-`%lQPFj^6|z`EhDdj}6S zi2jlcqJ~qZ&)>udxR_j@+YF>e3^AM5dpg(gUdUkv(dK)29umue#-g4n`=KmBqH;CB z*tUKJP5r~Q;L@udthvy=D!h+-*$s&txQMsuUX1CM5zN!r-1h&wz;>>trB8Uu%I(mV z7OVqPrp7tli%l^e6?5;0+6%^B+WKKB&kca1y*N-qsPWxI9Xt8Giyw>AqU<98s}lKM zGIyirL=>~}NRqf2b#+GgG4+GE4O!W`$f;{Bx;T!t9m^S4>@h4lKa(;Ui)ZZg<@MHl zM4d24Ia4!@gBD2o-zaGd++-NBNiAM|z*^X7fhirXSAhduKPL0^;*P|<*Yjr z`Wl6%u5z~ob^9GRto`qu9N`8d5jqZDiJdTZsBfBqts*AyNo%(8j33#SB`NL58jblP zR)2JW{DWCZC6>lS^w6u0Rl_Z@uUorrh{1* zI*G51LUY_D`+Xj_2l?AQ5C;Q5D8pSO%#5N%BWaI;#gr49U>j|lyx=@qD5wy)uBauQ zxm8k92IIA2ZM1?i0noa9dFsfT(ayLM=h$?Zw`Op@?vmr*O9VB^(;DO?X^Gr^Is&w; z^-8Wh!S~x%aG({lM}cEK#dq!Npu$~h0_H^%*a8ojT%3vA7{JB)UZ5k$KrHi2ajZ?h zd>54K8K1X*F(YVSC=>4+x=p|?>a(pHy{UBP8FchZk8^ecqwvl>wY@eIs&5(_YS(CL z$7JmLe=Zdw!Ug6*vLRiT{LQ2g2brIiEO3|EzV=N^5wZ6lLBi|3y_VI*Kfm}yD$B%s znmv(>KqyvNZ)xma3E>!#gixzXMV3qYf=$mQ0RkpGAsH8o-U{(ClF&~Y1=KQAxyKI5 z>3*Mvg7J;x>~fnuoD>o5#V9LD53B0n-W{vq`NF$&GvsMwdyOiul8xy8JfKmD?-+xT zSGwCzlkKxA`-Clb7Q0ixm#btSC1G3-n)knUzsY?qANZ+TKTWzU%t5N4>J#$GtjX2b z@qtg6DGNhomogE<>6bBjrkVhmI9F&FJ+5E`Z_UL>FU+g2SQ?alR`+<;Ep8G)NnSpHSL?c5nf6B4A0pBe5H%sGe z7-01;eO0xYWV9d*3R}#$&1G!|RiLd9F|g@D##P`zEr&OZbROHX0QkQ>T*sM)){;}CmnBVHT?<_%U-dZ%(9-BwfA?9AkC|NB ze}5`>L-*!(*8vLF>GF?ASxo;Pv;@p+?Xa~f|J)?Yhw}CSsY#BXkN{ho{NNmtLitVE zEuwF~GpB_RJ5l#cpm?x>WG-R4HhDHjSnZV0fL;Wh;5{Q14b8gEvTuzJ;J_@H=gcC_ zUR#vOW{>NgYe+iq`$nUZln_}E0*sa2P~V&A&#ALwN|=|}H!PJoQc!$!lNy}Ry}snN z)&IPb zR7jnu2F1<4gN+Z~d92(k&Qr_uv^3lcsL;B}x7&anhiTSEUv1fMay}6vLhCNM9yqV< z;6>TcR)zRrC)jxwN!dU&y8ca8AjCwqVgztWLKMF@6zljisp&q>!mc8%>0J$n^*3eG zPH|;XpC3wCJ)Y|+*D3GQ2YcC#N21taLHJ4O|HVLjS??jpe?=s0b;w#%(XCL=?s5kf_O^8HKk0-{}Gi=kUpjyEI(h){p*TFi26K z9UbNJ21<2In_X_56ha0*Hk~FGIVM909GWG!gBc=k zkeWb?%9@$k3qZb^xZiIwPK76_0#lGwtAXEyXT zF~!WAvKrE6@0ovVsQ_(6=(n}H?l!jfSxwvd5Qny94U>l@QlC^L4qWV?A;=@ZB>i;i z!sgqI6iXFxO?eedf0=U$$>V#5W2kn7yZanS;S3{B2fA?rb9&o=kY;GFk4x2M3uGcY zlHNP&{SBc%hzeUZ$VROpSiSEtfG_XqV(s$ zcWTg}9P6bPA6X~|LOmnh5dzj8r;lkWDN7uSx6QSc-x6;AFYZK3(@q5n6JD8I8@YB& zqJhE2U%zX(q=kz?7}ueEVUZ>)ZK2My;*MSnE)&QuRt0I8u7AE*$LZ_OOM_U`^u`zI z@F#_(f?ory+WYM$$zjWt)g|e1NwLI8bF|Ge#;}u=220*j`sJr@yRudZ18qkcUs9n? z>L?}MQ=wZwpTscxAx4>7m>s?i3aeN|;Pqtf{x_2}@th@gl0Z-16T?@oW}t2JI=>DP zE39oZ0!{zA++N=r;3GXSz5fc^G|b&#U1eBfoJ>{nUB~{~Qk4`YJqB9}@loxZ8D! zYU4w&b&vcJ`@^@4^go!^{r3oboHF!45B;j8>LD8+0tYm;Il9seG<#lpr(BLW)^F7CK zU+#;^kP&;>yKX=8_+AY95^HSaDS{GB{x);yv3FPVU!NJ0A>xV`W!t(o%6TQ17ys48 z7jj=Odynz2nVpY%-SbtNDaR3TqVjcFrJO45!4Ixh5ot+@wCh=*PHo1>} zU)bRfSjxvY5|XtWh?LE6;ICX*Zej{x)g}ZqZB_B&I(4BlU&uab|63e9m|6w-mFBH9 zpgdC*NdUL(*y?`2B#~)ON?*rsxA|)$J^|o^;e{a?x~@t2iVZ(*MML!u<#$bReApq! zl_!^gxotUZIPf;cqy)15k4OwJP%m%(dMqqX0CI#KOKF_la_!-Ca#E>%VRGQeEWvK~ zhs1c;SHkLU$JxqDDf~Rko$u}i075{j{(uvLtdgJJoa~Q$DeM$p8)wK+3Zb%+^ZvL` z&0--dQQZ<{w%@n)e%i4xN=UyIo^dsj$0$;OSC-CKD7tSno*<`IbHZaa>F5ryfQT?JO z9kN9Raw5;iedzf1q|X?$*q-=8c+2O}%t6iwdq^gNNmWJ~Z~OLOj2{Oe-chN6Xv^0H zBY=pePY9nnppiid%QunSM!4rHmDeOO})^Z*a!$j0s6 zOCP{!MoqY`xuT3~&jmq`7vBrrmdDO0c5eqX#OPM5>@-RHOiy1SZOg(+AVbeh_M204 z(6J#~l(1UM>|6jrzDRViX&F@IP@@fW7LFD*%Gdw>kvliO*`|CKf*GE$3Ik2x-Rrb{ zXspWNmPEMXf?Qn0vy3Q?i?TLhXA&!sv^p(6=B5V0C{cy5=&M50Ufj_2hZtI;NM7@? z?i}Pz70BLjqurJ~u0puO@AQ$lg`i}r0cG8&zU_4|z0LCa+m5ISzA+gQIr;mN=}(2u zGu(ppTj{@_$?J>%^x{p+4zDRkbXGPak)2x8R=oDbI)Svl1tJFF#bXZhQ^yp-cmOR> zd?L|Zm*mU5=wo>8ZU0S5WM99SJI>R40p{$e4B}KDa~eiCKq7x?o03wO{K3$d6t&Nu zUp;wamk17*fMvaVb*tnm>YfV3OY6R_-;vQ>a0EKC`2nU6tg74Bo|-v1Xa1r58=w<$_f(cxeVOky=d)u^hEj3jm1Wx`uXp$GJRA6>^Ikk_=MK(z zcIn`angGx3{al>KaJuK7UprD%Ea%+edNDu*-TQwG^;6wFJN!=toj`MUub8$sQwBZ7 z9`yfz>cymXf!wMAq8@Rz3Jf&?j4v+!lSx42UcYDJTi&1NhB8d|nWLk*A>JLEjD*Nw zV{qj_T$_x{Je<7UU&-pm;fxZFHEj8k1k=FvAQmK;iWYTr=zHVp3r=DiGu8DaSp)3? zDvZ5Q=5eqH$a(bKEXjzNOB*oAWA`R7p848_d~$VWmAV7Xg@8N>7VeGjJ$b|aWtp#3 z40ykXB558OT=pBb-0<^IVcyXi`HLDlvfSI1qc}E_F>$H+)}$cP8~F=5#5k119#1J zV3Mn9Yha`k@5%!KrX-d}$}A~LX8UR_eYX877#d?v3hzI!pfYUK>ApyA(K zTy<>3-O9{4yNNQX5tS(xw1$y|G6&fn$$Lr*?&AodR6_1mqICY^byJGI27xtjTrT4v z{Bmd-aBo)C$dhnk_}QJVzdj%g7p{FrLq47tzip%ZT^fHla=<(#9OVFYN%pP!Eb(h! zK)u=GBYtMCWaI-(?D3IBmGYpR({N@4&^LfybMPj|AKFv>k^D}V9)B@eB&o`sF$May zI{JFZ^m_vLL9v=$+8}7(r=-BauQYqJxKl0JVk6cZ#OlOgUzsBff=R{Vl)d|k_mr-5 zUoBF1Y!u{zcxi$V)#V1Hd=Hkqqe3?y*cXvG=C9l42%trwMzs1?b&R;9!lG#3(76;z za6q<}QDV>iwFUdII@EED(4oi27td9A=&%3$@x`?_K06@?2}B%a3em3HBcBjs>br-f zE^O@355#4~LE%WoEoyMIV~-&Zs_*YcD7=YBScJ2OE-DefPkSkaBkO%G7Tx$UYLc=H-r+%b15ckWN;{q0=mG#62Bv z88`KtGE4$1-ETiST*wGZ{-Vv9)~xBPssmD2F2W2Pm9PfeXVux0V>!>~6de$3$n!Ig zX)=Y!-=%u!4vDmHU7AIyI&P8`FI7p|3j0G(U)y&aASQ#OeTs#qBxsO%(eQL#aV4&TU>rL|Cs! zw(kO$_y_}%OVmJPj2nFFBwn4|Npl->zBBN;Z%pqJXSsm-VPw-0zFW!CP{4Wk@M;+O zSGXTULxFDwPRS?DzGyRxn=)w-;$R$jWZV4GA3s^!*=sfYHYt+f34>=VB&CPcObAHvD!$icBB;{>4@{n(a@l0^4q#I!ok=aB9ek&kJw;Oqxi3-NC_9GmCk0 z&xkX2&MmeDw>aS3iWJB{uqzJ>9D~LIQ*iv}(T!eb{Ir+ak39F!IJ8CFEaP9h1od@y z-4H9Y=0@{uAJE#3!-SZqv0R7dk@#5C(?iUA2Ti8D7l|^f6I7ZU)qi^k=1=5bn>=aZ z+v|$7n8LREtkao-lJ=;jxKVUia3$YDm!W=#V~LzsdX)Ktk4RzceicJIZ3JXU&(bo} z?-$q|{ zRj}Tw%gb{?Q>#LbmaPe0621%gmwdlgzD(>ugH|GPzZh;J(d4~Eu@s2XOjr7zY0tnu zKJ1}|pi3=bd)Fl9{JDG+|JY>5pHF8!8`g0fEsJ*4&@Zw^A zB2|;!wx;9CC|I-A`9Ce8dqZSoQJCRSjUM`WpY;c$(iTOev+>Dkyz-7ahpiXj`qPAd zIV6Gmk0P=zqbD27(;~IQu=(LJID?Wu)SvXZ(vXgW#k@MQBBP+)aE}4B20{Mv;{6Um zZo?q|>S857m(Z2hLk3ES#N0}CRhDd*_WKSScf-Ag_9)b-kkH41AEl7zbn9;ErK}>B zH+eRRPw5K}5294)3uK8NE)=6b+mkNx!z}IAg;lj^R*6cM)YEfGHJ+1r!kw}6PzB$M zMBy-d_iZx&-y(pYY8p-#IIh9f|EwQq*ZSh_K4GzKXFs$&lTAyjXp4|H$Y7f zF`7)lSz>lA5^yrWr^4u(c+&RaIZ5eJsxiOamdTZ?65GGt<>|aY&kG{9!mIjj_%(}E zH^qVmo$h9}EpR!iC=KY?PNJ^4JZ&L3U`uG?h2t_hK@TfEvfD8h^W1+IJYREqlaaCr z|7NS9}~46k$a=1=5bWk^C+*Bahcyfa<-EHrYzUAFy)iWgI)l&&OX zzBsicXIkf1!+SoaVwyDrbbV?r_L@so$xY+gTF*F1-<-c{UYm$CqP9Ia8d)j2u~Bi z;7CrxSHVAXc5%zLG7jkx z;V(;F=b9HUrWLgq$$SX^R2pCzZ02iLNN8HXopzG$n&RGc=)s?0yKq zQIcfoGStTspdUGJ{vNeUH`Z9s`0v)RkOMt?9?8XHI3sbnqi_7hnBV7z7a2S%)Z)T! zs4#(3WRuYG#zT-v{p-C!tTi^+u-l8|h*}py(#lYA{f?XkE8BN}h0%xE{=_q*i8=nZ zZoF@#Ui{1u$)DAaOu|@9uamhM)uJf;I9%l(8_Hhzn8V$*s+S~ zuxqlvG2F97nj|t`Sjv? zk|1|$L6e!{?n%0D^8wn^3`o&_(v?;unM7j0sU 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

_a4uAVdr;YOsZ~H&VBC-HZm}f? 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

!^*k1TC^W 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

L|~TV*+UYKEkO{(a9%0PF_5e-VT#P{ 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𝔐6fax3=gxX!Wl9sbw|P|jwC+$ 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