[GDI32_APITEST] Fix MSVC build
[reactos.git] / modules / rostests / kmtests / ntos_mm / MmMdl.c
1 /*
2 * PROJECT: ReactOS kernel-mode tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Kernel-Mode Test Suite MDL test
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include <kmt_test.h>
9
10 static
11 VOID
12 TestMmAllocatePagesForMdl(VOID)
13 {
14 PMDL Mdl;
15 PHYSICAL_ADDRESS LowAddress;
16 PHYSICAL_ADDRESS HighAddress;
17 PHYSICAL_ADDRESS SkipBytes;
18 PVOID SystemVa;
19 PMDL Mdls[32];
20 PVOID SystemVas[32];
21 ULONG i;
22 PPFN_NUMBER MdlPages;
23 ULONG MdlPageCount;
24
25 LowAddress.QuadPart = 0;
26 HighAddress.QuadPart = -1;
27 SkipBytes.QuadPart = 0;
28 /* simple allocate/free */
29 Mdl = MmAllocatePagesForMdl(LowAddress,
30 HighAddress,
31 SkipBytes,
32 2 * 1024 * 1024);
33 ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
34 if (skip(Mdl != NULL, "No Mdl\n"))
35 return;
36 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
37 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
38 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
39 MdlPages = MmGetMdlPfnArray(Mdl);
40 MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Mdl), MmGetMdlByteCount(Mdl));
41 ok(MdlPageCount == 2 * 1024 * 1024 / PAGE_SIZE, "MdlPageCount = %lu\n", MdlPageCount);
42 for (i = 0; i < MdlPageCount; i++)
43 {
44 ok(MdlPages[i] != 0 && MdlPages[i] != (PFN_NUMBER)-1,
45 "MdlPages[%lu] = 0x%I64x\n", i, (ULONGLONG)MdlPages[i]);
46 }
47 MmFreePagesFromMdl(Mdl);
48 ExFreePoolWithTag(Mdl, 0);
49
50 /* Now map/unmap it */
51 Mdl = MmAllocatePagesForMdl(LowAddress,
52 HighAddress,
53 SkipBytes,
54 2 * 1024 * 1024);
55 ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
56 if (skip(Mdl != NULL, "No Mdl\n"))
57 return;
58 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
59 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
60 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
61 SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
62 KernelMode,
63 MmCached,
64 NULL,
65 FALSE,
66 NormalPagePriority);
67 ok(SystemVa != NULL, "MmMapLockedPagesSpecifyCache failed\n");
68 if (!skip(SystemVa != NULL, "No system VA\n"))
69 {
70 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
71 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdl), SystemVa);
72 ok(Mdl->MappedSystemVa == SystemVa, "MappedSystemVa: %p, System VA: %p\n", Mdl->MappedSystemVa, SystemVa);
73 ok((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
74 MmUnmapLockedPages(SystemVa, Mdl);
75 }
76 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
77 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
78 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
79 MmFreePagesFromMdl(Mdl);
80 ExFreePoolWithTag(Mdl, 0);
81
82 /* Now map it, and free without unmapping */
83 Mdl = MmAllocatePagesForMdl(LowAddress,
84 HighAddress,
85 SkipBytes,
86 2 * 1024 * 1024);
87 ok(Mdl != NULL, "MmAllocatePagesForMdl failed\n");
88 if (skip(Mdl != NULL, "No Mdl\n"))
89 return;
90 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
91 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
92 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
93 SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
94 KernelMode,
95 MmCached,
96 NULL,
97 FALSE,
98 NormalPagePriority);
99 ok(SystemVa != NULL, "MmMapLockedPagesSpecifyCache failed\n");
100 ok(MmGetMdlByteCount(Mdl) == 2 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
101 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdl), SystemVa);
102 ok(Mdl->MappedSystemVa == SystemVa, "MappedSystemVa: %p, System VA: %p\n", Mdl->MappedSystemVa, SystemVa);
103 ok((Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
104 MmFreePagesFromMdl(Mdl);
105 ExFreePoolWithTag(Mdl, 0);
106
107 /* try to allocate 2 GB -- should succeed but not map */
108 Mdl = MmAllocatePagesForMdl(LowAddress,
109 HighAddress,
110 SkipBytes,
111 2UL * 1024 * 1024 * 1024);
112 ok(Mdl != NULL, "MmAllocatePagesForMdl failed for 2 GB\n");
113 if (Mdl != NULL)
114 {
115 ok(MmGetMdlByteCount(Mdl) != 2UL * 1024 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
116 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
117 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
118 MdlPages = MmGetMdlPfnArray(Mdl);
119 MdlPageCount = ADDRESS_AND_SIZE_TO_SPAN_PAGES(MmGetMdlVirtualAddress(Mdl), MmGetMdlByteCount(Mdl));
120 ok(MdlPageCount < 2UL * 1024 * 1024 * 1024 / PAGE_SIZE, "MdlPageCount = %lu\n", MdlPageCount);
121 for (i = 0; i < MdlPageCount; i++)
122 {
123 if (MdlPages[i] == 0 ||
124 MdlPages[i] == (PFN_NUMBER)-1)
125 {
126 ok(0, "MdlPages[%lu] = 0x%I64x\n", i, (ULONGLONG)MdlPages[i]);
127 }
128 }
129 SystemVa = MmMapLockedPagesSpecifyCache(Mdl,
130 KernelMode,
131 MmCached,
132 NULL,
133 FALSE,
134 NormalPagePriority);
135 ok(SystemVa == NULL, "MmMapLockedPagesSpecifyCache succeeded for 2 GB\n");
136 if (SystemVa != NULL)
137 MmUnmapLockedPages(SystemVa, Mdl);
138 ok(MmGetMdlByteCount(Mdl) != 2UL * 1024 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdl));
139 ok(MmGetMdlVirtualAddress(Mdl) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdl));
140 ok(!(Mdl->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdl->MdlFlags);
141 MmFreePagesFromMdl(Mdl);
142 ExFreePoolWithTag(Mdl, 0);
143 }
144
145 /* now allocate and map 32 MB Mdls until we fail */
146 for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
147 {
148 Mdls[i] = MmAllocatePagesForMdl(LowAddress,
149 HighAddress,
150 SkipBytes,
151 32 * 1024 * 1024);
152 if (Mdls[i] == NULL)
153 {
154 trace("MmAllocatePagesForMdl failed with i = %lu\n", i);
155 break;
156 }
157 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
158 ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
159 SystemVas[i] = MmMapLockedPagesSpecifyCache(Mdls[i],
160 KernelMode,
161 MmCached,
162 NULL,
163 FALSE,
164 NormalPagePriority);
165 if (SystemVas[i] == NULL)
166 {
167 ok(MmGetMdlByteCount(Mdls[i]) <= 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
168 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p\n", MmGetMdlVirtualAddress(Mdls[i]));
169 ok(!(Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
170 trace("MmMapLockedPagesSpecifyCache failed with i = %lu\n", i);
171 break;
172 }
173 ok(MmGetMdlByteCount(Mdls[i]) == 32 * 1024 * 1024, "Byte count: %lu\n", MmGetMdlByteCount(Mdls[i]));
174 ok(MmGetMdlVirtualAddress(Mdls[i]) == NULL, "Virtual address: %p, System VA: %p\n", MmGetMdlVirtualAddress(Mdls[i]), SystemVas[i]);
175 ok(Mdls[i]->MappedSystemVa == SystemVas[i], "MappedSystemVa: %p\n", Mdls[i]->MappedSystemVa, SystemVas[i]);
176 ok((Mdls[i]->MdlFlags & MDL_MAPPED_TO_SYSTEM_VA), "MdlFlags: %lx\n", Mdls[i]->MdlFlags);
177 }
178 for (i = 0; i < sizeof(Mdls) / sizeof(Mdls[0]); i++)
179 {
180 if (Mdls[i] == NULL)
181 break;
182 if (SystemVas[i] != NULL)
183 MmUnmapLockedPages(SystemVas[i], Mdls[i]);
184 MmFreePagesFromMdl(Mdls[i]);
185 ExFreePoolWithTag(Mdls[i], 0);
186 if (SystemVas[i] == NULL)
187 break;
188 }
189 }
190
191 static
192 VOID
193 TestMmBuildMdlForNonPagedPool(VOID)
194 {
195 PVOID Page;
196 PMDL Mdl;
197
198 Page = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, 'Test');
199 ok(Page != NULL, "ExAllocatePoolWithTag failed\n");
200 if (skip(Page != NULL, "No buffer\n"))
201 return;
202
203 Mdl = IoAllocateMdl(Page, PAGE_SIZE, FALSE, FALSE, NULL);
204 ok(Mdl != NULL, "IoAllocateMdl failed\n");
205 if (skip(Mdl != NULL, "No MDL\n"))
206 return;
207
208 ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
209 ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
210
211 MmBuildMdlForNonPagedPool(Mdl);
212 ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
213 ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) != 0, "MDL from paged\n");
214
215 IoFreeMdl(Mdl);
216 ExFreePoolWithTag(Page, 'Test');
217
218 Page = ExAllocatePoolWithTag(NonPagedPool, PAGE_SIZE, 'Test');
219 ok(Page != NULL, "ExAllocatePoolWithTag failed\n");
220 if (skip(Page != NULL, "No buffer\n"))
221 return;
222
223 Mdl = IoAllocateMdl(Page, PAGE_SIZE, FALSE, FALSE, NULL);
224 ok(Mdl != NULL, "IoAllocateMdl failed\n");
225 if (skip(Mdl != NULL, "No MDL\n"))
226 return;
227
228 ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
229 ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) == 0, "MDL from non paged\n");
230
231 MmBuildMdlForNonPagedPool(Mdl);
232 ok((Mdl->MdlFlags & MDL_PAGES_LOCKED) == 0, "MDL locked\n");
233 ok((Mdl->MdlFlags & MDL_SOURCE_IS_NONPAGED_POOL) != 0, "MDL from paged\n");
234
235 IoFreeMdl(Mdl);
236 ExFreePoolWithTag(Page, 'Test');
237 }
238
239 START_TEST(MmMdl)
240 {
241 TestMmAllocatePagesForMdl();
242 TestMmBuildMdlForNonPagedPool();
243 }