@echo off REM REM win32-test-imagex-capture_and_apply.bat REM REM Run some tests on the Windows version of wimlib-imagex. REM REM This must be run on Windows Vista or later in a clean directory, with REM Administrator privileges. wimlib-imagex and win32-tree-cmp must be REM executable using the paths set below. setlocal EnableDelayedExpansion set WIMLIB_IMAGEX=wimlib-imagex set WIN32_TREE_CMP=win32-tree-cmp set SET_REPARSE_POINT=set_reparse_point if exist in.dir rd /S /Q in.dir if exist out.dir rd /S /Q out.dir md in.dir cd in.dir REM REM BEGIN TESTS REM call :msg "empty directory" call :do_test call :msg "single file" echo 1 > file call :do_test call :msg "different files" echo 1 > file echo 2 > anotherfile call :do_test call :msg "identical files" echo 1 > file echo 1 > identicalfile call :do_test call :msg "hard linked file" echo 1 > file mklink /h link file > nul call :do_test call :msg "hard linked file, with other identical files" echo 1 > file mklink /h link file > nul echo 1 > identicalfile call :do_test call :msg "empty file" type nul > emptyfile call :do_test call :msg "hard linked empty file" type nul > file mklink /h link file > nul call :do_test call :msg "various hard linked, identical, different, and empty files" echo 1 > file echo 5 > file mklink /h link1 file > nul mklink /h link2 file > nul type nul > emptyfile type nul > emptyfile2 mklink /h emptyfilelink emptyfile > nul echo 5 > identicalfile echo 1 > 1file mklink /h 1filelink 1file > nul call :do_test call :msg "multiple subdirectories, some empty, some not" md subdir1 md subdir2 md subdir3 echo 1 > subdir1\1 echo 5 > subdir1\5 mklink /h link subdir1\1 > nul md subdir2\subdir2subdir type nul > subdir2\emptyfile call :do_test call :msg "file with custom security descriptor" echo hello > file icacls file /deny Administrator:F > nul call :do_test call :msg "directory with custom security descriptor (inheritence enabled)" md subdir icacls subdir /inheritance:e > nul call :do_test call :msg "directory with custom security descriptor (inheritence disabled)" md subdir icacls subdir /inheritance:d > nul call :do_test REM win32-tree-cmp can't handle this case. REM REM call :msg "file with custom security descriptor (all inherited ACEs removed)" REM echo hello > file REM icacls file /inheritance:r > nul REM call :do_test call :msg "file with custom integrity level" echo hello > file icacls file /setintegritylevel H > nul call :do_test call :msg "relative symlink" mklink relink dest > nul call :do_test call :msg "absolute symlink, with drive letter" mklink abslink C:\absolute\target > nul call :do_test call :msg "absolute symlink, without drive letter" mklink abslink \absolute\target > nul call :do_test call :msg "relative symlink, with file target" echo 1 > 1 mklink relink 1 > nul call :do_test call :msg "relative symlink, with directory target" md subdir mklink reldlink subdir > nul call :do_test call :msg "junction" md subdir mklink /j junction subdir > nul call :do_test call :msg "symlinks, junctions, files, subdirectories, etc." echo 1 > 1 mklink relink 1 > nul mklink rellinklink relink > nul mklink /j junction . > nul md subdir mklink /h subdir\hardlink 1 > nul echo "hello world!!!!" > hello mklink subdir\hello hello > nul mklink abslink C:\Users > nul md subdir2 type nul > emptyfile type nul > subdir2\emptyfile md subdir2\s md subdir2\s\s md subdir2\s\s\s echo "hello world!!!!" > subdir2\otherfile call :do_test call :msg "reparse point that is neither a symlink nor a junction" type nul > file %SET_REPARSE_POINT% file call :do_test call :msg "reparse point with named data streams" type nul > file echo 11 > file:a echo 1 > file:aa %SET_REPARSE_POINT% file call :do_test call :msg "reparse point with unnamed data stream" echo "test" > file %SET_REPARSE_POINT% file call :do_test call :msg "reparse point with unnamed data stream and named data streams" echo "test" > file echo 11 > file:a echo 1 > file:aa %SET_REPARSE_POINT% file call :do_test call :msg "empty reparse point" type nul > file %SET_REPARSE_POINT% file 0 call :do_test call :msg "empty reparse point with unnamed data stream" echo hello > file %SET_REPARSE_POINT% file 0 call :do_test call :msg "empty reparse point with unnamed data stream and named data streams" echo hello > file echo hello > file:ads1 type nul > file:ads2 %SET_REPARSE_POINT% file 0 call :do_test call :msg "maximum length reparse point" type nul > file %SET_REPARSE_POINT% file 16376 call :do_test call :msg "directory reparse point that is neither a symlink nor a junction" md subdir %SET_REPARSE_POINT% subdir call :do_test call :msg "directory reparse point with named data streams" md subdir echo 11 > subdir:a echo 1 > subdir:aa %SET_REPARSE_POINT% subdir call :do_test call :msg "compressed file" echo "test" > test compact /C test > nul call :do_test call :msg "compressed directory" md subdir compact /C subdir > nul call :do_test call :msg "compressed directory with files in it" md subdir compact /C subdir > nul echo 1 > subdir\file1 echo 2 > subdir\file2 echo 1 > subdir\file1 md subdir\subsubdir mklink /h subdir\hardlink subdir\file1 > nul mklink /j subdir\j subdir\subsubdir > nul call :do_test call :msg "compressed directory with some uncompressed files in it" md subdir compact /C subdir > nul echo 1 > subdir\1 echo 5 > subdir\5 compact /U subdir\1 > nul call :do_test call :msg "file with alternate data stream" echo 1 > file echo 5 > file:ads call :do_test call :msg "file with multiple alternate data streams" echo 1 > file echo a > file:a echo aa > file:aa echo aaa > file:aaa echo aaaa > file:aaaa call :do_test call :msg "file with multiple alternate data streams, with hard link" echo 1 > file echo a > file:a echo aa > file:aa echo aaa > file:aaa echo aaaa > file:aaaa mklink /h link file > nul call :do_test call :msg "files with multiple alternate data streams, some identical, with hard link" echo 1 > file echo 5 > file2 echo 1 > file:1 echo 1 > file:1again echo aaa > file:aaa echo 5 > file:5 mklink /h link file > nul echo aaa > file2:aaa call :do_test call :msg "file with empty alternate data stream" echo 1 > file type nul > file:ads call :do_test call :msg "directory with empty alternate data stream" md subdir type nul > subdir:ads call :do_test call :msg "root directory with alternate data stream" echo 1 > ..\in.dir:ads call :do_test call :msg "root directory with empty alternate data stream" type nul > ..\in.dir:ads call :do_test call :msg "subdirectory with alternate data streams" md subdir echo 1 > subdir:1 echo 2 > subdir:2 echo 2 > subdir:2again call :do_test call :msg "subdirectories and files with alternate data streams" md subdir echo hello > hello echo hello > subdir:hello echo hello > subdir:helloagain echo hello > helloagain mklink /h hellolink hello > nul echo 1 > helloagain:1 echo 8 > helloagain:8 echo 1 > 1 type nul > helloagain:dummy call :do_test call :msg "symbolic link and hard link, to file with alternate data streams" echo 1 > 1 echo test > .\1:test mklink symlink 1 > nul mklink /h hardlink 1 > nul call :do_test call :msg "compressed file with alternate data streams" echo 1 > 1 echo 1 > .\1:1 echo 2 > .\1:2 compact /C 1 > nul call :do_test call :msg "hidden file" echo 1 > hidden attrib +h hidden call :do_test call :msg "hidden system file" echo 1 > file attrib +h +s file call :do_test call :msg "hidden, readonly, system file" echo 1 > file attrib +h +r +s file call :do_test call :msg "hidden directory" md subdir attrib +h subdir call :do_test call :msg "hidden system directory" md subdir attrib +h +s subdir call :do_test call :msg "hidden, readonly, system directory" md subdir attrib +h +r +s subdir call :do_test call :msg "readonly directory with named data stream" md subdir echo foo > subdir:ads attrib +r subdir call :do_test call :msg "encrypted file" echo "hello" > encrypted cipher /e encrypted > nul call :do_test call :msg "identical encrypted files" echo "hello" > encrypted1 echo "hello" > encrypted2 cipher /e encrypted1 > nul cipher /e encrypted2 > nul call :do_test call :msg "encrypted directory" md subdir cipher /e subdir > nul call :do_test call :msg "encrypted directory with encrypted file in it" md subdir echo 1 > subdir\1 cipher /e subdir > nul cipher /e subdir\1 > nul call :do_test call :msg "encrypted directory with unencrypted file in it" md subdir echo 1 > subdir\1 cipher /e subdir > nul cipher /d subdir\1 > nul call :do_test call :msg "encrypted root directory" cd .. cipher /e in.dir > nul cd in.dir echo "hello" > encrypted call :do_test call :msg "unencrypted file in encrypted directory in compressed directory" md 1 md 1\2 compact /c 1 > nul cipher /e 1\2 > nul echo hello > 1\2\file cipher /d 1\2\file > nul call :do_test call :msg "encrypted directory with alternate data streams" md subdir cipher /e subdir > nul echo ads1 > subdir:ads1 echo ads2 > subdir:ads2 call :do_test call :msg "hardlinked, encrypted file with alternate data streams" echo hello > file echo hello > file:ads cipher /e file > nul mklink /h link file > nul call :do_test REM Note: since object IDs must be unique per filesystem, we can't expect them REM to preserved using our testing scheme. Therefore, win32-tree-cmp doesn't REM compare them, and the below tests really just ensure the object ID code is REM run to some extent. call :msg "file with object ID" echo hello > file fsutil objectid create file > nul call :do_test call :msg "directory with object ID" md subdir fsutil objectid set f67394c12b17608e1d050d181ba8ffd2 7df80cbdf620f4c82c79b9e6799147b6 97621aff72915ade05abb96b15dea1a3 e0bda4caa9e33cfd461c92c16be9713d subdir call :do_test call :msg "sparse files" fsutil file createnew sparse 1000000 > nul fsutil sparse setflag sparse fsutil sparse setrange sparse 0 1000000 fsutil file createnew mostly_sparse 1000000 > nul fsutil sparse setflag mostly_sparse fsutil sparse setrange mostly_sparse 0 1000000 echo hello >> mostly_sparse type sparse >> mostly_sparse fsutil sparse setrange mostly_sparse 1000100 2000000 call :do_test call :msg "sparse and compressed files" fsutil file createnew sparse 1000000 > nul fsutil sparse setflag sparse fsutil sparse setrange sparse 0 1000000 compact /c sparse > nul fsutil file createnew mostly_sparse 1000000 > nul fsutil sparse setflag mostly_sparse fsutil sparse setrange mostly_sparse 0 1000000 echo hello >> mostly_sparse type sparse >> mostly_sparse fsutil sparse setrange mostly_sparse 1000100 2000000 compact /c mostly_sparse > nul type nul > compressed_first compact /c compressed_first > nul type sparse >> compressed_first fsutil sparse setflag compressed_first fsutil sparse setrange compressed_first 0 500000 call :do_test :rpfix_tests echo Testing rpfix junction md subdir echo 1 > subdir\file mklink /j junction subdir > nul cd .. %WIMLIB_IMAGEX% capture in.dir test.wim > nul rd /s /q in.dir %WIMLIB_IMAGEX% apply test.wim out.dir > nul echo 1 > tmp1 type out.dir\junction\file > tmp2 fc tmp1 tmp2 > nul if %errorlevel% neq 0 goto :fail rd /s /q out.dir del tmp1 tmp2 md in.dir cd in.dir echo Testing rpfix relative echo 1 > file mklink relink file > nul cd .. %WIMLIB_IMAGEX% capture in.dir test.wim > nul %WIMLIB_IMAGEX% apply test.wim out.dir > nul type out.dir\relink > out.dir\tmp if %errorlevel% neq 0 goto :fail fc in.dir\file out.dir\tmp > nul if %errorlevel% neq 0 goto :fail rd /s /q in.dir out.dir md in.dir cd in.dir REM REM END OF TESTS REM cd .. del test.wim rd /s /q in.dir exit /b 0 :do_test cd .. %WIMLIB_IMAGEX% capture in.dir test.wim --norpfix > NUL if %errorlevel% neq 0 goto :fail %WIMLIB_IMAGEX% apply test.wim out.dir > NUL if %errorlevel% neq 0 goto :fail %WIN32_TREE_CMP% in.dir out.dir if %errorlevel% neq 0 goto :fail REM apply a second time so we test the case where the files already exist %WIMLIB_IMAGEX% apply test.wim out.dir > NUL if %errorlevel% neq 0 goto :fail %WIN32_TREE_CMP% in.dir out.dir if %errorlevel% neq 0 goto :fail REM Fun fact: Microsoft's WIMGAPI has bugs that make it fail some of our tests. REM Even the Windows 8.1 version has incorrect behavior with empty files with REM multiple links, or files with named data streams and multiple links. rd /S /Q out.dir md out.dir REM dism /capture-image /capturedir:in.dir /imagefile:test.wim /name:"test" /norpfix > nul REM if %errorlevel% neq 0 goto :fail dism /apply-image /imagefile:test.wim /index:1 /applydir:out.dir > nul if %errorlevel% neq 0 goto :fail %WIN32_TREE_CMP% in.dir out.dir rd /S /Q in.dir out.dir md in.dir cd in.dir goto :eof :msg echo Testing capture and apply of %~1 goto :eof :fail echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ echo TEST FAILED!!!!!!! echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ exit %errorlevel%