Skip to content

Commit d5258ea

Browse files
Improve/fix unittest for Psapi#QueryWorkingSetEx
1 parent 04ae48f commit d5258ea

File tree

1 file changed

+90
-22
lines changed

1 file changed

+90
-22
lines changed

contrib/platform/test/com/sun/jna/platform/win32/PsapiTest.java

+90-22
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import static org.junit.Assert.assertTrue;
2727
import static org.junit.Assert.assertNotEquals;
2828
import static org.junit.Assert.assertFalse;
29+
import static org.junit.Assert.assertEquals;
2930

3031
import java.util.LinkedList;
3132
import java.util.List;
@@ -45,6 +46,7 @@
4546
import com.sun.jna.platform.win32.WinNT.HANDLE;
4647
import com.sun.jna.platform.win32.WinNT.MEMORY_BASIC_INFORMATION;
4748
import com.sun.jna.platform.win32.BaseTSD.SIZE_T;
49+
import com.sun.jna.platform.win32.Psapi.PSAPI_WORKING_SET_EX_INFORMATION;
4850
import com.sun.jna.ptr.IntByReference;
4951

5052
/**
@@ -280,38 +282,104 @@ public void testEnumProcesses() {
280282
}
281283

282284
@Test
285+
@SuppressWarnings("ResultOfObjectAllocationIgnored")
283286
public void testQueryWorkingSetEx() {
284-
Win32Exception we = null;
285287
HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentProcess();
286-
MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
288+
289+
Memory[] mem = new Memory[4];
290+
mem[0] = new Memory(4096);
291+
new Memory(8192); // Try to ensure the memory pages are not adjacent
292+
mem[1] = new Memory(4096);
293+
new Memory(8192); // Try to ensure the memory pages are not adjacent
294+
mem[3] = new Memory(4096);
295+
287296
try {
288-
SIZE_T bytesRead = Kernel32.INSTANCE.VirtualQueryEx(selfHandle, Pointer.NULL, mbi, new SIZE_T(mbi.size()));
289-
assertNotEquals("Kernel should be able to read this Process' Bytes", bytesRead.intValue(), 0);
290-
Psapi.PSAPI_WORKING_SET_EX_INFORMATION pswsi = new Psapi.PSAPI_WORKING_SET_EX_INFORMATION();
291-
pswsi.VirtualAddress = mbi.baseAddress;
292-
if (!Psapi.INSTANCE.QueryWorkingSetEx(selfHandle, pswsi.VirtualAddress, pswsi.size())) {
293-
throw new Win32Exception(Native.getLastError());
297+
PSAPI_WORKING_SET_EX_INFORMATION[] pswsi = (PSAPI_WORKING_SET_EX_INFORMATION[]) new PSAPI_WORKING_SET_EX_INFORMATION().toArray(4);
298+
299+
pswsi[0].VirtualAddress = mem[0];
300+
pswsi[1].VirtualAddress = mem[1];
301+
pswsi[2].VirtualAddress = mem[2];
302+
pswsi[3].VirtualAddress = mem[3];
303+
304+
for(int i = 0; i < pswsi.length; i++) {
305+
pswsi[i].write();
294306
}
295-
assertTrue("Virual Attributes should not be null", pswsi.VirtualAttributes != null);
296-
if (Psapi.INSTANCE.QueryWorkingSetEx(new HANDLE(), pswsi.VirtualAddress, pswsi.size())) {
297-
throw new Win32Exception(Native.getLastError());
307+
308+
assertTrue("Failed to invoke QueryWorkingSetEx (1)", Psapi.INSTANCE.QueryWorkingSetEx(selfHandle, pswsi[0].getPointer(), pswsi[0].size() * pswsi.length));
309+
310+
for (int i = 0; i < pswsi.length; i++) {
311+
pswsi[i].read();
312+
assertTrue("Virtual Attributes should not be null (1)", pswsi[i].VirtualAttributes != null);
313+
assertEquals("Virtual Address should not change before and after call (1)", pswsi[i].VirtualAddress, mem[i]);
314+
if (i != 2) {
315+
assertTrue("Data was invalid (1)", pswsi[i].isValid());
316+
assertFalse("Data was reported as bad (1)", pswsi[i].isBad());
317+
assertEquals("Data indicates sharing (1)", pswsi[i].getShareCount(), 0);
318+
assertEquals("Data indicated that protection does not match PAGE_READWRITE (1)",
319+
pswsi[i].getWin32Protection(), WinNT.PAGE_READWRITE);
320+
assertFalse("Data was reported as shared (1)", pswsi[i].isShared());
321+
assertFalse("Data was reported as locked (1)", pswsi[i].isLocked());
322+
assertFalse("Data was reported as large pages (1)", pswsi[i].isLargePage());
323+
} else {
324+
assertFalse("Data was reported valid, but expected to be invalid (1)", pswsi[i].isValid());
325+
}
298326
}
299-
assertFalse("This line should never be called", true);
300-
} catch (Win32Exception e) {
301-
we = e;
302-
throw we; // re-throw to invoke finally block
327+
328+
// Lock the page we used into memory - this should be reflected in the reported flags in the next call
329+
assertTrue(Kernel32.INSTANCE.VirtualLock(mem[1], new SIZE_T(4096)));
330+
331+
for (int i = 0; i < pswsi.length; i++) {
332+
pswsi[i].write();
333+
}
334+
335+
assertTrue("Failed to invoke QueryWorkingSetEx (2)", Psapi.INSTANCE.QueryWorkingSetEx(selfHandle, pswsi[0].getPointer(), pswsi[0].size() * pswsi.length));
336+
337+
for (int i = 0; i < pswsi.length; i++) {
338+
pswsi[i].read();
339+
assertTrue("Virtual Attributes should not be null (2)", pswsi[i].VirtualAttributes != null);
340+
assertEquals("Virtual Address should not change before and after call (2)", pswsi[i].VirtualAddress, mem[i]);
341+
if (i != 2) {
342+
assertTrue("Virtual Attributes should not be null (2)", pswsi[i].VirtualAttributes != null);
343+
assertEquals("Virtual Address should not change before and after call (2)", pswsi[i].VirtualAddress, mem[i]);
344+
assertTrue("Data was invalid (2)", pswsi[i].isValid());
345+
assertFalse("Data was reported as bad (2)", pswsi[i].isBad());
346+
assertEquals("Data indicates sharing (2)", pswsi[i].getShareCount(), 0);
347+
assertEquals("Data indicated that protection does not match PAGE_READWRITE (2)",
348+
pswsi[i].getWin32Protection(), WinNT.PAGE_READWRITE);
349+
assertFalse("Data was reported as shared (2)", pswsi[i].isShared());
350+
// Only the second page should be locked
351+
if( i == 1 ) {
352+
assertTrue("Data was reported as unlocked (2)", pswsi[i].isLocked());
353+
} else {
354+
assertFalse("Data was reported as locked (2)", pswsi[i].isLocked());
355+
}
356+
assertFalse("Data was reported as large pages (2)", pswsi[i].isLargePage());
357+
} else {
358+
assertFalse("Data was reported valid, but expected to be invalid (2)", pswsi[i].isValid());
359+
}
360+
}
361+
362+
// Check that a query against an invalid target succeeds, but report
363+
// invalid data
364+
PSAPI_WORKING_SET_EX_INFORMATION pswsi2 = new PSAPI_WORKING_SET_EX_INFORMATION();
365+
pswsi2.VirtualAddress = null;
366+
pswsi2.write();
367+
assertTrue("Failed to invoke QueryWorkingSetEx (3)", Psapi.INSTANCE.QueryWorkingSetEx(WinBase.INVALID_HANDLE_VALUE, pswsi2.getPointer(), pswsi2.size()));
368+
pswsi2.read();
369+
370+
assertTrue("Virtual Attributes should not be null (3)", pswsi2.VirtualAttributes != null);
371+
assertTrue("Virtual Address should not change before and after call (3)", pswsi2.VirtualAddress == null);
372+
assertFalse("Data was reported valid, but expected to be invalid (3)", pswsi2.isValid());
303373
} finally {
304374
try {
305375
Kernel32Util.closeHandle(selfHandle);
306376
} catch (Win32Exception e) {
307-
if (we == null) {
308-
we = e;
309-
} else {
310-
we.addSuppressedReflected(e);
311-
}
377+
// Ignore
312378
}
313-
if (we != null) {
314-
throw we;
379+
try {
380+
Kernel32.INSTANCE.VirtualUnlock(mem[1], new SIZE_T(4096));
381+
} catch (Win32Exception e) {
382+
// Ignore
315383
}
316384
}
317385
}

0 commit comments

Comments
 (0)