├── BINARY ├── BINARY.gz ├── lznt1.bin ├── BINARY.upx ├── README.md ├── generate-specimens-unicode-windows.bat ├── generate-specimens-unicode-linux.sh ├── generate-specimens-linux.sh ├── generate-specimens-behavior-linux.sh ├── generate-specimens-behavior-windows.bat ├── LICENSE └── generate-specimens-windows.bat /BINARY: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfirlabs/ntfs-specimens/HEAD/BINARY -------------------------------------------------------------------------------- /BINARY.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfirlabs/ntfs-specimens/HEAD/BINARY.gz -------------------------------------------------------------------------------- /lznt1.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfirlabs/ntfs-specimens/HEAD/lznt1.bin -------------------------------------------------------------------------------- /BINARY.upx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dfirlabs/ntfs-specimens/HEAD/BINARY.upx -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NTFS file system specimens. 2 | 3 | This project is licensend under [CC-BY-4.0](https://github.com/dfirlabs/ntfs-specimens/blob/master/LICENSE) 4 | with the exception of: 5 | 6 | * BINARY 7 | * BINARY.gz 8 | * BINARY.upx 9 | 10 | Which are licensed under [LGPLv3+](https://raw.githubusercontent.com/libyal/libcerror/master/COPYING.LESSER) 11 | and copied with permission granted by the [libcerror project](https://github.com/libyal/libcerror). 12 | 13 | * lznt1.bin 14 | 15 | Which orignates from the Greendale test images and is is licensend under [CC-BY-4.0](https://github.com/dfirlabs/ntfs-specimens/blob/master/LICENSE). 16 | 17 | -------------------------------------------------------------------------------- /generate-specimens-unicode-windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | chcp 65001 3 | 4 | rem Script to generate NTFS test files 5 | rem Requires Windows 7 or later 6 | 7 | rem Split the output of ver e.g. "Microsoft Windows [Version 10.0.10586]" 8 | rem and keep the last part "10.0.10586]". 9 | for /f "tokens=1,2,3,4" %%a in ('ver') do ( 10 | set version=%%d 11 | ) 12 | 13 | rem Replace dots by spaces "10 0 10586]". 14 | set version=%version:.= % 15 | 16 | rem Split the last part of the ver output "10 0 10586]" and keep the first 17 | rem 2 values formatted with a dot as separator "10.0". 18 | for /f "tokens=1,2,*" %%a in ("%version%") do ( 19 | set version=%%a.%%b 20 | ) 21 | 22 | rem TODO add check for other supported versions of Windows 23 | rem Also see: https://en.wikipedia.org/wiki/Ver_(command) 24 | 25 | if not "%version%" == "10.0" ( 26 | echo Unsupported Windows version: %version% 27 | 28 | exit /b 1 29 | ) 30 | 31 | set specimenspath=specimens\%version% 32 | 33 | if exist "%specimenspath%" ( 34 | echo Specimens directory: %specimenspath% already exists. 35 | 36 | exit /b 1 37 | ) 38 | 39 | mkdir "%specimenspath%" 40 | 41 | rem Create a variable-size VHD image with a NTFS file system and files for individual Unicode characters 42 | set unitsize=4096 43 | set imagename=ntfs_unicode_files.vhd 44 | set imagesize=2048 45 | 46 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=expandable > CreateVHD.diskpart 47 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 48 | echo attach vdisk >> CreateVHD.diskpart 49 | echo convert mbr >> CreateVHD.diskpart 50 | echo create partition primary >> CreateVHD.diskpart 51 | 52 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 53 | 54 | echo assign letter=x >> CreateVHD.diskpart 55 | 56 | call :run_diskpart CreateVHD.diskpart 57 | 58 | set sourcedir=%cd% 59 | 60 | mkdir x:\testdir1 61 | pushd x:\testdir1 62 | 63 | rem TODO use UnicodeData.txt instead of brute forcing Unicode character space 64 | 65 | for /l %%a in (0, 1, 1114111) do call %sourcedir%\unicodetouch.exe %%a > nul 66 | 67 | popd 68 | 69 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 70 | echo detach vdisk >> UnmountVHD.diskpart 71 | 72 | call :run_diskpart UnmountVHD.diskpart 73 | 74 | exit /b 0 75 | 76 | rem Runs diskpart with a script 77 | rem Note that diskpart requires Administrator privileges to run 78 | :run_diskpart 79 | SETLOCAL 80 | set diskpartscript=%1 81 | 82 | rem Note that diskpart requires Administrator privileges to run 83 | diskpart /s %diskpartscript% 84 | 85 | if %errorlevel% neq 0 ( 86 | echo Failed to run: "diskpart /s %diskpartscript%" 87 | 88 | exit /b 1 89 | ) 90 | 91 | del /q %diskpartscript% 92 | 93 | rem Give the system a bit of time to adjust 94 | timeout /t 1 > nul 95 | 96 | ENDLOCAL 97 | exit /b 0 98 | 99 | -------------------------------------------------------------------------------- /generate-specimens-unicode-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script to generate NTFS test files for testing Unicode conversions 4 | # Requires Linux with dd and mkntfs and unicodetouch of the libyal assorted project. 5 | 6 | EXIT_SUCCESS=0; 7 | EXIT_FAILURE=1; 8 | 9 | UNICODETOUCH="${HOME}/Projects/assorted/src/unicodetouch"; 10 | 11 | # Checks the availability of a binary and exits if not available. 12 | # 13 | # Arguments: 14 | # a string containing the name of the binary 15 | # 16 | assert_availability_binary() 17 | { 18 | local BINARY=$1; 19 | 20 | which ${BINARY} > /dev/null 2>&1; 21 | if test $? -ne ${EXIT_SUCCESS}; 22 | then 23 | echo "Missing binary: ${BINARY}"; 24 | echo ""; 25 | 26 | exit ${EXIT_FAILURE}; 27 | fi 28 | } 29 | 30 | create_test_file_entries_unicode() 31 | { 32 | MOUNT_POINT=$1; 33 | 34 | # Create a directory 35 | mkdir ${MOUNT_POINT}/testdir1 36 | 37 | set +e; 38 | 39 | # Create a file for Unicode characters defined in UnicodeData.txt 40 | for NUMBER in `cat UnicodeData.txt | sed 's/;.*$//'`; 41 | do 42 | UNICODE_CHARACTER=`printf "%08x" $(( 0x${NUMBER} ))`; 43 | 44 | # There are different methods to generate file names with Unicode characters 45 | # using unicodetouch is currently the most comprehensive method. 46 | 47 | # touch `python2 -c "print(''.join(['${MOUNT_POINT}/testdir1/unicode_U+${UNICODE_CHARACTER}_', '${UNICODE_CHARACTER}'.decode('hex').decode('utf-32-be')]).encode('utf-8'))"` 2> /dev/null; 48 | 49 | # touch `python3 -c "print(''.join(['${MOUNT_POINT}/testdir1/unicode_U+{0:08x}_'.format(0x${NUMBER}), eval('\\\\'\\\\\\\\U{0:08x}\\\\''.format(0x${NUMBER}))]))"` 2> /dev/null; 50 | 51 | # if test $? -ne 0; 52 | # then 53 | # echo "Unsupported: 0x${UNICODE_CHARACTER}"; 54 | # fi 55 | 56 | # CHARACTER=`/usr/bin/printf "\\U${UNICODE_CHARACTER}" 2> /dev/null`; 57 | 58 | # if test -z ${CHARACTER}; 59 | # then 60 | # echo "Unsupported: 0x${UNICODE_CHARACTER}"; 61 | # else 62 | # touch "${MOUNT_POINT}/testdir1/unicode_U+${UNICODE_CHARACTER}_${CHARACTER}"; 63 | # fi 64 | 65 | (cd ${MOUNT_POINT}/testdir1 && ${UNICODETOUCH} $(( 0x${NUMBER} )) &> /dev/null) 66 | 67 | if test $? -ne 0; 68 | then 69 | echo "Unsupported: 0x${UNICODE_CHARACTER}"; 70 | fi 71 | done 72 | 73 | set -e; 74 | } 75 | 76 | assert_availability_binary dd; 77 | assert_availability_binary mkntfs; 78 | assert_availability_binary ${UNICODETOUCH}; 79 | 80 | SPECIMENS_PATH="specimens/mkntfs"; 81 | 82 | if ! test -f "UnicodeData.txt"; 83 | then 84 | echo "Missing UnicodeData.txt file. UnicodeData.txt can be obtained from " 85 | echo "unicode.org make sure you have a local copy in the current working "; 86 | echo "directory."; 87 | 88 | exit ${EXIT_FAILURE}; 89 | fi 90 | 91 | if test -d ${SPECIMENS_PATH}; 92 | then 93 | echo "Specimens directory: ${SPECIMENS_PATH} already exists."; 94 | 95 | exit ${EXIT_FAILURE}; 96 | fi 97 | 98 | mkdir -p ${SPECIMENS_PATH}; 99 | 100 | set -e; 101 | 102 | MOUNT_POINT="/mnt/ntfs"; 103 | 104 | sudo mkdir -p ${MOUNT_POINT}; 105 | 106 | IMAGE_SIZE=$(( 64 * 1024 * 1024 )); 107 | SECTOR_SIZE=512; 108 | 109 | # Create raw disk image with a NTFS file system and files for individual Unicode characters 110 | IMAGE_FILE="${SPECIMENS_PATH}/ntfs_unicode_files.raw"; 111 | 112 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 113 | 114 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 115 | 116 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 117 | 118 | create_test_file_entries_unicode ${MOUNT_POINT} 119 | 120 | sudo umount ${MOUNT_POINT}; 121 | 122 | exit ${EXIT_SUCCESS}; 123 | 124 | -------------------------------------------------------------------------------- /generate-specimens-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script to generate NTFS test files 4 | # Requires Linux with dd and mkntfs 5 | 6 | EXIT_SUCCESS=0; 7 | EXIT_FAILURE=1; 8 | 9 | # Checks the availability of a binary and exits if not available. 10 | # 11 | # Arguments: 12 | # a string containing the name of the binary 13 | # 14 | assert_availability_binary() 15 | { 16 | local BINARY=$1; 17 | 18 | which ${BINARY} > /dev/null 2>&1; 19 | if test $? -ne ${EXIT_SUCCESS}; 20 | then 21 | echo "Missing binary: ${BINARY}"; 22 | echo ""; 23 | 24 | exit ${EXIT_FAILURE}; 25 | fi 26 | } 27 | 28 | # Creates test file entries. 29 | # 30 | # Arguments: 31 | # a string containing the mount point of the image file 32 | # 33 | create_test_file_entries() 34 | { 35 | MOUNT_POINT=$1; 36 | 37 | # Create an empty file 38 | touch ${MOUNT_POINT}/emptyfile 39 | 40 | # Create a directory 41 | mkdir ${MOUNT_POINT}/testdir1 42 | 43 | # Create a file with a non-resident MFT data attribute 44 | echo "My file" > ${MOUNT_POINT}/testdir1/testfile1 45 | 46 | # Create a file with a non-resident MFT data attribute 47 | cp LICENSE ${MOUNT_POINT}/testdir1/testfile2 48 | 49 | # Create a file with a long filename 50 | touch "${MOUNT_POINT}/My long, very long file name, so very long" 51 | 52 | # Create a hard link to a file 53 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/file_hardlink1 54 | 55 | # Create a symbolic link to a file 56 | ln -s ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/file_symboliclink1 57 | 58 | # Create a hard link to a directory 59 | # ln: hard link not allowed for directory 60 | 61 | # Create a symbolic link to a directory 62 | ln -s ${MOUNT_POINT}/testdir1 ${MOUNT_POINT}/directory_symboliclink1 63 | 64 | # Create a file with a control code in the filename 65 | touch `printf "${MOUNT_POINT}/control_cod\x03"` 66 | 67 | # Create a file with an UTF-8 NFC encoded filename 68 | touch `printf "${MOUNT_POINT}/nfc_t\xc3\xa9stfil\xc3\xa8"` 69 | 70 | # Create a file with an UTF-8 NFD encoded filename 71 | touch `printf "${MOUNT_POINT}/nfd_te\xcc\x81stfile\xcc\x80"` 72 | 73 | # Create a file with an UTF-8 NFD encoded filename 74 | touch `printf "${MOUNT_POINT}/nfd_\xc2\xbe"` 75 | 76 | # Create a file with an UTF-8 NFKD encoded filename 77 | touch `printf "${MOUNT_POINT}/nfkd_3\xe2\x81\x844"` 78 | 79 | # Create a file with a 2-byte UTF-16 character that will expand into 3-byte UTF-8 character 80 | touch `printf "${MOUNT_POINT}/funky\xe2\x98\x80name"` 81 | 82 | # Create a file with an alternate data stream (ADS) with content 83 | touch ${MOUNT_POINT}/file_ads1 84 | echo "My file ADS" > ${MOUNT_POINT}/file_ads1:myads 85 | 86 | # Create a file with an alternate data stream (ADS) with a control code in the ADS name 87 | # touch ${MOUNT_POINT}/file_ads2 88 | # touch `printf "${MOUNT_POINT}/file_ads2:\x05SummaryInformation"` 89 | 90 | # Create a directory with an alternate data stream (ADS) with content 91 | mkdir ${MOUNT_POINT}/directory_ads1 92 | echo "My directory ADS" > ${MOUNT_POINT}/directory_ads1:myads 93 | 94 | # Create a symbolic link with an alternate data stream (ADS) with content 95 | ln -s ${MOUNT_POINT}/directory_ads1 ${MOUNT_POINT}/directory_ads1_symboliclink1 96 | echo "My symbolic link ADS" > ${MOUNT_POINT}/directory_ads1_symboliclink1:myads 97 | 98 | # Create an LZNT1 compressed file if supported 99 | mkdir ${MOUNT_POINT}/compressed 100 | 101 | setfattr -h -v 0x00080000 -n system.ntfs_attrib ${MOUNT_POINT}/compressed 102 | 103 | cp LICENSE ${MOUNT_POINT}/compressed/ 104 | } 105 | 106 | assert_availability_binary dd; 107 | assert_availability_binary mkntfs; 108 | 109 | set -e; 110 | 111 | SPECIMENS_PATH="specimens/mkntfs"; 112 | 113 | mkdir -p ${SPECIMENS_PATH}; 114 | 115 | MOUNT_POINT="/mnt/ntfs"; 116 | 117 | sudo mkdir -p ${MOUNT_POINT}; 118 | 119 | # Minimum NTFS volume size is 1 MiB. 120 | DEFAULT_IMAGE_SIZE=$(( 4096 * 1024 )); 121 | 122 | IMAGE_SIZE=${DEFAULT_IMAGE_SIZE}; 123 | SECTOR_SIZE=512; 124 | 125 | # Create a NTFS file system 126 | IMAGE_NAME="ntfs.raw" 127 | IMAGE_FILE="${SPECIMENS_PATH}/${IMAGE_NAME}"; 128 | 129 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 130 | 131 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 132 | 133 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 134 | 135 | create_test_file_entries ${MOUNT_POINT}; 136 | 137 | sudo umount ${MOUNT_POINT}; 138 | 139 | # Create a NTFS file system without ADS support (streams_interface=windows) 140 | IMAGE_NAME="ntfs_no_ads.raw" 141 | IMAGE_FILE="${SPECIMENS_PATH}/${IMAGE_NAME}"; 142 | 143 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 144 | 145 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 146 | 147 | sudo mount -o loop,rw,compression ${IMAGE_FILE} ${MOUNT_POINT}; 148 | 149 | create_test_file_entries ${MOUNT_POINT}; 150 | 151 | sudo umount ${MOUNT_POINT}; 152 | 153 | # Create NTFS file systems with a specific cluster (block) sizes and bytes per sector. 154 | for CLUSTER_SIZE in 256 512 1024 2048 4096 8192 16384 32768 65536 131072 262144 524288 1048576 2097152; 155 | do 156 | for SECTOR_SIZE in 256 512 1024 2048 4096; 157 | do 158 | # Note that mkntfs requires the cluster size to be greater or equal the sector size or 159 | # the cluster size less than or equal 4096 times the size of the sector size. 160 | if test ${CLUSTER_SIZE} -lt ${SECTOR_SIZE} || test ${CLUSTER_SIZE} -gt $(( ${SECTOR_SIZE} * 4096 )); 161 | then 162 | continue; 163 | fi 164 | IMAGE_NAME="ntfs_cluster_${CLUSTER_SIZE}_sector_${SECTOR_SIZE}.raw" 165 | IMAGE_FILE="${SPECIMENS_PATH}/${IMAGE_NAME}"; 166 | 167 | # Make sure the image has more than 32 cluster blocks 168 | IMAGE_SIZE=$(( ${CLUSTER_SIZE} * 48 )); 169 | 170 | if test ${IMAGE_SIZE} -lt ${DEFAULT_IMAGE_SIZE}; 171 | then 172 | IMAGE_SIZE=${DEFAULT_IMAGE_SIZE}; 173 | fi 174 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 175 | 176 | mkntfs -F -q -L "ntfs_test" -c ${CLUSTER_SIZE} -s ${SECTOR_SIZE} ${IMAGE_FILE}; 177 | 178 | # NTFS3g does not support a cluster size of 256. 179 | if test ${CLUSTER_SIZE} -gt 256; 180 | then 181 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 182 | 183 | create_test_file_entries ${MOUNT_POINT}; 184 | 185 | sudo umount ${MOUNT_POINT}; 186 | fi 187 | done 188 | done 189 | 190 | # Create a NTFS file system with many files 191 | SECTOR_SIZE=512; 192 | 193 | # 1000000 is disabled for now since it creates a 2 GiB test image and 194 | # a while to generate causing sudo to time out. 195 | for NUMBER_OF_FILES in 100 1000 10000 100000; 196 | do 197 | if test ${NUMBER_OF_FILES} -eq 10000000; 198 | then 199 | # TODO: this is an guestimate 200 | IMAGE_SIZE=$(( 8192 * 4096 * 1024 )); 201 | 202 | elif test ${NUMBER_OF_FILES} -eq 1000000; 203 | then 204 | IMAGE_SIZE=$(( 512 * 4096 * 1024 )); 205 | 206 | elif test ${NUMBER_OF_FILES} -eq 100000; 207 | then 208 | IMAGE_SIZE=$(( 32 * 4096 * 1024 )); 209 | 210 | elif test ${NUMBER_OF_FILES} -eq 10000; 211 | then 212 | IMAGE_SIZE=$(( 4 * 4096 * 1024 )); 213 | else 214 | IMAGE_SIZE=${DEFAULT_IMAGE_SIZE}; 215 | fi 216 | 217 | IMAGE_NAME="ntfs_${NUMBER_OF_FILES}_files.raw" 218 | IMAGE_FILE="${SPECIMENS_PATH}/${IMAGE_NAME}"; 219 | 220 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 221 | 222 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 223 | 224 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 225 | 226 | create_test_file_entries ${MOUNT_POINT}; 227 | 228 | # Create additional files 229 | for NUMBER in `seq 3 ${NUMBER_OF_FILES}`; 230 | do 231 | if test $(( ${NUMBER} % 2 )) -eq 0; 232 | then 233 | touch ${MOUNT_POINT}/testdir1/TestFile${NUMBER}; 234 | else 235 | touch ${MOUNT_POINT}/testdir1/testfile${NUMBER}; 236 | fi 237 | done 238 | 239 | sudo umount ${MOUNT_POINT}; 240 | done 241 | 242 | # Create a NTFS file system with several corrupted files. 243 | IMAGE_NAME="ntfs_corrupted.raw" 244 | IMAGE_SIZE=${DEFAULT_IMAGE_SIZE}; 245 | IMAGE_FILE="${SPECIMENS_PATH}/${IMAGE_NAME}"; 246 | 247 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 248 | 249 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 250 | 251 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 252 | 253 | mkdir ${MOUNT_POINT}/compressed; 254 | 255 | setfattr -h -v 0x00080000 -n system.ntfs_attrib ${MOUNT_POINT}/compressed 256 | 257 | cp LICENSE ${MOUNT_POINT}/compressed/lznt1_empty 258 | 259 | # Make sure the lznt1 compressed data run is large enough to store lznt1.bin 260 | cp LICENSE ${MOUNT_POINT}/compressed/lznt1_truncated 261 | cat LICENSE >> ${MOUNT_POINT}/compressed/lznt1_truncated 262 | 263 | sudo umount ${MOUNT_POINT}; 264 | 265 | # Make sure to unmount before making modifications to the data streams 266 | 267 | # TODO: determine extent of lznt1_empty file and fill with 0-byte values 268 | dd conv=notrunc if=/dev/zero of=${IMAGE_FILE} bs=4096 seek=$(( 0x000e9000 / 4096 )) count=$(( 12288 / 4096 )) 269 | 270 | # TODO: determine extent of lznt1_truncated file and fill first 0x4000 bytes with lznt1.bin and the remainder with with 0-byte values 271 | dd conv=notrunc if=/dev/zero of=${IMAGE_FILE} bs=4096 seek=$(( 0x000ec000 / 4096 )) count=$(( 20480 / 4096 )) 272 | dd conv=notrunc if=lznt1.bin of=${IMAGE_FILE} bs=4096 seek=$(( 0x000ec000 / 4096 )) 273 | 274 | exit ${EXIT_SUCCESS}; 275 | 276 | -------------------------------------------------------------------------------- /generate-specimens-behavior-linux.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Script to generate NTFS test files 4 | 5 | EXIT_SUCCESS=0; 6 | EXIT_FAILURE=1; 7 | 8 | # Checks the availability of a binary and exits if not available. 9 | # 10 | # Arguments: 11 | # a string containing the name of the binary 12 | # 13 | assert_availability_binary() 14 | { 15 | local BINARY=$1; 16 | 17 | which ${BINARY} > /dev/null 2>&1; 18 | if test $? -ne ${EXIT_SUCCESS}; 19 | then 20 | echo "Missing binary: ${BINARY}"; 21 | echo ""; 22 | 23 | exit ${EXIT_FAILURE}; 24 | fi 25 | } 26 | 27 | assert_availability_binary dd; 28 | assert_availability_binary mkntfs; 29 | 30 | set -e; 31 | 32 | SPECIMENS_PATH="specimens/mkntfs"; 33 | 34 | mkdir -p ${SPECIMENS_PATH}; 35 | 36 | MOUNT_POINT="/mnt/ntfs"; 37 | 38 | sudo mkdir -p ${MOUNT_POINT}; 39 | 40 | DEFAULT_IMAGE_SIZE=$(( 4096 * 1024 )); 41 | 42 | IMAGE_SIZE=${DEFAULT_IMAGE_SIZE}; 43 | SECTOR_SIZE=512; 44 | 45 | # Scenario 1: 46 | # 1. Create a file and directory 47 | # 2. Modify the content of the file 48 | # 3. Rename the file 49 | # 4. Remove the file 50 | # 5. Rename the directory 51 | # 6. Remove the directory 52 | 53 | # Create a NTFS file system. 54 | IMAGE_FILE="${SPECIMENS_PATH}/ntfs.raw"; 55 | 56 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 57 | 58 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 59 | 60 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 61 | 62 | # Step 1 create a file and directory. 63 | echo "testfile1" > ${MOUNT_POINT}/testfile1 64 | mkdir ${MOUNT_POINT}/testdir1 65 | 66 | sudo umount ${MOUNT_POINT}; 67 | 68 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario1.1.raw; 69 | 70 | # Sleep so that changes are noticeable. 71 | sleep 5; 72 | 73 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 74 | 75 | # Step 2 modify the content of a file. 76 | echo "1eliftset" > ${MOUNT_POINT}/testfile1 77 | 78 | sudo umount ${MOUNT_POINT}; 79 | 80 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario1.2.raw; 81 | 82 | # Sleep so that changes are noticeable. 83 | sleep 5; 84 | 85 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 86 | 87 | # Step 3 rename a file. 88 | mv ${MOUNT_POINT}/testfile1 ${MOUNT_POINT}/1eliftset; 89 | 90 | sudo umount ${MOUNT_POINT}; 91 | 92 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario1.3.raw; 93 | 94 | # Sleep so that changes are noticeable. 95 | sleep 5; 96 | 97 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 98 | 99 | # Step 4 remove a file. 100 | rm -f ${MOUNT_POINT}/1eliftset; 101 | 102 | sudo umount ${MOUNT_POINT}; 103 | 104 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario1.4.raw; 105 | 106 | # Sleep so that changes are noticeable. 107 | sleep 5; 108 | 109 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 110 | 111 | # Step 5 rename a directory. 112 | mv ${MOUNT_POINT}/testdir1 ${MOUNT_POINT}/1ridtset; 113 | 114 | sudo umount ${MOUNT_POINT}; 115 | 116 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario1.5.raw; 117 | 118 | # Sleep so that changes are noticeable. 119 | sleep 5; 120 | 121 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 122 | 123 | # Step 6 remove a directory. 124 | rm -rf ${MOUNT_POINT}/1ridtset; 125 | 126 | sudo umount ${MOUNT_POINT}; 127 | 128 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario1.6.raw; 129 | 130 | # Remove the working image file. 131 | rm -f ${IMAGE_FILE}; 132 | 133 | # Scenario 2: 134 | # TODO implement 135 | 136 | # Scenario 3: 137 | # 1. Create a file in a directory 138 | # 2. Create hard links in directories. 139 | 140 | # Create a NTFS file system. 141 | IMAGE_FILE="${SPECIMENS_PATH}/ntfs.raw"; 142 | 143 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 144 | 145 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 146 | 147 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 148 | 149 | # Step 1 create files and directories. 150 | mkdir ${MOUNT_POINT}/testdir1 151 | echo "testfile1" > ${MOUNT_POINT}/testdir1/testfile1 152 | 153 | # Step 2 create hard links in directories. 154 | mkdir ${MOUNT_POINT}/testdir2 155 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir2/hardlink1 156 | 157 | mkdir ${MOUNT_POINT}/testdir3 158 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir3/hardlink2 159 | 160 | mkdir ${MOUNT_POINT}/testdir4 161 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir4/hardlink3 162 | 163 | mkdir ${MOUNT_POINT}/testdir5 164 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir5/hardlink4 165 | 166 | mkdir ${MOUNT_POINT}/testdir6 167 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir6/hardlink5 168 | 169 | mkdir ${MOUNT_POINT}/testdir7 170 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir7/hardlink6 171 | 172 | mkdir ${MOUNT_POINT}/testdir8 173 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir8/hardlink7 174 | 175 | mkdir ${MOUNT_POINT}/testdir9 176 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir9/hardlink8 177 | 178 | mkdir ${MOUNT_POINT}/testdir10 179 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir10/hardlink9 180 | 181 | mkdir ${MOUNT_POINT}/testdir11 182 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir11/hardlink10 183 | 184 | mkdir ${MOUNT_POINT}/testdir12 185 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir12/hardlink11 186 | 187 | mkdir ${MOUNT_POINT}/testdir13 188 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir13/hardlink12 189 | 190 | mkdir ${MOUNT_POINT}/testdir14 191 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir14/hardlink13 192 | 193 | mkdir ${MOUNT_POINT}/testdir15 194 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir15/hardlink14 195 | 196 | mkdir ${MOUNT_POINT}/testdir16 197 | ln ${MOUNT_POINT}/testdir1/testfile1 ${MOUNT_POINT}/testdir16/hardlink15 198 | 199 | sudo umount ${MOUNT_POINT}; 200 | 201 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario3.1.raw; 202 | 203 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 204 | 205 | # Step 3 remove hard links. 206 | 207 | rm -f ${MOUNT_POINT}/testdir3/hardlink2; 208 | rm -f ${MOUNT_POINT}/testdir5/hardlink4; 209 | rm -f ${MOUNT_POINT}/testdir7/hardlink6; 210 | rm -f ${MOUNT_POINT}/testdir9/hardlink8; 211 | rm -f ${MOUNT_POINT}/testdir11/hardlink10; 212 | rm -f ${MOUNT_POINT}/testdir13/hardlink12; 213 | rm -f ${MOUNT_POINT}/testdir15/hardlink14; 214 | 215 | sudo umount ${MOUNT_POINT}; 216 | 217 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario3.2.raw; 218 | 219 | # Remove the working image file. 220 | rm -f ${IMAGE_FILE}; 221 | 222 | # Scenario 4: 223 | # 1. Create a file containing a pipe (|) in the name. The pipe character is used by the bodyfile format as a separator. 224 | # 2. Create a file containing backslash (\\) in the name. The backslash character is used by the bodyfile format as escape character. 225 | # 3. Create a file containing a containing a control character in the name and a hardlink with a carrot (^) instead of the control characters. 226 | # 4. Create a file named $OrphanFiles. 227 | 228 | # Create a NTFS file system. 229 | IMAGE_FILE="${SPECIMENS_PATH}/ntfs.raw"; 230 | 231 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 232 | 233 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 234 | 235 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 236 | 237 | # Step 1 create a file containing pipe (|) in the name 238 | echo "file with pipes" > "${MOUNT_POINT}/file\|with\|pipes" 239 | 240 | # Step 2 create a file containing backslashes (\\) in the name 241 | echo "file with backslashes" > "${MOUNT_POINT}/file\\\\with\\\\backslashes" 242 | 243 | # Step 3 create a file containing a control character in the name and a hardlink with a carrot (^) instead of the control characters 244 | touch `printf "${MOUNT_POINT}/file\x03with\x04control\x04codes"` 245 | (cd ${MOUNT_POINT} && ln 'file'$'\003''with'$'\004''control'$'\004''codes' "file^with^control^codes") 246 | 247 | # Step 4 create a file named $OrphanFiles 248 | echo "file named $OrphanFiles" > "${MOUNT_POINT}/\$OrphanFiles" 249 | 250 | sudo umount ${MOUNT_POINT}; 251 | 252 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario4.1.raw; 253 | 254 | # Remove the working image file. 255 | rm -f ${IMAGE_FILE}; 256 | 257 | # Scenario 5: 258 | 259 | # Create a NTFS file system. 260 | IMAGE_FILE="${SPECIMENS_PATH}/ntfs.raw"; 261 | 262 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 263 | 264 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 265 | 266 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 267 | 268 | # Step 1 create a file. 269 | echo "testfile1" > ${MOUNT_POINT}/testfile1 270 | 271 | sleep 0.1 272 | 273 | # Step 2 alter the access time 274 | touch -a ${MOUNT_POINT}/testfile1 275 | 276 | sleep 0.1 277 | 278 | # Step 3 alter the modification time 279 | touch -m ${MOUNT_POINT}/testfile1 280 | 281 | sleep 0.1 282 | 283 | sudo umount ${MOUNT_POINT}; 284 | 285 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario5.1.raw; 286 | 287 | # Remove the working image file. 288 | rm -f ${IMAGE_FILE}; 289 | 290 | # Scenario 6: 291 | # Based on https://github.com/log2timeline/plaso/issues/3840 292 | 293 | # Create a NTFS file system. 294 | IMAGE_FILE="${SPECIMENS_PATH}/ntfs.raw"; 295 | 296 | dd if=/dev/zero of=${IMAGE_FILE} bs=${SECTOR_SIZE} count=$(( ${IMAGE_SIZE} / ${SECTOR_SIZE} )) 2> /dev/null; 297 | 298 | mkntfs -F -q -L "ntfs_test" -s ${SECTOR_SIZE} ${IMAGE_FILE}; 299 | 300 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 301 | 302 | # Step 1 create a file and directory. 303 | mkdir ${MOUNT_POINT}/testdir1 304 | echo "testfile1" > ${MOUNT_POINT}/testdir1/testfile1 305 | 306 | # Step 2 ensure $FILE_NAME of testdir1 is stored in an attribute list. 307 | echo "ads1" > ${MOUNT_POINT}/testdir1:ads1 308 | echo "ads2" > ${MOUNT_POINT}/testdir1:ads2 309 | echo "ads3" > ${MOUNT_POINT}/testdir1:ads3 310 | echo "ads4" > ${MOUNT_POINT}/testdir1:ads4 311 | echo "ads5" > ${MOUNT_POINT}/testdir1:ads5 312 | echo "ads6" > ${MOUNT_POINT}/testdir1:ads6 313 | echo "ads7" > ${MOUNT_POINT}/testdir1:ads7 314 | echo "ads8" > ${MOUNT_POINT}/testdir1:ads8 315 | echo "ads9" > ${MOUNT_POINT}/testdir1:ads9 316 | echo "ads10" > ${MOUNT_POINT}/testdir1:ads10 317 | echo "ads11" > ${MOUNT_POINT}/testdir1:ads11 318 | echo "ads12" > ${MOUNT_POINT}/testdir1:ads12 319 | echo "ads13" > ${MOUNT_POINT}/testdir1:ads13 320 | echo "ads14" > ${MOUNT_POINT}/testdir1:ads14 321 | echo "ads15" > ${MOUNT_POINT}/testdir1:ads15 322 | echo "ads16" > ${MOUNT_POINT}/testdir1:ads16 323 | 324 | sleep 0.1 325 | 326 | sudo umount ${MOUNT_POINT}; 327 | 328 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario6.1.raw; 329 | 330 | sudo mount -o loop,rw,compression,streams_interface=windows ${IMAGE_FILE} ${MOUNT_POINT}; 331 | 332 | # Step 3 remove a directory. 333 | rm -rf ${MOUNT_POINT}/testdir1; 334 | 335 | sleep 0.1 336 | 337 | # Step 4 create a file. 338 | # This steps assumes the MFT entry previously used by testdir1 is reused for testfile2. 339 | echo "testfile2" > ${MOUNT_POINT}/testfile2 340 | 341 | sudo umount ${MOUNT_POINT}; 342 | 343 | cp ${IMAGE_FILE} ${SPECIMENS_PATH}/ntfs-scenario6.2.raw; 344 | 345 | # Remove the working image file. 346 | rm -f ${IMAGE_FILE}; 347 | 348 | exit ${EXIT_SUCCESS}; 349 | 350 | -------------------------------------------------------------------------------- /generate-specimens-behavior-windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem Script to generate NTFS test files 4 | rem Requires Windows 7 or later 5 | 6 | rem Split the output of ver e.g. "Microsoft Windows [Version 10.0.10586]" 7 | rem and keep the last part "10.0.10586]". 8 | for /f "tokens=1,2,3,4" %%a in ('ver') do ( 9 | set version=%%d 10 | ) 11 | 12 | rem Replace dots by spaces "10 0 10586]". 13 | set version=%version:.= % 14 | 15 | rem Split the last part of the ver output "10 0 10586]" and keep the first 16 | rem 2 values formatted with a dot as separator "10.0". 17 | for /f "tokens=1,2,*" %%a in ("%version%") do ( 18 | set version=%%a.%%b 19 | ) 20 | 21 | rem TODO add check for other supported versions of Windows 22 | rem Also see: https://en.wikipedia.org/wiki/Ver_(command) 23 | 24 | if not "%version%" == "10.0" ( 25 | echo Unsupported Windows version: %version% 26 | 27 | exit /b 1 28 | ) 29 | 30 | set specimenspath=specimens\%version% 31 | 32 | if exist "%specimenspath%" ( 33 | echo Specimens directory: %specimenspath% already exists. 34 | 35 | exit /b 1 36 | ) 37 | 38 | mkdir "%specimenspath%" 39 | 40 | rem Supported diskpart format fs= options: ntfs, fat, fat32 41 | rem Supported diskpart format unit= options: 512, 1024, 2048, 4096 (default), 8192, 16K, 32K, 64K 42 | rem unit= values added in Windows 10 (1903): 128K, 256K, 512K, 1M, 2M 43 | 44 | rem Scenario 1: 45 | rem 1. Create a file and directory 46 | rem 2. Modify the content of the file 47 | rem 3. Rename the file 48 | rem 4. Remove the file 49 | rem 5. Rename the directory 50 | rem 6. Remove the directory 51 | 52 | rem Create a fixed-size VHD image with a NTFS file system 53 | set unitsize=4096 54 | set imagename=ntfs.vhd 55 | set imagesize=8 56 | 57 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 58 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 59 | echo attach vdisk >> CreateVHD.diskpart 60 | echo convert mbr >> CreateVHD.diskpart 61 | echo create partition primary >> CreateVHD.diskpart 62 | 63 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 64 | 65 | echo assign letter=x >> CreateVHD.diskpart 66 | 67 | call :run_diskpart CreateVHD.diskpart 68 | 69 | rem Create an USN journal so we can track file changes in more detail. 70 | fsutil usn createjournal x: 71 | 72 | rem Step 1 create a file and directory. 73 | echo "testfile1" > x:\testfile1 74 | mkdir x:\testdir1 75 | 76 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 77 | echo detach vdisk >> UnmountVHD.diskpart 78 | 79 | call :run_diskpart UnmountVHD.diskpart 80 | 81 | copy %specimenspath%\%imagename% %specimenspath%\ntfs_scenario1.1.vhd 82 | 83 | rem Sleep so that changes are noticeable. 84 | timeout /t 5 /nobreak 85 | 86 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > MountVHD.diskpart 87 | echo attach vdisk >> MountVHD.diskpart 88 | 89 | echo assign letter=x >> MountVHD.diskpart 90 | 91 | call :run_diskpart MountVHD.diskpart 92 | 93 | rem Step 2 modify the content of a file. 94 | echo "1eliftset" > x:\testfile1 95 | 96 | call :run_diskpart UnmountVHD.diskpart 97 | 98 | copy %specimenspath%\%imagename% %specimenspath%\ntfs_scenario1.2.vhd 99 | 100 | rem Sleep so that changes are noticeable. 101 | timeout /t 5 /nobreak 102 | 103 | call :run_diskpart MountVHD.diskpart 104 | 105 | rem Step 3 rename a file. 106 | rename x:\testfile1 x:\1eliftset 107 | 108 | call :run_diskpart UnmountVHD.diskpart 109 | 110 | copy %specimenspath%\%imagename% %specimenspath%\ntfs_scenario1.3.vhd 111 | 112 | rem Sleep so that changes are noticeable. 113 | timeout /t 5 /nobreak 114 | 115 | call :run_diskpart MountVHD.diskpart 116 | 117 | rem Step 4 remove a file. 118 | del /f /q x:\1eliftset 119 | 120 | call :run_diskpart UnmountVHD.diskpart 121 | 122 | copy %specimenspath%\%imagename% %specimenspath%\ntfs_scenario1.4.vhd 123 | 124 | rem Sleep so that changes are noticeable. 125 | timeout /t 5 /nobreak 126 | 127 | call :run_diskpart MountVHD.diskpart 128 | 129 | rem Step 5 rename a directory. 130 | move /y x:\testdir1 x:\1ridtset 131 | 132 | call :run_diskpart UnmountVHD.diskpart 133 | 134 | copy %specimenspath%\%imagename% %specimenspath%\ntfs_scenario1.5.vhd 135 | 136 | rem Sleep so that changes are noticeable. 137 | timeout /t 5 /nobreak 138 | 139 | call :run_diskpart MountVHD.diskpart 140 | 141 | rem Step 6 remove a directory 142 | rmdir x:\1ridtset 143 | 144 | call :run_diskpart UnmountVHD.diskpart 145 | 146 | copy %specimenspath%\%imagename% %specimenspath%\ntfs_scenario1.6.vhd 147 | 148 | rem Remove the working image file. 149 | del /f /q %specimenspath%\%imagename% 150 | 151 | rem Scenario 2: 152 | rem 1. Create files and directories 153 | rem 2. Remove a file 154 | rem 3. Rename a directory 155 | 156 | rem Create a fixed-size VHD image with a NTFS file system 157 | set unitsize=4096 158 | set imagename=ntfs.vhd 159 | set imagesize=8 160 | 161 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 162 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 163 | echo attach vdisk >> CreateVHD.diskpart 164 | echo convert mbr >> CreateVHD.diskpart 165 | echo create partition primary >> CreateVHD.diskpart 166 | 167 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 168 | 169 | echo assign letter=x >> CreateVHD.diskpart 170 | 171 | call :run_diskpart CreateVHD.diskpart 172 | 173 | rem Create an USN journal so we can track file changes in more detail. 174 | fsutil usn createjournal x: 175 | 176 | rem Step 1 create files and directories. 177 | echo "testfile1" > x:\testfile1 178 | 179 | mkdir x:\testdir1 180 | echo "testfile2" > x:\testdir1\testfile2 181 | 182 | mkdir x:\testdir1\testdir2 183 | echo "testfile3" > x:\testdir1\testdir2\testfile3 184 | echo "testfile4" > x:\testdir1\testdir2\testfile4 185 | 186 | rem Windows does not support hardlinks to directories only junctions 187 | mklink /J x:\junction1 x:\testdir1\testdir2 188 | mklink /J x:\junction2 x:\testdir1\testdir2 189 | 190 | mkdir x:\testdir3 191 | mklink /H x:\testdir3\hardlink1 x:\testdir1\testdir2\testfile3 192 | 193 | rem Step 2 remove a file 194 | del /f /q x:\testdir1\testdir2\testfile4 195 | 196 | rmdir x:\junction2 197 | 198 | rem Step 3 rename a directory 199 | move /y x:\testdir1\testdir2 x:\testdir1\2ridtset 200 | 201 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 202 | echo detach vdisk >> UnmountVHD.diskpart 203 | 204 | call :run_diskpart UnmountVHD.diskpart 205 | 206 | copy %specimenspath%\%imagename% %specimenspath%\ntfs_path_hint.vhd 207 | 208 | rem Remove the working image file. 209 | del /f /q %specimenspath%\%imagename% 210 | 211 | rem Scenario 3: 212 | rem 1. Create a file in a directory 213 | rem 2. Create hard links in directories. 214 | 215 | rem Create a fixed-size VHD image with a NTFS file system 216 | set unitsize=4096 217 | set imagename=ntfs.vhd 218 | set imagesize=8 219 | 220 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 221 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 222 | echo attach vdisk >> CreateVHD.diskpart 223 | echo convert mbr >> CreateVHD.diskpart 224 | echo create partition primary >> CreateVHD.diskpart 225 | 226 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 227 | 228 | echo assign letter=x >> CreateVHD.diskpart 229 | 230 | call :run_diskpart CreateVHD.diskpart 231 | 232 | rem Step 1 create files and directories. 233 | mkdir x:\testdir1 234 | echo "testfile1" > x:\testdir1\testfile1 235 | 236 | rem Step 2 create hard links in directories. 237 | mkdir x:\testdir2 238 | mklink /H x:\testdir2\hardlink1 x:\testdir1\testfile1 239 | 240 | mkdir x:\testdir3 241 | mklink /H x:\testdir3\hardlink2 x:\testdir1\testfile1 242 | 243 | mkdir x:\testdir4 244 | mklink /H x:\testdir4\hardlink3 x:\testdir1\testfile1 245 | 246 | mkdir x:\testdir5 247 | mklink /H x:\testdir5\hardlink4 x:\testdir1\testfile1 248 | 249 | mkdir x:\testdir6 250 | mklink /H x:\testdir6\hardlink5 x:\testdir1\testfile1 251 | 252 | mkdir x:\testdir7 253 | mklink /H x:\testdir7\hardlink6 x:\testdir1\testfile1 254 | 255 | mkdir x:\testdir8 256 | mklink /H x:\testdir8\hardlink7 x:\testdir1\testfile1 257 | 258 | mkdir x:\testdir9 259 | mklink /H x:\testdir9\hardlink8 x:\testdir1\testfile1 260 | 261 | mkdir x:\testdir10 262 | mklink /H x:\testdir10\hardlink9 x:\testdir1\testfile1 263 | 264 | mkdir x:\testdir11 265 | mklink /H x:\testdir11\hardlink10 x:\testdir1\testfile1 266 | 267 | mkdir x:\testdir12 268 | mklink /H x:\testdir12\hardlink11 x:\testdir1\testfile1 269 | 270 | mkdir x:\testdir13 271 | mklink /H x:\testdir13\hardlink12 x:\testdir1\testfile1 272 | 273 | mkdir x:\testdir14 274 | mklink /H x:\testdir14\hardlink13 x:\testdir1\testfile1 275 | 276 | mkdir x:\testdir15 277 | mklink /H x:\testdir15\hardlink14 x:\testdir1\testfile1 278 | 279 | mkdir x:\testdir16 280 | mklink /H x:\testdir16\hardlink15 x:\testdir1\testfile1 281 | 282 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 283 | echo detach vdisk >> UnmountVHD.diskpart 284 | 285 | call :run_diskpart UnmountVHD.diskpart 286 | 287 | copy %specimenspath%\%imagename% %specimenspath%\ntfs-scenario3.1.vhd 288 | 289 | rem Sleep so that changes are noticeable. 290 | timeout /t 5 /nobreak 291 | 292 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > MountVHD.diskpart 293 | echo attach vdisk >> MountVHD.diskpart 294 | 295 | echo assign letter=x >> MountVHD.diskpart 296 | 297 | call :run_diskpart MountVHD.diskpart 298 | 299 | rem Step 3 remove hard links. 300 | 301 | del /f /q x:\testdir3\hardlink2; 302 | del /f /q x:\testdir5\hardlink4; 303 | del /f /q x:\testdir7\hardlink6; 304 | del /f /q x:\testdir9\hardlink8; 305 | del /f /q x:\testdir11\hardlink10; 306 | del /f /q x:\testdir13\hardlink12; 307 | del /f /q x:\testdir15\hardlink14; 308 | 309 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 310 | echo detach vdisk >> UnmountVHD.diskpart 311 | 312 | call :run_diskpart UnmountVHD.diskpart 313 | 314 | copy %specimenspath%\%imagename% %specimenspath%\ntfs-scenario3.2.vhd 315 | 316 | rem Remove the working image file. 317 | del /f /q %specimenspath%\%imagename% 318 | 319 | rem Scenario 6: 320 | rem Based on https://github.com/log2timeline/plaso/issues/3840 321 | 322 | rem Create a fixed-size VHD image with a NTFS file system 323 | set unitsize=4096 324 | set imagename=ntfs.vhd 325 | set imagesize=8 326 | 327 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 328 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 329 | echo attach vdisk >> CreateVHD.diskpart 330 | echo convert mbr >> CreateVHD.diskpart 331 | echo create partition primary >> CreateVHD.diskpart 332 | 333 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 334 | 335 | echo assign letter=x >> CreateVHD.diskpart 336 | 337 | call :run_diskpart CreateVHD.diskpart 338 | 339 | rem Create an USN journal so we can track file changes in more detail. 340 | fsutil usn createjournal x: 341 | 342 | rem Step 1 create files and directories. 343 | mkdir x:\testdir1 344 | echo "testfile1" > x:\testdir1\testfile1 345 | 346 | rem Step 2 ensure $FILE_NAME of testdir1 is stored in an attribute list. 347 | echo "ads1" > x:\testdir1:ads1 348 | echo "ads2" > x:\testdir1:ads2 349 | echo "ads3" > x:\testdir1:ads3 350 | echo "ads4" > x:\testdir1:ads4 351 | echo "ads5" > x:\testdir1:ads5 352 | echo "ads6" > x:\testdir1:ads6 353 | echo "ads7" > x:\testdir1:ads7 354 | echo "ads8" > x:\testdir1:ads8 355 | echo "ads9" > x:\testdir1:ads9 356 | echo "ads10" > x:\testdir1:ads10 357 | echo "ads11" > x:\testdir1:ads11 358 | echo "ads12" > x:\testdir1:ads12 359 | echo "ads13" > x:\testdir1:ads13 360 | echo "ads14" > x:\testdir1:ads14 361 | echo "ads15" > x:\testdir1:ads15 362 | echo "ads16" > x:\testdir1:ads16 363 | 364 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 365 | echo detach vdisk >> UnmountVHD.diskpart 366 | 367 | call :run_diskpart UnmountVHD.diskpart 368 | 369 | copy %specimenspath%\%imagename% %specimenspath%\ntfs-scenario6.1.vhd 370 | 371 | rem Sleep so that changes are noticeable. 372 | timeout /t 5 /nobreak 373 | 374 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > MountVHD.diskpart 375 | echo attach vdisk >> MountVHD.diskpart 376 | 377 | echo assign letter=x >> MountVHD.diskpart 378 | 379 | call :run_diskpart MountVHD.diskpart 380 | 381 | rem Step 3 remove a directory. 382 | del /f /q /s x:\testdir1 383 | rmdir x:\testdir1 384 | 385 | rem Step 4 create a file. 386 | rem This steps assumes the MFT entry previously used by testdir1 is reused for testfile2. 387 | echo "testfile2" > x:\testfile2 388 | 389 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 390 | echo detach vdisk >> UnmountVHD.diskpart 391 | 392 | call :run_diskpart UnmountVHD.diskpart 393 | 394 | copy %specimenspath%\%imagename% %specimenspath%\ntfs-scenario6.2.vhd 395 | 396 | rem Remove the working image file. 397 | del /f /q %specimenspath%\%imagename% 398 | 399 | rem Scenario 7: 400 | rem Variant of scenario 6 401 | 402 | rem Create a fixed-size VHD image with a NTFS file system 403 | set unitsize=4096 404 | set imagename=ntfs.vhd 405 | set imagesize=8 406 | 407 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 408 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 409 | echo attach vdisk >> CreateVHD.diskpart 410 | echo convert mbr >> CreateVHD.diskpart 411 | echo create partition primary >> CreateVHD.diskpart 412 | 413 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 414 | 415 | echo assign letter=x >> CreateVHD.diskpart 416 | 417 | call :run_diskpart CreateVHD.diskpart 418 | 419 | rem Create an USN journal so we can track file changes in more detail. 420 | fsutil usn createjournal x: 421 | 422 | rem Step 1 create files and directories. 423 | mkdir x:\testdir1 424 | echo "testfile1" > x:\testdir1\testfile1 425 | echo "testfile2" > x:\testdir1\testfile2 426 | echo "testfile3" > x:\testdir1\testfile3 427 | echo "testfile4" > x:\testdir1\testfile4 428 | echo "testfile5" > x:\testdir1\testfile5 429 | echo "testfile6" > x:\testdir1\testfile6 430 | echo "testfile7" > x:\testdir1\testfile7 431 | echo "testfile8" > x:\testdir1\testfile8 432 | echo "testfile9" > x:\testdir1\testfile9 433 | echo "testfile10" > x:\testdir1\testfile10 434 | echo "testfile11" > x:\testdir1\testfile11 435 | echo "testfile12" > x:\testdir1\testfile12 436 | echo "testfile13" > x:\testdir1\testfile13 437 | echo "testfile14" > x:\testdir1\testfile14 438 | 14ho "testfile15" > x:\testdir1\testfile15 439 | 14ho "testfile16" > x:\testdir1\testfile16 440 | 441 | rem Step 2 ensure $FILE_NAME of testdir1 is stored in an attribute list. 442 | echo "ads1" > x:\testdir1:ads1 443 | echo "ads2" > x:\testdir1:ads2 444 | echo "ads3" > x:\testdir1:ads3 445 | echo "ads4" > x:\testdir1:ads4 446 | echo "ads5" > x:\testdir1:ads5 447 | echo "ads6" > x:\testdir1:ads6 448 | echo "ads7" > x:\testdir1:ads7 449 | echo "ads8" > x:\testdir1:ads8 450 | echo "ads9" > x:\testdir1:ads9 451 | echo "ads10" > x:\testdir1:ads10 452 | echo "ads11" > x:\testdir1:ads11 453 | echo "ads12" > x:\testdir1:ads12 454 | echo "ads13" > x:\testdir1:ads13 455 | echo "ads14" > x:\testdir1:ads14 456 | echo "ads15" > x:\testdir1:ads15 457 | echo "ads16" > x:\testdir1:ads16 458 | 459 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 460 | echo detach vdisk >> UnmountVHD.diskpart 461 | 462 | call :run_diskpart UnmountVHD.diskpart 463 | 464 | copy %specimenspath%\%imagename% %specimenspath%\ntfs-scenario7.1.vhd 465 | 466 | rem Sleep so that changes are noticeable. 467 | timeout /t 5 /nobreak 468 | 469 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > MountVHD.diskpart 470 | echo attach vdisk >> MountVHD.diskpart 471 | 472 | echo assign letter=x >> MountVHD.diskpart 473 | 474 | call :run_diskpart MountVHD.diskpart 475 | 476 | rem Step 3 remove a directory. 477 | del /f /q /s x:\testdir1 478 | rmdir x:\testdir1 479 | 480 | rem Step 4 create a file. 481 | rem This steps assumes the MFT entry previously used by testdir1 is reused for testfile20. 482 | echo "testfile20" > x:\testfile20 483 | 484 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 485 | echo detach vdisk >> UnmountVHD.diskpart 486 | 487 | call :run_diskpart UnmountVHD.diskpart 488 | 489 | copy %specimenspath%\%imagename% %specimenspath%\ntfs-scenario7.2.vhd 490 | 491 | rem Sleep so that changes are noticeable. 492 | timeout /t 5 /nobreak 493 | 494 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > MountVHD.diskpart 495 | echo attach vdisk >> MountVHD.diskpart 496 | 497 | echo assign letter=x >> MountVHD.diskpart 498 | 499 | call :run_diskpart MountVHD.diskpart 500 | 501 | rem Step 5 create a directory. 502 | mkdir x:\testdir1 503 | 504 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 505 | echo detach vdisk >> UnmountVHD.diskpart 506 | 507 | call :run_diskpart UnmountVHD.diskpart 508 | 509 | copy %specimenspath%\%imagename% %specimenspath%\ntfs-scenario7.3.vhd 510 | 511 | rem Remove the working image file. 512 | del /f /q %specimenspath%\%imagename% 513 | 514 | exit /b 0 515 | 516 | rem Runs diskpart with a script 517 | rem Note that diskpart requires Administrator privileges to run 518 | :run_diskpart 519 | SETLOCAL 520 | set diskpartscript=%1 521 | 522 | rem Note that diskpart requires Administrator privileges to run 523 | diskpart /s %diskpartscript% 524 | 525 | if %errorlevel% neq 0 ( 526 | echo Failed to run: "diskpart /s %diskpartscript%" 527 | 528 | exit /b 1 529 | ) 530 | 531 | del /q %diskpartscript% 532 | 533 | rem Give the system a bit of time to adjust 534 | timeout /t 1 > nul 535 | 536 | ENDLOCAL 537 | exit /b 0 538 | 539 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More_considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution 4.0 International Public License 58 | 59 | By exercising the Licensed Rights (defined below), You accept and agree 60 | to be bound by the terms and conditions of this Creative Commons 61 | Attribution 4.0 International Public License ("Public License"). To the 62 | extent this Public License may be interpreted as a contract, You are 63 | granted the Licensed Rights in consideration of Your acceptance of 64 | these terms and conditions, and the Licensor grants You such rights in 65 | consideration of benefits the Licensor receives from making the 66 | Licensed Material available under these terms and conditions. 67 | 68 | 69 | Section 1 -- Definitions. 70 | 71 | a. Adapted Material means material subject to Copyright and Similar 72 | Rights that is derived from or based upon the Licensed Material 73 | and in which the Licensed Material is translated, altered, 74 | arranged, transformed, or otherwise modified in a manner requiring 75 | permission under the Copyright and Similar Rights held by the 76 | Licensor. For purposes of this Public License, where the Licensed 77 | Material is a musical work, performance, or sound recording, 78 | Adapted Material is always produced where the Licensed Material is 79 | synched in timed relation with a moving image. 80 | 81 | b. Adapter's License means the license You apply to Your Copyright 82 | and Similar Rights in Your contributions to Adapted Material in 83 | accordance with the terms and conditions of this Public License. 84 | 85 | c. Copyright and Similar Rights means copyright and/or similar rights 86 | closely related to copyright including, without limitation, 87 | performance, broadcast, sound recording, and Sui Generis Database 88 | Rights, without regard to how the rights are labeled or 89 | categorized. For purposes of this Public License, the rights 90 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 91 | Rights. 92 | 93 | d. Effective Technological Measures means those measures that, in the 94 | absence of proper authority, may not be circumvented under laws 95 | fulfilling obligations under Article 11 of the WIPO Copyright 96 | Treaty adopted on December 20, 1996, and/or similar international 97 | agreements. 98 | 99 | e. Exceptions and Limitations means fair use, fair dealing, and/or 100 | any other exception or limitation to Copyright and Similar Rights 101 | that applies to Your use of the Licensed Material. 102 | 103 | f. Licensed Material means the artistic or literary work, database, 104 | or other material to which the Licensor applied this Public 105 | License. 106 | 107 | g. Licensed Rights means the rights granted to You subject to the 108 | terms and conditions of this Public License, which are limited to 109 | all Copyright and Similar Rights that apply to Your use of the 110 | Licensed Material and that the Licensor has authority to license. 111 | 112 | h. Licensor means the individual(s) or entity(ies) granting rights 113 | under this Public License. 114 | 115 | i. Share means to provide material to the public by any means or 116 | process that requires permission under the Licensed Rights, such 117 | as reproduction, public display, public performance, distribution, 118 | dissemination, communication, or importation, and to make material 119 | available to the public including in ways that members of the 120 | public may access the material from a place and at a time 121 | individually chosen by them. 122 | 123 | j. Sui Generis Database Rights means rights other than copyright 124 | resulting from Directive 96/9/EC of the European Parliament and of 125 | the Council of 11 March 1996 on the legal protection of databases, 126 | as amended and/or succeeded, as well as other essentially 127 | equivalent rights anywhere in the world. 128 | 129 | k. You means the individual or entity exercising the Licensed Rights 130 | under this Public License. Your has a corresponding meaning. 131 | 132 | 133 | Section 2 -- Scope. 134 | 135 | a. License grant. 136 | 137 | 1. Subject to the terms and conditions of this Public License, 138 | the Licensor hereby grants You a worldwide, royalty-free, 139 | non-sublicensable, non-exclusive, irrevocable license to 140 | exercise the Licensed Rights in the Licensed Material to: 141 | 142 | a. reproduce and Share the Licensed Material, in whole or 143 | in part; and 144 | 145 | b. produce, reproduce, and Share Adapted Material. 146 | 147 | 2. Exceptions and Limitations. For the avoidance of doubt, where 148 | Exceptions and Limitations apply to Your use, this Public 149 | License does not apply, and You do not need to comply with 150 | its terms and conditions. 151 | 152 | 3. Term. The term of this Public License is specified in Section 153 | 6(a). 154 | 155 | 4. Media and formats; technical modifications allowed. The 156 | Licensor authorizes You to exercise the Licensed Rights in 157 | all media and formats whether now known or hereafter created, 158 | and to make technical modifications necessary to do so. The 159 | Licensor waives and/or agrees not to assert any right or 160 | authority to forbid You from making technical modifications 161 | necessary to exercise the Licensed Rights, including 162 | technical modifications necessary to circumvent Effective 163 | Technological Measures. For purposes of this Public License, 164 | simply making modifications authorized by this Section 2(a) 165 | (4) never produces Adapted Material. 166 | 167 | 5. Downstream recipients. 168 | 169 | a. Offer from the Licensor -- Licensed Material. Every 170 | recipient of the Licensed Material automatically 171 | receives an offer from the Licensor to exercise the 172 | Licensed Rights under the terms and conditions of this 173 | Public License. 174 | 175 | b. No downstream restrictions. You may not offer or impose 176 | any additional or different terms or conditions on, or 177 | apply any Effective Technological Measures to, the 178 | Licensed Material if doing so restricts exercise of the 179 | Licensed Rights by any recipient of the Licensed 180 | Material. 181 | 182 | 6. No endorsement. Nothing in this Public License constitutes or 183 | may be construed as permission to assert or imply that You 184 | are, or that Your use of the Licensed Material is, connected 185 | with, or sponsored, endorsed, or granted official status by, 186 | the Licensor or others designated to receive attribution as 187 | provided in Section 3(a)(1)(A)(i). 188 | 189 | b. Other rights. 190 | 191 | 1. Moral rights, such as the right of integrity, are not 192 | licensed under this Public License, nor are publicity, 193 | privacy, and/or other similar personality rights; however, to 194 | the extent possible, the Licensor waives and/or agrees not to 195 | assert any such rights held by the Licensor to the limited 196 | extent necessary to allow You to exercise the Licensed 197 | Rights, but not otherwise. 198 | 199 | 2. Patent and trademark rights are not licensed under this 200 | Public License. 201 | 202 | 3. To the extent possible, the Licensor waives any right to 203 | collect royalties from You for the exercise of the Licensed 204 | Rights, whether directly or through a collecting society 205 | under any voluntary or waivable statutory or compulsory 206 | licensing scheme. In all other cases the Licensor expressly 207 | reserves any right to collect such royalties. 208 | 209 | 210 | Section 3 -- License Conditions. 211 | 212 | Your exercise of the Licensed Rights is expressly made subject to the 213 | following conditions. 214 | 215 | a. Attribution. 216 | 217 | 1. If You Share the Licensed Material (including in modified 218 | form), You must: 219 | 220 | a. retain the following if it is supplied by the Licensor 221 | with the Licensed Material: 222 | 223 | i. identification of the creator(s) of the Licensed 224 | Material and any others designated to receive 225 | attribution, in any reasonable manner requested by 226 | the Licensor (including by pseudonym if 227 | designated); 228 | 229 | ii. a copyright notice; 230 | 231 | iii. a notice that refers to this Public License; 232 | 233 | iv. a notice that refers to the disclaimer of 234 | warranties; 235 | 236 | v. a URI or hyperlink to the Licensed Material to the 237 | extent reasonably practicable; 238 | 239 | b. indicate if You modified the Licensed Material and 240 | retain an indication of any previous modifications; and 241 | 242 | c. indicate the Licensed Material is licensed under this 243 | Public License, and include the text of, or the URI or 244 | hyperlink to, this Public License. 245 | 246 | 2. You may satisfy the conditions in Section 3(a)(1) in any 247 | reasonable manner based on the medium, means, and context in 248 | which You Share the Licensed Material. For example, it may be 249 | reasonable to satisfy the conditions by providing a URI or 250 | hyperlink to a resource that includes the required 251 | information. 252 | 253 | 3. If requested by the Licensor, You must remove any of the 254 | information required by Section 3(a)(1)(A) to the extent 255 | reasonably practicable. 256 | 257 | 4. If You Share Adapted Material You produce, the Adapter's 258 | License You apply must not prevent recipients of the Adapted 259 | Material from complying with this Public License. 260 | 261 | 262 | Section 4 -- Sui Generis Database Rights. 263 | 264 | Where the Licensed Rights include Sui Generis Database Rights that 265 | apply to Your use of the Licensed Material: 266 | 267 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 268 | to extract, reuse, reproduce, and Share all or a substantial 269 | portion of the contents of the database; 270 | 271 | b. if You include all or a substantial portion of the database 272 | contents in a database in which You have Sui Generis Database 273 | Rights, then the database in which You have Sui Generis Database 274 | Rights (but not its individual contents) is Adapted Material; and 275 | 276 | c. You must comply with the conditions in Section 3(a) if You Share 277 | all or a substantial portion of the contents of the database. 278 | 279 | For the avoidance of doubt, this Section 4 supplements and does not 280 | replace Your obligations under this Public License where the Licensed 281 | Rights include other Copyright and Similar Rights. 282 | 283 | 284 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 285 | 286 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 287 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 288 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 289 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 290 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 291 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 292 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 293 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 294 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 295 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 296 | 297 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 298 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 299 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 300 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 301 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 302 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 303 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 304 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 305 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 306 | 307 | c. The disclaimer of warranties and limitation of liability provided 308 | above shall be interpreted in a manner that, to the extent 309 | possible, most closely approximates an absolute disclaimer and 310 | waiver of all liability. 311 | 312 | 313 | Section 6 -- Term and Termination. 314 | 315 | a. This Public License applies for the term of the Copyright and 316 | Similar Rights licensed here. However, if You fail to comply with 317 | this Public License, then Your rights under this Public License 318 | terminate automatically. 319 | 320 | b. Where Your right to use the Licensed Material has terminated under 321 | Section 6(a), it reinstates: 322 | 323 | 1. automatically as of the date the violation is cured, provided 324 | it is cured within 30 days of Your discovery of the 325 | violation; or 326 | 327 | 2. upon express reinstatement by the Licensor. 328 | 329 | For the avoidance of doubt, this Section 6(b) does not affect any 330 | right the Licensor may have to seek remedies for Your violations 331 | of this Public License. 332 | 333 | c. For the avoidance of doubt, the Licensor may also offer the 334 | Licensed Material under separate terms or conditions or stop 335 | distributing the Licensed Material at any time; however, doing so 336 | will not terminate this Public License. 337 | 338 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 339 | License. 340 | 341 | 342 | Section 7 -- Other Terms and Conditions. 343 | 344 | a. The Licensor shall not be bound by any additional or different 345 | terms or conditions communicated by You unless expressly agreed. 346 | 347 | b. Any arrangements, understandings, or agreements regarding the 348 | Licensed Material not stated herein are separate from and 349 | independent of the terms and conditions of this Public License. 350 | 351 | 352 | Section 8 -- Interpretation. 353 | 354 | a. For the avoidance of doubt, this Public License does not, and 355 | shall not be interpreted to, reduce, limit, restrict, or impose 356 | conditions on any use of the Licensed Material that could lawfully 357 | be made without permission under this Public License. 358 | 359 | b. To the extent possible, if any provision of this Public License is 360 | deemed unenforceable, it shall be automatically reformed to the 361 | minimum extent necessary to make it enforceable. If the provision 362 | cannot be reformed, it shall be severed from this Public License 363 | without affecting the enforceability of the remaining terms and 364 | conditions. 365 | 366 | c. No term or condition of this Public License will be waived and no 367 | failure to comply consented to unless expressly agreed to by the 368 | Licensor. 369 | 370 | d. Nothing in this Public License constitutes or may be interpreted 371 | as a limitation upon, or waiver of, any privileges and immunities 372 | that apply to the Licensor or You, including from the legal 373 | processes of any jurisdiction or authority. 374 | 375 | 376 | ======================================================================= 377 | 378 | Creative Commons is not a party to its public 379 | licenses. Notwithstanding, Creative Commons may elect to apply one of 380 | its public licenses to material it publishes and in those instances 381 | will be considered the “Licensor.” The text of the Creative Commons 382 | public licenses is dedicated to the public domain under the CC0 Public 383 | Domain Dedication. Except for the limited purpose of indicating that 384 | material is shared under a Creative Commons public license or as 385 | otherwise permitted by the Creative Commons policies published at 386 | creativecommons.org/policies, Creative Commons does not authorize the 387 | use of the trademark "Creative Commons" or any other trademark or logo 388 | of Creative Commons without its prior written consent including, 389 | without limitation, in connection with any unauthorized modifications 390 | to any of its public licenses or any other arrangements, 391 | understandings, or agreements concerning use of licensed material. For 392 | the avoidance of doubt, this paragraph does not form part of the 393 | public licenses. 394 | 395 | Creative Commons may be contacted at creativecommons.org. 396 | 397 | -------------------------------------------------------------------------------- /generate-specimens-windows.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | rem Script to generate NTFS test files 4 | rem Requires Windows 7 or later 5 | 6 | rem Split the output of ver e.g. "Microsoft Windows [Version 10.0.10586]" 7 | rem and keep the last part "10.0.10586]". 8 | for /f "tokens=1,2,3,4" %%a in ('ver') do ( 9 | set version=%%d 10 | ) 11 | 12 | rem Replace dots by spaces "10 0 10586]". 13 | set version=%version:.= % 14 | 15 | rem Split the last part of the ver output "10 0 10586]" and keep the first 16 | rem 2 values formatted with a dot as separator "10.0". 17 | for /f "tokens=1,2,*" %%a in ("%version%") do ( 18 | set version=%%a.%%b 19 | ) 20 | 21 | rem TODO add check for other supported versions of Windows 22 | rem Also see: https://en.wikipedia.org/wiki/Ver_(command) 23 | 24 | if not "%version%" == "10.0" ( 25 | echo Unsupported Windows version: %version% 26 | 27 | exit /b 1 28 | ) 29 | 30 | set specimenspath=specimens\%version% 31 | 32 | if exist "%specimenspath%" ( 33 | echo Specimens directory: %specimenspath% already exists. 34 | 35 | exit /b 1 36 | ) 37 | 38 | mkdir "%specimenspath%" 39 | 40 | rem Supported diskpart format fs= options: ntfs, fat, fat32 41 | rem Supported diskpart format unit= options: 512, 1024, 2048, 4096 (default), 8192, 16K, 32K, 64K 42 | rem unit= values added in Windows 10 (1903): 128K, 256K, 512K, 1M, 2M 43 | 44 | rem Create a fixed-size VHD image with a NTFS file system 45 | set unitsize=4096 46 | set imagename=ntfs.vhd 47 | set imagesize=8 48 | 49 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 50 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 51 | echo attach vdisk >> CreateVHD.diskpart 52 | echo convert mbr >> CreateVHD.diskpart 53 | echo create partition primary >> CreateVHD.diskpart 54 | 55 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 56 | 57 | echo assign letter=x >> CreateVHD.diskpart 58 | 59 | call :run_diskpart CreateVHD.diskpart 60 | 61 | call :create_test_file_entries x 62 | 63 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 64 | echo detach vdisk >> UnmountVHD.diskpart 65 | 66 | call :run_diskpart UnmountVHD.diskpart 67 | 68 | rem Create a fixed-size VHD image with a NTFS file system with compression 69 | set unitsize=4096 70 | set imagename=ntfs_compress.vhd 71 | set imagesize=8 72 | 73 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 74 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 75 | echo attach vdisk >> CreateVHD.diskpart 76 | echo convert mbr >> CreateVHD.diskpart 77 | echo create partition primary >> CreateVHD.diskpart 78 | 79 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick compress >> CreateVHD.diskpart 80 | 81 | echo assign letter=x >> CreateVHD.diskpart 82 | 83 | call :run_diskpart CreateVHD.diskpart 84 | 85 | call :create_test_file_entries x 86 | 87 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 88 | echo detach vdisk >> UnmountVHD.diskpart 89 | 90 | call :run_diskpart UnmountVHD.diskpart 91 | 92 | rem Create a fixed-size VHD image with a NTFS file system and unit size 512 93 | set unitsize=512 94 | set imagename=ntfs_%unitsize%.vhd 95 | set imagesize=8 96 | 97 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 98 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 99 | echo attach vdisk >> CreateVHD.diskpart 100 | echo convert mbr >> CreateVHD.diskpart 101 | echo create partition primary >> CreateVHD.diskpart 102 | 103 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 104 | 105 | echo assign letter=x >> CreateVHD.diskpart 106 | 107 | call :run_diskpart CreateVHD.diskpart 108 | 109 | call :create_test_file_entries x 110 | 111 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 112 | echo detach vdisk >> UnmountVHD.diskpart 113 | 114 | call :run_diskpart UnmountVHD.diskpart 115 | 116 | rem Create a fixed-size VHD image with a NTFS file system and unit size 1024 117 | set unitsize=1024 118 | set imagename=ntfs_%unitsize%.vhd 119 | set imagesize=8 120 | 121 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 122 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 123 | echo attach vdisk >> CreateVHD.diskpart 124 | echo convert mbr >> CreateVHD.diskpart 125 | echo create partition primary >> CreateVHD.diskpart 126 | 127 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 128 | 129 | echo assign letter=x >> CreateVHD.diskpart 130 | 131 | call :run_diskpart CreateVHD.diskpart 132 | 133 | call :create_test_file_entries x 134 | 135 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 136 | echo detach vdisk >> UnmountVHD.diskpart 137 | 138 | call :run_diskpart UnmountVHD.diskpart 139 | 140 | rem Create a fixed-size VHD image with a NTFS file system and unit size 2048 141 | set unitsize=2048 142 | set imagename=ntfs_%unitsize%.vhd 143 | set imagesize=8 144 | 145 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 146 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 147 | echo attach vdisk >> CreateVHD.diskpart 148 | echo convert mbr >> CreateVHD.diskpart 149 | echo create partition primary >> CreateVHD.diskpart 150 | 151 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 152 | 153 | echo assign letter=x >> CreateVHD.diskpart 154 | 155 | call :run_diskpart CreateVHD.diskpart 156 | 157 | call :create_test_file_entries x 158 | 159 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 160 | echo detach vdisk >> UnmountVHD.diskpart 161 | 162 | call :run_diskpart UnmountVHD.diskpart 163 | 164 | rem Create a fixed-size VHD image with a NTFS file system and unit size 4096 165 | set unitsize=4096 166 | set imagename=ntfs_%unitsize%.vhd 167 | set imagesize=8 168 | 169 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 170 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 171 | echo attach vdisk >> CreateVHD.diskpart 172 | echo convert mbr >> CreateVHD.diskpart 173 | echo create partition primary >> CreateVHD.diskpart 174 | 175 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 176 | 177 | echo assign letter=x >> CreateVHD.diskpart 178 | 179 | call :run_diskpart CreateVHD.diskpart 180 | 181 | call :create_test_file_entries x 182 | 183 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 184 | echo detach vdisk >> UnmountVHD.diskpart 185 | 186 | call :run_diskpart UnmountVHD.diskpart 187 | 188 | rem Create a fixed-size VHD image with a NTFS file system and unit size 8192 189 | set unitsize=8192 190 | set imagename=ntfs_%unitsize%.vhd 191 | set imagesize=8 192 | 193 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 194 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 195 | echo attach vdisk >> CreateVHD.diskpart 196 | echo convert mbr >> CreateVHD.diskpart 197 | echo create partition primary >> CreateVHD.diskpart 198 | 199 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 200 | 201 | echo assign letter=x >> CreateVHD.diskpart 202 | 203 | call :run_diskpart CreateVHD.diskpart 204 | 205 | call :create_test_file_entries x 206 | 207 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 208 | echo detach vdisk >> UnmountVHD.diskpart 209 | 210 | call :run_diskpart UnmountVHD.diskpart 211 | 212 | rem Create a fixed-size VHD image with a NTFS file system and unit size 16k 213 | set unitsize=16k 214 | set imagename=ntfs_%unitsize%.vhd 215 | set imagesize=8 216 | 217 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 218 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 219 | echo attach vdisk >> CreateVHD.diskpart 220 | echo convert mbr >> CreateVHD.diskpart 221 | echo create partition primary >> CreateVHD.diskpart 222 | 223 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 224 | 225 | echo assign letter=x >> CreateVHD.diskpart 226 | 227 | call :run_diskpart CreateVHD.diskpart 228 | 229 | call :create_test_file_entries x 230 | 231 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 232 | echo detach vdisk >> UnmountVHD.diskpart 233 | 234 | call :run_diskpart UnmountVHD.diskpart 235 | 236 | rem Create a fixed-size VHD image with a NTFS file system and unit size 32k 237 | set unitsize=32k 238 | set imagename=ntfs_%unitsize%.vhd 239 | set imagesize=8 240 | 241 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 242 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 243 | echo attach vdisk >> CreateVHD.diskpart 244 | echo convert mbr >> CreateVHD.diskpart 245 | echo create partition primary >> CreateVHD.diskpart 246 | 247 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 248 | 249 | echo assign letter=x >> CreateVHD.diskpart 250 | 251 | call :run_diskpart CreateVHD.diskpart 252 | 253 | call :create_test_file_entries x 254 | 255 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 256 | echo detach vdisk >> UnmountVHD.diskpart 257 | 258 | call :run_diskpart UnmountVHD.diskpart 259 | 260 | rem Create a fixed-size VHD image with a NTFS file system and unit size 64k 261 | set unitsize=64k 262 | set imagename=ntfs_%unitsize%.vhd 263 | set imagesize=8 264 | 265 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 266 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 267 | echo attach vdisk >> CreateVHD.diskpart 268 | echo convert mbr >> CreateVHD.diskpart 269 | echo create partition primary >> CreateVHD.diskpart 270 | 271 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 272 | 273 | echo assign letter=x >> CreateVHD.diskpart 274 | 275 | call :run_diskpart CreateVHD.diskpart 276 | 277 | call :create_test_file_entries x 278 | 279 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 280 | echo detach vdisk >> UnmountVHD.diskpart 281 | 282 | call :run_diskpart UnmountVHD.diskpart 283 | 284 | rem Create a fixed-size VHD image with a NTFS file system and unit size 128k 285 | set unitsize=128k 286 | set imagename=ntfs_%unitsize%.vhd 287 | set imagesize=8 288 | 289 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 290 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 291 | echo attach vdisk >> CreateVHD.diskpart 292 | echo convert mbr >> CreateVHD.diskpart 293 | rem The start of the partition must be aligned with the (cluster block) unit size. 294 | echo create partition primary align=128 >> CreateVHD.diskpart 295 | 296 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 297 | 298 | echo assign letter=x >> CreateVHD.diskpart 299 | 300 | call :run_diskpart CreateVHD.diskpart 301 | 302 | call :create_test_file_entries x 303 | 304 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 305 | echo detach vdisk >> UnmountVHD.diskpart 306 | 307 | call :run_diskpart UnmountVHD.diskpart 308 | 309 | rem Create a fixed-size VHD image with a NTFS file system and unit size 256k 310 | set unitsize=256k 311 | set imagename=ntfs_%unitsize%.vhd 312 | set imagesize=16 313 | 314 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 315 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 316 | echo attach vdisk >> CreateVHD.diskpart 317 | echo convert mbr >> CreateVHD.diskpart 318 | rem The start of the partition must be aligned with the (cluster block) unit size. 319 | echo create partition primary align=256 >> CreateVHD.diskpart 320 | 321 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 322 | 323 | echo assign letter=x >> CreateVHD.diskpart 324 | 325 | call :run_diskpart CreateVHD.diskpart 326 | 327 | call :create_test_file_entries x 328 | 329 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 330 | echo detach vdisk >> UnmountVHD.diskpart 331 | 332 | call :run_diskpart UnmountVHD.diskpart 333 | 334 | rem Create a fixed-size VHD image with a NTFS file system and unit size 512k 335 | set unitsize=512k 336 | set imagename=ntfs_%unitsize%.vhd 337 | set imagesize=16 338 | 339 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 340 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 341 | echo attach vdisk >> CreateVHD.diskpart 342 | echo convert mbr >> CreateVHD.diskpart 343 | rem The start of the partition must be aligned with the (cluster block) unit size. 344 | echo create partition primary align=512 >> CreateVHD.diskpart 345 | 346 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 347 | 348 | echo assign letter=x >> CreateVHD.diskpart 349 | 350 | call :run_diskpart CreateVHD.diskpart 351 | 352 | call :create_test_file_entries x 353 | 354 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 355 | echo detach vdisk >> UnmountVHD.diskpart 356 | 357 | call :run_diskpart UnmountVHD.diskpart 358 | 359 | rem Create a fixed-size VHD image with a NTFS file system and unit size 1m 360 | set unitsize=1m 361 | set imagename=ntfs_%unitsize%.vhd 362 | set imagesize=32 363 | 364 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 365 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 366 | echo attach vdisk >> CreateVHD.diskpart 367 | echo convert mbr >> CreateVHD.diskpart 368 | rem The start of the partition must be aligned with the (cluster block) unit size. 369 | echo create partition primary align=1024 >> CreateVHD.diskpart 370 | 371 | echo format fs=ntfs label="TestVolume" unit=1024k quick >> CreateVHD.diskpart 372 | 373 | echo assign letter=x >> CreateVHD.diskpart 374 | 375 | call :run_diskpart CreateVHD.diskpart 376 | 377 | call :create_test_file_entries x 378 | 379 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 380 | echo detach vdisk >> UnmountVHD.diskpart 381 | 382 | call :run_diskpart UnmountVHD.diskpart 383 | 384 | rem Create a fixed-size VHD image with a NTFS file system and unit size 2m 385 | set unitsize=2m 386 | set imagename=ntfs_%unitsize%.vhd 387 | set imagesize=64 388 | 389 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 390 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 391 | echo attach vdisk >> CreateVHD.diskpart 392 | echo convert mbr >> CreateVHD.diskpart 393 | rem The start of the partition must be aligned with the (cluster block) unit size. 394 | echo create partition primary align=2048 >> CreateVHD.diskpart 395 | 396 | echo format fs=ntfs label="TestVolume" unit=2048k quick >> CreateVHD.diskpart 397 | 398 | echo assign letter=x >> CreateVHD.diskpart 399 | 400 | call :run_diskpart CreateVHD.diskpart 401 | 402 | call :create_test_file_entries x 403 | 404 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 405 | echo detach vdisk >> UnmountVHD.diskpart 406 | 407 | call :run_diskpart UnmountVHD.diskpart 408 | 409 | rem Create a fixed-size VHD image with a NTFS file system and 100 files 410 | set unitsize=4096 411 | set imagename=ntfs_100_files.vhd 412 | set imagesize=8 413 | 414 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 415 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 416 | echo attach vdisk >> CreateVHD.diskpart 417 | echo convert mbr >> CreateVHD.diskpart 418 | echo create partition primary >> CreateVHD.diskpart 419 | 420 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 421 | 422 | echo assign letter=x >> CreateVHD.diskpart 423 | 424 | call :run_diskpart CreateVHD.diskpart 425 | 426 | call :create_many_test_files x 100 427 | 428 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 429 | echo detach vdisk >> UnmountVHD.diskpart 430 | 431 | call :run_diskpart UnmountVHD.diskpart 432 | 433 | rem Create a fixed-size VHD image with a NTFS file system and 100 alternative data streams (ADS) 434 | set unitsize=4096 435 | set imagename=ntfs_100_ads.vhd 436 | set imagesize=8 437 | 438 | echo create vdisk file=%cd%\%specimenspath%\%imagename% maximum=%imagesize% type=fixed > CreateVHD.diskpart 439 | echo select vdisk file=%cd%\%specimenspath%\%imagename% >> CreateVHD.diskpart 440 | echo attach vdisk >> CreateVHD.diskpart 441 | echo convert mbr >> CreateVHD.diskpart 442 | echo create partition primary >> CreateVHD.diskpart 443 | 444 | echo format fs=ntfs label="TestVolume" unit=%unitsize% quick >> CreateVHD.diskpart 445 | 446 | echo assign letter=x >> CreateVHD.diskpart 447 | 448 | call :run_diskpart CreateVHD.diskpart 449 | 450 | call :create_many_test_data_streams x 100 451 | 452 | echo select vdisk file=%cd%\%specimenspath%\%imagename% > UnmountVHD.diskpart 453 | echo detach vdisk >> UnmountVHD.diskpart 454 | 455 | call :run_diskpart UnmountVHD.diskpart 456 | 457 | exit /b 0 458 | 459 | rem Creates many test data_streams 460 | :create_many_test_data_streams 461 | SETLOCAL 462 | SET driveletter=%1 463 | SET totalnumber=%2 464 | 465 | call :create_test_file_entries %driveletter% 466 | 467 | type nul >> %driveletter%:\file_ads2 468 | 469 | for /l %%a in (1, 1, %totalnumber%) do ( 470 | echo More ADS %%a > %driveletter%:\file_ads2:ads%%a 471 | ) 472 | 473 | ENDLOCAL 474 | exit /b 0 475 | 476 | rem Creates many test files 477 | :create_many_test_files 478 | SETLOCAL 479 | SET driveletter=%1 480 | SET totalnumber=%2 481 | 482 | call :create_test_file_entries %driveletter% 483 | 484 | for /l %%a in (3, 1, %totalnumber%) do ( 485 | type nul >> %driveletter%:\testdir1\testfile%%a 486 | ) 487 | 488 | ENDLOCAL 489 | exit /b 0 490 | 491 | rem Creates test file entries 492 | :create_test_file_entries 493 | SETLOCAL 494 | SET driveletter=%1 495 | 496 | rem Create an empty file 497 | type nul >> %driveletter%:\emptyfile 498 | 499 | rem Create a directory 500 | mkdir %driveletter%:\testdir1 501 | 502 | rem Create a file with a resident MFT data attribute 503 | echo My file > %driveletter%:\testdir1\testfile1 504 | 505 | rem Create a file with a non-resident MFT data attribute 506 | copy LICENSE %driveletter%:\testdir1\testfile2 507 | 508 | rem Create a file with a long filename 509 | type nul >> "%driveletter%:\My long, very long file name, so very long" 510 | 511 | rem Create an LZNT1 compressed file if supported 512 | rem copy LICENSE %driveletter%:\testdir1\compressed1 513 | rem compact /c /f /q %driveletter%:\testdir1\compressed1 514 | 515 | rem Create LZXPRESS 4k compressed files 516 | copy BINARY %driveletter%:\testdir1\lzxpress4k_compressed1 517 | compact /c /exe:XPRESS4K /f /q %driveletter%:\testdir1\lzxpress4k_compressed1 518 | 519 | rem Create LZXPRESS 8k compressed files 520 | copy BINARY %driveletter%:\testdir1\lzxpress8k_compressed1 521 | compact /c /exe:XPRESS8K /f /q %driveletter%:\testdir1\lzxpress8k_compressed1 522 | 523 | rem Create LZXPRESS 16k compressed files 524 | copy BINARY %driveletter%:\testdir1\lzxpress16k_compressed1 525 | compact /c /exe:XPRESS16K /f /q %driveletter%:\testdir1\lzxpress16k_compressed1 526 | 527 | rem Create LZX compressed files 528 | rem Use multiple samples for the different modes of LZX compression 529 | copy BINARY %driveletter%:\testdir1\lzx_compressed1 530 | compact /c /exe:LZX /f /q %driveletter%:\testdir1\lzx_compressed1 531 | 532 | copy BINARY.upx %driveletter%:\testdir1\lzx_compressed2 533 | compact /c /exe:LZX /f /q %driveletter%:\testdir1\lzx_compressed2 534 | 535 | copy BINARY.gz %driveletter%:\testdir1\lzx_compressed3 536 | compact /c /exe:LZX /f /q %driveletter%:\testdir1\lzx_compressed3 537 | 538 | rem Create a hard link to a file 539 | mklink /H %driveletter%:\file_hardlink1 %driveletter%:\testdir1\testfile1 540 | 541 | rem Create a symbolic link to a file 542 | mklink %driveletter%:\file_symboliclink1 %driveletter%:\testdir1\testfile1 543 | 544 | rem Create a junction (hard link to a directory) 545 | mklink /J %driveletter%:\directory_junction1 %driveletter%:\testdir1 546 | 547 | rem Create a symbolic link to a directory 548 | mklink /D %driveletter%:\directory_symboliclink1 %driveletter%:\testdir1 549 | 550 | rem Create a file with an alternative data stream (ADS) 551 | type nul >> %driveletter%:\file_ads1 552 | echo My file ADS > %driveletter%:\file_ads1:myads 553 | 554 | rem Create a directory with an alternative data stream (ADS) 555 | mkdir %driveletter%:\directory_ads1 556 | echo My directory ADS > %driveletter%:\directory_ads1:myads 557 | 558 | rem Create a file with valid data size set 559 | copy LICENSE %driveletter%:\testdir1\file_valid_data_size1 560 | fsutil file setValidData %driveletter%:\testdir1\file_valid_data_size1 18652 561 | 562 | rem Create a file with short name set 563 | echo My short file > %driveletter%:\testdir1\file_short_name1 564 | fsutil file setShortName %driveletter%:\testdir1\file_short_name1 short1 565 | 566 | rem Create a file with a sparse data run 567 | copy LICENSE %driveletter%:\testdir1\file_sparse1 568 | fsutil sparse setflag %driveletter%:\testdir1\file_sparse1 569 | fsutil sparse setRange %driveletter%:\testdir1\file_sparse1 0 18000 570 | 571 | rem TODO: add test case that sets a sparse extent 572 | rem fsutil file setZeroData 573 | 574 | rem TODO: add test case that sets an object identifier 575 | rem fsutil objectid set 576 | 577 | rem Create a case-sensitive directory 578 | rem This requires Microsoft-Windows-Subsystem-Linux to be enabled 579 | rem Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux 580 | mkdir %driveletter%:\testdir2\normal 581 | mkdir %driveletter%:\testdir2\sensitive 582 | fsutil file setCaseSensitiveInfo %driveletter%:\testdir2\sensitive enable 583 | 584 | echo My second file > %driveletter%:\testdir2\normal\testfile1 585 | echo My second file > %driveletter%:\testdir2\sensitive\testfile1 586 | 587 | echo My third file > %driveletter%:\testdir2\normal\TestFile1 588 | echo My third file > %driveletter%:\testdir2\sensitive\TestFile1 589 | 590 | ENDLOCAL 591 | exit /b 0 592 | 593 | rem Runs diskpart with a script 594 | rem Note that diskpart requires Administrator privileges to run 595 | :run_diskpart 596 | SETLOCAL 597 | set diskpartscript=%1 598 | 599 | rem Note that diskpart requires Administrator privileges to run 600 | diskpart /s %diskpartscript% 601 | 602 | if %errorlevel% neq 0 ( 603 | echo Failed to run: "diskpart /s %diskpartscript%" 604 | 605 | exit /b 1 606 | ) 607 | 608 | del /q %diskpartscript% 609 | 610 | rem Give the system a bit of time to adjust 611 | timeout /t 1 > nul 612 | 613 | ENDLOCAL 614 | exit /b 0 615 | 616 | --------------------------------------------------------------------------------