Get titles of Non-Java Windows in Java - java

Window.getWindows();
Doesn't get all the open windows, just the java ones. Is there a way to get all the windows the operating system has open. I'm making a java taskbar.

There is no solution using core Java, but the problem can be solved using JNI or for an easier time, JNA. As noted in the comments, no solution (that I know of) will be platform independent.
For instance, this demo program uses JNA to enumerate all Windows with title in a Windows platform, but will also include windows that are not top-level windows and even windows that aren't visible:
import java.util.ArrayList;
import java.util.List;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.win32.StdCallLibrary;
public class EnumAllWindowNames {
static interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
interface WNDENUMPROC extends StdCallCallback {
boolean callback(Pointer hWnd, Pointer arg);
}
boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer userData);
int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount);
Pointer GetWindow(Pointer hWnd, int uCmd);
}
public static List<String> getAllWindowNames() {
final List<String> windowNames = new ArrayList<String>();
final User32 user32 = User32.INSTANCE;
user32 .EnumWindows(new User32.WNDENUMPROC() {
#Override
public boolean callback(Pointer hWnd, Pointer arg) {
byte[] windowText = new byte[512];
user32.GetWindowTextA(hWnd, windowText, 512);
String wText = Native.toString(windowText).trim();
if (!wText.isEmpty()) {
windowNames.add(wText);
}
return true;
}
}, null);
return windowNames;
}
public static void main(String[] args) {
List<String> winNameList = getAllWindowNames();
for (String winName : winNameList) {
System.out.println(winName);
}
}
}

Addition to #Hovercraft Full Of Eels, if you also have windows which are titled with unreadable characters and get "?" printed for those characters, try to:
convert byte[] to string by using different encoding (as I understood)
see below:
String wText = Native.toString(windowText, "windows-1254").trim();
Possible encodings instead of "windows-1254 (which worked well for Turkish characters)":
UTF-8
UTF-16
ASCII
ISO-8859-1
...

You can now call into native Windows APIs to read the titles of non-java windows with pure-Java code using Foreign Memory API and code bindings generated by a compatible jextract.
This example works with the preview code in JDK19 release and is the equivalent to Hovercraft Full Of Eels answer:
/**
* Run with Windows JDK19 and preview enabled:
* jdk-19\bin\java --enable-native-access=ALL-UNNAMED --enable-preview -cp your.jar EnumWindowsDemo
*/
public class EnumWindowsDemo {
// Wide to Java String
private static String toJavaString(MemorySegment wide, int len) {
final CharBuffer cb = wide.asByteBuffer().order(ByteOrder.nativeOrder()).asCharBuffer();
return cb.limit(len).toString();
}
public static void main(String[] args) {
// TODO: You could use someParam to detect specific hWnd inside the callback
long someParam = 0x1234;
final int isRunning = User32_h.TRUE();
final int maxChars = 1024;
System.out.format("EnumWindows Panama 19 Demo Java %s%n", System.getProperty("java.runtime.version"));
HashMap<Long,String> windowNames = new HashMap<>();
try(MemorySession arena = MemorySession.openConfined()) {
// JDK20 try(Arena arena = Arena.openConfined()) {
MemorySegment lpString = arena.allocateArray(JAVA_CHAR, maxChars);
// Windows callback WNDENUMPROC(MemorySegment hwnd, long lParam)
WNDENUMPROC callback = (hWnd, lParam) -> {
int used = User32_h.GetWindowTextW(hWnd, lpString, maxChars);
if (used > 0) {
String text = toJavaString(lpString, used);
System.out.format("hWnd:%x lParam:%x => `%s`%n", hWnd.toRawLongValue(), lParam, text);
// JDK20: System.out.format("hWnd:%x lParam:%x => `%s`%n", hWnd.address(), lParam, text);
if (used >= maxChars) {
System.out.format("*** Oops: increase maxChars > %d, or call GetWindowTextLength first ***%n", used);
}
windowNames.put(hWnd.toRawLongValue(), text);
// JDK20: windowNames.put(hWnd.address(), text);
}
return isRunning;
};
final MemorySegment ewProc = WNDENUMPROC.allocate(callback, arena);
// JDK20: final MemorySegment ewProc = WNDENUMPROC.allocate(callback, arena.scope());
// Note that someParam is passed to the callback as lParam value
int rc = User32_h.EnumWindows(ewProc, someParam);
System.out.format("EnumWindows rc:%s%n", rc == 0 ? "FAIL":"OK");
if (rc == 0) {
throw new RuntimeException("EnumWindows failed rc="+rc);
}
}
System.out.format("Found windowNames: %s%n", windowNames.toString());
}
}
The standalone jextract is used to generate bindings for calling native code. You need to create a header User32.h referencing suitable Windows API headers:
echo #include ^<shlobj_core.h^> > User32.h
Run jextract to generate bindings for a suitable set of Windows APIs:
set JEXTRACT_ARGS=--source -luser32 User32.h -t somepackage --output java
set JEXTRACT_SYMBOLS=--include-macro TRUE --include-function EnumWindows --include-function GetWindowTextW --include-function GetWindowTextLengthW --include-typedef WNDENUMPROC
jextract %JEXTRACT_ARGS% %JEXTRACT_SYMBOLS%
You can also save symbols to a file for easy editing, and re-generate by replacing use of %JEXTRACT_SYMBOLS% above by #your.symbols.
See also:
Holger's answer Windows wide string to Java String conversion.
EnumWindows
GetWindowTextW

