On 2013.06.07 08:05, Ludovic Rousseau wrote:
It is too late to rewrite exiting and working code.

How is it too late?
This code has not been integrated and furthermore was proposed for review.
Also, it does not work, since it breaks Windows (see below).

Unless you have a lot of free time :-)

I don't, but with Windows being a demanding mistress, I don't really have much choice but to offer a _working_ counter proposal, which I have now tested on Linux, OS-X and all the Windowses (MSVC, WDK, MinGW, cygwin).

And yeah, the patch itself is much larger than Hans' (though the strerror.c is smaller), because Hans' version ignored MSVC altogether, so the VS solution files and the WDK build scripts didn't reference strerror.c. This means that compilation with MSVC/WDK was out from the get go.

On that topic, I'll add a note that if you add any source, I have to spend about 1/2 hour manually adding it to the MSVC/WDK solution files (very repetitive and boring process). Thus, since I was going to get involved anyway, I went for the 3 course meal.

Still I'm tempted to give a good point to Hans for trying to cater for the .def file... except he aliased libusb_set_locale rather than libusb_setlocale, so that broke MinGW (and probably cygwin too).

Sorry Ludovic (and Hans), but working code this isn't -- though I should probably have tested and reported earlier that it wasn't.

So, while I was there, I took Ludovic's remarks into account, but went with my version of strerror, which I continue to think is much simpler and better (since it groups the localized strings together, and it'll actually break compilation if people add a new message and forget to add a string for the languages - which might very well be "SOMEONE NEED TO TRANSLATE THIS CODE" -- With Hans' proposal, I'm willing to bet we'll get missing cases, since a case switch doesn't enforce jack and thus it's way too easy to miss a translation) and I also added French. To complete the picture, since we might as well test the feature, I added a new -l parameter to xusb.

