Add Windows tests for empty and max length reparse points
authorEric Biggers <ebiggers3@gmail.com>
Sat, 27 Jun 2015 22:55:33 +0000 (17:55 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sat, 27 Jun 2015 23:03:44 +0000 (18:03 -0500)
tests/set_reparse_point.c
tests/win32-test-imagex-capture_and_apply.bat

index 73428f06aed6730e79889edc86ea38f7e05eec74..d22cd08ac13680d74232e6a6e137298117947e03 100644 (file)
@@ -1,59 +1,65 @@
 #include <inttypes.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <windows.h>
 
-static wchar_t *
-win32_error_string(DWORD err_code)
+static const wchar_t *
+win32_error_string(DWORD err)
 {
        static wchar_t buf[1024];
        buf[0] = L'\0';
-       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err_code, 0,
-                     buf, 1024, NULL);
+       FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, 1024, NULL);
        return buf;
 }
 
 static void
-fail(const char *func, DWORD code)
+fail(const char *func)
 {
+       DWORD err = GetLastError();
        fprintf(stderr, "%s (err 0x%08x: %ls)\n", func,
-               (unsigned int)code, win32_error_string(code));
+               (uint32_t)err, win32_error_string(err));
        exit(1);
 }
 
 int
 wmain(int argc, wchar_t **argv)
 {
-       if (argc != 2) {
-               fprintf(stderr, "Usage: %ls FILE\n", argv[0]);
-               return 2;
+       uint16_t rpdatalen = 80;
+
+       if (argc < 2 || argc > 3) {
+               fprintf(stderr, "Usage: %ls FILE [rpdatalen]\n", argv[0]);
+               return 1;
        }
 
+       if (argc == 3)
+               rpdatalen = wcstol(argv[2], NULL, 10);
+
        HANDLE h = CreateFile(argv[1],
                              GENERIC_WRITE,
                              FILE_SHARE_VALID_FLAGS,
                              NULL,
                              OPEN_EXISTING,
-                             FILE_FLAG_BACKUP_SEMANTICS,
+                             FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
                              NULL);
        if (h == INVALID_HANDLE_VALUE)
-               fail("CreateFile", GetLastError());
+               fail("CreateFile");
 
-       uint8_t in[128];
+       uint8_t in[8 + rpdatalen];
        uint8_t *p = in;
        *(uint32_t *)p = 0x80000000; /* rptag */
        p += 4;
-       *(uint16_t *)p = 80; /* rpdatalen */
+       *(uint16_t *)p = rpdatalen; /* rpdatalen */
        p += 2;
-       *(uint16_t *)p = 0; /* rpreserved */
+       *(uint16_t *)p = 0x1234; /* rpreserved */
        p += 2;
-       memset(p, 0, 80); /* rpdata */
-       p += 80;
+       memset(p, 0, rpdatalen); /* rpdata */
+       p += rpdatalen;
 
        DWORD bytes_returned;
 
        if (!DeviceIoControl(h, FSCTL_SET_REPARSE_POINT, in, p - in,
                             NULL, 0, &bytes_returned, NULL))
-               fail("DeviceIoControl", GetLastError());
+               fail("DeviceIoControl");
 
        CloseHandle(h);
 
index 8283ddd44a40b5fe3f71dc4dd3820962675b8c1c..8f573eceb62bd5ea4c7f8f7ca4b0692fa1ef816f 100644 (file)
@@ -207,6 +207,32 @@ echo 1 > file:aa
 call :do_test\r
 if %errorlevel% neq 0 goto :fail\r
 \r
+call :msg "empty reparse point"\r
+type nul > file\r
+%SET_REPARSE_POINT% file 0\r
+call :do_test\r
+if %errorlevel% neq 0 goto :fail\r
+\r
+call :msg "empty reparse point with unnamed data stream"\r
+echo hello > file\r
+%SET_REPARSE_POINT% file 0\r
+call :do_test\r
+if %errorlevel% neq 0 goto :fail\r
+\r
+call :msg "empty reparse point with unnamed data stream and named data streams"\r
+echo hello > file\r
+echo hello > file:ads1\r
+type nul > file:ads2\r
+%SET_REPARSE_POINT% file 0\r
+call :do_test\r
+if %errorlevel% neq 0 goto :fail\r
+\r
+call :msg "maximum length reparse point"\r
+type nul > file\r
+%SET_REPARSE_POINT% file 16376\r
+call :do_test\r
+if %errorlevel% neq 0 goto :fail\r
+\r
 call :msg "directory reparse point that is neither a symlink nor a junction"\r
 md subdir\r
 %SET_REPARSE_POINT% subdir\r