Related

In Linux and Mac , using JAVA , how can we get the processId and window title of other running programs [duplicate]

Window.getWindows();
Doesn't get all the open windows, just the java ones. Is there a way to get all the windows the operating system has open. I'm making a java taskbar.
There is no solution using core Java, but the problem can be solved using JNI or for an easier time, JNA. As noted in the comments, no solution (that I know of) will be platform independent.
For instance, this demo program uses JNA to enumerate all Windows with title in a Windows platform, but will also include windows that are not top-level windows and even windows that aren't visible:
import java.util.ArrayList;
import java.util.List;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.win32.StdCallLibrary;
public class EnumAllWindowNames {
static interface User32 extends StdCallLibrary {
User32 INSTANCE = (User32) Native.loadLibrary("user32", User32.class);
interface WNDENUMPROC extends StdCallCallback {
boolean callback(Pointer hWnd, Pointer arg);
}
boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer userData);
int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount);
Pointer GetWindow(Pointer hWnd, int uCmd);
}
public static List<String> getAllWindowNames() {
final List<String> windowNames = new ArrayList<String>();
final User32 user32 = User32.INSTANCE;
user32 .EnumWindows(new User32.WNDENUMPROC() {
#Override
public boolean callback(Pointer hWnd, Pointer arg) {
byte[] windowText = new byte[512];
user32.GetWindowTextA(hWnd, windowText, 512);
String wText = Native.toString(windowText).trim();
if (!wText.isEmpty()) {
windowNames.add(wText);
}
return true;
}
}, null);
return windowNames;
}
public static void main(String[] args) {
List<String> winNameList = getAllWindowNames();
for (String winName : winNameList) {
System.out.println(winName);
}
}
}
Addition to #Hovercraft Full Of Eels, if you also have windows which are titled with unreadable characters and get "?" printed for those characters, try to:
convert byte[] to string by using different encoding (as I understood)
see below:
String wText = Native.toString(windowText, "windows-1254").trim();
Possible encodings instead of "windows-1254 (which worked well for Turkish characters)":
UTF-8
UTF-16
ASCII
ISO-8859-1
...
You can now call into native Windows APIs to read the titles of non-java windows with pure-Java code using Foreign Memory API and code bindings generated by a compatible jextract.
This example works with the preview code in JDK19 release and is the equivalent to Hovercraft Full Of Eels answer:
/**
* Run with Windows JDK19 and preview enabled:
* jdk-19\bin\java --enable-native-access=ALL-UNNAMED --enable-preview -cp your.jar EnumWindowsDemo
*/
public class EnumWindowsDemo {
// Wide to Java String
private static String toJavaString(MemorySegment wide, int len) {
final CharBuffer cb = wide.asByteBuffer().order(ByteOrder.nativeOrder()).asCharBuffer();
return cb.limit(len).toString();
}
public static void main(String[] args) {
// TODO: You could use someParam to detect specific hWnd inside the callback
long someParam = 0x1234;
final int isRunning = User32_h.TRUE();
final int maxChars = 1024;
System.out.format("EnumWindows Panama 19 Demo Java %s%n", System.getProperty("java.runtime.version"));
HashMap<Long,String> windowNames = new HashMap<>();
try(MemorySession arena = MemorySession.openConfined()) {
// JDK20 try(Arena arena = Arena.openConfined()) {
MemorySegment lpString = arena.allocateArray(JAVA_CHAR, maxChars);
// Windows callback WNDENUMPROC(MemorySegment hwnd, long lParam)
WNDENUMPROC callback = (hWnd, lParam) -> {
int used = User32_h.GetWindowTextW(hWnd, lpString, maxChars);
if (used > 0) {
String text = toJavaString(lpString, used);
System.out.format("hWnd:%x lParam:%x => `%s`%n", hWnd.toRawLongValue(), lParam, text);
// JDK20: System.out.format("hWnd:%x lParam:%x => `%s`%n", hWnd.address(), lParam, text);
if (used >= maxChars) {
System.out.format("*** Oops: increase maxChars > %d, or call GetWindowTextLength first ***%n", used);
}
windowNames.put(hWnd.toRawLongValue(), text);
// JDK20: windowNames.put(hWnd.address(), text);
}
return isRunning;
};
final MemorySegment ewProc = WNDENUMPROC.allocate(callback, arena);
// JDK20: final MemorySegment ewProc = WNDENUMPROC.allocate(callback, arena.scope());
// Note that someParam is passed to the callback as lParam value
int rc = User32_h.EnumWindows(ewProc, someParam);
System.out.format("EnumWindows rc:%s%n", rc == 0 ? "FAIL":"OK");
if (rc == 0) {
throw new RuntimeException("EnumWindows failed rc="+rc);
}
}
System.out.format("Found windowNames: %s%n", windowNames.toString());
}
}
The standalone jextract is used to generate bindings for calling native code. You need to create a header User32.h referencing suitable Windows API headers:
echo #include ^<shlobj_core.h^> > User32.h
Run jextract to generate bindings for a suitable set of Windows APIs:
set JEXTRACT_ARGS=--source -luser32 User32.h -t somepackage --output java
set JEXTRACT_SYMBOLS=--include-macro TRUE --include-function EnumWindows --include-function GetWindowTextW --include-function GetWindowTextLengthW --include-typedef WNDENUMPROC
jextract %JEXTRACT_ARGS% %JEXTRACT_SYMBOLS%
You can also save symbols to a file for easy editing, and re-generate by replacing use of %JEXTRACT_SYMBOLS% above by #your.symbols.
See also:
Holger's answer Windows wide string to Java String conversion.
EnumWindows
GetWindowTextW

