libusb-win32

 

Take note the latest version can be found in the  libusb-win32 Sourceforge Trac Wiki.

 libusb-win32 is a port of the USB library libusb-0.1 to the Microsoft Windows operating systems (Windows 98 SE, Windows ME, Windows 2000, Windows XP, Windows Vista and Windows 7. Starting from version 1.1.14.0, libusb-win32 support of Win98SE and WinME is dropped due to the age of these Operating systems.

Vista/7 64 bit are supported from version 1.2.0.0 since a Microsoft KMCS accepted digital signature is embedded in the kernel driver libusb0.sys. libusb-win32 based device drivers can also be submitted for Microsoft WHQL testing. Several companies have successfully finished the WHQL testing with their libusb-win32 based driver package. This will allow the customers to install the driver without a warning under current 32bit/64bit Windows. However, the latest Windows Logo Kit (WLK) license lists GPL as an "excluded license" so that WHQL submission will not be possible right now. The project administrators will try to address the issue by releasing the driver with dual license in the future: Modified_BSD and GPL v3 license.

Features:

  • Can be used as a filter driver for existing, already installed devices. This feature allows libusb-win32 to communicate with almost any installed USB device. The filter driver may cause problems for certain device. Therefore it should not be used by normal users. Rather it should be considered more as a development tool for developers or power users of Windows.

Starting with v1.2.2.0, a GUI (filter wizard) is provided and it is only to attach the filter driver to particular USB device of interests. So this should be safer to use than the older behavior which tries to attach the filter to all USB device (acting as class filters to all possible device class). It is still possible to do that by using the console version of install-filter.exe but this is only recommended to be used by developers and power users.

  • Can be used as a normal device driver for devices for which no driver exists (self build/developed USB hardware, etc). You can also replace the existing device driver with libusb-win32 device driver if desired. This is the preferred way to use libusb-win32.
  • The two methods described above can used in parallel.
  • 100% API and functional compatible with the libusb 0.1 project.
  • Supports all USB transfer: Control, Bulk, Interrupt and Isochronous transfers. Take note libusb 0.1 does not support Isochronous Transfer under other Operating Systems like Linux.
  • Supports all Standard Device Requests (control messages) described in chapter 9 of the USB specification.
  • Supports vendor specific control messages.

License

  • The library (including DLL, import libraries, examples and installers) is distributed under the terms of the GNU Lesser General Public License ( LGPL).
  • The driver is distributed under the terms of the GNU General Public License ( GPL).
  • This license combination explicitly allows the use of this library in commercial, non Open Source applications. Read the licenses carefully and apply all of their requirements before including this library in a commercial application!
  • In the future the project administrators will add a New BSD option to the license to address the WHQL issue.

Support

If something isn't working as expected, make sure that you have installed the latest service packs for your OS and the latest version of libusb-win32 before requesting for any support.

Available Support Options:

  • A  mailing list is available for discussions, questions, bug reports, feature request, and other issues. It is the preferred support channel. Please subscribe to the list first before posting.
  • The project page offers different forms which can be filled out to get support, to report bugs, or to request new features. Please describe your problems and your system as precise as possible (OS, service packs, version of libusb-win32, type of device, output of "testlibusb-win.exe", etc.). This will make solving problems a lot easier.
  • Debug version of the libusb-win32 are provided from libusb-1.2.3.0 onwards. Together with Microsoft debugview, detailed debug information can be printed out to facilitate easier debugging process.

Download

Source code and binary packages can be downloaded from the  project download site. Source code is also available via anonymous Subversion.

Installation

Installation

Filter Driver Installation

  • Please use the latest release version.
  • Versions up until 0.1.12.2 have serious bugs related to the filter drivers under Vista and Windows 7 and some XP installations. Please use later versions (1.1.14.0 or newer). For 64bit Windows Vista/7/2008/2008R2, the version should be 1.2.0.0 or later.
  • The filters driver is installed by a user friendly GUI installer which makes the install and uninstall process easier and more secure. Starting with 1.2.2.0, a GUI for installing the filter driver (Filter Wizard) is the preferred way to use the filter. It only tries to attach the filter driver to a particular USB device. You can still use the command line install-filter.exe application to install class filter. But it is not recommended.
  • Log in as a user with administrator privileges.
  •  Download the latest filter driver installer (libusb-win32-devel-filter-x.x.x.x.zip) and then unzip).
  • Close all applications which use USB devices before installing.
  • Run the installer, and follow its instructions. Do not run the installer from an USB storage device!
  • At the end of the installation process the installer will offer to run a test program. This program will verify the correct installation and print the descriptors of all USB devices accessible by the library. The test program can also be run later from the system's start menu.
  • A reboot isn't necessary but is recommended.

