Skip to content

Commit 04ae48f

Browse files
Bind VirtualLock and VirtualUnlock in c.s.j.p.win32.Kernel32
1 parent dbf8751 commit 04ae48f

3 files changed

Lines changed: 93 additions & 1 deletion

File tree

CHANGES.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ Next Release (5.13.0)
77

88
Features
99
--------
10-
* [#1454](https://github.com/java-native-access/jna/pull/1454): Add `c.s.j.p.win32.Psapi.QueryWorkingSetEx` and associated Types = [@crain-32](https://github.com/Crain-32).
10+
* [#1454](https://github.com/java-native-access/jna/pull/1454): Add `c.s.j.p.win32.Psapi.QueryWorkingSetEx` and associated Types - [@crain-32](https://github.com/Crain-32).
11+
* [#1459](https://github.com/java-native-access/jna/pull/1459): Add `VirtualLock` and `VirtualUnlock` in `c.s.j.p.win32.Kernel32` - [@matthiasblaesing](https://github.com/matthiasblaesing).
1112

1213
Bug Fixes
1314
---------

contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4307,4 +4307,84 @@ Pointer VirtualAllocEx(HANDLE hProcess, Pointer lpAddress, SIZE_T dwSize,
43074307
* @see <A HREF="https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getapplicationrestartsettings">MSDN Entry</A>
43084308
*/
43094309
HRESULT GetApplicationRestartSettings(HANDLE hProcess, char[] pwzCommandline, IntByReference pcchSize, IntByReference pdwFlags);
4310+
4311+
/**
4312+
* Locks the specified region of the process's virtual address space into
4313+
* physical memory, ensuring that subsequent access to the region will not
4314+
* incur a page fault.
4315+
*
4316+
* @param lpAddress A pointer to the base address of the region of pages to
4317+
* be locked.
4318+
* @param dwSize The size of the region to be locked, in bytes. The
4319+
* region of affected pages includes all pages that contain
4320+
* one or more bytes in the range from the lpAddress
4321+
* parameter to (lpAddress+dwSize). This means that a
4322+
* 2-byte range straddling a page boundary causes both
4323+
* pages to be locked.
4324+
*
4325+
* @return {@code true} if locking succeeded.
4326+
*
4327+
* <p>
4328+
* All pages in the specified region must be committed. Memory protected
4329+
* with {@code PAGE_NOACCESS} cannot be locked.
4330+
* </p>
4331+
* <p>
4332+
* Locking pages into memory may degrade the performance of the system by
4333+
* reducing the available RAM and forcing the system to swap out other
4334+
* critical pages to the paging file. Each version of Windows has a limit on
4335+
* the maximum number of pages a process can lock. This limit is
4336+
* intentionally small to avoid severe performance degradation. Applications
4337+
* that need to lock larger numbers of pages must first call the
4338+
* SetProcessWorkingSetSize function to increase their minimum and maximum
4339+
* working set sizes. The maximum number of pages that a process can lock is
4340+
* equal to the number of pages in its minimum working set minus a small
4341+
* overhead.
4342+
* </p>
4343+
* <p>
4344+
* Pages that a process has locked remain in physical memory until the
4345+
* process unlocks them or terminates. These pages are guaranteed not to be
4346+
* written to the pagefile while they are locked.
4347+
* </p>
4348+
* <p>
4349+
* To unlock a region of locked pages, use the VirtualUnlock function.
4350+
* Locked pages are automatically unlocked when the process terminates.
4351+
* </p>
4352+
* <p>
4353+
* This function is not like the GlobalLock or LocalLock function in that it
4354+
* does not increment a lock count and translate a handle into a pointer.
4355+
* There is no lock count for virtual pages, so multiple calls to the
4356+
* VirtualUnlock function are never required to unlock a region of pages.
4357+
* </p>
4358+
*/
4359+
boolean VirtualLock(Pointer lpAddress, SIZE_T dwSize);
4360+
4361+
/**
4362+
* Unlocks a specified range of pages in the virtual address space of a
4363+
* process, enabling the system to swap the pages out to the paging file if
4364+
* necessary.
4365+
*
4366+
* @param lpAddress A pointer to the base address of the region of pages to
4367+
* be unlocked.
4368+
* @param dwSize The size of the region being unlocked, in bytes. The
4369+
* region of affected pages includes all pages containing
4370+
* one or more bytes in the range from the lpAddress
4371+
* parameter to (lpAddress+dwSize). This means that a
4372+
* 2-byte range straddling a page boundary causes both
4373+
* pages to be unlocked.
4374+
*
4375+
* @return {@code true} if unlocking succeeded.
4376+
*
4377+
* <p>
4378+
* For the function to succeed, the range specified need not match a range
4379+
* passed to a previous call to the VirtualLock function, but all pages in
4380+
* the range must be locked. If any of the pages in the specified range are
4381+
* not locked, VirtualUnlock removes such pages from the working set, sets
4382+
* last error to ERROR_NOT_LOCKED, and returns FALSE.
4383+
* </p>
4384+
* <p>
4385+
* Calling VirtualUnlock on a range of memory that is not locked releases
4386+
* the pages from the process's working set.
4387+
* </p>
4388+
*/
4389+
boolean VirtualUnlock(Pointer lpAddress, SIZE_T dwSize);
43104390
}

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,4 +2088,15 @@ public void testOpenFileMapping() throws IOException {
20882088

20892089
}
20902090

2091+
public void testVirtualLockUnlock() {
2092+
Memory mem = new Memory(4096);
2093+
// Test that locking works
2094+
assertTrue(Kernel32.INSTANCE.VirtualLock(mem, new SIZE_T(4096)));
2095+
// Test that unlocked region can be unlocked
2096+
assertTrue(Kernel32.INSTANCE.VirtualUnlock(mem, new SIZE_T(4096)));
2097+
// Locking a region we don't have access to should fail
2098+
assertFalse(Kernel32.INSTANCE.VirtualLock(null, new SIZE_T(4096)));
2099+
// Unlocking an unlocked region should fail
2100+
assertFalse(Kernel32.INSTANCE.VirtualUnlock(mem, new SIZE_T(4096)));
2101+
}
20912102
}

0 commit comments

Comments
 (0)