[Lprof-devel] lprof/src/argyll/libusbw/src common.rc, NONE, 1.1 descriptors.c, NONE, 1.1 error.c, N
Brought to you by:
hvengel
From: Joe S. <jsi...@us...> - 2007-06-15 16:13:17
|
Update of /cvsroot/lprof/lprof/src/argyll/libusbw/src In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv19887 Added Files: common.rc descriptors.c error.c error.h inf_wizard.c inf_wizard_rc.rc install.c install_filter.c libusb_dyn.c registry.c registry.h resource.rc usb.c usb.h usbi.h usbpp.cpp usbpp.h wdm.h windows.c Log Message: Initial commit of Argyll related libusb windows code. --- NEW FILE: wdm.h --- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // Use of this source code is subject to the terms of the Microsoft end-user // license agreement (EULA) under which you licensed this SOFTWARE PRODUCT. // If you did not accept the terms of the EULA, you are not authorized to use // this source code. For a copy of the EULA, please see the LICENSE.RTF on your // install media. // /*++ Module Name: wdm.h Abstract: [...3454 lines suppressed...] IN USHORT Source ); ULONG FASTCALL RtlUlongByteSwap( IN ULONG Source ); ULONGLONG FASTCALL RtlUlonglongByteSwap( IN ULONGLONG Source ); #ifdef __cplusplus } #endif // __cplusplus #endif // _WDMDDK_ --- NEW FILE: registry.c --- /* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2005 Stephan Meyer <ste...@we...> * * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ [...1077 lines suppressed...] return FALSE; } static bool_t usb_registry_free_class_keys(usb_class_key_t **head) { usb_class_key_t *p = *head; usb_class_key_t *q; while(p) { q = p->next; free(p); p = q; } *head = NULL; return TRUE; } --- NEW FILE: windows.c --- /* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2005 Stephan Meyer <ste...@we...> * Copyright (c) 2000-2005 Johannes Erdfelt <joh...@er...> * * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ [...1289 lines suppressed...] if(dev->impl_info == INVALID_HANDLE_VALUE) { usb_error("usb_abort_ep: device not open"); return -EINVAL; } req.endpoint.endpoint = (int)ep; req.timeout = LIBUSB_DEFAULT_TIMEOUT; if(!DeviceIoControl(dev->impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &req, sizeof(libusb_request), NULL, 0, &ret, NULL)) { usb_error("usb_abort_ep: could not abort ep 0x%02x, win error: %s", ep, usb_win_error_to_string()); return -usb_win_error_to_errno(); } return 0; } --- NEW FILE: descriptors.c --- /* * Parses descriptors * * Copyright (c) 2001 Johannes Erdfelt <joh...@er...> * * This library is covered by the LGPL, read LICENSE for details. */ #include <stdio.h> #include <string.h> #include "usbi.h" #include "error.h" int usb_get_descriptor_by_endpoint(usb_dev_handle *udev, int ep, unsigned char type, unsigned char index, void *buf, int size) { memset(buf, 0, size); return usb_control_msg(udev, ep | USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (type << 8) + index, 0, buf, size, 1000); } int usb_get_descriptor(usb_dev_handle *udev, unsigned char type, unsigned char index, void *buf, int size) { memset(buf, 0, size); return usb_control_msg(udev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR, (type << 8) + index, 0, buf, size, 1000); } /* * This code looks surprisingly similar to the code I wrote for the Linux * kernel. It's not a coincidence :) */ static int usb_parse_endpoint(struct usb_endpoint_descriptor *endpoint, unsigned char *buffer, int size) { struct usb_descriptor_header *header; unsigned char *begin; int parsed = 0, len, numskipped; header = (struct usb_descriptor_header *)buffer; /* Everything should be fine being passed into here, but we sanity */ /* check JIC */ if (header->bLength > size) { if (usb_debug >= 1) usb_error("ran out of descriptors parsing\n"); return -1; } if (header->bDescriptorType != USB_DT_ENDPOINT) { if (usb_debug >= 2) usb_error("unexpected descriptor 0x%X, expecting endpoint descriptor, type 0x%X\n", endpoint->bDescriptorType, USB_DT_ENDPOINT); return parsed; } if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE) memcpy(endpoint, buffer, USB_DT_ENDPOINT_AUDIO_SIZE); else memcpy(endpoint, buffer, USB_DT_ENDPOINT_SIZE); USB_LE16_TO_CPU(endpoint->wMaxPacketSize); buffer += header->bLength; size -= header->bLength; parsed += header->bLength; /* Skip over the rest of the Class Specific or Vendor Specific */ /* descriptors */ begin = buffer; numskipped = 0; while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; if (header->bLength < 2) { if (usb_debug >= 1) usb_error("invalid descriptor length of %d\n", header->bLength); return -1; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; if (usb_debug >= 1) usb_error("skipping descriptor 0x%X\n", header->bDescriptorType); numskipped++; buffer += header->bLength; size -= header->bLength; parsed += header->bLength; } if (numskipped && usb_debug >= 2) usb_error("skipped %d class/vendor specific endpoint descriptors\n", numskipped); /* Copy any unknown descriptors into a storage area for drivers */ /* to later parse */ len = (int)(buffer - begin); if (!len) { endpoint->extra = NULL; endpoint->extralen = 0; return parsed; } endpoint->extra = malloc(len); if (!endpoint->extra) { if (usb_debug >= 1) usb_error("couldn't allocate memory for endpoint extra descriptors\n"); endpoint->extralen = 0; return parsed; } memcpy(endpoint->extra, begin, len); endpoint->extralen = len; return parsed; } static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size) { int i, len, numskipped, retval, parsed = 0; struct usb_descriptor_header *header; struct usb_interface_descriptor *ifp; unsigned char *begin; interface->num_altsetting = 0; while (size > 0) { interface->altsetting = realloc(interface->altsetting, sizeof(struct usb_interface_descriptor) * (interface->num_altsetting + 1)); if (!interface->altsetting) { if (usb_debug >= 1) usb_error("couldn't malloc interface->altsetting\n"); return -1; } ifp = interface->altsetting + interface->num_altsetting; interface->num_altsetting++; memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE); /* Skip over the interface */ buffer += ifp->bLength; parsed += ifp->bLength; size -= ifp->bLength; begin = buffer; numskipped = 0; /* Skip over any interface, class or vendor descriptors */ while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; if (header->bLength < 2) { if (usb_debug >= 1) usb_error("invalid descriptor length of %d\n", header->bLength); return -1; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; numskipped++; buffer += header->bLength; parsed += header->bLength; size -= header->bLength; } if (numskipped && usb_debug >= 2) usb_error("skipped %d class/vendor specific interface descriptors\n", numskipped); /* Copy any unknown descriptors into a storage area for */ /* drivers to later parse */ len = (int)(buffer - begin); if (!len) { ifp->extra = NULL; ifp->extralen = 0; } else { ifp->extra = malloc(len); if (!ifp->extra) { if (usb_debug >= 1) usb_error("couldn't allocate memory for interface extra descriptors\n"); ifp->extralen = 0; return -1; } memcpy(ifp->extra, begin, len); ifp->extralen = len; } /* Did we hit an unexpected descriptor? */ header = (struct usb_descriptor_header *)buffer; if ((size >= sizeof(struct usb_descriptor_header)) && ((header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE))) return parsed; if (ifp->bNumEndpoints > USB_MAXENDPOINTS) { if (usb_debug >= 1) usb_error("too many endpoints\n"); return -1; } ifp->endpoint = (struct usb_endpoint_descriptor *) malloc(ifp->bNumEndpoints * sizeof(struct usb_endpoint_descriptor)); if (!ifp->endpoint) { if (usb_debug >= 1) usb_error("couldn't allocate memory for ifp->endpoint\n"); return -1; } memset(ifp->endpoint, 0, ifp->bNumEndpoints * sizeof(struct usb_endpoint_descriptor)); for (i = 0; i < ifp->bNumEndpoints; i++) { header = (struct usb_descriptor_header *)buffer; if (header->bLength > size) { if (usb_debug >= 1) usb_error("ran out of descriptors parsing\n"); return -1; } retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size); if (retval < 0) return retval; buffer += retval; parsed += retval; size -= retval; } /* We check to see if it's an alternate to this one */ ifp = (struct usb_interface_descriptor *)buffer; if (size < USB_DT_INTERFACE_SIZE || ifp->bDescriptorType != USB_DT_INTERFACE || !ifp->bAlternateSetting) return parsed; } return parsed; } int usb_parse_configuration(struct usb_config_descriptor *config, char *buffer) { int i, retval, size; struct usb_descriptor_header *header; memcpy(config, buffer, USB_DT_CONFIG_SIZE); USB_LE16_TO_CPU(config->wTotalLength); size = config->wTotalLength; if (config->bNumInterfaces > USB_MAXINTERFACES) { if (usb_debug >= 1) usb_error("too many interfaces\n"); return -1; } config->interface = (struct usb_interface *) malloc(config->bNumInterfaces * sizeof(struct usb_interface)); if (!config->interface) { if (usb_debug >= 1) usb_error("out of memory\n"); return -1; } memset(config->interface, 0, config->bNumInterfaces * sizeof(struct usb_interface)); buffer += config->bLength; size -= config->bLength; config->extra = NULL; config->extralen = 0; for (i = 0; i < config->bNumInterfaces; i++) { int numskipped, len; char *begin; /* Skip over the rest of the Class Specific or Vendor */ /* Specific descriptors */ begin = buffer; numskipped = 0; while (size >= sizeof(struct usb_descriptor_header)) { header = (struct usb_descriptor_header *)buffer; if ((header->bLength > size) || (header->bLength < 2)) { if (usb_debug >= 1) usb_error("invalid descriptor length of %d\n", header->bLength); return -1; } /* If we find another "proper" descriptor then we're done */ if ((header->bDescriptorType == USB_DT_ENDPOINT) || (header->bDescriptorType == USB_DT_INTERFACE) || (header->bDescriptorType == USB_DT_CONFIG) || (header->bDescriptorType == USB_DT_DEVICE)) break; if (usb_debug >= 2) usb_error("skipping descriptor 0x%X\n", header->bDescriptorType); numskipped++; buffer += header->bLength; size -= header->bLength; } if (numskipped && usb_debug >= 2) usb_error("skipped %d class/vendor specific endpoint descriptors\n", numskipped); /* Copy any unknown descriptors into a storage area for */ /* drivers to later parse */ len = (int)(buffer - begin); if (len) { /* FIXME: We should realloc and append here */ if (!config->extralen) { config->extra = malloc(len); if (!config->extra) { if (usb_debug >= 1) usb_error("couldn't allocate memory for config extra descriptors\n"); config->extralen = 0; return -1; } memcpy(config->extra, begin, len); config->extralen = len; } } retval = usb_parse_interface(config->interface + i, buffer, size); if (retval < 0) return retval; buffer += retval; size -= retval; } return size; } void usb_destroy_configuration(struct usb_device *dev) { int c, i, j, k; if (!dev->config) return; for (c = 0; c < dev->descriptor.bNumConfigurations; c++) { struct usb_config_descriptor *cf = &dev->config[c]; if (!cf->interface) break; for (i = 0; i < cf->bNumInterfaces; i++) { struct usb_interface *ifp = &cf->interface[i]; if (!ifp->altsetting) break; for (j = 0; j < ifp->num_altsetting; j++) { struct usb_interface_descriptor *as = &ifp->altsetting[j]; if (as->extra) free(as->extra); if (!as->endpoint) break; for (k = 0; k < as->bNumEndpoints; k++) { if (as->endpoint[k].extra) free(as->endpoint[k].extra); } free(as->endpoint); } free(ifp->altsetting); } free(cf->interface); } free(dev->config); } void usb_fetch_and_parse_descriptors(usb_dev_handle *udev) { struct usb_device *dev = udev->device; int i; if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) { if (usb_debug >= 1) usb_error("Too many configurations (%d > %d)\n", dev->descriptor.bNumConfigurations, USB_MAXCONFIG); return; } if (dev->descriptor.bNumConfigurations < 1) { if (usb_debug >= 1) usb_error("Not enough configurations (%d < %d)\n", dev->descriptor.bNumConfigurations, 1); return; } dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor)); if (!dev->config) { if (usb_debug >= 1) usb_error("Unable to allocate memory for config descriptor\n"); return; } memset(dev->config, 0, dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor)); for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { char buffer[8], *bigbuffer; struct usb_config_descriptor *desc = (struct usb_config_descriptor *)buffer; int res; /* Get the first 8 bytes so we can figure out what the total length is */ res = usb_get_descriptor(udev, USB_DT_CONFIG, (unsigned char) i, buffer, 8); if (res < 8) { if (usb_debug >= 1) { if (res < 0) usb_error("Unable to get descriptor (%d)\n", res); else usb_error("Config descriptor too short (expected %d, got %d)\n", 8, res); } goto err; } USB_LE16_TO_CPU(desc->wTotalLength); bigbuffer = malloc(desc->wTotalLength); if (!bigbuffer) { if (usb_debug >= 1) usb_error("Unable to allocate memory for descriptors\n"); goto err; } res = usb_get_descriptor(udev, USB_DT_CONFIG, (unsigned char) i, bigbuffer, desc->wTotalLength); if (res < desc->wTotalLength) { if (usb_debug >= 1) { if (res < 0) usb_error("Unable to get descriptor (%d)\n", res); else usb_error("Config descriptor too short (expected %d, got %d)\n", desc->wTotalLength, res); } free(bigbuffer); goto err; } res = usb_parse_configuration(&dev->config[i], bigbuffer); if (usb_debug >= 2) { if (res > 0) usb_error("Descriptor data still left\n"); else if (res < 0) usb_error("Unable to parse descriptors\n"); } free(bigbuffer); } return; err: free(dev->config); dev->config = NULL; } --- NEW FILE: error.h --- #ifndef __ERROR_H__ #define __ERROR_H__ /* Connection timed out */ #define ETIMEDOUT 116 typedef enum { USB_ERROR_TYPE_NONE = 0, USB_ERROR_TYPE_STRING, USB_ERROR_TYPE_ERRNO, } usb_error_type_t; void usb_error(char *format, ...); void usb_message(char *format, ...); const char *usb_win_error_to_string(void); int usb_win_error_to_errno(void); #endif /* _ERROR_H_ */ --- NEW FILE: registry.h --- /* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2005 Stephan Meyer <ste...@we...> * * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef __USB_REGISTRY_H__ #define __USB_REGISTRY_H__ #include <windows.h> #include <setupapi.h> #define LIBUSB_DRIVER_NAME_NT "libusb0" #define LIBUSB_DRIVER_NAME_9X "libusb0.sys" typedef int bool_t; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE (!(FALSE)) #endif #define REGISTRY_BUF_SIZE 512 bool_t usb_registry_is_nt(void); bool_t usb_registry_restart_device(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data); bool_t usb_registry_stop_device(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data); bool_t usb_registry_start_device(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data); bool_t usb_registry_get_property(DWORD which, HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data, char *buf, int size); bool_t usb_registry_set_property(DWORD which, HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data, char *buf, int size); bool_t usb_registry_restart_root_hubs(void); bool_t usb_registry_insert_class_filter(void); bool_t usb_registry_remove_class_filter(void); bool_t usb_registry_remove_device_filter(void); void usb_registry_stop_libusb_devices(void); void usb_registry_start_libusb_devices(void); bool_t usb_registry_match(HDEVINFO dev_info, SP_DEVINFO_DATA *dev_info_data); bool_t usb_registry_get_mz_value(const char *key, const char *value, char *buf, int size); bool_t usb_registry_set_mz_value(const char *key, const char *value, char *buf, int size); int usb_registry_mz_string_size(const char *src); char *usb_registry_mz_string_find(const char *src, const char *str); char *usb_registry_mz_string_find_sub(const char *src, const char *str); bool_t usb_registry_mz_string_insert(char *src, const char *str); bool_t usb_registry_mz_string_remove(char *src, const char *str); void usb_registry_mz_string_lower(char *src); int usb_registry_get_num_busses(void); #endif --- NEW FILE: usbpp.h --- // -*- C++;indent-tabs-mode: t; tab-width: 4; c-basic-offset: 4; -*- #ifndef __USBPP_HEADER__ #define __USBPP_HEADER__ #include <string> #include <list> #include <usb.h> /* * The following usb.h function is not wrapped yet: * char *usb_strerror(void); */ /** * \brief Classes to access Universal Serial Bus devices * * The USB Namespace provides a number of classes to work * with Universal Serial Bus (USB) devices attached to the * system. * * \author Brad Hards */ namespace USB { class Device; /** * \brief Class representing a device endpoint * * This class represents a device endpoint. You need this class to * perform bulk reads and writes. * */ class Endpoint { /** * Busses is a friend because it fills in the descriptor type * information on initialisation and rescan. */ friend class Busses; public: Endpoint() {}; #ifdef USE_UNTESTED_LIBUSBPP_METHODS /** * \brief Bulk write * * This method performs a bulk transfer to the endpoint. * * \param message is the message to be sent. * \param timeout is the USB transaction timeout in milliseconds * * \returns the number of bytes sent, or a negative value on * failure */ int bulkWrite(QByteArray message, int timeout = 100); /** * \brief Bulk read * * This method performs a bulk transfer from the endpoint. * * \param length is the maximum data transfer required. * \param message is the message that was received. * \param timeout is the USB transaction timeout in milliseconds * * \returns the number of bytes received, or a negative value on * failure */ int bulkRead(int length, unsigned char *message, int timeout = 100); /** * \brief Reset endpoint * * This method resets the endpoint. */ int reset(void); /** * \brief Clear halt * * This method clears a halt (stall) on the endpoint. */ int clearHalt(void); #endif /* USE_UNTESTED_LIBUSBPP_METHODS */ /** * \brief Endpoint descriptor information output * * This method dumps out the various characteristics * of the endpoint to standard output. * * It is mostly useful for debugging. */ void dumpDescriptor(void); private: void setDescriptor(struct usb_endpoint_descriptor); void setParent(Device *parent); u_int8_t m_Length; u_int8_t m_DescriptorType; u_int8_t m_EndpointAddress; u_int8_t m_Attributes; u_int16_t m_MaxPacketSize; u_int8_t m_Interval; u_int8_t m_Refresh; u_int8_t m_SynchAddress; Device *m_parent; }; class AltSetting : public std::list<Endpoint *> { /** * Busses is a friend because it fills in the descriptor type * information on initialisation and rescan. */ friend class Busses; public: AltSetting() {}; u_int8_t numEndpoints(void); /** * \brief AltSetting descriptor information output * * This method dumps out the various characteristics * of the alternate setting to standard output. * * It is mostly useful for debugging. */ void dumpDescriptor(void); Endpoint *firstEndpoint(void); Endpoint *nextEndpoint(void); Endpoint *lastEndpoint(void); private: std::list<Endpoint *>::const_iterator iter; void setDescriptor(struct usb_interface_descriptor); /* we don't use a normal usb_interface_descriptor */ /* because that would bring in the endpoint list */ u_int8_t m_Length; u_int8_t m_DescriptorType; u_int8_t m_InterfaceNumber; u_int8_t m_AlternateSetting; u_int8_t m_NumEndpoints; u_int8_t m_InterfaceClass; u_int8_t m_InterfaceSubClass; u_int8_t m_InterfaceProtocol; u_int8_t m_Interface; }; /** * \brief Class representing an interface of a Device * * The Interface class represents a USB interface * for a device attached to a Universal Serial Bus. * * Interfaces are the main element of the USB class * structure. * * \author Brad Hards */ class Interface : public std::list<AltSetting *> { /** * Busses is a friend because it fills in the descriptor type * information on initialisation and rescan. */ friend class Busses; public: Interface() {}; #ifdef LIBUSB_HAS_GET_DRIVER_NP /** * \brief get the current driver for an interface * * \param driver a string containing the name of the current * driver for the interface. You can typically pass in an empty * string for this. * * \return length of string, or 0 on error. */ int driverName(std::string &driver); #endif #ifdef USE_UNTESTED_LIBUSBPP_METHODS /** * \brief Claim this interface * * This method claims the interface. You have to claim the * interface before performing any operations on the interface (or * on endpoints that are part of the interface). * * \return 0 on success or negative number on error. */ int claim(void); /** * \brief Release this interface * * This method releases the interface. You should release the * interface after all operations on it (and any lower level * endpoints) are completed. * * \return 0 on success or negative number on error. */ int release(void); /** * \brief Set interface alternate setting * * This method sets the interface to a particular AltSetting. * * \param altSettingNumber the AltSetting that the interface * should be changed to. * * \return 0 on success, or a negative number in case of error. */ int setAltSetting(int altSettingNumber); #endif /* USE_UNTESTED_LIBUSBPP_METHODS */ /** * \brief Number of Alternative Settings that this interface has * * This is a simple accessor method that specifies the number * alternative settings that this device interface has. */ u_int8_t numAltSettings(void); /** * \brief First AltSetting for the Interface * * This method returns a pointer to the first AltSetting * for the Interface. * * See nextAltSetting() for an example of how it might be * used. * * \see nextAltSetting(), lastAltSetting(), numAltSettings() */ AltSetting *firstAltSetting(void); /** * \brief Next AltSetting for the Interface * * This method returns a pointer to the next AltSetting * for the Interface. * * If you want to iterate through each AltSetting on * a device, you can use something like the following: * \code * USB::Configuration *this_Configuration; * this_Configuration = device->firstConfiguration(); * for (i=0; i < device->numConfigurations(); i++) { * this_Configuration->dumpDescriptor(); * USB::Interface *this_Interface; * this_Interface = this_Configuration->firstInterface(); * for (j=0; j < this_Configuration->numInterfaces(); j++) { * USB::AltSetting *this_AltSetting; * this_AltSetting = this_Interface->firstAltSetting(); * for (k=0; k < this_Interface->numAltSettings(); k++) { * // do something with this_AltSetting * this_AltSetting = this_Interface->nextAltSetting(); * } * this_Interface = this_Configuration->nextInterface(); * } * this_Configuration = device->nextConfiguration(); * } * \endcode * * \see firstAltSetting(), lastAltSetting(), numAltSettings() */ AltSetting *nextAltSetting(void); /** * \brief Last AltSetting for the Interface * * This method returns a pointer to the last AltSetting * for the Interface. * * \see firstAltSetting(), nextAltSetting(), numAltSettings() */ AltSetting *lastAltSetting(void); private: std::list<AltSetting *>::const_iterator iter; void setNumAltSettings(u_int8_t); void setParent(Device *parent); u_int8_t m_numAltSettings; Device *m_parent; /* index representing the interface, in this configuration */ int m_interfaceNumber; void setInterfaceNumber(int interfaceNumber); }; /** * \brief Class representing a configuration of a Device * * The Configuration class represents a single configuration * of a device attached to a Universal Serial Bus. * * \author Brad Hards */ class Configuration : public std::list<Interface *> { /** * Busses is a friend because it fills in the descriptor type * information on initialisation and rescan. */ friend class Busses; public: Configuration() {}; /** * \brief Configuration descriptor information output * * This method dumps out the various characteristics * of the configuration to standard output. * * It is mostly useful for debugging. */ void dumpDescriptor(void); /** * \brief Number of Interfaces that this device has * * This is a simple accessor method that specifies the number * Interfaces that this device configuration has. */ u_int8_t numInterfaces(void); /** * \brief First Interface for the Configuration * * This method returns a pointer to the first Interface * for the Configuration. * * See nextInterface() for an example of how it might be * used. * * \see nextInterface(), lastInterface(), numInterfaces() */ Interface *firstInterface(void); /** * \brief Next Interface for the Configuration * * This method returns a pointer to the next Interface * for the Configuration. * * If you want to iterate through each Interface on * a device, you can use something like the following: * \code * USB::Configuration *this_Configuration; * this_Configuration = device->firstConfiguration(); * for (i=0; i < device->numConfigurations(); i++) { * this_Interface = this_Configuration->firstInterface(); * for (j=0; j < this_Configuration->numInterfaces(); j++) { * // do something with this_Interface * this_Interface = this_Configuration->nextInterface(); * } * this_Configuration->nextConfiguration(); * } * \endcode * * \see firstInterface(), lastInterface(), numInterfaces() */ Interface *nextInterface(void); /** * \brief Last Interface for the Configuration * * This method returns a pointer to the last Interface * for the Configuration. * * \see firstInterface(), nextInterface(), numInterfaces() */ Interface *lastInterface(void); private: std::list<Interface *>::const_iterator iter; void setDescriptor(struct usb_config_descriptor); /* we don't use a normal usb_config_descriptor */ /* because that would bring in the interface list */ u_int8_t m_Length; u_int8_t m_DescriptorType; u_int16_t m_TotalLength; u_int8_t m_NumInterfaces; u_int8_t m_ConfigurationValue; u_int8_t m_Configuration; u_int8_t m_Attributes; u_int8_t m_MaxPower; }; /** * \brief Class representing a Device on the Bus * * The Device class represents a single device * attached to a Universal Serial Bus. * * \author Brad Hards */ class Device : public std::list<Configuration *> { /** * Busses is a friend because it fills in the descriptor type * information on initialisation and rescan. */ friend class Busses; /** * Interface is a friend because it needs the handle() function to * perform claim(), release(). */ friend class Interface; /** * Endpoint is a friend because it needs the handle() function to * perform reads, writes, and other transactions. */ friend class Endpoint; public: Device() {}; ~Device(); /** * \brief OS representation of filename for this device * * libusb++ provides a uniform way of accessing USB * devices irrespective of the underlying Operation System * representation. If you want to map the libusb++ representation * to the Operating System representation, you can do this * with filename(). * * On Linux, the filename is usually something like 002, which * represents the second device (usually the first real device, * after the root hub pseudo-device) on the bus. * * \see Bus::directoryName() */ std::string fileName(void); /** * \brief The vendor ID number, as provided by the device. * * This method returns a number containing the vendor * (manufacturer) identification number. These are allocated * by the USB Implementers Forum, and you can construct a * lookup based on the number to get the manufacturer's name, * even if the device does not contain a vendor string. * * \see Vendor() */ u_int16_t idVendor(void); /** * \brief The product ID number, as provided by the device. * * This method returns a number containing the product * identification number. These are allocated * by the manufacturer, and should be different on each device. * * \see Product() */ u_int16_t idProduct(void); /** * \brief The product's revision ID, as provided by the device. * * This method returns a number containing the product's revision. * This revision level is nominally binary coded decimal, but * hexadecimal revision levels are not uncommon. The binary coded * decimal version nominally has a major version in the high byte, * and a minor version in the low byte. */ u_int16_t idRevision(void); /** * \brief The device's USB class, as provided by the device. * * This method returns a number containing the device's class. * These are defined by the USB Implementer's Forum. * * A code of Zero is special (and common) - it means that the * class is found in the Interface descriptor, rather than in the * Device descriptor. * * A code of 0xFF is also special (and far too common) - it means * that the manufacturer didn't conform to one of the defined * class specifications, and chose to implement a vendor specified * protocol. * */ u_int8_t devClass(void); /** * \brief The device's USB subclass, as provided by the device. * * This method returns a number containing the device's subclass. * These subclasses are defined by the USB Implementer's Forum, * and only have meaning in the context of a specified class. */ u_int8_t devSubClass(void); /** * \brief The device's USB protocol, as provided by the device. * * This method returns a number containing the device's protocol. * These protocols are defined by the USB Implementer's Forum, and * only have meaning in the context of a specified class and * subclass. */ u_int8_t devProtocol(void); /** * \brief The vendor name string, as provided by the device. * * This method returns a string containing the name of the * device's vendor (manufacturer), as encoded into the device. * * Note that not all devices contain a vendor name, and also * that under some operating systems you may not be able to * read the vendor name without elevated privledges (typically * root privledges). * * \see idVendor() **/ std::string Vendor(void); /** * \brief The product name string, as provided by the device. * * This method returns a string containing the name of the * device's product name, as encoded into the device. * * Note that not all devices contain a product name, and also * that under some operating systems you may not be able to * read the vendor name without elevated privledges (typically * root privledges). * * \see idProduct() **/ std::string Product(void); /** * \brief The serial number string, as provided by the device. * * This method returns a string containing a serial number for * the device, as encoded into the device. * * Note that few devices contain a serial number string, and also * that under some operating systems you may not be able to * read the serial number without elevated privledges (typically * root privledges). The USB specification requires that serial * numbers are unique if they are provided, but adherence to this * requirement by manufacturers is not universal. **/ std::string SerialNumber(void); /** * \brief Number of Configurations that this device has * * This is a simple accessor method that specifies the number * configurations that this device has. */ u_int8_t numConfigurations(void); /** * \brief fetch an arbitrary string from the device * * \param string the string from the device. You can typically * pass in an empty string for this. * \param index the index of the string required * \param lang the language ID to use. Defaults to using the * first language ID. * * \return length of string, or 0 on error. */ int string(std::string &buf, int index, u_int16_t lang=0); /** * \brief First Configuration for the Device * * This method returns a pointer to the first Configuration * for the Device. * * See nextConfiguration() for an example of how it might be * used. */ Configuration *firstConfiguration(void); /** * \brief Next Configuration for the Device * * This method returns a pointer to the next Configuration * for the Device. * * If you want to iterate through each Configuration on * a device, you can use something like the following: * \code * USB::Configuration *this_Configuration; * this_Configuration = device->firstConfiguration(); * for (i=0; i < device->numConfigurations(); i++) { * // do something with this_Configuration * this_Configuration->nextConfiguration(); * } * \endcode */ Configuration *nextConfiguration(void); /** * \brief Last Configuration for the Device * * This method returns a pointer to the last Configuration * for the Device. * */ Configuration *lastConfiguration(void); /** * \brief USB control transfer * * This method performs a standard control transfer to the default * endpoint. See the USB specification for more details on this. * * \param requestType corresponds to the bmRequestType field * in the transfer * \param request corresponds to the bRequest field in the * transfer * \param value corresponds to the wValue field in the transfer * \param index corresponds to the wIndex field in the transfer * \param length corresponds to the wLength field in the transfer * \param payload corresponds to the data phase of a control * transfer * \param timeout is the timeout period for the control transfer, * in milliseconds * * \return number of bytes sent or received, or a negative number * in case of error. */ int controlTransfer(u_int8_t requestType, u_int8_t request, u_int16_t value, u_int16_t index, u_int16_t length, unsigned char *payload, int timeout = 100); #ifdef USE_UNTESTED_LIBUSBPP_METHODS /** * \brief USB device reset * * This method performs a device reset - see USB Specification * 9.1 for how this changes the device state to the Default state. * * \return 0 on success, or a negative number in case of error. */ int reset(void); /** * \brief Set device configuration * * This method sets the device to a particular Configuration. * * \param configurationNumber the configuration that the device * should be changed to. * * \return 0 on success, or a negative number in case of error. */ int setConfiguration(int configurationNumber); #endif /* USE_UNTESTED_LIBUSBPP_METHODS */ private: std::list<Configuration *>::const_iterator iter; struct usb_dev_handle *handle(); void setFileName(std::string); void setDescriptor(struct usb_device_descriptor); void setVendor(std::string); void setProduct(std::string); void setSerialNumber(std::string); void setDevHandle(struct usb_dev_handle *); std::string m_fileName; std::string m_Vendor; std::string m_Product; std::string m_SerialNumber; struct usb_device *m_dev; struct usb_dev_handle *m_handle; struct usb_device_descriptor m_descriptor; }; /** * \brief Class representing a single bus on the machine * * This class is essentially a list of Device class instances */ class Bus : public std::list<Device *> { /** * Busses is a friend because it fills in the directory name * information on initialisation and rescan. */ friend class Busses; public: Bus() {}; /** * \brief OS representation of directory name for this Bus * * libusb++ provides a uniform way of accessing USB * busses irrespective of the underlying Operation System * representation. If you want to map the libusb++ representation * to the Operating System representation, you can do this * with directory name(). * * On Linux, the directoryname is usually something like 003, which * represents the third bus on the host. * * \see Directory::filename() */ std::string directoryName(void); private: std::list<Device *>::const_iterator iter; void setDirectoryName(std::string); std::string m_directoryName; }; /** * \brief A vendor/product ID pair * * DeviceID provides a list of (vendor, product) identification * pairs. It is intended for use in a list of device numbers to * search for, but there is no reason why it couldn't be used for a * general purpose (vendor,product) tuple if you had some reason for * this. * * The description for Busses::match() provides an example of how * this class might be used. * * \see DeviceIDList, Busses::match() */ class DeviceID { public: DeviceID() {}; /** * \brief Standard constructor * * This constructor takes (vendor, product) tuple, which are * stored away. * * \param vendor the 16 bit vendor number for the device * \param product the 16 bit product number for the device */ DeviceID(u_int16_t vendor, u_int16_t product); /** * \brief vendor number for the device * * This method returns the 16 bit vendor number. */ u_int16_t vendor(void); /** * \brief product number for the device * * This method returns the 16 bit product number. */ u_int16_t product(void); private: u_int16_t m_vendor; u_int16_t m_product; }; /** * \brief A list of vendor/product pairs * * DeviceIDList provides a list of DeviceID classes, which is * essentially a list of (vendor, product) identification pairs. * * \see DeviceID */ typedef std::list<DeviceID> DeviceIDList; /** * \brief Class representing all the busses on the machine * * This class is essentially a list of Bus class instances */ class Busses : public std::list<Bus *> { public: Busses(); /** * \brief Update method * * This method can be called to rescan the various devices * attached to the various busses. You should use it to * update if things change. Unfortunately there is no * way to automatically detect this change in a portable way, * so worst case is that you need to call this using some * kind of timer in the background. */ void rescan(void); /** * \brief find all devices with matching device class designator * * This method searches every device on every bus, and returns a * list of pointers to the devices that have a matching device * class code */ std::list<Device *> match(u_int8_t Class); /** * \brief find all devices with matching device IDs * * This method searches every device on every bus, and returns a * list of pointers to the devices that have a matching device * ID. That is, if the (vendor, product) tuple of a device matches * one of the tuples on the list, then the device will be added to * the list of matches. * * An example of usage is shown below: * \code * USB::Busses buslist; * USB::Device *device; * std::list<USB::Device> miceFound; * USB::DeviceIDList mouseList; * * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC00E)); // Wheel Mouse Optical * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC012)); // MouseMan Dual Optical * mouseList.append(USB::DeviceID(VENDOR_LOGITECH, 0xC506)); // MX700 Optical Mouse * * miceFound = buslist.match(mouseList); * * for ( device = miceFound.first(); device; device = miceFound.next() ) { * // do something with each mouse that matched * } * FIXME: This is incorrect now * \endcode */ std::list<Device *> match(DeviceIDList); private: std::list<Bus *>::const_iterator iter; }; class Error { public: private: }; } #endif /* __USBPP_HEADER__ */ --- NEW FILE: resource.rc --- /* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2005 Stephan Meyer <ste...@we...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define RC_FILE_TYPE VFT_DLL #define RC_FILE_SUB_TYPE VFT2_UNKNOWN #define RC_PRODUCT_STR "LibUSB-Win32 - DLL" #define RC_FILE_NAME_STR "libusb0.dll" #include "common.rc" --- NEW FILE: common.rc --- /* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2005 Stephan Meyer <ste...@we...> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <winver.h> VS_VERSION_INFO VERSIONINFO FILEVERSION RC_VERSION PRODUCTVERSION RC_VERSION FILEFLAGSMASK 0x3FL FILEFLAGS 0x0L FILEOS VOS_NT_WINDOWS32 FILETYPE RC_FILE_TYPE FILESUBTYPE RC_FILE_SUB_TYPE BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "CompanyName", "http://libusb-win32.sourceforge.net" VALUE "FileDescription", RC_PRODUCT_STR VALUE "FileVersion", RC_VERSION_STR VALUE "InternalName", RC_FILE_NAME_STR VALUE "LegalCopyright", "© 2002-2005 S. Meyer, <ste...@we...>" VALUE "OriginalFilename",RC_FILE_NAME_STR VALUE "ProductName", RC_PRODUCT_STR VALUE "ProductVersion", RC_VERSION_STR END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END --- NEW FILE: inf_wizard.c --- /* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2004 Stephan Meyer <ste...@we...> * * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define _WIN32_IE 0x0400 #define WINVER 0x0500 #define INITGUID #include <windows.h> #include <dbt.h> #include <stdio.h> #include <initguid.h> #include <commctrl.h> #include <setupapi.h> #include "registry.h" #define __INF_WIZARD_C__ #include "inf_wizard_rc.rc" #define _STRINGIFY(x) #x #define STRINGIFY(x) _STRINGIFY(x) DEFINE_GUID(GUID_DEVINTERFACE_USB_HUB, 0xf18a0e88, 0xc30c, 0x11d0, 0x88, \ 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8); DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, \ 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED); const char cat_file_content[] = "This file will contain the digital signature of the files to be installed\n" "on the system.\n" "This file will be provided by Microsoft upon certification of your " "drivers.\n"; const char info_text_0[] = "This program will create an .inf file for your device.\n\n" "Before clicking \"Next\" make sure that your device is connected to the " "system.\n"; const char info_text_1[] = "An .inf and .cat file has been created successfully for the following " "device:\n\n"; const char list_header_text[] = "Select your device from the list of detected devices below.\n" "If your device isn't listed then either connect it or just click \"Next\"\n" "and enter your device description manually\n"; const char inf_header[] = "[Version]\n" "Signature = \"$Chicago$\"\n" "provider = %manufacturer%\n" "DriverVer = " STRINGIFY(INF_DATE) "," STRINGIFY(INF_VERSION) "\n"; const char inf_body[] = "Class = LibUsbDevices\n" "ClassGUID = {EB781AAF-9C70-4523-A5DF-642A87ECA567}\n" "\n" "[ClassInstall]\n" "AddReg=ClassInstall.AddReg\n" "\n" "[ClassInstall32]\n" "AddReg=ClassInstall.AddReg\n" "\n" "[ClassInstall.AddReg]\n" "HKR,,,,\"LibUSB-Win32 Devices\"\n" "HKR,,Icon,,\"-20\"\n" "\n" "[Manufacturer]\n" "%manufacturer%=Devices\n" "\n" ";--------------------------------------------------------------------------\n" "; Files\n" ";--------------------------------------------------------------------------\n" "\n" "[SourceDisksNames]\n" "1 = \"Libusb-Win32 Driver Installation Disk\",,\n" "\n" "[SourceDisksFiles]\n" "libusb0.sys = 1,,\n" "libusb0.dll = 1,,\n" "\n" "[DestinationDirs]\n" "LIBUSB.Files.Sys = 10,System32\\Drivers\n" "LIBUSB.Files.Dll = 10,System32\n" "\n" "[LIBUSB.Files.Sys]\n" "libusb0.sys\n" "\n" "[LIBUSB.Files.Dll]\n" "libusb0.dll\n" "\n" ";--------------------------------------------------------------------------\n" "; Device driver\n" ";--------------------------------------------------------------------------\n" "\n" "[LIBUSB_DEV]\n" "CopyFiles = LIBUSB.Files.Sys, LIBUSB.Files.Dll\n" "AddReg = LIBUSB_DEV.AddReg\n" "\n" "[LIBUSB_DEV.NT]\n" "CopyFiles = LIBUSB.Files.Sys, LIBUSB.Files.Dll\n" "\n" "[LIBUSB_DEV.HW]\n" "DelReg = LIBUSB_DEV.DelReg.HW\n" "AddReg = LIBUSB_DEV.AddReg.HW\n" "\n" "[LIBUSB_DEV.NT.HW]\n" "DelReg = LIBUSB_DEV.DelReg.HW\n" "AddReg = LIBUSB_DEV.AddReg.HW\n" "\n" "[LIBUSB_DEV.NT.Services]\n" "AddService = libusb0, 0x00000002, LIBUSB.AddService\n" "\n" "[LIBUSB_DEV.AddReg]\n" "HKR,,DevLoader,,*ntkern\n" "HKR,,NTMPDriver,,libusb0.sys\n" "\n" "[LIBUSB_DEV.DelReg.HW]\n" "HKR,,LowerFilters\n" "HKR,,UpperFilters\n" "\n" "[LIBUSB_DEV.AddReg.HW]\n" "HKR,,libusb_is_device_driver, 0x00010001 ,1\n" "\n" ";--------------------------------------------------------------------------\n" "; Services\n" ";--------------------------------------------------------------------------\n" "\n" "[LIBUSB.AddService]\n" "DisplayName = \"LibUsb-Win32 - Kernel Driver " STRINGIFY(INF_DATE) ", " STRINGIFY(INF_VERSION) "\"\n" "ServiceType = 1\n" "StartType = 3\n" "ErrorControl = 0\n" "ServiceBinary = %12%\\libusb0.sys\n" "\n" ";--------------------------------------------------------------------------\n" "; Devices\n" ";--------------------------------------------------------------------------\n" "\n"; const char strings_header[] = "\n" ";--------------------------------------------------------------------------\n" "; Strings\n" ";--------------------------------------------------------------------------\n" "\n" "[Strings]\n\n"; typedef struct { int vid; int pid; char description[MAX_PATH]; char manufacturer[MAX_PATH]; } device_context_t; BOOL CALLBACK dialog_proc_0(HWND dialog, UINT message, WPARAM w_param, LPARAM l_param); BOOL CALLBACK dialog_proc_1(HWND dialog, UINT message, WPARAM w_param, LPARAM l_param); BOOL CALLBACK dialog_proc_2(HWND dialog, UINT message, WPARAM w_param, LPARAM l_param); BOOL CALLBACK dialog_proc_3(HWND dialog, UINT message, WPARAM w_param, LPARAM l_param); static void device_list_init(HWND list); static void device_list_refresh(HWND list); static void device_list_add(HWND list, device_context_t *device); static void device_list_clean(HWND list); static int save_file(HWND dialog, device_context_t *device); int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmd_line, int cmd_show) { MSG msg; int next_dialog; device_context_t device; LoadLibrary("comctl32.dll"); InitCommonControls(); memset(&device, 0, sizeof(device)); next_dialog = ID_DIALOG_0; while(next_dialog) { switch(next_dialog) { case ID_DIALOG_0: next_dialog = DialogBoxParam(instance, MAKEINTRESOURCE(next_dialog), NULL, dialog_proc_0, (LPARAM)&device); break; case ID_DIALOG_1: next_dialog = DialogBoxParam(instance, MAKEINTRESOURCE(next_dialog), NULL, dialog_proc_1, (LPARAM)&device); break; case ID_DIALOG_2: next_dialog = DialogBoxParam(instance, MAKEINTRESOURCE(next_dialog), NULL, dialog_proc_2, (LPARAM)&device); break; case ID_DIALOG_3: next_dialog = DialogBoxParam(instance, MAKEINTRESOURCE(next_dialog), NULL, dialog_proc_3, (LPARAM)&device); break; default: ; } } PostQuitMessage(0); while(GetMessage(&msg, NULL, 0, 0) ) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } BOOL CALLBACK dialog_proc_0(HWND dialog, UINT message, WPARAM w_param, LPARAM l_param) { switch(message) { case WM_INITDIALOG: SetWindowText(GetDlgItem(dialog, ID_INFO_TEXT), info_text_0); return TRUE; case WM_COMMAND: switch(LOWORD(w_param)) { case ID_BUTTON_NEXT: EndDialog(dialog, ID_DIALOG_1); return TRUE ; case ID_BUTTON_CANCEL: case IDCANCEL: EndDialog(dialog, 0); return TRUE ; } } return FALSE; } BOOL CALLBACK dialog_proc_1(HWND dialog, UINT message, WPARAM w_param, LPARAM l_param) { static HDEVNOTIFY notification_handle_hub = NULL; static HDEVNOTIFY notification_handle_dev = NULL; DEV_BROADCAST_HDR *hdr = (DEV_BROADCAST_HDR *) l_param; DEV_BROADCAST_DEVICEINTERFACE dev_if; static device_context_t *device = NULL; HWND list = GetDlgItem(dialog, ID_LIST); LVITEM item; switch(message) { case WM_INITDIALOG: device = (device_context_t *)l_param; memset(device, 0, sizeof(*device)); SetWindowText(GetDlgItem(dialog, ID_LIST_HEADER_TEXT), list_header_text); device_list_init(list); device_list_refresh(list); dev_if.dbcc_size = sizeof(dev_if); dev_if.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; dev_if.dbcc_classguid = GUID_DEVINTERFACE_USB_HUB; notification_handle_hub = RegisterDeviceNotification(dialog, &dev_if, 0); dev_if.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE; notification_handle_dev = RegisterDeviceNotification(dialog, &dev_if, 0); return TRUE; case WM_DEVICECHANGE: switch(w_param) { case DBT_DEVICEREMOVECOMPLETE: if(hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) device_list_refresh(list); break; case DBT_DEVICEARRIVAL: if(hdr->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) device_list_refresh(list); break; default: ; } return TRUE; case WM_COMMAND: switch(LOWORD(w_param)) { case ID_BUTTON_NEXT: if(notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if(notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); memset(&item, 0, sizeof(item)); item.mask = LVIF_TEXT | LVIF_PARAM; item.iItem = ListView_GetNextItem(list, -1, LVNI_SELECTED); memset(device, 0, sizeof(*device)); if(item.iItem >= 0) { if(ListView_GetItem(list, &item)) { if(item.lParam) { memcpy(device, (void *)item.lParam, sizeof(*device)); } } } if(!device->vid) { device->vid = 0x12AB; device->pid = 0x12AB; } if(!device->manufacturer[0]) strcpy(device->manufacturer, "Insert manufacturer name"); if(!device->description[0]) strcpy(device->description, "Insert device description"); if(notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if(notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); device_list_clean(list); EndDialog(dialog, ID_DIALOG_2); return TRUE; case ID_BUTTON_BACK: device_list_clean(list); if(notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if(notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); EndDialog(dialog, ID_DIALOG_0); return TRUE ; case ID_BUTTON_CANCEL: case IDCANCEL: device_list_clean(list); if(notification_handle_hub) UnregisterDeviceNotification(notification_handle_hub); if(notification_handle_dev) UnregisterDeviceNotification(notification_handle_dev); EndDialog(dialog, 0); return TRUE ; } } return FALSE; } BOOL CALLBACK dialog_proc_2(HWND dialog, UINT message, WPARAM w_param, LPARAM l_param) { static device_context_t *device = NULL; char tmp[MAX_PATH]; switch(message) { case WM_INITDIALOG: device = (device_context_t *)l_param; if(device) { memset(tmp, 0, sizeof(tmp)); sprintf(tmp, "0x%04X", device->vid); SetWindowText(GetDlgItem(dialog, ID_TEXT_VID), tmp); memset(tmp, 0, sizeof(tmp)); sprintf(tmp, "0x%04X", device->pid); SetWindowText(GetDlgItem(dialog, ID_TEXT_PID), tmp); SetWindowText(GetDlgItem(dialog, ID_TEXT_MANUFACTURER), ... [truncated message content] |