1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         LGPLv2.1+ - See COPYING.LIB in the top level directory
4  * PURPOSE:         Test for FsRtlDissectName/FsRtlDissectDbcs
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <kmt_test.h>
9 
10 static struct
11 {
12     PCSTR Name;
13     INT Offset1;
14     INT Offset2;
15     INT Length1;
16     INT Length2;
17 } Tests[] =
18 {
19     { NULL,         -1, -1       },
20     { "",           -1, -1       },
21     { "a",           0, -1, 1, 1 },
22     { "a\\b",        0,  2, 1, 1 },
23     { "a\\",         0,  2, 1, 0 },
24     { "\\b",         1, -1, 1    },
25     { "\\",          1, -1, 0    },
26     { "a\\b\\c",     0,  2, 1, 3 },
27     { "\\a\\b\\c",   1,  3, 1, 3 },
28     /* Forward slashes are not separators */
29     { "/",           0, -1, 1    },
30     { "/a",          0, -1, 2    },
31     { "/a/b",        0, -1, 4    },
32     /* Normal parsing cycle */
33     { "Good Morning!\\Good Evening!\\Good Night",   0,  14, 13, 24 },
34     { "Good Evening!\\Good Night",                  0,  14, 13, 10 },
35     { "Good Night",                                 0,  -1, 10 },
36     /* Double backslashes */
37     { "\\\\",        1,  2, 0, 0 },
38     { "a\\\\",       0,  2, 1, 1 },
39     { "\\\\b",       1,  2, 0, 1 },
40     { "a\\\\b",      0,  2, 1, 2 },
41     /* Even more backslashes */
42     { "\\\\\\",      1,  2, 0, 1 },
43     { "a\\\\\\",     0,  2, 1, 2 },
44     { "\\\\\\b",     1,  2, 0, 2 },
45     { "a\\\\\\b",    0,  2, 1, 3 },
46     { "a\\\\\\\\b",  0,  2, 1, 4 },
47 };
48 
49 START_TEST(FsRtlDissect)
50 {
51     NTSTATUS Status;
52     ANSI_STRING NameA;
53     ANSI_STRING FirstA;
54     ANSI_STRING RemainingA;
55     UNICODE_STRING NameU;
56     UNICODE_STRING FirstU;
57     UNICODE_STRING RemainingU;
58     ULONG i;
59 
60     for (i = 0; i < RTL_NUMBER_OF(Tests); i++)
61     {
62         RtlInitAnsiString(&NameA, Tests[i].Name);
63         RtlFillMemory(&FirstA, sizeof(FirstA), 0x55);
64         RtlFillMemory(&RemainingA, sizeof(RemainingA), 0x55);
65         FsRtlDissectDbcs(NameA, &FirstA, &RemainingA);
66         if (Tests[i].Offset1 == -1)
67         {
68             ok(FirstA.Buffer == NULL, "[%s] First=%p, expected NULL\n", Tests[i].Name, FirstA.Buffer);
69             ok(FirstA.Length == 0, "[%s] FirstLen=%u, expected 0\n", Tests[i].Name, FirstA.Length);
70             ok(FirstA.MaximumLength == 0, "[%s] FirstMaxLen=%u, expected 0\n", Tests[i].Name, FirstA.MaximumLength);
71         }
72         else
73         {
74             ok(FirstA.Buffer == NameA.Buffer + Tests[i].Offset1, "[%s] First=%p, expected %p\n", Tests[i].Name, FirstA.Buffer, NameA.Buffer + Tests[i].Offset1);
75             ok(FirstA.Length == Tests[i].Length1, "[%s] FirstLen=%u, expected %d\n", Tests[i].Name, FirstA.Length, Tests[i].Length1);
76             ok(FirstA.MaximumLength == Tests[i].Length1, "[%s] FirstMaxLen=%u, expected %d\n", Tests[i].Name, FirstA.MaximumLength, Tests[i].Length1);
77         }
78         if (Tests[i].Offset2 == -1)
79         {
80             ok(RemainingA.Buffer == NULL, "[%s] Remaining=%p, expected NULL\n", Tests[i].Name, RemainingA.Buffer);
81             ok(RemainingA.Length == 0, "[%s] RemainingLen=%u, expected 0\n", Tests[i].Name, RemainingA.Length);
82             ok(RemainingA.MaximumLength == 0, "[%s] RemainingMaxLen=%u, expected 0\n", Tests[i].Name, RemainingA.MaximumLength);
83         }
84         else
85         {
86             ok(RemainingA.Buffer == NameA.Buffer + Tests[i].Offset2, "[%s] Remaining=%p, expected %p\n", Tests[i].Name, RemainingA.Buffer, NameA.Buffer + Tests[i].Offset2);
87             ok(RemainingA.Length == Tests[i].Length2, "[%s] RemainingLen=%u, expected %d\n", Tests[i].Name, RemainingA.Length, Tests[i].Length2);
88             ok(RemainingA.MaximumLength == Tests[i].Length2, "[%s] RemainingMaxLen=%u, expected %d\n", Tests[i].Name, RemainingA.MaximumLength, Tests[i].Length2);
89         }
90 
91         Status = RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
92         if (skip(NT_SUCCESS(Status), "Conversion failed with %lx\n", Status))
93             continue;
94         RtlFillMemory(&FirstU, sizeof(FirstU), 0x55);
95         RtlFillMemory(&RemainingU, sizeof(RemainingU), 0x55);
96         FsRtlDissectName(NameU, &FirstU, &RemainingU);
97         if (Tests[i].Offset1 == -1)
98         {
99             ok(FirstU.Buffer == NULL, "[%s] First=%p, expected NULL\n", Tests[i].Name, FirstU.Buffer);
100             ok(FirstU.Length == 0, "[%s] FirstLen=%u, expected 0\n", Tests[i].Name, FirstU.Length);
101             ok(FirstU.MaximumLength == 0, "[%s] FirstMaxLen=%u, expected 0\n", Tests[i].Name, FirstU.MaximumLength);
102         }
103         else
104         {
105             ok(FirstU.Buffer == NameU.Buffer + Tests[i].Offset1, "[%s] First=%p, expected %p\n", Tests[i].Name, FirstU.Buffer, NameU.Buffer + Tests[i].Offset1);
106             ok(FirstU.Length == Tests[i].Length1 * sizeof(WCHAR), "[%s] FirstLen=%u, expected %d\n", Tests[i].Name, FirstU.Length, Tests[i].Length1 * sizeof(WCHAR));
107             ok(FirstU.MaximumLength == Tests[i].Length1 * sizeof(WCHAR), "[%s] FirstMaxLen=%u, expected %d\n", Tests[i].Name, FirstU.MaximumLength, Tests[i].Length1 * sizeof(WCHAR));
108         }
109         if (Tests[i].Offset2 == -1)
110         {
111             ok(RemainingU.Buffer == NULL, "[%s] Remaining=%p, expected NULL\n", Tests[i].Name, RemainingU.Buffer);
112             ok(RemainingU.Length == 0, "[%s] RemainingLen=%u, expected 0\n", Tests[i].Name, RemainingU.Length);
113             ok(RemainingU.MaximumLength == 0, "[%s] RemainingMaxLen=%u, expected 0\n", Tests[i].Name, RemainingU.MaximumLength);
114         }
115         else
116         {
117             ok(RemainingU.Buffer == NameU.Buffer + Tests[i].Offset2, "[%s] Remaining=%p, expected %p\n", Tests[i].Name, RemainingU.Buffer, NameU.Buffer + Tests[i].Offset2);
118             ok(RemainingU.Length == Tests[i].Length2 * sizeof(WCHAR), "[%s] RemainingLen=%u, expected %d\n", Tests[i].Name, RemainingU.Length, Tests[i].Length2 * sizeof(WCHAR));
119             ok(RemainingU.MaximumLength == Tests[i].Length2 * sizeof(WCHAR), "[%s] RemainingMaxLen=%u, expected %d\n", Tests[i].Name, RemainingU.MaximumLength, Tests[i].Length2 * sizeof(WCHAR));
120         }
121         RtlFreeUnicodeString(&NameU);
122     }
123 }
124