The end result will then produce something like this (on Windows, against a *broken* USB 3.0 flash drive. I'm using French so that we get UTF-8 accents.):
-----------------------------------------------------------------------
D:\libusbx\x64\Release\examples>chcp 65001  ; set console to UTF-8
Active code page: 65001
D:\libusbx\x64\Release\examples>xusb -l fr 125f:312b
Using libusbx v1.0.16.10733

Opening device 125F:312B...

Reading device descriptor:
            length: 18
      device class: 0
               S/N: 3
           VID:PID: 125F:312B
         bcdDevice: 0100
   iMan:iProd:iSer: 1:2:3
          nb confs: 1

Reading BOS descriptor: 2 caps
    USB 2.0 extension:
      attributes             : 02
    USB 3.0 capabilities:
      attributes             : 00
      supported speeds       : 000E
      supported functionality: 01

Reading first configuration descriptor:
             nb interfaces: 1
              interface[0]: id = 0
interface[0].altsetting[0]: num endpoints = 2
   Class.SubClass.Protocol: 08.06.50
       endpoint[0].address: 02
           max packet size: 0400
          polling interval: 00
                 max burst: 0F   (USB 3.0)
        bytes per interval: 0000 (USB 3.0)
       endpoint[1].address: 81
           max packet size: 0400
          polling interval: 00
                 max burst: 0F   (USB 3.0)
        bytes per interval: 0000 (USB 3.0)

Claiming interface 0...

Reading string descriptors:
   String (0x01): "ADATA"
   String (0x02): "ADATA USB Flash Drive"
   String (0x03): "000000000000000204"
Reading Max LUN:
   Max LUN = 0
Sending Inquiry:
   send_mass_storage_command: Operation expirée
   received 13 bytes
   VID:PID:REV "      ":"        ":"    "
   get_mass_storage_status: Operation expirée
Reading Capacity:
   sent 10 CDB bytes
   Erreur de pipe
   Erreur d'entrée/sortie
-------------------------------------------------------------------

And I prefer Hans version.

You're free to cast your vote for the proposal you like best. And this too, just like Hans, is _only_ a proposal (albeit an actually working and tested one).

Regards,

/Pete

PS: I'm also currently observing libusbx breakage on ARM/Linux (Feroceon/Slackware ARM). Every libusbx app I try to run there seems to freeze during libusb_init. Trying to identify if it's anything to do with my system (which used to work fine before, and I also confirmed that the same source on Slackware x86 was OK) or if it has anything to do with the latest series of changes.



>From 724a9582fa2690c293f448904ba7c44b3546d446 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdego...@redhat.com>
Date: Fri, 7 Jun 2013 19:07:16 +0100
Subject: [PATCH] Core: Add a libusb_strerror() function

This patch adds the much requested libusb_strerror() function, taking into
account all issues people raised wrt previous attempts.

Criteria / Decisions underlying this implementation:
- Must support translated messages
- Must not use gettext as that does not work well in combination with Windows
 (when building with Visual C, or for Windows CE)
- API compatible with FreeBSD and various patched libusb-s floating around
- KISS:
 - Do not add any (other) library dependencies
 - Do not try to deal with message encodings (iconv), simply always return UTF-8
   making encoding the problem of the application using libusb_strerror.
 - Defaults to English, so apps which don't want translated messages,
   don't need to do anything special
 - Defaults to English (with pure ASCII messages), so apps which don't
   call libusb_setlocale() don't need to worry about encoding
---
 examples/xusb.c                         |  30 ++++--
 libusb/Makefile.am                      |   5 +-
 libusb/libusb-1.0.def                   |   8 +-
 libusb/libusb.h                         |  13 ++-
 libusb/libusbi.h                        |   4 +
 libusb/strerror.c                       | 156 ++++++++++++++++++++++++++++++++
 libusb/version_nano.h                   |   2 +-
 msvc/libusb_dll_2005.vcproj             |   4 +
 msvc/libusb_dll_2010.vcxproj            |   1 +
 msvc/libusb_dll_2010.vcxproj.filters    |   3 +
 msvc/libusb_dll_2012.vcxproj            |   1 +
 msvc/libusb_dll_2012.vcxproj.filters    |   3 +
 msvc/libusb_dll_wince.vcproj            |   4 +
 msvc/libusb_sources                     |   1 +
 msvc/libusb_static_2005.vcproj          |   4 +
 msvc/libusb_static_2010.vcxproj         |   1 +
 msvc/libusb_static_2010.vcxproj.filters |   3 +
 msvc/libusb_static_2012.vcxproj         |   1 +
 msvc/libusb_static_2012.vcxproj.filters |   3 +
 msvc/libusb_static_wince.vcproj         |   4 +
 20 files changed, 232 insertions(+), 19 deletions(-)
 create mode 100644 libusb/strerror.c

diff --git a/examples/xusb.c b/examples/xusb.c
index 4e2f6a5..cae3d82 100644
--- a/examples/xusb.c
+++ b/examples/xusb.c
@@ -64,7 +64,7 @@ static int perr(char const *format, ...)
        return r;
 }
 
-#define ERR_EXIT(errcode) do { perr("   %s\n", libusb_error_name((enum 
libusb_error)errcode)); return -1; } while (0)
+#define ERR_EXIT(errcode) do { perr("   %s\n", libusb_strerror((enum 
libusb_error)errcode)); return -1; } while (0)
 #define CALL_CHECK(fcall) do { r=fcall; if (r < 0) ERR_EXIT(r); } while (0);
 #define B(x) (((x)!=0)?1:0)
 #define be_to_int32(buf) (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|(buf)[3])
@@ -354,7 +354,7 @@ static int send_mass_storage_command(libusb_device_handle 
*handle, uint8_t endpo
                i++;
        } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
        if (r != LIBUSB_SUCCESS) {
-               perr("   send_mass_storage_command: %s\n", 
libusb_error_name(r));
+               perr("   send_mass_storage_command: %s\n", 
libusb_strerror((enum libusb_error)r));
                return -1;
        }
 
