Add Windows tests for empty and max length reparse points
[wimlib] / tests / set_reparse_point.c
1 #include <inttypes.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <windows.h>
5
6 static const wchar_t *
7 win32_error_string(DWORD err)
8 {
9         static wchar_t buf[1024];
10         buf[0] = L'\0';
11         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buf, 1024, NULL);
12         return buf;
13 }
14
15 static void
16 fail(const char *func)
17 {
18         DWORD err = GetLastError();
19         fprintf(stderr, "%s (err 0x%08x: %ls)\n", func,
20                 (uint32_t)err, win32_error_string(err));
21         exit(1);
22 }
23
24 int
25 wmain(int argc, wchar_t **argv)
26 {
27         uint16_t rpdatalen = 80;
28
29         if (argc < 2 || argc > 3) {
30                 fprintf(stderr, "Usage: %ls FILE [rpdatalen]\n", argv[0]);
31                 return 1;
32         }
33
34         if (argc == 3)
35                 rpdatalen = wcstol(argv[2], NULL, 10);
36
37         HANDLE h = CreateFile(argv[1],
38                               GENERIC_WRITE,
39                               FILE_SHARE_VALID_FLAGS,
40                               NULL,
41                               OPEN_EXISTING,
42                               FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT,
43                               NULL);
44         if (h == INVALID_HANDLE_VALUE)
45                 fail("CreateFile");
46
47         uint8_t in[8 + rpdatalen];
48         uint8_t *p = in;
49         *(uint32_t *)p = 0x80000000; /* rptag */
50         p += 4;
51         *(uint16_t *)p = rpdatalen; /* rpdatalen */
52         p += 2;
53         *(uint16_t *)p = 0x1234; /* rpreserved */
54         p += 2;
55         memset(p, 0, rpdatalen); /* rpdata */
56         p += rpdatalen;
57
58         DWORD bytes_returned;
59
60         if (!DeviceIoControl(h, FSCTL_SET_REPARSE_POINT, in, p - in,
61                              NULL, 0, &bytes_returned, NULL))
62                 fail("DeviceIoControl");
63
64         CloseHandle(h);
65
66         return 0;
67 }