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

📄 windows.c

📁 这是USB驱动程序库
💻 C
📖 第 1 页 / 共 3 页
字号:

  for(i = 1; i < LIBUSB_MAX_DEVICES; i++)
    {
      ret = 0;

      _snprintf(dev_name, sizeof(dev_name) - 1,"%s%04d", 
                LIBUSB_DEVICE_NAME, i);

      if(!(dev = malloc(sizeof(*dev)))) 
        {
          usb_error("usb_os_find_devices: memory allocation failed");
          return -ENOMEM;
        }
      
      memset(dev, 0, sizeof(*dev));
      dev->bus = bus;
      dev->devnum = (unsigned char)i;

      handle = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
                          FILE_FLAG_OVERLAPPED, NULL);

      if(handle == INVALID_HANDLE_VALUE) 
        {
          free(dev);
          continue;
        }

      /* retrieve device descriptor */
      req.descriptor.type = USB_DT_DEVICE;
      req.descriptor.recipient = USB_RECIP_DEVICE;
      req.descriptor.index = 0;
      req.descriptor.language_id = 0;
      req.timeout = LIBUSB_DEFAULT_TIMEOUT;
      
      _usb_io_sync(handle, LIBUSB_IOCTL_GET_DESCRIPTOR, 
                   &req, sizeof(libusb_request), 
                   &dev->descriptor, USB_DT_DEVICE_SIZE, &ret);
      
      if(ret < USB_DT_DEVICE_SIZE) 
        {
          usb_error("usb_os_find_devices: couldn't read device descriptor");
          free(dev);
          CloseHandle(handle);
          continue;
        }
      
      _snprintf(dev->filename, LIBUSB_PATH_MAX - 1, "%s--0x%04x-0x%04x", 
                dev_name, dev->descriptor.idVendor, dev->descriptor.idProduct);

      CloseHandle(handle);

      LIST_ADD(fdev, dev);

      usb_message("usb_os_find_devices: found %s on %s",
                  dev->filename, bus->dirname);
    }
  
  *devices = fdev;

  return 0;
}


void usb_os_init(void)
{
  HANDLE dev;
  libusb_request req;
  int i;
  int ret;
  char dev_name[LIBUSB_PATH_MAX];

  usb_message("usb_os_init: dll version: %d.%d.%d.%d",
              VERSION_MAJOR, VERSION_MINOR,
              VERSION_MICRO, VERSION_NANO);


  for(i = 1; i < LIBUSB_MAX_DEVICES; i++)
    {
      /* build the Windows file name */
      _snprintf(dev_name, sizeof(dev_name) - 1,"%s%04d", 
                LIBUSB_DEVICE_NAME, i);

      dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
                       FILE_FLAG_OVERLAPPED, NULL);
  
      if(dev == INVALID_HANDLE_VALUE) 
        {
          continue;
        }
      
      if(!_usb_io_sync(dev, LIBUSB_IOCTL_GET_VERSION,
                       &req, sizeof(libusb_request), 
                       &req, sizeof(libusb_request), &ret) 
         || (ret < sizeof(libusb_request)))
        {
          usb_error("usb_os_init: getting driver version failed");
          CloseHandle(dev);
          continue;
        }
      else 
        {
          _usb_version.driver.major = req.version.major;
          _usb_version.driver.minor = req.version.minor;
          _usb_version.driver.micro = req.version.micro;
          _usb_version.driver.nano = req.version.nano;
	  
          usb_message("usb_os_init: driver version: %d.%d.%d.%d",
                      req.version.major, req.version.minor, 
                      req.version.micro, req.version.nano);
      
          /* set debug level */
          req.timeout = 0;
          req.debug.level = __usb_debug;
          
          if(!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, 
                           &req, sizeof(libusb_request), 
                           NULL, 0, NULL))
            {
              usb_error("usb_os_init: setting debug level failed");
            }
          
          CloseHandle(dev);
          break;
        }
    }
}


int usb_resetep(usb_dev_handle *dev, unsigned int ep)
{
  libusb_request req;

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

  req.endpoint.endpoint = (int)ep;
  req.timeout = LIBUSB_DEFAULT_TIMEOUT;

  if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &req, 
                   sizeof(libusb_request), NULL, 0, NULL))
    {
      usb_error("usb_resetep: could not abort ep 0x%02x, win error: %s", 
                ep, usb_win_error_to_string());
      return -usb_win_error_to_errno();
    }

  if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &req, 
                   sizeof(libusb_request), NULL, 0, NULL))
    {
      usb_error("usb_resetep: could not reset ep 0x%02x, win error: %s", 
                ep, usb_win_error_to_string());
      return -usb_win_error_to_errno();
    }
  
  return 0;
}

int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
{
  libusb_request req;

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

  req.endpoint.endpoint = (int)ep;
  req.timeout = LIBUSB_DEFAULT_TIMEOUT;

  if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RESET_ENDPOINT, &req, 
                   sizeof(libusb_request), NULL, 0, NULL))
    {
      usb_error("usb_clear_halt: could not clear halt, ep 0x%02x, "
                "win error: %s", ep, usb_win_error_to_string());
      return -usb_win_error_to_errno();
    }
  
  return 0;
}