Is it possible to access the MS Windows certificate template name of an X509 certificate from Java?

Using BouncyCastle library and the code below it is possible to access the MS Windows certificate template information extension of a SSL certificate stored in MS Windows' trust/certificate store.
final KeyStore keyStore = KeyStore.getInstance("Windows-My", "SunMSCAPI");
keyStore.load(null, null);
final X509Certificate certificate = (X509Certificate)keyStore.aliases().nextElement();
// see https://learn.microsoft.com/en-us/windows/win32/seccertenroll/supported-extensions#template
final String XCN_OID_CERTIFICATE_TEMPLATE = "1.3.6.1.4.1.311.21.7";
final byte[] extensionValue = certificate.getExtensionValue(XCN_OID_CERTIFICATE_TEMPLATE);
final ASN1InputStream aIn = new ASN1InputStream(extensionValue);
ASN1Primitive asn1obj = aIn.readObject();
if (asn1obj instanceof DEROctetString)
{
final DEROctetString octets = (DEROctetString) asn1obj;
asn1obj = ASN1Primitive.fromByteArray(octets.getOctets());
}
final ASN1Sequence asn1seq = ASN1Sequence.getInstance(asn1obj);
final ASN1Encodable obj1 = asn1seq.getObjectAt(0);
final ASN1Primitive certificateTemplateOID = obj1.toASN1Primitive();
System.out.println(certificateTemplateOID.toString());
It will print out something like 1.3.6.1.4.1.311.21.8.... which is the OID of the certificate template.
Now I would like to know if there is a Java method or Java library which provides a mapping of this OID to the certificate template name (as a user-friendly string) - like it is done when you click on details of a certificate in Windows certificiate store:
Certificate template information in MS Windows
Additional links:
Windows certificate extension for certificate templates
Windows certificate extension for certificate templates - data structure
ObjectIdentifiers (OID) in PKI
the only way to get mapping for this OID value is to call CryptEnumOIDInfo function on a domain-joined machine. These OIDs are generated dynamically and stored in Active Directory. This function can read OIDs from local OID database and from Active Directory. Note, that you must call this function in AD forest where that certificate template is installed.
17.02.2021 update:
I specified wrong function. Actual function is CryptFindOIDInfo. The function accepts three parameters with the following values (for your given case):
dwKeyType -- must be 1 (CRYPT_OID_INFO_OID_KEY)
*pvKey -- must be a pointer to an ANSI string.
dwGroupId -- must be 9 (CRYPT_TEMPLATE_OID_GROUP_ID)
the function returns a pointer to a CRYPT_OID_INFO structure. pwszName will store friendly name of the requested OID. In a given case, union value of CRYPT_OID_INFO structure is DWORD dwValue. I have no idea how easy this is in Java.
As another option, if you can access .NET API from Java, you can try instantiating an Oid class using Oid(String) constructor:
var oid = new System.Security.Cryptography.Oid("1.3.6.1.4.1.311.21.8...");
Console.WriteLine(oid.FriendlyName); // this will output template display name.
As pointed out by #Crypt32, the function CryptFindOIDInfo has to be called via Java NativeAccess (JNA):
Here is the code for JNA Version 4.1.0:
final NativeLibrary crypt32 = NativeLibrary.getInstance("Crypt32");
final int CRYPT_OID_INFO_OID_KEY = 1;
final int XCN_CRYPT_TEMPLATE_OID_GROUP_ID = 9;
final Function functionCryptFindOIDInfo = crypt32.getFunction("CryptFindOIDInfo");
final String ptrPvKey = certificateTemplateOID.toString();
final Object[] argsCryptFindOIDInfo = new Object[] { CRYPT_OID_INFO_OID_KEY, ptrPvKey,
XCN_CRYPT_TEMPLATE_OID_GROUP_ID };
final CRYPT_OID_INFO result = (CRYPT_OID_INFO) functionCryptFindOIDInfo.invoke(CRYPT_OID_INFO.class,
argsCryptFindOIDInfo);
System.out.println(result.pwszName);
class CRYPT_OID_INFO.java
public class CRYPT_OID_INFO extends Structure
{
public int cbSize;
public String pszOID;
public WString pwszName;
public int dwGroupId;
public DUMMYUNION DUMMYUNIONNAME;
public CRYPT_DATA_BLOB ExtraInfo;
public String pwszCNGAlgid;
public String pwszCNGExtraAlgid;
#Override
public List<String> getFieldOrder()
{
final List<String> result = new ArrayList<>();
result.add("cbSize");
result.add("pszOID");
result.add("pwszName");
result.add("dwGroupId");
result.add("DUMMYUNIONNAME");
result.add("ExtraInfo");
result.add("pwszCNGAlgid");
result.add("pwszCNGExtraAlgid");
return result;
}
}
class DUMMYUNION .java
public class DUMMYUNION extends Union
{
public int dwValue;
public int Algid;
public int dwLength;
}
class CRYPT_DATA_BLOB
public class CRYPT_DATA_BLOB extends Structure
{
public int cbData;
public Pointer pbData;
#Override
public List<String> getFieldOrder()
{
final String[] array = new String[] { "cbData", "pbData" };
return Arrays.asList(array);
}
}

