1 /*
2 * PROJECT:         ReactOS kernel-mode tests
3 * LICENSE:         LGPLv2+ - See COPYING.LIB in the top level directory
4 * PURPOSE:         Kernel-Mode Test Suite FsRtl Test
5 * PROGRAMMER:      Ashuha Arseny, Moscow State Technical University
6 *                  Marina Volosnikova, Moscow State Technical University
7 *                  Denis Petkevich, Moscow State Technical University
8 */
9 
10 #include <kmt_test.h>
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 /*
16 Tested with the system kmtest
17 the following functions:
18 FsRtlInitializeTunnelCache
19 FsRtlDeleteTunnelCache
20 FsRtlAddToTunnelCache
21 FsRtlDeleteKeyFromTunnelCache
22 FsRtlFindInTunnelCache
23 */
24 
25 static PTUNNEL T;
26 static PTUNNEL Tb;
27 
28 #define BufSize 10000
29 
30 PUNICODE_STRING CopyUS(PUNICODE_STRING a)
31 {
32     PUNICODE_STRING b = (PUNICODE_STRING)ExAllocatePool(PagedPool,sizeof(UNICODE_STRING));
33     ok(b != NULL, "US is NULL after allocated memory\n");
34     b->Length = 0;
35     b->MaximumLength =a->MaximumLength;
36     if (b->MaximumLength)
37     {
38         b->Buffer = (PWSTR)ExAllocatePoolWithTag(PagedPool, b->MaximumLength, 1633);
39         ok(b->Buffer != NULL, "US->Buffer is NULL after allocated memory\n");
40         RtlCopyUnicodeString(b, a);
41     }
42     else
43     {
44         b->Buffer = NULL;
45     }
46     return b;
47 }
48 
49 void TestFsRtlInitializeTunnelCache()
50 {
51     SIZE_T eq;
52     T = ExAllocatePool(PagedPool, sizeof(TUNNEL));
53     ok(T != NULL, "PTUNEL is NULL after allocated memory\n");
54     Tb = ExAllocatePool(PagedPool, sizeof(TUNNEL));
55     ok(Tb != NULL, "PTUNEL is NULL after allocated memory\n");
56 
57     memset((void*)T, 0, sizeof(TUNNEL));
58     memset((void*)Tb, 0, sizeof(TUNNEL));
59 
60     FsRtlInitializeTunnelCache(T);
61 
62     eq = RtlCompareMemory((const VOID*)T, (const VOID*)Tb,  sizeof(TUNNEL));
63 
64     ok ( eq != sizeof(TUNNEL), "FsRtlInitializeTunnelCache function did not change anything in the memory at the address PTUNEL.\n");
65 }
66 
67 void TestFsRtlAddToTunnelCache(ULONGLONG DirectoryKey, PUNICODE_STRING s_name, PUNICODE_STRING l_name, BOOLEAN KeyByShortName)
68 {
69     SIZE_T eq;
70     LONG b;
71     PUNICODE_STRING bs_name;
72     PUNICODE_STRING bl_name;
73     PVOID Bufb;
74     PVOID Buf;
75 
76     Buf = ExAllocatePool(PagedPool, BufSize);
77     ok(Buf != NULL, "Buff in TestFsRtlAddToTunnelCache is NULL after allocated memory\n");
78     Bufb = ExAllocatePool(PagedPool, BufSize);
79     ok(Bufb != NULL, "Buff in TestFsRtlAddToTunnelCache is NULL after allocated memory\n");
80 
81     // Allocate memory for the  bufs_name
82     bs_name = CopyUS(s_name);
83 
84     // Allocate memory for the l_name and bl_name
85     bl_name = CopyUS(l_name);
86 
87     memset((void*)Buf, 0, BufSize);
88     memset((void*)Bufb, 0, BufSize);
89 
90     FsRtlAddToTunnelCache(T, DirectoryKey, s_name, l_name, KeyByShortName, BufSize, Buf);
91 
92     eq = RtlCompareMemory((const VOID*)Buf, (const VOID*)Bufb,  BufSize);
93 
94     ok( eq !=  sizeof(TUNNEL),"FsRtlAddToTunnelCache function did not change anything in the memory at the address Buf.\n");
95 
96     b = RtlCompareUnicodeString(l_name, bl_name, TRUE);
97     ok (b == 0, "long name after call FsRtlAddToTunnelCache != long name befo call FsRtlAddToTunnelCache\n\n");
98     b = RtlCompareUnicodeString(s_name, bs_name, TRUE);
99     ok (b == 0, "short name after call FsRtlAddToTunnelCache != short name befo call FsRtlAddToTunnelCache\n\n");
100 
101     if (bs_name->Buffer) ExFreePool(bs_name->Buffer);
102     ExFreePool(bs_name);
103     if (bl_name->Buffer) ExFreePool(bl_name->Buffer);
104     ExFreePool(bl_name);
105     ExFreePool(Bufb);
106     ExFreePool(Buf);
107 }
108 
109 BOOLEAN TestFsRtlFindInTunnelCache(ULONG DirectoryKey, PUNICODE_STRING name, PUNICODE_STRING s_name, PUNICODE_STRING l_name)
110 {
111     // Allocate memory for the Buf
112     ULONG BufsizeTemp = BufSize;
113     PVOID Buf = ExAllocatePool(PagedPool, BufSize*2);
114     ok(Buf != NULL, "Buff in FsRtlFindInTunnelCache is NULL after allocated memory\n");
115 
116     return FsRtlFindInTunnelCache(T, DirectoryKey, name, s_name, l_name, &BufsizeTemp, Buf);
117 }
118 
119 void TestFsRtlDeleteKeyFromTunnelCache(ULONGLONG a)
120 {
121     FsRtlDeleteKeyFromTunnelCache(T, a);
122 }
123 
124 static
125 void DuplicatesTest()
126 {
127     UNICODE_STRING ShortName, LongName, OutShort, OutLong, ShortName2, LongName2;
128     ULONG First, Second, OutLength, OutData;
129     PTUNNEL Tunnel;
130     PVOID Buffer;
131 
132     First = 1;
133     Second = 2;
134     RtlInitUnicodeString(&ShortName, L"LONGFI~1.TXT");
135     RtlInitUnicodeString(&LongName, L"Longfilename.txt");
136     RtlInitUnicodeString(&ShortName2, L"LONGFI~2.TXT");
137     RtlInitUnicodeString(&LongName2, L"Longfilenamr.txt");
138     Tunnel = ExAllocatePool(NonPagedPool, sizeof(TUNNEL));
139     RtlZeroMemory(Tunnel, sizeof(TUNNEL));
140     OutShort.MaximumLength = 13 * sizeof(WCHAR);
141     OutShort.Buffer = ExAllocatePool(PagedPool, OutShort.MaximumLength);
142     OutLong.MaximumLength = 17 * sizeof(WCHAR);
143     OutLong.Buffer = Buffer = ExAllocatePool(PagedPool, OutLong.MaximumLength);
144 
145     FsRtlInitializeTunnelCache(Tunnel);
146     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName, &LongName, TRUE, sizeof(ULONG), &First);
147     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "First call");
148     ok_eq_ulong(OutLength, sizeof(ULONG));
149     ok_eq_ulong(OutData, 1);
150     ok_eq_pointer(OutLong.Buffer, Buffer);
151 
152     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName, &LongName, TRUE, sizeof(ULONG), &Second);
153     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Second call");
154     ok_eq_ulong(OutLength, sizeof(ULONG));
155     ok_eq_ulong(OutData, 2);
156     ok_eq_pointer(OutLong.Buffer, Buffer);
157 
158     OutLong.MaximumLength = 13 * sizeof(WCHAR);
159     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Third call");
160     ok_eq_ulong(OutLength, sizeof(ULONG));
161     ok_eq_ulong(OutData, 2);
162     ok(OutLong.Buffer != Buffer, "Buffer didn't get reallocated!\n");
163     ok_eq_uint(OutLong.MaximumLength, 16 * sizeof(WCHAR));
164 
165     FsRtlDeleteKeyFromTunnelCache(Tunnel, 1);
166     ok_bool_false(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Fourth call");
167 
168     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName, &LongName, TRUE, sizeof(ULONG), &First);
169     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Fifth call");
170     ok_eq_ulong(OutLength, sizeof(ULONG));
171     ok_eq_ulong(OutData, 1);
172 
173     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName2, &LongName2, TRUE, sizeof(ULONG), &First);
174     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Sixth call");
175     ok_eq_ulong(OutLength, sizeof(ULONG));
176     ok_eq_ulong(OutData, 1);
177     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName2, &OutShort, &OutLong, &OutLength, &OutData), "Seventh call");
178     ok_eq_ulong(OutLength, sizeof(ULONG));
179     ok_eq_ulong(OutData, 1);
180 
181     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName, &LongName, TRUE, sizeof(ULONG), &Second);
182     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Eighth call");
183     ok_eq_ulong(OutLength, sizeof(ULONG));
184     ok_eq_ulong(OutData, 2);
185     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName2, &OutShort, &OutLong, &OutLength, &OutData), "Ninth call");
186     ok_eq_ulong(OutLength, sizeof(ULONG));
187     ok_eq_ulong(OutData, 1);
188 
189     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName2, &LongName2, TRUE, sizeof(ULONG), &Second);
190     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Tenth call");
191     ok_eq_ulong(OutLength, sizeof(ULONG));
192     ok_eq_ulong(OutData, 2);
193     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName2, &OutShort, &OutLong, &OutLength, &OutData), "Eleventh call");
194     ok_eq_ulong(OutLength, sizeof(ULONG));
195     ok_eq_ulong(OutData, 2);
196 
197     FsRtlDeleteKeyFromTunnelCache(Tunnel, 1);
198     ok_bool_false(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Twelfth call");
199     ok_bool_false(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName2, &OutShort, &OutLong, &OutLength, &OutData), "Thirteenth call");
200 
201     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName, &LongName, TRUE, sizeof(ULONG), &First);
202     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Fourteenth call");
203     ok_eq_ulong(OutLength, sizeof(ULONG));
204     ok_eq_ulong(OutData, 1);
205 
206     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName, &LongName, TRUE, sizeof(ULONG), &Second);
207     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Fifteenth call");
208     ok_eq_ulong(OutLength, sizeof(ULONG));
209     ok_eq_ulong(OutData, 2);
210 
211     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName2, &LongName2, TRUE, sizeof(ULONG), &First);
212     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Sixteenth call");
213     ok_eq_ulong(OutLength, sizeof(ULONG));
214     ok_eq_ulong(OutData, 2);
215     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName2, &OutShort, &OutLong, &OutLength, &OutData), "Seventeenth call");
216     ok_eq_ulong(OutLength, sizeof(ULONG));
217     ok_eq_ulong(OutData, 1);
218 
219     FsRtlAddToTunnelCache(Tunnel, 1, &ShortName2, &LongName2, TRUE, sizeof(ULONG), &Second);
220     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName, &OutShort, &OutLong, &OutLength, &OutData), "Eighteenth call");
221     ok_eq_ulong(OutLength, sizeof(ULONG));
222     ok_eq_ulong(OutData, 2);
223     ok_bool_true(FsRtlFindInTunnelCache(Tunnel, 1, &ShortName2, &OutShort, &OutLong, &OutLength, &OutData), "Nineteenth call");
224     ok_eq_ulong(OutLength, sizeof(ULONG));
225     ok_eq_ulong(OutData, 2);
226 
227     FsRtlDeleteTunnelCache(Tunnel);
228     ExFreePool(OutShort.Buffer);
229     ExFreePool(OutLong.Buffer);
230     ExFreePool(Buffer);
231     ExFreePool(Tunnel);
232 }
233 
234 START_TEST(FsRtlTunnel)
235 {
236     UNICODE_STRING s_name;
237     UNICODE_STRING l_name;
238     UNICODE_STRING name;
239     UNICODE_STRING a;
240     BOOLEAN is;
241 
242     //Initialize Cash
243     TestFsRtlInitializeTunnelCache();
244 
245     s_name.Length = 0;
246     s_name.MaximumLength = 64 * sizeof(WCHAR);
247     s_name.Buffer = ExAllocatePoolWithTag(PagedPool, s_name.MaximumLength, 'sFmK');
248     ok(s_name.Buffer != NULL, "s_name.Buffer in TestFsRtlAddToTunnelCache is NULL after allocated memory\n");
249     RtlAppendUnicodeToString(&s_name, L"smal");
250 
251     l_name.Length = 0;
252     l_name.MaximumLength = 64 * sizeof(WCHAR);
253     l_name.Buffer = ExAllocatePoolWithTag(PagedPool, l_name.MaximumLength, 'lFmK');
254     ok(l_name.Buffer != NULL, "l_name.Buffer in TestFsRtlAddToTunnelCache is NULL after allocated memory\n");
255     RtlAppendUnicodeToString(&l_name, L"bigbigbigbigbig");
256 
257     // Add elem
258     TestFsRtlAddToTunnelCache(12345, &s_name, &l_name, TRUE);
259 
260     name.Length = 0;
261     name.MaximumLength = 64 * sizeof(WCHAR);
262     name.Buffer = ExAllocatePoolWithTag(PagedPool, name.MaximumLength, 'nFmK');
263     ok(name.Buffer != NULL, "name.Buffer in FsRtlFindInTunnelCache is NULL after allocated memory\n");
264     RtlAppendUnicodeToString(&name, L"smal");
265 
266     // Find
267     is = TestFsRtlFindInTunnelCache(12345, &name, &s_name, &l_name);
268     ok(is == TRUE, "FsRtlFindInTunnelCache dosn't find elem id = 12345\n");
269 
270     TestFsRtlDeleteKeyFromTunnelCache(12345);	//Delete
271     is = TestFsRtlFindInTunnelCache(12345, &name, &s_name, &l_name);
272     ok(is == FALSE, "TestFsRtlDeleteKeyFromTunnelCache dosn't delete elem id = 12345\n");
273 
274     is = TestFsRtlFindInTunnelCache(12347, &name, &s_name, &l_name);
275     ok(is == FALSE, "FsRtlDeleteTunnelCache dosn't clear cash\n");
276 
277     TestFsRtlAddToTunnelCache(12345, &s_name, &l_name, TRUE);
278     TestFsRtlAddToTunnelCache(12347, &s_name, &l_name, TRUE);
279     RtlInitUnicodeString(&a, NULL);
280     TestFsRtlAddToTunnelCache(12346, &a, &l_name, FALSE);
281 
282     //Clear all
283     FsRtlDeleteTunnelCache(T);
284 
285     is = TestFsRtlFindInTunnelCache(12345, &name, &s_name, &l_name);
286     ok(is == FALSE, "FsRtlDeleteTunnelCache dosn't clear cash\n");
287 
288     is = TestFsRtlFindInTunnelCache(12346, &name, &a, &l_name);
289     ok(is == FALSE, "FsRtlDeleteTunnelCache dosn't clear cash\n");
290 
291     is = TestFsRtlFindInTunnelCache(12347, &name, &s_name, &l_name);
292     ok(is == FALSE, "FsRtlDeleteTunnelCache dosn't clear cash\n");
293 
294     ExFreePoolWithTag(name.Buffer, 'nFmK');
295     ExFreePoolWithTag(l_name.Buffer, 'lFmK');
296     ExFreePoolWithTag(s_name.Buffer, 'sFmK');
297 
298     ExFreePool(Tb);
299     ExFreePool(T);
300 
301     DuplicatesTest();
302 }
303