⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 windows.c

📁 这是USB驱动程序库
💻 C
📖 第 1 页 / 共 3 页
字号:
    }
    
  if(c->dev->impl_info == INVALID_HANDLE_VALUE)
    {
      usb_error("usb_submit_async: device not open");
      return -EINVAL;
    }

  if(c->dev->config <= 0)
    {
      usb_error("usb_submit_async: invalid configuration %d", c->dev->config);
      return -EINVAL;
    }

  if(c->dev->interface < 0)
    {
      usb_error("usb_submit_async: invalid interface %d", c->dev->interface);
      return -EINVAL;
    }
  
  
  c->ol.Offset = 0;
  c->ol.OffsetHigh = 0;
  c->bytes = bytes;
  c->size = size;

  ResetEvent(c->ol.hEvent);
  
  if(!DeviceIoControl(c->dev->impl_info, 
                      c->control_code, 
                      &c->req, sizeof(libusb_request), 
                      c->bytes, 
                      c->size, NULL, &c->ol))
    {
      if(GetLastError() != ERROR_IO_PENDING)
        {
          usb_error("usb_submit_async: submitting request failed, "
                    "win error: %s", usb_win_error_to_string());
          return -usb_win_error_to_errno();
        }
    }

  return 0;
}

static int _usb_reap_async(void *context, int timeout, int cancel)
{
  usb_context_t *c = (usb_context_t *)context;
  ULONG ret = 0;
    
  if(!c)
    {
      usb_error("usb_reap: invalid context");
      return -EINVAL;
    }

  if(WaitForSingleObject(c->ol.hEvent, timeout) == WAIT_TIMEOUT)
    {
      /* request timed out */
      if(cancel)
        {
          _usb_cancel_io(c);
        }

      usb_error("usb_reap: timeout error");
      return -ETIMEDOUT;
    }
  
  if(!GetOverlappedResult(c->dev->impl_info, &c->ol, &ret, TRUE))
    {
      usb_error("usb_reap: reaping request failed, win error: %s", 
                usb_win_error_to_string());
      return -usb_win_error_to_errno();
    }

  return ret;
}

int usb_reap_async(void *context, int timeout)
{
  return _usb_reap_async(context, timeout, TRUE);
}

int usb_reap_async_nocancel(void *context, int timeout)
{
  return _usb_reap_async(context, timeout, FALSE);
}


int usb_cancel_async(void *context)
{
  /* NOTE that this function will cancel all pending URBs */
  /* on the same endpoint as this particular context, or even */
  /* all pending URBs for this particular device. */
  
  usb_context_t *c = (usb_context_t *)context;
  
  if(!c)
    {
      usb_error("usb_cancel_async: invalid context");
      return -EINVAL;
    }

  if(c->dev->impl_info == INVALID_HANDLE_VALUE)
    {
      usb_error("usb_cancel_async: device not open");
      return -EINVAL;
    }
  
  _usb_cancel_io(c);

  return 0;
}

int usb_free_async(void **context)
{
  usb_context_t **c = (usb_context_t **)context;

  if(!*c)
    {
      usb_error("usb_free_async: invalid context");
      return -EINVAL;
    }

  CloseHandle((*c)->ol.hEvent);

  free(*c);
  *c = NULL;

  return 0;
}

static int _usb_transfer_sync(usb_dev_handle *dev, int control_code,
                              int ep, int pktsize, char *bytes, int size,
                              int timeout)
{
  void *context = NULL;
  int transmitted = 0;
  int ret;
  int requested;

  ret = _usb_setup_async(dev, &context, control_code, (unsigned char )ep, 
                         pktsize);

  if(ret < 0)
    {
      return ret;
    }

  do {
    requested = size > LIBUSB_MAX_READ_WRITE ? LIBUSB_MAX_READ_WRITE : size;

    ret = usb_submit_async(context, bytes, requested);
    
    if(ret < 0)
      {
        transmitted = ret;
        break;
      }

    ret = usb_reap_async(context, timeout);

    if(ret < 0)
      {
        transmitted = ret;
        break;
      }

    transmitted += ret;
    bytes += ret;
    size -= ret;
  } while(size > 0 && ret == requested);
  
  usb_free_async(&context);

  return transmitted;
}

int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
                   int timeout)
{
  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
                            ep, 0, bytes, size, timeout);
}

int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
                  int timeout)
{
  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
                            ep, 0, bytes, size, timeout);
}

int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
                        int timeout)
{
  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
                            ep, 0, bytes, size, timeout);
}

int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
                       int timeout)
{
  return _usb_transfer_sync(dev, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
                            ep, 0, bytes, size, timeout);
}

int usb_isochronous_setup_async(usb_dev_handle *dev, void **context, 
                                unsigned char ep, int pktsize)
{
  if(ep & 0x80)
    return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_READ,
                            ep, pktsize);
  else
    return _usb_setup_async(dev, context, LIBUSB_IOCTL_ISOCHRONOUS_WRITE,
                            ep, pktsize);    
}

int usb_bulk_setup_async(usb_dev_handle *dev, void **context, unsigned char ep)
{
  if(ep & 0x80)
    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
                            ep, 0);
  else
    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
                            ep, 0);    
}

int usb_interrupt_setup_async(usb_dev_handle *dev, void **context, 
                              unsigned char ep)
{
  if(ep & 0x80)
    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ,
                            ep, 0);
  else
    return _usb_setup_async(dev, context, LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE,
                            ep, 0);    
}

