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