📄 windows.c
字号:
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 + -