Device Driver Installation

  • Please use the latest release version.
  • The device driver is distributed as a separate package which includes everything to use libusb-win32 for single devices as a normal device driver. The installation of the filter driver is not necessary any more!
  • Log in as a user with administrator privileges.
  •  Download the latest device driver binary package (libusb-win32-device-bin-x.x.x.x.zip or tar.gz).
  • Extract it to a temporary directory.
  • Use the INFWizard program to generate the INF file (modify the vendor and product IDs, strings etc). Create different inf-files to install different types of devices (devices with different IDs).
  • Unplug the device(s) from the system.
  • Open the Windows Device Manager and remove all incorrectly installed USB devices (device entries with a yellow exclamation mark).
  • Reconnect the device(s) to the system.
  • When Windows asks for a driver, choose the inf-file(s) created above. When Windows asks for a driver, choose the inf-file(s) created above. Windows will warn that the driver is is not 'digitally signed'. Ignore this message and continue with the installation. As of version V1.2.0.0, a valid digital signature is embedded inside libusb0.sys for AMD/Intel x86_64 version of Windows so that the users can install the driver as well under 64bit x86_64 version of Windows Vista/7/2008/2008R2. Please read more about the Microsoft Kernel Mode Code Signing (KMCS) policy for more information.
  • Open the Windows Device Manager to verify that the device is installed correctly. Run the test program (testlibusb-win.exe) from the 'bin directory'. It should print out the descriptors of your device(s).
  • A reboot isn't necessary.
  • Starting from version 1.2.1.0, the inf-wizard.exe has embedded driver binaries and provide an option to install the driver at the end of the process.

Removing

Removing the Filter Driver

  • To remove the filter driver open the Control Panel, open 'Software', choose the 'LibUsb?-Win32-x.x.x.x' entry, and remove it.
  • A reboot isn't necessary.
  • If the above failed, you can manually run "install-filer -u" as admin. After that you can remove the other relevant files.

Removing the Device Driver

  • To remove device filter driver, run the GUI filter driver wizard to remove it.
  • The device driver can not be easily removed from the system. You can however try to use usbdeview to remove the entries. Under Vista and Windows 7, you can use pnputil to remove the driver package.

Updating

Updating the Filter Driver

  • Remove the old version first (see above). This is the recommended method.
  • Install the new version as described above.

Updating the Device Driver

  •  Download the latest device driver binary package (libusb-win32-bin-x.x.x.x.zip).
  • Modify the inf-file as described in the Installation section.
  • Open the Device Manager and select the device you want to update.
  • Choose 'Properties->Driver->Update'. Disable the automatic installation and select the new inf-file manually.
  • Since 1.2.1.0, inf-wizard.exe GUI program can be used to automatically install/update the device driver.

Development

Requirements to build libusb-win32 from source package

  • A WinXP or later system.
  • The Windows WDK 6001.18002 or later. You can get  WDK from Microsoft . From 1.1.14.0 onwards, WDK will be the official tools to build the kernel driver files since it is the primary tools Windows driver developers use. It will be the official tools to build the release packages as well.
  •  MinGW/Msys is required to build the MinGW GCC import library.
  •  Cygwin is not officially supported but there is a port of libusb-win32 for Cygwin.
  •  Borland C++ 5.5 or above is required to build the import library file for Borland C++.
  •  Inno Setup 5 or above install system is required if you want to build the installer.

Build Process

Until 0.1.12.2 (including 0.1.12.2), the package is built with a standard Makefile under MinGW/MSys or Cygwin. Starting from version 1.1.4.0, MinGW/MSys can only be used to to build 32bit library and test programs.

  • Download the latest source code.
  • From a Msys shell run the command "make" to build the library and test programs.

Starting from version 1.1.4.0, batch files in the DDK_MAKE directory will be the main tools to build the driver, library, and distribution packages.

  • Download the latest source code.
  • Edit make.cfg according to your particular setup (WDK directory, locations of MinGW, Borland C++, Inno Setup, etc).
  • Use the provided batch files to the build the 32bit/64bit drivers, library and test programs. Please refer to the output of "make.cmd" for more build options.
  • To build the distribution archives and the installer run "make.cmd dist". Please refer to the output of "make.cmd" for more build options.

For developers who want to use libusb-wi32

  • To use libusb-win32 in your own programs include the supplied header file usb.h, and link against the import library (libraries for GCC, BCC, and MSVC 32bit/64bit are available).
  • To avoid any version conflicts, DO NOT include the DLL libusb0.dll in your application's directory. The DLL is part of the driver and installed automatically to the Windows system directory.
  • If you are porting a libusb 0.1.x based program from Unix style systems to Windows, remove all references to the library's global variable usb_busses. Use the function usb_get_busses() instead to get this variable. Global variables in shared libraries (DLLs) do not work well on Windows systems across different compilers. Please also take note that libusb-win32 differentiate IN Endpoints and OUT Endpoints. So IN Endpoint 1 is 0x81 and OUT Endpoint 1 is 0x01.
  • Please also refer to the following section on documentation and examples.

Documentation and Examples

This is the detailed  libusb-win32 Documentation.

The excellent  libusb-1.0 documentation can also serve as a good reference even though the API is not compatible.

The codes can also serve as some kind of documentation for the libusb-win32 developers. However, examples are often the best documentations for Open Source Projects like libusb and libusb-win32, especially for the users of the library. Here are some links to  projects and code examples using libusb-0.1 and libusb-win32. Language wrappers (Dotnet, Python, Perl, Ruby, Java, etc) are also listed.

Portability

libusb-0.1 is widely supported by operating systems like Linux, FreeBSD, NetBSD, OpenBSD, Darwin/MacOS X and Solaris. libusb-win32 is API compatible with libusb 0.1. So it will greatly help you porting your libusb-0.1 based application to Windows.

FreeBSD 8/9 includes a new FreeBSD-specific reimplementation of the libusb-0.1 API, so your applications will probably work there too. The source code for this library can be found here.

Mailing list

The libusb-win32-devel mailing list exists for both users of the library and developers interested in contributing to the library itself.

  •  Subscribe
  •  Archives at SourceForge
  •  Archives at GMANE
  •  Archives at Nabble
  •  libusb-0.1: The original libusb-0.1 project from which libusb-win32 is derived.
  • libusb.org: The new libusb website.
  •  libusbdotnet: .Net and Mono wrapper for libusb, libusb-win32 and more.
  •  pyusb: Python wrapper for libusb, libusb-win32 and more.
  •  usb.org: The place to get USB specifications and other general information about USB.
  •  www.lvr.com: A lot of information about USB hardware and software development.
  •  Beyondlogic.org: Another site with information about USB hardware and software development.
  •  USB Made Simple: Introduction to the ABCs of USB.
  •  MCCI: Sells commercial generic USB drivers for Windows.
  •  Jungo: Another vendor of generic USB drivers.
  •  Thesycon: Another vendor of generic USB drivers.
  •  Microsoft MSDN: You can find Windows specific information about USB Driver development from MSDN.
  • libusb-1.0 Windows Backend: Related project -- libusb-1.0 Windows backend
  • libwdi: Related project -- Windows Driver Installer library libwdi

 

 

The following documentation is based on libusb-0.1 API documentation by Johannes Erdfelt.

Preface

The purpose of this document is to explain the libusb-win32 API and how to use it to make a USB aware application. Any suggestions, corrections and comments regarding this document should be sent to the libusb-win32 developers mailing list.

I. Introduction¶

