Windows: Fix GCC printf format warnings due to DWORD/ULONG types
authorChris Dickens <christopher.a.dickens@gmail.com>
Sun, 26 Jan 2020 22:31:35 +0000 (14:31 -0800)
committerChris Dickens <christopher.a.dickens@gmail.com>
Sun, 26 Jan 2020 22:31:35 +0000 (14:31 -0800)
The Visual Studio compiler considers a long to always be 32-bits, so the
official Windows API headers define the DWORD and ULONG types as
unsigned long proper. GCC (and possibly other compilers) vary the width
of a long to match the build target, so this complicates printf format
strings for these two types because the underlying type is inconsistent.

Address this mess by introducing a macro that casts as necessary for the
compiler.

Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
libusb/os/poll_windows.c
libusb/os/windows_common.c
libusb/os/windows_common.h
libusb/os/windows_winusb.c
libusb/version_nano.h

index afcc233..830c7e5 100644 (file)
@@ -36,6 +36,7 @@
  */
 
 #include "libusbi.h"
+#include "windows_common.h"
 
 #include <errno.h>
 #include <intrin.h>
@@ -133,14 +134,14 @@ static int install_fd(struct file_descriptor *fd)
 
        for (n = 0; n < fd_table_size; n += BITMAP_BITS_PER_WORD) {
                unsigned int idx = n / BITMAP_BITS_PER_WORD;
-               unsigned long mask, pos = 0UL;
+               ULONG mask, pos = 0U;
 
                mask = ~fd_table_bitmap[idx];
-               if (mask == 0UL)
+               if (mask == 0U)
                        continue;
 
                assert(_BitScanForward(&pos, mask));
-               fd_table_bitmap[idx] |= 1UL << pos;
+               fd_table_bitmap[idx] |= 1U << pos;
                n += pos;
                break;
        }
