diff -Nru libfsapfs-20181215/AUTHORS libfsapfs-20190210/AUTHORS --- libfsapfs-20181215/AUTHORS 2018-12-03 17:49:10.000000000 +0000 +++ libfsapfs-20190210/AUTHORS 2019-02-06 20:10:13.000000000 +0000 @@ -1,4 +1,4 @@ Acknowledgements: libfsapfs -Copyright (C) 2018, Joachim Metz +Copyright (C) 2018-2019, Joachim Metz diff -Nru libfsapfs-20181215/ChangeLog libfsapfs-20190210/ChangeLog --- libfsapfs-20181215/ChangeLog 2018-12-14 10:57:41.000000000 +0000 +++ libfsapfs-20190210/ChangeLog 2019-01-13 18:18:14.000000000 +0000 @@ -1,6 +1,6 @@ TODO * B-tree -** Validate (expected) btree level to detect loops +** Validate (expected) btree level to detect loops - added maximum recursion depth for now * Validate checksum ** B-tree node ** Container key bag @@ -63,6 +63,7 @@ ** add volume selection support ** add extended attributes support ** does fuse override file types such as socket? +** dokan add symbolic link support Tests: * add tests for container_key_bag diff -Nru libfsapfs-20181215/common/byte_stream.h libfsapfs-20190210/common/byte_stream.h --- libfsapfs-20181215/common/byte_stream.h 2018-12-03 17:49:10.000000000 +0000 +++ libfsapfs-20190210/common/byte_stream.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Byte stream functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/common.h libfsapfs-20190210/common/common.h --- libfsapfs-20181215/common/common.h 2018-12-03 17:49:10.000000000 +0000 +++ libfsapfs-20190210/common/common.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Common include file * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/config_borlandc.h libfsapfs-20190210/common/config_borlandc.h --- libfsapfs-20181215/common/config_borlandc.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/config_borlandc.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Configuration for the Borland/CodeGear C++ Builder compiler * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/config.h libfsapfs-20190210/common/config.h --- libfsapfs-20181215/common/config.h 2018-12-15 06:44:19.000000000 +0000 +++ libfsapfs-20190210/common/config.h 2019-02-10 19:53:09.000000000 +0000 @@ -5,6 +5,12 @@ language is requested. */ #define ENABLE_NLS 1 +/* Define to 1 if you have the `AES_cbc_encrypt' function". */ +/* #undef HAVE_AES_CBC_ENCRYPT */ + +/* Define to 1 if you have the `AES_ecb_encrypt' function". */ +/* #undef HAVE_AES_ECB_ENCRYPT */ + /* Define to 1 if you have the `bindtextdomain' function. */ #define HAVE_BINDTEXTDOMAIN 1 @@ -58,6 +64,18 @@ /* Define to 1 if you have the `EVP_CIPHER_CTX_init' function". */ /* #undef HAVE_EVP_CIPHER_CTX_INIT */ +/* Define to 1 if you have the `EVP_aes_128_cbc', `EVP_aes_192_cbc' and + `EVP_aes_256_cbc' functions". */ +#define HAVE_EVP_CRYPTO_AES_CBC 1 + +/* Define to 1 if you have the `EVP_aes_128_ecb', `EVP_aes_192_ecb' and + `EVP_aes_256_ecb' functions". */ +#define HAVE_EVP_CRYPTO_AES_ECB 1 + +/* Define to 1 if you have the `EVP_aes_128_xts' and `EVP_aes_256_xts' + functions". */ +#define HAVE_EVP_CRYPTO_AES_XTS 1 + /* Define to 1 if you have the `EVP_md5' function". */ #define HAVE_EVP_MD5 1 @@ -142,7 +160,7 @@ /* Define if the GNU gettext() function is already present or preinstalled. */ #define HAVE_GETTEXT 1 -/* Define to 1 if dlsym funtion is available in GNU dl. */ +/* Define to 1 if dlsym function is available in GNU dl. */ #define HAVE_GNU_DL_DLSYM 1 /* Define if you have the iconv() function and it works. */ @@ -614,7 +632,7 @@ #define PACKAGE_NAME "libfsapfs" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "libfsapfs 20181215" +#define PACKAGE_STRING "libfsapfs 20190210" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "libfsapfs" @@ -623,7 +641,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "20181215" +#define PACKAGE_VERSION "20190210" /* The size of `int', as computed by sizeof. */ #define SIZEOF_INT 4 @@ -653,7 +671,7 @@ /* #undef TM_IN_SYS_TIME */ /* Version number of package */ -#define VERSION "20181215" +#define VERSION "20190210" /* Enable large inode numbers on Mac OS X 10.5. */ #ifndef _DARWIN_USE_64_BIT_INODE diff -Nru libfsapfs-20181215/common/config.h.in libfsapfs-20190210/common/config.h.in --- libfsapfs-20181215/common/config.h.in 2018-12-15 06:44:00.000000000 +0000 +++ libfsapfs-20190210/common/config.h.in 2019-02-10 19:59:39.000000000 +0000 @@ -4,6 +4,12 @@ language is requested. */ #undef ENABLE_NLS +/* Define to 1 if you have the `AES_cbc_encrypt' function". */ +#undef HAVE_AES_CBC_ENCRYPT + +/* Define to 1 if you have the `AES_ecb_encrypt' function". */ +#undef HAVE_AES_ECB_ENCRYPT + /* Define to 1 if you have the `bindtextdomain' function. */ #undef HAVE_BINDTEXTDOMAIN @@ -57,6 +63,18 @@ /* Define to 1 if you have the `EVP_CIPHER_CTX_init' function". */ #undef HAVE_EVP_CIPHER_CTX_INIT +/* Define to 1 if you have the `EVP_aes_128_cbc', `EVP_aes_192_cbc' and + `EVP_aes_256_cbc' functions". */ +#undef HAVE_EVP_CRYPTO_AES_CBC + +/* Define to 1 if you have the `EVP_aes_128_ecb', `EVP_aes_192_ecb' and + `EVP_aes_256_ecb' functions". */ +#undef HAVE_EVP_CRYPTO_AES_ECB + +/* Define to 1 if you have the `EVP_aes_128_xts' and `EVP_aes_256_xts' + functions". */ +#undef HAVE_EVP_CRYPTO_AES_XTS + /* Define to 1 if you have the `EVP_md5' function". */ #undef HAVE_EVP_MD5 @@ -141,7 +159,7 @@ /* Define if the GNU gettext() function is already present or preinstalled. */ #undef HAVE_GETTEXT -/* Define to 1 if dlsym funtion is available in GNU dl. */ +/* Define to 1 if dlsym function is available in GNU dl. */ #undef HAVE_GNU_DL_DLSYM /* Define if you have the iconv() function and it works. */ diff -Nru libfsapfs-20181215/common/config_msc.h libfsapfs-20190210/common/config_msc.h --- libfsapfs-20181215/common/config_msc.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/config_msc.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Configuration for the Microsoft Visual Studio C++ compiler * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/config_winapi.h libfsapfs-20190210/common/config_winapi.h --- libfsapfs-20181215/common/config_winapi.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/config_winapi.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Configuration file for WINAPI * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/file_stream.h libfsapfs-20190210/common/file_stream.h --- libfsapfs-20181215/common/file_stream.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/file_stream.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * FILE stream functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/memory.h libfsapfs-20190210/common/memory.h --- libfsapfs-20181215/common/memory.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/memory.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Memory functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/narrow_string.h libfsapfs-20190210/common/narrow_string.h --- libfsapfs-20181215/common/narrow_string.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/narrow_string.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Narrow character string functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/system_string.h libfsapfs-20190210/common/system_string.h --- libfsapfs-20181215/common/system_string.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/system_string.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * System character string functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/types.h libfsapfs-20190210/common/types.h --- libfsapfs-20181215/common/types.h 2018-12-15 06:44:19.000000000 +0000 +++ libfsapfs-20190210/common/types.h 2019-02-10 19:59:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Type and type-support defintions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/types.h.in libfsapfs-20190210/common/types.h.in --- libfsapfs-20181215/common/types.h.in 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/types.h.in 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Type and type-support defintions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/common/wide_string.h libfsapfs-20190210/common/wide_string.h --- libfsapfs-20181215/common/wide_string.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/common/wide_string.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Wide character string functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/configure libfsapfs-20190210/configure --- libfsapfs-20181215/configure 2018-12-15 06:43:58.000000000 +0000 +++ libfsapfs-20190210/configure 2019-02-10 19:59:37.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for libfsapfs 20181215. +# Generated by GNU Autoconf 2.69 for libfsapfs 20190210. # # Report bugs to . # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='libfsapfs' PACKAGE_TARNAME='libfsapfs' -PACKAGE_VERSION='20181215' -PACKAGE_STRING='libfsapfs 20181215' +PACKAGE_VERSION='20190210' +PACKAGE_STRING='libfsapfs 20190210' PACKAGE_BUGREPORT='joachim.metz@gmail.com' PACKAGE_URL='' @@ -1689,7 +1689,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libfsapfs 20181215 to adapt to many kinds of systems. +\`configure' configures libfsapfs 20190210 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1759,7 +1759,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libfsapfs 20181215:";; + short | recursive ) echo "Configuration of libfsapfs 20190210:";; esac cat <<\_ACEOF @@ -2042,7 +2042,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libfsapfs configure 20181215 +libfsapfs configure 20190210 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2694,7 +2694,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libfsapfs $as_me 20181215, which was +It was created by libfsapfs $as_me 20190210, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3561,7 +3561,7 @@ # Define the identity of the package. PACKAGE='libfsapfs' - VERSION='20181215' + VERSION='20190210' cat >>confdefs.h <<_ACEOF @@ -20329,12 +20329,12 @@ pkg_cv_libcdata_CFLAGS="$libcdata_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcdata >= 20160108\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libcdata >= 20160108") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcdata >= 20190112\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libcdata >= 20190112") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_libcdata_CFLAGS=`$PKG_CONFIG --cflags "libcdata >= 20160108" 2>/dev/null` + pkg_cv_libcdata_CFLAGS=`$PKG_CONFIG --cflags "libcdata >= 20190112" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -20346,12 +20346,12 @@ pkg_cv_libcdata_LIBS="$libcdata_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ - { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcdata >= 20160108\""; } >&5 - ($PKG_CONFIG --exists --print-errors "libcdata >= 20160108") 2>&5 + { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libcdata >= 20190112\""; } >&5 + ($PKG_CONFIG --exists --print-errors "libcdata >= 20190112") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - pkg_cv_libcdata_LIBS=`$PKG_CONFIG --libs "libcdata >= 20160108" 2>/dev/null` + pkg_cv_libcdata_LIBS=`$PKG_CONFIG --libs "libcdata >= 20190112" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes @@ -20372,9 +20372,9 @@ _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - libcdata_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcdata >= 20160108" 2>&1` + libcdata_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libcdata >= 20190112" 2>&1` else - libcdata_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcdata >= 20160108" 2>&1` + libcdata_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libcdata >= 20190112" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$libcdata_PKG_ERRORS" >&5 @@ -45568,13 +45568,6 @@ if test "x$ac_cv_libhmac" != xyes; then : - ac_cv_libhmac_md5=no - ac_cv_libhmac_sha1=no - ac_cv_libhmac_sha224=no - ac_cv_libhmac_sha256=no - ac_cv_libhmac_sha512=no - - if test "x$ac_cv_libhmac_md5" = xno && test "x$ac_cv_libhmac_sha1" = xno && test "x$ac_cv_libhmac_sha224" = xno && test "x$ac_cv_libhmac_sha256" = xno && test "x$ac_cv_libhmac_sha512" = xno; then : # Check whether --with-openssl was given. @@ -45910,7 +45903,7 @@ fi - if test "x$ac_cv_libcrypto" != xno; then : + if test "x$ac_cv_libcrypto" != xno; then : ac_cv_libcrypto_md5=no if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_libcrypto_evp_md" != xyes; then : @@ -46492,7 +46485,7 @@ fi - ac_cv_libcrypto_sha1=no + ac_cv_libcrypto_sha1=no if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_md" != xno && test "x$ac_cv_libcrypto_evp_md" != xyes; then : ac_cv_libcrypto_evp_md=yes @@ -47073,7 +47066,7 @@ fi - ac_cv_libcrypto_sha224=no + ac_cv_libcrypto_sha224=no if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_md" != xno && test "x$ac_cv_libcrypto_evp_md" != xyes; then : ac_cv_libcrypto_evp_md=yes @@ -47654,7 +47647,7 @@ fi - ac_cv_libcrypto_sha256=no + ac_cv_libcrypto_sha256=no if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_md" != xno && test "x$ac_cv_libcrypto_evp_md" != xyes; then : ac_cv_libcrypto_evp_md=yes @@ -48235,7 +48228,7 @@ fi - ac_cv_libcrypto_sha512=no + ac_cv_libcrypto_sha512=no if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_md" != xno && test "x$ac_cv_libcrypto_evp_md" != xyes; then : ac_cv_libcrypto_evp_md=yes @@ -48816,35 +48809,36 @@ fi - - ac_cv_libhmac_md5=$ac_cv_libcrypto_md5 - ac_cv_libhmac_sha1=$ac_cv_libcrypto_sha1 - ac_cv_libhmac_sha224=$ac_cv_libcrypto_sha224 - ac_cv_libhmac_sha256=$ac_cv_libcrypto_sha256 - ac_cv_libhmac_sha512=$ac_cv_libcrypto_sha512 - -fi - fi - if test "x$ac_cv_libhmac_md5" = xno; then : + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_md5" = xno; then : ac_cv_libhmac_md5=local +else + ac_cv_libhmac_md5=$ac_cv_libcrypto_md5 fi - if test "x$ac_cv_libhmac_sha1" = xno; then : + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha1" = xno; then : ac_cv_libhmac_sha1=local +else + ac_cv_libhmac_sha1=$ac_cv_libcrypto_sha1 fi - if test "x$ac_cv_libhmac_sha224" = xno; then : + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha224" = xno; then : ac_cv_libhmac_sha224=local +else + ac_cv_libhmac_sha224=$ac_cv_libcrypto_sha224 fi - if test "x$ac_cv_libhmac_sha256" = xno; then : + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha256" = xno; then : ac_cv_libhmac_sha256=local +else + ac_cv_libhmac_sha256=$ac_cv_libcrypto_sha256 fi - if test "x$ac_cv_libhmac_sha512" = xno; then : + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha512" = xno; then : ac_cv_libhmac_sha512=local +else + ac_cv_libhmac_sha512=$ac_cv_libcrypto_sha512 fi ac_cv_libhmac_CPPFLAGS="-I../libhmac"; @@ -49534,13 +49528,6 @@ if test "x$ac_cv_libcaes" != xyes; then : - ac_cv_libcaes_aes=no - - if test "x$ac_cv_enable_winapi" = xyes; then : - ac_cv_libcaes_aes=libadvapi32 -fi - - if test "x$ac_cv_libcaes_aes" = xno; then : # Check whether --with-openssl was given. @@ -49876,9 +49863,7 @@ fi - if test "x$ac_cv_libcrypto" != xno; then : - ac_cv_libcrypto_aes=no - + if test "x$ac_cv_libcrypto" != xno; then : if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_cipher" != xno && test "x$ac_cv_libcrypto_evp_cipher" != xyes; then : ac_cv_libcrypto_evp_cipher=yes @@ -50292,34 +50277,199 @@ fi +fi - if test "x$ac_cv_libcrypto_evp_cipher" = xyes; then : - ac_cv_libcrypto_aes=libcrypto_evp + if test "x$ac_cv_libcrypto_evp_cipher" != xyes; then : + ac_cv_libcrypto_aes_cbc=no +else + ac_cv_libcrypto_aes_cbc=libcrypto_evp + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_128_cbc in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_128_cbc in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_128_cbc+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_128_cbc (); +int +main () +{ +return EVP_aes_128_cbc (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_128_cbc=yes +else + ac_cv_lib_crypto_EVP_aes_128_cbc=no fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_128_cbc" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_128_cbc" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_128_cbc" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_cbc=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_192_cbc in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_192_cbc in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_192_cbc+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_192_cbc (); +int +main () +{ +return EVP_aes_192_cbc (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_192_cbc=yes +else + ac_cv_lib_crypto_EVP_aes_192_cbc=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_192_cbc" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_192_cbc" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_192_cbc" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_cbc=no fi - if test "x$ac_cv_libcrypto_aes" = xno; then : - for ac_header in openssl/aes.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "openssl/aes.h" "ac_cv_header_openssl_aes_h" "$ac_includes_default" -if test "x$ac_cv_header_openssl_aes_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_OPENSSL_AES_H 1 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_256_cbc in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_256_cbc in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_256_cbc+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_256_cbc (); +int +main () +{ +return EVP_aes_256_cbc (); + ; + return 0; +} _ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_256_cbc=yes +else + ac_cv_lib_crypto_EVP_aes_256_cbc=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_256_cbc" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_256_cbc" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_256_cbc" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_cbc=no +fi + + + if test "x$ac_cv_lib_crypto_EVP_aes_128_cbc" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_192_cbc" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_256_cbc" = xyes; then : + +$as_echo "#define HAVE_EVP_CRYPTO_AES_CBC 1" >>confdefs.h + fi -done +fi + if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_cipher" != xno && test "x$ac_cv_libcrypto_evp_cipher" != xyes; then : + ac_cv_libcrypto_evp_cipher=yes - if test "x$ac_cv_header_openssl_aes_h" = xno; then : - ac_cv_libcrypto_aes=no + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_new in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_new in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_new+:} false; then : + $as_echo_n "(cached) " >&6 else - ac_cv_libcrypto_aes=libcrypto - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_128_ecb in -lcrypto" >&5 -$as_echo_n "checking for EVP_aes_128_ecb in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_EVP_aes_128_ecb+:} false; then : + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_new (); +int +main () +{ +return EVP_CIPHER_CTX_new (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_dummy=no +fi + + + if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_free in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_free in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_free+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -50333,35 +50483,37 @@ #ifdef __cplusplus extern "C" #endif -char EVP_aes_128_ecb (); +char EVP_CIPHER_CTX_free (); int main () { -return EVP_aes_128_ecb (); +return EVP_CIPHER_CTX_free (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_EVP_aes_128_ecb=yes + ac_cv_lib_crypto_EVP_CIPHER_CTX_free=yes else - ac_cv_lib_crypto_EVP_aes_128_ecb=no + ac_cv_lib_crypto_EVP_CIPHER_CTX_free=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_128_ecb" >&5 -$as_echo "$ac_cv_lib_crypto_EVP_aes_128_ecb" >&6; } -if test "x$ac_cv_lib_crypto_EVP_aes_128_ecb" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_free" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_free" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_free" = xyes; then : ac_cv_libcrypto_dummy=yes else - ac_cv_libcrypto_aes=no + ac_cv_libcrypto_evp_cipher=no fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_192_ecb in -lcrypto" >&5 -$as_echo_n "checking for EVP_aes_192_ecb in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_EVP_aes_192_ecb+:} false; then : + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_init in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_init in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_init+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -50375,35 +50527,35 @@ #ifdef __cplusplus extern "C" #endif -char EVP_aes_192_ecb (); +char EVP_CIPHER_CTX_init (); int main () { -return EVP_aes_192_ecb (); +return EVP_CIPHER_CTX_init (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_EVP_aes_192_ecb=yes + ac_cv_lib_crypto_EVP_CIPHER_CTX_init=yes else - ac_cv_lib_crypto_EVP_aes_192_ecb=no + ac_cv_lib_crypto_EVP_CIPHER_CTX_init=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_192_ecb" >&5 -$as_echo "$ac_cv_lib_crypto_EVP_aes_192_ecb" >&6; } -if test "x$ac_cv_lib_crypto_EVP_aes_192_ecb" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_init" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_init" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_init" = xyes; then : ac_cv_libcrypto_dummy=yes else - ac_cv_libcrypto_aes=no + ac_cv_libcrypto_evp_cipher=no fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_256_ecb in -lcrypto" >&5 -$as_echo_n "checking for EVP_aes_256_ecb in -lcrypto... " >&6; } -if ${ac_cv_lib_crypto_EVP_aes_256_ecb+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_cleanup in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_cleanup in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS @@ -50417,49 +50569,1177 @@ #ifdef __cplusplus extern "C" #endif -char EVP_aes_256_ecb (); +char EVP_CIPHER_CTX_cleanup (); int main () { -return EVP_aes_256_ecb (); +return EVP_CIPHER_CTX_cleanup (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_crypto_EVP_aes_256_ecb=yes + ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup=yes else - ac_cv_lib_crypto_EVP_aes_256_ecb=no + ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_256_ecb" >&5 -$as_echo "$ac_cv_lib_crypto_EVP_aes_256_ecb" >&6; } -if test "x$ac_cv_lib_crypto_EVP_aes_256_ecb" = xyes; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" = xyes; then : ac_cv_libcrypto_dummy=yes else - ac_cv_libcrypto_aes=no + ac_cv_libcrypto_evp_cipher=no +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ERR_remove_thread_state in -lcrypto" >&5 +$as_echo_n "checking for ERR_remove_thread_state in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_ERR_remove_thread_state+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ERR_remove_thread_state (); +int +main () +{ +return ERR_remove_thread_state (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_ERR_remove_thread_state=yes +else + ac_cv_lib_crypto_ERR_remove_thread_state=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_ERR_remove_thread_state" >&5 +$as_echo "$ac_cv_lib_crypto_ERR_remove_thread_state" >&6; } +if test "x$ac_cv_lib_crypto_ERR_remove_thread_state" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no fi fi - if test "x$ac_cv_libcrypto" = xno && test "x$ac_cv_libcrypto_aes" = xlibcrypto; then : - ac_cv_libcrypto=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_set_padding in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_set_padding in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_set_padding (); +int +main () +{ +return EVP_CIPHER_CTX_set_padding (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CipherInit_ex in -lcrypto" >&5 +$as_echo_n "checking for EVP_CipherInit_ex in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CipherInit_ex+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CipherInit_ex (); +int +main () +{ +return EVP_CipherInit_ex (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CipherInit_ex=yes +else + ac_cv_lib_crypto_EVP_CipherInit_ex=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CipherInit_ex" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CipherInit_ex" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CipherInit_ex" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CipherUpdate in -lcrypto" >&5 +$as_echo_n "checking for EVP_CipherUpdate in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CipherUpdate+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CipherUpdate (); +int +main () +{ +return EVP_CipherUpdate (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CipherUpdate=yes +else + ac_cv_lib_crypto_EVP_CipherUpdate=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CipherUpdate" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CipherUpdate" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CipherUpdate" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CipherFinal_ex in -lcrypto" >&5 +$as_echo_n "checking for EVP_CipherFinal_ex in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CipherFinal_ex+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CipherFinal_ex (); +int +main () +{ +return EVP_CipherFinal_ex (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CipherFinal_ex=yes +else + ac_cv_lib_crypto_EVP_CipherFinal_ex=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CipherFinal_ex" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CipherFinal_ex" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CipherFinal_ex" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + + if test "x$ac_cv_enable_openssl_evp_cipher" = xyes && "x$ac_cv_libcrypto_evp_cipher" = xno; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 1 "Missing OpenSSL EVP CIPHER support +See \`config.log' for more details" "$LINENO" 5; } + fi + if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_init" = xyes; then : + +$as_echo "#define HAVE_EVP_CIPHER_CTX_INIT 1" >>confdefs.h + + fi + if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" = xyes; then : + +$as_echo "#define HAVE_EVP_CIPHER_CTX_CLEANUP 1" >>confdefs.h + + +fi - ac_cv_libcaes_aes=$ac_cv_libcrypto_aes fi + if test "x$ac_cv_libcrypto_evp_cipher" != xyes; then : + ac_cv_libcrypto_aes_ecb=no +else + ac_cv_libcrypto_aes_ecb=libcrypto_evp + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_128_ecb in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_128_ecb in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_128_ecb+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_128_ecb (); +int +main () +{ +return EVP_aes_128_ecb (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_128_ecb=yes +else + ac_cv_lib_crypto_EVP_aes_128_ecb=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_128_ecb" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_128_ecb" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_128_ecb" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_ecb=no fi - if test "x$ac_cv_libcaes_aes" = xno; then : - ac_cv_libcaes_aes=local + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_192_ecb in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_192_ecb in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_192_ecb+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_192_ecb (); +int +main () +{ +return EVP_aes_192_ecb (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_192_ecb=yes +else + ac_cv_lib_crypto_EVP_aes_192_ecb=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_192_ecb" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_192_ecb" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_192_ecb" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_ecb=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_256_ecb in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_256_ecb in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_256_ecb+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_256_ecb (); +int +main () +{ +return EVP_aes_256_ecb (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_256_ecb=yes +else + ac_cv_lib_crypto_EVP_aes_256_ecb=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_256_ecb" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_256_ecb" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_256_ecb" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_ecb=no +fi + + + if test "x$ac_cv_lib_crypto_EVP_aes_128_ecb" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_192_ecb" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_256_ecb" = xyes; then : + +$as_echo "#define HAVE_EVP_CRYPTO_AES_ECB 1" >>confdefs.h + + +fi + +fi + + + if test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno; then : + ac_cv_libcrypto_aes=no +else + ac_cv_libcrypto_aes=libcrypto_evp +fi + + if test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno; then : + for ac_header in openssl/aes.h +do : + ac_fn_c_check_header_mongrel "$LINENO" "openssl/aes.h" "ac_cv_header_openssl_aes_h" "$ac_includes_default" +if test "x$ac_cv_header_openssl_aes_h" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_OPENSSL_AES_H 1 +_ACEOF + +fi + +done + + + if test "x$ac_cv_header_openssl_aes_h" = xno; then : + ac_cv_libcrypto_aes_cbc=no + ac_cv_libcrypto_aes_ecb=no +else + ac_cv_libcrypto_aes_cbc=libcrypto + ac_cv_libcrypto_aes_ecb=libcrypto + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AES_set_decrypt_key in -lcrypto" >&5 +$as_echo_n "checking for AES_set_decrypt_key in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_AES_set_decrypt_key+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char AES_set_decrypt_key (); +int +main () +{ +return AES_set_decrypt_key (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_AES_set_decrypt_key=yes +else + ac_cv_lib_crypto_AES_set_decrypt_key=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_AES_set_decrypt_key" >&5 +$as_echo "$ac_cv_lib_crypto_AES_set_decrypt_key" >&6; } +if test "x$ac_cv_lib_crypto_AES_set_decrypt_key" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_cbc=no, + ac_cv_libcrypto_aes_ecb=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AES_set_encrypt_key in -lcrypto" >&5 +$as_echo_n "checking for AES_set_encrypt_key in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_AES_set_encrypt_key+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char AES_set_encrypt_key (); +int +main () +{ +return AES_set_encrypt_key (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_AES_set_encrypt_key=yes +else + ac_cv_lib_crypto_AES_set_encrypt_key=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_AES_set_encrypt_key" >&5 +$as_echo "$ac_cv_lib_crypto_AES_set_encrypt_key" >&6; } +if test "x$ac_cv_lib_crypto_AES_set_encrypt_key" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_cbc=no, + ac_cv_libcrypto_aes_ecb=no +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AES_cbc_encrypt in -lcrypto" >&5 +$as_echo_n "checking for AES_cbc_encrypt in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_AES_cbc_encrypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char AES_cbc_encrypt (); +int +main () +{ +return AES_cbc_encrypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_AES_cbc_encrypt=yes +else + ac_cv_lib_crypto_AES_cbc_encrypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_AES_cbc_encrypt" >&5 +$as_echo "$ac_cv_lib_crypto_AES_cbc_encrypt" >&6; } +if test "x$ac_cv_lib_crypto_AES_cbc_encrypt" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_cbc=no +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for AES_ecb_encrypt in -lcrypto" >&5 +$as_echo_n "checking for AES_ecb_encrypt in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_AES_ecb_encrypt+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char AES_ecb_encrypt (); +int +main () +{ +return AES_ecb_encrypt (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_AES_ecb_encrypt=yes +else + ac_cv_lib_crypto_AES_ecb_encrypt=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_AES_ecb_encrypt" >&5 +$as_echo "$ac_cv_lib_crypto_AES_ecb_encrypt" >&6; } +if test "x$ac_cv_lib_crypto_AES_ecb_encrypt" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_ecb=no +fi + + + if test "x$ac_cv_lib_crypto_AES_cbc_encrypt" = xyes; then : + +$as_echo "#define HAVE_AES_CBC_ENCRYPT 1" >>confdefs.h + + +fi + + if test "x$ac_cv_lib_crypto_AES_ecb_encrypt" = xyes; then : + +$as_echo "#define HAVE_AES_ECB_ENCRYPT 1" >>confdefs.h + + +fi + +fi + + if test "x$ac_cv_libcrypto" = xno; then : + if test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno; then : + ac_cv_libcrypto=yes +fi + +fi + + if test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno; then : + ac_cv_libcrypto_aes=no +else + ac_cv_libcrypto_aes=libcrypto +fi + +fi + + if test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_cipher" != xno && test "x$ac_cv_libcrypto_evp_cipher" != xyes; then : + ac_cv_libcrypto_evp_cipher=yes + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_new in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_new in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_new+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_new (); +int +main () +{ +return EVP_CIPHER_CTX_new (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_new=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_dummy=no +fi + + + if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_new" = xyes; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_free in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_free in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_free+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_free (); +int +main () +{ +return EVP_CIPHER_CTX_free (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_free=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_free=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_free" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_free" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_free" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_init in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_init in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_init+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_init (); +int +main () +{ +return EVP_CIPHER_CTX_init (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_init=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_init=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_init" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_init" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_init" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_cleanup in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_cleanup in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_cleanup (); +int +main () +{ +return EVP_CIPHER_CTX_cleanup (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ERR_remove_thread_state in -lcrypto" >&5 +$as_echo_n "checking for ERR_remove_thread_state in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_ERR_remove_thread_state+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char ERR_remove_thread_state (); +int +main () +{ +return ERR_remove_thread_state (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_ERR_remove_thread_state=yes +else + ac_cv_lib_crypto_ERR_remove_thread_state=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_ERR_remove_thread_state" >&5 +$as_echo "$ac_cv_lib_crypto_ERR_remove_thread_state" >&6; } +if test "x$ac_cv_lib_crypto_ERR_remove_thread_state" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CIPHER_CTX_set_padding in -lcrypto" >&5 +$as_echo_n "checking for EVP_CIPHER_CTX_set_padding in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CIPHER_CTX_set_padding (); +int +main () +{ +return EVP_CIPHER_CTX_set_padding (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=yes +else + ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_set_padding" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CipherInit_ex in -lcrypto" >&5 +$as_echo_n "checking for EVP_CipherInit_ex in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CipherInit_ex+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CipherInit_ex (); +int +main () +{ +return EVP_CipherInit_ex (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CipherInit_ex=yes +else + ac_cv_lib_crypto_EVP_CipherInit_ex=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CipherInit_ex" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CipherInit_ex" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CipherInit_ex" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CipherUpdate in -lcrypto" >&5 +$as_echo_n "checking for EVP_CipherUpdate in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CipherUpdate+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CipherUpdate (); +int +main () +{ +return EVP_CipherUpdate (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CipherUpdate=yes +else + ac_cv_lib_crypto_EVP_CipherUpdate=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CipherUpdate" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CipherUpdate" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CipherUpdate" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_CipherFinal_ex in -lcrypto" >&5 +$as_echo_n "checking for EVP_CipherFinal_ex in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_CipherFinal_ex+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_CipherFinal_ex (); +int +main () +{ +return EVP_CipherFinal_ex (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_CipherFinal_ex=yes +else + ac_cv_lib_crypto_EVP_CipherFinal_ex=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_CipherFinal_ex" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_CipherFinal_ex" >&6; } +if test "x$ac_cv_lib_crypto_EVP_CipherFinal_ex" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_evp_cipher=no +fi + + + if test "x$ac_cv_enable_openssl_evp_cipher" = xyes && "x$ac_cv_libcrypto_evp_cipher" = xno; then : + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 1 "Missing OpenSSL EVP CIPHER support +See \`config.log' for more details" "$LINENO" 5; } + +fi + + if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_init" = xyes; then : + +$as_echo "#define HAVE_EVP_CIPHER_CTX_INIT 1" >>confdefs.h + + +fi + + if test "x$ac_cv_lib_crypto_EVP_CIPHER_CTX_cleanup" = xyes; then : + +$as_echo "#define HAVE_EVP_CIPHER_CTX_CLEANUP 1" >>confdefs.h + + +fi + +fi + + if test "x$ac_cv_libcrypto_evp_cipher" != xyes; then : + ac_cv_libcrypto_aes_xts=no +else + ac_cv_libcrypto_aes_xts=libcrypto_evp + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_128_xts in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_128_xts in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_128_xts+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_128_xts (); +int +main () +{ +return EVP_aes_128_xts (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_128_xts=yes +else + ac_cv_lib_crypto_EVP_aes_128_xts=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_128_xts" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_128_xts" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_128_xts" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_xts=no +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for EVP_aes_256_xts in -lcrypto" >&5 +$as_echo_n "checking for EVP_aes_256_xts in -lcrypto... " >&6; } +if ${ac_cv_lib_crypto_EVP_aes_256_xts+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char EVP_aes_256_xts (); +int +main () +{ +return EVP_aes_256_xts (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_crypto_EVP_aes_256_xts=yes +else + ac_cv_lib_crypto_EVP_aes_256_xts=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_EVP_aes_256_xts" >&5 +$as_echo "$ac_cv_lib_crypto_EVP_aes_256_xts" >&6; } +if test "x$ac_cv_lib_crypto_EVP_aes_256_xts" = xyes; then : + ac_cv_libcrypto_dummy=yes +else + ac_cv_libcrypto_aes_xts=no +fi + + + if test "x$ac_cv_lib_crypto_EVP_aes_128_xts" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_256_xts" = xyes; then : + +$as_echo "#define HAVE_EVP_CRYPTO_AES_XTS 1" >>confdefs.h + + +fi + +fi + +fi + + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_aes_cbc" = xno; then : + ac_cv_libcaes_aes_cbc=local +else + ac_cv_libcaes_aes_cbc=$ac_cv_libcrypto_aes_cbc +fi + + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno; then : + ac_cv_libcaes_aes_ecb=local +else + ac_cv_libcaes_aes_ecb=$ac_cv_libcrypto_aes_ecb +fi + + if test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_aes_xts" = xno; then : + ac_cv_libcaes_aes_xts=local +else + ac_cv_libcaes_aes_xts=$ac_cv_libcrypto_aes_xts fi ac_cv_libcaes_CPPFLAGS="-I../libcaes"; @@ -52991,7 +54271,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libfsapfs $as_me 20181215, which was +This file was extended by libfsapfs $as_me 20190210, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -53057,7 +54337,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libfsapfs config.status 20181215 +libfsapfs config.status 20190210 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -54928,7 +56208,8 @@ libhmac support: $ac_cv_libhmac SHA256 support: $ac_cv_libhmac_sha256 libcaes support: $ac_cv_libcaes - AES support: $ac_cv_libcaes_aes + AES-ECB support: $ac_cv_libcaes_aes_ecb + AES-XTS support: $ac_cv_libcaes_aes_xts FUSE support: $ac_cv_libfuse Features: @@ -54959,7 +56240,8 @@ libhmac support: $ac_cv_libhmac SHA256 support: $ac_cv_libhmac_sha256 libcaes support: $ac_cv_libcaes - AES support: $ac_cv_libcaes_aes + AES-ECB support: $ac_cv_libcaes_aes_ecb + AES-XTS support: $ac_cv_libcaes_aes_xts FUSE support: $ac_cv_libfuse Features: diff -Nru libfsapfs-20181215/configure.ac libfsapfs-20190210/configure.ac --- libfsapfs-20181215/configure.ac 2018-12-14 15:53:07.000000000 +0000 +++ libfsapfs-20190210/configure.ac 2019-02-10 18:26:03.000000000 +0000 @@ -2,7 +2,7 @@ AC_INIT( [libfsapfs], - [20181215], + [20190210], [joachim.metz@gmail.com]) AC_CONFIG_SRCDIR( @@ -263,7 +263,8 @@ libhmac support: $ac_cv_libhmac SHA256 support: $ac_cv_libhmac_sha256 libcaes support: $ac_cv_libcaes - AES support: $ac_cv_libcaes_aes + AES-ECB support: $ac_cv_libcaes_aes_ecb + AES-XTS support: $ac_cv_libcaes_aes_xts FUSE support: $ac_cv_libfuse Features: diff -Nru libfsapfs-20181215/debian/changelog libfsapfs-20190210/debian/changelog --- libfsapfs-20181215/debian/changelog 2019-01-14 10:10:02.000000000 +0000 +++ libfsapfs-20190210/debian/changelog 2019-02-10 21:28:47.000000000 +0000 @@ -1,3 +1,11 @@ +libfsapfs (20190210-1) unstable; urgency=medium + + * Enable hardening options + * Add libssl-dev build-dependency + * New upstream version 20190210 + + -- Hilko Bengen Sun, 10 Feb 2019 22:28:47 +0100 + libfsapfs (20181215-1) unstable; urgency=medium * Initial release (Closes: #919268) diff -Nru libfsapfs-20181215/debian/control libfsapfs-20190210/debian/control --- libfsapfs-20181215/debian/control 2019-01-14 10:10:02.000000000 +0000 +++ libfsapfs-20190210/debian/control 2019-01-22 23:48:52.000000000 +0000 @@ -7,6 +7,7 @@ pkg-config, libbfio-dev (>= 20160108), libfuse-dev, + libssl-dev, python-dev, python3-dev, Standards-Version: 4.3.0 Section: libs diff -Nru libfsapfs-20181215/debian/libfsapfs1.symbols libfsapfs-20190210/debian/libfsapfs1.symbols --- libfsapfs-20181215/debian/libfsapfs1.symbols 2019-01-14 10:10:02.000000000 +0000 +++ libfsapfs-20190210/debian/libfsapfs1.symbols 2019-02-10 21:27:53.000000000 +0000 @@ -57,6 +57,10 @@ libfsapfs_checksum_crc32_table@Base 20181215 libfsapfs_checksum_crc32_table_computed@Base 20181215 libfsapfs_checksum_initialize_crc32_table@Base 20181215 + libfsapfs_chunk_information_block_free@Base 20190210 + libfsapfs_chunk_information_block_initialize@Base 20190210 + libfsapfs_chunk_information_block_read_data@Base 20190210 + libfsapfs_chunk_information_block_read_file_io_handle@Base 20190210 libfsapfs_compressed_data_handle_free@Base 20181215 libfsapfs_compressed_data_handle_get_compressed_block_offsets@Base 20181215 libfsapfs_compressed_data_handle_initialize@Base 20181215 @@ -85,10 +89,6 @@ libfsapfs_container_reaper_read_data@Base 20181215 libfsapfs_container_reaper_read_file_io_handle@Base 20181215 libfsapfs_container_signal_abort@Base 20181215 - libfsapfs_container_space_manager_free@Base 20181215 - libfsapfs_container_space_manager_initialize@Base 20181215 - libfsapfs_container_space_manager_read_data@Base 20181215 - libfsapfs_container_space_manager_read_file_io_handle@Base 20181215 libfsapfs_container_superblock_free@Base 20181215 libfsapfs_container_superblock_get_container_identifier@Base 20181215 libfsapfs_container_superblock_initialize@Base 20181215 @@ -154,10 +154,16 @@ libfsapfs_extended_attribute_read_key_data@Base 20181215 libfsapfs_extended_attribute_read_value_data@Base 20181215 libfsapfs_extended_attribute_seek_offset@Base 20181215 + libfsapfs_extent_reference_tree_free@Base 20190210 + libfsapfs_extent_reference_tree_initialize@Base 20190210 + libfsapfs_extent_reference_tree_read_data@Base 20190210 + libfsapfs_extent_reference_tree_read_file_io_handle@Base 20190210 libfsapfs_file_entry_free@Base 20181215 libfsapfs_file_entry_get_access_time@Base 20181215 libfsapfs_file_entry_get_creation_time@Base 20181215 libfsapfs_file_entry_get_extended_attribute_by_index@Base 20181215 + libfsapfs_file_entry_get_extended_attribute_by_utf16_name@Base 20190210 + libfsapfs_file_entry_get_extended_attribute_by_utf8_name@Base 20190210 libfsapfs_file_entry_get_extent_by_index@Base 20181215 libfsapfs_file_entry_get_file_mode@Base 20181215 libfsapfs_file_entry_get_group_identifier@Base 20181215 @@ -183,6 +189,8 @@ libfsapfs_file_entry_get_utf8_name_size@Base 20181215 libfsapfs_file_entry_get_utf8_symbolic_link_target@Base 20181215 libfsapfs_file_entry_get_utf8_symbolic_link_target_size@Base 20181215 + libfsapfs_file_entry_has_extended_attribute_by_utf16_name@Base 20190210 + libfsapfs_file_entry_has_extended_attribute_by_utf8_name@Base 20190210 libfsapfs_file_entry_initialize@Base 20181215 libfsapfs_file_entry_read_buffer@Base 20181215 libfsapfs_file_entry_read_buffer_at_offset@Base 20181215 @@ -219,6 +227,10 @@ libfsapfs_file_system_data_handle_free@Base 20181215 libfsapfs_file_system_data_handle_initialize@Base 20181215 libfsapfs_file_system_data_handle_read_data_block@Base 20181215 + libfsapfs_fusion_middle_tree_free@Base 20190210 + libfsapfs_fusion_middle_tree_initialize@Base 20190210 + libfsapfs_fusion_middle_tree_read_data@Base 20190210 + libfsapfs_fusion_middle_tree_read_file_io_handle@Base 20190210 libfsapfs_get_access_flags_read@Base 20181215 libfsapfs_get_codepage@Base 20181215 libfsapfs_get_version@Base 20181215 @@ -332,6 +344,21 @@ libfsapfs_object_read_file_io_handle@Base 20181215 libfsapfs_password_pbkdf2@Base 20181215 libfsapfs_set_codepage@Base 20181215 + libfsapfs_snapshot_metadata_free@Base 20190210 + libfsapfs_snapshot_metadata_initialize@Base 20190210 + libfsapfs_snapshot_metadata_read_key_data@Base 20190210 + libfsapfs_snapshot_metadata_read_value_data@Base 20190210 + libfsapfs_snapshot_metadata_tree_free@Base 20190210 + libfsapfs_snapshot_metadata_tree_get_entry_by_identifier@Base 20190210 + libfsapfs_snapshot_metadata_tree_get_entry_from_node_by_identifier@Base 20190210 + libfsapfs_snapshot_metadata_tree_get_metadata_by_object_identifier@Base 20190210 + libfsapfs_snapshot_metadata_tree_get_root_node@Base 20190210 + libfsapfs_snapshot_metadata_tree_get_sub_node@Base 20190210 + libfsapfs_snapshot_metadata_tree_initialize@Base 20190210 + libfsapfs_space_manager_free@Base 20190210 + libfsapfs_space_manager_initialize@Base 20190210 + libfsapfs_space_manager_read_data@Base 20190210 + libfsapfs_space_manager_read_file_io_handle@Base 20190210 libfsapfs_volume_close@Base 20181215 libfsapfs_volume_free@Base 20181215 libfsapfs_volume_get_file_entry_by_identifier@Base 20181215 diff -Nru libfsapfs-20181215/debian/rules libfsapfs-20190210/debian/rules --- libfsapfs-20181215/debian/rules 2019-01-14 10:10:02.000000000 +0000 +++ libfsapfs-20190210/debian/rules 2019-01-30 10:30:50.000000000 +0000 @@ -4,6 +4,9 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 +export DEB_BUILD_MAINT_OPTIONS = hardening=+all +export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + export SKIP_PYTHON_TESTS=1 %: diff -Nru libfsapfs-20181215/dpkg/changelog libfsapfs-20190210/dpkg/changelog --- libfsapfs-20181215/dpkg/changelog 2018-12-15 06:44:19.000000000 +0000 +++ libfsapfs-20190210/dpkg/changelog 2019-02-10 19:59:54.000000000 +0000 @@ -1,5 +1,5 @@ -libfsapfs (20181215-1) unstable; urgency=low +libfsapfs (20190210-1) unstable; urgency=low * Auto-generated - -- Joachim Metz Sat, 15 Dec 2018 07:44:17 +0100 + -- Joachim Metz Sun, 10 Feb 2019 20:59:53 +0100 diff -Nru libfsapfs-20181215/dpkg/control libfsapfs-20190210/dpkg/control --- libfsapfs-20181215/dpkg/control 2018-12-03 17:48:57.000000000 +0000 +++ libfsapfs-20190210/dpkg/control 2019-02-06 20:10:07.000000000 +0000 @@ -9,6 +9,8 @@ Package: libfsapfs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} +Conflicts: libfsapfs1 +Replaces: libfsapfs1 Suggests: libfsapfs-dbg Description: Library to access the Apple File System (APFS) format libfsapfs is a library to access the Apple File System (APFS) format. @@ -31,6 +33,8 @@ Section: utils Architecture: any Depends: libfsapfs (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Conflicts: libfsapfs-utils +Replaces: libfsapfs-utils Description: Several tools for reading Apple File System (APFS) volumes Several tools for reading Apple File System (APFS) volumes. @@ -45,6 +49,8 @@ Section: python Architecture: any Depends: libfsapfs (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Conflicts: python-libfsapfs +Replaces: python-libfsapfs Suggests: libfsapfs-python-dbg Description: Python 2 bindings for libfsapfs Python 2 bindings for libfsapfs. @@ -60,6 +66,8 @@ Section: python Architecture: any Depends: libfsapfs (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} +Conflicts: python3-libfsapfs +Replaces: python3-libfsapfs Suggests: libfsapfs-python3-dbg Description: Python 3 bindings for libfsapfs Python 3 bindings for libfsapfs. diff -Nru libfsapfs-20181215/dpkg/copyright libfsapfs-20190210/dpkg/copyright --- libfsapfs-20181215/dpkg/copyright 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/dpkg/copyright 2019-02-06 20:10:16.000000000 +0000 @@ -3,7 +3,7 @@ Source: https://github.com/libyal/libfsapfs Files: * -Copyright: 2018, Joachim Metz +Copyright: 2018-2019, Joachim Metz License: LGPL-3.0+ License: LGPL-3.0+ diff -Nru libfsapfs-20181215/fsapfstools/fsapfsinfo.c libfsapfs-20190210/fsapfstools/fsapfsinfo.c --- libfsapfs-20181215/fsapfstools/fsapfsinfo.c 2018-12-14 09:49:26.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfsinfo.c 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* * Shows information obtained from an Apple File System (APFS) * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfsmount.c libfsapfs-20190210/fsapfstools/fsapfsmount.c --- libfsapfs-20181215/fsapfstools/fsapfsmount.c 2018-12-14 09:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfsmount.c 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* - * Mounts an APFS container + * Mounts an Apple File System (APFS) container * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -35,21 +35,12 @@ #include #endif -#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) -#define FUSE_USE_VERSION 26 - -#if defined( HAVE_LIBFUSE ) -#include - -#elif defined( HAVE_LIBOSXFUSE ) -#include +#if defined( HAVE_UNISTD_H ) +#include #endif -#endif /* defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) */ - -#include "mount_fuse.h" -#include "mount_handle.h" #include "fsapfstools_getopt.h" +#include "fsapfstools_i18n.h" #include "fsapfstools_libcerror.h" #include "fsapfstools_libclocale.h" #include "fsapfstools_libcnotify.h" @@ -57,11 +48,14 @@ #include "fsapfstools_output.h" #include "fsapfstools_signal.h" #include "fsapfstools_unused.h" +#include "mount_dokan.h" +#include "mount_fuse.h" +#include "mount_handle.h" mount_handle_t *fsapfsmount_mount_handle = NULL; int fsapfsmount_abort = 0; -/* Prints the executable usage information +/* Prints usage information */ void usage_fprint( FILE *stream ) @@ -70,20 +64,20 @@ { return; } - fprintf( stream, "Use fsapfsmount to mount an APFS container\n\n" ); + fprintf( stream, "Use fsapfsmount to mount an Apple File System (APFS) container\n\n" ); fprintf( stream, "Usage: fsapfsmount [ -f file_system_index ] [ -o offset ] [ -p password ]\n" - " [ -r password ] [ -X extended_options ] [ -hvV ]\n" - " container mount_point\n\n" ); + " [ -r recovery_password ] [ -X extended_options ]\n" + " [ -hvV ] container mount_point\n\n" ); - fprintf( stream, "\tcontainer: an APFS container\n\n" ); + fprintf( stream, "\tcontainer: an Apple File System (APFS) container\n\n" ); fprintf( stream, "\tmount_point: the directory to serve as mount point\n\n" ); fprintf( stream, "\t-f: mounts a specific file system or \"all\"\n" ); fprintf( stream, "\t-h: shows this help\n" ); - fprintf( stream, "\t-o: specify the volume offset\n" ); - fprintf( stream, "\t-p: specify the password\n" ); - fprintf( stream, "\t-r: specify the recovery password\n" ); + fprintf( stream, "\t-o: specify the container offset in bytes\n" ); + fprintf( stream, "\t-p: specify the password/passphrase\n" ); + fprintf( stream, "\t-r: specify the recovery password/passphrase\n" ); fprintf( stream, "\t-v: verbose output to stderr, while fsapfsmount will remain running in the\n" "\t foreground\n" ); fprintf( stream, "\t-V: print version\n" ); @@ -146,9 +140,9 @@ system_character_t *mount_point = NULL; system_character_t *option_extended_options = NULL; system_character_t *option_file_system_index = NULL; + system_character_t *option_offset = NULL; system_character_t *option_password = NULL; system_character_t *option_recovery_password = NULL; - system_character_t *option_volume_offset = NULL; system_character_t *source = NULL; char *program = "fsapfsmount"; system_integer_t option = 0; @@ -161,6 +155,10 @@ struct fuse_args fsapfsmount_fuse_arguments = FUSE_ARGS_INIT(0, NULL); struct fuse_chan *fsapfsmount_fuse_channel = NULL; struct fuse *fsapfsmount_fuse_handle = NULL; + +#elif defined( HAVE_LIBDOKAN ) + DOKAN_OPERATIONS fsapfsmount_dokan_operations; + DOKAN_OPTIONS fsapfsmount_dokan_options; #endif libcnotify_stream_set( @@ -170,7 +168,7 @@ 1 ); if( libclocale_initialize( - "fsapfstools", + "fsapfstools", &error ) != 1 ) { fprintf( @@ -180,8 +178,8 @@ goto on_error; } if( fsapfstools_output_initialize( - _IONBF, - &error ) != 1 ) + _IONBF, + &error ) != 1 ) { fprintf( stderr, @@ -224,7 +222,7 @@ return( EXIT_SUCCESS ); case (system_integer_t) 'o': - option_volume_offset = optarg; + option_offset = optarg; break; @@ -316,75 +314,70 @@ "Unsupported file system index defaulting to: all.\n" ); } } - if( option_password != NULL ) + if( option_offset != NULL ) { - if( mount_handle_set_password( + if( mount_handle_set_offset( fsapfsmount_mount_handle, - option_password, + option_offset, &error ) != 1 ) { fprintf( stderr, - "Unable to set password.\n" ); + "Unable to set container offset.\n" ); goto on_error; } } - if( option_recovery_password != NULL ) + if( option_password != NULL ) { - if( mount_handle_set_recovery_password( + if( mount_handle_set_password( fsapfsmount_mount_handle, - option_recovery_password, + option_password, &error ) != 1 ) { fprintf( stderr, - "Unable to set recovery password.\n" ); + "Unable to set password.\n" ); goto on_error; } } - if( option_volume_offset != NULL ) + if( option_recovery_password != NULL ) { - if( mount_handle_set_volume_offset( + if( mount_handle_set_recovery_password( fsapfsmount_mount_handle, - option_volume_offset, + option_recovery_password, &error ) != 1 ) { - libcnotify_print_error_backtrace( - error ); - libcerror_error_free( - &error ); - fprintf( stderr, - "Unsupported volume offset defaulting to: %" PRIi64 ".\n", - fsapfsmount_mount_handle->volume_offset ); + "Unable to set recovery password.\n" ); + + goto on_error; } } - if( mount_handle_open_input( + if( mount_handle_open( fsapfsmount_mount_handle, source, &error ) != 1 ) { fprintf( stderr, - "Unable to open input.\n" ); + "Unable to open source container\n" ); goto on_error; } -#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) - if( memory_set( - &fsapfsmount_fuse_operations, - 0, - sizeof( struct fuse_operations ) ) == NULL ) + if( mount_handle_is_locked( + fsapfsmount_mount_handle, + &error ) != 0 ) { fprintf( stderr, - "Unable to clear fuse operations.\n" ); + "Unable to unlock source container\n" ); goto on_error; } +#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) if( option_extended_options != NULL ) { /* This argument is required but ignored @@ -420,6 +413,17 @@ goto on_error; } } + if( memory_set( + &fsapfsmount_fuse_operations, + 0, + sizeof( struct fuse_operations ) ) == NULL ) + { + fprintf( + stderr, + "Unable to clear fuse operations.\n" ); + + goto on_error; + } fsapfsmount_fuse_operations.open = &mount_fuse_open; fsapfsmount_fuse_operations.read = &mount_fuse_read; fsapfsmount_fuse_operations.release = &mount_fuse_release; @@ -448,7 +452,7 @@ &fsapfsmount_fuse_operations, sizeof( struct fuse_operations ), fsapfsmount_mount_handle ); - + if( fsapfsmount_fuse_handle == NULL ) { fprintf( @@ -488,10 +492,160 @@ return( EXIT_SUCCESS ); +#elif defined( HAVE_LIBDOKAN ) + if( memory_set( + &fsapfsmount_dokan_operations, + 0, + sizeof( DOKAN_OPERATIONS ) ) == NULL ) + { + fprintf( + stderr, + "Unable to clear dokan operations.\n" ); + + goto on_error; + } + if( memory_set( + &fsapfsmount_dokan_options, + 0, + sizeof( DOKAN_OPTIONS ) ) == NULL ) + { + fprintf( + stderr, + "Unable to clear dokan options.\n" ); + + goto on_error; + } + fsapfsmount_dokan_options.Version = DOKAN_VERSION; + fsapfsmount_dokan_options.ThreadCount = 0; + fsapfsmount_dokan_options.MountPoint = mount_point; + + if( verbose != 0 ) + { + fsapfsmount_dokan_options.Options |= DOKAN_OPTION_STDERR; +#if defined( HAVE_DEBUG_OUTPUT ) + fsapfsmount_dokan_options.Options |= DOKAN_OPTION_DEBUG; +#endif + } +/* This will only affect the drive properties + fsapfsmount_dokan_options.Options |= DOKAN_OPTION_REMOVABLE; +*/ + +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) + fsapfsmount_dokan_options.Options |= DOKAN_OPTION_KEEP_ALIVE; + + fsapfsmount_dokan_operations.CreateFile = &mount_dokan_CreateFile; + fsapfsmount_dokan_operations.OpenDirectory = &mount_dokan_OpenDirectory; + fsapfsmount_dokan_operations.CreateDirectory = NULL; + fsapfsmount_dokan_operations.Cleanup = NULL; + fsapfsmount_dokan_operations.CloseFile = &mount_dokan_CloseFile; + fsapfsmount_dokan_operations.ReadFile = &mount_dokan_ReadFile; + fsapfsmount_dokan_operations.WriteFile = NULL; + fsapfsmount_dokan_operations.FlushFileBuffers = NULL; + fsapfsmount_dokan_operations.GetFileInformation = &mount_dokan_GetFileInformation; + fsapfsmount_dokan_operations.FindFiles = &mount_dokan_FindFiles; + fsapfsmount_dokan_operations.FindFilesWithPattern = NULL; + fsapfsmount_dokan_operations.SetFileAttributes = NULL; + fsapfsmount_dokan_operations.SetFileTime = NULL; + fsapfsmount_dokan_operations.DeleteFile = NULL; + fsapfsmount_dokan_operations.DeleteDirectory = NULL; + fsapfsmount_dokan_operations.MoveFile = NULL; + fsapfsmount_dokan_operations.SetEndOfFile = NULL; + fsapfsmount_dokan_operations.SetAllocationSize = NULL; + fsapfsmount_dokan_operations.LockFile = NULL; + fsapfsmount_dokan_operations.UnlockFile = NULL; + fsapfsmount_dokan_operations.GetFileSecurity = NULL; + fsapfsmount_dokan_operations.SetFileSecurity = NULL; + fsapfsmount_dokan_operations.GetDiskFreeSpace = NULL; + fsapfsmount_dokan_operations.GetVolumeInformation = &mount_dokan_GetVolumeInformation; + fsapfsmount_dokan_operations.Unmount = &mount_dokan_Unmount; + +#else + fsapfsmount_dokan_operations.ZwCreateFile = &mount_dokan_ZwCreateFile; + fsapfsmount_dokan_operations.Cleanup = NULL; + fsapfsmount_dokan_operations.CloseFile = &mount_dokan_CloseFile; + fsapfsmount_dokan_operations.ReadFile = &mount_dokan_ReadFile; + fsapfsmount_dokan_operations.WriteFile = NULL; + fsapfsmount_dokan_operations.FlushFileBuffers = NULL; + fsapfsmount_dokan_operations.GetFileInformation = &mount_dokan_GetFileInformation; + fsapfsmount_dokan_operations.FindFiles = &mount_dokan_FindFiles; + fsapfsmount_dokan_operations.FindFilesWithPattern = NULL; + fsapfsmount_dokan_operations.SetFileAttributes = NULL; + fsapfsmount_dokan_operations.SetFileTime = NULL; + fsapfsmount_dokan_operations.DeleteFile = NULL; + fsapfsmount_dokan_operations.DeleteDirectory = NULL; + fsapfsmount_dokan_operations.MoveFile = NULL; + fsapfsmount_dokan_operations.SetEndOfFile = NULL; + fsapfsmount_dokan_operations.SetAllocationSize = NULL; + fsapfsmount_dokan_operations.LockFile = NULL; + fsapfsmount_dokan_operations.UnlockFile = NULL; + fsapfsmount_dokan_operations.GetFileSecurity = NULL; + fsapfsmount_dokan_operations.SetFileSecurity = NULL; + fsapfsmount_dokan_operations.GetDiskFreeSpace = NULL; + fsapfsmount_dokan_operations.GetVolumeInformation = &mount_dokan_GetVolumeInformation; + fsapfsmount_dokan_operations.Unmounted = NULL; + fsapfsmount_dokan_operations.FindStreams = NULL; + fsapfsmount_dokan_operations.Mounted = NULL; + +#endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */ + + result = DokanMain( + &fsapfsmount_dokan_options, + &fsapfsmount_dokan_operations ); + + switch( result ) + { + case DOKAN_SUCCESS: + break; + + case DOKAN_ERROR: + fprintf( + stderr, + "Unable to run dokan main: generic error\n" ); + break; + + case DOKAN_DRIVE_LETTER_ERROR: + fprintf( + stderr, + "Unable to run dokan main: bad drive letter\n" ); + break; + + case DOKAN_DRIVER_INSTALL_ERROR: + fprintf( + stderr, + "Unable to run dokan main: unable to load driver\n" ); + break; + + case DOKAN_START_ERROR: + fprintf( + stderr, + "Unable to run dokan main: driver error\n" ); + break; + + case DOKAN_MOUNT_ERROR: + fprintf( + stderr, + "Unable to run dokan main: unable to assign drive letter\n" ); + break; + + case DOKAN_MOUNT_POINT_ERROR: + fprintf( + stderr, + "Unable to run dokan main: mount point error\n" ); + break; + + default: + fprintf( + stderr, + "Unable to run dokan main: unknown error: %d\n", + result ); + break; + } + return( EXIT_SUCCESS ); + #else fprintf( stderr, - "No sub system to mount APFS container.\n" ); + "No sub system to mount APFS format.\n" ); return( EXIT_FAILURE ); diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_getopt.c libfsapfs-20190210/fsapfstools/fsapfstools_getopt.c --- libfsapfs-20181215/fsapfstools/fsapfstools_getopt.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_getopt.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * GetOpt functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_getopt.h libfsapfs-20190210/fsapfstools/fsapfstools_getopt.h --- libfsapfs-20181215/fsapfstools/fsapfstools_getopt.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_getopt.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * GetOpt functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_i18n.h libfsapfs-20190210/fsapfstools/fsapfstools_i18n.h --- libfsapfs-20181215/fsapfstools/fsapfstools_i18n.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_i18n.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Internationalization (i18n) functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libbfio.h libfsapfs-20190210/fsapfstools/fsapfstools_libbfio.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libbfio.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libbfio.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libbfio header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libcdata.h libfsapfs-20190210/fsapfstools/fsapfstools_libcdata.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libcdata.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libcdata.h 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,54 @@ +/* + * The libcdata header wrapper + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _FSAPFSTOOLS_LIBCDATA_H ) +#define _FSAPFSTOOLS_LIBCDATA_H + +#include + +/* Define HAVE_LOCAL_LIBCDATA for local use of libcdata + */ +#if defined( HAVE_LOCAL_LIBCDATA ) + +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +/* If libtool DLL support is enabled set LIBCDATA_DLL_IMPORT + * before including libcdata.h + */ +#if defined( _WIN32 ) && defined( DLL_IMPORT ) +#define LIBCDATA_DLL_IMPORT +#endif + +#include + +#endif /* defined( HAVE_LOCAL_LIBCDATA ) */ + +#endif /* !defined( _FSAPFSTOOLS_LIBCDATA_H ) */ + diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libcerror.h libfsapfs-20190210/fsapfstools/fsapfstools_libcerror.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libcerror.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libcerror.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libclocale.h libfsapfs-20190210/fsapfstools/fsapfstools_libclocale.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libclocale.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libclocale.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libclocale header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libcnotify.h libfsapfs-20190210/fsapfstools/fsapfstools_libcnotify.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libcnotify.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libcnotify.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcnotify header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libcpath.h libfsapfs-20190210/fsapfstools/fsapfstools_libcpath.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libcpath.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libcpath.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcpath header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libfdatetime.h libfsapfs-20190210/fsapfstools/fsapfstools_libfdatetime.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libfdatetime.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libfdatetime.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfdatetime header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libfguid.h libfsapfs-20190210/fsapfstools/fsapfstools_libfguid.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libfguid.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libfguid.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfguid header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libfsapfs.h libfsapfs-20190210/fsapfstools/fsapfstools_libfsapfs.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libfsapfs.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libfsapfs.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfsapfs header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_libuna.h libfsapfs-20190210/fsapfstools/fsapfstools_libuna.h --- libfsapfs-20181215/fsapfstools/fsapfstools_libuna.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_libuna.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libuna header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_output.c libfsapfs-20190210/fsapfstools/fsapfstools_output.c --- libfsapfs-20181215/fsapfstools/fsapfstools_output.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_output.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Common output functions for the fsapfstools * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -105,7 +105,7 @@ */ fprintf( stream, - _( "Copyright (C) 2018, %s.\n" ), + _( "Copyright (C) 2018-2019, %s.\n" ), _( "Joachim Metz" ) ); fprintf( diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_output.h libfsapfs-20190210/fsapfstools/fsapfstools_output.h --- libfsapfs-20181215/fsapfstools/fsapfstools_output.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_output.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Common output functions for the fsapfstools * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_signal.c libfsapfs-20190210/fsapfstools/fsapfstools_signal.c --- libfsapfs-20181215/fsapfstools/fsapfstools_signal.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_signal.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Signal handling functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_signal.h libfsapfs-20190210/fsapfstools/fsapfstools_signal.h --- libfsapfs-20181215/fsapfstools/fsapfstools_signal.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_signal.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Signal handling functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/fsapfstools_unused.h libfsapfs-20190210/fsapfstools/fsapfstools_unused.h --- libfsapfs-20181215/fsapfstools/fsapfstools_unused.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/fsapfstools_unused.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/info_handle.c libfsapfs-20190210/fsapfstools/info_handle.c --- libfsapfs-20181215/fsapfstools/info_handle.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/info_handle.c 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* * Info handle * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/info_handle.h libfsapfs-20190210/fsapfstools/info_handle.h --- libfsapfs-20181215/fsapfstools/info_handle.h 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/info_handle.h 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* * Info handle * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/fsapfstools/Makefile.am libfsapfs-20190210/fsapfstools/Makefile.am --- libfsapfs-20181215/fsapfstools/Makefile.am 2018-11-17 17:35:12.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/Makefile.am 2019-01-02 18:29:13.000000000 +0000 @@ -59,6 +59,7 @@ fsapfstools_getopt.c fsapfstools_getopt.h \ fsapfstools_i18n.h \ fsapfstools_libbfio.h \ + fsapfstools_libcdata.h \ fsapfstools_libcerror.h \ fsapfstools_libclocale.h \ fsapfstools_libcnotify.h \ @@ -68,6 +69,9 @@ fsapfstools_output.c fsapfstools_output.h \ fsapfstools_signal.c fsapfstools_signal.h \ fsapfstools_unused.h \ + mount_dokan.c mount_dokan.h \ + mount_file_entry.c mount_file_entry.h \ + mount_file_system.c mount_file_system.h \ mount_fuse.c mount_fuse.h \ mount_handle.c mount_handle.h diff -Nru libfsapfs-20181215/fsapfstools/Makefile.in libfsapfs-20190210/fsapfstools/Makefile.in --- libfsapfs-20181215/fsapfstools/Makefile.in 2018-12-15 06:44:01.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/Makefile.in 2019-02-10 19:59:39.000000000 +0000 @@ -132,8 +132,9 @@ am__v_lt_1 = am_fsapfsmount_OBJECTS = fsapfsmount.$(OBJEXT) \ fsapfstools_getopt.$(OBJEXT) fsapfstools_output.$(OBJEXT) \ - fsapfstools_signal.$(OBJEXT) mount_fuse.$(OBJEXT) \ - mount_handle.$(OBJEXT) + fsapfstools_signal.$(OBJEXT) mount_dokan.$(OBJEXT) \ + mount_file_entry.$(OBJEXT) mount_file_system.$(OBJEXT) \ + mount_fuse.$(OBJEXT) mount_handle.$(OBJEXT) fsapfsmount_OBJECTS = $(am_fsapfsmount_OBJECTS) fsapfsmount_DEPENDENCIES = ../libfsapfs/libfsapfs.la AM_V_P = $(am__v_P_@AM_V@) @@ -155,7 +156,9 @@ ./$(DEPDIR)/fsapfsmount.Po ./$(DEPDIR)/fsapfstools_getopt.Po \ ./$(DEPDIR)/fsapfstools_output.Po \ ./$(DEPDIR)/fsapfstools_signal.Po ./$(DEPDIR)/info_handle.Po \ - ./$(DEPDIR)/mount_fuse.Po ./$(DEPDIR)/mount_handle.Po + ./$(DEPDIR)/mount_dokan.Po ./$(DEPDIR)/mount_file_entry.Po \ + ./$(DEPDIR)/mount_file_system.Po ./$(DEPDIR)/mount_fuse.Po \ + ./$(DEPDIR)/mount_handle.Po am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -627,6 +630,7 @@ fsapfstools_getopt.c fsapfstools_getopt.h \ fsapfstools_i18n.h \ fsapfstools_libbfio.h \ + fsapfstools_libcdata.h \ fsapfstools_libcerror.h \ fsapfstools_libclocale.h \ fsapfstools_libcnotify.h \ @@ -636,6 +640,9 @@ fsapfstools_output.c fsapfstools_output.h \ fsapfstools_signal.c fsapfstools_signal.h \ fsapfstools_unused.h \ + mount_dokan.c mount_dokan.h \ + mount_file_entry.c mount_file_entry.h \ + mount_file_system.c mount_file_system.h \ mount_fuse.c mount_fuse.h \ mount_handle.c mount_handle.h @@ -759,6 +766,9 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfstools_output.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfstools_signal.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/info_handle.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_dokan.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_file_entry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_file_system.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_fuse.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mount_handle.Po@am__quote@ # am--include-marker @@ -972,6 +982,9 @@ -rm -f ./$(DEPDIR)/fsapfstools_output.Po -rm -f ./$(DEPDIR)/fsapfstools_signal.Po -rm -f ./$(DEPDIR)/info_handle.Po + -rm -f ./$(DEPDIR)/mount_dokan.Po + -rm -f ./$(DEPDIR)/mount_file_entry.Po + -rm -f ./$(DEPDIR)/mount_file_system.Po -rm -f ./$(DEPDIR)/mount_fuse.Po -rm -f ./$(DEPDIR)/mount_handle.Po -rm -f Makefile diff -Nru libfsapfs-20181215/fsapfstools/mount_dokan.c libfsapfs-20190210/fsapfstools/mount_dokan.c --- libfsapfs-20181215/fsapfstools/mount_dokan.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_dokan.c 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,1609 @@ +/* + * Mount tool dokan functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include + +#include "fsapfstools_libcerror.h" +#include "fsapfstools_libcnotify.h" +#include "fsapfstools_libfsapfs.h" +#include "fsapfstools_unused.h" +#include "mount_dokan.h" +#include "mount_file_entry.h" +#include "mount_handle.h" + +extern mount_handle_t *fsapfsmount_mount_handle; + +#if defined( HAVE_LIBDOKAN ) + +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) +#define MOUNT_DOKAN_ERROR_BAD_ARGUMENTS -ERROR_BAD_ARGUMENTS +#define MOUNT_DOKAN_ERROR_FILE_NOT_FOUND -ERROR_FILE_NOT_FOUND +#define MOUNT_DOKAN_ERROR_GENERIC_FAILURE -ERROR_GEN_FAILURE +#define MOUNT_DOKAN_ERROR_READ_FAULT -ERROR_READ_FAULT + +#else +#define MOUNT_DOKAN_ERROR_BAD_ARGUMENTS STATUS_UNSUCCESSFUL +#define MOUNT_DOKAN_ERROR_FILE_NOT_FOUND STATUS_OBJECT_NAME_NOT_FOUND +#define MOUNT_DOKAN_ERROR_GENERIC_FAILURE STATUS_UNSUCCESSFUL +#define MOUNT_DOKAN_ERROR_READ_FAULT STATUS_UNEXPECTED_IO_ERROR + +#endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */ + +/* Sets the values in a file information structure + * The time values contain an unsigned 64-bit FILETIME timestamp + * Returns 1 if successful or -1 on error + */ +int mount_dokan_set_file_information( + BY_HANDLE_FILE_INFORMATION *file_information, + size64_t size, + uint16_t file_mode, + uint64_t creation_time, + uint64_t access_time, + uint64_t modification_time, + libcerror_error_t **error ) +{ + static char *function = "mount_dokan_set_file_information"; + + if( file_information == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file information.", + function ); + + return( -1 ); + } + if( size > 0 ) + { + file_information->nFileSizeHigh = (DWORD) ( size >> 32 ); + file_information->nFileSizeLow = (DWORD) ( size & 0xffffffffUL ); + } + if( ( file_mode & 0x4000 ) != 0 ) + { + file_information->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; + } + else + { + file_information->dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + } + file_information->ftCreationTime.dwLowDateTime = (uint32_t) ( creation_time & 0x00000000ffffffffULL ); + file_information->ftCreationTime.dwHighDateTime = creation_time >> 32; + + file_information->ftLastAccessTime.dwLowDateTime = (uint32_t) ( access_time & 0x00000000ffffffffULL ); + file_information->ftLastAccessTime.dwHighDateTime = access_time >> 32; + + file_information->ftLastWriteTime.dwLowDateTime = (uint32_t) ( modification_time & 0x00000000ffffffffULL ); + file_information->ftLastWriteTime.dwHighDateTime = modification_time >> 32; + + return( 1 ); +} + +/* Sets the values in a find data structure + * The time values contain an unsigned 64-bit FILETIME timestamp + * Returns 1 if successful or -1 on error + */ +int mount_dokan_set_find_data( + WIN32_FIND_DATAW *find_data, + size64_t size, + uint16_t file_mode, + uint64_t creation_time, + uint64_t access_time, + uint64_t modification_time, + libcerror_error_t **error ) +{ + static char *function = "mount_dokan_set_find_data"; + + if( find_data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid find data.", + function ); + + return( -1 ); + } + if( size > 0 ) + { + find_data->nFileSizeHigh = (DWORD) ( size >> 32 ); + find_data->nFileSizeLow = (DWORD) ( size & 0xffffffffUL ); + } + if( ( file_mode & 0x4000 ) != 0 ) + { + find_data->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; + } + else + { + find_data->dwFileAttributes = FILE_ATTRIBUTE_NORMAL; + } + find_data->ftCreationTime.dwLowDateTime = (uint32_t) ( creation_time & 0x00000000ffffffffULL ); + find_data->ftCreationTime.dwHighDateTime = creation_time >> 32; + + find_data->ftLastAccessTime.dwLowDateTime = (uint32_t) ( access_time & 0x00000000ffffffffULL ); + find_data->ftLastAccessTime.dwHighDateTime = access_time >> 32; + + find_data->ftLastWriteTime.dwLowDateTime = (uint32_t) ( modification_time & 0x00000000ffffffffULL ); + find_data->ftLastWriteTime.dwHighDateTime = modification_time >> 32; + + return( 1 ); +} + +/* Fills a directory entry + * Returns 1 if successful or -1 on error + */ +int mount_dokan_filldir( + PFillFindData fill_find_data, + DOKAN_FILE_INFO *file_info, + wchar_t *name, + size_t name_size, + WIN32_FIND_DATAW *find_data, + mount_file_entry_t *file_entry, + libcerror_error_t **error ) +{ + static char *function = "mount_dokan_filldir"; + size64_t file_size = 0; + uint64_t access_time = 0; + uint64_t creation_time = 0; + uint64_t modification_time = 0; + uint16_t file_mode = 0; + + if( fill_find_data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid fill find data.", + function ); + + return( -1 ); + } + if( name == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid name.", + function ); + + return( -1 ); + } + if( name_size > (size_t) MAX_PATH ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid name size value out of bounds.", + function ); + + return( -1 ); + } + if( file_entry != NULL ) + { + if( mount_file_entry_get_size( + file_entry, + &file_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry size.", + function ); + + return( -1 ); + } + if( mount_file_entry_get_file_mode( + file_entry, + &file_mode, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file mode.", + function ); + + return( -1 ); + } + if( mount_file_entry_get_creation_time( + file_entry, + &creation_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve creation time.", + function ); + + return( -1 ); + } + if( mount_file_entry_get_access_time( + file_entry, + &access_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve access time.", + function ); + + return( -1 ); + } + if( mount_file_entry_get_modification_time( + file_entry, + &modification_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve modification time.", + function ); + + return( -1 ); + } + } + if( memory_set( + find_data, + 0, + sizeof( WIN32_FIND_DATAW ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear find data.", + function ); + + return( -1 ); + } + if( wide_string_copy( + find_data->cFileName, + name, + name_size ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy filename.", + function ); + + return( -1 ); + } + if( name_size <= (size_t) 14 ) + { + if( wide_string_copy( + find_data->cAlternateFileName, + name, + name_size ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy alternate filename.", + function ); + + return( -1 ); + } + } + if( mount_dokan_set_find_data( + find_data, + file_size, + file_mode, + creation_time, + access_time, + modification_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set find data.", + function ); + + return( -1 ); + } + if( fill_find_data( + find_data, + file_info ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set directory entry.", + function ); + + return( -1 ); + } + return( 1 ); +} + +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) + +/* Opens a file or directory + * Returns 0 if successful or an error code otherwise + */ +int __stdcall mount_dokan_CreateFile( + const wchar_t *path, + DWORD desired_access, + DWORD share_mode FSAPFSTOOLS_ATTRIBUTE_UNUSED, + DWORD creation_disposition, + DWORD attribute_flags FSAPFSTOOLS_ATTRIBUTE_UNUSED, + DOKAN_FILE_INFO *file_info ) +{ + libcerror_error_t *error = NULL; + static char *function = "mount_dokan_CreateFile"; + int result = 0; + + FSAPFSTOOLS_UNREFERENCED_PARAMETER( share_mode ) + FSAPFSTOOLS_UNREFERENCED_PARAMETER( attribute_flags ) + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: %ls\n", + function, + path ); + } +#endif + if( path == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + result = -ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( ( desired_access & GENERIC_WRITE ) != 0 ) + { + return( -ERROR_WRITE_PROTECT ); + } + /* Ignore the share_mode + */ + if( creation_disposition == CREATE_NEW ) + { + return( -ERROR_FILE_EXISTS ); + } + else if( creation_disposition == CREATE_ALWAYS ) + { + return( -ERROR_ALREADY_EXISTS ); + } + else if( creation_disposition == OPEN_ALWAYS ) + { + return( -ERROR_FILE_NOT_FOUND ); + } + else if( creation_disposition == TRUNCATE_EXISTING ) + { + return( -ERROR_FILE_NOT_FOUND ); + } + else if( creation_disposition != OPEN_EXISTING ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid creation disposition.", + function ); + + result = -ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file information.", + function ); + + result = -ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info->Context != (ULONG64) NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid file information - context already set.", + function ); + + result = -ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( mount_handle_get_file_entry_by_path( + fsapfsmount_mount_handle, + path, + (mount_file_entry_t **) &( file_info->Context ), + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry for path: %ls.", + function, + path ); + + result = -ERROR_FILE_NOT_FOUND; + + goto on_error; + } + return( 0 ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + return( result ); +} + +#else + +/* Opens a file or directory + * Returns 0 if successful or an error code otherwise + */ +NTSTATUS __stdcall mount_dokan_ZwCreateFile( + const wchar_t *path, + DOKAN_IO_SECURITY_CONTEXT *security_context FSAPFSTOOLS_ATTRIBUTE_UNUSED, + ACCESS_MASK desired_access, + ULONG file_attributes FSAPFSTOOLS_ATTRIBUTE_UNUSED, + ULONG share_access FSAPFSTOOLS_ATTRIBUTE_UNUSED, + ULONG creation_disposition, + ULONG creation_options FSAPFSTOOLS_ATTRIBUTE_UNUSED, + DOKAN_FILE_INFO *file_info ) +{ + libcerror_error_t *error = NULL; + static char *function = "mount_dokan_ZwCreateFile"; + int result = 0; + + FSAPFSTOOLS_UNREFERENCED_PARAMETER( security_context ) + FSAPFSTOOLS_UNREFERENCED_PARAMETER( file_attributes ) + FSAPFSTOOLS_UNREFERENCED_PARAMETER( share_access ) + FSAPFSTOOLS_UNREFERENCED_PARAMETER( creation_options ) + + if( path == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + result = STATUS_UNSUCCESSFUL; + + goto on_error; + } + if( ( desired_access & GENERIC_WRITE ) != 0 ) + { + return( STATUS_MEDIA_WRITE_PROTECTED ); + } + /* Ignore the share_mode + */ + if( creation_disposition == FILE_CREATE ) + { + return( STATUS_OBJECT_NAME_COLLISION ); + } + else if( ( creation_disposition != FILE_OPEN ) + && ( creation_disposition != FILE_OPEN_IF ) ) + { + return( STATUS_ACCESS_DENIED ); + } + if( file_info == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file information.", + function ); + + result = STATUS_UNSUCCESSFUL; + + goto on_error; + } + if( file_info->Context != (ULONG64) NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid file information - context already set.", + function ); + + result = STATUS_UNSUCCESSFUL; + + goto on_error; + } + if( mount_handle_get_file_entry_by_path( + fsapfsmount_mount_handle, + path, + (mount_file_entry_t **) &( file_info->Context ), + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry for path: %ls.", + function, + path ); + + result = STATUS_OBJECT_NAME_NOT_FOUND; + + goto on_error; + } + return( STATUS_SUCCESS ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + return( result ); +} + +#endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */ + +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) + +/* Opens a directory + * Returns 0 if successful or an error code otherwise + */ +int __stdcall mount_dokan_OpenDirectory( + const wchar_t *path, + DOKAN_FILE_INFO *file_info ) +{ + libcerror_error_t *error = NULL; + static char *function = "mount_dokan_OpenDirectory"; + int result = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: %ls\n", + function, + path ); + } +#endif + if( path == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file information.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info->Context != (ULONG64) NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid file information - context already set.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( mount_handle_get_file_entry_by_path( + fsapfsmount_mount_handle, + path, + (mount_file_entry_t **) &( file_info->Context ), + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry for path: %ls.", + function, + path ); + + result = MOUNT_DOKAN_ERROR_FILE_NOT_FOUND; + + goto on_error; + } + return( 0 ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + return( result ); +} + +#endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */ + +/* Closes a file or direcotry + * Returns 0 if successful or an error code otherwise + */ +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) +int __stdcall mount_dokan_CloseFile( + const wchar_t *path, + DOKAN_FILE_INFO *file_info ) +#else +NTSTATUS __stdcall mount_dokan_CloseFile( + const wchar_t *path, + DOKAN_FILE_INFO *file_info ) +#endif +{ + libcerror_error_t *error = NULL; + static char *function = "mount_dokan_CloseFile"; + int result = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: %ls\n", + function, + path ); + } +#endif + if( path == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file information.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info->Context != (ULONG64) NULL ) + { + if( mount_file_entry_free( + (mount_file_entry_t **) &( file_info->Context ), + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free file entry.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + } + return( 0 ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + return( result ); +} + +/* Reads a buffer of data at the specified offset + * Returns 0 if successful or an error code otherwise + */ +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) +int __stdcall mount_dokan_ReadFile( + const wchar_t *path, + void *buffer, + DWORD number_of_bytes_to_read, + DWORD *number_of_bytes_read, + LONGLONG offset, + DOKAN_FILE_INFO *file_info ) +#else +NTSTATUS __stdcall mount_dokan_ReadFile( + const wchar_t *path, + void *buffer, + DWORD number_of_bytes_to_read, + DWORD *number_of_bytes_read, + LONGLONG offset, + DOKAN_FILE_INFO *file_info ) +#endif +{ + libcerror_error_t *error = NULL; + static char *function = "mount_dokan_ReadFile"; + ssize_t read_count = 0; + int result = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: %ls\n", + function, + path ); + } +#endif + if( path == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( number_of_bytes_to_read > (DWORD) INT32_MAX ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid number of bytes to read value exceeds maximum.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( number_of_bytes_read == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid number of bytes read.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file information.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( file_info->Context == (ULONG64) NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid file information - missing context.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + read_count = mount_file_entry_read_buffer_at_offset( + (mount_file_entry_t *) file_info->Context, + buffer, + (size_t) number_of_bytes_to_read, + (off64_t) offset, + &error ); + + if( read_count < 0 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read from mount handle.", + function ); + + result = MOUNT_DOKAN_ERROR_READ_FAULT; + + goto on_error; + } + if( read_count > (size_t) INT32_MAX ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid read count value exceeds maximum.", + function ); + + result = MOUNT_DOKAN_ERROR_READ_FAULT; + + goto on_error; + } + /* Dokan does not require the read function to return ERROR_HANDLE_EOF + */ + *number_of_bytes_read = (DWORD) read_count; + + return( 0 ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + return( result ); +} + +/* Reads a directory + * Returns 0 if successful or an error code otherwise + */ +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) +int __stdcall mount_dokan_FindFiles( + const wchar_t *path, + PFillFindData fill_find_data, + DOKAN_FILE_INFO *file_info ) +#else +NTSTATUS __stdcall mount_dokan_FindFiles( + const wchar_t *path, + PFillFindData fill_find_data, + DOKAN_FILE_INFO *file_info ) +#endif +{ + WIN32_FIND_DATAW find_data; + + libcerror_error_t *error = NULL; + mount_file_entry_t *file_entry = NULL; + mount_file_entry_t *parent_file_entry = NULL; + mount_file_entry_t *sub_file_entry = NULL; + wchar_t *name = NULL; + static char *function = "mount_dokan_FindFiles"; + size_t name_size = 0; + int number_of_sub_file_entries = 0; + int result = 0; + int sub_file_entry_index = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: %ls\n", + function, + path ); + } +#endif + if( path == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( mount_handle_get_file_entry_by_path( + fsapfsmount_mount_handle, + path, + &file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry for path: %ls.", + function, + path ); + + result = MOUNT_DOKAN_ERROR_FILE_NOT_FOUND; + + goto on_error; + } + if( mount_dokan_filldir( + fill_find_data, + file_info, + L".", + 2, + &find_data, + file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set find data.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + result = mount_file_entry_get_parent_file_entry( + file_entry, + &parent_file_entry, + &error ); + + if( result == -1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve parent file entry.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_dokan_filldir( + fill_find_data, + file_info, + L"..", + 3, + &find_data, + parent_file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set find data.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_free( + &parent_file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free parent file entry.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_get_number_of_sub_file_entries( + file_entry, + &number_of_sub_file_entries, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub file entries.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + for( sub_file_entry_index = 0; + sub_file_entry_index < number_of_sub_file_entries; + sub_file_entry_index++ ) + { + if( mount_file_entry_get_sub_file_entry_by_index( + file_entry, + sub_file_entry_index, + &sub_file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub file entry: %d.", + function, + sub_file_entry_index ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_get_name_size( + sub_file_entry, + &name_size, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub file entry: %d name size.", + function, + sub_file_entry_index ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + name = wide_string_allocate( + name_size ); + + if( name == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create sub file entry: %d name.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_get_name( + sub_file_entry, + name, + name_size, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub file entry: %d name.", + function, + sub_file_entry_index ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_dokan_filldir( + fill_find_data, + file_info, + name, + name_size, + &find_data, + sub_file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set find data for sub file entry: %d.", + function, + sub_file_entry_index ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + memory_free( + name ); + + name = NULL; + + if( mount_file_entry_free( + &sub_file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free sub file entry: %d.", + function, + sub_file_entry_index ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + } + if( mount_file_entry_free( + &file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free file entry.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + return( 0 ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + if( name != NULL ) + { + memory_free( + name ); + } + if( sub_file_entry != NULL ) + { + mount_file_entry_free( + &sub_file_entry, + NULL ); + } + if( parent_file_entry != NULL ) + { + mount_file_entry_free( + &parent_file_entry, + NULL ); + } + if( file_entry != NULL ) + { + mount_file_entry_free( + &file_entry, + NULL ); + } + return( result ); +} + +/* Retrieves the file information + * Returns 0 if successful or an error code otherwise + */ +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) +int __stdcall mount_dokan_GetFileInformation( + const wchar_t *path, + BY_HANDLE_FILE_INFORMATION *file_information, + DOKAN_FILE_INFO *file_info FSAPFSTOOLS_ATTRIBUTE_UNUSED ) +#else +NTSTATUS __stdcall mount_dokan_GetFileInformation( + const wchar_t *path, + BY_HANDLE_FILE_INFORMATION *file_information, + DOKAN_FILE_INFO *file_info FSAPFSTOOLS_ATTRIBUTE_UNUSED ) +#endif +{ + libcerror_error_t *error = NULL; + mount_file_entry_t *file_entry = NULL; + static char *function = "mount_dokan_GetFileInformation"; + size64_t file_size = 0; + uint64_t access_time = 0; + uint64_t creation_time = 0; + uint64_t modification_time = 0; + uint16_t file_mode = 0; + int result = 0; + + FSAPFSTOOLS_UNREFERENCED_PARAMETER( file_info ) + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: %ls\n", + function, + path ); + } +#endif + if( path == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + result = MOUNT_DOKAN_ERROR_BAD_ARGUMENTS; + + goto on_error; + } + if( mount_handle_get_file_entry_by_path( + fsapfsmount_mount_handle, + path, + &file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry for path: %ls.", + function, + path ); + + result = MOUNT_DOKAN_ERROR_FILE_NOT_FOUND; + + goto on_error; + } + if( file_entry != NULL ) + { + if( mount_file_entry_get_size( + file_entry, + &file_size, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry size.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_get_file_mode( + file_entry, + &file_mode, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file mode.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_get_creation_time( + file_entry, + &creation_time, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve creation time.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_get_access_time( + file_entry, + &access_time, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve access time.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_get_modification_time( + file_entry, + &modification_time, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve modification time.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + } + if( mount_dokan_set_file_information( + file_information, + file_size, + file_mode, + creation_time, + access_time, + modification_time, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set file information.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + if( mount_file_entry_free( + &file_entry, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free file entry.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + return( 0 ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + if( file_entry != NULL ) + { + mount_file_entry_free( + &file_entry, + NULL ); + } + return( result ); +} + +/* Retrieves the volume information + * Returns 0 if successful or an error code otherwise + */ +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) +int __stdcall mount_dokan_GetVolumeInformation( + wchar_t *volume_name, + DWORD volume_name_size, + DWORD *volume_serial_number, + DWORD *maximum_filename_length, + DWORD *file_system_flags, + wchar_t *file_system_name, + DWORD file_system_name_size, + DOKAN_FILE_INFO *file_info FSAPFSTOOLS_ATTRIBUTE_UNUSED ) +#else +NTSTATUS __stdcall mount_dokan_GetVolumeInformation( + wchar_t *volume_name, + DWORD volume_name_size, + DWORD *volume_serial_number, + DWORD *maximum_filename_length, + DWORD *file_system_flags, + wchar_t *file_system_name, + DWORD file_system_name_size, + DOKAN_FILE_INFO *file_info FSAPFSTOOLS_ATTRIBUTE_UNUSED ) +#endif +{ + libcerror_error_t *error = NULL; + const wchar_t *name = NULL; + static char *function = "mount_dokan_GetVolumeInformation"; + size_t name_size = 0; + int result = 0; + + FSAPFSTOOLS_UNREFERENCED_PARAMETER( file_info ) + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: %ls\n", + function, + volume_name ); + } +#endif + name = L"FSAPFS"; + name_size = 1 + wide_string_length( + name ); + + if( ( volume_name != NULL ) + && ( volume_name_size > (DWORD) name_size ) ) + { + /* Using wcsncpy seems to cause strange behavior here + */ + if( memory_copy( + volume_name, + name, + name_size * sizeof( wchar_t ) ) == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy volume name.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + } + if( volume_serial_number != NULL ) + { + /* If this value contains 0 it can crash the system is this an issue in Dokan? + */ + *volume_serial_number = 0x19831116; + } + if( maximum_filename_length != NULL ) + { + *maximum_filename_length = 256; + } + if( file_system_flags != NULL ) + { + *file_system_flags = FILE_CASE_SENSITIVE_SEARCH + | FILE_CASE_PRESERVED_NAMES + | FILE_UNICODE_ON_DISK + | FILE_READ_ONLY_VOLUME; + } + name = L"Dokan"; + name_size = 1 + wide_string_length( + name ); + + if( ( file_system_name != NULL ) + && ( file_system_name_size > (DWORD) name_size ) ) + { + /* Using wcsncpy seems to cause strange behavior here + */ + if( memory_copy( + file_system_name, + name, + name_size * sizeof( wchar_t ) ) == NULL ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy file system name.", + function ); + + result = MOUNT_DOKAN_ERROR_GENERIC_FAILURE; + + goto on_error; + } + } + return( 0 ); + +on_error: + if( error != NULL ) + { + libcnotify_print_error_backtrace( + error ); + libcerror_error_free( + &error ); + } + return( result ); +} + +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) + +/* Unmounts the volume + * Returns 0 if successful or an error code otherwise + */ +int __stdcall mount_dokan_Unmount( + DOKAN_FILE_INFO *file_info FSAPFSTOOLS_ATTRIBUTE_UNUSED ) +{ + static char *function = "mount_dokan_Unmount"; + + FSAPFSTOOLS_UNREFERENCED_PARAMETER( file_info ) + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s\n", + function ); + } +#endif + return( 0 ); +} + +#endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */ + +#endif /* defined( HAVE_LIBDOKAN ) */ + diff -Nru libfsapfs-20181215/fsapfstools/mount_dokan.h libfsapfs-20190210/fsapfstools/mount_dokan.h --- libfsapfs-20181215/fsapfstools/mount_dokan.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_dokan.h 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,171 @@ +/* + * Mount tool dokan functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _MOUNT_DOKAN_H ) +#define _MOUNT_DOKAN_H + +#include +#include + +#if defined( HAVE_LIBDOKAN ) +#include +#endif + +#include "fsapfstools_libcerror.h" +#include "fsapfstools_libfsapfs.h" +#include "mount_file_entry.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +#if defined( HAVE_LIBDOKAN ) + +int mount_dokan_set_file_information( + BY_HANDLE_FILE_INFORMATION *file_information, + size64_t size, + uint16_t file_mode, + uint64_t creation_time, + uint64_t access_time, + uint64_t modification_time, + libcerror_error_t **error ); + +int mount_dokan_set_find_data( + WIN32_FIND_DATAW *find_data, + size64_t size, + uint16_t file_mode, + uint64_t creation_time, + uint64_t access_time, + uint64_t modification_time, + libcerror_error_t **error ); + +int mount_dokan_filldir( + PFillFindData fill_find_data, + DOKAN_FILE_INFO *file_info, + wchar_t *name, + size_t name_size, + WIN32_FIND_DATAW *find_data, + mount_file_entry_t *file_entry, + libcerror_error_t **error ); + +#if ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) + +int __stdcall mount_dokan_CreateFile( + const wchar_t *path, + DWORD desired_access, + DWORD share_mode, + DWORD creation_disposition, + DWORD attribute_flags, + DOKAN_FILE_INFO *file_info ); + +int __stdcall mount_dokan_OpenDirectory( + const wchar_t *path, + DOKAN_FILE_INFO *file_info ); + +int __stdcall mount_dokan_CloseFile( + const wchar_t *path, + DOKAN_FILE_INFO *file_info ); + +int __stdcall mount_dokan_ReadFile( + const wchar_t *path, + void *buffer, + DWORD number_of_bytes_to_read, + DWORD *number_of_bytes_read, + LONGLONG offset, + DOKAN_FILE_INFO *file_info ); + +int __stdcall mount_dokan_FindFiles( + const wchar_t *path, + PFillFindData fill_find_data, + DOKAN_FILE_INFO *file_info ); + +int __stdcall mount_dokan_GetFileInformation( + const wchar_t *path, + BY_HANDLE_FILE_INFORMATION *file_information, + DOKAN_FILE_INFO *file_info ); + +int __stdcall mount_dokan_GetVolumeInformation( + wchar_t *volume_name, + DWORD volume_name_size, + DWORD *volume_serial_number, + DWORD *maximum_filename_length, + DWORD *file_system_flags, + wchar_t *file_system_name, + DWORD file_system_name_size, + DOKAN_FILE_INFO *file_info ); + +int __stdcall mount_dokan_Unmount( + DOKAN_FILE_INFO *file_info ); + +#else + +NTSTATUS __stdcall mount_dokan_ZwCreateFile( + const wchar_t *path, + DOKAN_IO_SECURITY_CONTEXT *security_context, + ACCESS_MASK desired_access, + ULONG file_attributes, + ULONG share_access, + ULONG creation_disposition, + ULONG creation_options, + DOKAN_FILE_INFO *file_info ); + +NTSTATUS __stdcall mount_dokan_CloseFile( + const wchar_t *path, + DOKAN_FILE_INFO *file_info ); + +NTSTATUS __stdcall mount_dokan_ReadFile( + const wchar_t *path, + void *buffer, + DWORD number_of_bytes_to_read, + DWORD *number_of_bytes_read, + LONGLONG offset, + DOKAN_FILE_INFO *file_info ); + +NTSTATUS __stdcall mount_dokan_FindFiles( + const wchar_t *path, + PFillFindData fill_find_data, + DOKAN_FILE_INFO *file_info ); + +NTSTATUS __stdcall mount_dokan_GetFileInformation( + const wchar_t *path, + BY_HANDLE_FILE_INFORMATION *file_information, + DOKAN_FILE_INFO *file_info ); + +NTSTATUS __stdcall mount_dokan_GetVolumeInformation( + wchar_t *volume_name, + DWORD volume_name_size, + DWORD *volume_serial_number, + DWORD *maximum_filename_length, + DWORD *file_system_flags, + wchar_t *file_system_name, + DWORD file_system_name_size, + DOKAN_FILE_INFO *file_info ); + +#endif /* ( DOKAN_VERSION >= 600 ) && ( DOKAN_VERSION < 800 ) */ + +#endif /* defined( HAVE_LIBDOKAN ) */ + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _MOUNT_DOKAN_H ) */ + diff -Nru libfsapfs-20181215/fsapfstools/mount_file_entry.c libfsapfs-20190210/fsapfstools/mount_file_entry.c --- libfsapfs-20181215/fsapfstools/mount_file_entry.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_file_entry.c 2019-02-06 20:14:03.000000000 +0000 @@ -0,0 +1,1106 @@ +/* + * Mount file entry + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#if defined( HAVE_SYS_STAT_H ) +#include +#endif + +#include "fsapfstools_libcerror.h" +#include "fsapfstools_libfsapfs.h" +#include "mount_file_entry.h" +#include "mount_file_system.h" + +#if !defined( S_IFDIR ) +#define S_IFDIR 0x4000 +#endif + +#if !defined( S_IFREG ) +#define S_IFREG 0x8000 +#endif + +/* Creates a file entry + * Make sure the value file_entry is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_initialize( + mount_file_entry_t **file_entry, + mount_file_system_t *file_system, + const system_character_t *name, + size_t name_length, + libfsapfs_file_entry_t *fsapfs_file_entry, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_initialize"; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( *file_entry != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid file entry value already set.", + function ); + + return( -1 ); + } + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( name_length > (size_t) ( SSIZE_MAX - 1 ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid name length value exceeds maximum.", + function ); + + return( -1 ); + } + *file_entry = memory_allocate_structure( + mount_file_entry_t ); + + if( *file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create file entry.", + function ); + + goto on_error; + } + if( memory_set( + *file_entry, + 0, + sizeof( mount_file_entry_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear file entry.", + function ); + + memory_free( + *file_entry ); + + *file_entry = NULL; + + return( -1 ); + } + ( *file_entry )->file_system = file_system; + + if( name != NULL ) + { + ( *file_entry )->name = system_string_allocate( + name_length + 1 ); + + if( ( *file_entry )->name == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create name string.", + function ); + + goto on_error; + } + if( name_length > 0 ) + { + if( system_string_copy( + ( *file_entry )->name, + name, + name_length ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_COPY_FAILED, + "%s: unable to copy name.", + function ); + + goto on_error; + } + } + ( *file_entry )->name[ name_length ] = 0; + + ( *file_entry )->name_size = name_length + 1; + } + ( *file_entry )->fsapfs_file_entry = fsapfs_file_entry; + + return( 1 ); + +on_error: + if( *file_entry != NULL ) + { + if( ( *file_entry )->name != NULL ) + { + memory_free( + ( *file_entry )->name ); + } + memory_free( + *file_entry ); + + *file_entry = NULL; + } + return( -1 ); +} + +/* Frees a file entry + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_free( + mount_file_entry_t **file_entry, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_free"; + int result = 1; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( *file_entry != NULL ) + { + if( ( *file_entry )->name != NULL ) + { + memory_free( + ( *file_entry )->name ); + } + if( libfsapfs_file_entry_free( + &( ( *file_entry )->fsapfs_file_entry ), + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free file entry.", + function ); + + result = -1; + } + memory_free( + *file_entry ); + + *file_entry = NULL; + } + return( result ); +} + +/* Retrieves the parent file entry + * Returns 1 if successful, 0 if no such file entry or -1 on error + */ +int mount_file_entry_get_parent_file_entry( + mount_file_entry_t *file_entry, + mount_file_entry_t **parent_file_entry, + libcerror_error_t **error ) +{ + libfsapfs_file_entry_t *parent_fsapfs_file_entry = NULL; + system_character_t *filename = NULL; + static char *function = "mount_file_entry_get_parent_file_entry"; + size_t filename_size = 0; + int result = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( parent_file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid parent file entry.", + function ); + + return( -1 ); + } + if( *parent_file_entry != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid parent file entry value already set.", + function ); + + return( -1 ); + } + result = libfsapfs_file_entry_get_parent_file_entry( + file_entry->fsapfs_file_entry, + &parent_fsapfs_file_entry, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve parent file entry.", + function ); + + return( -1 ); + } + else if( result != 0 ) + { + if( mount_file_system_get_filename_from_file_entry( + file_entry->file_system, + parent_fsapfs_file_entry, + &filename, + &filename_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve filename of parent file entry.", + function ); + + goto on_error; + } + if( mount_file_entry_initialize( + parent_file_entry, + file_entry->file_system, + filename, + filename_size - 1, + parent_fsapfs_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to initialize parent file entry.", + function ); + + goto on_error; + } + } + if( filename != NULL ) + { + memory_free( + filename ); + } + return( result ); + +on_error: + if( filename != NULL ) + { + memory_free( + filename ); + } + if( parent_fsapfs_file_entry != NULL ) + { + libfsapfs_file_entry_free( + &parent_fsapfs_file_entry, + NULL ); + } + return( -1 ); +} + +/* Retrieves the creation date and time + * On Windows the timestamp is an unsigned 64-bit FILETIME timestamp + * otherwise the timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_creation_time( + mount_file_entry_t *file_entry, + uint64_t *creation_time, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_creation_time"; + int64_t posix_time = 0; + +#if defined( WINAPI ) + uint64_t filetime = 0; +#endif + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( creation_time == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid creation time.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_creation_time( + file_entry->fsapfs_file_entry, + &posix_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve creation time from file entry.", + function ); + + return( -1 ); + } +#if defined( WINAPI ) + if( posix_time != 0 ) + { + /* Convert the POSIX nanoseconds timestamp into a FILETIME timestamp + */ + filetime = (uint64_t) ( ( posix_time / 100 ) + 116444736000000000L ); + } + *creation_time = filetime; +#else + *creation_time = (uint64_t) posix_time; +#endif + return( 1 ); +} + +/* Retrieves the access date and time + * On Windows the timestamp is an unsigned 64-bit FILETIME timestamp + * otherwise the timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_access_time( + mount_file_entry_t *file_entry, + uint64_t *access_time, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_access_time"; + int64_t posix_time = 0; + +#if defined( WINAPI ) + uint64_t filetime = 0; +#endif + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( access_time == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid access time.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_access_time( + file_entry->fsapfs_file_entry, + &posix_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve access time from file entry.", + function ); + + return( -1 ); + } +#if defined( WINAPI ) + if( posix_time != 0 ) + { + /* Convert the POSIX nanoseconds timestamp into a FILETIME timestamp + */ + filetime = (uint64_t) ( ( posix_time / 100 ) + 116444736000000000L ); + } + *access_time = filetime; +#else + *access_time = (uint64_t) posix_time; +#endif + return( 1 ); +} + +/* Retrieves the modification date and time + * On Windows the timestamp is an unsigned 64-bit FILETIME timestamp + * otherwise the timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_modification_time( + mount_file_entry_t *file_entry, + uint64_t *modification_time, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_modification_time"; + int64_t posix_time = 0; + +#if defined( WINAPI ) + uint64_t filetime = 0; +#endif + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( modification_time == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid modification time.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_modification_time( + file_entry->fsapfs_file_entry, + &posix_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve modification time from file entry.", + function ); + + return( -1 ); + } +#if defined( WINAPI ) + if( posix_time != 0 ) + { + /* Convert the POSIX nanoseconds timestamp into a FILETIME timestamp + */ + filetime = (uint64_t) ( ( posix_time / 100 ) + 116444736000000000L ); + } + *modification_time = filetime; +#else + *modification_time = (uint64_t) posix_time; +#endif + return( 1 ); +} + +/* Retrieves the inode change date and time + * On Windows the timestamp is an unsigned 64-bit FILETIME timestamp + * otherwise the timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_inode_change_time( + mount_file_entry_t *file_entry, + uint64_t *inode_change_time, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_inode_change_time"; + int64_t posix_time = 0; + +#if defined( WINAPI ) + uint64_t filetime = 0; +#endif + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( inode_change_time == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid inode change time.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_inode_change_time( + file_entry->fsapfs_file_entry, + &posix_time, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve inode change time from file entry.", + function ); + + return( -1 ); + } +#if defined( WINAPI ) + if( posix_time != 0 ) + { + /* Convert the POSIX nanoseconds timestamp into a FILETIME timestamp + */ + filetime = (uint64_t) ( ( posix_time / 100 ) + 116444736000000000L ); + } + *inode_change_time = filetime; +#else + *inode_change_time = (uint64_t) posix_time; +#endif + return( 1 ); +} + +/* Retrieves the file mode + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_file_mode( + mount_file_entry_t *file_entry, + uint16_t *file_mode, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_file_mode"; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( file_mode == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file mode.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_file_mode( + file_entry->fsapfs_file_entry, + file_mode, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file mode.", + function ); + + return( -1 ); + } + /* The APFS file mode matches that of POSIX, with the exception of S_IFWHT + */ + if( ( *file_mode & 0xf000 ) == 0xe000 ) + { + *file_mode = S_IFREG | ( *file_mode & 0x0fff ); + } + return( 1 ); +} + +/* Retrieves the size of the name + * The returned size includes the end of string character + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_name_size( + mount_file_entry_t *file_entry, + size_t *string_size, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_name_size"; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( string_size == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid string size.", + function ); + + return( -1 ); + } + *string_size = file_entry->name_size; + + return( 1 ); +} + +/* Retrieves the name + * The size should include the end of string character + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_name( + mount_file_entry_t *file_entry, + system_character_t *string, + size_t string_size, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_name"; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( file_entry->name == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid file entry - missing name.", + function ); + + return( -1 ); + } + if( string == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid string.", + function ); + + return( -1 ); + } + if( string_size > (size_t) SSIZE_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid string size value exceeds maximum.", + function ); + + return( -1 ); + } + if( string_size < file_entry->name_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, + "%s: invalid string size value too small.", + function ); + + return( -1 ); + } + if( system_string_copy( + string, + file_entry->name, + file_entry->name_size ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_COPY_FAILED, + "%s: unable to copy name.", + function ); + + return( -1 ); + } + string[ file_entry->name_size - 1 ] = 0; + + return( 1 ); +} + +/* Retrieves the symbolic link target + * The size should include the end of string character + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_symbolic_link_target( + mount_file_entry_t *file_entry, + system_character_t *string, + size_t string_size, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_symbolic_link_target"; + int result = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libfsapfs_file_entry_get_utf16_symbolic_link_target( + file_entry->fsapfs_file_entry, + (uint16_t *) string, + string_size, + error ); +#else + result = libfsapfs_file_entry_get_utf8_symbolic_link_target( + file_entry->fsapfs_file_entry, + (uint8_t *) string, + string_size, + error ); +#endif + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve symbolic link target string.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Retrieves the number of sub file entries + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_number_of_sub_file_entries( + mount_file_entry_t *file_entry, + int *number_of_sub_file_entries, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_number_of_sub_file_entries"; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_number_of_sub_file_entries( + file_entry->fsapfs_file_entry, + number_of_sub_file_entries, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub file entries.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Retrieves the sub file entry for the specific index + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_sub_file_entry_by_index( + mount_file_entry_t *file_entry, + int sub_file_entry_index, + mount_file_entry_t **sub_file_entry, + libcerror_error_t **error ) +{ + libfsapfs_file_entry_t *sub_fsapfs_file_entry = NULL; + system_character_t *filename = NULL; + static char *function = "mount_file_entry_get_sub_file_entry_by_index"; + size_t filename_size = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( sub_file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid sub file entry.", + function ); + + return( -1 ); + } + if( *sub_file_entry != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid sub file entry value already set.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_sub_file_entry_by_index( + file_entry->fsapfs_file_entry, + sub_file_entry_index, + &sub_fsapfs_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub file entry: %d.", + function, + sub_file_entry_index ); + + goto on_error; + } + if( mount_file_system_get_filename_from_file_entry( + file_entry->file_system, + sub_fsapfs_file_entry, + &filename, + &filename_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve filename of sub file entry: %d.", + function, + sub_file_entry_index ); + + goto on_error; + } + if( mount_file_entry_initialize( + sub_file_entry, + file_entry->file_system, + filename, + filename_size - 1, + sub_fsapfs_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to initialize sub file entry: %d.", + function, + sub_file_entry_index ); + + goto on_error; + } + if( filename != NULL ) + { + memory_free( + filename ); + } + return( 1 ); + +on_error: + if( filename != NULL ) + { + memory_free( + filename ); + } + if( sub_fsapfs_file_entry != NULL ) + { + libfsapfs_file_entry_free( + &sub_fsapfs_file_entry, + NULL ); + } + return( -1 ); +} + +/* Reads data at a specific offset + * Returns the number of bytes read or -1 on error + */ +ssize_t mount_file_entry_read_buffer_at_offset( + mount_file_entry_t *file_entry, + void *buffer, + size_t buffer_size, + off64_t offset, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_read_buffer_at_offset"; + ssize_t read_count = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + read_count = libfsapfs_file_entry_read_buffer_at_offset( + file_entry->fsapfs_file_entry, + buffer, + buffer_size, + offset, + error ); + + if( read_count < 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read buffer at offset: %" PRIi64 " (0x%08" PRIx64 ") from file entry.", + function, + offset, + offset ); + + return( -1 ); + } + return( read_count ); +} + +/* Retrieves the size + * Returns 1 if successful or -1 on error + */ +int mount_file_entry_get_size( + mount_file_entry_t *file_entry, + size64_t *size, + libcerror_error_t **error ) +{ + static char *function = "mount_file_entry_get_size"; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + if( libfsapfs_file_entry_get_size( + file_entry->fsapfs_file_entry, + size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve size from file entry.", + function ); + + return( -1 ); + } + return( 1 ); +} + diff -Nru libfsapfs-20181215/fsapfstools/mount_file_entry.h libfsapfs-20190210/fsapfstools/mount_file_entry.h --- libfsapfs-20181215/fsapfstools/mount_file_entry.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_file_entry.h 2019-02-06 20:14:03.000000000 +0000 @@ -0,0 +1,144 @@ +/* + * Mount file entry + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _MOUNT_FILE_ENTRY_H ) +#define _MOUNT_FILE_ENTRY_H + +#include +#include + +#include "fsapfstools_libcerror.h" +#include "fsapfstools_libfsapfs.h" +#include "mount_file_system.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct mount_file_entry mount_file_entry_t; + +struct mount_file_entry +{ + /* The file system + */ + mount_file_system_t *file_system; + + /* The name + */ + system_character_t *name; + + /* The name size + */ + size_t name_size; + + /* The file entry + */ + libfsapfs_file_entry_t *fsapfs_file_entry; +}; + +int mount_file_entry_initialize( + mount_file_entry_t **file_entry, + mount_file_system_t *file_system, + const system_character_t *name, + size_t name_length, + libfsapfs_file_entry_t *fsapfs_file_entry, + libcerror_error_t **error ); + +int mount_file_entry_free( + mount_file_entry_t **file_entry, + libcerror_error_t **error ); + +int mount_file_entry_get_parent_file_entry( + mount_file_entry_t *file_entry, + mount_file_entry_t **parent_file_entry, + libcerror_error_t **error ); + +int mount_file_entry_get_creation_time( + mount_file_entry_t *file_entry, + uint64_t *creation_time, + libcerror_error_t **error ); + +int mount_file_entry_get_access_time( + mount_file_entry_t *file_entry, + uint64_t *access_time, + libcerror_error_t **error ); + +int mount_file_entry_get_modification_time( + mount_file_entry_t *file_entry, + uint64_t *modification_time, + libcerror_error_t **error ); + +int mount_file_entry_get_inode_change_time( + mount_file_entry_t *file_entry, + uint64_t *inode_change_time, + libcerror_error_t **error ); + +int mount_file_entry_get_file_mode( + mount_file_entry_t *file_entry, + uint16_t *file_mode, + libcerror_error_t **error ); + +int mount_file_entry_get_name_size( + mount_file_entry_t *file_entry, + size_t *string_size, + libcerror_error_t **error ); + +int mount_file_entry_get_name( + mount_file_entry_t *file_entry, + system_character_t *string, + size_t string_size, + libcerror_error_t **error ); + +int mount_file_entry_get_symbolic_link_target( + mount_file_entry_t *file_entry, + system_character_t *string, + size_t string_size, + libcerror_error_t **error ); + +int mount_file_entry_get_number_of_sub_file_entries( + mount_file_entry_t *file_entry, + int *number_of_sub_entries, + libcerror_error_t **error ); + +int mount_file_entry_get_sub_file_entry_by_index( + mount_file_entry_t *file_entry, + int sub_file_entry_index, + mount_file_entry_t **sub_file_entry, + libcerror_error_t **error ); + +ssize_t mount_file_entry_read_buffer_at_offset( + mount_file_entry_t *file_entry, + void *buffer, + size_t buffer_size, + off64_t offset, + libcerror_error_t **error ); + +int mount_file_entry_get_size( + mount_file_entry_t *file_entry, + size64_t *size, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _MOUNT_FILE_ENTRY_H ) */ + diff -Nru libfsapfs-20181215/fsapfstools/mount_file_system.c libfsapfs-20190210/fsapfstools/mount_file_system.c --- libfsapfs-20181215/fsapfstools/mount_file_system.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_file_system.c 2019-02-06 20:14:03.000000000 +0000 @@ -0,0 +1,1295 @@ +/* + * Mount file system + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#if defined( HAVE_SYS_STAT_H ) +#include +#endif + +#if defined( TIME_WITH_SYS_TIME ) +#include +#include +#elif defined( HAVE_SYS_TIME_H ) +#include +#else +#include +#endif + +#include "fsapfstools_libcerror.h" +#include "fsapfstools_libcpath.h" +#include "fsapfstools_libfsapfs.h" +#include "fsapfstools_libuna.h" +#include "mount_file_system.h" + +/* Creates a file system + * Make sure the value file_system is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int mount_file_system_initialize( + mount_file_system_t **file_system, + libcerror_error_t **error ) +{ +#if defined( WINAPI ) + FILETIME filetime; + SYSTEMTIME systemtime; + +#elif defined( HAVE_CLOCK_GETTIME ) + struct timespec time_structure; +#endif + + static char *function = "mount_file_system_initialize"; + +#if defined( WINAPI ) + DWORD error_code = 0; +#else + int64_t timestamp = 0; +#endif + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( *file_system != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid file system value already set.", + function ); + + return( -1 ); + } + *file_system = memory_allocate_structure( + mount_file_system_t ); + + if( *file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create file system.", + function ); + + goto on_error; + } + if( memory_set( + *file_system, + 0, + sizeof( mount_file_system_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear file system.", + function ); + + memory_free( + *file_system ); + + *file_system = NULL; + + return( -1 ); + } +#if defined( WINAPI ) + if( memory_set( + &systemtime, + 0, + sizeof( SYSTEMTIME ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear systemtime.", + function ); + + goto on_error; + } + GetSystemTime( + &systemtime ); + + if( SystemTimeToFileTime( + &systemtime, + &filetime ) == 0 ) + { + error_code = GetLastError(); + + libcerror_system_set_error( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + error_code, + "%s: unable to retrieve FILETIME of current time.", + function ); + + goto on_error; + } + ( *file_system )->mounted_timestamp = ( (uint64_t) filetime.dwHighDateTime << 32 ) | filetime.dwLowDateTime; + +#elif defined( HAVE_CLOCK_GETTIME ) + if( clock_gettime( + CLOCK_REALTIME, + &time_structure ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve current time structure.", + function ); + + goto on_error; + } + timestamp = ( (int64_t) time_structure.tv_sec * 1000000000 ) + time_structure.tv_nsec; + + ( *file_system )->mounted_timestamp = (uint64_t) timestamp; + +#else + timestamp = (int64_t) time( NULL ); + + if( timestamp == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve current time.", + function ); + + goto on_error; + } + timestamp *= 1000000000; + + ( *file_system )->mounted_timestamp = (uint64_t) timestamp; + +#endif /* defined( HAVE_CLOCK_GETTIME ) */ + + return( 1 ); + +on_error: + if( *file_system != NULL ) + { + memory_free( + *file_system ); + + *file_system = NULL; + } + return( -1 ); +} + +/* Frees a file system + * Returns 1 if successful or -1 on error + */ +int mount_file_system_free( + mount_file_system_t **file_system, + libcerror_error_t **error ) +{ + static char *function = "mount_file_system_free"; + int result = 1; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( *file_system != NULL ) + { + memory_free( + *file_system ); + + *file_system = NULL; + } + return( result ); +} + +/* Signals the mount volume system to abort + * Returns 1 if successful or -1 on error + */ +int mount_file_system_signal_abort( + mount_file_system_t *file_system, + libcerror_error_t **error ) +{ + static char *function = "mount_file_system_signal_abort"; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( file_system->fsapfs_volume != NULL ) + { + if( libfsapfs_volume_signal_abort( + file_system->fsapfs_volume, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to signal volume to abort.", + function ); + + return( -1 ); + } + } + return( 1 ); +} + +/* Sets the volume + * Returns 1 if successful or -1 on error + */ +int mount_file_system_set_volume( + mount_file_system_t *file_system, + libfsapfs_volume_t *fsapfs_volume, + libcerror_error_t **error ) +{ + static char *function = "mount_file_system_set_volume"; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + file_system->fsapfs_volume = fsapfs_volume; + + return( 1 ); +} + +/* Retrieves the volume + * Returns 1 if successful or -1 on error + */ +int mount_file_system_get_volume( + mount_file_system_t *file_system, + libfsapfs_volume_t **fsapfs_volume, + libcerror_error_t **error ) +{ + static char *function = "mount_file_system_get_volume"; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( fsapfs_volume == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid volume.", + function ); + + return( -1 ); + } + *fsapfs_volume = file_system->fsapfs_volume; + + return( 1 ); +} + +/* Retrieves the mounted timestamp + * On Windows the timestamp is an unsigned 64-bit FILETIME timestamp + * otherwise the timestamp is a signed 64-bit POSIX date and time value in number of nanoseconds + * Returns 1 if successful or -1 on error + */ +int mount_file_system_get_mounted_timestamp( + mount_file_system_t *file_system, + uint64_t *mounted_timestamp, + libcerror_error_t **error ) +{ + static char *function = "mount_file_system_get_mounted_timestamp"; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( mounted_timestamp == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid mounted timestamp.", + function ); + + return( -1 ); + } + *mounted_timestamp = file_system->mounted_timestamp; + + return( 1 ); +} + +/* Retrieves the file entry path from the path + * Returns 1 if successful or -1 on error + */ +int mount_file_system_get_file_entry_path_from_path( + mount_file_system_t *file_system, + const system_character_t *path, + size_t path_length, + system_character_t **file_entry_path, + size_t *file_entry_path_size, + libcerror_error_t **error ) +{ + system_character_t *safe_file_entry_path = NULL; + static char *function = "mount_file_system_get_file_entry_path_from_path"; + libuna_unicode_character_t unicode_character = 0; + system_character_t character = 0; + system_character_t escape_character = 0; + system_character_t hex_digit = 0; + system_character_t hex_value = 0; + size_t file_entry_path_index = 0; + size_t path_index = 0; + size_t safe_file_entry_path_size = 0; + int result = 0; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( path == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path.", + function ); + + return( -1 ); + } + if( path_length == 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid path length.", + function ); + + return( -1 ); + } + if( path_length > (size_t) ( SSIZE_MAX - 1 ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid path length value exceeds maximum.", + function ); + + return( -1 ); + } + if( file_entry_path == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry path.", + function ); + + return( -1 ); + } + if( file_entry_path_size == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry path size.", + function ); + + return( -1 ); + } + if( path[ 0 ] != (system_character_t) LIBCPATH_SEPARATOR ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported path - path is not absolute.", + function ); + + return( -1 ); + } + *file_entry_path = NULL; + *file_entry_path_size = 0; + + safe_file_entry_path_size = path_length + 1; + + if( safe_file_entry_path_size > (size_t) ( SSIZE_MAX / sizeof( system_character_t ) ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid file entry path size value exceeds maximum.", + function ); + + goto on_error; + } + safe_file_entry_path = system_string_allocate( + safe_file_entry_path_size ); + + if( safe_file_entry_path == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create file entry path.", + function ); + + goto on_error; + } +#if defined( WINAPI ) + escape_character = (system_character_t) '^'; +#else + escape_character = (system_character_t) '\\'; +#endif + + while( path_index < path_length ) + { +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libuna_unicode_character_copy_from_utf16( + &unicode_character, + (libuna_utf16_character_t *) path, + path_length, + &path_index, + error ); +#else + result = libuna_unicode_character_copy_from_utf8( + &unicode_character, + (libuna_utf8_character_t *) path, + path_length, + &path_index, + error ); +#endif + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_INPUT_FAILED, + "%s: unable to copy Unicode character from path.", + function ); + + goto on_error; + } + /* On Windows replaces: + * ^^ by ^ + * ^x5c by \ + * ^x## by values <= 0x1f and 0x7f + * + * On other platforms replaces: + * \\ by \ + * \x2f by / + * \x## by values <= 0x1f and 0x7f + * / by \ + */ + if( unicode_character == (libuna_unicode_character_t) escape_character ) + { + if( ( path_index + 1 ) > path_length ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid path index value out of bounds.", + function ); + + goto on_error; + } + character = path[ path_index++ ]; + +#if defined( WINAPI ) + if( ( character != escape_character ) + && ( character != (system_character_t) 'X' ) + && ( character != (system_character_t) 'x' ) ) +#else + if( ( character != escape_character ) + && ( character != (system_character_t) 'x' ) ) +#endif + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported path - invalid character: %" PRIc_SYSTEM " after escape character.", + function, + character ); + + goto on_error; + } + if( character == escape_character ) + { + if( ( file_entry_path_index + 1 ) > safe_file_entry_path_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid file entry path index value out of bounds.", + function ); + + goto on_error; + } + safe_file_entry_path[ file_entry_path_index++ ] = escape_character; + } + else + { + if( ( path_index + 2 ) > path_length ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid path index value out of bounds.", + function ); + + goto on_error; + } + hex_digit = path[ path_index++ ]; + + if( ( hex_digit >= (system_character_t) '0' ) + && ( hex_digit <= (system_character_t) '9' ) ) + { + hex_value = hex_digit - (system_character_t) '0'; + } +#if defined( WINAPI ) + else if( ( hex_digit >= (system_character_t) 'A' ) + && ( hex_digit <= (system_character_t) 'F' ) ) + { + hex_value = hex_digit - (system_character_t) 'A' + 10; + } +#endif + else if( ( hex_digit >= (system_character_t) 'a' ) + && ( hex_digit <= (system_character_t) 'f' ) ) + { + hex_value = hex_digit - (system_character_t) 'a' + 10; + } + else + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported path - invalid hexadecimal character: %" PRIc_SYSTEM " after escape character.", + function, + hex_digit ); + + goto on_error; + } + hex_value <<= 4; + + hex_digit = path[ path_index++ ]; + + if( ( hex_digit >= (system_character_t) '0' ) + && ( hex_digit <= (system_character_t) '9' ) ) + { + hex_value |= hex_digit - (system_character_t) '0'; + } +#if defined( WINAPI ) + else if( ( hex_digit >= (system_character_t) 'A' ) + && ( hex_digit <= (system_character_t) 'F' ) ) + { + hex_value = hex_digit - (system_character_t) 'A' + 10; + } +#endif + else if( ( hex_digit >= (system_character_t) 'a' ) + && ( hex_digit <= (system_character_t) 'f' ) ) + { + hex_value |= hex_digit - (system_character_t) 'a' + 10; + } + else + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported path - invalid hexadecimal character: %" PRIc_SYSTEM " after escape character.", + function, + hex_digit ); + + goto on_error; + } +#if defined( WINAPI ) + if( ( hex_value == 0 ) + || ( ( hex_value > 0x1f ) + && ( hex_value != 0x5c ) + && ( hex_value != 0x7f ) ) ) +#else + if( ( hex_value == 0 ) + || ( ( hex_value > 0x1f ) + && ( hex_value != 0x2f ) + && ( hex_value != 0x7f ) ) ) +#endif + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid escaped character value out of bounds.", + function ); + + goto on_error; + } + if( ( file_entry_path_index + 1 ) > safe_file_entry_path_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid file entry path index value out of bounds.", + function ); + + goto on_error; + } + safe_file_entry_path[ file_entry_path_index++ ] = hex_value; + } + } +#if !defined( WINAPI ) + else if( unicode_character == (system_character_t) '\\' ) + { + if( ( file_entry_path_index + 1 ) > safe_file_entry_path_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid file entry path index value out of bounds.", + function ); + + goto on_error; + } + safe_file_entry_path[ file_entry_path_index++ ] = (system_character_t) '\\'; + } +#endif + else + { +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libuna_unicode_character_copy_to_utf16( + unicode_character, + (libuna_utf16_character_t *) safe_file_entry_path, + safe_file_entry_path_size, + &file_entry_path_index, + error ); +#else + result = libuna_unicode_character_copy_to_utf8( + unicode_character, + (libuna_utf8_character_t *) safe_file_entry_path, + safe_file_entry_path_size, + &file_entry_path_index, + error ); +#endif + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_INPUT_FAILED, + "%s: unable to copy Unicode character to file entry path.", + function ); + + goto on_error; + } + } + } + if( file_entry_path_index >= safe_file_entry_path_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid file entry path index value out of bounds.", + function ); + + goto on_error; + } + safe_file_entry_path[ file_entry_path_index ] = 0; + + *file_entry_path = safe_file_entry_path; + *file_entry_path_size = safe_file_entry_path_size; + + return( 1 ); + +on_error: + if( safe_file_entry_path != NULL ) + { + memory_free( + safe_file_entry_path ); + } + return( -1 ); +} +/* Retrieves the file entry of a specific path + * Returns 1 if successful, 0 if no such file entry or -1 on error + */ +int mount_file_system_get_file_entry_by_path( + mount_file_system_t *file_system, + const system_character_t *path, + size_t path_length, + libfsapfs_file_entry_t **fsapfs_file_entry, + libcerror_error_t **error ) +{ + system_character_t *file_entry_path = NULL; + static char *function = "mount_file_system_get_file_entry_by_path"; + size_t file_entry_path_length = 0; + size_t file_entry_path_size = 0; + int result = 0; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( mount_file_system_get_file_entry_path_from_path( + file_system, + path, + path_length, + &file_entry_path, + &file_entry_path_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry path from path.", + function ); + + goto on_error; + } + if( file_entry_path == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing file entry path.", + function ); + + goto on_error; + } + /* Need to determine length here since size is based on the worst case + */ + file_entry_path_length = system_string_length( + file_entry_path ); + +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libfsapfs_volume_get_file_entry_by_utf16_path( + file_system->fsapfs_volume, + (uint16_t *) file_entry_path, + file_entry_path_length, + fsapfs_file_entry, + error ); +#else + result = libfsapfs_volume_get_file_entry_by_utf8_path( + file_system->fsapfs_volume, + (uint8_t *) file_entry_path, + file_entry_path_length, + fsapfs_file_entry, + error ); +#endif + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry ", + function ); + + goto on_error; + } + memory_free( + file_entry_path ); + + return( result ); + +on_error: + if( file_entry_path != NULL ) + { + memory_free( + file_entry_path ); + } + return( -1 ); +} + +/* Retrieves a filename from the name + * Returns 1 if successful or -1 on error + */ +int mount_file_system_get_filename_from_name( + mount_file_system_t *file_system, + const system_character_t *name, + size_t name_length, + system_character_t **filename, + size_t *filename_size, + libcerror_error_t **error ) +{ + system_character_t *safe_filename = NULL; + static char *function = "mount_file_system_get_filename_from_name"; + libuna_unicode_character_t unicode_character = 0; + system_character_t escape_character = 0; + system_character_t hex_digit = 0; + size_t filename_index = 0; + size_t name_index = 0; + size_t safe_filename_size = 0; + int result = 0; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } + if( name == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid name.", + function ); + + return( -1 ); + } + if( name_length > (size_t) ( SSIZE_MAX - 1 ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid name length value exceeds maximum.", + function ); + + return( -1 ); + } + if( filename == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid filename.", + function ); + + return( -1 ); + } + if( filename_size == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid filename size.", + function ); + + return( -1 ); + } + *filename = NULL; + *filename_size = 0; + + safe_filename_size = ( name_length * 4 ) + 1; + + if( safe_filename_size > (size_t) ( SSIZE_MAX / sizeof( system_character_t ) ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid filename size value exceeds maximum.", + function ); + + goto on_error; + } + safe_filename = system_string_allocate( + safe_filename_size ); + + if( safe_filename == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create filename.", + function ); + + goto on_error; + } +#if defined( WINAPI ) + escape_character = (system_character_t) '^'; +#else + escape_character = (system_character_t) '\\'; +#endif + + while( name_index < name_length ) + { +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libuna_unicode_character_copy_from_utf16( + &unicode_character, + (libuna_utf16_character_t *) name, + name_length, + &name_index, + error ); +#else + result = libuna_unicode_character_copy_from_utf8( + &unicode_character, + (libuna_utf8_character_t *) name, + name_length, + &name_index, + error ); +#endif + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_INPUT_FAILED, + "%s: unable to copy Unicode character from name.", + function ); + + goto on_error; + } + if( unicode_character == 0 ) + { + break; + } + /* On Windows replaces: + * values <= 0x1f and 0x7f by ^x## + * \ by ^x5c + * ^ by ^^ + * + * On other platforms replaces: + * values <= 0x1f and 0x7f by \x## + * / by \x2f + * \ by \\ + */ +#if defined( WINAPI ) + if( ( unicode_character <= 0x1f ) + || ( unicode_character == 0x5c ) + || ( unicode_character == 0x7f ) ) +#else + if( ( unicode_character <= 0x1f ) + || ( unicode_character == 0x2f ) + || ( unicode_character == 0x7f ) ) +#endif + { + if( ( filename_index + 4 ) > safe_filename_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid filename index value out of bounds.", + function ); + + goto on_error; + } + safe_filename[ filename_index++ ] = escape_character; + safe_filename[ filename_index++ ] = (system_character_t) 'x'; + + hex_digit = unicode_character >> 4; + + if( hex_digit <= 0x09 ) + { + safe_filename[ filename_index++ ] = (system_character_t) '0' + hex_digit; + } + else + { + safe_filename[ filename_index++ ] = (system_character_t) 'a' + hex_digit - 10; + } + hex_digit = unicode_character & 0x0f; + + if( hex_digit <= 0x09 ) + { + safe_filename[ filename_index++ ] = (system_character_t) '0' + hex_digit; + } + else + { + safe_filename[ filename_index++ ] = (system_character_t) 'a' + hex_digit - 10; + } + } + else if( unicode_character == (libuna_unicode_character_t) escape_character ) + { + if( ( filename_index + 2 ) > safe_filename_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid filename index value out of bounds.", + function ); + + goto on_error; + } + safe_filename[ filename_index++ ] = escape_character; + safe_filename[ filename_index++ ] = escape_character; + } + else + { +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libuna_unicode_character_copy_to_utf16( + unicode_character, + (libuna_utf16_character_t *) safe_filename, + safe_filename_size, + &filename_index, + error ); +#else + result = libuna_unicode_character_copy_to_utf8( + unicode_character, + (libuna_utf8_character_t *) safe_filename, + safe_filename_size, + &filename_index, + error ); +#endif + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_INPUT_FAILED, + "%s: unable to copy Unicode character to filename.", + function ); + + goto on_error; + } + } + } + if( filename_index >= safe_filename_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid filename index value out of bounds.", + function ); + + goto on_error; + } + safe_filename[ filename_index ] = 0; + + *filename = safe_filename; + *filename_size = safe_filename_size; + + return( 1 ); + +on_error: + if( safe_filename != NULL ) + { + memory_free( + safe_filename ); + } + return( -1 ); +} + +/* Retrieves the filename from an file entry + * Returns 1 if successful or -1 on error + */ +int mount_file_system_get_filename_from_file_entry( + mount_file_system_t *file_system, + libfsapfs_file_entry_t *fsapfs_file_entry, + system_character_t **filename, + size_t *filename_size, + libcerror_error_t **error ) +{ + system_character_t *file_entry_name = NULL; + static char *function = "mount_file_system_get_filename_from_file_entry"; + size_t file_entry_name_size = 0; + int result = 0; + + if( file_system == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file system.", + function ); + + return( -1 ); + } +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libfsapfs_file_entry_get_utf16_name_size( + fsapfs_file_entry, + &file_entry_name_size, + error ); +#else + result = libfsapfs_file_entry_get_utf8_name_size( + fsapfs_file_entry, + &file_entry_name_size, + error ); +#endif + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry name size.", + function ); + + goto on_error; + } + if( ( file_entry_name_size == 0 ) + || ( file_entry_name_size > SSIZE_MAX ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid file entry name size value out of bounds.", + function ); + + goto on_error; + } + file_entry_name = system_string_allocate( + file_entry_name_size ); + + if( file_entry_name == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create file entry name string.", + function ); + + goto on_error; + } +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libfsapfs_file_entry_get_utf16_name( + fsapfs_file_entry, + (uint16_t *) file_entry_name, + file_entry_name_size, + error ); +#else + result = libfsapfs_file_entry_get_utf8_name( + fsapfs_file_entry, + (uint8_t *) file_entry_name, + file_entry_name_size, + error ); +#endif + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve file entry name.", + function ); + + goto on_error; + } + if( mount_file_system_get_filename_from_name( + file_system, + file_entry_name, + file_entry_name_size - 1, + filename, + filename_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve a filename from the file entry name.", + function ); + + goto on_error; + } + memory_free( + file_entry_name ); + + return( 1 ); + +on_error: + if( file_entry_name != NULL ) + { + memory_free( + file_entry_name ); + } + return( -1 ); +} + diff -Nru libfsapfs-20181215/fsapfstools/mount_file_system.h libfsapfs-20190210/fsapfstools/mount_file_system.h --- libfsapfs-20181215/fsapfstools/mount_file_system.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_file_system.h 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,110 @@ +/* + * Mount file system + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _MOUNT_FILE_SYSTEM_H ) +#define _MOUNT_FILE_SYSTEM_H + +#include +#include + +#include "fsapfstools_libcerror.h" +#include "fsapfstools_libfsapfs.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct mount_file_system mount_file_system_t; + +struct mount_file_system +{ + /* The mounted timestamp + */ + uint64_t mounted_timestamp; + + /* The volume + */ + libfsapfs_volume_t *fsapfs_volume; +}; + +int mount_file_system_initialize( + mount_file_system_t **file_system, + libcerror_error_t **error ); + +int mount_file_system_free( + mount_file_system_t **file_system, + libcerror_error_t **error ); + +int mount_file_system_signal_abort( + mount_file_system_t *file_system, + libcerror_error_t **error ); + +int mount_file_system_set_volume( + mount_file_system_t *file_system, + libfsapfs_volume_t *fsapfs_volume, + libcerror_error_t **error ); + +int mount_file_system_get_volume( + mount_file_system_t *file_system, + libfsapfs_volume_t **fsapfs_volume, + libcerror_error_t **error ); + +int mount_file_system_get_mounted_timestamp( + mount_file_system_t *file_system, + uint64_t *mounted_timestamp, + libcerror_error_t **error ); + +int mount_file_system_get_file_entry_path_from_path( + mount_file_system_t *file_system, + const system_character_t *path, + size_t path_length, + system_character_t **file_entry_path, + size_t *file_entry_path_size, + libcerror_error_t **error ); + +int mount_file_system_get_file_entry_by_path( + mount_file_system_t *file_system, + const system_character_t *path, + size_t path_length, + libfsapfs_file_entry_t **fsapfs_file_entry, + libcerror_error_t **error ); + +int mount_file_system_get_filename_from_name( + mount_file_system_t *file_system, + const system_character_t *name, + size_t name_length, + system_character_t **filename, + size_t *filename_size, + libcerror_error_t **error ); + +int mount_file_system_get_filename_from_file_entry( + mount_file_system_t *file_system, + libfsapfs_file_entry_t *fsapfs_file_entry, + system_character_t **filename, + size_t *filename_size, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _MOUNT_FILE_SYSTEM_H ) */ + diff -Nru libfsapfs-20181215/fsapfstools/mount_fuse.c libfsapfs-20190210/fsapfstools/mount_fuse.c --- libfsapfs-20181215/fsapfstools/mount_fuse.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_fuse.c 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* - * Fuse functions for mount tool + * Mount tool fuse functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -35,35 +35,12 @@ #include #endif -#if !defined( WINAPI ) -#if defined( TIME_WITH_SYS_TIME ) -#include -#include -#elif defined( HAVE_SYS_TIME_H ) -#include -#else -#include -#endif -#endif - -#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) -#define FUSE_USE_VERSION 26 - -#if defined( HAVE_LIBFUSE ) -#include - -#elif defined( HAVE_LIBOSXFUSE ) -#include -#endif - -#endif /* defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) */ - -#include "mount_fuse.h" -#include "mount_handle.h" #include "fsapfstools_libcerror.h" #include "fsapfstools_libcnotify.h" #include "fsapfstools_libfsapfs.h" #include "fsapfstools_unused.h" +#include "mount_fuse.h" +#include "mount_handle.h" extern mount_handle_t *fsapfsmount_mount_handle; @@ -74,6 +51,7 @@ #endif /* Sets the values in a stat info structure + * The time values are a signed 64-bit POSIX date and time value in number of nanoseconds * Returns 1 if successful or -1 on error */ int mount_fuse_set_stat_info( @@ -114,38 +92,8 @@ return( -1 ); } stat_info->st_size = (off_t) size; - stat_info->st_mode = file_mode & 0x0fff; - - switch( file_mode & 0xf000 ) - { - case 0x1000: - stat_info->st_mode |= S_IFIFO; - break; - - case 0x2000: - stat_info->st_mode |= S_IFCHR; - break; - - case 0x4000: - stat_info->st_mode |= S_IFDIR; - break; - - case 0x6000: - stat_info->st_mode |= S_IFBLK; - break; + stat_info->st_mode = file_mode; - case 0xa000: - stat_info->st_mode |= S_IFLNK; - break; - - case 0xe000: - stat_info->st_mode |= S_IFSOCK; - break; - - default: - stat_info->st_mode |= S_IFREG; - break; - } if( ( file_mode & 0x4000 ) != 0 ) { stat_info->st_nlink = 2; @@ -162,13 +110,13 @@ #endif stat_info->st_atime = access_time / 1000000000; - stat_info->st_mtime = modification_time / 1000000000; stat_info->st_ctime = inode_change_time / 1000000000; + stat_info->st_mtime = modification_time / 1000000000; #if defined( STAT_HAVE_NSEC ) stat_info->st_atime_nsec = access_time % 1000000000; - stat_info->st_mtime_nsec = modification_time % 1000000000; stat_info->st_ctime_nsec = inode_change_time % 1000000000; + stat_info->st_mtime_nsec = modification_time % 1000000000; #endif return( 1 ); } @@ -181,15 +129,15 @@ fuse_fill_dir_t filler, const char *name, struct stat *stat_info, - libfsapfs_file_entry_t *file_entry, + mount_file_entry_t *file_entry, libcerror_error_t **error ) { - static char *function = "mount_fuse_filldir"; - size64_t file_size = 0; - int64_t access_time = 0; - int64_t inode_change_time = 0; - int64_t modification_time = 0; - uint16_t file_mode = 0; + static char *function = "mount_fuse_filldir"; + size64_t file_size = 0; + uint64_t access_time = 0; + uint64_t inode_change_time = 0; + uint64_t modification_time = 0; + uint16_t file_mode = 0; if( filler == NULL ) { @@ -202,23 +150,9 @@ return( -1 ); } - if( memory_set( - stat_info, - 0, - sizeof( struct stat ) ) == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_SET_FAILED, - "%s: unable to clear stat info.", - function ); - - return( -1 ); - } if( file_entry != NULL ) { - if( libfsapfs_file_entry_get_size( + if( mount_file_entry_get_size( file_entry, &file_size, error ) != 1 ) @@ -232,7 +166,7 @@ return( -1 ); } - if( libfsapfs_file_entry_get_file_mode( + if( mount_file_entry_get_file_mode( file_entry, &file_mode, error ) != 1 ) @@ -246,7 +180,7 @@ return( -1 ); } - if( libfsapfs_file_entry_get_access_time( + if( mount_file_entry_get_access_time( file_entry, &access_time, error ) != 1 ) @@ -260,7 +194,7 @@ return( -1 ); } - if( libfsapfs_file_entry_get_modification_time( + if( mount_file_entry_get_modification_time( file_entry, &modification_time, error ) != 1 ) @@ -274,7 +208,7 @@ return( -1 ); } - if( libfsapfs_file_entry_get_inode_change_time( + if( mount_file_entry_get_inode_change_time( file_entry, &inode_change_time, error ) != 1 ) @@ -289,13 +223,27 @@ return( -1 ); } } + if( memory_set( + stat_info, + 0, + sizeof( struct stat ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear stat info.", + function ); + + return( -1 ); + } if( mount_fuse_set_stat_info( stat_info, file_size, file_mode, - access_time, - modification_time, - inode_change_time, + (int64_t) access_time, + (int64_t) inode_change_time, + (int64_t) modification_time, error ) != 1 ) { libcerror_error_set( @@ -325,7 +273,7 @@ return( 1 ); } -/* Opens a file +/* Opens a file or directory * Returns 0 if successful or a negative errno value otherwise */ int mount_fuse_open( @@ -400,7 +348,7 @@ if( mount_handle_get_file_entry_by_path( fsapfsmount_mount_handle, path, - (libfsapfs_file_entry_t **) &( file_info->fh ), + (mount_file_entry_t **) &( file_info->fh ), &error ) != 1 ) { libcerror_error_set( @@ -504,9 +452,9 @@ goto on_error; } - read_count = libfsapfs_file_entry_read_buffer_at_offset( - (libfsapfs_file_entry_t *) file_info->fh, - (uint8_t *) buffer, + read_count = mount_file_entry_read_buffer_at_offset( + (mount_file_entry_t *) file_info->fh, + (void *) buffer, size, (off64_t) offset, &error ); @@ -585,8 +533,8 @@ } if( file_info->fh != (uint64_t) NULL ) { - if( libfsapfs_file_entry_free( - (libfsapfs_file_entry_t **) &( file_info->fh ), + if( mount_file_entry_free( + (mount_file_entry_t **) &( file_info->fh ), &error ) != 1 ) { libcerror_error_set( @@ -676,7 +624,7 @@ if( mount_handle_get_file_entry_by_path( fsapfsmount_mount_handle, path, - (libfsapfs_file_entry_t **) &( file_info->fh ), + (mount_file_entry_t **) &( file_info->fh ), &error ) != 1 ) { libcerror_error_set( @@ -712,18 +660,18 @@ void *buffer, fuse_fill_dir_t filler, off_t offset FSAPFSTOOLS_ATTRIBUTE_UNUSED, - struct fuse_file_info *file_info ) + struct fuse_file_info *file_info FSAPFSTOOLS_ATTRIBUTE_UNUSED ) { - libfsapfs_file_entry_t *parent_file_entry = NULL; - libfsapfs_file_entry_t *sub_file_entry = NULL; - libcerror_error_t *error = NULL; - struct stat *stat_info = NULL; - static char *function = "mount_fuse_readdir"; - char *name = NULL; - size_t name_size = 0; - int number_of_sub_file_entries = 0; - int result = 0; - int sub_file_entry_index = 0; + struct stat *stat_info = NULL; + libcerror_error_t *error = NULL; + mount_file_entry_t *parent_file_entry = NULL; + mount_file_entry_t *sub_file_entry = NULL; + static char *function = "mount_fuse_readdir"; + char *name = NULL; + size_t name_size = 0; + int number_of_sub_file_entries = 0; + int result = 0; + int sub_file_entry_index = 0; FSAPFSTOOLS_UNREFERENCED_PARAMETER( offset ) @@ -775,22 +723,6 @@ goto on_error; } - if( libfsapfs_file_entry_get_number_of_sub_file_entries( - (libfsapfs_file_entry_t *) file_info->fh, - &number_of_sub_file_entries, - &error ) != 1 ) - { - libcerror_error_set( - &error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of sub file entries.", - function ); - - result = -EIO; - - goto on_error; - } stat_info = memory_allocate_structure( struct stat ); @@ -812,7 +744,7 @@ filler, ".", stat_info, - (libfsapfs_file_entry_t *) file_info->fh, + (mount_file_entry_t *) file_info->fh, &error ) != 1 ) { libcerror_error_set( @@ -826,8 +758,8 @@ goto on_error; } - result = libfsapfs_file_entry_get_parent_file_entry( - (libfsapfs_file_entry_t *) file_info->fh, + result = mount_file_entry_get_parent_file_entry( + (mount_file_entry_t *) file_info->fh, &parent_file_entry, &error ); @@ -863,7 +795,7 @@ goto on_error; } - if( libfsapfs_file_entry_free( + if( mount_file_entry_free( &parent_file_entry, &error ) != 1 ) { @@ -878,12 +810,28 @@ goto on_error; } + if( mount_file_entry_get_number_of_sub_file_entries( + (mount_file_entry_t *) file_info->fh, + &number_of_sub_file_entries, + &error ) != 1 ) + { + libcerror_error_set( + &error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub file entries.", + function ); + + result = -EIO; + + goto on_error; + } for( sub_file_entry_index = 0; sub_file_entry_index < number_of_sub_file_entries; sub_file_entry_index++ ) { - if( libfsapfs_file_entry_get_sub_file_entry_by_index( - (libfsapfs_file_entry_t *) file_info->fh, + if( mount_file_entry_get_sub_file_entry_by_index( + (mount_file_entry_t *) file_info->fh, sub_file_entry_index, &sub_file_entry, &error ) != 1 ) @@ -900,7 +848,7 @@ goto on_error; } - if( libfsapfs_file_entry_get_utf8_name_size( + if( mount_file_entry_get_name_size( sub_file_entry, &name_size, &error ) != 1 ) @@ -933,9 +881,9 @@ goto on_error; } - if( libfsapfs_file_entry_get_utf8_name( + if( mount_file_entry_get_name( sub_file_entry, - (uint8_t *) name, + name, name_size, &error ) != 1 ) { @@ -975,7 +923,7 @@ name = NULL; - if( libfsapfs_file_entry_free( + if( mount_file_entry_free( &sub_file_entry, &error ) != 1 ) { @@ -1012,13 +960,13 @@ } if( sub_file_entry != NULL ) { - libfsapfs_file_entry_free( + mount_file_entry_free( &sub_file_entry, NULL ); } if( parent_file_entry != NULL ) { - libfsapfs_file_entry_free( + mount_file_entry_free( &parent_file_entry, NULL ); } @@ -1078,21 +1026,7 @@ } if( file_info->fh != (uint64_t) NULL ) { - if( libfsapfs_file_entry_free( - (libfsapfs_file_entry_t **) &( file_info->fh ), - &error ) != 1 ) - { - libcerror_error_set( - &error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free file entry.", - function ); - - result = -ENOENT; - - goto on_error; - } + file_info->fh = (uint64_t) NULL; } return( 0 ); @@ -1114,15 +1048,15 @@ const char *path, struct stat *stat_info ) { - libcerror_error_t *error = NULL; - libfsapfs_file_entry_t *file_entry = NULL; - static char *function = "mount_fuse_getattr"; - size64_t file_size = 0; - int64_t access_time = 0; - int64_t inode_change_time = 0; - int64_t modification_time = 0; - uint16_t file_mode = 0; - int result = 0; + libcerror_error_t *error = NULL; + mount_file_entry_t *file_entry = NULL; + static char *function = "mount_fuse_getattr"; + size64_t file_size = 0; + uint64_t access_time = 0; + uint64_t inode_change_time = 0; + uint64_t modification_time = 0; + uint16_t file_mode = 0; + int result = 0; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) @@ -1199,7 +1133,7 @@ { return( -ENOENT ); } - if( libfsapfs_file_entry_get_size( + if( mount_file_entry_get_size( file_entry, &file_size, &error ) != 1 ) @@ -1215,7 +1149,7 @@ goto on_error; } - if( libfsapfs_file_entry_get_file_mode( + if( mount_file_entry_get_file_mode( file_entry, &file_mode, &error ) != 1 ) @@ -1231,7 +1165,7 @@ goto on_error; } - if( libfsapfs_file_entry_get_access_time( + if( mount_file_entry_get_access_time( file_entry, &access_time, &error ) != 1 ) @@ -1247,7 +1181,7 @@ goto on_error; } - if( libfsapfs_file_entry_get_modification_time( + if( mount_file_entry_get_modification_time( file_entry, &modification_time, &error ) != 1 ) @@ -1263,7 +1197,7 @@ goto on_error; } - if( libfsapfs_file_entry_get_inode_change_time( + if( mount_file_entry_get_inode_change_time( file_entry, &inode_change_time, &error ) != 1 ) @@ -1283,9 +1217,9 @@ stat_info, file_size, file_mode, - access_time, - modification_time, - inode_change_time, + (int64_t) access_time, + (int64_t) inode_change_time, + (int64_t) modification_time, &error ) != 1 ) { libcerror_error_set( @@ -1299,7 +1233,7 @@ goto on_error; } - if( libfsapfs_file_entry_free( + if( mount_file_entry_free( &file_entry, &error ) != 1 ) { @@ -1326,7 +1260,7 @@ } if( file_entry != NULL ) { - libfsapfs_file_entry_free( + mount_file_entry_free( &file_entry, NULL ); } @@ -1341,10 +1275,10 @@ char *buffer, size_t size ) { - libcerror_error_t *error = NULL; - libfsapfs_file_entry_t *file_entry = NULL; - static char *function = "mount_fuse_readlink"; - int result = 0; + libcerror_error_t *error = NULL; + mount_file_entry_t *file_entry = NULL; + static char *function = "mount_fuse_readlink"; + int result = 0; #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) @@ -1392,9 +1326,9 @@ { return( -ENOENT ); } - if( libfsapfs_file_entry_get_utf8_symbolic_link_target( + if( mount_file_entry_get_symbolic_link_target( file_entry, - (uint8_t *) buffer, + buffer, size, &error ) != 1 ) { @@ -1409,7 +1343,7 @@ goto on_error; } - if( libfsapfs_file_entry_free( + if( mount_file_entry_free( &file_entry, &error ) != 1 ) { @@ -1436,14 +1370,13 @@ } if( file_entry != NULL ) { - libfsapfs_file_entry_free( + mount_file_entry_free( &file_entry, NULL ); } return( result ); } - /* Cleans up when fuse is done */ void mount_fuse_destroy( diff -Nru libfsapfs-20181215/fsapfstools/mount_fuse.h libfsapfs-20190210/fsapfstools/mount_fuse.h --- libfsapfs-20181215/fsapfstools/mount_fuse.h 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_fuse.h 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* - * Fuse functions for mount tool + * Mount tool fuse functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,6 +25,9 @@ #include #include +#if defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) +#define FUSE_USE_VERSION 26 + #if defined( HAVE_LIBFUSE ) #include @@ -32,7 +35,12 @@ #include #endif +#endif /* defined( HAVE_LIBFUSE ) || defined( HAVE_LIBOSXFUSE ) */ + #include "fsapfstools_libcerror.h" +#include "fsapfstools_libfsapfs.h" +#include "mount_file_entry.h" +#include "mount_handle.h" #if defined( __cplusplus ) extern "C" { @@ -54,7 +62,7 @@ fuse_fill_dir_t filler, const char *name, struct stat *stat_info, - libfsapfs_file_entry_t *file_entry, + mount_file_entry_t *file_entry, libcerror_error_t **error ); int mount_fuse_open( diff -Nru libfsapfs-20181215/fsapfstools/mount_handle.c libfsapfs-20190210/fsapfstools/mount_handle.c --- libfsapfs-20181215/fsapfstools/mount_handle.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_handle.c 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* - * Info handle + * Mount handle * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -20,7 +20,6 @@ */ #include -#include #include #include #include @@ -29,10 +28,10 @@ #include "fsapfstools_libbfio.h" #include "fsapfstools_libcerror.h" -#include "fsapfstools_libclocale.h" -#include "fsapfstools_libcnotify.h" #include "fsapfstools_libcpath.h" #include "fsapfstools_libfsapfs.h" +#include "mount_file_entry.h" +#include "mount_file_system.h" #include "mount_handle.h" #if !defined( LIBFSAPFS_HAVE_BFIO ) @@ -46,20 +45,18 @@ #endif /* !defined( LIBFSAPFS_HAVE_BFIO ) */ -#define INFO_HANDLE_NOTIFY_STREAM stdout - /* Copies a string of a decimal value to a 64-bit value * Returns 1 if successful or -1 on error */ -int fsapfstools_system_string_copy_from_64_bit_in_decimal( +int mount_handle_system_string_copy_from_64_bit_in_decimal( const system_character_t *string, size_t string_size, uint64_t *value_64bit, libcerror_error_t **error ) { - static char *function = "fsapfstools_system_string_copy_from_64_bit_in_decimal"; - size_t string_index = 0; + static char *function = "mount_handle_system_string_copy_from_64_bit_in_decimal"; system_character_t character_value = 0; + size_t string_index = 0; uint8_t maximum_string_index = 20; int8_t sign = 1; @@ -158,7 +155,7 @@ return( 1 ); } -/* Creates an mount handle +/* Creates a mount handle * Make sure the value mount_handle is referencing, is set to NULL * Returns 1 if successful or -1 on error */ @@ -218,45 +215,24 @@ goto on_error; } - if( libbfio_file_range_initialize( - &( ( *mount_handle )->input_file_io_handle ), + if( mount_file_system_initialize( + &( ( *mount_handle )->file_system ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to initialize input file IO handle.", + "%s: unable to initialize file system.", function ); goto on_error; } - if( libfsapfs_container_initialize( - &( ( *mount_handle )->input_container ), - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to initialize input container.", - function ); - - goto on_error; - } - ( *mount_handle )->notify_stream = INFO_HANDLE_NOTIFY_STREAM; - return( 1 ); on_error: if( *mount_handle != NULL ) { - if( ( *mount_handle )->input_file_io_handle != NULL ) - { - libbfio_handle_free( - &( ( *mount_handle )->input_file_io_handle ), - NULL ); - } memory_free( *mount_handle ); @@ -265,7 +241,7 @@ return( -1 ); } -/* Frees an mount handle +/* Frees a mount handle * Returns 1 if successful or -1 on error */ int mount_handle_free( @@ -288,92 +264,19 @@ } if( *mount_handle != NULL ) { - if( ( *mount_handle )->input_volume != NULL ) - { - if( libfsapfs_volume_free( - &( ( *mount_handle )->input_volume ), - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free input volume.", - function ); - - result = -1; - } - } - if( libfsapfs_container_free( - &( ( *mount_handle )->input_container ), + if( mount_file_system_free( + &( ( *mount_handle )->file_system ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free input container.", + "%s: unable to free file system.", function ); result = -1; } - if( libbfio_handle_free( - &( ( *mount_handle )->input_file_io_handle ), - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free input file IO handle.", - function ); - - result = -1; - } - if( ( *mount_handle )->recovery_password != NULL ) - { - if( memory_set( - ( *mount_handle )->recovery_password, - 0, - ( *mount_handle )->recovery_password_size ) == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_SET_FAILED, - "%s: unable to clear recovery password.", - function ); - - result = -1; - } - memory_free( - ( *mount_handle )->recovery_password ); - - ( *mount_handle )->recovery_password = NULL; - ( *mount_handle )->recovery_password_size = 0; - } - if( ( *mount_handle )->user_password != NULL ) - { - if( memory_set( - ( *mount_handle )->user_password, - 0, - ( *mount_handle )->user_password_size ) == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_SET_FAILED, - "%s: unable to clear user password.", - function ); - - result = -1; - } - memory_free( - ( *mount_handle )->user_password ); - - ( *mount_handle )->user_password = NULL; - ( *mount_handle )->user_password_size = 0; - } memory_free( *mount_handle ); @@ -402,23 +305,18 @@ return( -1 ); } - mount_handle->abort = 1; - - if( mount_handle->input_container != NULL ) + if( mount_file_system_signal_abort( + mount_handle->file_system, + error ) != 1 ) { - if( libfsapfs_container_signal_abort( - mount_handle->input_container, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to signal input container to abort.", - function ); + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to signal file system to abort.", + function ); - return( -1 ); - } + return( -1 ); } return( 1 ); } @@ -449,7 +347,7 @@ string_length = system_string_length( string ); - if( fsapfstools_system_string_copy_from_64_bit_in_decimal( + if( mount_handle_system_string_copy_from_64_bit_in_decimal( string, string_length + 1, &value_64bit, @@ -481,16 +379,17 @@ return( 1 ); } -/* Sets the password +/* Sets the container offset * Returns 1 if successful or -1 on error */ -int mount_handle_set_password( +int mount_handle_set_offset( mount_handle_t *mount_handle, const system_character_t *string, libcerror_error_t **error ) { - static char *function = "mount_handle_set_password"; + static char *function = "mount_handle_set_offset"; size_t string_length = 0; + uint64_t value_64bit = 0; if( mount_handle == NULL ) { @@ -503,85 +402,38 @@ return( -1 ); } - if( mount_handle->user_password != NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: invalid mount handle - user password value already set.", - function ); - - return( -1 ); - } - if( string == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid string.", - function ); - - return( -1 ); - } string_length = system_string_length( string ); - mount_handle->user_password_size = string_length + 1; - - mount_handle->user_password = system_string_allocate( - mount_handle->user_password_size ); - - if( mount_handle->user_password == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_INSUFFICIENT, - "%s: unable to create user password.", - function ); - - goto on_error; - } - if( system_string_copy( - mount_handle->user_password, + if( mount_handle_system_string_copy_from_64_bit_in_decimal( string, - mount_handle->user_password_size ) == NULL ) + string_length + 1, + &value_64bit, + error ) != 1 ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_COPY_FAILED, - "%s: unable to copy user password.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_COPY_FAILED, + "%s: unable to copy string to 64-bit decimal.", function ); - goto on_error; - } - return( 1 ); - -on_error: - if( mount_handle->user_password != NULL ) - { - memory_free( - mount_handle->user_password ); - - mount_handle->user_password = NULL; + return( -1 ); } - mount_handle->user_password_size = 0; + mount_handle->container_offset = (off64_t) value_64bit; - return( -1 ); + return( 1 ); } -/* Sets the recovery password +/* Sets the password * Returns 1 if successful or -1 on error */ -int mount_handle_set_recovery_password( +int mount_handle_set_password( mount_handle_t *mount_handle, const system_character_t *string, libcerror_error_t **error ) { - static char *function = "mount_handle_set_recovery_password"; + static char *function = "mount_handle_set_password"; size_t string_length = 0; if( mount_handle == NULL ) @@ -595,17 +447,6 @@ return( -1 ); } - if( mount_handle->recovery_password != NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: invalid mount handle - recovery password value already set.", - function ); - - return( -1 ); - } if( string == NULL ) { libcerror_error_set( @@ -620,62 +461,22 @@ string_length = system_string_length( string ); - mount_handle->recovery_password_size = string_length + 1; - - mount_handle->recovery_password = system_string_allocate( - mount_handle->recovery_password_size ); - - if( mount_handle->recovery_password == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_INSUFFICIENT, - "%s: unable to create recovery password.", - function ); - - goto on_error; - } - if( system_string_copy( - mount_handle->recovery_password, - string, - mount_handle->recovery_password_size ) == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_COPY_FAILED, - "%s: unable to copy recovery password.", - function ); + mount_handle->password = string; + mount_handle->password_length = string_length; - goto on_error; - } return( 1 ); - -on_error: - if( mount_handle->recovery_password != NULL ) - { - memory_free( - mount_handle->recovery_password ); - - mount_handle->recovery_password = NULL; - } - mount_handle->recovery_password_size = 0; - - return( -1 ); } -/* Sets the volume offset +/* Sets the recovery password * Returns 1 if successful or -1 on error */ -int mount_handle_set_volume_offset( +int mount_handle_set_recovery_password( mount_handle_t *mount_handle, const system_character_t *string, libcerror_error_t **error ) { - static char *function = "mount_handle_set_volume_offset"; + static char *function = "mount_handle_set_recovery_password"; size_t string_length = 0; - uint64_t value_64bit = 0; if( mount_handle == NULL ) { @@ -688,41 +489,42 @@ return( -1 ); } - string_length = system_string_length( - string ); - - if( fsapfstools_system_string_copy_from_64_bit_in_decimal( - string, - string_length + 1, - &value_64bit, - error ) != 1 ) + if( string == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_COPY_FAILED, - "%s: unable to copy string to 64-bit decimal.", + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid string.", function ); return( -1 ); } - mount_handle->volume_offset = (off64_t) value_64bit; + string_length = system_string_length( + string ); + + mount_handle->recovery_password = string; + mount_handle->recovery_password_length = string_length; return( 1 ); } -/* Opens the input - * Returns 1 if successful or -1 on error +/* Opens the mount handle + * Returns 1 if successful, 0 if not or -1 on error */ -int mount_handle_open_input( +int mount_handle_open( mount_handle_t *mount_handle, const system_character_t *filename, libcerror_error_t **error ) { - static char *function = "mount_handle_open_input"; - size_t filename_length = 0; - int number_of_volumes = 0; - int volume_index = 0; + libbfio_handle_t *file_io_handle = NULL; + libfsapfs_container_t *fsapfs_container = NULL; + libfsapfs_volume_t *fsapfs_volume = NULL; + static char *function = "mount_handle_open"; + size_t filename_length = 0; + int number_of_volumes = 0; + int result = 0; + int volume_index = 0; if( mount_handle == NULL ) { @@ -735,18 +537,42 @@ return( -1 ); } + if( filename == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid filename.", + function ); + + return( -1 ); + } filename_length = system_string_length( filename ); + if( libbfio_file_range_initialize( + &file_io_handle, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to initialize file IO handle.", + function ); + + goto on_error; + } #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( libbfio_file_range_set_name_wide( - mount_handle->input_file_io_handle, + file_io_handle, filename, filename_length, error ) != 1 ) #else if( libbfio_file_range_set_name( - mount_handle->input_file_io_handle, + file_io_handle, filename, filename_length, error ) != 1 ) @@ -756,14 +582,14 @@ error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, - "%s: unable to open set file name.", + "%s: unable to set file range name.", function ); - return( -1 ); + goto on_error; } if( libbfio_file_range_set( - mount_handle->input_file_io_handle, - mount_handle->volume_offset, + file_io_handle, + mount_handle->container_offset, 0, error ) != 1 ) { @@ -771,29 +597,44 @@ error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, - "%s: unable to open set volume offset.", + "%s: unable to set file range offset.", function ); - return( -1 ); + goto on_error; } - if( libfsapfs_container_open_file_io_handle( - mount_handle->input_container, - mount_handle->input_file_io_handle, - LIBFSAPFS_OPEN_READ, + if( libfsapfs_container_initialize( + &fsapfs_container, error ) != 1 ) { libcerror_error_set( error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to initialize container.", + function ); + + goto on_error; + } + result = libfsapfs_container_open_file_io_handle( + fsapfs_container, + file_io_handle, + LIBFSAPFS_OPEN_READ, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_OPEN_FAILED, - "%s: unable to open input container.", + "%s: unable to open container.", function ); - return( -1 ); + goto on_error; } /* TODO add support for volume selection including all volumes */ if( libfsapfs_container_get_number_of_volumes( - mount_handle->input_container, + fsapfs_container, &number_of_volumes, error ) != 1 ) { @@ -801,7 +642,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of volumes.", + "%s: unable to retrieve number of volumes from container.", function ); return( -1 ); @@ -820,7 +661,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid file system index value out of bounds.", + "%s: invalid volume index value out of bounds.", function ); return( -1 ); @@ -829,8 +670,9 @@ if( mount_handle_get_volume_by_index( mount_handle, + fsapfs_container, volume_index, - &( mount_handle->input_volume ), + &fsapfs_volume, error ) != 1 ) { libcerror_error_set( @@ -843,17 +685,72 @@ return( -1 ); } + result = libfsapfs_volume_is_locked( + fsapfs_volume, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine if volume is locked.", + function ); + + goto on_error; + } + mount_handle->is_locked = result; + + if( mount_file_system_set_volume( + mount_handle->file_system, + fsapfs_volume, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set volume in file system.", + function ); + + goto on_error; + } + mount_handle->file_io_handle = file_io_handle; + return( 1 ); + +on_error: + if( fsapfs_volume != NULL ) + { + libfsapfs_volume_free( + &fsapfs_volume, + NULL ); + } + if( fsapfs_container != NULL ) + { + libfsapfs_container_free( + &fsapfs_container, + NULL ); + } + if( file_io_handle != NULL ) + { + libbfio_handle_free( + &file_io_handle, + NULL ); + } + return( -1 ); } -/* Closes the input +/* Closes the mount handle * Returns the 0 if succesful or -1 on error */ -int mount_handle_close_input( +int mount_handle_close( mount_handle_t *mount_handle, libcerror_error_t **error ) { - static char *function = "mount_handle_close_input"; + libfsapfs_volume_t *fsapfs_volume = NULL; + static char *function = "mount_handle_close"; if( mount_handle == NULL ) { @@ -866,20 +763,121 @@ return( -1 ); } - if( libfsapfs_container_close( - mount_handle->input_container, + if( mount_file_system_get_volume( + mount_handle->file_system, + &fsapfs_volume, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve volume from file system.", + function ); + + goto on_error; + } + if( mount_file_system_set_volume( + mount_handle->file_system, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set volume in file system.", + function ); + + fsapfs_volume = NULL; + + goto on_error; + } + if( libfsapfs_volume_close( + fsapfs_volume, error ) != 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_CLOSE_FAILED, - "%s: unable to close input container.", + "%s: unable to close volume.", function ); - return( -1 ); + goto on_error; + } + if( libfsapfs_volume_free( + &fsapfs_volume, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free volume.", + function ); + + goto on_error; + } + if( libbfio_handle_close( + mount_handle->file_io_handle, + error ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to close file IO handle.", + function ); + + goto on_error; + } + if( libbfio_handle_free( + &( mount_handle->file_io_handle ), + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free file IO handle.", + function ); + + goto on_error; } return( 0 ); + +on_error: + if( fsapfs_volume != NULL ) + { + libfsapfs_volume_free( + &fsapfs_volume, + NULL ); + } + return( -1 ); +} + +/* Determine if the mount handle is locked + * Returns 1 if locked, 0 if not or -1 on error + */ +int mount_handle_is_locked( + mount_handle_t *mount_handle, + libcerror_error_t **error ) +{ + static char *function = "mount_handle_is_locked"; + + if( mount_handle == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid mount handle.", + function ); + + return( -1 ); + } + return( mount_handle->is_locked ); } /* Retrieves a specific volume from the container @@ -887,8 +885,9 @@ */ int mount_handle_get_volume_by_index( mount_handle_t *mount_handle, + libfsapfs_container_t *fsapfs_container, int volume_index, - libfsapfs_volume_t **volume, + libfsapfs_volume_t **fsapfs_volume, libcerror_error_t **error ) { static char *function = "mount_handle_get_volume_by_index"; @@ -904,7 +903,7 @@ return( -1 ); } - if( volume == NULL ) + if( fsapfs_volume == NULL ) { libcerror_error_set( error, @@ -915,7 +914,7 @@ return( -1 ); } - if( *volume != NULL ) + if( *fsapfs_volume != NULL ) { libcerror_error_set( error, @@ -927,9 +926,9 @@ return( -1 ); } if( libfsapfs_container_get_volume_by_index( - mount_handle->input_container, + fsapfs_container, volume_index, - volume, + fsapfs_volume, error ) != 1 ) { libcerror_error_set( @@ -942,19 +941,19 @@ goto on_error; } - if( mount_handle->user_password != NULL ) + if( mount_handle->password != NULL ) { #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( libfsapfs_volume_set_utf16_password( - *volume, - (uint16_t *) mount_handle->user_password, - mount_handle->user_password_size - 1, + *fsapfs_volume, + (uint16_t *) mount_handle->password, + mount_handle->password_length, error ) != 1 ) #else if( libfsapfs_volume_set_utf8_password( - *volume, - (uint8_t *) mount_handle->user_password, - mount_handle->user_password_size - 1, + *fsapfs_volume, + (uint8_t *) mount_handle->password, + mount_handle->password_length, error ) != 1 ) #endif { @@ -972,15 +971,15 @@ { #if defined( HAVE_WIDE_SYSTEM_CHARACTER ) if( libfsapfs_volume_set_utf16_recovery_password( - *volume, + *fsapfs_volume, (uint16_t *) mount_handle->recovery_password, - mount_handle->recovery_password_size - 1, + mount_handle->recovery_password_length, error ) != 1 ) #else if( libfsapfs_volume_set_utf8_recovery_password( - *volume, + *fsapfs_volume, (uint8_t *) mount_handle->recovery_password, - mount_handle->recovery_password_size - 1, + mount_handle->recovery_password_length, error ) != 1 ) #endif { @@ -998,10 +997,10 @@ return( 1 ); on_error: - if( *volume != NULL ) + if( *fsapfs_volume != NULL ) { libfsapfs_volume_free( - volume, + fsapfs_volume, NULL ); } return( -1 ); @@ -1013,12 +1012,16 @@ int mount_handle_get_file_entry_by_path( mount_handle_t *mount_handle, const system_character_t *path, - libfsapfs_file_entry_t **file_entry, + mount_file_entry_t **file_entry, libcerror_error_t **error ) { - static char *function = "mount_handle_get_file_entry_by_path"; - size_t path_length = 0; - int result = 0; + libfsapfs_file_entry_t *fsapfs_file_entry = NULL; + const system_character_t *filename = NULL; + static char *function = "mount_handle_get_file_entry_by_path"; + size_t filename_length = 0; + size_t path_index = 0; + size_t path_length = 0; + int result = 0; if( mount_handle == NULL ) { @@ -1045,21 +1048,51 @@ path_length = system_string_length( path ); -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) - result = libfsapfs_volume_get_file_entry_by_utf16_path( - mount_handle->input_volume, - (uint16_t *) path, - path_length, - file_entry, - error ); -#else - result = libfsapfs_volume_get_file_entry_by_utf8_path( - mount_handle->input_volume, - (uint8_t *) path, - path_length, - file_entry, - error ); -#endif + if( path_length == 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid path length value out of bounds.", + function ); + + goto on_error; + } + if( ( path_length >= 2 ) + && ( path[ path_length - 1 ] == LIBCPATH_SEPARATOR ) ) + { + path_length--; + } + path_index = path_length; + + while( path_index > 0 ) + { + if( path[ path_index ] == LIBCPATH_SEPARATOR ) + { + break; + } + path_index--; + } + /* Ignore the name of the root item + */ + if( path_length == 0 ) + { + filename = _SYSTEM_STRING( "" ); + filename_length = 0; + } + else + { + filename = &( path[ path_index + 1 ] ); + filename_length = path_length - ( path_index + 1 ); + } + result = mount_file_system_get_file_entry_by_path( + mount_handle->file_system, + path, + path_length, + &fsapfs_file_entry, + error ); + if( result == -1 ) { libcerror_error_set( @@ -1069,8 +1102,37 @@ "%s: unable to retrieve file entry.", function ); - return( -1 ); + goto on_error; + } + else if( result != 0 ) + { + if( mount_file_entry_initialize( + file_entry, + mount_handle->file_system, + filename, + filename_length, + fsapfs_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to initialize file entry.", + function ); + + goto on_error; + } } return( result ); + +on_error: + if( fsapfs_file_entry != NULL ) + { + libfsapfs_file_entry_free( + &fsapfs_file_entry, + NULL ); + } + return( -1 ); } diff -Nru libfsapfs-20181215/fsapfstools/mount_handle.h libfsapfs-20190210/fsapfstools/mount_handle.h --- libfsapfs-20181215/fsapfstools/mount_handle.h 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/fsapfstools/mount_handle.h 2019-02-06 20:14:03.000000000 +0000 @@ -1,7 +1,7 @@ /* * Mount handle * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -29,6 +29,8 @@ #include "fsapfstools_libbfio.h" #include "fsapfstools_libcerror.h" #include "fsapfstools_libfsapfs.h" +#include "mount_file_entry.h" +#include "mount_file_system.h" #if defined( __cplusplus ) extern "C" { @@ -38,52 +40,48 @@ struct mount_handle { - /* The file system index + /* The file system */ - int file_system_index; + mount_file_system_t *file_system; - /* The recovery password + /* The file system index */ - system_character_t *recovery_password; + int file_system_index; - /* The recovery password size + /* The container offset */ - size_t recovery_password_size; + off64_t container_offset; - /* The user password + /* The libbfio file IO handle */ - system_character_t *user_password; + libbfio_handle_t *file_io_handle; - /* The user password size + /* The password */ - size_t user_password_size; + const system_character_t *password; - /* The volume offset + /* The password length */ - off64_t volume_offset; + size_t password_length; - /* The libbfio input file IO handle + /* The recovery password */ - libbfio_handle_t *input_file_io_handle; + const system_character_t *recovery_password; - /* The libfsapfs input container + /* The recovery password length */ - libfsapfs_container_t *input_container; + size_t recovery_password_length; - /* The libfsapfs input volume + /* Value to indicate the mount handle is locked */ - libfsapfs_volume_t *input_volume; + int is_locked; /* The notification output stream */ FILE *notify_stream; - - /* Value to indicate if abort was signalled - */ - int abort; }; -int fsapfstools_system_string_copy_from_64_bit_in_decimal( +int mount_handle_system_string_copy_from_64_bit_in_decimal( const system_character_t *string, size_t string_size, uint64_t *value_64bit, @@ -106,40 +104,45 @@ const system_character_t *string, libcerror_error_t **error ); -int mount_handle_set_password( +int mount_handle_set_offset( mount_handle_t *mount_handle, const system_character_t *string, libcerror_error_t **error ); -int mount_handle_set_recovery_password( +int mount_handle_set_password( mount_handle_t *mount_handle, const system_character_t *string, libcerror_error_t **error ); -int mount_handle_set_volume_offset( +int mount_handle_set_recovery_password( mount_handle_t *mount_handle, const system_character_t *string, libcerror_error_t **error ); -int mount_handle_open_input( +int mount_handle_open( mount_handle_t *mount_handle, const system_character_t *filename, libcerror_error_t **error ); -int mount_handle_close_input( +int mount_handle_close( + mount_handle_t *mount_handle, + libcerror_error_t **error ); + +int mount_handle_is_locked( mount_handle_t *mount_handle, libcerror_error_t **error ); int mount_handle_get_volume_by_index( mount_handle_t *mount_handle, + libfsapfs_container_t *fsapfs_container, int volume_index, - libfsapfs_volume_t **volume, + libfsapfs_volume_t **fsapfs_volume, libcerror_error_t **error ); int mount_handle_get_file_entry_by_path( mount_handle_t *mount_handle, const system_character_t *path, - libfsapfs_file_entry_t **file_entry, + mount_file_entry_t **file_entry, libcerror_error_t **error ); #if defined( __cplusplus ) diff -Nru libfsapfs-20181215/include/libfsapfs/codepage.h libfsapfs-20190210/include/libfsapfs/codepage.h --- libfsapfs-20181215/include/libfsapfs/codepage.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/codepage.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Codepage definitions for libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs/definitions.h libfsapfs-20190210/include/libfsapfs/definitions.h --- libfsapfs-20181215/include/libfsapfs/definitions.h 2018-12-15 06:44:18.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/definitions.h 2019-02-10 19:59:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Definitions for libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -24,11 +24,11 @@ #include -#define LIBFSAPFS_VERSION 20181215 +#define LIBFSAPFS_VERSION 20190210 /* The version string */ -#define LIBFSAPFS_VERSION_STRING "20181215" +#define LIBFSAPFS_VERSION_STRING "20190210" /* The file access * bit 1 set to 1 for read access diff -Nru libfsapfs-20181215/include/libfsapfs/definitions.h.in libfsapfs-20190210/include/libfsapfs/definitions.h.in --- libfsapfs-20181215/include/libfsapfs/definitions.h.in 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/definitions.h.in 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Definitions for libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs/error.h libfsapfs-20190210/include/libfsapfs/error.h --- libfsapfs-20181215/include/libfsapfs/error.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/error.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * The error code definitions for libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs/extern.h libfsapfs-20190210/include/libfsapfs/extern.h --- libfsapfs-20181215/include/libfsapfs/extern.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/extern.h 2019-02-06 20:10:13.000000000 +0000 @@ -4,7 +4,7 @@ * This header should be included in header files that export or import * library functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs/features.h libfsapfs-20190210/include/libfsapfs/features.h --- libfsapfs-20181215/include/libfsapfs/features.h 2018-12-15 06:44:18.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/features.h 2019-02-10 19:59:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Features of libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs/features.h.in libfsapfs-20190210/include/libfsapfs/features.h.in --- libfsapfs-20181215/include/libfsapfs/features.h.in 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/features.h.in 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Features of libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs/types.h libfsapfs-20190210/include/libfsapfs/types.h --- libfsapfs-20181215/include/libfsapfs/types.h 2018-12-15 06:44:18.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/types.h 2019-02-10 19:59:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Type definitions for libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs/types.h.in libfsapfs-20190210/include/libfsapfs/types.h.in --- libfsapfs-20181215/include/libfsapfs/types.h.in 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs/types.h.in 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * Type definitions for libfsapfs * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/include/libfsapfs.h libfsapfs-20190210/include/libfsapfs.h --- libfsapfs-20181215/include/libfsapfs.h 2018-12-15 06:44:18.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs.h 2019-02-10 19:59:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library to access the Apple File System (APFS) format * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -787,6 +787,48 @@ libfsapfs_extended_attribute_t **extended_attribute, libfsapfs_error_t **error ); +/* Determines if there is an extended attribute for an UTF-8 encoded name + * Returns 1 if available, 0 if not or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_has_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libfsapfs_error_t **error ); + +/* Determines if there is an extended attribute for an UTF-16 encoded name + * Returns 1 if available, 0 if not or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_has_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libfsapfs_error_t **error ); + +/* Retrieves the extended attribute for an UTF-8 encoded name + * Returns 1 if successful, 0 if the file entry does not contain such value or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_get_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libfsapfs_error_t **error ); + +/* Retrieves the extended attribute for an UTF-16 encoded name + * Returns 1 if successful, 0 if the file entry does not contain such value or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_get_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libfsapfs_error_t **error ); + /* Retrieves the number of sub file entries * Returns 1 if successful or -1 on error */ @@ -910,6 +952,15 @@ libfsapfs_extended_attribute_t **extended_attribute, libfsapfs_error_t **error ); +/* Retrieves the identifier + * Returns 1 if successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_extended_attribute_get_identifier( + libfsapfs_extended_attribute_t *extended_attribute, + uint64_t *identifier, + libfsapfs_error_t **error ); + /* Retrieves the size of the UTF-8 encoded name * The returned size includes the end of string character * Returns 1 if successful or -1 on error @@ -952,6 +1003,55 @@ size_t utf16_string_size, libfsapfs_error_t **error ); +/* Reads data at the current offset into a buffer + * Returns the number of bytes read or -1 on error + */ +LIBFSAPFS_EXTERN \ +ssize_t libfsapfs_extended_attribute_read_buffer( + libfsapfs_extended_attribute_t *extended_attribute, + void *buffer, + size_t buffer_size, + libfsapfs_error_t **error ); + +/* Reads data at a specific offset + * Returns the number of bytes read or -1 on error + */ +LIBFSAPFS_EXTERN \ +ssize_t libfsapfs_extended_attribute_read_buffer_at_offset( + libfsapfs_extended_attribute_t *extended_attribute, + void *buffer, + size_t buffer_size, + off64_t offset, + libfsapfs_error_t **error ); + +/* Seeks a certain offset + * Returns the offset if seek is successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +off64_t libfsapfs_extended_attribute_seek_offset( + libfsapfs_extended_attribute_t *extended_attribute, + off64_t offset, + int whence, + libfsapfs_error_t **error ); + +/* Retrieves the current offset + * Returns the offset if successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_extended_attribute_get_offset( + libfsapfs_extended_attribute_t *extended_attribute, + off64_t *offset, + libfsapfs_error_t **error ); + +/* Retrieves the size of the data stream object + * Returns 1 if successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_extended_attribute_get_size( + libfsapfs_extended_attribute_t *extended_attribute, + size64_t *size, + libfsapfs_error_t **error ); + #if defined( __cplusplus ) } #endif diff -Nru libfsapfs-20181215/include/libfsapfs.h.in libfsapfs-20190210/include/libfsapfs.h.in --- libfsapfs-20181215/include/libfsapfs.h.in 2018-12-03 17:52:38.000000000 +0000 +++ libfsapfs-20190210/include/libfsapfs.h.in 2019-02-10 19:17:35.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library to access the Apple File System (APFS) format * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -787,6 +787,48 @@ libfsapfs_extended_attribute_t **extended_attribute, libfsapfs_error_t **error ); +/* Determines if there is an extended attribute for an UTF-8 encoded name + * Returns 1 if available, 0 if not or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_has_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libfsapfs_error_t **error ); + +/* Determines if there is an extended attribute for an UTF-16 encoded name + * Returns 1 if available, 0 if not or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_has_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libfsapfs_error_t **error ); + +/* Retrieves the extended attribute for an UTF-8 encoded name + * Returns 1 if successful, 0 if the file entry does not contain such value or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_get_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libfsapfs_error_t **error ); + +/* Retrieves the extended attribute for an UTF-16 encoded name + * Returns 1 if successful, 0 if the file entry does not contain such value or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_get_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libfsapfs_error_t **error ); + /* Retrieves the number of sub file entries * Returns 1 if successful or -1 on error */ @@ -910,6 +952,15 @@ libfsapfs_extended_attribute_t **extended_attribute, libfsapfs_error_t **error ); +/* Retrieves the identifier + * Returns 1 if successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_extended_attribute_get_identifier( + libfsapfs_extended_attribute_t *extended_attribute, + uint64_t *identifier, + libfsapfs_error_t **error ); + /* Retrieves the size of the UTF-8 encoded name * The returned size includes the end of string character * Returns 1 if successful or -1 on error @@ -952,6 +1003,55 @@ size_t utf16_string_size, libfsapfs_error_t **error ); +/* Reads data at the current offset into a buffer + * Returns the number of bytes read or -1 on error + */ +LIBFSAPFS_EXTERN \ +ssize_t libfsapfs_extended_attribute_read_buffer( + libfsapfs_extended_attribute_t *extended_attribute, + void *buffer, + size_t buffer_size, + libfsapfs_error_t **error ); + +/* Reads data at a specific offset + * Returns the number of bytes read or -1 on error + */ +LIBFSAPFS_EXTERN \ +ssize_t libfsapfs_extended_attribute_read_buffer_at_offset( + libfsapfs_extended_attribute_t *extended_attribute, + void *buffer, + size_t buffer_size, + off64_t offset, + libfsapfs_error_t **error ); + +/* Seeks a certain offset + * Returns the offset if seek is successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +off64_t libfsapfs_extended_attribute_seek_offset( + libfsapfs_extended_attribute_t *extended_attribute, + off64_t offset, + int whence, + libfsapfs_error_t **error ); + +/* Retrieves the current offset + * Returns the offset if successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_extended_attribute_get_offset( + libfsapfs_extended_attribute_t *extended_attribute, + off64_t *offset, + libfsapfs_error_t **error ); + +/* Retrieves the size of the data stream object + * Returns 1 if successful or -1 on error + */ +LIBFSAPFS_EXTERN \ +int libfsapfs_extended_attribute_get_size( + libfsapfs_extended_attribute_t *extended_attribute, + size64_t *size, + libfsapfs_error_t **error ); + #if defined( __cplusplus ) } #endif diff -Nru libfsapfs-20181215/libbfio/libbfio_codepage.h libfsapfs-20190210/libbfio/libbfio_codepage.h --- libfsapfs-20181215/libbfio/libbfio_codepage.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_codepage.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Codepage functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_definitions.h libfsapfs-20190210/libbfio/libbfio_definitions.h --- libfsapfs-20181215/libbfio/libbfio_definitions.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_definitions.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal definitions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -33,11 +33,11 @@ * for local use of libbfio */ #else -#define LIBBFIO_VERSION 20180910 +#define LIBBFIO_VERSION 20190112 /* The libbfio version string */ -#define LIBBFIO_VERSION_STRING "20180910" +#define LIBBFIO_VERSION_STRING "20190112" /* The library flags definitions */ diff -Nru libfsapfs-20181215/libbfio/libbfio_error.c libfsapfs-20190210/libbfio/libbfio_error.c --- libfsapfs-20181215/libbfio/libbfio_error.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_error.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_error.h libfsapfs-20190210/libbfio/libbfio_error.h --- libfsapfs-20181215/libbfio/libbfio_error.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_error.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_extern.h libfsapfs-20190210/libbfio/libbfio_extern.h --- libfsapfs-20181215/libbfio/libbfio_extern.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_extern.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal extern definition * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file.c libfsapfs-20190210/libbfio/libbfio_file.c --- libfsapfs-20181215/libbfio/libbfio_file.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file.h libfsapfs-20190210/libbfio/libbfio_file.h --- libfsapfs-20181215/libbfio/libbfio_file.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_io_handle.c libfsapfs-20190210/libbfio/libbfio_file_io_handle.c --- libfsapfs-20181215/libbfio/libbfio_file_io_handle.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_io_handle.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File IO handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_io_handle.h libfsapfs-20190210/libbfio/libbfio_file_io_handle.h --- libfsapfs-20181215/libbfio/libbfio_file_io_handle.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_io_handle.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File IO handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_pool.c libfsapfs-20190210/libbfio/libbfio_file_pool.c --- libfsapfs-20181215/libbfio/libbfio_file_pool.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_pool.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File pool functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_pool.h libfsapfs-20190210/libbfio/libbfio_file_pool.h --- libfsapfs-20181215/libbfio/libbfio_file_pool.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_pool.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File pool functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_range.c libfsapfs-20190210/libbfio/libbfio_file_range.c --- libfsapfs-20181215/libbfio/libbfio_file_range.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_range.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File range functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_range.h libfsapfs-20190210/libbfio/libbfio_file_range.h --- libfsapfs-20181215/libbfio/libbfio_file_range.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_range.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File range functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_range_io_handle.c libfsapfs-20190210/libbfio/libbfio_file_range_io_handle.c --- libfsapfs-20181215/libbfio/libbfio_file_range_io_handle.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_range_io_handle.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File range IO handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_file_range_io_handle.h libfsapfs-20190210/libbfio/libbfio_file_range_io_handle.h --- libfsapfs-20181215/libbfio/libbfio_file_range_io_handle.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_file_range_io_handle.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * File range IO handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_handle.c libfsapfs-20190210/libbfio/libbfio_handle.c --- libfsapfs-20181215/libbfio/libbfio_handle.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_handle.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -132,7 +132,10 @@ "%s: unable to clear handle.", function ); - goto on_error; + memory_free( + internal_handle ); + + return( -1 ); } if( libcdata_range_list_initialize( &( internal_handle->offsets_read ), @@ -145,10 +148,7 @@ "%s: unable to create read offsets list.", function ); - memory_free( - internal_handle ); - - return( -1 ); + goto on_error; } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBBFIO ) if( libcthreads_read_write_lock_initialize( @@ -185,6 +185,13 @@ on_error: if( internal_handle != NULL ) { + if( internal_handle->offsets_read != NULL ) + { + libcdata_range_list_free( + &( internal_handle->offsets_read ), + NULL, + NULL ); + } memory_free( internal_handle ); } @@ -977,6 +984,7 @@ static char *function = "libbfio_handle_read_buffer"; ssize_t read_count = 0; int is_open = 0; + int result = 0; if( handle == NULL ) { @@ -1153,14 +1161,16 @@ } if( internal_handle->track_offsets_read != 0 ) { - if( libcdata_range_list_insert_range( - internal_handle->offsets_read, - (uint64_t) internal_handle->current_offset, - (uint64_t) read_count, - NULL, - NULL, - NULL, - error ) != 1 ) + result = libcdata_range_list_insert_range( + internal_handle->offsets_read, + (uint64_t) internal_handle->current_offset, + (uint64_t) read_count, + NULL, + NULL, + NULL, + error ); + + if( result == -1 ) { libcerror_error_set( error, diff -Nru libfsapfs-20181215/libbfio/libbfio_handle.h libfsapfs-20190210/libbfio/libbfio_handle.h --- libfsapfs-20181215/libbfio/libbfio_handle.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_handle.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_libcdata.h libfsapfs-20190210/libbfio/libbfio_libcdata.h --- libfsapfs-20181215/libbfio/libbfio_libcdata.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_libcdata.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcdata header wrapper * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_libcerror.h libfsapfs-20190210/libbfio/libbfio_libcerror.h --- libfsapfs-20181215/libbfio/libbfio_libcerror.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_libcerror.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_libcfile.h libfsapfs-20190210/libbfio/libbfio_libcfile.h --- libfsapfs-20181215/libbfio/libbfio_libcfile.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_libcfile.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal libcfile header * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -44,7 +44,7 @@ #include -#endif +#endif /* defined( HAVE_LOCAL_LIBCFILE ) */ -#endif +#endif /* !defined( _LIBBFIO_LIBCFILE_H ) */ diff -Nru libfsapfs-20181215/libbfio/libbfio_libclocale.h libfsapfs-20190210/libbfio/libbfio_libclocale.h --- libfsapfs-20181215/libbfio/libbfio_libclocale.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_libclocale.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libclocale header wrapper * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_libcpath.h libfsapfs-20190210/libbfio/libbfio_libcpath.h --- libfsapfs-20181215/libbfio/libbfio_libcpath.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_libcpath.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal libcpath header * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -42,7 +42,7 @@ #include -#endif +#endif /* defined( HAVE_LOCAL_LIBCPATH ) */ -#endif +#endif /* !defined( _LIBBFIO_LIBCPATH_H ) */ diff -Nru libfsapfs-20181215/libbfio/libbfio_libcthreads.h libfsapfs-20190210/libbfio/libbfio_libcthreads.h --- libfsapfs-20181215/libbfio/libbfio_libcthreads.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_libcthreads.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcthreads header wrapper * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_libuna.h libfsapfs-20190210/libbfio/libbfio_libuna.h --- libfsapfs-20181215/libbfio/libbfio_libuna.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_libuna.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libuna header wrapper * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_memory_range.c libfsapfs-20190210/libbfio/libbfio_memory_range.c --- libfsapfs-20181215/libbfio/libbfio_memory_range.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_memory_range.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Memory range functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_memory_range.h libfsapfs-20190210/libbfio/libbfio_memory_range.h --- libfsapfs-20181215/libbfio/libbfio_memory_range.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_memory_range.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Memory range functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_memory_range_io_handle.c libfsapfs-20190210/libbfio/libbfio_memory_range_io_handle.c --- libfsapfs-20181215/libbfio/libbfio_memory_range_io_handle.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_memory_range_io_handle.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Memory range IO handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_memory_range_io_handle.h libfsapfs-20190210/libbfio/libbfio_memory_range_io_handle.h --- libfsapfs-20181215/libbfio/libbfio_memory_range_io_handle.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_memory_range_io_handle.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Memory range IO handle functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_pool.c libfsapfs-20190210/libbfio/libbfio_pool.c --- libfsapfs-20181215/libbfio/libbfio_pool.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_pool.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal pool functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -158,7 +158,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -398,7 +398,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -418,6 +418,10 @@ "%s: unable to release read/write lock for reading.", function ); + libbfio_pool_free( + (libbfio_pool_t **) &internal_destination_pool, + NULL ); + return( -1 ); } #endif @@ -656,7 +660,7 @@ */ int libbfio_internal_pool_append_handle_to_last_used_list( libbfio_internal_pool_t *internal_pool, - libbfio_handle_t *handle, + const libbfio_handle_t *handle, libcerror_error_t **error ) { libbfio_internal_handle_t *internal_handle = NULL; @@ -945,6 +949,109 @@ return( 1 ); } +/* Removes a handle from the last used list + * Returns 1 if successful or -1 on error + */ +int libbfio_internal_pool_remove_handle_from_last_used_list( + libbfio_internal_pool_t *internal_pool, + const libbfio_handle_t *handle, + libcerror_error_t **error ) +{ + libbfio_handle_t *last_used_handle = NULL; + libcdata_list_element_t *last_used_list_element = NULL; + static char *function = "libbfio_internal_pool_remove_handle_from_last_used_list"; + + if( internal_pool == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid pool.", + function ); + + return( -1 ); + } + if( handle == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid handle.", + function ); + + return( -1 ); + } + if( libcdata_list_get_first_element( + internal_pool->last_used_list, + &last_used_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve first list element from last used list.", + function ); + + return( -1 ); + } + while( last_used_list_element != NULL ) + { + if( libcdata_list_element_get_value( + last_used_list_element, + (intptr_t **) &last_used_handle, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve last used handle.", + function ); + + return( -1 ); + } + if( last_used_handle == handle ) + { + break; + } + if( libcdata_list_element_get_next_element( + last_used_list_element, + &last_used_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next last used list element.", + function ); + + return( -1 ); + } + } + if( last_used_list_element != NULL ) + { + if( libcdata_list_remove_element( + internal_pool->last_used_list, + last_used_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove last list element from last used list.", + function ); + + return( -1 ); + } + } + return( 1 ); +} + /* Retrieves the number of handles in the pool * Returns 1 if successful or -1 on error */ @@ -1017,7 +1124,7 @@ return( result ); } -/* Retrieves a certain handle from the pool +/* Retrieves a specific handle from the pool * Returns 1 if successful or -1 on error */ int libbfio_pool_get_handle( @@ -1306,7 +1413,7 @@ return( -1 ); } -/* Sets a certain handle in the pool +/* Sets a specific handle in the pool * Returns 1 if successful or -1 on error */ int libbfio_pool_set_handle( @@ -1316,10 +1423,11 @@ int access_flags, libcerror_error_t **error ) { - libbfio_internal_handle_t *internal_handle = NULL; - libbfio_internal_pool_t *internal_pool = NULL; - static char *function = "libbfio_pool_set_handle"; - int is_open = 0; + libbfio_internal_handle_t *backup_handle = NULL; + libbfio_internal_pool_t *internal_pool = NULL; + static char *function = "libbfio_pool_set_handle"; + int is_open = 0; + int result = 1; if( pool == NULL ) { @@ -1334,32 +1442,6 @@ } internal_pool = (libbfio_internal_pool_t *) pool; - if( internal_pool->last_used_list == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid pool - missing last used list.", - function ); - - return( -1 ); - } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBBFIO ) - if( libcthreads_read_write_lock_grab_for_write( - internal_pool->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", - function ); - - return( -1 ); - } -#endif /* Check if the handle is open */ is_open = libbfio_handle_is_open( @@ -1375,7 +1457,7 @@ "%s: unable to determine if handle is open.", function ); - goto on_error; + return( -1 ); } else if( is_open == 0 ) { @@ -1393,13 +1475,28 @@ "%s: unable to set access flags.", function ); - goto on_error; + return( -1 ); } } +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBBFIO ) + if( libcthreads_read_write_lock_grab_for_write( + internal_pool->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + + return( -1 ); + } +#endif if( libcdata_array_get_entry_by_index( internal_pool->handles_array, entry, - (intptr_t **) &internal_handle, + (intptr_t **) &backup_handle, error ) != 1 ) { libcerror_error_set( @@ -1410,10 +1507,10 @@ function, entry ); - goto on_error; + result = -1; } /* TODO allow to re set handles, make sure all pool references are removed */ - if( internal_handle != NULL ) + else if( backup_handle != NULL ) { libcerror_error_set( error, @@ -1423,41 +1520,53 @@ function, entry ); - goto on_error; + result = -1; } - if( libcdata_array_set_entry_by_index( - internal_pool->handles_array, - entry, - (intptr_t *) handle, - error ) != 1 ) + if( result == 1 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set handle: %d.", - function, - entry ); + if( libcdata_array_set_entry_by_index( + internal_pool->handles_array, + entry, + (intptr_t *) handle, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set handle: %d.", + function, + entry ); - goto on_error; + result = -1; + } } - if( is_open != 0 ) + if( result == 1 ) { - if( internal_pool->maximum_number_of_open_handles != LIBBFIO_POOL_UNLIMITED_NUMBER_OF_OPEN_HANDLES ) + if( is_open != 0 ) { - if( libbfio_internal_pool_append_handle_to_last_used_list( - internal_pool, - handle, - error ) != 1 ) + if( internal_pool->maximum_number_of_open_handles != LIBBFIO_POOL_UNLIMITED_NUMBER_OF_OPEN_HANDLES ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append handle to last used list.", - function ); + if( libbfio_internal_pool_append_handle_to_last_used_list( + internal_pool, + handle, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to append handle to last used list.", + function ); + + libcdata_array_set_entry_by_index( + internal_pool->handles_array, + entry, + (intptr_t *) backup_handle, + NULL ); - goto on_error; + result = -1; + } } } } @@ -1473,21 +1582,26 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif - return( 1 ); + return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBBFIO ) - libcthreads_read_write_lock_release_for_write( - internal_pool->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + libcdata_array_set_entry_by_index( + internal_pool->handles_array, + entry, + (intptr_t *) backup_handle, + NULL ); + } return( -1 ); +#endif } -/* Removes a certain handle from the pool +/* Removes a specific handle from the pool * Returns 1 if successful or -1 on error */ int libbfio_pool_remove_handle( @@ -1496,10 +1610,10 @@ libbfio_handle_t **handle, libcerror_error_t **error ) { - libbfio_handle_t *last_used_handle = NULL; - libbfio_internal_pool_t *internal_pool = NULL; - libcdata_list_element_t *last_used_list_element = NULL; - static char *function = "libbfio_pool_remove_handle"; + libbfio_handle_t *backup_handle = NULL; + libbfio_internal_pool_t *internal_pool = NULL; + static char *function = "libbfio_pool_remove_handle"; + int result = 1; if( pool == NULL ) { @@ -1525,6 +1639,19 @@ return( -1 ); } + if( handle == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid handle.", + function ); + + return( -1 ); + } + *handle = NULL; + #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBBFIO ) if( libcthreads_read_write_lock_grab_for_write( internal_pool->read_write_lock, @@ -1540,88 +1667,68 @@ return( -1 ); } #endif - if( libcdata_array_remove_entry( + if( libcdata_array_get_entry_by_index( internal_pool->handles_array, entry, - (intptr_t **) handle, + (intptr_t **) &backup_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove handle: %d.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve handle: %d.", function, entry ); - goto on_error; - } - if( libcdata_list_get_first_element( - internal_pool->last_used_list, - &last_used_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve first list element from last used list.", - function ); - - return( -1 ); + result = -1; } - while( last_used_list_element != NULL ) + if( result == 1 ) { - if( libcdata_list_element_get_value( - last_used_list_element, - (intptr_t **) &last_used_handle, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve last used handle.", - function ); - - return( -1 ); - } - if( last_used_handle == *handle ) - { - break; - } - if( libcdata_list_element_get_next_element( - last_used_list_element, - &last_used_list_element, + if( libbfio_internal_pool_remove_handle_from_last_used_list( + internal_pool, + backup_handle, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next last used list element.", - function ); + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove handle: %d from last used list.", + function, + entry ); - return( -1 ); + result = -1; } } - if( last_used_list_element != NULL ) + if( result == 1 ) { - if( libcdata_list_remove_element( - internal_pool->last_used_list, - last_used_list_element, + if( libcdata_array_set_entry_by_index( + internal_pool->handles_array, + entry, + NULL, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove last list element from last used list.", - function ); + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set handle: %d.", + function, + entry ); - return( -1 ); + libbfio_internal_pool_append_handle_to_last_used_list( + internal_pool, + backup_handle, + NULL ); + + result = -1; } } + if( result == 1 ) + { + internal_pool->number_of_used_handles -= 1; + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBBFIO ) if( libcthreads_read_write_lock_release_for_write( internal_pool->read_write_lock, @@ -1634,18 +1741,34 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif - return( 1 ); + if( result == 1 ) + { + *handle = backup_handle; + } + return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBBFIO ) - libcthreads_read_write_lock_release_for_write( - internal_pool->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + libcdata_array_set_entry_by_index( + internal_pool->handles_array, + entry, + (intptr_t *) backup_handle, + NULL ); + + libbfio_internal_pool_append_handle_to_last_used_list( + internal_pool, + backup_handle, + NULL ); + + internal_pool->number_of_used_handles += 1; + } return( -1 ); +#endif } /* Retrieves the maximum number of open handles in the pool diff -Nru libfsapfs-20181215/libbfio/libbfio_pool.h libfsapfs-20190210/libbfio/libbfio_pool.h --- libfsapfs-20181215/libbfio/libbfio_pool.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_pool.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal pool functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -100,7 +100,7 @@ int libbfio_internal_pool_append_handle_to_last_used_list( libbfio_internal_pool_t *internal_pool, - libbfio_handle_t *handle, + const libbfio_handle_t *handle, libcerror_error_t **error ); int libbfio_internal_pool_move_handle_to_front_of_last_used_list( @@ -108,6 +108,11 @@ libbfio_handle_t *handle, libcerror_error_t **error ); +int libbfio_internal_pool_remove_handle_from_last_used_list( + libbfio_internal_pool_t *internal_pool, + const libbfio_handle_t *handle, + libcerror_error_t **error ); + LIBBFIO_EXTERN \ int libbfio_pool_get_number_of_handles( libbfio_pool_t *pool, diff -Nru libfsapfs-20181215/libbfio/libbfio_support.c libfsapfs-20190210/libbfio/libbfio_support.c --- libfsapfs-20181215/libbfio/libbfio_support.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_support.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_support.h libfsapfs-20190210/libbfio/libbfio_support.h --- libfsapfs-20181215/libbfio/libbfio_support.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_support.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_system_string.c libfsapfs-20190210/libbfio/libbfio_system_string.c --- libfsapfs-20181215/libbfio/libbfio_system_string.c 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_system_string.c 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * System string functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_system_string.h libfsapfs-20190210/libbfio/libbfio_system_string.h --- libfsapfs-20181215/libbfio/libbfio_system_string.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_system_string.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * System string functions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_types.h libfsapfs-20190210/libbfio/libbfio_types.h --- libfsapfs-20181215/libbfio/libbfio_types.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_types.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal type definitions * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libbfio/libbfio_unused.h libfsapfs-20190210/libbfio/libbfio_unused.h --- libfsapfs-20181215/libbfio/libbfio_unused.h 2018-12-15 06:43:00.000000000 +0000 +++ libfsapfs-20190210/libbfio/libbfio_unused.h 2019-02-10 19:58:20.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2009-2018, Joachim Metz + * Copyright (C) 2009-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _LIBBFIO_INTERNAL_UNUSED_H ) -#define _LIBBFIO_INTERNAL_UNUSED_H +#if !defined( _LIBBFIO_UNUSED_H ) +#define _LIBBFIO_UNUSED_H #include @@ -40,5 +40,5 @@ /* parameter */ #endif -#endif /* !defined( _LIBBFIO_INTERNAL_UNUSED_H ) */ +#endif /* !defined( _LIBBFIO_UNUSED_H ) */ diff -Nru libfsapfs-20181215/libcaes/libcaes_context.c libfsapfs-20190210/libcaes/libcaes_context.c --- libfsapfs-20181215/libcaes/libcaes_context.c 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_context.c 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * AES de/encryption context functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -312,10 +312,10 @@ goto on_error; } -#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) /* No additional initialization necessary */ -#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) ) #if defined( HAVE_EVP_CIPHER_CTX_INIT ) EVP_CIPHER_CTX_init( &( internal_context->internal_evp_cipher_context ) ); @@ -378,7 +378,7 @@ } libcaes_tables_initialized = 1; } -#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) */ +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */ *context = (libcaes_context_t *) internal_context; @@ -402,6 +402,7 @@ { libcaes_internal_context_t *internal_context = NULL; static char *function = "libcaes_context_free"; + int result = 1; if( context == NULL ) { @@ -419,10 +420,10 @@ internal_context = (libcaes_internal_context_t *) *context; *context = NULL; -#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) /* No additional clean up necessary */ -#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) ) #if defined( HAVE_EVP_CIPHER_CTX_CLEANUP ) if( EVP_CIPHER_CTX_cleanup( &( internal_context->internal_evp_cipher_context ) ) != 1 ) @@ -433,6 +434,8 @@ LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, "%s: unable to clean up EVP cipher context.", function ); + + result = -1; } /* Make sure the error state is removed otherwise OpenSSL will leak memory */ @@ -447,11 +450,13 @@ internal_context->evp_cipher_context = NULL; #else /* No additional clean up necessary */ -#endif + +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */ + memory_free( internal_context ); } - return( 1 ); + return( result ); } /* Sets the key @@ -505,7 +510,7 @@ return( -1 ); } -#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) if( mode == LIBCAES_CRYPT_MODE_ENCRYPT ) { if( AES_set_encrypt_key( @@ -541,7 +546,7 @@ } } -#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) ) if( key == NULL ) { libcerror_error_set( @@ -606,7 +611,7 @@ return( -1 ); } } -#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) */ +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */ return( 1 ); } @@ -1161,7 +1166,7 @@ #endif /* !defined( LIBCAES_HAVE_AES_SUPPORT ) */ -#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_CBC_ENCRYPT ) /* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using OpenSSL * The size must be a multitude of the AES block size (16 byte) @@ -1348,7 +1353,7 @@ return( 1 ); } -#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_CBC ) /* De- or encrypts a block of data using AES-CBC (Cipher Block Chaining) using OpenSSL EVP * The size must be a multitude of the AES block size (16 byte) @@ -1879,7 +1884,7 @@ return( -1 ); } -#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) */ +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_CBC_ENCRYPT ) */ /* De- or encrypts a block of data using AES-CCM (Counter with CBC-MAC) * Note that the key must be set in encryption mode (LIBCAES_CRYPT_MODE_ENCRYPT) for both de- and encryption. @@ -2349,7 +2354,7 @@ #endif /* TODO */ -#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_ECB_ENCRYPT ) /* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using OpenSSL * The size must be a multitude of the AES block size (16 byte) @@ -2449,13 +2454,13 @@ return( -1 ); } - if( output_data_size < 16 ) + if( output_data_size < input_data_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid output data size value too small.", + "%s: invalid ouput data size smaller than input data size.", function ); return( -1 ); @@ -2477,7 +2482,7 @@ return( result ); } -#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_ECB ) /* De- or encrypts a block of data using AES-ECB (Electronic CodeBook) using OpenSSL EVP * The size must be a multitude of the AES block size (16 byte) @@ -2580,13 +2585,13 @@ return( -1 ); } - if( output_data_size < 16 ) + if( output_data_size < input_data_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid output data size value too small.", + "%s: invalid ouput data size smaller than input data size.", function ); return( -1 ); @@ -2767,13 +2772,13 @@ return( -1 ); } - if( output_data_size < 16 ) + if( output_data_size < input_data_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: invalid output data size value too small.", + "%s: invalid ouput data size smaller than input data size.", function ); return( -1 ); @@ -2926,5 +2931,5 @@ return( result ); } -#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) */ +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && defined( HAVE_AES_ECB_ENCRYPT ) */ diff -Nru libfsapfs-20181215/libcaes/libcaes_context.h libfsapfs-20190210/libcaes/libcaes_context.h --- libfsapfs-20181215/libcaes/libcaes_context.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_context.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * AES de/encryption context functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -44,12 +44,12 @@ struct libcaes_internal_context { -#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) /* The AES key */ AES_KEY key; -#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#elif defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && ( defined( HAVE_EVP_CRYPTO_AES_CBC ) || defined( HAVE_EVP_CRYPTO_AES_ECB ) ) /* The EVP cipher context */ #if defined( HAVE_EVP_CIPHER_CTX_INIT ) @@ -79,7 +79,7 @@ */ uint32_t round_keys_data[ 68 ]; -#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) */ +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_AES_H ) && ( defined( HAVE_AES_CBC_ENCRYPT ) || defined( HAVE_AES_ECB_ENCRYPT ) ) */ }; LIBCAES_EXTERN \ diff -Nru libfsapfs-20181215/libcaes/libcaes_definitions.h libfsapfs-20190210/libcaes/libcaes_definitions.h --- libfsapfs-20181215/libcaes/libcaes_definitions.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_definitions.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal definitions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -34,11 +34,11 @@ * for local use of libcaes */ #else -#define LIBCAES_VERSION 20180929 +#define LIBCAES_VERSION 20190102 /* The libcaes version string */ -#define LIBCAES_VERSION_STRING "20180929" +#define LIBCAES_VERSION_STRING "20190102" /* The crypt modes */ diff -Nru libfsapfs-20181215/libcaes/libcaes_error.c libfsapfs-20190210/libcaes/libcaes_error.c --- libfsapfs-20181215/libcaes/libcaes_error.c 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_error.c 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcaes/libcaes_error.h libfsapfs-20190210/libcaes/libcaes_error.h --- libfsapfs-20181215/libcaes/libcaes_error.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_error.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcaes/libcaes_extern.h libfsapfs-20190210/libcaes/libcaes_extern.h --- libfsapfs-20181215/libcaes/libcaes_extern.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_extern.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal extern definition * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcaes/libcaes_libcerror.h libfsapfs-20190210/libcaes/libcaes_libcerror.h --- libfsapfs-20181215/libcaes/libcaes_libcerror.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_libcerror.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcaes/libcaes_support.c libfsapfs-20190210/libcaes/libcaes_support.c --- libfsapfs-20181215/libcaes/libcaes_support.c 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_support.c 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcaes/libcaes_support.h libfsapfs-20190210/libcaes/libcaes_support.h --- libfsapfs-20181215/libcaes/libcaes_support.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_support.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcaes/libcaes_tweaked_context.c libfsapfs-20190210/libcaes/libcaes_tweaked_context.c --- libfsapfs-20181215/libcaes/libcaes_tweaked_context.c 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_tweaked_context.c 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * AES encryption functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -24,6 +24,11 @@ #include #include +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#include +#include +#endif + #include "libcaes_context.h" #include "libcaes_definitions.h" #include "libcaes_libcerror.h" @@ -94,6 +99,53 @@ return( -1 ); } +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) +#if defined( HAVE_EVP_CIPHER_CTX_INIT ) + EVP_CIPHER_CTX_init( + &( internal_tweaked_context->internal_evp_cipher_context ) ); + + internal_tweaked_context->evp_cipher_context = &( internal_tweaked_context->internal_evp_cipher_context ); +#else + internal_tweaked_context->evp_cipher_context = EVP_CIPHER_CTX_new(); + + if( internal_tweaked_context->evp_cipher_context == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create EVP cipher context.", + function ); + + goto on_error; + } +#endif /* defined( HAVE_EVP_CIPHER_CTX_INIT ) */ + + if( EVP_CIPHER_CTX_set_padding( + internal_tweaked_context->evp_cipher_context, + 1 ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set padding in context.", + function ); + +#if defined( HAVE_EVP_CIPHER_CTX_CLEANUP ) + EVP_CIPHER_CTX_cleanup( + &( internal_tweaked_context->internal_evp_cipher_context ) ); + ERR_remove_thread_state( + NULL ); +#else + EVP_CIPHER_CTX_free( + internal_tweaked_context->evp_cipher_context ); +#endif + internal_tweaked_context->evp_cipher_context = NULL; + + goto on_error; + } +#else if( libcaes_context_initialize( &( internal_tweaked_context->main_context ), error ) != 1) @@ -120,6 +172,8 @@ goto on_error; } +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */ + *tweaked_context = (libcaes_tweaked_context_t *) internal_tweaked_context; return( 1 ); @@ -127,12 +181,18 @@ on_error: if( internal_tweaked_context != NULL ) { +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) + /* No additional clean up necessary */ + +#else if( internal_tweaked_context->main_context != NULL ) { libcaes_context_free( &( internal_tweaked_context->main_context ), NULL ); } +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */ + memory_free( internal_tweaked_context ); } @@ -166,6 +226,32 @@ internal_tweaked_context = (libcaes_internal_tweaked_context_t *) *tweaked_context; *tweaked_context = NULL; +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) +#if defined( HAVE_EVP_CIPHER_CTX_CLEANUP ) + if( EVP_CIPHER_CTX_cleanup( + &( internal_tweaked_context->internal_evp_cipher_context ) ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to clean up EVP cipher context.", + function ); + + result = -1; + } + /* Make sure the error state is removed otherwise OpenSSL will leak memory + */ + ERR_remove_thread_state( + NULL ); +#else + EVP_CIPHER_CTX_free( + internal_tweaked_context->evp_cipher_context ); + +#endif /* defined( HAVE_EVP_CIPHER_CTX_CLEANUP ) */ + + internal_tweaked_context->evp_cipher_context = NULL; +#else if( libcaes_context_free( &( internal_tweaked_context->tweak_context ), error ) != 1 ) @@ -192,6 +278,8 @@ result = -1; } +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */ + memory_free( internal_tweaked_context ); } @@ -213,6 +301,10 @@ libcaes_internal_tweaked_context_t *internal_tweaked_context = NULL; static char *function = "libcaes_tweaked_context_set_key"; +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) + size_t key_byte_size = 0; +#endif + if( tweaked_context == NULL ) { libcerror_error_set( @@ -239,7 +331,6 @@ return( -1 ); } if( ( key_bit_size != 128 ) - && ( key_bit_size != 192 ) && ( key_bit_size != 256 ) ) { libcerror_error_set( @@ -251,6 +342,73 @@ return( -1 ); } + if( tweak_key_bit_size != key_bit_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported tweak key bit size.", + function ); + + return( -1 ); + } +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) + if( key == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid key.", + function ); + + return( -1 ); + } + if( tweak_key == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid tweak key.", + function ); + + return( -1 ); + } + key_byte_size = key_bit_size / 8; + + if( memory_copy( + internal_tweaked_context->key, + key, + key_byte_size ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy key.", + function ); + + return( -1 ); + } + if( memory_copy( + &( internal_tweaked_context->key[ key_byte_size ] ), + tweak_key, + key_byte_size ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy tweak key.", + function ); + + return( -1 ); + } + internal_tweaked_context->key_bit_size = key_bit_size; + +#else if( libcaes_context_set_key( internal_tweaked_context->main_context, mode, @@ -283,10 +441,217 @@ return( -1 ); } +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */ + + return( 1 ); +} + +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) + +/* De- or encrypts a block of data using AES-XTS (XEX-based tweaked-codebook mode with ciphertext stealing) using OpenSSL EVP + * The size must be a multitude of the AES block size (16 byte) + * Returns 1 if successful or -1 on error + */ +int libcaes_crypt_xts( + libcaes_tweaked_context_t *tweaked_context, + int mode, + const uint8_t *tweak_value, + size_t tweak_value_size, + const uint8_t *input_data, + size_t input_data_size, + uint8_t *output_data, + size_t output_data_size, + libcerror_error_t **error ) +{ + uint8_t block_data[ EVP_MAX_BLOCK_LENGTH ]; + + const EVP_CIPHER *cipher = NULL; + libcaes_internal_tweaked_context_t *internal_tweaked_context = NULL; + static char *function = "libcaes_crypt_xts"; + int safe_output_data_size = 0; + + if( tweaked_context == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid tweaked context.", + function ); + + return( -1 ); + } + internal_tweaked_context = (libcaes_internal_tweaked_context_t *) tweaked_context; + + if( ( mode != LIBCAES_CRYPT_MODE_DECRYPT ) + && ( mode != LIBCAES_CRYPT_MODE_ENCRYPT ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported mode.", + function ); + + return( -1 ); + } + if( tweak_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid tweak value.", + function ); + + return( -1 ); + } + if( tweak_value_size != 16 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid tweak value size value out of bounds.", + function ); + + return( -1 ); + } + if( input_data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid input data.", + function ); + + return( -1 ); + } + if( input_data_size > (size_t) INT_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid input data size value exceeds maximum.", + function ); + + return( -1 ); + } + if( input_data_size < 16 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, + "%s: invalid input data size value too small.", + function ); + + return( -1 ); + } + if( output_data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid output data.", + function ); + + return( -1 ); + } + if( output_data_size > (size_t) INT_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid output data size value exceeds maximum.", + function ); + + return( -1 ); + } + if( output_data_size < input_data_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid ouput data size smaller than input data size.", + function ); + + return( -1 ); + } + if( memory_set( + block_data, + 0, + EVP_MAX_BLOCK_LENGTH ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear input block data.", + function ); + + return( -1 ); + } + if( internal_tweaked_context->key_bit_size == 128 ) + { + cipher = EVP_aes_128_xts(); + } + else if( internal_tweaked_context->key_bit_size == 256 ) + { + cipher = EVP_aes_256_xts(); + } + if( EVP_CipherInit_ex( + internal_tweaked_context->evp_cipher_context, + cipher, + NULL, + (unsigned char *) internal_tweaked_context->key, + (unsigned char *) tweak_value, + mode ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to initialize cipher.", + function ); + + return( -1 ); + } + if( EVP_CipherUpdate( + internal_tweaked_context->evp_cipher_context, + (unsigned char *) output_data, + &safe_output_data_size, + (unsigned char *) input_data, + input_data_size ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to update cipher.", + function ); + + return( -1 ); + } + /* Just ignore the output of this function + */ + EVP_CipherFinal_ex( + internal_tweaked_context->evp_cipher_context, + (unsigned char *) block_data, + &safe_output_data_size ); + return( 1 ); } -/* De- or encrypts a block of data using AES-XTS (XEX-based tweaked-codebook mode with ciphertext stealing) +#else + +/* De- or encrypts a block of data using AES-XTS (XEX-based tweaked-codebook mode with ciphertext stealing) using fallback implementation + * The size must be a multitude of the AES block size (16 byte) * Returns 1 if successful or -1 on error */ int libcaes_crypt_xts( @@ -758,3 +1123,5 @@ return( -1 ); } +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */ + diff -Nru libfsapfs-20181215/libcaes/libcaes_tweaked_context.h libfsapfs-20190210/libcaes/libcaes_tweaked_context.h --- libfsapfs-20181215/libcaes/libcaes_tweaked_context.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_tweaked_context.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * AES tweaked de/encryption context functions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,6 +25,10 @@ #include #include +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) +#include +#endif + #include "libcaes_extern.h" #include "libcaes_libcerror.h" #include "libcaes_types.h" @@ -37,6 +41,24 @@ struct libcaes_internal_tweaked_context { +#if defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) + /* The EVP cipher context + */ +#if defined( HAVE_EVP_CIPHER_CTX_INIT ) + EVP_CIPHER_CTX internal_evp_cipher_context; +#endif + + EVP_CIPHER_CTX *evp_cipher_context; + + /* The key + */ + uint8_t key[ 64 ]; + + /* The key bit size + */ + size_t key_bit_size; + +#else /* The main de/encryption context */ libcaes_context_t *main_context; @@ -44,6 +66,8 @@ /* The tweak encryption context */ libcaes_context_t *tweak_context; + +#endif /* defined( HAVE_LIBCRYPTO ) && defined( HAVE_OPENSSL_EVP_H ) && defined( HAVE_EVP_CRYPTO_AES_XTS ) */ }; LIBCAES_EXTERN \ diff -Nru libfsapfs-20181215/libcaes/libcaes_types.h libfsapfs-20190210/libcaes/libcaes_types.h --- libfsapfs-20181215/libcaes/libcaes_types.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_types.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal type definitions * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcaes/libcaes_unused.h libfsapfs-20190210/libcaes/libcaes_unused.h --- libfsapfs-20181215/libcaes/libcaes_unused.h 2018-12-15 06:43:03.000000000 +0000 +++ libfsapfs-20190210/libcaes/libcaes_unused.h 2019-02-10 19:58:22.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2011-2018, Joachim Metz + * Copyright (C) 2011-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _LIBCAES_INTERNAL_UNUSED_H ) -#define _LIBCAES_INTERNAL_UNUSED_H +#if !defined( _LIBCAES_UNUSED_H ) +#define _LIBCAES_UNUSED_H #include @@ -40,5 +40,5 @@ /* parameter */ #endif -#endif /* !defined( _LIBCAES_INTERNAL_UNUSED_H ) */ +#endif /* !defined( _LIBCAES_UNUSED_H ) */ diff -Nru libfsapfs-20181215/libcdata/libcdata_array.c libfsapfs-20190210/libcdata/libcdata_array.c --- libfsapfs-20181215/libcdata/libcdata_array.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_array.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Array functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -134,7 +134,7 @@ } entries_size = sizeof( intptr_t * ) * number_of_allocated_entries; - if( entries_size > (size_t) SSIZE_MAX ) + if( entries_size > (size_t) LIBCDATA_ARRAY_ENTRIES_MEMORY_LIMIT ) { libcerror_error_set( error, @@ -185,7 +185,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -282,6 +282,8 @@ /* Empties an array and frees its entries * The entries are freed using the entry_free_function + * If the entry_free_function fails for a specific entry it is not freed and kept in the array + * * Returns 1 if successful or -1 on error */ int libcdata_array_empty( @@ -337,8 +339,10 @@ result = -1; } - internal_array->number_of_entries = 0; - + else + { + internal_array->number_of_entries = 0; + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_array->read_write_lock, @@ -359,6 +363,8 @@ /* Clears an array and frees its entries * The entries are freed using the entry_free_function + * If the entry_free_function fails for a specific entry it is not freed and kept in the array + * * This function is not multi-thread safe acquire write lock before call * Returns 1 if successful or -1 on error */ @@ -370,6 +376,7 @@ libcerror_error_t **error ) { static char *function = "libcdata_internal_array_clear"; + int entry_free_result = 0; int entry_iterator = 0; int result = 1; @@ -384,31 +391,47 @@ return( -1 ); } - if( internal_array->entries != NULL ) + if( internal_array->entries == NULL ) { - for( entry_iterator = 0; - entry_iterator < internal_array->number_of_entries; - entry_iterator++ ) + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid array - missing entries.", + function ); + + return( -1 ); + } + for( entry_iterator = 0; + entry_iterator < internal_array->number_of_entries; + entry_iterator++ ) + { + if( internal_array->entries[ entry_iterator ] != NULL ) { - if( internal_array->entries[ entry_iterator ] != NULL ) + if( entry_free_function == NULL ) { - if( entry_free_function != NULL ) - { - if( entry_free_function( - &( internal_array->entries[ entry_iterator ] ), - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free array entry: %d.", - function, - entry_iterator ); + entry_free_result = 1; + } + else + { + entry_free_result = entry_free_function( + &( internal_array->entries[ entry_iterator ] ), + error ); + } + if( entry_free_result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free array entry: %d.", + function, + entry_iterator ); - result = -1; - } - } + result = -1; + } + else + { internal_array->entries[ entry_iterator ] = NULL; } } @@ -418,6 +441,8 @@ /* Clears an array and frees its entries * The entries are freed using the entry_free_function + * If the entry_free_function fails for a specific entry it is not freed and kept in the array + * * Returns 1 if successful or -1 on error */ int libcdata_array_clear( @@ -567,46 +592,46 @@ } internal_source_array = (libcdata_internal_array_t *) source_array; - if( libcdata_array_initialize( - (libcdata_array_t **) &internal_destination_array, - internal_source_array->number_of_entries, +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_read( + internal_source_array->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create destination array.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for reading.", function ); return( -1 ); } - if( internal_destination_array == NULL ) +#endif + if( libcdata_array_initialize( + (libcdata_array_t **) &internal_destination_array, + internal_source_array->number_of_entries, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing destination array.", + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create destination array.", function ); - return( -1 ); + goto on_error; } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_read( - internal_source_array->read_write_lock, - error ) != 1 ) + if( internal_destination_array == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for reading.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing destination array.", function ); - return( -1 ); + goto on_error; } -#endif if( internal_source_array->entries != NULL ) { for( entry_iterator = 0; @@ -703,6 +728,17 @@ return( -1 ); } + if( internal_array->entries == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid array - missing entries.", + function ); + + return( -1 ); + } if( number_of_entries < 0 ) { libcerror_error_set( @@ -743,7 +779,7 @@ } entries_size = sizeof( intptr_t * ) * number_of_allocated_entries; - if( entries_size > (size_t) SSIZE_MAX ) + if( entries_size > (size_t) LIBCDATA_ARRAY_ENTRIES_MEMORY_LIMIT ) { libcerror_error_set( error, @@ -771,19 +807,15 @@ } internal_array->entries = (intptr_t **) reallocation; - if( memory_set( - &( internal_array->entries[ internal_array->number_of_allocated_entries ] ), - 0, - sizeof( intptr_t * ) * ( number_of_allocated_entries - internal_array->number_of_allocated_entries ) ) == NULL ) + /* Cannot use memset reliably here. The loop below will be removed + * when memset is used and the code is optimized. Therefore the loop + * is not executed when memset fails. + */ + for( entry_iterator = internal_array->number_of_allocated_entries; + entry_iterator < number_of_allocated_entries; + entry_iterator++ ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_SET_FAILED, - "%s: unable to clear array entries.", - function ); - - result = -1; + internal_array->entries[ entry_iterator ] = NULL; } internal_array->number_of_allocated_entries = number_of_allocated_entries; internal_array->number_of_entries = number_of_entries; @@ -1194,6 +1226,17 @@ } internal_array = (libcdata_internal_array_t *) array; + if( internal_array->entries == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid array - missing entries.", + function ); + + return( -1 ); + } if( entry_compare_function == NULL ) { libcerror_error_set( @@ -1231,39 +1274,36 @@ return( -1 ); } #endif - if( internal_array->entries != NULL ) - { - for( entry_index = 0; - entry_index < internal_array->number_of_entries; - entry_index++ ) - { - compare_result = entry_compare_function( - entry, - internal_array->entries[ entry_index ], - error ); + for( entry_index = 0; + entry_index < internal_array->number_of_entries; + entry_index++ ) + { + compare_result = entry_compare_function( + entry, + internal_array->entries[ entry_index ], + error ); - if( compare_result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to compare entry: %d.", - function, - entry_index ); + if( compare_result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to compare entry: %d.", + function, + entry_index ); - result = -1; + result = -1; - break; - } - else if( compare_result == LIBCDATA_COMPARE_EQUAL ) - { - *existing_entry = internal_array->entries[ entry_index ]; + break; + } + else if( compare_result == LIBCDATA_COMPARE_EQUAL ) + { + *existing_entry = internal_array->entries[ entry_index ]; - result = 1; + result = 1; - break; - } + break; } } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) @@ -1296,6 +1336,10 @@ libcdata_internal_array_t *internal_array = NULL; static char *function = "libcdata_array_set_entry_by_index"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + intptr_t *backup_entry = NULL; +#endif + if( array == NULL ) { libcerror_error_set( @@ -1346,6 +1390,7 @@ return( -1 ); } + backup_entry = internal_array->entries[ entry_index ]; #endif internal_array->entries[ entry_index ] = entry; @@ -1361,10 +1406,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_array->entries[ entry_index ] = backup_entry; + + return( -1 ); +#endif } /* Prepends an entry @@ -1378,6 +1430,7 @@ libcdata_internal_array_t *internal_array = NULL; static char *function = "libcdata_array_prepend_entry"; int entry_iterator = 0; + int result = 0; if( array == NULL ) { @@ -1392,6 +1445,17 @@ } internal_array = (libcdata_internal_array_t *) array; + if( internal_array->entries == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid array - missing entries.", + function ); + + return( -1 ); + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_grab_for_write( internal_array->read_write_lock, @@ -1407,11 +1471,13 @@ return( -1 ); } #endif - if( libcdata_internal_array_resize( - internal_array, - internal_array->number_of_entries + 1, - NULL, - error ) != 1 ) + result = libcdata_internal_array_resize( + internal_array, + internal_array->number_of_entries + 1, + NULL, + error ); + + if( result != 1 ) { libcerror_error_set( error, @@ -1420,19 +1486,18 @@ "%s: unable to resize array.", function ); - goto on_error; + result = -1; } - if( internal_array->number_of_entries > 1 ) + else { - for( entry_iterator = internal_array->number_of_entries - 2; - entry_iterator >= 0; + for( entry_iterator = internal_array->number_of_entries - 1; + entry_iterator > 0; entry_iterator-- ) { - internal_array->entries[ entry_iterator + 1 ] = internal_array->entries[ entry_iterator ]; + internal_array->entries[ entry_iterator ] = internal_array->entries[ entry_iterator - 1 ]; } + internal_array->entries[ entry_iterator ] = entry; } - internal_array->entries[ 0 ] = entry; - #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_array->read_write_lock, @@ -1445,18 +1510,27 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif - return( 1 ); + return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_array->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + for( entry_iterator = 0; + entry_iterator < ( internal_array->number_of_entries - 1 ); + entry_iterator++ ) + { + internal_array->entries[ entry_iterator ] = internal_array->entries[ entry_iterator + 1 ]; + } + internal_array->entries[ entry_iterator ] = NULL; + + internal_array->number_of_entries -= 1; + } return( -1 ); +#endif } /* Appends an entry @@ -1471,6 +1545,8 @@ { libcdata_internal_array_t *internal_array = NULL; static char *function = "libcdata_array_append_entry"; + int result = 0; + int safe_entry_index = 0; if( array == NULL ) { @@ -1485,6 +1561,17 @@ } internal_array = (libcdata_internal_array_t *) array; + if( internal_array->entries == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid array - missing entries.", + function ); + + return( -1 ); + } if( entry_index == NULL ) { libcerror_error_set( @@ -1511,13 +1598,15 @@ return( -1 ); } #endif - *entry_index = internal_array->number_of_entries; + safe_entry_index = internal_array->number_of_entries; - if( libcdata_internal_array_resize( - internal_array, - internal_array->number_of_entries + 1, - NULL, - error ) != 1 ) + result = libcdata_internal_array_resize( + internal_array, + internal_array->number_of_entries + 1, + NULL, + error ); + + if( result != 1 ) { libcerror_error_set( error, @@ -1526,10 +1615,12 @@ "%s: unable to resize array.", function ); - goto on_error; + result = -1; + } + else + { + internal_array->entries[ safe_entry_index ] = entry; } - internal_array->entries[ *entry_index ] = entry; - #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_array->read_write_lock, @@ -1542,18 +1633,25 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif - return( 1 ); + if( result == 1 ) + { + *entry_index = safe_entry_index; + } + return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_array->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + internal_array->entries[ safe_entry_index ] = NULL; + + internal_array->number_of_entries -= 1; + } return( -1 ); +#endif } /* Inserts an entry in the array @@ -1565,6 +1663,8 @@ * Duplicate entries are allowed by default and inserted after the last duplicate entry. * Only allowing unique entries can be enforced by setting the flag LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES * + * entry_index is set when the entry was successfully inserted + * * Returns 1 if successful, 0 if the entry already exists or -1 on error */ int libcdata_array_insert_entry( @@ -1582,7 +1682,8 @@ static char *function = "libcdata_tree_node_insert_node"; int compare_result = 0; int entry_iterator = 0; - int result = 1; + int result = 0; + int safe_entry_index = 0; if( array == NULL ) { @@ -1597,6 +1698,17 @@ } internal_array = (libcdata_internal_array_t *) array; + if( internal_array->entries == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid array - missing entries.", + function ); + + return( -1 ); + } if( entry_index == NULL ) { libcerror_error_set( @@ -1646,119 +1758,93 @@ return( -1 ); } #endif - if( internal_array->entries != NULL ) - { - for( entry_iterator = 0; - entry_iterator < internal_array->number_of_entries; - entry_iterator++ ) - { - compare_result = entry_compare_function( - entry, - internal_array->entries[ entry_iterator ], - error ); + compare_result = LIBCDATA_COMPARE_GREATER; + result = 1; - if( compare_result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to compare entry: %d.", - function, - entry_iterator ); + for( entry_iterator = 0; + entry_iterator < internal_array->number_of_entries; + entry_iterator++ ) + { + compare_result = entry_compare_function( + entry, + internal_array->entries[ entry_iterator ], + error ); - goto on_error; - } - else if( compare_result == LIBCDATA_COMPARE_EQUAL ) - { - if( ( insert_flags & LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) != 0 ) - { - result = 0; + if( compare_result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to compare entry: %d.", + function, + entry_iterator ); - break; - } - } - else if( compare_result == LIBCDATA_COMPARE_LESS ) + result = -1; + } + else if( compare_result == LIBCDATA_COMPARE_EQUAL ) + { + if( ( insert_flags & LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) != 0 ) { - result = 1; - - break; + result = 0; } - else if( compare_result != LIBCDATA_COMPARE_GREATER ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, - "%s: unsupported entry compare function return value: %d.", - function, - compare_result ); + } + else if( compare_result == LIBCDATA_COMPARE_LESS ) + { + result = 1; - goto on_error; - } + break; + } + else if( compare_result != LIBCDATA_COMPARE_GREATER ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported entry compare function return value: %d.", + function, + compare_result ); + + result = -1; + } + if( result != 1 ) + { + break; } } - if( result != 0 ) + if( result == 1 ) { - if( ( internal_array->entries != NULL ) - && ( compare_result == LIBCDATA_COMPARE_LESS ) ) - { - *entry_index = entry_iterator; + result = libcdata_internal_array_resize( + internal_array, + internal_array->number_of_entries + 1, + NULL, + error ); - if( libcdata_internal_array_resize( - internal_array, - internal_array->number_of_entries + 1, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, - "%s: unable to resize array.", - function ); + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, + "%s: unable to resize array.", + function ); - goto on_error; - } - for( entry_iterator = internal_array->number_of_entries - 1; - entry_iterator > *entry_index; - entry_iterator-- ) - { - internal_array->entries[ entry_iterator ] = internal_array->entries[ entry_iterator - 1 ]; - } - internal_array->entries[ *entry_index ] = entry; + result = -1; } else { - *entry_index = internal_array->number_of_entries; + safe_entry_index = entry_iterator; - if( libcdata_internal_array_resize( - internal_array, - internal_array->number_of_entries + 1, - NULL, - error ) != 1 ) + if( compare_result == LIBCDATA_COMPARE_LESS ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, - "%s: unable to resize array.", - function ); - - goto on_error; - } - if( internal_array->entries == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid array - missing entries.", - function ); - - goto on_error; + for( entry_iterator = internal_array->number_of_entries - 1; + entry_iterator > safe_entry_index; + entry_iterator-- ) + { + internal_array->entries[ entry_iterator ] = internal_array->entries[ entry_iterator - 1 ]; + } } - internal_array->entries[ *entry_index ] = entry; + internal_array->entries[ safe_entry_index ] = entry; } } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) @@ -1773,18 +1859,31 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif + if( result == 1 ) + { + *entry_index = safe_entry_index; + } return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_array->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + for( entry_iterator = safe_entry_index; + entry_iterator < ( internal_array->number_of_entries - 1 ); + entry_iterator++ ) + { + internal_array->entries[ entry_iterator ] = internal_array->entries[ entry_iterator + 1 ]; + } + internal_array->entries[ entry_iterator ] = NULL; + + internal_array->number_of_entries -= 1; + } return( -1 ); +#endif } /* Removes an entry @@ -1797,6 +1896,7 @@ libcerror_error_t **error ) { libcdata_internal_array_t *internal_array = NULL; + intptr_t *safe_entry = NULL; static char *function = "libcdata_array_remove_entry"; int entry_iterator = 0; @@ -1813,6 +1913,17 @@ } internal_array = (libcdata_internal_array_t *) array; + if( internal_array->entries == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid array - missing entries.", + function ); + + return( -1 ); + } if( ( entry_index < 0 ) || ( entry_index >= internal_array->number_of_entries ) ) { @@ -1836,6 +1947,8 @@ return( -1 ); } + *entry = NULL; + #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_grab_for_write( internal_array->read_write_lock, @@ -1851,37 +1964,18 @@ return( -1 ); } #endif - *entry = internal_array->entries[ entry_index ]; + safe_entry = internal_array->entries[ entry_index ]; - if( entry_index == ( internal_array->number_of_entries - 1 ) ) + for( entry_iterator = entry_index; + entry_iterator < ( internal_array->number_of_entries - 1 ); + entry_iterator++ ) { - internal_array->entries[ entry_index ] = NULL; + internal_array->entries[ entry_iterator ] = internal_array->entries[ entry_iterator + 1 ]; } - else - { - for( entry_iterator = ( internal_array->number_of_entries - 1 ); - entry_iterator > entry_index; - entry_iterator-- ) - { - internal_array->entries[ entry_iterator - 1 ] = internal_array->entries[ entry_iterator ]; - internal_array->entries[ entry_iterator ] = NULL; - } - } - if( libcdata_internal_array_resize( - internal_array, - internal_array->number_of_entries - 1, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_RESIZE_FAILED, - "%s: unable to resize array.", - function ); + internal_array->entries[ entry_iterator ] = NULL; + + internal_array->number_of_entries -= 1; - goto on_error; - } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_array->read_write_lock, @@ -1894,17 +1988,26 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif + *entry = safe_entry; + return( 1 ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_array->read_write_lock, - NULL ); -#endif +on_error: + internal_array->number_of_entries += 1; + + for( entry_iterator = ( internal_array->number_of_entries - 1 ); + entry_iterator > entry_index; + entry_iterator-- ) + { + internal_array->entries[ entry_iterator ] = internal_array->entries[ entry_iterator - 1 ]; + } + internal_array->entries[ entry_index ] = safe_entry; + return( -1 ); +#endif } diff -Nru libfsapfs-20181215/libcdata/libcdata_array.h libfsapfs-20190210/libcdata/libcdata_array.h --- libfsapfs-20181215/libcdata/libcdata_array.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_array.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Array functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_btree.c libfsapfs-20190210/libcdata/libcdata_btree.c --- libfsapfs-20181215/libcdata/libcdata_btree.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_btree.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Balanced tree type functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,6 +25,8 @@ #include "libcdata_array.h" #include "libcdata_btree.h" +#include "libcdata_btree_node.h" +#include "libcdata_btree_values_list.h" #include "libcdata_definitions.h" #include "libcdata_libcerror.h" #include "libcdata_libcthreads.h" @@ -147,7 +149,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -221,7 +223,7 @@ #endif if( libcdata_tree_node_free( &( internal_tree->root_node ), - (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_free_values_list, + (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_values_list_free, error ) != 1 ) { libcerror_error_set( @@ -253,1564 +255,8 @@ return( result ); } -/* Frees a values list - * Returns 1 if successful or -1 on error - */ -int libcdata_btree_free_values_list( - libcdata_list_t **values_list, - libcerror_error_t **error ) -{ - static char *function = "libcdata_btree_free_values_list"; - int result = 1; - - if( values_list == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid values list.", - function ); - - return( -1 ); - } - if( libcdata_list_free( - values_list, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free values list.", - function ); - - result = -1; - } - return( result ); -} - /* TODO add clone function ? */ -/* Retrieves the sub node for the specific value - * - * Uses the value_compare_function to determine the similarity of the entries - * The value_compare_function should return LIBCDATA_COMPARE_LESS, - * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error - * - * If value_compare_function is NULL the pointer of the value is used to check for a match - * - * Returns 1 if successful, 0 if the value does not exist or -1 on error - * If there was no possible sub match values_list_element is set to NULL - * it there is a possible sub match values_list_element is set but 0 is returned - * If the node is a leaf node sub_node is not set to NULL - */ -int libcdata_btree_node_get_sub_node_by_value( - libcdata_tree_node_t *node, - intptr_t *value, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - libcdata_tree_node_t **sub_node, - libcdata_list_element_t **values_list_element, - libcerror_error_t **error ) -{ - libcdata_list_t *values_list = NULL; - libcdata_list_element_t *safe_values_list_element = NULL; - libcdata_tree_node_t *safe_sub_node = NULL; - intptr_t *values_list_value = NULL; - static char *function = "libcdata_btree_node_get_sub_node_by_value"; - int number_of_sub_nodes = 0; - int number_of_values_list_elements = 0; - int result = 0; - int sub_node_index = 0; - int values_list_element_index = 0; - - if( value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value.", - function ); - - return( -1 ); - } - if( sub_node == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid sub node.", - function ); - - return( -1 ); - } - if( values_list_element == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid values list element.", - function ); - - return( -1 ); - } - *sub_node = NULL; - *values_list_element = NULL; - - if( libcdata_tree_node_get_value( - node, - (intptr_t **) &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve values list.", - function ); - - return( -1 ); - } - if( values_list != NULL ) - { - if( libcdata_list_get_number_of_elements( - values_list, - &number_of_values_list_elements, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of values list elements.", - function ); - - return( -1 ); - } - } - if( libcdata_tree_node_get_number_of_sub_nodes( - node, - &number_of_sub_nodes, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of sub nodes.", - function ); - - return( -1 ); - } - if( ( number_of_sub_nodes != 0 ) - && ( ( number_of_values_list_elements + 1 ) != number_of_sub_nodes ) ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid number of values list elements value out of bounds.", - function ); - - return( -1 ); - } - if( number_of_values_list_elements == 0 ) - { - return( 0 ); - } - if( libcdata_list_get_first_element( - values_list, - &safe_values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve first values list element.", - function ); - - return( -1 ); - } - if( number_of_sub_nodes != 0 ) - { - if( libcdata_tree_node_get_sub_node_by_index( - node, - 0, - &safe_sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve sub node: 0.", - function ); - - return( -1 ); - } - } - for( values_list_element_index = 0; - values_list_element_index < number_of_values_list_elements; - values_list_element_index++ ) - { - if( libcdata_list_element_get_value( - safe_values_list_element, - &values_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from values list element: %d.", - function, - values_list_element_index ); - - return( -1 ); - } - if( values_list_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid values list element: %d - missing value.", - function, - values_list_element_index ); - - return( -1 ); - } - if( value_compare_function != NULL ) - { - result = value_compare_function( - value, - values_list_value, - error ); - } - else if( value == values_list_value ) - { - result = LIBCDATA_COMPARE_EQUAL; - } - else - { - result = LIBCDATA_COMPARE_GREATER; - } - if( result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to compare value with values list value: %d.", - function, - values_list_element_index ); - - return( -1 ); - } - else if( result == LIBCDATA_COMPARE_EQUAL ) - { - *sub_node = safe_sub_node; - *values_list_element = safe_values_list_element; - - return( 1 ); - } - else if( result == LIBCDATA_COMPARE_LESS ) - { - break; - } - else if( result != LIBCDATA_COMPARE_GREATER ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, - "%s: unsupported value compare function return value: %d.", - function, - result ); - - return( -1 ); - } - if( libcdata_list_element_get_next_element( - safe_values_list_element, - &safe_values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next element from values list element: %d.", - function, - values_list_element_index ); - - return( -1 ); - } - if( number_of_sub_nodes != 0 ) - { - if( libcdata_tree_node_get_next_node( - safe_sub_node, - &safe_sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next node from sub node: %d.", - function, - sub_node_index ); - - return( -1 ); - } - sub_node_index++; - } - } - return( 0 ); -} - -/* Retrieves the upper node for the specific value - * - * Uses the value_compare_function to determine the similarity of the entries - * The value_compare_function should return LIBCDATA_COMPARE_LESS, - * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error - * - * Returns 1 if successful, 0 if the value does not exist or -1 on error - */ -int libcdata_btree_node_get_upper_node_by_value( - libcdata_tree_node_t *node, - intptr_t *value, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - libcdata_tree_node_t **upper_node, - libcdata_list_element_t **values_list_element, - libcerror_error_t **error ) -{ - libcdata_list_element_t *sub_values_list_element = NULL; - libcdata_tree_node_t *sub_node = NULL; - static char *function = "libcdata_btree_node_get_upper_node_by_value"; - int result = 0; - - if( node == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid node.", - function ); - - return( -1 ); - } - if( value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value.", - function ); - - return( -1 ); - } - if( value_compare_function == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value compare function.", - function ); - - return( -1 ); - } - if( upper_node == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid upper node.", - function ); - - return( -1 ); - } - if( values_list_element == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid values list element.", - function ); - - return( -1 ); - } - *upper_node = NULL; - *values_list_element = NULL; - - result = libcdata_btree_node_get_sub_node_by_value( - node, - value, - value_compare_function, - &sub_node, - &sub_values_list_element, - error ); - - if( result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve sub node by value.", - function ); - - return( -1 ); - } - else if( sub_node != NULL ) - { - result = libcdata_btree_node_get_upper_node_by_value( - sub_node, - value, - value_compare_function, - upper_node, - values_list_element, - error ); - - if( result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve upper node in sub node.", - function ); - - return( -1 ); - } - } - else if( result != 0 ) - { - *values_list_element = sub_values_list_element; - } - if( *upper_node == NULL ) - { - *upper_node = node; - } - return( result ); -} - -/* Appends a value into a tree node - * Returns 1 if successful or -1 on error - */ -int libcdata_btree_node_append_value( - libcdata_tree_node_t *node, - intptr_t *value, - libcerror_error_t **error ) -{ - libcdata_list_t *values_list = NULL; - static char *function = "libcdata_btree_node_append_value"; - - if( libcdata_tree_node_get_value( - node, - (intptr_t **) &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve values list.", - function ); - - return( -1 ); - } - if( values_list == NULL ) - { - if( libcdata_list_initialize( - &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create values list.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_set_value( - node, - (intptr_t *) values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set values list.", - function ); - - libcdata_list_free( - &values_list, - NULL, - NULL ); - - return( -1 ); - } - } - if( libcdata_list_append_value( - values_list, - value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append value to values list.", - function ); - - return( -1 ); - } - return( 1 ); -} - -/* Inserts a value into a tree node - * The tree node must be the most upper node (leaf) - * - * Uses the value_compare_function to determine the order of the entries - * The value_compare_function should return LIBCDATA_COMPARE_LESS, - * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error - * - * Returns 1 if successful, 0 if the value already exists or -1 on error - */ -int libcdata_btree_node_insert_value( - libcdata_tree_node_t *node, - intptr_t *value, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - libcerror_error_t **error ) -{ - libcdata_list_t *values_list = NULL; - static char *function = "libcdata_btree_node_insert_value"; - int number_of_sub_nodes = 0; - int result = 0; - - if( libcdata_tree_node_get_number_of_sub_nodes( - node, - &number_of_sub_nodes, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of sub nodes.", - function ); - - return( -1 ); - } - if( number_of_sub_nodes != 0 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, - "%s: cannot insert value in node with sub nodes.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_get_value( - node, - (intptr_t **) &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve values list.", - function ); - - return( -1 ); - } - if( values_list == NULL ) - { - if( libcdata_list_initialize( - &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create values list.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_set_value( - node, - (intptr_t *) values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set values list.", - function ); - - libcdata_list_free( - &values_list, - NULL, - NULL ); - - return( -1 ); - } - } - result = libcdata_list_insert_value( - values_list, - value, - value_compare_function, - LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, - error ); - - if( result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert value in values list.", - function ); - - return( -1 ); - } - return( result ); -} - -/* Replaces a value in the tree node - * The tree node must be the most upper node (leaf) in the first call - * Returns 1 if successful or -1 on error - */ -int libcdata_btree_node_replace_value( - libcdata_tree_node_t *node, - intptr_t *value, - intptr_t *replacement_value, - libcerror_error_t **error ) -{ - libcdata_list_element_t *values_list_element = NULL; - libcdata_tree_node_t *parent_node = NULL; - libcdata_tree_node_t *sub_node = NULL; - static char *function = "libcdata_btree_node_replace_value"; - int result = 0; - - if( value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value.", - function ); - - return( -1 ); - } - if( replacement_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid replacement value.", - function ); - - return( -1 ); - } - result = libcdata_btree_node_get_sub_node_by_value( - node, - value, - NULL, - &sub_node, - &values_list_element, - error ); - - if( result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve sub node by value.", - function ); - - return( -1 ); - } - else if( result != 0 ) - { - if( libcdata_list_element_set_value( - values_list_element, - replacement_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set value in values list element.", - function ); - - return( -1 ); - } - } - if( libcdata_tree_node_get_parent_node( - node, - &parent_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve parent node.", - function ); - - return( -1 ); - } - if( parent_node != NULL ) - { - if( libcdata_btree_node_replace_value( - parent_node, - value, - replacement_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to replace value in parent node.", - function ); - - return( -1 ); - } - } - return( 1 ); -} - -/* Removes a value from the tree node - * The tree node must be the most upper node (leaf) in the first call - * Returns 1 if successful, 0 if no such value or -1 on error - */ -int libcdata_btree_node_remove_value( - libcdata_tree_node_t *node, - intptr_t *value, - intptr_t *replacement_value, - libcerror_error_t **error ) -{ - libcdata_list_t *sub_node_values_list = NULL; - libcdata_list_t *values_list = NULL; - libcdata_list_element_t *previous_values_list_element = NULL; - libcdata_list_element_t *values_list_element = NULL; - libcdata_tree_node_t *parent_node = NULL; - libcdata_tree_node_t *sub_node = NULL; - static char *function = "libcdata_btree_node_remove_value"; - int number_of_sub_nodes = 0; - int number_of_values_list_elements = 0; - int result = 0; - int sub_node_number_of_sub_nodes = 0; - int sub_node_number_of_values_list_elements = 0; - - if( value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value.", - function ); - - return( -1 ); - } - result = libcdata_btree_node_get_sub_node_by_value( - node, - value, - NULL, - &sub_node, - &values_list_element, - error ); - - if( result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve sub node by value.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_get_value( - node, - (intptr_t **) &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve values list.", - function ); - - return( -1 ); - } - if( libcdata_list_get_number_of_elements( - values_list, - &number_of_values_list_elements, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of values list elements.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_get_number_of_sub_nodes( - node, - &number_of_sub_nodes, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of sub nodes.", - function ); - - return( -1 ); - } - if( sub_node != NULL ) - { - if( libcdata_tree_node_get_value( - sub_node, - (intptr_t **) &sub_node_values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve sub node values list.", - function ); - - return( -1 ); - } - if( libcdata_list_get_number_of_elements( - sub_node_values_list, - &sub_node_number_of_values_list_elements, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve sub node number of values list elements.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_get_number_of_sub_nodes( - sub_node, - &sub_node_number_of_sub_nodes, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of sub nodes.", - function ); - - return( -1 ); - } - /* If the sub node is empty remove it - */ - if( ( sub_node_number_of_sub_nodes == 0 ) - && ( sub_node_number_of_values_list_elements == 0 ) ) - { - if( libcdata_tree_node_remove_node( - node, - sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove remaining sub node from node.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_free( - &sub_node, - (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_free_values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free remaining sub node.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_get_number_of_sub_nodes( - node, - &number_of_sub_nodes, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of sub nodes.", - function ); - - return( -1 ); - } - if( values_list_element == NULL ) - { - if( libcdata_list_get_last_element( - values_list, - &values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve last values list element.", - function ); - - return( -1 ); - } - if( libcdata_list_element_get_value( - values_list_element, - &replacement_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from last values list element.", - function ); - - return( -1 ); - } - } - if( values_list_element != NULL ) - { - if( libcdata_list_remove_element( - values_list, - values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove values list element from values list.", - function ); - - return( -1 ); - } - if( libcdata_list_element_free( - &values_list_element, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free values list element.", - function ); - - return( -1 ); - } - if( libcdata_list_get_number_of_elements( - values_list, - &number_of_values_list_elements, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of values list elements.", - function ); - - return( -1 ); - } - } - } - } - if( number_of_sub_nodes != 0 ) - { - if( ( number_of_values_list_elements + 1 ) != number_of_sub_nodes ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid number of values list elements value out of bounds.", - function ); - - return( -1 ); - } - /* If one sub node remains flatten the tree - */ - if( number_of_sub_nodes == 1 ) - { - if( libcdata_tree_node_get_sub_node_by_index( - node, - 0, - &sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve remaining sub node.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_remove_node( - node, - sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove remaining sub node from node.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_replace_node( - node, - sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to replace node with remaining sub node.", - function ); - - libcdata_tree_node_append_node( - node, - sub_node, - NULL ); - - return( -1 ); - } - if( libcdata_tree_node_get_value( - node, - (intptr_t **) &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve values list.", - function ); - - return( -1 ); - } - if( libcdata_tree_node_free( - &sub_node, - (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_free_values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free remaining sub node.", - function ); - - return( -1 ); - } - } - /* If the sub node contains more than one values list elements - * use the replacement value determined in the sub node - */ - else if( values_list_element != NULL ) - { - if( replacement_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid replacement value.", - function ); - - return( -1 ); - } - if( libcdata_list_element_set_value( - values_list_element, - replacement_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set value in values list element.", - function ); - - return( -1 ); - } - } - } - /* In a leaf node remove the values list element from the list - */ - else if( values_list_element != NULL ) - { - if( libcdata_list_element_get_previous_element( - values_list_element, - &previous_values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous element from values list element.", - function ); - - return( -1 ); - } - if( previous_values_list_element != NULL ) - { - if( libcdata_list_element_get_value( - previous_values_list_element, - &replacement_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from previous values list element.", - function ); - - return( -1 ); - } - } - if( libcdata_list_remove_element( - values_list, - values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove values list element from values list.", - function ); - - return( -1 ); - } - if( libcdata_list_element_free( - &values_list_element, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free values list element.", - function ); - - return( -1 ); - } - } - if( libcdata_tree_node_get_parent_node( - node, - &parent_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve parent node.", - function ); - - return( -1 ); - } - if( parent_node != NULL ) - { - if( libcdata_btree_node_remove_value( - parent_node, - value, - replacement_value, - error ) == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove value from parent node.", - function ); - - return( -1 ); - } - } - return( result ); -} - -/* Splits the node - * Returns 1 if successful or -1 on error - */ -int libcdata_btree_node_split( - libcdata_tree_node_t *node, - libcerror_error_t **error ) -{ - libcdata_list_t *split_values_list = NULL; - libcdata_list_t *values_list = NULL; - libcdata_list_element_t *values_list_element = NULL; - libcdata_tree_node_t *sub_node = NULL; - intptr_t *values_list_value = NULL; - static char *function = "libcdata_btree_node_split"; - int number_of_split_values_list_elements = 0; - int number_of_sub_nodes = 0; - int number_of_values_list_elements = 0; - int split_values_list_element_index = 0; - int sub_node_index = 0; - int values_list_element_index = 0; - - if( libcdata_tree_node_get_number_of_sub_nodes( - node, - &number_of_sub_nodes, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of sub nodes.", - function ); - - goto on_error; - } - if( number_of_sub_nodes != 0 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, - "%s: cannot split node with sub nodes.", - function ); - - goto on_error; - } - if( libcdata_tree_node_get_value( - node, - (intptr_t **) &values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve values list.", - function ); - - goto on_error; - } - /* Split to have about 25 values per sub node - */ - number_of_split_values_list_elements = 25; - - if( libcdata_list_initialize( - &split_values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create split values list.", - function ); - - goto on_error; - } - if( libcdata_tree_node_set_value( - node, - (intptr_t *) split_values_list, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set split values list.", - function ); - - goto on_error; - } - if( libcdata_list_get_number_of_elements( - values_list, - &number_of_values_list_elements, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of values list elements.", - function ); - - goto on_error; - } - if( libcdata_list_get_first_element( - values_list, - &values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve first values list element.", - function ); - - goto on_error; - } - for( values_list_element_index = 0; - values_list_element_index < number_of_values_list_elements; - values_list_element_index++ ) - { - if( libcdata_list_element_get_value( - values_list_element, - &values_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from values list element: %d.", - function, - values_list_element_index ); - - goto on_error; - } - if( values_list_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid values list element: %d - missing value.", - function, - values_list_element_index ); - - goto on_error; - } - if( sub_node == NULL ) - { - if( libcdata_tree_node_initialize( - &sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create sub node: %d.", - function, - sub_node_index ); - - goto on_error; - } - } - if( libcdata_btree_node_append_value( - sub_node, - values_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append value: %d to sub node: %d.", - function, - values_list_element_index, - sub_node_index ); - - goto on_error; - } - if( values_list_element_index >= split_values_list_element_index ) - { - if( ( values_list_element_index + 1 ) < number_of_values_list_elements ) - { - if( libcdata_list_append_value( - split_values_list, - values_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append value: %d to sub nodes values list.", - function, - values_list_element_index ); - - goto on_error; - } - } - split_values_list_element_index += number_of_split_values_list_elements; - - if( libcdata_tree_node_append_node( - node, - sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append sub node: %d to node.", - function, - sub_node_index ); - - goto on_error; - } - sub_node = NULL; - - sub_node_index++; - } - if( libcdata_list_element_get_next_element( - values_list_element, - &values_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next element from values list element: %d.", - function, - values_list_element_index ); - - goto on_error; - } - } - if( sub_node != NULL ) - { - if( libcdata_tree_node_append_node( - node, - sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append sub node: %d to node.", - function, - sub_node_index ); - - goto on_error; - } - sub_node = NULL; - - sub_node_index++; - } - split_values_list = NULL; - - if( libcdata_list_free( - &values_list, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free values list.", - function ); - - goto on_error; - } - return( 1 ); - -on_error: - if( sub_node != NULL ) - { - libcdata_tree_node_remove_node( - node, - sub_node, - NULL ); - libcdata_tree_node_free( - &sub_node, - NULL, - NULL ); - } - if( split_values_list != NULL ) - { - libcdata_tree_node_empty( - node, - NULL, - NULL ); - libcdata_tree_node_set_value( - node, - (intptr_t *) values_list, - NULL ); - libcdata_list_free( - &split_values_list, - NULL, - NULL ); - } - return( -1 ); -} - /* Retrieves the number of values in the tree * Returns 1 if successful or -1 on error */ diff -Nru libfsapfs-20181215/libcdata/libcdata_btree.h libfsapfs-20190210/libcdata/libcdata_btree.h --- libfsapfs-20181215/libcdata/libcdata_btree.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_btree.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Balanced tree type functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -75,64 +75,8 @@ libcerror_error_t **error ), libcerror_error_t **error ); -int libcdata_btree_free_values_list( - libcdata_list_t **values_list, - libcerror_error_t **error ); - /* TODO clone function */ -int libcdata_btree_node_get_sub_node_by_value( - libcdata_tree_node_t *node, - intptr_t *value, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - libcdata_tree_node_t **sub_node, - libcdata_list_element_t **values_list_element, - libcerror_error_t **error ); - -int libcdata_btree_node_get_upper_node_by_value( - libcdata_tree_node_t *node, - intptr_t *value, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - libcdata_tree_node_t **upper_node, - libcdata_list_element_t **values_list_element, - libcerror_error_t **error ); - -int libcdata_btree_node_append_value( - libcdata_tree_node_t *node, - intptr_t *value, - libcerror_error_t **error ); - -int libcdata_btree_node_insert_value( - libcdata_tree_node_t *node, - intptr_t *value, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - libcerror_error_t **error ); - -int libcdata_btree_node_replace_value( - libcdata_tree_node_t *node, - intptr_t *value, - intptr_t *replacement_value, - libcerror_error_t **error ); - -int libcdata_btree_node_remove_value( - libcdata_tree_node_t *node, - intptr_t *value, - intptr_t *replacement_value, - libcerror_error_t **error ); - -int libcdata_btree_node_split( - libcdata_tree_node_t *node, - libcerror_error_t **error ); - LIBCDATA_EXTERN \ int libcdata_btree_get_number_of_values( libcdata_btree_t *tree, diff -Nru libfsapfs-20181215/libcdata/libcdata_btree_node.c libfsapfs-20190210/libcdata/libcdata_btree_node.c --- libfsapfs-20181215/libcdata/libcdata_btree_node.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_btree_node.c 2019-02-10 19:58:26.000000000 +0000 @@ -0,0 +1,1607 @@ +/* + * Balanced tree node functions + * + * Copyright (C) 2006-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include + +#include "libcdata_array.h" +#include "libcdata_btree_node.h" +#include "libcdata_btree_values_list.h" +#include "libcdata_definitions.h" +#include "libcdata_libcerror.h" +#include "libcdata_list.h" +#include "libcdata_list_element.h" +#include "libcdata_tree_node.h" +#include "libcdata_types.h" + +/* Retrieves the sub node for the specific value + * + * Uses the value_compare_function to determine the similarity of the entries + * The value_compare_function should return LIBCDATA_COMPARE_LESS, + * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error + * + * If value_compare_function is NULL the pointer of the value is used to check for a match + * + * Returns 1 if successful, 0 if the value does not exist or -1 on error + * If there was no possible sub match values_list_element is set to NULL + * it there is a possible sub match values_list_element is set but 0 is returned + * If the node is a leaf node sub_node is not set to NULL + */ +int libcdata_btree_node_get_sub_node_by_value( + libcdata_tree_node_t *node, + intptr_t *value, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + libcdata_tree_node_t **sub_node, + libcdata_list_element_t **values_list_element, + libcerror_error_t **error ) +{ + libcdata_list_t *values_list = NULL; + libcdata_list_element_t *safe_values_list_element = NULL; + libcdata_tree_node_t *safe_sub_node = NULL; + intptr_t *values_list_value = NULL; + static char *function = "libcdata_btree_node_get_sub_node_by_value"; + int number_of_sub_nodes = 0; + int number_of_values_list_elements = 0; + int result = 0; + int sub_node_index = 0; + int values_list_element_index = 0; + + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value.", + function ); + + return( -1 ); + } + if( sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid sub node.", + function ); + + return( -1 ); + } + if( values_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid values list element.", + function ); + + return( -1 ); + } + *sub_node = NULL; + *values_list_element = NULL; + + if( libcdata_tree_node_get_value( + node, + (intptr_t **) &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve values list.", + function ); + + return( -1 ); + } + if( values_list != NULL ) + { + if( libcdata_list_get_number_of_elements( + values_list, + &number_of_values_list_elements, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of values list elements.", + function ); + + return( -1 ); + } + } + if( libcdata_tree_node_get_number_of_sub_nodes( + node, + &number_of_sub_nodes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub nodes.", + function ); + + return( -1 ); + } + if( ( number_of_sub_nodes != 0 ) + && ( ( number_of_values_list_elements + 1 ) != number_of_sub_nodes ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid number of values list elements value out of bounds.", + function ); + + return( -1 ); + } + if( number_of_values_list_elements == 0 ) + { + return( 0 ); + } + if( libcdata_list_get_first_element( + values_list, + &safe_values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve first values list element.", + function ); + + return( -1 ); + } + if( number_of_sub_nodes != 0 ) + { + if( libcdata_tree_node_get_sub_node_by_index( + node, + 0, + &safe_sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub node: 0.", + function ); + + return( -1 ); + } + } + for( values_list_element_index = 0; + values_list_element_index < number_of_values_list_elements; + values_list_element_index++ ) + { + if( libcdata_list_element_get_value( + safe_values_list_element, + &values_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from values list element: %d.", + function, + values_list_element_index ); + + return( -1 ); + } + if( values_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid values list element: %d - missing value.", + function, + values_list_element_index ); + + return( -1 ); + } + if( value_compare_function != NULL ) + { + result = value_compare_function( + value, + values_list_value, + error ); + } + else if( value == values_list_value ) + { + result = LIBCDATA_COMPARE_EQUAL; + } + else + { + result = LIBCDATA_COMPARE_GREATER; + } + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to compare value with values list value: %d.", + function, + values_list_element_index ); + + return( -1 ); + } + else if( result == LIBCDATA_COMPARE_EQUAL ) + { + *sub_node = safe_sub_node; + *values_list_element = safe_values_list_element; + + return( 1 ); + } + else if( result == LIBCDATA_COMPARE_LESS ) + { + break; + } + else if( result != LIBCDATA_COMPARE_GREATER ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported value compare function return value: %d.", + function, + result ); + + return( -1 ); + } + if( libcdata_list_element_get_next_element( + safe_values_list_element, + &safe_values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from values list element: %d.", + function, + values_list_element_index ); + + return( -1 ); + } + if( number_of_sub_nodes != 0 ) + { + if( libcdata_tree_node_get_next_node( + safe_sub_node, + &safe_sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next node from sub node: %d.", + function, + sub_node_index ); + + return( -1 ); + } + sub_node_index++; + } + } + *sub_node = safe_sub_node; + *values_list_element = safe_values_list_element; + + return( 0 ); +} + +/* Retrieves the upper node for the specific value + * + * Uses the value_compare_function to determine the similarity of the entries + * The value_compare_function should return LIBCDATA_COMPARE_LESS, + * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error + * + * Returns 1 if successful, 0 if the value does not exist or -1 on error + */ +int libcdata_btree_node_get_upper_node_by_value( + libcdata_tree_node_t *node, + intptr_t *value, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + libcdata_tree_node_t **upper_node, + libcdata_list_element_t **values_list_element, + libcerror_error_t **error ) +{ + libcdata_list_element_t *sub_values_list_element = NULL; + libcdata_tree_node_t *sub_node = NULL; + static char *function = "libcdata_btree_node_get_upper_node_by_value"; + int result = 0; + + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value.", + function ); + + return( -1 ); + } + if( value_compare_function == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value compare function.", + function ); + + return( -1 ); + } + if( upper_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid upper node.", + function ); + + return( -1 ); + } + if( values_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid values list element.", + function ); + + return( -1 ); + } + *upper_node = NULL; + *values_list_element = NULL; + + result = libcdata_btree_node_get_sub_node_by_value( + node, + value, + value_compare_function, + &sub_node, + &sub_values_list_element, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub node by value.", + function ); + + return( -1 ); + } + else if( sub_node != NULL ) + { + result = libcdata_btree_node_get_upper_node_by_value( + sub_node, + value, + value_compare_function, + upper_node, + values_list_element, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve upper node in sub node.", + function ); + + return( -1 ); + } + } + else if( result != 0 ) + { + *values_list_element = sub_values_list_element; + } + if( *upper_node == NULL ) + { + *upper_node = node; + } + return( result ); +} + +/* Appends a value into a tree node + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_node_append_value( + libcdata_tree_node_t *node, + intptr_t *value, + libcerror_error_t **error ) +{ + libcdata_list_t *values_list = NULL; + static char *function = "libcdata_btree_node_append_value"; + + if( libcdata_tree_node_get_value( + node, + (intptr_t **) &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve values list.", + function ); + + return( -1 ); + } + if( values_list == NULL ) + { + if( libcdata_list_initialize( + &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create values list.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_set_value( + node, + (intptr_t *) values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set values list.", + function ); + + libcdata_list_free( + &values_list, + NULL, + NULL ); + + return( -1 ); + } + } + if( libcdata_list_append_value( + values_list, + value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to append value to values list.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Inserts a value into a tree node + * The tree node must be the most upper node (leaf) + * + * Uses the value_compare_function to determine the order of the entries + * The value_compare_function should return LIBCDATA_COMPARE_LESS, + * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error + * + * Returns 1 if successful, 0 if the value already exists or -1 on error + */ +int libcdata_btree_node_insert_value( + libcdata_tree_node_t *node, + intptr_t *value, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + libcerror_error_t **error ) +{ + libcdata_list_t *values_list = NULL; + static char *function = "libcdata_btree_node_insert_value"; + int number_of_sub_nodes = 0; + int result = 0; + + if( libcdata_tree_node_get_number_of_sub_nodes( + node, + &number_of_sub_nodes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub nodes.", + function ); + + return( -1 ); + } + if( number_of_sub_nodes != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: cannot insert value in node with sub nodes.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_value( + node, + (intptr_t **) &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve values list.", + function ); + + return( -1 ); + } + if( values_list == NULL ) + { + if( libcdata_list_initialize( + &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create values list.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_set_value( + node, + (intptr_t *) values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set values list.", + function ); + + libcdata_list_free( + &values_list, + NULL, + NULL ); + + return( -1 ); + } + } + result = libcdata_list_insert_value( + values_list, + value, + value_compare_function, + LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert value in values list.", + function ); + + return( -1 ); + } + return( result ); +} + +/* Replaces a value in the tree node + * The tree node must be the most upper node (leaf) in the first call + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_node_replace_value( + libcdata_tree_node_t *node, + intptr_t *value, + intptr_t *replacement_value, + libcerror_error_t **error ) +{ + libcdata_list_element_t *values_list_element = NULL; + libcdata_tree_node_t *parent_node = NULL; + libcdata_tree_node_t *sub_node = NULL; + static char *function = "libcdata_btree_node_replace_value"; + int result = 0; + + if( value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value.", + function ); + + return( -1 ); + } + if( replacement_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid replacement value.", + function ); + + return( -1 ); + } + result = libcdata_btree_node_get_sub_node_by_value( + node, + value, + NULL, + &sub_node, + &values_list_element, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub node by value.", + function ); + + return( -1 ); + } + else if( result != 0 ) + { + if( libcdata_list_element_set_value( + values_list_element, + replacement_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set value in values list element.", + function ); + + return( -1 ); + } + } + if( libcdata_tree_node_get_parent_node( + node, + &parent_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve parent node.", + function ); + + return( -1 ); + } + if( parent_node != NULL ) + { + if( libcdata_btree_node_replace_value( + parent_node, + value, + replacement_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to replace value in parent node.", + function ); + + return( -1 ); + } + } + return( 1 ); +} + +/* Flattens a tree node and its sub node + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_node_flatten_node( + libcdata_tree_node_t **node, + libcerror_error_t **error ) +{ + libcdata_tree_node_t *sub_node = NULL; + static char *function = "libcdata_btree_node_flatten_node"; + + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_first_sub_node( + *node, + &sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve first sub node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_remove_node( + *node, + sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove sub node from node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_replace_node( + *node, + sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to replace node with sub node.", + function ); + + libcdata_tree_node_append_node( + *node, + sub_node, + NULL ); + + return( -1 ); + } + if( libcdata_tree_node_free( + node, + (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_values_list_free, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free node.", + function ); + + return( -1 ); + } + *node = sub_node; + + return( 1 ); +} + +/* Removes a sub node from the B-tree node + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_node_remove_sub_node( + libcdata_tree_node_t *node, + libcdata_tree_node_t **sub_node, + libcerror_error_t **error ) +{ + static char *function = "libcdata_btree_node_remove_sub_node"; + + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid sub node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_remove_node( + node, + *sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove sub node from node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_free( + sub_node, + (int (*)(intptr_t **, libcerror_error_t **)) &libcdata_btree_values_list_free, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free sub node.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Removes a value from the tree node + * The tree node must be the most upper node (leaf) in the first call + * Returns 1 if successful, 0 if no such value or -1 on error + */ +int libcdata_btree_node_remove_value( + libcdata_tree_node_t *node, + intptr_t *value, + intptr_t *replacement_value, + libcerror_error_t **error ) +{ + libcdata_list_t *sub_node_values_list = NULL; + libcdata_list_t *values_list = NULL; + libcdata_list_element_t *values_list_element = NULL; + libcdata_tree_node_t *parent_node = NULL; + libcdata_tree_node_t *sub_node = NULL; + static char *function = "libcdata_btree_node_remove_value"; + int number_of_sub_nodes = 0; + int number_of_values_list_elements = 0; + int result = 0; + int sub_node_number_of_sub_nodes = 0; + int sub_node_number_of_values_list_elements = 0; + + if( value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value.", + function ); + + return( -1 ); + } + result = libcdata_btree_node_get_sub_node_by_value( + node, + value, + NULL, + &sub_node, + &values_list_element, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub node by value.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_value( + node, + (intptr_t **) &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve values list.", + function ); + + return( -1 ); + } + if( libcdata_list_get_number_of_elements( + values_list, + &number_of_values_list_elements, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of values list elements.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_number_of_sub_nodes( + node, + &number_of_sub_nodes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub nodes.", + function ); + + return( -1 ); + } + if( sub_node != NULL ) + { + if( libcdata_tree_node_get_value( + sub_node, + (intptr_t **) &sub_node_values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub node values list.", + function ); + + return( -1 ); + } + if( libcdata_list_get_number_of_elements( + sub_node_values_list, + &sub_node_number_of_values_list_elements, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub node number of values list elements.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_number_of_sub_nodes( + sub_node, + &sub_node_number_of_sub_nodes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub nodes.", + function ); + + return( -1 ); + } + /* If the sub node is empty remove it + */ + if( ( sub_node_number_of_sub_nodes == 0 ) + && ( sub_node_number_of_values_list_elements == 0 ) ) + { + if( libcdata_btree_node_remove_sub_node( + node, + &sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove remaining sub node from node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_number_of_sub_nodes( + node, + &number_of_sub_nodes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub nodes.", + function ); + + return( -1 ); + } + if( values_list_element == NULL ) + { + if( libcdata_list_get_last_element( + values_list, + &values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve last values list element.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_value( + values_list_element, + &replacement_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from last values list element.", + function ); + + return( -1 ); + } + } + if( values_list_element != NULL ) + { + if( libcdata_btree_values_list_remove_element( + values_list, + &values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove element from values list.", + function ); + + return( -1 ); + } + if( libcdata_list_get_number_of_elements( + values_list, + &number_of_values_list_elements, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of values list elements.", + function ); + + return( -1 ); + } + } + } + } + if( number_of_sub_nodes != 0 ) + { + if( ( number_of_values_list_elements + 1 ) != number_of_sub_nodes ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid number of values list elements value out of bounds.", + function ); + + return( -1 ); + } + /* If one sub node remains flatten the node + */ + if( number_of_sub_nodes == 1 ) + { + if( libcdata_btree_node_flatten_node( + &node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to flatten node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_value( + node, + (intptr_t **) &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve values list.", + function ); + + return( -1 ); + } + } + /* If the sub node contains more than one values list elements + * use the replacement value determined in the sub node + */ + else if( values_list_element != NULL ) + { + if( replacement_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid replacement value.", + function ); + + return( -1 ); + } + if( libcdata_list_element_set_value( + values_list_element, + replacement_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set value in values list element.", + function ); + + return( -1 ); + } + } + } + /* In a leaf node remove the values list element from the list + */ + else if( values_list_element != NULL ) + { + if( libcdata_btree_values_list_replace_element_with_previous( + values_list, + &values_list_element, + &replacement_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to replace values list element with previous.", + function ); + + return( -1 ); + } + } + if( libcdata_tree_node_get_parent_node( + node, + &parent_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve parent node.", + function ); + + return( -1 ); + } + if( parent_node != NULL ) + { + if( libcdata_btree_node_remove_value( + parent_node, + value, + replacement_value, + error ) == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove value from parent node.", + function ); + + return( -1 ); + } + } + return( result ); +} + +/* Splits the node + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_node_split( + libcdata_tree_node_t *node, + libcerror_error_t **error ) +{ + libcdata_list_t *split_values_list = NULL; + libcdata_list_t *values_list = NULL; + libcdata_list_element_t *values_list_element = NULL; + libcdata_tree_node_t *sub_node = NULL; + intptr_t *values_list_value = NULL; + static char *function = "libcdata_btree_node_split"; + int number_of_split_values_list_elements = 0; + int number_of_sub_nodes = 0; + int number_of_values_list_elements = 0; + int split_values_list_element_index = 0; + int sub_node_index = 0; + int values_list_element_index = 0; + + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_get_number_of_sub_nodes( + node, + &number_of_sub_nodes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of sub nodes.", + function ); + + goto on_error; + } + if( number_of_sub_nodes != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: cannot split node with sub nodes.", + function ); + + goto on_error; + } + if( libcdata_tree_node_get_value( + node, + (intptr_t **) &values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve values list.", + function ); + + goto on_error; + } + /* Split to have about 25 values per sub node + */ + number_of_split_values_list_elements = 25; + + if( libcdata_list_initialize( + &split_values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create split values list.", + function ); + + goto on_error; + } + if( libcdata_tree_node_set_value( + node, + (intptr_t *) split_values_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set split values list.", + function ); + + goto on_error; + } + if( libcdata_list_get_number_of_elements( + values_list, + &number_of_values_list_elements, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of values list elements.", + function ); + + goto on_error; + } + if( libcdata_list_get_first_element( + values_list, + &values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve first values list element.", + function ); + + goto on_error; + } + for( values_list_element_index = 0; + values_list_element_index < number_of_values_list_elements; + values_list_element_index++ ) + { + if( libcdata_list_element_get_value( + values_list_element, + &values_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from values list element: %d.", + function, + values_list_element_index ); + + goto on_error; + } + if( values_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid values list element: %d - missing value.", + function, + values_list_element_index ); + + goto on_error; + } + if( sub_node == NULL ) + { + if( libcdata_tree_node_initialize( + &sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create sub node: %d.", + function, + sub_node_index ); + + goto on_error; + } + } + if( libcdata_btree_node_append_value( + sub_node, + values_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to append value: %d to sub node: %d.", + function, + values_list_element_index, + sub_node_index ); + + goto on_error; + } + if( values_list_element_index >= split_values_list_element_index ) + { + if( ( values_list_element_index + 1 ) < number_of_values_list_elements ) + { + if( libcdata_list_append_value( + split_values_list, + values_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to append value: %d to sub nodes values list.", + function, + values_list_element_index ); + + goto on_error; + } + } + split_values_list_element_index += number_of_split_values_list_elements; + + if( libcdata_tree_node_append_node( + node, + sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to append sub node: %d to node.", + function, + sub_node_index ); + + goto on_error; + } + sub_node = NULL; + + sub_node_index++; + } + if( libcdata_list_element_get_next_element( + values_list_element, + &values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from values list element: %d.", + function, + values_list_element_index ); + + goto on_error; + } + } + if( sub_node != NULL ) + { + if( libcdata_tree_node_append_node( + node, + sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to append sub node: %d to node.", + function, + sub_node_index ); + + goto on_error; + } + sub_node = NULL; + + sub_node_index++; + } + split_values_list = NULL; + + if( libcdata_list_free( + &values_list, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free values list.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( sub_node != NULL ) + { + libcdata_tree_node_remove_node( + node, + sub_node, + NULL ); + libcdata_tree_node_free( + &sub_node, + NULL, + NULL ); + } + if( split_values_list != NULL ) + { + libcdata_tree_node_empty( + node, + NULL, + NULL ); + libcdata_tree_node_set_value( + node, + (intptr_t *) values_list, + NULL ); + libcdata_list_free( + &split_values_list, + NULL, + NULL ); + } + return( -1 ); +} + + diff -Nru libfsapfs-20181215/libcdata/libcdata_btree_node.h libfsapfs-20190210/libcdata/libcdata_btree_node.h --- libfsapfs-20181215/libcdata/libcdata_btree_node.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_btree_node.h 2019-02-10 19:58:26.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * Balanced tree node functions + * + * Copyright (C) 2006-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBCDATA_BTREE_NODE_H ) +#define _LIBCDATA_BTREE_NODE_H + +#include +#include + +#include "libcdata_libcerror.h" +#include "libcdata_types.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +int libcdata_btree_node_get_sub_node_by_value( + libcdata_tree_node_t *node, + intptr_t *value, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + libcdata_tree_node_t **sub_node, + libcdata_list_element_t **values_list_element, + libcerror_error_t **error ); + +int libcdata_btree_node_get_upper_node_by_value( + libcdata_tree_node_t *node, + intptr_t *value, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + libcdata_tree_node_t **upper_node, + libcdata_list_element_t **values_list_element, + libcerror_error_t **error ); + +int libcdata_btree_node_append_value( + libcdata_tree_node_t *node, + intptr_t *value, + libcerror_error_t **error ); + +int libcdata_btree_node_insert_value( + libcdata_tree_node_t *node, + intptr_t *value, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + libcerror_error_t **error ); + +int libcdata_btree_node_replace_value( + libcdata_tree_node_t *node, + intptr_t *value, + intptr_t *replacement_value, + libcerror_error_t **error ); + +int libcdata_btree_node_flatten_node( + libcdata_tree_node_t **node, + libcerror_error_t **error ); + +int libcdata_btree_node_remove_sub_node( + libcdata_tree_node_t *node, + libcdata_tree_node_t **sub_node, + libcerror_error_t **error ); + +int libcdata_btree_node_remove_value( + libcdata_tree_node_t *node, + intptr_t *value, + intptr_t *replacement_value, + libcerror_error_t **error ); + +int libcdata_btree_node_split( + libcdata_tree_node_t *node, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBCDATA_BTREE_NODE_H ) */ + diff -Nru libfsapfs-20181215/libcdata/libcdata_btree_values_list.c libfsapfs-20190210/libcdata/libcdata_btree_values_list.c --- libfsapfs-20181215/libcdata/libcdata_btree_values_list.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_btree_values_list.c 2019-02-10 19:58:26.000000000 +0000 @@ -0,0 +1,217 @@ +/* + * Balanced tree values list functions + * + * Copyright (C) 2006-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include + +#include "libcdata_btree_values_list.h" +#include "libcdata_libcerror.h" +#include "libcdata_list.h" +#include "libcdata_list_element.h" +#include "libcdata_types.h" + +/* Frees a B-tree values list + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_values_list_free( + libcdata_list_t **values_list, + libcerror_error_t **error ) +{ + static char *function = "libcdata_btree_values_list_free"; + int result = 1; + + if( values_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid values list.", + function ); + + return( -1 ); + } + if( libcdata_list_free( + values_list, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free values list.", + function ); + + result = -1; + } + return( result ); +} + +/* Removes an element from the values list + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_values_list_remove_element( + libcdata_list_t *values_list, + libcdata_list_element_t **values_list_element, + libcerror_error_t **error ) +{ + static char *function = "libcdata_btree_values_list_remove_element"; + + if( values_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid values list.", + function ); + + return( -1 ); + } + if( values_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid values list element.", + function ); + + return( -1 ); + } + if( libcdata_list_remove_element( + values_list, + *values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove element from values list.", + function ); + + return( -1 ); + } + if( libcdata_list_element_free( + values_list_element, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free element.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Replaces the values list element with the previous element + * If available replacement_value is set to the value of the previous element + * Returns 1 if successful or -1 on error + */ +int libcdata_btree_values_list_replace_element_with_previous( + libcdata_list_t *values_list, + libcdata_list_element_t **values_list_element, + intptr_t **replacement_value, + libcerror_error_t **error ) +{ + libcdata_list_element_t *previous_element = NULL; + static char *function = "libcdata_btree_values_list_replace_element_with_previous"; + + if( values_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid values list.", + function ); + + return( -1 ); + } + if( values_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid values list element.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_previous_element( + *values_list_element, + &previous_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous element from values list element.", + function ); + + return( -1 ); + } + if( previous_element != NULL ) + { + if( libcdata_list_element_get_value( + previous_element, + replacement_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from previous element.", + function ); + + return( -1 ); + } + } + if( libcdata_btree_values_list_remove_element( + values_list, + values_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove element from values list.", + function ); + + return( -1 ); + } + *values_list_element = previous_element; + + return( 1 ); +} + diff -Nru libfsapfs-20181215/libcdata/libcdata_btree_values_list.h libfsapfs-20190210/libcdata/libcdata_btree_values_list.h --- libfsapfs-20181215/libcdata/libcdata_btree_values_list.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_btree_values_list.h 2019-02-10 19:58:26.000000000 +0000 @@ -0,0 +1,55 @@ +/* + * Balanced tree values list functions + * + * Copyright (C) 2006-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBCDATA_BTREE_VALUES_LIST_H ) +#define _LIBCDATA_BTREE_VALUES_LIST_H + +#include +#include + +#include "libcdata_libcerror.h" +#include "libcdata_types.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +int libcdata_btree_values_list_free( + libcdata_list_t **values_list, + libcerror_error_t **error ); + +int libcdata_btree_values_list_remove_element( + libcdata_list_t *values_list, + libcdata_list_element_t **values_list_element, + libcerror_error_t **error ); + +int libcdata_btree_values_list_replace_element_with_previous( + libcdata_list_t *values_list, + libcdata_list_element_t **values_list_element, + intptr_t **replacement_value, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBCDATA_BTREE_VALUES_LIST_H ) */ + diff -Nru libfsapfs-20181215/libcdata/libcdata_definitions.h libfsapfs-20190210/libcdata/libcdata_definitions.h --- libfsapfs-20181215/libcdata/libcdata_definitions.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_definitions.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal definitions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -35,11 +35,11 @@ */ #else -#define LIBCDATA_VERSION 20180724 +#define LIBCDATA_VERSION 20190112 /* The libcdata version string */ -#define LIBCDATA_VERSION_STRING "20180724" +#define LIBCDATA_VERSION_STRING "20190112" /* The comparison function definitions */ @@ -73,5 +73,9 @@ #endif /* !defined( HAVE_LOCAL_LIBCDATA ) */ +/* Limiting the maximum size of the array entries to 128 MiB + */ +#define LIBCDATA_ARRAY_ENTRIES_MEMORY_LIMIT 128 * 1024 * 1024 + #endif /* !defined( LIBCDATA_INTERNAL_DEFINITIONS_H ) */ diff -Nru libfsapfs-20181215/libcdata/libcdata_error.c libfsapfs-20190210/libcdata/libcdata_error.c --- libfsapfs-20181215/libcdata/libcdata_error.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_error.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_error.h libfsapfs-20190210/libcdata/libcdata_error.h --- libfsapfs-20181215/libcdata/libcdata_error.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_error.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_extern.h libfsapfs-20190210/libcdata/libcdata_extern.h --- libfsapfs-20181215/libcdata/libcdata_extern.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_extern.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal extern definition * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -28,13 +28,6 @@ */ #if !defined( HAVE_LOCAL_LIBCDATA ) -/* If libtool DLL support is enabled set LIBCDATA_DLL_EXPORT - * before including libcdata/extern.h - */ -#if defined( _WIN32 ) && defined( DLL_EXPORT ) -#define LIBCDATA_DLL_EXPORT -#endif - #include #define LIBCDATA_EXTERN_VARIABLE LIBCDATA_EXTERN diff -Nru libfsapfs-20181215/libcdata/libcdata_libcerror.h libfsapfs-20190210/libcdata/libcdata_libcerror.h --- libfsapfs-20181215/libcdata/libcdata_libcerror.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_libcerror.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_libcthreads.h libfsapfs-20190210/libcdata/libcdata_libcthreads.h --- libfsapfs-20181215/libcdata/libcdata_libcthreads.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_libcthreads.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcthreads header wrapper * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_list.c libfsapfs-20190210/libcdata/libcdata_list.c --- libfsapfs-20181215/libcdata/libcdata_list.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_list.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * List functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -103,7 +103,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -258,7 +258,9 @@ function, element_index ); - goto on_error; + result = -1; + + break; } internal_list->first_element = next_element; @@ -266,7 +268,7 @@ { internal_list->last_element = next_element; } - internal_list->number_of_elements--; + internal_list->number_of_elements -= 1; if( next_element != NULL ) { @@ -283,7 +285,7 @@ function, element_index + 1 ); - goto on_error; + result = -1; } } if( libcdata_list_element_set_next_element( @@ -299,7 +301,7 @@ function, element_index ); - goto on_error; + result = -1; } if( libcdata_list_element_free( &list_element, @@ -331,18 +333,10 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + result = -1; } #endif return( result ); - -on_error: -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - NULL ); -#endif - return( -1 ); } /* Clones the list and its elements @@ -423,45 +417,45 @@ } internal_source_list = (libcdata_internal_list_t *) source_list; - if( libcdata_list_initialize( - (libcdata_list_t **) &internal_destination_list, +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_read( + internal_source_list->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create destination list.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for reading.", function ); return( -1 ); } - if( internal_destination_list == NULL ) +#endif + if( libcdata_list_initialize( + (libcdata_list_t **) &internal_destination_list, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing destination list.", + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create destination list.", function ); - return( -1 ); + goto on_error; } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_read( - internal_source_list->read_write_lock, - error ) != 1 ) + if( internal_destination_list == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for reading.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing destination list.", function ); - return( -1 ); + goto on_error; } -#endif if( internal_source_list->first_element != NULL ) { internal_source_list_element = (libcdata_internal_list_element_t *) internal_source_list->first_element; @@ -704,7 +698,6 @@ } /* Sets the first element in the list - * This function is not multi-thread safe acquire write lock before call * Returns 1 if successful or -1 on error */ int libcdata_internal_list_set_first_element( @@ -712,7 +705,8 @@ libcdata_list_element_t *element, libcerror_error_t **error ) { - static char *function = "libcdata_internal_list_set_first_element"; + libcdata_list_element_t *backup_first_element = NULL; + static char *function = "libcdata_internal_list_set_first_element"; if( internal_list == NULL ) { @@ -725,6 +719,8 @@ return( -1 ); } + backup_first_element = internal_list->first_element; + if( element != NULL ) { if( libcdata_list_element_set_next_element( @@ -736,10 +732,10 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next element of list element.", + "%s: unable to set next element of element.", function ); - return( -1 ); + goto on_error; } } if( internal_list->first_element != NULL ) @@ -756,84 +752,31 @@ "%s: unable to set previous element of first element.", function ); - return( -1 ); + goto on_error; } } internal_list->first_element = element; return( 1 ); -} - -/* Sets the first element in the list - * Returns 1 if successful or -1 on error - */ -int libcdata_list_set_first_element( - libcdata_list_t *list, - libcdata_list_element_t *element, - libcerror_error_t **error ) -{ - libcdata_internal_list_t *internal_list = NULL; - static char *function = "libcdata_list_set_first_element"; - int result = 1; - - if( list == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list.", - function ); - return( -1 ); - } - internal_list = (libcdata_internal_list_t *) list; - -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_list->read_write_lock, - error ) != 1 ) +on_error: + if( element != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", - function ); - - return( -1 ); + libcdata_list_element_set_next_element( + element, + NULL, + NULL ); } -#endif - if( libcdata_internal_list_set_first_element( - internal_list, - element, - error ) != 1 ) + if( backup_first_element != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set first element.", - function ); - - result = -1; + libcdata_list_element_set_next_element( + backup_first_element, + NULL, + NULL ); } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", - function ); + internal_list->first_element = backup_first_element; - return( -1 ); - } -#endif - return( result ); + return( -1 ); } /* Retrieves the last elements in the list @@ -907,7 +850,6 @@ } /* Sets the last element in the list - * This function is not multi-thread safe acquire write lock before call * Returns 1 if successful or -1 on error */ int libcdata_internal_list_set_last_element( @@ -915,7 +857,8 @@ libcdata_list_element_t *element, libcerror_error_t **error ) { - static char *function = "libcdata_internal_list_set_last_element"; + libcdata_list_element_t *backup_last_element = NULL; + static char *function = "libcdata_internal_list_set_last_element"; if( internal_list == NULL ) { @@ -928,6 +871,8 @@ return( -1 ); } + backup_last_element = internal_list->last_element; + if( element != NULL ) { if( libcdata_list_element_set_previous_element( @@ -939,10 +884,10 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous element of list element.", + "%s: unable to set previous element of element.", function ); - return( -1 ); + goto on_error; } } if( internal_list->last_element != NULL ) @@ -959,84 +904,31 @@ "%s: unable to set next element of last element.", function ); - return( -1 ); + goto on_error; } } internal_list->last_element = element; return( 1 ); -} -/* Sets the last element in the list - * Returns 1 if successful or -1 on error - */ -int libcdata_list_set_last_element( - libcdata_list_t *list, - libcdata_list_element_t *element, - libcerror_error_t **error ) -{ - libcdata_internal_list_t *internal_list = NULL; - static char *function = "libcdata_list_set_last_element"; - int result = 1; - - if( list == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list.", - function ); - - return( -1 ); - } - internal_list = (libcdata_internal_list_t *) list; - -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_list->read_write_lock, - error ) != 1 ) +on_error: + if( element != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", - function ); - - return( -1 ); + libcdata_list_element_set_previous_element( + element, + NULL, + NULL ); } -#endif - if( libcdata_internal_list_set_last_element( - internal_list, - element, - error ) != 1 ) + if( backup_last_element != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set last element.", - function ); - - result = -1; + libcdata_list_element_set_next_element( + backup_last_element, + NULL, + NULL ); } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", - function ); + internal_list->last_element = backup_last_element; - return( -1 ); - } -#endif - return( result ); + return( -1 ); } /* Retrieves a specific element from the list @@ -1271,8 +1163,16 @@ libcdata_list_element_t *element, libcerror_error_t **error ) { - libcdata_internal_list_t *internal_list = NULL; - static char *function = "libcdata_list_prepend_element"; + libcdata_internal_list_t *internal_list = NULL; + libcdata_list_element_t *next_element = NULL; + libcdata_list_element_t *previous_element = NULL; + static char *function = "libcdata_list_prepend_element"; + int result = 1; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_list_element_t *backup_first_element = NULL; + libcdata_list_element_t *backup_last_element = NULL; +#endif if( list == NULL ) { @@ -1287,6 +1187,56 @@ } internal_list = (libcdata_internal_list_t *) list; + if( internal_list->number_of_elements == 0 ) + { + if( internal_list->first_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - first element already set.", + function ); + + return( -1 ); + } + if( internal_list->last_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - last element already set.", + function ); + + return( -1 ); + } + } + else + { + if( internal_list->first_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing first element.", + function ); + + return( -1 ); + } + if( internal_list->last_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing last element.", + function ); + + return( -1 ); + } + } if( element == NULL ) { libcerror_error_set( @@ -1298,41 +1248,104 @@ return( -1 ); } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_list->read_write_lock, + if( libcdata_list_element_get_elements( + element, + &previous_element, + &next_element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous and next element from list element.", function ); return( -1 ); } -#endif - if( internal_list->last_element == NULL ) + if( ( previous_element != NULL ) + || ( next_element != NULL ) ) { - internal_list->last_element = element; + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: list element already part of a list.", + function ); + + return( -1 ); } - if( libcdata_internal_list_set_first_element( - internal_list, - element, +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_write( + internal_list->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set first element.", + "%s: unable to grab read/write lock for writing.", function ); - goto on_error; + return( -1 ); + } + backup_first_element = internal_list->first_element; + backup_last_element = internal_list->last_element; + +#endif + result = libcdata_list_element_set_next_element( + element, + internal_list->first_element, + error ); + + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next element of list element.", + function ); + + result = -1; + } + if( result == 1 ) + { + if( internal_list->first_element != NULL ) + { + result = libcdata_list_element_set_previous_element( + internal_list->first_element, + element, + error ); + + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous element of first element.", + function ); + + libcdata_list_element_set_next_element( + element, + NULL, + NULL ); + + result = -1; + } + } } - internal_list->number_of_elements++; + if( result == 1 ) + { + internal_list->first_element = element; + if( internal_list->last_element == NULL ) + { + internal_list->last_element = element; + } + internal_list->number_of_elements += 1; + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_list->read_write_lock, @@ -1345,18 +1358,32 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif - return( 1 ); + return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + libcdata_list_element_set_next_element( + element, + NULL, + NULL ); + + libcdata_list_element_set_previous_element( + backup_first_element, + NULL, + NULL ); + + internal_list->first_element = backup_first_element; + internal_list->last_element = backup_last_element; + + internal_list->number_of_elements -= 1; + } return( -1 ); +#endif } /* Prepends a value to the list @@ -1428,14 +1455,23 @@ /* Appends a list element to the list * Returns 1 if successful or -1 on error */ -int libcdata_internal_list_append_element( - libcdata_internal_list_t *internal_list, +int libcdata_list_append_element( + libcdata_list_t *list, libcdata_list_element_t *element, libcerror_error_t **error ) { - static char *function = "libcdata_internal_list_append_element"; + libcdata_internal_list_t *internal_list = NULL; + libcdata_list_element_t *next_element = NULL; + libcdata_list_element_t *previous_element = NULL; + static char *function = "libcdata_list_append_element"; + int result = 1; - if( internal_list == NULL ) +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_list_element_t *backup_first_element = NULL; + libcdata_list_element_t *backup_last_element = NULL; +#endif + + if( list == NULL ) { libcerror_error_set( error, @@ -1446,65 +1482,85 @@ return( -1 ); } - if( element == NULL ) + internal_list = (libcdata_internal_list_t *) list; + + if( internal_list->number_of_elements == 0 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list element.", - function ); + if( internal_list->first_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - first element already set.", + function ); - return( -1 ); + return( -1 ); + } + if( internal_list->last_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - last element already set.", + function ); + + return( -1 ); + } } - if( internal_list->first_element == NULL ) + else { - internal_list->first_element = element; + if( internal_list->first_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing first element.", + function ); + + return( -1 ); + } + if( internal_list->last_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing last element.", + function ); + + return( -1 ); + } } - if( libcdata_internal_list_set_last_element( - internal_list, + if( libcdata_list_element_get_elements( element, + &previous_element, + &next_element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set last element.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous and next element from list element.", function ); return( -1 ); } - internal_list->number_of_elements++; - - return( 1 ); -} - -/* Appends a list element to the list - * Returns 1 if successful or -1 on error - */ -int libcdata_list_append_element( - libcdata_list_t *list, - libcdata_list_element_t *element, - libcerror_error_t **error ) -{ - libcdata_internal_list_t *internal_list = NULL; - static char *function = "libcdata_list_append_element"; - int result = 1; - - if( list == NULL ) + if( ( previous_element != NULL ) + || ( next_element != NULL ) ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: list element already part of a list.", function ); return( -1 ); } - internal_list = (libcdata_internal_list_t *) list; - #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_grab_for_write( internal_list->read_write_lock, @@ -1519,21 +1575,63 @@ return( -1 ); } + backup_first_element = internal_list->first_element; + backup_last_element = internal_list->last_element; + #endif - if( libcdata_internal_list_append_element( - internal_list, - element, - error ) != 1 ) + result = libcdata_list_element_set_previous_element( + element, + internal_list->last_element, + error ); + + if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append element to list.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous element of list element.", function ); result = -1; } + if( result == 1 ) + { + if( internal_list->last_element != NULL ) + { + result = libcdata_list_element_set_next_element( + internal_list->last_element, + element, + error ); + + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next element of last element.", + function ); + + libcdata_list_element_set_previous_element( + element, + NULL, + NULL ); + + result = -1; + } + } + } + if( result == 1 ) + { + if( internal_list->first_element == NULL ) + { + internal_list->first_element = element; + } + internal_list->last_element = element; + + internal_list->number_of_elements += 1; + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_list->read_write_lock, @@ -1546,10 +1644,32 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( result ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + if( result == 1 ) + { + libcdata_list_element_set_previous_element( + element, + NULL, + NULL ); + + libcdata_list_element_set_next_element( + backup_last_element, + NULL, + NULL ); + + internal_list->first_element = backup_first_element; + internal_list->last_element = backup_last_element; + + internal_list->number_of_elements -= 1; + } + return( -1 ); +#endif } /* Appends a value to the list @@ -1561,38 +1681,9 @@ intptr_t *value, libcerror_error_t **error ) { - libcdata_internal_list_t *internal_list = NULL; - libcdata_list_element_t *element = NULL; - static char *function = "libcdata_list_append_value"; - - if( list == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list.", - function ); - - return( -1 ); - } - internal_list = (libcdata_internal_list_t *) list; - -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_list->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", - function ); + libcdata_list_element_t *element = NULL; + static char *function = "libcdata_list_append_value"; - return( -1 ); - } -#endif if( libcdata_list_element_initialize( &element, error ) != 1 ) @@ -1620,8 +1711,8 @@ goto on_error; } - if( libcdata_internal_list_append_element( - internal_list, + if( libcdata_list_append_element( + list, element, error ) != 1 ) { @@ -1634,29 +1725,9 @@ goto on_error; } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", - function ); - - return( -1 ); - } -#endif return( 1 ); on_error: -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - NULL ); -#endif if( element != NULL ) { libcdata_list_element_free( @@ -1667,7 +1738,7 @@ return( -1 ); } -/* Inserts a list element into the list +/* Retrieves the element which the element should be inserted before * * Uses the value_compare_function to determine the order of the entries * The value_compare_function should return LIBCDATA_COMPARE_LESS, @@ -1676,27 +1747,28 @@ * Duplicate entries are allowed by default and inserted after the last duplicate value. * Only allowing unique entries can be enforced by setting the flag LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES * - * Returns 1 if successful, 0 if the list element already exists or -1 on error + * On return element will be set to NULL if the element should be inserted at the end of the list. + * + * Returns 1 if successful, 0 if a list element containing the value already exists or -1 on error */ -int libcdata_internal_list_insert_element( +int libcdata_internal_list_insert_element_find_element( libcdata_internal_list_t *internal_list, - libcdata_list_element_t *element, + intptr_t *value_to_insert, int (*value_compare_function)( intptr_t *first_value, intptr_t *second_value, libcerror_error_t **error ), uint8_t insert_flags, + int *element_index, + libcdata_list_element_t **element, libcerror_error_t **error ) { - libcdata_list_element_t *list_element = NULL; - libcdata_list_element_t *next_element = NULL; - libcdata_list_element_t *previous_element = NULL; - intptr_t *element_value = NULL; - intptr_t *list_element_value = NULL; - static char *function = "libcdata_internal_list_insert_element"; - int compare_result = 0; - int element_index = 0; - int result = 1; + libcdata_list_element_t *list_element = NULL; + intptr_t *list_element_value = NULL; + static char *function = "libcdata_internal_list_insert_element_find_element"; + int compare_result = 0; + int result = 1; + int safe_element_index = 0; if( internal_list == NULL ) { @@ -1709,17 +1781,6 @@ return( -1 ); } - if( element == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list element.", - function ); - - return( -1 ); - } if( value_compare_function == NULL ) { libcerror_error_set( @@ -1743,274 +1804,285 @@ return( -1 ); } - if( libcdata_list_element_get_elements( - element, - &previous_element, - &next_element, - error ) != 1 ) + if( element_index == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous and next element from list element.", + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid element index.", function ); return( -1 ); } - if( ( previous_element != NULL ) - || ( next_element != NULL ) ) + if( element == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: list element already part of a list.", + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid element.", function ); return( -1 ); } - if( libcdata_list_element_get_value( - element, - &element_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from list element.", - function ); + list_element = internal_list->first_element; + compare_result = LIBCDATA_COMPARE_GREATER; - return( -1 ); - } - if( internal_list->number_of_elements == 0 ) - { - if( internal_list->first_element != NULL ) + for( safe_element_index = 0; + safe_element_index < internal_list->number_of_elements; + safe_element_index++ ) + { + if( libcdata_list_element_get_value( + list_element, + &list_element_value, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: corruption detected - first element already set.", - function ); + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from list element: %d.", + function, + safe_element_index ); return( -1 ); } - if( internal_list->last_element != NULL ) + compare_result = value_compare_function( + value_to_insert, + list_element_value, + error ); + + if( compare_result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: corruption detected - last element already set.", - function ); + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to compare list element: %d.", + function, + safe_element_index ); return( -1 ); } - internal_list->first_element = element; - internal_list->last_element = element; + else if( compare_result == LIBCDATA_COMPARE_EQUAL ) + { + if( ( insert_flags & LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) != 0 ) + { + result = 0; - internal_list->number_of_elements++; - } - else - { - if( internal_list->first_element == NULL ) + break; + } + } + else if( compare_result == LIBCDATA_COMPARE_LESS ) + { + break; + } + else if( compare_result != LIBCDATA_COMPARE_GREATER ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: corruption detected - missing first.", - function ); + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported value compare function return value: %d.", + function, + compare_result ); return( -1 ); } - if( internal_list->last_element == NULL ) + if( libcdata_list_element_get_next_element( + list_element, + &list_element, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: corruption detected - missing last.", - function ); + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from list element: %d.", + function, + safe_element_index ); return( -1 ); } - list_element = internal_list->first_element; + } + if( ( compare_result == LIBCDATA_COMPARE_EQUAL ) + || ( compare_result == LIBCDATA_COMPARE_LESS ) ) + { + *element_index = safe_element_index; + *element = list_element; + } + else + { + *element_index = internal_list->number_of_elements; + *element = NULL; + } + return( result ); +} - for( element_index = 0; - element_index < internal_list->number_of_elements; - element_index++ ) - { - if( libcdata_list_element_get_value( - list_element, - &list_element_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from list element: %d.", - function, - element_index ); +/* Inserts the element before the list element + * If list_element is NULL the element is inserted before or as the first element in the list + * Returns 1 if successful, or -1 on error + */ +int libcdata_internal_list_insert_element_before_element( + libcdata_internal_list_t *internal_list, + libcdata_list_element_t *list_element, + libcdata_list_element_t *element_to_insert, + libcerror_error_t **error ) +{ + libcdata_list_element_t *backup_first_element = NULL; + libcdata_list_element_t *backup_last_element = NULL; + libcdata_list_element_t *previous_element = NULL; + static char *function = "libcdata_internal_list_insert_element_before_element"; - return( -1 ); - } - compare_result = value_compare_function( - element_value, - list_element_value, - error ); + if( internal_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid list.", + function ); - if( compare_result == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to compare list element: %d.", - function, - element_index ); + return( -1 ); + } + if( element_to_insert == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid element to insert.", + function ); - return( -1 ); - } - else if( compare_result == LIBCDATA_COMPARE_EQUAL ) - { - if( ( insert_flags & LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) != 0 ) - { - result = 0; + return( -1 ); + } + backup_first_element = internal_list->first_element; + backup_last_element = internal_list->last_element; - break; - } - } - else if( compare_result == LIBCDATA_COMPARE_LESS ) - { - result = 1; + if( list_element != NULL ) + { + if( libcdata_list_element_get_previous_element( + list_element, + &previous_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous element from list element.", + function ); - break; - } - else if( compare_result != LIBCDATA_COMPARE_GREATER ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, - "%s: unsupported value compare function return value: %d.", - function, - compare_result ); + return( -1 ); + } + } + if( internal_list->number_of_elements == 0 ) + { + internal_list->first_element = element_to_insert; + internal_list->last_element = element_to_insert; + } + else if( list_element == NULL ) + { + if( libcdata_internal_list_set_last_element( + internal_list, + element_to_insert, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set last list element.", + function ); - return( -1 ); - } - if( libcdata_list_element_get_next_element( - list_element, - &list_element, + goto on_error; + } + } + else + { + if( libcdata_list_element_set_elements( + element_to_insert, + previous_element, + list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous and next element of element to insert.", + function ); + + goto on_error; + } + if( internal_list->first_element == list_element ) + { + internal_list->first_element = element_to_insert; + } + else + { + if( libcdata_list_element_set_next_element( + previous_element, + element_to_insert, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next element from list element: %d.", - function, - element_index ); + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next element of previous list element.", + function ); - return( -1 ); + goto on_error; } } - if( result != 0 ) + if( libcdata_list_element_set_previous_element( + list_element, + element_to_insert, + error ) != 1 ) { - if( compare_result == LIBCDATA_COMPARE_LESS ) - { - if( libcdata_list_element_get_previous_element( - list_element, - &previous_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous element from list element: %d.", - function, - element_index ); - - return( -1 ); - } - if( libcdata_list_element_set_elements( - element, - previous_element, - list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous and next element of list element.", - function ); - - return( -1 ); - } - if( list_element == internal_list->first_element ) - { - internal_list->first_element = element; - } - else - { - if( libcdata_list_element_set_next_element( - previous_element, - element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next element of list element: %d.", - function, - element_index - 1 ); + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous element of list element.", + function ); - return( -1 ); - } - } - if( libcdata_list_element_set_previous_element( - list_element, - element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous element of list element: %d.", - function, - element_index ); + goto on_error; + } + } + internal_list->number_of_elements += 1; - return( -1 ); - } - } - else - { - if( libcdata_internal_list_set_last_element( - internal_list, - element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set last element.", - function ); + return( 1 ); - return( -1 ); - } - } - internal_list->number_of_elements++; - } +on_error: + if( element_to_insert != NULL ) + { + libcdata_list_element_set_elements( + element_to_insert, + NULL, + NULL, + NULL ); } - return( result ); + if( previous_element != NULL ) + { + libcdata_list_element_set_next_element( + previous_element, + list_element, + NULL ); + } + if( list_element != NULL ) + { + libcdata_list_element_set_previous_element( + list_element, + previous_element, + NULL ); + } + internal_list->first_element = backup_first_element; + internal_list->last_element = backup_last_element; + + return( -1 ); } /* Inserts a list element into the list @@ -2026,7 +2098,7 @@ */ int libcdata_list_insert_element( libcdata_list_t *list, - libcdata_list_element_t *element, + libcdata_list_element_t *element_to_insert, int (*value_compare_function)( intptr_t *first_value, intptr_t *second_value, @@ -2034,9 +2106,19 @@ uint8_t insert_flags, libcerror_error_t **error ) { - libcdata_internal_list_t *internal_list = NULL; - static char *function = "libcdata_list_insert_element"; - int result = 1; + libcdata_internal_list_t *internal_list = NULL; + libcdata_list_element_t *list_element = NULL; + libcdata_list_element_t *next_element = NULL; + libcdata_list_element_t *previous_element = NULL; + intptr_t *value_to_insert = NULL; + static char *function = "libcdata_list_insert_element"; + int element_index = 0; + int result = 1; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_list_element_t *backup_first_element = NULL; + libcdata_list_element_t *backup_last_element = NULL; +#endif if( list == NULL ) { @@ -2051,6 +2133,131 @@ } internal_list = (libcdata_internal_list_t *) list; + if( internal_list->number_of_elements == 0 ) + { + if( internal_list->first_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - first element already set.", + function ); + + return( -1 ); + } + if( internal_list->last_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - last element already set.", + function ); + + return( -1 ); + } + } + else + { + if( internal_list->first_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing first element.", + function ); + + return( -1 ); + } + if( internal_list->last_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing last element.", + function ); + + return( -1 ); + } + } + if( element_to_insert == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid element to insert.", + function ); + + return( -1 ); + } + if( value_compare_function == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value compare function.", + function ); + + return( -1 ); + } + if( ( insert_flags & ~( LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported insert flags: 0x%02" PRIx8 ".", + function, + insert_flags ); + + return( -1 ); + } + if( libcdata_list_element_get_elements( + element_to_insert, + &previous_element, + &next_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous and next element from element to insert.", + function ); + + return( -1 ); + } + if( ( previous_element != NULL ) + || ( next_element != NULL ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid element to insert - already part of a list.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_value( + element_to_insert, + &value_to_insert, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from element to insert.", + function ); + + return( -1 ); + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_grab_for_write( internal_list->read_write_lock, @@ -2065,25 +2272,70 @@ return( -1 ); } + backup_first_element = internal_list->first_element; + backup_last_element = internal_list->last_element; #endif - result = libcdata_internal_list_insert_element( + + result = libcdata_internal_list_insert_element_find_element( internal_list, - element, + value_to_insert, value_compare_function, insert_flags, + &element_index, + &list_element, error ); if( result == -1 ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert element to list.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to find element in list.", function ); result = -1; } + else if( result == 1 ) + { + if( list_element != NULL ) + { + if( libcdata_list_element_get_elements( + list_element, + &previous_element, + &next_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous and next element from list element: %d.", + function, + element_index ); + + result = -1; + } + } + if( result == 1 ) + { + if( libcdata_internal_list_insert_element_before_element( + internal_list, + list_element, + element_to_insert, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert element before list element.", + function ); + + result = -1; + } + } + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_list->read_write_lock, @@ -2096,10 +2348,43 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( result ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + if( result == 1 ) + { + libcdata_list_element_set_elements( + element_to_insert, + NULL, + NULL, + NULL ); + + if( list_element != NULL ) + { + libcdata_list_element_set_elements( + list_element, + previous_element, + next_element, + NULL ); + } + else if( backup_last_element != NULL ) + { + libcdata_list_element_set_next_element( + backup_last_element, + NULL, + NULL ); + } + internal_list->first_element = backup_first_element; + internal_list->last_element = backup_last_element; + + internal_list->number_of_elements -= 1; + } + return( -1 ); +#endif } /* Inserts a value to the list @@ -2125,39 +2410,10 @@ uint8_t insert_flags, libcerror_error_t **error ) { - libcdata_internal_list_t *internal_list = NULL; - libcdata_list_element_t *element = NULL; - static char *function = "libcdata_list_insert_value"; - int result = 1; - - if( list == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list.", - function ); - - return( -1 ); - } - internal_list = (libcdata_internal_list_t *) list; + libcdata_list_element_t *element = NULL; + static char *function = "libcdata_list_insert_value"; + int result = 1; -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_list->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", - function ); - - return( -1 ); - } -#endif if( libcdata_list_element_initialize( &element, error ) != 1 ) @@ -2185,8 +2441,8 @@ goto on_error; } - result = libcdata_internal_list_insert_element( - internal_list, + result = libcdata_list_insert_element( + list, element, value_compare_function, insert_flags, @@ -2220,29 +2476,9 @@ goto on_error; } } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", - function ); - - return( -1 ); - } -#endif return( result ); on_error: -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - NULL ); -#endif if( element != NULL ) { libcdata_list_element_free( @@ -2258,13 +2494,19 @@ */ int libcdata_list_remove_element( libcdata_list_t *list, - libcdata_list_element_t *element, + libcdata_list_element_t *element_to_remove, libcerror_error_t **error ) { - libcdata_internal_list_t *internal_list = NULL; - libcdata_list_element_t *next_element = NULL; - libcdata_list_element_t *previous_element = NULL; - static char *function = "libcdata_list_remove_element"; + libcdata_internal_list_t *internal_list = NULL; + libcdata_list_element_t *next_element = NULL; + libcdata_list_element_t *previous_element = NULL; + static char *function = "libcdata_list_remove_element"; + int result = 1; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_list_element_t *backup_first_element = NULL; + libcdata_list_element_t *backup_last_element = NULL; +#endif if( list == NULL ) { @@ -2279,13 +2521,78 @@ } internal_list = (libcdata_internal_list_t *) list; - if( element == NULL ) + if( internal_list->number_of_elements == 0 ) + { + if( internal_list->first_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - first element already set.", + function ); + + return( -1 ); + } + if( internal_list->last_element != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - last element already set.", + function ); + + return( -1 ); + } + } + else + { + if( internal_list->first_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing first element.", + function ); + + return( -1 ); + } + if( internal_list->last_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing last element.", + function ); + + return( -1 ); + } + } + if( element_to_remove == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid list element.", + "%s: invalid element to remove.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_elements( + element_to_remove, + &previous_element, + &next_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous and next element from element to remove.", function ); return( -1 ); @@ -2304,81 +2611,102 @@ return( -1 ); } + backup_first_element = internal_list->first_element; + backup_last_element = internal_list->last_element; + #endif - if( libcdata_list_element_get_elements( - element, - &previous_element, - &next_element, - error ) != 1 ) + result = libcdata_list_element_set_elements( + element_to_remove, + NULL, + NULL, + error ); + + if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous and next element from list element.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous and next element of element to remove.", function ); - goto on_error; - } - if( element == internal_list->first_element ) - { - internal_list->first_element = next_element; - } - if( element == internal_list->last_element ) - { - internal_list->last_element = previous_element; + result = -1; } - if( next_element != NULL ) + if( result == 1 ) { - if( libcdata_list_element_set_previous_element( - next_element, - previous_element, - error ) != 1 ) + if( next_element != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous element of next element.", - function ); + result = libcdata_list_element_set_previous_element( + next_element, + previous_element, + error ); - goto on_error; + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous element of next element.", + function ); + + libcdata_list_element_set_elements( + element_to_remove, + previous_element, + next_element, + NULL ); + + result = -1; + } } } - if( previous_element != NULL ) + if( result == 1 ) { - if( libcdata_list_element_set_next_element( - previous_element, - next_element, - error ) != 1 ) + if( previous_element != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next element of previous element.", - function ); + result = libcdata_list_element_set_next_element( + previous_element, + next_element, + error ); - goto on_error; + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next element of previous element.", + function ); + + if( next_element != NULL ) + { + libcdata_list_element_set_previous_element( + next_element, + element_to_remove, + NULL ); + } + libcdata_list_element_set_elements( + element_to_remove, + previous_element, + next_element, + NULL ); + + result = -1; + } } } - if( libcdata_list_element_set_elements( - element, - NULL, - NULL, - error ) != 1 ) + if( result == 1 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous and next element of list element.", - function ); - - goto on_error; + if( element_to_remove == internal_list->first_element ) + { + internal_list->first_element = next_element; + } + if( element_to_remove == internal_list->last_element ) + { + internal_list->last_element = previous_element; + } + internal_list->number_of_elements -= 1; } - internal_list->number_of_elements--; - #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_list->read_write_lock, @@ -2391,17 +2719,41 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif - return( 1 ); + return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_list->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + libcdata_list_element_set_elements( + element_to_remove, + previous_element, + next_element, + NULL ); + + if( next_element != NULL ) + { + libcdata_list_element_set_previous_element( + next_element, + element_to_remove, + NULL ); + } + if( previous_element != NULL ) + { + libcdata_list_element_set_next_element( + previous_element, + element_to_remove, + NULL ); + } + internal_list->first_element = backup_first_element; + internal_list->last_element = backup_last_element; + + internal_list->number_of_elements += 1; + } return( -1 ); +#endif } diff -Nru libfsapfs-20181215/libcdata/libcdata_list_element.c libfsapfs-20190210/libcdata/libcdata_list_element.c --- libfsapfs-20181215/libcdata/libcdata_list_element.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_list_element.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * List element functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -101,7 +101,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -201,16 +201,16 @@ return( result ); } -/* Retrieves the value from the list element +/* Retrieves the parent list from the list element * Returns 1 if successful or -1 on error */ -int libcdata_list_element_get_value( +int libcdata_list_element_get_parent_list( libcdata_list_element_t *element, - intptr_t **value, + intptr_t **parent_list, libcerror_error_t **error ) { libcdata_internal_list_element_t *internal_element = NULL; - static char *function = "libcdata_list_element_get_value"; + static char *function = "libcdata_list_element_get_parent_list"; if( element == NULL ) { @@ -225,13 +225,13 @@ } internal_element = (libcdata_internal_list_element_t *) element; - if( value == NULL ) + if( parent_list == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value.", + "%s: invalid parent list.", function ); return( -1 ); @@ -251,7 +251,7 @@ return( -1 ); } #endif - *value = internal_element->value; + *parent_list = internal_element->parent_list; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_read( @@ -271,16 +271,20 @@ return( 1 ); } -/* Sets the value in the list element +/* Sets the parent list in the list element * Returns 1 if successful or -1 on error */ -int libcdata_list_element_set_value( +int libcdata_list_element_set_parent_list( libcdata_list_element_t *element, - intptr_t *value, + intptr_t *parent_list, libcerror_error_t **error ) { libcdata_internal_list_element_t *internal_element = NULL; - static char *function = "libcdata_list_element_set_value"; + static char *function = "libcdata_list_element_set_parent_list"; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + intptr_t *backup_parent_list = NULL; +#endif if( element == NULL ) { @@ -309,8 +313,9 @@ return( -1 ); } + backup_parent_list = internal_element->parent_list; #endif - internal_element->value = value; + internal_element->parent_list = parent_list; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( @@ -324,10 +329,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_element->parent_list = backup_parent_list; + + return( -1 ); +#endif } /* Retrieves the previous element from the list element @@ -411,6 +423,10 @@ libcdata_internal_list_element_t *internal_element = NULL; static char *function = "libcdata_list_element_set_previous_element"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_list_element_t *backup_previous_element = NULL; +#endif + if( element == NULL ) { libcerror_error_set( @@ -438,6 +454,7 @@ return( -1 ); } + backup_previous_element = internal_element->previous_element; #endif internal_element->previous_element = previous_element; @@ -453,10 +470,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_element->previous_element = backup_previous_element; + + return( -1 ); +#endif } /* Retrieves the next element from the list element @@ -540,6 +564,10 @@ libcdata_internal_list_element_t *internal_element = NULL; static char *function = "libcdata_list_element_set_next_element"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_list_element_t *backup_next_element = NULL; +#endif + if( element == NULL ) { libcerror_error_set( @@ -567,6 +595,7 @@ return( -1 ); } + backup_next_element = internal_element->next_element; #endif internal_element->next_element = next_element; @@ -582,10 +611,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_element->next_element = backup_next_element; + + return( -1 ); +#endif } /* Retrieves the previous and next element from the list element @@ -683,6 +719,11 @@ libcdata_internal_list_element_t *internal_element = NULL; static char *function = "libcdata_list_element_set_elements"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_list_element_t *backup_next_element = NULL; + libcdata_list_element_t *backup_previous_element = NULL; +#endif + if( element == NULL ) { libcerror_error_set( @@ -710,6 +751,8 @@ return( -1 ); } + backup_previous_element = internal_element->previous_element; + backup_next_element = internal_element->next_element; #endif internal_element->previous_element = previous_element; internal_element->next_element = next_element; @@ -726,9 +769,158 @@ "%s: unable to release read/write lock for writing.", function ); + goto on_error; + } +#endif + return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_element->previous_element = backup_previous_element; + internal_element->next_element = backup_next_element; + + return( -1 ); +#endif +} + +/* Retrieves the value from the list element + * Returns 1 if successful or -1 on error + */ +int libcdata_list_element_get_value( + libcdata_list_element_t *element, + intptr_t **value, + libcerror_error_t **error ) +{ + libcdata_internal_list_element_t *internal_element = NULL; + static char *function = "libcdata_list_element_get_value"; + + if( element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid list element.", + function ); + + return( -1 ); + } + internal_element = (libcdata_internal_list_element_t *) element; + + if( value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value.", + function ); + + return( -1 ); + } +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_read( + internal_element->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for reading.", + function ); + + return( -1 ); + } +#endif + *value = internal_element->value; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_release_for_read( + internal_element->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for reading.", + function ); + + return( -1 ); + } +#endif + return( 1 ); +} + +/* Sets the value in the list element + * Returns 1 if successful or -1 on error + */ +int libcdata_list_element_set_value( + libcdata_list_element_t *element, + intptr_t *value, + libcerror_error_t **error ) +{ + libcdata_internal_list_element_t *internal_element = NULL; + static char *function = "libcdata_list_element_set_value"; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + intptr_t *backup_value = NULL; +#endif + + if( element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid list element.", + function ); + + return( -1 ); + } + internal_element = (libcdata_internal_list_element_t *) element; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_write( + internal_element->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + return( -1 ); } + backup_value = internal_element->value; +#endif + internal_element->value = value; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_release_for_write( + internal_element->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for writing.", + function ); + + goto on_error; + } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_element->value = backup_value; + + return( -1 ); +#endif } diff -Nru libfsapfs-20181215/libcdata/libcdata_list_element.h libfsapfs-20190210/libcdata/libcdata_list_element.h --- libfsapfs-20181215/libcdata/libcdata_list_element.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_list_element.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * List element functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -38,6 +38,10 @@ struct libcdata_internal_list_element { + /* The list the element is part of + */ + intptr_t *parent_list; + /* The previous list element */ libcdata_list_element_t *previous_element; @@ -70,16 +74,14 @@ libcerror_error_t **error ), libcerror_error_t **error ); -LIBCDATA_EXTERN \ -int libcdata_list_element_get_value( +int libcdata_list_element_get_parent_list( libcdata_list_element_t *element, - intptr_t **value, + intptr_t **parent_list, libcerror_error_t **error ); -LIBCDATA_EXTERN \ -int libcdata_list_element_set_value( +int libcdata_list_element_set_parent_list( libcdata_list_element_t *element, - intptr_t *value, + intptr_t *parent_list, libcerror_error_t **error ); LIBCDATA_EXTERN \ @@ -120,6 +122,18 @@ libcdata_list_element_t *next_element, libcerror_error_t **error ); +LIBCDATA_EXTERN \ +int libcdata_list_element_get_value( + libcdata_list_element_t *element, + intptr_t **value, + libcerror_error_t **error ); + +LIBCDATA_EXTERN \ +int libcdata_list_element_set_value( + libcdata_list_element_t *element, + intptr_t *value, + libcerror_error_t **error ); + #if defined( __cplusplus ) } #endif diff -Nru libfsapfs-20181215/libcdata/libcdata_list.h libfsapfs-20190210/libcdata/libcdata_list.h --- libfsapfs-20181215/libcdata/libcdata_list.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_list.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * List functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -70,13 +70,6 @@ libcerror_error_t **error ), libcerror_error_t **error ); -int libcdata_internal_list_empty( - libcdata_internal_list_t *internal_list, - int (*value_free_function)( - intptr_t **value, - libcerror_error_t **error ), - libcerror_error_t **error ); - LIBCDATA_EXTERN \ int libcdata_list_empty( libcdata_list_t *list, @@ -115,11 +108,6 @@ libcdata_list_element_t *element, libcerror_error_t **error ); -int libcdata_list_set_first_element( - libcdata_list_t *list, - libcdata_list_element_t *element, - libcerror_error_t **error ); - LIBCDATA_EXTERN \ int libcdata_list_get_last_element( libcdata_list_t *list, @@ -131,11 +119,6 @@ libcdata_list_element_t *element, libcerror_error_t **error ); -int libcdata_list_set_last_element( - libcdata_list_t *list, - libcdata_list_element_t *element, - libcerror_error_t **error ); - LIBCDATA_EXTERN \ int libcdata_list_get_element_by_index( libcdata_list_t *list, @@ -162,11 +145,6 @@ intptr_t *value, libcerror_error_t **error ); -int libcdata_internal_list_append_element( - libcdata_internal_list_t *internal_list, - libcdata_list_element_t *element, - libcerror_error_t **error ); - LIBCDATA_EXTERN \ int libcdata_list_append_element( libcdata_list_t *list, @@ -179,20 +157,28 @@ intptr_t *value, libcerror_error_t **error ); -int libcdata_internal_list_insert_element( +int libcdata_internal_list_insert_element_find_element( libcdata_internal_list_t *internal_list, - libcdata_list_element_t *element, + intptr_t *value_to_insert, int (*value_compare_function)( - intptr_t *first, - intptr_t *second, + intptr_t *first_value, + intptr_t *second_value, libcerror_error_t **error ), uint8_t insert_flags, + int *element_index, + libcdata_list_element_t **element, + libcerror_error_t **error ); + +int libcdata_internal_list_insert_element_before_element( + libcdata_internal_list_t *internal_list, + libcdata_list_element_t *list_element, + libcdata_list_element_t *element_to_insert, libcerror_error_t **error ); LIBCDATA_EXTERN \ int libcdata_list_insert_element( libcdata_list_t *list, - libcdata_list_element_t *element, + libcdata_list_element_t *element_to_insert, int (*value_compare_function)( intptr_t *first, intptr_t *second, @@ -214,7 +200,7 @@ LIBCDATA_EXTERN \ int libcdata_list_remove_element( libcdata_list_t *list, - libcdata_list_element_t *element, + libcdata_list_element_t *element_to_remove, libcerror_error_t **error ); #if defined( __cplusplus ) diff -Nru libfsapfs-20181215/libcdata/libcdata_range_list.c libfsapfs-20190210/libcdata/libcdata_range_list.c --- libfsapfs-20181215/libcdata/libcdata_range_list.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_range_list.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Range list * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -30,6 +30,7 @@ #include "libcdata_range_list.h" #include "libcdata_range_list_value.h" #include "libcdata_types.h" +#include "libcdata_unused.h" /* Creates a range list * Make sure the value range_list is referencing, is set to NULL @@ -104,7 +105,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -189,6 +190,92 @@ return( result ); } +/* Frees a range list element + * Uses the value_free_function to free the element value + * Returns 1 if successful or -1 on error + */ +int libcdata_internal_range_list_free_element( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t **range_list_element, + int (*value_free_function)( + intptr_t **value, + libcerror_error_t **error ), + libcerror_error_t **error ) +{ + libcdata_range_list_value_t *range_list_value = NULL; + static char *function = "libcdata_internal_range_list_free_element"; + int result = 1; + + if( internal_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); + } + if( range_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list element.", + function ); + + return( -1 ); + } + if( *range_list_element != NULL ) + { + if( libcdata_list_element_get_value( + *range_list_element, + (intptr_t **) &range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from range list element.", + function ); + + return( -1 ); + } + if( libcdata_range_list_value_free( + &range_list_value, + value_free_function, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free range list value.", + function ); + + result = -1; + } + if( libcdata_list_element_free( + range_list_element, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free list element.", + function ); + + result = -1; + } + } + return( result ); +} + /* Empties a range list and frees the elements * Uses the value_free_function to free the element value * Returns 1 if successful or -1 on error @@ -203,7 +290,6 @@ libcdata_internal_range_list_t *internal_range_list = NULL; libcdata_list_element_t *list_element = NULL; libcdata_list_element_t *next_element = NULL; - libcdata_range_list_value_t *range_list_value = NULL; static char *function = "libcdata_range_list_empty"; int element_index = 0; int number_of_elements = 0; @@ -259,7 +345,9 @@ function, element_index ); - goto on_error; + result = -1; + + break; } internal_range_list->first_element = next_element; @@ -267,7 +355,7 @@ { internal_range_list->last_element = next_element; } - internal_range_list->number_of_elements--; + internal_range_list->number_of_elements -= 1; if( next_element != NULL ) { @@ -284,7 +372,7 @@ function, element_index + 1 ); - goto on_error; + result = -1; } } if( libcdata_list_element_set_next_element( @@ -300,48 +388,19 @@ function, element_index ); - goto on_error; - } - if( libcdata_list_element_get_value( - list_element, - (intptr_t **) &range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from list element: %d.", - function, - element_index ); - - goto on_error; - } - if( libcdata_range_list_value_free( - &range_list_value, - value_free_function, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free range list value: %d.", - function, - element_index ); - result = -1; } - if( libcdata_list_element_free( + if( libcdata_internal_range_list_free_element( + internal_range_list, &list_element, - NULL, + value_free_function, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free list element: %d.", + "%s: unable to free range list element: %d.", function, element_index ); @@ -364,18 +423,10 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + result = -1; } #endif return( result ); - -on_error: -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_range_list->read_write_lock, - NULL ); -#endif - return( -1 ); } /* Clones the range list @@ -434,45 +485,45 @@ } internal_source_range_list = (libcdata_internal_range_list_t *) source_range_list; - if( libcdata_range_list_initialize( - (libcdata_range_list_t **) &internal_destination_range_list, +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_read( + internal_source_range_list->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create destination range list.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for reading.", function ); return( -1 ); } - if( internal_destination_range_list == NULL ) +#endif + if( libcdata_range_list_initialize( + (libcdata_range_list_t **) &internal_destination_range_list, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing destination range list.", + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create destination range list.", function ); - return( -1 ); + goto on_error; } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_read( - internal_source_range_list->read_write_lock, - error ) != 1 ) + if( internal_destination_range_list == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for reading.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing destination range list.", function ); - return( -1 ); + goto on_error; } -#endif if( internal_source_range_list->first_element != NULL ) { internal_source_list_element = (libcdata_internal_list_element_t *) internal_source_range_list->first_element; @@ -725,7 +776,9 @@ libcdata_list_element_t *element, libcerror_error_t **error ) { - static char *function = "libcdata_internal_range_list_set_first_element"; + libcdata_list_element_t *backup_first_element = NULL; + libcdata_list_element_t *backup_next_element = NULL; + static char *function = "libcdata_internal_range_list_set_first_element"; if( internal_range_list == NULL ) { @@ -740,6 +793,25 @@ } if( element != NULL ) { + if( libcdata_list_element_get_next_element( + element, + &backup_next_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element of element.", + function ); + + return( -1 ); + } + } + backup_first_element = internal_range_list->first_element; + + if( element != NULL ) + { if( libcdata_list_element_set_next_element( element, internal_range_list->first_element, @@ -749,10 +821,10 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next element of list element.", + "%s: unable to set next element of element.", function ); - return( -1 ); + goto on_error; } } if( internal_range_list->first_element != NULL ) @@ -769,12 +841,31 @@ "%s: unable to set previous element of first element.", function ); - return( -1 ); + goto on_error; } } internal_range_list->first_element = element; return( 1 ); + +on_error: + if( element != NULL ) + { + libcdata_list_element_set_next_element( + element, + backup_next_element, + NULL ); + } + if( backup_first_element != NULL ) + { + libcdata_list_element_set_next_element( + backup_first_element, + NULL, + NULL ); + } + internal_range_list->first_element = backup_first_element; + + return( -1 ); } /* Retrieves the last elements in the range list @@ -855,7 +946,9 @@ libcdata_list_element_t *element, libcerror_error_t **error ) { - static char *function = "libcdata_internal_range_list_set_last_element"; + libcdata_list_element_t *backup_last_element = NULL; + libcdata_list_element_t *backup_previous_element = NULL; + static char *function = "libcdata_internal_range_list_set_last_element"; if( internal_range_list == NULL ) { @@ -870,6 +963,25 @@ } if( element != NULL ) { + if( libcdata_list_element_get_previous_element( + element, + &backup_previous_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous element of element.", + function ); + + return( -1 ); + } + } + backup_last_element = internal_range_list->last_element; + + if( element != NULL ) + { if( libcdata_list_element_set_previous_element( element, internal_range_list->last_element, @@ -879,10 +991,10 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous element of list element.", + "%s: unable to set previous element of element.", function ); - return( -1 ); + goto on_error; } } if( internal_range_list->last_element != NULL ) @@ -899,12 +1011,31 @@ "%s: unable to set next element of last element.", function ); - return( -1 ); + goto on_error; } } internal_range_list->last_element = element; return( 1 ); + +on_error: + if( element != NULL ) + { + libcdata_list_element_set_previous_element( + element, + backup_previous_element, + NULL ); + } + if( backup_last_element != NULL ) + { + libcdata_list_element_set_next_element( + backup_last_element, + NULL, + NULL ); + } + internal_range_list->last_element = backup_last_element; + + return( -1 ); } /* Append a list element to the list @@ -957,7 +1088,7 @@ return( -1 ); } - internal_range_list->number_of_elements++; + internal_range_list->number_of_elements += 1; return( 1 ); } @@ -1028,44 +1159,17 @@ return( -1 ); } -/* Inserts a range - * - * The values are merged using the value_merge_function. - * If the source value is NULL the merge function is not called. - * - * After a merge and on error the values are freed using - * the value_free_function - * +/* Removes an element from the range list * Returns 1 if successful, or -1 on error */ -int libcdata_internal_range_list_insert_range( +int libcdata_internal_range_list_remove_element( libcdata_internal_range_list_t *internal_range_list, - uint64_t range_start, - uint64_t range_size, - intptr_t *value, - int (*value_free_function)( - intptr_t **value, - libcerror_error_t **error ), - int (*value_merge_function)( - intptr_t *destination_value, - intptr_t *source_value, - libcerror_error_t **error ), + libcdata_list_element_t *range_list_element, libcerror_error_t **error ) { - libcdata_list_element_t *last_element = NULL; - libcdata_list_element_t *list_element = NULL; - libcdata_list_element_t *next_element = NULL; - libcdata_list_element_t *previous_element = NULL; - libcdata_range_list_value_t *next_range_list_value = NULL; - libcdata_range_list_value_t *new_range_list_value = NULL; - libcdata_range_list_value_t *range_list_value = NULL; - libcdata_range_list_value_t *previous_range_list_value = NULL; - static char *function = "libcdata_internal_range_list_insert_range"; - uint64_t range_end = 0; - int create_element = 0; - int element_index = 0; - int merge_next_element_check = 0; - int merge_previous_element_check = 0; + libcdata_list_element_t *next_element = NULL; + libcdata_list_element_t *previous_element = NULL; + static char *function = "libcdata_internal_range_list_remove_element"; if( internal_range_list == NULL ) { @@ -1078,52 +1182,249 @@ return( -1 ); } - if( range_start > (uint64_t) INT64_MAX ) + if( libcdata_list_element_get_elements( + range_list_element, + &previous_element, + &next_element, + error ) != 1 ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid range start value exceeds maximum.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous and next element from range list element.", function ); return( -1 ); } - if( range_size > (uint64_t) INT64_MAX ) + if( range_list_element == internal_range_list->first_element ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid range size value exceeds maximum.", - function ); - - return( -1 ); + internal_range_list->first_element = next_element; } - range_end = range_start + range_size; - - if( range_end < range_start ) + if( range_list_element == internal_range_list->last_element ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid range end value out of bounds.", + internal_range_list->last_element = previous_element; + } + if( next_element != NULL ) + { + if( libcdata_list_element_set_previous_element( + next_element, + previous_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous element of next element.", + function ); + + return( -1 ); + } + } + if( previous_element != NULL ) + { + if( libcdata_list_element_set_next_element( + previous_element, + next_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next element of previous element.", + function ); + + return( -1 ); + } + } + if( libcdata_list_element_set_elements( + range_list_element, + NULL, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous and next element of range list element.", function ); - goto on_error; + return( -1 ); + } + internal_range_list->current_element = NULL; + internal_range_list->current_element_index = 0; + + internal_range_list->number_of_elements -= 1; + + return( 1 ); +} + +/* Removes an element from the range list and frees the element + * Returns 1 if successful, or -1 on error + */ +int libcdata_internal_range_list_remove_range_value( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t **range_list_element, + int (*value_free_function)( + intptr_t **value, + libcerror_error_t **error ), + libcerror_error_t **error ) +{ + libcdata_range_list_value_t *range_list_value = NULL; + static char *function = "libcdata_internal_range_list_remove_range_value"; + int result = 1; + + if( internal_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); + } + if( range_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list element.", + function ); + + return( -1 ); + } + if( libcdata_internal_range_list_remove_element( + internal_range_list, + *range_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove range list element.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_value( + *range_list_element, + (intptr_t **) &range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve range list value from range list element.", + function ); + + return( -1 ); + } + if( libcdata_list_element_free( + range_list_element, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free range list element.", + function ); + + result = -1; + } + if( libcdata_range_list_value_free( + &range_list_value, + value_free_function, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free range list value.", + function ); + + result = -1; + } + return( result ); +} + +/* Retrieves the element which the range should be inserted before or merged within + * + * On return element will be set to NULL if the range should be inserted at the end of the list. + * + * Returns 1 if successful or -1 on error + */ +int libcdata_internal_range_list_insert_range_find_element( + libcdata_internal_range_list_t *internal_range_list, + uint64_t range_start, + uint64_t range_end LIBCDATA_ATTRIBUTE_UNUSED, + int *element_index, + libcdata_list_element_t **element, + libcerror_error_t **error ) +{ + libcdata_list_element_t *current_element = NULL; + libcdata_list_element_t *previous_element = NULL; + libcdata_range_list_value_t *range_list_value = NULL; + static char *function = "libcdata_internal_range_list_insert_range_find_element"; + int current_element_index = 0; + int last_element_index = 0; + + LIBCDATA_UNREFERENCED_PARAMETER( range_end ) + + if( internal_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); + } + if( element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid element.", + function ); + + return( -1 ); + } + if( element_index == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid element index.", + function ); + + return( -1 ); } - create_element = 1; + current_element = internal_range_list->last_element; + current_element_index = internal_range_list->number_of_elements; if( internal_range_list->number_of_elements > 0 ) { /* Check the last element first, most often the list will be filled linear */ - list_element = internal_range_list->last_element; - element_index = internal_range_list->number_of_elements - 1; + current_element_index--; if( libcdata_list_element_get_value( - list_element, + current_element, (intptr_t **) &range_list_value, error ) != 1 ) { @@ -1133,9 +1434,9 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value from list element: %d.", function, - element_index ); + current_element_index ); - goto on_error; + return( -1 ); } if( range_list_value == NULL ) { @@ -1145,79 +1446,79 @@ LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing range list value element: %d.", function, - element_index ); + current_element_index ); - goto on_error; - } - /* Check if the range overlaps at the end of the existing range - */ - if( ( range_start >= range_list_value->start ) - && ( range_start <= range_list_value->end ) ) - { - if( range_end > range_list_value->end ) - { - range_list_value->size += range_end - range_list_value->end; - range_list_value->end = range_end; - } - create_element = 0; - merge_next_element_check = 1; - } - /* Check if the range overlaps at the beginning of the existing range - */ - else if( ( range_end >= range_list_value->start ) - && ( range_end <= range_list_value->end ) ) - { - if( range_start < range_list_value->start ) - { - range_list_value->size += range_list_value->start - range_start; - range_list_value->start = range_start; - } - create_element = 0; - merge_previous_element_check = 1; + return( -1 ); } - /* Check if the range overlaps the existing range entirely - */ - else if( ( range_start < range_list_value->start ) - && ( range_end > range_list_value->end ) ) + if( range_start > range_list_value->end ) { - range_list_value->start = range_start; - range_list_value->size = range_size; - range_list_value->end = range_end; + current_element = NULL; - create_element = 0; - merge_previous_element_check = 1; - } - /* Check if the range is after the existing range - */ - else if( range_end > range_list_value->end ) - { - last_element = list_element; + current_element_index++; } else if( internal_range_list->number_of_elements > 1 ) { - if( range_end > ( range_list_value->end / 2 ) ) + last_element_index = current_element_index; + + if( ( current_element_index != internal_range_list->current_element_index ) + && ( internal_range_list->current_element != NULL ) ) { - if( libcdata_list_element_get_previous_element( - list_element, - &list_element, + /* Check the current element + */ + current_element = internal_range_list->current_element; + current_element_index = internal_range_list->current_element_index; + + if( libcdata_list_element_get_value( + current_element, + (intptr_t **) &range_list_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous element from list element: %d.", + "%s: unable to retrieve value from list element: %d.", + function, + current_element_index ); + + return( -1 ); + } + if( range_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing range list value element: %d.", function, - element_index ); + current_element_index ); - goto on_error; + return( -1 ); } - for( element_index = ( internal_range_list->number_of_elements - 2 ); - element_index >= 0; - element_index-- ) + } + if( range_start > range_list_value->end ) + { + while( current_element_index < last_element_index ) { + if( libcdata_list_element_get_next_element( + current_element, + ¤t_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from list element: %d.", + function, + current_element_index ); + + return( -1 ); + } + current_element_index++; + if( libcdata_list_element_get_value( - list_element, + current_element, (intptr_t **) &range_list_value, error ) != 1 ) { @@ -1227,9 +1528,9 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value from list element: %d.", function, - element_index ); + current_element_index ); - goto on_error; + return( -1 ); } if( range_list_value == NULL ) { @@ -1239,66 +1540,25 @@ LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing range list value element: %d.", function, - element_index ); + current_element_index ); - goto on_error; - } - /* Check if the range overlaps at the end of the existing range - */ - if( ( range_start >= range_list_value->start ) - && ( range_start <= range_list_value->end ) ) - { - if( range_end > range_list_value->end ) - { - range_list_value->size += range_end - range_list_value->end; - range_list_value->end = range_end; - } - create_element = 0; - merge_next_element_check = 1; - } - /* Check if the range overlaps at the beginning of the existing range - */ - else if( ( range_end >= range_list_value->start ) - && ( range_end <= range_list_value->end ) ) - { - if( range_start < range_list_value->start ) - { - range_list_value->size += range_list_value->start - range_start; - range_list_value->start = range_start; - } - create_element = 0; - merge_previous_element_check = 1; - } - /* Check if the range overlaps the existing range entirely - */ - else if( ( range_start < range_list_value->start ) - && ( range_end > range_list_value->end ) ) - { - range_list_value->start = range_start; - range_list_value->size = range_size; - range_list_value->end = range_end; - - create_element = 0; - merge_next_element_check = 1; - merge_previous_element_check = 1; - } - if( create_element == 0 ) - { - break; + return( -1 ); } - /* Check if the range is after the existing range - */ - if( range_end > range_list_value->end ) + if( range_start <= range_list_value->end ) { - last_element = list_element; - break; } - last_element = list_element; + } + } + else + { + while( current_element_index > 0 ) + { + previous_element = current_element; if( libcdata_list_element_get_previous_element( - list_element, - &list_element, + current_element, + ¤t_element, error ) != 1 ) { libcerror_error_set( @@ -1307,22 +1567,14 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve previous element from list element: %d.", function, - element_index ); + current_element_index ); - goto on_error; + return( -1 ); } - } - } - else - { - list_element = internal_range_list->first_element; + current_element_index--; - for( element_index = 0; - element_index < ( internal_range_list->number_of_elements - 1 ); - element_index++ ) - { if( libcdata_list_element_get_value( - list_element, + current_element, (intptr_t **) &range_list_value, error ) != 1 ) { @@ -1332,9 +1584,9 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve value from list element: %d.", function, - element_index ); + current_element_index ); - goto on_error; + return( -1 ); } if( range_list_value == NULL ) { @@ -1344,502 +1596,642 @@ LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: missing range list value element: %d.", function, - element_index ); + current_element_index ); - goto on_error; - } - /* Check if the range overlaps at the end of the existing range - */ - if( ( range_start >= range_list_value->start ) - && ( range_start <= range_list_value->end ) ) - { - if( range_end > range_list_value->end ) - { - range_list_value->size += range_end - range_list_value->end; - range_list_value->end = range_end; - } - create_element = 0; - merge_next_element_check = 1; + return( -1 ); } - /* Check if the range overlaps at the beginning of the existing range - */ - else if( ( range_end >= range_list_value->start ) - && ( range_end <= range_list_value->end ) ) + if( range_start > range_list_value->end ) { - if( range_start < range_list_value->start ) - { - range_list_value->size += range_list_value->start - range_start; - range_list_value->start = range_start; - } - create_element = 0; - merge_previous_element_check = 1; + current_element = previous_element; + + current_element_index++; + + break; } - /* Check if the range overlaps the existing range entirely - */ - else if( ( range_start < range_list_value->start ) - && ( range_end > range_list_value->end ) ) - { - range_list_value->start = range_start; - range_list_value->size = range_size; - range_list_value->end = range_end; - - create_element = 0; - merge_next_element_check = 1; - merge_previous_element_check = 1; - } - if( create_element == 0 ) - { - break; - } - /* Check if the range belongs before the existing range - */ - if( range_end < range_list_value->end ) - { - if( libcdata_list_element_get_previous_element( - list_element, - &last_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous element from list element: %d.", - function, - element_index ); + } + } + } + } + if( current_element != NULL ) + { + internal_range_list->current_element = current_element; + internal_range_list->current_element_index = current_element_index; + } + *element = current_element; + *element_index = current_element_index; - goto on_error; - } - break; - } - last_element = list_element; + return( 1 ); +} - if( libcdata_list_element_get_next_element( - list_element, - &list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next element from list element: %d.", - function, - element_index ); +/* Checks if the range overlaps with the value of the range list element + * Returns 1 if the range overlaps, 0 if not or -1 on error + */ +int libcdata_internal_range_list_check_range_overlap( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + uint64_t range_start, + uint64_t range_end, + libcerror_error_t **error ) +{ + libcdata_range_list_value_t *range_list_value = NULL; + static char *function = "libcdata_internal_range_list_check_range_overlap"; + int result = 0; - goto on_error; - } - } - } + if( internal_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); + } + if( range_list_element != NULL ) + { + if( libcdata_list_element_get_value( + range_list_element, + (intptr_t **) &range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from range list element.", + function ); + + return( -1 ); } - /* Check if the current range should be merged with the previous range - */ - if( merge_previous_element_check != 0 ) + result = libcdata_range_list_value_check_range_overlap( + range_list_value, + range_start, + range_end, + error ); + + if( result == -1 ) { - if( libcdata_list_element_get_previous_element( - list_element, - &previous_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous element from list element: %d.", - function, - element_index ); + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine if range overlaps with range list value.", + function ); - goto on_error; - } - if( previous_element != NULL ) - { - if( libcdata_list_element_get_value( - previous_element, - (intptr_t **) &previous_range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from list element: %d.", - function, - element_index - 1 ); + return( -1 ); + } + } + return( result ); +} - goto on_error; - } - if( previous_range_list_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing range list value element: %d.", - function, - element_index - 1 ); +/* Inserts the range before the range list element + * If range_list_element is NULL the element is inserted before or as the first element in the list + * Returns 1 if successful, or -1 on error + */ +int libcdata_internal_range_list_insert_range_before_element( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + uint64_t range_start, + uint64_t range_end, + intptr_t *value, + libcdata_list_element_t **new_range_list_element, + libcerror_error_t **error ) +{ + libcdata_list_element_t *backup_first_element = NULL; + libcdata_list_element_t *backup_last_element = NULL; + libcdata_list_element_t *new_element = NULL; + libcdata_list_element_t *previous_element = NULL; + libcdata_range_list_value_t *new_range_list_value = NULL; + static char *function = "libcdata_internal_range_list_insert_range_before_element"; - goto on_error; - } - if( range_list_value->start <= previous_range_list_value->end ) - { - /* Merge range with previous - */ - if( libcdata_range_list_value_merge( - range_list_value, - previous_range_list_value, - value_merge_function, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to merge range list value with previous.", - function ); + if( internal_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); - previous_range_list_value = NULL; + return( -1 ); + } + if( new_range_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid new range list element.", + function ); - goto on_error; - } - /* Remove previous list element - */ - if( libcdata_internal_range_list_remove_element( - internal_range_list, - previous_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove list element: %d.", - function, - element_index - 1 ); + return( -1 ); + } + if( range_list_element != NULL ) + { + if( libcdata_list_element_get_previous_element( + range_list_element, + &previous_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous element from range list element.", + function ); - previous_range_list_value = NULL; + return( -1 ); + } + } + if( libcdata_range_list_value_initialize( + &new_range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create range list value.", + function ); - goto on_error; - } - if( libcdata_list_element_free( - &previous_element, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free list element: %d.", - function, - element_index - 1 ); + goto on_error; + } + backup_first_element = internal_range_list->first_element; + backup_last_element = internal_range_list->last_element; - goto on_error; - } - if( libcdata_range_list_value_free( - &previous_range_list_value, - value_free_function, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free previous range list value: %d.", - function, - element_index ); + if( new_range_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing range list value.", + function ); - goto on_error; - } - } - previous_range_list_value = NULL; - } + goto on_error; + } + new_range_list_value->start = range_start; + new_range_list_value->size = range_end - range_start; + new_range_list_value->end = range_end; + new_range_list_value->value = value; + + if( libcdata_list_element_initialize( + &new_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create list element.", + function ); + + goto on_error; + } + if( libcdata_list_element_set_value( + new_element, + (intptr_t *) new_range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set value in list element.", + function ); + + goto on_error; + } + if( internal_range_list->number_of_elements == 0 ) + { + internal_range_list->first_element = new_element; + internal_range_list->last_element = new_element; + } + else if( range_list_element == NULL ) + { + if( libcdata_internal_range_list_set_last_element( + internal_range_list, + new_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set last element.", + function ); + + goto on_error; } - /* Check if the current range should be merged with the next range - */ - if( merge_next_element_check != 0 ) + } + else + { + if( libcdata_list_element_set_elements( + new_element, + previous_element, + range_list_element, + error ) != 1 ) { - if( libcdata_list_element_get_next_element( - list_element, - &next_element, + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous and next element of element.", + function ); + + goto on_error; + } + if( internal_range_list->first_element == range_list_element ) + { + internal_range_list->first_element = new_element; + } + else + { + if( libcdata_list_element_set_next_element( + previous_element, + new_element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next element from list element: %d.", - function, - element_index ); + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next element of previous element.", + function ); goto on_error; } - if( next_element != NULL ) - { - if( libcdata_list_element_get_value( - next_element, - (intptr_t **) &next_range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from list element: %d.", - function, - element_index + 1 ); + } + if( libcdata_list_element_set_previous_element( + range_list_element, + new_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous element of range list element.", + function ); - goto on_error; - } - if( next_range_list_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing range list value element: %d.", - function, - element_index + 1 ); + goto on_error; + } + } + internal_range_list->current_element = NULL; + internal_range_list->current_element_index = 0; - goto on_error; - } - if( range_list_value->end >= next_range_list_value->start ) - { - /* Merge range with next - */ - if( libcdata_range_list_value_merge( - range_list_value, - next_range_list_value, - value_merge_function, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to merge range list value with next.", - function ); + internal_range_list->number_of_elements += 1; - next_range_list_value = NULL; + *new_range_list_element = new_element; - goto on_error; - } - /* Remove next list element - */ - if( libcdata_internal_range_list_remove_element( - internal_range_list, - next_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove list element: %d.", - function, - element_index + 1 ); + return( 1 ); - next_range_list_value = NULL; +on_error: + if( new_element != NULL ) + { + libcdata_list_element_set_elements( + new_element, + NULL, + NULL, + NULL ); - goto on_error; - } - if( libcdata_list_element_free( - &next_element, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free list element: %d.", - function, - element_index + 1 ); + libcdata_list_element_free( + &new_element, + NULL, + NULL ); + } + if( new_range_list_value != NULL ) + { + libcdata_range_list_value_free( + &new_range_list_value, + NULL, + NULL ); + } + if( previous_element != NULL ) + { + libcdata_list_element_set_next_element( + previous_element, + range_list_element, + NULL ); + } + if( range_list_element != NULL ) + { + libcdata_list_element_set_previous_element( + range_list_element, + previous_element, + NULL ); + } + internal_range_list->first_element = backup_first_element; + internal_range_list->last_element = backup_last_element; - goto on_error; - } - if( libcdata_range_list_value_free( - &next_range_list_value, - value_free_function, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free next range list value: %d.", - function, - element_index + 1 ); + return( -1 ); +} - goto on_error; - } - } - next_range_list_value = NULL; - } - } +/* Inserts the element in the range list after the range list element + * If range_list_element is NULL the element is inserted as the first element in the list + * Returns 1 if successful, or -1 on error + */ +int libcdata_internal_range_list_insert_element_after_element( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + libcdata_list_element_t *element, + libcerror_error_t **error ) +{ + libcdata_list_element_t *next_element = NULL; + libcdata_list_element_t *previous_element = NULL; + static char *function = "libcdata_internal_range_list_insert_element_after_element"; + + if( internal_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_elements( + element, + &previous_element, + &next_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous and next element from list element.", + function ); + + return( -1 ); } - if( create_element != 0 ) + if( ( previous_element != NULL ) + || ( next_element != NULL ) ) { - if( libcdata_range_list_value_initialize( - &new_range_list_value, - error ) != 1 ) + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: list element already part of a list.", + function ); + + return( -1 ); + } + if( internal_range_list->number_of_elements == 0 ) + { + if( internal_range_list->first_element != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create range list value.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid range list - first element already set.", function ); - goto on_error; + return( -1 ); } - if( new_range_list_value == NULL ) + if( internal_range_list->last_element != NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing range list value.", + "%s: invalid range list - last element already set.", function ); - goto on_error; + return( -1 ); } - new_range_list_value->start = range_start; - new_range_list_value->size = range_size; - new_range_list_value->end = range_end; - new_range_list_value->value = value; + internal_range_list->first_element = element; + internal_range_list->last_element = element; + } + else + { + if( internal_range_list->first_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid range list - missing first element.", + function ); - if( libcdata_internal_range_list_insert_value( - internal_range_list, - last_element, - new_range_list_value, - error ) != 1 ) + return( -1 ); + } + if( internal_range_list->last_element == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert range list value in range list.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid range list - missing last element.", function ); - goto on_error; + return( -1 ); } - new_range_list_value = NULL; - } - else if( value != NULL ) - { - if( range_list_value->value == NULL ) + if( range_list_element == NULL ) { - range_list_value->value = value; + if( libcdata_internal_range_list_set_first_element( + internal_range_list, + element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set first element.", + function ); + + return( -1 ); + } } else { - if( value_free_function == NULL ) + if( libcdata_list_element_get_next_element( + range_list_element, + &next_element, + error ) != 1 ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value free function.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from range list element.", function ); - goto on_error; + return( -1 ); } - if( value_merge_function == NULL ) + if( libcdata_list_element_set_elements( + element, + range_list_element, + next_element, + error ) != 1 ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value merge function.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous and next element of list element.", function ); - goto on_error; + return( -1 ); } - if( value_merge_function( - range_list_value->value, - value, - error ) != 1 ) + if( range_list_element == internal_range_list->last_element ) + { + internal_range_list->last_element = element; + } + else if( next_element == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to merge value.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid range list element - missing next element.", function ); - goto on_error; + return( -1 ); + } + else + { + if( libcdata_list_element_set_previous_element( + next_element, + element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous element of next element.", + function ); + + return( -1 ); + } } - if( value_free_function( - &value, + if( libcdata_list_element_set_next_element( + range_list_element, + element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to free value.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next element of range list element.", function ); - goto on_error; + return( -1 ); } } } + internal_range_list->number_of_elements += 1; + return( 1 ); +} -on_error: - if( next_range_list_value != NULL ) +/* Inserts the range list value in the range list after the range list element + * If range_list_element is NULL the value is inserted before the first element in the list + * Returns 1 if successful, or -1 on error + */ +int libcdata_internal_range_list_insert_value_after_element( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + libcdata_range_list_value_t *value, + libcerror_error_t **error ) +{ + libcdata_list_element_t *list_element = NULL; + static char *function = "libcdata_internal_range_list_insert_value_after_element"; + + if( internal_range_list == NULL ) { - libcdata_range_list_value_free( - &next_range_list_value, - value_free_function, - NULL ); + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); } - if( previous_range_list_value != NULL ) + if( libcdata_list_element_initialize( + &list_element, + error ) != 1 ) { - libcdata_range_list_value_free( - &previous_range_list_value, - value_free_function, - NULL ); + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create list element.", + function ); + + goto on_error; } - if( new_range_list_value != NULL ) + if( libcdata_list_element_set_value( + list_element, + (intptr_t *) value, + error ) != 1 ) { - libcdata_range_list_value_free( - &new_range_list_value, - value_free_function, + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set value in list element.", + function ); + + goto on_error; + } + if( libcdata_internal_range_list_insert_element_after_element( + internal_range_list, + range_list_element, + list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert element after range list element.", + function ); + + goto on_error; + } + list_element = NULL; + + return( 1 ); + +on_error: + if( list_element != NULL ) + { + libcdata_list_element_free( + &list_element, + NULL, NULL ); } return( -1 ); } -/* Inserts a range - * - * The values are merged using the value_merge_function. - * If the source value is NULL the merge function is not called. - * - * After a merge and on error the values are freed using - * the value_free_function - * +/* Merges the range into the range list element * Returns 1 if successful, or -1 on error */ -int libcdata_range_list_insert_range( - libcdata_range_list_t *range_list, +int libcdata_internal_range_list_merge_range( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, uint64_t range_start, - uint64_t range_size, + uint64_t range_end, intptr_t *value, - int (*value_free_function)( - intptr_t **value, - libcerror_error_t **error ), int (*value_merge_function)( intptr_t *destination_value, intptr_t *source_value, libcerror_error_t **error ), libcerror_error_t **error ) { - libcdata_internal_range_list_t *internal_range_list = NULL; - static char *function = "libcdata_range_list_insert_range"; - int result = 1; + libcdata_range_list_value_t *range_list_value = NULL; + static char *function = "libcdata_internal_range_list_merge_range"; - if( range_list == NULL ) + if( internal_range_list == NULL ) { libcerror_error_set( error, @@ -1850,91 +2242,273 @@ return( -1 ); } - internal_range_list = (libcdata_internal_range_list_t *) range_list; - -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_range_list->read_write_lock, + if( libcdata_list_element_get_value( + range_list_element, + (intptr_t **) &range_list_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from range list element.", function ); return( -1 ); } -#endif - if( libcdata_internal_range_list_insert_range( - internal_range_list, - range_start, - range_size, - value, - value_free_function, - value_merge_function, - error ) != 1 ) + if( range_list_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert range list into range list.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing range list value.", function ); - result = -1; + return( -1 ); } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( - internal_range_list->read_write_lock, + if( range_list_value->value != NULL ) + { + if( value_merge_function == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value merge function.", + function ); + + return( -1 ); + } + } + if( range_list_value->value == NULL ) + { + range_list_value->value = value; + } + else + { + if( value_merge_function( + range_list_value->value, + value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to merge value.", + function ); + + return( -1 ); + } + } + if( range_start < range_list_value->start ) + { + range_list_value->size += range_list_value->start - range_start; + range_list_value->start = range_start; + } + if( range_end > range_list_value->end ) + { + range_list_value->size += range_end - range_list_value->end; + range_list_value->end = range_end; + } + return( 1 ); +} + +/* Merges successive overlapping ranges + * Returns 1 if successful, or -1 on error + */ +int libcdata_internal_range_list_merge_overlapping_ranges( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + int (*value_merge_function)( + intptr_t *destination_value, + intptr_t *source_value, + libcerror_error_t **error ), + libcdata_range_list_t *backup_range_list, + libcerror_error_t **error ) +{ + libcdata_list_element_t *list_element = NULL; + libcdata_list_element_t *next_element = NULL; + libcdata_range_list_value_t *next_range_list_value = NULL; + static char *function = "libcdata_internal_range_list_merge_overlapping_ranges"; + int result = 0; + + if( internal_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_next_element( + range_list_element, + &next_element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from range list element.", function ); return( -1 ); } -#endif - return( result ); + while( next_element != NULL ) + { + list_element = next_element; + + if( libcdata_list_element_get_next_element( + list_element, + &next_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element.", + function ); + + return( -1 ); + } + if( libcdata_list_element_get_value( + list_element, + (intptr_t **) &next_range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from next element.", + function ); + + return( -1 ); + } + if( next_range_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing next range list value.", + function ); + + return( -1 ); + } + result = libcdata_internal_range_list_check_range_overlap( + internal_range_list, + range_list_element, + next_range_list_value->start, + next_range_list_value->end, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine if next range overlaps with range list element.", + function ); + + return( -1 ); + } + else if( result == 0 ) + { + break; + } + if( libcdata_internal_range_list_append_value( + (libcdata_internal_range_list_t *) backup_range_list, + next_range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to append value to backup range list.", + function ); + + return( -1 ); + } + if( libcdata_internal_range_list_remove_element( + internal_range_list, + list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove list element.", + function ); + + return( -1 ); + } + if( libcdata_list_element_free( + &list_element, + NULL, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free list element.", + function ); + + return( -1 ); + } + if( libcdata_internal_range_list_merge_range( + internal_range_list, + range_list_element, + next_range_list_value->start, + next_range_list_value->end, + next_range_list_value->value, + value_merge_function, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to merge next range with range list element.", + function ); + + return( -1 ); + } + } + return( 1 ); } -/* Inserts a range list - * - * The values are merged using the value_merge_function. - * If the source value is NULL the merge function is not called. - * - * After a merge and on error the values are freed using - * the value_free_function - * - * The values in the source_range_list are not affected. - * - * Returns 1 if successful, or -1 on error +/* Inserts a range by merging the range into the range list element and successive overlapping ranges + * Returns 1 if successful or -1 on error */ -int libcdata_range_list_insert_range_list( - libcdata_range_list_t *range_list, - libcdata_range_list_t *source_range_list, - int (*value_free_function)( - intptr_t **value, - libcerror_error_t **error ), +int libcdata_internal_range_list_insert_range_merge( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + uint64_t range_start, + uint64_t range_end, + intptr_t *value, int (*value_merge_function)( intptr_t *destination_value, intptr_t *source_value, libcerror_error_t **error ), + libcdata_range_list_t *backup_range_list, libcerror_error_t **error ) { - libcdata_internal_range_list_t *internal_range_list = NULL; - libcdata_list_element_t *source_list_element = NULL; - libcdata_range_list_value_t *source_range_list_value = NULL; - static char *function = "libcdata_range_list_insert_range_list"; - int element_index = 0; - int number_of_elements = 0; + libcdata_range_list_value_t *backup_range_list_value = NULL; + libcdata_range_list_value_t *range_list_value = NULL; + static char *function = "libcdata_internal_range_list_insert_range_merge"; - if( range_list == NULL ) + if( internal_range_list == NULL ) { libcerror_error_set( error, @@ -1945,155 +2519,114 @@ return( -1 ); } - internal_range_list = (libcdata_internal_range_list_t *) range_list; - - if( source_range_list == NULL ) + if( libcdata_list_element_get_value( + range_list_element, + (intptr_t **) &range_list_value, + error ) != 1 ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid source range list.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from range list element.", function ); - return( -1 ); + goto on_error; } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_range_list->read_write_lock, + if( libcdata_range_list_value_initialize( + &backup_range_list_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create backup range list value.", function ); - return( -1 ); + goto on_error; } -#endif - if( libcdata_range_list_get_number_of_elements( - source_range_list, - &number_of_elements, + backup_range_list_value->start = range_list_value->start; + backup_range_list_value->end = range_list_value->end; + backup_range_list_value->size = range_list_value->size; + + if( libcdata_internal_range_list_append_value( + (libcdata_internal_range_list_t *) backup_range_list, + backup_range_list_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve number of source list elements.", + "%s: unable to append value to backup range list.", function ); goto on_error; } - if( libcdata_range_list_get_first_element( - source_range_list, - &source_list_element, + backup_range_list_value = NULL; + + if( libcdata_internal_range_list_merge_range( + internal_range_list, + range_list_element, + range_start, + range_end, + value, + value_merge_function, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve first element from source list.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to merge range with range list element.", function ); goto on_error; } - for( element_index = 0; - element_index < number_of_elements; - element_index++ ) - { - if( libcdata_list_element_get_value( - source_list_element, - (intptr_t **) &source_range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from source list element: %d.", - function, - element_index ); - - goto on_error; - } - if( libcdata_internal_range_list_insert_range( - internal_range_list, - source_range_list_value->start, - source_range_list_value->size, - source_range_list_value->value, - value_free_function, - value_merge_function, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert source range list value: %d to range list.", - function, - element_index ); - - goto on_error; - } - if( libcdata_list_element_get_next_element( - source_list_element, - &source_list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next element from source list element: %d.", - function, - element_index ); - - goto on_error; - } - } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( - internal_range_list->read_write_lock, + if( libcdata_internal_range_list_merge_overlapping_ranges( + internal_range_list, + range_list_element, + value_merge_function, + backup_range_list, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", + "%s: unable to merge range list element with overlapping ranges.", function ); - return( -1 ); + goto on_error; } -#endif return( 1 ); on_error: -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_range_list->read_write_lock, - NULL ); -#endif + if( backup_range_list_value != NULL ) + { + libcdata_range_list_value_free( + &backup_range_list_value, + NULL, + NULL ); + } return( -1 ); } -/* Inserts the element in the range list after the range list element - * If range_list_element is NULL the element is inserted before the first element in the list - * Returns 1 if successful, or -1 on error +/* Reverts a previously merge of the range list element and successive overlapping ranges + * Returns 1 if successful or -1 on error */ -int libcdata_internal_range_list_insert_element( +int libcdata_internal_range_list_insert_range_revert_merge( libcdata_internal_range_list_t *internal_range_list, libcdata_list_element_t *range_list_element, - libcdata_list_element_t *element, + libcdata_range_list_t *backup_range_list, libcerror_error_t **error ) { - libcdata_list_element_t *next_element = NULL; - libcdata_list_element_t *previous_element = NULL; - static char *function = "libcdata_internal_range_list_insert_element"; + libcdata_internal_range_list_t *internal_backup_range_list = NULL; + libcdata_list_element_t *backup_range_list_element = NULL; + libcdata_range_list_value_t *backup_range_list_value = NULL; + libcdata_range_list_value_t *range_list_value = NULL; + static char *function = "libcdata_internal_range_list_insert_range_revert_merge"; if( internal_range_list == NULL ) { @@ -2104,201 +2637,393 @@ "%s: invalid range list.", function ); - return( -1 ); + return( -1 ); + } + if( backup_range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid backup range list.", + function ); + + return( -1 ); + } + internal_backup_range_list = (libcdata_internal_range_list_t *) backup_range_list; + + if( internal_backup_range_list->first_element == NULL ) + { + return( 1 ); } - if( libcdata_list_element_get_elements( - element, - &previous_element, - &next_element, + if( libcdata_list_element_get_value( + internal_backup_range_list->first_element, + (intptr_t **) &backup_range_list_value, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous and next element from list element.", + "%s: unable to retrieve value from first backup range list element.", function ); return( -1 ); } - if( ( previous_element != NULL ) - || ( next_element != NULL ) ) + if( libcdata_list_element_get_value( + range_list_element, + (intptr_t **) &range_list_value, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: list element already part of a list.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from range list element.", function ); return( -1 ); } - if( internal_range_list->number_of_elements == 0 ) + range_list_value->start = backup_range_list_value->start; + range_list_value->end = backup_range_list_value->end; + range_list_value->size = backup_range_list_value->size; + + while( internal_backup_range_list->first_element != NULL ) { - if( internal_range_list->first_element != NULL ) + if( libcdata_list_element_get_next_element( + internal_backup_range_list->first_element, + &backup_range_list_element, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid range list - first element already set.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from first backup range list element.", function ); return( -1 ); } - if( internal_range_list->last_element != NULL ) + if( backup_range_list_element == NULL ) + { + break; + } + if( libcdata_internal_range_list_remove_element( + internal_backup_range_list, + backup_range_list_element, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid range list - last element already set.", + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove backup range list element.", function ); return( -1 ); } - internal_range_list->first_element = element; - internal_range_list->last_element = element; - } - else - { - if( internal_range_list->first_element == NULL ) + if( libcdata_internal_range_list_insert_element_after_element( + internal_range_list, + range_list_element, + backup_range_list_element, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid range list - missing first element.", + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert element after range list element.", function ); return( -1 ); } - if( internal_range_list->last_element == NULL ) + backup_range_list_element = NULL; + } + return( 1 ); +} + +/* Inserts a range + * + * The values are merged using the value_merge_function. + * If the source value is NULL the merge function is not called. + * + * After a merge and on error the values are freed using + * the value_free_function + * + * Returns 1 if successful, 0 if the range was merged or -1 on error + */ +int libcdata_range_list_insert_range( + libcdata_range_list_t *range_list, + uint64_t range_start, + uint64_t range_size, + intptr_t *value, + int (*value_free_function)( + intptr_t **value, + libcerror_error_t **error ), + int (*value_merge_function)( + intptr_t *destination_value, + intptr_t *source_value, + libcerror_error_t **error ), + libcerror_error_t **error ) +{ + libcdata_internal_range_list_t *internal_range_list = NULL; + libcdata_list_element_t *list_element = NULL; + libcdata_list_element_t *new_element = NULL; + libcdata_range_list_t *backup_range_list = NULL; + static char *function = "libcdata_range_list_insert_range"; + uint64_t range_end = 0; + int element_index = 0; + int result = 1; + + if( range_list == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list.", + function ); + + return( -1 ); + } + internal_range_list = (libcdata_internal_range_list_t *) range_list; + + if( range_start > (uint64_t) INT64_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid range start value exceeds maximum.", + function ); + + return( -1 ); + } + if( range_size > (uint64_t) INT64_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid range size value exceeds maximum.", + function ); + + return( -1 ); + } + range_end = range_start + range_size; + + if( range_end < range_start ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid range end value out of bounds.", + function ); + + return( -1 ); + } + if( libcdata_range_list_initialize( + &backup_range_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create backup range list.", + function ); + + return( -1 ); + } +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_write( + internal_range_list->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + + libcdata_range_list_free( + &backup_range_list, + NULL, + NULL ); + + return( -1 ); + } +#endif + if( libcdata_internal_range_list_insert_range_find_element( + internal_range_list, + range_start, + range_end, + &element_index, + &list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to find element in list.", + function ); + + result = -1; + } + if( result == 1 ) + { + result = libcdata_internal_range_list_check_range_overlap( + internal_range_list, + list_element, + range_start, + range_end, + error ); + + if( result == -1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid range list - missing last element.", - function ); - - return( -1 ); - } - if( range_list_element == NULL ) - { - if( libcdata_internal_range_list_set_first_element( - internal_range_list, - element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set first element.", - function ); + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine if range overlaps with range list element: %d.", + function, + element_index ); - return( -1 ); - } + result = -1; } - else - { - if( libcdata_list_element_get_next_element( - range_list_element, - &next_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next element from range list element.", - function ); - - return( -1 ); - } - if( libcdata_list_element_set_elements( - element, - range_list_element, - next_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous and next element of list element.", - function ); - - return( -1 ); - } - if( range_list_element == internal_range_list->last_element ) - { - internal_range_list->last_element = element; - } - else if( next_element == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid range list element - missing next element.", - function ); + } + if( result == 0 ) + { + result = 1; - return( -1 ); - } - else - { - if( libcdata_list_element_set_previous_element( - next_element, - element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous element of next element.", - function ); + if( libcdata_internal_range_list_insert_range_before_element( + internal_range_list, + list_element, + range_start, + range_end, + value, + &new_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert range before range list element.", + function ); - return( -1 ); - } - } - if( libcdata_list_element_set_next_element( - range_list_element, - element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next element of range list element.", - function ); + result = -1; + } + } + else if( result != -1 ) + { + result = 0; - return( -1 ); - } + if( libcdata_internal_range_list_insert_range_merge( + internal_range_list, + list_element, + range_start, + range_end, + value, + value_merge_function, + backup_range_list, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to merge range with list element: %d.", + function, + element_index ); + + result = -1; } } - internal_range_list->number_of_elements++; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_release_for_write( + internal_range_list->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for writing.", + function ); + + goto on_error; + } +#endif + libcdata_range_list_free( + &backup_range_list, + value_free_function, + NULL ); - return( 1 ); + return( result ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + if( result == 0 ) + { + libcdata_internal_range_list_insert_range_revert_merge( + internal_range_list, + list_element, + backup_range_list, + NULL ); + } + else if( result == 1 ) + { + libcdata_internal_range_list_remove_range_value( + internal_range_list, + &new_element, + NULL, + NULL ); + } + libcdata_range_list_free( + &backup_range_list, + NULL, + NULL ); + + return( -1 ); +#endif } -/* Inserts the range list value in the range list after the range list element - * If range_list_element is NULL the value is inserted before the first element in the list +/* Inserts a range list + * + * The values are merged using the value_merge_function. + * If the source value is NULL the merge function is not called. + * + * After a merge and on error the values are freed using + * the value_free_function + * + * The values in the source_range_list are not affected. + * * Returns 1 if successful, or -1 on error */ -int libcdata_internal_range_list_insert_value( - libcdata_internal_range_list_t *internal_range_list, - libcdata_list_element_t *range_list_element, - libcdata_range_list_value_t *value, +int libcdata_range_list_insert_range_list( + libcdata_range_list_t *range_list, + libcdata_range_list_t *source_range_list, + int (*value_free_function)( + intptr_t **value, + libcerror_error_t **error ), + int (*value_merge_function)( + intptr_t *destination_value, + intptr_t *source_value, + libcerror_error_t **error ), libcerror_error_t **error ) { - libcdata_list_element_t *list_element = NULL; - static char *function = "libcdata_internal_range_list_insert_value"; + libcdata_list_element_t *source_list_element = NULL; + libcdata_range_list_value_t *source_range_list_value = NULL; + static char *function = "libcdata_range_list_insert_range_list"; + int element_index = 0; + int number_of_elements = 0; + int result = 0; - if( internal_range_list == NULL ) + if( range_list == NULL ) { libcerror_error_set( error, @@ -2309,74 +3034,130 @@ return( -1 ); } - if( libcdata_list_element_initialize( - &list_element, - error ) != 1 ) + if( source_range_list == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create list element.", + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid source range list.", function ); - goto on_error; + return( -1 ); } - if( libcdata_list_element_set_value( - list_element, - (intptr_t *) value, + if( libcdata_range_list_get_number_of_elements( + source_range_list, + &number_of_elements, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set value in list element.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of source list elements.", function ); - goto on_error; + return( -1 ); } - if( libcdata_internal_range_list_insert_element( - internal_range_list, - range_list_element, - list_element, + if( libcdata_range_list_get_first_element( + source_range_list, + &source_list_element, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert list element in range list.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve first element from source list.", function ); - goto on_error; + return( -1 ); } - list_element = NULL; + for( element_index = 0; + element_index < number_of_elements; + element_index++ ) + { + if( libcdata_list_element_get_value( + source_list_element, + (intptr_t **) &source_range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from source list element: %d.", + function, + element_index ); - return( 1 ); + return( -1 ); + } + result = libcdata_range_list_insert_range( + range_list, + source_range_list_value->start, + source_range_list_value->size, + source_range_list_value->value, + value_free_function, + value_merge_function, + error ); -on_error: - if( list_element != NULL ) - { - libcdata_list_element_free( - &list_element, - NULL, - NULL ); + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert source range list value: %d to range list.", + function, + element_index ); + + return( -1 ); + } + if( libcdata_list_element_get_next_element( + source_list_element, + &source_list_element, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next element from source list element: %d.", + function, + element_index ); + + return( -1 ); + } } - return( -1 ); + return( 1 ); } -/* Removes an element from the range list +/* Shrinks a range + * + * A range that either overlaps the start or the end of the range list element + * is removed by shrining the range of the range list element. + * * Returns 1 if successful, or -1 on error */ -int libcdata_internal_range_list_remove_element( +int libcdata_internal_range_list_remove_shrink_range( libcdata_internal_range_list_t *internal_range_list, - libcdata_list_element_t *element, + libcdata_list_element_t *range_list_element, + libcdata_range_list_value_t *range_list_value, + uint64_t range_start, + uint64_t range_end, + int (*value_free_function)( + intptr_t **value, + libcerror_error_t **error ), + int (*value_split_function)( + intptr_t **destination_value, + intptr_t *source_value, + uint64_t split_range_offset, + libcerror_error_t **error ), libcerror_error_t **error ) { - libcdata_list_element_t *next_element = NULL; - libcdata_list_element_t *previous_element = NULL; - static char *function = "libcdata_internal_range_list_remove_element"; + intptr_t *split_value = NULL; + static char *function = "libcdata_internal_range_list_remove_shrink_range"; + uint64_t split_offset = 0; if( internal_range_list == NULL ) { @@ -2389,99 +3170,137 @@ return( -1 ); } - if( libcdata_list_element_get_elements( - element, - &previous_element, - &next_element, - error ) != 1 ) + if( range_list_element == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list element.", + function ); + + return( -1 ); + } + if( range_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list value.", + function ); + + return( -1 ); + } + if( ( range_start > range_list_value->start ) + && ( range_end < range_list_value->end ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous and next element from list element.", + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid range value out of bounds.", function ); return( -1 ); } - if( element == internal_range_list->first_element ) + if( range_list_value->value != NULL ) + { + if( value_free_function == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value free function.", + function ); + + return( -1 ); + } + if( value_split_function == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value split function.", + function ); + + return( -1 ); + } + } + if( range_start <= range_list_value->start ) { - internal_range_list->first_element = next_element; + split_offset = range_end; } - if( element == internal_range_list->last_element ) + else { - internal_range_list->last_element = previous_element; + split_offset = range_start; } - if( next_element != NULL ) + if( range_list_value->value != NULL ) { - if( libcdata_list_element_set_previous_element( - next_element, - previous_element, + if( value_split_function( + &split_value, + range_list_value->value, + split_offset, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous element of next element.", - function ); + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to split value range offset: %" PRIu64 ".", + function, + split_offset ); - return( -1 ); + goto on_error; } - } - if( previous_element != NULL ) - { - if( libcdata_list_element_set_next_element( - previous_element, - next_element, + if( value_free_function( + &( range_list_value->value ), error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next element of previous element.", + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to free value.", function ); - return( -1 ); + range_list_value->value = split_value; + + goto on_error; } + range_list_value->value = split_value; } - if( libcdata_list_element_set_elements( - element, - NULL, - NULL, - error ) != 1 ) + if( split_offset > range_list_value->start ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous and next element of list element.", - function ); - - return( -1 ); + range_list_value->start = split_offset; + range_list_value->size = range_list_value->end - split_offset; + } + else + { + range_list_value->end = split_offset; + range_list_value->size = split_offset - range_list_value->start; } - internal_range_list->number_of_elements--; - return( 1 ); + +on_error: + return( -1 ); } -/* Removes a range - * - * The values are split using the value_merge_function. - * If the source value is NULL the split function is not called. - * On return destination_value of the value_merge_function - * should contain data greater equal to the split_range_offset. +/* Splits a range * - * After a split and on error the values are freed using - * the value_free_function + * A range that either overlaps a part of the range list element + * is removed by splitting the range of the range list element. * * Returns 1 if successful, or -1 on error */ -int libcdata_internal_range_list_remove_range( +int libcdata_internal_range_list_remove_split_range( libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + libcdata_range_list_value_t *range_list_value, uint64_t range_start, - uint64_t range_size, + uint64_t range_end, int (*value_free_function)( intptr_t **value, libcerror_error_t **error ), @@ -2492,14 +3311,9 @@ libcerror_error_t **error ), libcerror_error_t **error ) { - libcdata_list_element_t *list_element = NULL; - libcdata_range_list_value_t *range_list_value = NULL; libcdata_range_list_value_t *split_range_list_value = NULL; - intptr_t *split_value = NULL; - static char *function = "libcdata_internal_range_list_remove_range"; - uint64_t next_range_start = 0; - uint64_t range_end = 0; - int result = 0; + static char *function = "libcdata_internal_range_list_remove_split_range"; + uint64_t split_offset = 0; if( internal_range_list == NULL ) { @@ -2512,400 +3326,152 @@ return( -1 ); } - if( range_start > (uint64_t) INT64_MAX ) + if( range_list_element == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid range start value exceeds maximum.", + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list element.", function ); return( -1 ); } - if( range_size > (uint64_t) INT64_MAX ) + if( range_list_value == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid range size value exceeds maximum.", + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list value.", function ); return( -1 ); } - range_end = range_start + range_size; - - if( range_end < range_start ) + if( ( range_start <= range_list_value->start ) + || ( range_end >= range_list_value->end ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid range end value out of bounds.", + "%s: invalid range value out of bounds.", function ); - goto on_error; + return( -1 ); } - while( range_start < range_end ) + if( range_list_value->value != NULL ) { - result = libcdata_internal_range_list_get_element_at_offset( - internal_range_list, - range_start, - &list_element, - error ); - - if( result == -1 ) + if( value_free_function == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve list element for range offset: %" PRIu64 ".", - function, - range_start ); - - goto on_error; - } - else if( result == 0 ) - { - /* The specified range is not defined in the range list - */ - if( list_element == NULL ) - { - break; - } - if( libcdata_list_element_get_value( - list_element, - (intptr_t **) &range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from next list element.", - function ); - - goto on_error; - } - if( range_list_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing next range list value element.", - function ); - - goto on_error; - } - /* The specified range is not defined in the range list - */ - if( range_list_value->start >= range_end ) - { - break; - } - range_start = range_list_value->start; - } - else - { - if( libcdata_list_element_get_value( - list_element, - (intptr_t **) &range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value from list element for range offset: %" PRIu64 ".", - function, - range_start ); - - goto on_error; - } - if( range_list_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing range list value element for range offset: %" PRIu64 ".", - function, - range_start ); - - goto on_error; - } - } - next_range_start = range_list_value->end; - - if( range_list_value->value != NULL ) - { - if( value_free_function == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value free function.", - function ); - - goto on_error; - } - if( value_split_function == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value split function.", - function ); + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value free function.", + function ); - goto on_error; - } + return( -1 ); } - if( range_list_value->start == range_start ) + if( value_split_function == NULL ) { - if( range_list_value->end <= range_end ) - { - /* If the range marked for removal overlaps with the current range, - * remove the current range entirely. - */ - if( libcdata_internal_range_list_remove_element( - internal_range_list, - list_element, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove list element.", - function ); - - goto on_error; - } - if( libcdata_list_element_free( - &list_element, - NULL, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free list element.", - function ); - - libcdata_range_list_value_free( - &range_list_value, - value_free_function, - NULL ); - - goto on_error; - } - if( libcdata_range_list_value_free( - &range_list_value, - value_free_function, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free range list value.", - function ); - - goto on_error; - } - } - else - { - /* If the range marked for removal is smaller than the current range, - * split off of the part that remains after removal and remove the rest. - */ - if( range_list_value->value != NULL ) - { - if( value_split_function( - &split_value, - range_list_value->value, - range_end, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to split value at range offset: %" PRIu64 ".", - function, - range_end ); - - goto on_error; - } - if( value_free_function( - &( range_list_value->value ), - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to free value.", - function ); - - range_list_value->value = split_value; + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value split function.", + function ); - goto on_error; - } - range_list_value->value = split_value; - } - range_list_value->start = range_end; - range_list_value->size = range_list_value->end - range_list_value->start; - } + return( -1 ); } - else - { - if( range_list_value->end <= range_end ) - { - if( range_list_value->value != NULL ) - { - if( value_split_function( - &split_value, - range_list_value->value, - range_start, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to split value at range offset: %" PRIu64 ".", - function, - range_start ); - - goto on_error; - } - if( value_free_function( - &split_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to free value.", - function ); + } + split_offset = range_end; - goto on_error; - } - } - range_list_value->end = range_start; - range_list_value->size = range_list_value->end - range_list_value->start; - } - else - { - /* If the range marked for removal is smaller than the current range, - * split off of the part that remains after removal and remove the rest. - */ - if( libcdata_range_list_value_initialize( - &split_range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create range list value.", - function ); + if( libcdata_range_list_value_initialize( + &split_range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create range list value.", + function ); - goto on_error; - } - if( split_range_list_value == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing range list value.", - function ); + goto on_error; + } + if( split_range_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing range list value.", + function ); - goto on_error; - } - split_range_list_value->start = range_end; - split_range_list_value->size = range_list_value->end - range_end; - split_range_list_value->end = range_list_value->end; + goto on_error; + } + if( range_list_value->value != NULL ) + { + if( value_split_function( + &( split_range_list_value->value ), + range_list_value->value, + split_offset, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to split value at range offset: %" PRIu64 ".", + function, + split_offset ); - if( range_list_value->value != NULL ) - { - if( value_split_function( - &( split_range_list_value->value ), - range_list_value->value, - range_end, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to split value at range offset: %" PRIu64 ".", - function, - range_end ); + goto on_error; + } + } + split_range_list_value->start = split_offset; + split_range_list_value->size = range_list_value->end - split_offset; + split_range_list_value->end = range_list_value->end; - goto on_error; - } - if( value_split_function( - &split_value, - range_list_value->value, - range_start, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to split value at range offset: %" PRIu64 ".", - function, - range_start ); + range_list_value->size = split_offset - range_list_value->start; + range_list_value->end = split_offset; - goto on_error; - } - if( value_free_function( - &split_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to free value.", - function ); + if( libcdata_internal_range_list_insert_value_after_element( + internal_range_list, + range_list_element, + split_range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert range list value after range list element.", + function ); - goto on_error; - } - } - range_list_value->size = range_start - range_list_value->start; - range_list_value->end = range_start; + goto on_error; + } + split_range_list_value = NULL; - if( libcdata_internal_range_list_insert_value( - internal_range_list, - list_element, - split_range_list_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert range list value in range list.", - function ); + if( libcdata_internal_range_list_remove_shrink_range( + internal_range_list, + range_list_element, + range_list_value, + range_start, + range_end, + value_free_function, + value_split_function, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to shrink range.", + function ); - goto on_error; - } - split_range_list_value = NULL; - } - } - range_start = next_range_start; + goto on_error; } return( 1 ); @@ -2947,7 +3513,11 @@ libcerror_error_t **error ) { libcdata_internal_range_list_t *internal_range_list = NULL; + libcdata_list_element_t *list_element = NULL; + libcdata_range_list_value_t *range_list_value = NULL; static char *function = "libcdata_range_list_remove_range"; + uint64_t next_range_start = 0; + uint64_t range_end = 0; int result = 1; if( range_list == NULL ) @@ -2963,6 +3533,41 @@ } internal_range_list = (libcdata_internal_range_list_t *) range_list; + if( range_start > (uint64_t) INT64_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid range start value exceeds maximum.", + function ); + + return( -1 ); + } + if( range_size > (uint64_t) INT64_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid range size value exceeds maximum.", + function ); + + return( -1 ); + } + range_end = range_start + range_size; + + if( range_end < range_start ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid range end value out of bounds.", + function ); + + return( -1 ); + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_grab_for_write( internal_range_list->read_write_lock, @@ -2978,22 +3583,139 @@ return( -1 ); } #endif - if( libcdata_internal_range_list_remove_range( - internal_range_list, - range_start, - range_size, - value_free_function, - value_split_function, - error ) != 1 ) + while( range_start < range_end ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, - "%s: unable to remove range.", - function ); + result = libcdata_internal_range_list_get_element_at_offset( + internal_range_list, + range_start, + &list_element, + error ); - result = -1; + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve list element for range offset: %" PRIu64 ".", + function, + range_start ); + + goto on_error; + } + else if( result == 0 ) + { + /* The specified range is not defined in the range list + */ + if( list_element == NULL ) + { + break; + } + } + if( libcdata_list_element_get_value( + list_element, + (intptr_t **) &range_list_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from list element for range offset: %" PRIu64 ".", + function, + range_start ); + + goto on_error; + } + if( range_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing range list value element for range offset: %" PRIu64 ".", + function, + range_start ); + + goto on_error; + } + if( result == 0 ) + { + /* The specified range is not defined in the range list + */ + if( range_list_value->start >= range_end ) + { + break; + } + range_start = range_list_value->start; + } + next_range_start = range_list_value->end; + + if( ( range_start <= range_list_value->start ) + && ( range_end >= range_list_value->end ) ) + { + if( libcdata_internal_range_list_remove_range_value( + internal_range_list, + &list_element, + value_free_function, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_REMOVE_FAILED, + "%s: unable to remove range value.", + function ); + + goto on_error; + } + } + else if( ( range_start > range_list_value->start ) + && ( range_end < range_list_value->end ) ) + { + if( libcdata_internal_range_list_remove_split_range( + internal_range_list, + list_element, + range_list_value, + range_start, + range_end, + value_free_function, + value_split_function, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to split range.", + function ); + + goto on_error; + } + } + else + { + if( libcdata_internal_range_list_remove_shrink_range( + internal_range_list, + list_element, + range_list_value, + range_start, + range_end, + value_free_function, + value_split_function, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to shrink range.", + function ); + + goto on_error; + } + } + range_start = next_range_start; } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( @@ -3011,6 +3733,14 @@ } #endif return( result ); + +on_error: +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcthreads_read_write_lock_release_for_write( + internal_range_list->read_write_lock, + NULL ); +#endif + return( -1 ); } /* Retrieves a specific element from the range list @@ -3022,7 +3752,9 @@ libcdata_list_element_t **element, libcerror_error_t **error ) { - static char *function = "libcdata_internal_range_list_get_element_by_index"; + libcdata_list_element_t *current_element = NULL; + static char *function = "libcdata_internal_range_list_get_element_by_index"; + int current_element_index = 0; if( internal_range_list == NULL ) { @@ -3058,18 +3790,21 @@ return( -1 ); } - if( ( internal_range_list->current_element != NULL ) - && ( internal_range_list->current_element_index != element_index ) ) + current_element = internal_range_list->current_element; + current_element_index = internal_range_list->current_element_index; + + if( ( current_element != NULL ) + && ( current_element_index != element_index ) ) { - if( element_index < internal_range_list->current_element_index ) + if( element_index < current_element_index ) { - if( ( internal_range_list->current_element_index - element_index ) < ( internal_range_list->number_of_elements / 2 ) ) + if( ( current_element_index - element_index ) < ( internal_range_list->number_of_elements / 2 ) ) { - while( internal_range_list->current_element_index > element_index ) + while( current_element_index > element_index ) { if( libcdata_list_element_get_previous_element( - internal_range_list->current_element, - &( internal_range_list->current_element ), + current_element, + ¤t_element, error ) != 1 ) { libcerror_error_set( @@ -3078,23 +3813,23 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve previous element from list element: %d.", function, - internal_range_list->current_element_index ); + current_element_index ); return( -1 ); } - internal_range_list->current_element_index--; + current_element_index--; } } } else { - if( ( element_index - internal_range_list->current_element_index ) < ( internal_range_list->number_of_elements / 2 ) ) + if( ( element_index - current_element_index ) < ( internal_range_list->number_of_elements / 2 ) ) { - while( internal_range_list->current_element_index < element_index ) + while( current_element_index < element_index ) { if( libcdata_list_element_get_next_element( - internal_range_list->current_element, - &( internal_range_list->current_element ), + current_element, + ¤t_element, error ) != 1 ) { libcerror_error_set( @@ -3103,29 +3838,29 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve next element from list element: %d.", function, - internal_range_list->current_element_index ); + current_element_index ); return( -1 ); } - internal_range_list->current_element_index++; + current_element_index++; } } } } - if( ( internal_range_list->current_element == NULL ) - || ( internal_range_list->current_element_index != element_index ) ) + if( ( current_element == NULL ) + || ( current_element_index != element_index ) ) { if( element_index < ( internal_range_list->number_of_elements / 2 ) ) { - internal_range_list->current_element = internal_range_list->first_element; + current_element = internal_range_list->first_element; - for( internal_range_list->current_element_index = 0; - internal_range_list->current_element_index < element_index; - internal_range_list->current_element_index++ ) + for( current_element_index = 0; + current_element_index < element_index; + current_element_index++ ) { if( libcdata_list_element_get_next_element( - internal_range_list->current_element, - &( internal_range_list->current_element ), + current_element, + ¤t_element, error ) != 1 ) { libcerror_error_set( @@ -3134,7 +3869,7 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve next element from list element: %d.", function, - internal_range_list->current_element_index ); + current_element_index ); return( -1 ); } @@ -3142,15 +3877,15 @@ } else { - internal_range_list->current_element = internal_range_list->last_element; + current_element = internal_range_list->last_element; - for( internal_range_list->current_element_index = ( internal_range_list->number_of_elements - 1 ); - internal_range_list->current_element_index > element_index; - internal_range_list->current_element_index-- ) + for( current_element_index = ( internal_range_list->number_of_elements - 1 ); + current_element_index > element_index; + current_element_index-- ) { if( libcdata_list_element_get_previous_element( - internal_range_list->current_element, - &( internal_range_list->current_element ), + current_element, + ¤t_element, error ) != 1 ) { libcerror_error_set( @@ -3159,14 +3894,19 @@ LIBCERROR_RUNTIME_ERROR_GET_FAILED, "%s: unable to retrieve previous element from list element: %d.", function, - internal_range_list->current_element_index ); + current_element_index ); return( -1 ); } } } } - *element = internal_range_list->current_element; + if( current_element != NULL ) + { + internal_range_list->current_element = current_element; + internal_range_list->current_element_index = current_element_index; + } + *element = current_element; return( 1 ); } diff -Nru libfsapfs-20181215/libcdata/libcdata_range_list.h libfsapfs-20190210/libcdata/libcdata_range_list.h --- libfsapfs-20181215/libcdata/libcdata_range_list.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_range_list.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Range list * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -79,8 +79,9 @@ libcerror_error_t **error ), libcerror_error_t **error ); -int libcdata_internal_range_list_empty( +int libcdata_internal_range_list_free_element( libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t **range_list_element, int (*value_free_function)( intptr_t **value, libcerror_error_t **error ), @@ -113,6 +114,7 @@ int *number_of_elements, libcerror_error_t **error ); +LIBCDATA_EXTERN \ int libcdata_range_list_get_first_element( libcdata_range_list_t *range_list, libcdata_list_element_t **element, @@ -123,38 +125,115 @@ libcdata_list_element_t *element, libcerror_error_t **error ); +LIBCDATA_EXTERN \ +int libcdata_range_list_get_last_element( + libcdata_range_list_t *range_list, + libcdata_list_element_t **element, + libcerror_error_t **error ); + int libcdata_internal_range_list_set_last_element( libcdata_internal_range_list_t *internal_range_list, libcdata_list_element_t *element, libcerror_error_t **error ); -int libcdata_range_list_get_last_element( - libcdata_range_list_t *range_list, +int libcdata_internal_range_list_append_element( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *element, + libcerror_error_t **error ); + +int libcdata_internal_range_list_append_value( + libcdata_internal_range_list_t *internal_range_list, + libcdata_range_list_value_t *value, + libcerror_error_t **error ); + +int libcdata_internal_range_list_remove_element( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + libcerror_error_t **error ); + +int libcdata_internal_range_list_remove_range_value( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t **range_list_element, + int (*value_free_function)( + intptr_t **value, + libcerror_error_t **error ), + libcerror_error_t **error ); + +int libcdata_internal_range_list_insert_range_find_element( + libcdata_internal_range_list_t *internal_range_list, + uint64_t range_start, + uint64_t range_end, + int *element_index, libcdata_list_element_t **element, libcerror_error_t **error ); -int libcdata_internal_range_list_append_element( +int libcdata_internal_range_list_check_range_overlap( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + uint64_t range_start, + uint64_t range_end, + libcerror_error_t **error ); + +int libcdata_internal_range_list_insert_range_before_element( libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + uint64_t range_start, + uint64_t range_end, + intptr_t *value, + libcdata_list_element_t **new_range_list_element, + libcerror_error_t **error ); + +int libcdata_internal_range_list_insert_element_after_element( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, libcdata_list_element_t *element, libcerror_error_t **error ); -int libcdata_internal_range_list_append_value( +int libcdata_internal_range_list_insert_value_after_element( libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, libcdata_range_list_value_t *value, libcerror_error_t **error ); -int libcdata_internal_range_list_insert_range( +int libcdata_internal_range_list_merge_range( libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, uint64_t range_start, - uint64_t range_size, + uint64_t range_end, intptr_t *value, - int (*value_free_function)( - intptr_t **value, + int (*value_merge_function)( + intptr_t *destination_value, + intptr_t *source_value, libcerror_error_t **error ), + libcerror_error_t **error ); + +int libcdata_internal_range_list_merge_overlapping_ranges( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + int (*value_merge_function)( + intptr_t *destination_value, + intptr_t *source_value, + libcerror_error_t **error ), + libcdata_range_list_t *backup_range_list, + libcerror_error_t **error ); + +int libcdata_internal_range_list_insert_range_merge( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + uint64_t range_start, + uint64_t range_end, + intptr_t *value, int (*value_merge_function)( intptr_t *destination_value, intptr_t *source_value, libcerror_error_t **error ), + libcdata_range_list_t *backup_range_list, + libcerror_error_t **error ); + +int libcdata_internal_range_list_insert_range_revert_merge( + libcdata_internal_range_list_t *internal_range_list, + libcdata_list_element_t *range_list_element, + libcdata_range_list_t *backup_range_list, libcerror_error_t **error ); LIBCDATA_EXTERN \ @@ -185,27 +264,28 @@ libcerror_error_t **error ), libcerror_error_t **error ); -int libcdata_internal_range_list_insert_element( +int libcdata_internal_range_list_remove_shrink_range( libcdata_internal_range_list_t *internal_range_list, libcdata_list_element_t *range_list_element, - libcdata_list_element_t *element, + libcdata_range_list_value_t *range_list_value, + uint64_t range_start, + uint64_t range_end, + int (*value_free_function)( + intptr_t **value, + libcerror_error_t **error ), + int (*value_split_function)( + intptr_t **destination_value, + intptr_t *source_value, + uint64_t split_range_offset, + libcerror_error_t **error ), libcerror_error_t **error ); -int libcdata_internal_range_list_insert_value( +int libcdata_internal_range_list_remove_split_range( libcdata_internal_range_list_t *internal_range_list, libcdata_list_element_t *range_list_element, - libcdata_range_list_value_t *value, - libcerror_error_t **error ); - -int libcdata_internal_range_list_remove_element( - libcdata_internal_range_list_t *internal_range_list, - libcdata_list_element_t *element, - libcerror_error_t **error ); - -int libcdata_internal_range_list_remove_range( - libcdata_internal_range_list_t *internal_range_list, + libcdata_range_list_value_t *range_list_value, uint64_t range_start, - uint64_t range_size, + uint64_t range_end, int (*value_free_function)( intptr_t **value, libcerror_error_t **error ), diff -Nru libfsapfs-20181215/libcdata/libcdata_range_list_value.c libfsapfs-20190210/libcdata/libcdata_range_list_value.c --- libfsapfs-20181215/libcdata/libcdata_range_list_value.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_range_list_value.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Range list value * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -381,3 +381,49 @@ return( 1 ); } +/* Checks if the range overlaps with the range list value + * Returns 1 if the range overlaps, 0 if not or -1 on error + */ +int libcdata_range_list_value_check_range_overlap( + libcdata_range_list_value_t *range_list_value, + uint64_t range_start, + uint64_t range_end, + libcerror_error_t **error ) +{ + static char *function = "libcdata_range_list_value_check_range_overlap"; + + if( range_list_value == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid range list value.", + function ); + + return( -1 ); + } + /* Check if the range overlaps the existing range entirely + */ + if( ( range_start < range_list_value->start ) + && ( range_end > range_list_value->end ) ) + { + return( 1 ); + } + /* Check if the range overlaps at the end of the existing range + */ + if( ( range_start >= range_list_value->start ) + && ( range_start <= range_list_value->end ) ) + { + return( 1 ); + } + /* Check if the range overlaps at the beginning of the existing range + */ + if( ( range_end >= range_list_value->start ) + && ( range_end <= range_list_value->end ) ) + { + return( 1 ); + } + return( 0 ); +} + diff -Nru libfsapfs-20181215/libcdata/libcdata_range_list_value.h libfsapfs-20190210/libcdata/libcdata_range_list_value.h --- libfsapfs-20181215/libcdata/libcdata_range_list_value.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_range_list_value.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Range list value * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -86,6 +86,12 @@ libcerror_error_t **error ), libcerror_error_t **error ); +int libcdata_range_list_value_check_range_overlap( + libcdata_range_list_value_t *range_list_value, + uint64_t range_start, + uint64_t range_end, + libcerror_error_t **error ); + #if defined( __cplusplus ) } #endif diff -Nru libfsapfs-20181215/libcdata/libcdata_support.c libfsapfs-20190210/libcdata/libcdata_support.c --- libfsapfs-20181215/libcdata/libcdata_support.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_support.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_support.h libfsapfs-20190210/libcdata/libcdata_support.h --- libfsapfs-20181215/libcdata/libcdata_support.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_support.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_tree_node.c libfsapfs-20190210/libcdata/libcdata_tree_node.c --- libfsapfs-20181215/libcdata/libcdata_tree_node.c 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_tree_node.c 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Tree functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -103,7 +103,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -314,7 +314,7 @@ { internal_node->last_sub_node = next_node; } - internal_node->number_of_sub_nodes--; + internal_node->number_of_sub_nodes -= 1; if( next_node != NULL ) { @@ -472,45 +472,45 @@ } internal_source_node = (libcdata_internal_tree_node_t *) source_node; - if( libcdata_tree_node_initialize( - (libcdata_tree_node_t **) &internal_destination_node, +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_read( + internal_source_node->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create destination tree node.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for reading.", function ); return( -1 ); } - if( internal_destination_node == NULL ) +#endif + if( libcdata_tree_node_initialize( + (libcdata_tree_node_t **) &internal_destination_node, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: missing destination tree node.", + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create destination tree node.", function ); - return( -1 ); + goto on_error; } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_read( - internal_source_node->read_write_lock, - error ) != 1 ) + if( internal_destination_node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for reading.", + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing destination tree node.", function ); - return( -1 ); + goto on_error; } -#endif if( value_clone_function( &( internal_destination_node->value ), internal_source_node->value, @@ -723,6 +723,10 @@ libcdata_internal_tree_node_t *internal_node = NULL; static char *function = "libcdata_tree_node_set_value"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + intptr_t *backup_value = NULL; +#endif + if( node == NULL ) { libcerror_error_set( @@ -750,7 +754,9 @@ return( -1 ); } + backup_value = internal_node->value; #endif + internal_node->value = value; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) @@ -765,10 +771,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_node->value = backup_value; + + return( -1 ); +#endif } /* Retrieves the parent node from the tree node @@ -852,6 +865,10 @@ libcdata_internal_tree_node_t *internal_node = NULL; static char *function = "libcdata_tree_node_set_parent_node"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_parent_node = NULL; +#endif + if( node == NULL ) { libcerror_error_set( @@ -879,7 +896,9 @@ return( -1 ); } + backup_parent_node = internal_node->parent_node; #endif + internal_node->parent_node = parent_node; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) @@ -894,10 +913,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_node->parent_node = backup_parent_node; + + return( -1 ); +#endif } /* Retrieves the previous node from the tree node @@ -981,6 +1007,10 @@ libcdata_internal_tree_node_t *internal_node = NULL; static char *function = "libcdata_tree_node_set_previous_node"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_previous_node = NULL; +#endif + if( node == NULL ) { libcerror_error_set( @@ -1008,7 +1038,9 @@ return( -1 ); } + backup_previous_node = internal_node->previous_node; #endif + internal_node->previous_node = previous_node; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) @@ -1023,10 +1055,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_node->previous_node = backup_previous_node; + + return( -1 ); +#endif } /* Retrieves the next node from the tree node @@ -1110,6 +1149,10 @@ libcdata_internal_tree_node_t *internal_node = NULL; static char *function = "libcdata_tree_node_set_next_node"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_next_node = NULL; +#endif + if( node == NULL ) { libcerror_error_set( @@ -1137,7 +1180,9 @@ return( -1 ); } + backup_next_node = internal_node->next_node ; #endif + internal_node->next_node = next_node; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) @@ -1152,10 +1197,17 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_node->next_node = backup_next_node; + + return( -1 ); +#endif } /* Retrieves the nodes from the tree node @@ -1267,6 +1319,12 @@ libcdata_internal_tree_node_t *internal_node = NULL; static char *function = "libcdata_tree_node_set_nodes"; +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_next_node = NULL; + libcdata_tree_node_t *backup_parent_node = NULL; + libcdata_tree_node_t *backup_previous_node = NULL; +#endif + if( node == NULL ) { libcerror_error_set( @@ -1294,7 +1352,11 @@ return( -1 ); } + backup_parent_node = internal_node->parent_node; + backup_previous_node = internal_node->previous_node; + backup_next_node = internal_node->next_node; #endif + internal_node->parent_node = parent_node; internal_node->previous_node = previous_node; internal_node->next_node = next_node; @@ -1311,23 +1373,31 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + internal_node->parent_node = backup_parent_node; + internal_node->previous_node = backup_previous_node; + internal_node->next_node = backup_next_node; + + return( -1 ); +#endif } -/* Retrieves the sub nodes from the tree node +/* Retrieves the first sub node from the tree node * Returns 1 if successful or -1 on error */ -int libcdata_tree_node_get_sub_nodes( +int libcdata_tree_node_get_first_sub_node( libcdata_tree_node_t *node, libcdata_tree_node_t **first_sub_node, - libcdata_tree_node_t **last_sub_node, libcerror_error_t **error ) { libcdata_internal_tree_node_t *internal_node = NULL; - static char *function = "libcdata_tree_node_sub_get_nodes"; + static char *function = "libcdata_tree_node_get_first_sub_node"; if( node == NULL ) { @@ -1353,17 +1423,6 @@ return( -1 ); } - if( last_sub_node == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid last sub node.", - function ); - - return( -1 ); - } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_grab_for_read( internal_node->read_write_lock, @@ -1380,7 +1439,6 @@ } #endif *first_sub_node = internal_node->first_sub_node; - *last_sub_node = internal_node->last_sub_node; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_read( @@ -1400,17 +1458,116 @@ return( 1 ); } -/* Sets the sub nodes in the tree node +/* Sets the first sub node in the tree node * Returns 1 if successful or -1 on error */ -int libcdata_tree_node_set_sub_nodes( - libcdata_tree_node_t *node, +int libcdata_internal_tree_node_set_first_sub_node( + libcdata_internal_tree_node_t *internal_node, libcdata_tree_node_t *first_sub_node, - libcdata_tree_node_t *last_sub_node, + libcerror_error_t **error ) +{ + libcdata_tree_node_t *backup_first_sub_node = NULL; + libcdata_tree_node_t *backup_previous_node = NULL; + static char *function = "libcdata_internal_tree_node_set_first_sub_node"; + + if( internal_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( first_sub_node != NULL ) + { + if( libcdata_tree_node_get_previous_node( + first_sub_node, + &backup_previous_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous node of sub node.", + function ); + + return( -1 ); + } + } + backup_first_sub_node = internal_node->first_sub_node; + + if( first_sub_node != NULL ) + { + if( libcdata_tree_node_set_previous_node( + first_sub_node, + internal_node->first_sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous node of sub node.", + function ); + + goto on_error; + } + } + if( internal_node->first_sub_node != NULL ) + { + if( libcdata_tree_node_set_next_node( + internal_node->first_sub_node, + first_sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next node of first sub node.", + function ); + + goto on_error; + } + } + internal_node->first_sub_node = first_sub_node; + + return( 1 ); + +on_error: + if( first_sub_node != NULL ) + { + libcdata_tree_node_set_previous_node( + first_sub_node, + backup_previous_node, + NULL ); + } + if( backup_first_sub_node != NULL ) + { + libcdata_tree_node_set_next_node( + backup_first_sub_node, + NULL, + NULL ); + } + internal_node->first_sub_node = backup_first_sub_node; + + return( -1 ); +} + +/* Retrieves the last sub node from the tree node + * Returns 1 if successful or -1 on error + */ +int libcdata_tree_node_get_last_sub_node( + libcdata_tree_node_t *node, + libcdata_tree_node_t **last_sub_node, libcerror_error_t **error ) { libcdata_internal_tree_node_t *internal_node = NULL; - static char *function = "libcdata_tree_node_set_sub_nodes"; + static char *function = "libcdata_tree_node_get_last_sub_node"; if( node == NULL ) { @@ -1425,8 +1582,19 @@ } internal_node = (libcdata_internal_tree_node_t *) node; + if( last_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid last sub node.", + function ); + + return( -1 ); + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( + if( libcthreads_read_write_lock_grab_for_read( internal_node->read_write_lock, error ) != 1 ) { @@ -1434,17 +1602,16 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", + "%s: unable to grab read/write lock for reading.", function ); return( -1 ); } #endif - internal_node->first_sub_node = first_sub_node; - internal_node->last_sub_node = last_sub_node; + *last_sub_node = internal_node->last_sub_node; #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( + if( libcthreads_read_write_lock_release_for_read( internal_node->read_write_lock, error ) != 1 ) { @@ -1452,7 +1619,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", + "%s: unable to release read/write lock for reading.", function ); return( -1 ); @@ -1461,18 +1628,17 @@ return( 1 ); } -/* Appends a sub tree node to the node +/* Sets the last sub node in the tree node * Returns 1 if successful or -1 on error */ -int libcdata_internal_tree_node_append_node( +int libcdata_internal_tree_node_set_last_sub_node( libcdata_internal_tree_node_t *internal_node, - libcdata_tree_node_t *node_to_append, + libcdata_tree_node_t *last_sub_node, libcerror_error_t **error ) { - libcdata_tree_node_t *to_append_next_node = NULL; - libcdata_tree_node_t *to_append_parent_node = NULL; - libcdata_tree_node_t *to_append_previous_node = NULL; - static char *function = "libcdata_internal_tree_node_append_node"; + libcdata_tree_node_t *backup_last_sub_node = NULL; + libcdata_tree_node_t *backup_previous_node = NULL; + static char *function = "libcdata_internal_tree_node_set_last_sub_node"; if( internal_node == NULL ) { @@ -1485,100 +1651,47 @@ return( -1 ); } - if( node_to_append == NULL ) + if( last_sub_node != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid node to append.", - function ); + if( libcdata_tree_node_get_previous_node( + last_sub_node, + &backup_previous_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous node of sub node.", + function ); - return( -1 ); + return( -1 ); + } } - if( libcdata_tree_node_get_nodes( - node_to_append, - &to_append_parent_node, - &to_append_previous_node, - &to_append_next_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve nodes of node to append.", - function ); + backup_last_sub_node = internal_node->last_sub_node; - return( -1 ); - } - if( ( to_append_parent_node != NULL ) - || ( to_append_previous_node != NULL ) - || ( to_append_next_node != NULL ) ) + if( last_sub_node != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: invalid node to append - node is already part of a tree.", - function ); - - return( -1 ); - } - if( internal_node->number_of_sub_nodes == 0 ) - { - if( internal_node->first_sub_node != NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: corruption detected - first sub node already set.", - function ); - - return( -1 ); - } - if( internal_node->last_sub_node != NULL ) + if( libcdata_tree_node_set_previous_node( + last_sub_node, + internal_node->last_sub_node, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: corruption detected - last sub node already set.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous node of sub node.", function ); - return( -1 ); + goto on_error; } - internal_node->first_sub_node = node_to_append; - internal_node->last_sub_node = node_to_append; } - else + if( internal_node->last_sub_node != NULL ) { - if( internal_node->first_sub_node == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: corruption detected - missing first sub node.", - function ); - - return( -1 ); - } - if( internal_node->last_sub_node == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: corruption detected - missing last sub node.", - function ); - - return( -1 ); - } if( libcdata_tree_node_set_next_node( internal_node->last_sub_node, - node_to_append, + last_sub_node, error ) != 1 ) { libcerror_error_set( @@ -1588,54 +1701,44 @@ "%s: unable to set next node of last sub node.", function ); - return( -1 ); + goto on_error; } - if( libcdata_tree_node_set_previous_node( - node_to_append, - internal_node->last_sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous node of node to append.", - function ); + } + internal_node->last_sub_node = last_sub_node; - return( -1 ); - } - internal_node->last_sub_node = node_to_append; + return( 1 ); + +on_error: + if( last_sub_node != NULL ) + { + libcdata_tree_node_set_previous_node( + last_sub_node, + backup_previous_node, + NULL ); } - if( libcdata_tree_node_set_parent_node( - node_to_append, - (libcdata_tree_node_t *) internal_node, - error ) != 1 ) + if( backup_last_sub_node != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set parent node of node to append.", - function ); - - return( -1 ); + libcdata_tree_node_set_next_node( + backup_last_sub_node, + NULL, + NULL ); } - internal_node->number_of_sub_nodes++; + internal_node->last_sub_node = backup_last_sub_node; - return( 1 ); + return( -1 ); } -/* Appends a tree node to the node +/* Retrieves the sub nodes from the tree node * Returns 1 if successful or -1 on error */ -int libcdata_tree_node_append_node( +int libcdata_tree_node_get_sub_nodes( libcdata_tree_node_t *node, - libcdata_tree_node_t *sub_node, + libcdata_tree_node_t **first_sub_node, + libcdata_tree_node_t **last_sub_node, libcerror_error_t **error ) { libcdata_internal_tree_node_t *internal_node = NULL; - static char *function = "libcdata_tree_node_append_node"; - int result = 1; + static char *function = "libcdata_tree_node_sub_get_nodes"; if( node == NULL ) { @@ -1650,37 +1753,48 @@ } internal_node = (libcdata_internal_tree_node_t *) node; -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_node->read_write_lock, - error ) != 1 ) + if( first_sub_node == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid first sub node.", function ); return( -1 ); } -#endif - if( libcdata_internal_tree_node_append_node( - internal_node, - sub_node, + if( last_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid last sub node.", + function ); + + return( -1 ); + } +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_read( + internal_node->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append node.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for reading.", function ); - result = -1; + return( -1 ); } +#endif + *first_sub_node = internal_node->first_sub_node; + *last_sub_node = internal_node->last_sub_node; + #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( + if( libcthreads_read_write_lock_release_for_read( internal_node->read_write_lock, error ) != 1 ) { @@ -1688,27 +1802,31 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", + "%s: unable to release read/write lock for reading.", function ); return( -1 ); } #endif - return( result ); + return( 1 ); } -/* Appends a value to the node - * Creates a new sub tree node +/* Sets the sub nodes in the tree node * Returns 1 if successful or -1 on error */ -int libcdata_tree_node_append_value( +int libcdata_tree_node_set_sub_nodes( libcdata_tree_node_t *node, - intptr_t *value, + libcdata_tree_node_t *first_sub_node, + libcdata_tree_node_t *last_sub_node, libcerror_error_t **error ) { libcdata_internal_tree_node_t *internal_node = NULL; - libcdata_tree_node_t *sub_node = NULL; - static char *function = "libcdata_tree_node_append_value"; + static char *function = "libcdata_tree_node_set_sub_nodes"; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_first_sub_node = NULL; + libcdata_tree_node_t *backup_last_sub_node = NULL; +#endif if( node == NULL ) { @@ -1737,48 +1855,13 @@ return( -1 ); } + backup_first_sub_node = internal_node->first_sub_node; + backup_last_sub_node = internal_node->last_sub_node; #endif - if( libcdata_tree_node_initialize( - &sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create sub node.", - function ); - - goto on_error; - } - if( libcdata_tree_node_set_value( - sub_node, - value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_SET_FAILED, - "%s: unable to set value in sub node.", - function ); - goto on_error; - } - if( libcdata_internal_tree_node_append_node( - internal_node, - sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to append sub node to node.", - function ); + internal_node->first_sub_node = first_sub_node; + internal_node->last_sub_node = last_sub_node; - goto on_error; - } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_node->read_write_lock, @@ -1791,58 +1874,32 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_node->read_write_lock, - NULL ); -#endif - if( sub_node != NULL ) - { - libcdata_tree_node_free( - &sub_node, - NULL, - NULL ); - } +on_error: + internal_node->first_sub_node = backup_first_sub_node; + internal_node->last_sub_node = backup_last_sub_node; + return( -1 ); +#endif } -/* Inserts a sub tree node in the node - * - * Uses the entry_compare_function to determine the order of the entries - * The entry_compare_function should return LIBCDATA_COMPARE_LESS, - * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error - * - * Duplicate entries are allowed by default and inserted after the last duplicate entry. - * Only allowing unique entries can be enforced by setting the flag LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES - * - * Returns 1 if successful, 0 if the node already exists or -1 on error +/* Appends a sub tree node to the node + * Returns 1 if successful or -1 on error */ -int libcdata_internal_tree_node_insert_node( +int libcdata_internal_tree_node_append_node( libcdata_internal_tree_node_t *internal_node, - libcdata_tree_node_t *node_to_insert, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - uint8_t insert_flags, + libcdata_tree_node_t *node_to_append, libcerror_error_t **error ) { - libcdata_tree_node_t *previous_node = NULL; - libcdata_tree_node_t *sub_node = NULL; - libcdata_tree_node_t *to_insert_next_node = NULL; - libcdata_tree_node_t *to_insert_parent_node = NULL; - libcdata_tree_node_t *to_insert_previous_node = NULL; - intptr_t *sub_node_value = NULL; - intptr_t *value_to_insert = NULL; - static char *function = "libcdata_internal_tree_node_insert_node"; - int result = -1; - int sub_node_index = 0; + libcdata_tree_node_t *to_append_next_node = NULL; + libcdata_tree_node_t *to_append_parent_node = NULL; + libcdata_tree_node_t *to_append_previous_node = NULL; + static char *function = "libcdata_internal_tree_node_append_node"; if( internal_node == NULL ) { @@ -1855,69 +1912,179 @@ return( -1 ); } - if( node_to_insert == NULL ) + if( node_to_append == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid node to insert.", + "%s: invalid node to append.", function ); return( -1 ); } if( libcdata_tree_node_get_nodes( - node_to_insert, - &to_insert_parent_node, - &to_insert_previous_node, - &to_insert_next_node, + node_to_append, + &to_append_parent_node, + &to_append_previous_node, + &to_append_next_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve nodes of node to insert.", + "%s: unable to retrieve nodes of node to append.", function ); return( -1 ); } - if( ( to_insert_parent_node != NULL ) - || ( to_insert_previous_node != NULL ) - || ( to_insert_next_node != NULL ) ) + if( ( to_append_parent_node != NULL ) + || ( to_append_previous_node != NULL ) + || ( to_append_next_node != NULL ) ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: invalid node to insert - node is already part of a tree.", + "%s: invalid node to append - node is already part of a tree.", function ); return( -1 ); } - if( value_compare_function == NULL ) + if( internal_node->number_of_sub_nodes == 0 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid value compare function.", - function ); + if( internal_node->first_sub_node != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: corruption detected - first sub node already set.", + function ); + + return( -1 ); + } + if( internal_node->last_sub_node != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: corruption detected - last sub node already set.", + function ); + + return( -1 ); + } + internal_node->first_sub_node = node_to_append; + internal_node->last_sub_node = node_to_append; + } + else + { + if( internal_node->first_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing first sub node.", + function ); + + return( -1 ); + } + if( internal_node->last_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing last sub node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_set_next_node( + internal_node->last_sub_node, + node_to_append, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next node of last sub node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_set_previous_node( + node_to_append, + internal_node->last_sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous node of node to append.", + function ); + + return( -1 ); + } + internal_node->last_sub_node = node_to_append; + } + if( libcdata_tree_node_set_parent_node( + node_to_append, + (libcdata_tree_node_t *) internal_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set parent node of node to append.", + function ); return( -1 ); } - if( ( insert_flags & ~( LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) ) != 0 ) + internal_node->number_of_sub_nodes += 1; + + return( 1 ); +} + +/* Appends a tree node to the node + * Returns 1 if successful or -1 on error + */ +int libcdata_tree_node_append_node( + libcdata_tree_node_t *node, + libcdata_tree_node_t *node_to_append, + libcerror_error_t **error ) +{ + libcdata_internal_tree_node_t *internal_node = NULL; + libcdata_tree_node_t *to_append_next_node = NULL; + libcdata_tree_node_t *to_append_parent_node = NULL; + libcdata_tree_node_t *to_append_previous_node = NULL; + static char *function = "libcdata_tree_node_append_node"; + int result = 1; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_first_sub_node = NULL; + libcdata_tree_node_t *backup_last_sub_node = NULL; +#endif + + if( node == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, - "%s: unsupported insert flags: 0x%02" PRIx8 ".", - function, - insert_flags ); + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); return( -1 ); } + internal_node = (libcdata_internal_tree_node_t *) node; + if( internal_node->number_of_sub_nodes == 0 ) { if( internal_node->first_sub_node != NULL ) @@ -1925,7 +2092,7 @@ libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: corruption detected - first sub node already set.", function ); @@ -1936,14 +2103,12 @@ libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, "%s: corruption detected - last sub node already set.", function ); return( -1 ); } - internal_node->first_sub_node = node_to_insert; - internal_node->last_sub_node = node_to_insert; } else { @@ -1969,184 +2134,538 @@ return( -1 ); } - if( libcdata_tree_node_get_value( - node_to_insert, - &value_to_insert, - error ) != 1 ) + } + if( libcdata_tree_node_get_nodes( + node_to_append, + &to_append_parent_node, + &to_append_previous_node, + &to_append_next_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve nodes of node to append.", + function ); + + return( -1 ); + } + if( ( to_append_parent_node != NULL ) + || ( to_append_previous_node != NULL ) + || ( to_append_next_node != NULL ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid node to append - node is already part of a tree.", + function ); + + return( -1 ); + } +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_write( + internal_node->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + + return( -1 ); + } + backup_first_sub_node = internal_node->first_sub_node; + backup_last_sub_node = internal_node->last_sub_node; +#endif + + result = libcdata_tree_node_set_parent_node( + node_to_append, + node, + error ); + + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set parent node of node to append.", + function ); + + result = -1; + } + if( result == 1 ) + { + result = libcdata_tree_node_set_previous_node( + node_to_append, + internal_node->last_sub_node, + error ); + + if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value of node to insert.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous node of node to append.", function ); - return( -1 ); - } - sub_node = internal_node->first_sub_node; + libcdata_tree_node_set_parent_node( + node_to_append, + NULL, + NULL ); - for( sub_node_index = 0; - sub_node_index < internal_node->number_of_sub_nodes; - sub_node_index++ ) + result = -1; + } + } + if( result == 1 ) + { + if( internal_node->last_sub_node != NULL ) { - if( libcdata_tree_node_get_value( - sub_node, - &sub_node_value, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve value of sub node: %d.", - function, - sub_node_index ); - - return( -1 ); - } - result = value_compare_function( - value_to_insert, - sub_node_value, + result = libcdata_tree_node_set_next_node( + internal_node->last_sub_node, + node_to_append, error ); - if( result == -1 ) + if( result != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to compare sub node: %d.", - function, - sub_node_index ); - - return( -1 ); - } - else if( result == LIBCDATA_COMPARE_EQUAL ) - { - if( ( insert_flags & LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) != 0 ) - { - return( 0 ); - } - } - else if( result == LIBCDATA_COMPARE_LESS ) - { - break; - } - else if( result != LIBCDATA_COMPARE_GREATER ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, - "%s: unsupported value compare function return value: %d.", - function, - result ); + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next node of last sub node.", + function ); - return( -1 ); - } - if( libcdata_tree_node_get_next_node( - sub_node, - &sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve next node of sub node: %d.", - function, - sub_node_index ); + libcdata_tree_node_set_parent_node( + node_to_append, + NULL, + NULL ); + + libcdata_tree_node_set_previous_node( + node_to_append, + NULL, + NULL ); - return( -1 ); + result = -1; } } - if( result == LIBCDATA_COMPARE_LESS ) + } + if( result == 1 ) + { + if( internal_node->first_sub_node == NULL ) { - if( libcdata_tree_node_get_previous_node( - sub_node, - &previous_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve previous node of sub node: %d.", - function, - sub_node_index ); + internal_node->first_sub_node = node_to_append; + } + internal_node->last_sub_node = node_to_append; - return( -1 ); - } - if( libcdata_tree_node_set_nodes( - node_to_insert, - NULL, - previous_node, - sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous and next node of node to insert.", - function ); + internal_node->number_of_sub_nodes += 1; + } +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_release_for_write( + internal_node->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for writing.", + function ); - return( -1 ); - } - if( sub_node == internal_node->first_sub_node ) - { - internal_node->first_sub_node = node_to_insert; - } - else - { - if( previous_node == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: corruption detected - missing previous node in sub node: %d.", - function, - sub_node_index ); + goto on_error; + } +#endif + return( result ); - return( -1 ); - } - if( libcdata_tree_node_set_next_node( - previous_node, - node_to_insert, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next node of sub node: %d.", - function, - sub_node_index - 1 ); +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + libcdata_tree_node_set_parent_node( + node_to_append, + NULL, + NULL ); - return( -1 ); - } - } - if( libcdata_tree_node_set_previous_node( - sub_node, - node_to_insert, - error ) != 1 ) + libcdata_tree_node_set_previous_node( + node_to_append, + NULL, + NULL ); + + internal_node->first_sub_node = backup_first_sub_node; + internal_node->last_sub_node = backup_last_sub_node; + + internal_node->number_of_sub_nodes -= 1; + + return( -1 ); +#endif +} + +/* Appends a value to the node + * Creates a new sub tree node + * Returns 1 if successful or -1 on error + */ +int libcdata_tree_node_append_value( + libcdata_tree_node_t *node, + intptr_t *value, + libcerror_error_t **error ) +{ + libcdata_tree_node_t *sub_node = NULL; + static char *function = "libcdata_tree_node_append_value"; + + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( libcdata_tree_node_initialize( + &sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create sub node.", + function ); + + goto on_error; + } + if( libcdata_tree_node_set_value( + sub_node, + value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to set value in sub node.", + function ); + + goto on_error; + } + if( libcdata_tree_node_append_node( + node, + sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to append sub node to node.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( sub_node != NULL ) + { + libcdata_tree_node_free( + &sub_node, + NULL, + NULL ); + } + return( -1 ); +} + + +/* Retrieves the node which the sub node should be inserted before + * + * Uses the value_compare_function to determine the order of the entries + * The value_compare_function should return LIBCDATA_COMPARE_LESS, + * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error + * + * Duplicate entries are allowed by default and inserted after the last duplicate value. + * Only allowing unique entries can be enforced by setting the flag LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES + * + * On return sub_node will be set to NULL if the sub node should be inserted at the end of the list. + * + * Returns 1 if successful, 0 if a sub node containing the value already exists or -1 on error + */ +int libcdata_internal_tree_node_insert_node_find_sub_node( + libcdata_internal_tree_node_t *internal_node, + intptr_t *value_to_insert, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + uint8_t insert_flags, + int *sub_node_index, + libcdata_tree_node_t **sub_node, + libcerror_error_t **error ) +{ + libcdata_tree_node_t *sub_tree_node = NULL; + intptr_t *sub_node_value = NULL; + static char *function = "libcdata_internal_tree_node_insert_node_find_sub_node"; + int compare_result = 0; + int result = 1; + int safe_sub_node_index = 0; + + if( internal_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( value_compare_function == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value compare function.", + function ); + + return( -1 ); + } + if( ( insert_flags & ~( LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported insert flags: 0x%02" PRIx8 ".", + function, + insert_flags ); + + return( -1 ); + } + if( sub_node_index == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid sub node index.", + function ); + + return( -1 ); + } + if( sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid sub node.", + function ); + + return( -1 ); + } + sub_tree_node = internal_node->first_sub_node; + + for( safe_sub_node_index = 0; + safe_sub_node_index < internal_node->number_of_sub_nodes; + safe_sub_node_index++ ) + { + if( libcdata_tree_node_get_value( + sub_tree_node, + &sub_node_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value of sub node: %d.", + function, + safe_sub_node_index ); + + return( -1 ); + } + compare_result = value_compare_function( + value_to_insert, + sub_node_value, + error ); + + if( compare_result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to compare sub node: %d.", + function, + safe_sub_node_index ); + + return( -1 ); + } + else if( compare_result == LIBCDATA_COMPARE_EQUAL ) + { + if( ( insert_flags & LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) != 0 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous node of sub node: %d.", - function, - sub_node_index ); + result = 0; - return( -1 ); + break; } } + else if( compare_result == LIBCDATA_COMPARE_LESS ) + { + break; + } + else if( compare_result != LIBCDATA_COMPARE_GREATER ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported value compare function return value: %d.", + function, + result ); + + return( -1 ); + } + if( libcdata_tree_node_get_next_node( + sub_tree_node, + &sub_tree_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve next node of sub node: %d.", + function, + safe_sub_node_index ); + + return( -1 ); + } + } + if( ( compare_result == LIBCDATA_COMPARE_EQUAL ) + || ( compare_result == LIBCDATA_COMPARE_LESS ) ) + { + *sub_node_index = safe_sub_node_index; + *sub_node = sub_tree_node; + } + else + { + *sub_node_index = internal_node->number_of_sub_nodes; + *sub_node = NULL; + } + return( result ); +} + +/* Inserts the node before the sub node + * If sub_node is NULL the node is inserted before or as the first sub node in the list + * Returns 1 if successful, or -1 on error + */ +int libcdata_internal_tree_node_insert_node_before_sub_node( + libcdata_internal_tree_node_t *internal_node, + libcdata_tree_node_t *sub_node, + libcdata_tree_node_t *node_to_insert, + libcerror_error_t **error ) +{ + libcdata_tree_node_t *backup_first_sub_node = NULL; + libcdata_tree_node_t *backup_last_sub_node = NULL; + libcdata_tree_node_t *previous_node = NULL; + static char *function = "libcdata_internal_tree_node_insert_node_before_sub_node"; + + if( internal_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + if( node_to_insert == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node to insert.", + function ); + + return( -1 ); + } + backup_first_sub_node = internal_node->first_sub_node; + backup_last_sub_node = internal_node->last_sub_node; + + if( sub_node != NULL ) + { + if( libcdata_tree_node_get_previous_node( + sub_node, + &previous_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve previous node from sub node.", + function ); + + return( -1 ); + } + } + if( internal_node->number_of_sub_nodes == 0 ) + { + internal_node->first_sub_node = node_to_insert; + internal_node->last_sub_node = node_to_insert; + } + else if( sub_node == NULL ) + { + if( libcdata_internal_tree_node_set_last_sub_node( + internal_node, + node_to_insert, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set last sub node.", + function ); + + goto on_error; + } + } + else + { + if( libcdata_tree_node_set_nodes( + node_to_insert, + (libcdata_tree_node_t *) internal_node, + previous_node, + sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set parent, previous and next node of node to insert.", + function ); + + goto on_error; + } + if( internal_node->first_sub_node == sub_node ) + { + internal_node->first_sub_node = node_to_insert; + } else { if( libcdata_tree_node_set_next_node( - internal_node->last_sub_node, + previous_node, node_to_insert, error ) != 1 ) { @@ -2154,85 +2673,251 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next node of last sub node.", + "%s: unable to set next node of previous node.", function ); - return( -1 ); + goto on_error; } - if( libcdata_tree_node_set_previous_node( - node_to_insert, - internal_node->last_sub_node, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous node of node to insert.", - function ); + } + if( libcdata_tree_node_set_previous_node( + sub_node, + node_to_insert, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous node of sub node.", + function ); + + goto on_error; + } + } + if( libcdata_tree_node_set_parent_node( + node_to_insert, + (libcdata_tree_node_t *) internal_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set parent node of node to insert.", + function ); + + goto on_error; + } + internal_node->number_of_sub_nodes += 1; + + return( 1 ); + +on_error: + if( node_to_insert != NULL ) + { + libcdata_tree_node_set_nodes( + node_to_insert, + NULL, + NULL, + NULL, + NULL ); + } + if( previous_node != NULL ) + { + libcdata_tree_node_set_next_node( + previous_node, + sub_node, + NULL ); + } + if( sub_node != NULL ) + { + libcdata_tree_node_set_previous_node( + sub_node, + previous_node, + NULL ); + } + internal_node->first_sub_node = backup_first_sub_node; + internal_node->last_sub_node = backup_last_sub_node; + + return( -1 ); +} + +/* Inserts a sub node in the node + * + * Uses the value_compare_function to determine the order of the entries + * The value_compare_function should return LIBCDATA_COMPARE_LESS, + * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error + * + * Duplicate entries are allowed by default and inserted after the last duplicate value. + * Only allowing unique entries can be enforced by setting the flag LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES + * + * Returns 1 if successful, 0 if the node already exists or -1 on error + */ +int libcdata_tree_node_insert_node( + libcdata_tree_node_t *node, + libcdata_tree_node_t *node_to_insert, + int (*value_compare_function)( + intptr_t *first_value, + intptr_t *second_value, + libcerror_error_t **error ), + uint8_t insert_flags, + libcerror_error_t **error ) +{ + libcdata_internal_tree_node_t *internal_node = NULL; + libcdata_tree_node_t *next_node = NULL; + libcdata_tree_node_t *parent_node = NULL; + libcdata_tree_node_t *previous_node = NULL; + libcdata_tree_node_t *sub_node = NULL; + intptr_t *value_to_insert = NULL; + static char *function = "libcdata_tree_node_insert_node"; + int result = 1; + int sub_node_index = 0; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_first_sub_node = NULL; + libcdata_tree_node_t *backup_last_sub_node = NULL; +#endif + + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node.", + function ); + + return( -1 ); + } + internal_node = (libcdata_internal_tree_node_t *) node; + + if( internal_node->number_of_sub_nodes == 0 ) + { + if( internal_node->first_sub_node != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - first sub node already set.", + function ); + + return( -1 ); + } + if( internal_node->last_sub_node != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - last sub node already set.", + function ); + + return( -1 ); + } + } + else + { + if( internal_node->first_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing first sub node.", + function ); + + return( -1 ); + } + if( internal_node->last_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing last sub node.", + function ); - return( -1 ); - } - internal_node->last_sub_node = node_to_insert; + return( -1 ); } } - if( libcdata_tree_node_set_parent_node( - node_to_insert, - (libcdata_tree_node_t *) internal_node, - error ) != 1 ) + if( node_to_insert == NULL ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set parent node of node to insert.", + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid node to insert.", function ); return( -1 ); } - internal_node->number_of_sub_nodes++; + if( value_compare_function == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value compare function.", + function ); - return( 1 ); -} + return( -1 ); + } + if( ( insert_flags & ~( LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES ) ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported insert flags: 0x%02" PRIx8 ".", + function, + insert_flags ); -/* Inserts a sub tree node in the node - * - * Uses the entry_compare_function to determine the order of the entries - * The entry_compare_function should return LIBCDATA_COMPARE_LESS, - * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error - * - * Duplicate entries are allowed by default and inserted after the last duplicate entry. - * Only allowing unique entries can be enforced by setting the flag LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES - * - * Returns 1 if successful, 0 if the node already exists or -1 on error - */ -int libcdata_tree_node_insert_node( - libcdata_tree_node_t *node, - libcdata_tree_node_t *node_to_insert, - int (*value_compare_function)( - intptr_t *first_value, - intptr_t *second_value, - libcerror_error_t **error ), - uint8_t insert_flags, - libcerror_error_t **error ) -{ - libcdata_internal_tree_node_t *internal_node = NULL; - static char *function = "libcdata_tree_node_insert_node"; - int result = 1; + return( -1 ); + } + if( libcdata_tree_node_get_nodes( + node_to_insert, + &parent_node, + &previous_node, + &next_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve nodes of node to insert.", + function ); - if( node == NULL ) + return( -1 ); + } + if( ( parent_node != NULL ) + || ( previous_node != NULL ) + || ( next_node != NULL ) ) { libcerror_error_set( error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid node.", + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid node to insert - node is already part of a tree.", function ); return( -1 ); } - internal_node = (libcdata_internal_tree_node_t *) node; + if( libcdata_tree_node_get_value( + node_to_insert, + &value_to_insert, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from node to insert.", + function ); + return( -1 ); + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_grab_for_write( internal_node->read_write_lock, @@ -2247,12 +2932,17 @@ return( -1 ); } + backup_first_sub_node = internal_node->first_sub_node; + backup_last_sub_node = internal_node->last_sub_node; #endif - result = libcdata_internal_tree_node_insert_node( + + result = libcdata_internal_tree_node_insert_node_find_sub_node( internal_node, - node_to_insert, + value_to_insert, value_compare_function, insert_flags, + &sub_node_index, + &sub_node, error ); if( result == -1 ) @@ -2260,12 +2950,53 @@ libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, - "%s: unable to insert node.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to find sub node in tree node.", function ); result = -1; } + else if( result == 1 ) + { + if( sub_node != NULL ) + { + if( libcdata_tree_node_get_nodes( + sub_node, + &parent_node, + &previous_node, + &next_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve nodes of sub node: %d.", + function, + sub_node_index ); + + result = -1; + } + } + if( result == 1 ) + { + if( libcdata_internal_tree_node_insert_node_before_sub_node( + internal_node, + sub_node, + node_to_insert, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_APPEND_FAILED, + "%s: unable to insert node before tree sub node.", + function ); + + result = -1; + } + } + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_node->read_write_lock, @@ -2278,21 +3009,56 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( result ); + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) +on_error: + if( result == 1 ) + { + if( node_to_insert != NULL ) + { + libcdata_tree_node_set_nodes( + node_to_insert, + NULL, + NULL, + NULL, + NULL ); + } + if( previous_node != NULL ) + { + libcdata_tree_node_set_next_node( + previous_node, + sub_node, + NULL ); + } + if( sub_node != NULL ) + { + libcdata_tree_node_set_previous_node( + sub_node, + previous_node, + NULL ); + } + internal_node->first_sub_node = backup_first_sub_node; + internal_node->last_sub_node = backup_last_sub_node; + + internal_node->number_of_sub_nodes -= 1; + } + return( -1 ); +#endif } /* Inserts a value in the node * * Creates a new sub tree node * - * Uses the entry_compare_function to determine the order of the entries - * The entry_compare_function should return LIBCDATA_COMPARE_LESS, + * Uses the value_compare_function to determine the order of the entries + * The value_compare_function should return LIBCDATA_COMPARE_LESS, * LIBCDATA_COMPARE_EQUAL, LIBCDATA_COMPARE_GREATER if successful or -1 on error * - * Duplicate entries are allowed by default and inserted after the last duplicate entry. + * Duplicate entries are allowed by default and inserted after the last duplicate value. * Only allowing unique entries can be enforced by setting the flag LIBCDATA_INSERT_FLAG_UNIQUE_ENTRIES * * Returns 1 if successful, 0 if the node already exists or -1 on error @@ -2307,10 +3073,9 @@ uint8_t insert_flags, libcerror_error_t **error ) { - libcdata_internal_tree_node_t *internal_node = NULL; - libcdata_tree_node_t *sub_node = NULL; - static char *function = "libcdata_tree_node_insert_value"; - int result = 0; + libcdata_tree_node_t *sub_node = NULL; + static char *function = "libcdata_tree_node_insert_value"; + int result = 0; if( node == NULL ) { @@ -2323,23 +3088,6 @@ return( -1 ); } - internal_node = (libcdata_internal_tree_node_t *) node; - -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_node->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", - function ); - - return( -1 ); - } -#endif if( libcdata_tree_node_initialize( &sub_node, error ) != 1 ) @@ -2367,8 +3115,8 @@ goto on_error; } - result = libcdata_internal_tree_node_insert_node( - internal_node, + result = libcdata_tree_node_insert_node( + node, sub_node, value_compare_function, insert_flags, @@ -2402,29 +3150,9 @@ goto on_error; } } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_release_for_write( - internal_node->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to release read/write lock for writing.", - function ); - - return( -1 ); - } -#endif return( result ); on_error: -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_node->read_write_lock, - NULL ); -#endif if( sub_node != NULL ) { libcdata_tree_node_free( @@ -2443,16 +3171,19 @@ libcdata_tree_node_t *replacement_node, libcerror_error_t **error ) { - libcdata_internal_tree_node_t *internal_node = NULL; - libcdata_tree_node_t *next_node = NULL; - libcdata_tree_node_t *parent_first_sub_node = NULL; - libcdata_tree_node_t *parent_last_sub_node = NULL; - libcdata_tree_node_t *parent_node = NULL; - libcdata_tree_node_t *previous_node = NULL; - libcdata_tree_node_t *replacement_next_node = NULL; - libcdata_tree_node_t *replacement_parent_node = NULL; - libcdata_tree_node_t *replacement_previous_node = NULL; - static char *function = "libcdata_tree_node_replace_node"; + libcdata_internal_tree_node_t *internal_node = NULL; + libcdata_tree_node_t *backup_parent_first_sub_node = NULL; + libcdata_tree_node_t *backup_parent_last_sub_node = NULL; + libcdata_tree_node_t *next_node = NULL; + libcdata_tree_node_t *parent_first_sub_node = NULL; + libcdata_tree_node_t *parent_last_sub_node = NULL; + libcdata_tree_node_t *parent_node = NULL; + libcdata_tree_node_t *previous_node = NULL; + libcdata_tree_node_t *replacement_next_node = NULL; + libcdata_tree_node_t *replacement_parent_node = NULL; + libcdata_tree_node_t *replacement_previous_node = NULL; + static char *function = "libcdata_tree_node_replace_node"; + int result = 1; if( node == NULL ) { @@ -2489,21 +3220,6 @@ return( -1 ); } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_node->read_write_lock, - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", - function ); - - return( -1 ); - } -#endif if( libcdata_tree_node_get_nodes( replacement_node, &replacement_parent_node, @@ -2518,7 +3234,7 @@ "%s: unable to retrieve nodes of replacement node.", function ); - goto on_error; + return( -1 ); } if( ( replacement_parent_node != NULL ) || ( replacement_previous_node != NULL ) @@ -2528,111 +3244,189 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: invalid replacement node - node is already part of a tree.", + "%s: invalid replacement node - already part of a tree.", function ); - goto on_error; + return( -1 ); } - if( libcdata_tree_node_get_sub_nodes( - internal_node->parent_node, - &parent_first_sub_node, - &parent_last_sub_node, +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_write( + internal_node->read_write_lock, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve sub nodes of parent node.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", function ); - goto on_error; + return( -1 ); } - parent_node = internal_node->parent_node; - internal_node->parent_node = replacement_parent_node; - replacement_parent_node = parent_node; - - previous_node = internal_node->previous_node; - internal_node->previous_node = replacement_previous_node; - replacement_previous_node = previous_node; - - next_node = internal_node->next_node; - internal_node->next_node = replacement_next_node; - replacement_next_node = next_node; +#endif + parent_node = internal_node->parent_node; + previous_node = internal_node->previous_node; + next_node = internal_node->next_node; + + if( parent_node != NULL ) + { + if( libcdata_tree_node_get_sub_nodes( + parent_node, + &parent_first_sub_node, + &parent_last_sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub nodes of parent node.", + function ); - if( parent_first_sub_node == node ) - { - parent_first_sub_node = replacement_node; - } - if( parent_last_sub_node == node ) - { - parent_last_sub_node = replacement_node; + result = -1; + } } - if( libcdata_tree_node_set_nodes( - replacement_node, - replacement_parent_node, - replacement_previous_node, - replacement_next_node, - error ) != 1 ) + if( result == 1 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set nodes of replacement node.", - function ); + if( libcdata_tree_node_set_nodes( + replacement_node, + parent_node, + previous_node, + next_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set nodes of replacement node.", + function ); - goto on_error; + result = -1; + } } - if( libcdata_tree_node_set_sub_nodes( - parent_node, - parent_first_sub_node, - parent_last_sub_node, - error ) != 1 ) + if( result == 1 ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set sub nodes of parent node.", - function ); + if( parent_node != NULL ) + { + backup_parent_first_sub_node = parent_first_sub_node; + backup_parent_last_sub_node = parent_last_sub_node; + + if( parent_first_sub_node == node ) + { + parent_first_sub_node = replacement_node; + } + if( parent_last_sub_node == node ) + { + parent_last_sub_node = replacement_node; + } + if( libcdata_tree_node_set_sub_nodes( + parent_node, + parent_first_sub_node, + parent_last_sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set sub nodes of parent node.", + function ); - goto on_error; + libcdata_tree_node_set_nodes( + replacement_node, + NULL, + NULL, + NULL, + NULL ); + + result = -1; + } + } } - if( previous_node != NULL ) + if( result == 1 ) { - if( libcdata_tree_node_set_next_node( - previous_node, - replacement_node, - error ) != 1 ) + if( previous_node != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next node of previous node.", - function ); + if( libcdata_tree_node_set_next_node( + previous_node, + replacement_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next node of previous node.", + function ); - goto on_error; + libcdata_tree_node_set_nodes( + replacement_node, + NULL, + NULL, + NULL, + NULL ); + + if( parent_node != NULL ) + { + libcdata_tree_node_set_sub_nodes( + parent_node, + backup_parent_first_sub_node, + backup_parent_last_sub_node, + NULL ); + } + result = -1; + } } } - if( next_node != NULL ) + if( result == 1 ) { - if( libcdata_tree_node_set_previous_node( - next_node, - replacement_node, - error ) != 1 ) + if( next_node != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous node of next node.", - function ); + if( libcdata_tree_node_set_previous_node( + next_node, + replacement_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous node of next node.", + function ); - goto on_error; + libcdata_tree_node_set_nodes( + replacement_node, + NULL, + NULL, + NULL, + NULL ); + + if( parent_node != NULL ) + { + libcdata_tree_node_set_sub_nodes( + parent_node, + backup_parent_first_sub_node, + backup_parent_last_sub_node, + NULL ); + } + if( previous_node != NULL ) + { + libcdata_tree_node_set_next_node( + previous_node, + node, + NULL ); + } + result = -1; + } } } + if( result == 1 ) + { + internal_node->parent_node = NULL; + internal_node->previous_node = NULL; + internal_node->next_node = NULL; + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_node->read_write_lock, @@ -2645,18 +3439,50 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif - return( 1 ); + return( result ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_node->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + libcdata_tree_node_set_nodes( + replacement_node, + NULL, + NULL, + NULL, + NULL ); + + if( parent_node != NULL ) + { + libcdata_tree_node_set_sub_nodes( + parent_node, + backup_parent_first_sub_node, + backup_parent_last_sub_node, + NULL ); + } + if( previous_node != NULL ) + { + libcdata_tree_node_set_next_node( + previous_node, + node, + NULL ); + } + if( next_node != NULL ) + { + libcdata_tree_node_set_previous_node( + next_node, + node, + NULL ); + } + internal_node->parent_node = parent_node; + internal_node->previous_node = previous_node; + internal_node->next_node = next_node; + } return( -1 ); +#endif } /* Removes a sub tree node from the tree node @@ -2664,14 +3490,20 @@ */ int libcdata_tree_node_remove_node( libcdata_tree_node_t *node, - libcdata_tree_node_t *node_to_remove, + libcdata_tree_node_t *sub_node_to_remove, libcerror_error_t **error ) { - libcdata_internal_tree_node_t *internal_node = NULL; - libcdata_tree_node_t *to_remove_next_node = NULL; - libcdata_tree_node_t *to_remove_parent_node = NULL; - libcdata_tree_node_t *to_remove_previous_node = NULL; - static char *function = "libcdata_tree_node_remove_node"; + libcdata_internal_tree_node_t *internal_node = NULL; + libcdata_tree_node_t *next_node = NULL; + libcdata_tree_node_t *parent_node = NULL; + libcdata_tree_node_t *previous_node = NULL; + static char *function = "libcdata_tree_node_remove_node"; + int result = 1; + +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + libcdata_tree_node_t *backup_first_sub_node = NULL; + libcdata_tree_node_t *backup_last_sub_node = NULL; +#endif if( node == NULL ) { @@ -2686,13 +3518,63 @@ } internal_node = (libcdata_internal_tree_node_t *) node; - if( node_to_remove == NULL ) + if( internal_node->number_of_sub_nodes == 0 ) + { + if( internal_node->first_sub_node != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - first sub node already set.", + function ); + + return( -1 ); + } + if( internal_node->last_sub_node != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - last sub node already set.", + function ); + + return( -1 ); + } + } + else + { + if( internal_node->first_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing first sub node.", + function ); + + return( -1 ); + } + if( internal_node->last_sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: corruption detected - missing last sub node.", + function ); + + return( -1 ); + } + } + if( sub_node_to_remove == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid node to remove.", + "%s: invalid sub node to remove.", function ); return( -1 ); @@ -2730,54 +3612,58 @@ return( -1 ); } -#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - if( libcthreads_read_write_lock_grab_for_write( - internal_node->read_write_lock, + if( libcdata_tree_node_get_nodes( + sub_node_to_remove, + &parent_node, + &previous_node, + &next_node, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to grab read/write lock for writing.", + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve nodes of node to remove.", function ); return( -1 ); } -#endif - if( libcdata_tree_node_get_nodes( - node_to_remove, - &to_remove_parent_node, - &to_remove_previous_node, - &to_remove_next_node, - error ) != 1 ) + if( parent_node != node ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_GET_FAILED, - "%s: unable to retrieve nodes of node to remove.", + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid node to remove - parent node mismatch.", function ); - goto on_error; + return( -1 ); } - if( to_remove_parent_node != node ) +#if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) + if( libcthreads_read_write_lock_grab_for_write( + internal_node->read_write_lock, + error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid node to remove - parent node mismatch.", + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", function ); - goto on_error; + return( -1 ); } - if( libcdata_tree_node_set_nodes( - node_to_remove, - NULL, - NULL, - NULL, - error ) != 1 ) + backup_first_sub_node = internal_node->first_sub_node; + backup_last_sub_node = internal_node->last_sub_node; +#endif + result = libcdata_tree_node_set_nodes( + sub_node_to_remove, + NULL, + NULL, + NULL, + error ); + + if( result != 1 ) { libcerror_error_set( error, @@ -2786,52 +3672,81 @@ "%s: unable to set nodes of node to remove.", function ); - goto on_error; - } - if( internal_node->first_sub_node == node_to_remove ) - { - internal_node->first_sub_node = to_remove_next_node; + result = -1; } - if( internal_node->last_sub_node == node_to_remove ) + if( result == 1 ) { - internal_node->last_sub_node = to_remove_previous_node; + if( next_node != NULL ) + { + if( libcdata_tree_node_set_previous_node( + next_node, + previous_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set previous node of next node.", + function ); + + libcdata_tree_node_set_nodes( + sub_node_to_remove, + parent_node, + previous_node, + next_node, + NULL ); + + result = -1; + } + } } - if( to_remove_next_node != NULL ) + if( result == 1 ) { - if( libcdata_tree_node_set_previous_node( - to_remove_next_node, - to_remove_previous_node, - error ) != 1 ) + if( previous_node != NULL ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set previous node of next node.", - function ); + if( libcdata_tree_node_set_next_node( + previous_node, + next_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set next node of previous node.", + function ); - goto on_error; + libcdata_tree_node_set_nodes( + sub_node_to_remove, + parent_node, + previous_node, + next_node, + NULL ); + + if( next_node != NULL ) + { + libcdata_tree_node_set_previous_node( + next_node, + sub_node_to_remove, + NULL ); + } + result = -1; + } } } - if( to_remove_previous_node != NULL ) + if( result == 1 ) { - if( libcdata_tree_node_set_next_node( - to_remove_previous_node, - to_remove_next_node, - error ) != 1 ) + if( internal_node->first_sub_node == sub_node_to_remove ) { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_SET_FAILED, - "%s: unable to set next node of previous node.", - function ); - - goto on_error; + internal_node->first_sub_node = next_node; + } + if( internal_node->last_sub_node == sub_node_to_remove ) + { + internal_node->last_sub_node = previous_node; } + internal_node->number_of_sub_nodes -= 1; } - internal_node->number_of_sub_nodes--; - #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) if( libcthreads_read_write_lock_release_for_write( internal_node->read_write_lock, @@ -2844,18 +3759,43 @@ "%s: unable to release read/write lock for writing.", function ); - return( -1 ); + goto on_error; } #endif return( 1 ); -on_error: #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) - libcthreads_read_write_lock_release_for_write( - internal_node->read_write_lock, - NULL ); -#endif +on_error: + if( result == 1 ) + { + libcdata_tree_node_set_nodes( + sub_node_to_remove, + parent_node, + previous_node, + next_node, + NULL ); + + if( next_node != NULL ) + { + libcdata_tree_node_set_previous_node( + next_node, + sub_node_to_remove, + NULL ); + } + if( previous_node != NULL ) + { + libcdata_tree_node_set_next_node( + previous_node, + sub_node_to_remove, + NULL ); + } + internal_node->first_sub_node = backup_first_sub_node; + internal_node->last_sub_node = backup_last_sub_node; + + internal_node->number_of_sub_nodes += 1; + } return( -1 ); +#endif } /* Retrieves the number of sub nodes in the tree node @@ -3098,6 +4038,7 @@ libcdata_internal_tree_node_t *internal_node = NULL; libcdata_tree_node_t *sub_node = NULL; static char *function = "libcdata_tree_node_get_leaf_node_list"; + int leaf_node_list_created_in_node = 0; int sub_node_index = 0; if( node == NULL ) @@ -3154,6 +4095,7 @@ goto on_error; } + leaf_node_list_created_in_node = 1; } /* Traverse the sub nodes */ @@ -3255,6 +4197,15 @@ return( 1 ); on_error: + if( leaf_node_list_created_in_node != 0 ) + { + if( *leaf_node_list == NULL ) + { + libcdata_list_initialize( + leaf_node_list, + NULL ); + } + } #if defined( HAVE_MULTI_THREAD_SUPPORT ) && !defined( HAVE_LOCAL_LIBCDATA ) libcthreads_read_write_lock_release_for_read( internal_node->read_write_lock, diff -Nru libfsapfs-20181215/libcdata/libcdata_tree_node.h libfsapfs-20190210/libcdata/libcdata_tree_node.h --- libfsapfs-20181215/libcdata/libcdata_tree_node.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_tree_node.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * Tree functions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -171,6 +171,28 @@ libcdata_tree_node_t *next_node, libcerror_error_t **error ); +LIBCDATA_EXTERN \ +int libcdata_tree_node_get_first_sub_node( + libcdata_tree_node_t *node, + libcdata_tree_node_t **first_sub_node, + libcerror_error_t **error ); + +int libcdata_internal_tree_node_set_first_sub_node( + libcdata_internal_tree_node_t *internal_node, + libcdata_tree_node_t *first_sub_node, + libcerror_error_t **error ); + +LIBCDATA_EXTERN \ +int libcdata_tree_node_get_last_sub_node( + libcdata_tree_node_t *node, + libcdata_tree_node_t **last_sub_node, + libcerror_error_t **error ); + +int libcdata_internal_tree_node_set_last_sub_node( + libcdata_internal_tree_node_t *internal_node, + libcdata_tree_node_t *last_sub_node, + libcerror_error_t **error ); + int libcdata_tree_node_get_sub_nodes( libcdata_tree_node_t *node, libcdata_tree_node_t **first_sub_node, @@ -185,7 +207,7 @@ int libcdata_internal_tree_node_append_node( libcdata_internal_tree_node_t *internal_node, - libcdata_tree_node_t *sub_node, + libcdata_tree_node_t *node_to_append, libcerror_error_t **error ); LIBCDATA_EXTERN \ @@ -200,14 +222,22 @@ intptr_t *value, libcerror_error_t **error ); -int libcdata_internal_tree_node_insert_node( +int libcdata_internal_tree_node_insert_node_find_sub_node( libcdata_internal_tree_node_t *internal_node, - libcdata_tree_node_t *sub_node, + intptr_t *value_to_insert, int (*value_compare_function)( intptr_t *first_value, intptr_t *second_value, libcerror_error_t **error ), uint8_t insert_flags, + int *sub_node_index, + libcdata_tree_node_t **sub_node, + libcerror_error_t **error ); + +int libcdata_internal_tree_node_insert_node_before_sub_node( + libcdata_internal_tree_node_t *internal_node, + libcdata_tree_node_t *sub_node, + libcdata_tree_node_t *node_to_insert, libcerror_error_t **error ); LIBCDATA_EXTERN \ @@ -241,7 +271,7 @@ LIBCDATA_EXTERN \ int libcdata_tree_node_remove_node( libcdata_tree_node_t *node, - libcdata_tree_node_t *node_to_remove, + libcdata_tree_node_t *sub_node_to_remove, libcerror_error_t **error ); LIBCDATA_EXTERN \ diff -Nru libfsapfs-20181215/libcdata/libcdata_types.h libfsapfs-20190210/libcdata/libcdata_types.h --- libfsapfs-20181215/libcdata/libcdata_types.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_types.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal type definitions * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcdata/libcdata_unused.h libfsapfs-20190210/libcdata/libcdata_unused.h --- libfsapfs-20181215/libcdata/libcdata_unused.h 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/libcdata_unused.h 2019-02-10 19:58:26.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2006-2018, Joachim Metz + * Copyright (C) 2006-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _LIBCDATA_INTERNAL_UNUSED_H ) -#define _LIBCDATA_INTERNAL_UNUSED_H +#if !defined( _LIBCDATA_UNUSED_H ) +#define _LIBCDATA_UNUSED_H #include @@ -40,5 +40,5 @@ /* parameter */ #endif -#endif /* !defined( _LIBCDATA_INTERNAL_UNUSED_H ) */ +#endif /* !defined( _LIBCDATA_UNUSED_H ) */ diff -Nru libfsapfs-20181215/libcdata/Makefile.am libfsapfs-20190210/libcdata/Makefile.am --- libfsapfs-20181215/libcdata/Makefile.am 2018-12-15 06:43:06.000000000 +0000 +++ libfsapfs-20190210/libcdata/Makefile.am 2019-02-10 19:58:26.000000000 +0000 @@ -4,13 +4,15 @@ -I$(top_srcdir)/common \ @LIBCERROR_CPPFLAGS@ \ @LIBCTHREADS_CPPFLAGS@ \ - @PTHREAD_CPPFLAGS@ + @PTHREAD_CPPFLAGS@ noinst_LTLIBRARIES = libcdata.la libcdata_la_SOURCES = \ libcdata_array.c libcdata_array.h \ libcdata_btree.c libcdata_btree.h \ + libcdata_btree_node.c libcdata_btree_node.h \ + libcdata_btree_values_list.c libcdata_btree_values_list.h \ libcdata_definitions.h \ libcdata_error.c libcdata_error.h \ libcdata_extern.h \ diff -Nru libfsapfs-20181215/libcdata/Makefile.in libfsapfs-20190210/libcdata/Makefile.in --- libfsapfs-20181215/libcdata/Makefile.in 2018-12-15 06:44:01.000000000 +0000 +++ libfsapfs-20190210/libcdata/Makefile.in 2019-02-10 19:59:39.000000000 +0000 @@ -121,7 +121,9 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) libcdata_la_LIBADD = am__libcdata_la_SOURCES_DIST = libcdata_array.c libcdata_array.h \ - libcdata_btree.c libcdata_btree.h libcdata_definitions.h \ + libcdata_btree.c libcdata_btree.h libcdata_btree_node.c \ + libcdata_btree_node.h libcdata_btree_values_list.c \ + libcdata_btree_values_list.h libcdata_definitions.h \ libcdata_error.c libcdata_error.h libcdata_extern.h \ libcdata_libcerror.h libcdata_libcthreads.h libcdata_list.c \ libcdata_list.h libcdata_list_element.c \ @@ -131,8 +133,10 @@ libcdata_support.h libcdata_tree_node.c libcdata_tree_node.h \ libcdata_types.h libcdata_unused.h @HAVE_LOCAL_LIBCDATA_TRUE@am_libcdata_la_OBJECTS = libcdata_array.lo \ -@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_btree.lo libcdata_error.lo \ -@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_list.lo \ +@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_btree.lo \ +@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_btree_node.lo \ +@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_btree_values_list.lo \ +@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_error.lo libcdata_list.lo \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_list_element.lo \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_range_list.lo \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_range_list_value.lo \ @@ -160,8 +164,10 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__maybe_remake_depfiles = depfiles am__depfiles_remade = ./$(DEPDIR)/libcdata_array.Plo \ - ./$(DEPDIR)/libcdata_btree.Plo ./$(DEPDIR)/libcdata_error.Plo \ - ./$(DEPDIR)/libcdata_list.Plo \ + ./$(DEPDIR)/libcdata_btree.Plo \ + ./$(DEPDIR)/libcdata_btree_node.Plo \ + ./$(DEPDIR)/libcdata_btree_values_list.Plo \ + ./$(DEPDIR)/libcdata_error.Plo ./$(DEPDIR)/libcdata_list.Plo \ ./$(DEPDIR)/libcdata_list_element.Plo \ ./$(DEPDIR)/libcdata_range_list.Plo \ ./$(DEPDIR)/libcdata_range_list_value.Plo \ @@ -587,12 +593,14 @@ @HAVE_LOCAL_LIBCDATA_TRUE@ -I$(top_srcdir)/common \ @HAVE_LOCAL_LIBCDATA_TRUE@ @LIBCERROR_CPPFLAGS@ \ @HAVE_LOCAL_LIBCDATA_TRUE@ @LIBCTHREADS_CPPFLAGS@ \ -@HAVE_LOCAL_LIBCDATA_TRUE@ @PTHREAD_CPPFLAGS@ +@HAVE_LOCAL_LIBCDATA_TRUE@ @PTHREAD_CPPFLAGS@ @HAVE_LOCAL_LIBCDATA_TRUE@noinst_LTLIBRARIES = libcdata.la @HAVE_LOCAL_LIBCDATA_TRUE@libcdata_la_SOURCES = \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_array.c libcdata_array.h \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_btree.c libcdata_btree.h \ +@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_btree_node.c libcdata_btree_node.h \ +@HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_btree_values_list.c libcdata_btree_values_list.h \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_definitions.h \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_error.c libcdata_error.h \ @HAVE_LOCAL_LIBCDATA_TRUE@ libcdata_extern.h \ @@ -666,6 +674,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdata_array.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdata_btree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdata_btree_node.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdata_btree_values_list.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdata_error.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdata_list.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcdata_list_element.Plo@am__quote@ # am--include-marker @@ -878,6 +888,8 @@ maintainer-clean: maintainer-clean-am -rm -f ./$(DEPDIR)/libcdata_array.Plo -rm -f ./$(DEPDIR)/libcdata_btree.Plo + -rm -f ./$(DEPDIR)/libcdata_btree_node.Plo + -rm -f ./$(DEPDIR)/libcdata_btree_values_list.Plo -rm -f ./$(DEPDIR)/libcdata_error.Plo -rm -f ./$(DEPDIR)/libcdata_list.Plo -rm -f ./$(DEPDIR)/libcdata_list_element.Plo diff -Nru libfsapfs-20181215/libcpath/libcpath_definitions.h libfsapfs-20190210/libcpath/libcpath_definitions.h --- libfsapfs-20181215/libcpath/libcpath_definitions.h 2018-12-15 06:43:23.000000000 +0000 +++ libfsapfs-20190210/libcpath/libcpath_definitions.h 2019-02-10 19:58:52.000000000 +0000 @@ -35,11 +35,11 @@ */ #else -#define LIBCPATH_VERSION 20180720 +#define LIBCPATH_VERSION 20181228 /* The libcpath version string */ -#define LIBCPATH_VERSION_STRING "20180720" +#define LIBCPATH_VERSION_STRING "20181228" #if defined( WINAPI ) #define LIBCPATH_SEPARATOR '\\' @@ -65,6 +65,7 @@ LIBCPATH_TYPE_ABSOLUTE, LIBCPATH_TYPE_DEVICE, LIBCPATH_TYPE_EXTENDED_LENGTH, + LIBCPATH_TYPE_EXTENDED_LENGTH_UNC, LIBCPATH_TYPE_RELATIVE, LIBCPATH_TYPE_UNC }; diff -Nru libfsapfs-20181215/libcpath/libcpath_extern.h libfsapfs-20190210/libcpath/libcpath_extern.h --- libfsapfs-20181215/libcpath/libcpath_extern.h 2018-12-15 06:43:23.000000000 +0000 +++ libfsapfs-20190210/libcpath/libcpath_extern.h 2019-02-10 19:58:52.000000000 +0000 @@ -28,13 +28,6 @@ */ #if !defined( HAVE_LOCAL_LIBCPATH ) -/* If libtool DLL support is enabled set LIBCPATH_DLL_EXPORT - * before including libcpath/extern.h - */ -#if defined( _WIN32 ) && defined( DLL_EXPORT ) -#define LIBCPATH_DLL_EXPORT -#endif - #include #define LIBCPATH_EXTERN_VARIABLE LIBCPATH_EXTERN diff -Nru libfsapfs-20181215/libcpath/libcpath_path.c libfsapfs-20190210/libcpath/libcpath_path.c --- libfsapfs-20181215/libcpath/libcpath_path.c 2018-12-15 06:43:23.000000000 +0000 +++ libfsapfs-20190210/libcpath/libcpath_path.c 2019-02-10 19:58:52.000000000 +0000 @@ -621,7 +621,7 @@ && ( path[ 6 ] == 'C' ) && ( path[ 7 ] == '\\' ) ) { - *path_type = LIBCPATH_TYPE_EXTENDED_LENGTH; + *path_type = LIBCPATH_TYPE_EXTENDED_LENGTH_UNC; } else { @@ -1107,7 +1107,6 @@ size_t path_directory_name_index = 0; size_t path_string_segment_size = 0; size_t safe_full_path_size = 0; - size_t share_name_index = 0; size_t volume_name_length = 0; uint8_t path_type = LIBCPATH_TYPE_RELATIVE; int current_directory_number_of_segments = 0; @@ -1219,6 +1218,7 @@ */ if( ( path_type != LIBCPATH_TYPE_DEVICE ) && ( path_type != LIBCPATH_TYPE_EXTENDED_LENGTH ) + && ( path_type != LIBCPATH_TYPE_EXTENDED_LENGTH_UNC ) && ( path_type != LIBCPATH_TYPE_UNC ) ) { if( libcpath_path_get_current_working_directory_by_volume( @@ -1312,7 +1312,8 @@ /* If the path contains an UNC path * add the size of the UNC\ prefix */ - if( share_name_index > 0 ) + if( ( path_type == LIBCPATH_TYPE_EXTENDED_LENGTH_UNC ) + || ( path_type == LIBCPATH_TYPE_UNC ) ) { safe_full_path_size += 4; } @@ -1675,7 +1676,8 @@ /* If there is a share name the path is an UNC path */ - if( share_name_index > 0 ) + if( ( path_type == LIBCPATH_TYPE_EXTENDED_LENGTH_UNC ) + || ( path_type == LIBCPATH_TYPE_UNC ) ) { if( narrow_string_copy( &( ( *full_path )[ full_path_index ] ), @@ -4078,6 +4080,9 @@ goto on_error; } + memory_free( + narrow_current_working_directory ); + return( 1 ); on_error: @@ -4185,7 +4190,7 @@ && ( path[ 6 ] == (wchar_t) 'C' ) && ( path[ 7 ] == (wchar_t) '\\' ) ) { - *path_type = LIBCPATH_TYPE_EXTENDED_LENGTH; + *path_type = LIBCPATH_TYPE_EXTENDED_LENGTH_UNC; } else { @@ -4666,7 +4671,6 @@ size_t path_directory_name_index = 0; size_t path_string_segment_size = 0; size_t safe_full_path_size = 0; - size_t share_name_index = 0; size_t volume_name_length = 0; uint8_t path_type = LIBCPATH_TYPE_RELATIVE; int current_directory_number_of_segments = 0; @@ -4778,6 +4782,7 @@ */ if( ( path_type != LIBCPATH_TYPE_DEVICE ) && ( path_type != LIBCPATH_TYPE_EXTENDED_LENGTH ) + && ( path_type != LIBCPATH_TYPE_EXTENDED_LENGTH_UNC ) && ( path_type != LIBCPATH_TYPE_UNC ) ) { if( libcpath_path_get_current_working_directory_by_volume_wide( @@ -4873,7 +4878,8 @@ /* If the path contains an UNC path * add the size of the UNC\ prefix */ - if( share_name_index > 0 ) + if( ( path_type == LIBCPATH_TYPE_EXTENDED_LENGTH_UNC ) + || ( path_type == LIBCPATH_TYPE_UNC ) ) { safe_full_path_size += 4; } @@ -5236,7 +5242,8 @@ /* If there is a share name the path is an UNC path */ - if( share_name_index > 0 ) + if( ( path_type == LIBCPATH_TYPE_EXTENDED_LENGTH_UNC ) + || ( path_type == LIBCPATH_TYPE_UNC ) ) { if( wide_string_copy( &( ( *full_path )[ full_path_index ] ), diff -Nru libfsapfs-20181215/libcpath/Makefile.am libfsapfs-20190210/libcpath/Makefile.am --- libfsapfs-20181215/libcpath/Makefile.am 2018-12-15 06:43:23.000000000 +0000 +++ libfsapfs-20190210/libcpath/Makefile.am 2019-02-10 19:58:52.000000000 +0000 @@ -5,7 +5,7 @@ @LIBCERROR_CPPFLAGS@ \ @LIBCLOCALE_CPPFLAGS@ \ @LIBCSPLIT_CPPFLAGS@ \ - @LIBUNA_CPPFLAGS@ + @LIBUNA_CPPFLAGS@ noinst_LTLIBRARIES = libcpath.la diff -Nru libfsapfs-20181215/libcpath/Makefile.in libfsapfs-20190210/libcpath/Makefile.in --- libfsapfs-20181215/libcpath/Makefile.in 2018-12-15 06:44:01.000000000 +0000 +++ libfsapfs-20190210/libcpath/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -574,7 +574,7 @@ @HAVE_LOCAL_LIBCPATH_TRUE@ @LIBCERROR_CPPFLAGS@ \ @HAVE_LOCAL_LIBCPATH_TRUE@ @LIBCLOCALE_CPPFLAGS@ \ @HAVE_LOCAL_LIBCPATH_TRUE@ @LIBCSPLIT_CPPFLAGS@ \ -@HAVE_LOCAL_LIBCPATH_TRUE@ @LIBUNA_CPPFLAGS@ +@HAVE_LOCAL_LIBCPATH_TRUE@ @LIBUNA_CPPFLAGS@ @HAVE_LOCAL_LIBCPATH_TRUE@noinst_LTLIBRARIES = libcpath.la @HAVE_LOCAL_LIBCPATH_TRUE@libcpath_la_SOURCES = \ diff -Nru libfsapfs-20181215/libcsplit/libcsplit_definitions.h libfsapfs-20190210/libcsplit/libcsplit_definitions.h --- libfsapfs-20181215/libcsplit/libcsplit_definitions.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_definitions.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal definitions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -35,11 +35,11 @@ */ #else -#define LIBCSPLIT_VERSION 20180103 +#define LIBCSPLIT_VERSION 20190102 /* The libcsplit version string */ -#define LIBCSPLIT_VERSION_STRING "20180103" +#define LIBCSPLIT_VERSION_STRING "20190102" #endif /* !defined( HAVE_LOCAL_LIBCSPLIT ) */ diff -Nru libfsapfs-20181215/libcsplit/libcsplit_error.c libfsapfs-20190210/libcsplit/libcsplit_error.c --- libfsapfs-20181215/libcsplit/libcsplit_error.c 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_error.c 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_error.h libfsapfs-20190210/libcsplit/libcsplit_error.h --- libfsapfs-20181215/libcsplit/libcsplit_error.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_error.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_extern.h libfsapfs-20190210/libcsplit/libcsplit_extern.h --- libfsapfs-20181215/libcsplit/libcsplit_extern.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_extern.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal extern definition * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -28,17 +28,13 @@ */ #if !defined( HAVE_LOCAL_LIBCSPLIT ) -/* If libtool DLL support is enabled set LIBCSPLIT_DLL_EXPORT - * before including libcsplit/extern.h - */ -#if defined( _WIN32 ) && defined( DLL_EXPORT ) -#define LIBCSPLIT_DLL_EXPORT -#endif - #include +#define LIBCSPLIT_EXTERN_VARIABLE LIBCSPLIT_EXTERN + #else -#define LIBCSPLIT_EXTERN /* extern */ +#define LIBCSPLIT_EXTERN /* extern */ +#define LIBCSPLIT_EXTERN_VARIABLE extern #endif /* !defined( HAVE_LOCAL_LIBCSPLIT ) */ diff -Nru libfsapfs-20181215/libcsplit/libcsplit_libcerror.h libfsapfs-20190210/libcsplit/libcsplit_libcerror.h --- libfsapfs-20181215/libcsplit/libcsplit_libcerror.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_libcerror.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal libcerror header + * The libcerror header wrapper * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_narrow_split_string.c libfsapfs-20190210/libcsplit/libcsplit_narrow_split_string.c --- libfsapfs-20181215/libcsplit/libcsplit_narrow_split_string.c 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_narrow_split_string.c 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Split narrow string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_narrow_split_string.h libfsapfs-20190210/libcsplit/libcsplit_narrow_split_string.h --- libfsapfs-20181215/libcsplit/libcsplit_narrow_split_string.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_narrow_split_string.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Split narrow string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_narrow_string.c libfsapfs-20190210/libcsplit/libcsplit_narrow_string.c --- libfsapfs-20181215/libcsplit/libcsplit_narrow_string.c 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_narrow_string.c 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Narrow character string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -156,7 +156,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize split string.", + "%s: unable to initialize split string.", function ); goto on_error; diff -Nru libfsapfs-20181215/libcsplit/libcsplit_narrow_string.h libfsapfs-20190210/libcsplit/libcsplit_narrow_string.h --- libfsapfs-20181215/libcsplit/libcsplit_narrow_string.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_narrow_string.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Narrow character string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_support.c libfsapfs-20190210/libcsplit/libcsplit_support.c --- libfsapfs-20181215/libcsplit/libcsplit_support.c 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_support.c 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_support.h libfsapfs-20190210/libcsplit/libcsplit_support.h --- libfsapfs-20181215/libcsplit/libcsplit_support.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_support.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_types.h libfsapfs-20190210/libcsplit/libcsplit_types.h --- libfsapfs-20181215/libcsplit/libcsplit_types.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_types.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal type definitions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_unused.h libfsapfs-20190210/libcsplit/libcsplit_unused.h --- libfsapfs-20181215/libcsplit/libcsplit_unused.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_unused.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _LIBCSPLIT_INTERNAL_UNUSED_H ) -#define _LIBCSPLIT_INTERNAL_UNUSED_H +#if !defined( _LIBCSPLIT_UNUSED_H ) +#define _LIBCSPLIT_UNUSED_H #include @@ -40,5 +40,5 @@ /* parameter */ #endif -#endif /* !defined( _LIBCSPLIT_INTERNAL_UNUSED_H ) */ +#endif /* !defined( _LIBCSPLIT_UNUSED_H ) */ diff -Nru libfsapfs-20181215/libcsplit/libcsplit_wide_split_string.c libfsapfs-20190210/libcsplit/libcsplit_wide_split_string.c --- libfsapfs-20181215/libcsplit/libcsplit_wide_split_string.c 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_wide_split_string.c 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Split wide string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_wide_split_string.h libfsapfs-20190210/libcsplit/libcsplit_wide_split_string.h --- libfsapfs-20181215/libcsplit/libcsplit_wide_split_string.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_wide_split_string.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Split wide string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/libcsplit_wide_string.c libfsapfs-20190210/libcsplit/libcsplit_wide_string.c --- libfsapfs-20181215/libcsplit/libcsplit_wide_string.c 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_wide_string.c 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Wide character string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -158,7 +158,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize split string.", + "%s: unable to initialize split string.", function ); goto on_error; diff -Nru libfsapfs-20181215/libcsplit/libcsplit_wide_string.h libfsapfs-20190210/libcsplit/libcsplit_wide_string.h --- libfsapfs-20181215/libcsplit/libcsplit_wide_string.h 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/libcsplit_wide_string.h 2019-02-10 19:58:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Wide character string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libcsplit/Makefile.am libfsapfs-20190210/libcsplit/Makefile.am --- libfsapfs-20181215/libcsplit/Makefile.am 2018-12-15 06:43:25.000000000 +0000 +++ libfsapfs-20190210/libcsplit/Makefile.am 2019-02-10 19:58:54.000000000 +0000 @@ -2,7 +2,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common \ - @LIBCERROR_CPPFLAGS@ + @LIBCERROR_CPPFLAGS@ noinst_LTLIBRARIES = libcsplit.la diff -Nru libfsapfs-20181215/libcsplit/Makefile.in libfsapfs-20190210/libcsplit/Makefile.in --- libfsapfs-20181215/libcsplit/Makefile.in 2018-12-15 06:44:01.000000000 +0000 +++ libfsapfs-20190210/libcsplit/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -581,7 +581,7 @@ @HAVE_LOCAL_LIBCSPLIT_TRUE@AM_CPPFLAGS = \ @HAVE_LOCAL_LIBCSPLIT_TRUE@ -I$(top_srcdir)/include \ @HAVE_LOCAL_LIBCSPLIT_TRUE@ -I$(top_srcdir)/common \ -@HAVE_LOCAL_LIBCSPLIT_TRUE@ @LIBCERROR_CPPFLAGS@ +@HAVE_LOCAL_LIBCSPLIT_TRUE@ @LIBCERROR_CPPFLAGS@ @HAVE_LOCAL_LIBCSPLIT_TRUE@noinst_LTLIBRARIES = libcsplit.la @HAVE_LOCAL_LIBCSPLIT_TRUE@libcsplit_la_SOURCES = \ diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_btree.h libfsapfs-20190210/libfsapfs/fsapfs_btree.h --- libfsapfs-20181215/libfsapfs/fsapfs_btree.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_btree.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS B-tree definition * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_checkpoint_map.h libfsapfs-20190210/libfsapfs/fsapfs_checkpoint_map.h --- libfsapfs-20181215/libfsapfs/fsapfs_checkpoint_map.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_checkpoint_map.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS checkpoint map definition * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_chunk_information_block.h libfsapfs-20190210/libfsapfs/fsapfs_chunk_information_block.h --- libfsapfs-20181215/libfsapfs/fsapfs_chunk_information_block.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_chunk_information_block.h 2019-02-06 20:10:13.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * The APFS chunk information block definition + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _FSAPFS_CHUNK_INFORMATION_BLOCK_H ) +#define _FSAPFS_CHUNK_INFORMATION_BLOCK_H + +#include +#include + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct fsapfs_chunk_information_block fsapfs_chunk_information_block_t; + +struct fsapfs_chunk_information_block +{ + /* The object checksum + * Consists of 8 bytes + */ + uint8_t object_checksum[ 8 ]; + + /* The object identifier + * Consists of 8 bytes + */ + uint8_t object_identifier[ 8 ]; + + /* The object transaction identifier + * Consists of 8 bytes + */ + uint8_t object_transaction_identifier[ 8 ]; + + /* The object type + * Consists of 4 bytes + */ + uint8_t object_type[ 4 ]; + + /* The object subtype + * Consists of 4 bytes + */ + uint8_t object_subtype[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown1[ 4 ]; +}; + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _FSAPFS_CHUNK_INFORMATION_BLOCK_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_container_reaper.h libfsapfs-20190210/libfsapfs/fsapfs_container_reaper.h --- libfsapfs-20181215/libfsapfs/fsapfs_container_reaper.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_container_reaper.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS container reaper definition * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_container_space_manager.h libfsapfs-20190210/libfsapfs/fsapfs_container_space_manager.h --- libfsapfs-20181215/libfsapfs/fsapfs_container_space_manager.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_container_space_manager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,279 +0,0 @@ -/* - * The APFS container space manager definition - * - * Copyright (C) 2018, Joachim Metz - * - * Refer to AUTHORS for acknowledgements. - * - * This software is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this software. If not, see . - */ - -#if !defined( _FSAPFS_CONTAINER_SPACE_MANAGER_H ) -#define _FSAPFS_CONTAINER_SPACE_MANAGER_H - -#include -#include - -#if defined( __cplusplus ) -extern "C" { -#endif - -typedef struct fsapfs_container_space_manager fsapfs_container_space_manager_t; - -struct fsapfs_container_space_manager -{ - /* The object checksum - * Consists of 8 bytes - */ - uint8_t object_checksum[ 8 ]; - - /* The object identifier - * Consists of 8 bytes - */ - uint8_t object_identifier[ 8 ]; - - /* The object transaction identifier - * Consists of 8 bytes - */ - uint8_t object_transaction_identifier[ 8 ]; - - /* The object type - * Consists of 4 bytes - */ - uint8_t object_type[ 4 ]; - - /* The object subtype - * Consists of 4 bytes - */ - uint8_t object_subtype[ 4 ]; - - /* The block size - * Consists of 4 bytes - */ - uint8_t block_size[ 4 ]; - - /* The number of blocks per chunk - * Consists of 4 bytes - */ - uint8_t blocks_per_chunk[ 4 ]; - - /* The number of chunks per CIB - * Consists of 4 bytes - */ - uint8_t chunks_per_cib[ 4 ]; - - /* The number of CIBs per CAB - * Consists of 4 bytes - */ - uint8_t cibs_per_cab[ 4 ]; - - /* The number of blocks - * Consists of 8 bytes - */ - uint8_t number_of_blocks[ 8 ]; - - /* The number of chunks - * Consists of 8 bytes - */ - uint8_t number_of_chunks[ 8 ]; - - /* The number of CIBs - * Consists of 4 bytes - */ - uint8_t number_of_cibs[ 4 ]; - - /* The number of CABs - * Consists of 4 bytes - */ - uint8_t number_of_cabs[ 4 ]; - - /* The number of unsused blocks - * Consists of 8 bytes - */ - uint8_t number_of_unused_blocks[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown1[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown2[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown3[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown4[ 8 ]; - - /* Unknown - * Consists of 4 bytes - */ - uint8_t unknown5[ 4 ]; - - /* Unknown - * Consists of 4 bytes - */ - uint8_t unknown6[ 4 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown7[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown8[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown9[ 8 ]; - - /* Unknown - * Consists of 4 bytes - */ - uint8_t unknown10[ 4 ]; - - /* Unknown - * Consists of 4 bytes - */ - uint8_t unknown11[ 4 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown12[ 8 ]; - - /* Unknown - * Consists of 4 bytes - */ - uint8_t unknown13[ 4 ]; - - /* Unknown - * Consists of 4 bytes - */ - uint8_t unknown14[ 4 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown15[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown16[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown17[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown18[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown19[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown20[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown21[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown22[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown23[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown24[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown25[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown26[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown27[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown28[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown29[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown30[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown31[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown32[ 8 ]; - - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown33[ 8 ]; - -/* TODO add values starting with bitmap_next_array_free */ -}; - -#if defined( __cplusplus ) -} -#endif - -#endif /* !defined( _FSAPFS_CONTAINER_SPACE_MANAGER_H ) */ - diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_container_superblock.h libfsapfs-20190210/libfsapfs/fsapfs_container_superblock.h --- libfsapfs-20181215/libfsapfs/fsapfs_container_superblock.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_container_superblock.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS container superblock definition * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -105,25 +105,25 @@ */ uint8_t next_transaction_identifier[ 8 ]; - /* The metadata area number of blocks + /* The checkpoint descriptor area number of blocks * Consists of 4 bytes */ - uint8_t metadata_area_number_of_blocks[ 4 ]; + uint8_t checkpoint_descriptor_area_number_of_blocks[ 4 ]; - /* Unknown + /* The checkpoint data area number of blocks * Consists of 4 bytes */ - uint8_t unknown5[ 4 ]; + uint8_t checkpoint_data_area_number_of_blocks[ 4 ]; - /* The metadata area block number + /* The checkpoint descriptor area block number * Consists of 8 bytes */ - uint8_t metadata_area_block_number[ 8 ]; + uint8_t checkpoint_descriptor_area_block_number[ 8 ]; - /* Unknown + /* The checkpoint data area block number * Consists of 8 bytes */ - uint8_t unknown7[ 8 ]; + uint8_t checkpoint_data_area_block_number[ 8 ]; /* Unknown * Consists of 4 bytes @@ -185,10 +185,10 @@ */ uint8_t volume_object_identifiers[ 800 ]; - /* Unknown + /* The counters * Consists of 32 x 8 bytes */ - uint8_t unknown19[ 256 ]; + uint8_t counters[ 256 ]; /* Unknown * Consists of 8 bytes @@ -215,15 +215,11 @@ */ uint8_t unknown24[ 8 ]; - /* Unknown - * Consists of 8 bytes - */ - uint8_t unknown25[ 8 ]; - - /* Unknown - * Consists of 8 bytes + /* The Fusion set identifier + * Consists of 16 bytes + * Contains an UUID */ - uint8_t unknown26[ 8 ]; + uint8_t fusion_set_identifier[ 16 ]; /* The key bag block number * Consists of 8 bytes @@ -236,29 +232,34 @@ uint8_t key_bag_number_of_blocks[ 8 ]; /* Unknown - * Consists of 5 x 8 bytes + * Consists of 4 x 8 bytes */ - uint8_t unknown29[ 40 ]; + uint8_t unknown29[ 32 ]; /* Unknown * Consists of 8 bytes */ uint8_t unknown30[ 8 ]; - /* Unknown + /* The Fusion middle tree block number * Consists of 8 bytes */ - uint8_t unknown31[ 8 ]; + uint8_t fusion_middle_tree_block_number[ 8 ]; - /* Unknown + /* The Fusion write-back cache object identifier * Consists of 8 bytes */ - uint8_t unknown32[ 8 ]; + uint8_t fusion_write_back_cache_object_identifier[ 8 ]; /* Unknown * Consists of 8 bytes */ uint8_t unknown33[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown34[ 8 ]; }; #if defined( __cplusplus ) diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_extent_reference_tree.h libfsapfs-20190210/libfsapfs/fsapfs_extent_reference_tree.h --- libfsapfs-20181215/libfsapfs/fsapfs_extent_reference_tree.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_extent_reference_tree.h 2019-02-06 20:10:13.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * The APFS extent reference tree definition + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _FSAPFS_EXTENT_REFERENCE_TREE_H ) +#define _FSAPFS_EXTENT_REFERENCE_TREE_H + +#include +#include + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct fsapfs_extent_reference_tree fsapfs_extent_reference_tree_t; + +struct fsapfs_extent_reference_tree +{ + /* The object checksum + * Consists of 8 bytes + */ + uint8_t object_checksum[ 8 ]; + + /* The object identifier + * Consists of 8 bytes + */ + uint8_t object_identifier[ 8 ]; + + /* The object transaction identifier + * Consists of 8 bytes + */ + uint8_t object_transaction_identifier[ 8 ]; + + /* The object type + * Consists of 4 bytes + */ + uint8_t object_type[ 4 ]; + + /* The object subtype + * Consists of 4 bytes + */ + uint8_t object_subtype[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown1[ 4 ]; +}; + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _FSAPFS_EXTENT_REFERENCE_TREE_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_file_system.h libfsapfs-20190210/libfsapfs/fsapfs_file_system.h --- libfsapfs-20181215/libfsapfs/fsapfs_file_system.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_file_system.h 2019-02-06 20:10:13.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS file system definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_fusion_middle_tree.h libfsapfs-20190210/libfsapfs/fsapfs_fusion_middle_tree.h --- libfsapfs-20181215/libfsapfs/fsapfs_fusion_middle_tree.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_fusion_middle_tree.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,72 @@ +/* + * The APFS Fusion middle tree definition + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _FSAPFS_FUSION_MIDDLE_TREE_H ) +#define _FSAPFS_FUSION_MIDDLE_TREE_H + +#include +#include + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct fsapfs_fusion_middle_tree fsapfs_fusion_middle_tree_t; + +struct fsapfs_fusion_middle_tree +{ + /* The object checksum + * Consists of 8 bytes + */ + uint8_t object_checksum[ 8 ]; + + /* The object identifier + * Consists of 8 bytes + */ + uint8_t object_identifier[ 8 ]; + + /* The object transaction identifier + * Consists of 8 bytes + */ + uint8_t object_transaction_identifier[ 8 ]; + + /* The object type + * Consists of 4 bytes + */ + uint8_t object_type[ 4 ]; + + /* The object subtype + * Consists of 4 bytes + */ + uint8_t object_subtype[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown1[ 4 ]; +}; + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _FSAPFS_FUSION_MIDDLE_TREE_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_key_bag.h libfsapfs-20190210/libfsapfs/fsapfs_key_bag.h --- libfsapfs-20181215/libfsapfs/fsapfs_key_bag.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_key_bag.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS key bag definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_object.h libfsapfs-20190210/libfsapfs/fsapfs_object.h --- libfsapfs-20181215/libfsapfs/fsapfs_object.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_object.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS object definition * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_object_map.h libfsapfs-20190210/libfsapfs/fsapfs_object_map.h --- libfsapfs-20181215/libfsapfs/fsapfs_object_map.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_object_map.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS object map definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -58,40 +58,50 @@ */ uint8_t object_subtype[ 4 ]; - /* Unknown + /* The flags * Consists of 4 bytes */ - uint8_t unknown1[ 4 ]; + uint8_t flags[ 4 ]; - /* Unknown + /* The number of snapshots * Consists of 4 bytes */ - uint8_t unknown2[ 4 ]; + uint8_t number_of_snapshots[ 4 ]; - /* Unknown + /* The B-tree type * Consists of 4 bytes */ - uint8_t unknown3[ 4 ]; + uint8_t btree_type[ 4 ]; - /* Unknown + /* The snapshots B-tree type * Consists of 4 bytes */ - uint8_t unknown4[ 4 ]; + uint8_t snaphots_btree_type[ 4 ]; - /* The object map B-tree block number + /* The B-tree block number + * Consists of 8 bytes + */ + uint8_t btree_block_number[ 8 ]; + + /* The snapshots B-tree block number + * Consists of 8 bytes + */ + uint8_t snapshots_btree_block_number[ 8 ]; + + /* Unknown * Consists of 8 bytes */ - uint8_t object_map_btree_block_number[ 8 ]; + uint8_t unknown1[ 8 ]; /* Unknown * Consists of 8 bytes */ - uint8_t unknown6[ 8 ]; + uint8_t unknown2[ 8 ]; /* Unknown * Consists of 8 bytes */ - uint8_t unknown7[ 8 ]; + uint8_t unknown3[ 8 ]; }; typedef struct fsapfs_object_map_btree_key fsapfs_object_map_btree_key_t; diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_snapshot_metadata.h libfsapfs-20190210/libfsapfs/fsapfs_snapshot_metadata.h --- libfsapfs-20181215/libfsapfs/fsapfs_snapshot_metadata.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_snapshot_metadata.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,96 @@ +/* + * The APFS snapshot metadata definitions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _FSAPFS_SNAPSHOT_METADATA_H ) +#define _FSAPFS_SNAPSHOT_METADATA_H + +#include +#include + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct fsapfs_snapshot_metadata_btree_key fsapfs_snapshot_metadata_btree_key_t; + +struct fsapfs_snapshot_metadata_btree_key +{ + /* The key object identifier + * Consists of 8 bytes + */ + uint8_t object_identifier[ 8 ]; +}; + +typedef struct fsapfs_snapshot_metadata_btree_value fsapfs_snapshot_metadata_btree_value_t; + +struct fsapfs_snapshot_metadata_btree_value +{ + /* The extent-reference tree object identifier + * Consists of 8 bytes + */ + uint8_t extent_reference_tree_object_identifier[ 8 ]; + + /* The volume superblock tree object identifier + * Consists of 8 bytes + */ + uint8_t volume_superblock_object_identifier[ 8 ]; + + /* The creation date and time + * Consists of 8 bytes + */ + uint8_t creation_time[ 8 ]; + + /* The change date and time + * Consists of 8 bytes + */ + uint8_t change_time[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown1[ 8 ]; + + /* The extent-reference tree object type + * Consists of 8 bytes + */ + uint8_t extent_reference_tree_object_type[ 4 ]; + + /* The flags + * Consists of 4 bytes + */ + uint8_t flags[ 4 ]; + + /* The name size + * Consists of 2 bytes + */ + uint8_t name_size[ 2 ]; + + /* The name string + * Contains an UTF-8 string with end-of-string character + */ +}; + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _FSAPFS_SNAPSHOT_METADATA_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_space_manager.h libfsapfs-20190210/libfsapfs/fsapfs_space_manager.h --- libfsapfs-20181215/libfsapfs/fsapfs_space_manager.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_space_manager.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,332 @@ +/* + * The APFS space manager definition + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _FSAPFS_SPACE_MANAGER_H ) +#define _FSAPFS_SPACE_MANAGER_H + +#include +#include + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct fsapfs_space_manager fsapfs_space_manager_t; + +struct fsapfs_space_manager +{ + /* The object checksum + * Consists of 8 bytes + */ + uint8_t object_checksum[ 8 ]; + + /* The object identifier + * Consists of 8 bytes + */ + uint8_t object_identifier[ 8 ]; + + /* The object transaction identifier + * Consists of 8 bytes + */ + uint8_t object_transaction_identifier[ 8 ]; + + /* The object type + * Consists of 4 bytes + */ + uint8_t object_type[ 4 ]; + + /* The object subtype + * Consists of 4 bytes + */ + uint8_t object_subtype[ 4 ]; + + /* The block size + * Consists of 4 bytes + */ + uint8_t block_size[ 4 ]; + + /* The number of blocks per chunk + * Consists of 4 bytes + */ + uint8_t blocks_per_chunk[ 4 ]; + + /* The number of chunks per CIB + * Consists of 4 bytes + */ + uint8_t chunks_per_cib[ 4 ]; + + /* The number of CIBs per CAB + * Consists of 4 bytes + */ + uint8_t cibs_per_cab[ 4 ]; + + /* The number of blocks of the main device + * Consists of 8 bytes + */ + uint8_t main_device_number_of_blocks[ 8 ]; + + /* The number of chunks of the main device + * Consists of 8 bytes + */ + uint8_t main_device_number_of_chunks[ 8 ]; + + /* The number of CIBs of the main device + * Consists of 4 bytes + */ + uint8_t main_device_number_of_cibs[ 4 ]; + + /* The number of CABs of the main device + * Consists of 4 bytes + */ + uint8_t main_device_number_of_cabs[ 4 ]; + + /* The number of unsused blocks of the main device + * Consists of 8 bytes + */ + uint8_t main_device_number_of_unused_blocks[ 8 ]; + + /* The offset of the main device + * Consists of 4 bytes + */ + uint8_t main_device_offset[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown1[ 4 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown2[ 8 ]; + + /* The number of blocks of the tier2 device + * Consists of 8 bytes + */ + uint8_t tier2_device_number_of_blocks[ 8 ]; + + /* The number of chunks of the tier2 device + * Consists of 8 bytes + */ + uint8_t tier2_device_number_of_chunks[ 8 ]; + + /* The number of CIBs of the tier2 device + * Consists of 4 bytes + */ + uint8_t tier2_device_number_of_cibs[ 4 ]; + + /* The number of CABs of the tier2 device + * Consists of 4 bytes + */ + uint8_t tier2_device_number_of_cabs[ 4 ]; + + /* The number of unsused blocks of the tier2 device + * Consists of 8 bytes + */ + uint8_t tier2_device_number_of_unused_blocks[ 8 ]; + + /* The offset of the tier2 device + * Consists of 4 bytes + */ + uint8_t tier2_device_offset[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown8[ 4 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown9[ 8 ]; + + /* The flags + * Consists of 4 bytes + */ + uint8_t flags[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown11[ 4 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown12[ 8 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown13[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown14[ 4 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown15[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown16[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown17[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown18[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown19[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown20[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown21[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown22[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown23[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown24[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown25[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown26[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown27[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown28[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown29[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown30[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown31[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown32[ 8 ]; + + /* Unknown + * Consists of 8 bytes + */ + uint8_t unknown33[ 8 ]; + + /* Unknown + * Consists of 2 bytes + */ + uint8_t unknown34[ 2 ]; + + /* Unknown + * Consists of 2 bytes + */ + uint8_t unknown35[ 2 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown36[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown37[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown38[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown39[ 4 ]; + + /* Unknown + * Consists of 4 bytes + */ + uint8_t unknown40[ 4 ]; + + /* The main allocation zones + * Consists of 8 x 72 bytes + */ + uint8_t unknown41[ 8 * 72 ]; + + /* The tier2 allocation zones + * Consists of 8 x 72 bytes + */ + uint8_t unknown42[ 8 * 72 ]; +}; + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _FSAPFS_SPACE_MANAGER_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/fsapfs_volume_superblock.h libfsapfs-20190210/libfsapfs/fsapfs_volume_superblock.h --- libfsapfs-20181215/libfsapfs/fsapfs_volume_superblock.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/fsapfs_volume_superblock.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS volume superblock definition * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -129,10 +129,10 @@ */ uint8_t file_system_root_tree_object_type[ 4 ]; - /* Unknown - * Consists of 4 bytes + /* The extent-reference tree object type + * Consists of 8 bytes */ - uint8_t unknown14[ 4 ]; + uint8_t extent_reference_tree_object_type[ 4 ]; /* The snapshot metadata tree object type * Consists of 4 bytes @@ -149,15 +149,15 @@ */ uint8_t file_system_root_object_identifier[ 8 ]; - /* Unknown + /* The extent-reference tree block number * Consists of 8 bytes */ - uint8_t unknown18[ 8 ]; + uint8_t extent_reference_tree_block_number[ 8 ]; - /* Unknown + /* The snapshot metadata tree block number * Consists of 8 bytes */ - uint8_t unknown19[ 8 ]; + uint8_t snapshot_metadata_tree_block_number[ 8 ]; /* Unknown * Consists of 8 bytes diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_entry.c libfsapfs-20190210/libfsapfs/libfsapfs_btree_entry.c --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_entry.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_entry.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_entry.h libfsapfs-20190210/libfsapfs/libfsapfs_btree_entry.h --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_entry.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_entry.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_footer.c libfsapfs-20190210/libfsapfs/libfsapfs_btree_footer.c --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_footer.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_footer.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree footer functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_footer.h libfsapfs-20190210/libfsapfs/libfsapfs_btree_footer.h --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_footer.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_footer.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree footer functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_node.c libfsapfs-20190210/libfsapfs/libfsapfs_btree_node.c --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_node.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_node.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree node functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_node.h libfsapfs-20190210/libfsapfs/libfsapfs_btree_node.h --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_node.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_node.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree node functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_node_header.c libfsapfs-20190210/libfsapfs/libfsapfs_btree_node_header.c --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_node_header.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_node_header.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree node header functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_btree_node_header.h libfsapfs-20190210/libfsapfs/libfsapfs_btree_node_header.h --- libfsapfs-20181215/libfsapfs/libfsapfs_btree_node_header.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_btree_node_header.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The B-tree node header functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_buffer_data_handle.c libfsapfs-20190210/libfsapfs/libfsapfs_buffer_data_handle.c --- libfsapfs-20181215/libfsapfs/libfsapfs_buffer_data_handle.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_buffer_data_handle.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The buffer data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_buffer_data_handle.h libfsapfs-20190210/libfsapfs/libfsapfs_buffer_data_handle.h --- libfsapfs-20181215/libfsapfs/libfsapfs_buffer_data_handle.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_buffer_data_handle.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The buffer data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs.c libfsapfs-20190210/libfsapfs/libfsapfs.c --- libfsapfs-20181215/libfsapfs/libfsapfs.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library to access the Apple File System (APFS) format * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map.c libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map.c --- libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The checkpoint map functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -485,6 +485,15 @@ goto on_error; } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: entry: %" PRIu32 "\n", + function, + map_entry_index ); + } +#endif if( libfsapfs_checkpoint_map_entry_read_data( map_entry, &( data[ data_offset ] ), diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map_entry.c libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map_entry.c --- libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map_entry.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map_entry.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The checkpoint map entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map_entry.h libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map_entry.h --- libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map_entry.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map_entry.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The checkpoint map entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map.h libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map.h --- libfsapfs-20181215/libfsapfs/libfsapfs_checkpoint_map.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_checkpoint_map.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The checkpoint map functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_checksum.c libfsapfs-20190210/libfsapfs/libfsapfs_checksum.c --- libfsapfs-20181215/libfsapfs/libfsapfs_checksum.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_checksum.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Checksum functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_checksum.h libfsapfs-20190210/libfsapfs/libfsapfs_checksum.h --- libfsapfs-20181215/libfsapfs/libfsapfs_checksum.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_checksum.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Checksum functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_chunk_information_block.c libfsapfs-20190210/libfsapfs/libfsapfs_chunk_information_block.c --- libfsapfs-20181215/libfsapfs/libfsapfs_chunk_information_block.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_chunk_information_block.c 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,372 @@ +/* + * The chunk information block functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include + +#include "libfsapfs_chunk_information_block.h" +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" +#include "libfsapfs_libcnotify.h" + +#include "fsapfs_chunk_information_block.h" + +/* Creates a chunk information block + * Make sure the value chunk_information_block is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int libfsapfs_chunk_information_block_initialize( + libfsapfs_chunk_information_block_t **chunk_information_block, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_chunk_information_block_initialize"; + + if( chunk_information_block == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid chunk information block.", + function ); + + return( -1 ); + } + if( *chunk_information_block != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid chunk information block value already set.", + function ); + + return( -1 ); + } + *chunk_information_block = memory_allocate_structure( + libfsapfs_chunk_information_block_t ); + + if( *chunk_information_block == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create chunk information block.", + function ); + + goto on_error; + } + if( memory_set( + *chunk_information_block, + 0, + sizeof( libfsapfs_chunk_information_block_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear chunk information block.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( *chunk_information_block != NULL ) + { + memory_free( + *chunk_information_block ); + + *chunk_information_block = NULL; + } + return( -1 ); +} + +/* Frees a chunk information block + * Returns 1 if successful or -1 on error + */ +int libfsapfs_chunk_information_block_free( + libfsapfs_chunk_information_block_t **chunk_information_block, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_chunk_information_block_free"; + + if( chunk_information_block == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid chunk information block.", + function ); + + return( -1 ); + } + if( *chunk_information_block != NULL ) + { + memory_free( + *chunk_information_block ); + + *chunk_information_block = NULL; + } + return( 1 ); +} + +/* Reads the chunk information block + * Returns 1 if successful or -1 on error + */ +int libfsapfs_chunk_information_block_read_file_io_handle( + libfsapfs_chunk_information_block_t *chunk_information_block, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ) +{ + uint8_t chunk_information_block_data[ 4096 ]; + + static char *function = "libfsapfs_chunk_information_block_read_file_io_handle"; + ssize_t read_count = 0; + + if( chunk_information_block == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid chunk information block.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: reading chunk information block at offset: %" PRIi64 " (0x%08" PRIx64 ")\n", + function, + file_offset, + file_offset ); + } +#endif + if( libbfio_handle_seek_offset( + file_io_handle, + file_offset, + SEEK_SET, + error ) == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_SEEK_FAILED, + "%s: unable to seek chunk information block offset: %" PRIi64 " (0x%08" PRIx64 ").", + function, + file_offset, + file_offset ); + + return( -1 ); + } + read_count = libbfio_handle_read_buffer( + file_io_handle, + chunk_information_block_data, + 4096, + error ); + + if( read_count != (ssize_t) 4096 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read chunk information block data.", + function ); + + return( -1 ); + } + if( libfsapfs_chunk_information_block_read_data( + chunk_information_block, + chunk_information_block_data, + 4096, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read chunk information block data.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Reads the chunk information block + * Returns 1 if successful or -1 on error + */ +int libfsapfs_chunk_information_block_read_data( + libfsapfs_chunk_information_block_t *chunk_information_block, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_chunk_information_block_read_data"; + uint32_t object_subtype = 0; + uint32_t object_type = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + uint64_t value_64bit = 0; + uint32_t value_32bit = 0; +#endif + + if( chunk_information_block == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid chunk information block.", + function ); + + return( -1 ); + } + if( data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data.", + function ); + + return( -1 ); + } + if( ( data_size < sizeof( fsapfs_chunk_information_block_t ) ) + || ( data_size > (size_t) SSIZE_MAX ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid data size value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: chunk information block data:\n", + function ); + libcnotify_print_data( + data, + data_size, + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + } +#endif + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_chunk_information_block_t *) data )->object_type, + object_type ); + + if( object_type != 0x40000007UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object type: 0x%08" PRIx32 ".", + function, + object_type ); + + return( -1 ); + } + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_chunk_information_block_t *) data )->object_subtype, + object_subtype ); + + if( object_subtype != 0x00000000UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object subtype: 0x%08" PRIx32 ".", + function, + object_subtype ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_chunk_information_block_t *) data )->object_checksum, + value_64bit ); + libcnotify_printf( + "%s: object checksum\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_chunk_information_block_t *) data )->object_identifier, + value_64bit ); + libcnotify_printf( + "%s: object identifier\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_chunk_information_block_t *) data )->object_transaction_identifier, + value_64bit ); + libcnotify_printf( + "%s: object transaction identifier\t: %" PRIu64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "%s: object type\t\t\t\t: 0x%08" PRIx32 "\n", + function, + object_type ); + + libcnotify_printf( + "%s: object subtype\t\t\t: 0x%08" PRIx32 "\n", + function, + object_subtype ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_chunk_information_block_t *) data )->unknown1, + value_32bit ); + libcnotify_printf( + "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + libcnotify_printf( + "\n" ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + + return( 1 ); +} + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_chunk_information_block.h libfsapfs-20190210/libfsapfs/libfsapfs_chunk_information_block.h --- libfsapfs-20181215/libfsapfs/libfsapfs_chunk_information_block.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_chunk_information_block.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * The chunk information block functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBFSAPFS_CHUNK_INFORMATION_BLOCK_H ) +#define _LIBFSAPFS_CHUNK_INFORMATION_BLOCK_H + +#include +#include + +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct libfsapfs_chunk_information_block libfsapfs_chunk_information_block_t; + +struct libfsapfs_chunk_information_block +{ + /* Dummy + */ + int dummy; +}; + +int libfsapfs_chunk_information_block_initialize( + libfsapfs_chunk_information_block_t **chunk_information_block, + libcerror_error_t **error ); + +int libfsapfs_chunk_information_block_free( + libfsapfs_chunk_information_block_t **chunk_information_block, + libcerror_error_t **error ); + +int libfsapfs_chunk_information_block_read_file_io_handle( + libfsapfs_chunk_information_block_t *chunk_information_block, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ); + +int libfsapfs_chunk_information_block_read_data( + libfsapfs_chunk_information_block_t *chunk_information_block, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBFSAPFS_CHUNK_INFORMATION_BLOCK_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_compressed_data_handle.c libfsapfs-20190210/libfsapfs/libfsapfs_compressed_data_handle.c --- libfsapfs-20181215/libfsapfs/libfsapfs_compressed_data_handle.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_compressed_data_handle.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The compressed data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_compressed_data_handle.h libfsapfs-20190210/libfsapfs/libfsapfs_compressed_data_handle.h --- libfsapfs-20181215/libfsapfs/libfsapfs_compressed_data_handle.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_compressed_data_handle.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The compressed data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_compression.c libfsapfs-20190210/libfsapfs/libfsapfs_compression.c --- libfsapfs-20181215/libfsapfs/libfsapfs_compression.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_compression.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Compression functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_compression.h libfsapfs-20190210/libfsapfs/libfsapfs_compression.h --- libfsapfs-20181215/libfsapfs/libfsapfs_compression.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_compression.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Compression functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container.c libfsapfs-20190210/libfsapfs/libfsapfs_container.c --- libfsapfs-20181215/libfsapfs/libfsapfs_container.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Container functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -30,10 +30,11 @@ #include "libfsapfs_container_data_handle.h" #include "libfsapfs_container_key_bag.h" #include "libfsapfs_container_reaper.h" -#include "libfsapfs_container_space_manager.h" +#include "libfsapfs_space_manager.h" #include "libfsapfs_container_superblock.h" #include "libfsapfs_debug.h" #include "libfsapfs_definitions.h" +#include "libfsapfs_fusion_middle_tree.h" #include "libfsapfs_io_handle.h" #include "libfsapfs_libbfio.h" #include "libfsapfs_libcerror.h" @@ -129,7 +130,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -911,6 +912,22 @@ result = -1; } } + if( internal_container->fusion_middle_tree != NULL ) + { + if( libfsapfs_fusion_middle_tree_free( + &( internal_container->fusion_middle_tree ), + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free Fusion middle tree.", + function ); + + result = -1; + } + } if( internal_container->checkpoint_map != NULL ) { if( libfsapfs_checkpoint_map_free( @@ -999,23 +1016,23 @@ off64_t file_offset, libcerror_error_t **error ) { - libfsapfs_container_data_handle_t *container_data_handle = NULL; - libfsapfs_container_superblock_t *container_superblock = NULL; - libfsapfs_container_superblock_t *container_superblock_swap = NULL; - libfsapfs_object_t *object = NULL; - libfsapfs_object_map_t *object_map = NULL; - static char *function = "libfsapfs_internal_container_open_read"; - uint64_t checkpoint_map_block_number = 0; - uint64_t checkpoint_map_transaction_identifier = 0; - uint64_t metadata_block_index = 0; - int element_index = 0; + libfsapfs_container_data_handle_t *container_data_handle = NULL; + libfsapfs_container_superblock_t *container_superblock = NULL; + libfsapfs_container_superblock_t *container_superblock_swap = NULL; + libfsapfs_object_t *object = NULL; + libfsapfs_object_map_t *object_map = NULL; + static char *function = "libfsapfs_internal_container_open_read"; + uint64_t checkpoint_map_block_number = 0; + uint64_t checkpoint_map_transaction_identifier = 0; + uint64_t metadata_block_index = 0; + int element_index = 0; #if defined( HAVE_DEBUG_OUTPUT ) - libfsapfs_checkpoint_map_t *checkpoint_map = NULL; - libfsapfs_container_reaper_t *container_reaper = NULL; - libfsapfs_container_space_manager_t *container_space_manager = NULL; - uint64_t reaper_block_number = 0; - uint64_t space_manager_block_number = 0; + libfsapfs_checkpoint_map_t *checkpoint_map = NULL; + libfsapfs_container_reaper_t *container_reaper = NULL; + libfsapfs_space_manager_t *space_manager = NULL; + uint64_t reaper_block_number = 0; + uint64_t space_manager_block_number = 0; #endif if( internal_container == NULL ) @@ -1051,6 +1068,17 @@ return( -1 ); } + if( internal_container->fusion_middle_tree != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid container - Fusion middle tree value already set.", + function ); + + return( -1 ); + } if( internal_container->checkpoint_map != NULL ) { libcerror_error_set( @@ -1135,11 +1163,24 @@ internal_container->io_handle->block_size = internal_container->superblock->block_size; internal_container->io_handle->container_size = (size64_t) internal_container->superblock->number_of_blocks * (size64_t) internal_container->io_handle->block_size; +#if !defined( HAVE_DEBUG_OUTPUT ) + if( ( internal_container->superblock->incompatible_features_flags & 0x0000000000000100UL ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: Fusion drive not supported.", + function ); + + return( -1 ); + } +#endif #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( - "Scanning metadata area:\n" ); + "Scanning checkpoint descriptor area:\n" ); } #endif if( libfsapfs_object_initialize( @@ -1155,10 +1196,10 @@ goto on_error; } - file_offset = internal_container->superblock->metadata_area_block_number * internal_container->io_handle->block_size; + file_offset = internal_container->superblock->checkpoint_descriptor_area_block_number * internal_container->io_handle->block_size; for( metadata_block_index = 0; - metadata_block_index <= internal_container->superblock->metadata_area_number_of_blocks; + metadata_block_index <= internal_container->superblock->checkpoint_descriptor_area_number_of_blocks; metadata_block_index++ ) { if( libfsapfs_object_read_file_io_handle( @@ -1231,10 +1272,10 @@ goto on_error; } } -#endif +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ if( object->transaction_identifier > checkpoint_map_transaction_identifier ) { - checkpoint_map_block_number = internal_container->superblock->metadata_area_block_number + metadata_block_index; + checkpoint_map_block_number = internal_container->superblock->checkpoint_descriptor_area_block_number + metadata_block_index; checkpoint_map_transaction_identifier = object->transaction_identifier; } break; @@ -1316,6 +1357,17 @@ goto on_error; } + if( checkpoint_map_block_number == 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: missing checkpoint map block number.", + function ); + + goto on_error; + } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { @@ -1358,6 +1410,44 @@ #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { + if( internal_container->superblock->fusion_middle_tree_block_number != 0 ) + { + libcnotify_printf( + "Reading Fusion middle tree:\n" ); + + file_offset = internal_container->superblock->fusion_middle_tree_block_number * internal_container->io_handle->block_size; + + if( libfsapfs_fusion_middle_tree_initialize( + &( internal_container->fusion_middle_tree ), + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create Fusion middle tree.", + function ); + + goto on_error; + } + if( libfsapfs_fusion_middle_tree_read_file_io_handle( + internal_container->fusion_middle_tree, + file_io_handle, + file_offset, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read Fusion middle tree at offset: %" PRIi64 " (0x%08" PRIx64 ").", + function, + file_offset, + file_offset ); + + goto on_error; + } + } if( internal_container->superblock->space_manager_object_identifier > 0 ) { libcnotify_printf( @@ -1381,21 +1471,21 @@ } file_offset = space_manager_block_number * internal_container->io_handle->block_size; - if( libfsapfs_container_space_manager_initialize( - &container_space_manager, + if( libfsapfs_space_manager_initialize( + &space_manager, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to create container space manager.", + "%s: unable to create space manager.", function ); goto on_error; } - if( libfsapfs_container_space_manager_read_file_io_handle( - container_space_manager, + if( libfsapfs_space_manager_read_file_io_handle( + space_manager, file_io_handle, file_offset, error ) != 1 ) @@ -1404,22 +1494,22 @@ error, LIBCERROR_ERROR_DOMAIN_IO, LIBCERROR_IO_ERROR_READ_FAILED, - "%s: unable to read container space manager at offset: %" PRIi64 " (0x%08" PRIx64 ").", + "%s: unable to read space manager at offset: %" PRIi64 " (0x%08" PRIx64 ").", function, file_offset, file_offset ); goto on_error; } - if( libfsapfs_container_space_manager_free( - &container_space_manager, + if( libfsapfs_space_manager_free( + &space_manager, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, - "%s: unable to free container space manager.", + "%s: unable to free space manager.", function ); goto on_error; @@ -1601,7 +1691,7 @@ goto on_error; } - if( object_map->object_map_btree_block_number == 0 ) + if( object_map->btree_block_number == 0 ) { libcerror_error_set( error, @@ -1623,7 +1713,7 @@ &( internal_container->object_map_btree ), internal_container->io_handle, internal_container->data_block_vector, - object_map->object_map_btree_block_number, + object_map->btree_block_number, error ) != 1 ) { libcerror_error_set( @@ -1721,10 +1811,10 @@ &container_reaper, NULL ); } - if( container_space_manager != NULL ) + if( space_manager != NULL ) { - libfsapfs_container_space_manager_free( - &container_space_manager, + libfsapfs_space_manager_free( + &space_manager, NULL ); } #endif @@ -1748,6 +1838,12 @@ NULL ); } #endif + if( internal_container->fusion_middle_tree != NULL ) + { + libfsapfs_fusion_middle_tree_free( + &( internal_container->fusion_middle_tree ), + NULL ); + } if( object != NULL ) { libfsapfs_object_free( diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_data_handle.c libfsapfs-20190210/libfsapfs/libfsapfs_container_data_handle.c --- libfsapfs-20181215/libfsapfs/libfsapfs_container_data_handle.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_data_handle.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_data_handle.h libfsapfs-20190210/libfsapfs/libfsapfs_container_data_handle.h --- libfsapfs-20181215/libfsapfs/libfsapfs_container_data_handle.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_data_handle.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container.h libfsapfs-20190210/libfsapfs/libfsapfs_container.h --- libfsapfs-20181215/libfsapfs/libfsapfs_container.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Container functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -30,6 +30,7 @@ #include "libfsapfs_container_key_bag.h" #include "libfsapfs_container_superblock.h" #include "libfsapfs_extern.h" +#include "libfsapfs_fusion_middle_tree.h" #include "libfsapfs_io_handle.h" #include "libfsapfs_libbfio.h" #include "libfsapfs_libcerror.h" @@ -50,6 +51,10 @@ */ libfsapfs_container_superblock_t *superblock; + /* The Fusion middle tree + */ + libfsapfs_fusion_middle_tree_t *fusion_middle_tree; + /* The checkpoint map */ libfsapfs_checkpoint_map_t *checkpoint_map; @@ -62,7 +67,7 @@ */ libfdata_vector_t *data_block_vector; - /* The container object map B-tree + /* The object map B-tree */ libfsapfs_object_map_btree_t *object_map_btree; diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_key_bag.c libfsapfs-20190210/libfsapfs/libfsapfs_container_key_bag.c --- libfsapfs-20181215/libfsapfs/libfsapfs_container_key_bag.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_key_bag.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container key bag functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_key_bag.h libfsapfs-20190210/libfsapfs/libfsapfs_container_key_bag.h --- libfsapfs-20181215/libfsapfs/libfsapfs_container_key_bag.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_key_bag.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container key bag functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_reaper.c libfsapfs-20190210/libfsapfs/libfsapfs_container_reaper.c --- libfsapfs-20181215/libfsapfs/libfsapfs_container_reaper.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_reaper.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container reaper functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_reaper.h libfsapfs-20190210/libfsapfs/libfsapfs_container_reaper.h --- libfsapfs-20181215/libfsapfs/libfsapfs_container_reaper.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_reaper.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container reaper functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_space_manager.c libfsapfs-20190210/libfsapfs/libfsapfs_container_space_manager.c --- libfsapfs-20181215/libfsapfs/libfsapfs_container_space_manager.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_space_manager.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,700 +0,0 @@ -/* - * The container space manager functions - * - * Copyright (C) 2018, Joachim Metz - * - * Refer to AUTHORS for acknowledgements. - * - * This software is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this software. If not, see . - */ - -#include -#include -#include -#include - -#include "libfsapfs_container_space_manager.h" -#include "libfsapfs_libbfio.h" -#include "libfsapfs_libcerror.h" -#include "libfsapfs_libcnotify.h" - -#include "fsapfs_container_space_manager.h" - -/* Creates a container space manager - * Make sure the value container_space_manager is referencing, is set to NULL - * Returns 1 if successful or -1 on error - */ -int libfsapfs_container_space_manager_initialize( - libfsapfs_container_space_manager_t **container_space_manager, - libcerror_error_t **error ) -{ - static char *function = "libfsapfs_container_space_manager_initialize"; - - if( container_space_manager == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid container space manager.", - function ); - - return( -1 ); - } - if( *container_space_manager != NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, - "%s: invalid container space manager value already set.", - function ); - - return( -1 ); - } - *container_space_manager = memory_allocate_structure( - libfsapfs_container_space_manager_t ); - - if( *container_space_manager == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_INSUFFICIENT, - "%s: unable to create container space manager.", - function ); - - goto on_error; - } - if( memory_set( - *container_space_manager, - 0, - sizeof( libfsapfs_container_space_manager_t ) ) == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_SET_FAILED, - "%s: unable to clear container space manager.", - function ); - - goto on_error; - } - return( 1 ); - -on_error: - if( *container_space_manager != NULL ) - { - memory_free( - *container_space_manager ); - - *container_space_manager = NULL; - } - return( -1 ); -} - -/* Frees a container space manager - * Returns 1 if successful or -1 on error - */ -int libfsapfs_container_space_manager_free( - libfsapfs_container_space_manager_t **container_space_manager, - libcerror_error_t **error ) -{ - static char *function = "libfsapfs_container_space_manager_free"; - - if( container_space_manager == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid container space manager.", - function ); - - return( -1 ); - } - if( *container_space_manager != NULL ) - { - memory_free( - *container_space_manager ); - - *container_space_manager = NULL; - } - return( 1 ); -} - -/* Reads the container space manager - * Returns 1 if successful or -1 on error - */ -int libfsapfs_container_space_manager_read_file_io_handle( - libfsapfs_container_space_manager_t *container_space_manager, - libbfio_handle_t *file_io_handle, - off64_t file_offset, - libcerror_error_t **error ) -{ - fsapfs_container_space_manager_t container_space_manager_data; - - static char *function = "libfsapfs_container_space_manager_read_file_io_handle"; - ssize_t read_count = 0; - - if( container_space_manager == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid container space manager.", - function ); - - return( -1 ); - } -#if defined( HAVE_DEBUG_OUTPUT ) - if( libcnotify_verbose != 0 ) - { - libcnotify_printf( - "%s: reading container space manager at offset: %" PRIi64 " (0x%08" PRIx64 ")\n", - function, - file_offset, - file_offset ); - } -#endif - if( libbfio_handle_seek_offset( - file_io_handle, - file_offset, - SEEK_SET, - error ) == -1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_IO, - LIBCERROR_IO_ERROR_SEEK_FAILED, - "%s: unable to seek container space manager offset: %" PRIi64 " (0x%08" PRIx64 ").", - function, - file_offset, - file_offset ); - - return( -1 ); - } - read_count = libbfio_handle_read_buffer( - file_io_handle, - (uint8_t *) &container_space_manager_data, - sizeof( fsapfs_container_space_manager_t ), - error ); - - if( read_count != (ssize_t) sizeof( fsapfs_container_space_manager_t ) ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_IO, - LIBCERROR_IO_ERROR_READ_FAILED, - "%s: unable to read container space manager data.", - function ); - - return( -1 ); - } - if( libfsapfs_container_space_manager_read_data( - container_space_manager, - (uint8_t *) &container_space_manager_data, - sizeof( fsapfs_container_space_manager_t ), - error ) != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_IO, - LIBCERROR_IO_ERROR_READ_FAILED, - "%s: unable to read container space manager data.", - function ); - - return( -1 ); - } - return( 1 ); -} - -/* Reads the container space manager - * Returns 1 if successful or -1 on error - */ -int libfsapfs_container_space_manager_read_data( - libfsapfs_container_space_manager_t *container_space_manager, - const uint8_t *data, - size_t data_size, - libcerror_error_t **error ) -{ - static char *function = "libfsapfs_container_space_manager_read_data"; - uint32_t object_subtype = 0; - uint32_t object_type = 0; - -#if defined( HAVE_DEBUG_OUTPUT ) - uint64_t value_64bit = 0; - uint32_t value_32bit = 0; -#endif - - if( container_space_manager == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid container space manager.", - function ); - - return( -1 ); - } - if( data == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, - "%s: invalid data.", - function ); - - return( -1 ); - } - if( ( data_size < sizeof( fsapfs_container_space_manager_t ) ) - || ( data_size > (size_t) SSIZE_MAX ) ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid data size value out of bounds.", - function ); - - return( -1 ); - } -#if defined( HAVE_DEBUG_OUTPUT ) - if( libcnotify_verbose != 0 ) - { - libcnotify_printf( - "%s: container space manager data:\n", - function ); - libcnotify_print_data( - data, - sizeof( fsapfs_container_space_manager_t ), - LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); - } -#endif - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->object_type, - object_type ); - - if( object_type != 0x80000005UL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, - "%s: invalid object type: 0x%08" PRIx32 ".", - function, - object_type ); - - return( -1 ); - } - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->object_subtype, - object_subtype ); - - if( object_subtype != 0x00000000UL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, - "%s: invalid object subtype: 0x%08" PRIx32 ".", - function, - object_subtype ); - - return( -1 ); - } -#if defined( HAVE_DEBUG_OUTPUT ) - if( libcnotify_verbose != 0 ) - { - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->object_checksum, - value_64bit ); - libcnotify_printf( - "%s: object checksum\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->object_identifier, - value_64bit ); - libcnotify_printf( - "%s: object identifier\t\t\t: %" PRIu64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->object_transaction_identifier, - value_64bit ); - libcnotify_printf( - "%s: object transaction identifier\t: %" PRIu64 "\n", - function, - value_64bit ); - - libcnotify_printf( - "%s: object type\t\t\t: 0x%08" PRIx32 "\n", - function, - object_type ); - - libcnotify_printf( - "%s: object subtype\t\t\t: 0x%08" PRIx32 "\n", - function, - object_subtype ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->block_size, - value_32bit ); - libcnotify_printf( - "%s: block size\t\t\t\t: %" PRIu32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->blocks_per_chunk, - value_32bit ); - libcnotify_printf( - "%s: blocks per chunk\t\t\t: %" PRIu32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->chunks_per_cib, - value_32bit ); - libcnotify_printf( - "%s: chunks per CIB\t\t\t: %" PRIu32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->cibs_per_cab, - value_32bit ); - libcnotify_printf( - "%s: CIBs per CAB\t\t\t: %" PRIu32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->number_of_blocks, - value_64bit ); - libcnotify_printf( - "%s: number of blocks\t\t\t: %" PRIu64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->number_of_chunks, - value_64bit ); - libcnotify_printf( - "%s: number of chunks\t\t\t: %" PRIu64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->number_of_cibs, - value_32bit ); - libcnotify_printf( - "%s: number of CIBs\t\t\t: %" PRIu32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->number_of_cabs, - value_32bit ); - libcnotify_printf( - "%s: number of CABs\t\t\t: %" PRIu32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->number_of_unused_blocks, - value_64bit ); - libcnotify_printf( - "%s: number of unused blocks\t\t: %" PRIu64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown1, - value_64bit ); - libcnotify_printf( - "%s: unknown1\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown2, - value_64bit ); - libcnotify_printf( - "%s: unknown2\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown3, - value_64bit ); - libcnotify_printf( - "%s: unknown3\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown4, - value_64bit ); - libcnotify_printf( - "%s: unknown4\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown5, - value_32bit ); - libcnotify_printf( - "%s: unknown5\t\t\t\t: 0x%08" PRIx32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown6, - value_32bit ); - libcnotify_printf( - "%s: unknown6\t\t\t\t: 0x%08" PRIx32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown7, - value_64bit ); - libcnotify_printf( - "%s: unknown7\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown8, - value_64bit ); - libcnotify_printf( - "%s: unknown8\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown9, - value_64bit ); - libcnotify_printf( - "%s: unknown9\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown10, - value_32bit ); - libcnotify_printf( - "%s: unknown10\t\t\t\t: 0x%08" PRIx32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown11, - value_32bit ); - libcnotify_printf( - "%s: unknown11\t\t\t\t: 0x%08" PRIx32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown12, - value_64bit ); - libcnotify_printf( - "%s: unknown12\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown13, - value_32bit ); - libcnotify_printf( - "%s: unknown13\t\t\t\t: 0x%08" PRIx32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown14, - value_32bit ); - libcnotify_printf( - "%s: unknown14\t\t\t\t: 0x%08" PRIx32 "\n", - function, - value_32bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown15, - value_64bit ); - libcnotify_printf( - "%s: unknown15\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown16, - value_64bit ); - libcnotify_printf( - "%s: unknown16\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown17, - value_64bit ); - libcnotify_printf( - "%s: unknown17\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown18, - value_64bit ); - libcnotify_printf( - "%s: unknown18\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown19, - value_64bit ); - libcnotify_printf( - "%s: unknown19\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown20, - value_64bit ); - libcnotify_printf( - "%s: unknown20\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown21, - value_64bit ); - libcnotify_printf( - "%s: unknown21\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown22, - value_64bit ); - libcnotify_printf( - "%s: unknown22\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown23, - value_64bit ); - libcnotify_printf( - "%s: unknown23\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown24, - value_64bit ); - libcnotify_printf( - "%s: unknown24\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown25, - value_64bit ); - libcnotify_printf( - "%s: unknown25\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown26, - value_64bit ); - libcnotify_printf( - "%s: unknown26\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown27, - value_64bit ); - libcnotify_printf( - "%s: unknown27\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown28, - value_64bit ); - libcnotify_printf( - "%s: unknown28\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown29, - value_64bit ); - libcnotify_printf( - "%s: unknown29\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown30, - value_64bit ); - libcnotify_printf( - "%s: unknown30\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown31, - value_64bit ); - libcnotify_printf( - "%s: unknown31\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown32, - value_64bit ); - libcnotify_printf( - "%s: unknown32\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_space_manager_t *) data )->unknown33, - value_64bit ); - libcnotify_printf( - "%s: unknown33\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - libcnotify_printf( - "\n" ); - } -#endif /* defined( HAVE_DEBUG_OUTPUT ) */ - - return( 1 ); -} - diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_space_manager.h libfsapfs-20190210/libfsapfs/libfsapfs_container_space_manager.h --- libfsapfs-20181215/libfsapfs/libfsapfs_container_space_manager.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_space_manager.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/* - * The container space manager functions - * - * Copyright (C) 2018, Joachim Metz - * - * Refer to AUTHORS for acknowledgements. - * - * This software is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this software. If not, see . - */ - -#if !defined( _LIBFSAPFS_CONTAINER_SPACE_MANAGER_H ) -#define _LIBFSAPFS_CONTAINER_SPACE_MANAGER_H - -#include -#include - -#include "libfsapfs_libbfio.h" -#include "libfsapfs_libcerror.h" - -#if defined( __cplusplus ) -extern "C" { -#endif - -typedef struct libfsapfs_container_space_manager libfsapfs_container_space_manager_t; - -struct libfsapfs_container_space_manager -{ - /* Dummy - */ - int dummy; -}; - -int libfsapfs_container_space_manager_initialize( - libfsapfs_container_space_manager_t **container_space_manager, - libcerror_error_t **error ); - -int libfsapfs_container_space_manager_free( - libfsapfs_container_space_manager_t **container_space_manager, - libcerror_error_t **error ); - -int libfsapfs_container_space_manager_read_file_io_handle( - libfsapfs_container_space_manager_t *container_space_manager, - libbfio_handle_t *file_io_handle, - off64_t file_offset, - libcerror_error_t **error ); - -int libfsapfs_container_space_manager_read_data( - libfsapfs_container_space_manager_t *container_space_manager, - const uint8_t *data, - size_t data_size, - libcerror_error_t **error ); - -#if defined( __cplusplus ) -} -#endif - -#endif /* !defined( _LIBFSAPFS_CONTAINER_SPACE_MANAGER_H ) */ - diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_superblock.c libfsapfs-20190210/libfsapfs/libfsapfs_container_superblock.c --- libfsapfs-20181215/libfsapfs/libfsapfs_container_superblock.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_superblock.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container superblock functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -234,20 +234,20 @@ size_t data_size, libcerror_error_t **error ) { - static char *function = "libfsapfs_container_superblock_read_data"; - size_t data_offset = 0; - uint64_t calculated_checksum = 0; - uint64_t incompatible_features_flags = 0; - uint64_t stored_checksum = 0; - uint64_t volume_object_identifier = 0; - uint32_t maximum_number_of_volumes = 0; - uint32_t object_subtype = 0; - uint32_t object_type = 0; - int object_identifier_index = 0; + static char *function = "libfsapfs_container_superblock_read_data"; + size_t data_offset = 0; + uint64_t calculated_checksum = 0; + uint64_t stored_checksum = 0; + uint64_t volume_object_identifier = 0; + uint32_t maximum_number_of_volumes = 0; + uint32_t object_subtype = 0; + uint32_t object_type = 0; + int object_identifier_index = 0; #if defined( HAVE_DEBUG_OUTPUT ) - uint64_t value_64bit = 0; - uint32_t value_32bit = 0; + uint64_t value_64bit = 0; + uint32_t value_32bit = 0; + int counter_index = 0; #endif if( container_superblock == NULL ) @@ -360,7 +360,7 @@ byte_stream_copy_to_uint64_little_endian( ( (fsapfs_container_superblock_t *) data )->incompatible_features_flags, - incompatible_features_flags ); + container_superblock->incompatible_features_flags ); if( memory_copy( container_superblock->container_identifier, @@ -412,6 +412,20 @@ container_superblock->number_of_volumes += 1; } } + if( memory_copy( + container_superblock->fusion_set_identifier, + ( (fsapfs_container_superblock_t *) data )->fusion_set_identifier, + 16 ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to copy Fusion set identifier.", + function ); + + return( -1 ); + } byte_stream_copy_to_uint64_little_endian( ( (fsapfs_container_superblock_t *) data )->key_bag_block_number, container_superblock->key_bag_block_number ); @@ -421,18 +435,22 @@ container_superblock->key_bag_number_of_blocks ); byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_superblock_t *) data )->metadata_area_number_of_blocks, - container_superblock->metadata_area_number_of_blocks ); + ( (fsapfs_container_superblock_t *) data )->checkpoint_descriptor_area_number_of_blocks, + container_superblock->checkpoint_descriptor_area_number_of_blocks ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_container_superblock_t *) data )->checkpoint_descriptor_area_block_number, + container_superblock->checkpoint_descriptor_area_block_number ); byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_superblock_t *) data )->metadata_area_block_number, - container_superblock->metadata_area_block_number ); + ( (fsapfs_container_superblock_t *) data )->fusion_middle_tree_block_number, + container_superblock->fusion_middle_tree_block_number ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { libcnotify_printf( - "%s: object checksum\t\t\t: 0x%08" PRIx64 "\n", + "%s: object checksum\t\t\t\t: 0x%08" PRIx64 "\n", function, stored_checksum ); @@ -440,27 +458,27 @@ ( (fsapfs_container_superblock_t *) data )->object_identifier, value_64bit ); libcnotify_printf( - "%s: object identifier\t\t\t: %" PRIu64 "\n", + "%s: object identifier\t\t\t\t: %" PRIu64 "\n", function, value_64bit ); libcnotify_printf( - "%s: object transaction identifier\t\t: %" PRIu64 "\n", + "%s: object transaction identifier\t\t\t: %" PRIu64 "\n", function, container_superblock->object_transaction_identifier ); libcnotify_printf( - "%s: object type\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: object type\t\t\t\t\t: 0x%08" PRIx32 "\n", function, object_type ); libcnotify_printf( - "%s: object subtype\t\t\t: 0x%08" PRIx32 "\n", + "%s: object subtype\t\t\t\t: 0x%08" PRIx32 "\n", function, object_subtype ); libcnotify_printf( - "%s: signature\t\t\t\t: %c%c%c%c\n", + "%s: signature\t\t\t\t\t: %c%c%c%c\n", function, ( (fsapfs_container_superblock_t *) data )->signature[ 0 ], ( (fsapfs_container_superblock_t *) data )->signature[ 1 ], @@ -468,12 +486,12 @@ ( (fsapfs_container_superblock_t *) data )->signature[ 3 ] ); libcnotify_printf( - "%s: block size\t\t\t\t: %" PRIu32 "\n", + "%s: block size\t\t\t\t\t: %" PRIu32 "\n", function, container_superblock->block_size ); libcnotify_printf( - "%s: number of blocks\t\t\t: %" PRIu64 "\n", + "%s: number of blocks\t\t\t\t: %" PRIu64 "\n", function, container_superblock->number_of_blocks ); @@ -481,7 +499,7 @@ ( (fsapfs_container_superblock_t *) data )->compatible_features_flags, value_64bit ); libcnotify_printf( - "%s: compatible features flags\t\t: 0x%08" PRIx64 "\n", + "%s: compatible features flags\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); libfsapfs_debug_print_container_compatible_features_flags( @@ -493,7 +511,7 @@ ( (fsapfs_container_superblock_t *) data )->read_only_compatible_features_flags, value_64bit ); libcnotify_printf( - "%s: read-only compatible features flags\t: 0x%08" PRIx64 "\n", + "%s: read-only compatible features flags\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); libfsapfs_debug_print_container_read_only_compatible_features_flags( @@ -502,17 +520,17 @@ "\n" ); libcnotify_printf( - "%s: incompatible features flags\t\t: 0x%08" PRIx64 "\n", + "%s: incompatible features flags\t\t\t: 0x%08" PRIx64 "\n", function, - incompatible_features_flags ); + container_superblock->incompatible_features_flags ); libfsapfs_debug_print_container_incompatible_features_flags( - incompatible_features_flags ); + container_superblock->incompatible_features_flags ); libcnotify_printf( "\n" ); if( libfsapfs_debug_print_guid_value( function, - "container identifier\t\t\t", + "container identifier\t\t\t\t", ( (fsapfs_container_superblock_t *) data )->container_identifier, 16, LIBFGUID_ENDIAN_BIG, @@ -532,7 +550,7 @@ ( (fsapfs_container_superblock_t *) data )->next_object_identifier, value_64bit ); libcnotify_printf( - "%s: next object identifier\t\t: %" PRIu64 "\n", + "%s: next object identifier\t\t\t: %" PRIu64 "\n", function, value_64bit ); @@ -540,33 +558,33 @@ ( (fsapfs_container_superblock_t *) data )->next_transaction_identifier, value_64bit ); libcnotify_printf( - "%s: next transaction identifier\t\t: %" PRIu64 "\n", + "%s: next transaction identifier\t\t\t: %" PRIu64 "\n", function, value_64bit ); libcnotify_printf( - "%s: metadata area number of blocks\t: %" PRIu32 "\n", + "%s: checkpoint descriptor area number of blocks\t: %" PRIu32 "\n", function, - container_superblock->metadata_area_number_of_blocks ); + container_superblock->checkpoint_descriptor_area_number_of_blocks ); byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_container_superblock_t *) data )->unknown5, + ( (fsapfs_container_superblock_t *) data )->checkpoint_data_area_number_of_blocks, value_32bit ); libcnotify_printf( - "%s: unknown5 number of blocks\t\t: %" PRIu32 "\n", + "%s: checkpoint data area number of blocks\t\t: %" PRIu32 "\n", function, value_32bit ); libcnotify_printf( - "%s: metadata area block number\t\t: %" PRIu64 "\n", + "%s: checkpoint descriptor area block number\t: %" PRIu64 "\n", function, - container_superblock->metadata_area_block_number ); + container_superblock->checkpoint_descriptor_area_block_number ); byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_superblock_t *) data )->unknown7, + ( (fsapfs_container_superblock_t *) data )->checkpoint_data_area_block_number, value_64bit ); libcnotify_printf( - "%s: unknown7 block number\t\t\t: %" PRIu64 "\n", + "%s: checkpoint data area block number\t\t: %" PRIu64 "\n", function, value_64bit ); @@ -574,7 +592,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown8, value_32bit ); libcnotify_printf( - "%s: unknown8\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: unknown8\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); @@ -582,7 +600,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown9, value_32bit ); libcnotify_printf( - "%s: unknown9\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: unknown9\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); @@ -590,7 +608,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown10, value_32bit ); libcnotify_printf( - "%s: unknown10\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: unknown10\t\t\t\t\t: %" PRIu32 "\n", function, value_32bit ); @@ -598,7 +616,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown11, value_32bit ); libcnotify_printf( - "%s: unknown11\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: unknown11\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); @@ -606,7 +624,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown12, value_32bit ); libcnotify_printf( - "%s: unknown12\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: unknown12\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); @@ -614,22 +632,22 @@ ( (fsapfs_container_superblock_t *) data )->unknown13, value_32bit ); libcnotify_printf( - "%s: unknown13\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: unknown13\t\t\t\t\t: %" PRIu32 "\n", function, value_32bit ); libcnotify_printf( - "%s: space manager object identifier\t: %" PRIu64 "\n", + "%s: space manager object identifier\t\t: %" PRIu64 "\n", function, container_superblock->space_manager_object_identifier ); libcnotify_printf( - "%s: object map block number\t\t: %" PRIu64 "\n", + "%s: object map block number\t\t\t: %" PRIu64 "\n", function, container_superblock->object_map_block_number ); libcnotify_printf( - "%s: reaper object identifier\t\t: %" PRIu64 "\n", + "%s: reaper object identifier\t\t\t: %" PRIu64 "\n", function, container_superblock->reaper_object_identifier ); @@ -637,12 +655,12 @@ ( (fsapfs_container_superblock_t *) data )->unknown17, value_32bit ); libcnotify_printf( - "%s: unknown17\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: unknown17\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( - "%s: maximum number of volumes\t\t: %" PRIu32 "\n", + "%s: maximum number of volumes\t\t\t: %" PRIu32 "\n", function, maximum_number_of_volumes ); @@ -653,25 +671,34 @@ if( container_superblock->volume_object_identifiers[ object_identifier_index ] != 0 ) { libcnotify_printf( - "%s: volume object identifier: %d\t\t: %" PRIu64 "\n", + "%s: volume object identifier: %d\t\t\t: %" PRIu64 "\n", function, object_identifier_index, container_superblock->volume_object_identifiers[ object_identifier_index ] ); } } - libcnotify_printf( - "%s: unknown19:\n", - function ); - libcnotify_print_data( - ( (fsapfs_container_superblock_t *) data )->unknown19, - 256, - LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + for( counter_index = 0; + counter_index < 32; + counter_index++ ) + { + byte_stream_copy_to_uint64_little_endian( + &( ( (fsapfs_container_superblock_t *) data )->counters[ counter_index * 8 ] ), + value_64bit ); + if( value_64bit != 0 ) + { + libcnotify_printf( + "%s: counter: %02d\t\t\t\t\t: 0x%08" PRIx64 "\n", + function, + counter_index, + value_64bit ); + } + } byte_stream_copy_to_uint64_little_endian( ( (fsapfs_container_superblock_t *) data )->unknown20, value_64bit ); libcnotify_printf( - "%s: unknown20\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown20\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); @@ -679,7 +706,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown21, value_64bit ); libcnotify_printf( - "%s: unknown21\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown21\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); @@ -687,7 +714,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown22, value_64bit ); libcnotify_printf( - "%s: unknown22\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown22\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); @@ -695,7 +722,7 @@ ( (fsapfs_container_superblock_t *) data )->unknown23, value_64bit ); libcnotify_printf( - "%s: unknown23\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown23\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); @@ -703,33 +730,35 @@ ( (fsapfs_container_superblock_t *) data )->unknown24, value_64bit ); libcnotify_printf( - "%s: unknown24\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); - - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_superblock_t *) data )->unknown25, - value_64bit ); - libcnotify_printf( - "%s: unknown25\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown24\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_superblock_t *) data )->unknown26, - value_64bit ); - libcnotify_printf( - "%s: unknown26\t\t\t\t: 0x%08" PRIx64 "\n", - function, - value_64bit ); + if( libfsapfs_debug_print_guid_value( + function, + "Fusion set identifier\t\t\t\t", + ( (fsapfs_container_superblock_t *) data )->fusion_set_identifier, + 16, + LIBFGUID_ENDIAN_BIG, + LIBFGUID_STRING_FORMAT_FLAG_USE_LOWER_CASE, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, + "%s: unable to print UUID value.", + function ); + return( -1 ); + } libcnotify_printf( - "%s: key bag block number\t\t\t: %" PRIu64 "\n", + "%s: key bag block number\t\t\t\t: %" PRIu64 "\n", function, container_superblock->key_bag_block_number ); libcnotify_printf( - "%s: key bag number of blocks\t\t: %" PRIu64 "\n", + "%s: key bag number of blocks\t\t\t: %" PRIu64 "\n", function, container_superblock->key_bag_number_of_blocks ); @@ -745,31 +774,36 @@ ( (fsapfs_container_superblock_t *) data )->unknown30, value_64bit ); libcnotify_printf( - "%s: unknown30\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown30\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); + libcnotify_printf( + "%s: Fusion middle tree block number\t\t: %" PRIu64 "\n", + function, + container_superblock->fusion_middle_tree_block_number ); + byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_superblock_t *) data )->unknown31, + ( (fsapfs_container_superblock_t *) data )->fusion_write_back_cache_object_identifier, value_64bit ); libcnotify_printf( - "%s: unknown31\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: Fusion write-back cache object identifier\t: %" PRIu64 "\n", function, value_64bit ); byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_superblock_t *) data )->unknown32, + ( (fsapfs_container_superblock_t *) data )->unknown33, value_64bit ); libcnotify_printf( - "%s: unknown32\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown33\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_container_superblock_t *) data )->unknown33, + ( (fsapfs_container_superblock_t *) data )->unknown34, value_64bit ); libcnotify_printf( - "%s: unknown33\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: unknown34\t\t\t\t\t: 0x%08" PRIx64 "\n", function, value_64bit ); @@ -807,7 +841,7 @@ return( -1 ); } - if( ( incompatible_features_flags & 0x0000000000000001 ) != 0 ) + if( ( container_superblock->incompatible_features_flags & 0x0000000000000001 ) != 0 ) { libcerror_error_set( error, @@ -830,15 +864,26 @@ return( -1 ); } - if( container_superblock->metadata_area_block_number == 0 ) + if( ( container_superblock->checkpoint_descriptor_area_number_of_blocks & 0x80000000UL ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported checkpoint descriptor area number of blocks - MSB is set.", + function ); + + return( -1 ); + } + if( container_superblock->checkpoint_descriptor_area_block_number == 0 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, - "%s: unsupported metadata area block number: %" PRIu32 ".", + "%s: unsupported checkpoint descriptor area block number: %" PRIu32 ".", function, - container_superblock->metadata_area_block_number ); + container_superblock->checkpoint_descriptor_area_block_number ); return( -1 ); } diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_container_superblock.h libfsapfs-20190210/libfsapfs/libfsapfs_container_superblock.h --- libfsapfs-20181215/libfsapfs/libfsapfs_container_superblock.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_container_superblock.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The container superblock functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -48,17 +48,21 @@ */ uint64_t number_of_blocks; + /* The incompatible features flags + */ + uint64_t incompatible_features_flags; + /* The container identifier */ uint8_t container_identifier[ 16 ]; - /* The number of blocks of the metadata area + /* The number of blocks of the checkpoint descriptor area */ - uint32_t metadata_area_number_of_blocks; + uint32_t checkpoint_descriptor_area_number_of_blocks; - /* The block number of the metadata area + /* The block number of the checkpoint descriptor area */ - uint32_t metadata_area_block_number; + uint32_t checkpoint_descriptor_area_block_number; /* The space manager object identifier */ @@ -72,6 +76,10 @@ */ uint64_t reaper_object_identifier; + /* The Fusion set identifier + */ + uint8_t fusion_set_identifier[ 16 ]; + /* The key bag block number */ uint64_t key_bag_block_number; @@ -87,6 +95,10 @@ /* The volume object identifier */ uint64_t volume_object_identifiers[ 100 ]; + + /* The Fusion middle tree block number + */ + uint64_t fusion_middle_tree_block_number; }; int libfsapfs_container_superblock_initialize( diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_data_block.c libfsapfs-20190210/libfsapfs/libfsapfs_data_block.c --- libfsapfs-20181215/libfsapfs/libfsapfs_data_block.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_data_block.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Data block functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_data_block_data_handle.c libfsapfs-20190210/libfsapfs/libfsapfs_data_block_data_handle.c --- libfsapfs-20181215/libfsapfs/libfsapfs_data_block_data_handle.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_data_block_data_handle.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The data block data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_data_block_data_handle.h libfsapfs-20190210/libfsapfs/libfsapfs_data_block_data_handle.h --- libfsapfs-20181215/libfsapfs/libfsapfs_data_block_data_handle.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_data_block_data_handle.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The data block data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_data_block.h libfsapfs-20190210/libfsapfs/libfsapfs_data_block.h --- libfsapfs-20181215/libfsapfs/libfsapfs_data_block.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_data_block.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Data block functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_data_stream.c libfsapfs-20190210/libfsapfs/libfsapfs_data_stream.c --- libfsapfs-20181215/libfsapfs/libfsapfs_data_stream.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_data_stream.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Data stream functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_data_stream.h libfsapfs-20190210/libfsapfs/libfsapfs_data_stream.h --- libfsapfs-20181215/libfsapfs/libfsapfs_data_stream.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_data_stream.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Data stream functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_debug.c libfsapfs-20190210/libfsapfs/libfsapfs_debug.c --- libfsapfs-20181215/libfsapfs/libfsapfs_debug.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_debug.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Debug functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_debug.h libfsapfs-20190210/libfsapfs/libfsapfs_debug.h --- libfsapfs-20181215/libfsapfs/libfsapfs_debug.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_debug.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Debug functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_definitions.h libfsapfs-20190210/libfsapfs/libfsapfs_definitions.h --- libfsapfs-20181215/libfsapfs/libfsapfs_definitions.h 2018-12-15 06:44:18.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_definitions.h 2019-02-10 19:59:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -37,11 +37,11 @@ * for local use of libfsapfs */ #else -#define LIBFSAPFS_VERSION 20181215 +#define LIBFSAPFS_VERSION 20190210 /* The version string */ -#define LIBFSAPFS_VERSION_STRING "20181215" +#define LIBFSAPFS_VERSION_STRING "20190210" /* The file access * bit 1 set to 1 for read access @@ -110,5 +110,7 @@ #define LIBFSAPFS_MAXIMUM_CACHE_ENTRIES_BTREE_NODES 8192 #define LIBFSAPFS_MAXIMUM_CACHE_ENTRIES_DATA_BLOCKS 16 +#define LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH 256 + #endif /* !defined( _LIBFSAPFS_INTERNAL_DEFINITIONS_H ) */ diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_definitions.h.in libfsapfs-20190210/libfsapfs/libfsapfs_definitions.h.in --- libfsapfs-20181215/libfsapfs/libfsapfs_definitions.h.in 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_definitions.h.in 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -110,5 +110,7 @@ #define LIBFSAPFS_MAXIMUM_CACHE_ENTRIES_BTREE_NODES 8192 #define LIBFSAPFS_MAXIMUM_CACHE_ENTRIES_DATA_BLOCKS 16 +#define LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH 256 + #endif /* !defined( _LIBFSAPFS_INTERNAL_DEFINITIONS_H ) */ diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_deflate.c libfsapfs-20190210/libfsapfs/libfsapfs_deflate.c --- libfsapfs-20181215/libfsapfs/libfsapfs_deflate.c 2018-12-14 15:40:05.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_deflate.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Deflate (zlib) (un)compression functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_deflate.h libfsapfs-20190210/libfsapfs/libfsapfs_deflate.h --- libfsapfs-20181215/libfsapfs/libfsapfs_deflate.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_deflate.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Deflate (zlib) (un)compression functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_directory_record.c libfsapfs-20190210/libfsapfs/libfsapfs_directory_record.c --- libfsapfs-20181215/libfsapfs/libfsapfs_directory_record.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_directory_record.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Directory record functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_directory_record.h libfsapfs-20190210/libfsapfs/libfsapfs_directory_record.h --- libfsapfs-20181215/libfsapfs/libfsapfs_directory_record.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_directory_record.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Directory record functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_encryption_context.c libfsapfs-20190210/libfsapfs/libfsapfs_encryption_context.c --- libfsapfs-20181215/libfsapfs/libfsapfs_encryption_context.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_encryption_context.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Encryption functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_encryption_context.h libfsapfs-20190210/libfsapfs/libfsapfs_encryption_context.h --- libfsapfs-20181215/libfsapfs/libfsapfs_encryption_context.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_encryption_context.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Encryption functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_error.c libfsapfs-20190210/libfsapfs/libfsapfs_error.c --- libfsapfs-20181215/libfsapfs/libfsapfs_error.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_error.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_error.h libfsapfs-20190210/libfsapfs/libfsapfs_error.h --- libfsapfs-20181215/libfsapfs/libfsapfs_error.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_error.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_extended_attribute.c libfsapfs-20190210/libfsapfs/libfsapfs_extended_attribute.c --- libfsapfs-20181215/libfsapfs/libfsapfs_extended_attribute.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_extended_attribute.c 2019-02-06 20:48:29.000000000 +0000 @@ -1,7 +1,7 @@ /* * Extended attribute functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -121,7 +121,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -689,7 +689,7 @@ libcerror_error_t **error ) { libfsapfs_internal_extended_attribute_t *internal_extended_attribute = NULL; - static char *function = "libfsapfs_extended_attribute_get_identifier"; + static char *function = "libfsapfs_extended_attribute_get_data_stream"; if( extended_attribute == NULL ) { diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_extended_attribute.h libfsapfs-20190210/libfsapfs/libfsapfs_extended_attribute.h --- libfsapfs-20181215/libfsapfs/libfsapfs_extended_attribute.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_extended_attribute.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Extended attribute functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_extent_reference_tree.c libfsapfs-20190210/libfsapfs/libfsapfs_extent_reference_tree.c --- libfsapfs-20181215/libfsapfs/libfsapfs_extent_reference_tree.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_extent_reference_tree.c 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,372 @@ +/* + * The extent reference tree functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include + +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" +#include "libfsapfs_libcnotify.h" +#include "libfsapfs_extent_reference_tree.h" + +#include "fsapfs_extent_reference_tree.h" + +/* Creates a extent reference tree + * Make sure the value extent_reference_tree is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int libfsapfs_extent_reference_tree_initialize( + libfsapfs_extent_reference_tree_t **extent_reference_tree, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_extent_reference_tree_initialize"; + + if( extent_reference_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid extent reference tree.", + function ); + + return( -1 ); + } + if( *extent_reference_tree != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid extent reference tree value already set.", + function ); + + return( -1 ); + } + *extent_reference_tree = memory_allocate_structure( + libfsapfs_extent_reference_tree_t ); + + if( *extent_reference_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create extent reference tree.", + function ); + + goto on_error; + } + if( memory_set( + *extent_reference_tree, + 0, + sizeof( libfsapfs_extent_reference_tree_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear extent reference tree.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( *extent_reference_tree != NULL ) + { + memory_free( + *extent_reference_tree ); + + *extent_reference_tree = NULL; + } + return( -1 ); +} + +/* Frees a extent reference tree + * Returns 1 if successful or -1 on error + */ +int libfsapfs_extent_reference_tree_free( + libfsapfs_extent_reference_tree_t **extent_reference_tree, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_extent_reference_tree_free"; + + if( extent_reference_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid extent reference tree.", + function ); + + return( -1 ); + } + if( *extent_reference_tree != NULL ) + { + memory_free( + *extent_reference_tree ); + + *extent_reference_tree = NULL; + } + return( 1 ); +} + +/* Reads the extent reference tree + * Returns 1 if successful or -1 on error + */ +int libfsapfs_extent_reference_tree_read_file_io_handle( + libfsapfs_extent_reference_tree_t *extent_reference_tree, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ) +{ + uint8_t extent_reference_tree_data[ 4096 ]; + + static char *function = "libfsapfs_extent_reference_tree_read_file_io_handle"; + ssize_t read_count = 0; + + if( extent_reference_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid extent reference tree.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: reading extent reference tree at offset: %" PRIi64 " (0x%08" PRIx64 ")\n", + function, + file_offset, + file_offset ); + } +#endif + if( libbfio_handle_seek_offset( + file_io_handle, + file_offset, + SEEK_SET, + error ) == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_SEEK_FAILED, + "%s: unable to seek extent reference tree offset: %" PRIi64 " (0x%08" PRIx64 ").", + function, + file_offset, + file_offset ); + + return( -1 ); + } + read_count = libbfio_handle_read_buffer( + file_io_handle, + extent_reference_tree_data, + 4096, + error ); + + if( read_count != (ssize_t) 4096 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read extent reference tree data.", + function ); + + return( -1 ); + } + if( libfsapfs_extent_reference_tree_read_data( + extent_reference_tree, + extent_reference_tree_data, + 4096, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read extent reference tree data.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Reads the extent reference tree + * Returns 1 if successful or -1 on error + */ +int libfsapfs_extent_reference_tree_read_data( + libfsapfs_extent_reference_tree_t *extent_reference_tree, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_extent_reference_tree_read_data"; + uint32_t object_subtype = 0; + uint32_t object_type = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + uint64_t value_64bit = 0; + uint32_t value_32bit = 0; +#endif + + if( extent_reference_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid extent reference tree.", + function ); + + return( -1 ); + } + if( data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data.", + function ); + + return( -1 ); + } + if( ( data_size < sizeof( fsapfs_extent_reference_tree_t ) ) + || ( data_size > (size_t) SSIZE_MAX ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid data size value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: extent reference tree data:\n", + function ); + libcnotify_print_data( + data, + data_size, + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + } +#endif + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_extent_reference_tree_t *) data )->object_type, + object_type ); + + if( object_type != 0x40000002UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object type: 0x%08" PRIx32 ".", + function, + object_type ); + + return( -1 ); + } + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_extent_reference_tree_t *) data )->object_subtype, + object_subtype ); + + if( object_subtype != 0x0000000fUL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object subtype: 0x%08" PRIx32 ".", + function, + object_subtype ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_extent_reference_tree_t *) data )->object_checksum, + value_64bit ); + libcnotify_printf( + "%s: object checksum\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_extent_reference_tree_t *) data )->object_identifier, + value_64bit ); + libcnotify_printf( + "%s: object identifier\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_extent_reference_tree_t *) data )->object_transaction_identifier, + value_64bit ); + libcnotify_printf( + "%s: object transaction identifier\t: %" PRIu64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "%s: object type\t\t\t\t: 0x%08" PRIx32 "\n", + function, + object_type ); + + libcnotify_printf( + "%s: object subtype\t\t\t: 0x%08" PRIx32 "\n", + function, + object_subtype ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_extent_reference_tree_t *) data )->unknown1, + value_32bit ); + libcnotify_printf( + "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + libcnotify_printf( + "\n" ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + + return( 1 ); +} + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_extent_reference_tree.h libfsapfs-20190210/libfsapfs/libfsapfs_extent_reference_tree.h --- libfsapfs-20181215/libfsapfs/libfsapfs_extent_reference_tree.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_extent_reference_tree.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * The extent reference tree functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBFSAPFS_EXTENT_REFERENCE_TREE_H ) +#define _LIBFSAPFS_EXTENT_REFERENCE_TREE_H + +#include +#include + +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct libfsapfs_extent_reference_tree libfsapfs_extent_reference_tree_t; + +struct libfsapfs_extent_reference_tree +{ + /* Dummy + */ + int dummy; +}; + +int libfsapfs_extent_reference_tree_initialize( + libfsapfs_extent_reference_tree_t **extent_reference_tree, + libcerror_error_t **error ); + +int libfsapfs_extent_reference_tree_free( + libfsapfs_extent_reference_tree_t **extent_reference_tree, + libcerror_error_t **error ); + +int libfsapfs_extent_reference_tree_read_file_io_handle( + libfsapfs_extent_reference_tree_t *extent_reference_tree, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ); + +int libfsapfs_extent_reference_tree_read_data( + libfsapfs_extent_reference_tree_t *extent_reference_tree, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBFSAPFS_EXTENT_REFERENCE_TREE_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_extern.h libfsapfs-20190210/libfsapfs/libfsapfs_extern.h --- libfsapfs-20181215/libfsapfs/libfsapfs_extern.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_extern.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal extern definition * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_entry.c libfsapfs-20190210/libfsapfs/libfsapfs_file_entry.c --- libfsapfs-20181215/libfsapfs/libfsapfs_file_entry.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_entry.c 2019-02-10 19:07:25.000000000 +0000 @@ -1,7 +1,7 @@ /* * File entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -131,7 +131,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -1718,8 +1718,9 @@ libfsapfs_internal_file_entry_t *internal_file_entry, libcerror_error_t **error ) { - static char *function = "libfsapfs_internal_file_entry_get_symbolic_link_data"; - ssize_t read_count = 0; + static char *function = "libfsapfs_internal_file_entry_get_symbolic_link_data"; + size64_t extended_attribute_size = 0; + ssize_t read_count = 0; if( internal_file_entry == NULL ) { @@ -1763,7 +1764,7 @@ { if( libfsapfs_extended_attribute_get_size( internal_file_entry->symbolic_link_extended_attribute, - &( internal_file_entry->symbolic_link_data_size ), + &extended_attribute_size, error ) != 1 ) { libcerror_error_set( @@ -1775,7 +1776,7 @@ goto on_error; } - if( internal_file_entry->symbolic_link_data_size > (size_t) SSIZE_MAX ) + if( extended_attribute_size > (size64_t) SSIZE_MAX ) { libcerror_error_set( error, @@ -1787,7 +1788,7 @@ goto on_error; } internal_file_entry->symbolic_link_data = (uint8_t *) memory_allocate( - sizeof( uint8_t ) * internal_file_entry->symbolic_link_data_size ); + sizeof( uint8_t ) * extended_attribute_size ); if( internal_file_entry->symbolic_link_data == NULL ) { @@ -1800,6 +1801,8 @@ goto on_error; } + internal_file_entry->symbolic_link_data_size = (size_t) extended_attribute_size; + read_count = libfsapfs_extended_attribute_read_buffer_at_offset( internal_file_entry->symbolic_link_extended_attribute, internal_file_entry->symbolic_link_data, @@ -2458,6 +2461,630 @@ on_error: #if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + NULL ); +#endif + return( -1 ); +} + +/* Determines if there is an extended attribute for an UTF-8 encoded name + * Returns 1 if available, 0 if not or -1 on error + */ +int libfsapfs_file_entry_has_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libcerror_error_t **error ) +{ + libfsapfs_extended_attribute_t *extended_attribute = NULL; + libfsapfs_internal_file_entry_t *internal_file_entry = NULL; + static char *function = "libfsapfs_file_entry_has_extended_attribute_by_utf8_name"; + int extended_attribute_index = 0; + int number_of_extended_attributes = 0; + int result = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + internal_file_entry = (libfsapfs_internal_file_entry_t *) file_entry; + +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_grab_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + if( internal_file_entry->extended_attributes == NULL ) + { + if( libfsapfs_internal_file_entry_get_extended_attributes( + internal_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine extended attributes.", + function ); + + goto on_error; + } + } + if( libcdata_array_get_number_of_entries( + internal_file_entry->extended_attributes, + &number_of_extended_attributes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of entries from extended attributes array.", + function ); + + goto on_error; + } + for( extended_attribute_index = 0; + extended_attribute_index < number_of_extended_attributes; + extended_attribute_index++ ) + { + if( libcdata_array_get_entry_by_index( + internal_file_entry->extended_attributes, + extended_attribute_index, + (intptr_t **) &extended_attribute, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve extended attribute: %d.", + function, + extended_attribute_index ); + + goto on_error; + } + result = libfsapfs_extended_attribute_compare_name_with_utf8_string( + extended_attribute, + utf8_string, + utf8_string_length, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GENERIC, + "%s: unable to compare UTF-8 string with name of extended attribute.", + function ); + + goto on_error; + } + else if( result == LIBUNA_COMPARE_EQUAL ) + { + result = 1; + + break; + } + } +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + return( result ); + +on_error: +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + NULL ); +#endif + return( -1 ); +} + +/* Determines if there is an extended attribute for an UTF-8 encoded name + * Returns 1 if available, 0 if not or -1 on error + */ +int libfsapfs_file_entry_has_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libcerror_error_t **error ) +{ + libfsapfs_extended_attribute_t *extended_attribute = NULL; + libfsapfs_internal_file_entry_t *internal_file_entry = NULL; + static char *function = "libfsapfs_file_entry_has_extended_attribute_by_utf16_name"; + int extended_attribute_index = 0; + int number_of_extended_attributes = 0; + int result = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + internal_file_entry = (libfsapfs_internal_file_entry_t *) file_entry; + +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_grab_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + if( internal_file_entry->extended_attributes == NULL ) + { + if( libfsapfs_internal_file_entry_get_extended_attributes( + internal_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine extended attributes.", + function ); + + goto on_error; + } + } + if( libcdata_array_get_number_of_entries( + internal_file_entry->extended_attributes, + &number_of_extended_attributes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of entries from extended attributes array.", + function ); + + goto on_error; + } + for( extended_attribute_index = 0; + extended_attribute_index < number_of_extended_attributes; + extended_attribute_index++ ) + { + if( libcdata_array_get_entry_by_index( + internal_file_entry->extended_attributes, + extended_attribute_index, + (intptr_t **) &extended_attribute, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve extended attribute: %d.", + function, + extended_attribute_index ); + + goto on_error; + } + result = libfsapfs_extended_attribute_compare_name_with_utf16_string( + extended_attribute, + utf16_string, + utf16_string_length, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GENERIC, + "%s: unable to compare UTF-16 string with name of extended attribute.", + function ); + + goto on_error; + } + else if( result == LIBUNA_COMPARE_EQUAL ) + { + result = 1; + + break; + } + } +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + return( result ); + +on_error: +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + NULL ); +#endif + return( -1 ); +} + +/* Retrieves the extended attribute for an UTF-8 encoded name + * Returns 1 if successful, 0 if no such file entry or -1 on error + */ +int libfsapfs_file_entry_get_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libcerror_error_t **error ) +{ + libfsapfs_extended_attribute_t *safe_extended_attribute = NULL; + libfsapfs_internal_file_entry_t *internal_file_entry = NULL; + static char *function = "libfsapfs_file_entry_get_extended_attribute_by_utf8_name"; + int extended_attribute_index = 0; + int number_of_extended_attributes = 0; + int result = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + internal_file_entry = (libfsapfs_internal_file_entry_t *) file_entry; + + if( extended_attribute == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid extended attribute.", + function ); + + return( -1 ); + } + if( *extended_attribute != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid extended attribute value already set.", + function ); + + return( -1 ); + } +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_grab_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + if( internal_file_entry->extended_attributes == NULL ) + { + if( libfsapfs_internal_file_entry_get_extended_attributes( + internal_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine extended attributes.", + function ); + + goto on_error; + } + } + if( libcdata_array_get_number_of_entries( + internal_file_entry->extended_attributes, + &number_of_extended_attributes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of entries from extended attributes array.", + function ); + + goto on_error; + } + for( extended_attribute_index = 0; + extended_attribute_index < number_of_extended_attributes; + extended_attribute_index++ ) + { + if( libcdata_array_get_entry_by_index( + internal_file_entry->extended_attributes, + extended_attribute_index, + (intptr_t **) &safe_extended_attribute, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve extended attribute: %d.", + function, + extended_attribute_index ); + + goto on_error; + } + result = libfsapfs_extended_attribute_compare_name_with_utf8_string( + safe_extended_attribute, + utf8_string, + utf8_string_length, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GENERIC, + "%s: unable to compare UTF-8 string with name of extended attribute.", + function ); + + goto on_error; + } + else if( result == LIBUNA_COMPARE_EQUAL ) + { + *extended_attribute = safe_extended_attribute; + result = 1; + + break; + } + } +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + return( result ); + +on_error: +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + NULL ); +#endif + return( -1 ); +} + +/* Retrieves the extended attribute for an UTF-16 encoded name + * Returns 1 if successful, 0 if no such file entry or -1 on error + */ +int libfsapfs_file_entry_get_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libcerror_error_t **error ) +{ + libfsapfs_extended_attribute_t *safe_extended_attribute = NULL; + libfsapfs_internal_file_entry_t *internal_file_entry = NULL; + static char *function = "libfsapfs_file_entry_get_extended_attribute_by_utf16_name"; + int extended_attribute_index = 0; + int number_of_extended_attributes = 0; + int result = 0; + + if( file_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file entry.", + function ); + + return( -1 ); + } + internal_file_entry = (libfsapfs_internal_file_entry_t *) file_entry; + + if( extended_attribute == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid extended attribute.", + function ); + + return( -1 ); + } + if( *extended_attribute != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid extended attribute value already set.", + function ); + + return( -1 ); + } +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_grab_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to grab read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + if( internal_file_entry->extended_attributes == NULL ) + { + if( libfsapfs_internal_file_entry_get_extended_attributes( + internal_file_entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine extended attributes.", + function ); + + goto on_error; + } + } + if( libcdata_array_get_number_of_entries( + internal_file_entry->extended_attributes, + &number_of_extended_attributes, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of entries from extended attributes array.", + function ); + + goto on_error; + } + for( extended_attribute_index = 0; + extended_attribute_index < number_of_extended_attributes; + extended_attribute_index++ ) + { + if( libcdata_array_get_entry_by_index( + internal_file_entry->extended_attributes, + extended_attribute_index, + (intptr_t **) &safe_extended_attribute, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve extended attribute: %d.", + function, + extended_attribute_index ); + + goto on_error; + } + result = libfsapfs_extended_attribute_compare_name_with_utf16_string( + safe_extended_attribute, + utf16_string, + utf16_string_length, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GENERIC, + "%s: unable to compare UTF-16 string with name of extended attribute.", + function ); + + goto on_error; + } + else if( result == LIBUNA_COMPARE_EQUAL ) + { + *extended_attribute = safe_extended_attribute; + result = 1; + + break; + } + } +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) + if( libcthreads_read_write_lock_release_for_write( + internal_file_entry->read_write_lock, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to release read/write lock for writing.", + function ); + + return( -1 ); + } +#endif + return( result ); + +on_error: +#if defined( HAVE_LIBFSAPFS_MULTI_THREAD_SUPPORT ) libcthreads_read_write_lock_release_for_write( internal_file_entry->read_write_lock, NULL ); diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_entry.h libfsapfs-20190210/libfsapfs/libfsapfs_file_entry.h --- libfsapfs-20181215/libfsapfs/libfsapfs_file_entry.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_entry.h 2019-02-10 19:07:31.000000000 +0000 @@ -1,7 +1,7 @@ /* * File entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -268,6 +268,36 @@ libfsapfs_extended_attribute_t **extended_attribute, libcerror_error_t **error ); +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_has_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libcerror_error_t **error ); + +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_has_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libcerror_error_t **error ); + +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_get_extended_attribute_by_utf8_name( + libfsapfs_file_entry_t *file_entry, + const uint8_t *utf8_string, + size_t utf8_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libcerror_error_t **error ); + +LIBFSAPFS_EXTERN \ +int libfsapfs_file_entry_get_extended_attribute_by_utf16_name( + libfsapfs_file_entry_t *file_entry, + const uint16_t *utf16_string, + size_t utf16_string_length, + libfsapfs_extended_attribute_t **extended_attribute, + libcerror_error_t **error ); + int libfsapfs_internal_file_entry_get_directory_entries( libfsapfs_internal_file_entry_t *internal_file_entry, libcerror_error_t **error ); diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_extent.c libfsapfs-20190210/libfsapfs/libfsapfs_file_extent.c --- libfsapfs-20181215/libfsapfs/libfsapfs_file_extent.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_extent.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * File extent functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_extent.h libfsapfs-20190210/libfsapfs/libfsapfs_file_extent.h --- libfsapfs-20181215/libfsapfs/libfsapfs_file_extent.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_extent.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * File extent functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_system_btree.c libfsapfs-20190210/libfsapfs/libfsapfs_file_system_btree.c --- libfsapfs-20181215/libfsapfs/libfsapfs_file_system_btree.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_system_btree.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The file system B-tree functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -1206,6 +1206,7 @@ static char *function = "libfsapfs_file_system_btree_get_entry_by_identifier"; uint64_t sub_node_block_number = 0; int is_leaf_node = 0; + int recursion_depth = 0; int result = 0; if( file_system_btree == NULL ) @@ -1259,6 +1260,18 @@ } do { + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } is_leaf_node = libfsapfs_btree_node_is_leaf_node( node, error ); @@ -1339,6 +1352,7 @@ return( -1 ); } + recursion_depth++; } while( is_leaf_node == 0 ); @@ -1616,6 +1630,7 @@ size_t utf8_string_length, uint32_t name_hash, libfsapfs_directory_record_t **directory_record, + int recursion_depth, libcerror_error_t **error ) { libfsapfs_btree_entry_t *entry = NULL; @@ -1665,6 +1680,18 @@ return( -1 ); } + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { @@ -1927,6 +1954,7 @@ utf8_string_length, name_hash, directory_record, + recursion_depth + 1, error ); } if( result == -1 ) @@ -2231,6 +2259,7 @@ size_t utf16_string_length, uint32_t name_hash, libfsapfs_directory_record_t **directory_record, + int recursion_depth, libcerror_error_t **error ) { libfsapfs_btree_entry_t *entry = NULL; @@ -2280,6 +2309,18 @@ return( -1 ); } + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) { @@ -2542,6 +2583,7 @@ utf16_string_length, name_hash, directory_record, + recursion_depth + 1, error ); } if( result == -1 ) @@ -2831,6 +2873,7 @@ libfsapfs_btree_node_t *node, uint64_t parent_identifier, libcdata_array_t *directory_entries, + int recursion_depth, libcerror_error_t **error ) { libfsapfs_btree_entry_t *entry = NULL; @@ -2868,6 +2911,18 @@ return( -1 ); } + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } is_leaf_node = libfsapfs_btree_node_is_leaf_node( node, error ); @@ -3056,6 +3111,7 @@ sub_node, parent_identifier, directory_entries, + recursion_depth + 1, error ); } if( result == -1 ) @@ -3143,6 +3199,7 @@ sub_node, parent_identifier, directory_entries, + recursion_depth + 1, error ); } if( result == -1 ) @@ -3290,6 +3347,7 @@ root_node, parent_identifier, directory_entries, + 0, error ); } if( result == -1 ) @@ -3599,6 +3657,7 @@ libfsapfs_btree_node_t *node, uint64_t identifier, libcdata_array_t *extended_attributes, + int recursion_depth, libcerror_error_t **error ) { libfsapfs_btree_entry_t *entry = NULL; @@ -3636,6 +3695,18 @@ return( -1 ); } + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } is_leaf_node = libfsapfs_btree_node_is_leaf_node( node, error ); @@ -3825,6 +3896,7 @@ sub_node, identifier, extended_attributes, + recursion_depth + 1, error ); } if( result == -1 ) @@ -3913,6 +3985,7 @@ sub_node, identifier, extended_attributes, + recursion_depth + 1, error ); } if( result == -1 ) @@ -4061,6 +4134,7 @@ root_node, identifier, extended_attributes, + 0, error ); } if( result == -1 ) @@ -4354,6 +4428,7 @@ libfsapfs_btree_node_t *node, uint64_t identifier, libcdata_array_t *file_extents, + int recursion_depth, libcerror_error_t **error ) { libfsapfs_btree_entry_t *entry = NULL; @@ -4392,6 +4467,18 @@ return( -1 ); } + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } is_leaf_node = libfsapfs_btree_node_is_leaf_node( node, error ); @@ -4592,6 +4679,7 @@ sub_node, identifier, file_extents, + recursion_depth + 1, error ); } if( result == -1 ) @@ -4681,6 +4769,7 @@ sub_node, identifier, file_extents, + recursion_depth + 1, error ); } if( result == -1 ) @@ -4793,6 +4882,7 @@ root_node, identifier, file_extents, + 0, error ); } if( result == -1 ) @@ -5192,6 +5282,7 @@ utf8_string_length, name_hash, directory_record, + 0, error ); } if( result == -1 ) @@ -5576,6 +5667,7 @@ utf8_string_segment_length, name_hash, &safe_directory_record, + 0, error ); } } @@ -5889,6 +5981,7 @@ utf16_string_length, name_hash, directory_record, + 0, error ); } if( result == -1 ) @@ -6273,6 +6366,7 @@ utf16_string_segment_length, name_hash, &safe_directory_record, + 0, error ); } } diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_system_btree.h libfsapfs-20190210/libfsapfs/libfsapfs_file_system_btree.h --- libfsapfs-20181215/libfsapfs/libfsapfs_file_system_btree.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_system_btree.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The file system B-tree functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -149,6 +149,7 @@ size_t utf8_string_length, uint32_t name_hash, libfsapfs_directory_record_t **directory_record, + int recursion_depth, libcerror_error_t **error ); int libfsapfs_file_system_btree_get_directory_record_from_leaf_node_by_utf16_name( @@ -170,6 +171,7 @@ size_t utf16_string_length, uint32_t name_hash, libfsapfs_directory_record_t **directory_record, + int recursion_depth, libcerror_error_t **error ); int libfsapfs_file_system_btree_get_directory_entries_from_leaf_node( @@ -185,6 +187,7 @@ libfsapfs_btree_node_t *node, uint64_t parent_identifier, libcdata_array_t *directory_entries, + int recursion_depth, libcerror_error_t **error ); int libfsapfs_file_system_btree_get_directory_entries( @@ -208,6 +211,7 @@ libfsapfs_btree_node_t *node, uint64_t identifier, libcdata_array_t *extended_attributes, + int recursion_depth, libcerror_error_t **error ); int libfsapfs_file_system_btree_get_extended_attributes( @@ -230,6 +234,7 @@ libfsapfs_btree_node_t *node, uint64_t identifier, libcdata_array_t *file_extents, + int recursion_depth, libcerror_error_t **error ); int libfsapfs_file_system_btree_get_file_extents( diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_system_data_handle.c libfsapfs-20190210/libfsapfs/libfsapfs_file_system_data_handle.c --- libfsapfs-20181215/libfsapfs/libfsapfs_file_system_data_handle.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_system_data_handle.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The file system data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_file_system_data_handle.h libfsapfs-20190210/libfsapfs/libfsapfs_file_system_data_handle.h --- libfsapfs-20181215/libfsapfs/libfsapfs_file_system_data_handle.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_file_system_data_handle.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The file system data handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_fusion_middle_tree.c libfsapfs-20190210/libfsapfs/libfsapfs_fusion_middle_tree.c --- libfsapfs-20181215/libfsapfs/libfsapfs_fusion_middle_tree.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_fusion_middle_tree.c 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,372 @@ +/* + * The Fusion middle tree functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include + +#include "libfsapfs_fusion_middle_tree.h" +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" +#include "libfsapfs_libcnotify.h" + +#include "fsapfs_fusion_middle_tree.h" + +/* Creates a Fusion middle tree + * Make sure the value fusion_middle_tree is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int libfsapfs_fusion_middle_tree_initialize( + libfsapfs_fusion_middle_tree_t **fusion_middle_tree, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_fusion_middle_tree_initialize"; + + if( fusion_middle_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid Fusion middle tree.", + function ); + + return( -1 ); + } + if( *fusion_middle_tree != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid Fusion middle tree value already set.", + function ); + + return( -1 ); + } + *fusion_middle_tree = memory_allocate_structure( + libfsapfs_fusion_middle_tree_t ); + + if( *fusion_middle_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create Fusion middle tree.", + function ); + + goto on_error; + } + if( memory_set( + *fusion_middle_tree, + 0, + sizeof( libfsapfs_fusion_middle_tree_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear Fusion middle tree.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( *fusion_middle_tree != NULL ) + { + memory_free( + *fusion_middle_tree ); + + *fusion_middle_tree = NULL; + } + return( -1 ); +} + +/* Frees a Fusion middle tree + * Returns 1 if successful or -1 on error + */ +int libfsapfs_fusion_middle_tree_free( + libfsapfs_fusion_middle_tree_t **fusion_middle_tree, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_fusion_middle_tree_free"; + + if( fusion_middle_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid Fusion middle tree.", + function ); + + return( -1 ); + } + if( *fusion_middle_tree != NULL ) + { + memory_free( + *fusion_middle_tree ); + + *fusion_middle_tree = NULL; + } + return( 1 ); +} + +/* Reads the Fusion middle tree + * Returns 1 if successful or -1 on error + */ +int libfsapfs_fusion_middle_tree_read_file_io_handle( + libfsapfs_fusion_middle_tree_t *fusion_middle_tree, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ) +{ + uint8_t fusion_middle_tree_data[ 4096 ]; + + static char *function = "libfsapfs_fusion_middle_tree_read_file_io_handle"; + ssize_t read_count = 0; + + if( fusion_middle_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid Fusion middle tree.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: reading Fusion middle tree at offset: %" PRIi64 " (0x%08" PRIx64 ")\n", + function, + file_offset, + file_offset ); + } +#endif + if( libbfio_handle_seek_offset( + file_io_handle, + file_offset, + SEEK_SET, + error ) == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_SEEK_FAILED, + "%s: unable to seek Fusion middle tree offset: %" PRIi64 " (0x%08" PRIx64 ").", + function, + file_offset, + file_offset ); + + return( -1 ); + } + read_count = libbfio_handle_read_buffer( + file_io_handle, + fusion_middle_tree_data, + 4096, + error ); + + if( read_count != (ssize_t) 4096 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read Fusion middle tree data.", + function ); + + return( -1 ); + } + if( libfsapfs_fusion_middle_tree_read_data( + fusion_middle_tree, + fusion_middle_tree_data, + 4096, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read Fusion middle tree data.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Reads the Fusion middle tree + * Returns 1 if successful or -1 on error + */ +int libfsapfs_fusion_middle_tree_read_data( + libfsapfs_fusion_middle_tree_t *fusion_middle_tree, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_fusion_middle_tree_read_data"; + uint32_t object_subtype = 0; + uint32_t object_type = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + uint64_t value_64bit = 0; + uint32_t value_32bit = 0; +#endif + + if( fusion_middle_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid Fusion middle tree.", + function ); + + return( -1 ); + } + if( data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data.", + function ); + + return( -1 ); + } + if( ( data_size < sizeof( fsapfs_fusion_middle_tree_t ) ) + || ( data_size > (size_t) SSIZE_MAX ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid data size value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: Fusion middle tree data:\n", + function ); + libcnotify_print_data( + data, + data_size, + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + } +#endif + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_fusion_middle_tree_t *) data )->object_type, + object_type ); + + if( object_type != 0x40000002UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object type: 0x%08" PRIx32 ".", + function, + object_type ); + + return( -1 ); + } + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_fusion_middle_tree_t *) data )->object_subtype, + object_subtype ); + + if( object_subtype != 0x00000015UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object subtype: 0x%08" PRIx32 ".", + function, + object_subtype ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_fusion_middle_tree_t *) data )->object_checksum, + value_64bit ); + libcnotify_printf( + "%s: object checksum\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_fusion_middle_tree_t *) data )->object_identifier, + value_64bit ); + libcnotify_printf( + "%s: object identifier\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_fusion_middle_tree_t *) data )->object_transaction_identifier, + value_64bit ); + libcnotify_printf( + "%s: object transaction identifier\t: %" PRIu64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "%s: object type\t\t\t: 0x%08" PRIx32 "\n", + function, + object_type ); + + libcnotify_printf( + "%s: object subtype\t\t\t: 0x%08" PRIx32 "\n", + function, + object_subtype ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_fusion_middle_tree_t *) data )->unknown1, + value_32bit ); + libcnotify_printf( + "%s: unknown1\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + libcnotify_printf( + "\n" ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + + return( 1 ); +} + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_fusion_middle_tree.h libfsapfs-20190210/libfsapfs/libfsapfs_fusion_middle_tree.h --- libfsapfs-20181215/libfsapfs/libfsapfs_fusion_middle_tree.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_fusion_middle_tree.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * The Fusion middle tree functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBFSAPFS_FUSION_MIDDLE_TREE_H ) +#define _LIBFSAPFS_FUSION_MIDDLE_TREE_H + +#include +#include + +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct libfsapfs_fusion_middle_tree libfsapfs_fusion_middle_tree_t; + +struct libfsapfs_fusion_middle_tree +{ + /* Dummy + */ + int dummy; +}; + +int libfsapfs_fusion_middle_tree_initialize( + libfsapfs_fusion_middle_tree_t **fusion_middle_tree, + libcerror_error_t **error ); + +int libfsapfs_fusion_middle_tree_free( + libfsapfs_fusion_middle_tree_t **fusion_middle_tree, + libcerror_error_t **error ); + +int libfsapfs_fusion_middle_tree_read_file_io_handle( + libfsapfs_fusion_middle_tree_t *fusion_middle_tree, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ); + +int libfsapfs_fusion_middle_tree_read_data( + libfsapfs_fusion_middle_tree_t *fusion_middle_tree, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBFSAPFS_FUSION_MIDDLE_TREE_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_inode.c libfsapfs-20190210/libfsapfs/libfsapfs_inode.c --- libfsapfs-20181215/libfsapfs/libfsapfs_inode.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_inode.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Inode functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_inode.h libfsapfs-20190210/libfsapfs/libfsapfs_inode.h --- libfsapfs-20181215/libfsapfs/libfsapfs_inode.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_inode.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Inode functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_io_handle.c libfsapfs-20190210/libfsapfs/libfsapfs_io_handle.c --- libfsapfs-20181215/libfsapfs/libfsapfs_io_handle.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_io_handle.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Input/Output (IO) handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_io_handle.h libfsapfs-20190210/libfsapfs/libfsapfs_io_handle.h --- libfsapfs-20181215/libfsapfs/libfsapfs_io_handle.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_io_handle.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Input/Output (IO) handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_entry.c libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_entry.c --- libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_entry.c 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_entry.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The key bag entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_entry.h libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_entry.h --- libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_entry.h 2018-12-03 17:49:11.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_entry.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The key bag entry functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_header.c libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_header.c --- libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_header.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_header.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The key bag header functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_header.h libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_header.h --- libfsapfs-20181215/libfsapfs/libfsapfs_key_bag_header.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_key_bag_header.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The key bag header functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_key_encrypted_key.c libfsapfs-20190210/libfsapfs/libfsapfs_key_encrypted_key.c --- libfsapfs-20181215/libfsapfs/libfsapfs_key_encrypted_key.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_key_encrypted_key.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The key encrypted key (KEK) functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_key_encrypted_key.h libfsapfs-20190210/libfsapfs/libfsapfs_key_encrypted_key.h --- libfsapfs-20181215/libfsapfs/libfsapfs_key_encrypted_key.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_key_encrypted_key.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The key encrypted key (KEK) functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libbfio.h libfsapfs-20190210/libfsapfs/libfsapfs_libbfio.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libbfio.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libbfio.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libbfio header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libcaes.h libfsapfs-20190210/libfsapfs/libfsapfs_libcaes.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libcaes.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libcaes.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcaes header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libcdata.h libfsapfs-20190210/libfsapfs/libfsapfs_libcdata.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libcdata.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libcdata.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcdata header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libcerror.h libfsapfs-20190210/libfsapfs/libfsapfs_libcerror.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libcerror.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libcerror.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libclocale.h libfsapfs-20190210/libfsapfs/libfsapfs_libclocale.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libclocale.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libclocale.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libclocale header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libcnotify.h libfsapfs-20190210/libfsapfs/libfsapfs_libcnotify.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libcnotify.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libcnotify.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcnotify header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libcthreads.h libfsapfs-20190210/libfsapfs/libfsapfs_libcthreads.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libcthreads.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libcthreads.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcthreads header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libfcache.h libfsapfs-20190210/libfsapfs/libfsapfs_libfcache.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libfcache.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libfcache.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfcache header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libfdata.h libfsapfs-20190210/libfsapfs/libfsapfs_libfdata.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libfdata.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libfdata.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfdata header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libfdatetime.h libfsapfs-20190210/libfsapfs/libfsapfs_libfdatetime.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libfdatetime.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libfdatetime.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfdatetime header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libfguid.h libfsapfs-20190210/libfsapfs/libfsapfs_libfguid.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libfguid.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libfguid.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfguid header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libhmac.h libfsapfs-20190210/libfsapfs/libfsapfs_libhmac.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libhmac.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libhmac.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal libhmac header * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_libuna.h libfsapfs-20190210/libfsapfs/libfsapfs_libuna.h --- libfsapfs-20181215/libfsapfs/libfsapfs_libuna.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_libuna.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libuna header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_lzvn.c libfsapfs-20190210/libfsapfs/libfsapfs_lzvn.c --- libfsapfs-20181215/libfsapfs/libfsapfs_lzvn.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_lzvn.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * LZVN (un)compression functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_lzvn.h libfsapfs-20190210/libfsapfs/libfsapfs_lzvn.h --- libfsapfs-20181215/libfsapfs/libfsapfs_lzvn.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_lzvn.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * LZVN (un)compression functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_name.c libfsapfs-20190210/libfsapfs/libfsapfs_name.c --- libfsapfs-20181215/libfsapfs/libfsapfs_name.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_name.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Name functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_name.h libfsapfs-20190210/libfsapfs/libfsapfs_name.h --- libfsapfs-20181215/libfsapfs/libfsapfs_name.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_name.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Name functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_name_hash.c libfsapfs-20190210/libfsapfs/libfsapfs_name_hash.c --- libfsapfs-20181215/libfsapfs/libfsapfs_name_hash.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_name_hash.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Name hash functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_name_hash.h libfsapfs-20190210/libfsapfs/libfsapfs_name_hash.h --- libfsapfs-20181215/libfsapfs/libfsapfs_name_hash.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_name_hash.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Name hash functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_notify.c libfsapfs-20190210/libfsapfs/libfsapfs_notify.c --- libfsapfs-20181215/libfsapfs/libfsapfs_notify.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_notify.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Notification functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_notify.h libfsapfs-20190210/libfsapfs/libfsapfs_notify.h --- libfsapfs-20181215/libfsapfs/libfsapfs_notify.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_notify.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Notification functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object.c libfsapfs-20190210/libfsapfs/libfsapfs_object.c --- libfsapfs-20181215/libfsapfs/libfsapfs_object.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS object functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object.h libfsapfs-20190210/libfsapfs/libfsapfs_object.h --- libfsapfs-20181215/libfsapfs/libfsapfs_object.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The APFS object functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object_map_btree.c libfsapfs-20190210/libfsapfs/libfsapfs_object_map_btree.c --- libfsapfs-20181215/libfsapfs/libfsapfs_object_map_btree.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object_map_btree.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The object map B-tree functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -990,6 +990,7 @@ static char *function = "libfsapfs_object_map_btree_get_entry_by_identifier"; uint64_t sub_node_block_number = 0; int is_leaf_node = 0; + int recursion_depth = 0; int result = 0; if( object_map_btree == NULL ) @@ -1043,6 +1044,18 @@ } do { + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } is_leaf_node = libfsapfs_btree_node_is_leaf_node( node, error ); @@ -1152,6 +1165,7 @@ return( -1 ); } + recursion_depth++; } while( is_leaf_node == 0 ); diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object_map_btree.h libfsapfs-20190210/libfsapfs/libfsapfs_object_map_btree.h --- libfsapfs-20181215/libfsapfs/libfsapfs_object_map_btree.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object_map_btree.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The object map B-tree functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object_map.c libfsapfs-20190210/libfsapfs/libfsapfs_object_map.c --- libfsapfs-20181215/libfsapfs/libfsapfs_object_map.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object_map.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The object map functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -317,9 +317,17 @@ return( -1 ); } + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_object_map_t *) data )->number_of_snapshots, + object_map->number_of_snapshots ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_object_map_t *) data )->btree_block_number, + object_map->btree_block_number ); + byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_object_map_t *) data )->object_map_btree_block_number, - object_map->object_map_btree_block_number ); + ( (fsapfs_object_map_t *) data )->snapshots_btree_block_number, + object_map->snapshots_btree_block_number ); #if defined( HAVE_DEBUG_OUTPUT ) if( libcnotify_verbose != 0 ) @@ -359,55 +367,65 @@ object_subtype ); byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_object_map_t *) data )->unknown1, + ( (fsapfs_object_map_t *) data )->flags, value_32bit ); libcnotify_printf( - "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: flags\t\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); - byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_object_map_t *) data )->unknown2, - value_32bit ); libcnotify_printf( - "%s: unknown2\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: number of snapshots\t\t\t: %" PRIu32 "\n", function, - value_32bit ); + object_map->number_of_snapshots ); byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_object_map_t *) data )->unknown3, + ( (fsapfs_object_map_t *) data )->btree_type, value_32bit ); libcnotify_printf( - "%s: unknown3\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: B-tree type\t\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_object_map_t *) data )->unknown4, + ( (fsapfs_object_map_t *) data )->snaphots_btree_type, value_32bit ); libcnotify_printf( - "%s: unknown4\t\t\t\t: 0x%08" PRIx32 "\n", + "%s: snapshots B-tree type\t\t\t: 0x%08" PRIx32 "\n", function, value_32bit ); libcnotify_printf( - "%s: object map B-tree block number\t\t: %" PRIu64 "\n", + "%s: B-tree block number\t\t\t: %" PRIu64 "\n", + function, + object_map->btree_block_number ); + + libcnotify_printf( + "%s: snapshots B-tree block number\t\t: %" PRIu64 "\n", function, - object_map->object_map_btree_block_number ); + object_map->snapshots_btree_block_number ); byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_object_map_t *) data )->unknown6, + ( (fsapfs_object_map_t *) data )->unknown1, value_64bit ); libcnotify_printf( - "%s: unknown6\t\t\t\t: %" PRIu64 "\n", + "%s: unknown1\t\t\t\t: %" PRIu64 "\n", function, value_64bit ); byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_object_map_t *) data )->unknown7, + ( (fsapfs_object_map_t *) data )->unknown2, + value_64bit ); + libcnotify_printf( + "%s: unknown2\t\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_object_map_t *) data )->unknown3, value_64bit ); libcnotify_printf( - "%s: unknown7\t\t\t\t: %" PRIu64 "\n", + "%s: unknown3\t\t\t\t: %" PRIu64 "\n", function, value_64bit ); diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object_map_descriptor.c libfsapfs-20190210/libfsapfs/libfsapfs_object_map_descriptor.c --- libfsapfs-20181215/libfsapfs/libfsapfs_object_map_descriptor.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object_map_descriptor.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The object map descriptor functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object_map_descriptor.h libfsapfs-20190210/libfsapfs/libfsapfs_object_map_descriptor.h --- libfsapfs-20181215/libfsapfs/libfsapfs_object_map_descriptor.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object_map_descriptor.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The object map descriptor functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_object_map.h libfsapfs-20190210/libfsapfs/libfsapfs_object_map.h --- libfsapfs-20181215/libfsapfs/libfsapfs_object_map.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_object_map.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The object map functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -36,9 +36,17 @@ struct libfsapfs_object_map { - /* The object map btree block number + /* The number of snapshots */ - uint64_t object_map_btree_block_number; + uint32_t number_of_snapshots; + + /* The B-tree block number + */ + uint64_t btree_block_number; + + /* The snapshots B-tree block number + */ + uint64_t snapshots_btree_block_number; }; int libfsapfs_object_map_initialize( diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_password.c libfsapfs-20190210/libfsapfs/libfsapfs_password.c --- libfsapfs-20181215/libfsapfs/libfsapfs_password.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_password.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Password functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_password.h libfsapfs-20190210/libfsapfs/libfsapfs_password.h --- libfsapfs-20181215/libfsapfs/libfsapfs_password.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_password.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Password functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_profiler.c libfsapfs-20190210/libfsapfs/libfsapfs_profiler.c --- libfsapfs-20181215/libfsapfs/libfsapfs_profiler.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_profiler.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The profiler functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_profiler.h libfsapfs-20190210/libfsapfs/libfsapfs_profiler.h --- libfsapfs-20181215/libfsapfs/libfsapfs_profiler.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_profiler.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The profiler functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs.rc libfsapfs-20190210/libfsapfs/libfsapfs.rc --- libfsapfs-20181215/libfsapfs/libfsapfs.rc 2018-12-15 06:44:19.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs.rc 2019-02-10 19:59:54.000000000 +0000 @@ -22,12 +22,12 @@ BLOCK "040904E4" BEGIN VALUE "FileDescription", "Library to access the Apple File System (APFS) format\0" - VALUE "FileVersion", "20181215" "\0" + VALUE "FileVersion", "20190210" "\0" VALUE "InternalName", "libfsapfs.dll\0" - VALUE "LegalCopyright", "(C) 2018, Joachim Metz \0" + VALUE "LegalCopyright", "(C) 2018-2019, Joachim Metz \0" VALUE "OriginalFilename", "libfsapfs.dll\0" VALUE "ProductName", "libfsapfs\0" - VALUE "ProductVersion", "20181215" "\0" + VALUE "ProductVersion", "20190210" "\0" VALUE "Comments", "For more information visit https://github.com/libyal/libfsapfs/\0" END END diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs.rc.in libfsapfs-20190210/libfsapfs/libfsapfs.rc.in --- libfsapfs-20181215/libfsapfs/libfsapfs.rc.in 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs.rc.in 2019-02-06 20:10:15.000000000 +0000 @@ -24,7 +24,7 @@ VALUE "FileDescription", "Library to access the Apple File System (APFS) format\0" VALUE "FileVersion", "@VERSION@" "\0" VALUE "InternalName", "libfsapfs.dll\0" - VALUE "LegalCopyright", "(C) 2018, Joachim Metz \0" + VALUE "LegalCopyright", "(C) 2018-2019, Joachim Metz \0" VALUE "OriginalFilename", "libfsapfs.dll\0" VALUE "ProductName", "libfsapfs\0" VALUE "ProductVersion", "@VERSION@" "\0" diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata.c libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata.c --- libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata.c 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,372 @@ +/* + * The snapshot metadata functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include + +#include "libfsapfs_debug.h" +#include "libfsapfs_libcerror.h" +#include "libfsapfs_libcnotify.h" +#include "libfsapfs_libfdatetime.h" +#include "libfsapfs_snapshot_metadata.h" + +#include "fsapfs_snapshot_metadata.h" + +/* Creates physical_map_entry + * Make sure the value snapshot_metadata is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_initialize( + libfsapfs_snapshot_metadata_t **snapshot_metadata, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_snapshot_metadata_initialize"; + + if( snapshot_metadata == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata.", + function ); + + return( -1 ); + } + if( *snapshot_metadata != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid snapshot metadata value already set.", + function ); + + return( -1 ); + } + *snapshot_metadata = memory_allocate_structure( + libfsapfs_snapshot_metadata_t ); + + if( *snapshot_metadata == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create snapshot metadata.", + function ); + + goto on_error; + } + if( memory_set( + *snapshot_metadata, + 0, + sizeof( libfsapfs_snapshot_metadata_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear snapshot metadata.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( *snapshot_metadata != NULL ) + { + memory_free( + *snapshot_metadata ); + + *snapshot_metadata = NULL; + } + return( -1 ); +} + +/* Frees snapshot metadata + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_free( + libfsapfs_snapshot_metadata_t **snapshot_metadata, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_snapshot_metadata_free"; + + if( snapshot_metadata == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata.", + function ); + + return( -1 ); + } + if( *snapshot_metadata != NULL ) + { + memory_free( + *snapshot_metadata ); + + *snapshot_metadata = NULL; + } + return( 1 ); +} + +/* Reads the snapshot metadata B-tree key data + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_read_key_data( + libfsapfs_snapshot_metadata_t *snapshot_metadata, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_snapshot_metadata_read_key_data"; + +#if defined( HAVE_DEBUG_OUTPUT ) + uint64_t value_64bit = 0; +#endif + + if( snapshot_metadata == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata.", + function ); + + return( -1 ); + } + if( data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data.", + function ); + + return( -1 ); + } + if( ( data_size < sizeof( fsapfs_snapshot_metadata_btree_key_t ) ) + || ( data_size > (size_t) SSIZE_MAX ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid data size value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: snapshot metadata tree key data:\n", + function ); + libcnotify_print_data( + data, + sizeof( fsapfs_snapshot_metadata_btree_key_t ), + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + } +#endif + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_snapshot_metadata_btree_key_t *) data )->object_identifier, + value_64bit ); + libcnotify_printf( + "%s: object identifier\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "\n" ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + + return( 1 ); +} + +/* Reads the snapshot metadata B-tree value data + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_read_value_data( + libfsapfs_snapshot_metadata_t *snapshot_metadata, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_snapshot_metadata_read_value_data"; + +#if defined( HAVE_DEBUG_OUTPUT ) + uint64_t value_64bit = 0; + uint32_t value_32bit = 0; + uint16_t value_16bit = 0; +#endif + + if( snapshot_metadata == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata.", + function ); + + return( -1 ); + } + if( data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data.", + function ); + + return( -1 ); + } + if( ( data_size < sizeof( fsapfs_snapshot_metadata_btree_value_t ) ) + || ( data_size > (size_t) SSIZE_MAX ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid data size value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: snapshot metadata tree value data:\n", + function ); + libcnotify_print_data( + data, + sizeof( fsapfs_snapshot_metadata_btree_value_t ), + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + } +#endif +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_snapshot_metadata_btree_value_t *) data )->extent_reference_tree_object_identifier, + value_64bit ); + libcnotify_printf( + "%s: extent-reference tree object identifier\t: %" PRIu32 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_snapshot_metadata_btree_value_t *) data )->volume_superblock_object_identifier, + value_64bit ); + libcnotify_printf( + "%s: volume superblock object identifier\t\t\t: %" PRIu32 "\n", + function, + value_64bit ); + + if( libfsapfs_debug_print_posix_time_value( + function, + "creation time\t\t\t\t", + ( (fsapfs_snapshot_metadata_btree_value_t *) data )->creation_time, + 8, + LIBFDATETIME_ENDIAN_LITTLE, + LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED, + LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, + "%s: unable to print POSIX time value.", + function ); + + return( -1 ); + } + if( libfsapfs_debug_print_posix_time_value( + function, + "change time\t\t\t\t", + ( (fsapfs_snapshot_metadata_btree_value_t *) data )->change_time, + 8, + LIBFDATETIME_ENDIAN_LITTLE, + LIBFDATETIME_POSIX_TIME_VALUE_TYPE_NANO_SECONDS_64BIT_SIGNED, + LIBFDATETIME_STRING_FORMAT_TYPE_ISO8601 | LIBFDATETIME_STRING_FORMAT_FLAG_DATE_TIME_NANO_SECONDS, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_PRINT_FAILED, + "%s: unable to print POSIX time value.", + function ); + + return( -1 ); + } + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_snapshot_metadata_btree_value_t *) data )->extent_reference_tree_object_type, + value_32bit ); + libcnotify_printf( + "%s: extent-reference tree object type\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_snapshot_metadata_btree_value_t *) data )->flags, + value_32bit ); + libcnotify_printf( + "%s: flags\t\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint16_little_endian( + ( (fsapfs_snapshot_metadata_btree_value_t *) data )->name_size, + value_16bit ); + libcnotify_printf( + "%s: name size\t\t\t\t\t: size: %" PRIu16 "\n", + function, + value_16bit ); + +/* TODO debug print name */ + + libcnotify_printf( + "\n" ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + + return( 1 ); +} + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata.h libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata.h --- libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,68 @@ +/* + * The snapshot metadata functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBFSAPFS_SNAPSHOT_METADATA_H ) +#define _LIBFSAPFS_SNAPSHOT_METADATA_H + +#include +#include + +#include "libfsapfs_libcerror.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct libfsapfs_snapshot_metadata libfsapfs_snapshot_metadata_t; + +struct libfsapfs_snapshot_metadata +{ + /* Dummy + */ + int dummy; +}; + +int libfsapfs_snapshot_metadata_initialize( + libfsapfs_snapshot_metadata_t **snapshot_metadata, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_free( + libfsapfs_snapshot_metadata_t **snapshot_metadata, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_read_key_data( + libfsapfs_snapshot_metadata_t *snapshot_metadata, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_read_value_data( + libfsapfs_snapshot_metadata_t *snapshot_metadata, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBFSAPFS_SNAPSHOT_METADATA_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata_tree.c libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata_tree.c --- libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata_tree.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata_tree.c 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,1320 @@ +/* + * The snapshot metadata tree functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include + +#include "libfsapfs_btree_entry.h" +#include "libfsapfs_btree_node.h" +#include "libfsapfs_data_block.h" +#include "libfsapfs_definitions.h" +#include "libfsapfs_io_handle.h" +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" +#include "libfsapfs_libcnotify.h" +#include "libfsapfs_libfcache.h" +#include "libfsapfs_libfdata.h" +#include "libfsapfs_snapshot_metadata.h" +#include "libfsapfs_snapshot_metadata_tree.h" + +#include "fsapfs_object.h" +#include "fsapfs_snapshot_metadata.h" + +/* Creates a snapshot metadata tree + * Make sure the value snapshot_metadata_tree is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_tree_initialize( + libfsapfs_snapshot_metadata_tree_t **snapshot_metadata_tree, + libfsapfs_io_handle_t *io_handle, + libfdata_vector_t *data_block_vector, + uint64_t root_node_block_number, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_snapshot_metadata_tree_initialize"; + + if( snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata tree.", + function ); + + return( -1 ); + } + if( *snapshot_metadata_tree != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid snapshot metadata tree value already set.", + function ); + + return( -1 ); + } + *snapshot_metadata_tree = memory_allocate_structure( + libfsapfs_snapshot_metadata_tree_t ); + + if( *snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create snapshot metadata tree.", + function ); + + goto on_error; + } + if( memory_set( + *snapshot_metadata_tree, + 0, + sizeof( libfsapfs_snapshot_metadata_tree_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear snapshot metadata tree.", + function ); + + memory_free( + *snapshot_metadata_tree ); + + *snapshot_metadata_tree = NULL; + + return( -1 ); + } + if( libfcache_cache_initialize( + &( ( *snapshot_metadata_tree )->data_block_cache ), + LIBFSAPFS_MAXIMUM_CACHE_ENTRIES_DATA_BLOCKS, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create data block cache.", + function ); + + goto on_error; + } + if( libfcache_cache_initialize( + &( ( *snapshot_metadata_tree )->node_cache ), + LIBFSAPFS_MAXIMUM_CACHE_ENTRIES_BTREE_NODES, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create node cache.", + function ); + + goto on_error; + } + ( *snapshot_metadata_tree )->io_handle = io_handle; + ( *snapshot_metadata_tree )->data_block_vector = data_block_vector; + ( *snapshot_metadata_tree )->root_node_block_number = root_node_block_number; + + return( 1 ); + +on_error: + if( *snapshot_metadata_tree != NULL ) + { + memory_free( + *snapshot_metadata_tree ); + + *snapshot_metadata_tree = NULL; + } + return( -1 ); +} + +/* Frees a snapshot metadata tree + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_tree_free( + libfsapfs_snapshot_metadata_tree_t **snapshot_metadata_tree, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_snapshot_metadata_tree_free"; + int result = 1; + + if( snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata tree.", + function ); + + return( -1 ); + } + if( *snapshot_metadata_tree != NULL ) + { + /* The data_block_vector is referenced and freed elsewhere + */ + if( libfcache_cache_free( + &( ( *snapshot_metadata_tree )->node_cache ), + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free node cache.", + function ); + + result = -1; + } + if( libfcache_cache_free( + &( ( *snapshot_metadata_tree )->data_block_cache ), + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free data block cache.", + function ); + + result = -1; + } + memory_free( + *snapshot_metadata_tree ); + + *snapshot_metadata_tree = NULL; + } + return( result ); +} + +/* Retrieves the snapshot metadata tree root node + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_tree_get_root_node( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t root_node_block_number, + libfsapfs_btree_node_t **root_node, + libcerror_error_t **error ) +{ + libfcache_cache_value_t *cache_value = NULL; + libfsapfs_btree_node_t *node = NULL; + libfsapfs_data_block_t *data_block = NULL; + static char *function = "libfsapfs_snapshot_metadata_tree_get_root_node"; + int result = 0; + +#if defined( HAVE_PROFILER ) + int64_t profiler_start_timestamp = 0; +#endif + + if( snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata tree.", + function ); + + return( -1 ); + } + if( root_node_block_number > (uint64_t) INT_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid root node block number value out of bounds.", + function ); + + return( -1 ); + } + if( root_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid root node.", + function ); + + return( -1 ); + } +#if defined( HAVE_PROFILER ) + if( snapshot_metadata_tree->io_handle->profiler != NULL ) + { + if( libfsapfs_profiler_start_timing( + snapshot_metadata_tree->io_handle->profiler, + &profiler_start_timestamp, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to start timing.", + function ); + + goto on_error; + } + } +#endif /* defined( HAVE_PROFILER ) */ + + result = libfcache_cache_get_value_by_identifier( + snapshot_metadata_tree->node_cache, + 0, + (off64_t) root_node_block_number, + 0, + &cache_value, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from cache.", + function ); + + goto on_error; + } + else if( result == 0 ) + { + if( libfdata_vector_get_element_value_by_index( + snapshot_metadata_tree->data_block_vector, + (intptr_t *) file_io_handle, + (libfdata_cache_t *) snapshot_metadata_tree->data_block_cache, + (int) root_node_block_number, + (intptr_t **) &data_block, + 0, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve data block: %" PRIu64 ".", + function, + root_node_block_number ); + + goto on_error; + } + if( data_block == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data block: %" PRIu64 ".", + function, + root_node_block_number ); + + goto on_error; + } + if( libfsapfs_btree_node_initialize( + &node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create B-tree node.", + function ); + + goto on_error; + } + if( libfsapfs_btree_node_read_data( + node, + data_block->data, + data_block->data_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read B-tree node.", + function ); + + goto on_error; + } + if( node->object_type != 0x40000002UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object type: 0x%08" PRIx32 ".", + function, + node->object_type ); + + goto on_error; + } + if( node->object_subtype != 0x00000010UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object subtype: 0x%08" PRIx32 ".", + function, + node->object_subtype ); + + goto on_error; + } + if( ( node->node_header->flags & 0x0001 ) == 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported flags: 0x%04" PRIx16 ".", + function, + node->node_header->flags ); + + goto on_error; + } + if( node->footer->node_size != 4096 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid node size value out of bounds.", + function ); + + goto on_error; + } + if( node->footer->key_size != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid key size value out of bounds.", + function ); + + goto on_error; + } + if( node->footer->value_size != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid value size value out of bounds.", + function ); + + goto on_error; + } + if( libfcache_cache_set_value_by_identifier( + snapshot_metadata_tree->node_cache, + 0, + (off64_t) root_node_block_number, + 0, + (intptr_t *) node, + (int (*)(intptr_t **, libcerror_error_t **)) &libfsapfs_btree_node_free, + LIBFCACHE_CACHE_VALUE_FLAG_MANAGED, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set value in cache.", + function ); + + goto on_error; + } + node = NULL; + + if( libfcache_cache_get_value_by_identifier( + snapshot_metadata_tree->node_cache, + 0, + (off64_t) root_node_block_number, + 0, + &cache_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from cache.", + function ); + + goto on_error; + } + } +#if defined( HAVE_PROFILER ) + if( snapshot_metadata_tree->io_handle->profiler != NULL ) + { + if( libfsapfs_profiler_stop_timing( + snapshot_metadata_tree->io_handle->profiler, + profiler_start_timestamp, + function, + root_node_block_number * snapshot_metadata_tree->io_handle->block_size, + snapshot_metadata_tree->io_handle->block_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to stop timing.", + function ); + + goto on_error; + } + } +#endif /* defined( HAVE_PROFILER ) */ + + if( libfcache_cache_value_get_value( + cache_value, + (intptr_t **) root_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve root node.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( node != NULL ) + { + libfsapfs_btree_node_free( + &node, + NULL ); + } + return( -1 ); +} + +/* Retrieves a snapshot metadata tree sub node + * Returns 1 if successful or -1 on error + */ +int libfsapfs_snapshot_metadata_tree_get_sub_node( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t sub_node_block_number, + libfsapfs_btree_node_t **sub_node, + libcerror_error_t **error ) +{ + libfcache_cache_value_t *cache_value = NULL; + libfsapfs_btree_node_t *node = NULL; + libfsapfs_data_block_t *data_block = NULL; + static char *function = "libfsapfs_snapshot_metadata_tree_get_sub_node"; + int result = 0; + +#if defined( HAVE_PROFILER ) + int64_t profiler_start_timestamp = 0; +#endif + + if( snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata tree.", + function ); + + return( -1 ); + } + if( sub_node_block_number > (uint64_t) INT_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid sub node block number value out of bounds.", + function ); + + return( -1 ); + } + if( sub_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid sub node.", + function ); + + return( -1 ); + } +#if defined( HAVE_PROFILER ) + if( snapshot_metadata_tree->io_handle->profiler != NULL ) + { + if( libfsapfs_profiler_start_timing( + snapshot_metadata_tree->io_handle->profiler, + &profiler_start_timestamp, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to start timing.", + function ); + + goto on_error; + } + } +#endif /* defined( HAVE_PROFILER ) */ + + result = libfcache_cache_get_value_by_identifier( + snapshot_metadata_tree->node_cache, + 0, + (off64_t) sub_node_block_number, + 0, + &cache_value, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from cache.", + function ); + + goto on_error; + } + else if( result == 0 ) + { + if( libfdata_vector_get_element_value_by_index( + snapshot_metadata_tree->data_block_vector, + (intptr_t *) file_io_handle, + (libfdata_cache_t *) snapshot_metadata_tree->data_block_cache, + (int) sub_node_block_number, + (intptr_t **) &data_block, + 0, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve data block: %" PRIu64 ".", + function, + sub_node_block_number ); + + goto on_error; + } + if( data_block == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data block: %" PRIu64 ".", + function, + sub_node_block_number ); + + goto on_error; + } + if( libfsapfs_btree_node_initialize( + &node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create B-tree node.", + function ); + + goto on_error; + } + if( libfsapfs_btree_node_read_data( + node, + data_block->data, + data_block->data_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read B-tree node.", + function ); + + goto on_error; + } + if( node->object_type != 0x40000003UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object type: 0x%08" PRIx32 ".", + function, + node->object_type ); + + goto on_error; + } + if( node->object_subtype != 0x00000010UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object subtype: 0x%08" PRIx32 ".", + function, + node->object_subtype ); + + goto on_error; + } + if( ( node->node_header->flags & 0x0001 ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported flags: 0x%04" PRIx16 ".", + function, + node->node_header->flags ); + + goto on_error; + } + if( libfcache_cache_set_value_by_identifier( + snapshot_metadata_tree->node_cache, + 0, + (off64_t) sub_node_block_number, + 0, + (intptr_t *) node, + (int (*)(intptr_t **, libcerror_error_t **)) &libfsapfs_btree_node_free, + LIBFCACHE_CACHE_VALUE_FLAG_MANAGED, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set value in cache.", + function ); + + goto on_error; + } + node = NULL; + + if( libfcache_cache_get_value_by_identifier( + snapshot_metadata_tree->node_cache, + 0, + (off64_t) sub_node_block_number, + 0, + &cache_value, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve value from cache.", + function ); + + goto on_error; + } + } +#if defined( HAVE_PROFILER ) + if( snapshot_metadata_tree->io_handle->profiler != NULL ) + { + if( libfsapfs_profiler_stop_timing( + snapshot_metadata_tree->io_handle->profiler, + profiler_start_timestamp, + function, + sub_node_block_number * snapshot_metadata_tree->io_handle->block_size, + snapshot_metadata_tree->io_handle->block_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to stop timing.", + function ); + + goto on_error; + } + } +#endif /* defined( HAVE_PROFILER ) */ + + if( libfcache_cache_value_get_value( + cache_value, + (intptr_t **) sub_node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve sub node.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( node != NULL ) + { + libfsapfs_btree_node_free( + &node, + NULL ); + } + return( -1 ); +} + +/* Retrieves an entry for a specific identifier from the snapshot metadata tree node + * Returns 1 if successful, 0 if not found or -1 on error + */ +int libfsapfs_snapshot_metadata_tree_get_entry_from_node_by_identifier( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libfsapfs_btree_node_t *node, + uint64_t object_identifier, + libfsapfs_btree_entry_t **btree_entry, + libcerror_error_t **error ) +{ + libfsapfs_btree_entry_t *entry = NULL; + libfsapfs_btree_entry_t *previous_entry = NULL; + static char *function = "libfsapfs_snapshot_metadata_tree_get_entry_from_node_by_identifier"; + uint64_t snapshot_metadata_identifier = 0; + int btree_entry_index = 0; + int is_leaf_node = 0; + int number_of_entries = 0; + + if( snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata tree.", + function ); + + return( -1 ); + } + if( btree_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid B-tree entry.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: retrieving B-tree entry identifier: %" PRIu64 ".\n", + function, + object_identifier ); + } +#endif + is_leaf_node = libfsapfs_btree_node_is_leaf_node( + node, + error ); + + if( is_leaf_node == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine if B-tree node is a leaf node.", + function ); + + return( -1 ); + } + if( libfsapfs_btree_node_get_number_of_entries( + node, + &number_of_entries, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of entries from B-tree node.", + function ); + + return( -1 ); + } + for( btree_entry_index = 0; + btree_entry_index < number_of_entries; + btree_entry_index++ ) + { + if( libfsapfs_btree_node_get_entry_by_index( + node, + btree_entry_index, + &entry, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve number of entries from B-tree node.", + function ); + + return( -1 ); + } + if( entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid B-tree entry: %d.", + function, + btree_entry_index ); + + return( -1 ); + } + if( entry->key_data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid B-tree entry: %d - missing key data.", + function, + btree_entry_index ); + + return( -1 ); + } + byte_stream_copy_to_uint64_little_endian( + entry->key_data, + snapshot_metadata_identifier ); + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: B-tree entry: %d, identifier: %" PRIu64 "\n", + function, + btree_entry_index, + snapshot_metadata_identifier ); + } +#endif + if( snapshot_metadata_identifier > object_identifier ) + { + break; + } + if( is_leaf_node != 0 ) + { + if( snapshot_metadata_identifier == object_identifier ) + { + *btree_entry = entry; + + return( 1 ); + } + } + else + { + if( snapshot_metadata_identifier >= object_identifier ) + { + if( ( previous_entry == NULL ) + || ( snapshot_metadata_identifier == object_identifier ) ) + { + previous_entry = entry; + } + *btree_entry = previous_entry; + + return( 1 ); + } + previous_entry = entry; + } + } + if( is_leaf_node == 0 ) + { + *btree_entry = previous_entry; + + return( 1 ); + } + return( 0 ); +} + +/* Retrieves an entry for a specific identifier from the snapshot metadata tree + * Returns 1 if successful, 0 if not found or -1 on error + */ +int libfsapfs_snapshot_metadata_tree_get_entry_by_identifier( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t object_identifier, + libfsapfs_btree_node_t **btree_node, + libfsapfs_btree_entry_t **btree_entry, + libcerror_error_t **error ) +{ + libfsapfs_btree_entry_t *entry = NULL; + libfsapfs_btree_node_t *node = NULL; + static char *function = "libfsapfs_snapshot_metadata_tree_get_entry_by_identifier"; + uint64_t sub_node_block_number = 0; + int is_leaf_node = 0; + int recursion_depth = 0; + int result = 0; + + if( snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata tree.", + function ); + + return( -1 ); + } + if( btree_node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid B-tree node.", + function ); + + return( -1 ); + } + if( btree_entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid B-tree entry.", + function ); + + return( -1 ); + } + if( libfsapfs_snapshot_metadata_tree_get_root_node( + snapshot_metadata_tree, + file_io_handle, + snapshot_metadata_tree->root_node_block_number, + &node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve B-tree root node.", + function ); + + return( -1 ); + } + do + { + if( ( recursion_depth < 0 ) + || ( recursion_depth > LIBFSAPFS_MAXIMUM_BTREE_NODE_RECURSION_DEPTH ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid recursion depth value out of bounds.", + function ); + + return( -1 ); + } + is_leaf_node = libfsapfs_btree_node_is_leaf_node( + node, + error ); + + if( is_leaf_node == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to determine if B-tree node is a leaf node.", + function ); + + return( -1 ); + } + result = libfsapfs_snapshot_metadata_tree_get_entry_from_node_by_identifier( + snapshot_metadata_tree, + node, + object_identifier, + &entry, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve entry from B-tree node.", + function ); + + return( -1 ); + } + else if( result == 0 ) + { + break; + } + if( is_leaf_node != 0 ) + { + *btree_node = node; + *btree_entry = entry; + + return( 1 ); + } + if( entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid B-tree entry.", + function ); + + return( -1 ); + } + if( entry->value_data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid B-tree entry - missing value data.", + function ); + + return( -1 ); + } + if( entry->value_data_size != 8 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid B-tree entry - unsupported value data size.", + function ); + + return( -1 ); + } + byte_stream_copy_to_uint64_little_endian( + entry->value_data, + sub_node_block_number ); + +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: B-tree sub node block number: %" PRIu64 "\n", + function, + sub_node_block_number ); + } +#endif + node = NULL; + + if( libfsapfs_snapshot_metadata_tree_get_sub_node( + snapshot_metadata_tree, + file_io_handle, + sub_node_block_number, + &node, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve B-tree sub node from block: %" PRIu64 ".", + function, + sub_node_block_number ); + + return( -1 ); + } + recursion_depth++; + } + while( is_leaf_node == 0 ); + + return( 0 ); +} + +/* Retrieves the snapshot metadata of a specific object identifier + * Returns 1 if successful, 0 if no such value or -1 on error + */ +int libfsapfs_snapshot_metadata_tree_get_metadata_by_object_identifier( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t object_identifier, + libfsapfs_snapshot_metadata_t **metadata, + libcerror_error_t **error ) +{ + libfsapfs_btree_entry_t *entry = NULL; + libfsapfs_btree_node_t *node = NULL; + static char *function = "libfsapfs_snapshot_metadata_tree_get_metadata_by_object_identifier"; + int result = 0; + + if( snapshot_metadata_tree == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid snapshot metadata tree.", + function ); + + return( -1 ); + } + if( metadata == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid metadata.", + function ); + + return( -1 ); + } + if( *metadata != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid metadata value already set.", + function ); + + return( -1 ); + } + result = libfsapfs_snapshot_metadata_tree_get_entry_by_identifier( + snapshot_metadata_tree, + file_io_handle, + object_identifier, + &node, + &entry, + error ); + + if( result == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve entry from B-tree.", + function ); + + goto on_error; + } + else if( result != 0 ) + { + if( node == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid B-tree node.", + function ); + + goto on_error; + } + if( entry == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid B-tree entry.", + function ); + + goto on_error; + } + if( libfsapfs_snapshot_metadata_initialize( + metadata, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create snapshot metadata.", + function ); + + goto on_error; + } + if( libfsapfs_snapshot_metadata_read_key_data( + *metadata, + entry->key_data, + (size_t) entry->key_data_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read snapshot metadata key data.", + function ); + + goto on_error; + } + if( libfsapfs_snapshot_metadata_read_value_data( + *metadata, + entry->value_data, + (size_t) entry->value_data_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read snapshot metadata value data.", + function ); + + goto on_error; + } + node = NULL; + } + return( result ); + +on_error: + if( *metadata != NULL ) + { + libfsapfs_snapshot_metadata_free( + metadata, + NULL ); + } + return( -1 ); +} + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata_tree.h libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata_tree.h --- libfsapfs-20181215/libfsapfs/libfsapfs_snapshot_metadata_tree.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_snapshot_metadata_tree.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,118 @@ +/* + * The snapshot metadata tree functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBFSAPFS_SNAPSHOT_METADATA_TREE_H ) +#define _LIBFSAPFS_SNAPSHOT_METADATA_TREE_H + +#include +#include + +#include "libfsapfs_btree_entry.h" +#include "libfsapfs_btree_node.h" +#include "libfsapfs_io_handle.h" +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" +#include "libfsapfs_libfcache.h" +#include "libfsapfs_libfdata.h" +#include "libfsapfs_snapshot_metadata.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct libfsapfs_snapshot_metadata_tree libfsapfs_snapshot_metadata_tree_t; + +struct libfsapfs_snapshot_metadata_tree +{ + /* The IO handle + */ + libfsapfs_io_handle_t *io_handle; + + /* Data block vector + */ + libfdata_vector_t *data_block_vector; + + /* Data block cache + */ + libfcache_cache_t *data_block_cache; + + /* The node cache + */ + libfcache_cache_t *node_cache; + + /* Block number of B-tree root node + */ + uint64_t root_node_block_number; +}; + +int libfsapfs_snapshot_metadata_tree_initialize( + libfsapfs_snapshot_metadata_tree_t **snapshot_metadata_tree, + libfsapfs_io_handle_t *io_handle, + libfdata_vector_t *data_block_vector, + uint64_t root_node_block_number, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_tree_free( + libfsapfs_snapshot_metadata_tree_t **snapshot_metadata_tree, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_tree_get_root_node( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t root_node_block_number, + libfsapfs_btree_node_t **root_node, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_tree_get_sub_node( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t sub_node_block_number, + libfsapfs_btree_node_t **sub_node, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_tree_get_entry_from_node_by_identifier( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libfsapfs_btree_node_t *node, + uint64_t object_identifier, + libfsapfs_btree_entry_t **btree_entry, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_tree_get_entry_by_identifier( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t object_identifier, + libfsapfs_btree_node_t **btree_node, + libfsapfs_btree_entry_t **btree_entry, + libcerror_error_t **error ); + +int libfsapfs_snapshot_metadata_tree_get_metadata_by_object_identifier( + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree, + libbfio_handle_t *file_io_handle, + uint64_t object_identifier, + libfsapfs_snapshot_metadata_t **metadata, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBFSAPFS_SNAPSHOT_METADATA_TREE_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_space_manager.c libfsapfs-20190210/libfsapfs/libfsapfs_space_manager.c --- libfsapfs-20181215/libfsapfs/libfsapfs_space_manager.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_space_manager.c 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,830 @@ +/* + * The space manager functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include +#include + +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" +#include "libfsapfs_libcnotify.h" +#include "libfsapfs_space_manager.h" + +#include "fsapfs_space_manager.h" + +/* Creates a space manager + * Make sure the value space_manager is referencing, is set to NULL + * Returns 1 if successful or -1 on error + */ +int libfsapfs_space_manager_initialize( + libfsapfs_space_manager_t **space_manager, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_space_manager_initialize"; + + if( space_manager == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid space manager.", + function ); + + return( -1 ); + } + if( *space_manager != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid space manager value already set.", + function ); + + return( -1 ); + } + *space_manager = memory_allocate_structure( + libfsapfs_space_manager_t ); + + if( *space_manager == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_INSUFFICIENT, + "%s: unable to create space manager.", + function ); + + goto on_error; + } + if( memory_set( + *space_manager, + 0, + sizeof( libfsapfs_space_manager_t ) ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_SET_FAILED, + "%s: unable to clear space manager.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( *space_manager != NULL ) + { + memory_free( + *space_manager ); + + *space_manager = NULL; + } + return( -1 ); +} + +/* Frees a space manager + * Returns 1 if successful or -1 on error + */ +int libfsapfs_space_manager_free( + libfsapfs_space_manager_t **space_manager, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_space_manager_free"; + + if( space_manager == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid space manager.", + function ); + + return( -1 ); + } + if( *space_manager != NULL ) + { + memory_free( + *space_manager ); + + *space_manager = NULL; + } + return( 1 ); +} + +/* Reads the space manager + * Returns 1 if successful or -1 on error + */ +int libfsapfs_space_manager_read_file_io_handle( + libfsapfs_space_manager_t *space_manager, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ) +{ + uint8_t space_manager_data[ 4096 ]; + + static char *function = "libfsapfs_space_manager_read_file_io_handle"; + ssize_t read_count = 0; + + if( space_manager == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid space manager.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: reading space manager at offset: %" PRIi64 " (0x%08" PRIx64 ")\n", + function, + file_offset, + file_offset ); + } +#endif + if( libbfio_handle_seek_offset( + file_io_handle, + file_offset, + SEEK_SET, + error ) == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_SEEK_FAILED, + "%s: unable to seek space manager offset: %" PRIi64 " (0x%08" PRIx64 ").", + function, + file_offset, + file_offset ); + + return( -1 ); + } + read_count = libbfio_handle_read_buffer( + file_io_handle, + space_manager_data, + 4096, + error ); + + if( read_count != (ssize_t) 4096 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read space manager data.", + function ); + + return( -1 ); + } + if( libfsapfs_space_manager_read_data( + space_manager, + space_manager_data, + 4096, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read space manager data.", + function ); + + return( -1 ); + } + return( 1 ); +} + +/* Reads the space manager + * Returns 1 if successful or -1 on error + */ +int libfsapfs_space_manager_read_data( + libfsapfs_space_manager_t *space_manager, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ) +{ + static char *function = "libfsapfs_space_manager_read_data"; + uint32_t object_subtype = 0; + uint32_t object_type = 0; + +#if defined( HAVE_DEBUG_OUTPUT ) + uint64_t value_64bit = 0; + uint32_t value_32bit = 0; + uint16_t value_16bit = 0; +#endif + + if( space_manager == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid space manager.", + function ); + + return( -1 ); + } + if( data == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_MISSING, + "%s: invalid data.", + function ); + + return( -1 ); + } + if( ( data_size < sizeof( fsapfs_space_manager_t ) ) + || ( data_size > (size_t) SSIZE_MAX ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid data size value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + libcnotify_printf( + "%s: space manager data:\n", + function ); + libcnotify_print_data( + data, + data_size, + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + } +#endif + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->object_type, + object_type ); + + if( object_type != 0x80000005UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object type: 0x%08" PRIx32 ".", + function, + object_type ); + + return( -1 ); + } + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->object_subtype, + object_subtype ); + + if( object_subtype != 0x00000000UL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: invalid object subtype: 0x%08" PRIx32 ".", + function, + object_subtype ); + + return( -1 ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( libcnotify_verbose != 0 ) + { + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->object_checksum, + value_64bit ); + libcnotify_printf( + "%s: object checksum\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->object_identifier, + value_64bit ); + libcnotify_printf( + "%s: object identifier\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->object_transaction_identifier, + value_64bit ); + libcnotify_printf( + "%s: object transaction identifier\t: %" PRIu64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "%s: object type\t\t\t\t: 0x%08" PRIx32 "\n", + function, + object_type ); + + libcnotify_printf( + "%s: object subtype\t\t\t: 0x%08" PRIx32 "\n", + function, + object_subtype ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->block_size, + value_32bit ); + libcnotify_printf( + "%s: block size\t\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->blocks_per_chunk, + value_32bit ); + libcnotify_printf( + "%s: blocks per chunk\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->chunks_per_cib, + value_32bit ); + libcnotify_printf( + "%s: chunks per CIB\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->cibs_per_cab, + value_32bit ); + libcnotify_printf( + "%s: CIBs per CAB\t\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + libcnotify_printf( + "\n" ); + + libcnotify_printf( + "%s: main device\n", + function ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->main_device_number_of_blocks, + value_64bit ); + libcnotify_printf( + "%s: number of blocks\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->main_device_number_of_chunks, + value_64bit ); + libcnotify_printf( + "%s: number of chunks\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->main_device_number_of_cibs, + value_32bit ); + libcnotify_printf( + "%s: number of CIBs\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->main_device_number_of_cabs, + value_32bit ); + libcnotify_printf( + "%s: number of CABs\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->main_device_number_of_unused_blocks, + value_64bit ); + libcnotify_printf( + "%s: number of unused blocks\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->main_device_offset, + value_32bit ); + libcnotify_printf( + "%s: offset\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown1, + value_32bit ); + libcnotify_printf( + "%s: unknown1\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown2, + value_64bit ); + libcnotify_printf( + "%s: unknown2\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "\n" ); + + libcnotify_printf( + "%s: tier2 device\n", + function ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->tier2_device_number_of_blocks, + value_64bit ); + libcnotify_printf( + "%s: number of blocks\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->tier2_device_number_of_chunks, + value_64bit ); + libcnotify_printf( + "%s: number of chunks\t\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->tier2_device_number_of_cibs, + value_32bit ); + libcnotify_printf( + "%s: number of CIBs\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->tier2_device_number_of_cabs, + value_32bit ); + libcnotify_printf( + "%s: number of CABs\t\t\t: %" PRIu32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->tier2_device_number_of_unused_blocks, + value_64bit ); + libcnotify_printf( + "%s: number of unused blocks\t\t: %" PRIu64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->tier2_device_offset, + value_32bit ); + libcnotify_printf( + "%s: offset\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown8, + value_32bit ); + libcnotify_printf( + "%s: unknown8\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown9, + value_64bit ); + libcnotify_printf( + "%s: unknown9\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "\n" ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->flags, + value_32bit ); + libcnotify_printf( + "%s: flags\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown11, + value_32bit ); + libcnotify_printf( + "%s: unknown11\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown12, + value_64bit ); + libcnotify_printf( + "%s: unknown12\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown13, + value_32bit ); + libcnotify_printf( + "%s: unknown13\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown14, + value_32bit ); + libcnotify_printf( + "%s: unknown14\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown15, + value_64bit ); + libcnotify_printf( + "%s: unknown15\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown16, + value_64bit ); + libcnotify_printf( + "%s: unknown16\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown17, + value_64bit ); + libcnotify_printf( + "%s: unknown17\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown18, + value_64bit ); + libcnotify_printf( + "%s: unknown18\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "\n" ); + + libcnotify_printf( + "%s: unknown free queue\n", + function ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown19, + value_64bit ); + libcnotify_printf( + "%s: unknown19\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown20, + value_64bit ); + libcnotify_printf( + "%s: unknown20\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown21, + value_64bit ); + libcnotify_printf( + "%s: unknown21\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown22, + value_64bit ); + libcnotify_printf( + "%s: unknown22\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown23, + value_64bit ); + libcnotify_printf( + "%s: unknown23\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "\n" ); + + libcnotify_printf( + "%s: main free queue\n", + function ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown24, + value_64bit ); + libcnotify_printf( + "%s: unknown24\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown25, + value_64bit ); + libcnotify_printf( + "%s: unknown25\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown26, + value_64bit ); + libcnotify_printf( + "%s: unknown26\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown27, + value_64bit ); + libcnotify_printf( + "%s: unknown27\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown28, + value_64bit ); + libcnotify_printf( + "%s: unknown28\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "\n" ); + + libcnotify_printf( + "%s: tier2 free queue\n", + function ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown29, + value_64bit ); + libcnotify_printf( + "%s: unknown29\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown30, + value_64bit ); + libcnotify_printf( + "%s: unknown30\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown31, + value_64bit ); + libcnotify_printf( + "%s: unknown31\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown32, + value_64bit ); + libcnotify_printf( + "%s: unknown32\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown33, + value_64bit ); + libcnotify_printf( + "%s: unknown33\t\t\t\t: 0x%08" PRIx64 "\n", + function, + value_64bit ); + + libcnotify_printf( + "\n" ); + + byte_stream_copy_to_uint16_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown34, + value_16bit ); + libcnotify_printf( + "%s: unknown34\t\t\t\t: 0x%04" PRIx16 "\n", + function, + value_16bit ); + + byte_stream_copy_to_uint16_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown35, + value_16bit ); + libcnotify_printf( + "%s: unknown35\t\t\t\t: 0x%04" PRIx16 "\n", + function, + value_16bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown36, + value_32bit ); + libcnotify_printf( + "%s: unknown36\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown37, + value_32bit ); + libcnotify_printf( + "%s: unknown37\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown38, + value_32bit ); + libcnotify_printf( + "%s: unknown38\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown39, + value_32bit ); + libcnotify_printf( + "%s: unknown39\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + byte_stream_copy_to_uint32_little_endian( + ( (fsapfs_space_manager_t *) data )->unknown40, + value_32bit ); + libcnotify_printf( + "%s: unknown40\t\t\t\t: 0x%08" PRIx32 "\n", + function, + value_32bit ); + + libcnotify_printf( + "%s: unknown41:\n", + function ); + libcnotify_print_data( + ( (fsapfs_space_manager_t *) data )->unknown41, + 8 * 72, + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + + libcnotify_printf( + "%s: unknown42:\n", + function ); + libcnotify_print_data( + ( (fsapfs_space_manager_t *) data )->unknown42, + 8 * 72, + LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA ); + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + +/* TODO read value at main device offset */ +/* TODO read value at tier2 device offset */ + + return( 1 ); +} + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_space_manager.h libfsapfs-20190210/libfsapfs/libfsapfs_space_manager.h --- libfsapfs-20181215/libfsapfs/libfsapfs_space_manager.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_space_manager.h 2019-02-06 20:10:14.000000000 +0000 @@ -0,0 +1,69 @@ +/* + * The space manager functions + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _LIBFSAPFS_SPACE_MANAGER_H ) +#define _LIBFSAPFS_SPACE_MANAGER_H + +#include +#include + +#include "libfsapfs_libbfio.h" +#include "libfsapfs_libcerror.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct libfsapfs_space_manager libfsapfs_space_manager_t; + +struct libfsapfs_space_manager +{ + /* Dummy + */ + int dummy; +}; + +int libfsapfs_space_manager_initialize( + libfsapfs_space_manager_t **space_manager, + libcerror_error_t **error ); + +int libfsapfs_space_manager_free( + libfsapfs_space_manager_t **space_manager, + libcerror_error_t **error ); + +int libfsapfs_space_manager_read_file_io_handle( + libfsapfs_space_manager_t *space_manager, + libbfio_handle_t *file_io_handle, + off64_t file_offset, + libcerror_error_t **error ); + +int libfsapfs_space_manager_read_data( + libfsapfs_space_manager_t *space_manager, + const uint8_t *data, + size_t data_size, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _LIBFSAPFS_SPACE_MANAGER_H ) */ + diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_support.c libfsapfs-20190210/libfsapfs/libfsapfs_support.c --- libfsapfs-20181215/libfsapfs/libfsapfs_support.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_support.c 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_support.h libfsapfs-20190210/libfsapfs/libfsapfs_support.h --- libfsapfs-20181215/libfsapfs/libfsapfs_support.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_support.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_types.h libfsapfs-20190210/libfsapfs/libfsapfs_types.h --- libfsapfs-20181215/libfsapfs/libfsapfs_types.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_types.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal type definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_unused.h libfsapfs-20190210/libfsapfs/libfsapfs_unused.h --- libfsapfs-20181215/libfsapfs/libfsapfs_unused.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_unused.h 2019-02-06 20:10:14.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _LIBFSAPFS_INTERNAL_UNUSED_H ) -#define _LIBFSAPFS_INTERNAL_UNUSED_H +#if !defined( _LIBFSAPFS_UNUSED_H ) +#define _LIBFSAPFS_UNUSED_H #include @@ -40,5 +40,5 @@ /* parameter */ #endif -#endif /* !defined( _LIBFSAPFS_INTERNAL_UNUSED_H ) */ +#endif /* !defined( _LIBFSAPFS_UNUSED_H ) */ diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_volume.c libfsapfs-20190210/libfsapfs/libfsapfs_volume.c --- libfsapfs-20181215/libfsapfs/libfsapfs_volume.c 2018-12-03 19:26:13.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_volume.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Volume functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -30,6 +30,7 @@ #include "libfsapfs_debug.h" #include "libfsapfs_definitions.h" #include "libfsapfs_encryption_context.h" +#include "libfsapfs_extent_reference_tree.h" #include "libfsapfs_file_entry.h" #include "libfsapfs_file_system_btree.h" #include "libfsapfs_file_system_data_handle.h" @@ -44,6 +45,8 @@ #include "libfsapfs_object_map.h" #include "libfsapfs_object_map_btree.h" #include "libfsapfs_object_map_descriptor.h" +#include "libfsapfs_snapshot_metadata.h" +#include "libfsapfs_snapshot_metadata_tree.h" #include "libfsapfs_volume.h" #include "libfsapfs_volume_key_bag.h" #include "libfsapfs_volume_superblock.h" @@ -149,7 +152,7 @@ error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, - "%s: unable to intialize read/write lock.", + "%s: unable to initialize read/write lock.", function ); goto on_error; @@ -979,6 +982,22 @@ result = -1; } } + if( internal_volume->snapshot_metadata_tree != NULL ) + { + if( libfsapfs_snapshot_metadata_tree_free( + &( internal_volume->snapshot_metadata_tree ), + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free snapshot metadata tree.", + function ); + + result = -1; + } + } if( internal_volume->key_bag != NULL ) { if( libfsapfs_volume_key_bag_free( @@ -1076,6 +1095,10 @@ int element_index = 0; int result = 0; +#if defined( HAVE_DEBUG_OUTPUT ) + libfsapfs_extent_reference_tree_t *extent_reference_tree = NULL; +#endif + if( internal_volume == NULL ) { libcerror_error_set( @@ -1131,6 +1154,17 @@ return( -1 ); } + if( internal_volume->snapshot_metadata_tree != NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET, + "%s: invalid volume - snapshot metadata tree value already set.", + function ); + + return( -1 ); + } if( internal_volume->key_bag != NULL ) { libcerror_error_set( @@ -1307,7 +1341,7 @@ goto on_error; } - if( object_map->object_map_btree_block_number == 0 ) + if( object_map->btree_block_number == 0 ) { libcerror_error_set( error, @@ -1329,7 +1363,7 @@ &( internal_volume->object_map_btree ), internal_volume->io_handle, internal_volume->container_data_block_vector, - object_map->object_map_btree_block_number, + object_map->btree_block_number, error ) != 1 ) { libcerror_error_set( @@ -1443,6 +1477,96 @@ internal_volume->is_locked = 1; } } +#if defined( HAVE_DEBUG_OUTPUT ) + if( internal_volume->superblock->extent_reference_tree_block_number != 0 ) + { + if( libfsapfs_extent_reference_tree_initialize( + &extent_reference_tree, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create extent reference tree.", + function ); + + goto on_error; + } + file_offset = internal_volume->superblock->extent_reference_tree_block_number * internal_volume->io_handle->block_size; + + if( libfsapfs_extent_reference_tree_read_file_io_handle( + extent_reference_tree, + file_io_handle, + file_offset, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_READ_FAILED, + "%s: unable to read extent reference tree at offset: %" PRIi64 " (0x%08" PRIx64 ").", + function, + file_offset, + file_offset ); + + goto on_error; + } + if( libfsapfs_extent_reference_tree_free( + &extent_reference_tree, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED, + "%s: unable to free extent reference tree.", + function ); + + goto on_error; + } + } + if( internal_volume->superblock->snapshot_metadata_tree_block_number != 0 ) + { + if( libfsapfs_snapshot_metadata_tree_initialize( + &( internal_volume->snapshot_metadata_tree ), + internal_volume->io_handle, + internal_volume->container_data_block_vector, + internal_volume->superblock->snapshot_metadata_tree_block_number, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create snapshot metadata tree.", + function ); + + goto on_error; + } +/* TODO free snapshot metadata */ + libfsapfs_snapshot_metadata_t *snapshot_metadata = NULL; + + if( libfsapfs_snapshot_metadata_tree_get_metadata_by_object_identifier( + internal_volume->snapshot_metadata_tree, + internal_volume->file_io_handle, + 10000, + &snapshot_metadata, + error ) == -1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_GET_FAILED, + "%s: unable to retrieve snapshot metadata for object identifier: %" PRIu64 ".", + function, + 10000 ); + + goto on_error; + } + } +#endif /* defined( HAVE_DEBUG_OUTPUT ) */ + if( internal_volume->superblock->file_system_root_object_identifier == 0 ) { libcerror_error_set( @@ -1538,6 +1662,20 @@ &( internal_volume->key_bag ), NULL ); } + if( internal_volume->snapshot_metadata_tree != NULL ) + { + libfsapfs_snapshot_metadata_tree_free( + &( internal_volume->snapshot_metadata_tree ), + NULL ); + } +#if defined( HAVE_DEBUG_OUTPUT ) + if( extent_reference_tree != NULL ) + { + libfsapfs_extent_reference_tree_free( + &extent_reference_tree, + NULL ); + } +#endif if( internal_volume->object_map_btree != NULL ) { libfsapfs_object_map_btree_free( diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_volume.h libfsapfs-20190210/libfsapfs/libfsapfs_volume.h --- libfsapfs-20181215/libfsapfs/libfsapfs_volume.h 2018-12-03 17:52:38.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_volume.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Volume functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -37,6 +37,7 @@ #include "libfsapfs_libcthreads.h" #include "libfsapfs_libfdata.h" #include "libfsapfs_object_map_btree.h" +#include "libfsapfs_snapshot_metadata_tree.h" #include "libfsapfs_volume_key_bag.h" #include "libfsapfs_volume_superblock.h" #include "libfsapfs_types.h" @@ -65,10 +66,14 @@ */ libfdata_vector_t *container_data_block_vector; - /* The volume object map B-tree + /* The object map B-tree */ libfsapfs_object_map_btree_t *object_map_btree; + /* The snapshot metadata tree + */ + libfsapfs_snapshot_metadata_tree_t *snapshot_metadata_tree; + /* The volume key bag */ libfsapfs_volume_key_bag_t *key_bag; diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_volume_key_bag.c libfsapfs-20190210/libfsapfs/libfsapfs_volume_key_bag.c --- libfsapfs-20181215/libfsapfs/libfsapfs_volume_key_bag.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_volume_key_bag.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The volume key bag functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_volume_key_bag.h libfsapfs-20190210/libfsapfs/libfsapfs_volume_key_bag.h --- libfsapfs-20181215/libfsapfs/libfsapfs_volume_key_bag.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_volume_key_bag.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The volume key bag functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_volume_superblock.c libfsapfs-20190210/libfsapfs/libfsapfs_volume_superblock.c --- libfsapfs-20181215/libfsapfs/libfsapfs_volume_superblock.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_volume_superblock.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The volume superblock functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -356,6 +356,14 @@ volume_superblock->file_system_root_object_identifier ); byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_volume_superblock_t *) data )->extent_reference_tree_block_number, + volume_superblock->extent_reference_tree_block_number ); + + byte_stream_copy_to_uint64_little_endian( + ( (fsapfs_volume_superblock_t *) data )->snapshot_metadata_tree_block_number, + volume_superblock->snapshot_metadata_tree_block_number ); + + byte_stream_copy_to_uint64_little_endian( ( (fsapfs_volume_superblock_t *) data )->next_file_system_object_identifier, volume_superblock->next_file_system_object_identifier ); @@ -560,10 +568,10 @@ value_32bit ); byte_stream_copy_to_uint32_little_endian( - ( (fsapfs_volume_superblock_t *) data )->unknown14, + ( (fsapfs_volume_superblock_t *) data )->extent_reference_tree_object_type, value_32bit ); libcnotify_printf( - "%s: unknown14 object type\t\t\t: 0x%08" PRIx32 "\n", + "%s: extent-reference tree object type\t: 0x%08" PRIx32 "\n", function, value_32bit ); @@ -585,21 +593,15 @@ function, volume_superblock->file_system_root_object_identifier ); - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_volume_superblock_t *) data )->unknown18, - value_64bit ); libcnotify_printf( - "%s: unknown18\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: extent-reference tree block number\t: %" PRIu64 "\n", function, - value_64bit ); + volume_superblock->extent_reference_tree_block_number ); - byte_stream_copy_to_uint64_little_endian( - ( (fsapfs_volume_superblock_t *) data )->unknown19, - value_64bit ); libcnotify_printf( - "%s: unknown19\t\t\t\t: 0x%08" PRIx64 "\n", + "%s: snapshot metadata tree block number\t: %" PRIu64 "\n", function, - value_64bit ); + volume_superblock->snapshot_metadata_tree_block_number ); byte_stream_copy_to_uint64_little_endian( ( (fsapfs_volume_superblock_t *) data )->unknown20, diff -Nru libfsapfs-20181215/libfsapfs/libfsapfs_volume_superblock.h libfsapfs-20190210/libfsapfs/libfsapfs_volume_superblock.h --- libfsapfs-20181215/libfsapfs/libfsapfs_volume_superblock.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/libfsapfs_volume_superblock.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The volume superblock functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -48,6 +48,14 @@ */ uint64_t file_system_root_object_identifier; + /* The extent-reference tree block number + */ + uint64_t extent_reference_tree_block_number; + + /* The snapshot metadata tree block number + */ + uint64_t snapshot_metadata_tree_block_number; + /* The next file system object identifier */ uint64_t next_file_system_object_identifier; diff -Nru libfsapfs-20181215/libfsapfs/Makefile.am libfsapfs-20190210/libfsapfs/Makefile.am --- libfsapfs-20181215/libfsapfs/Makefile.am 2018-10-31 16:35:50.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/Makefile.am 2019-01-27 18:49:24.000000000 +0000 @@ -27,13 +27,17 @@ libfsapfs_la_SOURCES = \ fsapfs_btree.h \ fsapfs_checkpoint_map.h \ + fsapfs_chunk_information_block.h \ fsapfs_container_reaper.h \ - fsapfs_container_space_manager.h \ fsapfs_container_superblock.h \ + fsapfs_extent_reference_tree.h \ fsapfs_file_system.h \ + fsapfs_fusion_middle_tree.h \ fsapfs_key_bag.h \ fsapfs_object.h \ fsapfs_object_map.h \ + fsapfs_snapshot_metadata.h \ + fsapfs_space_manager.h \ fsapfs_volume_superblock.h \ libfsapfs.c \ libfsapfs_btree_entry.c libfsapfs_btree_entry.h \ @@ -44,13 +48,13 @@ libfsapfs_checkpoint_map.c libfsapfs_checkpoint_map.h \ libfsapfs_checkpoint_map_entry.c libfsapfs_checkpoint_map_entry.h \ libfsapfs_checksum.c libfsapfs_checksum.h \ + libfsapfs_chunk_information_block.c libfsapfs_chunk_information_block.h \ libfsapfs_compressed_data_handle.c libfsapfs_compressed_data_handle.h \ libfsapfs_compression.c libfsapfs_compression.h \ libfsapfs_container.c libfsapfs_container.h \ libfsapfs_container_data_handle.c libfsapfs_container_data_handle.h \ libfsapfs_container_key_bag.c libfsapfs_container_key_bag.h \ libfsapfs_container_reaper.c libfsapfs_container_reaper.h \ - libfsapfs_container_space_manager.c libfsapfs_container_space_manager.h \ libfsapfs_container_superblock.c libfsapfs_container_superblock.h \ libfsapfs_data_block.c libfsapfs_data_block.h \ libfsapfs_data_block_data_handle.c libfsapfs_data_block_data_handle.h \ @@ -63,10 +67,12 @@ libfsapfs_encryption_context.c libfsapfs_encryption_context.h \ libfsapfs_extended_attribute.c libfsapfs_extended_attribute.h \ libfsapfs_extern.h \ + libfsapfs_extent_reference_tree.c libfsapfs_extent_reference_tree.h \ libfsapfs_file_entry.c libfsapfs_file_entry.h \ libfsapfs_file_extent.c libfsapfs_file_extent.h \ libfsapfs_file_system_btree.c libfsapfs_file_system_btree.h \ libfsapfs_file_system_data_handle.c libfsapfs_file_system_data_handle.h \ + libfsapfs_fusion_middle_tree.c libfsapfs_fusion_middle_tree.h \ libfsapfs_inode.c libfsapfs_inode.h \ libfsapfs_io_handle.c libfsapfs_io_handle.h \ libfsapfs_key_bag_entry.c libfsapfs_key_bag_entry.h \ @@ -95,6 +101,9 @@ libfsapfs_object_map_descriptor.c libfsapfs_object_map_descriptor.h \ libfsapfs_password.c libfsapfs_password.h \ libfsapfs_profiler.c libfsapfs_profiler.h \ + libfsapfs_snapshot_metadata.c libfsapfs_snapshot_metadata.h \ + libfsapfs_snapshot_metadata_tree.c libfsapfs_snapshot_metadata_tree.h \ + libfsapfs_space_manager.c libfsapfs_space_manager.h \ libfsapfs_support.c libfsapfs_support.h \ libfsapfs_types.h \ libfsapfs_unused.h \ diff -Nru libfsapfs-20181215/libfsapfs/Makefile.in libfsapfs-20190210/libfsapfs/Makefile.in --- libfsapfs-20181215/libfsapfs/Makefile.in 2018-12-15 06:44:02.000000000 +0000 +++ libfsapfs-20190210/libfsapfs/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -152,26 +152,29 @@ libfsapfs_btree_footer.lo libfsapfs_btree_node.lo \ libfsapfs_btree_node_header.lo libfsapfs_buffer_data_handle.lo \ libfsapfs_checkpoint_map.lo libfsapfs_checkpoint_map_entry.lo \ - libfsapfs_checksum.lo libfsapfs_compressed_data_handle.lo \ - libfsapfs_compression.lo libfsapfs_container.lo \ - libfsapfs_container_data_handle.lo \ + libfsapfs_checksum.lo libfsapfs_chunk_information_block.lo \ + libfsapfs_compressed_data_handle.lo libfsapfs_compression.lo \ + libfsapfs_container.lo libfsapfs_container_data_handle.lo \ libfsapfs_container_key_bag.lo libfsapfs_container_reaper.lo \ - libfsapfs_container_space_manager.lo \ libfsapfs_container_superblock.lo libfsapfs_data_block.lo \ libfsapfs_data_block_data_handle.lo libfsapfs_data_stream.lo \ libfsapfs_debug.lo libfsapfs_deflate.lo \ libfsapfs_directory_record.lo libfsapfs_error.lo \ libfsapfs_encryption_context.lo \ - libfsapfs_extended_attribute.lo libfsapfs_file_entry.lo \ + libfsapfs_extended_attribute.lo \ + libfsapfs_extent_reference_tree.lo libfsapfs_file_entry.lo \ libfsapfs_file_extent.lo libfsapfs_file_system_btree.lo \ - libfsapfs_file_system_data_handle.lo libfsapfs_inode.lo \ + libfsapfs_file_system_data_handle.lo \ + libfsapfs_fusion_middle_tree.lo libfsapfs_inode.lo \ libfsapfs_io_handle.lo libfsapfs_key_bag_entry.lo \ libfsapfs_key_bag_header.lo libfsapfs_key_encrypted_key.lo \ libfsapfs_lzvn.lo libfsapfs_name.lo libfsapfs_name_hash.lo \ libfsapfs_notify.lo libfsapfs_object.lo \ libfsapfs_object_map.lo libfsapfs_object_map_btree.lo \ libfsapfs_object_map_descriptor.lo libfsapfs_password.lo \ - libfsapfs_profiler.lo libfsapfs_support.lo libfsapfs_volume.lo \ + libfsapfs_profiler.lo libfsapfs_snapshot_metadata.lo \ + libfsapfs_snapshot_metadata_tree.lo libfsapfs_space_manager.lo \ + libfsapfs_support.lo libfsapfs_volume.lo \ libfsapfs_volume_key_bag.lo libfsapfs_volume_superblock.lo libfsapfs_la_OBJECTS = $(am_libfsapfs_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -205,13 +208,13 @@ ./$(DEPDIR)/libfsapfs_checkpoint_map.Plo \ ./$(DEPDIR)/libfsapfs_checkpoint_map_entry.Plo \ ./$(DEPDIR)/libfsapfs_checksum.Plo \ + ./$(DEPDIR)/libfsapfs_chunk_information_block.Plo \ ./$(DEPDIR)/libfsapfs_compressed_data_handle.Plo \ ./$(DEPDIR)/libfsapfs_compression.Plo \ ./$(DEPDIR)/libfsapfs_container.Plo \ ./$(DEPDIR)/libfsapfs_container_data_handle.Plo \ ./$(DEPDIR)/libfsapfs_container_key_bag.Plo \ ./$(DEPDIR)/libfsapfs_container_reaper.Plo \ - ./$(DEPDIR)/libfsapfs_container_space_manager.Plo \ ./$(DEPDIR)/libfsapfs_container_superblock.Plo \ ./$(DEPDIR)/libfsapfs_data_block.Plo \ ./$(DEPDIR)/libfsapfs_data_block_data_handle.Plo \ @@ -222,10 +225,12 @@ ./$(DEPDIR)/libfsapfs_encryption_context.Plo \ ./$(DEPDIR)/libfsapfs_error.Plo \ ./$(DEPDIR)/libfsapfs_extended_attribute.Plo \ + ./$(DEPDIR)/libfsapfs_extent_reference_tree.Plo \ ./$(DEPDIR)/libfsapfs_file_entry.Plo \ ./$(DEPDIR)/libfsapfs_file_extent.Plo \ ./$(DEPDIR)/libfsapfs_file_system_btree.Plo \ ./$(DEPDIR)/libfsapfs_file_system_data_handle.Plo \ + ./$(DEPDIR)/libfsapfs_fusion_middle_tree.Plo \ ./$(DEPDIR)/libfsapfs_inode.Plo \ ./$(DEPDIR)/libfsapfs_io_handle.Plo \ ./$(DEPDIR)/libfsapfs_key_bag_entry.Plo \ @@ -240,6 +245,9 @@ ./$(DEPDIR)/libfsapfs_object_map_descriptor.Plo \ ./$(DEPDIR)/libfsapfs_password.Plo \ ./$(DEPDIR)/libfsapfs_profiler.Plo \ + ./$(DEPDIR)/libfsapfs_snapshot_metadata.Plo \ + ./$(DEPDIR)/libfsapfs_snapshot_metadata_tree.Plo \ + ./$(DEPDIR)/libfsapfs_space_manager.Plo \ ./$(DEPDIR)/libfsapfs_support.Plo \ ./$(DEPDIR)/libfsapfs_volume.Plo \ ./$(DEPDIR)/libfsapfs_volume_key_bag.Plo \ @@ -688,13 +696,17 @@ libfsapfs_la_SOURCES = \ fsapfs_btree.h \ fsapfs_checkpoint_map.h \ + fsapfs_chunk_information_block.h \ fsapfs_container_reaper.h \ - fsapfs_container_space_manager.h \ fsapfs_container_superblock.h \ + fsapfs_extent_reference_tree.h \ fsapfs_file_system.h \ + fsapfs_fusion_middle_tree.h \ fsapfs_key_bag.h \ fsapfs_object.h \ fsapfs_object_map.h \ + fsapfs_snapshot_metadata.h \ + fsapfs_space_manager.h \ fsapfs_volume_superblock.h \ libfsapfs.c \ libfsapfs_btree_entry.c libfsapfs_btree_entry.h \ @@ -705,13 +717,13 @@ libfsapfs_checkpoint_map.c libfsapfs_checkpoint_map.h \ libfsapfs_checkpoint_map_entry.c libfsapfs_checkpoint_map_entry.h \ libfsapfs_checksum.c libfsapfs_checksum.h \ + libfsapfs_chunk_information_block.c libfsapfs_chunk_information_block.h \ libfsapfs_compressed_data_handle.c libfsapfs_compressed_data_handle.h \ libfsapfs_compression.c libfsapfs_compression.h \ libfsapfs_container.c libfsapfs_container.h \ libfsapfs_container_data_handle.c libfsapfs_container_data_handle.h \ libfsapfs_container_key_bag.c libfsapfs_container_key_bag.h \ libfsapfs_container_reaper.c libfsapfs_container_reaper.h \ - libfsapfs_container_space_manager.c libfsapfs_container_space_manager.h \ libfsapfs_container_superblock.c libfsapfs_container_superblock.h \ libfsapfs_data_block.c libfsapfs_data_block.h \ libfsapfs_data_block_data_handle.c libfsapfs_data_block_data_handle.h \ @@ -724,10 +736,12 @@ libfsapfs_encryption_context.c libfsapfs_encryption_context.h \ libfsapfs_extended_attribute.c libfsapfs_extended_attribute.h \ libfsapfs_extern.h \ + libfsapfs_extent_reference_tree.c libfsapfs_extent_reference_tree.h \ libfsapfs_file_entry.c libfsapfs_file_entry.h \ libfsapfs_file_extent.c libfsapfs_file_extent.h \ libfsapfs_file_system_btree.c libfsapfs_file_system_btree.h \ libfsapfs_file_system_data_handle.c libfsapfs_file_system_data_handle.h \ + libfsapfs_fusion_middle_tree.c libfsapfs_fusion_middle_tree.h \ libfsapfs_inode.c libfsapfs_inode.h \ libfsapfs_io_handle.c libfsapfs_io_handle.h \ libfsapfs_key_bag_entry.c libfsapfs_key_bag_entry.h \ @@ -756,6 +770,9 @@ libfsapfs_object_map_descriptor.c libfsapfs_object_map_descriptor.h \ libfsapfs_password.c libfsapfs_password.h \ libfsapfs_profiler.c libfsapfs_profiler.h \ + libfsapfs_snapshot_metadata.c libfsapfs_snapshot_metadata.h \ + libfsapfs_snapshot_metadata_tree.c libfsapfs_snapshot_metadata_tree.h \ + libfsapfs_space_manager.c libfsapfs_space_manager.h \ libfsapfs_support.c libfsapfs_support.h \ libfsapfs_types.h \ libfsapfs_unused.h \ @@ -885,13 +902,13 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_checkpoint_map.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_checkpoint_map_entry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_checksum.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_chunk_information_block.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_compressed_data_handle.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_compression.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_container.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_container_data_handle.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_container_key_bag.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_container_reaper.Plo@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_container_space_manager.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_container_superblock.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_data_block.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_data_block_data_handle.Plo@am__quote@ # am--include-marker @@ -902,10 +919,12 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_encryption_context.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_error.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_extended_attribute.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_extent_reference_tree.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_file_entry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_file_extent.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_file_system_btree.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_file_system_data_handle.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_fusion_middle_tree.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_inode.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_io_handle.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_key_bag_entry.Plo@am__quote@ # am--include-marker @@ -921,6 +940,9 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_object_map_descriptor.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_password.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_profiler.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_snapshot_metadata.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_snapshot_metadata_tree.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_space_manager.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_support.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_volume.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libfsapfs_volume_key_bag.Plo@am__quote@ # am--include-marker @@ -1140,13 +1162,13 @@ -rm -f ./$(DEPDIR)/libfsapfs_checkpoint_map.Plo -rm -f ./$(DEPDIR)/libfsapfs_checkpoint_map_entry.Plo -rm -f ./$(DEPDIR)/libfsapfs_checksum.Plo + -rm -f ./$(DEPDIR)/libfsapfs_chunk_information_block.Plo -rm -f ./$(DEPDIR)/libfsapfs_compressed_data_handle.Plo -rm -f ./$(DEPDIR)/libfsapfs_compression.Plo -rm -f ./$(DEPDIR)/libfsapfs_container.Plo -rm -f ./$(DEPDIR)/libfsapfs_container_data_handle.Plo -rm -f ./$(DEPDIR)/libfsapfs_container_key_bag.Plo -rm -f ./$(DEPDIR)/libfsapfs_container_reaper.Plo - -rm -f ./$(DEPDIR)/libfsapfs_container_space_manager.Plo -rm -f ./$(DEPDIR)/libfsapfs_container_superblock.Plo -rm -f ./$(DEPDIR)/libfsapfs_data_block.Plo -rm -f ./$(DEPDIR)/libfsapfs_data_block_data_handle.Plo @@ -1157,10 +1179,12 @@ -rm -f ./$(DEPDIR)/libfsapfs_encryption_context.Plo -rm -f ./$(DEPDIR)/libfsapfs_error.Plo -rm -f ./$(DEPDIR)/libfsapfs_extended_attribute.Plo + -rm -f ./$(DEPDIR)/libfsapfs_extent_reference_tree.Plo -rm -f ./$(DEPDIR)/libfsapfs_file_entry.Plo -rm -f ./$(DEPDIR)/libfsapfs_file_extent.Plo -rm -f ./$(DEPDIR)/libfsapfs_file_system_btree.Plo -rm -f ./$(DEPDIR)/libfsapfs_file_system_data_handle.Plo + -rm -f ./$(DEPDIR)/libfsapfs_fusion_middle_tree.Plo -rm -f ./$(DEPDIR)/libfsapfs_inode.Plo -rm -f ./$(DEPDIR)/libfsapfs_io_handle.Plo -rm -f ./$(DEPDIR)/libfsapfs_key_bag_entry.Plo @@ -1176,6 +1200,9 @@ -rm -f ./$(DEPDIR)/libfsapfs_object_map_descriptor.Plo -rm -f ./$(DEPDIR)/libfsapfs_password.Plo -rm -f ./$(DEPDIR)/libfsapfs_profiler.Plo + -rm -f ./$(DEPDIR)/libfsapfs_snapshot_metadata.Plo + -rm -f ./$(DEPDIR)/libfsapfs_snapshot_metadata_tree.Plo + -rm -f ./$(DEPDIR)/libfsapfs_space_manager.Plo -rm -f ./$(DEPDIR)/libfsapfs_support.Plo -rm -f ./$(DEPDIR)/libfsapfs_volume.Plo -rm -f ./$(DEPDIR)/libfsapfs_volume_key_bag.Plo diff -Nru libfsapfs-20181215/libfsapfs.spec libfsapfs-20190210/libfsapfs.spec --- libfsapfs-20181215/libfsapfs.spec 2018-12-15 06:44:19.000000000 +0000 +++ libfsapfs-20190210/libfsapfs.spec 2019-02-10 19:59:54.000000000 +0000 @@ -1,5 +1,5 @@ Name: libfsapfs -Version: 20181215 +Version: 20190210 Release: 1 Summary: Library to access the Apple File System (APFS) format Group: System Environment/Libraries @@ -13,6 +13,14 @@ %description -n libfsapfs Library to access the Apple File System (APFS) format +%package -n libfsapfs-static +Summary: Library to access the Apple File System (APFS) format +Group: Development/Libraries +Requires: libfsapfs = %{version}-%{release} + +%description -n libfsapfs-static +Static library version of libfsapfs. + %package -n libfsapfs-devel Summary: Header files and libraries for developing applications for libfsapfs Group: Development/Libraries @@ -74,11 +82,16 @@ %doc AUTHORS README %attr(755,root,root) %{_libdir}/*.so.* +%files -n libfsapfs-static +%defattr(644,root,root,755) +%license COPYING +%doc AUTHORS README +%attr(755,root,root) %{_libdir}/*.a + %files -n libfsapfs-devel %defattr(644,root,root,755) %license COPYING -%doc AUTHORS README ChangeLog -%{_libdir}/*.a +%doc AUTHORS README %{_libdir}/*.la %{_libdir}/*.so %{_libdir}/pkgconfig/libfsapfs.pc @@ -109,6 +122,6 @@ %{_mandir}/man1/* %changelog -* Sat Dec 15 2018 Joachim Metz 20181215-1 +* Sun Feb 10 2019 Joachim Metz 20190210-1 - Auto-generated diff -Nru libfsapfs-20181215/libfsapfs.spec.in libfsapfs-20190210/libfsapfs.spec.in --- libfsapfs-20181215/libfsapfs.spec.in 2018-12-03 17:48:57.000000000 +0000 +++ libfsapfs-20190210/libfsapfs.spec.in 2019-02-06 20:10:07.000000000 +0000 @@ -13,6 +13,14 @@ %description -n libfsapfs Library to access the Apple File System (APFS) format +%package -n libfsapfs-static +Summary: Library to access the Apple File System (APFS) format +Group: Development/Libraries +Requires: libfsapfs = %{version}-%{release} + +%description -n libfsapfs-static +Static library version of libfsapfs. + %package -n libfsapfs-devel Summary: Header files and libraries for developing applications for libfsapfs Group: Development/Libraries @@ -74,11 +82,16 @@ %doc AUTHORS README %attr(755,root,root) %{_libdir}/*.so.* +%files -n libfsapfs-static +%defattr(644,root,root,755) +%license COPYING +%doc AUTHORS README +%attr(755,root,root) %{_libdir}/*.a + %files -n libfsapfs-devel %defattr(644,root,root,755) %license COPYING -%doc AUTHORS README ChangeLog -%{_libdir}/*.a +%doc AUTHORS README %{_libdir}/*.la %{_libdir}/*.so %{_libdir}/pkgconfig/libfsapfs.pc diff -Nru libfsapfs-20181215/libuna/libuna_base16_stream.c libfsapfs-20190210/libuna/libuna_base16_stream.c --- libfsapfs-20181215/libuna/libuna_base16_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_base16_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Base16 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_base16_stream.h libfsapfs-20190210/libuna/libuna_base16_stream.h --- libfsapfs-20181215/libuna/libuna_base16_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_base16_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Base16 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_base32_stream.c libfsapfs-20190210/libuna/libuna_base32_stream.c --- libfsapfs-20181215/libuna/libuna_base32_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_base32_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Base32 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_base32_stream.h libfsapfs-20190210/libuna/libuna_base32_stream.h --- libfsapfs-20181215/libuna/libuna_base32_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_base32_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Base32 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_base64_stream.c libfsapfs-20190210/libuna/libuna_base64_stream.c --- libfsapfs-20181215/libuna/libuna_base64_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_base64_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Base64 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_base64_stream.h libfsapfs-20190210/libuna/libuna_base64_stream.h --- libfsapfs-20181215/libuna/libuna_base64_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_base64_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Base64 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_byte_stream.c libfsapfs-20190210/libuna/libuna_byte_stream.c --- libfsapfs-20181215/libuna/libuna_byte_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_byte_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Byte stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_byte_stream.h libfsapfs-20190210/libuna/libuna_byte_stream.h --- libfsapfs-20181215/libuna/libuna_byte_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_byte_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Byte stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_10.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_10.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_10.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_10.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-10 codepage (Nordic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_10.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_10.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_10.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_10.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-10 codepage (Nordic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_10_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_10_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_10_unicode_to_byte_stream_base_0x00c0[ 144 ]; -extern const uint8_t libuna_codepage_iso_8859_10_unicode_to_byte_stream_base_0x00c0[ 144 ]; -extern const uint8_t libuna_codepage_iso_8859_10_unicode_to_byte_stream_base_0x0160[ 16 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_10_unicode_to_byte_stream_base_0x0160[ 16 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_13.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_13.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_13.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_13.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-13 codepage (Baltic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_13.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_13.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_13.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_13.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-13 codepage (Baltic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_13_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_13_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_13_unicode_to_byte_stream_base_0x00a0[ 224 ]; -extern const uint8_t libuna_codepage_iso_8859_13_unicode_to_byte_stream_base_0x00a0[ 224 ]; -extern const uint8_t libuna_codepage_iso_8859_13_unicode_to_byte_stream_base_0x2018[ 8 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_13_unicode_to_byte_stream_base_0x2018[ 8 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_14.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_14.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_14.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_14.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-14 codepage (Celtic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_14.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_14.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_14.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_14.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-14 codepage (Celtic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,15 +25,23 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_14_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_14_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x00c0[ 64 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x0170[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x00c0[ 64 ]; -extern const uint8_t libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x0170[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x1e80[ 8 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_14_unicode_to_byte_stream_base_0x1e80[ 8 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_15.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_15.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_15.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_15.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-15 codepage (Latin 9) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_15.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_15.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_15.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_15.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-15 codepage (Latin 9) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,13 +25,17 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_15_byte_stream_to_unicode_base_0xa0[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_15_byte_stream_to_unicode_base_0xa0[ 32 ]; -extern const uint8_t libuna_codepage_iso_8859_15_unicode_to_byte_stream_base_0x00a0[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_15_unicode_to_byte_stream_base_0x00a0[ 32 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_16.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_16.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_16.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_16.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-16 codepage (Latin 10) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_16.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_16.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_16.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_16.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-16 codepage (Latin 10) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,17 +25,29 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_16_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_16_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x00a8[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0140[ 8 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0150[ 8 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0178[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x00a8[ 96 ]; -extern const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0140[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0150[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0178[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0218[ 8 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_16_unicode_to_byte_stream_base_0x0218[ 8 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_2.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_2.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_2.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_2.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-2 codepage (Central European) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_2.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_2.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_2.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_2.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-2 codepage (Central European) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,15 +25,23 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_2_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_2_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x00a0[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x0138[ 72 ]; -extern const uint8_t libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x00a0[ 128 ]; -extern const uint8_t libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x0138[ 72 ]; -extern const uint8_t libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x02d8[ 8 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_2_unicode_to_byte_stream_base_0x02d8[ 8 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_3.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_3.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_3.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_3.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-3 codepage (Latin 3) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_3.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_3.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_3.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_3.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-3 codepage (Latin 3) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,17 +25,29 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_3_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_3_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x00a0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0108[ 8 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0118[ 16 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0130[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x00a0[ 96 ]; -extern const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0108[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0118[ 16 ]; -extern const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0130[ 8 ]; -extern const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0158[ 8 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_3_unicode_to_byte_stream_base_0x0158[ 8 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_4.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_4.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_4.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_4.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-4 codepage (Baltic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_4.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_4.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_4.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_4.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-4 codepage (Baltic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_4_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_4_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_4_unicode_to_byte_stream_base_0x00a0[ 184 ]; -extern const uint8_t libuna_codepage_iso_8859_4_unicode_to_byte_stream_base_0x00a0[ 184 ]; -extern const uint8_t libuna_codepage_iso_8859_4_unicode_to_byte_stream_base_0x0160[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_4_unicode_to_byte_stream_base_0x0160[ 32 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_5.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_5.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_5.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_5.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-5 codepage (Cyrillic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_5.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_5.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_5.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_5.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-5 codepage (Cyrillic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,13 +25,17 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_5_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_5_byte_stream_to_unicode_base_0xa0[ 96 ]; -extern const uint8_t libuna_codepage_iso_8859_5_unicode_to_byte_stream_base_0x0400[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_5_unicode_to_byte_stream_base_0x0400[ 96 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_6.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_6.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_6.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_6.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-6 codepage (Arabic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_6.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_6.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_6.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_6.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-6 codepage (Arabic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,13 +25,17 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_6_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_6_byte_stream_to_unicode_base_0xa0[ 96 ]; -extern const uint8_t libuna_codepage_iso_8859_6_unicode_to_byte_stream_base_0x0618[ 64 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_6_unicode_to_byte_stream_base_0x0618[ 64 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_7.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_7.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_7.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_7.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-7 codepage (Greek) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_7.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_7.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_7.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_7.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-7 codepage (Greek) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_7_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_7_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_7_unicode_to_byte_stream_base_0x00a0[ 24 ]; -extern const uint8_t libuna_codepage_iso_8859_7_unicode_to_byte_stream_base_0x00a0[ 24 ]; -extern const uint8_t libuna_codepage_iso_8859_7_unicode_to_byte_stream_base_0x0380[ 80 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_7_unicode_to_byte_stream_base_0x0380[ 80 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_8.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_8.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_8.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_8.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-8 codepage (Hebrew) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_8.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_8.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_8.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_8.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-8 codepage (Hebrew) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_8_byte_stream_to_unicode_base_0xa0[ 96 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_8_byte_stream_to_unicode_base_0xa0[ 96 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_8_unicode_to_byte_stream_base_0x00a0[ 32 ]; -extern const uint8_t libuna_codepage_iso_8859_8_unicode_to_byte_stream_base_0x00a0[ 32 ]; -extern const uint8_t libuna_codepage_iso_8859_8_unicode_to_byte_stream_base_0x05d0[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_8_unicode_to_byte_stream_base_0x05d0[ 32 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_9.c libfsapfs-20190210/libuna/libuna_codepage_iso_8859_9.c --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_9.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_9.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-9 codepage (Turkish) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_iso_8859_9.h libfsapfs-20190210/libuna/libuna_codepage_iso_8859_9.h --- libfsapfs-20181215/libuna/libuna_codepage_iso_8859_9.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_iso_8859_9.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * ISO 8859-9 codepage (Turkish) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,13 +25,17 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_iso_8859_9_byte_stream_to_unicode_base_0xd0[ 48 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_iso_8859_9_byte_stream_to_unicode_base_0xd0[ 48 ]; -extern const uint8_t libuna_codepage_iso_8859_9_unicode_to_byte_stream_base_0x00d0[ 48 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_iso_8859_9_unicode_to_byte_stream_base_0x00d0[ 48 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_koi8_r.c libfsapfs-20190210/libuna/libuna_codepage_koi8_r.c --- libfsapfs-20181215/libuna/libuna_codepage_koi8_r.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_koi8_r.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * KOI8-R codepage (Russian Cyrillic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_koi8_r.h libfsapfs-20190210/libuna/libuna_codepage_koi8_r.h --- libfsapfs-20181215/libuna/libuna_codepage_koi8_r.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_koi8_r.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * KOI8-R codepage (Russian Cyrillic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_koi8_r_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_koi8_r_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_koi8_r_unicode_to_byte_stream_base_0x0410[ 64 ]; -extern const uint8_t libuna_codepage_koi8_r_unicode_to_byte_stream_base_0x0410[ 64 ]; -extern const uint8_t libuna_codepage_koi8_r_unicode_to_byte_stream_base_0x2550[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_koi8_r_unicode_to_byte_stream_base_0x2550[ 32 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_koi8_u.c libfsapfs-20190210/libuna/libuna_codepage_koi8_u.c --- libfsapfs-20181215/libuna/libuna_codepage_koi8_u.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_koi8_u.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * KOI8-U codepage (Ukrainian Cyrillic) function * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_koi8_u.h libfsapfs-20190210/libuna/libuna_codepage_koi8_u.h --- libfsapfs-20181215/libuna/libuna_codepage_koi8_u.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_koi8_u.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * KOI8-U codepage (Ukrainian Cyrillic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_koi8_u_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_koi8_u_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_koi8_u_unicode_to_byte_stream_base_0x0410[ 64 ]; -extern const uint8_t libuna_codepage_koi8_u_unicode_to_byte_stream_base_0x0410[ 64 ]; -extern const uint8_t libuna_codepage_koi8_u_unicode_to_byte_stream_base_0x2550[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_koi8_u_unicode_to_byte_stream_base_0x2550[ 32 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1250.c libfsapfs-20190210/libuna/libuna_codepage_windows_1250.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1250.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1250.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1250 codepage (Central European) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1250.h libfsapfs-20190210/libuna/libuna_codepage_windows_1250.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1250.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1250.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1250 codepage (Central European) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,17 +25,29 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1250_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1250_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x00a0[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x0138[ 72 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x02d8[ 8 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x2010[ 24 ]; -extern const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x00a0[ 128 ]; -extern const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x0138[ 72 ]; -extern const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x02d8[ 8 ]; -extern const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x2010[ 24 ]; -extern const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x2030[ 16 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1250_unicode_to_byte_stream_base_0x2030[ 16 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1251.c libfsapfs-20190210/libuna/libuna_codepage_windows_1251.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1251.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1251.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1251 codepage (Cyrillic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1251.h libfsapfs-20190210/libuna/libuna_codepage_windows_1251.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1251.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1251.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1251 codepage (Cyrillic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,15 +25,23 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1251_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1251_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1251_unicode_to_byte_stream_base_0x00a0[ 32 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1251_unicode_to_byte_stream_base_0x0400[ 96 ]; -extern const uint8_t libuna_codepage_windows_1251_unicode_to_byte_stream_base_0x00a0[ 32 ]; -extern const uint8_t libuna_codepage_windows_1251_unicode_to_byte_stream_base_0x0400[ 96 ]; -extern const uint8_t libuna_codepage_windows_1251_unicode_to_byte_stream_base_0x2010[ 24 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1251_unicode_to_byte_stream_base_0x2010[ 24 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1252.c libfsapfs-20190210/libuna/libuna_codepage_windows_1252.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1252.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1252.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1252 codepage (Western European/Latin 1) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1252.h libfsapfs-20190210/libuna/libuna_codepage_windows_1252.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1252.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1252.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1252 codepage (Western European/Latin 1) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,13 +25,17 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1252_byte_stream_to_unicode_base_0x80[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1252_byte_stream_to_unicode_base_0x80[ 32 ]; -extern const uint8_t libuna_codepage_windows_1252_unicode_to_byte_stream_base_0x2010[ 24 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1252_unicode_to_byte_stream_base_0x2010[ 24 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1253.c libfsapfs-20190210/libuna/libuna_codepage_windows_1253.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1253.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1253.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1253 codepage (Greek) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1253.h libfsapfs-20190210/libuna/libuna_codepage_windows_1253.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1253.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1253.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1253 codepage (Greek) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,15 +25,23 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1253_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1253_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1253_unicode_to_byte_stream_base_0x00a0[ 32 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1253_unicode_to_byte_stream_base_0x0380[ 80 ]; -extern const uint8_t libuna_codepage_windows_1253_unicode_to_byte_stream_base_0x00a0[ 32 ]; -extern const uint8_t libuna_codepage_windows_1253_unicode_to_byte_stream_base_0x0380[ 80 ]; -extern const uint8_t libuna_codepage_windows_1253_unicode_to_byte_stream_base_0x2010[ 24 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1253_unicode_to_byte_stream_base_0x2010[ 24 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1254.c libfsapfs-20190210/libuna/libuna_codepage_windows_1254.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1254.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1254.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1254 codepage (Turkish) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1254.h libfsapfs-20190210/libuna/libuna_codepage_windows_1254.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1254.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1254.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1254 codepage (Turkish) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,16 +25,26 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0x80[ 32 ]; -extern const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xd0[ 16 ]; -extern const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xf0[ 16 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0x80[ 32 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xd0[ 16 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xf0[ 16 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x00d0[ 48 ]; -extern const uint8_t libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x00d0[ 48 ]; -extern const uint8_t libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x2010[ 24 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x2010[ 24 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1255.c libfsapfs-20190210/libuna/libuna_codepage_windows_1255.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1255.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1255.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1255 codepage (Hebrew) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1255.h libfsapfs-20190210/libuna/libuna_codepage_windows_1255.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1255.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1255.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1255 codepage (Hebrew) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,16 +25,26 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1255_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1255_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x00a0[ 32 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x05b0[ 24 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x05d0[ 40 ]; -extern const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x00a0[ 32 ]; -extern const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x05b0[ 24 ]; -extern const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x05d0[ 40 ]; -extern const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x2010[ 24 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1255_unicode_to_byte_stream_base_0x2010[ 24 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1256.c libfsapfs-20190210/libuna/libuna_codepage_windows_1256.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1256.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1256.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1256 codepage (Arabic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1256.h libfsapfs-20190210/libuna/libuna_codepage_windows_1256.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1256.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1256.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1256 codepage (Arabic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,16 +25,26 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1256_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1256_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x00a0[ 32 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x00e0[ 32 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x0618[ 64 ]; -extern const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x00a0[ 32 ]; -extern const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x00e0[ 32 ]; -extern const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x0618[ 64 ]; -extern const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x2008[ 32 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1256_unicode_to_byte_stream_base_0x2008[ 32 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1257.c libfsapfs-20190210/libuna/libuna_codepage_windows_1257.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1257.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1257.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1257 codepage (Baltic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1257.h libfsapfs-20190210/libuna/libuna_codepage_windows_1257.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1257.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1257.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1257 codepage (Baltic) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1257_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1257_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1257_unicode_to_byte_stream_base_0x00a0[ 224 ]; -extern const uint8_t libuna_codepage_windows_1257_unicode_to_byte_stream_base_0x00a0[ 224 ]; -extern const uint8_t libuna_codepage_windows_1257_unicode_to_byte_stream_base_0x2010[ 24 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1257_unicode_to_byte_stream_base_0x2010[ 24 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1258.c libfsapfs-20190210/libuna/libuna_codepage_windows_1258.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_1258.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1258.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1258 codepage (Vietnamese) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_1258.h libfsapfs-20190210/libuna/libuna_codepage_windows_1258.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_1258.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_1258.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 1258 codepage (Vietnamese) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_1258_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_1258_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1258_unicode_to_byte_stream_base_0x00c0[ 72 ]; -extern const uint8_t libuna_codepage_windows_1258_unicode_to_byte_stream_base_0x00c0[ 72 ]; -extern const uint8_t libuna_codepage_windows_1258_unicode_to_byte_stream_base_0x2010[ 24 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_1258_unicode_to_byte_stream_base_0x2010[ 24 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_874.c libfsapfs-20190210/libuna/libuna_codepage_windows_874.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_874.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_874.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 874 codepage (Thai) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_874.h libfsapfs-20190210/libuna/libuna_codepage_windows_874.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_874.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_874.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 874 codepage (Thai) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -25,14 +25,20 @@ #include #include +#include "libuna_extern.h" + #if defined( __cplusplus ) extern "C" { #endif -extern const uint16_t libuna_codepage_windows_874_byte_stream_to_unicode_base_0x80[ 128 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint16_t libuna_codepage_windows_874_byte_stream_to_unicode_base_0x80[ 128 ]; + +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_874_unicode_to_byte_stream_base_0x0e00[ 96 ]; -extern const uint8_t libuna_codepage_windows_874_unicode_to_byte_stream_base_0x0e00[ 96 ]; -extern const uint8_t libuna_codepage_windows_874_unicode_to_byte_stream_base_0x2018[ 8 ]; +LIBUNA_EXTERN_VARIABLE \ +const uint8_t libuna_codepage_windows_874_unicode_to_byte_stream_base_0x2018[ 8 ]; #if defined( __cplusplus ) } diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_932.c libfsapfs-20190210/libuna/libuna_codepage_windows_932.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_932.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_932.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 932 codepage (Japanese Shift-JIS) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_932.h libfsapfs-20190210/libuna/libuna_codepage_windows_932.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_932.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_932.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 932 codepage (Japanese Shift-JIS) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_936.c libfsapfs-20190210/libuna/libuna_codepage_windows_936.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_936.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_936.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 936 codepage (Chinese Simplified) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_936.h libfsapfs-20190210/libuna/libuna_codepage_windows_936.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_936.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_936.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 936 codepage (Chinese Simplified) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_949.c libfsapfs-20190210/libuna/libuna_codepage_windows_949.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_949.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_949.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 949 codepage (Korean) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_949.h libfsapfs-20190210/libuna/libuna_codepage_windows_949.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_949.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_949.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 949 codepage (Korean) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_950.c libfsapfs-20190210/libuna/libuna_codepage_windows_950.c --- libfsapfs-20181215/libuna/libuna_codepage_windows_950.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_950.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 950 codepage (Traditional Chinese) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_codepage_windows_950.h libfsapfs-20190210/libuna/libuna_codepage_windows_950.h --- libfsapfs-20181215/libuna/libuna_codepage_windows_950.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_codepage_windows_950.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Windows 950 codepage (Traditional Chinese) functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_definitions.h libfsapfs-20190210/libuna/libuna_definitions.h --- libfsapfs-20181215/libuna/libuna_definitions.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_definitions.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal definitions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -35,11 +35,11 @@ #else #include -#define LIBUNA_VERSION 20181006 +#define LIBUNA_VERSION 20190102 /* The libuna version string */ -#define LIBUNA_VERSION_STRING "20181006" +#define LIBUNA_VERSION_STRING "20190102" /* The endian definitions */ diff -Nru libfsapfs-20181215/libuna/libuna_error.c libfsapfs-20190210/libuna/libuna_error.c --- libfsapfs-20181215/libuna/libuna_error.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_error.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_error.h libfsapfs-20190210/libuna/libuna_error.h --- libfsapfs-20181215/libuna/libuna_error.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_error.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_extern.h libfsapfs-20190210/libuna/libuna_extern.h --- libfsapfs-20181215/libuna/libuna_extern.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_extern.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal extern definition * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_libcerror.h libfsapfs-20190210/libuna/libuna_libcerror.h --- libfsapfs-20181215/libuna/libuna_libcerror.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_libcerror.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_support.c libfsapfs-20190210/libuna/libuna_support.c --- libfsapfs-20181215/libuna/libuna_support.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_support.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_support.h libfsapfs-20190210/libuna/libuna_support.h --- libfsapfs-20181215/libuna/libuna_support.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_support.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Support functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_types.h libfsapfs-20190210/libuna/libuna_types.h --- libfsapfs-20181215/libuna/libuna_types.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_types.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal type definitions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_unicode_character.c libfsapfs-20190210/libuna/libuna_unicode_character.c --- libfsapfs-20181215/libuna/libuna_unicode_character.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_unicode_character.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Unicode character functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_unicode_character.h libfsapfs-20190210/libuna/libuna_unicode_character.h --- libfsapfs-20181215/libuna/libuna_unicode_character.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_unicode_character.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Unicode character functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _LIBUNA_UNICDODE_CHARACTER_H ) -#define _LIBUNA_UNICDODE_CHARACTER_H +#if !defined( _LIBUNA_UNICODE_CHARACTER_H ) +#define _LIBUNA_UNICODE_CHARACTER_H #include #include @@ -190,5 +190,5 @@ } #endif -#endif /* !defined( _LIBUNA_UNICDODE_CHARACTER_H ) */ +#endif /* !defined( _LIBUNA_UNICODE_CHARACTER_H ) */ diff -Nru libfsapfs-20181215/libuna/libuna_unused.h libfsapfs-20190210/libuna/libuna_unused.h --- libfsapfs-20181215/libuna/libuna_unused.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_unused.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _LIBUNA_INTERNAL_UNUSED_H ) -#define _LIBUNA_INTERNAL_UNUSED_H +#if !defined( _LIBUNA_UNUSED_H ) +#define _LIBUNA_UNUSED_H #include @@ -40,5 +40,5 @@ /* parameter */ #endif -#endif /* !defined( _LIBUNA_INTERNAL_UNUSED_H ) */ +#endif /* !defined( _LIBUNA_UNUSED_H ) */ diff -Nru libfsapfs-20181215/libuna/libuna_url_stream.c libfsapfs-20190210/libuna/libuna_url_stream.c --- libfsapfs-20181215/libuna/libuna_url_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_url_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Percent or URL encoded stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_url_stream.h libfsapfs-20190210/libuna/libuna_url_stream.h --- libfsapfs-20181215/libuna/libuna_url_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_url_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * Percent or URL encoded stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf16_stream.c libfsapfs-20190210/libuna/libuna_utf16_stream.c --- libfsapfs-20181215/libuna/libuna_utf16_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf16_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-16 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf16_stream.h libfsapfs-20190210/libuna/libuna_utf16_stream.h --- libfsapfs-20181215/libuna/libuna_utf16_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf16_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-16 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf16_string.c libfsapfs-20190210/libuna/libuna_utf16_string.c --- libfsapfs-20181215/libuna/libuna_utf16_string.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf16_string.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-16 string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -2480,9 +2480,9 @@ { utf16_string_size -= 1; } - if( utf32_string[ utf16_string_size - 1 ] == 0 ) + if( utf32_string[ utf32_string_size - 1 ] == 0 ) { - utf16_string_size -= 1; + utf32_string_size -= 1; } while( ( utf16_string_index < utf16_string_size ) && ( utf32_string_index < utf32_string_size ) ) diff -Nru libfsapfs-20181215/libuna/libuna_utf16_string.h libfsapfs-20190210/libuna/libuna_utf16_string.h --- libfsapfs-20181215/libuna/libuna_utf16_string.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf16_string.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-16 string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf32_stream.c libfsapfs-20190210/libuna/libuna_utf32_stream.c --- libfsapfs-20181215/libuna/libuna_utf32_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf32_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-32 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf32_stream.h libfsapfs-20190210/libuna/libuna_utf32_stream.h --- libfsapfs-20181215/libuna/libuna_utf32_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf32_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-32 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf32_string.c libfsapfs-20190210/libuna/libuna_utf32_string.c --- libfsapfs-20181215/libuna/libuna_utf32_string.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf32_string.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-32 string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf32_string.h libfsapfs-20190210/libuna/libuna_utf32_string.h --- libfsapfs-20181215/libuna/libuna_utf32_string.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf32_string.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-32 string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf7_stream.c libfsapfs-20190210/libuna/libuna_utf7_stream.c --- libfsapfs-20181215/libuna/libuna_utf7_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf7_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-7 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf7_stream.h libfsapfs-20190210/libuna/libuna_utf7_stream.h --- libfsapfs-20181215/libuna/libuna_utf7_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf7_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-7 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf8_stream.c libfsapfs-20190210/libuna/libuna_utf8_stream.c --- libfsapfs-20181215/libuna/libuna_utf8_stream.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf8_stream.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-8 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf8_stream.h libfsapfs-20190210/libuna/libuna_utf8_stream.h --- libfsapfs-20181215/libuna/libuna_utf8_stream.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf8_stream.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-8 stream functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf8_string.c libfsapfs-20190210/libuna/libuna_utf8_string.c --- libfsapfs-20181215/libuna/libuna_utf8_string.c 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf8_string.c 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-8 string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/libuna/libuna_utf8_string.h libfsapfs-20190210/libuna/libuna_utf8_string.h --- libfsapfs-20181215/libuna/libuna_utf8_string.h 2018-12-15 06:43:43.000000000 +0000 +++ libfsapfs-20190210/libuna/libuna_utf8_string.h 2019-02-10 19:59:23.000000000 +0000 @@ -1,7 +1,7 @@ /* * UTF-8 string functions * - * Copyright (C) 2008-2018, Joachim Metz + * Copyright (C) 2008-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/m4/libcaes.m4 libfsapfs-20190210/m4/libcaes.m4 --- libfsapfs-20181215/m4/libcaes.m4 2018-11-17 13:06:56.000000000 +0000 +++ libfsapfs-20190210/m4/libcaes.m4 2019-01-02 18:29:13.000000000 +0000 @@ -1,6 +1,6 @@ dnl Checks for libcaes required headers and functions dnl -dnl Version: 20181117 +dnl Version: 20190102 dnl Function to detect if libcaes is available dnl ac_libcaes_dummy is used to prevent AC_CHECK_LIB adding unnecessary -l arguments @@ -144,29 +144,29 @@ dnl Function to detect if libcaes dependencies are available AC_DEFUN([AX_LIBCAES_CHECK_LOCAL], - [ac_cv_libcaes_aes=no + [dnl Check for libcrypto (openssl) support + AX_LIBCRYPTO_CHECK_ENABLE - dnl Check for Windows crypto API support AS_IF( - [test "x$ac_cv_enable_winapi" = xyes], - [ac_cv_libcaes_aes=libadvapi32]) + [test "x$ac_cv_libcrypto" != xno], + [AX_LIBCRYPTO_CHECK_AES + AX_LIBCRYPTO_CHECK_AES_XTS]) - dnl Check for libcrypto (openssl) support + dnl Fallback to local versions if necessary AS_IF( - [test "x$ac_cv_libcaes_aes" = xno], - [AX_LIBCRYPTO_CHECK_ENABLE - - AS_IF( - [test "x$ac_cv_libcrypto" != xno], - [AX_LIBCRYPTO_CHECK_AES + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_aes_cbc" = xno], + [ac_cv_libcaes_aes_cbc=local], + [ac_cv_libcaes_aes_cbc=$ac_cv_libcrypto_aes_cbc]) - ac_cv_libcaes_aes=$ac_cv_libcrypto_aes]) - ]) + AS_IF( + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno], + [ac_cv_libcaes_aes_ecb=local], + [ac_cv_libcaes_aes_ecb=$ac_cv_libcrypto_aes_ecb]) - dnl Fallback to local versions if necessary AS_IF( - [test "x$ac_cv_libcaes_aes" = xno], - [ac_cv_libcaes_aes=local]) + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_aes_xts" = xno], + [ac_cv_libcaes_aes_xts=local], + [ac_cv_libcaes_aes_xts=$ac_cv_libcrypto_aes_xts]) ac_cv_libcaes_CPPFLAGS="-I../libcaes"; ac_cv_libcaes_LIBADD="../libcaes/libcaes.la"; diff -Nru libfsapfs-20181215/m4/libcdata.m4 libfsapfs-20190210/m4/libcdata.m4 --- libfsapfs-20181215/m4/libcdata.m4 2018-11-17 11:34:44.000000000 +0000 +++ libfsapfs-20190210/m4/libcdata.m4 2019-01-13 18:18:11.000000000 +0000 @@ -1,6 +1,6 @@ dnl Checks for libcdata required headers and functions dnl -dnl Version: 20181117 +dnl Version: 20190112 dnl Function to detect if libcdata is available dnl ac_libcdata_dummy is used to prevent AC_CHECK_LIB adding unnecessary -l arguments @@ -25,7 +25,7 @@ [test "x$cross_compiling" != "xyes" && test "x$PKGCONFIG" != "x"], [PKG_CHECK_MODULES( [libcdata], - [libcdata >= 20160108], + [libcdata >= 20190112], [ac_cv_libcdata=yes], [ac_cv_libcdata=check]) ]) diff -Nru libfsapfs-20181215/m4/libcrypto.m4 libfsapfs-20190210/m4/libcrypto.m4 --- libfsapfs-20181215/m4/libcrypto.m4 2018-11-17 13:06:56.000000000 +0000 +++ libfsapfs-20190210/m4/libcrypto.m4 2019-01-02 18:29:13.000000000 +0000 @@ -1,6 +1,6 @@ dnl Checks for libcrypto required headers and functions dnl -dnl Version: 20181117 +dnl Version: 20190102 dnl Function to detect whether openssl/evp.h can be used in combination with zlib.h AC_DEFUN([AX_LIBCRYPTO_CHECK_OPENSSL_EVP_ZLIB_COMPATIBILE], @@ -355,7 +355,7 @@ [ac_cv_libcrypto=yes]) ]) -dnl Function to detect if openssl EVP AES functions are available +dnl Function to detect if openssl EVP CIPHER functions are available AC_DEFUN([AX_LIBCRYPTO_CHECK_OPENSSL_EVP_CIPHER], [ac_cv_libcrypto_evp_cipher=yes @@ -440,34 +440,71 @@ ]) ]) -dnl Function to detect if openssl AES functions are available +dnl Function to detect if openssl AES-CBC and AES-ECB functions are available AC_DEFUN([AX_LIBCRYPTO_CHECK_OPENSSL_AES], [AC_CHECK_HEADERS([openssl/aes.h]) AS_IF( [test "x$ac_cv_header_openssl_aes_h" = xno], - [ac_cv_libcrypto_aes=no], - [ac_cv_libcrypto_aes=libcrypto + [ac_cv_libcrypto_aes_cbc=no + ac_cv_libcrypto_aes_ecb=no], + [ac_cv_libcrypto_aes_cbc=libcrypto + ac_cv_libcrypto_aes_ecb=libcrypto + AC_CHECK_LIB( crypto, - EVP_aes_128_ecb, + AES_set_decrypt_key, [ac_cv_libcrypto_dummy=yes], - [ac_cv_libcrypto_aes=no]) + [ac_cv_libcrypto_aes_cbc=no, + ac_cv_libcrypto_aes_ecb=no]) AC_CHECK_LIB( crypto, - EVP_aes_192_ecb, + AES_set_encrypt_key, [ac_cv_libcrypto_dummy=yes], - [ac_cv_libcrypto_aes=no]) + [ac_cv_libcrypto_aes_cbc=no, + ac_cv_libcrypto_aes_ecb=no]) + AC_CHECK_LIB( crypto, - EVP_aes_256_ecb, + AES_cbc_encrypt, [ac_cv_libcrypto_dummy=yes], - [ac_cv_libcrypto_aes=no]) + [ac_cv_libcrypto_aes_cbc=no]) + + AC_CHECK_LIB( + crypto, + AES_ecb_encrypt, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_ecb=no]) + + AS_IF( + [test "x$ac_cv_lib_crypto_AES_cbc_encrypt" = xyes], + [AC_DEFINE( + [HAVE_AES_CBC_ENCRYPT], + [1], + [Define to 1 if you have the `AES_cbc_encrypt' function".]) + ]) + + AS_IF( + [test "x$ac_cv_lib_crypto_AES_ecb_encrypt" = xyes], + [AC_DEFINE( + [HAVE_AES_ECB_ENCRYPT], + [1], + [Define to 1 if you have the `AES_ecb_encrypt' function".]) + ]) ]) AS_IF( - [test "x$ac_cv_libcrypto" = xno && test "x$ac_cv_libcrypto_aes" = xlibcrypto], - [ac_cv_libcrypto=yes]) + [test "x$ac_cv_libcrypto" = xno], + [AS_IF( + [test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno], + [ac_cv_libcrypto=yes]) + ]) + + dnl ac_cv_libcrypto_aes is deprecated but kept for backwards compatibility + AS_IF( + [test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno], + [ac_cv_libcrypto_aes=no], + [ac_cv_libcrypto_aes=libcrypto]) ]) dnl Function to detect if libcrypto (openssl) dependencies are available @@ -651,24 +688,128 @@ [AX_LIBCRYPTO_CHECK_OPENSSL_SHA512]) ]) -dnl Function to detect if libcrypto AES functions are available +dnl Function to detect if libcrypto AES-CBC and AES-ECB functions are available AC_DEFUN([AX_LIBCRYPTO_CHECK_AES], - [ac_cv_libcrypto_aes=no + [dnl Check for libcrypto (openssl) EVP CIPHER AES-CBC and AES-ECB support + AX_LIBCRYPTO_CHECK_AES_CBC + AX_LIBCRYPTO_CHECK_AES_ECB + + dnl ac_cv_libcrypto_aes is deprecated but kept for backwards compatibility + AS_IF( + [test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno], + [ac_cv_libcrypto_aes=no], + [ac_cv_libcrypto_aes=libcrypto_evp]) + + dnl Check for libcrypto (openssl) AES-CBC and AES-ECB support + AS_IF( + [test "x$ac_cv_libcrypto_aes_cbc" = xno || test "x$ac_cv_libcrypto_aes_ecb" = xno], + [AX_LIBCRYPTO_CHECK_OPENSSL_AES]) + ]) + +dnl Function to detect if libcrypto AES-CBC functions are available +AC_DEFUN([AX_LIBCRYPTO_CHECK_AES_CBC], + [AS_IF( + [test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_cipher" != xno && test "x$ac_cv_libcrypto_evp_cipher" != xyes], + [AX_LIBCRYPTO_CHECK_OPENSSL_EVP_CIPHER]) - dnl Check for libcrypto (openssl) EVP CIPHER support AS_IF( + [test "x$ac_cv_libcrypto_evp_cipher" != xyes], + [ac_cv_libcrypto_aes_cbc=no], + [ac_cv_libcrypto_aes_cbc=libcrypto_evp + + AC_CHECK_LIB( + crypto, + EVP_aes_128_cbc, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_cbc=no]) + AC_CHECK_LIB( + crypto, + EVP_aes_192_cbc, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_cbc=no]) + AC_CHECK_LIB( + crypto, + EVP_aes_256_cbc, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_cbc=no]) + + AS_IF( + [test "x$ac_cv_lib_crypto_EVP_aes_128_cbc" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_192_cbc" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_256_cbc" = xyes], + [AC_DEFINE( + [HAVE_EVP_CRYPTO_AES_CBC], + [1], + [Define to 1 if you have the `EVP_aes_128_cbc', `EVP_aes_192_cbc' and `EVP_aes_256_cbc' functions".]) + ]) + ]) + ]) + +dnl Function to detect if libcrypto AES-ECB functions are available +AC_DEFUN([AX_LIBCRYPTO_CHECK_AES_ECB], + [AS_IF( [test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_cipher" != xno && test "x$ac_cv_libcrypto_evp_cipher" != xyes], - [AX_LIBCRYPTO_CHECK_OPENSSL_EVP_CIPHER + [AX_LIBCRYPTO_CHECK_OPENSSL_EVP_CIPHER]) + + AS_IF( + [test "x$ac_cv_libcrypto_evp_cipher" != xyes], + [ac_cv_libcrypto_aes_ecb=no], + [ac_cv_libcrypto_aes_ecb=libcrypto_evp + + AC_CHECK_LIB( + crypto, + EVP_aes_128_ecb, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_ecb=no]) + AC_CHECK_LIB( + crypto, + EVP_aes_192_ecb, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_ecb=no]) + AC_CHECK_LIB( + crypto, + EVP_aes_256_ecb, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_ecb=no]) AS_IF( - [test "x$ac_cv_libcrypto_evp_cipher" = xyes], - [ac_cv_libcrypto_aes=libcrypto_evp]) + [test "x$ac_cv_lib_crypto_EVP_aes_128_ecb" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_192_ecb" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_256_ecb" = xyes], + [AC_DEFINE( + [HAVE_EVP_CRYPTO_AES_ECB], + [1], + [Define to 1 if you have the `EVP_aes_128_ecb', `EVP_aes_192_ecb' and `EVP_aes_256_ecb' functions".]) + ]) ]) + ]) + +dnl Function to detect if libcrypto AES-XTS functions are available +AC_DEFUN([AX_LIBCRYPTO_CHECK_AES_XTS], + [AS_IF( + [test "x$ac_cv_libcrypto_evp" = xyes && test "x$ac_cv_enable_openssl_evp_cipher" != xno && test "x$ac_cv_libcrypto_evp_cipher" != xyes], + [AX_LIBCRYPTO_CHECK_OPENSSL_EVP_CIPHER]) - dnl Check for libcrypto (openssl) AES support AS_IF( - [test "x$ac_cv_libcrypto_aes" = xno], - [AX_LIBCRYPTO_CHECK_OPENSSL_AES]) + [test "x$ac_cv_libcrypto_evp_cipher" != xyes], + [ac_cv_libcrypto_aes_xts=no], + [ac_cv_libcrypto_aes_xts=libcrypto_evp + + AC_CHECK_LIB( + crypto, + EVP_aes_128_xts, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_xts=no]) + AC_CHECK_LIB( + crypto, + EVP_aes_256_xts, + [ac_cv_libcrypto_dummy=yes], + [ac_cv_libcrypto_aes_xts=no]) + + AS_IF( + [test "x$ac_cv_lib_crypto_EVP_aes_128_xts" = xyes && test "x$ac_cv_lib_crypto_EVP_aes_256_xts" = xyes], + [AC_DEFINE( + [HAVE_EVP_CRYPTO_AES_XTS], + [1], + [Define to 1 if you have the `EVP_aes_128_xts' and `EVP_aes_256_xts' functions".]) + ]) + ]) ]) dnl Function to detect how to enable libcrypto (openssl) diff -Nru libfsapfs-20181215/m4/libhmac.m4 libfsapfs-20190210/m4/libhmac.m4 --- libfsapfs-20181215/m4/libhmac.m4 2018-11-17 13:06:56.000000000 +0000 +++ libfsapfs-20190210/m4/libhmac.m4 2019-01-02 18:29:13.000000000 +0000 @@ -1,6 +1,6 @@ dnl Checks for libhmac required headers and functions dnl -dnl Version: 20181117 +dnl Version: 20190102 dnl Function to detect if libhmac is available dnl ac_libhmac_dummy is used to prevent AC_CHECK_LIB adding unnecessary -l arguments @@ -206,53 +206,42 @@ dnl Function to detect if libhmac dependencies are available AC_DEFUN([AX_LIBHMAC_CHECK_LOCAL], - [ac_cv_libhmac_md5=no - ac_cv_libhmac_sha1=no - ac_cv_libhmac_sha224=no - ac_cv_libhmac_sha256=no - ac_cv_libhmac_sha512=no + [dnl Check for libcrypto (openssl) support + AX_LIBCRYPTO_CHECK_ENABLE - dnl Check for libcrypto (openssl) support AS_IF( - [test "x$ac_cv_libhmac_md5" = xno && test "x$ac_cv_libhmac_sha1" = xno && test "x$ac_cv_libhmac_sha224" = xno && test "x$ac_cv_libhmac_sha256" = xno && test "x$ac_cv_libhmac_sha512" = xno], - [AX_LIBCRYPTO_CHECK_ENABLE - - AS_IF( - [test "x$ac_cv_libcrypto" != xno], - [AX_LIBCRYPTO_CHECK_MD5 - AX_LIBCRYPTO_CHECK_SHA1 - AX_LIBCRYPTO_CHECK_SHA224 - AX_LIBCRYPTO_CHECK_SHA256 - AX_LIBCRYPTO_CHECK_SHA512 - - ac_cv_libhmac_md5=$ac_cv_libcrypto_md5 - ac_cv_libhmac_sha1=$ac_cv_libcrypto_sha1 - ac_cv_libhmac_sha224=$ac_cv_libcrypto_sha224 - ac_cv_libhmac_sha256=$ac_cv_libcrypto_sha256 - ac_cv_libhmac_sha512=$ac_cv_libcrypto_sha512 - ]) - ]) + [test "x$ac_cv_libcrypto" != xno], + [AX_LIBCRYPTO_CHECK_MD5 + AX_LIBCRYPTO_CHECK_SHA1 + AX_LIBCRYPTO_CHECK_SHA224 + AX_LIBCRYPTO_CHECK_SHA256 + AX_LIBCRYPTO_CHECK_SHA512]) dnl Fallback to local versions if necessary AS_IF( - [test "x$ac_cv_libhmac_md5" = xno], - [ac_cv_libhmac_md5=local]) + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_md5" = xno], + [ac_cv_libhmac_md5=local], + [ac_cv_libhmac_md5=$ac_cv_libcrypto_md5]) AS_IF( - [test "x$ac_cv_libhmac_sha1" = xno], - [ac_cv_libhmac_sha1=local]) + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha1" = xno], + [ac_cv_libhmac_sha1=local], + [ac_cv_libhmac_sha1=$ac_cv_libcrypto_sha1]) AS_IF( - [test "x$ac_cv_libhmac_sha224" = xno], - [ac_cv_libhmac_sha224=local]) + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha224" = xno], + [ac_cv_libhmac_sha224=local], + [ac_cv_libhmac_sha224=$ac_cv_libcrypto_sha224]) AS_IF( - [test "x$ac_cv_libhmac_sha256" = xno], - [ac_cv_libhmac_sha256=local]) + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha256" = xno], + [ac_cv_libhmac_sha256=local], + [ac_cv_libhmac_sha256=$ac_cv_libcrypto_sha256]) AS_IF( - [test "x$ac_cv_libhmac_sha512" = xno], - [ac_cv_libhmac_sha512=local]) + [test "x$ac_cv_libcrypto" = xno || test "x$ac_cv_libcrypto_sha512" = xno], + [ac_cv_libhmac_sha512=local], + [ac_cv_libhmac_sha512=$ac_cv_libcrypto_sha512]) ac_cv_libhmac_CPPFLAGS="-I../libhmac"; ac_cv_libhmac_LIBADD="../libhmac/libhmac.la"; diff -Nru libfsapfs-20181215/m4/tests.m4 libfsapfs-20190210/m4/tests.m4 --- libfsapfs-20181215/m4/tests.m4 2018-09-08 11:50:35.000000000 +0000 +++ libfsapfs-20190210/m4/tests.m4 2019-01-13 18:18:11.000000000 +0000 @@ -1,6 +1,6 @@ dnl Functions for testing dnl -dnl Version: 20180905 +dnl Version: 20190112 dnl Function to detect if tests dependencies are available AC_DEFUN([AX_TESTS_CHECK_LOCAL], @@ -17,7 +17,7 @@ [AC_DEFINE( [HAVE_GNU_DL_DLSYM], [1], - [Define to 1 if dlsym funtion is available in GNU dl.]) + [Define to 1 if dlsym function is available in GNU dl.]) ]) ]) diff -Nru libfsapfs-20181215/manuals/fsapfsmount.1 libfsapfs-20190210/manuals/fsapfsmount.1 --- libfsapfs-20181215/manuals/fsapfsmount.1 2018-12-14 09:53:10.000000000 +0000 +++ libfsapfs-20190210/manuals/fsapfsmount.1 2019-02-06 20:10:16.000000000 +0000 @@ -64,7 +64,7 @@ .Sh AUTHOR These man pages were written by Joachim Metz. .Sh COPYRIGHT -Copyright (C) 2018, Joachim Metz . +Copyright (C) 2018-2019, Joachim Metz . This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. .Sh SEE ALSO .Xr fsapfsinfo 1 diff -Nru libfsapfs-20181215/manuals/libfsapfs.3 libfsapfs-20190210/manuals/libfsapfs.3 --- libfsapfs-20181215/manuals/libfsapfs.3 2018-12-03 17:54:06.000000000 +0000 +++ libfsapfs-20190210/manuals/libfsapfs.3 2019-02-06 20:10:16.000000000 +0000 @@ -243,7 +243,7 @@ .Sh AUTHOR These man pages are generated from "libfsapfs.h". .Sh COPYRIGHT -Copyright (C) 2018, Joachim Metz . +Copyright (C) 2018-2019, Joachim Metz . This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff -Nru libfsapfs-20181215/msvscpp/fsapfsmount/fsapfsmount.vcproj libfsapfs-20190210/msvscpp/fsapfsmount/fsapfsmount.vcproj --- libfsapfs-20181215/msvscpp/fsapfsmount/fsapfsmount.vcproj 2018-12-03 17:50:34.000000000 +0000 +++ libfsapfs-20190210/msvscpp/fsapfsmount/fsapfsmount.vcproj 2019-02-06 20:29:46.000000000 +0000 @@ -58,7 +58,7 @@ /> + + + + + + @@ -220,6 +232,10 @@ > + + @@ -256,6 +272,18 @@ > + + + + + + diff -Nru libfsapfs-20181215/msvscpp/fsapfs_test_chunk_information_block/fsapfs_test_chunk_information_block.vcproj libfsapfs-20190210/msvscpp/fsapfs_test_chunk_information_block/fsapfs_test_chunk_information_block.vcproj --- libfsapfs-20181215/msvscpp/fsapfs_test_chunk_information_block/fsapfs_test_chunk_information_block.vcproj 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/msvscpp/fsapfs_test_chunk_information_block/fsapfs_test_chunk_information_block.vcproj 2019-02-06 20:29:46.000000000 +0000 @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libfsapfs-20181215/msvscpp/fsapfs_test_container_space_manager/fsapfs_test_container_space_manager.vcproj libfsapfs-20190210/msvscpp/fsapfs_test_container_space_manager/fsapfs_test_container_space_manager.vcproj --- libfsapfs-20181215/msvscpp/fsapfs_test_container_space_manager/fsapfs_test_container_space_manager.vcproj 2018-12-03 17:51:41.000000000 +0000 +++ libfsapfs-20190210/msvscpp/fsapfs_test_container_space_manager/fsapfs_test_container_space_manager.vcproj 1970-01-01 00:00:00.000000000 +0000 @@ -1,234 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff -Nru libfsapfs-20181215/msvscpp/fsapfs_test_space_manager/fsapfs_test_space_manager.vcproj libfsapfs-20190210/msvscpp/fsapfs_test_space_manager/fsapfs_test_space_manager.vcproj --- libfsapfs-20181215/msvscpp/fsapfs_test_space_manager/fsapfs_test_space_manager.vcproj 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/msvscpp/fsapfs_test_space_manager/fsapfs_test_space_manager.vcproj 2019-02-06 20:29:46.000000000 +0000 @@ -0,0 +1,234 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -Nru libfsapfs-20181215/msvscpp/libcdata/libcdata.vcproj libfsapfs-20190210/msvscpp/libcdata/libcdata.vcproj --- libfsapfs-20181215/msvscpp/libcdata/libcdata.vcproj 2018-12-03 17:50:34.000000000 +0000 +++ libfsapfs-20190210/msvscpp/libcdata/libcdata.vcproj 2019-02-06 20:29:46.000000000 +0000 @@ -159,6 +159,14 @@ > + + + + @@ -201,6 +209,14 @@ > + + + + diff -Nru libfsapfs-20181215/msvscpp/libfsapfs/libfsapfs.vcproj libfsapfs-20190210/msvscpp/libfsapfs/libfsapfs.vcproj --- libfsapfs-20181215/msvscpp/libfsapfs/libfsapfs.vcproj 2018-12-03 17:50:34.000000000 +0000 +++ libfsapfs-20190210/msvscpp/libfsapfs/libfsapfs.vcproj 2019-02-06 20:29:46.000000000 +0000 @@ -206,6 +206,10 @@ > + + @@ -230,10 +234,6 @@ > - - @@ -274,6 +274,10 @@ > + + @@ -290,6 +294,10 @@ > + + @@ -350,6 +358,18 @@ > + + + + + + @@ -380,11 +400,11 @@ > + + + + @@ -408,6 +436,14 @@ > + + + + @@ -444,6 +480,10 @@ > + + @@ -468,10 +508,6 @@ > - - @@ -516,6 +552,10 @@ > + + @@ -536,6 +576,10 @@ > + + @@ -648,6 +692,18 @@ > + + + + + + diff -Nru libfsapfs-20181215/msvscpp/libfsapfs.sln libfsapfs-20190210/msvscpp/libfsapfs.sln --- libfsapfs-20181215/msvscpp/libfsapfs.sln 2018-12-03 17:51:41.000000000 +0000 +++ libfsapfs-20190210/msvscpp/libfsapfs.sln 2019-02-06 20:29:46.000000000 +0000 @@ -69,6 +69,20 @@ {F480F61D-4950-4603-9F6F-F95ECC64A31C} = {F480F61D-4950-4603-9F6F-F95ECC64A31C} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsapfs_test_chunk_information_block", "fsapfs_test_chunk_information_block\fsapfs_test_chunk_information_block.vcproj", "{69BD1901-531F-449B-B57C-A72A046CEB96}" + ProjectSection(ProjectDependencies) = postProject + {ABB04F9A-768A-4F12-9751-65A0E2F81229} = {ABB04F9A-768A-4F12-9751-65A0E2F81229} + {D9CF8B05-7395-4338-BAC5-124E72335F21} = {D9CF8B05-7395-4338-BAC5-124E72335F21} + {ABF4D2D6-8EFB-4A8E-815C-C831C9CA3EF2} = {ABF4D2D6-8EFB-4A8E-815C-C831C9CA3EF2} + {75064AFE-F331-40B7-AB9C-F0040C889610} = {75064AFE-F331-40B7-AB9C-F0040C889610} + {4B0DA96F-94B6-4904-9701-3A9371E8914E} = {4B0DA96F-94B6-4904-9701-3A9371E8914E} + {8AA44886-07A3-430D-90E0-F622A051A571} = {8AA44886-07A3-430D-90E0-F622A051A571} + {670BD730-824A-4304-81D7-DF5B5AE5340C} = {670BD730-824A-4304-81D7-DF5B5AE5340C} + {3EAA2B38-404A-4EE2-B675-8E39E41CEBAA} = {3EAA2B38-404A-4EE2-B675-8E39E41CEBAA} + {66956CAB-8580-4D29-AFA4-49E9934D9E42} = {66956CAB-8580-4D29-AFA4-49E9934D9E42} + {F480F61D-4950-4603-9F6F-F95ECC64A31C} = {F480F61D-4950-4603-9F6F-F95ECC64A31C} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsapfs_test_compressed_data_handle", "fsapfs_test_compressed_data_handle\fsapfs_test_compressed_data_handle.vcproj", "{0759FC1E-239B-4AA8-90E0-3DD006550AFE}" ProjectSection(ProjectDependencies) = postProject {66956CAB-8580-4D29-AFA4-49E9934D9E42} = {66956CAB-8580-4D29-AFA4-49E9934D9E42} @@ -130,20 +144,6 @@ {F480F61D-4950-4603-9F6F-F95ECC64A31C} = {F480F61D-4950-4603-9F6F-F95ECC64A31C} EndProjectSection EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsapfs_test_container_space_manager", "fsapfs_test_container_space_manager\fsapfs_test_container_space_manager.vcproj", "{B9AB3EF5-2424-428E-A57F-D256D4170487}" - ProjectSection(ProjectDependencies) = postProject - {ABB04F9A-768A-4F12-9751-65A0E2F81229} = {ABB04F9A-768A-4F12-9751-65A0E2F81229} - {D9CF8B05-7395-4338-BAC5-124E72335F21} = {D9CF8B05-7395-4338-BAC5-124E72335F21} - {ABF4D2D6-8EFB-4A8E-815C-C831C9CA3EF2} = {ABF4D2D6-8EFB-4A8E-815C-C831C9CA3EF2} - {75064AFE-F331-40B7-AB9C-F0040C889610} = {75064AFE-F331-40B7-AB9C-F0040C889610} - {4B0DA96F-94B6-4904-9701-3A9371E8914E} = {4B0DA96F-94B6-4904-9701-3A9371E8914E} - {8AA44886-07A3-430D-90E0-F622A051A571} = {8AA44886-07A3-430D-90E0-F622A051A571} - {670BD730-824A-4304-81D7-DF5B5AE5340C} = {670BD730-824A-4304-81D7-DF5B5AE5340C} - {3EAA2B38-404A-4EE2-B675-8E39E41CEBAA} = {3EAA2B38-404A-4EE2-B675-8E39E41CEBAA} - {66956CAB-8580-4D29-AFA4-49E9934D9E42} = {66956CAB-8580-4D29-AFA4-49E9934D9E42} - {F480F61D-4950-4603-9F6F-F95ECC64A31C} = {F480F61D-4950-4603-9F6F-F95ECC64A31C} - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsapfs_test_container_superblock", "fsapfs_test_container_superblock\fsapfs_test_container_superblock.vcproj", "{301E1DCF-F551-40A4-9D0D-E07D48322C15}" ProjectSection(ProjectDependencies) = postProject {ABB04F9A-768A-4F12-9751-65A0E2F81229} = {ABB04F9A-768A-4F12-9751-65A0E2F81229} @@ -297,6 +297,20 @@ {F480F61D-4950-4603-9F6F-F95ECC64A31C} = {F480F61D-4950-4603-9F6F-F95ECC64A31C} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsapfs_test_space_manager", "fsapfs_test_space_manager\fsapfs_test_space_manager.vcproj", "{E732C23E-8642-4EFA-A580-1E9D8E6DE090}" + ProjectSection(ProjectDependencies) = postProject + {ABB04F9A-768A-4F12-9751-65A0E2F81229} = {ABB04F9A-768A-4F12-9751-65A0E2F81229} + {D9CF8B05-7395-4338-BAC5-124E72335F21} = {D9CF8B05-7395-4338-BAC5-124E72335F21} + {ABF4D2D6-8EFB-4A8E-815C-C831C9CA3EF2} = {ABF4D2D6-8EFB-4A8E-815C-C831C9CA3EF2} + {75064AFE-F331-40B7-AB9C-F0040C889610} = {75064AFE-F331-40B7-AB9C-F0040C889610} + {4B0DA96F-94B6-4904-9701-3A9371E8914E} = {4B0DA96F-94B6-4904-9701-3A9371E8914E} + {8AA44886-07A3-430D-90E0-F622A051A571} = {8AA44886-07A3-430D-90E0-F622A051A571} + {670BD730-824A-4304-81D7-DF5B5AE5340C} = {670BD730-824A-4304-81D7-DF5B5AE5340C} + {3EAA2B38-404A-4EE2-B675-8E39E41CEBAA} = {3EAA2B38-404A-4EE2-B675-8E39E41CEBAA} + {66956CAB-8580-4D29-AFA4-49E9934D9E42} = {66956CAB-8580-4D29-AFA4-49E9934D9E42} + {F480F61D-4950-4603-9F6F-F95ECC64A31C} = {F480F61D-4950-4603-9F6F-F95ECC64A31C} + EndProjectSection +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fsapfs_test_support", "fsapfs_test_support\fsapfs_test_support.vcproj", "{D69E0261-FD4E-4E82-BC60-67E67C9DD8F7}" ProjectSection(ProjectDependencies) = postProject {ABB04F9A-768A-4F12-9751-65A0E2F81229} = {ABB04F9A-768A-4F12-9751-65A0E2F81229} @@ -553,6 +567,10 @@ {54670300-9762-426C-9A05-EE0028AD8081}.Release|Win32.Build.0 = Release|Win32 {54670300-9762-426C-9A05-EE0028AD8081}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 {54670300-9762-426C-9A05-EE0028AD8081}.VSDebug|Win32.Build.0 = VSDebug|Win32 + {69BD1901-531F-449B-B57C-A72A046CEB96}.Release|Win32.ActiveCfg = Release|Win32 + {69BD1901-531F-449B-B57C-A72A046CEB96}.Release|Win32.Build.0 = Release|Win32 + {69BD1901-531F-449B-B57C-A72A046CEB96}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 + {69BD1901-531F-449B-B57C-A72A046CEB96}.VSDebug|Win32.Build.0 = VSDebug|Win32 {0759FC1E-239B-4AA8-90E0-3DD006550AFE}.Release|Win32.ActiveCfg = Release|Win32 {0759FC1E-239B-4AA8-90E0-3DD006550AFE}.Release|Win32.Build.0 = Release|Win32 {0759FC1E-239B-4AA8-90E0-3DD006550AFE}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 @@ -577,10 +595,6 @@ {B8C75A64-9CE8-4CCF-B6B8-F7DA658AB6E2}.Release|Win32.Build.0 = Release|Win32 {B8C75A64-9CE8-4CCF-B6B8-F7DA658AB6E2}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 {B8C75A64-9CE8-4CCF-B6B8-F7DA658AB6E2}.VSDebug|Win32.Build.0 = VSDebug|Win32 - {B9AB3EF5-2424-428E-A57F-D256D4170487}.Release|Win32.ActiveCfg = Release|Win32 - {B9AB3EF5-2424-428E-A57F-D256D4170487}.Release|Win32.Build.0 = Release|Win32 - {B9AB3EF5-2424-428E-A57F-D256D4170487}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 - {B9AB3EF5-2424-428E-A57F-D256D4170487}.VSDebug|Win32.Build.0 = VSDebug|Win32 {301E1DCF-F551-40A4-9D0D-E07D48322C15}.Release|Win32.ActiveCfg = Release|Win32 {301E1DCF-F551-40A4-9D0D-E07D48322C15}.Release|Win32.Build.0 = Release|Win32 {301E1DCF-F551-40A4-9D0D-E07D48322C15}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 @@ -657,6 +671,10 @@ {98CA92D4-AF28-40CE-A177-29BFA4B75677}.Release|Win32.Build.0 = Release|Win32 {98CA92D4-AF28-40CE-A177-29BFA4B75677}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 {98CA92D4-AF28-40CE-A177-29BFA4B75677}.VSDebug|Win32.Build.0 = VSDebug|Win32 + {E732C23E-8642-4EFA-A580-1E9D8E6DE090}.Release|Win32.ActiveCfg = Release|Win32 + {E732C23E-8642-4EFA-A580-1E9D8E6DE090}.Release|Win32.Build.0 = Release|Win32 + {E732C23E-8642-4EFA-A580-1E9D8E6DE090}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 + {E732C23E-8642-4EFA-A580-1E9D8E6DE090}.VSDebug|Win32.Build.0 = VSDebug|Win32 {D69E0261-FD4E-4E82-BC60-67E67C9DD8F7}.Release|Win32.ActiveCfg = Release|Win32 {D69E0261-FD4E-4E82-BC60-67E67C9DD8F7}.Release|Win32.Build.0 = Release|Win32 {D69E0261-FD4E-4E82-BC60-67E67C9DD8F7}.VSDebug|Win32.ActiveCfg = VSDebug|Win32 diff -Nru libfsapfs-20181215/msvscpp/Makefile.am libfsapfs-20190210/msvscpp/Makefile.am --- libfsapfs-20181215/msvscpp/Makefile.am 2018-12-03 17:51:41.000000000 +0000 +++ libfsapfs-20190210/msvscpp/Makefile.am 2019-02-06 20:29:46.000000000 +0000 @@ -7,13 +7,13 @@ fsapfs_test_checkpoint_map/fsapfs_test_checkpoint_map.vcproj \ fsapfs_test_checkpoint_map_entry/fsapfs_test_checkpoint_map_entry.vcproj \ fsapfs_test_checksum/fsapfs_test_checksum.vcproj \ + fsapfs_test_chunk_information_block/fsapfs_test_chunk_information_block.vcproj \ fsapfs_test_compressed_data_handle/fsapfs_test_compressed_data_handle.vcproj \ fsapfs_test_compression/fsapfs_test_compression.vcproj \ fsapfs_test_container/fsapfs_test_container.vcproj \ fsapfs_test_container_data_handle/fsapfs_test_container_data_handle.vcproj \ fsapfs_test_container_key_bag/fsapfs_test_container_key_bag.vcproj \ fsapfs_test_container_reaper/fsapfs_test_container_reaper.vcproj \ - fsapfs_test_container_space_manager/fsapfs_test_container_space_manager.vcproj \ fsapfs_test_container_superblock/fsapfs_test_container_superblock.vcproj \ fsapfs_test_data_block/fsapfs_test_data_block.vcproj \ fsapfs_test_directory_record/fsapfs_test_directory_record.vcproj \ @@ -33,6 +33,7 @@ fsapfs_test_object_map/fsapfs_test_object_map.vcproj \ fsapfs_test_object_map_btree/fsapfs_test_object_map_btree.vcproj \ fsapfs_test_object_map_descriptor/fsapfs_test_object_map_descriptor.vcproj \ + fsapfs_test_space_manager/fsapfs_test_space_manager.vcproj \ fsapfs_test_support/fsapfs_test_support.vcproj \ fsapfs_test_volume/fsapfs_test_volume.vcproj \ fsapfs_test_volume_key_bag/fsapfs_test_volume_key_bag.vcproj \ diff -Nru libfsapfs-20181215/msvscpp/Makefile.in libfsapfs-20190210/msvscpp/Makefile.in --- libfsapfs-20181215/msvscpp/Makefile.in 2018-12-15 06:44:02.000000000 +0000 +++ libfsapfs-20190210/msvscpp/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -516,13 +516,13 @@ fsapfs_test_checkpoint_map/fsapfs_test_checkpoint_map.vcproj \ fsapfs_test_checkpoint_map_entry/fsapfs_test_checkpoint_map_entry.vcproj \ fsapfs_test_checksum/fsapfs_test_checksum.vcproj \ + fsapfs_test_chunk_information_block/fsapfs_test_chunk_information_block.vcproj \ fsapfs_test_compressed_data_handle/fsapfs_test_compressed_data_handle.vcproj \ fsapfs_test_compression/fsapfs_test_compression.vcproj \ fsapfs_test_container/fsapfs_test_container.vcproj \ fsapfs_test_container_data_handle/fsapfs_test_container_data_handle.vcproj \ fsapfs_test_container_key_bag/fsapfs_test_container_key_bag.vcproj \ fsapfs_test_container_reaper/fsapfs_test_container_reaper.vcproj \ - fsapfs_test_container_space_manager/fsapfs_test_container_space_manager.vcproj \ fsapfs_test_container_superblock/fsapfs_test_container_superblock.vcproj \ fsapfs_test_data_block/fsapfs_test_data_block.vcproj \ fsapfs_test_directory_record/fsapfs_test_directory_record.vcproj \ @@ -542,6 +542,7 @@ fsapfs_test_object_map/fsapfs_test_object_map.vcproj \ fsapfs_test_object_map_btree/fsapfs_test_object_map_btree.vcproj \ fsapfs_test_object_map_descriptor/fsapfs_test_object_map_descriptor.vcproj \ + fsapfs_test_space_manager/fsapfs_test_space_manager.vcproj \ fsapfs_test_support/fsapfs_test_support.vcproj \ fsapfs_test_volume/fsapfs_test_volume.vcproj \ fsapfs_test_volume_key_bag/fsapfs_test_volume_key_bag.vcproj \ diff -Nru libfsapfs-20181215/msvscpp/pyfsapfs/pyfsapfs.vcproj libfsapfs-20190210/msvscpp/pyfsapfs/pyfsapfs.vcproj --- libfsapfs-20181215/msvscpp/pyfsapfs/pyfsapfs.vcproj 2018-12-03 17:50:34.000000000 +0000 +++ libfsapfs-20190210/msvscpp/pyfsapfs/pyfsapfs.vcproj 2019-02-06 20:29:46.000000000 +0000 @@ -186,6 +186,14 @@ > + + + + @@ -236,6 +244,14 @@ > + + + + diff -Nru libfsapfs-20181215/pyfsapfs/Makefile.am libfsapfs-20190210/pyfsapfs/Makefile.am --- libfsapfs-20181215/pyfsapfs/Makefile.am 2018-09-30 13:07:09.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/Makefile.am 2019-02-06 20:27:17.000000000 +0000 @@ -20,6 +20,8 @@ pyfsapfs_container.c pyfsapfs_container.h \ pyfsapfs_datetime.c pyfsapfs_datetime.h \ pyfsapfs_error.c pyfsapfs_error.h \ + pyfsapfs_extended_attribute.c pyfsapfs_extended_attribute.h \ + pyfsapfs_extended_attributes.c pyfsapfs_extended_attributes.h \ pyfsapfs_file_entries.c pyfsapfs_file_entries.h \ pyfsapfs_file_entry.c pyfsapfs_file_entry.h \ pyfsapfs_file_object_io_handle.c pyfsapfs_file_object_io_handle.h \ diff -Nru libfsapfs-20181215/pyfsapfs/Makefile.in libfsapfs-20190210/pyfsapfs/Makefile.in --- libfsapfs-20181215/pyfsapfs/Makefile.in 2018-12-15 06:44:02.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -152,6 +152,8 @@ am__pyfsapfs_la_SOURCES_DIST = pyfsapfs.c pyfsapfs.h \ pyfsapfs_container.c pyfsapfs_container.h pyfsapfs_datetime.c \ pyfsapfs_datetime.h pyfsapfs_error.c pyfsapfs_error.h \ + pyfsapfs_extended_attribute.c pyfsapfs_extended_attribute.h \ + pyfsapfs_extended_attributes.c pyfsapfs_extended_attributes.h \ pyfsapfs_file_entries.c pyfsapfs_file_entries.h \ pyfsapfs_file_entry.c pyfsapfs_file_entry.h \ pyfsapfs_file_object_io_handle.c \ @@ -165,6 +167,8 @@ @HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_container.lo \ @HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_datetime.lo \ @HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_error.lo \ +@HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_extended_attribute.lo \ +@HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_extended_attributes.lo \ @HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_file_entries.lo \ @HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_file_entry.lo \ @HAVE_PYTHON_TRUE@ pyfsapfs_la-pyfsapfs_file_object_io_handle.lo \ @@ -200,6 +204,8 @@ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo \ + ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo \ + ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo \ @@ -642,6 +648,8 @@ @HAVE_PYTHON_TRUE@ pyfsapfs_container.c pyfsapfs_container.h \ @HAVE_PYTHON_TRUE@ pyfsapfs_datetime.c pyfsapfs_datetime.h \ @HAVE_PYTHON_TRUE@ pyfsapfs_error.c pyfsapfs_error.h \ +@HAVE_PYTHON_TRUE@ pyfsapfs_extended_attribute.c pyfsapfs_extended_attribute.h \ +@HAVE_PYTHON_TRUE@ pyfsapfs_extended_attributes.c pyfsapfs_extended_attributes.h \ @HAVE_PYTHON_TRUE@ pyfsapfs_file_entries.c pyfsapfs_file_entries.h \ @HAVE_PYTHON_TRUE@ pyfsapfs_file_entry.c pyfsapfs_file_entry.h \ @HAVE_PYTHON_TRUE@ pyfsapfs_file_object_io_handle.c pyfsapfs_file_object_io_handle.h \ @@ -756,6 +764,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo@am__quote@ # am--include-marker @@ -819,6 +829,20 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_error.lo `test -f 'pyfsapfs_error.c' || echo '$(srcdir)/'`pyfsapfs_error.c +pyfsapfs_la-pyfsapfs_extended_attribute.lo: pyfsapfs_extended_attribute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_extended_attribute.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Tpo -c -o pyfsapfs_la-pyfsapfs_extended_attribute.lo `test -f 'pyfsapfs_extended_attribute.c' || echo '$(srcdir)/'`pyfsapfs_extended_attribute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyfsapfs_extended_attribute.c' object='pyfsapfs_la-pyfsapfs_extended_attribute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_extended_attribute.lo `test -f 'pyfsapfs_extended_attribute.c' || echo '$(srcdir)/'`pyfsapfs_extended_attribute.c + +pyfsapfs_la-pyfsapfs_extended_attributes.lo: pyfsapfs_extended_attributes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_extended_attributes.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Tpo -c -o pyfsapfs_la-pyfsapfs_extended_attributes.lo `test -f 'pyfsapfs_extended_attributes.c' || echo '$(srcdir)/'`pyfsapfs_extended_attributes.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyfsapfs_extended_attributes.c' object='pyfsapfs_la-pyfsapfs_extended_attributes.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_extended_attributes.lo `test -f 'pyfsapfs_extended_attributes.c' || echo '$(srcdir)/'`pyfsapfs_extended_attributes.c + pyfsapfs_la-pyfsapfs_file_entries.lo: pyfsapfs_file_entries.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_file_entries.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Tpo -c -o pyfsapfs_la-pyfsapfs_file_entries.lo `test -f 'pyfsapfs_file_entries.c' || echo '$(srcdir)/'`pyfsapfs_file_entries.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo @@ -1050,6 +1074,8 @@ -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo + -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo + -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs.c libfsapfs-20190210/pyfsapfs/pyfsapfs.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs.c 2019-02-06 20:17:41.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python bindings module for libfsapfs (pyfsapfs) * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -30,6 +30,8 @@ #include "pyfsapfs.h" #include "pyfsapfs_container.h" #include "pyfsapfs_error.h" +#include "pyfsapfs_extended_attribute.h" +#include "pyfsapfs_extended_attributes.h" #include "pyfsapfs_file_entries.h" #include "pyfsapfs_file_entry.h" #include "pyfsapfs_file_object_io_handle.h" @@ -556,6 +558,41 @@ "container", (PyObject *) &pyfsapfs_container_type_object ); + /* Setup the extended_attribute type object + */ + pyfsapfs_extended_attribute_type_object.tp_new = PyType_GenericNew; + + if( PyType_Ready( + &pyfsapfs_extended_attribute_type_object ) < 0 ) + { + goto on_error; + } + Py_IncRef( + (PyObject *) &pyfsapfs_extended_attribute_type_object ); + + PyModule_AddObject( + module, + "extended_attribute", + (PyObject *) &pyfsapfs_extended_attribute_type_object ); + + /* Setup the extended_attributes type object + */ + pyfsapfs_extended_attributes_type_object.tp_new = PyType_GenericNew; + + if( PyType_Ready( + &pyfsapfs_extended_attributes_type_object ) < 0 ) + { + goto on_error; + } + Py_IncRef( + (PyObject *) &pyfsapfs_extended_attributes_type_object ); + + PyModule_AddObject( + module, + "extended_attributes", + (PyObject *) &pyfsapfs_extended_attributes_type_object ); + + /* Setup the file_entries type object */ pyfsapfs_file_entries_type_object.tp_new = PyType_GenericNew; diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_container.c libfsapfs-20190210/pyfsapfs/pyfsapfs_container.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_container.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_container.c 2019-02-06 20:15:52.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object wrapper of libfsapfs_container_t * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_container.h libfsapfs-20190210/pyfsapfs/pyfsapfs_container.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_container.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_container.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object wrapper of libfsapfs_container_t * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_datetime.c libfsapfs-20190210/pyfsapfs/pyfsapfs_datetime.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_datetime.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_datetime.c 2019-02-06 20:15:42.000000000 +0000 @@ -1,7 +1,7 @@ /* * Date and time functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_datetime.h libfsapfs-20190210/pyfsapfs/pyfsapfs_datetime.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_datetime.h 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_datetime.h 2019-02-06 20:15:42.000000000 +0000 @@ -1,7 +1,7 @@ /* * Date and time functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_error.c libfsapfs-20190210/pyfsapfs/pyfsapfs_error.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_error.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_error.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_error.h libfsapfs-20190210/pyfsapfs/pyfsapfs_error.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_error.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_error.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Error functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attribute.c libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attribute.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attribute.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attribute.c 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,1160 @@ +/* + * Python object wrapper of libfsapfs_extended_attribute_t + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include + +#if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI ) +#include +#endif + +#include "pyfsapfs_error.h" +#include "pyfsapfs_extended_attribute.h" +#include "pyfsapfs_integer.h" +#include "pyfsapfs_libcerror.h" +#include "pyfsapfs_libfsapfs.h" +#include "pyfsapfs_python.h" +#include "pyfsapfs_unused.h" + +PyMethodDef pyfsapfs_extended_attribute_object_methods[] = { + + { "get_identifier", + (PyCFunction) pyfsapfs_extended_attribute_get_identifier, + METH_NOARGS, + "get_identifier() -> Integer\n" + "\n" + "Retrieves the identifier." }, + + { "get_name", + (PyCFunction) pyfsapfs_extended_attribute_get_name, + METH_NOARGS, + "get_name() -> Unicode string\n" + "\n" + "Retrieves the name." }, + + { "read_buffer", + (PyCFunction) pyfsapfs_extended_attribute_read_buffer, + METH_VARARGS | METH_KEYWORDS, + "read_buffer(size) -> Binary string\n" + "\n" + "Reads a buffer of data." }, + + { "read_buffer_at_offset", + (PyCFunction) pyfsapfs_extended_attribute_read_buffer_at_offset, + METH_VARARGS | METH_KEYWORDS, + "read_buffer_at_offset(size, offset) -> Binary string\n" + "\n" + "Reads a buffer of data at a specific offset." }, + + { "seek_offset", + (PyCFunction) pyfsapfs_extended_attribute_seek_offset, + METH_VARARGS | METH_KEYWORDS, + "seek_offset(offset, whence) -> None\n" + "\n" + "Seeks an offset within the data." }, + + { "get_offset", + (PyCFunction) pyfsapfs_extended_attribute_get_offset, + METH_NOARGS, + "get_offset() -> Integer\n" + "\n" + "Retrieves the current offset within the data." }, + + { "read", + (PyCFunction) pyfsapfs_extended_attribute_read_buffer, + METH_VARARGS | METH_KEYWORDS, + "read(size) -> Binary string\n" + "\n" + "Reads a buffer of data." }, + + { "seek", + (PyCFunction) pyfsapfs_extended_attribute_seek_offset, + METH_VARARGS | METH_KEYWORDS, + "seek(offset, whence) -> None\n" + "\n" + "Seeks an offset within the data." }, + + { "tell", + (PyCFunction) pyfsapfs_extended_attribute_get_offset, + METH_NOARGS, + "tell() -> Integer\n" + "\n" + "Retrieves the current offset within the data." }, + + { "get_size", + (PyCFunction) pyfsapfs_extended_attribute_get_size, + METH_NOARGS, + "get_size() -> Integer\n" + "\n" + "Retrieves the size of the data stream object." }, + + /* Sentinel */ + { NULL, NULL, 0, NULL } +}; + +PyGetSetDef pyfsapfs_extended_attribute_object_get_set_definitions[] = { + + { "identifier", + (getter) pyfsapfs_extended_attribute_get_identifier, + (setter) 0, + "The identifier.", + NULL }, + + { "name", + (getter) pyfsapfs_extended_attribute_get_name, + (setter) 0, + "The name.", + NULL }, + + { "size", + (getter) pyfsapfs_extended_attribute_get_size, + (setter) 0, + "The size of the data stream object.", + NULL }, + + /* Sentinel */ + { NULL, NULL, NULL, NULL, NULL } +}; + +PyTypeObject pyfsapfs_extended_attribute_type_object = { + PyVarObject_HEAD_INIT( NULL, 0 ) + + /* tp_name */ + "pyfsapfs.extended_attribute", + /* tp_basicsize */ + sizeof( pyfsapfs_extended_attribute_t ), + /* tp_itemsize */ + 0, + /* tp_dealloc */ + (destructor) pyfsapfs_extended_attribute_free, + /* tp_print */ + 0, + /* tp_getattr */ + 0, + /* tp_setattr */ + 0, + /* tp_compare */ + 0, + /* tp_repr */ + 0, + /* tp_as_number */ + 0, + /* tp_as_sequence */ + 0, + /* tp_as_mapping */ + 0, + /* tp_hash */ + 0, + /* tp_call */ + 0, + /* tp_str */ + 0, + /* tp_getattro */ + 0, + /* tp_setattro */ + 0, + /* tp_as_buffer */ + 0, + /* tp_flags */ + Py_TPFLAGS_DEFAULT, + /* tp_doc */ + "pyfsapfs extended attribute object (wraps libfsapfs_extended_attribute_t)", + /* tp_traverse */ + 0, + /* tp_clear */ + 0, + /* tp_richcompare */ + 0, + /* tp_weaklistoffset */ + 0, + /* tp_iter */ + 0, + /* tp_iternext */ + 0, + /* tp_methods */ + pyfsapfs_extended_attribute_object_methods, + /* tp_members */ + 0, + /* tp_getset */ + pyfsapfs_extended_attribute_object_get_set_definitions, + /* tp_base */ + 0, + /* tp_dict */ + 0, + /* tp_descr_get */ + 0, + /* tp_descr_set */ + 0, + /* tp_dictoffset */ + 0, + /* tp_init */ + (initproc) pyfsapfs_extended_attribute_init, + /* tp_alloc */ + 0, + /* tp_new */ + 0, + /* tp_free */ + 0, + /* tp_is_gc */ + 0, + /* tp_bases */ + NULL, + /* tp_mro */ + NULL, + /* tp_cache */ + NULL, + /* tp_subclasses */ + NULL, + /* tp_weaklist */ + NULL, + /* tp_del */ + 0 +}; + +/* Creates a new extended attribute object + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_new( + libfsapfs_extended_attribute_t *extended_attribute, + PyObject *parent_object ) +{ + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute = NULL; + static char *function = "pyfsapfs_extended_attribute_new"; + + if( extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + /* PyObject_New does not invoke tp_init + */ + pyfsapfs_extended_attribute = PyObject_New( + struct pyfsapfs_extended_attribute, + &pyfsapfs_extended_attribute_type_object ); + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to initialize extended attribute.", + function ); + + goto on_error; + } + pyfsapfs_extended_attribute->extended_attribute = extended_attribute; + pyfsapfs_extended_attribute->parent_object = parent_object; + + if( pyfsapfs_extended_attribute->parent_object != NULL ) + { + Py_IncRef( + pyfsapfs_extended_attribute->parent_object ); + } + return( (PyObject *) pyfsapfs_extended_attribute ); + +on_error: + if( pyfsapfs_extended_attribute != NULL ) + { + Py_DecRef( + (PyObject *) pyfsapfs_extended_attribute ); + } + return( NULL ); +} + +/* Intializes an extended attribute object + * Returns 0 if successful or -1 on error + */ +int pyfsapfs_extended_attribute_init( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute ) +{ + static char *function = "pyfsapfs_extended_attribute_init"; + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( -1 ); + } + /* Make sure libfsapfs extended attribute is set to NULL + */ + pyfsapfs_extended_attribute->extended_attribute = NULL; + + PyErr_Format( + PyExc_NotImplementedError, + "%s: initialize of extended attribute not supported.", + function ); + + return( -1 ); +} + +/* Frees an extended attribute object + */ +void pyfsapfs_extended_attribute_free( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute ) +{ + struct _typeobject *ob_type = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfsapfs_extended_attribute_free"; + int result = 0; + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return; + } + ob_type = Py_TYPE( + pyfsapfs_extended_attribute ); + + if( ob_type == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: missing ob_type.", + function ); + + return; + } + if( ob_type->tp_free == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid ob_type - missing tp_free.", + function ); + + return; + } + if( pyfsapfs_extended_attribute->extended_attribute != NULL ) + { + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_extended_attribute_free( + &( pyfsapfs_extended_attribute->extended_attribute ), + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_MemoryError, + "%s: unable to free libfsapfs extended attribute.", + function ); + + libcerror_error_free( + &error ); + } + } + if( pyfsapfs_extended_attribute->parent_object != NULL ) + { + Py_DecRef( + pyfsapfs_extended_attribute->parent_object ); + } + ob_type->tp_free( + (PyObject*) pyfsapfs_extended_attribute ); +} + +/* Retrieves the + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_get_identifier( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments PYFSAPFS_ATTRIBUTE_UNUSED ) +{ + PyObject *integer_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfsapfs_extended_attribute_get_identifier"; + uint64_t value_64bit = 0; + int result = 0; + + PYFSAPFS_UNREFERENCED_PARAMETER( arguments ) + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_extended_attribute_get_identifier( + pyfsapfs_extended_attribute->extended_attribute, + &value_64bit, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve .", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + integer_object = pyfsapfs_integer_unsigned_new_from_64bit( + (uint64_t) value_64bit ); + + return( integer_object ); +} + +/* Retrieves the + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_get_name( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments PYFSAPFS_ATTRIBUTE_UNUSED ) +{ + PyObject *string_object = NULL; + libcerror_error_t *error = NULL; + const char *errors = NULL; + static char *function = "pyfsapfs_extended_attribute_get_name"; + char *utf8_string = NULL; + size_t utf8_string_size = 0; + int result = 0; + + PYFSAPFS_UNREFERENCED_PARAMETER( arguments ) + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_extended_attribute_get_utf8_name_size( + pyfsapfs_extended_attribute->extended_attribute, + &utf8_string_size, + &error ); + + Py_END_ALLOW_THREADS + + if( result == -1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to determine size of as UTF-8 string.", + function ); + + libcerror_error_free( + &error ); + + goto on_error; + } + else if( ( result == 0 ) + || ( utf8_string_size == 0 ) ) + { + Py_IncRef( + Py_None ); + + return( Py_None ); + } + utf8_string = (char *) PyMem_Malloc( + sizeof( char ) * utf8_string_size ); + + if( utf8_string == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to create UTF-8 string.", + function ); + + goto on_error; + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_extended_attribute_get_utf8_name( + pyfsapfs_extended_attribute->extended_attribute, + (uint8_t *) utf8_string, + utf8_string_size, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve as UTF-8 string.", + function ); + + libcerror_error_free( + &error ); + + goto on_error; + } + /* Pass the string length to PyUnicode_DecodeUTF8 otherwise it makes + * the end of string character is part of the string. + */ + string_object = PyUnicode_DecodeUTF8( + utf8_string, + (Py_ssize_t) utf8_string_size - 1, + errors ); + + if( string_object == NULL ) + { + PyErr_Format( + PyExc_IOError, + "%s: unable to convert UTF-8 string into Unicode object.", + function ); + + goto on_error; + } + PyMem_Free( + utf8_string ); + + return( string_object ); + +on_error: + if( utf8_string != NULL ) + { + PyMem_Free( + utf8_string ); + } + return( NULL ); +} + +/* Reads data at the current offset into a buffer + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_read_buffer( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments, + PyObject *keywords ) +{ + PyObject *integer_object = NULL; + PyObject *string_object = NULL; + libcerror_error_t *error = NULL; + char *buffer = NULL; + static char *function = "pyfsapfs_extended_attribute_read_buffer"; + static char *keyword_list[] = { "size", NULL }; + ssize_t read_count = 0; + int64_t read_size = 0; + int result = 0; + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + if( PyArg_ParseTupleAndKeywords( + arguments, + keywords, + "|O", + keyword_list, + &integer_object ) == 0 ) + { + return( NULL ); + } + if( integer_object == NULL ) + { + result = 0; + } + else + { + result = PyObject_IsInstance( + integer_object, + (PyObject *) &PyLong_Type ); + + if( result == -1 ) + { + pyfsapfs_error_fetch_and_raise( + PyExc_RuntimeError, + "%s: unable to determine if integer object is of type long.", + function ); + + return( NULL ); + } +#if PY_MAJOR_VERSION < 3 + else if( result == 0 ) + { + PyErr_Clear(); + + result = PyObject_IsInstance( + integer_object, + (PyObject *) &PyInt_Type ); + + if( result == -1 ) + { + pyfsapfs_error_fetch_and_raise( + PyExc_RuntimeError, + "%s: unable to determine if integer object is of type int.", + function ); + + return( NULL ); + } + } +#endif + } + if( result != 0 ) + { + if( pyfsapfs_integer_signed_copy_to_64bit( + integer_object, + &read_size, + &error ) != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to convert integer object into read size.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + } + else if( ( integer_object == NULL ) + || ( integer_object == Py_None ) ) + { + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_extended_attribute_get_size( + pyfsapfs_extended_attribute->extended_attribute, + (size64_t *) &read_size, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve size.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + } + else + { + PyErr_Format( + PyExc_TypeError, + "%s: unsupported integer object type.", + function ); + + return( NULL ); + } + if( read_size == 0 ) + { +#if PY_MAJOR_VERSION >= 3 + string_object = PyBytes_FromString( + "" ); +#else + string_object = PyString_FromString( + "" ); +#endif + return( string_object ); + } + if( read_size < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid read size value less than zero.", + function ); + + return( NULL ); + } + /* Make sure the data fits into a memory buffer + */ + if( ( read_size > (int64_t) INT_MAX ) + || ( read_size > (int64_t) SSIZE_MAX ) ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid argument read size value exceeds maximum.", + function ); + + return( NULL ); + } +#if PY_MAJOR_VERSION >= 3 + string_object = PyBytes_FromStringAndSize( + NULL, + (Py_ssize_t) read_size ); + + buffer = PyBytes_AsString( + string_object ); +#else + /* Note that a size of 0 is not supported + */ + string_object = PyString_FromStringAndSize( + NULL, + (Py_ssize_t) read_size ); + + buffer = PyString_AsString( + string_object ); +#endif + Py_BEGIN_ALLOW_THREADS + + read_count = libfsapfs_extended_attribute_read_buffer( + pyfsapfs_extended_attribute->extended_attribute, + (uint8_t *) buffer, + (size_t) read_size, + &error ); + + Py_END_ALLOW_THREADS + + if( read_count == -1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to read data.", + function ); + + libcerror_error_free( + &error ); + + Py_DecRef( + (PyObject *) string_object ); + + return( NULL ); + } + /* Need to resize the string here in case read_size was not fully read. + */ +#if PY_MAJOR_VERSION >= 3 + if( _PyBytes_Resize( + &string_object, + (Py_ssize_t) read_count ) != 0 ) +#else + if( _PyString_Resize( + &string_object, + (Py_ssize_t) read_count ) != 0 ) +#endif + { + Py_DecRef( + (PyObject *) string_object ); + + return( NULL ); + } + return( string_object ); +} + +/* Reads data at a specific offset into a buffer + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_read_buffer_at_offset( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments, + PyObject *keywords ) +{ + PyObject *integer_object = NULL; + PyObject *string_object = NULL; + libcerror_error_t *error = NULL; + char *buffer = NULL; + static char *function = "pyfsapfs_extended_attribute_read_buffer_at_offset"; + static char *keyword_list[] = { "size", "offset", NULL }; + ssize_t read_count = 0; + off64_t read_offset = 0; + int64_t read_size = 0; + int result = 0; + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + if( PyArg_ParseTupleAndKeywords( + arguments, + keywords, + "OL", + keyword_list, + &integer_object, + &read_offset ) == 0 ) + { + return( NULL ); + } + result = PyObject_IsInstance( + integer_object, + (PyObject *) &PyLong_Type ); + + if( result == -1 ) + { + pyfsapfs_error_fetch_and_raise( + PyExc_RuntimeError, + "%s: unable to determine if integer object is of type long.", + function ); + + return( NULL ); + } +#if PY_MAJOR_VERSION < 3 + else if( result == 0 ) + { + PyErr_Clear(); + + result = PyObject_IsInstance( + integer_object, + (PyObject *) &PyInt_Type ); + + if( result == -1 ) + { + pyfsapfs_error_fetch_and_raise( + PyExc_RuntimeError, + "%s: unable to determine if integer object is of type int.", + function ); + + return( NULL ); + } + } +#endif + if( result != 0 ) + { + if( pyfsapfs_integer_signed_copy_to_64bit( + integer_object, + &read_size, + &error ) != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to convert integer object into read size.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + } + else + { + PyErr_Format( + PyExc_TypeError, + "%s: unsupported integer object type.", + function ); + + return( NULL ); + } + if( read_size == 0 ) + { +#if PY_MAJOR_VERSION >= 3 + string_object = PyBytes_FromString( + "" ); +#else + string_object = PyString_FromString( + "" ); +#endif + return( string_object ); + } + if( read_size < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid read size value less than zero.", + function ); + + return( NULL ); + } + /* Make sure the data fits into a memory buffer + */ + if( ( read_size > (int64_t) INT_MAX ) + || ( read_size > (int64_t) SSIZE_MAX ) ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid argument read size value exceeds maximum.", + function ); + + return( NULL ); + } + if( read_offset < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid read offset value less than zero.", + function ); + + return( NULL ); + } +#if PY_MAJOR_VERSION >= 3 + string_object = PyBytes_FromStringAndSize( + NULL, + (Py_ssize_t) read_size ); + + buffer = PyBytes_AsString( + string_object ); +#else + /* Note that a size of 0 is not supported + */ + string_object = PyString_FromStringAndSize( + NULL, + (Py_ssize_t) read_size ); + + buffer = PyString_AsString( + string_object ); +#endif + Py_BEGIN_ALLOW_THREADS + + read_count = libfsapfs_extended_attribute_read_buffer_at_offset( + pyfsapfs_extended_attribute->extended_attribute, + (uint8_t *) buffer, + (size_t) read_size, + (off64_t) read_offset, + &error ); + + Py_END_ALLOW_THREADS + + if( read_count == -1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to read data.", + function ); + + libcerror_error_free( + &error ); + + Py_DecRef( + (PyObject *) string_object ); + + return( NULL ); + } + /* Need to resize the string here in case read_size was not fully read. + */ +#if PY_MAJOR_VERSION >= 3 + if( _PyBytes_Resize( + &string_object, + (Py_ssize_t) read_count ) != 0 ) +#else + if( _PyString_Resize( + &string_object, + (Py_ssize_t) read_count ) != 0 ) +#endif + { + Py_DecRef( + (PyObject *) string_object ); + + return( NULL ); + } + return( string_object ); +} + +/* Seeks a certain offset + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_seek_offset( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments, + PyObject *keywords ) +{ + libcerror_error_t *error = NULL; + static char *function = "pyfsapfs_extended_attribute_seek_offset"; + static char *keyword_list[] = { "offset", "whence", NULL }; + off64_t offset = 0; + int whence = 0; + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + if( PyArg_ParseTupleAndKeywords( + arguments, + keywords, + "L|i", + keyword_list, + &offset, + &whence ) == 0 ) + { + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + offset = libfsapfs_extended_attribute_seek_offset( + pyfsapfs_extended_attribute->extended_attribute, + offset, + whence, + &error ); + + Py_END_ALLOW_THREADS + + if( offset == -1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to seek offset.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + Py_IncRef( + Py_None ); + + return( Py_None ); +} + +/* Retrieves the current offset + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_get_offset( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments PYFSAPFS_ATTRIBUTE_UNUSED ) +{ + PyObject *integer_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfsapfs_extended_attribute_get_offset"; + off64_t offset = 0; + int result = 0; + + PYFSAPFS_UNREFERENCED_PARAMETER( arguments ) + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_extended_attribute_get_offset( + pyfsapfs_extended_attribute->extended_attribute, + &offset, + &error ); + + Py_END_ALLOW_THREADS + + if( result == -1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve current offset.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + else if( result == 0 ) + { + Py_IncRef( + Py_None ); + + return( Py_None ); + } + integer_object = pyfsapfs_integer_signed_new_from_64bit( + (int64_t) offset ); + + return( integer_object ); +} + +/* Retrieves the size of the data stream object + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attribute_get_size( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments PYFSAPFS_ATTRIBUTE_UNUSED ) +{ + PyObject *integer_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfsapfs_extended_attribute_get_size"; + size64_t size = 0; + int result = 0; + + PYFSAPFS_UNREFERENCED_PARAMETER( arguments ) + + if( pyfsapfs_extended_attribute == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid extended attribute.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_extended_attribute_get_size( + pyfsapfs_extended_attribute->extended_attribute, + &size, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: failed to retrieve size of the data stream object.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + integer_object = pyfsapfs_integer_unsigned_new_from_64bit( + (uint64_t) size ); + + return( integer_object ); +} + diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attribute.h libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attribute.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attribute.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attribute.h 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,101 @@ +/* + * Python object wrapper of libfsapfs_extended_attribute_t + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _PYFSAPFS_EXTENDED_ATTRIBUTE_H ) +#define _PYFSAPFS_EXTENDED_ATTRIBUTE_H + +#include +#include + +#include "pyfsapfs_libfsapfs.h" +#include "pyfsapfs_python.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct pyfsapfs_extended_attribute pyfsapfs_extended_attribute_t; + +struct pyfsapfs_extended_attribute +{ + /* Python object initialization + */ + PyObject_HEAD + + /* The libfsapfs extended attribute + */ + libfsapfs_extended_attribute_t *extended_attribute; + + /* The parent object + */ + PyObject *parent_object; +}; + +extern PyMethodDef pyfsapfs_extended_attribute_object_methods[]; +extern PyTypeObject pyfsapfs_extended_attribute_type_object; + +PyObject *pyfsapfs_extended_attribute_new( + libfsapfs_extended_attribute_t *extended_attribute, + PyObject *parent_object ); + +int pyfsapfs_extended_attribute_init( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute ); + +void pyfsapfs_extended_attribute_free( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute ); + +PyObject *pyfsapfs_extended_attribute_get_identifier( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments ); + +PyObject *pyfsapfs_extended_attribute_get_name( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments ); + +PyObject *pyfsapfs_extended_attribute_read_buffer( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments, + PyObject *keywords ); + +PyObject *pyfsapfs_extended_attribute_read_buffer_at_offset( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments, + PyObject *keywords ); + +PyObject *pyfsapfs_extended_attribute_seek_offset( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments, + PyObject *keywords ); + +PyObject *pyfsapfs_extended_attribute_get_offset( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments ); + +PyObject *pyfsapfs_extended_attribute_get_size( + pyfsapfs_extended_attribute_t *pyfsapfs_extended_attribute, + PyObject *arguments ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _PYFSAPFS_EXTENDED_ATTRIBUTE_H ) */ + diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attributes.c libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attributes.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attributes.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attributes.c 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,452 @@ +/* + * Python object definition of the sequence and iterator object of extended attributes + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include + +#if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI ) +#include +#endif + +#include "pyfsapfs_extended_attribute.h" +#include "pyfsapfs_extended_attributes.h" +#include "pyfsapfs_libcerror.h" +#include "pyfsapfs_libfsapfs.h" +#include "pyfsapfs_python.h" + +PySequenceMethods pyfsapfs_extended_attributes_sequence_methods = { + /* sq_length */ + (lenfunc) pyfsapfs_extended_attributes_len, + /* sq_concat */ + 0, + /* sq_repeat */ + 0, + /* sq_item */ + (ssizeargfunc) pyfsapfs_extended_attributes_getitem, + /* sq_slice */ + 0, + /* sq_ass_item */ + 0, + /* sq_ass_slice */ + 0, + /* sq_contains */ + 0, + /* sq_inplace_concat */ + 0, + /* sq_inplace_repeat */ + 0 +}; + +PyTypeObject pyfsapfs_extended_attributes_type_object = { + PyVarObject_HEAD_INIT( NULL, 0 ) + + /* tp_name */ + "pyfsapfs.extended_attributes", + /* tp_basicsize */ + sizeof( pyfsapfs_extended_attributes_t ), + /* tp_itemsize */ + 0, + /* tp_dealloc */ + (destructor) pyfsapfs_extended_attributes_free, + /* tp_print */ + 0, + /* tp_getattr */ + 0, + /* tp_setattr */ + 0, + /* tp_compare */ + 0, + /* tp_repr */ + 0, + /* tp_as_number */ + 0, + /* tp_as_sequence */ + &pyfsapfs_extended_attributes_sequence_methods, + /* tp_as_mapping */ + 0, + /* tp_hash */ + 0, + /* tp_call */ + 0, + /* tp_str */ + 0, + /* tp_getattro */ + 0, + /* tp_setattro */ + 0, + /* tp_as_buffer */ + 0, + /* tp_flags */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_ITER, + /* tp_doc */ + "pyfsapfs sequence and iterator object of extended attributes", + /* tp_traverse */ + 0, + /* tp_clear */ + 0, + /* tp_richcompare */ + 0, + /* tp_weaklistoffset */ + 0, + /* tp_iter */ + (getiterfunc) pyfsapfs_extended_attributes_iter, + /* tp_iternext */ + (iternextfunc) pyfsapfs_extended_attributes_iternext, + /* tp_methods */ + 0, + /* tp_members */ + 0, + /* tp_getset */ + 0, + /* tp_base */ + 0, + /* tp_dict */ + 0, + /* tp_descr_get */ + 0, + /* tp_descr_set */ + 0, + /* tp_dictoffset */ + 0, + /* tp_init */ + (initproc) pyfsapfs_extended_attributes_init, + /* tp_alloc */ + 0, + /* tp_new */ + 0, + /* tp_free */ + 0, + /* tp_is_gc */ + 0, + /* tp_bases */ + NULL, + /* tp_mro */ + NULL, + /* tp_cache */ + NULL, + /* tp_subclasses */ + NULL, + /* tp_weaklist */ + NULL, + /* tp_del */ + 0 +}; + +/* Creates a new extended attributes sequence and iterator object + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_extended_attributes_new( + PyObject *parent_object, + PyObject* (*get_item_by_index)( + PyObject *parent_object, + int index ), + int number_of_items ) +{ + pyfsapfs_extended_attributes_t *sequence_object = NULL; + static char *function = "pyfsapfs_extended_attributes_new"; + + if( parent_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid parent object.", + function ); + + return( NULL ); + } + if( get_item_by_index == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid get item by index function.", + function ); + + return( NULL ); + } + /* Make sure the extended attributes values are initialized + */ + sequence_object = PyObject_New( + struct pyfsapfs_extended_attributes, + &pyfsapfs_extended_attributes_type_object ); + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to create sequence object.", + function ); + + goto on_error; + } + sequence_object->parent_object = parent_object; + sequence_object->get_item_by_index = get_item_by_index; + sequence_object->current_index = 0; + sequence_object->number_of_items = number_of_items; + + Py_IncRef( + (PyObject *) sequence_object->parent_object ); + + return( (PyObject *) sequence_object ); + +on_error: + if( sequence_object != NULL ) + { + Py_DecRef( + (PyObject *) sequence_object ); + } + return( NULL ); +} + +/* Intializes an extended attributes sequence and iterator object + * Returns 0 if successful or -1 on error + */ +int pyfsapfs_extended_attributes_init( + pyfsapfs_extended_attributes_t *sequence_object ) +{ + static char *function = "pyfsapfs_extended_attributes_init"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( -1 ); + } + /* Make sure the extended attributes values are initialized + */ + sequence_object->parent_object = NULL; + sequence_object->get_item_by_index = NULL; + sequence_object->current_index = 0; + sequence_object->number_of_items = 0; + + PyErr_Format( + PyExc_NotImplementedError, + "%s: initialize of extended attributes not supported.", + function ); + + return( 0 ); +} + +/* Frees an extended attributes sequence object + */ +void pyfsapfs_extended_attributes_free( + pyfsapfs_extended_attributes_t *sequence_object ) +{ + struct _typeobject *ob_type = NULL; + static char *function = "pyfsapfs_extended_attributes_free"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return; + } + ob_type = Py_TYPE( + sequence_object ); + + if( ob_type == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: missing ob_type.", + function ); + + return; + } + if( ob_type->tp_free == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid ob_type - missing tp_free.", + function ); + + return; + } + if( sequence_object->parent_object != NULL ) + { + Py_DecRef( + (PyObject *) sequence_object->parent_object ); + } + ob_type->tp_free( + (PyObject*) sequence_object ); +} + +/* The extended attributes len() function + */ +Py_ssize_t pyfsapfs_extended_attributes_len( + pyfsapfs_extended_attributes_t *sequence_object ) +{ + static char *function = "pyfsapfs_extended_attributes_len"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( -1 ); + } + return( (Py_ssize_t) sequence_object->number_of_items ); +} + +/* The extended attributes getitem() function + */ +PyObject *pyfsapfs_extended_attributes_getitem( + pyfsapfs_extended_attributes_t *sequence_object, + Py_ssize_t item_index ) +{ + PyObject *extended_attribute_object = NULL; + static char *function = "pyfsapfs_extended_attributes_getitem"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( NULL ); + } + if( sequence_object->get_item_by_index == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - missing get item by index function.", + function ); + + return( NULL ); + } + if( sequence_object->number_of_items < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - invalid number of items.", + function ); + + return( NULL ); + } + if( ( item_index < 0 ) + || ( item_index >= (Py_ssize_t) sequence_object->number_of_items ) ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid invalid item index value out of bounds.", + function ); + + return( NULL ); + } + extended_attribute_object = sequence_object->get_item_by_index( + sequence_object->parent_object, + (int) item_index ); + + return( extended_attribute_object ); +} + +/* The extended attributes iter() function + */ +PyObject *pyfsapfs_extended_attributes_iter( + pyfsapfs_extended_attributes_t *sequence_object ) +{ + static char *function = "pyfsapfs_extended_attributes_iter"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( NULL ); + } + Py_IncRef( + (PyObject *) sequence_object ); + + return( (PyObject *) sequence_object ); +} + +/* The extended attributes iternext() function + */ +PyObject *pyfsapfs_extended_attributes_iternext( + pyfsapfs_extended_attributes_t *sequence_object ) +{ + PyObject *extended_attribute_object = NULL; + static char *function = "pyfsapfs_extended_attributes_iternext"; + + if( sequence_object == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object.", + function ); + + return( NULL ); + } + if( sequence_object->get_item_by_index == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - missing get item by index function.", + function ); + + return( NULL ); + } + if( sequence_object->current_index < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - invalid current index.", + function ); + + return( NULL ); + } + if( sequence_object->number_of_items < 0 ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid sequence object - invalid number of items.", + function ); + + return( NULL ); + } + if( sequence_object->current_index >= sequence_object->number_of_items ) + { + PyErr_SetNone( + PyExc_StopIteration ); + + return( NULL ); + } + extended_attribute_object = sequence_object->get_item_by_index( + sequence_object->parent_object, + sequence_object->current_index ); + + if( extended_attribute_object != NULL ) + { + sequence_object->current_index++; + } + return( extended_attribute_object ); +} + diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attributes.h libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attributes.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_extended_attributes.h 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_extended_attributes.h 2019-02-06 20:10:15.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Python object definition of the sequence and iterator object of extended attributes + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#if !defined( _PYFSAPFS_EXTENDED_ATTRIBUTES_H ) +#define _PYFSAPFS_EXTENDED_ATTRIBUTES_H + +#include +#include + +#include "pyfsapfs_libfsapfs.h" +#include "pyfsapfs_python.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +typedef struct pyfsapfs_extended_attributes pyfsapfs_extended_attributes_t; + +struct pyfsapfs_extended_attributes +{ + /* Python object initialization + */ + PyObject_HEAD + + /* The parent object + */ + PyObject *parent_object; + + /* The get item by index callback function + */ + PyObject* (*get_item_by_index)( + PyObject *parent_object, + int index ); + + /* The current index + */ + int current_index; + + /* The number of items + */ + int number_of_items; +}; + +extern PyTypeObject pyfsapfs_extended_attributes_type_object; + +PyObject *pyfsapfs_extended_attributes_new( + PyObject *parent_object, + PyObject* (*get_item_by_index)( + PyObject *parent_object, + int index ), + int number_of_items ); + +int pyfsapfs_extended_attributes_init( + pyfsapfs_extended_attributes_t *sequence_object ); + +void pyfsapfs_extended_attributes_free( + pyfsapfs_extended_attributes_t *sequence_object ); + +Py_ssize_t pyfsapfs_extended_attributes_len( + pyfsapfs_extended_attributes_t *sequence_object ); + +PyObject *pyfsapfs_extended_attributes_getitem( + pyfsapfs_extended_attributes_t *sequence_object, + Py_ssize_t item_index ); + +PyObject *pyfsapfs_extended_attributes_iter( + pyfsapfs_extended_attributes_t *sequence_object ); + +PyObject *pyfsapfs_extended_attributes_iternext( + pyfsapfs_extended_attributes_t *sequence_object ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _PYFSAPFS_EXTENDED_ATTRIBUTES_H ) */ + diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entries.c libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entries.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entries.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entries.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object definition of the sequence and iterator object of file entries * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entries.h libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entries.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entries.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entries.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object definition of the sequence and iterator object of file entries * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entry.c libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entry.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entry.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entry.c 2019-02-10 19:22:56.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object wrapper of libfsapfs_file_entry_t * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -29,6 +29,8 @@ #include "pyfsapfs_datetime.h" #include "pyfsapfs_error.h" +#include "pyfsapfs_extended_attribute.h" +#include "pyfsapfs_extended_attributes.h" #include "pyfsapfs_file_entries.h" #include "pyfsapfs_file_entry.h" #include "pyfsapfs_integer.h" @@ -144,6 +146,34 @@ "\n" "Returns the symbolic link target." }, + { "get_number_of_extended_attributes", + (PyCFunction) pyfsapfs_file_entry_get_number_of_extended_attributes, + METH_NOARGS, + "get_number_of_extended_attributes() -> Integer\n" + "\n" + "Retrieves the number of extended attributes." }, + + { "get_extended_attribute", + (PyCFunction) pyfsapfs_file_entry_get_extended_attribute, + METH_VARARGS | METH_KEYWORDS, + "get_extended_attribute(extended_attribute_index) -> Object\n" + "\n" + "Retrieves the extended attribute specified by the index." }, + + { "has_extended_attribute_by_name", + (PyCFunction) pyfsapfs_file_entry_has_extended_attribute_by_name, + METH_VARARGS | METH_KEYWORDS, + "has_extended_attribute_by_name(name) -> Boolean\n" + "\n" + "Determines if there is an extended attribute specified by the name." }, + + { "get_extended_attribute_by_name", + (PyCFunction) pyfsapfs_file_entry_get_extended_attribute_by_name, + METH_VARARGS | METH_KEYWORDS, + "get_extended_attribute_by_name(name) -> Object or None\n" + "\n" + "Retrieves an extended attribute specified by the name." }, + { "get_number_of_sub_file_entries", (PyCFunction) pyfsapfs_file_entry_get_number_of_sub_file_entries, METH_NOARGS, @@ -307,6 +337,18 @@ "The symbolic link target.", NULL }, + { "number_of_extended_attributes", + (getter) pyfsapfs_file_entry_get_number_of_extended_attributes, + (setter) 0, + "The number of extended attributes.", + NULL }, + + { "extended_attributes", + (getter) pyfsapfs_file_entry_get_extended_attributes, + (setter) 0, + "The extended attributes.", + NULL }, + { "number_of_sub_file_entries", (getter) pyfsapfs_file_entry_get_number_of_sub_file_entries, (setter) 0, @@ -1554,6 +1596,395 @@ } return( NULL ); } + +/* Retrieves the number of extended attributes + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_file_entry_get_number_of_extended_attributes( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments PYFSAPFS_ATTRIBUTE_UNUSED ) +{ + PyObject *integer_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfsapfs_file_entry_get_number_of_extended_attributes"; + int number_of_extended_attributes = 0; + int result = 0; + + PYFSAPFS_UNREFERENCED_PARAMETER( arguments ) + + if( pyfsapfs_file_entry == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid file entry.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_file_entry_get_number_of_extended_attributes( + pyfsapfs_file_entry->file_entry, + &number_of_extended_attributes, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve .", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } +#if PY_MAJOR_VERSION >= 3 + integer_object = PyLong_FromLong( + (long) number_of_extended_attributes ); +#else + integer_object = PyInt_FromLong( + (long) number_of_extended_attributes ); +#endif + return( integer_object ); +} + +/* Retrieves a specific extended attribute by index + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_file_entry_get_extended_attribute_by_index( + PyObject *pyfsapfs_file_entry, + int extended_attribute_index ) +{ + PyObject *extended_attribute_object = NULL; + libcerror_error_t *error = NULL; + libfsapfs_extended_attribute_t *extended_attribute = NULL; + static char *function = "pyfsapfs_file_entry_get_extended_attribute_by_index"; + int result = 0; + + if( pyfsapfs_file_entry == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid file entry.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_file_entry_get_extended_attribute_by_index( + ( (pyfsapfs_file_entry_t *) pyfsapfs_file_entry )->file_entry, + extended_attribute_index, + &extended_attribute, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve : %d.", + function, + extended_attribute_index ); + + libcerror_error_free( + &error ); + + goto on_error; + } + extended_attribute_object = pyfsapfs_extended_attribute_new( + extended_attribute, + pyfsapfs_file_entry ); + + if( extended_attribute_object == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to create extended attribute object.", + function ); + + goto on_error; + } + return( extended_attribute_object ); + +on_error: + if( extended_attribute != NULL ) + { + libfsapfs_extended_attribute_free( + &extended_attribute, + NULL ); + } + return( NULL ); +} + +/* Retrieves a specific extended attribute + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_file_entry_get_extended_attribute( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments, + PyObject *keywords ) +{ + PyObject *extended_attribute_object = NULL; + static char *keyword_list[] = { "extended_attribute_index", NULL }; + int extended_attribute_index = 0; + + if( PyArg_ParseTupleAndKeywords( + arguments, + keywords, + "i", + keyword_list, + &extended_attribute_index ) == 0 ) + { + return( NULL ); + } + extended_attribute_object = pyfsapfs_file_entry_get_extended_attribute_by_index( + (PyObject *) pyfsapfs_file_entry, + extended_attribute_index ); + + return( extended_attribute_object ); +} + +/* Retrieves a sequence and iterator object for the extended attributes + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_file_entry_get_extended_attributes( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments PYFSAPFS_ATTRIBUTE_UNUSED ) +{ + PyObject *sequence_object = NULL; + libcerror_error_t *error = NULL; + static char *function = "pyfsapfs_file_entry_get_extended_attributes"; + int number_of_extended_attributes = 0; + int result = 0; + + PYFSAPFS_UNREFERENCED_PARAMETER( arguments ) + + if( pyfsapfs_file_entry == NULL ) + { + PyErr_Format( + PyExc_ValueError, + "%s: invalid file entry.", + function ); + + return( NULL ); + } + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_file_entry_get_number_of_extended_attributes( + pyfsapfs_file_entry->file_entry, + &number_of_extended_attributes, + &error ); + + Py_END_ALLOW_THREADS + + if( result != 1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve number of extended attributes.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + sequence_object = pyfsapfs_extended_attributes_new( + (PyObject *) pyfsapfs_file_entry, + &pyfsapfs_file_entry_get_extended_attribute_by_index, + number_of_extended_attributes ); + + if( sequence_object == NULL ) + { + pyfsapfs_error_raise( + error, + PyExc_MemoryError, + "%s: unable to create sequence object.", + function ); + + return( NULL ); + } + return( sequence_object ); +} + +/* Determines if there is an extended attribute specified by the name + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_file_entry_has_extended_attribute_by_name( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments, + PyObject *keywords ) +{ + libcerror_error_t *error = NULL; + char *extended_attribute_name = NULL; + static char *keyword_list[] = { "extended_attribute_name", NULL }; + static char *function = "pyfsapfs_file_entry_has_extended_attribute_by_name"; + size_t extended_attribute_name_length = 0; + int result = 0; + + if( pyfsapfs_file_entry == NULL ) + { + PyErr_Format( + PyExc_TypeError, + "%s: invalid file entry.", + function ); + + return( NULL ); + } + if( PyArg_ParseTupleAndKeywords( + arguments, + keywords, + "s", + keyword_list, + &extended_attribute_name ) == 0 ) + { + return( NULL ); + } + extended_attribute_name_length = narrow_string_length( + extended_attribute_name ); + + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_file_entry_has_extended_attribute_by_utf8_name( + pyfsapfs_file_entry->file_entry, + (uint8_t *) extended_attribute_name, + extended_attribute_name_length, + &error ); + + Py_END_ALLOW_THREADS + + if( result == -1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to determine if extended attribute exists.", + function ); + + libcerror_error_free( + &error ); + + return( NULL ); + } + /* Check if the extended attribute is present + */ + if( result != 0 ) + { + Py_IncRef( + (PyObject *) Py_True ); + + return( Py_True ); + } + Py_IncRef( + (PyObject *) Py_False ); + + return( Py_False ); +} + +/* Retrieves the extended attribute specified by the name + * Returns a Python object if successful or NULL on error + */ +PyObject *pyfsapfs_file_entry_get_extended_attribute_by_name( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments, + PyObject *keywords ) +{ + libcerror_error_t *error = NULL; + libfsapfs_extended_attribute_t *extended_attribute = NULL; + PyObject *extended_attribute_object = NULL; + char *extended_attribute_name = NULL; + static char *keyword_list[] = { "extended_attribute_name", NULL }; + static char *function = "pyfsapfs_file_entry_get_extended_attribute_by_name"; + size_t extended_attribute_name_length = 0; + int result = 0; + + if( pyfsapfs_file_entry == NULL ) + { + PyErr_Format( + PyExc_TypeError, + "%s: invalid file entry.", + function ); + + return( NULL ); + } + if( PyArg_ParseTupleAndKeywords( + arguments, + keywords, + "s", + keyword_list, + &extended_attribute_name ) == 0 ) + { + goto on_error; + } + extended_attribute_name_length = narrow_string_length( + extended_attribute_name ); + + Py_BEGIN_ALLOW_THREADS + + result = libfsapfs_file_entry_get_extended_attribute_by_utf8_name( + pyfsapfs_file_entry->file_entry, + (uint8_t *) extended_attribute_name, + extended_attribute_name_length, + &extended_attribute, + &error ); + + Py_END_ALLOW_THREADS + + if( result == -1 ) + { + pyfsapfs_error_raise( + error, + PyExc_IOError, + "%s: unable to retrieve extended attribute.", + function ); + + libcerror_error_free( + &error ); + + goto on_error; + } + /* Check if the extended attribute is present + */ + else if( result == 0 ) + { + Py_IncRef( + Py_None ); + + return( Py_None ); + } + extended_attribute_object = pyfsapfs_extended_attribute_new( + extended_attribute, + (PyObject *) pyfsapfs_file_entry ); + + if( extended_attribute_object == NULL ) + { + PyErr_Format( + PyExc_MemoryError, + "%s: unable to create extended attribute object.", + function ); + + goto on_error; + } + return( extended_attribute_object ); + +on_error: + if( extended_attribute != NULL ) + { + libfsapfs_extended_attribute_free( + &extended_attribute, + NULL ); + } + return( NULL ); +} /* Retrieves the number of sub file entries * Returns a Python object if successful or NULL on error diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entry.h libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entry.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_file_entry.h 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_file_entry.h 2019-02-10 18:27:27.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object wrapper of libfsapfs_file_entry_t * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -122,6 +122,33 @@ pyfsapfs_file_entry_t *pyfsapfs_file_entry, PyObject *arguments ); +PyObject *pyfsapfs_file_entry_get_number_of_extended_attributes( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments ); + +PyObject *pyfsapfs_file_entry_get_extended_attribute_by_index( + PyObject *pyfsapfs_file_entry, + int extended_attribute_index ); + +PyObject *pyfsapfs_file_entry_get_extended_attribute( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments, + PyObject *keywords ); + +PyObject *pyfsapfs_file_entry_get_extended_attributes( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments ); + +PyObject *pyfsapfs_file_entry_has_extended_attribute_by_name( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments, + PyObject *keywords ); + +PyObject *pyfsapfs_file_entry_get_extended_attribute_by_name( + pyfsapfs_file_entry_t *pyfsapfs_file_entry, + PyObject *arguments, + PyObject *keywords ); + PyObject *pyfsapfs_file_entry_get_number_of_sub_file_entries( pyfsapfs_file_entry_t *pyfsapfs_file_entry, PyObject *arguments ); diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_file_object_io_handle.c libfsapfs-20190210/pyfsapfs/pyfsapfs_file_object_io_handle.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_file_object_io_handle.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_file_object_io_handle.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python file object IO handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_file_object_io_handle.h libfsapfs-20190210/pyfsapfs/pyfsapfs_file_object_io_handle.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_file_object_io_handle.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_file_object_io_handle.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python file object IO handle functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_guid.c libfsapfs-20190210/pyfsapfs/pyfsapfs_guid.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_guid.c 2018-12-03 17:51:54.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_guid.c 2019-02-06 20:15:25.000000000 +0000 @@ -1,7 +1,7 @@ /* * GUID functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_guid.h libfsapfs-20190210/pyfsapfs/pyfsapfs_guid.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_guid.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_guid.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * GUID functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs.h libfsapfs-20190210/pyfsapfs/pyfsapfs.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python bindings module for libfsapfs (pyfsapfs) * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_integer.c libfsapfs-20190210/pyfsapfs/pyfsapfs_integer.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_integer.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_integer.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Integer functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_integer.h libfsapfs-20190210/pyfsapfs/pyfsapfs_integer.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_integer.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_integer.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Integer functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_libbfio.h libfsapfs-20190210/pyfsapfs/pyfsapfs_libbfio.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_libbfio.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_libbfio.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libbfio header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_libcerror.h libfsapfs-20190210/pyfsapfs/pyfsapfs_libcerror.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_libcerror.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_libcerror.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_libclocale.h libfsapfs-20190210/pyfsapfs/pyfsapfs_libclocale.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_libclocale.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_libclocale.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libclocale header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_libfguid.h libfsapfs-20190210/pyfsapfs/pyfsapfs_libfguid.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_libfguid.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_libfguid.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfguid header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_libfsapfs.h libfsapfs-20190210/pyfsapfs/pyfsapfs_libfsapfs.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_libfsapfs.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_libfsapfs.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The internal libfsapfs header * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_python.h libfsapfs-20190210/pyfsapfs/pyfsapfs_python.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_python.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_python.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The python header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_unused.h libfsapfs-20190210/pyfsapfs/pyfsapfs_unused.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_unused.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_unused.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The internal unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -19,8 +19,8 @@ * along with this software. If not, see . */ -#if !defined( _PYFSAPFS_INTERNAL_UNUSED_H ) -#define _PYFSAPFS_INTERNAL_UNUSED_H +#if !defined( _PYFSAPFS_UNUSED_H ) +#define _PYFSAPFS_UNUSED_H #include @@ -40,5 +40,5 @@ /* parameter */ #endif -#endif /* !defined( _PYFSAPFS_INTERNAL_UNUSED_H ) */ +#endif /* !defined( _PYFSAPFS_UNUSED_H ) */ diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_volume.c libfsapfs-20190210/pyfsapfs/pyfsapfs_volume.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_volume.c 2018-12-04 19:28:52.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_volume.c 2019-02-06 20:15:25.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object wrapper of libfsapfs_volume_t * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_volume.h libfsapfs-20190210/pyfsapfs/pyfsapfs_volume.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_volume.h 2018-12-04 19:27:41.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_volume.h 2019-02-06 20:15:25.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object wrapper of libfsapfs_volume_t * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_volumes.c libfsapfs-20190210/pyfsapfs/pyfsapfs_volumes.c --- libfsapfs-20181215/pyfsapfs/pyfsapfs_volumes.c 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_volumes.c 2019-02-06 20:15:25.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object definition of the sequence and iterator object of volumes * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs/pyfsapfs_volumes.h libfsapfs-20190210/pyfsapfs/pyfsapfs_volumes.h --- libfsapfs-20181215/pyfsapfs/pyfsapfs_volumes.h 2018-12-03 17:49:12.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs/pyfsapfs_volumes.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Python object definition of the sequence and iterator object of volumes * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/pyfsapfs-python2/Makefile.am libfsapfs-20190210/pyfsapfs-python2/Makefile.am --- libfsapfs-20181215/pyfsapfs-python2/Makefile.am 2018-12-03 17:49:05.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs-python2/Makefile.am 2019-02-06 20:27:29.000000000 +0000 @@ -26,6 +26,8 @@ pyfsapfs_container.c pyfsapfs_container.h \ pyfsapfs_datetime.c pyfsapfs_datetime.h \ pyfsapfs_error.c pyfsapfs_error.h \ + pyfsapfs_extended_attribute.c pyfsapfs_extended_attribute.h \ + pyfsapfs_extended_attributes.c pyfsapfs_extended_attributes.h \ pyfsapfs_file_entries.c pyfsapfs_file_entries.h \ pyfsapfs_file_entry.c pyfsapfs_file_entry.h \ pyfsapfs_file_object_io_handle.c pyfsapfs_file_object_io_handle.h \ diff -Nru libfsapfs-20181215/pyfsapfs-python2/Makefile.in libfsapfs-20190210/pyfsapfs-python2/Makefile.in --- libfsapfs-20181215/pyfsapfs-python2/Makefile.in 2018-12-15 06:44:02.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs-python2/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -152,6 +152,8 @@ @HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_container.lo \ @HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_datetime.lo \ @HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_error.lo \ +@HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_extended_attribute.lo \ +@HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_extended_attributes.lo \ @HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_file_entries.lo \ @HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_file_entry.lo \ @HAVE_PYTHON2_TRUE@ pyfsapfs_la-pyfsapfs_file_object_io_handle.lo \ @@ -187,6 +189,8 @@ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo \ + ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo \ + ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo \ @@ -634,6 +638,8 @@ @HAVE_PYTHON2_TRUE@ pyfsapfs_container.c pyfsapfs_container.h \ @HAVE_PYTHON2_TRUE@ pyfsapfs_datetime.c pyfsapfs_datetime.h \ @HAVE_PYTHON2_TRUE@ pyfsapfs_error.c pyfsapfs_error.h \ +@HAVE_PYTHON2_TRUE@ pyfsapfs_extended_attribute.c pyfsapfs_extended_attribute.h \ +@HAVE_PYTHON2_TRUE@ pyfsapfs_extended_attributes.c pyfsapfs_extended_attributes.h \ @HAVE_PYTHON2_TRUE@ pyfsapfs_file_entries.c pyfsapfs_file_entries.h \ @HAVE_PYTHON2_TRUE@ pyfsapfs_file_entry.c pyfsapfs_file_entry.h \ @HAVE_PYTHON2_TRUE@ pyfsapfs_file_object_io_handle.c pyfsapfs_file_object_io_handle.h \ @@ -751,6 +757,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo@am__quote@ # am--include-marker @@ -814,6 +822,20 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_error.lo `test -f 'pyfsapfs_error.c' || echo '$(srcdir)/'`pyfsapfs_error.c +pyfsapfs_la-pyfsapfs_extended_attribute.lo: pyfsapfs_extended_attribute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_extended_attribute.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Tpo -c -o pyfsapfs_la-pyfsapfs_extended_attribute.lo `test -f 'pyfsapfs_extended_attribute.c' || echo '$(srcdir)/'`pyfsapfs_extended_attribute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyfsapfs_extended_attribute.c' object='pyfsapfs_la-pyfsapfs_extended_attribute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_extended_attribute.lo `test -f 'pyfsapfs_extended_attribute.c' || echo '$(srcdir)/'`pyfsapfs_extended_attribute.c + +pyfsapfs_la-pyfsapfs_extended_attributes.lo: pyfsapfs_extended_attributes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_extended_attributes.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Tpo -c -o pyfsapfs_la-pyfsapfs_extended_attributes.lo `test -f 'pyfsapfs_extended_attributes.c' || echo '$(srcdir)/'`pyfsapfs_extended_attributes.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyfsapfs_extended_attributes.c' object='pyfsapfs_la-pyfsapfs_extended_attributes.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_extended_attributes.lo `test -f 'pyfsapfs_extended_attributes.c' || echo '$(srcdir)/'`pyfsapfs_extended_attributes.c + pyfsapfs_la-pyfsapfs_file_entries.lo: pyfsapfs_file_entries.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_file_entries.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Tpo -c -o pyfsapfs_la-pyfsapfs_file_entries.lo `test -f 'pyfsapfs_file_entries.c' || echo '$(srcdir)/'`pyfsapfs_file_entries.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo @@ -1048,6 +1070,8 @@ -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo + -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo + -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo diff -Nru libfsapfs-20181215/pyfsapfs-python3/Makefile.am libfsapfs-20190210/pyfsapfs-python3/Makefile.am --- libfsapfs-20181215/pyfsapfs-python3/Makefile.am 2018-12-03 17:49:05.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs-python3/Makefile.am 2019-02-06 20:29:32.000000000 +0000 @@ -26,6 +26,8 @@ pyfsapfs_container.c pyfsapfs_container.h \ pyfsapfs_datetime.c pyfsapfs_datetime.h \ pyfsapfs_error.c pyfsapfs_error.h \ + pyfsapfs_extended_attribute.c pyfsapfs_extended_attribute.h \ + pyfsapfs_extended_attributes.c pyfsapfs_extended_attributes.h \ pyfsapfs_file_entries.c pyfsapfs_file_entries.h \ pyfsapfs_file_entry.c pyfsapfs_file_entry.h \ pyfsapfs_file_object_io_handle.c pyfsapfs_file_object_io_handle.h \ diff -Nru libfsapfs-20181215/pyfsapfs-python3/Makefile.in libfsapfs-20190210/pyfsapfs-python3/Makefile.in --- libfsapfs-20181215/pyfsapfs-python3/Makefile.in 2018-12-15 06:44:02.000000000 +0000 +++ libfsapfs-20190210/pyfsapfs-python3/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -152,6 +152,8 @@ @HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_container.lo \ @HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_datetime.lo \ @HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_error.lo \ +@HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_extended_attribute.lo \ +@HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_extended_attributes.lo \ @HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_file_entries.lo \ @HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_file_entry.lo \ @HAVE_PYTHON3_TRUE@ pyfsapfs_la-pyfsapfs_file_object_io_handle.lo \ @@ -187,6 +189,8 @@ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo \ + ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo \ + ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo \ ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo \ @@ -634,6 +638,8 @@ @HAVE_PYTHON3_TRUE@ pyfsapfs_container.c pyfsapfs_container.h \ @HAVE_PYTHON3_TRUE@ pyfsapfs_datetime.c pyfsapfs_datetime.h \ @HAVE_PYTHON3_TRUE@ pyfsapfs_error.c pyfsapfs_error.h \ +@HAVE_PYTHON3_TRUE@ pyfsapfs_extended_attribute.c pyfsapfs_extended_attribute.h \ +@HAVE_PYTHON3_TRUE@ pyfsapfs_extended_attributes.c pyfsapfs_extended_attributes.h \ @HAVE_PYTHON3_TRUE@ pyfsapfs_file_entries.c pyfsapfs_file_entries.h \ @HAVE_PYTHON3_TRUE@ pyfsapfs_file_entry.c pyfsapfs_file_entry.h \ @HAVE_PYTHON3_TRUE@ pyfsapfs_file_object_io_handle.c pyfsapfs_file_object_io_handle.h \ @@ -751,6 +757,8 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo@am__quote@ # am--include-marker @@ -814,6 +822,20 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_error.lo `test -f 'pyfsapfs_error.c' || echo '$(srcdir)/'`pyfsapfs_error.c +pyfsapfs_la-pyfsapfs_extended_attribute.lo: pyfsapfs_extended_attribute.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_extended_attribute.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Tpo -c -o pyfsapfs_la-pyfsapfs_extended_attribute.lo `test -f 'pyfsapfs_extended_attribute.c' || echo '$(srcdir)/'`pyfsapfs_extended_attribute.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyfsapfs_extended_attribute.c' object='pyfsapfs_la-pyfsapfs_extended_attribute.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_extended_attribute.lo `test -f 'pyfsapfs_extended_attribute.c' || echo '$(srcdir)/'`pyfsapfs_extended_attribute.c + +pyfsapfs_la-pyfsapfs_extended_attributes.lo: pyfsapfs_extended_attributes.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_extended_attributes.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Tpo -c -o pyfsapfs_la-pyfsapfs_extended_attributes.lo `test -f 'pyfsapfs_extended_attributes.c' || echo '$(srcdir)/'`pyfsapfs_extended_attributes.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='pyfsapfs_extended_attributes.c' object='pyfsapfs_la-pyfsapfs_extended_attributes.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o pyfsapfs_la-pyfsapfs_extended_attributes.lo `test -f 'pyfsapfs_extended_attributes.c' || echo '$(srcdir)/'`pyfsapfs_extended_attributes.c + pyfsapfs_la-pyfsapfs_file_entries.lo: pyfsapfs_file_entries.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pyfsapfs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pyfsapfs_la-pyfsapfs_file_entries.lo -MD -MP -MF $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Tpo -c -o pyfsapfs_la-pyfsapfs_file_entries.lo `test -f 'pyfsapfs_file_entries.c' || echo '$(srcdir)/'`pyfsapfs_file_entries.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Tpo $(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo @@ -1048,6 +1070,8 @@ -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_container.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_datetime.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_error.Plo + -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attribute.Plo + -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_extended_attributes.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entries.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_entry.Plo -rm -f ./$(DEPDIR)/pyfsapfs_la-pyfsapfs_file_object_io_handle.Plo diff -Nru libfsapfs-20181215/README libfsapfs-20190210/README --- libfsapfs-20181215/README 2018-12-03 17:52:03.000000000 +0000 +++ libfsapfs-20190210/README 2019-02-06 20:14:21.000000000 +0000 @@ -18,9 +18,10 @@ Unsupported APFS format features: * APFS version 1 +* Fusion drive (NX_INCOMPAT_FUSION) +* snapshots * LZFSE compression, compression methods 11 and 12 * "uncompressed", compression methods 1, 9 and 10 -* snapshots For more information see: diff -Nru libfsapfs-20181215/tests/fsapfs_test_btree_entry.c libfsapfs-20190210/tests/fsapfs_test_btree_entry.c --- libfsapfs-20181215/tests/fsapfs_test_btree_entry.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_btree_entry.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library btree_entry type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_btree_footer.c libfsapfs-20190210/tests/fsapfs_test_btree_footer.c --- libfsapfs-20181215/tests/fsapfs_test_btree_footer.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_btree_footer.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library btree_footer type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_btree_node.c libfsapfs-20190210/tests/fsapfs_test_btree_node.c --- libfsapfs-20181215/tests/fsapfs_test_btree_node.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_btree_node.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library btree_node type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_btree_node_header.c libfsapfs-20190210/tests/fsapfs_test_btree_node_header.c --- libfsapfs-20181215/tests/fsapfs_test_btree_node_header.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_btree_node_header.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library btree_node_header type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_buffer_data_handle.c libfsapfs-20190210/tests/fsapfs_test_buffer_data_handle.c --- libfsapfs-20181215/tests/fsapfs_test_buffer_data_handle.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_buffer_data_handle.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library buffer_data_handle type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_checkpoint_map.c libfsapfs-20190210/tests/fsapfs_test_checkpoint_map.c --- libfsapfs-20181215/tests/fsapfs_test_checkpoint_map.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_checkpoint_map.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library checkpoint_map type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_checkpoint_map_entry.c libfsapfs-20190210/tests/fsapfs_test_checkpoint_map_entry.c --- libfsapfs-20181215/tests/fsapfs_test_checkpoint_map_entry.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_checkpoint_map_entry.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library checkpoint_map_entry type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_checksum.c libfsapfs-20190210/tests/fsapfs_test_checksum.c --- libfsapfs-20181215/tests/fsapfs_test_checksum.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_checksum.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library checksum functions test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_chunk_information_block.c libfsapfs-20190210/tests/fsapfs_test_chunk_information_block.c --- libfsapfs-20181215/tests/fsapfs_test_chunk_information_block.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_chunk_information_block.c 2019-02-06 20:13:54.000000000 +0000 @@ -0,0 +1,965 @@ +/* + * Library chunk_information_block type test program + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include + +#if defined( HAVE_STDLIB_H ) || defined( WINAPI ) +#include +#endif + +#include "fsapfs_test_functions.h" +#include "fsapfs_test_libcerror.h" +#include "fsapfs_test_libfsapfs.h" +#include "fsapfs_test_macros.h" +#include "fsapfs_test_memory.h" +#include "fsapfs_test_unused.h" + +#include "../libfsapfs/libfsapfs_chunk_information_block.h" + +uint8_t fsapfs_test_chunk_information_block_data1[ 4096 ] = { + 0x0d, 0xcd, 0xdf, 0x3f, 0xcb, 0x2a, 0x20, 0x80, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x03, 0x00, 0x00, 0x86, 0x03, 0x00, 0x00, + 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#if defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) + +/* Tests the libfsapfs_chunk_information_block_initialize function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_chunk_information_block_initialize( + void ) +{ + libcerror_error_t *error = NULL; + libfsapfs_chunk_information_block_t *chunk_information_block = NULL; + int result = 0; + +#if defined( HAVE_FSAPFS_TEST_MEMORY ) + int number_of_malloc_fail_tests = 1; + int number_of_memset_fail_tests = 1; + int test_number = 0; +#endif + + /* Test regular cases + */ + result = libfsapfs_chunk_information_block_initialize( + &chunk_information_block, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libfsapfs_chunk_information_block_free( + &chunk_information_block, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ + result = libfsapfs_chunk_information_block_initialize( + NULL, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + chunk_information_block = (libfsapfs_chunk_information_block_t *) 0x12345678UL; + + result = libfsapfs_chunk_information_block_initialize( + &chunk_information_block, + &error ); + + chunk_information_block = NULL; + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + +#if defined( HAVE_FSAPFS_TEST_MEMORY ) + + for( test_number = 0; + test_number < number_of_malloc_fail_tests; + test_number++ ) + { + /* Test libfsapfs_chunk_information_block_initialize with malloc failing + */ + fsapfs_test_malloc_attempts_before_fail = test_number; + + result = libfsapfs_chunk_information_block_initialize( + &chunk_information_block, + &error ); + + if( fsapfs_test_malloc_attempts_before_fail != -1 ) + { + fsapfs_test_malloc_attempts_before_fail = -1; + + if( chunk_information_block != NULL ) + { + libfsapfs_chunk_information_block_free( + &chunk_information_block, + NULL ); + } + } + else + { + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + } + } + for( test_number = 0; + test_number < number_of_memset_fail_tests; + test_number++ ) + { + /* Test libfsapfs_chunk_information_block_initialize with memset failing + */ + fsapfs_test_memset_attempts_before_fail = test_number; + + result = libfsapfs_chunk_information_block_initialize( + &chunk_information_block, + &error ); + + if( fsapfs_test_memset_attempts_before_fail != -1 ) + { + fsapfs_test_memset_attempts_before_fail = -1; + + if( chunk_information_block != NULL ) + { + libfsapfs_chunk_information_block_free( + &chunk_information_block, + NULL ); + } + } + else + { + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + } + } +#endif /* defined( HAVE_FSAPFS_TEST_MEMORY ) */ + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + if( chunk_information_block != NULL ) + { + libfsapfs_chunk_information_block_free( + &chunk_information_block, + NULL ); + } + return( 0 ); +} + +/* Tests the libfsapfs_chunk_information_block_free function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_chunk_information_block_free( + void ) +{ + libcerror_error_t *error = NULL; + int result = 0; + + /* Test error cases + */ + result = libfsapfs_chunk_information_block_free( + NULL, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + return( 0 ); +} + +/* Tests the libfsapfs_chunk_information_block_read_file_io_handle function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_chunk_information_block_read_file_io_handle( + void ) +{ + libbfio_handle_t *file_io_handle = NULL; + libcerror_error_t *error = NULL; + libfsapfs_chunk_information_block_t *chunk_information_block = NULL; + int result = 0; + + /* Initialize test + */ + result = libfsapfs_chunk_information_block_initialize( + &chunk_information_block, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Initialize file IO handle + */ + result = fsapfs_test_open_file_io_handle( + &file_io_handle, + fsapfs_test_chunk_information_block_data1, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "file_io_handle", + file_io_handle ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test regular cases + */ + result = libfsapfs_chunk_information_block_read_file_io_handle( + chunk_information_block, + file_io_handle, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ + result = libfsapfs_chunk_information_block_read_file_io_handle( + NULL, + file_io_handle, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_chunk_information_block_read_file_io_handle( + chunk_information_block, + NULL, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_chunk_information_block_read_file_io_handle( + chunk_information_block, + file_io_handle, + -1, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + /* Clean up file IO handle + */ + result = fsapfs_test_close_file_io_handle( + &file_io_handle, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test data too small + */ + result = fsapfs_test_open_file_io_handle( + &file_io_handle, + fsapfs_test_chunk_information_block_data1, + 8, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "file_io_handle", + file_io_handle ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libfsapfs_chunk_information_block_read_file_io_handle( + chunk_information_block, + file_io_handle, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = fsapfs_test_close_file_io_handle( + &file_io_handle, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + +/* TODO: test data invalid */ + + /* Clean up + */ + result = libfsapfs_chunk_information_block_free( + &chunk_information_block, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + if( file_io_handle != NULL ) + { + libbfio_handle_free( + &file_io_handle, + NULL ); + } + if( chunk_information_block != NULL ) + { + libfsapfs_chunk_information_block_free( + &chunk_information_block, + NULL ); + } + return( 0 ); +} + +/* Tests the libfsapfs_chunk_information_block_read_data function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_chunk_information_block_read_data( + void ) +{ + libcerror_error_t *error = NULL; + libfsapfs_chunk_information_block_t *chunk_information_block = NULL; + int result = 0; + + /* Initialize test + */ + result = libfsapfs_chunk_information_block_initialize( + &chunk_information_block, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test regular cases + */ + result = libfsapfs_chunk_information_block_read_data( + chunk_information_block, + fsapfs_test_chunk_information_block_data1, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ + result = libfsapfs_chunk_information_block_read_data( + NULL, + fsapfs_test_chunk_information_block_data1, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_chunk_information_block_read_data( + chunk_information_block, + NULL, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_chunk_information_block_read_data( + chunk_information_block, + fsapfs_test_chunk_information_block_data1, + (size_t) SSIZE_MAX + 1, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_chunk_information_block_read_data( + chunk_information_block, + fsapfs_test_chunk_information_block_data1, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + /* Clean up + */ + result = libfsapfs_chunk_information_block_free( + &chunk_information_block, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "chunk_information_block", + chunk_information_block ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + if( chunk_information_block != NULL ) + { + libfsapfs_chunk_information_block_free( + &chunk_information_block, + NULL ); + } + return( 0 ); +} + +#endif /* defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) */ + +/* The main program + */ +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) +int wmain( + int argc FSAPFS_TEST_ATTRIBUTE_UNUSED, + wchar_t * const argv[] FSAPFS_TEST_ATTRIBUTE_UNUSED ) +#else +int main( + int argc FSAPFS_TEST_ATTRIBUTE_UNUSED, + char * const argv[] FSAPFS_TEST_ATTRIBUTE_UNUSED ) +#endif +{ + FSAPFS_TEST_UNREFERENCED_PARAMETER( argc ) + FSAPFS_TEST_UNREFERENCED_PARAMETER( argv ) + +#if defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) + + FSAPFS_TEST_RUN( + "libfsapfs_chunk_information_block_initialize", + fsapfs_test_chunk_information_block_initialize ); + + FSAPFS_TEST_RUN( + "libfsapfs_chunk_information_block_free", + fsapfs_test_chunk_information_block_free ); + + FSAPFS_TEST_RUN( + "libfsapfs_chunk_information_block_read_file_io_handle", + fsapfs_test_chunk_information_block_read_file_io_handle ); + + FSAPFS_TEST_RUN( + "libfsapfs_chunk_information_block_read_data", + fsapfs_test_chunk_information_block_read_data ); + +#endif /* defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) */ + + return( EXIT_SUCCESS ); + +on_error: + return( EXIT_FAILURE ); +} + diff -Nru libfsapfs-20181215/tests/fsapfs_test_compressed_data_handle.c libfsapfs-20190210/tests/fsapfs_test_compressed_data_handle.c --- libfsapfs-20181215/tests/fsapfs_test_compressed_data_handle.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_compressed_data_handle.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library compressed_data_handle type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_compression.c libfsapfs-20190210/tests/fsapfs_test_compression.c --- libfsapfs-20181215/tests/fsapfs_test_compression.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_compression.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library compression type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_container.c libfsapfs-20190210/tests/fsapfs_test_container.c --- libfsapfs-20181215/tests/fsapfs_test_container.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_container.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library container type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_container_data_handle.c libfsapfs-20190210/tests/fsapfs_test_container_data_handle.c --- libfsapfs-20181215/tests/fsapfs_test_container_data_handle.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_container_data_handle.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library container_data_handle type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_container_key_bag.c libfsapfs-20190210/tests/fsapfs_test_container_key_bag.c --- libfsapfs-20181215/tests/fsapfs_test_container_key_bag.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_container_key_bag.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library container_key_bag type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_container_reaper.c libfsapfs-20190210/tests/fsapfs_test_container_reaper.c --- libfsapfs-20181215/tests/fsapfs_test_container_reaper.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_container_reaper.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library container_reaper type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_container_space_manager.c libfsapfs-20190210/tests/fsapfs_test_container_space_manager.c --- libfsapfs-20181215/tests/fsapfs_test_container_space_manager.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_container_space_manager.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,965 +0,0 @@ -/* - * Library container_space_manager type test program - * - * Copyright (C) 2018, Joachim Metz - * - * Refer to AUTHORS for acknowledgements. - * - * This software is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This software is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this software. If not, see . - */ - -#include -#include -#include - -#if defined( HAVE_STDLIB_H ) || defined( WINAPI ) -#include -#endif - -#include "fsapfs_test_functions.h" -#include "fsapfs_test_libcerror.h" -#include "fsapfs_test_libfsapfs.h" -#include "fsapfs_test_macros.h" -#include "fsapfs_test_memory.h" -#include "fsapfs_test_unused.h" - -#include "../libfsapfs/libfsapfs_container_space_manager.h" - -uint8_t fsapfs_test_container_space_manager_data1[ 4096 ] = { - 0xca, 0x56, 0x9b, 0xf0, 0x49, 0xce, 0x1c, 0x8f, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfb, 0x01, 0x00, 0x00, - 0xf6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x0f, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xe0, 0x09, 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 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, 0xff, 0xff, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - -#if defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) - -/* Tests the libfsapfs_container_space_manager_initialize function - * Returns 1 if successful or 0 if not - */ -int fsapfs_test_container_space_manager_initialize( - void ) -{ - libcerror_error_t *error = NULL; - libfsapfs_container_space_manager_t *container_space_manager = NULL; - int result = 0; - -#if defined( HAVE_FSAPFS_TEST_MEMORY ) - int number_of_malloc_fail_tests = 1; - int number_of_memset_fail_tests = 1; - int test_number = 0; -#endif - - /* Test regular cases - */ - result = libfsapfs_container_space_manager_initialize( - &container_space_manager, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - result = libfsapfs_container_space_manager_free( - &container_space_manager, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test error cases - */ - result = libfsapfs_container_space_manager_initialize( - NULL, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - container_space_manager = (libfsapfs_container_space_manager_t *) 0x12345678UL; - - result = libfsapfs_container_space_manager_initialize( - &container_space_manager, - &error ); - - container_space_manager = NULL; - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - -#if defined( HAVE_FSAPFS_TEST_MEMORY ) - - for( test_number = 0; - test_number < number_of_malloc_fail_tests; - test_number++ ) - { - /* Test libfsapfs_container_space_manager_initialize with malloc failing - */ - fsapfs_test_malloc_attempts_before_fail = test_number; - - result = libfsapfs_container_space_manager_initialize( - &container_space_manager, - &error ); - - if( fsapfs_test_malloc_attempts_before_fail != -1 ) - { - fsapfs_test_malloc_attempts_before_fail = -1; - - if( container_space_manager != NULL ) - { - libfsapfs_container_space_manager_free( - &container_space_manager, - NULL ); - } - } - else - { - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - } - } - for( test_number = 0; - test_number < number_of_memset_fail_tests; - test_number++ ) - { - /* Test libfsapfs_container_space_manager_initialize with memset failing - */ - fsapfs_test_memset_attempts_before_fail = test_number; - - result = libfsapfs_container_space_manager_initialize( - &container_space_manager, - &error ); - - if( fsapfs_test_memset_attempts_before_fail != -1 ) - { - fsapfs_test_memset_attempts_before_fail = -1; - - if( container_space_manager != NULL ) - { - libfsapfs_container_space_manager_free( - &container_space_manager, - NULL ); - } - } - else - { - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - } - } -#endif /* defined( HAVE_FSAPFS_TEST_MEMORY ) */ - - return( 1 ); - -on_error: - if( error != NULL ) - { - libcerror_error_free( - &error ); - } - if( container_space_manager != NULL ) - { - libfsapfs_container_space_manager_free( - &container_space_manager, - NULL ); - } - return( 0 ); -} - -/* Tests the libfsapfs_container_space_manager_free function - * Returns 1 if successful or 0 if not - */ -int fsapfs_test_container_space_manager_free( - void ) -{ - libcerror_error_t *error = NULL; - int result = 0; - - /* Test error cases - */ - result = libfsapfs_container_space_manager_free( - NULL, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - return( 1 ); - -on_error: - if( error != NULL ) - { - libcerror_error_free( - &error ); - } - return( 0 ); -} - -/* Tests the libfsapfs_container_space_manager_read_file_io_handle function - * Returns 1 if successful or 0 if not - */ -int fsapfs_test_container_space_manager_read_file_io_handle( - void ) -{ - libbfio_handle_t *file_io_handle = NULL; - libcerror_error_t *error = NULL; - libfsapfs_container_space_manager_t *container_space_manager = NULL; - int result = 0; - - /* Initialize test - */ - result = libfsapfs_container_space_manager_initialize( - &container_space_manager, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Initialize file IO handle - */ - result = fsapfs_test_open_file_io_handle( - &file_io_handle, - fsapfs_test_container_space_manager_data1, - 4096, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "file_io_handle", - file_io_handle ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test regular cases - */ - result = libfsapfs_container_space_manager_read_file_io_handle( - container_space_manager, - file_io_handle, - 0, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test error cases - */ - result = libfsapfs_container_space_manager_read_file_io_handle( - NULL, - file_io_handle, - 0, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - result = libfsapfs_container_space_manager_read_file_io_handle( - container_space_manager, - NULL, - 0, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - result = libfsapfs_container_space_manager_read_file_io_handle( - container_space_manager, - file_io_handle, - -1, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - /* Clean up file IO handle - */ - result = fsapfs_test_close_file_io_handle( - &file_io_handle, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 0 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test data too small - */ - result = fsapfs_test_open_file_io_handle( - &file_io_handle, - fsapfs_test_container_space_manager_data1, - 8, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "file_io_handle", - file_io_handle ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - result = libfsapfs_container_space_manager_read_file_io_handle( - container_space_manager, - file_io_handle, - 0, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - result = fsapfs_test_close_file_io_handle( - &file_io_handle, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 0 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - -/* TODO: test data invalid */ - - /* Clean up - */ - result = libfsapfs_container_space_manager_free( - &container_space_manager, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - return( 1 ); - -on_error: - if( error != NULL ) - { - libcerror_error_free( - &error ); - } - if( file_io_handle != NULL ) - { - libbfio_handle_free( - &file_io_handle, - NULL ); - } - if( container_space_manager != NULL ) - { - libfsapfs_container_space_manager_free( - &container_space_manager, - NULL ); - } - return( 0 ); -} - -/* Tests the libfsapfs_container_space_manager_read_data function - * Returns 1 if successful or 0 if not - */ -int fsapfs_test_container_space_manager_read_data( - void ) -{ - libcerror_error_t *error = NULL; - libfsapfs_container_space_manager_t *container_space_manager = NULL; - int result = 0; - - /* Initialize test - */ - result = libfsapfs_container_space_manager_initialize( - &container_space_manager, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test regular cases - */ - result = libfsapfs_container_space_manager_read_data( - container_space_manager, - fsapfs_test_container_space_manager_data1, - 4096, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test error cases - */ - result = libfsapfs_container_space_manager_read_data( - NULL, - fsapfs_test_container_space_manager_data1, - 4096, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - result = libfsapfs_container_space_manager_read_data( - container_space_manager, - NULL, - 4096, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - result = libfsapfs_container_space_manager_read_data( - container_space_manager, - fsapfs_test_container_space_manager_data1, - (size_t) SSIZE_MAX + 1, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - result = libfsapfs_container_space_manager_read_data( - container_space_manager, - fsapfs_test_container_space_manager_data1, - 0, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - -1 ); - - FSAPFS_TEST_ASSERT_IS_NOT_NULL( - "error", - error ); - - libcerror_error_free( - &error ); - - /* Clean up - */ - result = libfsapfs_container_space_manager_free( - &container_space_manager, - &error ); - - FSAPFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "container_space_manager", - container_space_manager ); - - FSAPFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - return( 1 ); - -on_error: - if( error != NULL ) - { - libcerror_error_free( - &error ); - } - if( container_space_manager != NULL ) - { - libfsapfs_container_space_manager_free( - &container_space_manager, - NULL ); - } - return( 0 ); -} - -#endif /* defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) */ - -/* The main program - */ -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) -int wmain( - int argc FSAPFS_TEST_ATTRIBUTE_UNUSED, - wchar_t * const argv[] FSAPFS_TEST_ATTRIBUTE_UNUSED ) -#else -int main( - int argc FSAPFS_TEST_ATTRIBUTE_UNUSED, - char * const argv[] FSAPFS_TEST_ATTRIBUTE_UNUSED ) -#endif -{ - FSAPFS_TEST_UNREFERENCED_PARAMETER( argc ) - FSAPFS_TEST_UNREFERENCED_PARAMETER( argv ) - -#if defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) - - FSAPFS_TEST_RUN( - "libfsapfs_container_space_manager_initialize", - fsapfs_test_container_space_manager_initialize ); - - FSAPFS_TEST_RUN( - "libfsapfs_container_space_manager_free", - fsapfs_test_container_space_manager_free ); - - FSAPFS_TEST_RUN( - "libfsapfs_container_space_manager_read_file_io_handle", - fsapfs_test_container_space_manager_read_file_io_handle ); - - FSAPFS_TEST_RUN( - "libfsapfs_container_space_manager_read_data", - fsapfs_test_container_space_manager_read_data ); - -#endif /* defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) */ - - return( EXIT_SUCCESS ); - -on_error: - return( EXIT_FAILURE ); -} - diff -Nru libfsapfs-20181215/tests/fsapfs_test_container_superblock.c libfsapfs-20190210/tests/fsapfs_test_container_superblock.c --- libfsapfs-20181215/tests/fsapfs_test_container_superblock.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_container_superblock.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library container_superblock type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_data_block.c libfsapfs-20190210/tests/fsapfs_test_data_block.c --- libfsapfs-20181215/tests/fsapfs_test_data_block.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_data_block.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library data_block type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_directory_record.c libfsapfs-20190210/tests/fsapfs_test_directory_record.c --- libfsapfs-20181215/tests/fsapfs_test_directory_record.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_directory_record.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library directory_record type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_encryption_context.c libfsapfs-20190210/tests/fsapfs_test_encryption_context.c --- libfsapfs-20181215/tests/fsapfs_test_encryption_context.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_encryption_context.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library encryption_context type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_error.c libfsapfs-20190210/tests/fsapfs_test_error.c --- libfsapfs-20181215/tests/fsapfs_test_error.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_error.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library error functions test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_file_extent.c libfsapfs-20190210/tests/fsapfs_test_file_extent.c --- libfsapfs-20181215/tests/fsapfs_test_file_extent.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_file_extent.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library file_extent type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_file_system_btree.c libfsapfs-20190210/tests/fsapfs_test_file_system_btree.c --- libfsapfs-20181215/tests/fsapfs_test_file_system_btree.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_file_system_btree.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library file_system_btree type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_functions.c libfsapfs-20190210/tests/fsapfs_test_functions.c --- libfsapfs-20181215/tests/fsapfs_test_functions.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_functions.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Functions for testing * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_functions.h libfsapfs-20190210/tests/fsapfs_test_functions.h --- libfsapfs-20181215/tests/fsapfs_test_functions.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_functions.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Functions for testing * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_getopt.c libfsapfs-20190210/tests/fsapfs_test_getopt.c --- libfsapfs-20181215/tests/fsapfs_test_getopt.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_getopt.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * GetOpt functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_getopt.h libfsapfs-20190210/tests/fsapfs_test_getopt.h --- libfsapfs-20181215/tests/fsapfs_test_getopt.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_getopt.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * GetOpt functions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_inode.c libfsapfs-20190210/tests/fsapfs_test_inode.c --- libfsapfs-20181215/tests/fsapfs_test_inode.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_inode.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library inode type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_io_handle.c libfsapfs-20190210/tests/fsapfs_test_io_handle.c --- libfsapfs-20181215/tests/fsapfs_test_io_handle.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_io_handle.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library io_handle type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_key_bag_entry.c libfsapfs-20190210/tests/fsapfs_test_key_bag_entry.c --- libfsapfs-20181215/tests/fsapfs_test_key_bag_entry.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_key_bag_entry.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library key_bag_entry type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_key_bag_header.c libfsapfs-20190210/tests/fsapfs_test_key_bag_header.c --- libfsapfs-20181215/tests/fsapfs_test_key_bag_header.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_key_bag_header.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library key_bag_header type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_key_encrypted_key.c libfsapfs-20190210/tests/fsapfs_test_key_encrypted_key.c --- libfsapfs-20181215/tests/fsapfs_test_key_encrypted_key.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_key_encrypted_key.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library key_encrypted_key type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_libbfio.h libfsapfs-20190210/tests/fsapfs_test_libbfio.h --- libfsapfs-20181215/tests/fsapfs_test_libbfio.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_libbfio.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libbfio header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_libcerror.h libfsapfs-20190210/tests/fsapfs_test_libcerror.h --- libfsapfs-20181215/tests/fsapfs_test_libcerror.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_libcerror.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcerror header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_libclocale.h libfsapfs-20190210/tests/fsapfs_test_libclocale.h --- libfsapfs-20181215/tests/fsapfs_test_libclocale.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_libclocale.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libclocale header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_libcnotify.h libfsapfs-20190210/tests/fsapfs_test_libcnotify.h --- libfsapfs-20181215/tests/fsapfs_test_libcnotify.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_libcnotify.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libcnotify header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_libfdata.h libfsapfs-20190210/tests/fsapfs_test_libfdata.h --- libfsapfs-20181215/tests/fsapfs_test_libfdata.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_libfdata.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfdata header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_libfsapfs.h libfsapfs-20190210/tests/fsapfs_test_libfsapfs.h --- libfsapfs-20181215/tests/fsapfs_test_libfsapfs.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_libfsapfs.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libfsapfs header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_libuna.h libfsapfs-20190210/tests/fsapfs_test_libuna.h --- libfsapfs-20181215/tests/fsapfs_test_libuna.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_libuna.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * The libuna header wrapper * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_macros.h libfsapfs-20190210/tests/fsapfs_test_macros.h --- libfsapfs-20181215/tests/fsapfs_test_macros.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_macros.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Macros for testing * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_memory.c libfsapfs-20190210/tests/fsapfs_test_memory.c --- libfsapfs-20181215/tests/fsapfs_test_memory.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_memory.c 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Memory allocation functions for testing * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_memory.h libfsapfs-20190210/tests/fsapfs_test_memory.h --- libfsapfs-20181215/tests/fsapfs_test_memory.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_memory.h 2019-02-06 20:10:15.000000000 +0000 @@ -1,7 +1,7 @@ /* * Memory allocation functions for testing * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_name.c libfsapfs-20190210/tests/fsapfs_test_name.c --- libfsapfs-20181215/tests/fsapfs_test_name.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_name.c 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library name functions test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_name_hash.c libfsapfs-20190210/tests/fsapfs_test_name_hash.c --- libfsapfs-20181215/tests/fsapfs_test_name_hash.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_name_hash.c 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library name_hash functions test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_notify.c libfsapfs-20190210/tests/fsapfs_test_notify.c --- libfsapfs-20181215/tests/fsapfs_test_notify.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_notify.c 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library notification functions test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_object.c libfsapfs-20190210/tests/fsapfs_test_object.c --- libfsapfs-20181215/tests/fsapfs_test_object.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_object.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library object type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_object_map_btree.c libfsapfs-20190210/tests/fsapfs_test_object_map_btree.c --- libfsapfs-20181215/tests/fsapfs_test_object_map_btree.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_object_map_btree.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library object_map_btree type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_object_map.c libfsapfs-20190210/tests/fsapfs_test_object_map.c --- libfsapfs-20181215/tests/fsapfs_test_object_map.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_object_map.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library object_map type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_object_map_descriptor.c libfsapfs-20190210/tests/fsapfs_test_object_map_descriptor.c --- libfsapfs-20181215/tests/fsapfs_test_object_map_descriptor.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_object_map_descriptor.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library object_map_descriptor type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_rwlock.c libfsapfs-20190210/tests/fsapfs_test_rwlock.c --- libfsapfs-20181215/tests/fsapfs_test_rwlock.c 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_rwlock.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Read/Write lock functions for testing * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_rwlock.h libfsapfs-20190210/tests/fsapfs_test_rwlock.h --- libfsapfs-20181215/tests/fsapfs_test_rwlock.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_rwlock.h 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* * Read/Write lock functions for testing * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -24,11 +24,13 @@ #include +#include "fsapfs_test_libfsapfs.h" + #if defined( __cplusplus ) extern "C" { #endif -#if defined( HAVE_GNU_DL_DLSYM ) && defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __CYGWIN__ ) +#if defined( LIBFSAPFS_HAVE_MULTI_THREAD_SUPPORT ) && defined( HAVE_GNU_DL_DLSYM ) && defined( __GNUC__ ) && !defined( __clang__ ) && !defined( __CYGWIN__ ) #define HAVE_FSAPFS_TEST_RWLOCK 1 #endif diff -Nru libfsapfs-20181215/tests/fsapfs_test_space_manager.c libfsapfs-20190210/tests/fsapfs_test_space_manager.c --- libfsapfs-20181215/tests/fsapfs_test_space_manager.c 1970-01-01 00:00:00.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_space_manager.c 2019-02-06 20:13:54.000000000 +0000 @@ -0,0 +1,965 @@ +/* + * Library space_manager type test program + * + * Copyright (C) 2018-2019, Joachim Metz + * + * Refer to AUTHORS for acknowledgements. + * + * This software is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this software. If not, see . + */ + +#include +#include +#include + +#if defined( HAVE_STDLIB_H ) || defined( WINAPI ) +#include +#endif + +#include "fsapfs_test_functions.h" +#include "fsapfs_test_libcerror.h" +#include "fsapfs_test_libfsapfs.h" +#include "fsapfs_test_macros.h" +#include "fsapfs_test_memory.h" +#include "fsapfs_test_unused.h" + +#include "../libfsapfs/libfsapfs_space_manager.h" + +uint8_t fsapfs_test_space_manager_data1[ 4096 ] = { + 0xca, 0x56, 0x9b, 0xf0, 0x49, 0xce, 0x1c, 0x8f, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0xfb, 0x01, 0x00, 0x00, + 0xf6, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x0f, 0x00, 0xd8, 0x09, 0x00, 0x00, 0xe0, 0x09, 0x00, 0x00, 0xe8, 0x09, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0xd8, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 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, 0xff, 0xff, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +#if defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) + +/* Tests the libfsapfs_space_manager_initialize function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_space_manager_initialize( + void ) +{ + libcerror_error_t *error = NULL; + libfsapfs_space_manager_t *space_manager = NULL; + int result = 0; + +#if defined( HAVE_FSAPFS_TEST_MEMORY ) + int number_of_malloc_fail_tests = 1; + int number_of_memset_fail_tests = 1; + int test_number = 0; +#endif + + /* Test regular cases + */ + result = libfsapfs_space_manager_initialize( + &space_manager, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libfsapfs_space_manager_free( + &space_manager, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ + result = libfsapfs_space_manager_initialize( + NULL, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + space_manager = (libfsapfs_space_manager_t *) 0x12345678UL; + + result = libfsapfs_space_manager_initialize( + &space_manager, + &error ); + + space_manager = NULL; + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + +#if defined( HAVE_FSAPFS_TEST_MEMORY ) + + for( test_number = 0; + test_number < number_of_malloc_fail_tests; + test_number++ ) + { + /* Test libfsapfs_space_manager_initialize with malloc failing + */ + fsapfs_test_malloc_attempts_before_fail = test_number; + + result = libfsapfs_space_manager_initialize( + &space_manager, + &error ); + + if( fsapfs_test_malloc_attempts_before_fail != -1 ) + { + fsapfs_test_malloc_attempts_before_fail = -1; + + if( space_manager != NULL ) + { + libfsapfs_space_manager_free( + &space_manager, + NULL ); + } + } + else + { + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + } + } + for( test_number = 0; + test_number < number_of_memset_fail_tests; + test_number++ ) + { + /* Test libfsapfs_space_manager_initialize with memset failing + */ + fsapfs_test_memset_attempts_before_fail = test_number; + + result = libfsapfs_space_manager_initialize( + &space_manager, + &error ); + + if( fsapfs_test_memset_attempts_before_fail != -1 ) + { + fsapfs_test_memset_attempts_before_fail = -1; + + if( space_manager != NULL ) + { + libfsapfs_space_manager_free( + &space_manager, + NULL ); + } + } + else + { + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + } + } +#endif /* defined( HAVE_FSAPFS_TEST_MEMORY ) */ + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + if( space_manager != NULL ) + { + libfsapfs_space_manager_free( + &space_manager, + NULL ); + } + return( 0 ); +} + +/* Tests the libfsapfs_space_manager_free function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_space_manager_free( + void ) +{ + libcerror_error_t *error = NULL; + int result = 0; + + /* Test error cases + */ + result = libfsapfs_space_manager_free( + NULL, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + return( 0 ); +} + +/* Tests the libfsapfs_space_manager_read_file_io_handle function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_space_manager_read_file_io_handle( + void ) +{ + libbfio_handle_t *file_io_handle = NULL; + libcerror_error_t *error = NULL; + libfsapfs_space_manager_t *space_manager = NULL; + int result = 0; + + /* Initialize test + */ + result = libfsapfs_space_manager_initialize( + &space_manager, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Initialize file IO handle + */ + result = fsapfs_test_open_file_io_handle( + &file_io_handle, + fsapfs_test_space_manager_data1, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "file_io_handle", + file_io_handle ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test regular cases + */ + result = libfsapfs_space_manager_read_file_io_handle( + space_manager, + file_io_handle, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ + result = libfsapfs_space_manager_read_file_io_handle( + NULL, + file_io_handle, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_space_manager_read_file_io_handle( + space_manager, + NULL, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_space_manager_read_file_io_handle( + space_manager, + file_io_handle, + -1, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + /* Clean up file IO handle + */ + result = fsapfs_test_close_file_io_handle( + &file_io_handle, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test data too small + */ + result = fsapfs_test_open_file_io_handle( + &file_io_handle, + fsapfs_test_space_manager_data1, + 8, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "file_io_handle", + file_io_handle ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libfsapfs_space_manager_read_file_io_handle( + space_manager, + file_io_handle, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = fsapfs_test_close_file_io_handle( + &file_io_handle, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + +/* TODO: test data invalid */ + + /* Clean up + */ + result = libfsapfs_space_manager_free( + &space_manager, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + if( file_io_handle != NULL ) + { + libbfio_handle_free( + &file_io_handle, + NULL ); + } + if( space_manager != NULL ) + { + libfsapfs_space_manager_free( + &space_manager, + NULL ); + } + return( 0 ); +} + +/* Tests the libfsapfs_space_manager_read_data function + * Returns 1 if successful or 0 if not + */ +int fsapfs_test_space_manager_read_data( + void ) +{ + libcerror_error_t *error = NULL; + libfsapfs_space_manager_t *space_manager = NULL; + int result = 0; + + /* Initialize test + */ + result = libfsapfs_space_manager_initialize( + &space_manager, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test regular cases + */ + result = libfsapfs_space_manager_read_data( + space_manager, + fsapfs_test_space_manager_data1, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ + result = libfsapfs_space_manager_read_data( + NULL, + fsapfs_test_space_manager_data1, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_space_manager_read_data( + space_manager, + NULL, + 4096, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_space_manager_read_data( + space_manager, + fsapfs_test_space_manager_data1, + (size_t) SSIZE_MAX + 1, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + result = libfsapfs_space_manager_read_data( + space_manager, + fsapfs_test_space_manager_data1, + 0, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSAPFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + /* Clean up + */ + result = libfsapfs_space_manager_free( + &space_manager, + &error ); + + FSAPFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "space_manager", + space_manager ); + + FSAPFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + if( space_manager != NULL ) + { + libfsapfs_space_manager_free( + &space_manager, + NULL ); + } + return( 0 ); +} + +#endif /* defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) */ + +/* The main program + */ +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) +int wmain( + int argc FSAPFS_TEST_ATTRIBUTE_UNUSED, + wchar_t * const argv[] FSAPFS_TEST_ATTRIBUTE_UNUSED ) +#else +int main( + int argc FSAPFS_TEST_ATTRIBUTE_UNUSED, + char * const argv[] FSAPFS_TEST_ATTRIBUTE_UNUSED ) +#endif +{ + FSAPFS_TEST_UNREFERENCED_PARAMETER( argc ) + FSAPFS_TEST_UNREFERENCED_PARAMETER( argv ) + +#if defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) + + FSAPFS_TEST_RUN( + "libfsapfs_space_manager_initialize", + fsapfs_test_space_manager_initialize ); + + FSAPFS_TEST_RUN( + "libfsapfs_space_manager_free", + fsapfs_test_space_manager_free ); + + FSAPFS_TEST_RUN( + "libfsapfs_space_manager_read_file_io_handle", + fsapfs_test_space_manager_read_file_io_handle ); + + FSAPFS_TEST_RUN( + "libfsapfs_space_manager_read_data", + fsapfs_test_space_manager_read_data ); + +#endif /* defined( __GNUC__ ) && !defined( LIBFSAPFS_DLL_IMPORT ) */ + + return( EXIT_SUCCESS ); + +on_error: + return( EXIT_FAILURE ); +} + diff -Nru libfsapfs-20181215/tests/fsapfs_test_support.c libfsapfs-20190210/tests/fsapfs_test_support.c --- libfsapfs-20181215/tests/fsapfs_test_support.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_support.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library support functions test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_types.h libfsapfs-20190210/tests/fsapfs_test_types.h --- libfsapfs-20181215/tests/fsapfs_test_types.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_types.h 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* * The type definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_unicode_case_folding_mappings.h libfsapfs-20190210/tests/fsapfs_test_unicode_case_folding_mappings.h --- libfsapfs-20181215/tests/fsapfs_test_unicode_case_folding_mappings.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_unicode_case_folding_mappings.h 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* * The Unicode case folding mappings definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_unicode_decomposition_mappings.h libfsapfs-20190210/tests/fsapfs_test_unicode_decomposition_mappings.h --- libfsapfs-20181215/tests/fsapfs_test_unicode_decomposition_mappings.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_unicode_decomposition_mappings.h 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* * The Unicode decomposition mappings definitions * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_unused.h libfsapfs-20190210/tests/fsapfs_test_unused.h --- libfsapfs-20181215/tests/fsapfs_test_unused.h 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_unused.h 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ /* - * The unused definition + * Definitions to silence compiler warnings about unused function attributes/parameters. * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_volume.c libfsapfs-20190210/tests/fsapfs_test_volume.c --- libfsapfs-20181215/tests/fsapfs_test_volume.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_volume.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library volume type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * @@ -1178,7 +1178,9 @@ "libfsapfs_volume_open_close", fsapfs_test_volume_open_close, source ); - + } + if( result != 0 ) + { /* Initialize test */ result = fsapfs_test_volume_open_source( diff -Nru libfsapfs-20181215/tests/fsapfs_test_volume_key_bag.c libfsapfs-20190210/tests/fsapfs_test_volume_key_bag.c --- libfsapfs-20181215/tests/fsapfs_test_volume_key_bag.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_volume_key_bag.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library volume_key_bag type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/fsapfs_test_volume_superblock.c libfsapfs-20190210/tests/fsapfs_test_volume_superblock.c --- libfsapfs-20181215/tests/fsapfs_test_volume_superblock.c 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/fsapfs_test_volume_superblock.c 2019-02-06 20:13:54.000000000 +0000 @@ -1,7 +1,7 @@ /* * Library volume_superblock type test program * - * Copyright (C) 2018, Joachim Metz + * Copyright (C) 2018-2019, Joachim Metz * * Refer to AUTHORS for acknowledgements. * diff -Nru libfsapfs-20181215/tests/Makefile.am libfsapfs-20190210/tests/Makefile.am --- libfsapfs-20181215/tests/Makefile.am 2018-12-03 17:51:35.000000000 +0000 +++ libfsapfs-20190210/tests/Makefile.am 2019-02-06 20:13:54.000000000 +0000 @@ -51,13 +51,13 @@ fsapfs_test_checkpoint_map \ fsapfs_test_checkpoint_map_entry \ fsapfs_test_checksum \ + fsapfs_test_chunk_information_block \ fsapfs_test_compressed_data_handle \ fsapfs_test_compression \ fsapfs_test_container \ fsapfs_test_container_data_handle \ fsapfs_test_container_key_bag \ fsapfs_test_container_reaper \ - fsapfs_test_container_space_manager \ fsapfs_test_container_superblock \ fsapfs_test_data_block \ fsapfs_test_directory_record \ @@ -77,6 +77,7 @@ fsapfs_test_object_map \ fsapfs_test_object_map_btree \ fsapfs_test_object_map_descriptor \ + fsapfs_test_space_manager \ fsapfs_test_support \ fsapfs_test_volume \ fsapfs_test_volume_key_bag \ @@ -187,6 +188,28 @@ ../libfsapfs/libfsapfs.la \ @LIBCERROR_LIBADD@ +fsapfs_test_chunk_information_block_SOURCES = \ + fsapfs_test_chunk_information_block.c \ + fsapfs_test_functions.c fsapfs_test_functions.h \ + fsapfs_test_libbfio.h \ + fsapfs_test_libcerror.h \ + fsapfs_test_libfsapfs.h \ + fsapfs_test_macros.h \ + fsapfs_test_memory.c fsapfs_test_memory.h \ + fsapfs_test_unused.h + +fsapfs_test_chunk_information_block_LDADD = \ + @LIBBFIO_LIBADD@ \ + @LIBCPATH_LIBADD@ \ + @LIBCFILE_LIBADD@ \ + @LIBUNA_LIBADD@ \ + @LIBCSPLIT_LIBADD@ \ + @LIBCNOTIFY_LIBADD@ \ + @LIBCLOCALE_LIBADD@ \ + @LIBCDATA_LIBADD@ \ + ../libfsapfs/libfsapfs.la \ + @LIBCERROR_LIBADD@ + fsapfs_test_compressed_data_handle_SOURCES = \ fsapfs_test_compressed_data_handle.c \ fsapfs_test_libcerror.h \ @@ -297,28 +320,6 @@ ../libfsapfs/libfsapfs.la \ @LIBCERROR_LIBADD@ -fsapfs_test_container_space_manager_SOURCES = \ - fsapfs_test_container_space_manager.c \ - fsapfs_test_functions.c fsapfs_test_functions.h \ - fsapfs_test_libbfio.h \ - fsapfs_test_libcerror.h \ - fsapfs_test_libfsapfs.h \ - fsapfs_test_macros.h \ - fsapfs_test_memory.c fsapfs_test_memory.h \ - fsapfs_test_unused.h - -fsapfs_test_container_space_manager_LDADD = \ - @LIBBFIO_LIBADD@ \ - @LIBCPATH_LIBADD@ \ - @LIBCFILE_LIBADD@ \ - @LIBUNA_LIBADD@ \ - @LIBCSPLIT_LIBADD@ \ - @LIBCNOTIFY_LIBADD@ \ - @LIBCLOCALE_LIBADD@ \ - @LIBCDATA_LIBADD@ \ - ../libfsapfs/libfsapfs.la \ - @LIBCERROR_LIBADD@ - fsapfs_test_container_superblock_SOURCES = \ fsapfs_test_container_superblock.c \ fsapfs_test_functions.c fsapfs_test_functions.h \ @@ -595,6 +596,28 @@ ../libfsapfs/libfsapfs.la \ @LIBCERROR_LIBADD@ +fsapfs_test_space_manager_SOURCES = \ + fsapfs_test_functions.c fsapfs_test_functions.h \ + fsapfs_test_libbfio.h \ + fsapfs_test_libcerror.h \ + fsapfs_test_libfsapfs.h \ + fsapfs_test_macros.h \ + fsapfs_test_memory.c fsapfs_test_memory.h \ + fsapfs_test_space_manager.c \ + fsapfs_test_unused.h + +fsapfs_test_space_manager_LDADD = \ + @LIBBFIO_LIBADD@ \ + @LIBCPATH_LIBADD@ \ + @LIBCFILE_LIBADD@ \ + @LIBUNA_LIBADD@ \ + @LIBCSPLIT_LIBADD@ \ + @LIBCNOTIFY_LIBADD@ \ + @LIBCLOCALE_LIBADD@ \ + @LIBCDATA_LIBADD@ \ + ../libfsapfs/libfsapfs.la \ + @LIBCERROR_LIBADD@ + fsapfs_test_support_SOURCES = \ fsapfs_test_functions.c fsapfs_test_functions.h \ fsapfs_test_getopt.c fsapfs_test_getopt.h \ diff -Nru libfsapfs-20181215/tests/Makefile.in libfsapfs-20190210/tests/Makefile.in --- libfsapfs-20181215/tests/Makefile.in 2018-12-15 06:44:02.000000000 +0000 +++ libfsapfs-20190210/tests/Makefile.in 2019-02-10 19:59:40.000000000 +0000 @@ -95,13 +95,13 @@ fsapfs_test_checkpoint_map$(EXEEXT) \ fsapfs_test_checkpoint_map_entry$(EXEEXT) \ fsapfs_test_checksum$(EXEEXT) \ + fsapfs_test_chunk_information_block$(EXEEXT) \ fsapfs_test_compressed_data_handle$(EXEEXT) \ fsapfs_test_compression$(EXEEXT) \ fsapfs_test_container$(EXEEXT) \ fsapfs_test_container_data_handle$(EXEEXT) \ fsapfs_test_container_key_bag$(EXEEXT) \ fsapfs_test_container_reaper$(EXEEXT) \ - fsapfs_test_container_space_manager$(EXEEXT) \ fsapfs_test_container_superblock$(EXEEXT) \ fsapfs_test_data_block$(EXEEXT) \ fsapfs_test_directory_record$(EXEEXT) \ @@ -117,6 +117,7 @@ fsapfs_test_object_map$(EXEEXT) \ fsapfs_test_object_map_btree$(EXEEXT) \ fsapfs_test_object_map_descriptor$(EXEEXT) \ + fsapfs_test_space_manager$(EXEEXT) \ fsapfs_test_support$(EXEEXT) fsapfs_test_volume$(EXEEXT) \ fsapfs_test_volume_key_bag$(EXEEXT) \ fsapfs_test_volume_superblock$(EXEEXT) @@ -200,6 +201,13 @@ fsapfs_test_memory.$(OBJEXT) fsapfs_test_checksum_OBJECTS = $(am_fsapfs_test_checksum_OBJECTS) fsapfs_test_checksum_DEPENDENCIES = ../libfsapfs/libfsapfs.la +am_fsapfs_test_chunk_information_block_OBJECTS = \ + fsapfs_test_chunk_information_block.$(OBJEXT) \ + fsapfs_test_functions.$(OBJEXT) fsapfs_test_memory.$(OBJEXT) +fsapfs_test_chunk_information_block_OBJECTS = \ + $(am_fsapfs_test_chunk_information_block_OBJECTS) +fsapfs_test_chunk_information_block_DEPENDENCIES = \ + ../libfsapfs/libfsapfs.la am_fsapfs_test_compressed_data_handle_OBJECTS = \ fsapfs_test_compressed_data_handle.$(OBJEXT) \ fsapfs_test_memory.$(OBJEXT) @@ -237,13 +245,6 @@ fsapfs_test_container_reaper_OBJECTS = \ $(am_fsapfs_test_container_reaper_OBJECTS) fsapfs_test_container_reaper_DEPENDENCIES = ../libfsapfs/libfsapfs.la -am_fsapfs_test_container_space_manager_OBJECTS = \ - fsapfs_test_container_space_manager.$(OBJEXT) \ - fsapfs_test_functions.$(OBJEXT) fsapfs_test_memory.$(OBJEXT) -fsapfs_test_container_space_manager_OBJECTS = \ - $(am_fsapfs_test_container_space_manager_OBJECTS) -fsapfs_test_container_space_manager_DEPENDENCIES = \ - ../libfsapfs/libfsapfs.la am_fsapfs_test_container_superblock_OBJECTS = \ fsapfs_test_container_superblock.$(OBJEXT) \ fsapfs_test_functions.$(OBJEXT) fsapfs_test_memory.$(OBJEXT) @@ -342,6 +343,12 @@ $(am_fsapfs_test_object_map_descriptor_OBJECTS) fsapfs_test_object_map_descriptor_DEPENDENCIES = \ ../libfsapfs/libfsapfs.la +am_fsapfs_test_space_manager_OBJECTS = \ + fsapfs_test_functions.$(OBJEXT) fsapfs_test_memory.$(OBJEXT) \ + fsapfs_test_space_manager.$(OBJEXT) +fsapfs_test_space_manager_OBJECTS = \ + $(am_fsapfs_test_space_manager_OBJECTS) +fsapfs_test_space_manager_DEPENDENCIES = ../libfsapfs/libfsapfs.la am_fsapfs_test_support_OBJECTS = fsapfs_test_functions.$(OBJEXT) \ fsapfs_test_getopt.$(OBJEXT) fsapfs_test_memory.$(OBJEXT) \ fsapfs_test_support.$(OBJEXT) @@ -388,13 +395,13 @@ ./$(DEPDIR)/fsapfs_test_checkpoint_map.Po \ ./$(DEPDIR)/fsapfs_test_checkpoint_map_entry.Po \ ./$(DEPDIR)/fsapfs_test_checksum.Po \ + ./$(DEPDIR)/fsapfs_test_chunk_information_block.Po \ ./$(DEPDIR)/fsapfs_test_compressed_data_handle.Po \ ./$(DEPDIR)/fsapfs_test_compression.Po \ ./$(DEPDIR)/fsapfs_test_container.Po \ ./$(DEPDIR)/fsapfs_test_container_data_handle.Po \ ./$(DEPDIR)/fsapfs_test_container_key_bag.Po \ ./$(DEPDIR)/fsapfs_test_container_reaper.Po \ - ./$(DEPDIR)/fsapfs_test_container_space_manager.Po \ ./$(DEPDIR)/fsapfs_test_container_superblock.Po \ ./$(DEPDIR)/fsapfs_test_data_block.Po \ ./$(DEPDIR)/fsapfs_test_directory_record.Po \ @@ -418,6 +425,7 @@ ./$(DEPDIR)/fsapfs_test_object_map_btree.Po \ ./$(DEPDIR)/fsapfs_test_object_map_descriptor.Po \ ./$(DEPDIR)/fsapfs_test_rwlock.Po \ + ./$(DEPDIR)/fsapfs_test_space_manager.Po \ ./$(DEPDIR)/fsapfs_test_support.Po \ ./$(DEPDIR)/fsapfs_test_volume.Po \ ./$(DEPDIR)/fsapfs_test_volume_key_bag.Po \ @@ -449,13 +457,13 @@ $(fsapfs_test_checkpoint_map_SOURCES) \ $(fsapfs_test_checkpoint_map_entry_SOURCES) \ $(fsapfs_test_checksum_SOURCES) \ + $(fsapfs_test_chunk_information_block_SOURCES) \ $(fsapfs_test_compressed_data_handle_SOURCES) \ $(fsapfs_test_compression_SOURCES) \ $(fsapfs_test_container_SOURCES) \ $(fsapfs_test_container_data_handle_SOURCES) \ $(fsapfs_test_container_key_bag_SOURCES) \ $(fsapfs_test_container_reaper_SOURCES) \ - $(fsapfs_test_container_space_manager_SOURCES) \ $(fsapfs_test_container_superblock_SOURCES) \ $(fsapfs_test_data_block_SOURCES) \ $(fsapfs_test_directory_record_SOURCES) \ @@ -472,6 +480,7 @@ $(fsapfs_test_object_map_SOURCES) \ $(fsapfs_test_object_map_btree_SOURCES) \ $(fsapfs_test_object_map_descriptor_SOURCES) \ + $(fsapfs_test_space_manager_SOURCES) \ $(fsapfs_test_support_SOURCES) $(fsapfs_test_volume_SOURCES) \ $(fsapfs_test_volume_key_bag_SOURCES) \ $(fsapfs_test_volume_superblock_SOURCES) @@ -483,13 +492,13 @@ $(fsapfs_test_checkpoint_map_SOURCES) \ $(fsapfs_test_checkpoint_map_entry_SOURCES) \ $(fsapfs_test_checksum_SOURCES) \ + $(fsapfs_test_chunk_information_block_SOURCES) \ $(fsapfs_test_compressed_data_handle_SOURCES) \ $(fsapfs_test_compression_SOURCES) \ $(fsapfs_test_container_SOURCES) \ $(fsapfs_test_container_data_handle_SOURCES) \ $(fsapfs_test_container_key_bag_SOURCES) \ $(fsapfs_test_container_reaper_SOURCES) \ - $(fsapfs_test_container_space_manager_SOURCES) \ $(fsapfs_test_container_superblock_SOURCES) \ $(fsapfs_test_data_block_SOURCES) \ $(fsapfs_test_directory_record_SOURCES) \ @@ -506,6 +515,7 @@ $(fsapfs_test_object_map_SOURCES) \ $(fsapfs_test_object_map_btree_SOURCES) \ $(fsapfs_test_object_map_descriptor_SOURCES) \ + $(fsapfs_test_space_manager_SOURCES) \ $(fsapfs_test_support_SOURCES) $(fsapfs_test_volume_SOURCES) \ $(fsapfs_test_volume_key_bag_SOURCES) \ $(fsapfs_test_volume_superblock_SOURCES) @@ -1255,6 +1265,28 @@ ../libfsapfs/libfsapfs.la \ @LIBCERROR_LIBADD@ +fsapfs_test_chunk_information_block_SOURCES = \ + fsapfs_test_chunk_information_block.c \ + fsapfs_test_functions.c fsapfs_test_functions.h \ + fsapfs_test_libbfio.h \ + fsapfs_test_libcerror.h \ + fsapfs_test_libfsapfs.h \ + fsapfs_test_macros.h \ + fsapfs_test_memory.c fsapfs_test_memory.h \ + fsapfs_test_unused.h + +fsapfs_test_chunk_information_block_LDADD = \ + @LIBBFIO_LIBADD@ \ + @LIBCPATH_LIBADD@ \ + @LIBCFILE_LIBADD@ \ + @LIBUNA_LIBADD@ \ + @LIBCSPLIT_LIBADD@ \ + @LIBCNOTIFY_LIBADD@ \ + @LIBCLOCALE_LIBADD@ \ + @LIBCDATA_LIBADD@ \ + ../libfsapfs/libfsapfs.la \ + @LIBCERROR_LIBADD@ + fsapfs_test_compressed_data_handle_SOURCES = \ fsapfs_test_compressed_data_handle.c \ fsapfs_test_libcerror.h \ @@ -1365,28 +1397,6 @@ ../libfsapfs/libfsapfs.la \ @LIBCERROR_LIBADD@ -fsapfs_test_container_space_manager_SOURCES = \ - fsapfs_test_container_space_manager.c \ - fsapfs_test_functions.c fsapfs_test_functions.h \ - fsapfs_test_libbfio.h \ - fsapfs_test_libcerror.h \ - fsapfs_test_libfsapfs.h \ - fsapfs_test_macros.h \ - fsapfs_test_memory.c fsapfs_test_memory.h \ - fsapfs_test_unused.h - -fsapfs_test_container_space_manager_LDADD = \ - @LIBBFIO_LIBADD@ \ - @LIBCPATH_LIBADD@ \ - @LIBCFILE_LIBADD@ \ - @LIBUNA_LIBADD@ \ - @LIBCSPLIT_LIBADD@ \ - @LIBCNOTIFY_LIBADD@ \ - @LIBCLOCALE_LIBADD@ \ - @LIBCDATA_LIBADD@ \ - ../libfsapfs/libfsapfs.la \ - @LIBCERROR_LIBADD@ - fsapfs_test_container_superblock_SOURCES = \ fsapfs_test_container_superblock.c \ fsapfs_test_functions.c fsapfs_test_functions.h \ @@ -1663,6 +1673,28 @@ ../libfsapfs/libfsapfs.la \ @LIBCERROR_LIBADD@ +fsapfs_test_space_manager_SOURCES = \ + fsapfs_test_functions.c fsapfs_test_functions.h \ + fsapfs_test_libbfio.h \ + fsapfs_test_libcerror.h \ + fsapfs_test_libfsapfs.h \ + fsapfs_test_macros.h \ + fsapfs_test_memory.c fsapfs_test_memory.h \ + fsapfs_test_space_manager.c \ + fsapfs_test_unused.h + +fsapfs_test_space_manager_LDADD = \ + @LIBBFIO_LIBADD@ \ + @LIBCPATH_LIBADD@ \ + @LIBCFILE_LIBADD@ \ + @LIBUNA_LIBADD@ \ + @LIBCSPLIT_LIBADD@ \ + @LIBCNOTIFY_LIBADD@ \ + @LIBCLOCALE_LIBADD@ \ + @LIBCDATA_LIBADD@ \ + ../libfsapfs/libfsapfs.la \ + @LIBCERROR_LIBADD@ + fsapfs_test_support_SOURCES = \ fsapfs_test_functions.c fsapfs_test_functions.h \ fsapfs_test_getopt.c fsapfs_test_getopt.h \ @@ -1840,6 +1872,10 @@ @rm -f fsapfs_test_checksum$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fsapfs_test_checksum_OBJECTS) $(fsapfs_test_checksum_LDADD) $(LIBS) +fsapfs_test_chunk_information_block$(EXEEXT): $(fsapfs_test_chunk_information_block_OBJECTS) $(fsapfs_test_chunk_information_block_DEPENDENCIES) $(EXTRA_fsapfs_test_chunk_information_block_DEPENDENCIES) + @rm -f fsapfs_test_chunk_information_block$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fsapfs_test_chunk_information_block_OBJECTS) $(fsapfs_test_chunk_information_block_LDADD) $(LIBS) + fsapfs_test_compressed_data_handle$(EXEEXT): $(fsapfs_test_compressed_data_handle_OBJECTS) $(fsapfs_test_compressed_data_handle_DEPENDENCIES) $(EXTRA_fsapfs_test_compressed_data_handle_DEPENDENCIES) @rm -f fsapfs_test_compressed_data_handle$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fsapfs_test_compressed_data_handle_OBJECTS) $(fsapfs_test_compressed_data_handle_LDADD) $(LIBS) @@ -1864,10 +1900,6 @@ @rm -f fsapfs_test_container_reaper$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fsapfs_test_container_reaper_OBJECTS) $(fsapfs_test_container_reaper_LDADD) $(LIBS) -fsapfs_test_container_space_manager$(EXEEXT): $(fsapfs_test_container_space_manager_OBJECTS) $(fsapfs_test_container_space_manager_DEPENDENCIES) $(EXTRA_fsapfs_test_container_space_manager_DEPENDENCIES) - @rm -f fsapfs_test_container_space_manager$(EXEEXT) - $(AM_V_CCLD)$(LINK) $(fsapfs_test_container_space_manager_OBJECTS) $(fsapfs_test_container_space_manager_LDADD) $(LIBS) - fsapfs_test_container_superblock$(EXEEXT): $(fsapfs_test_container_superblock_OBJECTS) $(fsapfs_test_container_superblock_DEPENDENCIES) $(EXTRA_fsapfs_test_container_superblock_DEPENDENCIES) @rm -f fsapfs_test_container_superblock$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fsapfs_test_container_superblock_OBJECTS) $(fsapfs_test_container_superblock_LDADD) $(LIBS) @@ -1944,6 +1976,10 @@ @rm -f fsapfs_test_object_map_descriptor$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fsapfs_test_object_map_descriptor_OBJECTS) $(fsapfs_test_object_map_descriptor_LDADD) $(LIBS) +fsapfs_test_space_manager$(EXEEXT): $(fsapfs_test_space_manager_OBJECTS) $(fsapfs_test_space_manager_DEPENDENCIES) $(EXTRA_fsapfs_test_space_manager_DEPENDENCIES) + @rm -f fsapfs_test_space_manager$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(fsapfs_test_space_manager_OBJECTS) $(fsapfs_test_space_manager_LDADD) $(LIBS) + fsapfs_test_support$(EXEEXT): $(fsapfs_test_support_OBJECTS) $(fsapfs_test_support_DEPENDENCIES) $(EXTRA_fsapfs_test_support_DEPENDENCIES) @rm -f fsapfs_test_support$(EXEEXT) $(AM_V_CCLD)$(LINK) $(fsapfs_test_support_OBJECTS) $(fsapfs_test_support_LDADD) $(LIBS) @@ -1974,13 +2010,13 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_checkpoint_map.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_checkpoint_map_entry.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_checksum.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_chunk_information_block.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_compressed_data_handle.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_compression.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_container.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_container_data_handle.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_container_key_bag.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_container_reaper.Po@am__quote@ # am--include-marker -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_container_space_manager.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_container_superblock.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_data_block.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_directory_record.Po@am__quote@ # am--include-marker @@ -2004,6 +2040,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_object_map_btree.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_object_map_descriptor.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_rwlock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_space_manager.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_support.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_volume.Po@am__quote@ # am--include-marker @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fsapfs_test_volume_key_bag.Po@am__quote@ # am--include-marker @@ -2401,13 +2438,13 @@ -rm -f ./$(DEPDIR)/fsapfs_test_checkpoint_map.Po -rm -f ./$(DEPDIR)/fsapfs_test_checkpoint_map_entry.Po -rm -f ./$(DEPDIR)/fsapfs_test_checksum.Po + -rm -f ./$(DEPDIR)/fsapfs_test_chunk_information_block.Po -rm -f ./$(DEPDIR)/fsapfs_test_compressed_data_handle.Po -rm -f ./$(DEPDIR)/fsapfs_test_compression.Po -rm -f ./$(DEPDIR)/fsapfs_test_container.Po -rm -f ./$(DEPDIR)/fsapfs_test_container_data_handle.Po -rm -f ./$(DEPDIR)/fsapfs_test_container_key_bag.Po -rm -f ./$(DEPDIR)/fsapfs_test_container_reaper.Po - -rm -f ./$(DEPDIR)/fsapfs_test_container_space_manager.Po -rm -f ./$(DEPDIR)/fsapfs_test_container_superblock.Po -rm -f ./$(DEPDIR)/fsapfs_test_data_block.Po -rm -f ./$(DEPDIR)/fsapfs_test_directory_record.Po @@ -2431,6 +2468,7 @@ -rm -f ./$(DEPDIR)/fsapfs_test_object_map_btree.Po -rm -f ./$(DEPDIR)/fsapfs_test_object_map_descriptor.Po -rm -f ./$(DEPDIR)/fsapfs_test_rwlock.Po + -rm -f ./$(DEPDIR)/fsapfs_test_space_manager.Po -rm -f ./$(DEPDIR)/fsapfs_test_support.Po -rm -f ./$(DEPDIR)/fsapfs_test_volume.Po -rm -f ./$(DEPDIR)/fsapfs_test_volume_key_bag.Po diff -Nru libfsapfs-20181215/tests/pyfsapfs_test_support.py libfsapfs-20190210/tests/pyfsapfs_test_support.py --- libfsapfs-20181215/tests/pyfsapfs_test_support.py 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/pyfsapfs_test_support.py 2019-02-06 20:10:16.000000000 +0000 @@ -2,7 +2,7 @@ # # Python-bindings support functions test script # -# Copyright (C) 2018, Joachim Metz +# Copyright (C) 2018-2019, Joachim Metz # # Refer to AUTHORS for acknowledgements. # diff -Nru libfsapfs-20181215/tests/test_fsapfsinfo.sh libfsapfs-20190210/tests/test_fsapfsinfo.sh --- libfsapfs-20181215/tests/test_fsapfsinfo.sh 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/test_fsapfsinfo.sh 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/bash # Info tool testing script # -# Version: 20181111 +# Version: 20190101 EXIT_SUCCESS=0; EXIT_FAILURE=1; @@ -100,7 +100,7 @@ fi done else - for INPUT_FILE in `ls -1 ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; + for INPUT_FILE in `ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; do run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "fsapfsinfo" "with_stdout_reference" "${OPTION_SETS}" "${TEST_EXECUTABLE}" "${INPUT_FILE}" "${OPTIONS[@]}"; RESULT=$?; diff -Nru libfsapfs-20181215/tests/test_library.sh libfsapfs-20190210/tests/test_library.sh --- libfsapfs-20181215/tests/test_library.sh 2018-12-03 17:52:28.000000000 +0000 +++ libfsapfs-20190210/tests/test_library.sh 2019-02-06 20:14:56.000000000 +0000 @@ -1,14 +1,14 @@ #!/bin/bash # Tests C library functions and types. # -# Version: 20180907 +# Version: 20190101 EXIT_SUCCESS=0; EXIT_FAILURE=1; EXIT_IGNORE=77; -LIBRARY_TESTS="btree_entry btree_footer btree_node btree_node_header buffer_data_handle checkpoint_map checkpoint_map_entry checksum container_data_handle container_key_bag container_reaper container_space_manager container_superblock compressed_data_handle compression data_block directory_record encryption_context error file_extent file_system_btree inode io_handle key_bag_entry key_bag_header key_encrypted_key name name_hash notify object object_map object_map_btree object_map_descriptor volume_key_bag"; -LIBRARY_TESTS_WITH_INPUT="container support volume"; +LIBRARY_TESTS="btree_entry btree_footer btree_node btree_node_header buffer_data_handle checkpoint_map checkpoint_map_entry checksum chunk_information_block container_data_handle container_key_bag container_reaper container_superblock compressed_data_handle compression data_block directory_record encryption_context error file_extent file_system_btree inode io_handle key_bag_entry key_bag_header key_encrypted_key name name_hash notify object object_map object_map_btree object_map_descriptor space_manager volume_key_bag"; +LIBRARY_TESTS_WITH_INPUT="container support"; OPTION_SETS="offset password"; INPUT_GLOB="*"; @@ -102,7 +102,7 @@ fi done else - for INPUT_FILE in `ls -1 ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; + for INPUT_FILE in `ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; do if test "${OSTYPE}" = "msys"; then diff -Nru libfsapfs-20181215/tests/test_python_module.sh libfsapfs-20190210/tests/test_python_module.sh --- libfsapfs-20181215/tests/test_python_module.sh 2018-12-03 17:49:13.000000000 +0000 +++ libfsapfs-20190210/tests/test_python_module.sh 2019-02-06 20:10:16.000000000 +0000 @@ -1,7 +1,7 @@ #!/bin/bash # Tests Python module functions and types. # -# Version: 20180728 +# Version: 20190101 EXIT_SUCCESS=0; EXIT_FAILURE=1; @@ -87,7 +87,7 @@ fi done else - for INPUT_FILE in `ls -1 ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; + for INPUT_FILE in `ls -1d ${TEST_SET_INPUT_DIRECTORY}/${INPUT_GLOB}`; do run_test_on_input_file_with_options "${TEST_SET_DIRECTORY}" "${TEST_DESCRIPTION}" "default" "${OPTION_SETS}" "${TEST_SCRIPT}" "${INPUT_FILE}"; RESULT=$?;