This documentation will provide an overview of how the v0.1 libusb API works and relates to USB. It is assumed that the reader has a good understanding of the USB 2.0 specification. The USB 2.0 specification can be found the USB Implementers Forum website (http://www.usb.org). libusb-0.1 works under Linux, FreeBSD, NetBSD, OpenBSD; Darwin/MacOS X and Solaris. libusb-win32 is API compatible with libusb-0.1 but also includes some new features.

II. API¶

This is the external API for applications to use. The API is relatively lean and designed to closely correspond with the USB 2.0 specification.

Devices and interfaces

The libusb API ties an open device to a specific interface. This means that if you want to claim multiple interfaces on a device, you should open the device multiple times to receive one usb_dev_handle for each interface you want to communicate with. Don't forget to call usb_claim_interface().

Timeouts in libusb are always specified in milliseconds.

libusb uses both abstracted and non abstracted structures to maintain portability.

All functions in the original libusb v0.1 are synchronous, meaning the functions block and wait for the operation to finish or timeout before returning execution to the calling application. libusb-win32 adds some asynchronous APIs. libusb-1.0 has more asynchronous API support.

There are two types of return values used in libusb v0.1. The first is a handle returned by usb_open(). The second is an int. In all cases where an int is returned, >= 0 is a success and < 0 is an error condition.

Timeout The unit for timeout value is ms.

Under Linux libusb-0.1 (which only supports synchronous API), timeout value of 0 means infinite. libusb-win32 version 1.2.4.7 and later will follow this for synchronous API. Before that, it behaves differently from Linux libusb-0.1.

Since Windows (same for Linux and Mac OS X) is not an RTOS, it is not a good idea to use small timeout value like 10ms or 100ms.

Caveats of synchronous transfer when timeout happens How synchronous API works: 1) Submits read request to driver 2) Waits the specified timeout usingWaitForSingleObject?()

  1. if a wait timeout occurred, send abort pipe request and return -116
  2. if wait succeeded, get transfer results via GetOverlappedResults?() and return error or transfer length.

So, if a transfer completes just after a timeout is detected in 2a, the entire transfer is lost.

There are currently a couple ways to avoid this: 1) Use the async transfer functions and usb_reap_async_nocancel() 2) Use the sync transfer functions from within their own thread and always use INFINITE for the timeout.

Reported Error Codes

/* Connection timed out */ #define ETRANSFER_TIMEDOUT 116

Standard Error Codes from WDK crt errno.h and the explanation from MinGW are listed here. Take note that not all error codes below are used.

#define EPERM		1	/* Operation not permitted */ 
#define	ENOENT		2	/* No entry, ENOFILE, no such file or directory */
#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 */
#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 */
#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) */
#define	EDEADLK		36      /* Resource deadlock avoided */
#define	ENAMETOOLONG	38	/* Filename too long */
#define	ENOLCK		39	/* No locks available */
#define	ENOSYS		40	/* Function not implemented */
#define	ENOTEMPTY	41	/* Directory not empty */

III. Functions¶

1. Core

These functions comprise the core of libusb. They are used by all applications that utilize libusb.


usb_init()
Name
usb_init -- Initialize libusb
Description
void usb_init(void);

Just like the name implies, usb_init sets up some internal structures. usb_init must be called before any other libusb functions.


usb_find_busses()
Name
usb_find_busses -- Finds all USB busses on system
Description
int usb_find_busses(void);

usb_find_busses will find all of the busses on the system. Returns the number of changes since previous call to this function (total of new busses and busses removed).


usb_find_devices()
Name
usb_find_devices -- Find all devices on all USB devices
Description
int usb_find_devices(void);

usb_find_devices() will find all of the devices on each bus. This should be called after usb_find_busses(). Returns the number of changes since the previous call to this function (total of new device and devices removed).


usb_get_busses()
Name
usb_get_busses -- Return the list of USB busses found
Description
struct usb_bus *usb_get_busses(void);

usb_get_busses() simply returns the value of the global variable usb_busses. This was implemented for those languages that support C calling convention and can use shared libraries, but don't support C global variables (like Delphi).


usb_set_debug()
Name
usb_set_debug -- set debug message verbose level
Description
void usb_set_debug(int level);

usb_set_debug() sets the debug message verbose level. You can set it to 4 to print the debug message which is quite verbose.

0 LOG_OFF, 1 LOG_ERROR, 2 LOG_WARNING, 3 LOG_INFO, 4 LOG_DEBUG,


