Mumble Link for Java using JNA?

Mumble Link for Java using JNA?

in API Development

Posted by: Lulan.8497

Lulan.8497

Q:

Hey,

did anybody figured out how to establish a Mumble Link for position retrieval using JNA (Java Native Access)?

Im stuck… I tried several different setups… Anyway… my current one looks similar to this:

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.HANDLE;

HANDLE sharedFile = Kernel32.INSTANCE.CreateFileMapping(WinBase.INVALID_HANDLE_VALUE, null, WinNT.PAGE_EXECUTE_READWRITE, 0, 48, “/MumbleLink”);
Pointer sharedMemory = Kernel32.INSTANCE.MapViewOfFile(this.sharedFile, WinNT.SECTION_QUERY, 0, 0, 48);
final int ret = Kernel32.INSTANCE.WaitForSingleObject(sharedFile, WinBase.INFINITE); System.out.println(Arrays.toString(sharedMemory.getByteArray(0, 48)));

But all i get is a bunch of zeros xD

Here is some small java test class you might start from …


import java.util.Arrays;

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.HANDLE;

public class JNATest {
	private final HANDLE sharedFile;
	private final Pointer sharedMemory;

	public JNATest() {
		// final String name = "MumbleLink." + ManagementFactory.getRuntimeMXBean().getName().split(Pattern.quote("@"))[0];
		final String name = "MumbleLink";
		System.out.println("filename: " + name);

		this.sharedFile = Kernel32.INSTANCE.CreateFileMapping(WinBase.INVALID_HANDLE_VALUE, null, WinNT.PAGE_READWRITE, 0, 48, name);
		this.sharedMemory = Kernel32.INSTANCE.MapViewOfFile(this.sharedFile, WinNT.SECTION_MAP_WRITE, 0, 0, 48);

		try {
			while (true) {
				System.out.println(Arrays.toString(this.sharedMemory.getByteArray(0, 48)));
				Thread.sleep(1000);
			}
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			if (!WinBase.INVALID_HANDLE_VALUE.equals(this.sharedFile)) {
				Kernel32.INSTANCE.CloseHandle(this.sharedFile);
			}
		}
	}

	public static void main(String[] args) throws InterruptedException {
		new JNATest();
	}
}

(edited by Lulan.8497)

Mumble Link for Java using JNA?

in API Development

Posted by: Lulan.8497

Lulan.8497

A:

Thank you for your answers
I put those correction into again a short example… well the result is still…. a bunch of zeros…
Is it possible, that i ran into some permission/security issues?


import java.util.Arrays;

import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinBase;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.platform.win32.WinNT.HANDLE;

public class JNATest {
	private static final int MEM_MAP_SIZE = 5460;
	private static final String MEM_MAP_NAME = "MumbleLink";
	private final HANDLE sharedFile;
	private Pointer sharedMemory;

	public JNATest() throws InterruptedException {

		int uiVersion = 0;
		int uiTick = 0;
		float[] fAvatarPosition = new float[0];
		float[] fAvatarFront = new float[0];
		float[] fAvatarTop = new float[0];
		float[] fCameraPosition = new float[0];
		float[] fCameraFront = new float[0];
		float[] fCameraTop = new float[0];
		char[] characterName = new char[0];
		char[] gameName = new char[0];
		int context_len = 0;
		byte[] context = new byte[0];

		this.sharedFile = Kernel32.INSTANCE.CreateFileMapping(WinBase.INVALID_HANDLE_VALUE, null, WinNT.PAGE_EXECUTE_READWRITE, 0, MEM_MAP_SIZE, MEM_MAP_NAME);
		this.sharedMemory = Kernel32.INSTANCE.MapViewOfFile(this.sharedFile, WinNT.SECTION_MAP_READ, 0, 0, MEM_MAP_SIZE);
		while (this.sharedMemory != null) {
			uiVersion = this.sharedMemory.getInt(0);
			uiTick = this.sharedMemory.getInt(4);
			fAvatarPosition = this.sharedMemory.getFloatArray(8, 3);
			fAvatarFront = this.sharedMemory.getFloatArray(20, 3);
			fAvatarTop = this.sharedMemory.getFloatArray(32, 3);
			gameName = this.sharedMemory.getCharArray(44, 256);
			fCameraPosition = this.sharedMemory.getFloatArray(556, 3);
			fCameraFront = this.sharedMemory.getFloatArray(568, 3);
			fCameraTop = this.sharedMemory.getFloatArray(580, 3);
			characterName = this.sharedMemory.getCharArray(592, 256);
			context_len = this.sharedMemory.getInt(1104);
			context = this.sharedMemory.getByteArray(1108, 256);
			System.out.println("uiVersion: " + uiVersion);
			System.out.println("uiTick: " + uiTick);
			System.out.println("fAvatarPosition: " + Arrays.toString(fAvatarPosition));
			System.out.println("fAvatarFront: " + Arrays.toString(fAvatarFront));
			System.out.println("fAvatarTop: " + Arrays.toString(fAvatarTop));
			System.out.println("gameName: " + Arrays.toString(gameName));
			System.out.println("fCameraPosition: " + Arrays.toString(fCameraPosition));
			System.out.println("fCameraFront: " + Arrays.toString(fCameraFront));
			System.out.println("fCameraTop: " + Arrays.toString(fCameraTop));
			System.out.println("identity: " + Arrays.toString(characterName));
			System.out.println("context_len: " + context_len);
			System.out.println("context: " + Arrays.toString(context));
			System.out.println("#####################################################");
			Thread.sleep(1000);
		}
	}