int usb_reset(usb_dev_handle *dev)
{
  libusb_request req;

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

  req.timeout = LIBUSB_DEFAULT_TIMEOUT;

  if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RESET_DEVICE,
                   &req, sizeof(libusb_request), NULL, 0, NULL))
    {
      usb_error("usb_reset: could not reset device, win error: %s", 
                usb_win_error_to_string());
      return -usb_win_error_to_errno();
    }

  return 0;
}

const struct usb_version *usb_get_version(void)
{
  return &_usb_version;
}

void usb_set_debug(int level)
{
  HANDLE dev;
  libusb_request req;
  int i;
  char dev_name[LIBUSB_PATH_MAX];

  if(__usb_debug || level)
    {
      usb_message("usb_set_debug: setting debugging level to %d (%s)\n",
                  level, level ? "on" : "off");
    }

  __usb_debug = level;

  /* find a valid device */
  for(i = 1; i < LIBUSB_MAX_DEVICES; i++)
    {
      /* build the Windows file name */
      _snprintf(dev_name, sizeof(dev_name) - 1,"%s%04d", 
                LIBUSB_DEVICE_NAME, i);

      dev = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, 
                       FILE_FLAG_OVERLAPPED, NULL);
  
      if(dev == INVALID_HANDLE_VALUE) 
        {
          continue;
        }
      
      /* set debug level */
      req.timeout = 0;
      req.debug.level = __usb_debug;
      
      if(!_usb_io_sync(dev, LIBUSB_IOCTL_SET_DEBUG_LEVEL, 
                       &req, sizeof(libusb_request), 
                       NULL, 0, NULL))
        {
          usb_error("usb_os_init: setting debug level failed");
        }
      
      CloseHandle(dev);

      break;
    }
}

int usb_os_determine_children(struct usb_bus *bus)
{
  struct usb_device *dev;
  int i = 0;

  /* add a virtual hub to the bus to emulate this feature */
  if(_usb_add_virtual_hub(bus))
    {
      if(bus->root_dev->children)
        {
          free(bus->root_dev->children);
        }

      bus->root_dev->num_children = 0;
      for(dev = bus->devices; dev; dev = dev->next)
        bus->root_dev->num_children++;

      bus->root_dev->children 
        = malloc(sizeof(struct usb_device *) * bus->root_dev->num_children);

      for(dev = bus->devices; dev; dev = dev->next)
        bus->root_dev->children[i++] = dev; 
    }

  return 0;
}

static int _usb_cancel_io(usb_context_t *context)
{
  int ret;
  ret = _usb_abort_ep(context->dev, context->req.endpoint.endpoint);
  WaitForSingleObject(context->ol.hEvent, 0);
  return ret; 
}

static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep)
{
  libusb_request req;

  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(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_ABORT_ENDPOINT, &req, 
                   sizeof(libusb_request), NULL, 0, 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;
}

static int _usb_io_sync(HANDLE dev, unsigned int code, void *out, int out_size,
                        void *in, int in_size, int *ret)
{
  OVERLAPPED ol;
  DWORD _ret;

  memset(&ol, 0, sizeof(ol));  

  if(ret)
    *ret = 0;

  ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

  if(!ol.hEvent)
    return FALSE;
  
  if(!DeviceIoControl(dev, code, out, out_size, in, in_size, NULL, &ol))
    {
      if(GetLastError() != ERROR_IO_PENDING)
        {
          CloseHandle(ol.hEvent);
          return FALSE;
        }
    }

  if(GetOverlappedResult(dev, &ol, &_ret, TRUE))
    {
      if(ret)
        *ret = (int)_ret;
      CloseHandle(ol.hEvent);
      return TRUE;
    }
  
  CloseHandle(ol.hEvent);
  return FALSE;
}

static int _usb_add_virtual_hub(struct usb_bus *bus)
{
  struct usb_device *dev;

  if(!bus->root_dev)
    {
      if(!(dev = malloc(sizeof(*dev))))
        return FALSE;
      
      memset(dev, 0, sizeof(*dev));
      strcpy(dev->filename, "virtual-hub");
      dev->bus = bus;
      
      dev->descriptor.bLength = USB_DT_DEVICE_SIZE;
      dev->descriptor.bDescriptorType = USB_DT_DEVICE;
      dev->descriptor.bcdUSB = 0x0200;
      dev->descriptor.bDeviceClass = USB_CLASS_HUB;
      dev->descriptor.bDeviceSubClass = 0;
      dev->descriptor.bDeviceProtocol = 0;
      dev->descriptor.bMaxPacketSize0 = 64;
      dev->descriptor.idVendor = 0;
      dev->descriptor.idProduct = 0;
      dev->descriptor.bcdDevice = 0x100;
      dev->descriptor.iManufacturer = 0;
      dev->descriptor.iProduct = 0;
      dev->descriptor.iSerialNumber = 0;
      dev->descriptor.bNumConfigurations = 0;
      
      bus->root_dev = dev;
    }

  return TRUE;
}

static void _usb_free_bus_list(struct usb_bus *bus)
{
  if(bus)
    {
      _usb_free_bus_list(bus->next);
      if(bus->root_dev)
        usb_free_dev(bus->root_dev);
      _usb_free_dev_list(bus->devices);
      usb_free_bus(bus);
    }
}

static void _usb_free_dev_list(struct usb_device *dev)
{
  if(dev)
    {
      _usb_free_dev_list(dev->next);
      usb_free_dev(dev);
    }
}

static void _usb_deinit(void)
{
  _usb_free_bus_list(usb_get_busses());
}

⌨️ 快捷键说明

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