2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: GPLv2+ - See COPYING in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite ZwMapViewOfSection
5 * PROGRAMMER: Nikolay Borisov <nib9@aber.ac.uk>
11 #define NEW_CONTENT "NewContent"
12 #define NEW_CONTENT_LEN sizeof(NEW_CONTENT)
14 static UNICODE_STRING FileReadOnlyPath
= RTL_CONSTANT_STRING(L
"\\SystemRoot\\system32\\ntdll.dll");
15 static UNICODE_STRING NtosImgPath
= RTL_CONSTANT_STRING(L
"\\SystemRoot\\system32\\ntoskrnl.exe");
16 static UNICODE_STRING WritableFilePath
= RTL_CONSTANT_STRING(L
"\\SystemRoot\\kmtest-MmSection.txt");
17 static UNICODE_STRING SharedSectionName
= RTL_CONSTANT_STRING(L
"\\BaseNamedObjects\\kmtest-SharedSection");
18 extern const char TestString
[];
19 extern const ULONG TestStringSize
;
20 static OBJECT_ATTRIBUTES NtdllObject
;
21 static OBJECT_ATTRIBUTES KmtestFileObject
;
22 static OBJECT_ATTRIBUTES NtoskrnlFileObject
;
24 #define TestMapView(SectionHandle, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect, MapStatus, UnmapStatus) do \
26 Status = ZwMapViewOfSection(SectionHandle, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect); \
27 ok_eq_hex(Status, MapStatus); \
28 if (NT_SUCCESS(Status)) \
30 Status = ZwUnmapViewOfSection(ProcessHandle, BaseAddress); \
31 if (UnmapStatus != IGNORE) ok_eq_hex(Status, UnmapStatus); \
32 *BaseAddress2 = NULL; \
37 #define MmTestMapView(Object, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect, MapStatus, UnmapStatus) do \
39 Status = MmMapViewOfSection(Object, ProcessHandle, BaseAddress2, ZeroBits, CommitSize, SectionOffset, ViewSize2, InheritDisposition, AllocationType, Win32Protect); \
40 ok_eq_hex(Status, MapStatus); \
41 if (NT_SUCCESS(Status)) \
43 Status = MmUnmapViewOfSection(ProcessHandle, BaseAddress); \
44 if (UnmapStatus != IGNORE) ok_eq_hex(Status, UnmapStatus); \
45 *BaseAddress2 = NULL; \
50 #define CheckObject(Handle, Pointers, Handles) do \
52 PUBLIC_OBJECT_BASIC_INFORMATION ObjectInfo; \
53 Status = ZwQueryObject(Handle, ObjectBasicInformation, \
54 &ObjectInfo, sizeof ObjectInfo, NULL); \
55 ok_eq_hex(Status, STATUS_SUCCESS); \
56 ok_eq_ulong(ObjectInfo.PointerCount, Pointers); \
57 ok_eq_ulong(ObjectInfo.HandleCount, Handles); \
62 KmtInitTestFiles(PHANDLE ReadOnlyFile
, PHANDLE WriteOnlyFile
, PHANDLE ExecutableFile
)
65 LARGE_INTEGER FileOffset
;
66 IO_STATUS_BLOCK IoStatusBlock
;
68 //INIT THE READ-ONLY FILE
69 Status
= ZwCreateFile(ReadOnlyFile
, GENERIC_READ
, &NtdllObject
, &IoStatusBlock
, NULL
, FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
, FILE_OPEN
, FILE_NON_DIRECTORY_FILE
, NULL
, 0);
70 ok_eq_hex(Status
, STATUS_SUCCESS
);
71 ok(*ReadOnlyFile
!= NULL
, "Couldn't acquire READONLY handle\n");
73 //INIT THE EXECUTABLE FILE
74 Status
= ZwCreateFile(ExecutableFile
, GENERIC_EXECUTE
, &NtdllObject
, &IoStatusBlock
, NULL
, FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_READ
, FILE_OPEN
, FILE_NON_DIRECTORY_FILE
, NULL
, 0);
75 ok_eq_hex(Status
, STATUS_SUCCESS
);
76 ok(*ExecutableFile
!= NULL
, "Couldn't acquire EXECUTE handle\n");
78 //INIT THE WRITE-ONLY FILE
79 //TODO: Delete the file when the tests are all executed
80 Status
= ZwCreateFile(WriteOnlyFile
, (GENERIC_WRITE
| SYNCHRONIZE
), &KmtestFileObject
, &IoStatusBlock
, NULL
, FILE_ATTRIBUTE_NORMAL
, FILE_SHARE_WRITE
, FILE_SUPERSEDE
, (FILE_NON_DIRECTORY_FILE
| FILE_DELETE_ON_CLOSE
), NULL
, 0);
81 ok_eq_hex(Status
, STATUS_SUCCESS
);
82 ok_eq_ulongptr(IoStatusBlock
.Information
, FILE_CREATED
);
83 ok(*WriteOnlyFile
!= NULL
, "WriteOnlyFile is NULL\n");
86 FileOffset
.QuadPart
= 0;
87 Status
= ZwWriteFile(*WriteOnlyFile
, NULL
, NULL
, NULL
, &IoStatusBlock
, (PVOID
)TestString
, TestStringSize
, &FileOffset
, NULL
);
88 ok(Status
== STATUS_SUCCESS
|| Status
== STATUS_PENDING
, "Status = 0x%08lx\n", Status
);
89 Status
= ZwWaitForSingleObject(*WriteOnlyFile
, FALSE
, NULL
);
90 ok_eq_hex(Status
, STATUS_SUCCESS
);
91 ok_eq_ulongptr(IoStatusBlock
.Information
, TestStringSize
);
97 SimpleErrorChecks(HANDLE FileHandleReadOnly
, HANDLE FileHandleWriteOnly
, HANDLE ExecutableImg
)
100 HANDLE WriteSectionHandle
;
101 HANDLE ReadOnlySection
;
102 HANDLE PageFileSectionHandle
;
103 LARGE_INTEGER MaximumSize
;
104 LARGE_INTEGER SectionOffset
;
105 SIZE_T AllocSize
= TestStringSize
;
107 PVOID BaseAddress
= NULL
;
108 PVOID AllocBase
= NULL
;
109 MaximumSize
.QuadPart
= TestStringSize
;
111 //Used for parameters working on file-based section
112 Status
= ZwCreateSection(&WriteSectionHandle
, SECTION_ALL_ACCESS
, NULL
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, FileHandleWriteOnly
);
113 ok_eq_hex(Status
, STATUS_SUCCESS
);
115 Status
= ZwCreateSection(&ReadOnlySection
, SECTION_ALL_ACCESS
, NULL
, &MaximumSize
, PAGE_READONLY
, SEC_COMMIT
, FileHandleReadOnly
);
116 ok_eq_hex(Status
, STATUS_SUCCESS
);
118 //Used for parameters taking effect only on page-file backed section
119 MaximumSize
.QuadPart
= 5 * MM_ALLOCATION_GRANULARITY
;
120 Status
= ZwCreateSection(&PageFileSectionHandle
, SECTION_ALL_ACCESS
, NULL
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, NULL
);
121 ok_eq_hex(Status
, STATUS_SUCCESS
);
123 MaximumSize
.QuadPart
= TestStringSize
;
126 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
127 TestMapView((HANDLE
)0xDEADBEEF, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_HANDLE
, IGNORE
);
128 TestMapView(INVALID_HANDLE_VALUE
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_OBJECT_TYPE_MISMATCH
, IGNORE
);
129 TestMapView(NULL
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_HANDLE
, IGNORE
);
132 TestMapView(WriteSectionHandle
, (HANDLE
)0xDEADBEEF, &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_HANDLE
, IGNORE
);
133 TestMapView(WriteSectionHandle
, (HANDLE
)NULL
, &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_HANDLE
, IGNORE
);
136 BaseAddress
= (PVOID
)0x00567A20;
137 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_MAPPED_ALIGNMENT
, IGNORE
);
139 BaseAddress
= (PVOID
) 0x60000000;
140 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
142 BaseAddress
= (PVOID
)((char *)MmSystemRangeStart
+ 200);
143 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_3
, IGNORE
);
145 //try mapping section to an already mapped address
146 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(), &AllocBase
, 0, &AllocSize
, MEM_COMMIT
, PAGE_READWRITE
);
147 if (!skip(NT_SUCCESS(Status
), "Cannot allocate memory\n"))
149 BaseAddress
= AllocBase
;
150 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_CONFLICTING_ADDRESSES
, IGNORE
);
151 Status
= ZwFreeVirtualMemory(NtCurrentProcess(), &AllocBase
, &AllocSize
, MEM_RELEASE
);
152 ok_eq_hex(Status
, STATUS_SUCCESS
);
156 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 1, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
157 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 5, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
158 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, -1, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_4
, IGNORE
);
159 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 20, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_NO_MEMORY
, IGNORE
);
160 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 21, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_NO_MEMORY
, IGNORE
);
161 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 22, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_4
, IGNORE
);
164 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
165 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
166 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, -1, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_5
, IGNORE
);
167 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0x10000000, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_5
, IGNORE
);
168 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_5
, IGNORE
);
169 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
172 SectionOffset
.QuadPart
= 0;
173 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
174 ok_eq_ulonglong(SectionOffset
.QuadPart
, 0);
176 SectionOffset
.QuadPart
= 0x00040211; //MSDN is wrong, in w2k3 the ZwMapViewOfSection doesn't align offsets automatically
177 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_MAPPED_ALIGNMENT
, IGNORE
);
179 SectionOffset
.QuadPart
= -1;
180 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_MAPPED_ALIGNMENT
, IGNORE
);
183 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
186 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_3
, IGNORE
);
188 ViewSize
= TestStringSize
+1;
189 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
190 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
192 ViewSize
= TestStringSize
;
193 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
195 ViewSize
= TestStringSize
-1;
196 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
199 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
200 /* FIXME: Fails ASSERT((AllocationType & MEM_RESERVE) == 0) in MmMapViewOfArm3Section. See ROSTESTS-109 */
201 #ifdef ROSTESTS_109_FIXED
202 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_9
, STATUS_SUCCESS
);
203 #endif /* ROSTESTS_109_FIXED */
204 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, (MEM_RESERVE
| MEM_COMMIT
), PAGE_READWRITE
, STATUS_INVALID_PARAMETER_9
, IGNORE
);
205 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, (MEM_LARGE_PAGES
| MEM_RESERVE
), PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
208 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
209 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
, STATUS_SUCCESS
, STATUS_SUCCESS
);
210 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE_WRITECOPY
, STATUS_SECTION_PROTECTION
, IGNORE
);
211 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SECTION_PROTECTION
, IGNORE
);
212 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_WRITECOPY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
213 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE_READ
, STATUS_SECTION_PROTECTION
, IGNORE
);
214 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE
, STATUS_SECTION_PROTECTION
, IGNORE
);
215 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
216 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
, STATUS_SUCCESS
, STATUS_SUCCESS
);
217 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, (PAGE_READWRITE
| PAGE_READONLY
), STATUS_INVALID_PAGE_PROTECTION
, IGNORE
);
218 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READONLY
, STATUS_SECTION_PROTECTION
, IGNORE
);
220 ZwClose(WriteSectionHandle
);
221 ZwClose(PageFileSectionHandle
);
222 ZwClose(ReadOnlySection
);
228 AdvancedErrorChecks(HANDLE FileHandleReadOnly
, HANDLE FileHandleWriteOnly
)
232 HANDLE FileSectionHandle
;
233 LARGE_INTEGER SectionOffset
;
234 LARGE_INTEGER MaximumSize
;
238 MaximumSize
.QuadPart
= TestStringSize
;
239 //Used for parameters working on file-based section
240 Status
= ZwCreateSection(&FileSectionHandle
, SECTION_ALL_ACCESS
, NULL
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, FileHandleWriteOnly
);
241 ok_eq_hex(Status
, STATUS_SUCCESS
);
243 Status
= ObReferenceObjectByHandle(FileSectionHandle
,
250 ok_eq_hex(Status
, STATUS_SUCCESS
);
252 //Bypassing Zw function calls mean bypassing the alignment checks which are not crucial for the branches being tested here
254 //test first conditional branch
256 MmTestMapView(SectionObject
, PsGetCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
258 //test second conditional branch
260 SectionOffset
.QuadPart
= TestStringSize
;
261 MmTestMapView(SectionObject
, PsGetCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
263 ObDereferenceObject(SectionObject
);
264 ZwClose(FileSectionHandle
);
269 CompareFileContents(HANDLE FileHandle
, ULONG BufferLength
, PVOID Buffer
)
272 LARGE_INTEGER ByteOffset
;
273 IO_STATUS_BLOCK IoStatusBlock
;
278 ByteOffset
.QuadPart
= 0;
280 FileContent
= ExAllocatePoolWithTag(PagedPool
, BufferLength
, 'Test');
281 if (!skip((FileContent
!= NULL
), "Error allocating memory for FileContent\n"))
283 Status
= ZwReadFile(FileHandle
, NULL
, NULL
, NULL
, &IoStatusBlock
, FileContent
, BufferLength
, &ByteOffset
, NULL
);
284 ok_eq_hex(Status
, STATUS_SUCCESS
);
285 ok_eq_ulongptr(IoStatusBlock
.Information
, BufferLength
);
288 Match
= RtlCompareMemory(FileContent
, Buffer
, BufferLength
);
289 ExFreePoolWithTag(FileContent
, 'Test');
299 SystemProcessWorker(PVOID StartContext
)
303 HANDLE SectionHandle
;
306 LARGE_INTEGER SectionOffset
;
307 OBJECT_ATTRIBUTES ObjectAttributes
;
309 UNREFERENCED_PARAMETER(StartContext
);
312 ViewSize
= TestStringSize
;
313 SectionOffset
.QuadPart
= 0;
315 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
316 Status
= ZwOpenSection(&SectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
);
317 if (!skip(NT_SUCCESS(Status
), "Error acquiring handle to section. Error = %p\n", Status
))
319 CheckObject(SectionHandle
, 4, 2);
320 Status
= ZwMapViewOfSection(SectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
322 //make sure ZwMapViewofSection doesn't touch the section ref counts.
323 CheckObject(SectionHandle
, 4, 2);
325 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view in system process. Error = %p\n", Status
))
327 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
328 ok_eq_size(Match
, TestStringSize
);
330 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
331 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
333 //make sure ZwMapViewofSection doesn't touch the section ref counts.
334 CheckObject(SectionHandle
, 4, 2);
337 ZwClose(SectionHandle
);
340 PsTerminateSystemThread(STATUS_SUCCESS
);
346 BehaviorChecks(HANDLE FileHandleReadOnly
, HANDLE FileHandleWriteOnly
)
349 PVOID BaseAddress
= NULL
;
351 HANDLE WriteSectionHandle
;
352 HANDLE SysThreadHandle
;
353 OBJECT_ATTRIBUTES ObjectAttributes
;
354 LARGE_INTEGER SectionOffset
;
355 LARGE_INTEGER MaximumSize
;
359 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
360 MaximumSize
.QuadPart
= TestStringSize
;
361 SectionOffset
.QuadPart
= 0;
363 Status
= ZwCreateSection(&WriteSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, FileHandleWriteOnly
);
364 CheckObject(WriteSectionHandle
, 3, 1);
365 ok(NT_SUCCESS(Status
), "Error creating write section from file. Error = %p\n", Status
);
367 //check for section reading/writing by comparing section content to a well-known value.
368 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess() ,&BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
369 CheckObject(WriteSectionHandle
, 3, 1);
370 if (!skip(NT_SUCCESS(Status
), "Error mapping view with READ/WRITE priv. Error = %p\n", Status
))
372 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
373 ok_eq_size(Match
, TestStringSize
);
375 //now check writing to section
376 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
378 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
379 ok_eq_size(Match
, NEW_CONTENT_LEN
);
381 //check to see if the contents have been flushed to the actual file on disk.
382 Match
= CompareFileContents(FileHandleWriteOnly
, NEW_CONTENT_LEN
, NEW_CONTENT
);
383 ok_eq_size(Match
, NEW_CONTENT_LEN
);
385 //bring everything back to normal
386 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
388 //Initiate an external thread to modify the file
389 InitializeObjectAttributes(&ObjectAttributes
, NULL
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
390 Status
= PsCreateSystemThread(&SysThreadHandle
, STANDARD_RIGHTS_ALL
, &ObjectAttributes
, NULL
, NULL
, SystemProcessWorker
, NULL
);
391 if (!skip(NT_SUCCESS(Status
), "Error creating System thread. Error = %p\n", Status
))
393 Status
= ObReferenceObjectByHandle(SysThreadHandle
, THREAD_ALL_ACCESS
, PsThreadType
, KernelMode
, &ThreadObject
, NULL
);
394 if (!skip(NT_SUCCESS(Status
), "Error getting reference to System thread when testing file-backed section\n"))
396 //wait until the system thread actually terminates
397 KeWaitForSingleObject(ThreadObject
, Executive
, KernelMode
, FALSE
, NULL
);
399 //no longer need the thread object
400 ObDereferenceObject(ThreadObject
);
402 //test for bi-directional access to the shared page file
403 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
404 ok_eq_size(Match
, NEW_CONTENT_LEN
);
406 //bring everything back to normal, again
407 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
411 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
414 //Try to write to read-only mapped view
417 SectionOffset
.QuadPart
= 0;
418 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
);
419 if (!skip(NT_SUCCESS(Status
), "Error mapping view with READ priv. Error = %p\n", Status
))
421 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
422 ok_eq_size(Match
, TestStringSize
);
425 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
426 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
428 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
431 /* FIXME: Crash. See ROSTESTS-110 */
432 #ifdef ROSTESTS_110_FIXED
433 //try to access forbidden memory
436 SectionOffset
.QuadPart
= 0;
437 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
);
438 if (!skip(NT_SUCCESS(Status
), "Error mapping view with PAGE_NOACCESS priv. Error = %p\n", Status
))
441 RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
442 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
444 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
446 #endif /* ROSTESTS_110_FIXED */
448 ZwClose(WriteSectionHandle
);
450 //section created with sec_reserve should not be commited.
453 SectionOffset
.QuadPart
= 0;
454 Status
= ZwCreateSection(&WriteSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaximumSize
, PAGE_READWRITE
, SEC_RESERVE
, FileHandleWriteOnly
);
455 if (!skip(NT_SUCCESS(Status
), "Error creating page file section. Error = %p\n", Status
))
457 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
);
458 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view. Error = %p\n", Status
))
460 //check also the SEC_COMMIT flag
461 /* This test proves that MSDN is once again wrong
462 * msdn.microsoft.com/en-us/library/windows/hardware/aa366537.aspx states that SEC_RESERVE
463 * should cause the allocated memory for the view to be reserved but in fact it is always committed.
464 * It fails also on windows.
466 Test_NtQueryVirtualMemory(BaseAddress
, PAGE_SIZE
, MEM_COMMIT
, PAGE_READWRITE
);
467 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
470 ZwClose(WriteSectionHandle
);
477 PageFileBehaviorChecks()
480 LARGE_INTEGER MaxSectionSize
;
481 LARGE_INTEGER SectionOffset
;
482 HANDLE PageFileSectionHandle
;
487 OBJECT_ATTRIBUTES ObjectAttributes
;
489 MaxSectionSize
.QuadPart
= TestStringSize
;
490 SectionOffset
.QuadPart
= 0;
491 PageFileSectionHandle
= INVALID_HANDLE_VALUE
;
493 ViewSize
= TestStringSize
;
494 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
496 //test memory sharing between 2 different processes
497 Status
= ZwCreateSection(&PageFileSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaxSectionSize
, PAGE_READWRITE
, SEC_COMMIT
, NULL
);
498 if (!skip(NT_SUCCESS(Status
), "Error creating page file section. Error = %p\n", Status
))
500 CheckObject(PageFileSectionHandle
, 3, 1);
501 Status
= ZwMapViewOfSection(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
502 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view. Error = %p\n", Status
))
504 HANDLE SysThreadHandle
;
506 CheckObject(PageFileSectionHandle
, 3, 1);
508 //check also the SEC_COMMIT flag
509 Test_NtQueryVirtualMemory(BaseAddress
, PAGE_SIZE
, MEM_COMMIT
, PAGE_READWRITE
);
511 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
513 InitializeObjectAttributes(&ObjectAttributes
, NULL
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
514 Status
= PsCreateSystemThread(&SysThreadHandle
, STANDARD_RIGHTS_ALL
, &ObjectAttributes
, NULL
, NULL
, SystemProcessWorker
, NULL
);
516 if (!skip(NT_SUCCESS(Status
), "Error creating System thread. Error = %p\n", Status
))
518 Status
= ObReferenceObjectByHandle(SysThreadHandle
, THREAD_ALL_ACCESS
, PsThreadType
, KernelMode
, &ThreadObject
, NULL
);
519 if (!skip(NT_SUCCESS(Status
), "Error getting reference to System thread when testing pagefile-backed section\n"))
521 //wait until the system thread actually terminates
522 KeWaitForSingleObject(ThreadObject
, Executive
, KernelMode
, FALSE
, NULL
);
524 //no longer need the thread object
525 ObDereferenceObject(ThreadObject
);
527 //test for bi-directional access to the shared page file
528 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
529 ok_eq_size(Match
, NEW_CONTENT_LEN
);
532 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
534 ZwClose(PageFileSectionHandle
);
539 START_TEST(ZwMapViewOfSection
)
541 HANDLE FileHandleReadOnly
= NULL
;
542 HANDLE FileHandleWriteOnly
= NULL
;
543 HANDLE ExecutableFileHandle
= NULL
;
545 InitializeObjectAttributes(&NtdllObject
, &FileReadOnlyPath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
546 InitializeObjectAttributes(&KmtestFileObject
, &WritableFilePath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
547 InitializeObjectAttributes(&NtoskrnlFileObject
, &NtosImgPath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
549 KmtInitTestFiles(&FileHandleReadOnly
, &FileHandleWriteOnly
, &ExecutableFileHandle
);
551 SimpleErrorChecks(FileHandleReadOnly
, FileHandleWriteOnly
, ExecutableFileHandle
);
552 AdvancedErrorChecks(FileHandleReadOnly
, FileHandleWriteOnly
);
553 BehaviorChecks(FileHandleReadOnly
, FileHandleWriteOnly
);
554 PageFileBehaviorChecks();
556 if (FileHandleReadOnly
)
557 ZwClose(FileHandleReadOnly
);
559 if (FileHandleWriteOnly
)
560 ZwClose(FileHandleWriteOnly
);
562 if (ExecutableFileHandle
)
563 ZwClose(ExecutableFileHandle
);