libusb 0.3.4 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
  }