• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Windows CE backend for libusb 1.0
3  * Copyright © 2011-2013 RealVNC Ltd.
4  * Large portions taken from Windows backend, which is
5  * Copyright © 2009-2010 Pete Batard <pbatard@gmail.com>
6  * With contributions from Michael Plante, Orin Eman et al.
7  * Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
8  * Major code testing contribution by Xiaofan Chen
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2.1 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 #include <config.h>
26 
27 #include <stdint.h>
28 #include <inttypes.h>
29 
30 #include "libusbi.h"
31 #include "wince_usb.h"
32 
33 // Global variables
34 const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
35 int windows_version = WINDOWS_CE;
36 static uint64_t hires_frequency, hires_ticks_to_ps;
37 static HANDLE driver_handle = INVALID_HANDLE_VALUE;
38 static int concurrent_usage = -1;
39 
40 /*
41  * Converts a windows error to human readable string
42  * uses retval as errorcode, or, if 0, use GetLastError()
43  */
44 #if defined(ENABLE_LOGGING)
windows_error_str(DWORD retval)45 static const char *windows_error_str(DWORD retval)
46 {
47 	static TCHAR wErr_string[ERR_BUFFER_SIZE];
48 	static char err_string[ERR_BUFFER_SIZE];
49 
50 	DWORD error_code, format_error;
51 	DWORD size;
52 	size_t i;
53 
54 	error_code = retval ? retval : GetLastError();
55 
56 	safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("[%u] "), (unsigned int)error_code);
57 
58 	size = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error_code,
59 		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wErr_string[safe_tcslen(wErr_string)],
60 		ERR_BUFFER_SIZE - (DWORD)safe_tcslen(wErr_string), NULL);
61 	if (size == 0) {
62 		format_error = GetLastError();
63 		if (format_error)
64 			safe_stprintf(wErr_string, ERR_BUFFER_SIZE,
65 				_T("Windows error code %u (FormatMessage error code %u)"),
66 				(unsigned int)error_code, (unsigned int)format_error);
67 		else
68 			safe_stprintf(wErr_string, ERR_BUFFER_SIZE, _T("Unknown error code %u"), (unsigned int)error_code);
69 	} else {
70 		// Remove CR/LF terminators
71 		for (i = safe_tcslen(wErr_string) - 1; ((wErr_string[i] == 0x0A) || (wErr_string[i] == 0x0D)); i--)
72 			wErr_string[i] = 0;
73 	}
74 
75 	if (WideCharToMultiByte(CP_ACP, 0, wErr_string, -1, err_string, ERR_BUFFER_SIZE, NULL, NULL) < 0)
76 		strcpy(err_string, "Unable to convert error string");
77 
78 	return err_string;
79 }
80 #endif
81 
_device_priv(struct libusb_device * dev)82 static struct wince_device_priv *_device_priv(struct libusb_device *dev)
83 {
84 	return (struct wince_device_priv *)dev->os_priv;
85 }
86 
87 // ceusbkwrapper to libusb error code mapping
translate_driver_error(DWORD error)88 static int translate_driver_error(DWORD error)
89 {
90 	switch (error) {
91 	case ERROR_INVALID_PARAMETER:
92 		return LIBUSB_ERROR_INVALID_PARAM;
93 	case ERROR_CALL_NOT_IMPLEMENTED:
94 	case ERROR_NOT_SUPPORTED:
95 		return LIBUSB_ERROR_NOT_SUPPORTED;
96 	case ERROR_NOT_ENOUGH_MEMORY:
97 		return LIBUSB_ERROR_NO_MEM;
98 	case ERROR_INVALID_HANDLE:
99 		return LIBUSB_ERROR_NO_DEVICE;
100 	case ERROR_BUSY:
101 		return LIBUSB_ERROR_BUSY;
102 
103 	// Error codes that are either unexpected, or have
104 	// no suitable LIBUSB_ERROR equivalent.
105 	case ERROR_CANCELLED:
106 	case ERROR_INTERNAL_ERROR:
107 	default:
108 		return LIBUSB_ERROR_OTHER;
109 	}
110 }
111 
init_dllimports(void)112 static int init_dllimports(void)
113 {
114 	DLL_GET_HANDLE(ceusbkwrapper);
115 	DLL_LOAD_FUNC(ceusbkwrapper, UkwOpenDriver, TRUE);
116 	DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceList, TRUE);
117 	DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseDeviceList, TRUE);
118 	DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceAddress, TRUE);
119 	DLL_LOAD_FUNC(ceusbkwrapper, UkwGetDeviceDescriptor, TRUE);
120 	DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfigDescriptor, TRUE);
121 	DLL_LOAD_FUNC(ceusbkwrapper, UkwCloseDriver, TRUE);
122 	DLL_LOAD_FUNC(ceusbkwrapper, UkwCancelTransfer, TRUE);
123 	DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueControlTransfer, TRUE);
124 	DLL_LOAD_FUNC(ceusbkwrapper, UkwClaimInterface, TRUE);
125 	DLL_LOAD_FUNC(ceusbkwrapper, UkwReleaseInterface, TRUE);
126 	DLL_LOAD_FUNC(ceusbkwrapper, UkwSetInterfaceAlternateSetting, TRUE);
127 	DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltHost, TRUE);
128 	DLL_LOAD_FUNC(ceusbkwrapper, UkwClearHaltDevice, TRUE);
129 	DLL_LOAD_FUNC(ceusbkwrapper, UkwGetConfig, TRUE);
130 	DLL_LOAD_FUNC(ceusbkwrapper, UkwSetConfig, TRUE);
131 	DLL_LOAD_FUNC(ceusbkwrapper, UkwResetDevice, TRUE);
132 	DLL_LOAD_FUNC(ceusbkwrapper, UkwKernelDriverActive, TRUE);
133 	DLL_LOAD_FUNC(ceusbkwrapper, UkwAttachKernelDriver, TRUE);
134 	DLL_LOAD_FUNC(ceusbkwrapper, UkwDetachKernelDriver, TRUE);
135 	DLL_LOAD_FUNC(ceusbkwrapper, UkwIssueBulkTransfer, TRUE);
136 	DLL_LOAD_FUNC(ceusbkwrapper, UkwIsPipeHalted, TRUE);
137 
138 	return LIBUSB_SUCCESS;
139 }
140 
exit_dllimports(void)141 static void exit_dllimports(void)
142 {
143 	DLL_FREE_HANDLE(ceusbkwrapper);
144 }
145 
init_device(struct libusb_device * dev,UKW_DEVICE drv_dev,unsigned char bus_addr,unsigned char dev_addr)146 static int init_device(
147 	struct libusb_device *dev, UKW_DEVICE drv_dev,
148 	unsigned char bus_addr, unsigned char dev_addr)
149 {
150 	struct wince_device_priv *priv = _device_priv(dev);
151 	int r = LIBUSB_SUCCESS;
152 
153 	dev->bus_number = bus_addr;
154 	dev->device_address = dev_addr;
155 	priv->dev = drv_dev;
156 
157 	if (!UkwGetDeviceDescriptor(priv->dev, &(priv->desc)))
158 		r = translate_driver_error(GetLastError());
159 
160 	return r;
161 }
162 
163 // Internal API functions
wince_init(struct libusb_context * ctx)164 static int wince_init(struct libusb_context *ctx)
165 {
166 	int r = LIBUSB_ERROR_OTHER;
167 	HANDLE semaphore;
168 	LARGE_INTEGER li_frequency;
169 	TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
170 
171 	_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
172 	semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
173 	if (semaphore == NULL) {
174 		usbi_err(ctx, "could not create semaphore: %s", windows_error_str(0));
175 		return LIBUSB_ERROR_NO_MEM;
176 	}
177 
178 	// A successful wait brings our semaphore count to 0 (unsignaled)
179 	// => any concurent wait stalls until the semaphore's release
180 	if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
181 		usbi_err(ctx, "failure to access semaphore: %s", windows_error_str(0));
182 		CloseHandle(semaphore);
183 		return LIBUSB_ERROR_NO_MEM;
184 	}
185 
186 	// NB: concurrent usage supposes that init calls are equally balanced with
187 	// exit calls. If init is called more than exit, we will not exit properly
188 	if ( ++concurrent_usage == 0 ) {	// First init?
189 		// Initialize pollable file descriptors
190 		init_polling();
191 
192 		// Load DLL imports
193 		if (init_dllimports() != LIBUSB_SUCCESS) {
194 			usbi_err(ctx, "could not resolve DLL functions");
195 			r = LIBUSB_ERROR_NOT_SUPPORTED;
196 			goto init_exit;
197 		}
198 
199 		// try to open a handle to the driver
200 		driver_handle = UkwOpenDriver();
201 		if (driver_handle == INVALID_HANDLE_VALUE) {
202 			usbi_err(ctx, "could not connect to driver");
203 			r = LIBUSB_ERROR_NOT_SUPPORTED;
204 			goto init_exit;
205 		}
206 
207 		// find out if we have access to a monotonic (hires) timer
208 		if (QueryPerformanceFrequency(&li_frequency)) {
209 			hires_frequency = li_frequency.QuadPart;
210 			// The hires frequency can go as high as 4 GHz, so we'll use a conversion
211 			// to picoseconds to compute the tv_nsecs part in clock_gettime
212 			hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
213 			usbi_dbg("hires timer available (Frequency: %"PRIu64" Hz)", hires_frequency);
214 		} else {
215 			usbi_dbg("no hires timer available on this platform");
216 			hires_frequency = 0;
217 			hires_ticks_to_ps = UINT64_C(0);
218 		}
219 	}
220 	// At this stage, either we went through full init successfully, or didn't need to
221 	r = LIBUSB_SUCCESS;
222 
223 init_exit: // Holds semaphore here.
224 	if (!concurrent_usage && r != LIBUSB_SUCCESS) { // First init failed?
225 		exit_dllimports();
226 		exit_polling();
227 
228 		if (driver_handle != INVALID_HANDLE_VALUE) {
229 			UkwCloseDriver(driver_handle);
230 			driver_handle = INVALID_HANDLE_VALUE;
231 		}
232 	}
233 
234 	if (r != LIBUSB_SUCCESS)
235 		--concurrent_usage; // Not expected to call libusb_exit if we failed.
236 
237 	ReleaseSemaphore(semaphore, 1, NULL);	// increase count back to 1
238 	CloseHandle(semaphore);
239 	return r;
240 }
241 
wince_exit(void)242 static void wince_exit(void)
243 {
244 	HANDLE semaphore;
245 	TCHAR sem_name[11 + 8 + 1]; // strlen("libusb_init") + (32-bit hex PID) + '\0'
246 
247 	_stprintf(sem_name, _T("libusb_init%08X"), (unsigned int)(GetCurrentProcessId() & 0xFFFFFFFF));
248 	semaphore = CreateSemaphore(NULL, 1, 1, sem_name);
249 	if (semaphore == NULL)
250 		return;
251 
252 	// A successful wait brings our semaphore count to 0 (unsignaled)
253 	// => any concurent wait stalls until the semaphore release
254 	if (WaitForSingleObject(semaphore, INFINITE) != WAIT_OBJECT_0) {
255 		CloseHandle(semaphore);
256 		return;
257 	}
258 
259 	// Only works if exits and inits are balanced exactly
260 	if (--concurrent_usage < 0) {	// Last exit
261 		exit_dllimports();
262 		exit_polling();
263 
264 		if (driver_handle != INVALID_HANDLE_VALUE) {
265 			UkwCloseDriver(driver_handle);
266 			driver_handle = INVALID_HANDLE_VALUE;
267 		}
268 	}
269 
270 	ReleaseSemaphore(semaphore, 1, NULL);	// increase count back to 1
271 	CloseHandle(semaphore);
272 }
273 
wince_get_device_list(struct libusb_context * ctx,struct discovered_devs ** discdevs)274 static int wince_get_device_list(
275 	struct libusb_context *ctx,
276 	struct discovered_devs **discdevs)
277 {
278 	UKW_DEVICE devices[MAX_DEVICE_COUNT];
279 	struct discovered_devs *new_devices = *discdevs;
280 	DWORD count = 0, i;
281 	struct libusb_device *dev = NULL;
282 	unsigned char bus_addr, dev_addr;
283 	unsigned long session_id;
284 	BOOL success;
285 	DWORD release_list_offset = 0;
286 	int r = LIBUSB_SUCCESS;
287 
288 	success = UkwGetDeviceList(driver_handle, devices, MAX_DEVICE_COUNT, &count);
289 	if (!success) {
290 		int libusbErr = translate_driver_error(GetLastError());
291 		usbi_err(ctx, "could not get devices: %s", windows_error_str(0));
292 		return libusbErr;
293 	}
294 
295 	for (i = 0; i < count; ++i) {
296 		release_list_offset = i;
297 		success = UkwGetDeviceAddress(devices[i], &bus_addr, &dev_addr, &session_id);
298 		if (!success) {
299 			r = translate_driver_error(GetLastError());
300 			usbi_err(ctx, "could not get device address for %u: %s", (unsigned int)i, windows_error_str(0));
301 			goto err_out;
302 		}
303 
304 		dev = usbi_get_device_by_session_id(ctx, session_id);
305 		if (dev) {
306 			usbi_dbg("using existing device for %u/%u (session %lu)",
307 					bus_addr, dev_addr, session_id);
308 			// Release just this element in the device list (as we already hold a
309 			// reference to it).
310 			UkwReleaseDeviceList(driver_handle, &devices[i], 1);
311 			release_list_offset++;
312 		} else {
313 			usbi_dbg("allocating new device for %u/%u (session %lu)",
314 					bus_addr, dev_addr, session_id);
315 			dev = usbi_alloc_device(ctx, session_id);
316 			if (!dev) {
317 				r = LIBUSB_ERROR_NO_MEM;
318 				goto err_out;
319 			}
320 
321 			r = init_device(dev, devices[i], bus_addr, dev_addr);
322 			if (r < 0)
323 				goto err_out;
324 
325 			r = usbi_sanitize_device(dev);
326 			if (r < 0)
327 				goto err_out;
328 		}
329 
330 		new_devices = discovered_devs_append(new_devices, dev);
331 		if (!discdevs) {
332 			r = LIBUSB_ERROR_NO_MEM;
333 			goto err_out;
334 		}
335 
336 		safe_unref_device(dev);
337 	}
338 
339 	*discdevs = new_devices;
340 	return r;
341 err_out:
342 	*discdevs = new_devices;
343 	safe_unref_device(dev);
344 	// Release the remainder of the unprocessed device list.
345 	// The devices added to new_devices already will still be passed up to libusb,
346 	// which can dispose of them at its leisure.
347 	UkwReleaseDeviceList(driver_handle, &devices[release_list_offset], count - release_list_offset);
348 	return r;
349 }
350 
wince_open(struct libusb_device_handle * handle)351 static int wince_open(struct libusb_device_handle *handle)
352 {
353 	// Nothing to do to open devices as a handle to it has
354 	// been retrieved by wince_get_device_list
355 	return LIBUSB_SUCCESS;
356 }
357 
wince_close(struct libusb_device_handle * handle)358 static void wince_close(struct libusb_device_handle *handle)
359 {
360 	// Nothing to do as wince_open does nothing.
361 }
362 
wince_get_device_descriptor(struct libusb_device * device,unsigned char * buffer,int * host_endian)363 static int wince_get_device_descriptor(
364 	struct libusb_device *device,
365 	unsigned char *buffer, int *host_endian)
366 {
367 	struct wince_device_priv *priv = _device_priv(device);
368 
369 	*host_endian = 1;
370 	memcpy(buffer, &priv->desc, DEVICE_DESC_LENGTH);
371 	return LIBUSB_SUCCESS;
372 }
373 
wince_get_active_config_descriptor(struct libusb_device * device,unsigned char * buffer,size_t len,int * host_endian)374 static int wince_get_active_config_descriptor(
375 	struct libusb_device *device,
376 	unsigned char *buffer, size_t len, int *host_endian)
377 {
378 	struct wince_device_priv *priv = _device_priv(device);
379 	DWORD actualSize = len;
380 
381 	*host_endian = 0;
382 	if (!UkwGetConfigDescriptor(priv->dev, UKW_ACTIVE_CONFIGURATION, buffer, len, &actualSize))
383 		return translate_driver_error(GetLastError());
384 
385 	return actualSize;
386 }
387 
wince_get_config_descriptor(struct libusb_device * device,uint8_t config_index,unsigned char * buffer,size_t len,int * host_endian)388 static int wince_get_config_descriptor(
389 	struct libusb_device *device,
390 	uint8_t config_index,
391 	unsigned char *buffer, size_t len, int *host_endian)
392 {
393 	struct wince_device_priv *priv = _device_priv(device);
394 	DWORD actualSize = len;
395 
396 	*host_endian = 0;
397 	if (!UkwGetConfigDescriptor(priv->dev, config_index, buffer, len, &actualSize))
398 		return translate_driver_error(GetLastError());
399 
400 	return actualSize;
401 }
402 
wince_get_configuration(struct libusb_device_handle * handle,int * config)403 static int wince_get_configuration(
404 	struct libusb_device_handle *handle,
405 	int *config)
406 {
407 	struct wince_device_priv *priv = _device_priv(handle->dev);
408 	UCHAR cv = 0;
409 
410 	if (!UkwGetConfig(priv->dev, &cv))
411 		return translate_driver_error(GetLastError());
412 
413 	(*config) = cv;
414 	return LIBUSB_SUCCESS;
415 }
416 
wince_set_configuration(struct libusb_device_handle * handle,int config)417 static int wince_set_configuration(
418 	struct libusb_device_handle *handle,
419 	int config)
420 {
421 	struct wince_device_priv *priv = _device_priv(handle->dev);
422 	// Setting configuration 0 places the device in Address state.
423 	// This should correspond to the "unconfigured state" required by
424 	// libusb when the specified configuration is -1.
425 	UCHAR cv = (config < 0) ? 0 : config;
426 	if (!UkwSetConfig(priv->dev, cv))
427 		return translate_driver_error(GetLastError());
428 
429 	return LIBUSB_SUCCESS;
430 }
431 
wince_claim_interface(struct libusb_device_handle * handle,int interface_number)432 static int wince_claim_interface(
433 	struct libusb_device_handle *handle,
434 	int interface_number)
435 {
436 	struct wince_device_priv *priv = _device_priv(handle->dev);
437 
438 	if (!UkwClaimInterface(priv->dev, interface_number))
439 		return translate_driver_error(GetLastError());
440 
441 	return LIBUSB_SUCCESS;
442 }
443 
wince_release_interface(struct libusb_device_handle * handle,int interface_number)444 static int wince_release_interface(
445 	struct libusb_device_handle *handle,
446 	int interface_number)
447 {
448 	struct wince_device_priv *priv = _device_priv(handle->dev);
449 
450 	if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, 0))
451 		return translate_driver_error(GetLastError());
452 
453 	if (!UkwReleaseInterface(priv->dev, interface_number))
454 		return translate_driver_error(GetLastError());
455 
456 	return LIBUSB_SUCCESS;
457 }
458 
wince_set_interface_altsetting(struct libusb_device_handle * handle,int interface_number,int altsetting)459 static int wince_set_interface_altsetting(
460 	struct libusb_device_handle *handle,
461 	int interface_number, int altsetting)
462 {
463 	struct wince_device_priv *priv = _device_priv(handle->dev);
464 
465 	if (!UkwSetInterfaceAlternateSetting(priv->dev, interface_number, altsetting))
466 		return translate_driver_error(GetLastError());
467 
468 	return LIBUSB_SUCCESS;
469 }
470 
wince_clear_halt(struct libusb_device_handle * handle,unsigned char endpoint)471 static int wince_clear_halt(
472 	struct libusb_device_handle *handle,
473 	unsigned char endpoint)
474 {
475 	struct wince_device_priv *priv = _device_priv(handle->dev);
476 
477 	if (!UkwClearHaltHost(priv->dev, endpoint))
478 		return translate_driver_error(GetLastError());
479 
480 	if (!UkwClearHaltDevice(priv->dev, endpoint))
481 		return translate_driver_error(GetLastError());
482 
483 	return LIBUSB_SUCCESS;
484 }
485 
wince_reset_device(struct libusb_device_handle * handle)486 static int wince_reset_device(
487 	struct libusb_device_handle *handle)
488 {
489 	struct wince_device_priv *priv = _device_priv(handle->dev);
490 
491 	if (!UkwResetDevice(priv->dev))
492 		return translate_driver_error(GetLastError());
493 
494 	return LIBUSB_SUCCESS;
495 }
496 
wince_kernel_driver_active(struct libusb_device_handle * handle,int interface_number)497 static int wince_kernel_driver_active(
498 	struct libusb_device_handle *handle,
499 	int interface_number)
500 {
501 	struct wince_device_priv *priv = _device_priv(handle->dev);
502 	BOOL result = FALSE;
503 
504 	if (!UkwKernelDriverActive(priv->dev, interface_number, &result))
505 		return translate_driver_error(GetLastError());
506 
507 	return result ? 1 : 0;
508 }
509 
wince_detach_kernel_driver(struct libusb_device_handle * handle,int interface_number)510 static int wince_detach_kernel_driver(
511 	struct libusb_device_handle *handle,
512 	int interface_number)
513 {
514 	struct wince_device_priv *priv = _device_priv(handle->dev);
515 
516 	if (!UkwDetachKernelDriver(priv->dev, interface_number))
517 		return translate_driver_error(GetLastError());
518 
519 	return LIBUSB_SUCCESS;
520 }
521 
wince_attach_kernel_driver(struct libusb_device_handle * handle,int interface_number)522 static int wince_attach_kernel_driver(
523 	struct libusb_device_handle *handle,
524 	int interface_number)
525 {
526 	struct wince_device_priv *priv = _device_priv(handle->dev);
527 
528 	if (!UkwAttachKernelDriver(priv->dev, interface_number))
529 		return translate_driver_error(GetLastError());
530 
531 	return LIBUSB_SUCCESS;
532 }
533 
wince_destroy_device(struct libusb_device * dev)534 static void wince_destroy_device(struct libusb_device *dev)
535 {
536 	struct wince_device_priv *priv = _device_priv(dev);
537 
538 	UkwReleaseDeviceList(driver_handle, &priv->dev, 1);
539 }
540 
wince_clear_transfer_priv(struct usbi_transfer * itransfer)541 static void wince_clear_transfer_priv(struct usbi_transfer *itransfer)
542 {
543 	struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
544 	struct winfd wfd = fd_to_winfd(transfer_priv->pollable_fd.fd);
545 
546 	// No need to cancel transfer as it is either complete or abandoned
547 	wfd.itransfer = NULL;
548 	CloseHandle(wfd.handle);
549 	usbi_free_fd(&transfer_priv->pollable_fd);
550 }
551 
wince_cancel_transfer(struct usbi_transfer * itransfer)552 static int wince_cancel_transfer(struct usbi_transfer *itransfer)
553 {
554 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
555 	struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
556 	struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
557 
558 	if (!UkwCancelTransfer(priv->dev, transfer_priv->pollable_fd.overlapped, UKW_TF_NO_WAIT))
559 		return translate_driver_error(GetLastError());
560 
561 	return LIBUSB_SUCCESS;
562 }
563 
wince_submit_control_or_bulk_transfer(struct usbi_transfer * itransfer)564 static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer)
565 {
566 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
567 	struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
568 	struct wince_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer);
569 	struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
570 	BOOL direction_in, ret;
571 	struct winfd wfd;
572 	DWORD flags;
573 	HANDLE eventHandle;
574 	PUKW_CONTROL_HEADER setup = NULL;
575 	const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;
576 
577 	transfer_priv->pollable_fd = INVALID_WINFD;
578 	if (control_transfer) {
579 		setup = (PUKW_CONTROL_HEADER) transfer->buffer;
580 		direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
581 	} else {
582 		direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
583 	}
584 	flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
585 	flags |= UKW_TF_SHORT_TRANSFER_OK;
586 
587 	eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
588 	if (eventHandle == NULL) {
589 		usbi_err(ctx, "Failed to create event for async transfer");
590 		return LIBUSB_ERROR_NO_MEM;
591 	}
592 
593 	wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer);
594 	if (wfd.fd < 0) {
595 		CloseHandle(eventHandle);
596 		return LIBUSB_ERROR_NO_MEM;
597 	}
598 
599 	transfer_priv->pollable_fd = wfd;
600 	if (control_transfer) {
601 		// Split out control setup header and data buffer
602 		DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
603 		PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)];
604 
605 		ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
606 	} else {
607 		ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer,
608 			transfer->length, &transfer->actual_length, wfd.overlapped);
609 	}
610 
611 	if (!ret) {
612 		int libusbErr = translate_driver_error(GetLastError());
613 		usbi_err(ctx, "UkwIssue%sTransfer failed: error %u",
614 			control_transfer ? "Control" : "Bulk", (unsigned int)GetLastError());
615 		wince_clear_transfer_priv(itransfer);
616 		return libusbErr;
617 	}
618 	usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
619 
620 	return LIBUSB_SUCCESS;
621 }
622 
wince_submit_iso_transfer(struct usbi_transfer * itransfer)623 static int wince_submit_iso_transfer(struct usbi_transfer *itransfer)
624 {
625 	return LIBUSB_ERROR_NOT_SUPPORTED;
626 }
627 
wince_submit_transfer(struct usbi_transfer * itransfer)628 static int wince_submit_transfer(struct usbi_transfer *itransfer)
629 {
630 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
631 
632 	switch (transfer->type) {
633 	case LIBUSB_TRANSFER_TYPE_CONTROL:
634 	case LIBUSB_TRANSFER_TYPE_BULK:
635 	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
636 		return wince_submit_control_or_bulk_transfer(itransfer);
637 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
638 		return wince_submit_iso_transfer(itransfer);
639 	case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
640 		return LIBUSB_ERROR_NOT_SUPPORTED;
641 	default:
642 		usbi_err(TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
643 		return LIBUSB_ERROR_INVALID_PARAM;
644 	}
645 }
646 
wince_transfer_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)647 static void wince_transfer_callback(
648 	struct usbi_transfer *itransfer,
649 	uint32_t io_result, uint32_t io_size)
650 {
651 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
652 	struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
653 	struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
654 	int status;
655 
656 	usbi_dbg("handling I/O completion with errcode %u", io_result);
657 
658 	if (io_result == ERROR_NOT_SUPPORTED &&
659 		transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) {
660 		/* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper
661 		 * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the
662 		 * endpoint isn't actually stalled.
663 		 *
664 		 * One example of this is that some devices will occasionally fail to reply to an IN
665 		 * token. The WinCE USB layer carries on with the transaction until it is completed
666 		 * (or cancelled) but then completes it with USB_ERROR_STALL.
667 		 *
668 		 * This code therefore needs to confirm that there really is a stall error, by both
669 		 * checking the pipe status and requesting the endpoint status from the device.
670 		 */
671 		BOOL halted = FALSE;
672 		usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall");
673 		if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) {
674 			/* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS
675 			 * control request to the device. This is done synchronously, which is a bit
676 			 * naughty, but this is a special corner case.
677 			 */
678 			WORD wStatus = 0;
679 			DWORD written = 0;
680 			UKW_CONTROL_HEADER ctrlHeader;
681 			ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD |
682 				LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT;
683 			ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS;
684 			ctrlHeader.wValue = 0;
685 			ctrlHeader.wIndex = transfer->endpoint;
686 			ctrlHeader.wLength = sizeof(wStatus);
687 			if (UkwIssueControlTransfer(priv->dev,
688 					UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT,
689 					&ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) {
690 				if (written == sizeof(wStatus) &&
691 						(wStatus & STATUS_HALT_FLAG) == 0) {
692 					if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) {
693 						usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success");
694 						io_result = ERROR_SUCCESS;
695 					} else {
696 						usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error");
697 						io_result = ERROR_IO_DEVICE;
698 					}
699 				}
700 			}
701 		}
702 	}
703 
704 	switch(io_result) {
705 	case ERROR_SUCCESS:
706 		itransfer->transferred += io_size;
707 		status = LIBUSB_TRANSFER_COMPLETED;
708 		break;
709 	case ERROR_CANCELLED:
710 		usbi_dbg("detected transfer cancel");
711 		status = LIBUSB_TRANSFER_CANCELLED;
712 		break;
713 	case ERROR_NOT_SUPPORTED:
714 	case ERROR_GEN_FAILURE:
715 		usbi_dbg("detected endpoint stall");
716 		status = LIBUSB_TRANSFER_STALL;
717 		break;
718 	case ERROR_SEM_TIMEOUT:
719 		usbi_dbg("detected semaphore timeout");
720 		status = LIBUSB_TRANSFER_TIMED_OUT;
721 		break;
722 	case ERROR_OPERATION_ABORTED:
723 		usbi_dbg("detected operation aborted");
724 		status = LIBUSB_TRANSFER_CANCELLED;
725 		break;
726 	default:
727 		usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result));
728 		status = LIBUSB_TRANSFER_ERROR;
729 		break;
730 	}
731 
732 	wince_clear_transfer_priv(itransfer);
733 	if (status == LIBUSB_TRANSFER_CANCELLED)
734 		usbi_handle_transfer_cancellation(itransfer);
735 	else
736 		usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status);
737 }
738 
wince_handle_callback(struct usbi_transfer * itransfer,uint32_t io_result,uint32_t io_size)739 static void wince_handle_callback(
740 	struct usbi_transfer *itransfer,
741 	uint32_t io_result, uint32_t io_size)
742 {
743 	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
744 
745 	switch (transfer->type) {
746 	case LIBUSB_TRANSFER_TYPE_CONTROL:
747 	case LIBUSB_TRANSFER_TYPE_BULK:
748 	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
749 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
750 		wince_transfer_callback (itransfer, io_result, io_size);
751 		break;
752 	case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
753 		break;
754 	default:
755 		usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type);
756 	}
757 }
758 
wince_handle_events(struct libusb_context * ctx,struct pollfd * fds,POLL_NFDS_TYPE nfds,int num_ready)759 static int wince_handle_events(
760 	struct libusb_context *ctx,
761 	struct pollfd *fds, POLL_NFDS_TYPE nfds, int num_ready)
762 {
763 	struct wince_transfer_priv* transfer_priv = NULL;
764 	POLL_NFDS_TYPE i = 0;
765 	BOOL found = FALSE;
766 	struct usbi_transfer *transfer;
767 	DWORD io_size, io_result;
768 	int r = LIBUSB_SUCCESS;
769 
770 	usbi_mutex_lock(&ctx->open_devs_lock);
771 	for (i = 0; i < nfds && num_ready > 0; i++) {
772 
773 		usbi_dbg("checking fd %d with revents = %04x", fds[i].fd, fds[i].revents);
774 
775 		if (!fds[i].revents)
776 			continue;
777 
778 		num_ready--;
779 
780 		// Because a Windows OVERLAPPED is used for poll emulation,
781 		// a pollable fd is created and stored with each transfer
782 		usbi_mutex_lock(&ctx->flying_transfers_lock);
783 		list_for_each_entry(transfer, &ctx->flying_transfers, list, struct usbi_transfer) {
784 			transfer_priv = usbi_transfer_get_os_priv(transfer);
785 			if (transfer_priv->pollable_fd.fd == fds[i].fd) {
786 				found = TRUE;
787 				break;
788 			}
789 		}
790 		usbi_mutex_unlock(&ctx->flying_transfers_lock);
791 
792 		if (found && HasOverlappedIoCompleted(transfer_priv->pollable_fd.overlapped)) {
793 			io_result = (DWORD)transfer_priv->pollable_fd.overlapped->Internal;
794 			io_size = (DWORD)transfer_priv->pollable_fd.overlapped->InternalHigh;
795 			usbi_remove_pollfd(ctx, transfer_priv->pollable_fd.fd);
796 			// let handle_callback free the event using the transfer wfd
797 			// If you don't use the transfer wfd, you run a risk of trying to free a
798 			// newly allocated wfd that took the place of the one from the transfer.
799 			wince_handle_callback(transfer, io_result, io_size);
800 		} else if (found) {
801 			usbi_err(ctx, "matching transfer for fd %d has not completed", fds[i]);
802 			r = LIBUSB_ERROR_OTHER;
803 			break;
804 		} else {
805 			usbi_err(ctx, "could not find a matching transfer for fd %d", fds[i]);
806 			r = LIBUSB_ERROR_NOT_FOUND;
807 			break;
808 		}
809 	}
810 	usbi_mutex_unlock(&ctx->open_devs_lock);
811 
812 	return r;
813 }
814 
815 /*
816  * Monotonic and real time functions
817  */
wince_clock_gettime(int clk_id,struct timespec * tp)818 static int wince_clock_gettime(int clk_id, struct timespec *tp)
819 {
820 	LARGE_INTEGER hires_counter;
821 	ULARGE_INTEGER rtime;
822 	FILETIME filetime;
823 	SYSTEMTIME st;
824 
825 	switch(clk_id) {
826 	case USBI_CLOCK_MONOTONIC:
827 		if (hires_frequency != 0 && QueryPerformanceCounter(&hires_counter)) {
828 			tp->tv_sec = (long)(hires_counter.QuadPart / hires_frequency);
829 			tp->tv_nsec = (long)(((hires_counter.QuadPart % hires_frequency) / 1000) * hires_ticks_to_ps);
830 			return LIBUSB_SUCCESS;
831 		}
832 		// Fall through and return real-time if monotonic read failed or was not detected @ init
833 	case USBI_CLOCK_REALTIME:
834 		// We follow http://msdn.microsoft.com/en-us/library/ms724928%28VS.85%29.aspx
835 		// with a predef epoch_time to have an epoch that starts at 1970.01.01 00:00
836 		// Note however that our resolution is bounded by the Windows system time
837 		// functions and is at best of the order of 1 ms (or, usually, worse)
838 		GetSystemTime(&st);
839 		SystemTimeToFileTime(&st, &filetime);
840 		rtime.LowPart = filetime.dwLowDateTime;
841 		rtime.HighPart = filetime.dwHighDateTime;
842 		rtime.QuadPart -= epoch_time;
843 		tp->tv_sec = (long)(rtime.QuadPart / 10000000);
844 		tp->tv_nsec = (long)((rtime.QuadPart % 10000000)*100);
845 		return LIBUSB_SUCCESS;
846 	default:
847 		return LIBUSB_ERROR_INVALID_PARAM;
848 	}
849 }
850 
851 const struct usbi_os_backend wince_backend = {
852 	"Windows CE",
853 	0,
854 	wince_init,
855 	wince_exit,
856 
857 	wince_get_device_list,
858 	NULL,				/* hotplug_poll */
859 	wince_open,
860 	wince_close,
861 
862 	wince_get_device_descriptor,
863 	wince_get_active_config_descriptor,
864 	wince_get_config_descriptor,
865 	NULL,				/* get_config_descriptor_by_value() */
866 
867 	wince_get_configuration,
868 	wince_set_configuration,
869 	wince_claim_interface,
870 	wince_release_interface,
871 
872 	wince_set_interface_altsetting,
873 	wince_clear_halt,
874 	wince_reset_device,
875 
876 	NULL,				/* alloc_streams */
877 	NULL,				/* free_streams */
878 
879 	NULL,				/* dev_mem_alloc() */
880 	NULL,				/* dev_mem_free() */
881 
882 	wince_kernel_driver_active,
883 	wince_detach_kernel_driver,
884 	wince_attach_kernel_driver,
885 
886 	wince_destroy_device,
887 
888 	wince_submit_transfer,
889 	wince_cancel_transfer,
890 	wince_clear_transfer_priv,
891 
892 	wince_handle_events,
893 	NULL,				/* handle_transfer_completion() */
894 
895 	wince_clock_gettime,
896 	sizeof(struct wince_device_priv),
897 	0,
898 	sizeof(struct wince_transfer_priv),
899 };
900