@@ -378,7 +378,7 @@ static int get_mass_storage_status(libusb_device_handle 
*handle, uint8_t endpoin
                i++;
        } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
        if (r != LIBUSB_SUCCESS) {
-               perr("   get_mass_storage_status: %s\n", libusb_error_name(r));
+               perr("   get_mass_storage_status: %s\n", libusb_strerror((enum 
libusb_error)r));
                return -1;
        }
        if (size != 13) {
@@ -460,7 +460,7 @@ static int test_mass_storage(libusb_device_handle *handle, 
uint8_t endpoint_in,
        if (r == 0) {
                lun = 0;
        } else if (r < 0) {
-               perr("   Failed: %s", libusb_error_name((enum libusb_error)r));
+               perr("   Failed: %s", libusb_strerror((enum libusb_error)r));
        }
        printf("   Max LUN = %d\n", lun);
 
@@ -638,7 +638,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t 
endpoint_in)
                                libusb_clear_halt(handle, 0);
                                break;
                        default:
-                               printf("   Error: %s\n", libusb_error_name(r));
+                               printf("   Error: %s\n", libusb_strerror((enum 
libusb_error)r));
                                break;
                        }
                }
@@ -669,7 +669,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t 
endpoint_in)
                                libusb_clear_halt(handle, 0);
                                break;
                        default:
-                               printf("   Error: %s\n", libusb_error_name(r));
+                               printf("   Error: %s\n", libusb_strerror((enum 
libusb_error)r));
                                break;
                        }
                }
@@ -680,7 +680,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t 
endpoint_in)
                if (r >= 0) {
                        display_buffer_hex(report_buffer, size);
                } else {
-                       printf("   %s\n", libusb_error_name(r));
+                       printf("   %s\n", libusb_strerror((enum 
libusb_error)r));
                }
 
                free(report_buffer);
