📄 windows.c
字号:
/* LIBUSB-WIN32, Generic Windows USB Library * Copyright (c) 2002-2005 Stephan Meyer <ste_meyer@web.de> * Copyright (c) 2000-2005 Johannes Erdfelt <johannes@erdfelt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <stdlib.h>#include <string.h>#include <stdio.h> #include <errno.h>#include <ctype.h>#include <windows.h>#include <winioctl.h>#include <setupapi.h>#include "usb.h"#include "error.h"#include "usbi.h"#include "driver_api.h"#include "registry.h"#define LIBUSB_DEFAULT_TIMEOUT 5000#define LIBUSB_DEVICE_NAME "\\\\.\\libusb0-"#define LIBUSB_BUS_NAME "bus-0"#define LIBUSB_MAX_DEVICES 256extern int __usb_debug;typedef struct { usb_dev_handle *dev; libusb_request req; char *bytes; int size; DWORD control_code; OVERLAPPED ol;} usb_context_t;static struct usb_version _usb_version = { { VERSION_MAJOR, VERSION_MINOR, VERSION_MICRO, VERSION_NANO }, { -1, -1, -1, -1 }};static int _usb_setup_async(usb_dev_handle *dev, void **context, DWORD control_code, unsigned char ep, int pktsize);static int _usb_transfer_sync(usb_dev_handle *dev, int control_code, int ep, int pktsize, char *bytes, int size, int timeout);/* static int usb_get_configuration(usb_dev_handle *dev); */static int _usb_cancel_io(usb_context_t *context);static int _usb_abort_ep(usb_dev_handle *dev, unsigned int ep);static int _usb_io_sync(HANDLE dev, unsigned int code, void *in, int in_size, void *out, int out_size, int *ret);static int _usb_reap_async(void *context, int timeout, int cancel);static int _usb_add_virtual_hub(struct usb_bus *bus);static void _usb_free_bus_list(struct usb_bus *bus);static void _usb_free_dev_list(struct usb_device *dev);static void _usb_deinit(void);/* DLL main entry point */BOOL WINAPI DllMain(HANDLE module, DWORD reason, LPVOID reserved){ switch(reason) { case DLL_PROCESS_ATTACH: break; case DLL_PROCESS_DETACH: _usb_deinit(); break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; default: break; } return TRUE;}/* static int usb_get_configuration(usb_dev_handle *dev) *//* { *//* int ret; *//* char config; *//* ret = usb_control_msg(dev, USB_RECIP_DEVICE | USB_ENDPOINT_IN, *//* USB_REQ_GET_CONFIGURATION, 0, 0, &config, 1, *//* LIBUSB_DEFAULT_TIMEOUT); */ /* if(ret >= 0) *//* { *//* return config; *//* } *//* return ret; *//* } */int usb_os_open(usb_dev_handle *dev){ char dev_name[LIBUSB_PATH_MAX]; char *p; /* int config; */ if(!dev) { usb_error("usb_os_open: invalid device handle %p", dev); return -EINVAL; } dev->impl_info = INVALID_HANDLE_VALUE; dev->config = 0; dev->interface = -1; dev->altsetting = -1; if(!dev->device->filename) { usb_error("usb_os_open: invalid file name"); return -ENOENT; } /* build the Windows file name from the unique device name */ strcpy(dev_name, dev->device->filename); p = strstr(dev_name, "--"); if(!p) { usb_error("usb_os_open: invalid file name %s", dev->device->filename); return -ENOENT; } *p = 0; dev->impl_info = CreateFile(dev_name, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if(dev->impl_info == INVALID_HANDLE_VALUE) { usb_error("usb_os_open: failed to open %s: win error: %s", dev->device->filename, usb_win_error_to_string()); return -ENOENT; } /* now, retrieve the device's current configuration, except from hubs */ /* if(dev->device->config && dev->device->config->interface */ /* && dev->device->config->interface[0].altsetting */ /* && dev->device->config->interface[0].altsetting[0].bInterfaceClass */ /* != USB_CLASS_HUB) */ /* { */ /* config = usb_get_configuration(dev); */ /* if(config > 0) */ /* { */ /* dev->config = config; */ /* } */ /* } */ return 0;}int usb_os_close(usb_dev_handle *dev){ if(dev->impl_info != INVALID_HANDLE_VALUE) { if(dev->interface >= 0) { usb_release_interface(dev, dev->interface); } CloseHandle(dev->impl_info); dev->impl_info = INVALID_HANDLE_VALUE; dev->interface = -1; dev->altsetting = -1; } return 0;}int usb_set_configuration(usb_dev_handle *dev, int configuration){ libusb_request req; if(dev->impl_info == INVALID_HANDLE_VALUE) { usb_error("usb_set_configuration: error: device not open"); return -EINVAL; } if(dev->config == configuration) { return 0; } if(dev->interface >= 0) { usb_error("usb_set_configuration: can't change configuration, " "an interface is still in use (claimed)"); return -EINVAL; } req.configuration.configuration = configuration; req.timeout = LIBUSB_DEFAULT_TIMEOUT; if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_SET_CONFIGURATION, &req, sizeof(libusb_request), NULL, 0, NULL)) { usb_error("usb_set_configuration: could not set config %d: " "win error: %s", configuration, usb_win_error_to_string()); return -usb_win_error_to_errno(); } dev->config = configuration; dev->interface = -1; dev->altsetting = -1; return 0;}int usb_claim_interface(usb_dev_handle *dev, int interface){ libusb_request req; if(dev->impl_info == INVALID_HANDLE_VALUE) { usb_error("usb_claim_interface: device not open"); return -EINVAL; } if(!dev->config) { usb_error("usb_claim_interface: could not claim interface %d, invalid " "configuration %d", interface, dev->config); return -EINVAL; } if(dev->interface == interface) { return 0; } req.interface.interface = interface; if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_CLAIM_INTERFACE, &req, sizeof(libusb_request), NULL, 0, NULL)) { usb_error("usb_claim_interface: could not claim interface %d, " "win error: %s", interface, usb_win_error_to_string()); return -usb_win_error_to_errno(); } else { dev->interface = interface; dev->altsetting = 0; return 0; }}int usb_release_interface(usb_dev_handle *dev, int interface){ libusb_request req; if(dev->impl_info == INVALID_HANDLE_VALUE) { usb_error("usb_release_interface: device not open"); return -EINVAL; } if(!dev->config) { usb_error("usb_release_interface: could not release interface %d, " "invalid configuration %d", interface, dev->config); return -EINVAL; } req.interface.interface = interface; if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_RELEASE_INTERFACE, &req, sizeof(libusb_request), NULL, 0, NULL)) { usb_error("usb_release_interface: could not release interface %d, " "win error: %s", interface, usb_win_error_to_string()); return -usb_win_error_to_errno(); } else { dev->interface = -1; dev->altsetting = -1; return 0; }}int usb_set_altinterface(usb_dev_handle *dev, int alternate){ libusb_request req; if(dev->impl_info == INVALID_HANDLE_VALUE) { usb_error("usb_set_altinterface: device not open"); return -EINVAL; } if(dev->config <= 0) { usb_error("usb_set_altinterface: could not set alt interface %d: " "invalid configuration %d", alternate, dev->config); return -EINVAL; } if(dev->interface < 0) { usb_error("usb_set_altinterface: could not set alt interface %d: " "no interface claimed", alternate); return -EINVAL; } req.interface.interface = dev->interface; req.interface.altsetting = alternate; req.timeout = LIBUSB_DEFAULT_TIMEOUT; if(!_usb_io_sync(dev->impl_info, LIBUSB_IOCTL_SET_INTERFACE, &req, sizeof(libusb_request), NULL, 0, NULL)) { usb_error("usb_set_altinterface: could not set alt interface " "%d/%d: win error: %s", dev->interface, alternate, usb_win_error_to_string()); return -usb_win_error_to_errno(); } dev->altsetting = alternate; return 0;}static int _usb_setup_async(usb_dev_handle *dev, void **context, DWORD control_code, unsigned char ep, int pktsize){ usb_context_t **c = (usb_context_t **)context; if(((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_WRITE) || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_WRITE)) && (ep & USB_ENDPOINT_IN)) { usb_error("_usb_setup_async: invalid endpoint 0x%02x", ep); return -EINVAL; } if(((control_code == LIBUSB_IOCTL_INTERRUPT_OR_BULK_READ) || (control_code == LIBUSB_IOCTL_ISOCHRONOUS_READ)) && !(ep & USB_ENDPOINT_IN)) { usb_error("_usb_setup_async: invalid endpoint 0x%02x", ep); return -EINVAL; } *c = malloc(sizeof(usb_context_t)); if(!*c) { usb_error("_usb_setup_async: memory allocation error"); return -ENOMEM; } memset(*c, 0, sizeof(usb_context_t)); (*c)->dev = dev; (*c)->req.endpoint.endpoint = ep; (*c)->req.endpoint.packet_size = pktsize; (*c)->control_code = control_code; (*c)->ol.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); if(!(*c)->ol.hEvent) { free(*c); *c = NULL; usb_error("_usb_setup_async: creating event failed: win error: %s", usb_win_error_to_string()); return -usb_win_error_to_errno(); } return 0;}int usb_submit_async(void *context, char *bytes, int size){ usb_context_t *c = (usb_context_t *)context; if(!c) { usb_error("usb_submit_async: invalid context"); return -EINVAL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -