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