@@ -715,7 +715,7 @@ static void 
read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
                r = libusb_control_transfer(handle, 
(uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
                        bRequest, (uint16_t)(((iface_number)<< 8)|0x00), 
os_fd[i].index, os_desc, os_fd[i].header_size, 1000);
                if (r < os_fd[i].header_size) {
-                       perr("   Failed: %s", (r<0)?libusb_error_name((enum 
libusb_error)r):"header size is too small");
+                       perr("   Failed: %s", (r<0)?libusb_strerror((enum 
libusb_error)r):"header size is too small");
                        return;
                }
                le_type_punning_IS_fine = (void*)os_desc;
@@ -728,7 +728,7 @@ static void 
read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin
                r = libusb_control_transfer(handle, 
(uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
                        bRequest, (uint16_t)(((iface_number)<< 8)|0x00), 
os_fd[i].index, os_desc, (uint16_t)length, 1000);
                if (r < 0) {
-                       perr("   Failed: %s", libusb_error_name((enum 
libusb_error)r));
+                       perr("   Failed: %s", libusb_strerror((enum 
libusb_error)r));
                        return;
                } else {
                        display_buffer_hex(os_desc, r);
@@ -977,6 +977,7 @@ int main(int argc, char** argv)
        size_t i, arglen;
        unsigned tmp_vid, tmp_pid;
        uint16_t endian_test = 0xBE00;
+       char* error_lang = NULL;
 
        // Default to generic, expecting VID:PID
        VID = 0;
@@ -1009,6 +1010,13 @@ int main(int argc, char** argv)
                                        binary_name = argv[++j];
                                        binary_dump = true;
                                        break;
+                               case 'l':
+                                       if ((j+1 >= argc) || (argv[j+1][0] == 
'-') || (argv[j+1][0] == '/')) {
+                                               printf("   Option -l requires 
an ISO 639-1 language parameter");
+                                               return 1;
+                                       }
+                                       error_lang = argv[++j];
+                                       break;
                                case 'j':
                                        // OLIMEX ARM-USB-TINY JTAG, 2 channel 
composite device - 2 interfaces
                                        if (!VID && !PID) {
@@ -1066,7 +1074,7 @@ int main(int argc, char** argv)
        }
 
        if ((show_help) || (argc == 1) || (argc > 7)) {
-               printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-j] [-x] [-s] 
[-p] [vid:pid]\n", argv[0]);
+               printf("usage: %s [-h] [-d] [-i] [-k] [-b file] [-l lang] [-j] 
[-x] [-s] [-p] [vid:pid]\n", argv[0]);
                printf("   -h      : display usage\n");
                printf("   -d      : enable debug output\n");
                printf("   -i      : print topology and speed info\n");
@@ -1076,6 +1084,7 @@ int main(int argc, char** argv)
                printf("   -p      : test Sony PS3 SixAxis controller\n");
                printf("   -s      : test Microsoft Sidewinder Precision Pro 
(HID)\n");
                printf("   -x      : test Microsoft XBox Controller Type S\n");
+               printf("   -l lang : language to report errors in (ISO 
639-1)\n");
                printf("If only the vid:pid is provided, xusb attempts to run 
the most appropriate test\n");
                return 0;
        }
@@ -1085,6 +1094,7 @@ int main(int argc, char** argv)
        r = libusb_init(NULL);
        if (r < 0)
                return r;
+       r = libusb_setlocale(error_lang);
 
        libusb_set_debug(NULL, 
debug_mode?LIBUSB_LOG_LEVEL_DEBUG:LIBUSB_LOG_LEVEL_INFO);
 
diff --git a/libusb/Makefile.am b/libusb/Makefile.am
index cd6db9c..7f9c1f9 100644
--- a/libusb/Makefile.am
+++ b/libusb/Makefile.am
@@ -59,9 +59,10 @@ endif
 
 libusb_1_0_la_CFLAGS = $(AM_CFLAGS)
 libusb_1_0_la_LDFLAGS = $(LTLDFLAGS)
-libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c sync.c $(OS_SRC) \
+libusb_1_0_la_SOURCES = libusbi.h core.c descriptor.c io.c strerror.c sync.c \
        os/linux_usbfs.h os/darwin_usb.h os/windows_usb.h os/windows_common.h \
-       hotplug.h hotplug.c $(THREADS_SRC) os/poll_posix.h os/poll_windows.h
+       hotplug.h hotplug.c $(THREADS_SRC) $(OS_SRC) \
+       os/poll_posix.h os/poll_windows.h
 
 hdrdir = $(includedir)/libusb-1.0
 hdr_HEADERS = libusb.h
diff --git a/libusb/libusb-1.0.def b/libusb/libusb-1.0.def
index 7166d47..e6c46fd 100644
--- a/libusb/libusb-1.0.def
+++ b/libusb/libusb-1.0.def
@@ -78,6 +78,8 @@ EXPORTS
   libusb_get_pollfds@4 = libusb_get_pollfds
   libusb_get_port_number
   libusb_get_port_number@4 = libusb_get_port_number
+  libusb_get_port_numbers
+  libusb_get_port_numbers@12 = libusb_get_port_numbers
   libusb_get_port_path
   libusb_get_port_path@16 = libusb_get_port_path
   libusb_get_ss_endpoint_companion_descriptor
@@ -136,6 +138,10 @@ EXPORTS
   libusb_set_interface_alt_setting@12 = libusb_set_interface_alt_setting
   libusb_set_pollfd_notifiers
   libusb_set_pollfd_notifiers@16 = libusb_set_pollfd_notifiers
+  libusb_setlocale
+  libusb_setlocale@4 = libusb_setlocale
+  libusb_strerror
+  libusb_strerror@4 = libusb_strerror
   libusb_submit_transfer
   libusb_submit_transfer@4 = libusb_submit_transfer
   libusb_try_lock_events
@@ -148,5 +154,3 @@ EXPORTS
   libusb_unref_device@4 = libusb_unref_device
   libusb_wait_for_event
   libusb_wait_for_event@8 = libusb_wait_for_event
-  libusb_get_port_numbers
-  libusb_get_port_numbers@12 = libusb_get_port_numbers
diff --git a/libusb/libusb.h b/libusb/libusb.h
index d733c46..a6849f4 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -1044,8 +1044,9 @@ enum libusb_bos_type {
 /** \ingroup misc
  * Error codes. Most libusbx functions return 0 on success or one of these
  * codes on failure.
- * You can call \ref libusb_error_name() to retrieve a string representation
- * of an error code.
+ * You can call libusb_error_name() to retrieve a string representation of an
+ * error code or libusb_strerror() to get an end-user suitable description of
+ * an error code.
  */
 enum libusb_error {
        /** Success (no error) */
@@ -1087,13 +1088,15 @@ enum libusb_error {
        /** Operation not supported or unimplemented on this platform */
        LIBUSB_ERROR_NOT_SUPPORTED = -12,
 
-       /* NB! Remember to update libusb_error_name()
-          when adding new error codes here. */
+       /* NB! Remember to update LIBUSB_ERROR_COUNT below as well as
+          the messages in strerror.c when adding new error codes here. */
 
        /** Other error */
        LIBUSB_ERROR_OTHER = -99,
 };
 
+#define LIBUSB_ERROR_COUNT 14
+
 /** \ingroup asyncio
  * Transfer status codes */
 enum libusb_transfer_status {
@@ -1299,6 +1302,8 @@ void LIBUSB_CALL libusb_set_debug(libusb_context *ctx, 
int level);
 const struct libusb_version * LIBUSB_CALL libusb_get_version(void);
 int LIBUSB_CALL libusb_has_capability(uint32_t capability);
 const char * LIBUSB_CALL libusb_error_name(int errcode);
+int LIBUSB_CALL libusb_setlocale(const char *locale);
+const char * LIBUSB_CALL libusb_strerror(enum libusb_error errcode);
 
 ssize_t LIBUSB_CALL libusb_get_device_list(libusb_context *ctx,
        libusb_device ***list);
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index eabf33d..d5e5c59 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -59,6 +59,10 @@
 /* The following is used to silence warnings for unused variables */
 #define UNUSED(var)                    do { (void)(var); } while(0)
 
+#if !defined(ARRAYSIZE)
+#define ARRAYSIZE(array) (sizeof(array)/sizeof(array[0]))
+#endif
+
 struct list_head {
        struct list_head *prev, *next;
 };
diff --git a/libusb/strerror.c b/libusb/strerror.c
new file mode 100644
index 0000000..bbea113
--- /dev/null
+++ b/libusb/strerror.c
@@ -0,0 +1,156 @@
+/*
+ * libusb strerror code
+ * Copyright © 2013 Hans de Goede <hdego...@redhat.com>
+ *
+ * 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.1 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include "config.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libusb.h"
+#include "libusbi.h"
+
+#if defined(_MSC_VER)
+#define strncasecmp _strnicmp
+#endif
+
+static int usbi_locale = 0;
+static const char* usbi_locale_supported[] = {"en", "nl", "fr"};
+static const char* 
usbi_localized_errors[ARRAYSIZE(usbi_locale_supported)][LIBUSB_ERROR_COUNT] = {
+       { /* English */
+               "Success",
+               "Input/Output Error",
+               "Invalid parameter",
+               "Access denied (insufficient permissions)",
+               "No such device (it may have been disconnected)",
+               "Entity not found",
+               "Resource busy",
+               "Operation timed out",
+               "Overflow",
+               "Pipe error",
+               "System call interrupted (perhaps due to signal)",
+               "Insufficient memory",
+               "Operation not supported or unimplemented on this platform",
+               "Other error",
+       }, { /* Dutch */
+               "Gelukt",
+               "Invoer-/uitvoerfout",
+               "Ongeldig argument",
+               "Toegang geweigerd (onvoldoende toegangsrechten)",
+               "Apparaat bestaat niet (verbinding met apparaat verbroken?)",
+               "Niet gevonden",
+               "Apparaat of hulpbron is bezig",
+               "Bewerking verlopen",
+               "Waarde is te groot",
+               "Gebroken pijp",
+               "Onderbroken systeemaanroep",
+               "Onvoldoende geheugen beschikbaar",
+               "Bewerking wordt niet ondersteund",
+               "Andere fout",
+       }, { /* French */
+               "Succès",
+               "Erreur d'entrée/sortie",
+               "Paramètre invalide",
+               "Accès refusé (permissions insuffisantes)",
+               "Périphérique introuvable (peut-être déconnecté)",
+               "Elément introuvable",
+               "Resource déjà occupée",
+               "Operation expirée",
+               "Débordement",
+               "Erreur de pipe",
+               "Appel système abandonné (peut-être à cause d’un signal)",
+               "Mémoire insuffisante",
+               "Opération non supportée or non implémentée sur cette 
plateforme",
+               "Autre erreur"
+       }
+};
+
+/** \ingroup misc
+ * Set the language, and only the language, not the encoding! used for
+ * translatable libusb messages.
+ *
+ * This takes a locale string in the default setlocale format:
+ * lang[_country_region][.codeset]. Only the lang part of the string is used,
+ * and only 2 letter ISO 639-1 codes are accepted, ie "en". The optional
+ * country_region and codeset parts are ignored. This means that functions
+ * which return translatable strings will NOT honor the specified encoding.
+ * If locale is "en", then all translatable strings will be pure ASCII. For
+ * all other languages they will be encoded as UTF-8 strings.
+ *
+ * If libusb_setlocale() is not called, all messages will be in English.
+ *
+ * The following functions return translatable strings: libusb_strerror().
+ * Note that the libusb log messages controlled through libusb_set_debug()
+ * are not translated, they are always in English.
+ *
+ * For POSIX UTF-8 environments if you want libusb to follow the standard
+ * locale settings, call libusb_setlocale(setlocale(LC_MESSAGES, NULL)),
+ * after your app has done its locale setup.
+ *
+ * \param locale locale-string in the form of lang[_country_region][.codeset]
+ * \returns LIBUSB_SUCCESS on success
+ * \returns LIBUSB_ERROR_NOT_FOUND if the requested language is not supported
+ * \returns a LIBUSB_ERROR code on other errors
+ */
+
+int API_EXPORTED libusb_setlocale(const char *locale)
+{
+       int i;
+
+       if (locale == NULL)
+               return LIBUSB_ERROR_INVALID_PARAM;
+
+       for (i=0; i<ARRAYSIZE(usbi_locale_supported); i++) {
+               if (strncasecmp(usbi_locale_supported[i], locale, 2) == 0)
+                       break;
+       }
+       if (i >= ARRAYSIZE(usbi_locale_supported)) {
+               usbi_warn(NULL, "Unrecognized locale format: %s", locale);
+               return LIBUSB_ERROR_NOT_FOUND;
+       }
+
+       usbi_locale = i;
+
+       return LIBUSB_SUCCESS;
+}
+
+/** \ingroup misc
+ * Returns a constant string with a short description of the given error code,
+ * this description is intended for displaying to the end user and will be in
+ * the language set by libusb_setlocale().
+ *
+ * The returned string is encoded in ASCII for English messages (the default
+ * if libusb_setlocale() is not called). For all other languages it is
+ * encoded in UTF-8.
+ *
+ * The messages always start with a capital letter and end without any dot.
+ * The caller must not free() the returned string.
+ *
+ * \param errcode the error code whose description is desired
+ * \returns a short description of the error code in UTF-8 encoding
+ */
+DEFAULT_VISIBILITY const char* LIBUSB_CALL libusb_strerror(enum libusb_error 
errcode)
+{
+       int errcode_index = -errcode;
+
+       if ((errcode_index < 0) || (errcode_index >= LIBUSB_ERROR_COUNT)) {
+               errcode_index = LIBUSB_ERROR_COUNT - 1;
+       }
+
+       return usbi_localized_errors[usbi_locale][errcode_index];
+}
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 2804c7d..47f4f0d 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 10728
+#define LIBUSB_NANO 10733
diff --git a/msvc/libusb_dll_2005.vcproj b/msvc/libusb_dll_2005.vcproj
index 9a8f6c3..82e5af5 100644
--- a/msvc/libusb_dll_2005.vcproj
+++ b/msvc/libusb_dll_2005.vcproj
@@ -362,6 +362,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
diff --git a/msvc/libusb_dll_2010.vcxproj b/msvc/libusb_dll_2010.vcxproj
index 7648e57..7b435b2 100644
--- a/msvc/libusb_dll_2010.vcxproj
+++ b/msvc/libusb_dll_2010.vcxproj
@@ -143,6 +143,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_dll_2010.vcxproj.filters 
b/msvc/libusb_dll_2010.vcxproj.filters
index 40281f1..cc7d1aa 100644
--- a/msvc/libusb_dll_2010.vcxproj.filters
+++ b/msvc/libusb_dll_2010.vcxproj.filters
@@ -29,6 +29,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_dll_2012.vcxproj b/msvc/libusb_dll_2012.vcxproj
index 5920895..adcad4a 100644
--- a/msvc/libusb_dll_2012.vcxproj
+++ b/msvc/libusb_dll_2012.vcxproj
@@ -147,6 +147,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_dll_2012.vcxproj.filters 
b/msvc/libusb_dll_2012.vcxproj.filters
index fff52f0..ccada70 100644
--- a/msvc/libusb_dll_2012.vcxproj.filters
+++ b/msvc/libusb_dll_2012.vcxproj.filters
@@ -26,6 +26,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_dll_wince.vcproj b/msvc/libusb_dll_wince.vcproj
index 4238a4d..822404c 100644
--- a/msvc/libusb_dll_wince.vcproj
+++ b/msvc/libusb_dll_wince.vcproj
@@ -1161,6 +1161,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
diff --git a/msvc/libusb_sources b/msvc/libusb_sources
index ca9bed8..308a666 100644
--- a/msvc/libusb_sources
+++ b/msvc/libusb_sources
@@ -29,6 +29,7 @@ TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib
 SOURCES=..\core.c \
        ..\descriptor.c \
        ..\io.c \
+       ..\strerror.c \
        ..\sync.c \
        ..\hotplug.c \
        threads_windows.c \
diff --git a/msvc/libusb_static_2005.vcproj b/msvc/libusb_static_2005.vcproj
index 68c9e2c..f7b8e45 100644
--- a/msvc/libusb_static_2005.vcproj
+++ b/msvc/libusb_static_2005.vcproj
@@ -298,6 +298,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
diff --git a/msvc/libusb_static_2010.vcxproj b/msvc/libusb_static_2010.vcxproj
index 37ee80c..1958d11 100644
--- a/msvc/libusb_static_2010.vcxproj
+++ b/msvc/libusb_static_2010.vcxproj
@@ -133,6 +133,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_static_2010.vcxproj.filters 
b/msvc/libusb_static_2010.vcxproj.filters
index 74a29cd..5cd8060 100644
--- a/msvc/libusb_static_2010.vcxproj.filters
+++ b/msvc/libusb_static_2010.vcxproj.filters
@@ -23,6 +23,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_static_2012.vcxproj b/msvc/libusb_static_2012.vcxproj
index 7baa2ae..88605ba 100644
--- a/msvc/libusb_static_2012.vcxproj
+++ b/msvc/libusb_static_2012.vcxproj
@@ -137,6 +137,7 @@
     <ClCompile Include="..\libusb\hotplug.c" />
     <ClCompile Include="..\libusb\io.c" />
     <ClCompile Include="..\libusb\os\poll_windows.c" />
+    <ClCompile Include="..\libusb\strerror.c" />
     <ClCompile Include="..\libusb\sync.c" />
     <ClCompile Include="..\libusb\os\threads_windows.c" />
     <ClCompile Include="..\libusb\os\windows_usb.c" />
diff --git a/msvc/libusb_static_2012.vcxproj.filters 
b/msvc/libusb_static_2012.vcxproj.filters
index 74a29cd..5cd8060 100644
--- a/msvc/libusb_static_2012.vcxproj.filters
+++ b/msvc/libusb_static_2012.vcxproj.filters
@@ -23,6 +23,9 @@
     <ClCompile Include="..\libusb\os\poll_windows.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="..\libusb\strerror.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\libusb\sync.c">
       <Filter>Source Files</Filter>
     </ClCompile>
diff --git a/msvc/libusb_static_wince.vcproj b/msvc/libusb_static_wince.vcproj
index 54fd48d..a595319 100644
--- a/msvc/libusb_static_wince.vcproj
+++ b/msvc/libusb_static_wince.vcproj
@@ -1103,6 +1103,10 @@
                                >
                        </File>
                        <File
+                               RelativePath="..\libusb\strerror.c"
+                               >
+                       </File>
+                       <File
                                RelativePath="..\libusb\sync.c"
                                >
                        </File>
-- 
1.8.0.msysgit.0

------------------------------------------------------------------------------
How ServiceNow helps IT people transform IT departments:
1. A cloud service to automate IT design, transition and operations
2. Dashboards that offer high-level views of enterprise services
3. A single system of record for all IT processes
http://p.sf.net/sfu/servicenow-d2d-j
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel

Reply via email to