WinCE: Add support for WinCE (sources)

This commit is contained in:
Toby Gray
2013-01-16 02:07:29 +00:00
parent 790ffc78b0
commit 244271931a
15 changed files with 1409 additions and 9 deletions

View File

@@ -18,7 +18,9 @@
*/
#include <stdio.h>
#if !defined(_WIN32_WCE)
#include <sys/types.h>
#endif
#include "libusb.h"

View File

@@ -33,7 +33,7 @@
#define msleep(msecs) usleep(1000*msecs)
#endif
#if !defined(_MSC_VER) || _MSC_VER<=1200
#if !defined(_MSC_VER) || _MSC_VER<=1200 || defined(_WIN32_WCE)
#define sscanf_s sscanf
#endif

View File

@@ -34,6 +34,10 @@
#include <sys/time.h>
#endif
#if defined(OS_WINCE)
#include "missing.h" // getenv()
#endif
#include "libusbi.h"
#if defined(OS_LINUX)
@@ -44,6 +48,8 @@ const struct usbi_os_backend * const usbi_backend = &darwin_backend;
const struct usbi_os_backend * const usbi_backend = &openbsd_backend;
#elif defined(OS_WINDOWS)
const struct usbi_os_backend * const usbi_backend = &windows_backend;
#elif defined(OS_WINCE)
const struct usbi_os_backend * const usbi_backend = &wince_backend;
#else
#error "Unsupported OS"
#endif
@@ -1789,7 +1795,13 @@ int usbi_gettimeofday(struct timeval *tp, void *tzp)
UNUSED(tzp);
if(tp) {
#if defined(OS_WINCE)
SYSTEMTIME st;
GetSystemTime(&st);
SystemTimeToFileTime(&st, &_now.ft);
#else
GetSystemTimeAsFileTime (&_now.ft);
#endif
tp->tv_usec=(long)((_now.ns100 / 10) % 1000000 );
tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000);
}

View File

@@ -5,7 +5,9 @@
* The information can then be queried using standard APIs and can also be
* viewed with utilities such as Windows Explorer.
*/
#ifndef _WIN32_WCE
#include "winresrc.h"
#endif
#include "version.h"
#ifndef LIBUSB_VERSIONSTRING

View File

@@ -49,7 +49,9 @@ typedef unsigned __int32 uint32_t;
#include <stdint.h>
#endif
#if !defined(_WIN32_WCE)
#include <sys/types.h>
#endif
#include <time.h>
#include <limits.h>
@@ -62,11 +64,15 @@ typedef unsigned __int32 uint32_t;
* libusb_config_descriptor has an 'interface' member
* As this can be problematic if you include windows.h after libusb.h
* in your sources, we force windows.h to be included first. */
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
#include <windows.h>
#if defined(interface)
#undef interface
#endif
#if defined(_WIN32_WCE)
// Needed for "struct timeval" definition
#include <winsock2.h>
#endif
#endif
/** \def LIBUSB_CALL
@@ -101,7 +107,7 @@ typedef unsigned __int32 uint32_t;
* return type, before the function name. See internal documentation for
* API_EXPORTED.
*/
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
#define LIBUSB_CALL WINAPI
#else
#define LIBUSB_CALL

View File

