diff --git a/.classpath b/.classpath index b6370d16..954c7452 100644 --- a/.classpath +++ b/.classpath @@ -2,7 +2,6 @@ - diff --git a/lib/common/registry.jar b/lib/common/registry.jar deleted file mode 100644 index 2aefa0f3..00000000 Binary files a/lib/common/registry.jar and /dev/null differ diff --git a/src/com/romraider/io/j2534/api/J2534DllLocator.java b/src/com/romraider/io/j2534/api/J2534DllLocator.java new file mode 100644 index 00000000..0d64fe50 --- /dev/null +++ b/src/com/romraider/io/j2534/api/J2534DllLocator.java @@ -0,0 +1,187 @@ +/* + * RomRaider Open-Source Tuning, Logging and Reflashing + * Copyright (C) 2006-2012 RomRaider.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package com.romraider.io.j2534.api; + +import static com.sun.jna.platform.win32.WinError.ERROR_SUCCESS; +import static com.sun.jna.platform.win32.WinReg.HKEY_LOCAL_MACHINE; +import static org.apache.log4j.Logger.getLogger; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.sun.jna.Native; +import com.sun.jna.platform.win32.Advapi32; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinReg.HKEY; +import com.sun.jna.platform.win32.WinReg.HKEYByReference; +import com.sun.jna.ptr.IntByReference; + +/** + * Discover all the J2534 device installations on the local computer from + * keys and value settings in the Windows registry. Return a List of + * J2534Library instances. + * @see J2534Library + */ +public class J2534DllLocator { + private static final Logger LOGGER = getLogger(J2534DllLocator.class); + private static final String ISO9141 = "ISO9141"; + private static final String FUNCTIONLIBRARY = "FunctionLibrary"; + private static final int KEY_READ = 0x20019; + private static final int ERROR_NO_MORE_ITEMS = 0x103; + private static Advapi32 advapi32 = Advapi32.INSTANCE; + + public static Set ListLibraries() throws Exception { + Set libraries = new HashSet(); + HKEY hklm = HKEY_LOCAL_MACHINE; + String passThru = "SOFTWARE\\PassThruSupport.04.04"; + HKEYByReference passThruHandle = getHandle(hklm, passThru); + + List vendors = getKeys(passThruHandle.getValue()); + for (String vendor : vendors) { + HKEYByReference vendorKey = + getHandle(passThruHandle.getValue(), vendor); + int supported = getDWord(vendorKey.getValue(), ISO9141); + if (supported == 0 ) continue; + String library = getSZ(vendorKey.getValue(), FUNCTIONLIBRARY); + LOGGER.debug(String.format("Vendor:%s | Library:%s", + vendor, library)); + libraries.add(new J2534Library(vendor, library)); + advapi32.RegCloseKey(vendorKey.getValue()); + } + advapi32.RegCloseKey(passThruHandle.getValue()); + return libraries; + } + + private static HKEYByReference getHandle(HKEY hKey, String lpSubKey) + throws Exception { + + HKEYByReference phkResult = new HKEYByReference(); + int ret = advapi32.RegOpenKeyEx( + hKey, + lpSubKey, + 0, + KEY_READ, + phkResult); + + if(ret != ERROR_SUCCESS) { + handleError("RegOpenKeyEx", ret); + } + return phkResult; + } + + private static int reverse(byte[] bytes, int size) { + ByteBuffer b = ByteBuffer.wrap(bytes, 0, size); + return b.order(ByteOrder.LITTLE_ENDIAN).getInt(); + } + + private static void handleError(String operation, int status) + throws Exception { + + String errString = String.format("%s error [%d]%n", + operation, status); + throw new Exception(errString); + } + + private static List getKeys(HKEY hkey) + throws Exception { + + int dwIndex = 0; + List vendors = new ArrayList(); + int ret = 0; + do { + char[] lpName = new char[255]; + IntByReference lpcName = new IntByReference(-1); + IntByReference lpReserved = null; + char[] lpClass = new char[255]; + IntByReference lpcClass = new IntByReference(-1); + FILETIME lpftLastWriteTime = new FILETIME(); + ret = advapi32.RegEnumKeyEx( + hkey, + dwIndex, + lpName, + lpcName, + lpReserved, + lpClass, + lpcClass, + lpftLastWriteTime); + + switch (ret) { + case ERROR_SUCCESS: + dwIndex++; + vendors.add(Native.toString(lpName)); + break; + case ERROR_NO_MORE_ITEMS: + break; + default: + handleError("RegEnumKeyEx", ret); + } + } while(ret == ERROR_SUCCESS); + return vendors; + } + + private static int getDWord(HKEY hkey, String valueName) + throws Exception { + + IntByReference lpType = new IntByReference(-1); + byte[] lpData = new byte[16]; + IntByReference lpcbData = new IntByReference(-1); + int ret = advapi32.RegQueryValueEx( + hkey, + valueName, + 0, + lpType, + lpData, + lpcbData); + if(ret != ERROR_SUCCESS) { + String errString = String.format("DWORD_RegQueryValueEx(%s)", + valueName); + handleError(errString, ret); + } + int dword = reverse(lpData, lpcbData.getValue()); + return dword; + } + + private static String getSZ(HKEY hkey, String valueName) + throws Exception { + + IntByReference lpType = new IntByReference(-1); + char[] lpData = new char[1024]; + IntByReference lpcbData = new IntByReference(-1); + int ret = advapi32.RegQueryValueEx( + hkey, + valueName, + 0, + lpType, + lpData, + lpcbData); + if(ret != ERROR_SUCCESS) { + String errString = String.format("SZ_RegQueryValueEx(%s)", + valueName); + handleError(errString, ret); + } + return Native.toString(lpData); + } +} diff --git a/src/com/romraider/io/j2534/api/J2534Library.java b/src/com/romraider/io/j2534/api/J2534Library.java new file mode 100644 index 00000000..351ffbd7 --- /dev/null +++ b/src/com/romraider/io/j2534/api/J2534Library.java @@ -0,0 +1,57 @@ +/* + * RomRaider Open-Source Tuning, Logging and Reflashing + * Copyright (C) 2006-2012 RomRaider.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +package com.romraider.io.j2534.api; + +/** + * Each class instance holds the Vendor and Library details for a J2534 + * installed device. These are discovered on the local computer from + * keys and value settings in the Windows registry. + * @see J2534DllLocator + */ +public class J2534Library { + private String vendor; + private String library; + + /** + * Create a new instance of a J2534 library detail. + * @param vendor - J2534 vendor string + * @param library - J2534 library path + */ + public J2534Library(String vendor, String library) { + this.vendor = vendor; + this.library = library; + } + + /** + * Get the vendor of this library detail instance. + * @return the vendor + */ + public String getVendor() { + return vendor; + } + + /** + * Get the fully qualified library path of this library detail instance. + * @return the library + */ + public String getLibrary() { + return library; + } +}