Функция RasEnumConnections в JNA возвращает неполные данные.Что я делаю не так? - PullRequest
0 голосов
/ 26 февраля 2019

Функция RasEnumConnections, реализованная в JNA, возвращает неполные данные.
Что не так?Это мой код:

public static void main(String[] args) {

    Connected();
}

private static void Connected () {
    boolean state = false;
    ArrayList<String> connectedNames = new ArrayList<>();
    IntByReference lpcb = new IntByReference(0);
    IntByReference lpcConnections = new IntByReference(0);
    Rasapi32.INSTANCE.RasEnumConnections(null, lpcb,lpcConnections);

    WinRas.RASCONN conn = new WinRas.RASCONN();
    conn.dwSize = lpcb.getValue();
    WinRas.RASCONN[] connArray;
    if(lpcConnections.getValue() > 0)
        connArray = (WinRas.RASCONN[])conn.toArray(lpcConnections.getValue());
    else
        connArray = (WinRas.RASCONN[])conn.toArray(1);
    System.out.println("lpcb: " + lpcb.getValue() + " lpcConnections: " + lpcConnections.getValue() + " RASCONN Size: " + conn.dwSize);
    int error = Rasapi32.INSTANCE.RasEnumConnections(connArray, lpcb,lpcConnections);

    if(error == WinError.ERROR_SUCCESS) {
        System.out.println("Entry name: " + Native.toString(connArray[0].szEntryName)
        + " Guid string: " + connArray[0].guidEntry.toGuidString());
        System.out.println(connArray[0].guidEntry.Data1);
        System.out.println(connArray[0].guidEntry.Data2);
        System.out.println(connArray[0].guidEntry.Data3);

    }
    else System.out.println("Error: " + error);

    WinRas.RASENTRY.ByReference entry = getPhoneBookEntry("test1");
    if(entry != null) {
        System.out.println("test1 guid: "+ entry.guidId.toGuidString());
        System.out.println(entry.guidId.Data1);
        System.out.println(entry.guidId.Data2);
        System.out.println(entry.guidId.Data3);
    }

    else System.out.println("Error: " + Native.getLastError());

    }
}

In debugger:

Символьный массив szEntryName содержит только 3 последних символа имени соединения.(Имя соединения "test1")

1 Ответ

0 голосов
/ 26 февраля 2019

Как я заметил в комментариях, вывод отладки дает вам сильный намек на то, что происходит.Недостающие символы «t» и «e» отображаются как 0x74 и 0x65 в середине того, что JNA ожидает в качестве 64-битного указателя.Логический вывод состоит в том, что Windows возвращает 32-битный указатель, за которым следует строка, на 4 байта раньше, чем ожидал JNA.

RasEnumConnections утверждает несколько вещей относительно буфера, который вы передаете, как connArray:

При вводе приложение должно установить для элемента dwSize первой структуры RASCONN в буфере значение sizeof (RASCONN), чтобы определить версию передаваемой структуры.

В приведенном выше примере кода вы оставляете это значение таким же, как и значение из исходного возврата.Это указывает на «неправильную» версию структуры.Вместо этого вы должны установить для элемента dwSize нужный размер в структуре JNA:

conn.dwSize = conn.size();

На самом деле конструктор для RASCONN устанавливает это для вас !Таким образом, вы на самом деле не должны делать это.Но в приведенном выше примере кода вы перезаписываете то, что было предварительно установлено;просто удалите conn.dwSize строку.

Обратите внимание, что, поскольку вы теперь запрашиваете (4 байта на элемент массива) больший буфер, определяя размер структуры, вам также нужно передать увеличенный размер в (секунде) RasEnumConnections() звонок.Он устанавливается как число элементов, умноженное на (меньший) размер структуры, но вы должны сбросить число элементов, умноженное на (больший) размер, например:

lpcb.setValue(conn.size() * lpcConnections.getValue());

перед извлечением полного массива.В противном случае вы получите ошибку 632 (неверный размер структуры).

Для справки (или, возможно, подходящей замены для вашего собственного кода), взгляните на код, реализованный в getRasConnection(String connName)метод в классе Jas Rasapi32Util.java .

...