@@ -157,7 +158,7 @@ static void remove_fd(unsigned int pos)
 {
        assert(fd_table[pos] != NULL);
        fd_table[pos] = NULL;
-       fd_table_bitmap[pos / BITMAP_BITS_PER_WORD] &= ~(1UL << (pos % BITMAP_BITS_PER_WORD));
+       fd_table_bitmap[pos / BITMAP_BITS_PER_WORD] &= ~(1U << (pos % BITMAP_BITS_PER_WORD));
        fd_count--;
        if (fd_count == 0) {
                free(fd_table);
@@ -307,11 +308,11 @@ static DWORD poll_wait(const HANDLE *wait_handles, DWORD num_wait_handles, DWORD
        for (n = 0; n < num_threads; n++) {
                if (thread_data[n].thread != NULL) {
                        if (WaitForSingleObject(thread_data[n].thread, INFINITE) != WAIT_OBJECT_0)
-                               usbi_err(NULL, "WaitForSingleObject() failed: %lu", GetLastError());
+                               usbi_err(NULL, "WaitForSingleObject() failed: %lu", ULONG_CAST(GetLastError()));
                        CloseHandle(thread_data[n].thread);
                }
                if (thread_data[n].error) {
-                       usbi_err(NULL, "wait thread %d had error %lu\n", n, thread_data[n].error);
+                       usbi_err(NULL, "wait thread %d had error %lu\n", n, ULONG_CAST(thread_data[n].error));
                        error = thread_data[n].error;
                        status = WAIT_FAILED;
                }
@@ -407,7 +408,7 @@ int usbi_poll(struct pollfd *fds, usbi_nfds_t nfds, int timeout)
                        assert(timeout > 0);
                        timeout = 0;
                } else if (ret == WAIT_FAILED) {
-                       usbi_err(NULL, "WaitForMultipleObjects failed: %lu", GetLastError());
+                       usbi_err(NULL, "WaitForMultipleObjects failed: %lu", ULONG_CAST(GetLastError()));
                        errno = EIO;
                        nready = -1;
                }
index df05eaf..a2c9beb 100644 (file)
@@ -59,7 +59,7 @@ const char *windows_error_str(DWORD error_code)
        if (error_code == 0)
                error_code = GetLastError();
 
-       len = sprintf(err_string, "[%lu] ", error_code);
+       len = sprintf(err_string, "[%lu] ", ULONG_CAST(error_code));
 
        // Translate codes returned by SetupAPI. The ones we are dealing with are either
        // in 0x0000xxxx or 0xE000xxxx and can be distinguished from standard error codes.
@@ -83,9 +83,10 @@ const char *windows_error_str(DWORD error_code)
                if (format_error)
                        snprintf(err_string, sizeof(err_string),
                                "Windows error code %lu (FormatMessage error code %lu)",
-                               error_code, format_error);
+                               ULONG_CAST(error_code), ULONG_CAST(format_error));
                else
-                       snprintf(err_string, sizeof(err_string), "Unknown error code %lu", error_code);
+                       snprintf(err_string, sizeof(err_string), "Unknown error code %lu",
+                               ULONG_CAST(error_code));
        } else {
                // Remove CRLF from end of message, if present
                size_t pos = len + size - 2;
@@ -381,7 +382,8 @@ static void windows_transfer_callback(const struct windows_backend *backend,
 {
        int status, istatus;
 
-       usbi_dbg("handling I/O completion with errcode %lu, size %lu", io_result, io_size);
+       usbi_dbg("handling I/O completion with errcode %lu, size %lu",
+               ULONG_CAST(io_result), ULONG_CAST(io_size));
 
        switch (io_result) {
        case NO_ERROR:
@@ -409,7 +411,8 @@ static void windows_transfer_callback(const struct windows_backend *backend,
                status = LIBUSB_TRANSFER_NO_DEVICE;
                break;
        default:
-               usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %lu: %s", io_result, windows_error_str(io_result));
+               usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %lu: %s",
+                       ULONG_CAST(io_result), windows_error_str(io_result));
                status = LIBUSB_TRANSFER_ERROR;
                break;
        }
index 069b147..93ea23e 100644 (file)
 
 #include <stdbool.h>
 
+/*
+ * Workaround for the mess that exists with the DWORD and ULONG types.
+ * Visual Studio unconditionally defines these types as 'unsigned long'
+ * and a long is always 32-bits, even on 64-bit builds. GCC on the other
+ * hand varies the width of a long, matching it to the build. To make
+ * matters worse, the platform headers for these GCC builds define a
+ * DWORD/ULONG to be 'unsigned long' on 32-bit builds and 'unsigned int'
+ * on 64-bit builds. This creates a great deal of warnings for compilers
+ * that support printf format checking since it will never actually be
+ * an unsigned long.
+ */
+#if defined(_MSC_VER)
+#define ULONG_CAST(x)  (x)
+#else
+#define ULONG_CAST(x)  ((unsigned long)(x))
+#endif
+
 #if defined(__CYGWIN__ )
 #define _stricmp strcasecmp
 #define _strdup strdup
index efc3f99..136abb2 100644 (file)
@@ -283,7 +283,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
                if (!pSetupDiEnumDeviceInfo(dev_info, *_index, dev_info_data)) {
                        if (GetLastError() != ERROR_NO_MORE_ITEMS) {
                                usbi_err(ctx, "Could not obtain device info data for %s index %lu: %s",
-                                       guid_to_string(guid), *_index, windows_error_str(0));
+                                       guid_to_string(guid), ULONG_CAST(*_index), windows_error_str(0));
                                return LIBUSB_ERROR_OTHER;
                        }
 
@@ -299,7 +299,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
 
                if (GetLastError() != ERROR_NO_MORE_ITEMS) {
                        usbi_err(ctx, "Could not obtain interface data for %s devInst %lX: %s",
-                               guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0));
+                               guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
                        return LIBUSB_ERROR_OTHER;
                }
 
@@ -311,7 +311,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
                // The dummy call should fail with ERROR_INSUFFICIENT_BUFFER
                if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
                        usbi_err(ctx, "could not access interface data (dummy) for %s devInst %lX: %s",
-                               guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0));
+                               guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
                        return LIBUSB_ERROR_OTHER;
                }
        } else {
@@ -322,7 +322,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
        dev_interface_details = malloc(size);
        if (dev_interface_details == NULL) {
                usbi_err(ctx, "could not allocate interface data for %s devInst %lX",
-                       guid_to_string(guid), dev_info_data->DevInst);
+                       guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst));
                return LIBUSB_ERROR_NO_MEM;
        }
 
