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");
84 if (!skip(*WriteOnlyFile
!= NULL
, "No WriteOnlyFile\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 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_9
, STATUS_SUCCESS
);
201 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, (MEM_RESERVE
| MEM_COMMIT
), PAGE_READWRITE
, STATUS_INVALID_PARAMETER_9
, IGNORE
);
202 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, (MEM_LARGE_PAGES
| MEM_RESERVE
), PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
205 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
206 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
, STATUS_SUCCESS
, STATUS_SUCCESS
);
207 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE_WRITECOPY
, STATUS_SECTION_PROTECTION
, IGNORE
);
208 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SECTION_PROTECTION
, IGNORE
);
209 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_WRITECOPY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
210 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE_READ
, STATUS_SECTION_PROTECTION
, IGNORE
);
211 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE
, STATUS_SECTION_PROTECTION
, IGNORE
);
212 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
213 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
, STATUS_SUCCESS
, STATUS_SUCCESS
);
214 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, (PAGE_READWRITE
| PAGE_READONLY
), STATUS_INVALID_PAGE_PROTECTION
, IGNORE
);
215 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READONLY
, STATUS_SECTION_PROTECTION
, IGNORE
);
217 ZwClose(WriteSectionHandle
);
218 ZwClose(PageFileSectionHandle
);
219 ZwClose(ReadOnlySection
);
225 AdvancedErrorChecks(HANDLE FileHandleReadOnly
, HANDLE FileHandleWriteOnly
)
229 HANDLE FileSectionHandle
;
230 LARGE_INTEGER SectionOffset
;
231 LARGE_INTEGER MaximumSize
;
235 MaximumSize
.QuadPart
= TestStringSize
;
236 //Used for parameters working on file-based section
237 Status
= ZwCreateSection(&FileSectionHandle
, SECTION_ALL_ACCESS
, NULL
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, FileHandleWriteOnly
);
238 ok_eq_hex(Status
, STATUS_SUCCESS
);
240 Status
= ObReferenceObjectByHandle(FileSectionHandle
,
247 ok_eq_hex(Status
, STATUS_SUCCESS
);
249 //Bypassing Zw function calls mean bypassing the alignment checks which are not crucial for the branches being tested here
251 //test first conditional branch
253 MmTestMapView(SectionObject
, PsGetCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
255 //test second conditional branch
257 SectionOffset
.QuadPart
= TestStringSize
;
258 MmTestMapView(SectionObject
, PsGetCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
260 ObDereferenceObject(SectionObject
);
261 ZwClose(FileSectionHandle
);
266 CompareFileContents(HANDLE FileHandle
, ULONG BufferLength
, PVOID Buffer
)
269 LARGE_INTEGER ByteOffset
;
270 IO_STATUS_BLOCK IoStatusBlock
;
275 ByteOffset
.QuadPart
= 0;
277 FileContent
= ExAllocatePoolWithTag(PagedPool
, BufferLength
, 'Test');
278 if (!skip((FileContent
!= NULL
), "Error allocating memory for FileContent\n"))
280 Status
= ZwReadFile(FileHandle
, NULL
, NULL
, NULL
, &IoStatusBlock
, FileContent
, BufferLength
, &ByteOffset
, NULL
);
281 ok_eq_hex(Status
, STATUS_SUCCESS
);
282 ok_eq_ulongptr(IoStatusBlock
.Information
, BufferLength
);
285 Match
= RtlCompareMemory(FileContent
, Buffer
, BufferLength
);
286 ExFreePoolWithTag(FileContent
, 'Test');
296 SystemProcessWorker(PVOID StartContext
)
300 HANDLE SectionHandle
;
303 LARGE_INTEGER SectionOffset
;
304 OBJECT_ATTRIBUTES ObjectAttributes
;
306 UNREFERENCED_PARAMETER(StartContext
);
309 ViewSize
= TestStringSize
;
310 SectionOffset
.QuadPart
= 0;
312 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
313 Status
= ZwOpenSection(&SectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
);
314 if (!skip(NT_SUCCESS(Status
), "Error acquiring handle to section. Error = %p\n", Status
))
316 CheckObject(SectionHandle
, 4, 2);
317 Status
= ZwMapViewOfSection(SectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
319 //make sure ZwMapViewofSection doesn't touch the section ref counts.
320 CheckObject(SectionHandle
, 4, 2);
322 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view in system process. Error = %p\n", Status
))
324 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
325 ok_eq_size(Match
, TestStringSize
);
327 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
328 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
330 //make sure ZwMapViewofSection doesn't touch the section ref counts.
331 CheckObject(SectionHandle
, 4, 2);
334 ZwClose(SectionHandle
);
337 PsTerminateSystemThread(STATUS_SUCCESS
);
343 BehaviorChecks(HANDLE FileHandleReadOnly
, HANDLE FileHandleWriteOnly
)
346 PVOID BaseAddress
= NULL
;
348 HANDLE WriteSectionHandle
;
349 HANDLE SysThreadHandle
;
350 OBJECT_ATTRIBUTES ObjectAttributes
;
351 LARGE_INTEGER SectionOffset
;
352 LARGE_INTEGER MaximumSize
;
356 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
357 MaximumSize
.QuadPart
= TestStringSize
;
358 SectionOffset
.QuadPart
= 0;
360 Status
= ZwCreateSection(&WriteSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, FileHandleWriteOnly
);
361 CheckObject(WriteSectionHandle
, 3, 1);
362 ok(NT_SUCCESS(Status
), "Error creating write section from file. Error = %p\n", Status
);
364 //check for section reading/writing by comparing section content to a well-known value.
365 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess() ,&BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
366 CheckObject(WriteSectionHandle
, 3, 1);
367 if (!skip(NT_SUCCESS(Status
), "Error mapping view with READ/WRITE priv. Error = %p\n", Status
))
369 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
370 ok_eq_size(Match
, TestStringSize
);
372 //now check writing to section
373 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
375 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
376 ok_eq_size(Match
, NEW_CONTENT_LEN
);
378 //check to see if the contents have been flushed to the actual file on disk.
379 Match
= CompareFileContents(FileHandleWriteOnly
, NEW_CONTENT_LEN
, NEW_CONTENT
);
380 ok_eq_size(Match
, NEW_CONTENT_LEN
);
382 //bring everything back to normal
383 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
385 //Initiate an external thread to modify the file
386 InitializeObjectAttributes(&ObjectAttributes
, NULL
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
387 Status
= PsCreateSystemThread(&SysThreadHandle
, STANDARD_RIGHTS_ALL
, &ObjectAttributes
, NULL
, NULL
, SystemProcessWorker
, NULL
);
388 if (!skip(NT_SUCCESS(Status
), "Error creating System thread. Error = %p\n", Status
))
390 Status
= ObReferenceObjectByHandle(SysThreadHandle
, THREAD_ALL_ACCESS
, *PsThreadType
, KernelMode
, &ThreadObject
, NULL
);
391 if (!skip(NT_SUCCESS(Status
), "Error getting reference to System thread when testing file-backed section\n"))
393 //wait until the system thread actually terminates
394 KeWaitForSingleObject(ThreadObject
, Executive
, KernelMode
, FALSE
, NULL
);
396 //no longer need the thread object
397 ObDereferenceObject(ThreadObject
);
399 //test for bi-directional access to the shared page file
400 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
401 ok_eq_size(Match
, NEW_CONTENT_LEN
);
403 //bring everything back to normal, again
404 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
408 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
411 //Try to write to read-only mapped view
414 SectionOffset
.QuadPart
= 0;
415 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
);
416 if (!skip(NT_SUCCESS(Status
), "Error mapping view with READ priv. Error = %p\n", Status
))
418 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
419 ok_eq_size(Match
, TestStringSize
);
422 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
423 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
425 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
428 /* FIXME: Crash. See ROSTESTS-110 */
429 #ifdef ROSTESTS_110_FIXED
430 //try to access forbidden memory
433 SectionOffset
.QuadPart
= 0;
434 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
);
435 if (!skip(NT_SUCCESS(Status
), "Error mapping view with PAGE_NOACCESS priv. Error = %p\n", Status
))
438 RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
439 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
441 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
443 #endif /* ROSTESTS_110_FIXED */
445 ZwClose(WriteSectionHandle
);
447 //section created with sec_reserve should not be commited.
450 SectionOffset
.QuadPart
= 0;
451 Status
= ZwCreateSection(&WriteSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaximumSize
, PAGE_READWRITE
, SEC_RESERVE
, FileHandleWriteOnly
);
452 if (!skip(NT_SUCCESS(Status
), "Error creating page file section. Error = %p\n", Status
))
454 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
);
455 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view. Error = %p\n", Status
))
457 //check also the SEC_COMMIT flag
458 /* This test proves that MSDN is once again wrong
459 * msdn.microsoft.com/en-us/library/windows/hardware/aa366537.aspx states that SEC_RESERVE
460 * should cause the allocated memory for the view to be reserved but in fact it is always committed.
461 * It fails also on windows.
463 Test_NtQueryVirtualMemory(BaseAddress
, PAGE_SIZE
, MEM_COMMIT
, PAGE_READWRITE
);
464 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
467 ZwClose(WriteSectionHandle
);
474 PageFileBehaviorChecks()
477 LARGE_INTEGER MaxSectionSize
;
478 LARGE_INTEGER SectionOffset
;
479 HANDLE PageFileSectionHandle
;
484 OBJECT_ATTRIBUTES ObjectAttributes
;
486 MaxSectionSize
.QuadPart
= TestStringSize
;
487 SectionOffset
.QuadPart
= 0;
488 PageFileSectionHandle
= INVALID_HANDLE_VALUE
;
490 ViewSize
= TestStringSize
;
491 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
493 //test memory sharing between 2 different processes
494 Status
= ZwCreateSection(&PageFileSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaxSectionSize
, PAGE_READWRITE
, SEC_COMMIT
, NULL
);
495 if (!skip(NT_SUCCESS(Status
), "Error creating page file section. Error = %p\n", Status
))
497 CheckObject(PageFileSectionHandle
, 3, 1);
498 Status
= ZwMapViewOfSection(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
499 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view. Error = %p\n", Status
))
501 HANDLE SysThreadHandle
;
503 CheckObject(PageFileSectionHandle
, 3, 1);
505 //check also the SEC_COMMIT flag
506 Test_NtQueryVirtualMemory(BaseAddress
, PAGE_SIZE
, MEM_COMMIT
, PAGE_READWRITE
);
508 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
510 InitializeObjectAttributes(&ObjectAttributes
, NULL
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
511 Status
= PsCreateSystemThread(&SysThreadHandle
, STANDARD_RIGHTS_ALL
, &ObjectAttributes
, NULL
, NULL
, SystemProcessWorker
, NULL
);
513 if (!skip(NT_SUCCESS(Status
), "Error creating System thread. Error = %p\n", Status
))
515 Status
= ObReferenceObjectByHandle(SysThreadHandle
, THREAD_ALL_ACCESS
, *PsThreadType
, KernelMode
, &ThreadObject
, NULL
);
516 if (!skip(NT_SUCCESS(Status
), "Error getting reference to System thread when testing pagefile-backed section\n"))
518 //wait until the system thread actually terminates
519 KeWaitForSingleObject(ThreadObject
, Executive
, KernelMode
, FALSE
, NULL
);
521 //no longer need the thread object
522 ObDereferenceObject(ThreadObject
);
524 //test for bi-directional access to the shared page file
525 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
526 ok_eq_size(Match
, NEW_CONTENT_LEN
);
529 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
531 ZwClose(PageFileSectionHandle
);
536 START_TEST(ZwMapViewOfSection
)
538 HANDLE FileHandleReadOnly
= NULL
;
539 HANDLE FileHandleWriteOnly
= NULL
;
540 HANDLE ExecutableFileHandle
= NULL
;
542 InitializeObjectAttributes(&NtdllObject
, &FileReadOnlyPath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
543 InitializeObjectAttributes(&KmtestFileObject
, &WritableFilePath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
544 InitializeObjectAttributes(&NtoskrnlFileObject
, &NtosImgPath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
546 KmtInitTestFiles(&FileHandleReadOnly
, &FileHandleWriteOnly
, &ExecutableFileHandle
);
548 SimpleErrorChecks(FileHandleReadOnly
, FileHandleWriteOnly
, ExecutableFileHandle
);
549 AdvancedErrorChecks(FileHandleReadOnly
, FileHandleWriteOnly
);
550 BehaviorChecks(FileHandleReadOnly
, FileHandleWriteOnly
);
551 PageFileBehaviorChecks();
553 if (FileHandleReadOnly
)
554 ZwClose(FileHandleReadOnly
);
556 if (FileHandleWriteOnly
)
557 ZwClose(FileHandleWriteOnly
);
559 if (ExecutableFileHandle
)
560 ZwClose(ExecutableFileHandle
);