	public static void main(String[] args) throws InterruptedException {
		new JNATest();
	}
}

Edit:
It turned out, that if mumble client first creates the mem mapped file and i start my java application after that file is already created, everything works….
Do i need some security settings to get the creation by my java app work?

Edit:
When using PAGE_EXECUTE_READWRITE it works as expected. -> altered code above

(edited by Lulan.8497)

Mumble Link for Java using JNA?

in API Development

Posted by: Lulan.8497

Lulan.8497

Hello Guys,

since i got no answers here, i investigated the whole problem a bit more by myself.

I used Microsofts Process Explorer (http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx) to check which memory mapped files are opened by which process.

I found out, that my java process has opened “\Sessions\1\BaseNamedObjects\MumbleLink” and the GW2 Process not.

Is that the expected behavior?

I executed my java app with elevated rights an got access to global scope…
that resulted in a ememory mapped file handle \BaseNamedObjects\MumbleLink … well… it didn’t worked out as well..

(edited by Lulan.8497)

Mumble Link for Java using JNA?

in API Development

Posted by: Lulan.8497

Lulan.8497

I found out, that when there is a Mumble client running an i than start my java application, i’m able to retrieve the data i wish…. Any ideas why?

Edit:
Restartet IDE, Mumble, Eclipse and Java App —> it doesnt work again

(edited by Lulan.8497)

Mumble Link for Java using JNA?

in API Development

Posted by: Healix.5819

Healix.5819

GW2 will not create MumbleLink. If it has been created and GW2 is logged in with a character, it will open and begin writing to it. If you’re in a scenario where GW2 is running and doesn’t have MumbleLink open, then either MumbleLink hasn’t been created or it’s been created in a way which GW2 cannot open and write to it.

Judging by the code in the first post, I see 3 errors.

1. Remove the / in “/MumbleLink”
2. Your mapping doesn’t allocate enough space, change each 48 to 5460
3. You’re not actually reading, change WinNT.SECTION_QUERY to WinNT.SECTION_MAP_READ

Mumble Link for Java using JNA?

in API Development

Posted by: Lulan.8497

Lulan.8497

I compared the address and size of the memory mapped file that is created by the mumble client with the one created by my own.

0xFFFFF8A00A581810 vs. 0xFFFFF8A00A581810

They are the same….

Mumble Link for Java using JNA?

in API Development

Posted by: Heimdall.4510

Heimdall.4510

Have you already tried to create the shared Memory section with just “MumbleLink” instead of “/MumbleLink”? – ah not fast enough…

~ Heimdall
Die Vollenstrecker [VS] – Elona Reach [DE]
https://gw2apicpp.codeplex.com – Gw2API C/C++ Project

Mumble Link for Java using JNA?

in API Development

Posted by: Much.2794

Much.2794

I got it working with a few changes to you’re setup.

Here are a few lines from the working code:

final String name = “MumbleLink”;

sharedFile = Kernel32.INSTANCE.CreateFileMapping(
WinBase.INVALID_HANDLE_VALUE, null, WinNT.PAGE_READONLY, 0,
5460, name);

Pointer sharedMemory = Kernel32.INSTANCE.MapViewOfFile(sharedFile,
WinNT.SECTION_MAP_READ, 0, 0, 5460);

if (sharedMemory != null) {
uiVersion = sharedMemory.getInt(0);
uiTick = sharedMemory.getInt(4);
fAvatarPosition = sharedMemory.getFloatArray(8, 3);
fAvatarFront = sharedMemory.getFloatArray(20, 3);
fAvatarTop = sharedMemory.getFloatArray(32, 3);
name = sharedMemory.getCharArray(44, 256);
fCameraPosition = sharedMemory.getFloatArray(556, 3);
fCameraFront = sharedMemory.getFloatArray(568, 3);
fCameraTop = sharedMemory.getFloatArray(580, 3);

identity = sharedMemory.getCharArray(592, 256);
context_len = sharedMemory.getInt(1104);
context = sharedMemory.getByteArray(1108, 256);
}