2. Device operations

This group of functions deal with the device. It allows you to open and close the device as well standard USB operations like setting the configuration, alternate settings, clearing halts and resetting the device. It also provides OS level operations such as claiming and releasing interfaces.


usb_open()
Name
usb_open -- Opens a USB device
Description
usb_dev_handle *usb_open(struct *usb_device dev);

usb_open() is to be used to open up a device for use. usb_open must be called before attempting to perform any operations to the device. Returns a handle used in future communication with the device.


usb_close()
Name
usb_close -- Closes a USB device
Description
int usb_close(usb_dev_handle *dev);

usb_close closes a device opened with usb_open. No further operations may be performed on the handle after usb_close is called. Returns 0 on success or < 0 on error.


usb_set_configuration()
Name
usb_set_configuration -- Sets the active configuration of a device
Description
int usb_set_configuration(usb_dev_handle *dev, int configuration);

usb_set_configuration sets the active configuration of a device. The configuration parameter is the value as specified in the descriptor field bConfigurationValue. Returns 0 on success or < 0 on error.

Must be called!: usb_set_configuration must be called with a valid configuration (not 0) before you can claim the interface. This might not be necessary in the future. This behavior is different from Linux libusb-0.1.


usb_set_altinterface()
Name
usb_set_altinterface -- Sets the active alternate setting of the current interface
Description
int usb_set_altinterface(usb_dev_handle *dev, int alternate);

usb_set_altinterface() sets the active alternate setting of the current interface. The alternate parameter is the value as specified in the descriptor field bAlternateSetting. Returns 0 on success or < 0 on error.


usb_resetep()
Name
usb_resetep -- Resets state for an endpoint
Description
int usb_resetep(usb_dev_handle *dev, unsigned int ep);

usb_resetep resets all state (like toggles) for the specified endpoint. The ep parameter is the value specified in the descriptor field bEndpointAddress. Returns 0 on success or < 0 on error.

Deprecated: usb_resetep is deprecated. You probably want to use usb_clear_halt.


usb_clear_halt()
Name
usb_clear_halt -- Clears any halt status on an endpoint
Description
int usb_clear_halt(usb_dev_handle *dev, unsigned int ep);

usb_clear_halt() clears any halt status on the specified endpoint. The ep parameter is the value specified in the descriptor field bEndpointAddress. Returns 0 on success or < 0 on error.


usb_reset()
Name
usb_reset -- Resets a device
Description
int usb_reset(usb_dev_handle *dev);
usb_reset() resets the specified device by sending a RESET down the port it is connected to. Returns 0 on success or < 0 on error.

Causes re-enumeration: After calling usb_reset, the device will need to re-enumerate and thus requires you to find the new device and open a new handle. The handle used to call usb_reset() will no longer work.


usb_claim_interface()
Name
usb_claim_interface -- Claim an interface of a device
Description
int usb_claim_interface(usb_dev_handle *dev, int interface);

usb_claim_interface() claims the interface with the Operating System. The interface parameter is the value as specified in the descriptor field bInterfaceNumber. Returns 0 on success or < 0 on error.

Must be called!: usb_claim_interface must be called before you perform any operations related to this interface (like usb_set_altinterface, usb_bulk_write, etc).

Return Codes for usb_claim_interface():
code description
-EBUSY Interface is not available to be claimed
-ENOMEM Insufficient memory


usb_release_interface()
Name
usb_release_interface -- Releases a previously claimed interface
Description
int usb_release_interface(usb_dev_handle *dev, int interface);

usb_release_interface() releases an interface previously claimed with usb_claim_interface. The interface parameter is the value as specified in the descriptor field bInterfaceNumber. Returns 0 on success or < 0 on error.


3. Control Transfers¶

This group of functions allow applications to send messages to the default control pipe.


usb_control_msg()
Name
usb_control_msg -- Send a control message to a device
Description
int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);

usb_control_msg() performs a control request to the default control pipe on a device. The parameters mirror the types of the same name in the USB specification. Returns number of bytes written/read or < 0 on error.


usb_get_string()
Name
usb_get_string -- Retrieves a string descriptor from a device
Description
int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);

