wiki:libwdi/usage

Version 11 (modified by pbatard, 3 years ago) (diff)

--

[Previous] [Next] [Back to Table of Content ]

API documentation & usage

This section documents the use of the libwdi API.

[TODO: TOC]

Basic usage

For those in a hurry, below is a basic example in C of how one would use libwdi to automatically install a driver, for all driverless USB devices present on a system.

struct wdi_device_info *device, *list;
int r;

r = wdi_create_list(&list, true);
if (r == WDI_SUCCESS) {
    for (device = list; device != NULL; device = device->next) {
        printf("Installing driver for USB device: "%s" (%04X:%04X)
",
            device->desc, device->vid, device->pid);
        if (wdi_create_inf(device, DEFAULT_DIR, INF_NAME, WDI_WINUSB) == WDI_SUCCESS) {
            wdi_install_driver(device, DEFAULT_DIR, INF_NAME);
        }
    }
    wdi_destroy_list(list);
}

In the program excerpt above, first we start by creating a list of all the driverless USB devices on the system using wdi_create_list, with second parameter "driverless_only" set to true. If any are found, the call returns success with a chained list of wdi_device_info elements containing, among other things, the system description of each device, as well as its USB VID & PID.
Using these properties, we then generate an inf through the wdi_create_inf (this step could be skipped if you embedded your own inf in libwdi), and then call wdi_install_driver, which starts the operating system driver installation procedure.

Error Codes

All of the liwdi API function, apart from wdi_strerror and wdi_is_driver_supported, return one of the error codes below.
The wdi_strerror function, documented in the next paragraph, is used to convert an error code to a human readable string.
Success is always indicated by a return value zero (WDI_SUCCESS) while any error will be a negative value.
[TODO: provide examples and common solutions]
[TODO: check if all of these codes are really used]

  • WDI_SUCCESS:
    This code is used to indicate that the function completed successfully. Its value is hardcoded to 0.
  • WDI_ERROR_IO:
    This code indicates that the function call was unable to read or write the data it needs to perform a successful operation.
  • WDI_ERROR_INVALID_PARAM:
    This code is returned when one of the parameters provided by the user is not valid within the scope of the function usage.
  • WDI_ERROR_ACCESS:
    This code indicates that the system explicitly refused access to a resource needed to perform a successful operation.
  • WDI_ERROR_NO_DEVICE:
    This code is returned when either the user is trying to access a USB device that is unavailable, or when a request to enumerate a set of devices finds that none are available.
  • WDI_ERROR_NOT_FOUND:
    This code is returned when a non device element, required for the function to perform a successful operation, is unavailable.
  • WDI_ERROR_BUSY:
    This code is returned when a resource (device, I/O channel, etc) needed for a function's operation and that does not support concurrent access is found busy.
  • WDI_ERROR_TIMEOUT:
    This code reports that an operation that has a time limit expired before it could be completed.
  • WDI_ERROR_OVERFLOW:
    This code indicates that an operation or API call returned more data than was requested.
  • WDI_ERROR_PENDING_INSTALLATION:
    This code indicates that the system is waiting for a previous driver installation operation to complete.
  • WDI_ERROR_INTERRUPTED:
    This code indicates that a system call was interrupted by another process.
  • WDI_ERROR_RESOURCE:
    This code indicates that a system resource required for the function to perform a successful operation, could not be allocated. This can occur if the system is running low on memory or disk, etc.
  • WDI_ERROR_NOT_SUPPORTED:
    This code indicates that the user requested an operation, or combination of operations, that the system does not currently support.
  • WDI_ERROR_EXISTS:
    This code is returned when an operation tried to create an entity (device, resource, etc.) that already exists and can only be unique.
  • WDI_ERROR_USER_CANCEL:
    This code indicates that the end user explicitly cancelled an operation, either when prompted or by forcefully interrupting an operation.
  • WDI_ERROR_NEEDS_ADMIN:
    This code is returned when a process does not have sufficient privileges to perform the administrative operations it requires.
  • WDI_ERROR_WOW64:
    This code is returned when a 32 bit process or operation is being run on in an incompatible 64 bit environment.
  • WDI_ERROR_INF_SYNTAX:
    This code is returned when the driver installation detects either a corrupted or improper inf file.
  • WDI_ERROR_CAT_MISSING:
    This code indicates that the driver installation required the presence of a cat file to match the inf, and could not find it.
  • WDI_ERROR_UNSIGNED:
    This code is returned when the system policy prevents the installation of unsigned drivers.
  • WDI_ERROR_OTHER:
    This code is returned for any error that does not fit in the categories above.

