ReactOS 0.4.15-dev-7918-g2a2556c
MmMapLockedPagesSpecifyCache_user.c
Go to the documentation of this file.
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#include <ndk/exfuncs.h>
10
12
13#define ALIGN_DOWN_BY(size, align) \
14 ((ULONG_PTR)(size) & ~((ULONG_PTR)(align) - 1))
15
16#define SET_BUFFER_LENGTH(Var, Length) \
17{ \
18 C_ASSERT(((Length) % sizeof(ULONG)) == 0); \
19 Var = (Length); \
20}
21
22#define FILL_QUERY_BUFFER(QueryBuffer, BufferLength, UseCache) \
23{ \
24 QueryBuffer.Length = BufferLength; \
25 QueryBuffer.Buffer = NULL; \
26 QueryBuffer.Cached = UseCache; \
27 QueryBuffer.Status = STATUS_SUCCESS; \
28}
29
30#define FILL_READ_BUFFER(QueryBuffer, ReadBuffer) \
31{ \
32 PULONG Buffer; \
33 ReadBuffer.Buffer = QueryBuffer.Buffer; \
34 if (!skip(QueryBuffer.Buffer != NULL, "Buffer is NULL\n")) \
35 { \
36 ReadBuffer.Pattern = WRITE_PATTERN; \
37 ReadBuffer.Length = QueryBuffer.Length; \
38 Buffer = QueryBuffer.Buffer; \
39 for (i = 0; i < ReadBuffer.Length / sizeof(ULONG); ++i) \
40 { \
41 Buffer[i] = ReadBuffer.Pattern; \
42 } \
43 } \
44}
45
46#define CHECK_ALLOC(MappedBuffer, BufferLength) \
47{ \
48 NTSTATUS Status; \
49 PVOID BaseAddress; \
50 SIZE_T Size; \
51 BaseAddress = MappedBuffer; \
52 Size = BufferLength; \
53 Status = NtAllocateVirtualMemory(NtCurrentProcess(), \
54 &BaseAddress, \
55 0, \
56 &Size, \
57 MEM_RESERVE, \
58 PAGE_READWRITE); \
59 ok_eq_hex(Status, STATUS_CONFLICTING_ADDRESSES); \
60 BaseAddress = MappedBuffer; \
61 Size = 0; \
62 Status = NtFreeVirtualMemory(NtCurrentProcess(), \
63 &BaseAddress, \
64 &Size, \
65 MEM_DECOMMIT); \
66 ok_eq_hex(Status, STATUS_UNABLE_TO_DELETE_SECTION); \
67 BaseAddress = MappedBuffer; \
68 Size = 0; \
69 Status = NtFreeVirtualMemory(NtCurrentProcess(), \
70 &BaseAddress, \
71 &Size, \
72 MEM_RELEASE); \
73 ok_eq_hex(Status, STATUS_UNABLE_TO_DELETE_SECTION); \
74 Status = NtUnmapViewOfSection(NtCurrentProcess(), \
75 MappedBuffer); \
76 ok_eq_hex(Status, STATUS_NOT_MAPPED_VIEW); \
77}
78
80{
81 QUERY_BUFFER QueryBuffer;
84 USHORT i;
88 ULONG_PTR HighestAddress;
90
91 Error = KmtLoadAndOpenDriver(L"MmMapLockedPagesSpecifyCache", FALSE);
93 if (Error)
94 return;
95
96 // Less than a page
98 Length = sizeof(QUERY_BUFFER);
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);
108
109 Length = sizeof(QUERY_BUFFER);
110 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
112 ok_eq_int(QueryBuffer.Length, BufferLength);
113 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
114 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
115
116 Length = 0;
117 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
119
120 // 1 page
122 Length = sizeof(QUERY_BUFFER);
123 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
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);
132
133 Length = sizeof(QUERY_BUFFER);
134 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
136 ok_eq_int(QueryBuffer.Length, BufferLength);
137 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
138 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
139
140 Length = 0;
141 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
143
144 // more than 1 page
145 SET_BUFFER_LENGTH(BufferLength, 4096 + 2048);
146 Length = sizeof(QUERY_BUFFER);
147 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
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);
156
157 Length = sizeof(QUERY_BUFFER);
158 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
160 ok_eq_int(QueryBuffer.Length, BufferLength);
161 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
162 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
163
164 Length = 0;
165 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
167
168 // 2 pages
170 Length = sizeof(QUERY_BUFFER);
171 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
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);
180
181 Length = sizeof(QUERY_BUFFER);
182 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
184 ok_eq_int(QueryBuffer.Length, BufferLength);
185 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
186 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
187
188 Length = 0;
189 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
191
192 // more than 2 pages
193 SET_BUFFER_LENGTH(BufferLength, 2 * 4096 + 2048);
194 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
195 Length = sizeof(QUERY_BUFFER);
197 ok_eq_int(QueryBuffer.Length, BufferLength);
198 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
199 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
200
201 Length = 0;
202 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
204
205 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, TRUE);
206 Length = sizeof(QUERY_BUFFER);
208 ok_eq_int(QueryBuffer.Length, BufferLength);
209 ok(QueryBuffer.Buffer != NULL, "Buffer is NULL\n");
210 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
211
212 Length = 0;
213 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
215
216 // ask for a specific address (we know that ReadBuffer.Buffer is free)
218 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
219 QueryBuffer.Buffer = ReadBuffer.Buffer;
220 Length = sizeof(QUERY_BUFFER);
222 ok_eq_int(QueryBuffer.Length, BufferLength);
223 ok(QueryBuffer.Buffer == ReadBuffer.Buffer, "Buffer is NULL\n");
224 CHECK_ALLOC(QueryBuffer.Buffer, BufferLength);
225
226 Length = 0;
227 FILL_READ_BUFFER(QueryBuffer, ReadBuffer);
229
230 // ask for an unaligned address
232 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
233 QueryBuffer.Buffer = (PVOID)((ULONG_PTR)ReadBuffer.Buffer + 2048);
234 QueryBuffer.Status = STATUS_INVALID_ADDRESS;
235 Length = sizeof(QUERY_BUFFER);
237 ok_eq_int(QueryBuffer.Length, BufferLength);
238 ok(QueryBuffer.Buffer == NULL, "Buffer is %p\n", QueryBuffer.Buffer);
239
240 Length = 0;
242
243 // get system info for MmHighestUserAddress
245 &BasicInfo,
246 sizeof(BasicInfo),
247 NULL);
249 trace("MaximumUserModeAddress: %lx\n", BasicInfo.MaximumUserModeAddress);
250 HighestAddress = ALIGN_DOWN_BY(BasicInfo.MaximumUserModeAddress, PAGE_SIZE);
251
252 // near MmHighestUserAddress
254 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
255 QueryBuffer.Buffer = (PVOID)(HighestAddress - 15 * PAGE_SIZE); // 7ffe0000
256 QueryBuffer.Status = STATUS_INVALID_ADDRESS;
257 trace("QueryBuffer.Buffer %p\n", QueryBuffer.Buffer);
258 Length = sizeof(QUERY_BUFFER);
260 ok_eq_int(QueryBuffer.Length, BufferLength);
261 ok(QueryBuffer.Buffer == NULL, "Buffer is %p\n", QueryBuffer.Buffer);
262
263 Length = 0;
265
266 // far enough away from MmHighestUserAddress
268 FILL_QUERY_BUFFER(QueryBuffer, BufferLength, FALSE);
269 QueryBuffer.Buffer = (PVOID)(HighestAddress - 16 * PAGE_SIZE); // 7ffdf000
270 QueryBuffer.Status = -1;
271 trace("QueryBuffer.Buffer %p\n", QueryBuffer.Buffer);
272 Length = sizeof(QUERY_BUFFER);
274 ok_eq_int(QueryBuffer.Length, BufferLength);
275 ok(QueryBuffer.Status == STATUS_SUCCESS ||
276 QueryBuffer.Status == STATUS_CONFLICTING_ADDRESSES, "Status = %lx\n", QueryBuffer.Status);
277
278 Length = 0;
280
283}
#define IOCTL_READ_BUFFER
struct _QUERY_BUFFER QUERY_BUFFER
#define IOCTL_CLEAN
#define IOCTL_QUERY_BUFFER
#define ALIGN_DOWN_BY(size, align)
#define FILL_READ_BUFFER(QueryBuffer, ReadBuffer)
#define CHECK_ALLOC(MappedBuffer, BufferLength)
#define FILL_QUERY_BUFFER(QueryBuffer, BufferLength, UseCache)
#define SET_BUFFER_LENGTH(Var, Length)
#define ok_eq_hex(value, expected)
Definition: apitest.h:77
#define ok_eq_int(value, expected)
Definition: apitest.h:60
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define START_TEST(x)
Definition: atltest.h:75
LONG NTSTATUS
Definition: precomp.h:26
BOOL Error
Definition: chkdsk.c:66
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define PAGE_SIZE
Definition: env_spec_w32.h:49
unsigned long DWORD
Definition: ntddk_ex.h:95
@ SystemBasicInformation
Definition: ntddk_ex.h:11
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
PVOID NTAPI MmMapLockedPagesSpecifyCache(IN PMDL Mdl, IN KPROCESSOR_MODE AccessMode, IN MEMORY_CACHING_TYPE CacheType, IN PVOID BaseAddress, IN ULONG BugCheckOnFailure, IN ULONG Priority)
Definition: mdlsup.c:660
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_INVALID_ADDRESS
Definition: ntstatus.h:557
#define STATUS_CONFLICTING_ADDRESSES
Definition: ntstatus.h:261
#define L(x)
Definition: ntvdm.h:50
unsigned short USHORT
Definition: pedump.c:61
#define STATUS_SUCCESS
Definition: shellext.h:65
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformation(IN SYSTEM_INFORMATION_CLASS SystemInfoClass, OUT PVOID SystemInfoBuffer, IN ULONG SystemInfoBufferSize, OUT PULONG BytesReturned OPTIONAL)
DWORD KmtLoadAndOpenDriver(IN PCWSTR ServiceName, IN BOOLEAN RestartIfRunning)
Definition: support.c:213
VOID KmtCloseDriver(VOID)
Definition: support.c:236
DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer OPTIONAL, IN DWORD InLength, IN OUT PDWORD OutLength)
Definition: support.c:360
VOID KmtUnloadDriver(VOID)
Definition: support.c:167
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3771