On 08/11/2013 06:47 AM, Scott Talbert wrote:
> Yeah, I think at the very least, we should do some sort of transition 
> period.

OK, this adds a new --enable-force-libusb-on-linux option which will use
libusb but warn.

It also removes the windows bits of libusb since I'm pretty darn sure no one
has ever used it. And it moves libusbhid.cpp into the top-level libconcord
directory to prevent the latest version of automake from complaining.

It keeps all the Mac magic, though I haven't tested it with this version of
the patch yet...

It cleans up some of the autoconf/automake stuff though.

Thoughts?

-- 
Phil Dibowitz                             p...@ipom.com
Open Source software and tech docs        Insanity Palace of Metallica
http://www.phildev.net/                   http://www.ipom.com/

"Be who you are and say what you feel, because those who mind don't matter
 and those who matter don't mind."
 - Dr. Seuss

commit eb672ac5ddbbb9d38dd77adec683647240a8e47f
Author: Phil Dibowitz <p...@ipom.com>
Date:   Fri Aug 9 23:23:37 2013 -0700

    Move libconcord to libhidapi
    
    libusb can no longer talk to HID devices on MacOSX.
    
    Further, libhidapi just allows is to handle the remote as a HID device
    directly rather than implementing HID ourself from a lower level.
    
    This patch:
     - Removes libusb Windows support - it's never used
     - Makes libhidapi-libusb default on Linux
     - Uses libhidapi-raw on MacOSX
     - Adds several fixes for MacOSX
    
    Note that on Linux you can use libhidapi-hidraw (the raw internal
    implementation), or libhidapi-libusb (uses libusb internally), but we
    use libusb becuase the hidraw is unstable at this point. On other
    platforms, only the respective native HID implementations are available.
    
    This version works on both Linux and Mac. I have not yet tried Windows.
    
    Thanks to Scott Talbert <s...@techie.net> for testing and fixes to early
    versions of this when I didn't have remotes available.
    
    Signed-off-by: Phil Dibowitz <p...@ipom.com>

diff --git a/concordance/Makefile.am b/concordance/Makefile.am
index 85b0606..1fc1040 100644
--- a/concordance/Makefile.am
+++ b/concordance/Makefile.am
@@ -1,7 +1,7 @@
+ACLOCAL_AMFLAGS = -I m4
 bin_PROGRAMS = concordance
 concordance_SOURCES = concordance.c
-concordance_LDFLAGS = -l:libconcord.so.3
-ACLOCAL_AMFLAGS= -I m4
+concordance_LDFLAGS = -l:$(LIBCONCORD)
 # -Wall just makes good sense
 # -ansi and -pednatic errors are needed to ensure we're compatible with
 # crappy Microsoft compilers - phil
diff --git a/concordance/configure.ac b/concordance/configure.ac
index 0f2b274..dcf913a 100644
--- a/concordance/configure.ac
+++ b/concordance/configure.ac
@@ -4,6 +4,16 @@ AM_PROG_CC_C_O
 AC_CONFIG_MACRO_DIR([m4])
 AC_PROG_LIBTOOL
 AC_PROG_CXX
+AC_CANONICAL_HOST
+case $host_os in
+  darwin*)
+    LIBCONCORD="libconcord.dynlib.3"
+    ;;
+  *)
+    LIBCONCORD="libconcord.so.3"
+    ;;
+esac
+AC_SUBST([LIBCONCORD], [$LIBCONCORD])
 AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_FILES([
  Makefile
diff --git a/libconcord/INSTALL.linux b/libconcord/INSTALL.linux
index 06a0385..27b7f22 100644
--- a/libconcord/INSTALL.linux
+++ b/libconcord/INSTALL.linux
@@ -10,6 +10,12 @@ source, see the instructions below.
 You *MUST* install libusb and libzzip. These libraries are in most
 distributions, so apt-get/yum/up2date/urpmi/etc. it.
 
+You also need hidapi which can be found at: https://github.com/signal11/hidapi
+It is important that you use git, as the last release (0.7.0) doesn't work.
+You'll want to build it as a shared library, which is basically just
+"./bootstrap && ./configure --prefix=/usr && make && sudo make install",
+tweaked to your taste.
+
 Also, if you are using 900/1000/1100 remotes, then dnsmasq is a requirement,
 as well as installing the udev support files for libconcord (see below).
 
diff --git a/libconcord/INSTALL.mac b/libconcord/INSTALL.mac
index 0c74b92..806ad89 100644
--- a/libconcord/INSTALL.mac
+++ b/libconcord/INSTALL.mac
@@ -30,6 +30,14 @@ that first. It is also straight forward:
    make
    sudo make install
 
+You must install hidapi (there's a few similarly named projects, you want:
+https://github.com/signal11/hidapi). Grab the source from git (NOT a release),
+and do:
+   ./bootstrap
+   ./configure --prefix=/usr
+   make
+   sudo make install
+
 Finally, you will need to install libzzip, which again is straight forward:
    ./configure --prefix=/usr
    make
diff --git a/libconcord/Makefile.am b/libconcord/Makefile.am
index 808484c..96f3e1f 100644
--- a/libconcord/Makefile.am
+++ b/libconcord/Makefile.am
@@ -1,12 +1,12 @@
 # libconcord
-ACLOCAL_AMFLAGS= -I m4
+ACLOCAL_AMFLAGS = -I m4
 lib_LTLIBRARIES = libconcord.la
 libconcord_la_SOURCES = remote.cpp remote_z.cpp libconcord.cpp binaryfile.cpp \
-    web.cpp libusb/libusbhid.cpp usblan.cpp binaryfile.h hid.h protocol_z.h \
-    remote_info.h web.h protocol.h remote.h usblan.h xml_headers.h \
-    operationfile.cpp remote_mh.cpp
+	web.cpp usblan.cpp binaryfile.h hid.h protocol_z.h \
+	remote_info.h web.h protocol.h remote.h usblan.h xml_headers.h \
+	operationfile.cpp remote_mh.cpp libusbhid.cpp libhidapi.cpp
 include_HEADERS = libconcord.h
-libconcord_la_LDFLAGS = -version-info 3:0:0 -lusb -lzzip
+libconcord_la_LDFLAGS = -version-info 3:0:0 -l$(USBLIB) -lzzip
 UDEVROOT ?= /
 UDEVLIBDIR ?= $(UDEVROOT)/lib
 
diff --git a/libconcord/configure.ac b/libconcord/configure.ac
index bd0477d..fd8a666 100644
--- a/libconcord/configure.ac
+++ b/libconcord/configure.ac
@@ -4,38 +4,83 @@ AC_CONFIG_MACRO_DIR([m4])
 m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
 AC_PROG_LIBTOOL
 AC_PROG_CXX
+AC_CANONICAL_HOST
 #
 # allow the user to disable the mime database update
 #
 AC_PATH_PROG(UPDATE_MIME_DATABASE, update-mime-database, no)
 HAVE_NEW_MIME=no
-AC_ARG_ENABLE(mime-update,
+AC_ARG_ENABLE(
+  mime-update,
 	AS_HELP_STRING([--disable-mime-update],
-	[Disable the MIME database update])],
+	               [Disable the MIME database update]),
 	[disable_mime=yes],
 	[disable_mime=no])
 if test "x$disable_mime" = "xno"; then
 	if test "x$UPDATE_MIME_DATABASE" != "xno"; then
-               HAVE_NEW_MIME=yes
-               AC_DEFINE(HAVE_NEW_MIME,1,[update mime database?])
+     HAVE_NEW_MIME=yes
+     AC_DEFINE(HAVE_NEW_MIME,1,[update mime database?])
 	fi
 fi
 AM_CONDITIONAL(HAVE_NEW_MIME, test x$HAVE_NEW_MIME = xyes)
+#
+# allow user to specify libusb on Linux
+#
+AC_ARG_ENABLE(
+  force-libusb-on-linux,
+  AS_HELP_STRING([--enable-force-libusb-on-linux],
+                 [Use libusb on Linux]),
+  [force_libusb_on_linux=$enableval],
+  [force_libusb_on_linux=no])
+case $host_os in
+  linux*)
+    if test "$force_libusb_on_linux" = "yes"; then
+      USBLIB="usb"
+      AC_DEFINE([WANT_LIBUSB], [1], [Want libusb])
+    else
+      USBLIB="hidapi-libusb"
+      AC_DEFINE([WANT_HIDAPI], [1], [Want hidapi])
+    fi
+    ;;
+  darwin*)
+    USBLIB="hidapi"
+    AC_DEFINE([WANT_HIDAPI], [1], [Want hidapi])
+    ;;
+esac
+AC_SUBST([USBLIB],[$USBLIB])
 a=1