int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
                    int value, int index, char *bytes, int size, int timeout)
{
  int read = 0;
  libusb_request req;
  void *out = &req;
  int out_size = sizeof(libusb_request);
  void *in = bytes;
  int in_size = size;
  int code;

  if(dev->impl_info == INVALID_HANDLE_VALUE)
    {
      usb_error("usb_control_msg: device not open");
      return -EINVAL;
    }

  req.timeout = timeout;

  /* windows doesn't support generic control messages, so it needs to be */
  /* split up */ 
  switch(requesttype & (0x03 << 5))
    {
    case USB_TYPE_STANDARD:      
      switch(request)
        {
        case USB_REQ_GET_STATUS: 
          req.status.recipient = requesttype & 0x1F;
          req.status.index = index;
          code = LIBUSB_IOCTL_GET_STATUS;
          break;
      
        case USB_REQ_CLEAR_FEATURE:
          req.feature.recipient = requesttype & 0x1F;
          req.feature.feature = value;
          req.feature.index = index;
          code = LIBUSB_IOCTL_CLEAR_FEATURE;
          break;
	  
        case USB_REQ_SET_FEATURE:
          req.feature.recipient = requesttype & 0x1F;
          req.feature.feature = value;
          req.feature.index = index;
          code = LIBUSB_IOCTL_SET_FEATURE;
          break;

        case USB_REQ_GET_DESCRIPTOR:
          req.descriptor.recipient = requesttype & 0x1F;
          req.descriptor.type = (value >> 8) & 0xFF;
          req.descriptor.index = value & 0xFF;
          req.descriptor.language_id = index;
          code = LIBUSB_IOCTL_GET_DESCRIPTOR;
          break;
	  
        case USB_REQ_SET_DESCRIPTOR:
          req.descriptor.recipient = requesttype & 0x1F;
          req.descriptor.type = (value >> 8) & 0xFF;
          req.descriptor.index = value & 0xFF;
          req.descriptor.language_id = index;
          code = LIBUSB_IOCTL_SET_DESCRIPTOR;
          break;
	  
        case USB_REQ_GET_CONFIGURATION:
          code = LIBUSB_IOCTL_GET_CONFIGURATION;
          break;
      
        case USB_REQ_SET_CONFIGURATION:	  
          req.configuration.configuration = value;
          code = LIBUSB_IOCTL_SET_CONFIGURATION;
          break;
	  
        case USB_REQ_GET_INTERFACE:
          req.interface.interface = index;
          code = LIBUSB_IOCTL_GET_INTERFACE;	  
          break;
      
        case USB_REQ_SET_INTERFACE:
          req.interface.interface = index;
          req.interface.altsetting = value;
          code = LIBUSB_IOCTL_SET_INTERFACE;	  
          break;
	  
        default:
          usb_error("usb_control_msg: invalid request 0x%x", request);
          return -EINVAL;
        }
      break;

    case USB_TYPE_VENDOR:  
    case USB_TYPE_CLASS:

      req.vendor.type = (requesttype >> 5) & 0x03;
      req.vendor.recipient = requesttype & 0x1F;
      req.vendor.request = request;
      req.vendor.value = value;
      req.vendor.index = index;

      if(requesttype & 0x80)
        code = LIBUSB_IOCTL_VENDOR_READ;
      else
        code = LIBUSB_IOCTL_VENDOR_WRITE;
      break;

    case USB_TYPE_RESERVED:
    default:
      usb_error("usb_control_msg: invalid or unsupported request type: %x", 
                requesttype);
      return -EINVAL;
    }
  
  /* out request? */
  if(!(requesttype & USB_ENDPOINT_IN))
    {
      if(!(out = malloc(sizeof(libusb_request) + size)))
        {
          usb_error("usb_control_msg: memory allocation failed"); 
          return -ENOMEM;
        }
      
      memcpy(out, &req, sizeof(libusb_request));
      memcpy((char *)out + sizeof(libusb_request), bytes, size);
      out_size = sizeof(libusb_request) + size;
      in = NULL; in_size = 0;
    }

  if(!_usb_io_sync(dev->impl_info, code, out, out_size, in, in_size, &read))
    {
      usb_error("usb_control_msg: sending control message failed, "
                "win error: %s", usb_win_error_to_string());
      if(!(requesttype & USB_ENDPOINT_IN))
        {
          free(out);
        }
      return -usb_win_error_to_errno();
    }

  /* out request? */
  if(!(requesttype & USB_ENDPOINT_IN))
    {
      free(out);
      return size;
    }
  else
    return read;
}


int usb_os_find_busses(struct usb_bus **busses)
{
  struct usb_bus *bus = NULL;

  /* create one 'virtual' bus */
  
  bus = malloc(sizeof(struct usb_bus));

  if(!bus)
    {
      usb_error("usb_os_find_busses: memory allocation failed");
      return -ENOMEM;
    }
  
  memset(bus, 0, sizeof(*bus));
  strcpy(bus->dirname, LIBUSB_BUS_NAME);
  
  usb_message("usb_os_find_busses: found %s", bus->dirname);
  
  *busses = bus;

  return 0;
}

int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
{
  int i;
  struct usb_device *dev, *fdev = NULL;
  char dev_name[LIBUSB_PATH_MAX];
  int ret;
  HANDLE handle;
  libusb_request req;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -