From 651807253b4f95fefa3ef7c6bd59d733da79ef05 Mon Sep 17 00:00:00 2001 From: Joachim Metz Date: Mon, 2 Apr 2018 18:06:59 +0200 Subject: [PATCH] Applied updates --- .gitignore | 7 +- COPYING | 4 +- README | 2 +- appveyor.yml | 18 +- configure.ac | 14 +- ...w Technologies File System (NTFS).asciidoc | 1098 ++++++++--------- dpkg/copyright | 2 +- fsntfstools/fsntfstools_getopt.c | 56 +- libfsntfs.ini | 1 + m4/libcdata.m4 | 44 +- m4/libcsplit.m4 | 4 +- m4/libfdata.m4 | 73 +- .../fsntfs_test_notify.vcproj | 4 + .../fsntfs_test_support.vcproj | 20 + .../fsntfs_test_volume.vcproj | 12 + msvscpp/libfsntfs.sln | 5 + runtests.sh | 23 +- setup.py | 5 +- synclibs.ps1 | 34 +- tests/Makefile.am | 17 +- tests/fsntfs_test_functions.c | 673 ++++++++++ tests/fsntfs_test_functions.h | 72 ++ tests/fsntfs_test_getopt.c | 56 +- tests/fsntfs_test_notify.c | 123 +- tests/fsntfs_test_support.c | 897 +++++--------- 25 files changed, 2049 insertions(+), 1215 deletions(-) create mode 100644 tests/fsntfs_test_functions.c create mode 100644 tests/fsntfs_test_functions.h diff --git a/.gitignore b/.gitignore index 32cc10ea..dca4726c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ # Files to ignore by git # -# Version: 20170916 +# Version: 20180318 # Generic auto-generated build files *~ @@ -57,12 +57,12 @@ stamp-h[1-9] /m4/extern-inline.m4 /m4/fcntl-o.m4 /m4/gettext.m4 -/m4/glibc2.m4 /m4/glibc21.m4 +/m4/glibc2.m4 /m4/iconv.m4 /m4/intdiv0.m4 -/m4/intl.m4 /m4/intldir.m4 +/m4/intl.m4 /m4/intlmacosx.m4 /m4/intmax.m4 /m4/inttypes_h.m4 @@ -90,6 +90,7 @@ stamp-h[1-9] /m4/wchar_t.m4 /m4/wint_t.m4 /m4/xsize.m4 +/MANIFEST /missing /po/boldquot.sed /po/en@boldquot.header diff --git a/COPYING b/COPYING index 3f7b8b1e..bdf8db0e 100644 --- a/COPYING +++ b/COPYING @@ -10,7 +10,7 @@ the terms and conditions of version 3 of the GNU General Public License, supplemented by the additional permissions listed below. - 0. Additional Definitions. + 0. Additional Definitions. As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to version 3 of the GNU @@ -111,7 +111,7 @@ the following: a copy of the Library already present on the user's computer system, and (b) will operate properly with a modified version of the Library that is interface-compatible with the Linked - Version. + Version. e) Provide Installation Information, but only if you would otherwise be required to provide such information under section 6 of the diff --git a/README b/README index 75b56b65..8d0e9d00 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -Library and tools to access the New Technology File System (NTFS). +libfsntfs is a library to access the New Technology File System (NTFS). Project information: diff --git a/appveyor.yml b/appveyor.yml index bac19776..a38fd1c2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -67,9 +67,9 @@ build_script: msbuild /verbosity:quiet vs2015\libfsntfs.sln /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" ) - cmd: if [%TARGET%]==[vs2017] ( set PYTHONPATH=..\vstools && - C:\Python27\python.exe ..\vstools\scripts\msvscpp-convert.py --extend-with-x64 --no-python-dll --output-format 2017 msvscpp\libfsntfs.sln && - msbuild /verbosity:quiet vs2017\libfsntfs.sln /property:Platform=Win32 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && - msbuild /verbosity:quiet vs2017\libfsntfs.sln /property:Platform=x64 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" ) + C:\Python27\python.exe ..\vstools\scripts\msvscpp-convert.py --extend-with-x64 --no-python-dll --output-format 2017 --with-dokany msvscpp\libfsntfs.sln && + msbuild /verbosity:quiet vs2017\libfsntfs.sln /property:Platform=Win32 /property:PlatformToolset=v141 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" && + msbuild /verbosity:quiet vs2017\libfsntfs.sln /property:Platform=x64 /property:PlatformToolset=v141 /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" ) - cmd: if [%TARGET%]==[python27] ( C:\Python27\python.exe setup.py bdist_msi ) - cmd: if [%TARGET%]==[python36] ( @@ -89,17 +89,7 @@ build_script: test_script: - cmd: rem Run tests -- ps: if ($env:TARGET -eq "vs2008") { - .\runtests.ps1 } -- ps: if ($env:TARGET -eq "vs2010") { - .\runtests.ps1 } -- ps: if ($env:TARGET -eq "vs2012") { - .\runtests.ps1 } -- ps: if ($env:TARGET -eq "vs2013") { - .\runtests.ps1 } -- ps: if ($env:TARGET -eq "vs2015") { - .\runtests.ps1 } -- ps: if ($env:TARGET -eq "vs2017") { +- ps: If ($env:TARGET -eq "vs2008" -or $env:TARGET -eq "vs2010" -or $env:TARGET -eq "vs2012" -or $env:TARGET -eq "vs2013" -or $env:TARGET -eq "vs2015" -or $env:TARGET -eq "vs2017") { .\runtests.ps1 } - cmd: if [%TARGET%]==[cygwin] ( C:\cygwin\bin\bash -e -l -c "cd libfsntfs && ./runtests.sh" ) diff --git a/configure.ac b/configure.ac index 61924239..af121f35 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ( 2.59 ) AC_INIT( [libfsntfs], - [20180101], + [20180402], [joachim.metz@gmail.com]) AC_CONFIG_SRCDIR( @@ -48,6 +48,12 @@ AX_COMMON_CHECK_ENABLE_WINAPI dnl Check if wide character type should be enabled AX_COMMON_CHECK_ENABLE_WIDE_CHARACTER_TYPE +dnl Check if verbose output should be enabled +AX_COMMON_CHECK_ENABLE_VERBOSE_OUTPUT + +dnl Check if debug output should be enabled +AX_COMMON_CHECK_ENABLE_DEBUG_OUTPUT + dnl Check for type definitions AX_TYPES_CHECK_LOCAL @@ -131,12 +137,6 @@ AX_LIBFUSN_CHECK_ENABLE dnl Check if fsntfstools required headers and functions are available AX_FSNTFSTOOLS_CHECK_LOCAL -dnl Check if libfsntfs should be build with verbose output -AX_COMMON_CHECK_ENABLE_VERBOSE_OUTPUT - -dnl Check if libfsntfs should be build with debug output -AX_COMMON_CHECK_ENABLE_DEBUG_OUTPUT - dnl Check if tests required headers and functions are available AX_TESTS_CHECK_LOCAL diff --git a/documentation/New Technologies File System (NTFS).asciidoc b/documentation/New Technologies File System (NTFS).asciidoc index bce6ca25..841b3c7d 100644 --- a/documentation/New Technologies File System (NTFS).asciidoc +++ b/documentation/New Technologies File System (NTFS).asciidoc @@ -7,11 +7,11 @@ Analysis the Windows NT File System :numbered!: [abstract] == Summary -NTFS is the primary file system for Microsoft Windows versions that are based +NTFS is the primary file system for Microsoft Windows versions that are based on Windows NT. -This document is intended as a working document for the NTFS format. Which -should allow existing Open Source forensic tooling to be able to process this +This document is intended as a working document for the NTFS format. Which +should allow existing Open Source forensic tooling to be able to process this type of file system. [preface] @@ -28,10 +28,10 @@ type of file system. == License .... Copyright (C) 2009-2016, Joachim Metz . -Permission is granted to copy, distribute and/or modify this document under the -terms of the GNU Free Documentation License, Version 1.3 or any later version -published by the Free Software Foundation; with no Invariant Sections, no -Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included +Permission is granted to copy, distribute and/or modify this document under the +terms of the GNU Free Documentation License, Version 1.3 or any later version +published by the Free Software Foundation; with no Invariant Sections, no +Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License". .... @@ -58,13 +58,13 @@ Switched to asccidoc format. | 0.0.10 | J.B. Metz | August 2015 | Additional information regarding index and security descriptors. | 0.0.11 | J.B. Metz | January 2016 | Additional information about common alternate data stream. | 0.0.12 | J.B. Metz | January 2016 | Additional information about extended attributes. -| 0.0.13 | J.B. Metz | March 2016 | Small changes. -| 0.0.14 | J.B. Metz | April 2016 | Small changes. +| 0.0.13 | J.B. Metz | March 2016 | Small changes. +| 0.0.14 | J.B. Metz | April 2016 | Small changes. |=== :numbered: == Overview -NTFS is the primary file system for Microsoft Windows versions that are based +NTFS is the primary file system for Microsoft Windows versions that are based on Windows NT. [yellow-background]*TODO describe relation to OS2 HPFS* @@ -95,12 +95,12 @@ There are multiple version of NTFS. [yellow-background]*Need test images for version 1.0 and 1.1* [NOTE] -The versions mentioned above are the version as used by NTFS. Another common -versioning schema uses the Windows version, e.g. NTFS 5.0 is the version of +The versions mentioned above are the version as used by NTFS. Another common +versioning schema uses the Windows version, e.g. NTFS 5.0 is the version of NTFS used on Windows XP which is version 3.1 in schema mentioned above. === Test version -The following version of programs were used to test the information within this +The following version of programs were used to test the information within this document: * Windows NT4 (version 1.2) @@ -116,23 +116,23 @@ document: == Terminology === Cluster -NTFS refers to it file system blocks as clusters. Note that these are not the -same as the physical clusters of a harddisk. For clarity these are referred to -as cluster blocks. In other sources they are also referred to as logical +NTFS refers to it file system blocks as clusters. Note that these are not the +same as the physical clusters of a harddisk. For clarity these are referred to +as cluster blocks. In other sources they are also referred to as logical clusters which are numbered globally (or absolute). Typically the cluster block is 8 sectors (8 x 512 = 4096 bytes) of size. === Virtual cluster -The term virtual cluster refers to cluster blocks which are numbered locally +The term virtual cluster refers to cluster blocks which are numbered locally (or relative). === Long and short (file) name -In Windows terminology the name of a file (or directory) can either be short or -long. The short name is an equivalent of the filename in the (DOS) 8.3 format. -The long name is actual the (full) name of the file. The term long refers to -the aspect that the name is longer than the short variant. Because most -documentation refer to the (full) name as the long name, for clarity sake so +In Windows terminology the name of a file (or directory) can either be short or +long. The short name is an equivalent of the filename in the (DOS) 8.3 format. +The long name is actual the (full) name of the file. The term long refers to +the aspect that the name is longer than the short variant. Because most +documentation refer to the (full) name as the long name, for clarity sake so will this document. == The volume @@ -142,8 +142,8 @@ Everything on an NTFS volume is a file. There are two types of files: * files that contain data (referred to as files). === The metadata files -NTFS uses the Master File Table (MFT) to store information about files and -directories. The MFT entries reference the different volume and file system +NTFS uses the Master File Table (MFT) to store information about files and +directories. The MFT entries reference the different volume and file system metadata. There are several predefined metadata files. The following metadata files are predefined and use a fixed MFT entry index. @@ -173,8 +173,8 @@ Marked as unused 3+| _As of Windows 2000_ | 24 | $Extend\$Quota | Quota information + Was MFT entry 9 in Windows NT 4 -| 25 | $Extend\$ObjId | Unique file identifiers for distributed link tracking -| 26 | $Extend\$Reparse | Backreferences to reparse points +| 25 | $Extend\$ObjId | Unique file identifiers for distributed link tracking +| 26 | $Extend\$Reparse | Backreferences to reparse points 3+| _As of Windows Vista_ ([yellow-background]*or server 2003?*) + _Transactional NTFS metadata (See section: <>)_ | 27 | $Extend\$RmMetadata | Resource manager metadata directory @@ -188,7 +188,7 @@ Used to store data that has been overwritten inside a currently active transacti | | ... | A file or directory |=== -The following metadata files are predefined, however the MFT entry index is +The following metadata files are predefined, however the MFT entry index is commonly used but not fixed. [cols="1,1,5",options="header"] @@ -200,7 +200,7 @@ See section: <> + |=== == The volume header -The volume header is stored at the start of the volume (in the $Boot metadata +The volume header is stored at the start of the volume (in the $Boot metadata file) and contains: * the volume signature @@ -270,7 +270,7 @@ Not used by NTFS `[MSDN]` See below. | 80 | 4 | 0x00 | Checksum + not used by NTFS `[POLLARD06]`, `[MSDN]` -4+| +4+| | 84 | 426 | | Bootcode + [yellow-background]*What is the exact end of the bootcode and are there no trailing values?* | 510 | 2 | 0x55 0xaa | Sector signature @@ -304,21 +304,21 @@ MFT offset = volume header offset + ( MFT cluster block number x Cluster block size ) .... -Note that the lower 32-bit part of the NTFS volume serial number is the WINAPI +Note that the lower 32-bit part of the NTFS volume serial number is the WINAPI volume serial number. E.g. compare the output of: .... fsutil fsinfo volumeinfo C: fsutil fsinfo ntfsinfo C: .... -Often the volume will be smaller than the underlying partition. A (nearly -identical) backup of the volume header is stored in last sector of cluster -block, that follows the last cluster block of the volume. Often this is the 512 -bytes after the last sector of the volume, but not necessarily. The backup +Often the volume will be smaller than the underlying partition. A (nearly +identical) backup of the volume header is stored in last sector of cluster +block, that follows the last cluster block of the volume. Often this is the 512 +bytes after the last sector of the volume, but not necessarily. The backup volume header is not included in the volume size. === BitLocker Drive Encryption (BDE) -BitLocker Drive Encryption (BDE) uses the file system signature: "-FVE-FS-". +BitLocker Drive Encryption (BDE) uses the file system signature: "-FVE-FS-". Where FVE is an abbreviation of Full Volume Encryption. The data structures of BDE on Windows Vista and 7 differ. @@ -333,12 +333,12 @@ A Windows 7 BDE volume starts with: eb 58 90 2d 46 56 45 26 46 53 2d .... -BDE is largely a stand-alone but has some integration with NTFS. For more +BDE is largely a stand-alone but has some integration with NTFS. For more information about BDE see https://github.com/libyal/libbde/blob/master/documentation/BitLocker%20Drive%20Encryption%20(BDE)%20format.asciidoc[[LIBBDE\]]. === Volume Shadow Snapshots (VSS) -Volume Shadow Snapshots (VSS) uses the GUID -3808876b-c176-4e48-b7ae-04046e6cc752 (stored in little-endian) to identify its +Volume Shadow Snapshots (VSS) uses the GUID +3808876b-c176-4e48-b7ae-04046e6cc752 (stored in little-endian) to identify its data. VSS is largely a stand-alone but has some integration with NTFS. For more information about VSS see https://github.com/libyal/libvshadow/blob/master/documentation/Volume%20Shadow%20Snapshot%20(VSS)%20format.asciidoc[[LIBVSHADOW\]]. @@ -356,7 +356,7 @@ For more information about VSS see https://github.com/libyal/libvshadow/blob/mas 1 => 8 sectors per track | 2 | | Density: + 0 => 80 tracks + -1 => 40 tracks +1 => 40 tracks | 3 | | Type: + 0 => Fixed disc + 1 => Removable disc @@ -373,16 +373,16 @@ For more information about VSS see https://github.com/libyal/libvshadow/blob/mas |=== == The Master File Table (MFT) -The MFT consist of an array of MFT entries. The offset of the MFT table can be -found in the volume header and the size of the MFT is defined by the MFT entry +The MFT consist of an array of MFT entries. The offset of the MFT table can be +found in the volume header and the size of the MFT is defined by the MFT entry of the $MFT metadata file. [NOTE] -The MFT can consists of multiple data ranges, defined by the data runs in the +The MFT can consists of multiple data ranges, defined by the data runs in the $MFT metadata file. === MFT entry -Although the size of a MFT entry is defined in the volume header is commonly +Although the size of a MFT entry is defined in the volume header is commonly 1024 bytes of size and consists of: * The MFT entry header @@ -409,7 +409,7 @@ Contains an offset relative from the start of the MFT entry + According to `[MSDN]` this value is the update sequence array offset | 6 | 2 | | The number of fix-up values + According to `[MSDN]` this value is the update sequence array size. -4+| +4+| | 8 | 8 | | Metadata transaction journal sequence number + Contains a $LogFile Sequence Number (LSN) | 16 | 2 | | Sequence (number) @@ -434,19 +434,19 @@ See section: <> | 44 | 4 | | The index |=== -The base record file reference indicates if the MFT entry is used to store +The base record file reference indicates if the MFT entry is used to store additional attributes for another MFT entry, e.g. for attribute list attributes. -According to `[MSDN]` the sequence number is incremented each time that a file +According to `[MSDN]` the sequence number is incremented each time that a file record segment is freed; it is 0 if the segment is not used. -`[MSDN]` states that the update sequence array must end before the last USHORT -value in the first sector. It also claims the update sequence array size value +`[MSDN]` states that the update sequence array must end before the last USHORT +value in the first sector. It also claims the update sequence array size value contains the number of bytes. It seems to be more likely to the number of words. -The "BAAD" signature presumably indicates a bad MFT entry. `[LINUXNTFS]` states -that during chkdsk, if NTFS finds a multi-sector item where the multi-sector -header does not match the values at the end of the sector, it marks the item as +The "BAAD" signature presumably indicates a bad MFT entry. `[LINUXNTFS]` states +that during chkdsk, if NTFS finds a multi-sector item where the multi-sector +header does not match the values at the end of the sector, it marks the item as "BAAD" and fill it with 0-byte values except for a fix-up value at the end of the first sector. The "BAAD" signature has been seen to be used on Windows NT4 and XP. @@ -480,7 +480,7 @@ When this flag is present the file entry is a directory (or contains sub file en |=== === [[file_reference]]The file reference -The file reference (FILE_REFERENCE or MFT_SEGMENT_REFERENCE) is 8 bytes of size +The file reference (FILE_REFERENCE or MFT_SEGMENT_REFERENCE) is 8 bytes of size and consists of: [cols="1,1,1,5",options="header"] @@ -501,8 +501,8 @@ The fix-up values are variable of size and consists of: | 2 | 2 x number of fix-up values | | Fix-up (original) value array |=== -On disk the last 2 bytes in each sector is replaced by the fix-up placeholder -value. The original value is stored in the corresponding fix-up (original) +On disk the last 2 bytes in each sector is replaced by the fix-up placeholder +value. The original value is stored in the corresponding fix-up (original) value array entry. [NOTE] @@ -521,7 +521,7 @@ The MFT attribute consist of: * alignment padding (8-byte alignment), can contain remnant data ==== MFT attribute header -The MFT attribute header (ATTRIBUTE_RECORD_HEADER) is 16 bytes of size and +The MFT attribute header (ATTRIBUTE_RECORD_HEADER) is 16 bytes of size and consists of: [cols="1,1,1,5",options="header"] @@ -563,8 +563,8 @@ identifier : 4 |=== | Value | Identifier | Description | 0x0001 | | Is compressed -| 0x00ff | ATTRIBUTE_FLAG_COMPRESSION_MASK | -| | | +| 0x00ff | ATTRIBUTE_FLAG_COMPRESSION_MASK | +| | | | 0x4000 | ATTRIBUTE_FLAG_ENCRYPTED | Is encrypted | 0x8000 | ATTRIBUTE_FLAG_SPARSE | Is sparse |=== @@ -573,7 +573,7 @@ identifier : 4 Do other values indicate other compression values?* ==== Resident MFT attribute -The resident MFT attribute data is present when the non-resident flag is not +The resident MFT attribute data is present when the non-resident flag is not set (0). The resident data is 8 bytes in size and consists of: [cols="1,1,1,5",options="header"] @@ -603,7 +603,7 @@ data flags : 0x0001 .... ==== Non-resident MFT attribute -The non-resident MFT attribute data is present when the non-resident flag is +The non-resident MFT attribute data is present when the non-resident flag is set (1). The non-resident data is 48 or 56 bytes in size and consists of: [cols="1,1,1,5",options="header"] @@ -640,9 +640,9 @@ Contains the total allocated size in number of cluster blocks. The total size of the data runs should be larger or equal to the data size. [NOTE] -Windows will fill data ranges beyond the valid data size with 0-byte values. +Windows will fill data ranges beyond the valid data size with 0-byte values. The data size remains unchanged. This applies to compressed and uncompressed -data. If the first VCN is zero a valid data size of 0 represents a file +data. If the first VCN is zero a valid data size of 0 represents a file entirely filled with 0-byte values. ==== Attribute name @@ -656,7 +656,7 @@ Contains an UTF-16 little-endian without the end-of-string character |=== ==== Data runs -The data runs are stored in a variable size (data) runlist. This runlist +The data runs are stored in a variable size (data) runlist. This runlist consists of runlist elements. A runlist element is variable of size and consists of: @@ -674,15 +674,15 @@ Contains the number of cluster blocks See below. |=== -The data run cluster block number is a singed value, where the MSB is the -singed bit, e.g. if the data run cluster block contains \'dbc8' it corresponds +The data run cluster block number is a singed value, where the MSB is the +singed bit, e.g. if the data run cluster block contains \'dbc8' it corresponds to the 64-bit value 0xffffffffffffdbc8. -The first data run offset contains the absolute cluster block number where +The first data run offset contains the absolute cluster block number where successive data run offsets are relative to the last data run offset. [NOTE] -The cluster block number byte size is the first nibble when reading the byte +The cluster block number byte size is the first nibble when reading the byte stream, but here it is represented as the upper nibble of the first byte. The last runlist element is an empty value size tuple; in other words a 0 byte. @@ -690,11 +690,11 @@ The last runlist element is an empty value size tuple; in other words a 0 byte. [yellow-background]*Does a data run with a "number of cluster blocks value size" of 0 represent this as well?* -The MFT attribute data flag (ATTRIBUTE_FLAG_SPARSE) indicates if the data +The MFT attribute data flag (ATTRIBUTE_FLAG_SPARSE) indicates if the data stream is sparse or not. -A sparse data run has a "cluster block number value size" 0, representing there -is no offset (cluster block number). A sparse data run should be filled with +A sparse data run has a "cluster block number value size" 0, representing there +is no offset (cluster block number). A sparse data run should be filled with 0-byte values. [NOTE] @@ -710,14 +710,14 @@ or not. The currently known value for LZNT1 compression is 1. [yellow-background]*TODO: have a look at Windows 10 compression see if they use a different value.* -The data is stored in compression unit blocks. A compression unit typically -consists of 16 cluster blocks. However the actual value is stored in the -non-resident MFT attribute. See <> for more -information on how to determine which data runs store the compressed and which +The data is stored in compression unit blocks. A compression unit typically +consists of 16 cluster blocks. However the actual value is stored in the +non-resident MFT attribute. See <> for more +information on how to determine which data runs store the compressed and which do not. [NOTE] -Compression is supported upto NTFS file systems with a cluster block size of +Compression is supported upto NTFS file systems with a cluster block size of 4096 bytes or less. The compression is specified on a pre attribute basis. Where an attribute @@ -725,9 +725,9 @@ chain can consists of attribute with compressed and uncompressed attribute data. [yellow-background]*Note that it is unknown if mixing compressed and uncompressed attributes is supported by the Windows implementation.* -According to `[RUSSON05]` the size of the runlist is rounded up to the next -multitude of 4 bytes. The size of the trailing data can be even larger than 3 -and are not always zero-bytes. +According to `[RUSSON05]` the size of the runlist is rounded up to the next +multitude of 4 bytes. The size of the trailing data can be even larger than 3 +and are not always zero-bytes. See `[CARRIER05]` and/or `[RUSSON05]` for examples on reading the runlist. @@ -764,17 +764,17 @@ Introduced in NTFS version 3.0 Removed in NTFS version 3.0 | 0x00000100 | $LOGGED_UTILITY_STREAM | Logged utility stream + Introduced in NTFS version 3.0 -| | | +| | | | 0x00001000 | | First user defined attribute -| | | +| | | | 0xffffffff | | End of attributes marker |=== === The standard information attribute -The standard information attribute ($STANDARD_INFORMATION) contains the basic +The standard information attribute ($STANDARD_INFORMATION) contains the basic file entry metadata. It is stored as a resident MFT attribute. -The standard information data (STANDARD_INFORMATION) is either 48 or 72 bytes +The standard information data (STANDARD_INFORMATION) is either 48 or 72 bytes of size and consists of: [cols="1,1,1,5",options="header"] @@ -810,16 +810,16 @@ See section: <> |=== === The attribute list attribute -The attribute list attribute ($ATTRIBUTE_LIST) is a list of attributes in an -MFT entry. The attributes stored in the list are placeholders for other -attributes. Some of these attributes could not be stored in the MFT entry due -to space limitations. The attribute list attribute can be stored as either a +The attribute list attribute ($ATTRIBUTE_LIST) is a list of attributes in an +MFT entry. The attributes stored in the list are placeholders for other +attributes. Some of these attributes could not be stored in the MFT entry due +to space limitations. The attribute list attribute can be stored as either a resident (for a small amount of data) and non-resident MFT attribute. The attribute list data contains an array of attribute list entries. -Note that MFT entry 0 also can contain an attribute list. -[yellow-background]*Does NTFS allow to store listed attributed beyond the first +Note that MFT entry 0 also can contain an attribute list. +[yellow-background]*Does NTFS allow to store listed attributed beyond the first data run?* ==== The attribute list entry @@ -851,9 +851,9 @@ See section: <> [yellow-background]*An unique identifier to distinguish between attributes that contain segmented data.* |=== -The data first VCN is used when the attribute data is stored in multiple MFT -entries. The attribute list contains an attribute list entry for every MFT -entry. The corresponding MFT entry will contain an MFT attribute containing the +The data first VCN is used when the attribute data is stored in multiple MFT +entries. The attribute list contains an attribute list entry for every MFT +entry. The corresponding MFT entry will contain an MFT attribute containing the attribute data. See `[CARRIER05]` pages 365 and 366 for more information. ===== Attribute name @@ -867,8 +867,8 @@ Contains an UTF-16 little-endian without the end-of-string character |=== === [[file_name_attribute]]The file name attribute -The file name attribute ($FILE_NAME) contains the basic file system -information, like the parent file entry, MAC times and filename. It is stored +The file name attribute ($FILE_NAME) contains the basic file system +information, like the parent file entry, MAC times and filename. It is stored as a resident MFT attribute. The file name data (FILE_NAME) is variable of size and consists of: @@ -907,23 +907,23 @@ The extended data contains: * the reparse point tag (see section <>) if the reparse point file attribute flag (FILE_ATTRIBUTE_REPARSE_POINT) is set; * [yellow-background]*the extended attribute data size.* -The allocated file size and file size values do not always contain accurate -values when stored in a MFT attribute, see `[CARRIER05]` page 363 for more -information. [CARRIER05] also states that the file size values are accurate -when 'used in a directory index' (stored in an index value), however this seems -to be true for most files but not for all. At least the $MFT and $MFTMirr -metadata file directory entries on a Windows Vista NTFS volume were found to -contain the same value as the corresponding MFT entries, which were not equal +The allocated file size and file size values do not always contain accurate +values when stored in a MFT attribute, see `[CARRIER05]` page 363 for more +information. [CARRIER05] also states that the file size values are accurate +when 'used in a directory index' (stored in an index value), however this seems +to be true for most files but not for all. At least the $MFT and $MFTMirr +metadata file directory entries on a Windows Vista NTFS volume were found to +contain the same value as the corresponding MFT entries, which were not equal to the size of the data stream. -An MFT attribute can contain multiple file name attributes, e.g. for a separate +An MFT attribute can contain multiple file name attributes, e.g. for a separate (long) name and short name. -In several cases on a Vista NTFS volume the MFT entry contained both a DOS & -Windows and POSIX namespace name. However the directory entry index ($I30) of +In several cases on a Vista NTFS volume the MFT entry contained both a DOS & +Windows and POSIX namespace name. However the directory entry index ($I30) of the parent directory only contained the DOS & Windows name. -In case of a hard link the MFT entry will contain additional file name +In case of a hard link the MFT entry will contain additional file name attributes with the parent file reference of each hard link. ==== Namespace @@ -953,9 +953,9 @@ Note the name must follow the 8.3 format. The Windows API function CreateFile allows to create case sensitive file names when the flag FILE_FLAG_POSIX_SEMANTICS is set. ==== Long to short name conversion -Basically the conversion from a long name to short name boils down to the -approach mentioned below. Note that it differs from the approach mentioned in -`[RUSSON05]` and `[MSSUPPORT]`, in regard of the third case to make the short name +Basically the conversion from a long name to short name boils down to the +approach mentioned below. Note that it differs from the approach mentioned in +`[RUSSON05]` and `[MSSUPPORT]`, in regard of the third case to make the short name unique. In the long name: @@ -972,8 +972,8 @@ Make the name unique: 2. if the name already exists try \~2 up to ~9 3. if the name already exists use [yellow-background]*some 16-bit hexadecimal value* for characters 3 to 6 with ~1 -[yellow-background]*`[MSDN]` Generates the next four letters of the short file -name by mathematically manipulating the remaining letters of the long file +[yellow-background]*`[MSDN]` Generates the next four letters of the short file +name by mathematically manipulating the remaining letters of the long file name.* [yellow-background]*Note: behavior dependent on fsutil?* @@ -982,18 +982,18 @@ case 1: "Program Files" becomes "PROGRA\~1" or " ~PLAYMOVIE.REG" becomes "\~PLAY case 2: "Program Data", in the same directory as "Program Files", becomes "PROGRA~2" -case 3: -"x86_microsoft-windows-r..ry-editor.resources_31bf3856ad364e35_6.0.6000.16386_en-us_f89a7b0005d42fd4", +case 3: +"x86_microsoft-windows-r..ry-editor.resources_31bf3856ad364e35_6.0.6000.16386_en-us_f89a7b0005d42fd4", in a directory with a lot of filenames starting with "x86_microsoft", becomes "X8FCA6~1.163" === The volume version attribute The volume version attribute ($VOLUME_VERSION) contains [yellow-background]*TODO* -[yellow-background]*Need a pre NTFS 3.0 volume with this attribute. $AttrDef +[yellow-background]*Need a pre NTFS 3.0 volume with this attribute. $AttrDef indicates the attribute to be 8 bytes of size.* === The object identifier attribute -The object identifier attribute ($OBJECT_ID) contains distributed link tracker +The object identifier attribute ($OBJECT_ID) contains distributed link tracker properties. It is stored as a resident MFT attribute. The object identifier data is either 16 or 64 bytes of size and consists of: @@ -1023,7 +1023,7 @@ of data) and non-resident MFT attribute. See: https://github.com/libyal/libfwnt/blob/master/documentation/Security%20Descriptor.asciidoc[[LIBFWNT\]] === The volume name attribute -The volume name attribute ($VOLUME_NAME) contains the name of the volume. It is +The volume name attribute ($VOLUME_NAME) contains the name of the volume. It is stored as a resident MFT attribute. The volume name data is variable of size and consists of: @@ -1038,7 +1038,7 @@ Contains an UTF-16 little-endian without an end-of-string character The volume name attribute is used in the $Volume metadata file MFT entry. === The volume information attribute -The volume information attribute ($VOLUME_INFORMATION) contains the name of the +The volume information attribute ($VOLUME_INFORMATION) contains the name of the volume. It is stored as a resident MFT attribute. The volume information data is 12 bytes of size and consists of: @@ -1065,53 +1065,53 @@ The volume information attribute is used in the $Volume metadata file MFT entry. | 0x0008 | | [yellow-background]*Mounted on Windows NT 4* | 0x0010 | | [yellow-background]*Delete USN underway* | 0x0020 | | [yellow-background]*Repair object identifiers* -| | | +| | | | 0x8000 | | [yellow-background]*Modified by chkdsk* |=== === The data stream attribute -The data stream attribute ($DATA) contains the file data. It can be stored as +The data stream attribute ($DATA) contains the file data. It can be stored as either a resident (for a small amount of data) and non-resident MFT attribute. -Also note that multiple data attributes for the same data stream can be used in -the attribute list to define different parts of the data stream data. The first -data stream attribute will contain the size of the entire data stream data. -Other data stream attributes should have a size of 0. Also see: +Also note that multiple data attributes for the same data stream can be used in +the attribute list to define different parts of the data stream data. The first +data stream attribute will contain the size of the entire data stream data. +Other data stream attributes should have a size of 0. Also see: <>. === The index root attribute -The index root attribute ($INDEX_ROOT) contains the root of the index tree. It +The index root attribute ($INDEX_ROOT) contains the root of the index tree. It is stored as a resident MFT attribute. See section: <> and <>. === The index allocation attribute -The index allocation attribute ($INDEX_ALLOCATION) contains an array of index +The index allocation attribute ($INDEX_ALLOCATION) contains an array of index entries. It is stored as a non-resident MFT attribute. -Note that the index allocation attribute itself does not define which attribute -type it contains in the index value data. For this information it needs the +Note that the index allocation attribute itself does not define which attribute +type it contains in the index value data. For this information it needs the corresponding index root attribute. -Also note that multiple index allocation attributes for the same index can be -used in the attribute list to define different parts of the index allocation -data. The first index allocation attribute will contain the size of the entire -index allocation data. Other index allocation attributes should have a size of +Also note that multiple index allocation attributes for the same index can be +used in the attribute list to define different parts of the index allocation +data. The first index allocation attribute will contain the size of the entire +index allocation data. Other index allocation attributes should have a size of 0. Also see: <>. See section: <>. === The bitmap attribute -The bitmap attribute ($BITMAP) contains the allocation bitmap. It can be stored -as either a resident (for a small amount of data) and non-resident MFT +The bitmap attribute ($BITMAP) contains the allocation bitmap. It can be stored +as either a resident (for a small amount of data) and non-resident MFT attribute. -It is used to maintain information about which entry is used and which is not. -Every bit in the bitmap represents an entry. The index is stored byte-wise with -the LSB of the byte corresponds to the first allocation element; the allocation +It is used to maintain information about which entry is used and which is not. +Every bit in the bitmap represents an entry. The index is stored byte-wise with +the LSB of the byte corresponds to the first allocation element; the allocation element can represent several things, see below. -The allocation element is allocated if the corresponding bit contains 1 or +The allocation element is allocated if the corresponding bit contains 1 or unallocated if 0. It is known to be used in: @@ -1122,17 +1122,17 @@ It is known to be used in: === The symbolic link attribute The symbolic link attribute ($SYMBOLIC_LINK) contains [yellow-background]*TODO* -[yellow-background]*Need a pre NTFS 3.0 volume with this attribute. $AttrDef +[yellow-background]*Need a pre NTFS 3.0 volume with this attribute. $AttrDef indicates the attribute is variable of size.* === The reparse point attribute -The reparse point attribute ($REPARSE_POINT) contains information about a file +The reparse point attribute ($REPARSE_POINT) contains information about a file system-level link. It is stored as a resident MFT attribute. See section: <>. === The (HPFS) extended attribute information -The (HPFS) extended attribute information ($EA_INFORMATION) contains +The (HPFS) extended attribute information ($EA_INFORMATION) contains information about the extended attribute ($EA). The extended attribute information data is 8 bytes of size and consists of: @@ -1175,7 +1175,7 @@ Contains an ASCII string + E.g. .... 00000000: 18 00 00 00 00 09 04 00 2e 55 4e 49 58 41 54 54 ........ .UNIXATT -00000010: 52 00 b6 01 00 00 03 87 R....... +00000010: 52 00 b6 01 00 00 03 87 R....... .... ==== UNITATTR extended attribute value data @@ -1189,7 +1189,7 @@ E.g. === The property set attribute The property set attribute ($PROPERTY_SET) contains [yellow-background]*TODO* -[yellow-background]*Need a pre NTFS 3.0 volume with this attribute. $AttrDef +[yellow-background]*Need a pre NTFS 3.0 volume with this attribute. $AttrDef indicates does not seem to always define this attribute.* === The logged utility stream attribute @@ -1212,10 +1212,10 @@ Multiple attributes can make up a single attribute, e.g. the attributes: 1. $INDEX_ALLOCATION ($I30) VCN: 0 2. $INDEX_ALLOCATION ($I30) VCN: 596 -The first attribute will contain the size of the data defined by all the +The first attribute will contain the size of the data defined by all the attributes. Other attributes should have a size of 0. -It is assumed that the attributes in a chain must be continuous and defined +It is assumed that the attributes in a chain must be continuous and defined in-order. == [[attribute_types]]The attribute types @@ -1254,32 +1254,32 @@ Seen: -1 (no maximum?), 48 .... == [[index]]The index -The index structures are used for various purposes one of which are the +The index structures are used for various purposes one of which are the directory entries. -The root of the index is stored in index root. The index root attribute defines +The root of the index is stored in index root. The index root attribute defines which type of attribute is stored in the index and the root index node. -If the index is too large part of the index is stored in an index allocation -attribute with the same attribute name. The index allocation attribute defines -a data stream which contains index entries. Each index entry contains an index +If the index is too large part of the index is stored in an index allocation +attribute with the same attribute name. The index allocation attribute defines +a data stream which contains index entries. Each index entry contains an index node. -See `[CARRIER05]` page 378 for an illustration how the index root and index +See `[CARRIER05]` page 378 for an illustration how the index root and index allocation attribute relate. -An index consists of a tree, where both the branch and index leaf nodes contain -the actual data. E.g. in case of a directory entries index, any node that +An index consists of a tree, where both the branch and index leaf nodes contain +the actual data. E.g. in case of a directory entries index, any node that contains index value data make up for the directory entries. -The index value data in a branch node signifies the upper bound of the values -in the that specific branch. E.g. if directory entries index branch node -contains the name 'textfile.txt' all names in that index branch are smaller -than 'textfile.txt'. Note the actual sorting order is dependent on the +The index value data in a branch node signifies the upper bound of the values +in the that specific branch. E.g. if directory entries index branch node +contains the name 'textfile.txt' all names in that index branch are smaller +than 'textfile.txt'. Note the actual sorting order is dependent on the collation type defined in the index root attribute. -The index allocation attribute is accompanied by a bitmap attribute with the -corresponding attribute name. The bitmap attribute defines the allocation of +The index allocation attribute is accompanied by a bitmap attribute with the +corresponding attribute name. The bitmap attribute defines the allocation of virtual cluster blocks within the index allocation attribute data stream. [NOTE] @@ -1322,12 +1322,12 @@ See section: <> | 12 | 4 | | Index entry number of cluster blocks |=== -Note that `[CARRIER05]` and `[RUSSON05]` state that the last 3 bytes are unused -(alignment padding). However it is highly probably that the last value is +Note that `[CARRIER05]` and `[RUSSON05]` state that the last 3 bytes are unused +(alignment padding). However it is highly probably that the last value is 32-bit of size. ===== Version 1.2 Notes -In NT4 (version 1.2) +In NT4 (version 1.2) * the index entry size does not have to match the index entry size in the volume header. The correct size seems to be the value in the index root header. @@ -1337,14 +1337,14 @@ In NT4 (version 1.2) |=== | Value | Identifier | Description | 0x00000000 | COLLATION_BINARY | Binary + -The first byte is most significant +The first byte is most significant | 0x00000001 | COLLATION_FILENAME | Unicode strings case-insensitive | 0x00000002 | COLLATION_UNICODE_STRING | Unicode strings case-sensitive + -Upper case letters should come first -| | | +Upper case letters should come first +| | | | 0x00000010 | COLLATION_NTOFS_ULONG | Unsigned 32-bit little-endian integer | 0x00000011 | COLLATION_NTOFS_SID | NT security identifier (SID) -| 0x00000012 | COLLATION_NTOFS_SECURITY_HASH | Security hash first, then NT security identifier +| 0x00000012 | COLLATION_NTOFS_SECURITY_HASH | Security hash first, then NT security identifier | 0x00000013 | COLLATION_NTOFS_ULONGS | An array of unsigned 32-bit little-endian integer values |=== @@ -1391,11 +1391,11 @@ The value includes the size of the index node header See section: <> |=== -Note that `[RUSSON05]` states that the last 3 bytes are unused (alignment -padding), while `[CARRIER05]` states that the last value is 32-bit of size. +Note that `[RUSSON05]` states that the last 3 bytes are unused (alignment +padding), while `[CARRIER05]` states that the last value is 32-bit of size. Here we assume that the index node flags are a 32‑bit value. -In an index entry (index allocation attribute) the index node size includes the +In an index entry (index allocation attribute) the index node size includes the size of the fix-up values and the alignment padding following it. The remainder of the index node contains remnant data and/or zero-byte values. @@ -1454,13 +1454,13 @@ key data. See section: <>. The index value data seems to contain remnant data. [NOTE] -Both the short and long names of the same file have a separate index value. The +Both the short and long names of the same file have a separate index value. The short name uses the DOS namespace and the long name the WINDOWS namespace. -[yellow-background]*Index values with a single name use either the POSIX or +[yellow-background]*Index values with a single name use either the POSIX or DOS_WINDOWS namespace?* -A hard link to a file in the same directory will also have a separate index +A hard link to a file in the same directory will also have a separate index value. [yellow-background]*Does the hard link always has POSIX namespace?* @@ -1478,20 +1478,20 @@ It appears to only to be used by the $Secure metadata file. See section: <> == [[compression]]Compression -Typically NTFS compression groups 16 cluster blocks together. This group of 16 -cluster blocks also named a compression unit is either \'compressed' or -uncompressed data. The term compressed is quoted here because, as you will see -below, the group of cluster blocks can also contain uncompressed data. A group -of cluster blocks is \'compressed' when it is compressed size is smaller than +Typically NTFS compression groups 16 cluster blocks together. This group of 16 +cluster blocks also named a compression unit is either \'compressed' or +uncompressed data. The term compressed is quoted here because, as you will see +below, the group of cluster blocks can also contain uncompressed data. A group +of cluster blocks is \'compressed' when it is compressed size is smaller than its uncompressed data size. [NOTE] The actual compression unit size is stored in the non-resident MFT attribute. -Within a group of cluster blocks each of the 16 blocks is \'compressed' +Within a group of cluster blocks each of the 16 blocks is \'compressed' individually see <>. The maximum uncompressed data size is always the cluster size (in most cases -4096). +4096). The data runs in the $DATA stream define cluster block ranges. A simple example: .... @@ -1513,8 +1513,8 @@ This data run defines 64 data blocks starting at block number 21047. Since this data run is larger than the compression unit size the data is stored uncompressed. -If the data run was e.g. 60 data blocks followed by 4 sparse blocks the first 3 -compression units (blocks 1 to 48) would be uncompressed and the last +If the data run was e.g. 60 data blocks followed by 4 sparse blocks the first 3 +compression units (blocks 1 to 48) would be uncompressed and the last compression unit (blocks 49 to 64) would be compressed. Also "sparse data" and "sparse compression unit" data runs can be mixed. If in @@ -1522,7 +1522,7 @@ the previous example the 60 data blocks would be followed by 20 sparse blocks the last compression unit (blocks 65 to 80) would be sparse. [NOTE] -A compression unit can consists of multiple compressed data runs, e.g. 1 data +A compression unit can consists of multiple compressed data runs, e.g. 1 data block followed by 4 data blocks followed by 11 sparse blocks. [NOTE] @@ -1537,7 +1537,7 @@ files?* Also see `[RUSSON05]` for more detailed examples. === [[compression_block_based_storage]]Block based storage -NTFS compression stores the \'compressed' data in blocks. Each block has a 2 +NTFS compression stores the \'compressed' data in blocks. Each block has a 2 byte block header. The block is variable of size and consists of: @@ -1562,72 +1562,72 @@ The upper 4 bits of the block size are used as flags. === LZNT1 compression method The LZNT1 compression method is based on LZ77 compression. -Every compression block consists of tagged compression groups. A tagged group +Every compression block consists of tagged compression groups. A tagged group consist of 8 values (not bytes) preceded by a tag byte: .... -tag A B C D E F G H +tag A B C D E F G H .... -The LSB of the tag byte represents the first value in the group, the MSB the +The LSB of the tag byte represents the first value in the group, the MSB the last * a tag bit of 0 indicates an uncompressed byte; * a tag bit of 1 indicates compressed data using a little-endian 16-bit (2-byte) compression tuple (meaning combination of two values). -The compression tuple contains an offset (back reference) and a size value. +The compression tuple contains an offset (back reference) and a size value. -Where the size is the actual size minus 3. Use the following calculation to +Where the size is the actual size minus 3. Use the following calculation to correct the size value in the tuple. .... -size = size + 3 +size = size + 3 .... -And the offset a positive representation of a back reference minus 1. Use the +And the offset a positive representation of a back reference minus 1. Use the following calculation to correct the offset value in the tuple. .... -offset = -1 * ( offset + 1 ) +offset = -1 * ( offset + 1 ) .... -The compression tuple uses a dynamic amount of bits to store the offset and -size values. +The compression tuple uses a dynamic amount of bits to store the offset and +size values. -The calculation of the amount of bits used for the offset and size values is as -following: +The calculation of the amount of bits used for the offset and size values is as +following: -* at the uncompressed data block offset 0, the size is stored in the least significant 12 bits of size and the offset 4 bits +* at the uncompressed data block offset 0, the size is stored in the least significant 12 bits of size and the offset 4 bits * the larger the uncompressed data block offset, the larger the amount of bits are used for the offset value and the smaller the amount of bits for the size . -The following calculation is used to determine the amount of bits to store the offset and size values. +The following calculation is used to determine the amount of bits to store the offset and size values. .... -compression_tuple_size_offset_shift = 12; -compression_tuple_size_mask = 0xfff; +compression_tuple_size_offset_shift = 12; +compression_tuple_size_mask = 0xfff; -for( iterator = uncompressed_data_block_offset - 1; - iterator >= 0x10; - iterator >>= 1 ) -{ - /* bit shift for the offset value */ - compression_tuple_size_offset_shift--; +for( iterator = uncompressed_data_block_offset - 1; + iterator >= 0x10; + iterator >>= 1 ) +{ + /* bit shift for the offset value */ + compression_tuple_size_offset_shift--; - /* bit mask for size value */ - compression_tuple_size_mask >>= 1; -} + /* bit mask for size value */ + compression_tuple_size_mask >>= 1; +} .... -The tuple is uncompressed by copying the byte at the offset in the uncompressed -data to the end of the uncompressed data. This is repeated for the size value +The tuple is uncompressed by copying the byte at the offset in the uncompressed +data to the end of the uncompressed data. This is repeated for the size value of the tuple. [NOTE] -The offset value itself does not change, the offset remains fixed relative to -the end of the uncompressed data. However this means that for every increment -of the size value the offset refers to another byte in the uncompressed data. +The offset value itself does not change, the offset remains fixed relative to +the end of the uncompressed data. However this means that for every increment +of the size value the offset refers to another byte in the uncompressed data. Consider the following example. ==== Example Consider the following tagged compression group: .... -0x02 0x20 0xfc 0x0f +0x02 0x20 0xfc 0x0f .... The tag byte consists of: @@ -1640,31 +1640,31 @@ This means that the 2nd and 3rd values contain a 16-bit compression tuple. 0x0ffc .... -Because this compression tuple is near the start of the uncompressed data the +Because this compression tuple is near the start of the uncompressed data the offset shift is 12 and the size mask is 0x0fff. .... -offset: 0x0ffc >> 12 => -1 * ( 0 + 1 ) => -1 -size: 0x0ffc & 0x0fff => 4092 + 3 => 4095 +offset: 0x0ffc >> 12 => -1 * ( 0 + 1 ) => -1 +size: 0x0ffc & 0x0fff => 4092 + 3 => 4095 .... -The algorithm starts with an uncompressed value of 0x20 which represents the -space character (ASCII). This value is added to the uncompressed data. Next the -algorithm reads the compression tuple and determines the offset and size -values. The offset refers to the previous space value in the uncompressed data -and add this to uncompressed data. And so on. Note that the offset remains -referring to the last value in the uncompressed data. In the end we end up with +The algorithm starts with an uncompressed value of 0x20 which represents the +space character (ASCII). This value is added to the uncompressed data. Next the +algorithm reads the compression tuple and determines the offset and size +values. The offset refers to the previous space value in the uncompressed data +and add this to uncompressed data. And so on. Note that the offset remains +referring to the last value in the uncompressed data. In the end we end up with a block of 4096 spaces. -Now consider the following uncompressed data: +Now consider the following uncompressed data: .... #include \n #include \n .... -Note that the \n is the string representation of the newline character (ASCII: +Note that the \n is the string representation of the newline character (ASCII: 0x0a) -This is logically compressed to: +This is logically compressed to: .... #include \n(-18,10)stdio(-17,4) .... @@ -1673,8 +1673,8 @@ In the example above the tuples are represented by (offset,size). The first part of this is data stored with tag bytes looks like: .... -00000000b '#' 'i' 'n' 'c' 'l' 'u' 'd' 'e' -00000000b ' ' '<' 'n' 't' 'f' 's' '.' 'h' +00000000b '#' 'i' 'n' 'c' 'l' 'u' 'd' 'e' +00000000b ' ' '<' 'n' 't' 'f' 's' '.' 'h' 00000100b '>' '\n' 0x07 0x88 's' 't' 'd' 'i' 'o' 00000001b 0x01 0x80 .... @@ -1685,7 +1685,7 @@ And as a hexdump: 00000010 2e 68 04 3e 0a 07 88 3c 73 74 64 69 01 01 80 |.h.>...stdio... | .... -For the first tuple the offset shift is 11 and the size mask is 0x07ff. The +For the first tuple the offset shift is 11 and the size mask is 0x07ff. The tuple consists of: .... offset: 0x8807 >> 11 => -1 * ( 17 + 1 ) => -18 @@ -1694,7 +1694,7 @@ size: 0x8807 & 0x07ff => 7 + 3 => 10 This tuples refer to: .... -(-18,10) => #include < +(-18,10) => #include < .... == [[reparse_point]]The reparse point @@ -1711,14 +1711,14 @@ The reparse point data (REPARSE_DATA_BUFFER) is variable of size and consists of | 8 | ... | | Reparse data |=== -[yellow-background]*What about the GUID mentioned in `[RUSSON05]` in third +[yellow-background]*What about the GUID mentioned in `[RUSSON05]` in third party reparse points.* -[yellow-background]*`[MSDN]` ReparseGuid: A 16-byte GUID that uniquely -identifies the owner of the reparse point. Reparse pointGUIDs are assigned by -the implementer of a file system, the file system filter driver, or the -minifilter driver. The implementer must generate one GUID to use with their -assigned reparse point tag, and must always use this GUID as the ReparseGuid +[yellow-background]*`[MSDN]` ReparseGuid: A 16-byte GUID that uniquely +identifies the owner of the reparse point. Reparse pointGUIDs are assigned by +the implementer of a file system, the file system filter driver, or the +minifilter driver. The implementer must generate one GUID to use with their +assigned reparse point tag, and must always use this GUID as the ReparseGuid for that tag.* === [[reparse_point_tag]]Reparse point tag @@ -1739,27 +1739,27 @@ Predefined reparse point tag values according to `[MSDN]`: | Value | Identifier | Description | 0x00000000 | IO_REPARSE_TAG_RESERVED_ZERO | Reserved | 0x00000001 | IO_REPARSE_TAG_RESERVED_ONE | Reserved -| | | +| | | | 0x80000005 | IO_REPARSE_TAG_DRIVER_EXTENDER | Used by Home server drive extender | 0x80000006 | IO_REPARSE_TAG_HSM2 | Used by Hierarchical Storage Manager Product | 0x80000007 | IO_REPARSE_TAG_SIS | Used by single-instance storage (SIS) filter driver -| | | +| | | | 0x8000000a | IO_REPARSE_TAG_DFS | Used by the Distributed File System (DFS) | 0x8000000b | IO_REPARSE_TAG_FILTER_MANAGER | Used by filter manager test harness -| | | +| | | | 0x80000012 | IO_REPARSE_TAG_DFSR | Used by the Distributed File System (DFS) -| | | +| | | | 0xa0000003 | IO_REPARSE_TAG_MOUNT_POINT | Junction or mount point -| | | +| | | | 0xa000000c | IO_REPARSE_TAG_SYMLINK | Symbolic link -| | | +| | | | 0xc0000004 | IO_REPARSE_TAG_HSM | Used by Hierarchical Storage Manager Product |=== ==== Notes -[yellow-background]*single-instance storage (SIS): An NTFS feature that -implements links with the semantics of copies for files stored on an -NTFSvolume. SIS uses copy-on-close to implement the copy semantics of its +[yellow-background]*single-instance storage (SIS): An NTFS feature that +implements links with the semantics of copies for files stored on an +NTFSvolume. SIS uses copy-on-close to implement the copy semantics of its links.* .... @@ -1851,7 +1851,7 @@ Contains an UTF-16 little-endian [yellow-background]*with the end-of-string char == The allocation bitmap The metadata file $Bitmap contains the allocation bitmap. -Every bit in the allocation bitmap represents a block the size of the cluster +Every bit in the allocation bitmap represents a block the size of the cluster block, where the LSB is the first bit in a byte. == [[access_control]]Access control @@ -1942,23 +1942,23 @@ Contains a GUID |=== .... -00000000 00 00 00 00 13 00 00 00 00 10 00 00 01 00 00 00 |................| -00000010 10 00 00 00 88 00 00 00 88 00 00 00 01 00 00 00 |................| -00000020 20 00 38 00 00 00 00 00 60 00 10 00 01 00 00 00 | .8.....`.......| +00000000 00 00 00 00 13 00 00 00 00 10 00 00 01 00 00 00 |................| +00000010 10 00 00 00 88 00 00 00 88 00 00 00 01 00 00 00 |................| +00000020 20 00 38 00 00 00 00 00 60 00 10 00 01 00 00 00 | .8.....`.......| OBJECT_ID: 43ecee59-e2b3-11dc-ad7e-001c2582598f of root directory -00000030 59 ee ec 43 b3 e2 dc 11 ad 7e 00 1c 25 82 59 8f |Y..C.....~..%.Y.| +00000030 59 ee ec 43 b3 e2 dc 11 ad 7e 00 1c 25 82 59 8f |Y..C.....~..%.Y.| MFT file reference OBJECT_ID: e6a67b60-c0b5-4b53-b8fe-94470c83df89 of $Volume -00000040 05 00 00 00 00 00 05 00 60 7b a6 e6 b5 c0 53 4b |........`{....SK| -00000050 b8 fe 94 47 0c 83 df 89 59 ee ec 43 b3 e2 dc 11 |...G....Y..C....| -00000060 ad 7e 00 1c 25 82 59 8f 00 00 00 00 00 00 00 00 |.~..%.Y.........| -00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| -00000080 00 00 00 00 00 00 00 00 18 00 00 00 03 00 00 00 |................| -00000090 01 00 00 00 00 00 00 00 |........| +00000040 05 00 00 00 00 00 05 00 60 7b a6 e6 b5 c0 53 4b |........`{....SK| +00000050 b8 fe 94 47 0c 83 df 89 59 ee ec 43 b3 e2 dc 11 |...G....Y..C....| +00000060 ad 7e 00 1c 25 82 59 8f 00 00 00 00 00 00 00 00 |.~..%.Y.........| +00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| +00000080 00 00 00 00 00 00 00 00 18 00 00 00 03 00 00 00 |................| +00000090 01 00 00 00 00 00 00 00 |........| .... == [[log_file]]Metadata transaction journal (log file) @@ -1970,7 +1970,7 @@ The metadata file $LogFile contains the metadata transaction journal. * <> === Log File service restart page header -The Log File service restart page header (LFS_RESTART_PAGE_HEADER) is 30 bytes +The Log File service restart page header (LFS_RESTART_PAGE_HEADER) is 30 bytes of size and consists of: [cols="1,1,1,5",options="header"] @@ -1985,7 +1985,7 @@ Contains an offset relative from the start of the restart page header + According to `[MSDN]` this value is the update sequence array offset | 6 | 2 | | The number of fix-up values + According to `[MSDN]` this value is the update sequence array size. -4+| +4+| | 8 | 8 | | Checkdisk last LSN | 16 | 4 | | System page size | 20 | 4 | | Log page size @@ -2060,15 +2060,15 @@ LFS_RECORD_HEADER { .... == [[usn_change_journal]]USN change journal -The metadata file $Extend\$UsnJrnl contains the USN change journal. It -is a sparse file in which NTFS stores records of changes to files and -directories. Applications make use of the journal to respond to file and -directory changes as they occur, like e.g. the Windows File Replication Service +The metadata file $Extend\$UsnJrnl contains the USN change journal. It +is a sparse file in which NTFS stores records of changes to files and +directories. Applications make use of the journal to respond to file and +directory changes as they occur, like e.g. the Windows File Replication Service (FRS) and the Windows (Desktop) Search service. The USN change journal consists of: -* the $UsnJrnl:$Max data stream, containing metadata like the maximum size of the journal +* the $UsnJrnl:$Max data stream, containing metadata like the maximum size of the journal * the $UsnJrnl:$J data stream, containing the update (or change) entries. The $UsnJrnl:$J data stream is sparse. === USN change journal metadata @@ -2087,7 +2087,7 @@ Contains a FILETIME |=== === USN change journal entries -The $UsnJrnl:$J data stream consists of an array of USN change journal entries. +The $UsnJrnl:$J data stream consists of an array of USN change journal entries. The USN change journal entries are stored on a per block-basis and 64-bit aligned. Therefore the remainder of the block can contain 0-byte values. @@ -2100,7 +2100,7 @@ are removed from the stream and replaced with a sparse data run. ==== USN change journal entry ===== USN change journal entry version 2 -The USN change journal entry version 2 (USN_RECORD or USN_RECORD_V2) is +The USN change journal entry version 2 (USN_RECORD or USN_RECORD_V2) is variable of size and consists of: [cols="1,1,1,5",options="header"] @@ -2134,11 +2134,11 @@ The offset is relative from the start of the USN chagne journal entry |=== ===== USN change journal entry version 3 -[yellow-background]*TODO need a sample to confirm this version of the USN -record is actually used by NTFS. For now it is assumed that it is likely used +[yellow-background]*TODO need a sample to confirm this version of the USN +record is actually used by NTFS. For now it is assumed that it is likely used by ReFS.* -The USN chagne journal entry version 3 (USN_RECORD_V3) is variable of size and +The USN chagne journal entry version 3 (USN_RECORD_V3) is variable of size and consists of: [cols="1,1,1,5",options="header"] @@ -2171,7 +2171,7 @@ The offset is relative from the start of the USN change journal entry | ... | ... | 0x00 | Padding |=== -The file reference has changed from a 64-bit to a 128-bit value which consists +The file reference has changed from a 64-bit to a 128-bit value which consists of: [cols="1,1,1,5",options="header"] @@ -2193,11 +2193,11 @@ Note that the index value in the MFT entry is only 32-bit of size. [yellow-background]*The default (unnamed) $DATA attribute was extended* | 0x00000004 | USN_REASON_DATA_TRUNCATION | The file or directory is truncated. + [yellow-background]*The default (unnamed) $DATA attribute was truncated* -| | | +| | | | 0x00000010 | USN_REASON_NAMED_DATA_OVERWRITE | One or more named data streams ($DATA attributes) of file were overwritten | 0x00000020 | USN_REASON_NAMED_DATA_EXTEND | One or more named data streams ($DATA attributes) of file were extended | 0x00000040 | USN_REASON_NAMED_DATA_TRUNCATION | One or more named data streams ($DATA attributes) of a file were truncated -| | | +| | | | 0x00000100 | USN_REASON_FILE_CREATE | The file or directory was created | 0x00000200 | USN_REASON_FILE_DELETE | The file or directory was deleted | 0x00000400 | USN_REASON_EA_CHANGE | The extended attributes of the file were changed @@ -2217,7 +2217,7 @@ One or more file or directory attributes were changed e.g. read-only, hidden, sy | 0x00100000 | USN_REASON_REPARSE_POINT_CHANGE | The reparse point that in a file or directory was changed, or a reparse point was added to or deleted from a file or directory. | 0x00200000 | USN_REASON_STREAM_CHANGE | A named data stream ($DATA attribute) is added to or removed from a file, or a named stream is renamed | 0x00400000 | USN_REASON_TRANSACTED_CHANGE | [yellow-background]*Unknown found in TxF USN change journal entry list* -| | | +| | | | 0x80000000 | USN_REASON_CLOSE | The file or directory was closed |=== @@ -2278,17 +2278,17 @@ AFP_Resource | Used to store Macintosh operating system property lists .... == [[transactional_ntfs]]Transactional NTFS (TxF) -As of Vista ([yellow-background]*or windows server 2003?*) Transactional NTFS +As of Vista ([yellow-background]*or windows server 2003?*) Transactional NTFS (TxF) was added. -In TxF the resource manager (RM) keeps track of transactional metadata and log +In TxF the resource manager (RM) keeps track of transactional metadata and log files. The TxF related metadata files are stored in the metadata directory: .... $Extend\$RmMetadata .... === Resource manager repair information -The resource manager repair information metadata file: +The resource manager repair information metadata file: $Extend\$RmMetadata\$Repair consists of the following data streams: * the default (unnamed) data stream, [yellow-background]*purpose unknown* @@ -2347,52 +2347,52 @@ Contains a GUID |=== ==== TxF Old Page Stream (TOPS) file data -The $Tops:$T data streams contains the file data that is partially overwritten +The $Tops:$T data streams contains the file data that is partially overwritten by a transaction. It consists of multiple pending transaction XML-documents. -[yellow-background]*Note that the start of each sector contains 0x0001, is this -a value indication the sector is empty? Or are there fix-up values stored +[yellow-background]*Note that the start of each sector contains 0x0001, is this +a value indication the sector is empty? Or are there fix-up values stored somewhere else?* -A pending transaction XML-document starts with an UTF-8 byte-order-mark. Is +A pending transaction XML-document starts with an UTF-8 byte-order-mark. Is roughly contains the following data: .... - - + + + RefExtra="..."/> ... - - - + + + ... - + - + fileAttribute="..."/> + - + + flags="..."/> + value="..."/> @@ -2405,7 +2405,7 @@ roughly contains the following data: Family="..., Culture=..., PublicKeyToken=..., ProcessorArchitecture=..., versionScope=..." Old="..." - New="..."/> + New="..."/> ... @@ -2413,10 +2413,10 @@ roughly contains the following data: .... === Transactional NTFS (TxF) Common Log File System (CLFS) files -TxF uses a Common Log File System (CLFS) log store and the logged utility +TxF uses a Common Log File System (CLFS) log store and the logged utility stream attribute named $TXF_DATA. -See `[RUSSNOVICH09]`, `[MSDN]` and `[LIBFSCLFS]` for more information about +See `[RUSSNOVICH09]`, `[MSDN]` and `[LIBFSCLFS]` for more information about CLFS. The base log file (BLF) of the TxF log store is: @@ -2436,7 +2436,7 @@ TxF uses a multiplexed log store which contains two streams: * TxfLog stream, which contains the TxF log records. === Transactional data logged utility stream attribute -The transactional data ($TXF_DATA) logged utility stream attribute is 56 bytes +The transactional data ($TXF_DATA) logged utility stream attribute is 56 bytes of size and consist of: [cols="1,1,1,5",options="header"] @@ -2512,7 +2512,7 @@ Signatures as indicated in `[LINUXNTFS]`: | | \$Extend\$Config | Used for NTFS repair activity | | \$Extend\$Delete | Delete file name | | \$Extend\$Repair.log | Repair log name -| | \$Extend\$Tops | +| | \$Extend\$Tops | | | \$Extend\$TxfLog | Transactional NTFS log |=== @@ -2687,7 +2687,7 @@ What file system metadata is missing: [cols="1,5",options="header"] |=== -| Title | NTFS Forensics - A Programmers View of Raw Filesystem Data Extraction +| Title | NTFS Forensics - A Programmers View of Raw Filesystem Data Extraction | Author(s) | Jason Medeiros | URL | http://grayscale-research.org/new/pdfs/NTFS%20forensics.pdf |=== @@ -2697,7 +2697,7 @@ What file system metadata is missing: [cols="1,5",options="header"] |=== | Title | Windows Internals 5 - Covering Windows Server 2008 and Windows Vista -| Author(s) | Mark E. Russinovich and David A. Solomon +| Author(s) | Mark E. Russinovich and David A. Solomon | Date | June 17, 2009 | ISBN-13 | 978-0735625303 |=== @@ -2706,7 +2706,7 @@ What file system metadata is missing: [cols="1,5",options="header"] |=== -| Title | BitLocker Drive Encryption (BDE) format specification - Analysis of theBitLocker Drive Encryption (BDE) volume format +| Title | BitLocker Drive Encryption (BDE) format specification - Analysis of theBitLocker Drive Encryption (BDE) volume format | Date | March 2011 | Author(s) | Joachim Metz | URL | https://github.com/libyal/libbde/blob/master/documentation/BitLocker%20Drive%20Encryption%20(BDE)%20format.asciidoc @@ -2726,7 +2726,7 @@ What file system metadata is missing: [cols="1,5",options="header"] |=== -| Title | Volume Shadow Snapshot (VSS) - Analysis the Windows NT VSS format +| Title | Volume Shadow Snapshot (VSS) - Analysis the Windows NT VSS format | Date | March 2011 | Author(s) | Joachim Metz | URL | https://github.com/libyal/libvshadow/blob/master/documentation/Volume%20Shadow%20Snapshot%20(VSS)%20format.asciidoc @@ -2833,377 +2833,377 @@ http://en.wikipedia.org/wiki/Transactional_NTFS [appendix] == GNU Free Documentation License Version 1.3, 3 November 2008 -Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. -Everyone is permitted to copy and distribute verbatim copies of this license +Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. === 0. PREAMBLE -The purpose of this License is to make a manual, textbook, or other functional -and useful document "free" in the sense of freedom: to assure everyone the -effective freedom to copy and redistribute it, with or without modifying it, -either commercially or noncommercially. Secondarily, this License preserves for -the author and publisher a way to get credit for their work, while not being +The purpose of this License is to make a manual, textbook, or other functional +and useful document "free" in the sense of freedom: to assure everyone the +effective freedom to copy and redistribute it, with or without modifying it, +either commercially or noncommercially. Secondarily, this License preserves for +the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. -This License is a kind of "copyleft", which means that derivative works of the -document must themselves be free in the same sense. It complements the GNU +This License is a kind of "copyleft", which means that derivative works of the +document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. -We have designed this License in order to use it for manuals for free software, -because free software needs free documentation: a free program should come with -manuals providing the same freedoms that the software does. But this License is -not limited to software manuals; it can be used for any textual work, -regardless of subject matter or whether it is published as a printed book. We -recommend this License principally for works whose purpose is instruction or +We have designed this License in order to use it for manuals for free software, +because free software needs free documentation: a free program should come with +manuals providing the same freedoms that the software does. But this License is +not limited to software manuals; it can be used for any textual work, +regardless of subject matter or whether it is published as a printed book. We +recommend this License principally for works whose purpose is instruction or reference. === 1. APPLICABILITY AND DEFINITIONS -This License applies to any manual or other work, in any medium, that contains -a notice placed by the copyright holder saying it can be distributed under the -terms of this License. Such a notice grants a world-wide, royalty-free license, -unlimited in duration, to use that work under the conditions stated herein. The -"Document", below, refers to any such manual or work. Any member of the public -is a licensee, and is addressed as "you". You accept the license if you copy, +This License applies to any manual or other work, in any medium, that contains +a notice placed by the copyright holder saying it can be distributed under the +terms of this License. Such a notice grants a world-wide, royalty-free license, +unlimited in duration, to use that work under the conditions stated herein. The +"Document", below, refers to any such manual or work. Any member of the public +is a licensee, and is addressed as "you". You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. -A "Modified Version" of the Document means any work containing the Document or -a portion of it, either copied verbatim, or with modifications and/or +A "Modified Version" of the Document means any work containing the Document or +a portion of it, either copied verbatim, or with modifications and/or translated into another language. -A "Secondary Section" is a named appendix or a front-matter section of the -Document that deals exclusively with the relationship of the publishers or -authors of the Document to the Document's overall subject (or to related -matters) and contains nothing that could fall directly within that overall -subject. (Thus, if the Document is in part a textbook of mathematics, a -Secondary Section may not explain any mathematics.) The relationship could be a -matter of historical connection with the subject or with related matters, or of +A "Secondary Section" is a named appendix or a front-matter section of the +Document that deals exclusively with the relationship of the publishers or +authors of the Document to the Document's overall subject (or to related +matters) and contains nothing that could fall directly within that overall +subject. (Thus, if the Document is in part a textbook of mathematics, a +Secondary Section may not explain any mathematics.) The relationship could be a +matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. -The "Invariant Sections" are certain Secondary Sections whose titles are -designated, as being those of Invariant Sections, in the notice that says that -the Document is released under this License. If a section does not fit the -above definition of Secondary then it is not allowed to be designated as -Invariant. The Document may contain zero Invariant Sections. If the Document +The "Invariant Sections" are certain Secondary Sections whose titles are +designated, as being those of Invariant Sections, in the notice that says that +the Document is released under this License. If a section does not fit the +above definition of Secondary then it is not allowed to be designated as +Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. -The "Cover Texts" are certain short passages of text that are listed, as -Front-Cover Texts or Back-Cover Texts, in the notice that says that the -Document is released under this License. A Front-Cover Text may be at most 5 +The "Cover Texts" are certain short passages of text that are listed, as +Front-Cover Texts or Back-Cover Texts, in the notice that says that the +Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. -A "Transparent" copy of the Document means a machine-readable copy, represented -in a format whose specification is available to the general public, that is -suitable for revising the document straightforwardly with generic text editors -or (for images composed of pixels) generic paint programs or (for drawings) -some widely available drawing editor, and that is suitable for input to text -formatters or for automatic translation to a variety of formats suitable for -input to text formatters. A copy made in an otherwise Transparent file format -whose markup, or absence of markup, has been arranged to thwart or discourage -subsequent modification by readers is not Transparent. An image format is not -Transparent if used for any substantial amount of text. A copy that is not +A "Transparent" copy of the Document means a machine-readable copy, represented +in a format whose specification is available to the general public, that is +suitable for revising the document straightforwardly with generic text editors +or (for images composed of pixels) generic paint programs or (for drawings) +some widely available drawing editor, and that is suitable for input to text +formatters or for automatic translation to a variety of formats suitable for +input to text formatters. A copy made in an otherwise Transparent file format +whose markup, or absence of markup, has been arranged to thwart or discourage +subsequent modification by readers is not Transparent. An image format is not +Transparent if used for any substantial amount of text. A copy that is not "Transparent" is called "Opaque". -Examples of suitable formats for Transparent copies include plain ASCII without -markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly -available DTD, and standard-conforming simple HTML, PostScript or PDF designed -for human modification. Examples of transparent image formats include PNG, XCF -and JPG. Opaque formats include proprietary formats that can be read and edited -only by proprietary word processors, SGML or XML for which the DTD and/or -processing tools are not generally available, and the machine-generated HTML, +Examples of suitable formats for Transparent copies include plain ASCII without +markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly +available DTD, and standard-conforming simple HTML, PostScript or PDF designed +for human modification. Examples of transparent image formats include PNG, XCF +and JPG. Opaque formats include proprietary formats that can be read and edited +only by proprietary word processors, SGML or XML for which the DTD and/or +processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only. -The "Title Page" means, for a printed book, the title page itself, plus such -following pages as are needed to hold, legibly, the material this License -requires to appear in the title page. For works in formats which do not have -any title page as such, "Title Page" means the text near the most prominent +The "Title Page" means, for a printed book, the title page itself, plus such +following pages as are needed to hold, legibly, the material this License +requires to appear in the title page. For works in formats which do not have +any title page as such, "Title Page" means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. -The "publisher" means any person or entity that distributes copies of the +The "publisher" means any person or entity that distributes copies of the Document to the public. -A section "Entitled XYZ" means a named subunit of the Document whose title -either is precisely XYZ or contains XYZ in parentheses following text that -translates XYZ in another language. (Here XYZ stands for a specific section -name mentioned below, such as "Acknowledgements", "Dedications", -"Endorsements", or "History".) To "Preserve the Title" of such a section when -you modify the Document means that it remains a section "Entitled XYZ" +A section "Entitled XYZ" means a named subunit of the Document whose title +either is precisely XYZ or contains XYZ in parentheses following text that +translates XYZ in another language. (Here XYZ stands for a specific section +name mentioned below, such as "Acknowledgements", "Dedications", +"Endorsements", or "History".) To "Preserve the Title" of such a section when +you modify the Document means that it remains a section "Entitled XYZ" according to this definition. -The Document may include Warranty Disclaimers next to the notice which states -that this License applies to the Document. These Warranty Disclaimers are -considered to be included by reference in this License, but only as regards -disclaiming warranties: any other implication that these Warranty Disclaimers +The Document may include Warranty Disclaimers next to the notice which states +that this License applies to the Document. These Warranty Disclaimers are +considered to be included by reference in this License, but only as regards +disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. === 2. VERBATIM COPYING -You may copy and distribute the Document in any medium, either commercially or -noncommercially, provided that this License, the copyright notices, and the -license notice saying this License applies to the Document are reproduced in -all copies, and that you add no other conditions whatsoever to those of this -License. You may not use technical measures to obstruct or control the reading -or further copying of the copies you make or distribute. However, you may -accept compensation in exchange for copies. If you distribute a large enough +You may copy and distribute the Document in any medium, either commercially or +noncommercially, provided that this License, the copyright notices, and the +license notice saying this License applies to the Document are reproduced in +all copies, and that you add no other conditions whatsoever to those of this +License. You may not use technical measures to obstruct or control the reading +or further copying of the copies you make or distribute. However, you may +accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. -You may also lend copies, under the same conditions stated above, and you may +You may also lend copies, under the same conditions stated above, and you may publicly display copies. === 3. COPYING IN QUANTITY -If you publish printed copies (or copies in media that commonly have printed -covers) of the Document, numbering more than 100, and the Document's license -notice requires Cover Texts, you must enclose the copies in covers that carry, -clearly and legibly, all these Cover Texts: Front-Cover Texts on the front -cover, and Back-Cover Texts on the back cover. Both covers must also clearly -and legibly identify you as the publisher of these copies. The front cover must -present the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. Copying with -changes limited to the covers, as long as they preserve the title of the -Document and satisfy these conditions, can be treated as verbatim copying in +If you publish printed copies (or copies in media that commonly have printed +covers) of the Document, numbering more than 100, and the Document's license +notice requires Cover Texts, you must enclose the copies in covers that carry, +clearly and legibly, all these Cover Texts: Front-Cover Texts on the front +cover, and Back-Cover Texts on the back cover. Both covers must also clearly +and legibly identify you as the publisher of these copies. The front cover must +present the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. Copying with +changes limited to the covers, as long as they preserve the title of the +Document and satisfy these conditions, can be treated as verbatim copying in other respects. -If the required texts for either cover are too voluminous to fit legibly, you -should put the first ones listed (as many as fit reasonably) on the actual +If the required texts for either cover are too voluminous to fit legibly, you +should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. -If you publish or distribute Opaque copies of the Document numbering more than -100, you must either include a machine-readable Transparent copy along with -each Opaque copy, or state in or with each Opaque copy a computer-network -location from which the general network-using public has access to download -using public-standard network protocols a complete Transparent copy of the -Document, free of added material. If you use the latter option, you must take -reasonably prudent steps, when you begin distribution of Opaque copies in -quantity, to ensure that this Transparent copy will remain thus accessible at -the stated location until at least one year after the last time you distribute -an Opaque copy (directly or through your agents or retailers) of that edition +If you publish or distribute Opaque copies of the Document numbering more than +100, you must either include a machine-readable Transparent copy along with +each Opaque copy, or state in or with each Opaque copy a computer-network +location from which the general network-using public has access to download +using public-standard network protocols a complete Transparent copy of the +Document, free of added material. If you use the latter option, you must take +reasonably prudent steps, when you begin distribution of Opaque copies in +quantity, to ensure that this Transparent copy will remain thus accessible at +the stated location until at least one year after the last time you distribute +an Opaque copy (directly or through your agents or retailers) of that edition to the public. -It is requested, but not required, that you contact the authors of the Document -well before redistributing any large number of copies, to give them a chance to +It is requested, but not required, that you contact the authors of the Document +well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. === 4. MODIFICATIONS -You may copy and distribute a Modified Version of the Document under the -conditions of sections 2 and 3 above, provided that you release the Modified -Version under precisely this License, with the Modified Version filling the -role of the Document, thus licensing distribution and modification of the -Modified Version to whoever possesses a copy of it. In addition, you must do +You may copy and distribute a Modified Version of the Document under the +conditions of sections 2 and 3 above, provided that you release the Modified +Version under precisely this License, with the Modified Version filling the +role of the Document, thus licensing distribution and modification of the +Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: -A. Use in the Title Page (and on the covers, if any) a title distinct from that -of the Document, and from those of previous versions (which should, if there -were any, be listed in the History section of the Document). You may use the -same title as a previous version if the original publisher of that version -gives permission. +A. Use in the Title Page (and on the covers, if any) a title distinct from that +of the Document, and from those of previous versions (which should, if there +were any, be listed in the History section of the Document). You may use the +same title as a previous version if the original publisher of that version +gives permission. -B. List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified Version, -together with at least five of the principal authors of the Document (all of -its principal authors, if it has fewer than five), unless they release you from -this requirement. +B. List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified Version, +together with at least five of the principal authors of the Document (all of +its principal authors, if it has fewer than five), unless they release you from +this requirement. -C. State on the Title page the name of the publisher of the Modified Version, -as the publisher. +C. State on the Title page the name of the publisher of the Modified Version, +as the publisher. -D. Preserve all the copyright notices of the Document. +D. Preserve all the copyright notices of the Document. -E. Add an appropriate copyright notice for your modifications adjacent to the -other copyright notices. +E. Add an appropriate copyright notice for your modifications adjacent to the +other copyright notices. -F. Include, immediately after the copyright notices, a license notice giving -the public permission to use the Modified Version under the terms of this -License, in the form shown in the Addendum below. +F. Include, immediately after the copyright notices, a license notice giving +the public permission to use the Modified Version under the terms of this +License, in the form shown in the Addendum below. -G. Preserve in that license notice the full lists of Invariant Sections and -required Cover Texts given in the Document's license notice. +G. Preserve in that license notice the full lists of Invariant Sections and +required Cover Texts given in the Document's license notice. -H. Include an unaltered copy of this License. +H. Include an unaltered copy of this License. -I. Preserve the section Entitled "History", Preserve its Title, and add to it -an item stating at least the title, year, new authors, and publisher of the -Modified Version as given on the Title Page. If there is no section Entitled -"History" in the Document, create one stating the title, year, authors, and -publisher of the Document as given on its Title Page, then add an item -describing the Modified Version as stated in the previous sentence. +I. Preserve the section Entitled "History", Preserve its Title, and add to it +an item stating at least the title, year, new authors, and publisher of the +Modified Version as given on the Title Page. If there is no section Entitled +"History" in the Document, create one stating the title, year, authors, and +publisher of the Document as given on its Title Page, then add an item +describing the Modified Version as stated in the previous sentence. -J. Preserve the network location, if any, given in the Document for public -access to a Transparent copy of the Document, and likewise the network -locations given in the Document for previous versions it was based on. These -may be placed in the "History" section. You may omit a network location for a -work that was published at least four years before the Document itself, or if -the original publisher of the version it refers to gives permission. +J. Preserve the network location, if any, given in the Document for public +access to a Transparent copy of the Document, and likewise the network +locations given in the Document for previous versions it was based on. These +may be placed in the "History" section. You may omit a network location for a +work that was published at least four years before the Document itself, or if +the original publisher of the version it refers to gives permission. -K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the -Title of the section, and preserve in the section all the substance and tone of -each of the contributor acknowledgements and/or dedications given therein. +K. For any section Entitled "Acknowledgements" or "Dedications", Preserve the +Title of the section, and preserve in the section all the substance and tone of +each of the contributor acknowledgements and/or dedications given therein. -L. Preserve all the Invariant Sections of the Document, unaltered in their text -and in their titles. Section numbers or the equivalent are not considered part -of the section titles. +L. Preserve all the Invariant Sections of the Document, unaltered in their text +and in their titles. Section numbers or the equivalent are not considered part +of the section titles. -M. Delete any section Entitled "Endorsements". Such a section may not be -included in the Modified Version. +M. Delete any section Entitled "Endorsements". Such a section may not be +included in the Modified Version. -N. Do not retitle any existing section to be Entitled "Endorsements" or to -conflict in title with any Invariant Section. +N. Do not retitle any existing section to be Entitled "Endorsements" or to +conflict in title with any Invariant Section. -O. Preserve any Warranty Disclaimers. +O. Preserve any Warranty Disclaimers. -If the Modified Version includes new front-matter sections or appendices that -qualify as Secondary Sections and contain no material copied from the Document, -you may at your option designate some or all of these sections as invariant. To -do this, add their titles to the list of Invariant Sections in the Modified -Version's license notice. These titles must be distinct from any other section +If the Modified Version includes new front-matter sections or appendices that +qualify as Secondary Sections and contain no material copied from the Document, +you may at your option designate some or all of these sections as invariant. To +do this, add their titles to the list of Invariant Sections in the Modified +Version's license notice. These titles must be distinct from any other section titles. -You may add a section Entitled "Endorsements", provided it contains nothing but -endorsements of your Modified Version by various parties—for example, -statements of peer review or that the text has been approved by an organization +You may add a section Entitled "Endorsements", provided it contains nothing but +endorsements of your Modified Version by various parties—for example, +statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. -You may add a passage of up to five words as a Front-Cover Text, and a passage -of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts -in the Modified Version. Only one passage of Front-Cover Text and one of -Back-Cover Text may be added by (or through arrangements made by) any one -entity. If the Document already includes a cover text for the same cover, -previously added by you or by arrangement made by the same entity you are -acting on behalf of, you may not add another; but you may replace the old one, +You may add a passage of up to five words as a Front-Cover Text, and a passage +of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts +in the Modified Version. Only one passage of Front-Cover Text and one of +Back-Cover Text may be added by (or through arrangements made by) any one +entity. If the Document already includes a cover text for the same cover, +previously added by you or by arrangement made by the same entity you are +acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. -The author(s) and publisher(s) of the Document do not by this License give -permission to use their names for publicity for or to assert or imply +The author(s) and publisher(s) of the Document do not by this License give +permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. === 5. COMBINING DOCUMENTS -You may combine the Document with other documents released under this License, -under the terms defined in section 4 above for modified versions, provided that -you include in the combination all of the Invariant Sections of all of the -original documents, unmodified, and list them all as Invariant Sections of your -combined work in its license notice, and that you preserve all their Warranty +You may combine the Document with other documents released under this License, +under the terms defined in section 4 above for modified versions, provided that +you include in the combination all of the Invariant Sections of all of the +original documents, unmodified, and list them all as Invariant Sections of your +combined work in its license notice, and that you preserve all their Warranty Disclaimers. -The combined work need only contain one copy of this License, and multiple -identical Invariant Sections may be replaced with a single copy. If there are -multiple Invariant Sections with the same name but different contents, make the -title of each such section unique by adding at the end of it, in parentheses, -the name of the original author or publisher of that section if known, or else -a unique number. Make the same adjustment to the section titles in the list of +The combined work need only contain one copy of this License, and multiple +identical Invariant Sections may be replaced with a single copy. If there are +multiple Invariant Sections with the same name but different contents, make the +title of each such section unique by adding at the end of it, in parentheses, +the name of the original author or publisher of that section if known, or else +a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. -In the combination, you must combine any sections Entitled "History" in the -various original documents, forming one section Entitled "History"; likewise -combine any sections Entitled "Acknowledgements", and any sections Entitled +In the combination, you must combine any sections Entitled "History" in the +various original documents, forming one section Entitled "History"; likewise +combine any sections Entitled "Acknowledgements", and any sections Entitled "Dedications". You must delete all sections Entitled "Endorsements". === 6. COLLECTIONS OF DOCUMENTS -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this License -in the various documents with a single copy that is included in the collection, -provided that you follow the rules of this License for verbatim copying of each +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this License +in the various documents with a single copy that is included in the collection, +provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. -You may extract a single document from such a collection, and distribute it -individually under this License, provided you insert a copy of this License -into the extracted document, and follow this License in all other respects +You may extract a single document from such a collection, and distribute it +individually under this License, provided you insert a copy of this License +into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. === 7. AGGREGATION WITH INDEPENDENT WORKS -A compilation of the Document or its derivatives with other separate and -independent documents or works, in or on a volume of a storage or distribution -medium, is called an "aggregate" if the copyright resulting from the -compilation is not used to limit the legal rights of the compilation's users -beyond what the individual works permit. When the Document is included in an -aggregate, this License does not apply to the other works in the aggregate +A compilation of the Document or its derivatives with other separate and +independent documents or works, in or on a volume of a storage or distribution +medium, is called an "aggregate" if the copyright resulting from the +compilation is not used to limit the legal rights of the compilation's users +beyond what the individual works permit. When the Document is included in an +aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. -If the Cover Text requirement of section 3 is applicable to these copies of the -Document, then if the Document is less than one half of the entire aggregate, -the Document's Cover Texts may be placed on covers that bracket the Document -within the aggregate, or the electronic equivalent of covers if the Document is -in electronic form. Otherwise they must appear on printed covers that bracket +If the Cover Text requirement of section 3 is applicable to these copies of the +Document, then if the Document is less than one half of the entire aggregate, +the Document's Cover Texts may be placed on covers that bracket the Document +within the aggregate, or the electronic equivalent of covers if the Document is +in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. === 8. TRANSLATION -Translation is considered a kind of modification, so you may distribute -translations of the Document under the terms of section 4. Replacing Invariant -Sections with translations requires special permission from their copyright -holders, but you may include translations of some or all Invariant Sections in -addition to the original versions of these Invariant Sections. You may include -a translation of this License, and all the license notices in the Document, and -any Warranty Disclaimers, provided that you also include the original English -version of this License and the original versions of those notices and -disclaimers. In case of a disagreement between the translation and the original -version of this License or a notice or disclaimer, the original version will +Translation is considered a kind of modification, so you may distribute +translations of the Document under the terms of section 4. Replacing Invariant +Sections with translations requires special permission from their copyright +holders, but you may include translations of some or all Invariant Sections in +addition to the original versions of these Invariant Sections. You may include +a translation of this License, and all the license notices in the Document, and +any Warranty Disclaimers, provided that you also include the original English +version of this License and the original versions of those notices and +disclaimers. In case of a disagreement between the translation and the original +version of this License or a notice or disclaimer, the original version will prevail. -If a section in the Document is Entitled "Acknowledgements", "Dedications", or -"History", the requirement (section 4) to Preserve its Title (section 1) will +If a section in the Document is Entitled "Acknowledgements", "Dedications", or +"History", the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. === 9. TERMINATION -You may not copy, modify, sublicense, or distribute the Document except as -expressly provided under this License. Any attempt otherwise to copy, modify, -sublicense, or distribute it is void, and will automatically terminate your +You may not copy, modify, sublicense, or distribute the Document except as +expressly provided under this License. Any attempt otherwise to copy, modify, +sublicense, or distribute it is void, and will automatically terminate your rights under this License. -However, if you cease all violation of this License, then your license from a -particular copyright holder is reinstated (a) provisionally, unless and until -the copyright holder explicitly and finally terminates your license, and (b) -permanently, if the copyright holder fails to notify you of the violation by +However, if you cease all violation of this License, then your license from a +particular copyright holder is reinstated (a) provisionally, unless and until +the copyright holder explicitly and finally terminates your license, and (b) +permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. -Moreover, your license from a particular copyright holder is reinstated -permanently if the copyright holder notifies you of the violation by some -reasonable means, this is the first time you have received notice of violation -of this License (for any work) from that copyright holder, and you cure the +Moreover, your license from a particular copyright holder is reinstated +permanently if the copyright holder notifies you of the violation by some +reasonable means, this is the first time you have received notice of violation +of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. -Termination of your rights under this section does not terminate the licenses -of parties who have received copies or rights from you under this License. If -your rights have been terminated and not permanently reinstated, receipt of a +Termination of your rights under this section does not terminate the licenses +of parties who have received copies or rights from you under this License. If +your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it. === 10. FUTURE REVISIONS OF THIS LICENSE -The Free Software Foundation may publish new, revised versions of the GNU Free -Documentation License from time to time. Such new versions will be similar in -spirit to the present version, but may differ in detail to address new problems +The Free Software Foundation may publish new, revised versions of the GNU Free +Documentation License from time to time. Such new versions will be similar in +spirit to the present version, but may differ in detail to address new problems or concerns. See http://www.gnu.org/copyleft/. -Each version of the License is given a distinguishing version number. If the -Document specifies that a particular numbered version of this License "or any -later version" applies to it, you have the option of following the terms and -conditions either of that specified version or of any later version that has -been published (not as a draft) by the Free Software Foundation. If the -Document does not specify a version number of this License, you may choose any -version ever published (not as a draft) by the Free Software Foundation. If the -Document specifies that a proxy can decide which future versions of this -License can be used, that proxy's public statement of acceptance of a version +Each version of the License is given a distinguishing version number. If the +Document specifies that a particular numbered version of this License "or any +later version" applies to it, you have the option of following the terms and +conditions either of that specified version or of any later version that has +been published (not as a draft) by the Free Software Foundation. If the +Document does not specify a version number of this License, you may choose any +version ever published (not as a draft) by the Free Software Foundation. If the +Document specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Document. === 11. RELICENSING -"Massive Multiauthor Collaboration Site" (or "MMC Site") means any World Wide -Web server that publishes copyrightable works and also provides prominent -facilities for anybody to edit those works. A public wiki that anybody can edit -is an example of such a server. A "Massive Multiauthor Collaboration" (or -"MMC") contained in the site means any set of copyrightable works thus +"Massive Multiauthor Collaboration Site" (or "MMC Site") means any World Wide +Web server that publishes copyrightable works and also provides prominent +facilities for anybody to edit those works. A public wiki that anybody can edit +is an example of such a server. A "Massive Multiauthor Collaboration" (or +"MMC") contained in the site means any set of copyrightable works thus published on the MMC site. -"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license -published by Creative Commons Corporation, a not-for-profit corporation with a -principal place of business in San Francisco, California, as well as future +"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0 license +published by Creative Commons Corporation, a not-for-profit corporation with a +principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization. -"Incorporate" means to publish or republish a Document, in whole or in part, as +"Incorporate" means to publish or republish a Document, in whole or in part, as part of another Document. -An MMC is "eligible for relicensing" if it is licensed under this License, and -if all works that were first published under this License somewhere other than -this MMC, and subsequently incorporated in whole or in part into the MMC, (1) -had no cover texts or invariant sections, and (2) were thus incorporated prior +An MMC is "eligible for relicensing" if it is licensed under this License, and +if all works that were first published under this License somewhere other than +this MMC, and subsequently incorporated in whole or in part into the MMC, (1) +had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008. -The operator of an MMC Site may republish an MMC contained in the site under -CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC +The operator of an MMC Site may republish an MMC contained in the site under +CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing. diff --git a/dpkg/copyright b/dpkg/copyright index 506a53d4..a38a139c 100644 --- a/dpkg/copyright +++ b/dpkg/copyright @@ -3,7 +3,7 @@ Upstream-Name: libfsntfs Source: https://github.com/libyal/libfsntfs Files: * -Copyright: 2010-2017, Joachim Metz +Copyright: 2010-2018, Joachim Metz License: LGPL-3.0+ License: LGPL-3.0+ diff --git a/fsntfstools/fsntfstools_getopt.c b/fsntfstools/fsntfstools_getopt.c index 174d6ecb..60f21081 100644 --- a/fsntfstools/fsntfstools_getopt.c +++ b/fsntfstools/fsntfstools_getopt.c @@ -47,6 +47,10 @@ system_character_t *optarg = NULL; */ system_integer_t optopt = 0; +/* The next option in a group + */ +system_character_t *next_option = NULL; + /* Get the program options * Function for platforms that do not have the getopt function * Returns the option character processed, or -1 on error, @@ -62,33 +66,41 @@ system_integer_t fsntfstools_getopt( static char *function = "fsntfstools_getopt"; size_t options_string_length = 0; - if( optind >= argument_count ) + if( next_option != NULL ) { - return( (system_integer_t) -1 ); + argument_value = next_option; + next_option = NULL; } - argument_value = argument_values[ optind ]; - - /* Check if the argument value is not an empty string - */ - if( *argument_value == 0 ) + else if( optind >= argument_count ) { return( (system_integer_t) -1 ); } - /* Check if the first character is a option marker '-' - */ - if( *argument_value != (system_character_t) '-' ) + else { - return( (system_integer_t) -1 ); - } - argument_value++; + argument_value = argument_values[ optind ]; - /* Check if long options are provided '--' - */ - if( *argument_value == (system_character_t) '-' ) - { - optind++; + /* Check if the argument value is not an empty string + */ + if( *argument_value == (system_character_t) '\0' ) + { + return( (system_integer_t) -1 ); + } + /* Check if the first character is a option marker '-' + */ + if( *argument_value != (system_character_t) '-' ) + { + return( (system_integer_t) -1 ); + } + argument_value++; - return( (system_integer_t) -1 ); + /* Check if long options are provided '--' + */ + if( *argument_value == (system_character_t) '-' ) + { + optind++; + + return( (system_integer_t) -1 ); + } } options_string_length = system_string_length( options_string ); @@ -133,6 +145,12 @@ system_integer_t fsntfstools_getopt( { optind++; } + else + { + /* Multiple options are grouped + */ + next_option = argument_value; + } } /* Check if the argument is right after the option flag with no space in between */ diff --git a/libfsntfs.ini b/libfsntfs.ini index b9dffc3b..e8317ad7 100644 --- a/libfsntfs.ini +++ b/libfsntfs.ini @@ -1,4 +1,5 @@ [project] +description: "libfsntfs is a library to access the New Technology File System (NTFS)." name: "libfsntfs" status: "experimental" year_of_creation: "2010" diff --git a/m4/libcdata.m4 b/m4/libcdata.m4 index c19c04f7..f4067aa6 100644 --- a/m4/libcdata.m4 +++ b/m4/libcdata.m4 @@ -1,6 +1,6 @@ dnl Checks for libcdata or required headers and functions dnl -dnl Version: 20170904 +dnl Version: 20180316 dnl Function to detect if libcdata is available dnl ac_libcdata_dummy is used to prevent AC_CHECK_LIB adding unnecessary -l arguments @@ -123,6 +123,48 @@ AC_DEFUN([AX_LIBCDATA_CHECK_LIB], [ac_cv_libcdata_dummy=yes], [ac_cv_libcdata=no]) + dnl Balanced tree functions + AC_CHECK_LIB( + cdata, + libfdata_btree_initialize, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + AC_CHECK_LIB( + cdata, + libcdata_btree_free, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + AC_CHECK_LIB( + cdata, + libcdata_btree_get_number_of_values, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + AC_CHECK_LIB( + cdata, + libcdata_btree_get_value_by_index, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + AC_CHECK_LIB( + cdata, + libcdata_btree_get_value_by_value, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + AC_CHECK_LIB( + cdata, + libcdata_btree_insert_value, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + AC_CHECK_LIB( + cdata, + libcdata_btree_replace_value, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + AC_CHECK_LIB( + cdata, + libcdata_btree_remove_value, + [ac_cv_libcdata_dummy=yes], + [ac_cv_libcdata=no]) + dnl List functions AC_CHECK_LIB( cdata, diff --git a/m4/libcsplit.m4 b/m4/libcsplit.m4 index f49d8399..c9110169 100644 --- a/m4/libcsplit.m4 +++ b/m4/libcsplit.m4 @@ -1,6 +1,6 @@ dnl Checks for libcsplit or required headers and functions dnl -dnl Version: 20170903 +dnl Version: 20180217 dnl Function to detect if libcsplit is available dnl ac_libcsplit_dummy is used to prevent AC_CHECK_LIB adding unnecessary -l arguments @@ -111,7 +111,7 @@ AC_DEFUN([AX_LIBCSPLIT_CHECK_LIB], AS_IF( [test "x$ac_cv_enable_wide_character_type" != xno], [AC_CHECK_LIB( - csplit, + csplit, libcsplit_wide_string_split, [ac_cv_libcsplit_dummy=yes], [ac_cv_libcsplit=no]) diff --git a/m4/libfdata.m4 b/m4/libfdata.m4 index 3e7670d8..6dfec55c 100644 --- a/m4/libfdata.m4 +++ b/m4/libfdata.m4 @@ -1,6 +1,6 @@ dnl Functions for libfdata dnl -dnl Version: 20170905 +dnl Version: 20180316 dnl Function to detect if libfdata is available dnl ac_libfdata_dummy is used to prevent AC_CHECK_LIB adding unnecessary -l arguments @@ -49,7 +49,76 @@ AC_DEFUN([AX_LIBFDATA_CHECK_LIB], [ac_cv_libfdata=no]) dnl Area functions - dnl TODO: add functions + AC_CHECK_LIB( + fdata, + libfdata_area_initialize, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_free, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_clone, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_empty, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_resize, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_get_number_of_segments, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_get_segment_by_index, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_set_segment_by_index, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_prepend_segment, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_append_segment, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_get_element_data_size, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_get_element_value_at_offset, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_set_element_value_at_offset, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) + AC_CHECK_LIB( + fdata, + libfdata_area_get_size, + [ac_cv_libfdata_dummy=yes], + [ac_cv_libfdata=no]) dnl Balanced tree functions dnl TODO: add functions diff --git a/msvscpp/fsntfs_test_notify/fsntfs_test_notify.vcproj b/msvscpp/fsntfs_test_notify/fsntfs_test_notify.vcproj index 9bc5492c..6c052d03 100644 --- a/msvscpp/fsntfs_test_notify/fsntfs_test_notify.vcproj +++ b/msvscpp/fsntfs_test_notify/fsntfs_test_notify.vcproj @@ -185,6 +185,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + diff --git a/msvscpp/fsntfs_test_support/fsntfs_test_support.vcproj b/msvscpp/fsntfs_test_support/fsntfs_test_support.vcproj index 66d8aa53..8b678cdd 100644 --- a/msvscpp/fsntfs_test_support/fsntfs_test_support.vcproj +++ b/msvscpp/fsntfs_test_support/fsntfs_test_support.vcproj @@ -175,10 +175,18 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + + + @@ -189,6 +197,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + @@ -221,6 +233,14 @@ RelativePath="..\..\tests\fsntfs_test_macros.h" > + + + + + + @@ -193,6 +197,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + @@ -225,6 +233,10 @@ RelativePath="..\..\tests\fsntfs_test_memory.h" > + + /dev/null; HAVE_ENABLE_WIDE_CHARACTER_TYPE=$?; +echo "${CONFIGURE_HELP}" | grep -- '--enable-verbose-output' > /dev/null; + +HAVE_ENABLE_VERBOSE_OUTPUT=$?; + +echo "${CONFIGURE_HELP}" | grep -- '--enable-debug-output' > /dev/null; + +HAVE_ENABLE_DEBUG_OUTPUT=$?; + echo "${CONFIGURE_HELP}" | grep -- '--with-zlib' > /dev/null; HAVE_WITH_ZLIB=$?; @@ -230,6 +238,19 @@ then exit ${EXIT_FAILURE}; fi +if test ${HAVE_ENABLE_VERBOSE_OUTPUT} -eq 0 && test ${HAVE_ENABLE_DEBUG_OUTPUT} -eq 0; +then + # Test "./configure && make && make check" with verbose and debug output. + + run_configure_make_check "--enable-verbose-output --enable-debug-output"; + RESULT=$?; + + if test ${RESULT} -ne ${EXIT_SUCCESS}; + then + exit ${EXIT_FAILURE}; + fi +fi + if test ${HAVE_WITH_ZLIB} -eq 0; then # Test "./configure && make && make check" with fallback zlib implementation. diff --git a/setup.py b/setup.py index be400e28..176e1d08 100755 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # # Script to build and install Python-bindings. -# Version: 20171105 +# Version: 20180317 from __future__ import print_function import glob @@ -164,6 +164,9 @@ def run(self): dist_files = getattr(self.distribution, "dist_files", []) dist_files.append(("sdist", "", sdist_package_file)) + # Make sure PKG-INFO is generated. + sdist.run(self) + class ProjectInformation(object): """Project information.""" diff --git a/synclibs.ps1 b/synclibs.ps1 index 3ab3a543..54fffa6c 100644 --- a/synclibs.ps1 +++ b/synclibs.ps1 @@ -1,6 +1,10 @@ # Script that synchronizes the local library dependencies # -# Version: 20170722 +# Version: 20180125 + +Param ( + [switch]$UseHead = $false +) $GitUrlPrefix = "https://github.com/libyal" $LocalLibs = "libbfio libcdata libcerror libcfile libclocale libcnotify libcpath libcsplit libcthreads libfcache libfdata libfdatetime libfguid libfusn libfwnt libuna" @@ -17,11 +21,35 @@ ForEach (${LocalLib} in ${LocalLibs}) { Continue } + $GitUrl = "${GitUrlPrefix}/${LocalLib}.git" + # PowerShell will raise NativeCommandError if git writes to stdout or stderr # therefore 2>&1 is added and the output is stored in a variable. - $Output = Invoke-Expression -Command "${Git} clone ${GitUrlPrefix}/${LocalLib}.git ${LocalLib}-${pid} 2>&1" - Write-Host ${Output} + $Output = Invoke-Expression -Command "${Git} clone ${GitUrl} ${LocalLib}-${pid} 2>&1" + + Push-Location "${LocalLib}-${pid}" + + Try + { + $Output = Invoke-Expression -Command "${Git} fetch --quiet --all --tags --prune 2>&1" + + $LatestTag = Invoke-Expression -Command "${Git} describe --tags --abbrev=0 2>&1" + + If (${LatestTag} -and -not ${UseHead}) + { + Write-Host "Synchronizing: ${LocalLib} from ${GitUrl} tag ${LatestTag}" + $Output = Invoke-Expression -Command "${Git} checkout --quiet tags/${LatestTag} 2>&1" + } + Else + { + Write-Host "Synchronizing: ${LocalLib} from ${GitUrl} HEAD" + } + } + Finally + { + Pop-Location + } If (Test-Path ${LocalLib}-${pid}) { $LocalLibVersion = Get-Content -Path ${LocalLib}-${pid}\configure.ac | select -skip 4 -first 1 | % { $_ -Replace " \[","" } | % { $_ -Replace "\],","" } diff --git a/tests/Makefile.am b/tests/Makefile.am index f4e3b57d..631ccb62 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -325,13 +325,15 @@ fsntfs_test_mft_metadata_file_LDADD = \ @PTHREAD_LIBADD@ fsntfs_test_notify_SOURCES = \ + fsntfs_test_libcerror.h \ fsntfs_test_libfsntfs.h \ fsntfs_test_macros.h \ fsntfs_test_notify.c \ fsntfs_test_unused.h fsntfs_test_notify_LDADD = \ - ../libfsntfs/libfsntfs.la + ../libfsntfs/libfsntfs.la \ + @LIBCERROR_LIBADD@ fsntfs_test_object_identifier_values_SOURCES = \ fsntfs_test_libcerror.h \ @@ -407,6 +409,7 @@ fsntfs_test_standard_information_values_LDADD = \ fsntfs_test_support_SOURCES = \ fsntfs_test_getopt.c fsntfs_test_getopt.h \ + fsntfs_test_functions.c fsntfs_test_functions.h \ fsntfs_test_libbfio.h \ fsntfs_test_libcerror.h \ fsntfs_test_libclocale.h \ @@ -414,7 +417,9 @@ fsntfs_test_support_SOURCES = \ fsntfs_test_libfsntfs.h \ fsntfs_test_libuna.h \ fsntfs_test_macros.h \ - fsntfs_test_support.c + fsntfs_test_memory.c fsntfs_test_memory.h \ + fsntfs_test_support.c \ + fsntfs_test_unused.h fsntfs_test_support_LDADD = \ @LIBBFIO_LIBADD@ \ @@ -454,6 +459,7 @@ fsntfs_test_usn_change_journal_LDADD = \ fsntfs_test_volume_SOURCES = \ fsntfs_test_getopt.c fsntfs_test_getopt.h \ + fsntfs_test_functions.c fsntfs_test_functions.h \ fsntfs_test_libcerror.h \ fsntfs_test_libclocale.h \ fsntfs_test_libcnotify.h \ @@ -461,10 +467,15 @@ fsntfs_test_volume_SOURCES = \ fsntfs_test_libuna.h \ fsntfs_test_macros.h \ fsntfs_test_memory.c fsntfs_test_memory.h \ - fsntfs_test_volume.c + fsntfs_test_volume.c \ + fsntfs_test_unused.h fsntfs_test_volume_LDADD = \ + @LIBBFIO_LIBADD@ \ + @LIBCPATH_LIBADD@ \ + @LIBCFILE_LIBADD@ \ @LIBUNA_LIBADD@ \ + @LIBCSPLIT_LIBADD@ \ @LIBCNOTIFY_LIBADD@ \ @LIBCLOCALE_LIBADD@ \ @LIBCDATA_LIBADD@ \ diff --git a/tests/fsntfs_test_functions.c b/tests/fsntfs_test_functions.c new file mode 100644 index 00000000..f8185c27 --- /dev/null +++ b/tests/fsntfs_test_functions.c @@ -0,0 +1,673 @@ +/* + * Functions for testing + * + * Copyright (C) 2010-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 +#include + +#if defined( HAVE_STDLIB_H ) || defined( WINAPI ) +#include +#endif + +#include "fsntfs_test_libbfio.h" +#include "fsntfs_test_libcerror.h" +#include "fsntfs_test_libclocale.h" +#include "fsntfs_test_libuna.h" + +/* Retrieves source as a narrow string + * Returns 1 if successful or -1 on error + */ +int fsntfs_test_get_narrow_source( + const system_character_t *source, + char *narrow_string, + size_t narrow_string_size, + libcerror_error_t **error ) +{ + static char *function = "fsntfs_test_get_narrow_source"; + size_t narrow_source_size = 0; + size_t source_length = 0; + +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + int result = 0; +#endif + + if( source == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid source.", + function ); + + return( -1 ); + } + if( narrow_string == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid narrow string.", + function ); + + return( -1 ); + } + if( narrow_string_size > (size_t) SSIZE_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid narrow string size value exceeds maximum.", + function ); + + return( -1 ); + } + source_length = system_string_length( + source ); + + if( source_length > (size_t) ( SSIZE_MAX - 1 ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid source length value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + if( libclocale_codepage == 0 ) + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_utf8_string_size_from_utf32( + (libuna_utf32_character_t *) source, + source_length + 1, + &narrow_source_size, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_utf8_string_size_from_utf16( + (libuna_utf16_character_t *) source, + source_length + 1, + &narrow_source_size, + error ); +#endif + } + else + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_byte_stream_size_from_utf32( + (libuna_utf32_character_t *) source, + source_length + 1, + libclocale_codepage, + &narrow_source_size, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_byte_stream_size_from_utf16( + (libuna_utf16_character_t *) source, + source_length + 1, + libclocale_codepage, + &narrow_source_size, + error ); +#endif + } + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_GENERIC, + "%s: unable to determine narrow string size.", + function ); + + return( -1 ); + } +#else + narrow_source_size = source_length + 1; + +#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ + + if( narrow_string_size < narrow_source_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, + "%s: narrow string too small.", + function ); + + return( -1 ); + } +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + if( libclocale_codepage == 0 ) + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_utf8_string_copy_from_utf32( + (libuna_utf8_character_t *) narrow_string, + narrow_string_size, + (libuna_utf32_character_t *) source, + source_length + 1, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_utf8_string_copy_from_utf16( + (libuna_utf8_character_t *) narrow_string, + narrow_string_size, + (libuna_utf16_character_t *) source, + source_length + 1, + error ); +#endif + } + else + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_byte_stream_copy_from_utf32( + (uint8_t *) narrow_string, + narrow_string_size, + libclocale_codepage, + (libuna_utf32_character_t *) source, + source_length + 1, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_byte_stream_copy_from_utf16( + (uint8_t *) narrow_string, + narrow_string_size, + libclocale_codepage, + (libuna_utf16_character_t *) source, + source_length + 1, + error ); +#endif + } + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_GENERIC, + "%s: unable to set narrow string.", + function ); + + return( -1 ); + } +#else + if( system_string_copy( + narrow_string, + source, + source_length ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to set narrow string.", + function ); + + return( -1 ); + } + narrow_string[ source_length ] = 0; + +#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ + + return( 1 ); +} + +#if defined( HAVE_WIDE_CHARACTER_TYPE ) + +/* Retrieves source as a wide string + * Returns 1 if successful or -1 on error + */ +int fsntfs_test_get_wide_source( + const system_character_t *source, + wchar_t *wide_string, + size_t wide_string_size, + libcerror_error_t **error ) +{ + static char *function = "fsntfs_test_get_wide_source"; + size_t wide_source_size = 0; + size_t source_length = 0; + +#if !defined( HAVE_WIDE_SYSTEM_CHARACTER ) + int result = 0; +#endif + + if( source == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid source.", + function ); + + return( -1 ); + } + if( wide_string == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid wide string.", + function ); + + return( -1 ); + } + if( wide_string_size > (size_t) SSIZE_MAX ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, + "%s: invalid wide string size value exceeds maximum.", + function ); + + return( -1 ); + } + source_length = system_string_length( + source ); + + if( source_length > (size_t) ( SSIZE_MAX - 1 ) ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, + "%s: invalid source length value out of bounds.", + function ); + + return( -1 ); + } +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + wide_source_size = source_length + 1; +#else + if( libclocale_codepage == 0 ) + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_utf32_string_size_from_utf8( + (libuna_utf8_character_t *) source, + source_length + 1, + &wide_source_size, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_utf16_string_size_from_utf8( + (libuna_utf8_character_t *) source, + source_length + 1, + &wide_source_size, + error ); +#endif + } + else + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_utf32_string_size_from_byte_stream( + (uint8_t *) source, + source_length + 1, + libclocale_codepage, + &wide_source_size, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_utf16_string_size_from_byte_stream( + (uint8_t *) source, + source_length + 1, + libclocale_codepage, + &wide_source_size, + error ); +#endif + } + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_GENERIC, + "%s: unable to determine wide string size.", + function ); + + return( -1 ); + } + +#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ + + if( wide_string_size < wide_source_size ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, + "%s: wide string too small.", + function ); + + return( -1 ); + } +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + if( system_string_copy( + wide_string, + source, + source_length ) == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_MEMORY, + LIBCERROR_MEMORY_ERROR_COPY_FAILED, + "%s: unable to set wide string.", + function ); + + return( -1 ); + } + wide_string[ source_length ] = 0; +#else + if( libclocale_codepage == 0 ) + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_utf32_string_copy_from_utf8( + (libuna_utf32_character_t *) wide_string, + wide_string_size, + (uint8_t *) source, + source_length + 1, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_utf16_string_copy_from_utf8( + (libuna_utf16_character_t *) wide_string, + wide_string_size, + (uint8_t *) source, + source_length + 1, + error ); +#endif + } + else + { +#if SIZEOF_WCHAR_T == 4 + result = libuna_utf32_string_copy_from_byte_stream( + (libuna_utf32_character_t *) wide_string, + wide_string_size, + (uint8_t *) source, + source_length + 1, + libclocale_codepage, + error ); +#elif SIZEOF_WCHAR_T == 2 + result = libuna_utf16_string_copy_from_byte_stream( + (libuna_utf16_character_t *) wide_string, + wide_string_size, + (uint8_t *) source, + source_length + 1, + libclocale_codepage, + error ); +#endif + } + if( result != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_CONVERSION, + LIBCERROR_CONVERSION_ERROR_GENERIC, + "%s: unable to set wide string.", + function ); + + return( -1 ); + } + +#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ + + return( 1 ); +} + +#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */ + +/* Copies a string of a decimal value to a 64-bit value + * Returns 1 if successful or -1 on error + */ +int fsntfs_test_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 = "fsntfs_test_system_string_copy_from_64_bit_in_decimal"; + size_t string_index = 0; + system_character_t character_value = 0; + uint8_t maximum_string_index = 20; + int8_t sign = 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( value_64bit == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid value 64-bit.", + function ); + + return( -1 ); + } + *value_64bit = 0; + + if( string[ string_index ] == (system_character_t) '-' ) + { + string_index++; + maximum_string_index++; + + sign = -1; + } + else if( string[ string_index ] == (system_character_t) '+' ) + { + string_index++; + maximum_string_index++; + } + while( string_index < string_size ) + { + if( string[ string_index ] == 0 ) + { + break; + } + if( string_index > (size_t) maximum_string_index ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_LARGE, + "%s: string too large.", + function ); + + return( -1 ); + } + *value_64bit *= 10; + + if( ( string[ string_index ] >= (system_character_t) '0' ) + && ( string[ string_index ] <= (system_character_t) '9' ) ) + { + character_value = (system_character_t) ( string[ string_index ] - (system_character_t) '0' ); + } + else + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE, + "%s: unsupported character value: %" PRIc_SYSTEM " at index: %d.", + function, + string[ string_index ], + string_index ); + + return( -1 ); + } + *value_64bit += character_value; + + string_index++; + } + if( sign == -1 ) + { + *value_64bit *= (uint64_t) -1; + } + return( 1 ); +} + +/* Creates a file IO handle for test data + * Returns 1 if successful or -1 on error + */ +int fsntfs_test_open_file_io_handle( + libbfio_handle_t **file_io_handle, + uint8_t *data, + size_t data_size, + libcerror_error_t **error ) +{ + static char *function = "fsntfs_test_open_file_io_handle"; + + if( file_io_handle == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file IO handle.", + function ); + + return( -1 ); + } + if( libbfio_memory_range_initialize( + file_io_handle, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED, + "%s: unable to create file IO handle.", + function ); + + goto on_error; + } + if( libbfio_memory_range_set( + *file_io_handle, + data, + data_size, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_RUNTIME, + LIBCERROR_RUNTIME_ERROR_SET_FAILED, + "%s: unable to set memory range of file IO handle.", + function ); + + goto on_error; + } + if( libbfio_handle_open( + *file_io_handle, + LIBBFIO_OPEN_READ, + error ) != 1 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_OPEN_FAILED, + "%s: unable to open file IO handle.", + function ); + + goto on_error; + } + return( 1 ); + +on_error: + if( *file_io_handle != NULL ) + { + libbfio_handle_free( + file_io_handle, + NULL ); + } + return( -1 ); +} + +/* Closes a file IO handle for test data + * Returns 0 if successful or -1 on error + */ +int fsntfs_test_close_file_io_handle( + libbfio_handle_t **file_io_handle, + libcerror_error_t **error ) +{ + static char *function = "fsntfs_test_close_file_io_handle"; + int result = 0; + + if( file_io_handle == NULL ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_ARGUMENTS, + LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, + "%s: invalid file IO handle.", + function ); + + return( -1 ); + } + if( libbfio_handle_close( + *file_io_handle, + error ) != 0 ) + { + libcerror_error_set( + error, + LIBCERROR_ERROR_DOMAIN_IO, + LIBCERROR_IO_ERROR_CLOSE_FAILED, + "%s: unable to close file IO handle.", + function ); + + result = -1; + } + if( libbfio_handle_free( + 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 ); + + result = -1; + } + return( result ); +} + diff --git a/tests/fsntfs_test_functions.h b/tests/fsntfs_test_functions.h new file mode 100644 index 00000000..2d0075d1 --- /dev/null +++ b/tests/fsntfs_test_functions.h @@ -0,0 +1,72 @@ +/* + * Functions for testing + * + * Copyright (C) 2010-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( _FSNTFS_TEST_FUNCTIONS_H ) +#define _FSNTFS_TEST_FUNCTIONS_H + +#include +#include + +#include "fsntfs_test_libbfio.h" +#include "fsntfs_test_libcerror.h" + +#if defined( __cplusplus ) +extern "C" { +#endif + +int fsntfs_test_get_narrow_source( + const system_character_t *source, + char *narrow_string, + size_t narrow_string_size, + libcerror_error_t **error ); + +#if defined( HAVE_WIDE_CHARACTER_TYPE ) + +int fsntfs_test_get_wide_source( + const system_character_t *source, + wchar_t *wide_string, + size_t wide_string_size, + libcerror_error_t **error ); + +#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */ + +int fsntfs_test_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 ); + +int fsntfs_test_open_file_io_handle( + libbfio_handle_t **file_io_handle, + uint8_t *data, + size_t data_size, + libcerror_error_t **error ); + +int fsntfs_test_close_file_io_handle( + libbfio_handle_t **file_io_handle, + libcerror_error_t **error ); + +#if defined( __cplusplus ) +} +#endif + +#endif /* !defined( _FSNTFS_TEST_FUNCTIONS_H ) */ + diff --git a/tests/fsntfs_test_getopt.c b/tests/fsntfs_test_getopt.c index f6efeff1..8b542adf 100644 --- a/tests/fsntfs_test_getopt.c +++ b/tests/fsntfs_test_getopt.c @@ -47,6 +47,10 @@ system_character_t *optarg = NULL; */ system_integer_t optopt = 0; +/* The next option in a group + */ +system_character_t *next_option = NULL; + /* Get the program options * Function for platforms that do not have the getopt function * Returns the option character processed, or -1 on error, @@ -62,33 +66,41 @@ system_integer_t fsntfs_test_getopt( static char *function = "fsntfs_test_getopt"; size_t options_string_length = 0; - if( optind >= argument_count ) + if( next_option != NULL ) { - return( (system_integer_t) -1 ); + argument_value = next_option; + next_option = NULL; } - argument_value = argument_values[ optind ]; - - /* Check if the argument value is not an empty string - */ - if( *argument_value == 0 ) + else if( optind >= argument_count ) { return( (system_integer_t) -1 ); } - /* Check if the first character is a option marker '-' - */ - if( *argument_value != (system_character_t) '-' ) + else { - return( (system_integer_t) -1 ); - } - argument_value++; + argument_value = argument_values[ optind ]; - /* Check if long options are provided '--' - */ - if( *argument_value == (system_character_t) '-' ) - { - optind++; + /* Check if the argument value is not an empty string + */ + if( *argument_value == (system_character_t) '\0' ) + { + return( (system_integer_t) -1 ); + } + /* Check if the first character is a option marker '-' + */ + if( *argument_value != (system_character_t) '-' ) + { + return( (system_integer_t) -1 ); + } + argument_value++; - return( (system_integer_t) -1 ); + /* Check if long options are provided '--' + */ + if( *argument_value == (system_character_t) '-' ) + { + optind++; + + return( (system_integer_t) -1 ); + } } options_string_length = system_string_length( options_string ); @@ -133,6 +145,12 @@ system_integer_t fsntfs_test_getopt( { optind++; } + else + { + /* Multiple options are grouped + */ + next_option = argument_value; + } } /* Check if the argument is right after the option flag with no space in between */ diff --git a/tests/fsntfs_test_notify.c b/tests/fsntfs_test_notify.c index ad5ef48f..852f3ffb 100644 --- a/tests/fsntfs_test_notify.c +++ b/tests/fsntfs_test_notify.c @@ -27,6 +27,7 @@ #include #endif +#include "fsntfs_test_libcerror.h" #include "fsntfs_test_libfsntfs.h" #include "fsntfs_test_macros.h" #include "fsntfs_test_unused.h" @@ -51,13 +52,37 @@ int fsntfs_test_notify_set_verbose( int fsntfs_test_notify_set_stream( void ) { - /* Test invocation of function only + libcerror_error_t *error = NULL; + int result = 0; + + /* Test regular cases */ - libfsntfs_notify_set_stream( - NULL, - NULL ); + result = libfsntfs_notify_set_stream( + NULL, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases + */ +/* TODO test libcnotify_stream_set failure */ return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + return( 0 ); } /* Tests the libfsntfs_notify_stream_open function @@ -66,13 +91,65 @@ int fsntfs_test_notify_set_stream( int fsntfs_test_notify_stream_open( void ) { - /* Test invocation of function only + libcerror_error_t *error = NULL; + int result = 0; + + /* Test regular cases + */ + result = libfsntfs_notify_stream_open( + "notify_stream.log", + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases */ - libfsntfs_notify_stream_open( - NULL, - NULL ); + result = libfsntfs_notify_stream_open( + NULL, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSNTFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + + /* Clean up + */ + result = libfsntfs_notify_stream_close( + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + return( 0 ); } /* Tests the libfsntfs_notify_stream_close function @@ -81,12 +158,36 @@ int fsntfs_test_notify_stream_open( int fsntfs_test_notify_stream_close( void ) { - /* Test invocation of function only + libcerror_error_t *error = NULL; + int result = 0; + + /* Test regular cases + */ + result = libfsntfs_notify_stream_close( + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test error cases */ - libfsntfs_notify_stream_close( - NULL ); +/* TODO test libcnotify_stream_close failure */ return( 1 ); + +on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } + return( 0 ); } /* The main program diff --git a/tests/fsntfs_test_support.c b/tests/fsntfs_test_support.c index c7653122..86c57c17 100644 --- a/tests/fsntfs_test_support.c +++ b/tests/fsntfs_test_support.c @@ -30,419 +30,23 @@ #include #endif +#include "fsntfs_test_functions.h" #include "fsntfs_test_getopt.h" #include "fsntfs_test_libbfio.h" #include "fsntfs_test_libcerror.h" -#include "fsntfs_test_libclocale.h" #include "fsntfs_test_libfsntfs.h" -#include "fsntfs_test_libuna.h" #include "fsntfs_test_macros.h" +#include "fsntfs_test_memory.h" #include "fsntfs_test_unused.h" +#if !defined( LIBFSNTFS_HAVE_BFIO ) + LIBFSNTFS_EXTERN \ int libfsntfs_check_volume_signature_file_io_handle( libbfio_handle_t *file_io_handle, libcerror_error_t **error ); -/* Retrieves source as a narrow string - * Returns 1 if successful or -1 on error - */ -int fsntfs_test_support_get_narrow_source( - const system_character_t *source, - char *narrow_string, - size_t narrow_string_size, - libcerror_error_t **error ) -{ - static char *function = "fsntfs_test_support_get_narrow_source"; - size_t narrow_source_size = 0; - size_t source_length = 0; - -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) - int result = 0; -#endif - - if( source == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid source.", - function ); - - return( -1 ); - } - if( narrow_string == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid narrow string.", - function ); - - return( -1 ); - } - if( narrow_string_size > (size_t) SSIZE_MAX ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid narrow string size value exceeds maximum.", - function ); - - return( -1 ); - } - source_length = system_string_length( - source ); - - if( source_length > (size_t) ( SSIZE_MAX - 1 ) ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid source length value out of bounds.", - function ); - - return( -1 ); - } -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) - if( libclocale_codepage == 0 ) - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_utf8_string_size_from_utf32( - (libuna_utf32_character_t *) source, - source_length + 1, - &narrow_source_size, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_utf8_string_size_from_utf16( - (libuna_utf16_character_t *) source, - source_length + 1, - &narrow_source_size, - error ); -#endif - } - else - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_byte_stream_size_from_utf32( - (libuna_utf32_character_t *) source, - source_length + 1, - libclocale_codepage, - &narrow_source_size, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_byte_stream_size_from_utf16( - (libuna_utf16_character_t *) source, - source_length + 1, - libclocale_codepage, - &narrow_source_size, - error ); -#endif - } - if( result != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_CONVERSION, - LIBCERROR_CONVERSION_ERROR_GENERIC, - "%s: unable to determine narrow string size.", - function ); - - return( -1 ); - } -#else - narrow_source_size = source_length + 1; - -#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ - - if( narrow_string_size < narrow_source_size ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: narrow string too small.", - function ); - - return( -1 ); - } -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) - if( libclocale_codepage == 0 ) - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_utf8_string_copy_from_utf32( - (libuna_utf8_character_t *) narrow_string, - narrow_string_size, - (libuna_utf32_character_t *) source, - source_length + 1, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_utf8_string_copy_from_utf16( - (libuna_utf8_character_t *) narrow_string, - narrow_string_size, - (libuna_utf16_character_t *) source, - source_length + 1, - error ); -#endif - } - else - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_byte_stream_copy_from_utf32( - (uint8_t *) narrow_string, - narrow_string_size, - libclocale_codepage, - (libuna_utf32_character_t *) source, - source_length + 1, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_byte_stream_copy_from_utf16( - (uint8_t *) narrow_string, - narrow_string_size, - libclocale_codepage, - (libuna_utf16_character_t *) source, - source_length + 1, - error ); -#endif - } - if( result != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_CONVERSION, - LIBCERROR_CONVERSION_ERROR_GENERIC, - "%s: unable to set narrow string.", - function ); - - return( -1 ); - } -#else - if( system_string_copy( - narrow_string, - source, - source_length ) == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_COPY_FAILED, - "%s: unable to set narrow string.", - function ); - - return( -1 ); - } - narrow_string[ source_length ] = 0; - -#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ - - return( 1 ); -} - -#if defined( HAVE_WIDE_CHARACTER_TYPE ) - -/* Retrieves source as a wide string - * Returns 1 if successful or -1 on error - */ -int fsntfs_test_support_get_wide_source( - const system_character_t *source, - wchar_t *wide_string, - size_t wide_string_size, - libcerror_error_t **error ) -{ - static char *function = "fsntfs_test_support_get_wide_source"; - size_t wide_source_size = 0; - size_t source_length = 0; - -#if !defined( HAVE_WIDE_SYSTEM_CHARACTER ) - int result = 0; -#endif - - if( source == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid source.", - function ); - - return( -1 ); - } - if( wide_string == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, - "%s: invalid wide string.", - function ); - - return( -1 ); - } - if( wide_string_size > (size_t) SSIZE_MAX ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, - "%s: invalid wide string size value exceeds maximum.", - function ); - - return( -1 ); - } - source_length = system_string_length( - source ); - - if( source_length > (size_t) ( SSIZE_MAX - 1 ) ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_RUNTIME, - LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS, - "%s: invalid source length value out of bounds.", - function ); - - return( -1 ); - } -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) - wide_source_size = source_length + 1; -#else - if( libclocale_codepage == 0 ) - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_utf32_string_size_from_utf8( - (libuna_utf8_character_t *) source, - source_length + 1, - &wide_source_size, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_utf16_string_size_from_utf8( - (libuna_utf8_character_t *) source, - source_length + 1, - &wide_source_size, - error ); -#endif - } - else - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_utf32_string_size_from_byte_stream( - (uint8_t *) source, - source_length + 1, - libclocale_codepage, - &wide_source_size, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_utf16_string_size_from_byte_stream( - (uint8_t *) source, - source_length + 1, - libclocale_codepage, - &wide_source_size, - error ); -#endif - } - if( result != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_CONVERSION, - LIBCERROR_CONVERSION_ERROR_GENERIC, - "%s: unable to determine wide string size.", - function ); - - return( -1 ); - } - -#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ - - if( wide_string_size < wide_source_size ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_ARGUMENTS, - LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, - "%s: wide string too small.", - function ); - - return( -1 ); - } -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) - if( system_string_copy( - wide_string, - source, - source_length ) == NULL ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_MEMORY, - LIBCERROR_MEMORY_ERROR_COPY_FAILED, - "%s: unable to set wide string.", - function ); - - return( -1 ); - } - wide_string[ source_length ] = 0; -#else - if( libclocale_codepage == 0 ) - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_utf32_string_copy_from_utf8( - (libuna_utf32_character_t *) wide_string, - wide_string_size, - (uint8_t *) source, - source_length + 1, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_utf16_string_copy_from_utf8( - (libuna_utf16_character_t *) wide_string, - wide_string_size, - (uint8_t *) source, - source_length + 1, - error ); -#endif - } - else - { -#if SIZEOF_WCHAR_T == 4 - result = libuna_utf32_string_copy_from_byte_stream( - (libuna_utf32_character_t *) wide_string, - wide_string_size, - (uint8_t *) source, - source_length + 1, - libclocale_codepage, - error ); -#elif SIZEOF_WCHAR_T == 2 - result = libuna_utf16_string_copy_from_byte_stream( - (libuna_utf16_character_t *) wide_string, - wide_string_size, - (uint8_t *) source, - source_length + 1, - libclocale_codepage, - error ); -#endif - } - if( result != 1 ) - { - libcerror_error_set( - error, - LIBCERROR_ERROR_DOMAIN_CONVERSION, - LIBCERROR_CONVERSION_ERROR_GENERIC, - "%s: unable to set wide string.", - function ); - - return( -1 ); - } - -#endif /* defined( HAVE_WIDE_SYSTEM_CHARACTER ) */ - - return( 1 ); -} - -#endif /* defined( HAVE_WIDE_CHARACTER_TYPE ) */ +#endif /* !defined( LIBFSNTFS_HAVE_BFIO ) */ /* Tests the libfsntfs_get_version function * Returns 1 if successful or 0 if not @@ -606,42 +210,60 @@ int fsntfs_test_check_volume_signature( libcerror_error_t *error = NULL; int result = 0; - /* Initialize test - */ - result = fsntfs_test_support_get_narrow_source( - source, - narrow_source, - 256, - &error ); - - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test check volume signature + if( source != NULL ) + { + /* Initialize test + */ + result = fsntfs_test_get_narrow_source( + source, + narrow_source, + 256, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test check volume signature + */ + result = libfsntfs_check_volume_signature( + narrow_source, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + } + /* Test error cases */ result = libfsntfs_check_volume_signature( - narrow_source, + NULL, &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( "result", result, - 1 ); + -1 ); - FSNTFS_TEST_ASSERT_IS_NULL( + FSNTFS_TEST_ASSERT_IS_NOT_NULL( "error", error ); - /* Test error cases - */ + libcerror_error_free( + &error ); + result = libfsntfs_check_volume_signature( - NULL, + "", &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( @@ -656,6 +278,38 @@ int fsntfs_test_check_volume_signature( libcerror_error_free( &error ); + if( source != NULL ) + { +#if defined( HAVE_FSNTFS_TEST_MEMORY ) + + /* Test libfsntfs_check_volume_signature with malloc failing in libbfio_file_initialize + */ + fsntfs_test_malloc_attempts_before_fail = 0; + + result = libfsntfs_check_volume_signature( + narrow_source, + &error ); + + if( fsntfs_test_malloc_attempts_before_fail != -1 ) + { + fsntfs_test_malloc_attempts_before_fail = -1; + } + else + { + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSNTFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + } +#endif /* defined( HAVE_FSNTFS_TEST_MEMORY ) */ + } return( 1 ); on_error: @@ -680,42 +334,60 @@ int fsntfs_test_check_volume_signature_wide( libcerror_error_t *error = NULL; int result = 0; - /* Initialize test - */ - result = fsntfs_test_support_get_wide_source( - source, - wide_source, - 256, - &error ); - - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test check volume signature + if( source != NULL ) + { + /* Initialize test + */ + result = fsntfs_test_get_wide_source( + source, + wide_source, + 256, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test check volume signature + */ + result = libfsntfs_check_volume_signature_wide( + wide_source, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + } + /* Test error cases */ result = libfsntfs_check_volume_signature_wide( - wide_source, + NULL, &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( "result", result, - 1 ); + -1 ); - FSNTFS_TEST_ASSERT_IS_NULL( + FSNTFS_TEST_ASSERT_IS_NOT_NULL( "error", error ); - /* Test error cases - */ + libcerror_error_free( + &error ); + result = libfsntfs_check_volume_signature_wide( - NULL, + L"", &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( @@ -730,6 +402,38 @@ int fsntfs_test_check_volume_signature_wide( libcerror_error_free( &error ); + if( source != NULL ) + { +#if defined( HAVE_FSNTFS_TEST_MEMORY ) + + /* Test libfsntfs_check_volume_signature_wide with malloc failing in libbfio_file_initialize + */ + fsntfs_test_malloc_attempts_before_fail = 0; + + result = libfsntfs_check_volume_signature_wide( + wide_source, + &error ); + + if( fsntfs_test_malloc_attempts_before_fail != -1 ) + { + fsntfs_test_malloc_attempts_before_fail = -1; + } + else + { + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + -1 ); + + FSNTFS_TEST_ASSERT_IS_NOT_NULL( + "error", + error ); + + libcerror_error_free( + &error ); + } +#endif /* defined( HAVE_FSNTFS_TEST_MEMORY ) */ + } return( 1 ); on_error: @@ -749,7 +453,7 @@ int fsntfs_test_check_volume_signature_wide( int fsntfs_test_check_volume_signature_file_io_handle( const system_character_t *source ) { - uint8_t empty_block[ 512 ]; + uint8_t empty_block[ 8192 ]; libbfio_handle_t *file_io_handle = NULL; libcerror_error_t *error = NULL; @@ -759,77 +463,90 @@ int fsntfs_test_check_volume_signature_file_io_handle( /* Initialize test */ - result = libbfio_file_initialize( - &file_io_handle, - &error ); - - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); + memset_result = memory_set( + empty_block, + 0, + sizeof( uint8_t ) * 8192 ); FSNTFS_TEST_ASSERT_IS_NOT_NULL( - "file_io_handle", - file_io_handle ); - - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - source_length = system_string_length( - source ); - -#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) - result = libbfio_file_set_name_wide( - file_io_handle, - source, - source_length, - &error ); -#else - result = libbfio_file_set_name( - file_io_handle, - source, - source_length, - &error ); -#endif - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); + "memset_result", + memset_result ); - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); + if( source != NULL ) + { + /* Initialize test + */ + result = libbfio_file_initialize( + &file_io_handle, + &error ); - result = libbfio_handle_open( - file_io_handle, - LIBBFIO_OPEN_READ, - &error ); + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); + FSNTFS_TEST_ASSERT_IS_NOT_NULL( + "file_io_handle", + file_io_handle ); - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); - - /* Test check volume signature - */ - result = libfsntfs_check_volume_signature_file_io_handle( - file_io_handle, - &error ); + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); - - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); + source_length = system_string_length( + source ); +#if defined( HAVE_WIDE_SYSTEM_CHARACTER ) + result = libbfio_file_set_name_wide( + file_io_handle, + source, + source_length, + &error ); +#else + result = libbfio_file_set_name( + file_io_handle, + source, + source_length, + &error ); +#endif + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + result = libbfio_handle_open( + file_io_handle, + LIBBFIO_OPEN_READ, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + + /* Test check volume signature + */ + result = libfsntfs_check_volume_signature_file_io_handle( + file_io_handle, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + } /* Test error cases */ result = libfsntfs_check_volume_signature_file_io_handle( @@ -850,49 +567,44 @@ int fsntfs_test_check_volume_signature_file_io_handle( /* Clean up */ - result = libbfio_handle_close( - file_io_handle, - &error ); - - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 0 ); + if( source != NULL ) + { + result = libbfio_handle_close( + file_io_handle, + &error ); - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 0 ); - result = libbfio_handle_free( - &file_io_handle, - &error ); + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); - FSNTFS_TEST_ASSERT_EQUAL_INT( - "result", - result, - 1 ); + result = libbfio_handle_free( + &file_io_handle, + &error ); - FSNTFS_TEST_ASSERT_IS_NULL( - "file_io_handle", - file_io_handle ); + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); - FSNTFS_TEST_ASSERT_IS_NULL( - "error", - error ); + FSNTFS_TEST_ASSERT_IS_NULL( + "file_io_handle", + file_io_handle ); - /* Initialize test + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + } + /* Test check volume signature with data too small */ - memset_result = memory_set( - empty_block, - 0, - sizeof( uint8_t ) * 512 ); - - FSNTFS_TEST_ASSERT_IS_NOT_NULL( - "memset_result", - memset_result ); - - result = libbfio_memory_range_initialize( + result = fsntfs_test_open_file_io_handle( &file_io_handle, + empty_block, + sizeof( uint8_t ) * 1, &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( @@ -908,53 +620,57 @@ int fsntfs_test_check_volume_signature_file_io_handle( "error", error ); - result = libbfio_memory_range_set( + result = libfsntfs_check_volume_signature_file_io_handle( file_io_handle, - empty_block, - sizeof( uint8_t ) * 512, &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( "result", result, - 1 ); + -1 ); - FSNTFS_TEST_ASSERT_IS_NULL( + FSNTFS_TEST_ASSERT_IS_NOT_NULL( "error", error ); - result = libbfio_handle_open( - file_io_handle, - LIBBFIO_OPEN_READ, + libcerror_error_free( + &error ); + + result = fsntfs_test_close_file_io_handle( + &file_io_handle, &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( "result", result, - 1 ); + 0 ); FSNTFS_TEST_ASSERT_IS_NULL( "error", error ); - /* Test check volume signature + /* Test check volume signature with empty block */ - result = libfsntfs_check_volume_signature_file_io_handle( - file_io_handle, + result = fsntfs_test_open_file_io_handle( + &file_io_handle, + empty_block, + sizeof( uint8_t ) * 8192, &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( "result", result, - 0 ); + 1 ); + + FSNTFS_TEST_ASSERT_IS_NOT_NULL( + "file_io_handle", + file_io_handle ); FSNTFS_TEST_ASSERT_IS_NULL( "error", error ); - /* Clean up - */ - result = libbfio_handle_close( + result = libfsntfs_check_volume_signature_file_io_handle( file_io_handle, &error ); @@ -967,25 +683,19 @@ int fsntfs_test_check_volume_signature_file_io_handle( "error", error ); - result = libbfio_handle_free( + result = fsntfs_test_close_file_io_handle( &file_io_handle, &error ); FSNTFS_TEST_ASSERT_EQUAL_INT( "result", result, - 1 ); - - FSNTFS_TEST_ASSERT_IS_NULL( - "file_io_handle", - file_io_handle ); + 0 ); FSNTFS_TEST_ASSERT_IS_NULL( "error", error ); - /* TODO test volume too small */ - return( 1 ); on_error: @@ -1015,13 +725,18 @@ int main( char * const argv[] ) #endif { - system_character_t *source = NULL; - system_integer_t option = 0; + libcerror_error_t *error = NULL; + system_character_t *option_offset = NULL; + system_character_t *source = NULL; + system_integer_t option = 0; + size_t string_length = 0; + off64_t volume_offset = 0; + int result = 0; while( ( option = fsntfs_test_getopt( argc, argv, - _SYSTEM_STRING( "" ) ) ) != (system_integer_t) -1 ) + _SYSTEM_STRING( "o:" ) ) ) != (system_integer_t) -1 ) { switch( option ) { @@ -1033,13 +748,37 @@ int main( argv[ optind - 1 ] ); return( EXIT_FAILURE ); + + case (system_integer_t) 'o': + option_offset = optarg; + + break; } } if( optind < argc ) { source = argv[ optind ]; } + if( option_offset != NULL ) + { + string_length = system_string_length( + option_offset ); + result = fsntfs_test_system_string_copy_from_64_bit_in_decimal( + option_offset, + string_length + 1, + (uint64_t *) &volume_offset, + &error ); + + FSNTFS_TEST_ASSERT_EQUAL_INT( + "result", + result, + 1 ); + + FSNTFS_TEST_ASSERT_IS_NULL( + "error", + error ); + } FSNTFS_TEST_RUN( "libfsntfs_get_version", fsntfs_test_get_version ); @@ -1057,7 +796,8 @@ int main( fsntfs_test_set_codepage ); #if !defined( __BORLANDC__ ) || ( __BORLANDC__ >= 0x0560 ) - if( source != NULL ) + if( ( source != NULL ) + && ( volume_offset == 0 ) ) { FSNTFS_TEST_RUN_WITH_ARGS( "libfsntfs_check_volume_signature", @@ -1083,6 +823,11 @@ int main( return( EXIT_SUCCESS ); on_error: + if( error != NULL ) + { + libcerror_error_free( + &error ); + } return( EXIT_FAILURE ); }