Get list of services using JNA

0

I need to list all of the services installed, running and stopped (STATE = ALL). Earlier I was using command "sc query" but I need to do this using JNA. I've never used JNA before so I don't know much.

I found this Query all Windows Services with JNA and did what was told in the answer but I can't get it to work.

public void getService(){
    IntByReference size = new IntByReference();
    IntByReference lppcbBytesneeded = new IntByReference();
    IntByReference retz = new IntByReference();
    lppcbBytesneeded.setValue(0);
    Winsvc.SC_HANDLE scm = Advapi32.INSTANCE.OpenSCManager(null, null, Winsvc.SC_MANAGER_ENUMERATE_SERVICE);
    boolean ret = CustomAdvapi32.INSTANCE.EnumServicesStatusEx(scm.getPointer(), 0, 0x00000030, 0x0000003, null, 0, lppcbBytesneeded,
            retz, size, null);
    int error = Native.getLastError();

    Memory buf = new Memory(lppcbBytesneeded.getValue());
    size.setValue(retz.getValue());
    ret = CustomAdvapi32.INSTANCE.EnumServicesStatusEx(scm.getPointer(), 0, 0x00000030, 0x0000000,
            buf, lppcbBytesneeded.getValue(), lppcbBytesneeded, retz, size, null);
    error = Native.getLastError();


    ENUM_SERVICE_STATUS_PROCESS serviceInfo = new ENUM_SERVICE_STATUS_PROCESS(buf);
    Structure[] serviceInfos = serviceInfo.toArray(retz.getValue());

    for(int i = 0; i < retz.getValue(); i++) {
        serviceInfo = (ENUM_SERVICE_STATUS_PROCESS) serviceInfos[i];
        System.out.println(serviceInfo.lpDisplayName + " / " + serviceInfo.lpServiceName);
    }
}

All I can get from this is error:

java.lang.ArrayIndexOutOfBoundsException: 0
at com.sun.jna.Structure.toArray(Structure.java:1562)
at com.sun.jna.Structure.toArray(Structure.java:1587)
at Main.getService(Main.java:156)
at Main.main(Main.java:22)
java
winapi
jna
asked on Stack Overflow Feb 26, 2019 by Rafikus • edited Feb 26, 2019 by Moshe Slavin

1 Answer

0

Your error is in size.setValue(retz.getValue());. When you call the method a second time, you are using size as the lpResumeHandle field:

A pointer to a variable that, on input, specifies the starting point of enumeration. You must set this value to zero the first time the EnumServicesStatusEx function is called. On output, this value is zero if the function succeeds. However, if the function returns zero and the GetLastError function returns ERROR_MORE_DATA, this value indicates the next service entry to be read when the EnumServicesStatusEx function is called to retrieve the additional data.

So in your second call you're telling JNA to start iterating after the last element in the previous list. Not surprisingly, you're getting an empty array (retz.getValue() == 0) which Structure.toArray() can't handle.

You should be calling EnumServicesStatusEx with that parameter set to 0 to start enumeration at the beginning.

answered on Stack Overflow Feb 26, 2019 by Daniel Widdis

User contributions licensed under CC BY-SA 3.0