Structures

struct wdi_device_info

This structure provides all the information related to the device installation

  • struct wdi_device_info* next (Optional)
    Used for wdi_device_info chained lists returned by wdi_create_list. If unused, set to NULL.
  • unsigned short vid (Mandatory)
    USB Vendor ID of the USB device.
  • unsigned short pid (Mandatory)
    USB Product ID of the USB device.
  • bool is_composite (Mandatory)
    Whether the device is a composite USB device.
  • unsigned char mi (Optional)
    Interface number for composite devices. If unused, set to 0.
  • char* desc (Mandatory)
    USB Device description string. UTF-8.
  • char* driver (Optional)
    Current driver (service) used by the device. If unused, set to NULL.
  • char* device_id (Optional)
    Microsoft's device URI string. If unused, set to NULL.
  • char* hardware_id (Optional)
    Microsoft's hardware ID string. If unused, set to NULL.

Function Calls

const char* wdi_strerror(int errcode)

Synopsis:

Convert a wdi error code to a human readable string. This can be used to provide a more explicit libwdi error message to the end users of your program.

Parameters:

errcode: The enum wdi_error value to convert to an error message.

Return value:

The error message string.


bool wdi_is_driver_supported(int driver_type)

Synopsis:

Indicates if the selected driver is supported (embedded) in this version of libwdi. This is useful as some versions of libwdi might not to embed all possible drivers.

Parameters:

driver_type: currently, either WDI_WINUSB or WDI_LIBUSB, depending on whether the driver files to be checked are for WinUSB or libusb0.sys.

Return value:

A boolean indicating whether the driver is supported for installation.

Remarks:

The bool type is defined in libwdi.h if needed.


int wdi_create_list(struct wdi_device_info list, bool driverless_only)

Synopsis:

Create a struct wdi_device_info list of USB device currently present on the system.

Parameters:

list: a pointer to a struct wdi_device_info* to act as the start of the list
driverless_only: indicates whether the list should enumerate USB devices that don't have a driver installed (true) or USB devices that have an existing valid driver (false)

Return value:

WDI_SUCCESS if the list of devices was successfully created.
WDI_ERROR_NO_DEVICE if the list is empty (*list will also be set to NULL).
WDI_ERROR_RESOURCE if memory could not be allocated internally.

Remarks:

Currently, driverless devices do not appear in the list returned when driverless_only is false.


int wdi_destroy_list(struct wdi_device_info* list)

Synopsis:

Frees the struct wdi_device_info list returned by wdi_create_list

Parameters:

list: a pointer to the first struct wdi_device_info device in the list

Return value:

Currently, this function always returns WDI_SUCCESS.


int wdi_create_inf(struct wdi_device_info* device_info, char* path, char* inf_name, int driver_type)

Synopsis:

Create an inf file for a specific device.

Parameters:

device_info: a pointer to the struct wdi_device_info device to create the inf for
path: the directory where the inf should be created
inf_name: the name of the inf to generate (including the .inf extension)
driver_type: must be either WDI_WINUSB or WDI_LIBUSB, depending on whether the device should use the WinUSB or libusb0.sys driver

Return value:

