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 coming 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
, QueryBuffer
->Buffer
, FALSE
, NormalPagePriority
);
183 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
185 SehStatus
= _SEH2_GetExceptionCode();
188 if (QueryBuffer
->Status
!= -1)
190 ok_eq_hex(SehStatus
, QueryBuffer
->Status
);
191 if (NT_SUCCESS(QueryBuffer
->Status
))
193 ok(CurrentUser
!= NULL
, "MmMapLockedPagesSpecifyCache failed!\n");
197 ok(CurrentUser
== NULL
, "MmMapLockedPagesSpecifyCache succeeded!\n");
200 QueryBuffer
->Status
= SehStatus
;
204 ExFreePoolWithTag(CurrentBuffer
, 'MLPC');
209 QueryBuffer
->Buffer
= CurrentUser
;
210 *OutLength
= sizeof(QUERY_BUFFER
);
215 case IOCTL_READ_BUFFER
:
217 ok(Buffer
!= NULL
, "Buffer is NULL\n");
218 ok_eq_size(InLength
, sizeof(READ_BUFFER
));
219 ok_eq_size(*OutLength
, 0);
220 ok(CurrentMdl
!= NULL
, "MDL is not in use!\n");
222 if (!skip(Buffer
&& InLength
>= sizeof(READ_BUFFER
), "Cannot read from buffer!\n"))
224 PREAD_BUFFER ReadBuffer
;
227 if (!skip(ReadBuffer
&& ReadBuffer
->Buffer
== CurrentUser
, "Cannot find matching MDL\n"))
229 if (ReadBuffer
->Buffer
!= NULL
)
232 PULONG KBuffer
= MmGetSystemAddressForMdlSafe(CurrentMdl
, NormalPagePriority
);
233 ok(KBuffer
!= NULL
, "Failed to get kmode ptr\n");
234 ok(ReadBuffer
->Length
% sizeof(ULONG
) == 0, "Invalid size: %d\n", ReadBuffer
->Length
);
236 if (!skip(Buffer
!= NULL
, "Failed to get kmode ptr\n"))
238 for (i
= 0; i
< ReadBuffer
->Length
/ sizeof(ULONG
); ++i
)
240 ok_eq_ulong(KBuffer
[i
], ReadBuffer
->Pattern
);
246 TestCleanEverything();
253 TestCleanEverything();
257 ok(0, "Got an unknown message! DeviceObject=%p, ControlCode=%lu, Buffer=%p, In=%lu, Out=%lu bytes\n",
258 DeviceObject
, ControlCode
, Buffer
, InLength
, *OutLength
);
268 _In_ PDEVICE_OBJECT DeviceObject
,
270 _In_ PIO_STACK_LOCATION IoStack
)
276 DPRINT("IRP %x/%x\n", IoStack
->MajorFunction
, IoStack
->MinorFunction
);
277 ASSERT(IoStack
->MajorFunction
== IRP_MJ_CLEANUP
);
279 Status
= STATUS_NOT_SUPPORTED
;
280 Irp
->IoStatus
.Information
= 0;
282 if (IoStack
->MajorFunction
== IRP_MJ_CLEANUP
)
284 TestCleanEverything();
285 Status
= STATUS_SUCCESS
;
288 if (Status
== STATUS_PENDING
)
290 IoMarkIrpPending(Irp
);
291 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
292 Status
= STATUS_PENDING
;
296 Irp
->IoStatus
.Status
= Status
;
297 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);