# JNA <details> <summary>Оригинальное сообщение</summary> В Java есть возможность дёргать нативные функции из API операционной системы. В нашем случае, речь идет о win32 api. [Документация на проект](https://java-native-access.github.io/jna/5.13.0/javadoc/) вроде бы достаточно подробная. Зависимости для maven: ```xml <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency> <dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna-platform</artifactId> <version>5.13.0</version> </dependency> ``` И пока дело касается примеров из интернета, все нормально работает. По крайней мере, вот этот код нормально печатает две строки, используя функцию printf из msvcrt.dll: ```java import com.sun.jna.Library; import com.sun.jna.Native; public class Main { public interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary) Native.load("msvcrt", CLibrary.class); void printf(String format,Object... args); } public static void main(String[] args) { CLibrary.INSTANCE.printf("Line one\n\t\tLine two\n"); } } ``` Но как дело касается чего-то внятного, то ничего не работает. В частности, пытаюсь использовать функцию [ADsGetObject](https://learn.microsoft.com/ru-ru/windows/win32/api/adshlp/nf-adshlp-adsgetobject) и даже есть [пример](https://learn.microsoft.com/ru-ru/windows/win32/adsi/binding-with-getobject-and-adsgetobject), но как это перевести в Java? Что такое [HRESULT](https://java-native-access.github.io/jna/5.13.0/javadoc/com/sun/jna/platform/win32/WinNT.HRESULT.html)? Что такое [LPCWSTR](https://java-native-access.github.io/jna/5.8.0/javadoc/com/sun/jna/WString.html) ([тык](https://stackoverflow.com/questions/10319152/jna-call-to-c-function-with-lpcwstr-parameters)), REFIID? Да и возвращаемый VOID не такой уж и пустой, как я понимаю? В принципе, в документации про это написано, но я ничего не понимаю... Похоже, сначала надо C выучить. Давайте попробуем вместе это как-то реализовать хотя бы на начальном уровне, переложить на Java вот такой простенький скрипт: ```vb Set objUser = GetObject("LDAP://CN=Митичев Игорь Владимирович,OU=IT,OU=Security,OU=Departments,DC=teplo,DC=local") wscript.echo objUser.Get("company") objUser.put "company","Шараш-Монтаж LTD" objUser.SetInfo ``` </details> ## Как я понимаю > Но как дело касается чего-то внятного, то ничего не работает Кажется, что решения работают. Я думаю, что JNA конкретно в этом случае скорее применим как практика, там чуть ниже у меня есть предложение как чуть проще всё сделать может быть. > Что такое HRESULT Это просто [какой-то](https://www.maruf.ca/files/caadoc/CAASysQuickRefs/CAASysHRESULT.htm) int, который возвращает [результат работы](https://learn.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values) функции. > Что такое LPCWSTR Это Long Pointer WChar String: указатель на начало строки в utf-16. Точнее это я про LPWSTR, а C означает const, в смысле эту строку нельзя будет менять. Поэтому в доке про него ты не нашёл ничего: можно передать LPWSTR и потом через `.getValue()` забрать строку из него. А если его хочется использовать для экспорта функции, то туда можно воткнуть byte[], как это будет в коде ниже, когда я чего-то делал с окошками > Guid.REFIID Айдишник интерфейса. Это указатель на IID. Можно создать его на основе, например, [GUID](https://learn.microsoft.com/en-us/windows/win32/wmformat/interface-identifiers) > VOID не такой уж и пустой Да, это странная штука, но когда мы возвращаем void - мы имеем в виду, что функция ничего не возвращает. Но если мы возвращаем void* - это значит, что мы возвращаем указатель на память без какой-то спецификации типа данных по этому указателю При этом нам хочется передать туда вопреки утверждениям хидера не void**, а, как видишь, некто `IADs *pObject;` Вот на него [спека](https://learn.microsoft.com/en-us/windows/win32/api/iads/nn-iads-iads), а вот тут в [вопросе](https://stackoverflow.com/questions/44016328/accessing-com-interface-with-jna/44122970) сказано, как с таким объектом работать в JNA > сначала надо C выучить Ну тут речь не про C, скорее про WinAPI. Оно пилится уже 30 с лишним лет, там есть много костылей, писало много разного народа, где-то подходы разнятся значительно как результат. C выучить - это прям хорошо, а главное, не очень долго. > Давайте попробуем вместе это как-то реализовать хотя бы на начальном уровне, переложить на Java вот такой простенький скрипт Я думаю ближе к вечеру попробую вернуться к этому. Но тут у меня скорее вопрос, почему не хочется использовать [вот это](https://learn.microsoft.com/en-us/windows/win32/adsi/programming-adsi-with-javacom) для того же самого? Гемора меньше, а результат на первый взгляд такой же. <details> <summary>Вот тут поделал что-то ещё с WinApi</summary> Переименовать окошко, перечислить группы пользователя - [Link](https://hastebin.com/share/kilocejipe.java) ```java package com.mycompany.app; import com.sun.jna.Pointer; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.LMAccess.LOCALGROUP_USERS_INFO_0; import com.sun.jna.Native; import com.sun.jna.win32.StdCallLibrary; /** * Hello world! * */ public class App { public interface User32 extends StdCallLibrary { User32 INSTANCE = (User32) Native.load("user32", User32.class); interface WNDENUMPROC extends StdCallCallback { boolean callback(Pointer hWnd, Pointer arg); } boolean EnumWindows(WNDENUMPROC lpEnumFunc, Pointer arg); int GetWindowTextA(Pointer hWnd, byte[] lpString, int nMaxCount); boolean SetWindowTextA(Pointer hWnd, byte[] lpString); } public interface Netapi32 extends StdCallLibrary { Netapi32 INSTANCE = (Netapi32) Native.load("netapi32", Netapi32.class); int NetUserGetLocalGroups(Pointer servername, byte[] username, int level, int flags, Pointer buffer, int prefmaxlen, Pointer entriesread, Pointer totalentries); } public static void main(String[] args) { final User32 user32 = User32.INSTANCE; user32.EnumWindows(new User32.WNDENUMPROC() { public boolean callback(Pointer hWnd, Pointer userData) { byte[] windowText = new byte[512]; user32.GetWindowTextA(hWnd, windowText, 512); String wText = Native.toString(windowText); if (wText.isEmpty()) { return true; } System.console().printf("%s - %s\n", wText, wText.compareTo("test")); if (wText.compareTo("test") == 0) { byte[] newText = Native.toByteArray("passed"); user32.SetWindowTextA(hWnd, newText); } return true; } }, null); LOCALGROUP_USERS_INFO_0 uInfo_0 = new LOCALGROUP_USERS_INFO_0(); WinDef.DWORDByReference entries = new WinDef.DWORDByReference(); WinDef.DWORDByReference entriesTotal = new WinDef.DWORDByReference(); Netapi32.INSTANCE.NetUserGetLocalGroups(null,Native.toByteArray("amitichev") , 0, 1, uInfo_0.getPointer(), -1, entries.getPointer(), entriesTotal.getPointer()); int entriesVal = entries.getValue().intValue(); int entriesTotalVal = entriesTotal.getValue().intValue(); System.console().printf(uInfo_0.toString()); } } ``` </details> ### Ссылки которые открыл при расследовании - https://apps.inock.ru/jna.html Оригинальное сообщение - https://stackoverflow.com/questions/10319152/jna-call-to-c-function-with-lpcwstr-parameters - Ответ про LPWSTR - https://learn.microsoft.com/en-us/windows/win32/api/adshlp/nf-adshlp-adsgetobject - Спека на ADsGetObject - https://learn.microsoft.com/en-us/windows/win32/adsi/binding-with-getobject-and-adsgetobject - Пример использования ADsGetObject - https://java-native-access.github.io/jna/5.13.0/javadoc/com/sun/jna/Pointer.html#field.detail - Дока про Pointer - https://github.com/nyholku/purejavacomm/blob/master/src/jtermios/windows/WinAPI.java - Пример продуктового использования winapi через JNA - https://java-native-access.github.io/jna/4.2.0/index.html?com/sun/jna/platform/win32/WTypes.LPWSTR.html - LPWSTR в JNA - https://learn.microsoft.com/en-us/windows/win32/seccrypto/common-hresult-values - Тип HRESULT - http://systemmanager.ru/adam-sdk.en/adsi/adsgetobject.htm - Ещё одно описание ADsGetObject, из которого можно получить название библиотеки - https://learn.microsoft.com/en-us/windows/win32/adsi/programming-adsi-with-javacom - Правильный путь использования ADSI в Java - https://stackoverflow.com/a/44122970 - Мапинг COM-объекта в Java - https://learn.microsoft.com/en-us/windows/win32/api/iads/nn-iads-iads - Спека на IADs интерфейс - https://learn.microsoft.com/en-us/windows/win32/wmformat/interface-identifiers - Таблица GUID для IID интерфейсов