Skip to content

OpenFileMapping method added to Kernel32 #1390

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Next Release (5.10.0)
Features
--------
* [#1377](https://github.com/java-native-access/jna/pull/1377): Add `RegLoadAppKey` to `c.s.j.p.win32.Advapi32` and `registryLoadAppKey` to `c.s.j.p.win32.Advapi32Util` - [@mfilippov](https://github.com/mfilippov).
* [#1093](https://github.com/java-native-access/jna/issues/1093): Add `OpenFileMapping` to `c.s.j.p.win32.Kernel32` - [@lmitusinski](https://github.com/lmitusinski).

Bug Fixes
---------
Expand Down
19 changes: 19 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java
Original file line number Diff line number Diff line change
Expand Up @@ -1107,6 +1107,25 @@ HANDLE CreateFileMapping(HANDLE hFile,
WinBase.SECURITY_ATTRIBUTES lpAttributes, int flProtect,
int dwMaximumSizeHigh, int dwMaximumSizeLow, String lpName);

/**
* Opens a named file mapping object.
*
* @param dwDesiredAccess
* The access to the file mapping object. This access is checked
* against any security descriptor on the target file mapping object.
* For a list of values, see File Mapping Security and Access Rights.
* @param bInheritHandle
* If this parameter is true, a process created by the CreateProcess
* function can inherit the handle; otherwise,
* the handle cannot be inherited.
* @param lpName
* The name of the file mapping object to be opened.
* @return If the function succeeds, the return value is an open handle to
* the specified file mapping object. If the function fails, the
* return value is NULL. To get extended error information, call GetLastError.
*/
HANDLE OpenFileMapping(int dwDesiredAccess, boolean bInheritHandle, String lpName);

/**
* Maps a view of a file mapping into the address space of a calling
* process.
Expand Down
6 changes: 6 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/WinBase.java
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,12 @@ public interface WinBase extends WinDef, BaseTSD {
int FileIdExtdDirectoryInfo = 19; // 0x13
int FileIdExtdDirectoryRestartInfo = 20; // 0x14

int FILE_MAP_COPY = WinNT.SECTION_QUERY;
int FILE_MAP_WRITE = WinNT.SECTION_MAP_WRITE;
int FILE_MAP_READ = WinNT.SECTION_MAP_READ;
int FILE_MAP_ALL_ACCESS = WinNT.SECTION_ALL_ACCESS;
int FILE_MAP_EXECUTE = WinNT.SECTION_MAP_EXECUTE_EXPLICIT;

/**
* Contains the basic information for a file. Used for file handles.
*/
Expand Down
7 changes: 7 additions & 0 deletions contrib/platform/src/com/sun/jna/platform/win32/WinNT.java
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,13 @@ public abstract class SID_NAME_USE {
int SECTION_MAP_READ = 0x0004;
int SECTION_MAP_EXECUTE = 0x0008;
int SECTION_EXTEND_SIZE = 0x0010;
int SECTION_ALL_ACCESS = WinNT.STANDARD_RIGHTS_REQUIRED
| WinNT.SECTION_QUERY
| WinNT.SECTION_MAP_WRITE
| WinNT.SECTION_MAP_READ
| WinNT.SECTION_MAP_EXECUTE
| WinNT.SECTION_EXTEND_SIZE;
int SECTION_MAP_EXECUTE_EXPLICIT = 0x0020;

int FILE_SHARE_READ = 0x00000001;
int FILE_SHARE_WRITE = 0x00000002;
Expand Down
126 changes: 126 additions & 0 deletions contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.file.Files;
Expand Down Expand Up @@ -92,6 +94,7 @@
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.ShortByReference;


import junit.framework.TestCase;
import org.junit.Assume;

Expand Down Expand Up @@ -1962,4 +1965,127 @@ public void testApplicationRestart() {
Kernel32.INSTANCE.UnregisterApplicationRestart();
}
}

public void testCreateFileMapping() throws IOException {
// Test creating an unnamed file mapping. The test creates a file, that
// containes "Hello World" followed by a NULL byte. The file is mapped
// into memory and read with the normal pointer getString funtion to
// read it as a NULL terminated string.

String testString = "Hello World";
File testFile = File.createTempFile("jna-test", ".txt");

try {
OutputStream os = new FileOutputStream(testFile);
try {
os.write(testString.getBytes("UTF-8"));
os.write(0);
} finally {
os.close();
}

SYSTEM_INFO lpSystemInfo = new SYSTEM_INFO();
Kernel32.INSTANCE.GetSystemInfo(lpSystemInfo);

HANDLE fileHandle = Kernel32.INSTANCE.CreateFile(
testFile.getAbsolutePath(),
WinNT.GENERIC_READ | WinNT.GENERIC_WRITE,
0,
null,
WinNT.OPEN_EXISTING,
WinNT.FILE_ATTRIBUTE_NORMAL,
null);

assertNotNull(fileHandle);

HANDLE fileMappingHandle = Kernel32.INSTANCE.CreateFileMapping(
fileHandle,
null,
WinNT.PAGE_READWRITE,
0,
lpSystemInfo.dwAllocationGranularity.intValue(),
null);

assertNotNull(fileMappingHandle);

Pointer mappingAddress = Kernel32.INSTANCE.MapViewOfFile(
fileMappingHandle,
WinNT.FILE_MAP_ALL_ACCESS,
0,
0,
lpSystemInfo.dwAllocationGranularity.intValue());

assertNotNull(mappingAddress);

assertEquals(testString, mappingAddress.getString(0, "UTF-8"));

assertTrue(Kernel32.INSTANCE.UnmapViewOfFile(mappingAddress));

assertTrue(Kernel32.INSTANCE.CloseHandle(fileMappingHandle));

assertTrue(Kernel32.INSTANCE.CloseHandle(fileHandle));
} finally {
testFile.delete();
}
}

public void testOpenFileMapping() throws IOException {
// Test creating an named file mapping. The test creates a file mapping
// backed by the paging paging file. A second Mapping is opened from
// that. The first mapping is used to write a test string and the
// second is used to read it.

int mappingSize = 256;
String nameOfMapping = "JNATestMapping";
String testString = "Hello World";

HANDLE fileMappingHandle1 = Kernel32.INSTANCE.CreateFileMapping(
WinNT.INVALID_HANDLE_VALUE,
null,
WinNT.PAGE_READWRITE,
0,
mappingSize,
nameOfMapping);

assertNotNull("Error: " + Kernel32.INSTANCE.GetLastError(), fileMappingHandle1);

HANDLE fileMappingHandle2 = Kernel32.INSTANCE.OpenFileMapping(
WinNT.FILE_MAP_ALL_ACCESS,
false,
nameOfMapping);

assertNotNull(fileMappingHandle1);

Pointer mappingAddress1 = Kernel32.INSTANCE.MapViewOfFile(
fileMappingHandle1,
WinNT.FILE_MAP_ALL_ACCESS,
0,
0,
mappingSize);

assertNotNull(mappingAddress1);

Pointer mappingAddress2 = Kernel32.INSTANCE.MapViewOfFile(
fileMappingHandle2,
WinNT.FILE_MAP_ALL_ACCESS,
0,
0,
mappingSize);

assertNotNull(mappingAddress2);

mappingAddress1.setString(0, testString, "UTF-8");

assertEquals(testString, mappingAddress2.getString(0, "UTF-8"));

assertTrue(Kernel32.INSTANCE.UnmapViewOfFile(mappingAddress1));

assertTrue(Kernel32.INSTANCE.UnmapViewOfFile(mappingAddress2));

assertTrue(Kernel32.INSTANCE.CloseHandle(fileMappingHandle1));

assertTrue(Kernel32.INSTANCE.CloseHandle(fileMappingHandle2));

}

}