If the code still returns a lot of “0” play the game for a few seconds and the values will change.

Elements of Much [PunK]

(edited by Much.2794)

Mumble Link for Java using JNA?

in API Development

Posted by: Healix.5819

Healix.5819

Pointer sharedMemory = Kernel32.INSTANCE.MapViewOfFile(sharedFile,
WinNT.SECTION_MAP_WRITE, 0, 0, 5460);

That SECTION_MAP_WRITE means you’re opening the mapping with write/read access. It doesn’t really matter, but since you only need to read the data, that WRITE should be a READ.

Mumble Link for Java using JNA?

in API Development

Posted by: Much.2794

Much.2794

Pointer sharedMemory = Kernel32.INSTANCE.MapViewOfFile(sharedFile,
WinNT.SECTION_MAP_WRITE, 0, 0, 5460);

That SECTION_MAP_WRITE means you’re opening the mapping with write/read access. It doesn’t really matter, but since you only need to read the data, that WRITE should be a READ.

Edited in my post and also changed the Kernel32.INSTANCE.CreateFileMapping to readonly

Elements of Much [PunK]

Mumble Link for Java using JNA?

in API Development

Posted by: Wothor.4781

Wothor.4781

It’s not really my expertise, since I only used it in c++ for CrossTalk yet before I switched over to the Qt variant, but imo
CreateFileMapping(
WinBase.INVALID_HANDLE_VALUE, null, WinNT.PAGE_READONLY, 0,
5460, name)
looks rather suspicious.
Aren’t you creating a File Mapping that’s protected for read-only access? I figure GW2 would not be able to write to that then.

Shouldn’t just recreating the exact same variant that Mumble Link itself uses:
Try to open file mapping, if not create file mapping (read/write access) be the way to go?


hMapObject = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");
if (hMapObject == NULL) {
hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(LinkedMem), L"MumbleLink");
bCreated = true;
if (hMapObject == NULL)
return false;
}
lm = static_cast<LinkedMem *>(MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, 0));

The access rights in OpenFileMapping and/or MapViewOfFile could probably indeed be opted to some sort of read access, unless you want to imitate Link’s unlock function, which I’d rather do not.

(edited by Wothor.4781)

Mumble Link for Java using JNA?

in API Development

Posted by: Healix.5819

Healix.5819

You created it as a read only memory. You need to change it back to PAGE_EXECUTE_READWRITE, like you had originally.

CreateFileMapping(WinBase.INVALID_HANDLE_VALUE, null, WinNT.PAGE_EXECUTE_READWRITE, 0, MEM_MAP_SIZE, MEM_MAP_NAME);

HANDLE sharedFile = Kernel32.INSTANCE.CreateFileMapping(WinBase.INVALID_HANDLE_VALUE, null, WinNT.PAGE_EXECUTE_READWRITE, 0, 5460, “MumbleLink”);
Pointer sharedMemory = Kernel32.INSTANCE.MapViewOfFile(sharedFile, WinNT.SECTION_MAP_READ, 0, 0, 5460);
System.out.println(Arrays.toString(sharedMemory.getByteArray(0, 48)));

(edited by Healix.5819)

Mumble Link for Java using JNA?

in API Development

Posted by: Wothor.4781

Wothor.4781

I’d still try to open it first, before I create it.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366537(v=vs.85).aspx
If the object exists before the function call, the function returns a handle to the existing object (with its current size, not the specified size), and GetLastError returns ERROR_ALREADY_EXISTS.

Just creating it would, as I read it, render it incompatible to simultaneously running applications, like the Mumble client or the CrossTalk TS3-Addon.

Also, I dunno why one would want to add execute to the standard implementation’s PAGE_READWRITE.

(edited by Wothor.4781)

Mumble Link for Java using JNA?

in API Development

Posted by: Lulan.8497

Lulan.8497

PAGE_EXECUTE_READWRITE worked out

The problem with open is that the platform component of JNA does not provide the OpenFileMapping method…

Mumble Link for Java using JNA?

in API Development

Posted by: Healix.5819

Healix.5819

JNA’s Open/CreateFileMapping is simplified. By default, it’s actually OpenFileMapping. If that fails, it becomes CreateFileMapping.

Mumble Link for Java using JNA?

in API Development

Posted by: Wothor.4781

Wothor.4781

Ah I see, they reference to GetLastError returns ERROR_ALREADY_EXISTS for checks. Well then.

Mumble Link for Java using JNA?

in API Development

Posted by: Lulan.8497

Lulan.8497

Okay nice As it finally works now im very grateful for your support! I think i will integrate it into my yagw2api project and publish it in the near future. if any one is interested in it before, just contact me