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
34const uint64_t epoch_time = UINT64_C(116444736000000000); // 1970.01.01 00:00:000 in MS Filetime
35int windows_version = WINDOWS_CE;
36static uint64_t hires_frequency, hires_ticks_to_ps;
37static HANDLE driver_handle = INVALID_HANDLE_VALUE;
38static 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)
45static 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
82static 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
88static 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
112static 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
141static void exit_dllimports(void)
142{
143	DLL_FREE_HANDLE(ceusbkwrapper);
144}
145
146static 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
164static 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
223init_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
242static 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
274static 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;
341err_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
351static 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
358static void wince_close(struct libusb_device_handle *handle)
359{
360	// Nothing to do as wince_open does nothing.
361}
362
363static 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
374static 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
388static 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
403static 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
417static 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
432static 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
444static 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
459static 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
471static 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
486static 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
497static 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
510static 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
522static 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
534static 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
541static 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
552static 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
564static 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
623static int wince_submit_iso_transfer(struct usbi_transfer *itransfer)
624{
625	return LIBUSB_ERROR_NOT_SUPPORTED;
626}
627
628static 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
647static 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
739static 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
759static 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 */
818static 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
851const 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