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
)(ULONG_PTR
)0xDEADBEEFDEADBEEFull
, 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
)(ULONG_PTR
)0xDEADBEEFDEADBEEFull
, &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
)(ULONG_PTR
)0x00567A20;
137 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_MAPPED_ALIGNMENT
, IGNORE
);
139 BaseAddress
= (PVOID
)(ULONG_PTR
)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 //invalid section handle AND unaligned base address
146 BaseAddress
= (PVOID
)(ULONG_PTR
)0x00567A20;
147 TestMapView((HANDLE
)(ULONG_PTR
)0xDEADBEEFDEADBEEFull
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_HANDLE
, IGNORE
);
149 //invalid process handle AND unaligned base address
150 BaseAddress
= (PVOID
)(ULONG_PTR
)0x00567A20;
151 TestMapView(WriteSectionHandle
, (HANDLE
)(ULONG_PTR
)0xDEADBEEFDEADBEEFull
, &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_HANDLE
, IGNORE
);
153 //try mapping section to an already mapped address
154 Status
= ZwAllocateVirtualMemory(NtCurrentProcess(), &AllocBase
, 0, &AllocSize
, MEM_COMMIT
, PAGE_READWRITE
);
155 if (!skip(NT_SUCCESS(Status
), "Cannot allocate memory\n"))
157 BaseAddress
= AllocBase
;
158 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_CONFLICTING_ADDRESSES
, IGNORE
);
159 Status
= ZwFreeVirtualMemory(NtCurrentProcess(), &AllocBase
, &AllocSize
, MEM_RELEASE
);
160 ok_eq_hex(Status
, STATUS_SUCCESS
);
164 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 1, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
165 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 5, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
166 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, -1, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_4
, IGNORE
);
167 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 20, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_NO_MEMORY
, IGNORE
);
168 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 21, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_NO_MEMORY
, IGNORE
);
169 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 22, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_4
, IGNORE
);
172 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
173 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
174 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, -1, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_5
, IGNORE
);
175 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0x10000000, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_5
, IGNORE
);
176 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_5
, IGNORE
);
177 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
180 SectionOffset
.QuadPart
= 0;
181 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
182 ok_eq_ulonglong(SectionOffset
.QuadPart
, 0);
184 SectionOffset
.QuadPart
= 0x00040211; //MSDN is wrong, in w2k3 the ZwMapViewOfSection doesn't align offsets automatically
185 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 500, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_MAPPED_ALIGNMENT
, IGNORE
);
187 SectionOffset
.QuadPart
= -1;
188 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_MAPPED_ALIGNMENT
, IGNORE
);
191 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
194 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_3
, IGNORE
);
196 ViewSize
= TestStringSize
+1;
197 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
198 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
200 ViewSize
= TestStringSize
;
201 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
203 ViewSize
= TestStringSize
-1;
204 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
207 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
208 TestMapView(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_INVALID_PARAMETER_9
, STATUS_SUCCESS
);
209 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, (MEM_RESERVE
| MEM_COMMIT
), PAGE_READWRITE
, STATUS_INVALID_PARAMETER_9
, IGNORE
);
210 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, (MEM_LARGE_PAGES
| MEM_RESERVE
), PAGE_READWRITE
, STATUS_SUCCESS
, STATUS_SUCCESS
);
213 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
214 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
, STATUS_SUCCESS
, STATUS_SUCCESS
);
215 TestMapView(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE_WRITECOPY
, STATUS_SECTION_PROTECTION
, IGNORE
);
216 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_SECTION_PROTECTION
, IGNORE
);
217 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_WRITECOPY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
218 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE_READ
, STATUS_SECTION_PROTECTION
, IGNORE
);
219 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_EXECUTE
, STATUS_SECTION_PROTECTION
, IGNORE
);
220 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
, STATUS_SUCCESS
, STATUS_SUCCESS
);
221 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
, STATUS_SUCCESS
, STATUS_SUCCESS
);
222 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, 0, (PAGE_READWRITE
| PAGE_READONLY
), STATUS_INVALID_PAGE_PROTECTION
, IGNORE
);
223 TestMapView(ReadOnlySection
, NtCurrentProcess(), &BaseAddress
, 0, 0, NULL
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READONLY
, STATUS_SECTION_PROTECTION
, IGNORE
);
225 ZwClose(WriteSectionHandle
);
226 ZwClose(PageFileSectionHandle
);
227 ZwClose(ReadOnlySection
);
233 AdvancedErrorChecks(HANDLE FileHandleReadOnly
, HANDLE FileHandleWriteOnly
)
237 HANDLE FileSectionHandle
;
238 LARGE_INTEGER SectionOffset
;
239 LARGE_INTEGER MaximumSize
;
243 MaximumSize
.QuadPart
= TestStringSize
;
244 //Used for parameters working on file-based section
245 Status
= ZwCreateSection(&FileSectionHandle
, SECTION_ALL_ACCESS
, NULL
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, FileHandleWriteOnly
);
246 ok_eq_hex(Status
, STATUS_SUCCESS
);
248 Status
= ObReferenceObjectByHandle(FileSectionHandle
,
255 ok_eq_hex(Status
, STATUS_SUCCESS
);
257 //Bypassing Zw function calls mean bypassing the alignment checks which are not crucial for the branches being tested here
259 //test first conditional branch
261 MmTestMapView(SectionObject
, PsGetCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
263 //test second conditional branch
265 SectionOffset
.QuadPart
= TestStringSize
;
266 MmTestMapView(SectionObject
, PsGetCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
, STATUS_INVALID_VIEW_SIZE
, IGNORE
);
268 ObDereferenceObject(SectionObject
);
269 ZwClose(FileSectionHandle
);
274 CompareFileContents(HANDLE FileHandle
, ULONG BufferLength
, PVOID Buffer
)
277 LARGE_INTEGER ByteOffset
;
278 IO_STATUS_BLOCK IoStatusBlock
;
283 ByteOffset
.QuadPart
= 0;
285 FileContent
= ExAllocatePoolWithTag(PagedPool
, BufferLength
, 'Test');
286 if (!skip((FileContent
!= NULL
), "Error allocating memory for FileContent\n"))
288 Status
= ZwReadFile(FileHandle
, NULL
, NULL
, NULL
, &IoStatusBlock
, FileContent
, BufferLength
, &ByteOffset
, NULL
);
289 ok_eq_hex(Status
, STATUS_SUCCESS
);
290 ok_eq_ulongptr(IoStatusBlock
.Information
, BufferLength
);
293 Match
= RtlCompareMemory(FileContent
, Buffer
, BufferLength
);
294 ExFreePoolWithTag(FileContent
, 'Test');
304 SystemProcessWorker(PVOID StartContext
)
308 HANDLE SectionHandle
;
311 LARGE_INTEGER SectionOffset
;
312 OBJECT_ATTRIBUTES ObjectAttributes
;
314 UNREFERENCED_PARAMETER(StartContext
);
317 ViewSize
= TestStringSize
;
318 SectionOffset
.QuadPart
= 0;
320 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
321 Status
= ZwOpenSection(&SectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
);
322 if (!skip(NT_SUCCESS(Status
), "Error acquiring handle to section. Error = %p\n", Status
))
324 CheckObject(SectionHandle
, 4, 2);
325 Status
= ZwMapViewOfSection(SectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
327 //make sure ZwMapViewofSection doesn't touch the section ref counts.
328 CheckObject(SectionHandle
, 4, 2);
330 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view in system process. Error = %p\n", Status
))
332 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
333 ok_eq_size(Match
, TestStringSize
);
335 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
336 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
338 //make sure ZwMapViewofSection doesn't touch the section ref counts.
339 CheckObject(SectionHandle
, 4, 2);
342 ZwClose(SectionHandle
);
345 PsTerminateSystemThread(STATUS_SUCCESS
);
351 BehaviorChecks(HANDLE FileHandleReadOnly
, HANDLE FileHandleWriteOnly
)
354 PVOID BaseAddress
= NULL
;
356 HANDLE WriteSectionHandle
;
357 HANDLE SysThreadHandle
;
358 OBJECT_ATTRIBUTES ObjectAttributes
;
359 LARGE_INTEGER SectionOffset
;
360 LARGE_INTEGER MaximumSize
;
364 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
365 MaximumSize
.QuadPart
= TestStringSize
;
366 SectionOffset
.QuadPart
= 0;
368 Status
= ZwCreateSection(&WriteSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaximumSize
, PAGE_READWRITE
, SEC_COMMIT
, FileHandleWriteOnly
);
369 CheckObject(WriteSectionHandle
, 3, 1);
370 ok(NT_SUCCESS(Status
), "Error creating write section from file. Error = %p\n", Status
);
372 //check for section reading/writing by comparing section content to a well-known value.
373 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess() ,&BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
374 CheckObject(WriteSectionHandle
, 3, 1);
375 if (!skip(NT_SUCCESS(Status
), "Error mapping view with READ/WRITE priv. Error = %p\n", Status
))
377 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
378 ok_eq_size(Match
, TestStringSize
);
380 //now check writing to section
381 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
383 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
384 ok_eq_size(Match
, NEW_CONTENT_LEN
);
386 //check to see if the contents have been flushed to the actual file on disk.
387 Match
= CompareFileContents(FileHandleWriteOnly
, NEW_CONTENT_LEN
, NEW_CONTENT
);
388 ok_eq_size(Match
, NEW_CONTENT_LEN
);
390 //bring everything back to normal
391 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
393 //Initiate an external thread to modify the file
394 InitializeObjectAttributes(&ObjectAttributes
, NULL
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
395 Status
= PsCreateSystemThread(&SysThreadHandle
, STANDARD_RIGHTS_ALL
, &ObjectAttributes
, NULL
, NULL
, SystemProcessWorker
, NULL
);
396 if (!skip(NT_SUCCESS(Status
), "Error creating System thread. Error = %p\n", Status
))
398 Status
= ObReferenceObjectByHandle(SysThreadHandle
, THREAD_ALL_ACCESS
, *PsThreadType
, KernelMode
, &ThreadObject
, NULL
);
399 if (!skip(NT_SUCCESS(Status
), "Error getting reference to System thread when testing file-backed section\n"))
401 //wait until the system thread actually terminates
402 KeWaitForSingleObject(ThreadObject
, Executive
, KernelMode
, FALSE
, NULL
);
404 //no longer need the thread object
405 ObDereferenceObject(ThreadObject
);
407 //test for bi-directional access to the shared page file
408 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
409 ok_eq_size(Match
, NEW_CONTENT_LEN
);
411 //bring everything back to normal, again
412 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
416 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
419 //Try to write to read-only mapped view
422 SectionOffset
.QuadPart
= 0;
423 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READONLY
);
424 if (!skip(NT_SUCCESS(Status
), "Error mapping view with READ priv. Error = %p\n", Status
))
426 Match
= RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
427 ok_eq_size(Match
, TestStringSize
);
430 RtlCopyMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
431 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
433 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
436 /* FIXME: Crash. See ROSTESTS-110 */
437 #ifdef ROSTESTS_110_FIXED
438 //try to access forbidden memory
441 SectionOffset
.QuadPart
= 0;
442 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, 0, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_NOACCESS
);
443 if (!skip(NT_SUCCESS(Status
), "Error mapping view with PAGE_NOACCESS priv. Error = %p\n", Status
))
446 RtlCompareMemory(BaseAddress
, TestString
, TestStringSize
);
447 KmtEndSeh(STATUS_ACCESS_VIOLATION
);
449 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
451 #endif /* ROSTESTS_110_FIXED */
453 ZwClose(WriteSectionHandle
);
455 //section created with sec_reserve should not be commited.
458 SectionOffset
.QuadPart
= 0;
459 Status
= ZwCreateSection(&WriteSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaximumSize
, PAGE_READWRITE
, SEC_RESERVE
, FileHandleWriteOnly
);
460 if (!skip(NT_SUCCESS(Status
), "Error creating page file section. Error = %p\n", Status
))
462 Status
= ZwMapViewOfSection(WriteSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, MEM_RESERVE
, PAGE_READWRITE
);
463 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view. Error = %p\n", Status
))
465 //check also the SEC_COMMIT flag
466 /* This test proves that MSDN is once again wrong
467 * msdn.microsoft.com/en-us/library/windows/hardware/aa366537.aspx states that SEC_RESERVE
468 * should cause the allocated memory for the view to be reserved but in fact it is always committed.
469 * It fails also on windows.
471 Test_NtQueryVirtualMemory(BaseAddress
, PAGE_SIZE
, MEM_COMMIT
, PAGE_READWRITE
);
472 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
475 ZwClose(WriteSectionHandle
);
482 PageFileBehaviorChecks()
485 LARGE_INTEGER MaxSectionSize
;
486 LARGE_INTEGER SectionOffset
;
487 HANDLE PageFileSectionHandle
;
492 OBJECT_ATTRIBUTES ObjectAttributes
;
494 MaxSectionSize
.QuadPart
= TestStringSize
;
495 SectionOffset
.QuadPart
= 0;
496 PageFileSectionHandle
= INVALID_HANDLE_VALUE
;
498 ViewSize
= TestStringSize
;
499 InitializeObjectAttributes(&ObjectAttributes
, &SharedSectionName
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
501 //test memory sharing between 2 different processes
502 Status
= ZwCreateSection(&PageFileSectionHandle
, SECTION_ALL_ACCESS
, &ObjectAttributes
, &MaxSectionSize
, PAGE_READWRITE
, SEC_COMMIT
, NULL
);
503 if (!skip(NT_SUCCESS(Status
), "Error creating page file section. Error = %p\n", Status
))
505 CheckObject(PageFileSectionHandle
, 3, 1);
506 Status
= ZwMapViewOfSection(PageFileSectionHandle
, NtCurrentProcess(), &BaseAddress
, 0, TestStringSize
, &SectionOffset
, &ViewSize
, ViewUnmap
, 0, PAGE_READWRITE
);
507 if (!skip(NT_SUCCESS(Status
), "Error mapping page file view. Error = %p\n", Status
))
509 HANDLE SysThreadHandle
;
511 CheckObject(PageFileSectionHandle
, 3, 1);
513 //check also the SEC_COMMIT flag
514 Test_NtQueryVirtualMemory(BaseAddress
, PAGE_SIZE
, MEM_COMMIT
, PAGE_READWRITE
);
516 RtlCopyMemory(BaseAddress
, TestString
, TestStringSize
);
518 InitializeObjectAttributes(&ObjectAttributes
, NULL
, OBJ_KERNEL_HANDLE
, NULL
, NULL
);
519 Status
= PsCreateSystemThread(&SysThreadHandle
, STANDARD_RIGHTS_ALL
, &ObjectAttributes
, NULL
, NULL
, SystemProcessWorker
, NULL
);
521 if (!skip(NT_SUCCESS(Status
), "Error creating System thread. Error = %p\n", Status
))
523 Status
= ObReferenceObjectByHandle(SysThreadHandle
, THREAD_ALL_ACCESS
, *PsThreadType
, KernelMode
, &ThreadObject
, NULL
);
524 if (!skip(NT_SUCCESS(Status
), "Error getting reference to System thread when testing pagefile-backed section\n"))
526 //wait until the system thread actually terminates
527 KeWaitForSingleObject(ThreadObject
, Executive
, KernelMode
, FALSE
, NULL
);
529 //no longer need the thread object
530 ObDereferenceObject(ThreadObject
);
532 //test for bi-directional access to the shared page file
533 Match
= RtlCompareMemory(BaseAddress
, NEW_CONTENT
, NEW_CONTENT_LEN
);
534 ok_eq_size(Match
, NEW_CONTENT_LEN
);
537 ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress
);
539 ZwClose(PageFileSectionHandle
);
544 START_TEST(ZwMapViewOfSection
)
546 HANDLE FileHandleReadOnly
= NULL
;
547 HANDLE FileHandleWriteOnly
= NULL
;
548 HANDLE ExecutableFileHandle
= NULL
;
550 InitializeObjectAttributes(&NtdllObject
, &FileReadOnlyPath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
551 InitializeObjectAttributes(&KmtestFileObject
, &WritableFilePath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
552 InitializeObjectAttributes(&NtoskrnlFileObject
, &NtosImgPath
, OBJ_CASE_INSENSITIVE
| OBJ_KERNEL_HANDLE
, NULL
, NULL
);
554 KmtInitTestFiles(&FileHandleReadOnly
, &FileHandleWriteOnly
, &ExecutableFileHandle
);
556 SimpleErrorChecks(FileHandleReadOnly
, FileHandleWriteOnly
, ExecutableFileHandle
);
557 AdvancedErrorChecks(FileHandleReadOnly
, FileHandleWriteOnly
);
558 BehaviorChecks(FileHandleReadOnly
, FileHandleWriteOnly
);
559 PageFileBehaviorChecks();
561 if (FileHandleReadOnly
)
562 ZwClose(FileHandleReadOnly
);
564 if (FileHandleWriteOnly
)
565 ZwClose(FileHandleWriteOnly
);
567 if (ExecutableFileHandle
)
568 ZwClose(ExecutableFileHandle
);