Add support for capturing/applying object IDs
[wimlib] / tests / win32-test-imagex-capture_and_apply.bat
1 @echo off\r
2 \r
3 REM\r
4 REM win32-test-imagex-capture_and_apply.bat\r
5 REM\r
6 REM Run some tests on the Windows version of wimlib-imagex.\r
7 REM\r
8 REM This must be run on Windows Vista or later in a clean directory, with\r
9 REM Administrator privileges.  wimlib-imagex and win32-tree-cmp must be\r
10 REM executable using the paths set below.\r
11 \r
12 setlocal EnableDelayedExpansion\r
13 set WIMLIB_IMAGEX=wimlib-imagex\r
14 set WIN32_TREE_CMP=win32-tree-cmp\r
15 set SET_REPARSE_POINT=set_reparse_point\r
16 \r
17 if exist in.dir rd /S /Q in.dir\r
18 if exist out.dir rd /S /Q out.dir\r
19 md in.dir\r
20 cd in.dir\r
21 \r
22 REM\r
23 REM BEGIN TESTS\r
24 REM\r
25 \r
26 call :msg "empty directory"\r
27 call :do_test\r
28 if %errorlevel% neq 0 goto :fail\r
29 \r
30 call :msg "single file"\r
31 echo 1 > file\r
32 call :do_test\r
33 if %errorlevel% neq 0 goto :fail\r
34 \r
35 call :msg "different files"\r
36 echo 1 > file\r
37 echo 2 > anotherfile\r
38 call :do_test\r
39 if %errorlevel% neq 0 goto :fail\r
40 \r
41 call :msg "identical files"\r
42 echo 1 > file\r
43 echo 1 > identicalfile\r
44 call :do_test\r
45 if %errorlevel% neq 0 goto :fail\r
46 \r
47 call :msg "hard linked file"\r
48 echo 1 > file\r
49 mklink /h link file > nul\r
50 call :do_test\r
51 if %errorlevel% neq 0 goto :fail\r
52 \r
53 call :msg "hard linked file, with other identical files"\r
54 echo 1 > file\r
55 mklink /h link file > nul\r
56 echo 1 > identicalfile\r
57 call :do_test\r
58 if %errorlevel% neq 0 goto :fail\r
59 \r
60 call :msg "empty file"\r
61 type nul > emptyfile\r
62 call :do_test\r
63 if %errorlevel% neq 0 goto :fail\r
64 \r
65 call :msg "hard linked empty file"\r
66 type nul > file\r
67 mklink /h link file > nul\r
68 call :do_test\r
69 if %errorlevel% neq 0 goto :fail\r
70 \r
71 call :msg "various hard linked, identical, different, and empty files"\r
72 echo 1 > file\r
73 echo 5 > file\r
74 mklink /h link1 file > nul\r
75 mklink /h link2 file > nul\r
76 type nul > emptyfile\r
77 type nul > emptyfile2\r
78 mklink /h emptyfilelink emptyfile > nul\r
79 echo 5 > identicalfile\r
80 echo 1 > 1file\r
81 mklink /h 1filelink 1file > nul\r
82 call :do_test\r
83 if %errorlevel% neq 0 goto :fail\r
84 \r
85 call :msg "multiple subdirectories, some empty, some not"\r
86 md subdir1\r
87 md subdir2\r
88 md subdir3\r
89 echo 1 > subdir1\1\r
90 echo 5 > subdir1\5\r
91 mklink /h link subdir1\1 > nul\r
92 md subdir2\subdir2subdir\r
93 type nul > subdir2\emptyfile\r
94 call :do_test\r
95 if %errorlevel% neq 0 goto :fail\r
96 \r
97 call :msg "file with custom security descriptor"\r
98 echo hello > file\r
99 icacls file /deny Administrator:F > nul\r
100 call :do_test\r
101 if %errorlevel% neq 0 goto :fail\r
102 \r
103 call :msg "directory with custom security descriptor (inheritence enabled)"\r
104 md subdir\r
105 icacls subdir /inheritance:e > nul\r
106 call :do_test\r
107 if %errorlevel% neq 0 goto :fail\r
108 \r
109 call :msg "directory with custom security descriptor (inheritence disabled)"\r
110 md subdir\r
111 icacls subdir /inheritance:d > nul\r
112 call :do_test\r
113 if %errorlevel% neq 0 goto :fail\r
114 \r
115 REM            win32-tree-cmp can't handle this case.\r
116 REM\r
117 REM call :msg "file with custom security descriptor (all inherited ACEs removed)"\r
118 REM echo hello > file\r
119 REM icacls file /inheritance:r > nul\r
120 REM call :do_test\r
121 REM if %errorlevel% neq 0 goto :fail\r
122 \r
123 call :msg "file with custom integrity level"\r
124 echo hello > file\r
125 icacls file /setintegritylevel H > nul\r
126 call :do_test\r
127 if %errorlevel% neq 0 goto :fail\r
128 \r
129 call :msg "relative symlink"\r
130 mklink relink dest > nul\r
131 call :do_test\r
132 if %errorlevel% neq 0 goto :fail\r
133 \r
134 call :msg "absolute symlink, with drive letter"\r
135 mklink abslink C:\absolute\target > nul\r
136 call :do_test\r
137 if %errorlevel% neq 0 goto :fail\r
138 \r
139 call :msg "absolute symlink, without drive letter"\r
140 mklink abslink \absolute\target > nul\r
141 call :do_test\r
142 if %errorlevel% neq 0 goto :fail\r
143 \r
144 call :msg "relative symlink, with file target"\r
145 echo 1 > 1\r
146 mklink relink 1 > nul\r
147 call :do_test\r
148 if %errorlevel% neq 0 goto :fail\r
149 \r
150 call :msg "relative symlink, with directory target"\r
151 md subdir\r
152 mklink reldlink subdir > nul\r
153 call :do_test\r
154 if %errorlevel% neq 0 goto :fail\r
155 \r
156 call :msg "junction"\r
157 md subdir\r
158 mklink /j junction subdir > nul\r
159 call :do_test\r
160 if %errorlevel% neq 0 goto :fail\r
161 \r
162 call :msg "symlinks, junctions, files, subdirectories, etc."\r
163 echo 1 > 1\r
164 mklink relink 1 > nul\r
165 mklink rellinklink relink > nul\r
166 mklink /j junction . > nul\r
167 md subdir\r
168 mklink /h subdir\hardlink 1 > nul\r
169 echo "hello world!!!!" > hello\r
170 mklink subdir\hello hello > nul\r
171 mklink abslink C:\Users > nul\r
172 md subdir2\r
173 type nul > emptyfile\r
174 type nul > subdir2\emptyfile\r
175 md subdir2\s\r
176 md subdir2\s\s\r
177 md subdir2\s\s\s\r
178 echo "hello world!!!!" > subdir2\otherfile\r
179 call :do_test\r
180 if %errorlevel% neq 0 goto :fail\r
181 \r
182 call :msg "reparse point that is neither a symlink nor a junction"\r
183 type nul > file\r
184 %SET_REPARSE_POINT% file\r
185 call :do_test\r
186 if %errorlevel% neq 0 goto :fail\r
187 \r
188 call :msg "reparse point with named data streams"\r
189 type nul > file\r
190 echo 11 > file:a\r
191 echo 1 > file:aa\r
192 %SET_REPARSE_POINT% file\r
193 call :do_test\r
194 if %errorlevel% neq 0 goto :fail\r
195 \r
196 call :msg "reparse point with unnamed data stream"\r
197 echo "test" > file\r
198 %SET_REPARSE_POINT% file\r
199 call :do_test\r
200 if %errorlevel% neq 0 goto :fail\r
201 \r
202 call :msg "reparse point with unnamed data stream and named data streams"\r
203 echo "test" > file\r
204 echo 11 > file:a\r
205 echo 1 > file:aa\r
206 %SET_REPARSE_POINT% file\r
207 call :do_test\r
208 if %errorlevel% neq 0 goto :fail\r
209 \r
210 call :msg "empty reparse point"\r
211 type nul > file\r
212 %SET_REPARSE_POINT% file 0\r
213 call :do_test\r
214 if %errorlevel% neq 0 goto :fail\r
215 \r
216 call :msg "empty reparse point with unnamed data stream"\r
217 echo hello > file\r
218 %SET_REPARSE_POINT% file 0\r
219 call :do_test\r
220 if %errorlevel% neq 0 goto :fail\r
221 \r
222 call :msg "empty reparse point with unnamed data stream and named data streams"\r
223 echo hello > file\r
224 echo hello > file:ads1\r
225 type nul > file:ads2\r
226 %SET_REPARSE_POINT% file 0\r
227 call :do_test\r
228 if %errorlevel% neq 0 goto :fail\r
229 \r
230 call :msg "maximum length reparse point"\r
231 type nul > file\r
232 %SET_REPARSE_POINT% file 16376\r
233 call :do_test\r
234 if %errorlevel% neq 0 goto :fail\r
235 \r
236 call :msg "directory reparse point that is neither a symlink nor a junction"\r
237 md subdir\r
238 %SET_REPARSE_POINT% subdir\r
239 call :do_test\r
240 if %errorlevel% neq 0 goto :fail\r
241 \r
242 call :msg "directory reparse point with named data streams"\r
243 md subdir\r
244 echo 11 > subdir:a\r
245 echo 1 > subdir:aa\r
246 %SET_REPARSE_POINT% subdir\r
247 call :do_test\r
248 if %errorlevel% neq 0 goto :fail\r
249 \r
250 call :msg "compressed file"\r
251 echo "test" > test\r
252 compact /C test > nul\r
253 call :do_test\r
254 if %errorlevel% neq 0 goto :fail\r
255 \r
256 call :msg "compressed directory"\r
257 md subdir\r
258 compact /C subdir > nul\r
259 call :do_test\r
260 if %errorlevel% neq 0 goto :fail\r
261 \r
262 call :msg "compressed directory with files in it"\r
263 md subdir\r
264 compact /C subdir > nul\r
265 echo 1 > subdir\file1\r
266 echo 2 > subdir\file2\r
267 echo 1 > subdir\file1\r
268 md subdir\subsubdir\r
269 mklink /h subdir\hardlink subdir\file1 > nul\r
270 mklink /j subdir\j subdir\subsubdir > nul\r
271 call :do_test\r
272 if %errorlevel% neq 0 goto :fail\r
273 \r
274 call :msg "compressed directory with some uncompressed files in it"\r
275 md subdir\r
276 compact /C subdir > nul\r
277 echo 1 > subdir\1\r
278 echo 5 > subdir\5\r
279 compact /U subdir\1 > nul\r
280 call :do_test\r
281 if %errorlevel% neq 0 goto :fail\r
282 \r
283 call :msg "file with alternate data stream"\r
284 echo 1 > file\r
285 echo 5 > file:ads\r
286 call :do_test\r
287 if %errorlevel% neq 0 goto :fail\r
288 \r
289 call :msg "file with multiple alternate data streams"\r
290 echo 1 > file\r
291 echo a > file:a\r
292 echo aa > file:aa\r
293 echo aaa > file:aaa\r
294 echo aaaa > file:aaaa\r
295 call :do_test\r
296 if %errorlevel% neq 0 goto :fail\r
297 \r
298 call :msg "file with multiple alternate data streams, with hard link"\r
299 echo 1 > file\r
300 echo a > file:a\r
301 echo aa > file:aa\r
302 echo aaa > file:aaa\r
303 echo aaaa > file:aaaa\r
304 mklink /h link file > nul\r
305 call :do_test\r
306 if %errorlevel% neq 0 goto :fail\r
307 \r
308 call :msg "files with multiple alternate data streams, some identical, with hard link"\r
309 echo 1 > file\r
310 echo 5 > file2\r
311 echo 1 > file:1\r
312 echo 1 > file:1again\r
313 echo aaa > file:aaa\r
314 echo 5 > file:5\r
315 mklink /h link file > nul\r
316 echo aaa > file2:aaa\r
317 call :do_test\r
318 if %errorlevel% neq 0 goto :fail\r
319 \r
320 call :msg "file with empty alternate data stream"\r
321 echo 1 > file\r
322 type nul > file:ads\r
323 call :do_test\r
324 if %errorlevel% neq 0 goto :fail\r
325 \r
326 call :msg "directory with empty alternate data stream"\r
327 md subdir\r
328 type nul > subdir:ads\r
329 call :do_test\r
330 if %errorlevel% neq 0 goto :fail\r
331 \r
332 call :msg "root directory with alternate data stream"\r
333 echo 1 > ..\in.dir:ads\r
334 call :do_test\r
335 if %errorlevel% neq 0 goto :fail\r
336 \r
337 call :msg "root directory with empty alternate data stream"\r
338 type nul > ..\in.dir:ads\r
339 call :do_test\r
340 if %errorlevel% neq 0 goto :fail\r
341 \r
342 call :msg "subdirectory with alternate data streams"\r
343 md subdir\r
344 echo 1 > subdir:1\r
345 echo 2 > subdir:2\r
346 echo 2 > subdir:2again\r
347 call :do_test\r
348 if %errorlevel% neq 0 goto :fail\r
349 \r
350 call :msg "subdirectories and files with alternate data streams"\r
351 md subdir\r
352 echo hello > hello\r
353 echo hello > subdir:hello\r
354 echo hello > subdir:helloagain\r
355 echo hello > helloagain\r
356 mklink /h hellolink hello > nul\r
357 echo 1 > helloagain:1\r
358 echo 8 > helloagain:8\r
359 echo 1 > 1\r
360 type nul > helloagain:dummy\r
361 call :do_test\r
362 if %errorlevel% neq 0 goto :fail\r
363 \r
364 call :msg "symbolic link and hard link, to file with alternate data streams"\r
365 echo 1 > 1\r
366 echo test > .\1:test\r
367 mklink symlink 1 > nul\r
368 mklink /h hardlink 1 > nul\r
369 call :do_test\r
370 if %errorlevel% neq 0 goto :fail\r
371 \r
372 call :msg "compressed file with alternate data streams"\r
373 echo 1 > 1\r
374 echo 1 > .\1:1\r
375 echo 2 > .\1:2\r
376 compact /C 1 > nul\r
377 call :do_test\r
378 if %errorlevel% neq 0 goto :fail\r
379 \r
380 call :msg "hidden file"\r
381 echo 1 > hidden\r
382 attrib +h hidden\r
383 call :do_test\r
384 if %errorlevel% neq 0 goto :fail\r
385 \r
386 call :msg "hidden system file"\r
387 echo 1 > file\r
388 attrib +h +s file\r
389 call :do_test\r
390 if %errorlevel% neq 0 goto :fail\r
391 \r
392 call :msg "hidden, readonly, system file"\r
393 echo 1 > file\r
394 attrib +h +r +s file\r
395 call :do_test\r
396 if %errorlevel% neq 0 goto :fail\r
397 \r
398 call :msg "hidden directory"\r
399 md subdir\r
400 attrib +h subdir\r
401 call :do_test\r
402 if %errorlevel% neq 0 goto :fail\r
403 \r
404 call :msg "hidden system directory"\r
405 md subdir\r
406 attrib +h +s subdir\r
407 call :do_test\r
408 if %errorlevel% neq 0 goto :fail\r
409 \r
410 call :msg "hidden, readonly, system directory"\r
411 md subdir\r
412 attrib +h +r +s subdir\r
413 call :do_test\r
414 if %errorlevel% neq 0 goto :fail\r
415 \r
416 call :msg "readonly directory with named data stream"\r
417 md subdir\r
418 echo foo > subdir:ads\r
419 attrib +r subdir\r
420 call :do_test\r
421 if %errorlevel% neq 0 goto :fail\r
422 \r
423 call :msg "encrypted file"\r
424 echo "hello" > encrypted\r
425 cipher /e encrypted > nul\r
426 call :do_test\r
427 if %errorlevel% neq 0 goto :fail\r
428 \r
429 call :msg "identical encrypted files"\r
430 echo "hello" > encrypted1\r
431 echo "hello" > encrypted2\r
432 cipher /e encrypted1 > nul\r
433 cipher /e encrypted2 > nul\r
434 call :do_test\r
435 if %errorlevel% neq 0 goto :fail\r
436 \r
437 call :msg "encrypted directory"\r
438 md subdir\r
439 cipher /e subdir > nul\r
440 call :do_test\r
441 if %errorlevel% neq 0 goto :fail\r
442 \r
443 call :msg "encrypted directory with encrypted file in it"\r
444 md subdir\r
445 echo 1 > subdir\1\r
446 cipher /e subdir > nul\r
447 cipher /e subdir\1 > nul\r
448 call :do_test\r
449 if %errorlevel% neq 0 goto :fail\r
450 \r
451 call :msg "encrypted directory with unencrypted file in it"\r
452 md subdir\r
453 echo 1 > subdir\1\r
454 cipher /e subdir > nul\r
455 cipher /d subdir\1 > nul\r
456 call :do_test\r
457 if %errorlevel% neq 0 goto :fail\r
458 \r
459 call :msg "encrypted root directory"\r
460 cd ..\r
461 cipher /e in.dir > nul\r
462 cd in.dir\r
463 echo "hello" > encrypted\r
464 call :do_test\r
465 if %errorlevel% neq 0 goto :fail\r
466 \r
467 call :msg "unencrypted file in encrypted directory in compressed directory"\r
468 md 1\r
469 md 1\2\r
470 compact /c 1 > nul\r
471 cipher /e 1\2 > nul\r
472 echo hello > 1\2\file\r
473 cipher /d 1\2\file > nul\r
474 call :do_test\r
475 if %errorlevel% neq 0 goto :fail\r
476 \r
477 call :msg "encrypted directory with alternate data streams"\r
478 md subdir\r
479 cipher /e subdir > nul\r
480 echo ads1 > subdir:ads1\r
481 echo ads2 > subdir:ads2\r
482 call :do_test\r
483 if %errorlevel% neq 0 goto :fail\r
484 \r
485 call :msg "hardlinked, encrypted file with alternate data streams"\r
486 echo hello > file\r
487 echo hello > file:ads\r
488 cipher /e file > nul\r
489 mklink /h link file > nul\r
490 call :do_test\r
491 if %errorlevel% neq 0 goto :fail\r
492 \r
493 REM Note: since object IDs must be unique per filesystem, we can't expect them\r
494 REM to preserved using our testing scheme.  Therefore, win32-tree-cmp doesn't\r
495 REM compare them, and the below tests really just ensure the object ID code is\r
496 REM run to some extent.\r
497 \r
498 call :msg "file with object ID"\r
499 echo hello > file\r
500 fsutil objectid create file > nul\r
501 call :do_test\r
502 if %errorlevel% neq 0 goto :fail\r
503 \r
504 call :msg "directory with object ID"\r
505 md subdir\r
506 fsutil objectid set f67394c12b17608e1d050d181ba8ffd2 7df80cbdf620f4c82c79b9e6799147b6 97621aff72915ade05abb96b15dea1a3 e0bda4caa9e33cfd461c92c16be9713d subdir\r
507 call :do_test\r
508 if %errorlevel% neq 0 goto :fail\r
509 \r
510 :rpfix_tests\r
511 \r
512 echo Testing rpfix junction\r
513 md subdir\r
514 echo 1 > subdir\file\r
515 mklink /j junction subdir > nul\r
516 cd ..\r
517 %WIMLIB_IMAGEX% capture in.dir test.wim > nul\r
518 rd /s /q in.dir\r
519 %WIMLIB_IMAGEX% apply test.wim out.dir > nul\r
520 echo 1 > tmp1\r
521 type out.dir\junction\file > tmp2\r
522 fc tmp1 tmp2 > nul\r
523 if %errorlevel% neq 0 goto :fail\r
524 rd /s /q out.dir\r
525 del tmp1 tmp2\r
526 md in.dir\r
527 cd in.dir\r
528 \r
529 echo Testing rpfix relative\r
530 echo 1 > file\r
531 mklink relink file > nul\r
532 cd ..\r
533 %WIMLIB_IMAGEX% capture in.dir test.wim > nul\r
534 %WIMLIB_IMAGEX% apply test.wim out.dir > nul\r
535 type out.dir\relink > out.dir\tmp\r
536 if %errorlevel% neq 0 goto :fail\r
537 fc in.dir\file out.dir\tmp > nul\r
538 if %errorlevel% neq 0 goto :fail\r
539 rd /s /q in.dir out.dir\r
540 md in.dir\r
541 cd in.dir\r
542 \r
543 REM\r
544 REM END OF TESTS\r
545 REM\r
546 \r
547 cd ..\r
548 del test.wim\r
549 rd /s /q in.dir\r
550 exit /b 0\r
551 \r
552 :do_test\r
553 cd ..\r
554 %WIMLIB_IMAGEX% capture in.dir test.wim --norpfix > NUL\r
555 if %errorlevel% neq 0 goto :fail\r
556 %WIMLIB_IMAGEX% apply test.wim out.dir > NUL\r
557 if %errorlevel% neq 0 goto :fail\r
558 %WIN32_TREE_CMP% in.dir out.dir\r
559 if %errorlevel% neq 0 goto :fail\r
560 \r
561 REM  apply a second time so we test the case where the files already exist\r
562 %WIMLIB_IMAGEX% apply test.wim out.dir > NUL\r
563 if %errorlevel% neq 0 goto :fail\r
564 %WIN32_TREE_CMP% in.dir out.dir\r
565 if %errorlevel% neq 0 goto :fail\r
566 \r
567 REM Fun fact: Microsoft's WIMGAPI has bugs that make it fail some of our tests.\r
568 REM Even the Windows 8.1 version has incorrect behavior with empty files with\r
569 REM multiple links, or files with named data streams and multiple links.\r
570 rd /S /Q out.dir\r
571 md out.dir\r
572 REM dism /capture-image /capturedir:in.dir /imagefile:test.wim /name:"test" /norpfix > nul\r
573 REM if %errorlevel% neq 0 goto :fail\r
574 dism /apply-image /imagefile:test.wim /index:1 /applydir:out.dir > nul\r
575 if %errorlevel% neq 0 goto :fail\r
576 %WIN32_TREE_CMP% in.dir out.dir\r
577 \r
578 rd /S /Q in.dir out.dir\r
579 md in.dir\r
580 cd in.dir\r
581 goto :eof\r
582 \r
583 :msg\r
584 echo Testing capture and apply of %~1\r
585 goto :eof\r
586 \r
587 :fail\r
588 echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
589 echo            TEST FAILED!!!!!!!\r
590 echo @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
591 exit /b %errorlevel%\r