JNR-FFI crash after calling c function copying struct

I am trying to interface with a C library libzbc using jnr-ffi.
The first function call zbc_open works and returns a pointer to a open device. Then the next call to zbc_get_device_info causes a JVM crash.
What is the cause? How to solve it?
I think the error is somewhere in the interface of zbc or my passing parameters but searching for any documentation for JNR yielded no helpful results in google.The crash happens too if i omit the array part in the structure.
I am using the project of jnr-fuse as a starting point because my goal is to write a FUSE filesystem.
Crash log at pastebin
C functions:
void zbc_set_log_level( char *log_level )
int zbc_open (const char *filename, int flags, struct zbc_device **dev)
void zbc_get_device_info( struct zbc_device *dev, struct zbc_device_info * info)
C structure zbc_device_info:
enum zbc_dev_type zbd_type
enum zbc_dev_model zbd_model
char zbd_vendor_id [ZBC_DEVICE_INFO_LENGTH]
uint32_t zbd_flags
uint64_t zbd_sectors
uint32_t zbd_lblock_size
uint64_t zbd_lblocks
uint32_t zbd_pblock_size
uint64_t zbd_pblocks
uint64_t zbd_max_rw_sectors
uint32_t zbd_opt_nr_open_seq_pref
uint32_t zbd_opt_nr_non_seq_write_seq_pref
uint32_t zbd_max_nr_open_seq_req
JNR interface:
public interface zbc{
public void zbc_set_log_level(String level);
public int zbc_open(String filename,int flags, PointerByReference p);
public void zbc_get_device_info(Pointer dev,zbc_device_info info);
}
public static class zbc_device_info extends Struct {
int zbd_type;
int zbd_model;
byte zbd_vendor_id[]=new byte[32];
u_int32_t zbd_flags;
u_int64_t zbd_sectors;
u_int32_t zbd_lblock_size;
u_int64_t zbd_lblocks;
u_int32_t zbd_pblock_size;
u_int64_t zbd_pblocks;
u_int64_t zbd_max_rw_sectors;
u_int32_t zbd_opt_nr_open_seq_pref;
u_int32_t zbd_opt_nr_non_seq_write_seq_pref;
u_int32_t zbd_max_nr_open_seq_pref;
protected zbc_device_info(Runtime runtime) {
super(runtime);
}
}
The main function:
public static void main(String[] args) {
zbc z = LibraryLoader.create(zbc.class).load("zbc");
Runtime runtime=Runtime.getRuntime(z);
z.zbc_set_log_level("debug");
PointerByReference pr = new PointerByReference();
int ret=z.zbc_open("/temp/test.img", IO_RDWR,pr);
zbc_device_info info=new zbc_device_info(runtime);
z.zbc_get_device_info(pr.getValue(),info);
}
JVM crash:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007fa794300c70, pid=29106, tid=0x00007fa7bd4a4700
#
# JRE version: OpenJDK Runtime Environment (8.0_131-b11) (build 1.8.0_131-8u131-b11-2ubuntu1.16.04.3-b11)
# Java VM: OpenJDK 64-Bit Server VM (25.131-b11 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [jffi6917022509387828651.so+0x5c70] jffi_releaseArrays+0x60
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/mmmm/jnr-fuse/hs_err_pid29106.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
The declaration of Struct is incorrect. The fields are not declared. Try to use the following declaration:
package com.github.goto1134.libzbc;
import jnr.ffi.Runtime;
import jnr.ffi.Struct;
import jnr.ffi.util.EnumMapper.IntegerEnum;
public class zbc_device_info
extends Struct {
public static final int ZBC_DEVICE_INFO_LENGTH = 32;
public final Enum<zbc_dev_type> zbd_type = new Enum<>(zbc_dev_type.class);
public final Enum<zbc_dev_model> zbd_model = new Enum<>(zbc_dev_model.class);
public final UTF8String zbd_vendor_id = new UTF8String(ZBC_DEVICE_INFO_LENGTH);
public final Unsigned32 zbd_flags = new Unsigned32();
public final Unsigned64 zbd_sectors = new Unsigned64();
public final Unsigned32 zbd_lblock_size = new Unsigned32();
public final Unsigned64 zbd_lblocks = new Unsigned64();
public final Unsigned32 zbd_pblock_size = new Unsigned32();
public final Unsigned64 zbd_pblocks = new Unsigned64();
public final Unsigned64 zbd_max_rw_sectors = new Unsigned64();
public final Unsigned32 zbd_opt_nr_open_seq_pref = new Unsigned32();
public final Unsigned32 zbd_opt_nr_non_seq_write_seq_pref = new Unsigned32();
public final Unsigned32 zbd_max_nr_open_seq_req = new Unsigned32();
protected zbc_device_info(Runtime runtime) {
super(runtime);
}
public enum zbc_dev_type
implements IntegerEnum {
/**
* Unknown drive type.
*/
ZBC_DT_UNKNOWN(0x00),
/**
* Zoned block device (for kernels supporting ZBC/ZAC).
*/
ZBC_DT_BLOCK(0x01),
/**
* SCSI device.
*/
ZBC_DT_SCSI(0x02),
/**
* ATA device.
*/
ZBC_DT_ATA(0x03),
/**
* Fake device (emulation mode).
*/
ZBC_DT_FAKE(0x04);
private final int value;
zbc_dev_type(int value) {
this.value = value;
}
#Override
public int intValue() {
return value;
}
}
public enum zbc_dev_model
implements IntegerEnum {
/**
* Unknown drive model.
*/
ZBC_DM_DRIVE_UNKNOWN(0x00),
/**
* Host-aware drive model: the device type/signature is 0x00
* and the ZONED field of the block device characteristics VPD
* page B1h is 01b.
*/
ZBC_DM_HOST_AWARE(0x01),
/**
* Host-managed drive model: the device type/signature is 0x14/0xabcd.
*/
ZBC_DM_HOST_MANAGED(0x02),
/**
* Drive-managed drive model: the device type/signature is 0x00
* and the ZONED field of the block device characteristics VPD
* page B1h is 10b.
*/
ZBC_DM_DEVICE_MANAGED(0x03),
/**
* Standard block device: the device type/signature is 0x00
* and the ZONED field of the block device characteristics VPD
* page B1h is 00b.
*/
ZBC_DM_STANDARD(0x04);
private final int value;
zbc_dev_model(int value) {
this.value = value;
}
#Override
public int intValue() {
return value;
}
}
}
In hs logs there is a call stack that made the program crash. Can you provide it?

