[KMTESTS:MM]
[reactos.git] / rostests / kmtests / ntos_mm / MmMapLockedPagesSpecifyCache_user.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite MmMapLockedPagesSpecifyCache test user-mode part
5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 #include "MmMapLockedPagesSpecifyCache.h"
11
12 #define SET_BUFFER_LENGTH(Var, Length) \
13 { \
14 C_ASSERT(((Length) % sizeof(ULONG)) == 0); \
15 Var = (Length); \
16 }
17
18 #define FILL_QUERY_BUFFER(QueryBuffer, BufferLength, UseCache) \
19 { \
20 QueryBuffer.Length = BufferLength; \
21 QueryBuffer.Buffer = NULL; \
22 QueryBuffer.Cached = UseCache; \
23 }
24
25 #define FILL_READ_BUFFER(QueryBuffer, ReadBuffer) \
26 { \
27 PULONG Buffer; \
28 ReadBuffer.Buffer = QueryBuffer.Buffer; \
29 if (!skip(QueryBuffer.Buffer != NULL, "Buffer is NULL\n")) \
30 { \
31 ReadBuffer.Pattern = WRITE_PATTERN; \
32 ReadBuffer.Length = QueryBuffer.Length; \
33 Buffer = QueryBuffer.Buffer; \
34 for (i = 0; i < ReadBuffer.Length / sizeof(ULONG); ++i) \
35 { \
36 Buffer[i] = ReadBuffer.Pattern; \
37 } \
38 } \
39 }
40
41 #define CHECK_ALLOC(MappedBuffer, BufferLength) \
42 { \
43 NTSTATUS Status; \
44 PVOID BaseAddress; \
45 SIZE_T Size; \
46 BaseAddress = MappedBuffer; \
47 Size = BufferLength; \
48 Status = NtAllocateVirtualMemory(NtCurrentProcess(), \
49 &BaseAddress, \
50 0, \
51 &Size, \
52 MEM_RESERVE, \
53 PAGE_READWRITE); \
54 ok_eq_hex(Status, STATUS_CONFLICTING_ADDRESSES); \
55 BaseAddress = MappedBuffer; \
56 Size = 0; \
57 Status = NtFreeVirtualMemory(NtCurrentProcess(), \
58 &BaseAddress, \
59 &Size, \
60 MEM_DECOMMIT); \
61 ok_eq_hex(Status, STATUS_UNABLE_TO_DELETE_SECTION); \
62 BaseAddress = MappedBuffer; \
63 Size = 0; \
64 Status = NtFreeVirtualMemory(NtCurrentProcess(), \
65 &BaseAddress, \
66 &Size, \
67 MEM_RELEASE); \
68 ok_eq_hex(Status, STATUS_UNABLE_TO_DELETE_SECTION); \
69 Status = NtUnmapViewOfSection(NtCurrentProcess(), \
70 MappedBuffer); \
71 ok_eq_hex(Status, STATUS_NOT_MAPPED_VIEW); \
72 }
73
74 START_TEST(MmMapLockedPagesSpecifyCache)
75 {
76 QUERY_BUFFER QueryBuffer;
77 READ_BUFFER ReadBuffer;
78 DWORD Length;
79 USHORT i;
80 USHORT BufferLength;
81
82 KmtLoadDriver(L"MmMapLockedPagesSpecifyCache", FALSE);
83 KmtOpenDriver();
84
85 // Less than a page
86 SET_BUFFER_LENGTH(BufferLength, 2048);
87 Length = sizeof(QUERY_BUFFER);
88 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
89 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
90 ok_eq_int(QueryBuffer.Length, BufferLength);
91 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
92 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
93
94 Length = 0;
95 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
96 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
97
98 Length = sizeof(QUERY_BUFFER);
99 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
100 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
101 ok_eq_int(QueryBuffer.Length, BufferLength);
102 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
103 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
104
105 Length = 0;
106 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
107 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
108
109 // 1 page
110 SET_BUFFER_LENGTH(BufferLength, 4096);
111 Length = sizeof(QUERY_BUFFER);
112 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
113 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
114 ok_eq_int(QueryBuffer.Length, BufferLength);
115 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
116 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
117
118 Length = 0;
119 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
120 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
121
122 Length = sizeof(QUERY_BUFFER);
123 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
124 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
125 ok_eq_int(QueryBuffer.Length, BufferLength);
126 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
127 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
128
129 Length = 0;
130 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
131 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
132
133 // more than 1 page
134 SET_BUFFER_LENGTH(BufferLength, 4096 + 2048);
135 Length = sizeof(QUERY_BUFFER);
136 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
137 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
138 ok_eq_int(QueryBuffer.Length, BufferLength);
139 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
140 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
141
142 Length = 0;
143 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
144 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
145
146 Length = sizeof(QUERY_BUFFER);
147 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
148 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
149 ok_eq_int(QueryBuffer.Length, BufferLength);
150 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
151 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
152
153 Length = 0;
154 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
155 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
156
157 // 2 pages
158 SET_BUFFER_LENGTH(BufferLength, 2 * 4096);
159 Length = sizeof(QUERY_BUFFER);
160 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
161 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
162 ok_eq_int(QueryBuffer.Length, BufferLength);
163 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
164 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
165
166 Length = 0;
167 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
168 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
169
170 Length = sizeof(QUERY_BUFFER);
171 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
172 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
173 ok_eq_int(QueryBuffer.Length, BufferLength);
174 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
175 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
176
177 Length = 0;
178 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
179 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
180
181 // more than 2 pages
182 SET_BUFFER_LENGTH(BufferLength, 2 * 4096 + 2048);
183 QueryBuffer.Length = BufferLength;
184 QueryBuffer.Buffer = NULL;
185 QueryBuffer.Cached = FALSE;
186 Length = sizeof(QUERY_BUFFER);
187 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
188 ok_eq_int(QueryBuffer.Length, BufferLength);
189 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
190 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
191
192 Length = 0;
193 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
194 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
195
196 QueryBuffer.Length = BufferLength;
197 QueryBuffer.Buffer = NULL;
198 QueryBuffer.Cached = TRUE;
199 Length = sizeof(QUERY_BUFFER);
200 ok(KmtSendBufferToDriver(IOCTL_QUERY_BUFFER, &QueryBuffer, sizeof(QUERY_BUFFER), &Length) == ERROR_SUCCESS, "\n");
201 ok_eq_int(QueryBuffer.Length, BufferLength);
202 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
203 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
204
205 Length = 0;
206 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
207 ok(KmtSendBufferToDriver(IOCTL_READ_BUFFER, &ReadBuffer, sizeof(READ_BUFFER), &Length) == ERROR_SUCCESS, "\n");
208
209 KmtCloseDriver();
210 KmtUnloadDriver();
211 }