Skip to content

Commit 7223ef7

Browse files
authored
Merge branch 'connection-callback' into copilot/optimize-hidapi-thread-wait
2 parents 07fa7e8 + 4398a7b commit 7223ef7

File tree

7 files changed

+84
-24
lines changed

7 files changed

+84
-24
lines changed

.github/workflows/checks.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ jobs:
7171

7272

7373
coverity-macos:
74-
runs-on: macos-13
74+
runs-on: macos-15-intel
7575
needs: [coverity-windows]
7676

7777
steps:

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,5 +31,8 @@ CMakeLists.txt.user
3131
# doxgen output
3232
doxygen/html/
3333

34+
# Visual Studio Code + CMake
35+
.vscode/
36+
3437
# Local build directory
3538
build/

netbsd/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,16 @@ find_package(Threads REQUIRED)
1010

1111
target_link_libraries(hidapi_netbsd PRIVATE Threads::Threads)
1212

13+
# check for error: "conflicting types for 'iconv'"
14+
include(CheckCSourceCompiles)
15+
check_c_source_compiles("#include<iconv.h>
16+
extern size_t iconv (iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
17+
int main() {}"
18+
HIDAPI_ICONV_CONST)
19+
if(HIDAPI_ICONV_CONST)
20+
target_compile_definitions(hidapi_netbsd PRIVATE "ICONV_CONST=const")
21+
endif()
22+
1323
set_target_properties(hidapi_netbsd
1424
PROPERTIES
1525
EXPORT_NAME "netbsd"

netbsd/hid.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@
3030
#include <unistd.h>
3131
#include <fcntl.h>
3232
#include <iconv.h>
33+
#ifndef ICONV_CONST
34+
#define ICONV_CONST
35+
#endif
36+
3337
#include <poll.h>
3438

3539
/* NetBSD */
@@ -724,6 +728,7 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
724728
for (size_t i = 0; i < len; i++) {
725729
char devpath[USB_MAX_DEVNAMELEN];
726730
int bus;
731+
struct hid_device_info *prev_end;
727732

728733
strlcpy(devpath, "/dev/", sizeof(devpath));
729734
strlcat(devpath, arr[i], sizeof(devpath));
@@ -732,7 +737,17 @@ struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned shor
732737
if (bus == -1)
733738
continue;
734739

740+
/*
741+
* ehci/ohci/uhci/dwctwo etc. use 'addr 1' for root hubs
742+
* but xhci uses 'addr 0' on NetBSD.
743+
* Check addr 0 (that would be unused on other than xhci)
744+
* and then check addr 1 if there is no device at addr 0.
745+
*/
746+
prev_end = hed.end;
735747
enumerate_usb_devices(bus, 0, hid_enumerate_callback, &hed);
748+
if (hed.end == prev_end)
749+
enumerate_usb_devices(bus, 1,
750+
hid_enumerate_callback, &hed);
736751

737752
close(bus);
738753
}
@@ -1109,7 +1124,7 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index
11091124
struct usb_string_desc usd;
11101125
usb_string_descriptor_t *str;
11111126
iconv_t ic;
1112-
const char *src;
1127+
ICONV_CONST char *src;
11131128
size_t srcleft;
11141129
char *dst;
11151130
size_t dstleft;
@@ -1153,7 +1168,7 @@ int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index
11531168
return -1;
11541169
}
11551170

1156-
src = (const char *) str->bString;
1171+
src = (ICONV_CONST char *)str->bString;
11571172
srcleft = str->bLength - 2;
11581173
dst = (char *) string;
11591174
dstleft = sizeof(wchar_t[maxlen]);

windows/hid.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,6 @@
2020
https://github.com/libusb/hidapi .
2121
********************************************************/
2222

23-
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
24-
/* Do not warn about wcsncpy usage.
25-
https://docs.microsoft.com/cpp/c-runtime-library/security-features-in-the-crt */
26-
#define _CRT_SECURE_NO_WARNINGS
27-
#endif
28-
2923
#ifdef __cplusplus
3024
extern "C" {
3125
#endif
@@ -67,6 +61,16 @@ typedef LONG NTSTATUS;
6761
#include <stdlib.h>
6862
#include <string.h>
6963

64+
/* MSVC secure CRT (VS2005+) provides swprintf_s/wcsncpy_s.
65+
Older MSVC and GCC/MinGW/Cygwin use the classic variants. */
66+
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
67+
#define HIDAPI_SWPRINTF swprintf_s
68+
#define HIDAPI_WCSNCPY(dest, dest_count, src) wcsncpy_s((dest), (dest_count), (src), _TRUNCATE)
69+
#else
70+
#define HIDAPI_SWPRINTF swprintf
71+
#define HIDAPI_WCSNCPY(dest, dest_count, src) wcsncpy((dest), (src), (dest_count))
72+
#endif
73+
7074
#ifdef MIN
7175
#undef MIN
7276
#endif
@@ -323,7 +327,8 @@ static void register_winapi_error_to_buffer(wchar_t **error_buffer, const WCHAR
323327
if (!msg)
324328
return;
325329

326-
int printf_written = swprintf(msg, msg_len + 1, L"%.*ls: (0x%08X) %.*ls", (int)op_len, op, error_code, (int)system_err_len, system_err_buf);
330+
int printf_written = HIDAPI_SWPRINTF(msg, msg_len + 1, L"%.*ls: (0x%08X) %.*ls", (int)op_len, op, error_code, (int)system_err_len, system_err_buf);
331+
msg[msg_len] = L'\0';
327332

328333
if (printf_written < 0)
329334
{
@@ -1825,7 +1830,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_manufacturer_string(hid_device *dev
18251830
return -1;
18261831
}
18271832

1828-
wcsncpy(string, dev->device_info->manufacturer_string, maxlen);
1833+
HIDAPI_WCSNCPY(string, maxlen, dev->device_info->manufacturer_string);
18291834
string[maxlen - 1] = L'\0';
18301835

18311836
register_string_error(dev, NULL);
@@ -1845,7 +1850,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_product_string(hid_device *dev, wch
18451850
return -1;
18461851
}
18471852

1848-
wcsncpy(string, dev->device_info->product_string, maxlen);
1853+
HIDAPI_WCSNCPY(string, maxlen, dev->device_info->product_string);
18491854
string[maxlen - 1] = L'\0';
18501855

18511856
register_string_error(dev, NULL);
@@ -1865,7 +1870,7 @@ int HID_API_EXPORT_CALL HID_API_CALL hid_get_serial_number_string(hid_device *de
18651870
return -1;
18661871
}
18671872

1868-
wcsncpy(string, dev->device_info->serial_number, maxlen);
1873+
HIDAPI_WCSNCPY(string, maxlen, dev->device_info->serial_number);
18691874
string[maxlen - 1] = L'\0';
18701875

18711876
register_string_error(dev, NULL);

windows/hidapi_descriptor_reconstruct.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@
1919
#ifndef HIDAPI_DESCRIPTOR_RECONSTRUCT_H__
2020
#define HIDAPI_DESCRIPTOR_RECONSTRUCT_H__
2121

22-
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
23-
/* Do not warn about wcsncpy usage.
24-
https://docs.microsoft.com/cpp/c-runtime-library/security-features-in-the-crt */
25-
#define _CRT_SECURE_NO_WARNINGS
26-
#endif
27-
2822
#include "hidapi_winapi.h"
2923

3024
#ifdef _MSC_VER

windows/test/hid_report_reconstructor_test.c

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,40 @@
99
#include <stdio.h>
1010
#include <string.h>
1111

12+
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
13+
#define HIDAPI_SSCANF sscanf_s
14+
#define HIDAPI_FSCANF fscanf_s
15+
#define HIDAPI_SCANSET_SIZE(buf) , (unsigned)_countof(buf)
16+
#else
17+
#define HIDAPI_SSCANF sscanf
18+
#define HIDAPI_FSCANF fscanf
19+
#define HIDAPI_SCANSET_SIZE(buf)
20+
#endif
21+
22+
#define sscanf HIDAPI_SSCANF
23+
24+
static const char* hidapi_strerror_compat(int errnum, char* buf, size_t buf_size)
25+
{
26+
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
27+
if (strerror_s(buf, buf_size, errnum) == 0) {
28+
return buf;
29+
}
30+
return "Unknown error";
31+
#else
32+
(void)buf;
33+
(void)buf_size;
34+
return strerror(errnum);
35+
#endif
36+
}
37+
1238
static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
1339
{
1440
FILE* file;
1541
errno_t err = fopen_s(&file, filename, "r");
1642

1743
if (err != 0) {
18-
fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, strerror(err));
44+
char err_buf[128];
45+
fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, hidapi_strerror_compat((int)err, err_buf, sizeof(err_buf)));
1946
return NULL;
2047
}
2148

@@ -49,8 +76,8 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
4976
if (sscanf(line, "dev->product_id = 0x%04hX\n", &product_id)) continue;
5077
if (sscanf(line, "dev->usage_page = 0x%04hX\n", &usage_page)) continue;
5178
if (sscanf(line, "dev->usage = 0x%04hX\n", &usage)) continue;
52-
if (sscanf(line, "dev->manufacturer_string = \"%127[^\"\n]", manufacturer_string)) continue;
53-
if (sscanf(line, "dev->product_string = \"%127[^\"\n]", product_string)) continue;
79+
if (sscanf(line, "dev->manufacturer_string = \"%127[^\"\n]", manufacturer_string HIDAPI_SCANSET_SIZE(manufacturer_string))) continue;
80+
if (sscanf(line, "dev->product_string = \"%127[^\"\n]", product_string HIDAPI_SCANSET_SIZE(product_string))) continue;
5481
if (sscanf(line, "dev->release_number = 0x%04hX\n", &release_number)) continue;
5582
if (sscanf(line, "dev->interface_number = %d\n", &interface_number)) continue;
5683
// if (sscanf(line, "dev->path = \"%127[^\"]\n", path)) continue;
@@ -96,6 +123,11 @@ static hidp_preparsed_data * alloc_preparsed_data_from_file(char* filename)
96123

97124
if (FirstByteOfLinkCollectionArray != 0 && NumberLinkCollectionNodes != 0) {
98125
size_t size_of_preparsed_data = offsetof(hidp_preparsed_data, caps) + FirstByteOfLinkCollectionArray + (NumberLinkCollectionNodes * sizeof(hid_pp_link_collection_node));
126+
if (size_of_preparsed_data > 1024 * 1024) {
127+
fprintf(stderr, "Error: preparsed data size too large: %zu\n", size_of_preparsed_data);
128+
fclose(file);
129+
return NULL;
130+
}
99131
pp_data->FirstByteOfLinkCollectionArray = FirstByteOfLinkCollectionArray;
100132
pp_data->NumberLinkCollectionNodes = NumberLinkCollectionNodes;
101133
FirstByteOfLinkCollectionArray = 0;
@@ -456,14 +488,15 @@ static BOOLEAN read_hex_data_from_text_file(const char *filename, unsigned char
456488
FILE* file = NULL;
457489
errno_t err = fopen_s(&file, filename, "r");
458490
if (err != 0) {
459-
fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, strerror(err));
491+
char err_buf[128];
492+
fprintf(stderr, "ERROR: Couldn't open file '%s' for reading: %s\n", filename, hidapi_strerror_compat((int)err, err_buf, sizeof(err_buf)));
460493
return FALSE;
461494
}
462495

463496
BOOLEAN result = TRUE;
464497
unsigned int val;
465498
char buf[16];
466-
while (fscanf(file, "%15s", buf) == 1) {
499+
while (HIDAPI_FSCANF(file, "%15s", buf HIDAPI_SCANSET_SIZE(buf)) == 1) {
467500
if (sscanf(buf, "0x%X", &val) != 1) {
468501
fprintf(stderr, "Invalid HEX text ('%s') file, got %s\n", filename, buf);
469502
result = FALSE;

0 commit comments

Comments
 (0)