-AC_CHECK_HEADER(usb.h, [], [a=0])
-AC_CHECK_LIB(usb, usb_init, [], [a=0])
+if test "$USBLIB" = "usb"; then
+  AC_CHECK_HEADER(usb.h, [], [a=0])
+  AC_CHECK_LIB(usb, usb_init, [], [a=0])
+else
+  AC_CHECK_HEADER(hidapi/hidapi.h, [], [a=0])
+  AC_CHECK_LIB(${USBLIB}, hid_init, [], [a=0])
+fi
 if test $a == 0
 then
-	AC_MSG_ERROR([Error, libusb is missing!])
+  errorstr="lib$USBLIB is missing!"
+  if test "x$force_libusb_on_linux" = "xno"; then
+    errorstr="$errorstr
+      Note that while we are deprecating the use of libusb on Linux in favor
+      of libhidapi, this release still supports it via
+      --enable-force-libusb-on-linux"
+  fi
+  AC_MSG_ERROR([$errorstr])
 fi
 AC_CHECK_HEADER(zzip/lib.h, [], [a=0])
 AC_CHECK_LIB(zzip, zzip_dir_open, [], [a=0])
 if test $a == 0
 then
-	AC_MSG_ERROR([Error, libzzip is missing!])
+    AC_MSG_ERROR([Error, libzzip is missing!])
 fi
-AC_CONFIG_HEADERS([config.h])
+#AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_FILES([
- Makefile
+    Makefile
 ])
 AC_OUTPUT
+if test "$force_libusb_on_linux" = "yes"; then
+  AC_MSG_WARN(
+    [
+      libusb support on linux will be dropped in a future release please
+      migrate to libhidapi!])
+fi
diff --git a/libconcord/lc_internal.h b/libconcord/lc_internal.h
index 5b8e933..31e2156 100644
--- a/libconcord/lc_internal.h
+++ b/libconcord/lc_internal.h
@@ -34,8 +34,6 @@
 
 #else /* END WINDOWS SECTION, BEGIN NON-WINDOWS SECTION */
 
-#define LIBUSB
-
 #define stricmp strcasecmp
 #define strnicmp strncasecmp
 
