[KMTESTS:MM]
[reactos.git] / rostests / kmtests / ntos_mm / MmSection.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite Section Object test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 #define CheckObject(Handle, Pointers, Handles) do \
11 { \
12 PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \
13 Status = ZwQueryObject(Handle, ObjectBasicInformation, \
14 &ObjectInfo, sizeof ObjectInfo, NULL); \
15 ok_eq_hex(Status, STATUS_SUCCESS); \
16 ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \
17 ok_eq_ulong(ObjectInfo.HandleCount, Handles); \
18 } while (0)
19
20 #define CheckSection(SectionObject, SectionFlag) do \
21 { \
22 SECTION_BASIC_INFORMATION Sbi; \
23 HANDLE SectionHandle = NULL; \
24 NTSTATUS Status; \
25 if (skip(SectionObject != NULL && \
26 SectionObject != (PVOID)0x5555555555555555ULL, \
27 "No section object\n")) \
28 break; \
29 Status = ObOpenObjectByPointer(SectionObject, OBJ_KERNEL_HANDLE, \
30 NULL, 0, MmSectionObjectType, \
31 KernelMode, &SectionHandle); \
32 ok_eq_hex(Status, STATUS_SUCCESS); \
33 ok(SectionHandle != NULL, "Section handle null\n"); \
34 if (!skip(NT_SUCCESS(Status) && SectionHandle, \
35 "No section handle\n")) \
36 { \
37 Status = ZwQuerySection(SectionHandle, SectionBasicInformation, \
38 &Sbi, sizeof Sbi, NULL); \
39 ok_eq_hex(Status, STATUS_SUCCESS); \
40 ok_eq_pointer(Sbi.BaseAddress, NULL); \
41 ok_eq_longlong(Sbi.Size.QuadPart, 1LL); \
42 ok_eq_hex(Sbi.Attributes, SectionFlag | SEC_FILE); \
43 ZwClose(SectionHandle); \
44 } \
45 } while (0)
46
47 #define TestMapView(SectionObject, ExpectAtBase, ExpectM) do \
48 { \
49 NTSTATUS Status; \
50 PVOID BaseAddress = NULL; \
51 SIZE_T ViewSize = 0; \
52 LARGE_INTEGER SectionOffset; \
53 if (skip(SectionObject != NULL && \
54 SectionObject != (PVOID)0x5555555555555555ULL, \
55 "No section object\n")) \
56 break; \
57 \
58 SectionOffset.QuadPart = 0; \
59 Status = MmMapViewOfSection(SectionObject, PsGetCurrentProcess(), \
60 &BaseAddress, 0, 1, &SectionOffset, \
61 &ViewSize, ViewUnmap, 0, PAGE_READONLY); \
62 ok_eq_hex(Status, ExpectAtBase ? STATUS_SUCCESS : STATUS_IMAGE_NOT_AT_BASE);\
63 if (!skip(NT_SUCCESS(Status), "Section not mapped\n")) \
64 { \
65 ok_eq_uint(*(PUCHAR)BaseAddress, ExpectM ? 'M' : 0); \
66 Status = MmUnmapViewOfSection(PsGetCurrentProcess(), BaseAddress); \
67 ok_eq_hex(Status, STATUS_SUCCESS); \
68 } \
69 } while (0)
70
71 static
72 VOID
73 TestCreateSection(
74 IN HANDLE FileHandle1,
75 IN PFILE_OBJECT FileObject1,
76 IN HANDLE FileHandle2,
77 IN PFILE_OBJECT FileObject2)
78 {
79 NTSTATUS Status = STATUS_SUCCESS;
80 PVOID SectionObject;
81 LARGE_INTEGER MaximumSize;
82 ULONG PointerCount1, PointerCount2;
83
84 KmtStartSeh()
85 Status = MmCreateSection(NULL, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL);
86 KmtEndSeh(STATUS_SUCCESS);
87 ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION);
88
89 if (!KmtIsCheckedBuild)
90 {
91 /* PAGE_NOACCESS and missing SEC_RESERVE/SEC_COMMIT/SEC_IMAGE assert */
92 KmtStartSeh()
93 Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, SEC_RESERVE, NULL, NULL);
94 KmtEndSeh(STATUS_ACCESS_VIOLATION);
95
96 KmtStartSeh()
97 Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_NOACCESS, 0, NULL, NULL);
98 KmtEndSeh(STATUS_ACCESS_VIOLATION);
99 }
100
101 SectionObject = KmtInvalidPointer;
102 KmtStartSeh()
103 Status = MmCreateSection(&SectionObject, 0, NULL, NULL, 0, SEC_RESERVE, NULL, NULL);
104 KmtEndSeh(STATUS_SUCCESS);
105 ok_eq_hex(Status, STATUS_INVALID_PAGE_PROTECTION);
106 ok_eq_pointer(SectionObject, KmtInvalidPointer);
107
108 if (SectionObject && SectionObject != KmtInvalidPointer)
109 ObDereferenceObject(SectionObject);
110
111 KmtStartSeh()
112 Status = MmCreateSection(NULL, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL);
113 KmtEndSeh(STATUS_ACCESS_VIOLATION);
114
115 SectionObject = KmtInvalidPointer;
116 KmtStartSeh()
117 Status = MmCreateSection(&SectionObject, 0, NULL, NULL, PAGE_READONLY, SEC_RESERVE, NULL, NULL);
118 KmtEndSeh(STATUS_ACCESS_VIOLATION);
119 ok_eq_pointer(SectionObject, KmtInvalidPointer);
120
121 if (SectionObject && SectionObject != KmtInvalidPointer)
122 ObDereferenceObject(SectionObject);
123
124 SectionObject = KmtInvalidPointer;
125 MaximumSize.QuadPart = 0;
126 KmtStartSeh()
127 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, NULL);
128 KmtEndSeh(STATUS_SUCCESS);
129 ok_eq_hex(Status, STATUS_INVALID_FILE_FOR_SECTION);
130 ok_eq_longlong(MaximumSize.QuadPart, 0LL);
131 ok_eq_pointer(SectionObject, KmtInvalidPointer);
132
133 if (SectionObject && SectionObject != KmtInvalidPointer)
134 ObDereferenceObject(SectionObject);
135
136 MaximumSize.QuadPart = 0;
137 KmtStartSeh()
138 Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL);
139 KmtEndSeh(STATUS_SUCCESS);
140 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4);
141 ok_eq_longlong(MaximumSize.QuadPart, 0LL);
142
143 if (SectionObject && SectionObject != KmtInvalidPointer)
144 ObDereferenceObject(SectionObject);
145
146 MaximumSize.QuadPart = 1;
147 KmtStartSeh()
148 Status = MmCreateSection(NULL, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL);
149 KmtEndSeh(STATUS_ACCESS_VIOLATION);
150 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
151
152 if (SectionObject && SectionObject != KmtInvalidPointer)
153 ObDereferenceObject(SectionObject);
154
155 SectionObject = KmtInvalidPointer;
156 MaximumSize.QuadPart = 0;
157 KmtStartSeh()
158 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL);
159 KmtEndSeh(STATUS_SUCCESS);
160 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_4);
161 ok_eq_longlong(MaximumSize.QuadPart, 0LL);
162 ok_eq_pointer(SectionObject, KmtInvalidPointer);
163
164 if (SectionObject && SectionObject != KmtInvalidPointer)
165 ObDereferenceObject(SectionObject);
166
167 /* page file section */
168 SectionObject = KmtInvalidPointer;
169 MaximumSize.QuadPart = 1;
170 KmtStartSeh()
171 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, NULL);
172 KmtEndSeh(STATUS_SUCCESS);
173 ok_eq_hex(Status, STATUS_SUCCESS);
174 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
175 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
176 ok(SectionObject != NULL, "Section object pointer NULL\n");
177
178 if (SectionObject && SectionObject != KmtInvalidPointer)
179 ObDereferenceObject(SectionObject);
180
181 if (!skip(FileHandle1 != NULL && FileObject1 != NULL &&
182 FileHandle2 != NULL && FileObject2 != NULL, "No file handle or object\n"))
183 {
184 PointerCount1 = 3;
185 PointerCount2 = 3;
186 /* image section */
187 CheckObject(FileHandle2, PointerCount2, 1L);
188 SectionObject = KmtInvalidPointer;
189 MaximumSize.QuadPart = 1;
190 KmtStartSeh()
191 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, NULL);
192 KmtEndSeh(STATUS_SUCCESS);
193 ok_eq_hex(Status, STATUS_SUCCESS);
194 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
195 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
196 ok(SectionObject != NULL, "Section object pointer NULL\n");
197 CheckObject(FileHandle2, PointerCount2, 1L);
198 CheckSection(SectionObject, SEC_IMAGE);
199 TestMapView(SectionObject, FALSE, TRUE);
200
201 if (SectionObject && SectionObject != KmtInvalidPointer)
202 ObDereferenceObject(SectionObject);
203
204 CheckObject(FileHandle2, PointerCount2, 1L);
205 SectionObject = KmtInvalidPointer;
206 MaximumSize.QuadPart = 1;
207 KmtStartSeh()
208 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, FileObject2);
209 KmtEndSeh(STATUS_SUCCESS);
210 ok_eq_hex(Status, STATUS_SUCCESS);
211 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
212 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
213 ok(SectionObject != NULL, "Section object pointer NULL\n");
214 ++PointerCount2;
215 CheckObject(FileHandle2, PointerCount2, 1L);
216 CheckSection(SectionObject, 0);
217 TestMapView(SectionObject, TRUE, TRUE);
218
219 if (SectionObject && SectionObject != KmtInvalidPointer)
220 ObDereferenceObject(SectionObject);
221 //--PointerCount2; // ????
222
223 CheckObject(FileHandle2, PointerCount2, 1L);
224 SectionObject = KmtInvalidPointer;
225 MaximumSize.QuadPart = 1;
226 KmtStartSeh()
227 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, FileObject2);
228 KmtEndSeh(STATUS_SUCCESS);
229 ok_eq_hex(Status, STATUS_SUCCESS);
230 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
231 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
232 ok(SectionObject != NULL, "Section object pointer NULL\n");
233 CheckObject(FileHandle2, PointerCount2, 1L);
234 CheckSection(SectionObject, 0);
235 TestMapView(SectionObject, TRUE, TRUE);
236
237 if (SectionObject && SectionObject != KmtInvalidPointer)
238 ObDereferenceObject(SectionObject);
239
240 /* image section with inappropriate file */
241 CheckObject(FileHandle1, PointerCount1, 1L);
242 SectionObject = KmtInvalidPointer;
243 MaximumSize.QuadPart = 1;
244 KmtStartSeh()
245 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, NULL);
246 KmtEndSeh(STATUS_SUCCESS);
247 ok_eq_hex(Status, STATUS_INVALID_IMAGE_NOT_MZ);
248 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
249 ok_eq_pointer(SectionObject, KmtInvalidPointer);
250 CheckObject(FileHandle1, PointerCount1, 1L);
251
252 if (SectionObject && SectionObject != KmtInvalidPointer)
253 ObDereferenceObject(SectionObject);
254
255 CheckObject(FileHandle1, PointerCount1, 1L);
256 SectionObject = KmtInvalidPointer;
257 MaximumSize.QuadPart = 1;
258 KmtStartSeh()
259 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, NULL, FileObject1);
260 KmtEndSeh(STATUS_SUCCESS);
261 ok_eq_hex(Status, STATUS_SUCCESS);
262 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
263 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
264 ok(SectionObject != NULL, "Section object pointer NULL\n");
265 ++PointerCount1;
266 CheckObject(FileHandle1, PointerCount1, 1L);
267 CheckSection(SectionObject, 0);
268 TestMapView(SectionObject, TRUE, FALSE);
269
270 if (SectionObject && SectionObject != KmtInvalidPointer)
271 ObDereferenceObject(SectionObject);
272 //--PointerCount1; // ????
273
274 CheckObject(FileHandle1, PointerCount1, 1L);
275 SectionObject = KmtInvalidPointer;
276 MaximumSize.QuadPart = 1;
277 KmtStartSeh()
278 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, FileObject1);
279 KmtEndSeh(STATUS_SUCCESS);
280 ok_eq_hex(Status, STATUS_SUCCESS);
281 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
282 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
283 ok(SectionObject != NULL, "Section object pointer NULL\n");
284 CheckObject(FileHandle1, PointerCount1, 1L);
285 CheckSection(SectionObject, 0);
286 TestMapView(SectionObject, TRUE, FALSE);
287
288 if (SectionObject && SectionObject != KmtInvalidPointer)
289 ObDereferenceObject(SectionObject);
290
291 /* image section with two different files */
292 CheckObject(FileHandle1, PointerCount1, 1L);
293 SectionObject = KmtInvalidPointer;
294 MaximumSize.QuadPart = 1;
295 KmtStartSeh()
296 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle1, FileObject2);
297 KmtEndSeh(STATUS_SUCCESS);
298 ok_eq_hex(Status, STATUS_SUCCESS);
299 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
300 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
301 ok(SectionObject != NULL, "Section object pointer NULL\n");
302 CheckObject(FileHandle1, PointerCount1, 1L);
303 CheckObject(FileHandle2, PointerCount2, 1L);
304 CheckSection(SectionObject, 0);
305 TestMapView(SectionObject, TRUE, TRUE);
306
307 if (SectionObject && SectionObject != KmtInvalidPointer)
308 ObDereferenceObject(SectionObject);
309
310 CheckObject(FileHandle1, PointerCount1, 1L);
311 SectionObject = KmtInvalidPointer;
312 MaximumSize.QuadPart = 1;
313 KmtStartSeh()
314 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_IMAGE, FileHandle2, FileObject1);
315 KmtEndSeh(STATUS_SUCCESS);
316 ok_eq_hex(Status, STATUS_SUCCESS);
317 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
318 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
319 ok(SectionObject != NULL, "Section object pointer NULL\n");
320 CheckObject(FileHandle1, PointerCount1, 1L);
321 CheckObject(FileHandle2, PointerCount2, 1L);
322 CheckSection(SectionObject, 0);
323 TestMapView(SectionObject, TRUE, FALSE);
324
325 if (SectionObject && SectionObject != KmtInvalidPointer)
326 ObDereferenceObject(SectionObject);
327
328 /* data file section */
329 CheckObject(FileHandle1, PointerCount1, 1L);
330 SectionObject = KmtInvalidPointer;
331 MaximumSize.QuadPart = 1;
332 KmtStartSeh()
333 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, FileHandle1, NULL);
334 KmtEndSeh(STATUS_SUCCESS);
335 ok_eq_hex(Status, STATUS_SUCCESS);
336 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
337 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
338 ok(SectionObject != NULL, "Section object pointer NULL\n");
339 CheckObject(FileHandle1, PointerCount1, 1L);
340 CheckSection(SectionObject, 0);
341 TestMapView(SectionObject, TRUE, FALSE);
342
343 if (SectionObject && SectionObject != KmtInvalidPointer)
344 ObDereferenceObject(SectionObject);
345
346 CheckObject(FileHandle1, PointerCount1, 1L);
347 SectionObject = KmtInvalidPointer;
348 MaximumSize.QuadPart = 1;
349 KmtStartSeh()
350 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, NULL, FileObject1);
351 KmtEndSeh(STATUS_SUCCESS);
352 ok_eq_hex(Status, STATUS_SUCCESS);
353 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
354 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
355 ok(SectionObject != NULL, "Section object pointer NULL\n");
356 CheckObject(FileHandle1, PointerCount1, 1L);
357 CheckSection(SectionObject, 0);
358 TestMapView(SectionObject, TRUE, FALSE);
359
360 if (SectionObject && SectionObject != KmtInvalidPointer)
361 ObDereferenceObject(SectionObject);
362
363 CheckObject(FileHandle1, PointerCount1, 1L);
364 SectionObject = KmtInvalidPointer;
365 MaximumSize.QuadPart = 1;
366 KmtStartSeh()
367 Status = MmCreateSection(&SectionObject, 0, NULL, &MaximumSize, PAGE_READONLY, SEC_RESERVE, FileHandle1, FileObject1);
368 KmtEndSeh(STATUS_SUCCESS);
369 ok_eq_hex(Status, STATUS_SUCCESS);
370 ok_eq_longlong(MaximumSize.QuadPart, 1LL);
371 ok(SectionObject != KmtInvalidPointer, "Section object pointer untouched\n");
372 ok(SectionObject != NULL, "Section object pointer NULL\n");
373 CheckObject(FileHandle1, PointerCount1, 1L);
374 CheckSection(SectionObject, 0);
375 TestMapView(SectionObject, TRUE, FALSE);
376
377 if (SectionObject && SectionObject != KmtInvalidPointer)
378 ObDereferenceObject(SectionObject);
379
380 CheckObject(FileHandle1, PointerCount1, 1L);
381 }
382 }
383
384 static
385 VOID
386 TestPhysicalMemorySection(VOID)
387 {
388 NTSTATUS Status;
389 UNICODE_STRING SectionName = RTL_CONSTANT_STRING(L"\\Device\\PhysicalMemory");
390 OBJECT_ATTRIBUTES ObjectAttributes;
391 HANDLE SectionHandle;
392 PVOID SectionObject;
393 PUCHAR MyPage;
394 PHYSICAL_ADDRESS MyPagePhysical;
395 PUCHAR ZeroPageContents;
396 PHYSICAL_ADDRESS ZeroPagePhysical;
397 PVOID Mapping;
398 PUCHAR MappingBytes;
399 SIZE_T ViewSize;
400 SIZE_T EqualBytes;
401
402 MyPage = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'MPmK');
403 if (skip(MyPage != NULL, "Out of memory\n"))
404 return;
405 MyPagePhysical = MmGetPhysicalAddress(MyPage);
406 RtlFillMemory(MyPage + 0 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x23);
407 RtlFillMemory(MyPage + 1 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0x67);
408 RtlFillMemory(MyPage + 2 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xab);
409 RtlFillMemory(MyPage + 3 * PAGE_SIZE / 4, PAGE_SIZE / 4, 0xef);
410
411 ZeroPageContents = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'ZPmK');
412 if (skip(ZeroPageContents != NULL, "Out of memory\n"))
413 {
414 ExFreePoolWithTag(MyPage, 'MPmK');
415 return;
416 }
417 ZeroPagePhysical.QuadPart = 0;
418
419 Mapping = MmMapIoSpace(ZeroPagePhysical, PAGE_SIZE, MmCached);
420 if (skip(Mapping != NULL, "Failed to map zero page\n"))
421 {
422 ExFreePoolWithTag(ZeroPageContents, 'ZPmK');
423 ExFreePoolWithTag(MyPage, 'MPmK');
424 return;
425 }
426
427 RtlCopyMemory(ZeroPageContents, Mapping, PAGE_SIZE);
428 MmUnmapIoSpace(Mapping, PAGE_SIZE);
429
430 InitializeObjectAttributes(&ObjectAttributes,
431 &SectionName,
432 OBJ_KERNEL_HANDLE,
433 NULL,
434 NULL);
435 Status = ZwOpenSection(&SectionHandle, SECTION_ALL_ACCESS, &ObjectAttributes);
436 ok_eq_hex(Status, STATUS_SUCCESS);
437 if (!skip(NT_SUCCESS(Status), "No section\n"))
438 {
439 /* Map zero page and compare */
440 Mapping = NULL;
441 ViewSize = PAGE_SIZE;
442 Status = ZwMapViewOfSection(SectionHandle,
443 ZwCurrentProcess(),
444 &Mapping,
445 0,
446 0,
447 &ZeroPagePhysical,
448 &ViewSize,
449 ViewUnmap,
450 0,
451 PAGE_READWRITE);
452 ok_eq_hex(Status, STATUS_SUCCESS);
453 if (!skip(NT_SUCCESS(Status), "No view\n"))
454 {
455 EqualBytes = RtlCompareMemory(Mapping,
456 ZeroPageContents,
457 PAGE_SIZE);
458 ok_eq_size(EqualBytes, PAGE_SIZE);
459 Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
460 ok_eq_hex(Status, STATUS_SUCCESS);
461 }
462
463 /* Map the zero page non-cached */
464 Mapping = NULL;
465 ViewSize = PAGE_SIZE;
466 Status = ZwMapViewOfSection(SectionHandle,
467 ZwCurrentProcess(),
468 &Mapping,
469 0,
470 0,
471 &ZeroPagePhysical,
472 &ViewSize,
473 ViewUnmap,
474 0,
475 PAGE_READWRITE | PAGE_NOCACHE);
476 ok_eq_hex(Status, STATUS_SUCCESS);
477 if (!skip(NT_SUCCESS(Status), "No view\n"))
478 {
479 EqualBytes = RtlCompareMemory(Mapping,
480 ZeroPageContents,
481 PAGE_SIZE);
482 ok_eq_size(EqualBytes, PAGE_SIZE);
483 Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
484 ok_eq_hex(Status, STATUS_SUCCESS);
485 }
486
487 /* Map our NP page, compare, and check that modifications are reflected */
488 Mapping = NULL;
489 ViewSize = PAGE_SIZE;
490 Status = ZwMapViewOfSection(SectionHandle,
491 ZwCurrentProcess(),
492 &Mapping,
493 0,
494 0,
495 &MyPagePhysical,
496 &ViewSize,
497 ViewUnmap,
498 0,
499 PAGE_READWRITE);
500 ok_eq_hex(Status, STATUS_SUCCESS);
501 if (!skip(NT_SUCCESS(Status), "No view\n"))
502 {
503 EqualBytes = RtlCompareMemory(Mapping,
504 MyPage,
505 PAGE_SIZE);
506 ok_eq_size(EqualBytes, PAGE_SIZE);
507
508 MappingBytes = Mapping;
509 ok(MappingBytes[5] == 0x23, "Mapping[5] = 0x%x\n", MappingBytes[5]);
510 ok(MyPage[5] == 0x23, "MyPage[5] = 0x%x\n", MyPage[5]);
511
512 MyPage[5] = 0x44;
513 ok(MappingBytes[5] == 0x44, "Mapping[5] = 0x%x\n", MappingBytes[5]);
514 ok(MyPage[5] == 0x44, "MyPage[5] = 0x%x\n", MyPage[5]);
515
516 MappingBytes[5] = 0x88;
517 ok(MappingBytes[5] == 0x88, "Mapping[5] = 0x%x\n", MappingBytes[5]);
518 ok(MyPage[5] == 0x88, "MyPage[5] = 0x%x\n", MyPage[5]);
519
520 Status = ZwUnmapViewOfSection(ZwCurrentProcess(), Mapping);
521 ok_eq_hex(Status, STATUS_SUCCESS);
522 }
523
524 Status = ZwClose(SectionHandle);
525 ok_eq_hex(Status, STATUS_SUCCESS);
526 }
527
528 /* Try flag 0x80000000, which ROS calls SEC_PHYSICALMEMORY */
529 InitializeObjectAttributes(&ObjectAttributes,
530 NULL,
531 OBJ_KERNEL_HANDLE,
532 NULL,
533 NULL);
534 Status = ZwCreateSection(&SectionHandle,
535 SECTION_ALL_ACCESS,
536 &ObjectAttributes,
537 NULL,
538 PAGE_READWRITE,
539 0x80000000,
540 NULL);
541 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
542 if (NT_SUCCESS(Status))
543 ZwClose(SectionHandle);
544
545 /* Assertion failure: AllocationAttributes & SEC_IMAGE | SEC_RESERVE | SEC_COMMIT */
546 if (!KmtIsCheckedBuild)
547 {
548 InitializeObjectAttributes(&ObjectAttributes,
549 NULL,
550 OBJ_KERNEL_HANDLE,
551 NULL,
552 NULL);
553 Status = MmCreateSection(&SectionObject,
554 SECTION_ALL_ACCESS,
555 &ObjectAttributes,
556 NULL,
557 PAGE_READWRITE,
558 0x80000000,
559 NULL,
560 NULL);
561 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
562 if (NT_SUCCESS(Status))
563 ObDereferenceObject(SectionObject);
564 }
565
566 InitializeObjectAttributes(&ObjectAttributes,
567 NULL,
568 OBJ_KERNEL_HANDLE,
569 NULL,
570 NULL);
571 Status = MmCreateSection(&SectionObject,
572 SECTION_ALL_ACCESS,
573 &ObjectAttributes,
574 NULL,
575 PAGE_READWRITE,
576 SEC_RESERVE | 0x80000000,
577 NULL,
578 NULL);
579 ok_eq_hex(Status, STATUS_INVALID_PARAMETER_6);
580 if (NT_SUCCESS(Status))
581 ObDereferenceObject(SectionObject);
582
583 ExFreePoolWithTag(ZeroPageContents, 'ZPmK');
584 ExFreePoolWithTag(MyPage, 'MPmK');
585 }
586
587 START_TEST(MmSection)
588 {
589 NTSTATUS Status;
590 HANDLE FileHandle1 = NULL, FileHandle2 = NULL;
591 PFILE_OBJECT FileObject1 = NULL, FileObject2 = NULL;
592 OBJECT_ATTRIBUTES ObjectAttributes;
593 IO_STATUS_BLOCK IoStatusBlock;
594 UNICODE_STRING FileName1 = RTL_CONSTANT_STRING(L"\\SystemRoot\\kmtest-MmSection.txt");
595 UNICODE_STRING FileName2 = RTL_CONSTANT_STRING(L"\\SystemRoot\\system32\\ntdll.dll");
596 LARGE_INTEGER FileOffset;
597 UCHAR FileData = 0;
598
599 ok(ExGetPreviousMode() == UserMode, "Previous mode is kernel mode\n");
600 /* create a one-byte file that we can use */
601 InitializeObjectAttributes(&ObjectAttributes, &FileName1, OBJ_CASE_INSENSITIVE, NULL, NULL);
602 Status = ZwCreateFile(&FileHandle1, GENERIC_WRITE | SYNCHRONIZE, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_SUPERSEDE, FILE_NON_DIRECTORY_FILE, NULL, 0);
603 ok_eq_hex(Status, STATUS_SUCCESS);
604 ok_eq_ulongptr(IoStatusBlock.Information, FILE_CREATED);
605 ok(FileHandle1 != NULL, "FileHandle1 is NULL\n");
606 if (FileHandle1)
607 {
608 FileOffset.QuadPart = 0;
609 Status = ZwWriteFile(FileHandle1, NULL, NULL, NULL, &IoStatusBlock, &FileData, sizeof FileData, &FileOffset, NULL);
610 ok(Status == STATUS_SUCCESS || Status == STATUS_PENDING, "Status = 0x%08lx\n", Status);
611 Status = ZwWaitForSingleObject(FileHandle1, FALSE, NULL);
612 ok_eq_hex(Status, STATUS_SUCCESS);
613 ok_eq_ulongptr(IoStatusBlock.Information, 1);
614 Status = ZwClose(FileHandle1);
615 ok_eq_hex(Status, STATUS_SUCCESS);
616 FileHandle1 = NULL;
617 }
618
619 InitializeObjectAttributes(&ObjectAttributes, &FileName1, OBJ_CASE_INSENSITIVE, NULL, NULL);
620 Status = ZwCreateFile(&FileHandle1, GENERIC_ALL, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE | FILE_DELETE_ON_CLOSE, NULL, 0);
621 ok_eq_hex(Status, STATUS_SUCCESS);
622 ok_eq_ulongptr(IoStatusBlock.Information, FILE_OPENED);
623 ok(FileHandle1 != NULL, "FileHandle1 is NULL\n");
624 CheckObject(FileHandle1, 2L, 1L);
625
626 InitializeObjectAttributes(&ObjectAttributes, &FileName2, OBJ_CASE_INSENSITIVE, NULL, NULL);
627 Status = ZwCreateFile(&FileHandle2, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_NON_DIRECTORY_FILE, NULL, 0);
628 ok_eq_hex(Status, STATUS_SUCCESS);
629 ok_eq_ulongptr(IoStatusBlock.Information, FILE_OPENED);
630 ok(FileHandle2 != NULL, "FileHandle2 is NULL\n");
631
632 if (!skip(Status == STATUS_SUCCESS && FileHandle1 != NULL, "Failed to open file 1\n"))
633 {
634 Status = ObReferenceObjectByHandle(FileHandle1, FILE_READ_DATA | FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID *)&FileObject1, NULL);
635 ok_eq_hex(Status, STATUS_SUCCESS);
636 ok(FileObject1 != NULL, "FileObject1 is NULL\n");
637 CheckObject(FileHandle1, 3L, 1L);
638 }
639
640 if (!skip(Status == STATUS_SUCCESS && FileHandle2 != NULL, "Failed to open file 2\n"))
641 {
642 Status = ObReferenceObjectByHandle(FileHandle2, FILE_READ_DATA | FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID *)&FileObject2, NULL);
643 ok_eq_hex(Status, STATUS_SUCCESS);
644 ok(FileObject2 != NULL, "FileObject2 is NULL\n");
645 }
646
647 trace("FileHandle1=%p, FileObject1=%p\n", FileHandle1, FileObject1);
648 trace("FileHandle2=%p, FileObject2=%p\n", FileHandle2, FileObject2);
649 TestCreateSection(FileHandle1, FileObject1, FileHandle2, FileObject2);
650
651 if (FileObject2)
652 ObDereferenceObject(FileObject2);
653 if (FileObject1)
654 ObDereferenceObject(FileObject1);
655 if (FileHandle2)
656 ZwClose(FileHandle2);
657 if (FileHandle1)
658 ZwClose(FileHandle1);
659
660 TestPhysicalMemorySection();
661 }