@@ -195,7 +195,7 @@ static inline void usbi_dbg(const char *format, ...)
/* Internal abstraction for thread synchronization */
#if defined(THREADS_POSIX)
#include "os/threads_posix.h"
#elif defined(OS_WINDOWS)
#elif defined(OS_WINDOWS) || defined(OS_WINCE)
#include <os/threads_windows.h>
#endif
@@ -396,7 +396,7 @@ int usbi_get_config_index_by_value(struct libusb_device *dev,
#include <os/poll_windows.h>
#endif
#if defined(OS_WINDOWS) && !defined(__GCC__)
#if (defined(OS_WINDOWS) || defined(OS_WINCE)) && !defined(__GCC__)
#undef HAVE_GETTIMEOFDAY
int usbi_gettimeofday(struct timeval *tp, void *tzp);
#define LIBUSB_GETTIMEOFDAY_WIN32
@@ -905,5 +905,6 @@ extern const struct usbi_os_backend linux_usbfs_backend;
extern const struct usbi_os_backend darwin_backend;
extern const struct usbi_os_backend openbsd_backend;
extern const struct usbi_os_backend windows_backend;
extern const struct usbi_os_backend wince_backend;
#endif

1013
libusb/os/wince_usb.c Normal file

File diff suppressed because it is too large Load Diff

131
libusb/os/wince_usb.h Normal file
View File

@@ -0,0 +1,131 @@
/*
* Windows CE backend for libusb 1.0
* Copyright (C) 2011-2012 RealVNC Ltd.
* Portions taken from Windows backend, which is
* Copyright (C) 2009-2010 Pete Batard <pbatard@gmail.com>
* With contributions from Michael Plante, Orin Eman et al.
* Parts of this code adapted from libusb-win32-v1 by Stephan Meyer
* Major code testing contribution by Xiaofan Chen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
#include "windows_common.h"
#include <windows.h>
#include "poll_windows.h"
#define MAX_DEVICE_COUNT 256
// This is a modified dump of the types in the ceusbkwrapper.h library header
// with functions transformed into extern pointers.
//
// This backend dynamically loads ceusbkwrapper.dll and doesn't include
// ceusbkwrapper.h directly to simplify the build process. The kernel
// side wrapper driver is built using the platform image build tools,
// which makes it difficult to reference directly from the libusbx build
// system.
struct UKW_DEVICE_PRIV;
typedef struct UKW_DEVICE_PRIV *UKW_DEVICE;
typedef UKW_DEVICE *PUKW_DEVICE, *LPUKW_DEVICE;
typedef struct {
UINT8 bLength;
UINT8 bDescriptorType;
UINT16 bcdUSB;
UINT8 bDeviceClass;
UINT8 bDeviceSubClass;
UINT8 bDeviceProtocol;
UINT8 bMaxPacketSize0;
UINT16 idVendor;
UINT16 idProduct;
UINT16 bcdDevice;
UINT8 iManufacturer;
UINT8 iProduct;
UINT8 iSerialNumber;
UINT8 bNumConfigurations;
} UKW_DEVICE_DESCRIPTOR, *PUKW_DEVICE_DESCRIPTOR, *LPUKW_DEVICE_DESCRIPTOR;
typedef struct {
UINT8 bmRequestType;
UINT8 bRequest;
UINT16 wValue;
UINT16 wIndex;
UINT16 wLength;
} UKW_CONTROL_HEADER, *PUKW_CONTROL_HEADER, *LPUKW_CONTROL_HEADER;
// Collection of flags which can be used when issuing transfer requests
/* Indicates that the transfer direction is 'in' */
#define UKW_TF_IN_TRANSFER 0x00000001
/* Indicates that the transfer direction is 'out' */
#define UKW_TF_OUT_TRANSFER 0x00000000
/* Specifies that the transfer should complete as soon as possible,
* even if no OVERLAPPED structure has been provided. */
#define UKW_TF_NO_WAIT 0x00000100
/* Indicates that transfers shorter than the buffer are ok */
#define UKW_TF_SHORT_TRANSFER_OK 0x00000200
#define UKW_TF_SEND_TO_DEVICE 0x00010000
#define UKW_TF_SEND_TO_INTERFACE 0x00020000
#define UKW_TF_SEND_TO_ENDPOINT 0x00040000
/* Don't block when waiting for memory allocations */
#define UKW_TF_DONT_BLOCK_FOR_MEM 0x00080000
/* Value to use when dealing with configuration values, such as UkwGetConfigDescriptor,
* to specify the currently active configuration for the device. */
#define UKW_ACTIVE_CONFIGURATION -1
DLL_DECLARE(WINAPI, HANDLE, UkwOpenDriver, ());
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceList, (HANDLE, LPUKW_DEVICE, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwReleaseDeviceList, (HANDLE, LPUKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceAddress, (UKW_DEVICE, unsigned char*, unsigned char*, unsigned long*));
DLL_DECLARE(WINAPI, BOOL, UkwGetDeviceDescriptor, (UKW_DEVICE, LPUKW_DEVICE_DESCRIPTOR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfigDescriptor, (UKW_DEVICE, DWORD, LPVOID, DWORD, LPDWORD));
DLL_DECLARE(WINAPI, void, UkwCloseDriver, (HANDLE));
DLL_DECLARE(WINAPI, BOOL, UkwCancelTransfer, (UKW_DEVICE, LPOVERLAPPED, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueControlTransfer, (UKW_DEVICE, DWORD, LPUKW_CONTROL_HEADER, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwClaimInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwReleaseInterface, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwSetInterfaceAlternateSetting, (UKW_DEVICE, DWORD, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltHost, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwClearHaltDevice, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwGetConfig, (UKW_DEVICE, PUCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwSetConfig, (UKW_DEVICE, UCHAR));
DLL_DECLARE(WINAPI, BOOL, UkwResetDevice, (UKW_DEVICE));
DLL_DECLARE(WINAPI, BOOL, UkwKernelDriverActive, (UKW_DEVICE, DWORD, PBOOL));
DLL_DECLARE(WINAPI, BOOL, UkwAttachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwDetachKernelDriver, (UKW_DEVICE, DWORD));
DLL_DECLARE(WINAPI, BOOL, UkwIssueBulkTransfer, (UKW_DEVICE, DWORD, UCHAR, LPVOID, DWORD, LPDWORD, LPOVERLAPPED));
DLL_DECLARE(WINAPI, BOOL, UkwIsPipeHalted, (UKW_DEVICE, UCHAR, LPBOOL));
// Used to determine if an endpoint status really is halted on a failed transfer.
#define STATUS_HALT_FLAG 0x1
struct wince_device_priv {
UKW_DEVICE dev;
UKW_DEVICE_DESCRIPTOR desc;
};
struct wince_device_handle_priv {
// This member isn't used, but only exists to avoid an empty structure
// for private data for the device handle.
int reserved;
};
struct wince_transfer_priv {
struct winfd pollable_fd;
uint8_t interface_number;
};

View File

@@ -1 +1 @@
#define LIBUSB_NANO 10595
#define LIBUSB_NANO 10596

View File

@@ -23,14 +23,22 @@
/* Message logging */
#define ENABLE_LOGGING 1
/* Windows backend */
/* Windows/WinCE backend */
#if defined(_WIN32_WCE)
#define OS_WINCE 1
#else
#define OS_WINDOWS 1
#endif
/* type of second poll() argument */
#define POLL_NFDS_TYPE unsigned int
#if !defined(_WIN32_WCE)
/* Define to 1 if you have the <signal.h> header file. */
#define HAVE_SIGNAL_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
#endif

100
msvc/errno.h Normal file
View File

@@ -0,0 +1,100 @@
/*
* errno.h
* This file has no copyright assigned and is placed in the Public Domain.
* This file is a part of the mingw-runtime package.
* No warranty is given; refer to the file DISCLAIMER within the package.
*
* Error numbers and access to error reporting.
*
*/
#ifndef _ERRNO_H_
#define _ERRNO_H_
#include <crtdefs.h>
/*
* Error numbers.
* TODO: Can't be sure of some of these assignments, I guessed from the
* names given by strerror and the defines in the Cygnus errno.h. A lot
* of the names from the Cygnus errno.h are not represented, and a few
* of the descriptions returned by strerror do not obviously match
* their error naming.
*/
#define EPERM 1 /* Operation not permitted */
#define ENOFILE 2 /* No such file or directory */
#define ENOENT 2
#define ESRCH 3 /* No such process */
#define EINTR 4 /* Interrupted function call */
#define EIO 5 /* Input/output error */
#define ENXIO 6 /* No such device or address */
#define E2BIG 7 /* Arg list too long */
#define ENOEXEC 8 /* Exec format error */
#define EBADF 9 /* Bad file descriptor */
#define ECHILD 10 /* No child processes */
#define EAGAIN 11 /* Resource temporarily unavailable */
#define ENOMEM 12 /* Not enough space */
#define EACCES 13 /* Permission denied */
#define EFAULT 14 /* Bad address */
/* 15 - Unknown Error */
#define EBUSY 16 /* strerror reports "Resource device" */
#define EEXIST 17 /* File exists */
#define EXDEV 18 /* Improper link (cross-device link?) */
#define ENODEV 19 /* No such device */
#define ENOTDIR 20 /* Not a directory */
#define EISDIR 21 /* Is a directory */
#define EINVAL 22 /* Invalid argument */
#define ENFILE 23 /* Too many open files in system */
#define EMFILE 24 /* Too many open files */
#define ENOTTY 25 /* Inappropriate I/O control operation */
/* 26 - Unknown Error */
#define EFBIG 27 /* File too large */
#define ENOSPC 28 /* No space left on device */
#define ESPIPE 29 /* Invalid seek (seek on a pipe?) */
#define EROFS 30 /* Read-only file system */
#define EMLINK 31 /* Too many links */
#define EPIPE 32 /* Broken pipe */
#define EDOM 33 /* Domain error (math functions) */
#define ERANGE 34 /* Result too large (possibly too small) */
/* 35 - Unknown Error */
#define EDEADLOCK 36 /* Resource deadlock avoided (non-Cyg) */
#define EDEADLK 36
/* 37 - Unknown Error */
#define ENAMETOOLONG 38 /* Filename too long (91 in Cyg?) */
#define ENOLCK 39 /* No locks available (46 in Cyg?) */
#define ENOSYS 40 /* Function not implemented (88 in Cyg?) */
#define ENOTEMPTY 41 /* Directory not empty (90 in Cyg?) */
#define EILSEQ 42 /* Illegal byte sequence */
/*
* NOTE: ENAMETOOLONG and ENOTEMPTY conflict with definitions in the
* sockets.h header provided with windows32api-0.1.2.
* You should go and put an #if 0 ... #endif around the whole block
* of errors (look at the comment above them).
*/
#ifndef RC_INVOKED
#ifdef __cplusplus
extern "C" {
#endif
/*
* Definitions of errno. For _doserrno, sys_nerr and * sys_errlist, see
* stdlib.h.
*/
#if defined(_UWIN) || defined(_WIN32_WCE)
#undef errno
extern int errno;
#else
_CRTIMP int* __cdecl _errno(void);
#define errno (*_errno())
#endif
#ifdef __cplusplus
}
#endif
#endif /* Not RC_INVOKED */
#endif /* Not _ERRNO_H_ */

80
msvc/missing.c Normal file
View File

@@ -0,0 +1,80 @@
/*
* Source file for missing WinCE functionality
* Copyright © 2012 RealVNC Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "missing.h"
#include <config.h>
#include <libusbi.h>
#include <windows.h>
// The registry path to store environment variables
#define ENVIRONMENT_REG_PATH _T("Software\\libusb\\environment")
/* Workaround getenv not being available on WinCE.
* Instead look in HKLM\Software\libusb\environment */
char *getenv(const char *name)
{
static char value[MAX_PATH];
TCHAR wValue[MAX_PATH];
WCHAR wName[MAX_PATH];
DWORD dwType, dwData;
HKEY hkey;
LONG rc;
if (!name)
return NULL;
if (MultiByteToWideChar(CP_UTF8, 0, name, -1, wName, MAX_PATH) <= 0) {
usbi_dbg("Failed to convert environment variable name to wide string");
return NULL;
}
wName[MAX_PATH - 1] = 0; // Be sure it's NUL terminated
rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, ENVIRONMENT_REG_PATH, 0, KEY_QUERY_VALUE, &hkey);
if (rc != ERROR_SUCCESS) {
usbi_dbg("Failed to open registry key for getenv with error %d", rc);
return NULL;
}
// Attempt to read the key
dwData = sizeof(wValue);
rc = RegQueryValueEx(hkey, wName, NULL, &dwType,
(LPBYTE)&wValue, &dwData);
RegCloseKey(hkey);
if (rc != ERROR_SUCCESS) {
usbi_dbg("Failed to read registry key value for getenv with error %d", rc);
return NULL;
}
if (dwType != REG_SZ) {
usbi_dbg("Registry value was of type %d instead of REG_SZ", dwType);
return NULL;
}
// Success in reading the key, convert from WCHAR to char
if (WideCharToMultiByte(CP_UTF8, 0,
wValue, dwData / sizeof(*wValue),
value, MAX_PATH,
NULL, NULL) <= 0) {
usbi_dbg("Failed to convert environment variable value to narrow string");
return NULL;
}
value[MAX_PATH - 1] = 0; // Be sure it's NUL terminated
return value;
}

29
msvc/missing.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* Header file for missing WinCE functionality
* Copyright © 2012 RealVNC Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MISSING_H
#define MISSING_H
/* Windows CE doesn't have any APIs to query environment variables.
*
* This contains a registry based implementation of getenv.
*/
char *getenv(const char *name);
#endif

View File

@@ -18,8 +18,10 @@
*/
#include <stdio.h>
#include <sys/types.h>
#include <memory.h>
#if !defined(_WIN32_WCE)
#include <sys/types.h>
#endif
#include "libusb.h"

View File

@@ -23,11 +23,17 @@
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#if !defined(_WIN32_WCE)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
#ifdef _WIN32
#if defined(_WIN32_WCE)
// No support for selective redirection of STDOUT on WinCE.
#define DISABLE_STDOUT_REDIRECTION
#define STDOUT_FILENO 1
#elif defined(_WIN32)
#include <io.h>
#define dup _dup
#define dup2 _dup2
@@ -72,6 +78,7 @@ static void print_usage(int argc, char ** argv)
static void cleanup_test_output(libusbx_testlib_ctx * ctx)
{
#ifndef DISABLE_STDOUT_REDIRECTION
if (ctx->output_file != NULL) {
fclose(ctx->output_file);
ctx->output_file = NULL;
@@ -84,6 +91,7 @@ static void cleanup_test_output(libusbx_testlib_ctx * ctx)
close(ctx->null_fd);
ctx->null_fd = INVALID_FD;
}
#endif
}
/**
@@ -92,6 +100,11 @@ static void cleanup_test_output(libusbx_testlib_ctx * ctx)
*/
static int setup_test_output(libusbx_testlib_ctx * ctx)
{
#ifdef DISABLE_STDOUT_REDIRECTION
ctx->output_fd = STDOUT_FILENO;
ctx->output_file = stdout;
return 0;
#else
/* Keep a copy of STDOUT for test output */
ctx->output_fd = dup(STDOUT_FILENO);
if (ctx->output_fd < 0) {
@@ -122,6 +135,7 @@ static int setup_test_output(libusbx_testlib_ctx * ctx)
}
}
return 0;
#endif
}
void libusbx_testlib_logf(libusbx_testlib_ctx * ctx,