|
26 | 26 | import static org.junit.Assert.assertTrue;
|
27 | 27 | import static org.junit.Assert.assertNotEquals;
|
28 | 28 | import static org.junit.Assert.assertFalse;
|
| 29 | +import static org.junit.Assert.assertEquals; |
29 | 30 |
|
30 | 31 | import java.util.LinkedList;
|
31 | 32 | import java.util.List;
|
@@ -281,37 +282,71 @@ public void testEnumProcesses() {
|
281 | 282 |
|
282 | 283 | @Test
|
283 | 284 | public void testQueryWorkingSetEx() {
|
284 |
| - Win32Exception we = null; |
285 | 285 | HANDLE selfHandle = Kernel32.INSTANCE.GetCurrentProcess();
|
286 | 286 | MEMORY_BASIC_INFORMATION mbi = new MEMORY_BASIC_INFORMATION();
|
287 | 287 | try {
|
288 | 288 | SIZE_T bytesRead = Kernel32.INSTANCE.VirtualQueryEx(selfHandle, Pointer.NULL, mbi, new SIZE_T(mbi.size()));
|
289 | 289 | assertNotEquals("Kernel should be able to read this Process' Bytes", bytesRead.intValue(), 0);
|
290 | 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()); |
294 |
| - } |
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()); |
298 |
| - } |
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 |
| 291 | + pswsi.VirtualAddress = mbi.getPointer(); |
| 292 | + |
| 293 | + // QueryWorkingSetEx expects an array of PSAPI_WORKING_SET_EX_INFORMATION |
| 294 | + // structures as second parameter, for the single element case we can |
| 295 | + // pass in just the pointer to the structure. As structure is passed |
| 296 | + // as a raw pointer it needs to be read and writte explicitly |
| 297 | + pswsi.write(); |
| 298 | + assertTrue("Failed to invoke QueryWorkingSetEx (1)", Psapi.INSTANCE.QueryWorkingSetEx(selfHandle, pswsi.getPointer(), pswsi.size())); |
| 299 | + pswsi.read(); |
| 300 | + |
| 301 | + assertTrue("Virtual Attributes should not be null (1)", pswsi.VirtualAttributes != null); |
| 302 | + assertEquals("Virtual Address should not change before and after call (1)", pswsi.VirtualAddress, mbi.getPointer()); |
| 303 | + assertTrue("Data was invalid (1)", pswsi.isValid()); |
| 304 | + assertFalse("Data was reported as bad (1)", pswsi.isBad()); |
| 305 | + assertEquals("Data indicates sharing (1)", pswsi.getShareCount(), 0); |
| 306 | + assertEquals("Data indicated that protection does not match PAGE_READWRITE (1)", |
| 307 | + pswsi.getWin32Protection(), WinNT.PAGE_READWRITE); |
| 308 | + assertFalse("Data was reported as shared (1)", pswsi.isShared()); |
| 309 | + assertFalse("Data was reported as locked (1)", pswsi.isLocked()); |
| 310 | + assertFalse("Data was reported as large pages (1)", pswsi.isLargePage()); |
| 311 | + |
| 312 | + // Lock the page we used into memory - this should be reflected in the reported flags now |
| 313 | + assertTrue(Kernel32.INSTANCE.VirtualLock(mbi.getPointer(), new SIZE_T(4096))); |
| 314 | + |
| 315 | + pswsi.write(); |
| 316 | + assertTrue("Failed to invoke QueryWorkingSetEx (2)", Psapi.INSTANCE.QueryWorkingSetEx(selfHandle, pswsi.getPointer(), pswsi.size())); |
| 317 | + pswsi.read(); |
| 318 | + |
| 319 | + assertTrue("Virtual Attributes should not be null (2)", pswsi.VirtualAttributes != null); |
| 320 | + assertEquals("Virtual Address should not change before and after call (2)", pswsi.VirtualAddress, mbi.getPointer()); |
| 321 | + assertTrue("Data was invalid (2)", pswsi.isValid()); |
| 322 | + assertFalse("Data was reported as bad (2)", pswsi.isBad()); |
| 323 | + assertEquals("Data indicates sharing (2)", pswsi.getShareCount(), 0); |
| 324 | + assertEquals("Data indicated that protection does not match PAGE_READWRITE (2)", |
| 325 | + pswsi.getWin32Protection(), WinNT.PAGE_READWRITE); |
| 326 | + assertFalse("Data was reported as shared (2)", pswsi.isShared()); |
| 327 | + assertTrue("Data was reported as locked (2)", pswsi.isLocked()); |
| 328 | + assertFalse("Data was reported as large pages (2)", pswsi.isLargePage()); |
| 329 | + |
| 330 | + // Check that a query against an invalid target succeeds, but report |
| 331 | + // invalid data |
| 332 | + pswsi.VirtualAddress = null; |
| 333 | + pswsi.write(); |
| 334 | + assertTrue("Failed to invoke QueryWorkingSetEx (3)", Psapi.INSTANCE.QueryWorkingSetEx(WinBase.INVALID_HANDLE_VALUE, pswsi.getPointer(), pswsi.size())); |
| 335 | + pswsi.read(); |
| 336 | + |
| 337 | + assertTrue("Virtual Attributes should not be null (3)", pswsi.VirtualAttributes != null); |
| 338 | + assertTrue("Virtual Address should not change before and after call (3)", pswsi.VirtualAddress == null); |
| 339 | + assertFalse("Data was reported valid, but expected to be invalid (3)", pswsi.isValid()); |
303 | 340 | } finally {
|
304 | 341 | try {
|
305 | 342 | Kernel32Util.closeHandle(selfHandle);
|
306 | 343 | } catch (Win32Exception e) {
|
307 |
| - if (we == null) { |
308 |
| - we = e; |
309 |
| - } else { |
310 |
| - we.addSuppressedReflected(e); |
311 |
| - } |
| 344 | + // Ignore |
312 | 345 | }
|
313 |
| - if (we != null) { |
314 |
| - throw we; |
| 346 | + try { |
| 347 | + Kernel32.INSTANCE.VirtualUnlock(mbi.getPointer(), new SIZE_T(4096)); |
| 348 | + } catch (Win32Exception e) { |
| 349 | + // Ignore |
315 | 350 | }
|
316 | 351 | }
|
317 | 352 | }
|
|
0 commit comments