From 80d2238cb80469aee03d0367080350496d8548eb Mon Sep 17 00:00:00 2001 From: Chris Dickens Date: Sun, 26 Jan 2020 14:31:35 -0800 Subject: Windows: Fix GCC printf format warnings due to DWORD/ULONG types 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 --- libusb/os/poll_windows.c | 15 ++++++++------- libusb/os/windows_common.c | 13 ++++++++----- libusb/os/windows_common.h | 17 +++++++++++++++++ libusb/os/windows_winusb.c | 22 +++++++++++----------- libusb/version_nano.h | 2 +- 5 files changed, 45 insertions(+), 24 deletions(-) diff --git a/libusb/os/poll_windows.c b/libusb/os/poll_windows.c index afcc233..830c7e5 100644 --- a/libusb/os/poll_windows.c +++ b/libusb/os/poll_windows.c @@ -36,6 +36,7 @@ */ #include "libusbi.h" +#include "windows_common.h" #include #include @@ -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; } diff --git a/libusb/os/windows_common.c b/libusb/os/windows_common.c index df05eaf..a2c9beb 100644 --- a/libusb/os/windows_common.c +++ b/libusb/os/windows_common.c @@ -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; } diff --git a/libusb/os/windows_common.h b/libusb/os/windows_common.h index 069b147..93ea23e 100644 --- a/libusb/os/windows_common.h +++ b/libusb/os/windows_common.h @@ -30,6 +30,23 @@ #include +/* + * 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 diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c index efc3f99..136abb2 100644 --- a/libusb/os/windows_winusb.c +++ b/libusb/os/windows_winusb.c @@ -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)); diff --git a/libusb/version_nano.h b/libusb/version_nano.h index eb561c0..f335fad 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11449 +#define LIBUSB_NANO 11450 -- cgit v1.2.1