usb_get_string() retrieves the string descriptor specified by index and langid from a device. The string will be returned in Unicode as specified by the USB specification. Returns the number of bytes returned in buf or < 0 on error.


usb_get_string_simple()
Name
usb_get_string_simple -- Retrieves a string descriptor from a device using the first language
Description
int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);

usb_get_string_simple() is a wrapper around usb_get_string that retrieves the string description specified by index in the first language for the descriptor and converts it into C style ASCII. Returns number of bytes returned in buf or < 0 on error.


usb_get_descriptor()
Name
usb_get_descriptor -- Retrieves a descriptor from a device's default control pipe
Description
int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);

usb_get_descriptor() retrieves a descriptor from the device identified by the type and index of the descriptor from the default control pipe. Returns number of bytes read for the descriptor or < 0 on error.
See usb_get_descriptor_by_endpoint() for a function that allows the control endpoint to be specified.


usb_get_descriptor_by_endpoint()
Name
usb_get_descriptor_by_endpoint -- Retrieves a descriptor from a device
Description
int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);

usb_get_descriptor_by_endpoint() retrieves a descriptor from the device identified by the type and index of the descriptor from the control pipe identified by ep. Returns number of bytes read for the descriptor or < 0 on error.


4. Bulk Transfers¶

This group of functions allow applications to send and receive data via bulk pipes.


usb_bulk_write()
Name
usb_bulk_write -- Write data to a bulk endpoint
Description
int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

usb_bulk_write() performs a bulk write request to the endpoint specified by ep. Returns number of bytes written on success or < 0 on error.


usb_bulk_read()
Name
usb_bulk_read -- Read data from a bulk endpoint
Description
int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

usb_bulk_read() performs a bulk read request to the endpoint specified by ep. Returns number of bytes read on success or < 0 on error.


5. Interrupt Transfers¶

This group of functions allow applications to send and receive data via interrupt pipes.


usb_interrupt_write()
Name
usb_interrupt_write -- Write data to an interrupt endpoint
Description
int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

usb_interrupt_write() performs an interrupt write request to the endpoint specified by ep. Returns number of bytes written on success or < 0 on error.


usb_interrupt_read()
Name
usb_interrupt_read -- Read data from a interrupt endpoint
Description
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

usb_interrupt_read performs a interrupt read request to the endpoint specified by ep. Returns number of bytes read on success or < 0 on error.


6. Asynchronous API and Isochronous Transfer¶

Windows Specific

libusb-win32 supports Isochronous Transfer through its Asynchronous API. The libusb-win32 Asynchronous API also supports the other transfer types like Control Transfer, Interrupt Transfer and Bulk Transfer.

int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, unsigned char ep, int pktsize);

Allocates an asynchonous request for endpoint 'ep' and returns that request in 'context'.
Returns 0 on success, < 0 on failure.

int usb_bulk_setup_async(usb_dev_handle *dev, void **context, unsigned char ep);

Allocates an asynchonous request for endpoint 'ep' and returns that request in 'context'.
Returns 0 on success, < 0 on failure.

int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, unsigned char ep);

Allocates an asynchonous request for endpoint 'ep' and returns that request in 'context'.
Returns 0 on success, < 0 on failure.

int usb_submit_async(void *context, char *bytes, int size);

Submits a previously allocated request to the device. Data pointed to by 'bytes' of size 'size' will be written or read to or from the device depending on the endpoint's direction bit.
Returns 0 on success, < 0 on failure.

int usb_reap_async(void *context, int timeout);

Waits for the request to finish. Returns the number of bytes written/read or < 0 on failure.
The request will be canceled if it doesn't complete within 'timeout' (in ms).

int usb_reap_async_nocancel(void *context, int timeout);

Same as usb_reap_async() but doesn't cancel the request if it times out. Therefore you can try to reap it later.

int usb_cancel_async(void *context);

Cancels a request.

int usb_free_async(void **context);

Frees a request.

* Usage:

 char data[1024];
 void *request;
 int read;
 if(usb_bulk_setup_async(dev, &request, 0x81) < 0) {
   // error handling
 }
 if(usb_submit_async(request, data, sizeof(data)) < 0) {
   // error handling
 }
 read =  usb_reap_async(request, 1000);
 if(read >= 0)
 printf("read %d bytes\n", read);
 else
   // error handling
 usb_free_async(&request);

