📄 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); /* wait until the request is cancelled */ WaitForSingleObject(c->ol.hEvent, 0); } 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; } 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -