libusb 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Gemfile +1 -0
  5. data/History.md +10 -0
  6. data/README.md +19 -6
  7. data/Rakefile +1 -1
  8. data/ext/extconf.rb +17 -1
  9. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
  10. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
  11. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
  12. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
  13. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
  14. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
  15. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
  16. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
  17. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
  18. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
  19. data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
  20. data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
  21. data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
  22. data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
  23. data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
  24. data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
  25. data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
  26. data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
  27. data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
  28. data/ext/libusbx-1.0.17/android/README +114 -0
  29. data/ext/libusbx-1.0.17/android/config.h +90 -0
  30. data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
  31. data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
  32. data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
  33. data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
  34. data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
  35. data/ext/libusbx-1.0.17/compile +347 -0
  36. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
  37. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
  38. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
  39. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
  40. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
  41. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
  42. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
  43. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
  44. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
  45. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
  46. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
  47. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
  48. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
  49. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
  50. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
  51. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
  52. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
  53. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
  54. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
  55. data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
  56. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
  57. data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
  58. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
  59. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
  60. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
  61. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
  62. data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
  63. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
  64. data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
  65. data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
  66. data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
  67. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
  68. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
  69. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
  70. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
  71. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
  72. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
  73. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
  74. data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
  75. data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
  76. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
  77. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
  78. data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
  79. data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
  80. data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
  81. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
  82. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
  83. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
  84. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
  85. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
  86. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
  87. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
  88. data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
  89. data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
  90. data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
  91. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
  92. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
  93. data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
  94. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
  95. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
  96. data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
  97. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
  98. data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
  99. data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
  100. data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
  101. data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
  102. data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
  103. data/ext/libusbx-1.0.17/missing +215 -0
  104. data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
  105. data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
  106. data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
  107. data/ext/libusbx-1.0.17/tests/stress.c +160 -0
  108. data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
  109. data/lib/libusb.rb +4 -0
  110. data/lib/libusb/call.rb +43 -1
  111. data/lib/libusb/constants.rb +5 -0
  112. data/lib/libusb/context.rb +100 -0
  113. data/lib/libusb/dev_handle.rb +27 -0
  114. data/lib/libusb/device.rb +10 -4
  115. data/lib/libusb/version_gem.rb +1 -1
  116. data/test/test_libusb_capability.rb +2 -2
  117. data/test/test_libusb_compat.rb +2 -2
  118. data/test/test_libusb_compat_mass_storage.rb +2 -2
  119. data/test/test_libusb_descriptors.rb +4 -2
  120. data/test/test_libusb_event_machine.rb +2 -2
  121. data/test/test_libusb_gc.rb +2 -2
  122. data/test/test_libusb_hotplug.rb +115 -0
  123. data/test/test_libusb_iso_transfer.rb +3 -3
  124. data/test/test_libusb_mass_storage.rb +6 -16
  125. data/test/test_libusb_mass_storage2.rb +26 -3
  126. data/test/test_libusb_structs.rb +2 -2
  127. data/test/test_libusb_threads.rb +2 -2
  128. data/test/test_libusb_version.rb +2 -2
  129. metadata +127 -68
  130. metadata.gz.sig +0 -0
  131. data/ext/libusbx-1.0.14/THANKS +0 -7
  132. data/ext/libusbx-1.0.14/compile +0 -143
  133. data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
  134. data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
  135. data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
  136. data/ext/libusbx-1.0.14/missing +0 -376
@@ -0,0 +1,51 @@
1
+ /*
2
+ * poll_posix: poll compatibility wrapper for POSIX systems
3
+ * Copyright © 2013 RealVNC Ltd.
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with this library; if not, write to the Free Software
17
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ *
19
+ */
20
+
21
+ #include <unistd.h>
22
+ #include <fcntl.h>
23
+ #include <errno.h>
24
+ #include <stdlib.h>
25
+
26
+ #include "libusbi.h"
27
+
28
+ int usbi_pipe(int pipefd[2])
29
+ {
30
+ int ret = pipe(pipefd);
31
+ if (ret != 0) {
32
+ return ret;
33
+ }
34
+ ret = fcntl(pipefd[1], F_GETFL);
35
+ if (ret == -1) {
36
+ usbi_dbg("Failed to get pipe fd flags: %d", errno);
37
+ goto err_close_pipe;
38
+ }
39
+ ret = fcntl(pipefd[1], F_SETFL, ret | O_NONBLOCK);
40
+ if (ret != 0) {
41
+ usbi_dbg("Failed to set non-blocking on new pipe: %d", errno);
42
+ goto err_close_pipe;
43
+ }
44
+
45
+ return 0;
46
+
47
+ err_close_pipe:
48
+ usbi_close(pipefd[0]);
49
+ usbi_close(pipefd[1]);
50
+ return ret;
51
+ }
@@ -4,7 +4,8 @@
4
4
  #define usbi_write write
5
5
  #define usbi_read read
6
6
  #define usbi_close close
7
- #define usbi_pipe pipe
8
7
  #define usbi_poll poll
9
8
 
9
+ int usbi_pipe(int pipefd[2]);
10
+
10
11
  #endif /* LIBUSB_POLL_POSIX_H */
@@ -1,6 +1,7 @@
1
1
  /*
2
2
  * poll_windows: poll compatibility wrapper for Windows
3
- * Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
3
+ * Copyright © 2012-2013 RealVNC Ltd.
4
+ * Copyright © 2009-2010 Pete Batard <pete@akeo.ie>
4
5
  * With contributions from Michael Plante, Orin Eman et al.
5
6
  * Parts of poll implementation from libusb-win32, by Stephan Meyer et al.
6
7
  *
@@ -31,7 +32,7 @@
31
32
  * OVERLAPPED mode
32
33
  * - call usbi_create_fd with this handle to obtain a custom fd.
33
34
  * Note that if you need simultaneous R/W access, you need to call create_fd
34
- * twice, once in _O_RDONLY and once in _O_WRONLY mode to obtain 2 separate
35
+ * twice, once in RW_READ and once in RW_WRITE mode to obtain 2 separate
35
36
  * pollable fds
36
37
  * - leave the core functions call the poll routine and flag POLLIN/POLLOUT
37
38
  *
@@ -40,12 +41,10 @@
40
41
  * context.
41
42
  */
42
43
  #include <errno.h>
43
- #include <fcntl.h>
44
44
  #include <stdio.h>
45
45
  #include <stdlib.h>
46
- #include <io.h>
47
46
 
48
- #include <libusbi.h>
47
+ #include "libusbi.h"
49
48
 
50
49
  // Uncomment to debug the polling layer
51
50
  //#define DEBUG_POLL_WINDOWS
@@ -54,7 +53,7 @@
54
53
  #else
55
54
  // MSVC++ < 2005 cannot use a variadic argument and non MSVC
56
55
  // compilers produce warnings if parenthesis are ommitted.
57
- #if defined(_MSC_VER) && _MSC_VER < 1400
56
+ #if defined(_MSC_VER) && (_MSC_VER < 1400)
58
57
  #define poll_dbg
59
58
  #else
60
59
  #define poll_dbg(...)
@@ -65,20 +64,10 @@
65
64
  #pragma warning(disable:28719)
66
65
  #endif
67
66
 
68
- #if defined(__CYGWIN__)
69
- // cygwin produces a warning unless these prototypes are defined
70
- extern int _open(char* name, int flags);
71
- extern int _close(int fd);
72
- extern int _snprintf(char *buffer, size_t count, const char *format, ...);
73
- #define NUL_DEVICE "/dev/null"
74
- #else
75
- #define NUL_DEVICE "NUL"
76
- #endif
77
-
78
67
  #define CHECK_INIT_POLLING do {if(!is_polling_set) init_polling();} while(0)
79
68
 
80
69
  // public fd data
81
- const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, RW_NONE};
70
+ const struct winfd INVALID_WINFD = {-1, INVALID_HANDLE_VALUE, NULL, NULL, NULL, RW_NONE};
82
71
  struct winfd poll_fd[MAX_FDS];
83
72
  // internal fd data
84
73
  struct {
@@ -93,12 +82,25 @@ BOOLEAN is_polling_set = FALSE;
93
82
  LONG pipe_number = 0;
94
83
  static volatile LONG compat_spinlock = 0;
95
84
 
85
+ #if !defined(_WIN32_WCE)
96
86
  // CancelIoEx, available on Vista and later only, provides the ability to cancel
97
87
  // a single transfer (OVERLAPPED) when used. As it may not be part of any of the
98
88
  // platform headers, we hook into the Kernel32 system DLL directly to seek it.
99
89
  static BOOL (__stdcall *pCancelIoEx)(HANDLE, LPOVERLAPPED) = NULL;
100
- #define CancelIoEx_Available (pCancelIoEx != NULL)
101
- static __inline BOOL cancel_io(int _index)
90
+ #define Use_Duplicate_Handles (pCancelIoEx == NULL)
91
+
92
+ static inline void setup_cancel_io(void)
93
+ {
94
+ HMODULE hKernel32 = GetModuleHandleA("KERNEL32");
95
+ if (hKernel32 != NULL) {
96
+ pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
97
+ GetProcAddress(hKernel32, "CancelIoEx");
98
+ }
99
+ usbi_dbg("Will use CancelIo%s for I/O cancellation",
100
+ Use_Duplicate_Handles?"":"Ex");
101
+ }
102
+
103
+ static inline BOOL cancel_io(int _index)
102
104
  {
103
105
  if ((_index < 0) || (_index >= MAX_FDS)) {
104
106
  return FALSE;
@@ -108,7 +110,12 @@ static __inline BOOL cancel_io(int _index)
108
110
  || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
109
111
  return TRUE;
110
112
  }
111
- if (CancelIoEx_Available) {
113
+ if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
114
+ // Cancel outstanding transfer via the specific callback
115
+ (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
116
+ return TRUE;
117
+ }
118
+ if (pCancelIoEx != NULL) {
112
119
  return (*pCancelIoEx)(poll_fd[_index].handle, poll_fd[_index].overlapped);
113
120
  }
114
121
  if (_poll_fd[_index].thread_id == GetCurrentThreadId()) {
@@ -117,6 +124,30 @@ static __inline BOOL cancel_io(int _index)
117
124
  usbi_warn(NULL, "Unable to cancel I/O that was started from another thread");
118
125
  return FALSE;
119
126
  }
127
+ #else
128
+ #define Use_Duplicate_Handles FALSE
129
+
130
+ static __inline void setup_cancel_io()
131
+ {
132
+ // No setup needed on WinCE
133
+ }
134
+
135
+ static __inline BOOL cancel_io(int _index)
136
+ {
137
+ if ((_index < 0) || (_index >= MAX_FDS)) {
138
+ return FALSE;
139
+ }
140
+ if ( (poll_fd[_index].fd < 0) || (poll_fd[_index].handle == INVALID_HANDLE_VALUE)
141
+ || (poll_fd[_index].handle == 0) || (poll_fd[_index].overlapped == NULL) ) {
142
+ return TRUE;
143
+ }
144
+ if (poll_fd[_index].itransfer && poll_fd[_index].cancel_fn) {
145
+ // Cancel outstanding transfer via the specific callback
146
+ (*poll_fd[_index].cancel_fn)(poll_fd[_index].itransfer);
147
+ }
148
+ return TRUE;
149
+ }
150
+ #endif
120
151
 
121
152
  // Init
122
153
  void init_polling(void)
@@ -127,10 +158,7 @@ void init_polling(void)
127
158
  SleepEx(0, TRUE);
128
159
  }
129
160
  if (!is_polling_set) {
130
- pCancelIoEx = (BOOL (__stdcall *)(HANDLE,LPOVERLAPPED))
131
- GetProcAddress(GetModuleHandleA("KERNEL32"), "CancelIoEx");
132
- usbi_dbg("Will use CancelIo%s for I/O cancellation",
133
- CancelIoEx_Available?"Ex":"");
161
+ setup_cancel_io();
134
162
  for (i=0; i<MAX_FDS; i++) {
135
163
  poll_fd[i] = INVALID_WINFD;
136
164
  _poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
@@ -143,11 +171,11 @@ void init_polling(void)
143
171
  }
144
172
 
145
173
  // Internal function to retrieve the table index (and lock the fd mutex)
146
- int _fd_to_index_and_lock(int fd)
174
+ static int _fd_to_index_and_lock(int fd)
147
175
  {
148
176
  int i;
149
177
 
150
- if (fd <= 0)
178
+ if (fd < 0)
151
179
  return -1;
152
180
 
153
181
  for (i=0; i<MAX_FDS; i++) {
@@ -164,7 +192,7 @@ int _fd_to_index_and_lock(int fd)
164
192
  return -1;
165
193
  }
166
194
 
167
- OVERLAPPED *create_overlapped(void)
195
+ static OVERLAPPED *create_overlapped(void)
168
196
  {
169
197
  OVERLAPPED *overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
170
198
  if (overlapped == NULL) {
@@ -178,7 +206,7 @@ OVERLAPPED *create_overlapped(void)
178
206
  return overlapped;
179
207
  }
180
208
 
181
- void free_overlapped(OVERLAPPED *overlapped)
209
+ static void free_overlapped(OVERLAPPED *overlapped)
182
210
  {
183
211
  if (overlapped == NULL)
184
212
  return;
@@ -190,20 +218,6 @@ void free_overlapped(OVERLAPPED *overlapped)
190
218
  free(overlapped);
191
219
  }
192
220
 
193
- void reset_overlapped(OVERLAPPED *overlapped)
194
- {
195
- HANDLE event_handle;
196
- if (overlapped == NULL)
197
- return;
198
-
199
- event_handle = overlapped->hEvent;
200
- if (event_handle != NULL) {
201
- ResetEvent(event_handle);
202
- }
203
- memset(overlapped, 0, sizeof(OVERLAPPED));
204
- overlapped->hEvent = event_handle;
205
- }
206
-
207
221
  void exit_polling(void)
208
222
  {
209
223
  int i;
@@ -221,12 +235,8 @@ void exit_polling(void)
221
235
  // terminating, and we should be able to access the fd
222
236
  // mutex lock before too long
223
237
  EnterCriticalSection(&_poll_fd[i].mutex);
224
- if ( (poll_fd[i].fd > 0) && (poll_fd[i].handle != INVALID_HANDLE_VALUE) && (poll_fd[i].handle != 0)
225
- && (GetFileType(poll_fd[i].handle) == FILE_TYPE_UNKNOWN) ) {
226
- _close(poll_fd[i].fd);
227
- }
228
238
  free_overlapped(poll_fd[i].overlapped);
229
- if (!CancelIoEx_Available) {
239
+ if (Use_Duplicate_Handles) {
230
240
  // Close duplicate handle
231
241
  if (_poll_fd[i].original_handle != INVALID_HANDLE_VALUE) {
232
242
  CloseHandle(poll_fd[i].handle);
@@ -253,7 +263,8 @@ int usbi_pipe(int filedes[2])
253
263
 
254
264
  CHECK_INIT_POLLING;
255
265
 
256
- overlapped = (OVERLAPPED*) calloc(1, sizeof(OVERLAPPED));
266
+ overlapped = create_overlapped();
267
+
257
268
  if (overlapped == NULL) {
258
269
  return -1;
259
270
  }
@@ -261,22 +272,6 @@ int usbi_pipe(int filedes[2])
261
272
  overlapped->Internal = STATUS_PENDING;
262
273
  overlapped->InternalHigh = 0;
263
274
 
264
- // Read end of the "pipe"
265
- filedes[0] = _open(NUL_DEVICE, _O_WRONLY);
266
- if (filedes[0] < 0) {
267
- usbi_err(NULL, "could not create pipe: errno %d", errno);
268
- goto out1;
269
- }
270
- // We can use the same handle for both ends
271
- filedes[1] = filedes[0];
272
- poll_dbg("pipe filedes = %d", filedes[0]);
273
-
274
- // Note: manual reset must be true (second param) as the reset occurs in read
275
- overlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
276
- if(!overlapped->hEvent) {
277
- goto out2;
278
- }
279
-
280
275
  for (i=0; i<MAX_FDS; i++) {
281
276
  if (poll_fd[i].fd < 0) {
282
277
  EnterCriticalSection(&_poll_fd[i].mutex);
@@ -286,7 +281,13 @@ int usbi_pipe(int filedes[2])
286
281
  continue;
287
282
  }
288
283
 
289
- poll_fd[i].fd = filedes[0];
284
+ // Use index as the unique fd number
285
+ poll_fd[i].fd = i;
286
+ // Read end of the "pipe"
287
+ filedes[0] = poll_fd[i].fd;
288
+ // We can use the same handle for both ends
289
+ filedes[1] = filedes[0];
290
+
290
291
  poll_fd[i].handle = DUMMY_HANDLE;
291
292
  poll_fd[i].overlapped = overlapped;
292
293
  // There's no polling on the write end, so we just use READ for our needs
@@ -296,12 +297,7 @@ int usbi_pipe(int filedes[2])
296
297
  return 0;
297
298
  }
298
299
  }
299
-
300
- CloseHandle(overlapped->hEvent);
301
- out2:
302
- _close(filedes[0]);
303
- out1:
304
- free(overlapped);
300
+ free_overlapped(overlapped);
305
301
  return -1;
306
302
  }
307
303
 
@@ -319,9 +315,9 @@ out1:
319
315
  * read and one for write. Using a single R/W fd is unsupported and will
320
316
  * produce unexpected results
321
317
  */
322
- struct winfd usbi_create_fd(HANDLE handle, int access_mode)
318
+ struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn)
323
319
  {
324
- int i, fd;
320
+ int i;
325
321
  struct winfd wfd = INVALID_WINFD;
326
322
  OVERLAPPED* overlapped = NULL;
327
323
 
@@ -331,27 +327,22 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode)
331
327
  return INVALID_WINFD;
332
328
  }
333
329
 
334
- if ((access_mode != _O_RDONLY) && (access_mode != _O_WRONLY)) {
335
- usbi_warn(NULL, "only one of _O_RDONLY or _O_WRONLY are supported.\n"
330
+ wfd.itransfer = itransfer;
331
+ wfd.cancel_fn = cancel_fn;
332
+
333
+ if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
334
+ usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
336
335
  "If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
337
336
  return INVALID_WINFD;
338
337
  }
339
- if (access_mode == _O_RDONLY) {
338
+ if (access_mode == RW_READ) {
340
339
  wfd.rw = RW_READ;
341
340
  } else {
342
341
  wfd.rw = RW_WRITE;
343
342
  }
344
343
 
345
- // Ensure that we get a non system conflicting unique fd, using
346
- // the same fd attribution system as the pipe ends
347
- fd = _open(NUL_DEVICE, _O_WRONLY);
348
- if (fd < 0) {
349
- return INVALID_WINFD;
350
- }
351
-
352
344
  overlapped = create_overlapped();
353
345
  if(overlapped == NULL) {
354
- _close(fd);
355
346
  return INVALID_WINFD;
356
347
  }
357
348
 
@@ -363,10 +354,11 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode)
363
354
  LeaveCriticalSection(&_poll_fd[i].mutex);
364
355
  continue;
365
356
  }
366
- wfd.fd = fd;
357
+ // Use index as the unique fd number
358
+ wfd.fd = i;
367
359
  // Attempt to emulate some of the CancelIoEx behaviour on platforms
368
360
  // that don't have it
369
- if (!CancelIoEx_Available) {
361
+ if (Use_Duplicate_Handles) {
370
362
  _poll_fd[i].thread_id = GetCurrentThreadId();
371
363
  if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
372
364
  &wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
@@ -387,21 +379,15 @@ struct winfd usbi_create_fd(HANDLE handle, int access_mode)
387
379
  }
388
380
  }
389
381
  free_overlapped(overlapped);
390
- _close(fd);
391
382
  return INVALID_WINFD;
392
383
  }
393
384
 
394
- void _free_index(int _index)
385
+ static void _free_index(int _index)
395
386
  {
396
387
  // Cancel any async IO (Don't care about the validity of our handles for this)
397
388
  cancel_io(_index);
398
- // close fake handle for devices
399
- if ( (poll_fd[_index].handle != INVALID_HANDLE_VALUE) && (poll_fd[_index].handle != 0)
400
- && (GetFileType(poll_fd[_index].handle) == FILE_TYPE_UNKNOWN) ) {
401
- _close(poll_fd[_index].fd);
402
- }
403
389
  // close the duplicate handle (if we have an actual duplicate)
404
- if (!CancelIoEx_Available) {
390
+ if (Use_Duplicate_Handles) {
405
391
  if (_poll_fd[_index].original_handle != INVALID_HANDLE_VALUE) {
406
392
  CloseHandle(poll_fd[_index].handle);
407
393
  }
@@ -417,17 +403,18 @@ void _free_index(int _index)
417
403
  *
418
404
  * Note that the associated Windows handle is not closed by this call
419
405
  */
420
- void usbi_free_fd(int fd)
406
+ void usbi_free_fd(struct winfd *wfd)
421
407
  {
422
408
  int _index;
423
409
 
424
410
  CHECK_INIT_POLLING;
425
411
 
426
- _index = _fd_to_index_and_lock(fd);
412
+ _index = _fd_to_index_and_lock(wfd->fd);
427
413
  if (_index < 0) {
428
414
  return;
429
415
  }
430
416
  _free_index(_index);
417
+ *wfd = INVALID_WINFD;
431
418
  LeaveCriticalSection(&_poll_fd[_index].mutex);
432
419
  }
433
420
 
@@ -441,7 +428,7 @@ struct winfd fd_to_winfd(int fd)
441
428
 
442
429
  CHECK_INIT_POLLING;
443
430
 
444
- if (fd <= 0)
431
+ if (fd < 0)
445
432
  return INVALID_WINFD;
446
433
 
447
434
  for (i=0; i<MAX_FDS; i++) {
@@ -651,15 +638,7 @@ int usbi_close(int fd)
651
638
  if (_index < 0) {
652
639
  errno = EBADF;
653
640
  } else {
654
- if (poll_fd[_index].overlapped != NULL) {
655
- // Must be a different event for each end of the pipe
656
- CloseHandle(poll_fd[_index].overlapped->hEvent);
657
- free(poll_fd[_index].overlapped);
658
- }
659
- r = _close(poll_fd[_index].fd);
660
- if (r != 0) {
661
- errno = EIO;
662
- }
641
+ free_overlapped(poll_fd[_index].overlapped);
663
642
  poll_fd[_index] = INVALID_WINFD;
664
643
  LeaveCriticalSection(&_poll_fd[_index].mutex);
665
644
  }