//----------------------------------------------------------------------- // // Copyright © 2012 Nils Hammar. All rights reserved. // //----------------------------------------------------------------------- /* * Software to access vehicle information via the OBD-II connector. * * Copyright © 2012 Nils Hammar * * 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 3 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, see . * * Alternative licensing is possible, see the licensing document. * * The above text may not be removed or modified. */ //// Implementation needs to be changed to support old version (pre 04.04) of J2534. //// #define SUPPORT_OLD_J2534 namespace DynamicApiLoading.Api.Dynamic { using System; using System.Collections.Generic; using global::Microsoft.Win32; /// /// Class that locates J2534 DLLs by searching the registry together with their supported options. /// public class DynamicLocater { /// /// Protocol name filter values. /// private static List protocolNames = new List() { "J1850PWM", "J1850VPW", "ISO9141", "ISO14230", "ISO15765", "CAN", }; /// /// List of encountered drivers. /// private List adapterList = new List(); /// /// Gets list of encountered drivers. /// public IList adapters { get { return this.adapterList; } } /// /// Initializes a new instance of the class. /// public DynamicLocater() { RegistryKey key = Registry.LocalMachine; RegistryKey swKey = key.OpenSubKey("SOFTWARE"); this.recursiveLookup(swKey); } /// /// Get a string representation of the object. /// /// String presenting object data. public override string ToString() { string txt = string.Empty; foreach (DynamicAdapter adapter in this.adapterList) { txt += "Adapter: " + adapter.ToString() + "\r\n"; } return txt; } /// /// Fetch a list of supported protocols for the device driver. /// /// Registry key for device driver. /// List of protocols supported. private static IList getSupportedProtocols(RegistryKey vendorDeviceRk) { string protocolsSupportedStr = getStringValue(vendorDeviceRk, "ProtocolsSupported"); SortedDictionary sortedProtocols = new SortedDictionary(); string[] valueNames; if (protocolsSupportedStr != null) { valueNames = protocolsSupportedStr.Split(new char[] { ',' }); } else { valueNames = vendorDeviceRk.GetValueNames(); } foreach (string valueName in valueNames) { string trimmedValueName = valueName.Trim(); if (protocolNames.Contains(trimmedValueName) && !sortedProtocols.ContainsKey(trimmedValueName)) { sortedProtocols.Add(trimmedValueName, trimmedValueName); } } IList protocols = new List(); foreach (KeyValuePair kvp in sortedProtocols) { protocols.Add(kvp.Key); } return protocols; } /// /// Get a value in string form from the registry. /// /// Registry key for device driver. /// Value name /// String value private static string getStringValue(RegistryKey vendorDeviceRk, string name) { string value = null; try { if (vendorDeviceRk.GetValueKind(name) == RegistryValueKind.String) { value = (string)vendorDeviceRk.GetValue(name); } } catch (Exception ex) { if (ex != null) { // this.iLogging.appendText("getStringValue(" + name + "):" + ex.Message + "\r\n", LogLevel.LOG_DEBUG); } } return value; } /// /// Get a value in int form from the registry. /// /// Notice: The returned value may be 'null' if the value doesn't exist. /// /// /// Registry key for device driver. /// Value name /// int value private static int? getIntValue(RegistryKey vendorDeviceRk, string name) { int? value = null; try { if (vendorDeviceRk.GetValueKind(name) == RegistryValueKind.DWord) { object obj = vendorDeviceRk.GetValue(name); if (obj is int) { value = (int)obj; } } } catch (Exception ex) { if (ex != null) { // this.iLogging.appendText("getIntValue(" + name + "):" + ex.Message + "\r\n", LogLevel.LOG_DEBUG); } } return value; } /// /// Do a recursive lookup. /// /// This is used since some registry keys are located in sub-locations depending /// on if it's a 64-bit or 32-bit OS. /// /// /// Registry key 'SOFTWARE' private void recursiveLookup(RegistryKey swRk) { string[] subkeys = swRk.GetSubKeyNames(); foreach (string keyName in subkeys) { switch (keyName) { case "PassThruSupport": #if SUPPORT_OLD_J2534 this.locateOldDevices(swRk, keyName); #endif break; case "PassThruSupport.04.04": this.locateDevices(swRk, keyName); break; case "Wow6432Node": this.nextLevel(swRk, keyName); break; default: break; } } } #if SUPPORT_OLD_J2534 /// /// Locate old J2534 drivers. /// /// These drivers have a bit of a different API and /// needs to be called a bit differently. /// /// /// Registry key 'SOFTWARE' /// Name of key. private void locateOldDevices(RegistryKey swRk, string keyName) { RegistryKey passthruRk = swRk.OpenSubKey(keyName); string[] vendorkeys = passthruRk.GetSubKeyNames(); foreach (string vendorkey in vendorkeys) { RegistryKey vendorRk = passthruRk.OpenSubKey(vendorkey); string vendor = this.getStringValue(vendorRk, "Name"); RegistryKey vendorDevicesRk = vendorRk.OpenSubKey("Devices"); string[] devicesKeys = vendorDevicesRk.GetSubKeyNames(); foreach (string deviceKey in devicesKeys) { RegistryKey vendorDeviceRk = vendorDevicesRk.OpenSubKey(deviceKey); this.addDriver(true, vendor, vendorDeviceRk, deviceKey); } } } #endif /// /// Locate J2534 devices supporting the 04.04 version of the API. /// /// Registry key 'SOFTWARE' /// Name of key. private void locateDevices(RegistryKey swRk, string keyName) { RegistryKey passthruRk = swRk.OpenSubKey(keyName); string[] devicesKeys = passthruRk.GetSubKeyNames(); foreach (string deviceKey in devicesKeys) { RegistryKey vendorDeviceRk = passthruRk.OpenSubKey(deviceKey); if (vendorDeviceRk != null) { string vendor = getStringValue(vendorDeviceRk, "Vendor"); this.addDriver(false, vendor, vendorDeviceRk, deviceKey); } } } /// /// Add one driver to the list of found drivers. /// /// 'true' if not 04.04 version. /// Name of vendor. /// Registry key for vendor device. /// Key string for device. private void addDriver(bool oldDriver, string vendor, RegistryKey vendorDeviceRk, string deviceKey) { string name = getStringValue(vendorDeviceRk, "Name"); string logfile = getStringValue(vendorDeviceRk, "Logfile2534"); string configApplication = getStringValue(vendorDeviceRk, "ConfigApplication"); string j2534dll = getStringValue(vendorDeviceRk, "FunctionLibrary"); string rp1210Library = getStringValue(vendorDeviceRk, "RP1210Library"); int? rp1210DeviceId = getIntValue(vendorDeviceRk, "RP1210DeviceId"); IList protocols = getSupportedProtocols(vendorDeviceRk); DynamicAdapter da = new DynamicAdapter( oldDriver, deviceKey, name, vendor, logfile, configApplication, j2534dll, rp1210Library, rp1210DeviceId, protocols); this.adapterList.Add(da); } /// /// Step to next level in lookup. /// /// Base registry key. /// Name of sub-key. private void nextLevel(RegistryKey key, string keyName) { RegistryKey key1 = key.OpenSubKey(keyName); if (key1 != null) { this.recursiveLookup(key1); } } } }