Error looking up function in a Borland DLL through JNA

Here is a running example of my DLLService :
import com.sun.jna.Native;
import com.sun.jna.win32.StdCallLibrary;
public class DLLService {
public DLLService() throws Exception {
System.out.println("version = " + version() + "\n");
testEvaluate();
}
public void testEvaluate() {
System.out.println(this.loadFile("file", 1));
int[] barre = new int[] {0, 1, 2, 3, 4};
int[] result = new int[]{};
evaluateParty(barre.length, barre, result, 1);
System.out.println(result);
}
public int version() {
return GDLL.INSTANCE.LireNoVersion();
}
public int loadFile(String tslName, int pdwNoSess) {
return GDLL.INSTANCE.ChargerFichier();
}
public interface GDLL extends StdCallLibrary {
GDLL INSTANCE = (GDLL) Native.loadLibrary("tsr32_mini", GDLL.class);
int LireNoVersion();
int ChargerFichier();
}
}
There is no problem with the function version() but not with the loadFile(...), I have the exception :
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'EvaluerPartie':
at com.sun.jna.Function.(Function.java:212) at
com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:541) at
com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:518) at
com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:504) at
com.sun.jna.Library$Handler.invoke(Library.java:220) at
com.sun.proxy.$Proxy0.EvaluerPartie(Unknown Source) at
DLLService.evaluateParty(DLLService.java:29) at
DLLService.testEvaluate(DLLService.java:16) at
DLLService.(DLLService.java:9) at
ProblemsIsolator.main(ProblemsIsolator.java:53)
I already search but found nothing that work (changing types, arguments, names, ...). Here is the prototype of the function l: DWORD ChargerFichier (LPSTR chNom, DWORD *pdwNoSess).
EDIT :
Same error, even after using a name mapper; it works for the LireVersion only :
public void testFunctionMapper() throws Exception {
FunctionMapper mapper = StdCallLibrary.FUNCTION_MAPPER;
NativeLibrary lib = NativeLibrary.getInstance("tsr32_mini");
Method[] methods = {
GDLL.class.getMethod("LireNoVersion",
new Class[] { String.class, int.class }),
GDLL.class.getMethod("ChargerFichier",
new Class[] { String.class, int.class }),
};
for (int i=0;i < methods.length;i++) {
String name = mapper.getFunctionName(lib, methods[i]);
lib.getFunction(name, StdCallLibrary.STDCALL_CONVENTION).getName();
}
}
Also, a dependency worker showed me well of the methods.
As it seems to works in that link: How do I get a java JNA call to a DLL to get data returned in parameters?, I can see that your definition of ChargerFichier is missing parameters.
Maybe the definition should be something like:
int ChargerFichier(PointerByReference chNom, IntByReference pdwNoSess);
Maybe this link can help you too: http://www.viaboxx.de/code/java-interoperation-with-a-native-dll-using-jna/
This is how you'd use the StdCallFunctionMapper:
Map options = new HashMap();
options.put(Library.OPTION_FUNCTION_MAPPER, new StdCallFunctionMapper());
MyLib lib = (MyLib)Native.loadLibrary("tsr32_mini", MyLib.class, options);

