2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Test driver for MmMapLockedPagesSpecifyCache function
5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org>
13 #include "MmMapLockedPagesSpecifyCache.h"
15 static KMT_IRP_HANDLER TestIrpHandler
;
16 static KMT_MESSAGE_HANDLER TestMessageHandler
;
18 static PVOID CurrentBuffer
;
19 static PMDL CurrentMdl
;
20 static PVOID CurrentUser
;
21 static SIZE_T NonCachedLength
;
25 IN PDRIVER_OBJECT DriverObject
,
26 IN PCUNICODE_STRING RegistryPath
,
27 OUT PCWSTR
*DeviceName
,
30 NTSTATUS Status
= STATUS_SUCCESS
;
34 UNREFERENCED_PARAMETER(RegistryPath
);
35 UNREFERENCED_PARAMETER(Flags
);
37 *DeviceName
= L
"MmMapLockedPagesSpecifyCache";
39 KmtRegisterIrpHandler(IRP_MJ_CLEANUP
, NULL
, TestIrpHandler
);
40 KmtRegisterMessageHandler(0, NULL
, TestMessageHandler
);
47 IN PDRIVER_OBJECT DriverObject
)
53 TestCleanEverything(VOID
)
57 if (CurrentMdl
== NULL
)
62 if (CurrentUser
!= NULL
)
64 SehStatus
= STATUS_SUCCESS
;
67 MmUnmapLockedPages(CurrentUser
, CurrentMdl
);
69 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
71 SehStatus
= _SEH2_GetExceptionCode();
74 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
78 SehStatus
= STATUS_SUCCESS
;
81 MmUnlockPages(CurrentMdl
);
83 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
85 SehStatus
= _SEH2_GetExceptionCode();
88 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
89 IoFreeMdl(CurrentMdl
);
92 MmFreeNonCachedMemory(CurrentBuffer
, NonCachedLength
);
96 ExFreePoolWithTag(CurrentBuffer
, 'MLPC');
104 IN PDEVICE_OBJECT DeviceObject
,
105 IN ULONG ControlCode
,
106 IN PVOID Buffer OPTIONAL
,
108 IN OUT PSIZE_T OutLength
)
110 NTSTATUS Status
= STATUS_SUCCESS
;
115 case IOCTL_QUERY_BUFFER
:
117 ok(Buffer
!= NULL
, "Buffer is NULL\n");
118 ok_eq_size(InLength
, sizeof(QUERY_BUFFER
));
119 ok_eq_size(*OutLength
, sizeof(QUERY_BUFFER
));
120 ok_eq_pointer(CurrentMdl
, NULL
);
122 TestCleanEverything();
124 ok(ExGetPreviousMode() == UserMode
, "Not comming from umode!\n");
125 if (!skip(Buffer
&& InLength
>= sizeof(QUERY_BUFFER
) && *OutLength
>= sizeof(QUERY_BUFFER
), "Cannot read/write from/to buffer!\n"))
127 PQUERY_BUFFER QueryBuffer
;
129 MEMORY_CACHING_TYPE CacheType
;
131 QueryBuffer
= Buffer
;
132 CacheType
= (QueryBuffer
->Cached
? MmCached
: MmNonCached
);
133 Length
= QueryBuffer
->Length
;
135 ok(Length
> 0, "Null size!\n");
137 if (!skip(Length
> 0, "Null size!\n"))
139 if (QueryBuffer
->Cached
)
141 CurrentBuffer
= ExAllocatePoolWithTag(NonPagedPool
, Length
, 'MLPC');
142 ok(CurrentBuffer
!= NULL
, "ExAllocatePool failed!\n");
147 CurrentBuffer
= MmAllocateNonCachedMemory(Length
);
148 ok(CurrentBuffer
!= NULL
, "MmAllocateNonCachedMemory failed!\n");
151 RtlZeroMemory(CurrentBuffer
, Length
);
152 NonCachedLength
= Length
;
155 if (!skip(CurrentBuffer
!= NULL
, "ExAllocatePool failed!\n"))
157 CurrentMdl
= IoAllocateMdl(CurrentBuffer
, Length
, FALSE
, FALSE
, NULL
);
158 ok(CurrentMdl
!= NULL
, "IoAllocateMdl failed!\n");
159 if (!skip(CurrentMdl
!= NULL
, "IoAllocateMdl failed!\n"))
163 SehStatus
= STATUS_SUCCESS
;
166 MmProbeAndLockPages(CurrentMdl
, KernelMode
, IoWriteAccess
);
168 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
170 SehStatus
= _SEH2_GetExceptionCode();
173 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
175 Irql
= KeGetCurrentIrql();
176 ok(Irql
<= APC_LEVEL
, "IRQL > APC_LEVEL: %d\n", Irql
);
178 SehStatus
= STATUS_SUCCESS
;
181 CurrentUser
= MmMapLockedPagesSpecifyCache(CurrentMdl
, UserMode
, CacheType
, NULL
, FALSE
, NormalPagePriority
);
183 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
185 SehStatus
= _SEH2_GetExceptionCode();
188 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
189 ok(CurrentUser
!= NULL
, "MmMapLockedPagesSpecifyCache failed!\n");
193 ExFreePoolWithTag(CurrentBuffer
, 'MLPC');
198 QueryBuffer
->Buffer
= CurrentUser
;
199 *OutLength
= sizeof(QUERY_BUFFER
);
204 case IOCTL_READ_BUFFER
:
206 ok(Buffer
!= NULL
, "Buffer is NULL\n");
207 ok_eq_size(InLength
, sizeof(READ_BUFFER
));
208 ok_eq_size(*OutLength
, 0);
209 ok(CurrentMdl
!= NULL
, "MDL is not in use!\n");
211 if (!skip(Buffer
&& InLength
>= sizeof(QUERY_BUFFER
), "Cannot read from buffer!\n"))
213 PREAD_BUFFER ReadBuffer
;
216 if (!skip(ReadBuffer
&& ReadBuffer
->Buffer
== CurrentUser
, "Cannot find matching MDL\n"))
218 if (ReadBuffer
->Buffer
!= NULL
)
221 PULONG KBuffer
= MmGetSystemAddressForMdlSafe(CurrentMdl
, NormalPagePriority
);
222 ok(KBuffer
!= NULL
, "Failed to get kmode ptr\n");
223 ok(ReadBuffer
->Length
% sizeof(ULONG
) == 0, "Invalid size: %d\n", ReadBuffer
->Length
);
225 if (!skip(Buffer
!= NULL
, "Failed to get kmode ptr\n"))
227 for (i
= 0; i
< ReadBuffer
->Length
/ sizeof(ULONG
); ++i
)
229 ok_eq_ulong(KBuffer
[i
], ReadBuffer
->Pattern
);
235 TestCleanEverything();
241 ok(0, "Got an unknown message! DeviceObject=%p, ControlCode=%lu, Buffer=%p, In=%lu, Out=%lu bytes\n",
242 DeviceObject
, ControlCode
, Buffer
, InLength
, *OutLength
);
252 _In_ PDEVICE_OBJECT DeviceObject
,
254 _In_ PIO_STACK_LOCATION IoStack
)
260 DPRINT("IRP %x/%x\n", IoStack
->MajorFunction
, IoStack
->MinorFunction
);
261 ASSERT(IoStack
->MajorFunction
== IRP_MJ_CLEANUP
);
263 Status
= STATUS_NOT_SUPPORTED
;
264 Irp
->IoStatus
.Information
= 0;
266 if (IoStack
->MajorFunction
== IRP_MJ_CLEANUP
)
268 TestCleanEverything();
269 Status
= STATUS_SUCCESS
;
272 if (Status
== STATUS_PENDING
)
274 IoMarkIrpPending(Irp
);
275 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
276 Status
= STATUS_PENDING
;
280 Irp
->IoStatus
.Status
= Status
;
281 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);