Friday 11 November 2016

Using JNA to call a Windows function without parameters

The applications for Java Native Access are limited only by the functions and parameters that the external DLL files allow. In this post, we discuss how JNA can be used to obtain the process identifying number of the calling process. 

The Kernel32.dll file supports a GetCurrentProcessId function that performs the terribly important function of returning the unique identifying number of the calling process. The return value is an integer. Following is the C++ syntax straight from the msdn page:


DWORD WINAPI GetCurrentProcessId(void);

As can be seen from the function signature, this takes in no parameters at all. 

We begin, next, by creating a new Java application project (I prefer Netbeans IDE). We then, link the necessary jna-4.2.2.jar to the project, and create a new package. Though the creation of the latter is not necessary, it is nonetheless an excellent practice.


The first way to go about There are two ways to go about the project. In the first case, we create a single Java file thus:


package jna01;

import com.sun.jna.Library;
import com.sun.jna.Native;

/**
 *
 * @author satadru
 */
public class jna_pid_01 {
    public interface Kenl32 extends Library {
        Kenl32 INNE = (Kenl32) Native.loadLibrary("kernel32", Kenl32.class);

        public int GetCurrentProcessId();
    }

    public int GetCurrentProcessId(){
        int pid = Kenl32.INNE.GetCurrentProcessId();
        return pid;
    }

    public static void main(String[] a){
        jna_pid_01 jpid = new jna_pid_01();
        
        System.out.println("Own process ID is "+jpid.GetCurrentProcessId());
    }
    
}

This when compiled and run (in Netbeans IDE) results an output that is similar to the one shown here:

run:
Own process ID is 4960
BUILD SUCCESSFUL (total time: 0 seconds)

On examining the single class file, it becomes evident that the interface name Kenl32 does not need to be identical to the primary file name of Kernel32.dll. In fact, this can be any regular valid name so long as it is uniformly addressed. Ditto in case of the instance variable INNE.

The most significant component of the whole code is the method   public int GetCurrentProcessId() which gathers the integer return value from the function call Kenl32.INNE.GetCurrentProcessId()



The second approach
Personally, though, I prefer the second approach. Although more complex, this approach allows to have a finer degree of control. 

We begin by creating an appropriate package in the same project. A simple interface is all that is required.

package jna02;

import com.sun.jna.Library;

/**
 *
 * @author satadru
 */
public interface KrnlInface extends Library{
    public int GetCurrentProcessId();
}

We create a suitably appropriate class to return the process ID number.

package jna02;

import com.sun.jna.Native;

/**
 *
 * @author satadru
 */
public class jna_pid01 {

    public static void main(String[] ar) {
        KrnlInface instnc = (KrnlInface) Native.loadLibrary("kernel32", KrnlInface.class);

        System.out.println("Own Process ID number is as follows: " + instnc.GetCurrentProcessId());

    }
}

The resultant output is as follows:

run:
Own Process ID number is as follows: 6068
BUILD SUCCESSFUL (total time: 0 seconds)


Many would find the second way of coding to be cleaner and perhaps slightly more structured.

Users may note that the packages, interfaces and classes have been randomly named. This has been done intentionally to show the degree of customization possible with the interface and instance names.


The author wishes to acknowledge the contributions of Mr. Rajesh Bose. Mr. Bose is a research scholar and an eminent author of papers in the field of Cloud and IoT computing. Mr. Bose has also written a book titled A Deep Vista of the fascinating world of Cloud Computing. He is currently writing another book in IoT which is soon to be published. Mr. Bose holds keen interest in Java programming in his quest to develop interesting models in Cloud and IoT computing.




Resetting password of Amazon Kindle Paperwhite (7th Generation)

What to do to in case one forgets the password of an Amazon Kindle Paperwhite (7th Generation)? The answer is to type in  111222777  and...