How can I trigger Steam to connect to a certain server using Java?

When you input a URL with this format into your browser:
steam://connect/[IP]
Steam automatically starts up and connects to said IP.
How can this be achieved in a Java program, or how can I reverse-engineer this?
This is not a Java question necessarily.
This is more of a "How do I configure a URI Protocol Handler" which is system and OS dependent.
In Windows, you would do something similar to this:
HKEY_CLASSES_ROOT
alert
(Default) = "URL:Alert Protocol"
URL Protocol = ""
DefaultIcon
(Default) = "alert.exe,1"
shell
open
command
(Default) = "C:\Program Files\Alert\alert.exe" "%1"
This will allow you to open a Java application similar to this:
java -jar MyJar.jar arg1 arg2
See more here from Windows MSDN.
To do this pragmatically you would need to use JNA to connect to a native library.
Although Java SDK does have a way to access the registry, it is declared private. You could use java.lang.Reflect to circumvent this and access these private methods, however it could break at any time.
public class RegEdit {
private static Method regAddKey = null;
private static Method regSetVal = null;
private static Method regDeleteKey = null;
private static Method regDeleteValue = null;
private static final Preferences userRoot = Preferences.userRoot();
private static final Preferences systemRoot = Preferences.systemRoot();
private static final Class<? extends Preferences> userClass = userRoot.getClass();
public RegEdit() {
try {
regAddKey = userClass.getDeclaredMethod("WindowsRegCreateKeyEx", new Class[]{int.class, byte[].class});
regAddKey.setAccessible(true);
regSetVal = userClass.getDeclaredMethod("WindowsRegSetValueEx", new Class[]{int.class, byte[].class, byte[].class});
regSetVal.setAccessible(true);
regDeleteValue = userClass.getDeclaredMethod("WindowsRegDeleteValue", new Class[]{int.class, byte[].class});
regDeleteValue.setAccessible(true);
regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey", new Class[]{int.class, byte[].class});
regDeleteKey.setAccessible(true);
} catch (NoSuchMethodException | SecurityException e) {
}
}
}
Hope this solves your question slightly.

Categories

Resources