diff --git a/.gitmodules b/.gitmodules index 29ebbb6..504003b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "libserialport"] path = libserialport url = https://github.com/facchinm/libserialport.git +[submodule "usbSearch"] + path = usbSearch + url = https://github.com/arduino/usbSearch.git diff --git a/compile_win.sh b/compile_win.sh index 66fbe92..d6242d9 100755 --- a/compile_win.sh +++ b/compile_win.sh @@ -11,5 +11,5 @@ make cd .. i686-w64-mingw32-gcc main.c -Llibserialport/.libs/ -Ilibserialport/ -lserialport -lsetupapi -static -o listSerialC.exe cp listSerialC.exe distrib/windows/ -i686-w64-mingw32-gcc -D_JNI_IMPLEMENTATION_ -Wl,--kill-at jnilib.c libserialport/.libs/libserialport.a -lsetupapi -Ilibserialport/ -I/opt/jvm/jdk1.8.0/include/ -Iwin32_jni -shared -o listSerialsj.dll -cp listSerialsj.dll distrib/windows/ \ No newline at end of file +i686-w64-mingw32-gcc -D_JNI_IMPLEMENTATION_ -Wl,--kill-at jnilib.c usbSearch/disphelper.c libserialport/.libs/libserialport.a -lhid -lsetupapi -lole32 -loleaut32 -luuid -Ilibserialport/ -IusbSearch -I/opt/jvm/jdk1.8.0/include/ -Iwin32_jni -shared -o listSerialsj.dll +cp listSerialsj.dll distrib/windows/ diff --git a/jnilib.c b/jnilib.c index 5487d00..d6dd4e2 100644 --- a/jnilib.c +++ b/jnilib.c @@ -12,7 +12,9 @@ JNIEXPORT jstring JNICALL Java_processing_app_Platform_resolveDeviceAttachedToNa const char *portname = (*env)->GetStringUTFChars(env, serial, NULL); jstring result; - sp_get_port_by_name(portname, &port); + if (sp_get_port_by_name(portname, &port) != SP_OK) { + return (*env)->NewStringUTF(env, ""); + } int vid, pid; if (sp_get_port_usb_vid_pid(port, &vid, &pid) == SP_OK) { @@ -25,6 +27,8 @@ JNIEXPORT jstring JNICALL Java_processing_app_Platform_resolveDeviceAttachedToNa return (*env)->NewStringUTF(env, vid_pid_iserial); } +#ifndef _WIN32 + JNIEXPORT jobjectArray JNICALL Java_processing_app_Platform_listSerialsNative (JNIEnv * env, jobject jobj) { @@ -34,7 +38,9 @@ JNIEXPORT jobjectArray JNICALL Java_processing_app_Platform_listSerialsNative char portname_vid_pid[256] = " "; - sp_list_ports(&ports); + if (sp_list_ports(&ports) != SP_OK) { + return (jobjectArray)(*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, ""));; + } // like ports.size() for (i = 0; ports[i]; i++) {}; @@ -56,3 +62,101 @@ JNIEXPORT jobjectArray JNICALL Java_processing_app_Platform_listSerialsNative return ret; } + +#else + +// use listcomports code +#include +#include +#include +#include +#include +#include + + +#include +#include + +#include + +JNIEXPORT jobjectArray JNICALL Java_processing_app_Platform_listSerialsNative + (JNIEnv * env, jobject jobj) +{ + jobjectArray ret; + char portname_vid_pid[256] = " "; + + struct sp_port **ports; + if (sp_list_ports(&ports) != SP_OK) { + return (jobjectArray)(*env)->NewObjectArray(env, 0, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, ""));; + } + + DISPATCH_OBJ(wmiSvc); + DISPATCH_OBJ(colDevices); + + dhInitialize(TRUE); + dhToggleExceptions(FALSE); + + dhGetObject(L"winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\cimv2", + //dhGetObject(L"winmgmts:\\\\.\\root\\cimv2", + NULL, &wmiSvc); + dhGetValue(L"%o", &colDevices, wmiSvc, + L".ExecQuery(%S)", + L"Select * from Win32_PnPEntity"); + + int port_count = 0; + int vid = 0; + int pid = 0; + int i = 0; + + // like ports.size() + for (i = 0; ports[i]; i++) {}; + sp_free_port_list(ports); + + ret = (jobjectArray)(*env)->NewObjectArray(env, i, (*env)->FindClass(env, "java/lang/String"), (*env)->NewStringUTF(env, "")); + + FOR_EACH(objDevice, colDevices, NULL) { + char* name = NULL; + char* pnpid = NULL; + char* match; + + dhGetValue(L"%s", &name, objDevice, L".Name"); + dhGetValue(L"%s", &pnpid, objDevice, L".PnPDeviceID"); + + if( name != NULL && ((match = strstr( name, "(COM" )) != NULL) ) { // look for "(COM23)" + char* comname = strtok( match, "()"); + char id_s[5]; + char * pch; + pch = strstr (pnpid,"VID_"); + strncpy(id_s, pch + 4, 4); + vid = strtol(id_s, NULL, 16); + pch = strstr (pnpid,"PID_"); + strncpy(id_s, pch + 4, 4); + pid = strtol(id_s, NULL, 16); + //sscanf(pnpid, "%*sVID_%4X", vid); + //sscanf(pnpid, "%*sPID_%4X", pid); + snprintf(portname_vid_pid, sizeof(portname_vid_pid), "%s_%04X_%04X", comname, vid, pid); + if (port_count < i) { + // only store element if safe (operations are not atomic) + (*env)->SetObjectArrayElement(env, ret, port_count, (*env)->NewStringUTF(env, portname_vid_pid)); + } + port_count++; + } + dhFreeString(name); + dhFreeString(pnpid); + + } NEXT(objDevice); + + for (; port_count < i; port_count++) { + // fill the array with copies of the last good value (operations are not atomic) + (*env)->SetObjectArrayElement(env, ret, port_count, (*env)->NewStringUTF(env, portname_vid_pid)); + } + + SAFE_RELEASE(colDevices); + SAFE_RELEASE(wmiSvc); + + dhUninitialize(TRUE); + + return ret; +} + +#endif \ No newline at end of file diff --git a/main.c b/main.c index 39c8d25..c3bc647 100644 --- a/main.c +++ b/main.c @@ -5,8 +5,12 @@ int main(void) { int i; struct sp_port **ports; + enum sp_return ret; - sp_list_ports(&ports); + ret = sp_list_ports(&ports); + if (ret != SP_OK) { + return 0; + } for (i = 0; ports[i]; i++) { int vid, pid; diff --git a/usbSearch b/usbSearch new file mode 160000 index 0000000..098b807 --- /dev/null +++ b/usbSearch @@ -0,0 +1 @@ +Subproject commit 098b807b163905a64b32cd7b51da165c2a612a24