WDI_SUCCESS if the inf file was successfully created.
WDI_ERROR_INVALID_PARAM if either one of the parameters is NULL or if driver_type is not WDI_WINUSB or WDI_LIBUSB.
WDI_ERROR_NOT_FOUND if the device_info is missing a description string.
WDI_ERROR_ACCESS if the destination directory, the inf file, or any of the required subdirectories for extraction, cannot be accessed or created.


int wdi_install_driver(struct wdi_device_info* device_info, char* path, char* inf_name)

Synopsis:

Perform the actual driver installation using the inf file named inf_name and driver files located in the directory pointed by path.

Parameters:

device_info: a pointer to the struct wdi_device_info device to install the driver for
path: the directory where the driver and inf files are located created
inf_name: the name of the inf file to use for installation (including the .inf extension)

Return value:

WDI_SUCCESS if the driver was installed successfully.
WDI_ERROR_INVALID_PARAM if either one of the parameters is NULL or the path to the inf file is invalid.
WDI_ERROR_PENDING_INSTALLATION if another driver installation is pending by the OS.
WDI_ERROR_RESOURCE if the pipe and associated event to communicate with the installer process could not be created.
WDI_ERROR_NOT_FOUND if the installer executable process (32 or 64 bit) could not be accessed or the inf file could not be opened.
WDI_ERROR_NEEDS_ADMIN if the installer executable process could not be run with necessary rights on platforms with UAC.
WDI_ERROR_WOW64 if a 32 bit driver installation is attempted on a 64 bit environment.
WDI_ERROR_TIMEOUT if the installer executable process failed to answer in the allocated time.
WDI_ERROR_NOT_FOUND if the installer executable process sent a message that was unrecognised.
WDI_ERROR_EXISTS if the existing driver cannot be overwritten.
WDI_ERROR_INF_SYNTAX if the inf file is not properly formatted.
WDI_ERROR_UNSIGNED if the system policy has been modified from Windows defaults, and is set to reject unsigned drivers.
If this occurs on Windows XP, you might want to revert the driver installation policy to default.
See http://articles.techrepublic.com.com/5100-10878_11-5875443.html
WDI_ERROR_CAT_MISSING if a cat file is required and cannot be located.
WDI_ERROR_USER_CANCEL if the user cancelled the installation process after an UAC prompt.
WDI_ERROR_OTHER for unhandled errors from the installer executable process.


int wdi_set_log_level(int level)

Synopsis:

Sets the logging output level. Log messages are sent either to stderr (in console application mode) or to the registered logger (see below).

Parameters:

level: can be one of LOG_LEVEL_DEBUG, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LOG_LEVEL_ERROR, as defined in libwdi.h.

Return value:

Currently, this function always returns WDI_SUCCESS.


int wdi_register_logger(HWND hWnd, UINT message)

Synopsis:

Register a Window as destination for logging messages. This Window will be notified with a message event and should call wdi_read_logger() to retreive the message data.

Parameters:

hWnd: the handle of the Window that should receive log notification messages. message: the value of the message ID that the logger should send back to the Window when log data is available.

Return value:

WDI_SUCCESS if the logger was successfully registered.
WDI_ERROR_EXISTS if a logger has already been registered.

Remarks:

Only one Window can be registered to receive logging messages at any one time.


int wdi_unregister_logger(HWND hWnd)

Synopsis:

Unregister a Window that was previously registered as destination for logging messages.

Parameters:

hWnd: the handle of the Window that was set to handle logging messages.

Return value:

WDI_SUCCESS if the logger was successfully unregistered.
WDI_ERROR_INVALID_PARAM if hWnd does not match the one from the current logger destination.


int wdi_read_logger(char* buffer, DWORD buffer_size, DWORD* message_size)

Synopsis:

Reads a log message (following a notification received by a registered window)

Parameters:

buffer: destination buffer.
buffer_size: destination buffer size.
message_size: pointer to the value receiving the actual length of the message received

Return value:

WDI_SUCCESS if a log message was successfully read.
WDI_ERROR_NOT_FOUND if no logger could be registered.
WDI_ERROR_IO if the log message could not be read.