@@ -330,7 +330,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
        if (!pSetupDiGetDeviceInterfaceDetailA(dev_info, &dev_interface_data,
                dev_interface_details, size, NULL, NULL)) {
                usbi_err(ctx, "could not access interface data (actual) for %s devInst %lX: %s",
-                       guid_to_string(guid), dev_info_data->DevInst, windows_error_str(0));
+                       guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst), windows_error_str(0));
                free(dev_interface_details);
                return LIBUSB_ERROR_OTHER;
        }
@@ -340,7 +340,7 @@ static int get_interface_details(struct libusb_context *ctx, HDEVINFO dev_info,
 
        if (*dev_interface_path == NULL) {
                usbi_err(ctx, "could not allocate interface path for %s devInst %lX",
-                       guid_to_string(guid), dev_info_data->DevInst);
+                       guid_to_string(guid), ULONG_CAST(dev_info_data->DevInst));
                return LIBUSB_ERROR_NO_MEM;
        }
 
@@ -1256,7 +1256,7 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
                        // Read the Device ID path
                        if (!pSetupDiGetDeviceInstanceIdA(*dev_info, &dev_info_data, dev_id, sizeof(dev_id), NULL)) {
                                usbi_warn(ctx, "could not read the device instance ID for devInst %lX, skipping",
-                                         dev_info_data.DevInst);
+                                         ULONG_CAST(dev_info_data.DevInst));
                                continue;
                        }
 
@@ -1365,8 +1365,8 @@ static int winusb_get_device_list(struct libusb_context *ctx, struct discovered_
                                        usbi_warn(ctx, "could not detect installation state of driver for '%s': %s",
                                                dev_id, windows_error_str(0));
                                } else if (install_state != 0) {
-                                       usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %u) - skipping",
-                                               dev_id, (unsigned int)install_state);
+                                       usbi_warn(ctx, "driver for device '%s' is reporting an issue (code: %lu) - skipping",
+                                               dev_id, ULONG_CAST(install_state));
                                        continue;
                                }
                                get_api_type(dev_info, &dev_info_data, &api, &sub_api);
@@ -2566,7 +2566,7 @@ static enum libusb_transfer_status usbd_status_to_libusb_transfer_status(USBD_ST
        case USBD_STATUS_DEVICE_GONE:
                return LIBUSB_TRANSFER_NO_DEVICE;
        default:
-               usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", status);
+               usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
                return LIBUSB_TRANSFER_ERROR;
        }
 }
@@ -3648,7 +3648,7 @@ static int hid_open(int sub_api, struct libusb_device_handle *dev_handle)
                size[1] = capabilities.NumberOutputValueCaps;
                size[2] = capabilities.NumberFeatureValueCaps;
                for (j = HidP_Input; j <= HidP_Feature; j++) {
-                       usbi_dbg("%lu HID %s report value(s) found", size[j], type[j]);
+                       usbi_dbg("%lu HID %s report value(s) found", ULONG_CAST(size[j]), type[j]);
                        priv->hid->uses_report_ids[j] = false;
                        if (size[j] > 0) {
                                value_caps = calloc(size[j], sizeof(HIDP_VALUE_CAPS));
index eb561c0..f335fad 100644 (file)
@@ -1 +1 @@
-#define LIBUSB_NANO 11449
+#define LIBUSB_NANO 11450