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
;
24 IN PDRIVER_OBJECT DriverObject
,
25 IN PCUNICODE_STRING RegistryPath
,
26 OUT PCWSTR
*DeviceName
,
29 NTSTATUS Status
= STATUS_SUCCESS
;
33 UNREFERENCED_PARAMETER(RegistryPath
);
34 UNREFERENCED_PARAMETER(Flags
);
36 *DeviceName
= L
"MmMapLockedPagesSpecifyCache";
38 KmtRegisterIrpHandler(IRP_MJ_CLEANUP
, NULL
, TestIrpHandler
);
39 KmtRegisterMessageHandler(0, NULL
, TestMessageHandler
);
46 IN PDRIVER_OBJECT DriverObject
)
52 TestCleanEverything(VOID
)
56 if (CurrentMdl
== NULL
)
61 if (CurrentUser
!= NULL
)
63 SehStatus
= STATUS_SUCCESS
;
66 MmUnmapLockedPages(CurrentUser
, CurrentMdl
);
68 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
70 SehStatus
= _SEH2_GetExceptionCode();
73 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
77 SehStatus
= STATUS_SUCCESS
;
80 MmUnlockPages(CurrentMdl
);
82 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
84 SehStatus
= _SEH2_GetExceptionCode();
87 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
88 IoFreeMdl(CurrentMdl
);
89 ExFreePoolWithTag(CurrentBuffer
, 'MLPC');
96 IN PDEVICE_OBJECT DeviceObject
,
98 IN PVOID Buffer OPTIONAL
,
100 IN OUT PSIZE_T OutLength
)
102 NTSTATUS Status
= STATUS_SUCCESS
;
107 case IOCTL_QUERY_BUFFER
:
109 ok(Buffer
!= NULL
, "Buffer is NULL\n");
110 ok_eq_size(InLength
, sizeof(QUERY_BUFFER
));
111 ok_eq_size(*OutLength
, sizeof(QUERY_BUFFER
));
112 ok_eq_pointer(CurrentMdl
, NULL
);
113 ok(ExGetPreviousMode() == UserMode
, "Not comming from umode!\n");
114 if (!skip(Buffer
&& InLength
>= sizeof(QUERY_BUFFER
) && *OutLength
>= sizeof(QUERY_BUFFER
), "Cannot read/write from/to buffer!\n"))
116 PQUERY_BUFFER QueryBuffer
;
118 MEMORY_CACHING_TYPE CacheType
;
120 QueryBuffer
= Buffer
;
121 CacheType
= (QueryBuffer
->Cached
? MmCached
: MmNonCached
);
122 Length
= QueryBuffer
->Length
;
123 ok(Length
> 0, "Null size!\n");
125 CurrentBuffer
= ExAllocatePoolWithTag(NonPagedPool
, Length
+ 0x8, 'MLPC');
126 ok(CurrentBuffer
!= NULL
, "ExAllocatePool failed!\n");
128 if (!skip(CurrentBuffer
!= NULL
, "ExAllocatePool failed!\n"))
130 CurrentMdl
= IoAllocateMdl(CurrentBuffer
, Length
, FALSE
, FALSE
, NULL
);
131 ok(CurrentMdl
!= NULL
, "IoAllocateMdl failed!\n");
136 SehStatus
= STATUS_SUCCESS
;
139 MmProbeAndLockPages(CurrentMdl
, KernelMode
, IoWriteAccess
);
141 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
143 SehStatus
= _SEH2_GetExceptionCode();
146 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
148 Irql
= KeGetCurrentIrql();
149 ok(Irql
<= APC_LEVEL
, "IRQL > APC_LEVEL: %d\n", Irql
);
151 SehStatus
= STATUS_SUCCESS
;
154 CurrentUser
= MmMapLockedPagesSpecifyCache(CurrentMdl
, UserMode
, CacheType
, NULL
, FALSE
, NormalPagePriority
);
156 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
158 SehStatus
= _SEH2_GetExceptionCode();
162 if (QueryBuffer
->Cached
)
164 ok_eq_hex(SehStatus
, STATUS_SUCCESS
);
165 ok(CurrentUser
!= NULL
, "MmMapLockedPagesSpecifyCache failed!\n");
169 ok_eq_hex(SehStatus
, STATUS_INVALID_ADDRESS
);
170 ok_eq_pointer(CurrentUser
, NULL
);
174 QueryBuffer
->Buffer
= CurrentUser
;
176 *OutLength
= sizeof(QUERY_BUFFER
);
181 case IOCTL_READ_BUFFER
:
183 ok(Buffer
!= NULL
, "Buffer is NULL\n");
184 ok_eq_size(InLength
, sizeof(READ_BUFFER
));
185 ok_eq_size(*OutLength
, 0);
186 ok(CurrentMdl
!= NULL
, "MDL is not in use!\n");
188 if (!skip(Buffer
&& InLength
>= sizeof(QUERY_BUFFER
), "Cannot read from buffer!\n"))
190 PREAD_BUFFER ReadBuffer
;
193 if (!skip(ReadBuffer
&& ReadBuffer
->Buffer
== CurrentUser
, "Cannot find matching MDL\n"))
195 if (ReadBuffer
->Buffer
!= NULL
)
198 PUSHORT KBuffer
= MmGetSystemAddressForMdlSafe(CurrentMdl
, NormalPagePriority
);
199 ok(KBuffer
!= NULL
, "Failed to get kmode ptr\n");
201 if (!skip(Buffer
!= NULL
, "Failed to get kmode ptr\n"))
203 for (i
= 0; i
< ReadBuffer
->Length
/ sizeof(USHORT
); ++i
)
205 ok_eq_ulong((ULONG
)KBuffer
[i
], (ULONG
)ReadBuffer
->Pattern
);
211 TestCleanEverything();
217 ok(0, "Got an unknown message! DeviceObject=%p, ControlCode=%lu, Buffer=%p, In=%lu, Out=%lu bytes\n",
218 DeviceObject
, ControlCode
, Buffer
, InLength
, *OutLength
);
228 _In_ PDEVICE_OBJECT DeviceObject
,
230 _In_ PIO_STACK_LOCATION IoStack
)
236 DPRINT("IRP %x/%x\n", IoStack
->MajorFunction
, IoStack
->MinorFunction
);
237 ASSERT(IoStack
->MajorFunction
== IRP_MJ_CLEANUP
);
239 Status
= STATUS_NOT_SUPPORTED
;
240 Irp
->IoStatus
.Information
= 0;
242 if (IoStack
->MajorFunction
== IRP_MJ_CLEANUP
)
244 TestCleanEverything();
245 Status
= STATUS_SUCCESS
;
248 if (Status
== STATUS_PENDING
)
250 IoMarkIrpPending(Irp
);
251 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
252 Status
= STATUS_PENDING
;
256 Irp
->IoStatus
.Status
= Status
;
257 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);