diff --git a/libconcord/libhidapi.cpp b/libconcord/libhidapi.cpp
new file mode 100644
index 0000000..26fc557
--- /dev/null
+++ b/libconcord/libhidapi.cpp
@@ -0,0 +1,148 @@
+/*
+ * vim:tw=80:ai:tabstop=4:softtabstop=4:shiftwidth=4:expandtab
+ *
+ * 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright Kevin Timmerman 2007
+ * (C) Copyright Phil Dibowitz 2007
+ */
+
+#include "lc_internal.h"
+#include "libconcord.h"
+
+#ifdef WANT_HIDAPI
+#ifndef LC_LIBHIDAPI
+#define LC_LIBHIDAPI
+
+#include "hid.h"
+#include <hidapi/hidapi.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+/*
+ * Harmonies either fall under logitech's VendorID (0x046d), and logitech's
+ * productID range for Harmonies (0xc110 - 0xc14f)...
+ *
+ * OR, they fall under 0x400/0xc359 (older 7-series, all 6-series).
+ */
+#define LOGITECH_VID 0x046D
+#define LOGITECH_MIN_PID 0xc110
+#define LOGITECH_MAX_PID 0xc14f
+#define NATIONAL_VID 0x0400
+#define NATIONAL_PID 0xc359
+
+#define USB_PACKET_LENGTH 64
+
+hid_device *h_dev;
+
+int InitUSB()
+{
+    hid_init();
+    return 0;
+}
+
+void ShutdownUSB()
+{
+    if (h_dev) {
+        hid_close(h_dev);
+    }
+    hid_exit();
+}
+
+bool is_harmony(struct hid_device_info *dev)
+{
+    /* IF vendor == logitech AND product is in range of harmony
+     *   OR vendor == National Semiconductor and product is harmony
+     */
+    if ((dev->vendor_id == LOGITECH_VID
+         && (dev->product_id >= LOGITECH_MIN_PID
+             && dev->product_id <= LOGITECH_MAX_PID))
+         || (dev->vendor_id == NATIONAL_VID
+             && dev->product_id == NATIONAL_PID)) {
+        return true;
+    }
+    return false;
+}
+
+/*
+ * Find a HID device that is a Harmony
+ */
+int FindRemote(THIDINFO &hid_info)
+{
+    struct hid_device_info *devs, *cur_dev;
+    bool found = false;
+    devs = hid_enumerate(0x0, 0x0);
+    cur_dev = devs;
+    while (cur_dev) {
+        debug("Testing: %d, %d", cur_dev->vendor_id, cur_dev->product_id);
+        if (is_harmony(cur_dev)) {
+            debug(" -- YES!");
+            hid_info.vid = cur_dev->vendor_id;
+            hid_info.pid = cur_dev->product_id;
+            hid_info.ver = cur_dev->release_number;
+            h_dev = hid_open(cur_dev->vendor_id, cur_dev->product_id, NULL);
+            found = true;
+            break;
+        }
+        cur_dev = cur_dev->next;
+    }
+    hid_free_enumeration(devs);
+    if (!found || !h_dev) {
+        debug("Failed to establish communication with remote");
+        return LC_ERROR_CONNECT;
+    }
+
+    // Fill in hid_info
+    const size_t buf_len = 128;
+    wchar_t wide_s[buf_len];
+    char s[buf_len];
+    hid_get_manufacturer_string(h_dev, wide_s, buf_len);
+    wcstombs(s, wide_s, buf_len);
+    hid_info.mfg = s;
+    hid_get_product_string(h_dev, wide_s, buf_len);
+    wcstombs(s, wide_s, buf_len);
+    hid_info.prod = s;
+
+    return 0;
+}
+
+int HID_WriteReport(const uint8_t *data)
+{
+    int err = hid_write(h_dev, data, USB_PACKET_LENGTH);
+    if (err < 0) {
+        debug("Failed to write to device: %d (%s)", err, hid_error(h_dev));
+        return err;
+    }
+
+    return 0;
+}
+
+int HID_ReadReport(uint8_t *data, unsigned int timeout)
+{
+    int err = hid_read_timeout(h_dev, data, USB_PACKET_LENGTH, timeout);
+    if (err < 0) {
+        debug("Failed to read from device: %d (%s)", err, hid_error(h_dev));
+        return err;
+    } else if (err == 0) {
+        debug("USB read timed out");
+        return 1;
+    }
+
+    return 0;
+}
+
+#endif
+#endif
diff --git a/libconcord/libusb/win/libusb_dyn.c b/libconcord/libusb/win/libusb_dyn.c
deleted file mode 100644
index f9ccdc0..0000000
--- a/libconcord/libusb/win/libusb_dyn.c
+++ /dev/null
@@ -1,492 +0,0 @@
-/* LIBUSB-WIN32, Generic Windows USB Library
- * Copyright (c) 2002-2005 Stephan Meyer <ste_me...@web.de>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#if defined(LIBUSB) && defined(WIN32)
-
-#include <windows.h>
-#include <errno.h>
-
-#ifndef ENOFILE
-#define ENOFILE 2
-#endif
-
-#include "usb.h"
-
-#define LIBUSB_DLL_NAME "libusb0.dll"
-
-
-typedef usb_dev_handle * (*usb_open_t)(struct usb_device *dev);
-typedef int (*usb_close_t)(usb_dev_handle *dev);
-typedef int (*usb_get_string_t)(usb_dev_handle *dev, int index, int langid, 
-                                char *buf, size_t buflen);
-typedef int (*usb_get_string_simple_t)(usb_dev_handle *dev, int index, 
-                                       char *buf, size_t buflen);
-typedef int (*usb_get_descriptor_by_endpoint_t)(usb_dev_handle *udev, int ep,
-                                                unsigned char type, 
-                                                unsigned char index,
-                                                void *buf, int size);
-typedef int (*usb_get_descriptor_t)(usb_dev_handle *udev, unsigned char type,
-                                    unsigned char index, void *buf, int size);
-typedef int (*usb_bulk_write_t)(usb_dev_handle *dev, int ep, char *bytes, 
-                                int size, int timeout);
-typedef int (*usb_bulk_read_t)(usb_dev_handle *dev, int ep, char *bytes, 
-                               int size, int timeout);
-typedef int (*usb_interrupt_write_t)(usb_dev_handle *dev, int ep, char *bytes,
-                                     int size, int timeout);
-typedef int (*usb_interrupt_read_t)(usb_dev_handle *dev, int ep, char *bytes,
-                                    int size, int timeout);
-typedef int (*usb_control_msg_t)(usb_dev_handle *dev, int requesttype, 
-                                 int request, int value, int index, 
-                                 char *bytes, int size, int timeout);
-typedef int (*usb_set_configuration_t)(usb_dev_handle *dev, int configuration);
-typedef int (*usb_claim_interface_t)(usb_dev_handle *dev, int interface);
-typedef int (*usb_release_interface_t)(usb_dev_handle *dev, int interface);
-typedef int (*usb_set_altinterface_t)(usb_dev_handle *dev, int alternate);
-typedef int (*usb_resetep_t)(usb_dev_handle *dev, unsigned int ep);
-typedef int (*usb_clear_halt_t)(usb_dev_handle *dev, unsigned int ep);
-typedef int (*usb_reset_t)(usb_dev_handle *dev);
-typedef char * (*usb_strerror_t)(void);
-typedef void (*usb_init_t)(void);
-typedef void (*usb_set_debug_t)(int level);
-typedef int (*usb_find_busses_t)(void);
-typedef int (*usb_find_devices_t)(void);
-typedef struct usb_device * (*usb_device_t)(usb_dev_handle *dev);
-typedef struct usb_bus * (*usb_get_busses_t)(void);
-typedef int (*usb_install_service_np_t)(void);
-typedef int (*usb_uninstall_service_np_t)(void);
-typedef int (*usb_install_driver_np_t)(const char *inf_file);
-typedef const struct usb_version * (*usb_get_version_t)(void);
-typedef int (*usb_isochronous_setup_async_t)(usb_dev_handle *dev, 
-                                             void **context,
-                                             unsigned char ep, int pktsize);
-typedef int (*usb_bulk_setup_async_t)(usb_dev_handle *dev, void **context,
-                                      unsigned char ep);
-typedef int (*usb_interrupt_setup_async_t)(usb_dev_handle *dev, void **context,
-                                           unsigned char ep);
-typedef int (*usb_submit_async_t)(void *context, char *bytes, int size);
-typedef int (*usb_reap_async_t)(void *context, int timeout);
-typedef int (*usb_free_async_t)(void **context);
-
-
-static usb_open_t _usb_open = NULL;
-static usb_close_t _usb_close = NULL;
-static usb_get_string_t _usb_get_string = NULL;
-static usb_get_string_simple_t _usb_get_string_simple = NULL;
-static usb_get_descriptor_by_endpoint_t _usb_get_descriptor_by_endpoint = NULL;
-static usb_get_descriptor_t _usb_get_descriptor = NULL;
-static usb_bulk_write_t _usb_bulk_write = NULL;
-static usb_bulk_read_t _usb_bulk_read = NULL;
-static usb_interrupt_write_t _usb_interrupt_write = NULL;
-static usb_interrupt_read_t _usb_interrupt_read = NULL;
-static usb_control_msg_t _usb_control_msg = NULL;
-static usb_set_configuration_t _usb_set_configuration = NULL;
-static usb_claim_interface_t _usb_claim_interface = NULL;
-static usb_release_interface_t _usb_release_interface = NULL;
-static usb_set_altinterface_t _usb_set_altinterface = NULL;
-static usb_resetep_t _usb_resetep = NULL;
-static usb_clear_halt_t _usb_clear_halt = NULL;
-static usb_reset_t _usb_reset = NULL;
-static usb_strerror_t _usb_strerror = NULL;
-static usb_init_t _usb_init = NULL;
-static usb_set_debug_t _usb_set_debug = NULL;
-static usb_find_busses_t _usb_find_busses = NULL;
-static usb_find_devices_t _usb_find_devices = NULL;
-static usb_device_t _usb_device = NULL;
-static usb_get_busses_t _usb_get_busses = NULL;
-static usb_install_service_np_t _usb_install_service_np = NULL;
-static usb_uninstall_service_np_t _usb_uninstall_service_np = NULL;
-static usb_install_driver_np_t _usb_install_driver_np = NULL;
-static usb_get_version_t _usb_get_version = NULL;
-static usb_isochronous_setup_async_t _usb_isochronous_setup_async = NULL;
-static usb_bulk_setup_async_t _usb_bulk_setup_async = NULL;
-static usb_interrupt_setup_async_t _usb_interrupt_setup_async = NULL;
-static usb_submit_async_t _usb_submit_async = NULL;
-static usb_reap_async_t _usb_reap_async = NULL;
-static usb_free_async_t _usb_free_async = NULL;
-
-
-
-
-void usb_init(void)
-{
-  HINSTANCE libusb_dll  = LoadLibrary(LIBUSB_DLL_NAME);
-  
-  if(!libusb_dll)
-    return;
-
-  _usb_open = (usb_open_t)
-    GetProcAddress(libusb_dll, "usb_open");
-  _usb_close = (usb_close_t)
-    GetProcAddress(libusb_dll, "usb_close");
-  _usb_get_string = (usb_get_string_t)
-    GetProcAddress(libusb_dll, "usb_get_string");
-  _usb_get_string_simple = (usb_get_string_simple_t)
-    GetProcAddress(libusb_dll, "usb_get_string_simple");
-  _usb_get_descriptor_by_endpoint = (usb_get_descriptor_by_endpoint_t)
-    GetProcAddress(libusb_dll, "usb_get_descriptor_by_endpoint");
-  _usb_get_descriptor = (usb_get_descriptor_t)
-    GetProcAddress(libusb_dll, "usb_get_descriptor");
-  _usb_bulk_write = (usb_bulk_write_t)
-    GetProcAddress(libusb_dll, "usb_bulk_write");
-  _usb_bulk_read = (usb_bulk_read_t)
-    GetProcAddress(libusb_dll, "usb_bulk_read");
-  _usb_interrupt_write = (usb_interrupt_write_t)
-    GetProcAddress(libusb_dll, "usb_interrupt_write");
-  _usb_interrupt_read = (usb_interrupt_read_t)
-    GetProcAddress(libusb_dll, "usb_interrupt_read");
-  _usb_control_msg = (usb_control_msg_t)
-    GetProcAddress(libusb_dll, "usb_control_msg");
-  _usb_set_configuration = (usb_set_configuration_t)
-    GetProcAddress(libusb_dll, "usb_set_configuration");
-  _usb_claim_interface = (usb_claim_interface_t)
-    GetProcAddress(libusb_dll, "usb_claim_interface");
-  _usb_release_interface = (usb_release_interface_t)
-    GetProcAddress(libusb_dll, "usb_release_interface");
-  _usb_set_altinterface = (usb_set_altinterface_t)
-    GetProcAddress(libusb_dll, "usb_set_altinterface");
-  _usb_resetep = (usb_resetep_t)
-    GetProcAddress(libusb_dll, "usb_resetep");
-  _usb_clear_halt = (usb_clear_halt_t)
-    GetProcAddress(libusb_dll, "usb_clear_halt");
-  _usb_reset = (usb_reset_t)
-    GetProcAddress(libusb_dll, "usb_reset");
-  _usb_strerror = (usb_strerror_t)
-    GetProcAddress(libusb_dll, "usb_strerror");
-  _usb_init = (usb_init_t)
-    GetProcAddress(libusb_dll, "usb_init");
-  _usb_set_debug = (usb_set_debug_t)
-    GetProcAddress(libusb_dll, "usb_set_debug");
-  _usb_find_busses = (usb_find_busses_t)
-    GetProcAddress(libusb_dll, "usb_find_busses");
-  _usb_find_devices = (usb_find_devices_t)
-    GetProcAddress(libusb_dll, "usb_find_devices");
-  _usb_device = (usb_device_t)
-    GetProcAddress(libusb_dll, "usb_device");
-  _usb_get_busses = (usb_get_busses_t)
-    GetProcAddress(libusb_dll, "usb_get_busses");
-  _usb_install_service_np = (usb_install_service_np_t)
-    GetProcAddress(libusb_dll, "usb_install_service_np");
-  _usb_uninstall_service_np = (usb_uninstall_service_np_t)
-    GetProcAddress(libusb_dll, "usb_uninstall_service_np");
-  _usb_install_driver_np = (usb_install_driver_np_t)
-    GetProcAddress(libusb_dll, "usb_install_driver_np");
-  _usb_get_version = (usb_get_version_t)
-    GetProcAddress(libusb_dll, "usb_get_version");
-  _usb_isochronous_setup_async = (usb_isochronous_setup_async_t)
-    GetProcAddress(libusb_dll, "usb_isochronous_setup_async");
-  _usb_bulk_setup_async = (usb_bulk_setup_async_t)
-    GetProcAddress(libusb_dll, "usb_bulk_setup_async");
-  _usb_interrupt_setup_async = (usb_interrupt_setup_async_t)
-    GetProcAddress(libusb_dll, "usb_interrupt_setup_async");
-  _usb_submit_async = (usb_submit_async_t)
-    GetProcAddress(libusb_dll, "usb_submit_async");
-  _usb_reap_async = (usb_reap_async_t)
-    GetProcAddress(libusb_dll, "usb_reap_async");
-  _usb_free_async = (usb_free_async_t)
-    GetProcAddress(libusb_dll, "usb_free_async");
-
-  if(_usb_init)
-    _usb_init();
-}
-
-usb_dev_handle *usb_open(struct usb_device *dev)
-{
-  if(_usb_open)
-    return _usb_open(dev);
-  else
-    return NULL;
-}
-
-int usb_close(usb_dev_handle *dev)
-{
-  if(_usb_close)
-    return _usb_close(dev);
-  else
-    return -ENOFILE;
-}
-
-int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
-                   size_t buflen)
-{
-  if(_usb_get_string)
-    return _usb_get_string(dev, index, langid, buf, buflen);
-  else
-    return -ENOFILE;
-}
-
-int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
-                          size_t buflen)
-{
-  if(_usb_get_string_simple)
-    return _usb_get_string_simple(dev, index, buf, buflen);
-  else
-    return -ENOFILE;
-}
-
-int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
-                                   unsigned char type, unsigned char index,
-                                   void *buf, int size)
-{
-  if(_usb_get_descriptor_by_endpoint)
-    return _usb_get_descriptor_by_endpoint(udev, ep, type, index, buf, size);
-  else
-    return -ENOFILE;
-}
-
-int usb_get_descriptor(usb_dev_handle *udev, unsigned char type,
-                       unsigned char index, void *buf, int size)
-{
-  if(_usb_get_descriptor)
-    return _usb_get_descriptor(udev, type, index, buf, size);
-  else
-    return -ENOFILE;
-}
-
-int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
-                   int timeout)
-{
-  if(_usb_bulk_write)
-    return _usb_bulk_write(dev, ep, bytes, size, timeout);
-  else
-    return -ENOFILE;
-}
-
-int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
-                  int timeout)
-{
-  if(_usb_bulk_read)
-    return _usb_bulk_read(dev, ep, bytes, size, timeout);
-  else
-    return -ENOFILE;
-}
-
-int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
-                        int timeout)
-{
-  if(_usb_interrupt_write)
-    return _usb_interrupt_write(dev, ep, bytes, size, timeout);
-  else
-    return -ENOFILE;
-}
-
-int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
-                       int timeout)
-{
-  if(_usb_interrupt_read)
-    return _usb_interrupt_read(dev, ep, bytes, size, timeout);
-  else
-    return -ENOFILE;
-}
-
-int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
-                    int value, int index, char *bytes, int size, 
-                    int timeout)
-{
-  if(_usb_control_msg)
-    return _usb_control_msg(dev, requesttype, request, value, index, bytes, 
-                            size, timeout);
-  else
-    return -ENOFILE;
-}
-
-int usb_set_configuration(usb_dev_handle *dev, int configuration)
-{
-  if(_usb_set_configuration)
-    return _usb_set_configuration(dev, configuration);
-  else
-    return -ENOFILE;
-}
-
-int usb_claim_interface(usb_dev_handle *dev, int interface)
-{
-  if(_usb_claim_interface)
-    return _usb_claim_interface(dev, interface);
-  else
-    return -ENOFILE;
-}
-
-int usb_release_interface(usb_dev_handle *dev, int interface)
-{
-  if(_usb_release_interface)
-    return _usb_release_interface(dev, interface);
-  else
-    return -ENOFILE;
-}
-
-int usb_set_altinterface(usb_dev_handle *dev, int alternate)
-{
-  if(_usb_set_altinterface)
-    return _usb_set_altinterface(dev, alternate);
-  else
-    return -ENOFILE;
-}
-
-int usb_resetep(usb_dev_handle *dev, unsigned int ep)
-{
-  if(_usb_resetep)
-    return _usb_resetep(dev, ep);
-  else
-    return -ENOFILE;
-}
-
-int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
-{
-  if(_usb_clear_halt)
-    return _usb_clear_halt(dev, ep);
-  else
-    return -ENOFILE;
-}
-
-int usb_reset(usb_dev_handle *dev)
-{
-  if(_usb_reset)
-    return _usb_reset(dev);
-  else
-    return -ENOFILE;
-}
-
-char *usb_strerror(void)
-{
-  if(_usb_strerror)
-    return _usb_strerror();
-  else
-    return NULL;
-}
-
-void usb_set_debug(int level)
-{
-  if(_usb_set_debug)
-    _usb_set_debug(level);
-}
-
-int usb_find_busses(void)
-{
-  if(_usb_find_busses)
-    return _usb_find_busses();
-  else
-    return -ENOFILE;
-}
-
-int usb_find_devices(void)
-{
-  if(_usb_find_devices)
-    return _usb_find_devices();
-  else
-    return -ENOFILE;
-}
-
-struct usb_device *usb_device(usb_dev_handle *dev)
-{
-  if(_usb_device)
-    return _usb_device(dev);
-  else
-    return NULL;
-}
-
-struct usb_bus *usb_get_busses(void)
-{
-  if(_usb_get_busses)
-    return _usb_get_busses();
-  else
-    return NULL;
-}
-
-int usb_install_service_np(void)
-{
-  if(_usb_install_service_np)
-    return _usb_install_service_np();
-  else
-    return -ENOFILE;
-}
-
-int usb_uninstall_service_np(void)
-{
-  if(_usb_uninstall_service_np)
-    return _usb_uninstall_service_np();
-  else
-    return -ENOFILE;
-}
-
-int usb_install_driver_np(const char *inf_file)
-{
-  if(_usb_install_driver_np)
-    return _usb_install_driver_np(inf_file);
-  else
-    return -ENOFILE;
-}
-
-const struct usb_version *usb_get_version(void)
-{
-  if(_usb_get_version)
-    return _usb_get_version();
-  else
-    return NULL;
-}
-
-int usb_isochronous_setup_async(usb_dev_handle *dev, void **context,
-                                unsigned char ep, int pktsize)
-{
-  if(_usb_isochronous_setup_async)
-    return _usb_isochronous_setup_async(dev, context, ep, pktsize);
-  else
-    return -ENOFILE;
-}
-
-int usb_bulk_setup_async(usb_dev_handle *dev, void **context,
-                         unsigned char ep)
-{
-  if(_usb_bulk_setup_async)
-    return _usb_bulk_setup_async(dev, context, ep);
-  else
-    return -ENOFILE;
-}
-
-int usb_interrupt_setup_async(usb_dev_handle *dev, void **context,
-                              unsigned char ep)
-{
-  if(_usb_interrupt_setup_async)
-    return _usb_interrupt_setup_async(dev, context, ep);
-  else
-    return -ENOFILE;
-}
-
-int usb_submit_async(void *context, char *bytes, int size)
-{
-  if(_usb_submit_async)
-    return _usb_submit_async(context, bytes, size);
-  else
-    return -ENOFILE;
-}
-
-int usb_reap_async(void *context, int timeout)
-{
-  if(_usb_reap_async)
-    return _usb_reap_async(context, timeout);
-  else
-    return -ENOFILE;
-}
-
-int usb_free_async(void **context)
-{
-  if(_usb_free_async)
-    return _usb_free_async(context);
-  else
-    return -ENOFILE;
-}
-
-#endif
diff --git a/libconcord/libusb/win/usb.h b/libconcord/libusb/win/usb.h
deleted file mode 100644
index 74186fb..0000000
--- a/libconcord/libusb/win/usb.h
+++ /dev/null
@@ -1,394 +0,0 @@
-#ifndef __USB_H__
-#define __USB_H__
-
-#include <stdlib.h>
-#include <windows.h>
-
-/* 
- * 'interface' is defined somewhere in the Windows header files. This macro 
- * is deleted here to avoid conflicts and compile errors.
- */
-
-#ifdef interface
-#undef interface
-#endif
-
-/*
- * PATH_MAX from limits.h can't be used on Windows if the dll and
- * import libraries are build/used by different compilers 
- */
-
-#define LIBUSB_PATH_MAX 512
-
-
-/*
- * USB spec information
- *
- * This is all stuff grabbed from various USB specs and is pretty much
- * not subject to change
- */
-
-/*
- * Device and/or Interface Class codes
- */
-#define USB_CLASS_PER_INTERFACE        0    /* for DeviceClass */
-#define USB_CLASS_AUDIO                  1
-#define USB_CLASS_COMM                  2
-#define USB_CLASS_HID                    3
-#define USB_CLASS_PRINTER              7
-#define USB_CLASS_MASS_STORAGE        8
-#define USB_CLASS_HUB                    9
-#define USB_CLASS_DATA                  10
-#define USB_CLASS_VENDOR_SPEC          0xff
-
-/*
- * Descriptor types
- */
-#define USB_DT_DEVICE            0x01
-#define USB_DT_CONFIG            0x02
-#define USB_DT_STRING            0x03
-#define USB_DT_INTERFACE    0x04
-#define USB_DT_ENDPOINT        0x05
-
-#define USB_DT_HID            0x21
-#define USB_DT_REPORT        0x22
-#define USB_DT_PHYSICAL    0x23
-#define USB_DT_HUB            0x29
-
-/*
- * Descriptor sizes per descriptor type
- */
-#define USB_DT_DEVICE_SIZE        18
-#define USB_DT_CONFIG_SIZE        9
-#define USB_DT_INTERFACE_SIZE        9
-#define USB_DT_ENDPOINT_SIZE        7
-#define USB_DT_ENDPOINT_AUDIO_SIZE    9    /* Audio extension */
-#define USB_DT_HUB_NONVAR_SIZE        7
-
-
-/* ensure byte-packed structures */
-#include <pshpack1.h> 
-
-
-/* All standard descriptors have these 2 fields in common */
-struct usb_descriptor_header {
-  unsigned char  bLength;
-  unsigned char  bDescriptorType;
-};
-
-/* String descriptor */
-struct usb_string_descriptor {
-  unsigned char  bLength;
-  unsigned char  bDescriptorType;
-  unsigned short wData[1];
-};
-
-/* HID descriptor */
-struct usb_hid_descriptor {
-  unsigned char  bLength;
-  unsigned char  bDescriptorType;
-  unsigned short bcdHID;
-  unsigned char  bCountryCode;
-  unsigned char  bNumDescriptors;
-};
-
-/* Endpoint descriptor */
-#define USB_MAXENDPOINTS    32
-struct usb_endpoint_descriptor {
-  unsigned char  bLength;
-  unsigned char  bDescriptorType;
-  unsigned char  bEndpointAddress;
-  unsigned char  bmAttributes;
-  unsigned short wMaxPacketSize;
-  unsigned char  bInterval;
-  unsigned char  bRefresh;
-  unsigned char  bSynchAddress;
-
-  unsigned char *extra;    /* Extra descriptors */
-  int extralen;
-};
-
-#define USB_ENDPOINT_ADDRESS_MASK    0x0f    /* in bEndpointAddress */
-#define USB_ENDPOINT_DIR_MASK          0x80
-
-#define USB_ENDPOINT_TYPE_MASK        0x03    /* in bmAttributes */
-#define USB_ENDPOINT_TYPE_CONTROL        0
-#define USB_ENDPOINT_TYPE_ISOCHRONOUS    1
-#define USB_ENDPOINT_TYPE_BULK            2
-#define USB_ENDPOINT_TYPE_INTERRUPT      3
-
-/* Interface descriptor */
-#define USB_MAXINTERFACES    32
-struct usb_interface_descriptor {
-  unsigned char  bLength;
-  unsigned char  bDescriptorType;
-  unsigned char  bInterfaceNumber;
-  unsigned char  bAlternateSetting;
-  unsigned char  bNumEndpoints;
-  unsigned char  bInterfaceClass;
-  unsigned char  bInterfaceSubClass;
-  unsigned char  bInterfaceProtocol;
-  unsigned char  iInterface;
-
-  struct usb_endpoint_descriptor *endpoint;
-
-  unsigned char *extra;    /* Extra descriptors */
-  int extralen;
-};
-
-#define USB_MAXALTSETTING    128    /* Hard limit */
-
-struct usb_interface {
-  struct usb_interface_descriptor *altsetting;
-
-  int num_altsetting;
-};
-
-/* Configuration descriptor information.. */
-#define USB_MAXCONFIG        8
-struct usb_config_descriptor {
-  unsigned char  bLength;
-  unsigned char  bDescriptorType;
-  unsigned short wTotalLength;
-  unsigned char  bNumInterfaces;
-  unsigned char  bConfigurationValue;
-  unsigned char  iConfiguration;
-  unsigned char  bmAttributes;
-  unsigned char  MaxPower;
-
-  struct usb_interface *interface;
-
-  unsigned char *extra;    /* Extra descriptors */
-  int extralen;
-};
-
-/* Device descriptor */
-struct usb_device_descriptor {
-  unsigned char  bLength;
-  unsigned char  bDescriptorType;
-  unsigned short bcdUSB;
-  unsigned char  bDeviceClass;
-  unsigned char  bDeviceSubClass;
-  unsigned char  bDeviceProtocol;
-  unsigned char  bMaxPacketSize0;
-  unsigned short idVendor;
-  unsigned short idProduct;
-  unsigned short bcdDevice;
-  unsigned char  iManufacturer;
-  unsigned char  iProduct;
-  unsigned char  iSerialNumber;
-  unsigned char  bNumConfigurations;
-};
-
-struct usb_ctrl_setup {
-  unsigned char  bRequestType;
-  unsigned char  bRequest;
-  unsigned short wValue;
-  unsigned short wIndex;
-  unsigned short wLength;
-};
-
-/*
- * Standard requests
- */
-#define USB_REQ_GET_STATUS            0x00
-#define USB_REQ_CLEAR_FEATURE        0x01
-/* 0x02 is reserved */
-#define USB_REQ_SET_FEATURE            0x03
-/* 0x04 is reserved */
-#define USB_REQ_SET_ADDRESS            0x05
-#define USB_REQ_GET_DESCRIPTOR        0x06
-#define USB_REQ_SET_DESCRIPTOR        0x07
-#define USB_REQ_GET_CONFIGURATION    0x08
-#define USB_REQ_SET_CONFIGURATION    0x09
-#define USB_REQ_GET_INTERFACE          0x0A
-#define USB_REQ_SET_INTERFACE          0x0B
-#define USB_REQ_SYNCH_FRAME            0x0C
-
-#define USB_TYPE_STANDARD        (0x00 << 5)
-#define USB_TYPE_CLASS            (0x01 << 5)
-#define USB_TYPE_VENDOR            (0x02 << 5)
-#define USB_TYPE_RESERVED        (0x03 << 5)
-
-#define USB_RECIP_DEVICE        0x00
-#define USB_RECIP_INTERFACE    0x01
-#define USB_RECIP_ENDPOINT    0x02
-#define USB_RECIP_OTHER            0x03
-
-/*
- * Various libusb API related stuff
- */
-
-#define USB_ENDPOINT_IN            0x80
-#define USB_ENDPOINT_OUT        0x00
-
-/* Error codes */
-#define USB_ERROR_BEGIN            500000
-
-/*
- * This is supposed to look weird. This file is generated from autoconf
- * and I didn't want to make this too complicated.
- */
-#define USB_LE16_TO_CPU(x)
-
-/* Data types */
-/* struct usb_device; */
-/* struct usb_bus; */
-
-struct usb_device {
-  struct usb_device *next, *prev;
-
-  char filename[LIBUSB_PATH_MAX];
-
-  struct usb_bus *bus;
-
-  struct usb_device_descriptor descriptor;
-  struct usb_config_descriptor *config;
-
-  void *dev;        /* Darwin support */
-
-  unsigned char devnum;
-
-  unsigned char num_children;
-  struct usb_device **children;
-};
-
-struct usb_bus {
-  struct usb_bus *next, *prev;
-
-  char dirname[LIBUSB_PATH_MAX];
-
-  struct usb_device *devices;
-  unsigned long location;
-
-  struct usb_device *root_dev;
-};
-
-/* Version information, Windows specific */
-struct usb_version {
-  struct {
-    int major;
-    int minor;
-    int micro;
-    int nano;
-  } dll;
-  struct {
-    int major;
-    int minor;
-    int micro;
-    int nano;
-  } driver;
-};
-
-
-struct usb_dev_handle;
-typedef struct usb_dev_handle usb_dev_handle;
-
-/* Variables */
-#ifndef __USB_C__
-#define usb_busses usb_get_busses()
-#endif
-
-
-
-#include <poppack.h>
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-  /* Function prototypes */
-
-  /* usb.c */
-  usb_dev_handle *usb_open(struct usb_device *dev);
-  int usb_close(usb_dev_handle *dev);
-  int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf,
-                     size_t buflen);
-  int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf,
-                            size_t buflen);
-
-  /* descriptors.c */
-  int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep,
-                                     unsigned char type, unsigned char index,
-                                     void *buf, int size);
-  int usb_get_descriptor(usb_dev_handle *udev, unsigned char type,
-                         unsigned char index, void *buf, int size);
-
-  /* <arch>.c */
-  int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
-                     int timeout);
-  int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
-                    int timeout);
-  int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
-                          int timeout);
-  int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
-                         int timeout);
-  int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
-                      int value, int index, char *bytes, int size, 
-                      int timeout);
-  int usb_set_configuration(usb_dev_handle *dev, int configuration);
-  int usb_claim_interface(usb_dev_handle *dev, int interface);
-  int usb_release_interface(usb_dev_handle *dev, int interface);
-  int usb_set_altinterface(usb_dev_handle *dev, int alternate);
-  int usb_resetep(usb_dev_handle *dev, unsigned int ep);
-  int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);
-  int usb_reset(usb_dev_handle *dev);
-
-  char *usb_strerror(void);
-
-  void usb_init(void);
-  void usb_set_debug(int level);
-  int usb_find_busses(void);
-  int usb_find_devices(void);
-  struct usb_device *usb_device(usb_dev_handle *dev);
-  struct usb_bus *usb_get_busses(void);
-
-
-  /* Windows specific functions */
-
-  #define LIBUSB_HAS_INSTALL_SERVICE_NP 1
-  int usb_install_service_np(void);
-  void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance,
-                                              LPSTR cmd_line, int cmd_show);
-  
-  #define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1
-  int usb_uninstall_service_np(void);
-  void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance,
-                                                LPSTR cmd_line, int cmd_show);
-
-  #define LIBUSB_HAS_INSTALL_DRIVER_NP 1
-  int usb_install_driver_np(const char *inf_file);
-  void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance,
-                                             LPSTR cmd_line, int cmd_show);
-
-  #define LIBUSB_HAS_TOUCH_INF_FILE_NP 1
-  int usb_touch_inf_file_np(const char *inf_file);
-  void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance,
-                                             LPSTR cmd_line, int cmd_show);
-
-  #define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1
-  int usb_install_needs_restart_np(void);
-
-  const struct usb_version *usb_get_version(void);
-
-  int usb_isochronous_setup_async(usb_dev_handle *dev, void **context,
-                                  unsigned char ep, int pktsize);
-  int usb_bulk_setup_async(usb_dev_handle *dev, void **context,
-                           unsigned char ep);
-  int usb_interrupt_setup_async(usb_dev_handle *dev, void **context,
-                                unsigned char ep);
-
-  int usb_submit_async(void *context, char *bytes, int size);
-  int usb_reap_async(void *context, int timeout);
-  int usb_reap_async_nocancel(void *context, int timeout);
-  int usb_cancel_async(void *context);
-  int usb_free_async(void **context);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __USB_H__ */
-
diff --git a/libconcord/libusb/libusbhid.cpp b/libconcord/libusbhid.cpp
similarity index 98%
rename from libconcord/libusb/libusbhid.cpp
rename to libconcord/libusbhid.cpp
index 2f75f61..915c11f 100644
--- a/libconcord/libusb/libusbhid.cpp
+++ b/libconcord/libusbhid.cpp
@@ -19,17 +19,16 @@
  * (C) Copyright Phil Dibowitz 2007
  */
 
-#include "../lc_internal.h"
-#include "../libconcord.h"
+#include "lc_internal.h"
+#include "libconcord.h"
 
-#ifdef LIBUSB
+#ifdef WANT_LIBUSB
 
-#include "../hid.h"
-#ifdef WIN32
-#include "win/usb.h"
-#else
+#ifndef LC_LIBUSB
+#define LC_LIBUSB
+
+#include "hid.h"
 #include <usb.h>
-#endif
 #include <errno.h>
 #include <string.h>
 
@@ -246,3 +245,4 @@ int HID_ReadReport(uint8_t *data, unsigned int timeout)
 }
 
 #endif
+#endif

Attachment: signature.asc
Description: OpenPGP digital signature

------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58041391&iu=/4140/ostg.clktrk
_______________________________________________
concordance-devel mailing list
concordance-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/concordance-devel

Reply via email to