1 /*
2  * PROJECT:         ReactOS kernel-mode tests
3  * LICENSE:         GPLv2+ - See COPYING in the top level directory
4  * PURPOSE:         Kernel-Mode Test Suite Runtime library memory functions test
5  * PROGRAMMER:      Thomas Faber <thomas.faber@reactos.org>
6  */
7 
8 #include <stddef.h>
9 __declspec(dllimport) void __stdcall RtlMoveMemory(void *, const void *, size_t);
10 __declspec(dllimport) void __stdcall RtlFillMemory(void *, size_t, unsigned char);
11 
12 #define KMT_EMULATE_KERNEL
13 #include <kmt_test.h>
14 
15 #ifdef __GNUC__
16 #pragma GCC diagnostic ignored "-Wnonnull"
17 #endif /* defined __GNUC__ */
18 
19 static
20 VOID
21 MakeBuffer(
22     OUT PVOID Buffer,
23     ...)
24 {
25     PUCHAR OutBuffer = Buffer;
26     INT Count;
27     INT Value;
28     va_list Arguments;
29 
30     va_start(Arguments, Buffer);
31 
32     while (1)
33     {
34         Count = va_arg(Arguments, INT);
35         if (!Count)
36             break;
37         ASSERT(Count > 0);
38 
39         Value = va_arg(Arguments, INT);
40         while (Count--)
41             *OutBuffer++ = Value;
42     }
43 
44     va_end(Arguments);
45 }
46 
47 static
48 BOOLEAN
49 CheckBuffer(
50     IN const VOID *Buffer,
51     ...)
52 {
53     CONST UCHAR *OutBuffer = Buffer;
54     INT Count;
55     INT Value;
56     va_list Arguments;
57 
58     va_start(Arguments, Buffer);
59 
60     while (1)
61     {
62         Count = va_arg(Arguments, INT);
63         if (!Count)
64             break;
65         ASSERT(Count > 0);
66 
67         Value = va_arg(Arguments, INT);
68         while (Count--)
69             if (*OutBuffer++ != Value)
70             {
71                 --OutBuffer;
72                 trace("CheckBuffer failed at offset %d, value %x, expected %x\n", OutBuffer - (CONST UCHAR*)Buffer, *OutBuffer, Value);
73                 return FALSE;
74             }
75     }
76 
77     va_end(Arguments);
78     return TRUE;
79 }
80 
81 static
82 VOID
83 MakePattern(
84     OUT PVOID Buffer,
85     ...)
86 {
87     PUCHAR OutBuffer = Buffer;
88     INT Count, Repeat, i;
89     INT Values[16];
90     va_list Arguments;
91 
92     va_start(Arguments, Buffer);
93 
94     while (1)
95     {
96         Count = va_arg(Arguments, INT);
97         if (!Count)
98             break;
99         ASSERT(Count > 0 && Count < sizeof Values / sizeof Values[0]);
100 
101         Repeat = va_arg(Arguments, INT);
102         ASSERT(Repeat > 0);
103 
104         for (i = 0; i < Count; ++i)
105             Values[i] = va_arg(Arguments, INT);
106 
107         while (Repeat--)
108             for (i = 0; i < Count; ++i)
109                 *OutBuffer++ = Values[i];
110     }
111 
112     va_end(Arguments);
113 }
114 
115 static
116 BOOLEAN
117 CheckPattern(
118     IN const VOID *Buffer,
119     ...)
120 {
121     CONST UCHAR *OutBuffer = Buffer;
122     INT Count, Repeat, i;
123     INT Values[16];
124     va_list Arguments;
125 
126     va_start(Arguments, Buffer);
127 
128     while (1)
129     {
130         Count = va_arg(Arguments, INT);
131         if (!Count)
132             break;
133         ASSERT(Count > 0 && Count < sizeof Values / sizeof Values[0]);
134 
135         Repeat = va_arg(Arguments, INT);
136         ASSERT(Repeat > 0);
137 
138         for (i = 0; i < Count; ++i)
139             Values[i] = va_arg(Arguments, INT);
140 
141         while (Repeat--)
142             for (i = 0; i < Count; ++i)
143                 if (*OutBuffer++ != Values[i])
144                 {
145                     --OutBuffer;
146                     trace("CheckPattern failed at offset %d, value %x, expected %x\n", OutBuffer - (CONST UCHAR*)Buffer, *OutBuffer, Values[i]);
147                     return FALSE;
148                 }
149     }
150 
151     va_end(Arguments);
152     return TRUE;
153 }
154 
155 START_TEST(RtlMemory)
156 {
157     NTSTATUS Status;
158     UCHAR Buffer[513];
159     const SIZE_T Size = 512;
160     const SIZE_T HalfSize = Size / 2;
161     SIZE_T RetSize;
162     KIRQL Irql;
163     SIZE_T i;
164 
165     KeRaiseIrql(HIGH_LEVEL, &Irql);
166     /* zero everything behind 'Size'. Tests will check that this wasn't changed.
167      * TODO: use guarded memory for this! */
168     MakeBuffer(Buffer + Size, sizeof Buffer - Size, 0, 0);
169 
170     /* test our helper functions first */
171     MakeBuffer(Buffer, HalfSize, 0x55, HalfSize, 0xAA, 0);
172     for (i = 0; i < HalfSize; ++i)
173         ok_eq_uint(Buffer[i], 0x55);
174     for (i = HalfSize; i < Size; ++i)
175         ok_eq_uint(Buffer[i], 0xAA);
176     ok_bool_true(CheckBuffer(Buffer, HalfSize, 0x55, HalfSize, 0xAA, 1, 0, 0), "CheckBuffer");
177 
178     MakePattern(Buffer, 3, 20, 0x11, 0x22, 0x33, 1, 4, 0x44, 0);
179     for (i = 0; i < 60; i += 3)
180     {
181         ok_eq_uint(Buffer[i+0], 0x11);
182         ok_eq_uint(Buffer[i+1], 0x22);
183         ok_eq_uint(Buffer[i+2], 0x33);
184     }
185     for (i = 60; i < 64; ++i)
186         ok_eq_uint(Buffer[i], 0x44);
187     for (i = 64; i < HalfSize; ++i)
188         ok_eq_uint(Buffer[i], 0x55);
189     for (i = HalfSize; i < Size; ++i)
190         ok_eq_uint(Buffer[i], 0xAA);
191     ok_bool_true(CheckPattern(Buffer, 3, 20, 0x11, 0x22, 0x33, 1, 4, 0x44, 0), "CheckPattern");
192 
193     /* RtlMoveMemory */
194     MakePattern(Buffer, 2, 64, 0x12, 0x34, 2, 192, 0x56, 0x78, 0);
195     RtlMoveMemory(Buffer + 13, Buffer + 62, 95);
196     ok_bool_true(CheckPattern(Buffer, 2, 6, 0x12, 0x34, 1, 1, 0x12, 2, 33, 0x12, 0x34, 2, 14, 0x56, 0x78, 1, 1, 0x56, 2, 10, 0x12, 0x34, 2, 192, 0x56, 0x78, 1, 1, 0, 0), "CheckPattern");
197 
198     MakePattern(Buffer, 2, 32, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 192, 0x9A, 0xAB, 0);
199     RtlMoveMemory(Buffer + 78, Buffer + 43, 107);
200     ok_bool_true(CheckPattern(Buffer, 2, 32, 0x12, 0x34, 2, 7, 0x56, 0x78, 1, 1, 0x34, 2, 10, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 11, 0x9A, 0xAB, 1, 1, 0xAB, 2, 163, 0x9A, 0xAB, 1, 1, 0, 0), "CheckPattern");
201 
202     KeLowerIrql(Irql);
203     Status = STATUS_SUCCESS;
204     _SEH2_TRY {
205         RtlMoveMemory(NULL, NULL, 0);
206     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
207         Status = _SEH2_GetExceptionCode();
208     } _SEH2_END;
209     ok_eq_hex(Status, STATUS_SUCCESS);
210     KeRaiseIrql(HIGH_LEVEL, &Irql);
211 
212 #undef RtlMoveMemory
213     /* RtlMoveMemory export */
214     MakePattern(Buffer, 2, 64, 0x12, 0x34, 2, 192, 0x56, 0x78, 0);
215     RtlMoveMemory(Buffer + 13, Buffer + 62, 95);
216     ok_bool_true(CheckPattern(Buffer, 2, 6, 0x12, 0x34, 1, 1, 0x12, 2, 33, 0x12, 0x34, 2, 14, 0x56, 0x78, 1, 1, 0x56, 2, 10, 0x12, 0x34, 2, 192, 0x56, 0x78, 1, 1, 0, 0), "CheckPattern");
217 
218     MakePattern(Buffer, 2, 32, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 192, 0x9A, 0xAB, 0);
219     RtlMoveMemory(Buffer + 78, Buffer + 43, 107);
220     ok_bool_true(CheckPattern(Buffer, 2, 32, 0x12, 0x34, 2, 7, 0x56, 0x78, 1, 1, 0x34, 2, 10, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 11, 0x9A, 0xAB, 1, 1, 0xAB, 2, 163, 0x9A, 0xAB, 1, 1, 0, 0), "CheckPattern");
221 
222     KeLowerIrql(Irql);
223     Status = STATUS_SUCCESS;
224     _SEH2_TRY {
225         RtlMoveMemory(NULL, NULL, 0);
226     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
227         Status = _SEH2_GetExceptionCode();
228     } _SEH2_END;
229     ok_eq_hex(Status, STATUS_SUCCESS);
230     KeRaiseIrql(HIGH_LEVEL, &Irql);
231 
232     /* RtlCopyMemory */
233     MakePattern(Buffer, 2, 64, 0x12, 0x34, 2, 192, 0x56, 0x78, 0);
234     RtlCopyMemory(Buffer + 13, Buffer + 62, 95);
235     ok_bool_true(CheckPattern(Buffer, 2, 6, 0x12, 0x34, 1, 1, 0x12, 2, 33, 0x12, 0x34, 2, 14, 0x56, 0x78, 1, 1, 0x56, 2, 10, 0x12, 0x34, 2, 192, 0x56, 0x78, 1, 1, 0, 0), "CheckPattern");
236 
237     MakePattern(Buffer, 2, 32, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 192, 0x9A, 0xAB, 0);
238     RtlCopyMemory(Buffer + 78, Buffer + 43, 107);
239     ok_bool_true(CheckPattern(Buffer, 2, 32, 0x12, 0x34, 2, 7, 0x56, 0x78, 1, 1, 0x34, 2, 10, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 11, 0x9A, 0xAB, 1, 1, 0xAB, 2, 163, 0x9A, 0xAB, 1, 1, 0, 0), "CheckPattern");
240 
241     KeLowerIrql(Irql);
242     Status = STATUS_SUCCESS;
243     _SEH2_TRY {
244         RtlCopyMemory(NULL, NULL, 0);
245     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
246         Status = _SEH2_GetExceptionCode();
247     } _SEH2_END;
248     ok_eq_hex(Status, STATUS_SUCCESS);
249     KeRaiseIrql(HIGH_LEVEL, &Irql);
250 
251     /* RtlCopyMemoryNonTemporal */
252     MakePattern(Buffer, 2, 64, 0x12, 0x34, 2, 192, 0x56, 0x78, 0);
253     RtlCopyMemoryNonTemporal(Buffer + 13, Buffer + 62, 95);
254     ok_bool_true(CheckPattern(Buffer, 2, 6, 0x12, 0x34, 1, 1, 0x12, 2, 33, 0x12, 0x34, 2, 14, 0x56, 0x78, 1, 1, 0x56, 2, 10, 0x12, 0x34, 2, 192, 0x56, 0x78, 1, 1, 0, 0), "CheckPattern");
255 
256     MakePattern(Buffer, 2, 32, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 192, 0x9A, 0xAB, 0);
257     RtlCopyMemoryNonTemporal(Buffer + 78, Buffer + 43, 107);
258     ok_bool_true(CheckPattern(Buffer, 2, 32, 0x12, 0x34, 2, 7, 0x56, 0x78, 1, 1, 0x34, 2, 10, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 11, 0x9A, 0xAB, 1, 1, 0xAB, 2, 163, 0x9A, 0xAB, 1, 1, 0, 0), "CheckPattern");
259 
260     KeLowerIrql(Irql);
261     Status = STATUS_SUCCESS;
262     _SEH2_TRY {
263         RtlCopyMemoryNonTemporal(NULL, NULL, 0);
264     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
265         Status = _SEH2_GetExceptionCode();
266     } _SEH2_END;
267     ok_eq_hex(Status, STATUS_SUCCESS);
268     KeRaiseIrql(HIGH_LEVEL, &Irql);
269 
270     /* RtlCopyBytes */
271     MakePattern(Buffer, 2, 64, 0x12, 0x34, 2, 192, 0x56, 0x78, 0);
272     RtlCopyBytes(Buffer + 13, Buffer + 62, 95);
273     ok_bool_true(CheckPattern(Buffer, 2, 6, 0x12, 0x34, 1, 1, 0x12, 2, 33, 0x12, 0x34, 2, 14, 0x56, 0x78, 1, 1, 0x56, 2, 10, 0x12, 0x34, 2, 192, 0x56, 0x78, 1, 1, 0, 0), "CheckPattern");
274 
275     MakePattern(Buffer, 2, 32, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 192, 0x9A, 0xAB, 0);
276     RtlCopyBytes(Buffer + 78, Buffer + 43, 107);
277     ok_bool_true(CheckPattern(Buffer, 2, 32, 0x12, 0x34, 2, 7, 0x56, 0x78, 1, 1, 0x34, 2, 10, 0x12, 0x34, 2, 32, 0x56, 0x78, 2, 11, 0x9A, 0xAB, 1, 1, 0xAB, 2, 163, 0x9A, 0xAB, 1, 1, 0, 0), "CheckPattern");
278 
279     KeLowerIrql(Irql);
280     Status = STATUS_SUCCESS;
281     _SEH2_TRY {
282         RtlCopyBytes(NULL, NULL, 0);
283     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
284         Status = _SEH2_GetExceptionCode();
285     } _SEH2_END;
286     ok_eq_hex(Status, STATUS_SUCCESS);
287     KeRaiseIrql(HIGH_LEVEL, &Irql);
288 
289     /* RtlEqualMemory */
290     MakePattern(Buffer, 8, HalfSize / 8 - 1, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
291                         1, 1,                0x12,
292                         8, HalfSize / 8,     0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
293                         1, 7,                0x12, 0);
294 
295     ok_bool_true(RtlEqualMemory((PVOID)1, (PVOID)2, 0),
296                  "RtlEqualMemory returned");
297     ok_bool_true(RtlEqualMemory(Buffer, Buffer + HalfSize - 7, HalfSize - 8),
298                  "RtlEqualMemory returned");
299     ok_bool_true(RtlEqualMemory(Buffer, Buffer + HalfSize - 7, HalfSize - 8 + 1),
300                  "RtlEqualMemory returned");
301     ok_bool_false(RtlEqualMemory(Buffer, Buffer + HalfSize - 7, HalfSize - 8 + 2),
302                   "RtlEqualMemory returned");
303 
304     /* RtlCompareMemory */
305     MakePattern(Buffer, 8, HalfSize / 8 - 1, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
306                         1, 1,                0x12,
307                         8, HalfSize / 8,     0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0,
308                         1, 7,                0x12, 0);
309 
310     RetSize = RtlCompareMemory(Buffer, Buffer + HalfSize - 7, HalfSize - 8);
311     ok_eq_size(RetSize, HalfSize - 8);
312     RetSize = RtlCompareMemory(Buffer, Buffer + HalfSize - 7, HalfSize - 8 + 1);
313     ok_eq_size(RetSize, HalfSize - 8 + 1);
314     RetSize = RtlCompareMemory(Buffer, Buffer + HalfSize - 7, HalfSize - 8 + 2);
315     ok_eq_size(RetSize, HalfSize - 8 + 1);
316 
317     KeLowerIrql(Irql);
318     Status = STATUS_SUCCESS;
319     _SEH2_TRY {
320         RetSize = RtlCompareMemory(Buffer, Buffer + HalfSize - 7, SIZE_MAX);
321         ok_eq_size(RetSize, HalfSize - 8 + 1);
322         RetSize = RtlCompareMemory(NULL, NULL, 0);
323         ok_eq_size(RetSize, 0);
324     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
325         Status = _SEH2_GetExceptionCode();
326     } _SEH2_END;
327     ok_eq_hex(Status, STATUS_SUCCESS);
328     KeRaiseIrql(HIGH_LEVEL, &Irql);
329 
330     /* RtlCompareMemoryUlong */
331     MakeBuffer(Buffer, 8, 0x55, Size - 8, 0, 0);
332     RetSize = RtlCompareMemoryUlong(Buffer, sizeof(ULONG), 0x55555555LU);
333     ok_eq_size(RetSize, 4);
334     RetSize = RtlCompareMemoryUlong(Buffer + 1, sizeof(ULONG), 0x55555555LU);
335     ok_eq_size(RetSize, 4);
336     RetSize = RtlCompareMemoryUlong(Buffer + 2, sizeof(ULONG), 0x55555555LU);
337     ok_eq_size(RetSize, 4);
338     RetSize = RtlCompareMemoryUlong(Buffer + 3, sizeof(ULONG), 0x55555555LU);
339     ok_eq_size(RetSize, 4);
340     RetSize = RtlCompareMemoryUlong(Buffer + 5, sizeof(ULONG), 0x55555555LU);
341     ok_eq_size(RetSize, 0);
342     RetSize = RtlCompareMemoryUlong(Buffer + 5, sizeof(ULONG), 0x00555555LU);
343     ok_eq_size(RetSize, 4);
344     RetSize = RtlCompareMemoryUlong(Buffer, 1, 0x55555555LU);
345     ok_eq_size(RetSize, 0);
346     RetSize = RtlCompareMemoryUlong(Buffer, 2, 0x55555555LU);
347     ok_eq_size(RetSize, 0);
348     RetSize = RtlCompareMemoryUlong(Buffer, 3, 0x55555555LU);
349     ok_eq_size(RetSize, 0);
350     RetSize = RtlCompareMemoryUlong(Buffer, 5, 0x55555555LU);
351     ok_eq_size(RetSize, 4);
352 
353     KeLowerIrql(Irql);
354     Status = STATUS_SUCCESS;
355     _SEH2_TRY {
356         RetSize = RtlCompareMemoryUlong(NULL, 0, 0x55555555LU);
357         ok_eq_size(RetSize, 0);
358     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
359         Status = _SEH2_GetExceptionCode();
360     } _SEH2_END;
361     ok_eq_hex(Status, STATUS_SUCCESS);
362     KeRaiseIrql(HIGH_LEVEL, &Irql);
363 
364     /* RtlZeroMemory */
365     MakeBuffer(Buffer, Size, 0x11, 0);
366     RtlZeroMemory(Buffer, 1);
367     ok_bool_true(CheckBuffer(Buffer, 1, 0, Size - 1, 0x11, 1, 0, 0), "CheckBuffer");
368     Buffer[0] = 0x11;
369     RtlZeroMemory(Buffer, Size - 1);
370     ok_bool_true(CheckBuffer(Buffer, Size - 1, 0, 1, 0x11, 1, 0, 0), "CheckBuffer");
371 
372     KeLowerIrql(Irql);
373     Status = STATUS_SUCCESS;
374     _SEH2_TRY {
375         RtlZeroMemory(NULL, 0);
376     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
377         Status = _SEH2_GetExceptionCode();
378     } _SEH2_END;
379     ok_eq_hex(Status, STATUS_SUCCESS);
380     KeRaiseIrql(HIGH_LEVEL, &Irql);
381 
382     /* RtlSecureZeroMemory */
383     MakeBuffer(Buffer, Size, 0x11, 0);
384     RtlSecureZeroMemory(Buffer, 1);
385     ok_bool_true(CheckBuffer(Buffer, 1, 0, Size - 1, 0x11, 1, 0, 0), "CheckBuffer");
386     Buffer[0] = 0x11;
387     RtlSecureZeroMemory(Buffer, Size - 1);
388     ok_bool_true(CheckBuffer(Buffer, Size - 1, 0, 1, 0x11, 1, 0, 0), "CheckBuffer");
389 
390     KeLowerIrql(Irql);
391     Status = STATUS_SUCCESS;
392     _SEH2_TRY {
393         RtlSecureZeroMemory(NULL, 0);
394     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
395         Status = _SEH2_GetExceptionCode();
396     } _SEH2_END;
397     ok_eq_hex(Status, STATUS_SUCCESS);
398     KeRaiseIrql(HIGH_LEVEL, &Irql);
399 
400     /* RtlZeroBytes */
401     MakeBuffer(Buffer, Size, 0x11, 0);
402     RtlZeroBytes(Buffer, 1);
403     ok_bool_true(CheckBuffer(Buffer, 1, 0, Size - 1, 0x11, 1, 0, 0), "CheckBuffer");
404     Buffer[0] = 0x11;
405     RtlZeroBytes(Buffer, Size - 1);
406     ok_bool_true(CheckBuffer(Buffer, Size - 1, 0, 1, 0x11, 1, 0, 0), "CheckBuffer");
407 
408     KeLowerIrql(Irql);
409     Status = STATUS_SUCCESS;
410     _SEH2_TRY {
411         RtlZeroBytes(NULL, 0);
412     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
413         Status = _SEH2_GetExceptionCode();
414     } _SEH2_END;
415     ok_eq_hex(Status, STATUS_SUCCESS);
416     KeRaiseIrql(HIGH_LEVEL, &Irql);
417 
418     /* RtlFillMemory */
419     MakeBuffer(Buffer, Size, 0, 0);
420     RtlFillMemory(Buffer, HalfSize, 0x55);
421     RtlFillMemory(Buffer + HalfSize, HalfSize, 0xAA);
422     ok_bool_true(CheckBuffer(Buffer, HalfSize, 0x55, HalfSize, 0xAA, 1, 0, 0), "CheckBuffer");
423     RtlFillMemory(Buffer + 3, 7, 0x88);
424     ok_bool_true(CheckBuffer(Buffer, 3, 0x55, 7, 0x88, HalfSize - 10, 0x55, HalfSize, 0xAA, 1, 0, 0), "CheckBuffer");
425 
426     KeLowerIrql(Irql);
427     Status = STATUS_SUCCESS;
428     _SEH2_TRY {
429 #if defined(__GNUC__) && __GNUC__ >= 5
430 #pragma GCC diagnostic push
431 #pragma GCC diagnostic ignored "-Wmemset-transposed-args"
432 #endif
433         RtlFillMemory(NULL, 0, 0x55);
434 #if defined(__GNUC__) && __GNUC__ >= 5
435 #pragma GCC diagnostic pop
436 #endif
437     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
438         Status = _SEH2_GetExceptionCode();
439     } _SEH2_END;
440     ok_eq_hex(Status, STATUS_SUCCESS);
441     KeRaiseIrql(HIGH_LEVEL, &Irql);
442 
443 #undef RtlFillMemory
444     /* RtlFillMemory export */
445     MakeBuffer(Buffer, Size, 0, 0);
446     RtlFillMemory(Buffer, HalfSize, 0x55);
447     RtlFillMemory(Buffer + HalfSize, HalfSize, 0xAA);
448     ok_bool_true(CheckBuffer(Buffer, HalfSize, 0x55, HalfSize, 0xAA, 1, 0, 0), "CheckBuffer");
449     RtlFillMemory(Buffer + 3, 7, 0x88);
450     ok_bool_true(CheckBuffer(Buffer, 3, 0x55, 7, 0x88, HalfSize - 10, 0x55, HalfSize, 0xAA, 1, 0, 0), "CheckBuffer");
451 
452     KeLowerIrql(Irql);
453     Status = STATUS_SUCCESS;
454     _SEH2_TRY {
455         RtlFillMemory(NULL, 0, 0x55);
456     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
457         Status = _SEH2_GetExceptionCode();
458     } _SEH2_END;
459     ok_eq_hex(Status, STATUS_SUCCESS);
460     KeRaiseIrql(HIGH_LEVEL, &Irql);
461 
462     /* TODO: fix NDK. This should work! */
463 #if !defined _M_AMD64 || defined KMT_KERNEL_MODE
464     /* RtlFillMemoryUlong */
465     MakeBuffer(Buffer, Size, 0, 0);
466     RtlFillMemoryUlong(Buffer, HalfSize, 0x01234567LU);
467     RtlFillMemoryUlong(Buffer + HalfSize, HalfSize, 0x89ABCDEFLU);
468     ok_bool_true(CheckPattern(Buffer, 4, HalfSize / 4, 0x67, 0x45, 0x23, 0x01, 4, HalfSize / 4, 0xEF, 0xCD, 0xAB, 0x89, 1, 1, 0, 0), "CheckPattern");
469 
470     KeLowerIrql(Irql);
471     Status = STATUS_SUCCESS;
472     _SEH2_TRY {
473         MakeBuffer(Buffer, Size, 0, 0);
474         RtlFillMemoryUlong(Buffer + 1, sizeof(ULONG), 0xAAAAAAAALU);
475         ok_bool_true(CheckBuffer(Buffer, 1, 0, sizeof(ULONG), 0xAA, Size - sizeof(ULONG) - 1, 0, 1, 0, 0), "CheckBuffer");
476 
477         RtlFillMemoryUlong(NULL, 0, 0x55555555LU);
478     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
479         Status = _SEH2_GetExceptionCode();
480     } _SEH2_END;
481     ok_eq_hex(Status, STATUS_SUCCESS);
482     KeRaiseIrql(HIGH_LEVEL, &Irql);
483 #endif
484 
485     /* RtlFillMemoryUlonglong */
486     /* TODO: this function doesn't exist in 2k3/x86? wdm.h error? */
487 
488     /* RtlFillBytes */
489     MakeBuffer(Buffer, Size, 0, 0);
490     RtlFillBytes(Buffer, HalfSize, 0x55);
491     RtlFillBytes(Buffer + HalfSize, HalfSize, 0xAA);
492     ok_bool_true(CheckBuffer(Buffer, HalfSize, 0x55, HalfSize, 0xAA, 1, 0, 0), "CheckBuffer");
493     RtlFillBytes(Buffer + 3, 7, 0x88);
494     ok_bool_true(CheckBuffer(Buffer, 3, 0x55, 7, 0x88, HalfSize - 10, 0x55, HalfSize, 0xAA, 1, 0, 0), "CheckBuffer");
495 
496     KeLowerIrql(Irql);
497     Status = STATUS_SUCCESS;
498     _SEH2_TRY {
499         RtlFillBytes(NULL, 0, 0x55);
500     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
501         Status = _SEH2_GetExceptionCode();
502     } _SEH2_END;
503     ok_eq_hex(Status, STATUS_SUCCESS);
504     KeRaiseIrql(HIGH_LEVEL, &Irql);
505 
506     /* RtlPrefetchMemoryNonTemporal */
507     RtlPrefetchMemoryNonTemporal(Buffer, Size);
508 
509     KeLowerIrql(Irql);
510     Status = STATUS_SUCCESS;
511     _SEH2_TRY {
512         RtlPrefetchMemoryNonTemporal(NULL, 0);
513     } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {
514         Status = _SEH2_GetExceptionCode();
515     } _SEH2_END;
516     ok_eq_hex(Status, STATUS_SUCCESS);
517     KeRaiseIrql(HIGH_LEVEL, &Irql);
518 
519     KeLowerIrql(Irql);
520 }
521