7. Non Portable¶

These functions are non portable. They may expose some part of the USB API on one OS or perhaps more, but not all. They are all marked with the string _np at the end of the function name.

A C preprocessor macro will be defined if the function is implemented. The form is LIBUSB_HAS_ prepended to the function name, without the leading "usb_", in all caps. For example, if usb_get_driver_np is implemented, LIBUSB_HAS_GET_DRIVER_NP will be defined.

Linux Specific


usb_get_driver_np()
Name
usb_get_driver_np -- Get driver name bound to interface
Description
int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name, int namelen);

This function will obtain the name of the driver bound to the interface specified by the parameter interface and place it into the buffer named name limited to namelen characters. Returns 0 on success or < 0 on error. Implemented on Linux only.


usb_detach_kernel_driver_np()
Name
usb_detach_kernel_driver_np -- Detach kernel driver from interface
Description
int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface);

This function will detach a kernel driver from the interface specified by parameter interface. Applications using libusb can then try claiming the interface. Returns 0 on success or < 0 on error. Implemented on Linux only.


Windows Specific

/* Windows specific functions */

const struct usb_version *usb_get_version(void);

Return the library version.

The following functions are related to driver installation (device driver mode of filter driver mode). Normally you should not use them. You can bundle the GUI Inf-Wizard with your application. Or you can choose to write your own driver installation applications.libwdi orWDK DIFx can be used for that purpose. You can combine libwdi/DIFx with installers likeInno Setup orNSIS.

#define LIBUSB_HAS_INSTALL_SERVICE_NP 1

int usb_install_service_np(void);
void CALLBACK usb_install_service_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show);

#define LIBUSB_HAS_UNINSTALL_SERVICE_NP 1

int usb_uninstall_service_np(void);
void CALLBACK usb_uninstall_service_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show);

#define LIBUSB_HAS_INSTALL_DRIVER_NP 1

int usb_install_driver_np(const char *inf_file);
void CALLBACK usb_install_driver_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show);

#define LIBUSB_HAS_TOUCH_INF_FILE_NP 1

int usb_touch_inf_file_np(const char *inf_file);
void CALLBACK usb_touch_inf_file_np_rundll(HWND wnd, HINSTANCE instance, LPSTR cmd_line, int cmd_show);

#define LIBUSB_HAS_INSTALL_NEEDS_RESTART_NP 1

int usb_install_needs_restart_np(void);

More details to Be Added.

IV. Examples¶

There are some non-intuitive parts of libusb v0.1 that aren't difficult, but are probably easier to understand with some examples.

Basic Examples

Before any communication can occur with a device, it needs to be found. This is accomplished by finding all of the busses and then finding all of the devices on all of the busses:

    	struct usb_bus *busses;
    
    	usb_init();
    	usb_find_busses();
    	usb_find_devices();
    
    	busses = usb_get_busses();

After this, the application should manually loop through all of the busess and all of the devices and matching the device by whatever criteria is needed:

    	struct usb_bus *bus;
    	int c, i, a;
    
    	/* ... */
    
    	for (bus = busses; bus; bus = bus->next) {
    		struct usb_device *dev;
    
    		for (dev = bus->devices; dev; dev = dev->next) {
    			/* Check if this device is a printer */
    			if (dev->descriptor.bDeviceClass == 7) {
    				/* Open the device, claim the interface and do your processing */
    				...
    			}
    
    			/* Loop through all of the configurations */
    			for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
    				/* Loop through all of the interfaces */
    				for (i = 0; i < dev->config[c].bNumInterfaces; i++) {
    					/* Loop through all of the alternate settings */
    					for (a = 0; a < dev->config[c].interface[i].num_altsetting; a++) {
    						/* Check if this interface is a printer */
    						if (dev->config[c].interface[i].altsetting[a].bInterfaceClass == 7) {
    						/* Open the device, set the alternate setting, claim the interface and do your processing */
    						   ...
    						}
    					}
    				}
    			}
    		}
    	}

 

 

你可能感兴趣的:(windows驱动开发,USB)