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