#include "poll_windows.h"
#include "windows_winusb.h"
-#define HANDLE_VALID(h) (((h) != 0) && ((h) != INVALID_HANDLE_VALUE))
+#define HANDLE_VALID(h) (((h) != NULL) && ((h) != INVALID_HANDLE_VALUE))
// The 2 macros below are used in conjunction with safe loops.
#define LOOP_CHECK(fcall) \
static int concurrent_usage = -1;
static usbi_mutex_t autoclaim_lock;
// API globals
+static HMODULE WinUSBX_handle = NULL;
+static struct winusb_interface WinUSBX[SUB_API_MAX];
#define CHECK_WINUSBX_AVAILABLE(sub_api) \
do { \
if (sub_api == SUB_API_NOTSET) \
sub_api = priv->sub_api; \
if (!WinUSBX[sub_api].initialized) \
return LIBUSB_ERROR_ACCESS; \
- } while(0)
+ } while (0)
-static HMODULE WinUSBX_handle = NULL;
-static struct winusb_interface WinUSBX[SUB_API_MAX];
static const char *sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES;
static bool api_hid_available = false;
*/
static char *sanitize_path(const char *path)
{
- const char root_prefix[] = { '\\', '\\', '.', '\\' };
+ const char root_prefix[] = {'\\', '\\', '.', '\\'};
size_t j, size;
char *ret_path;
size_t add_root = 0;
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInfo, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiEnumDeviceInterfaces, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceInterfaceDetailA, TRUE);
+ DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiDestroyDeviceInfoList, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDevRegKey, TRUE);
- DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiGetDeviceRegistryPropertyA, TRUE);
DLL_LOAD_FUNC_PREFIXED(SetupAPI, p, SetupDiOpenDeviceInterfaceRegKey, TRUE);
return LIBUSB_SUCCESS;
int current_interface = *interface_number;
int r = LIBUSB_SUCCESS;
- switch(api_type) {
+ switch (api_type) {
case USB_API_WINUSBX:
case USB_API_HID:
break;
dev_interface_path = NULL;
priv->apib = &usb_api_backend[api];
priv->sub_api = sub_api;
- switch(api) {
+ switch (api) {
case USB_API_COMPOSITE:
case USB_API_HUB:
break;
priv->hid = calloc(1, sizeof(struct hid_device_priv));
if (priv->hid == NULL)
LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
-
- priv->hid->nb_interfaces = 0;
break;
default:
// For other devices, the first interface is the same as the device
priv->usb_interface[0].path = _strdup(priv->path);
if (priv->usb_interface[0].path == NULL)
- usbi_warn(ctx, "could not duplicate interface path '%s'", priv->path);
+ LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
+
// The following is needed if we want API calls to work for both simple
// and composite devices.
for (j = 0; j < USB_MAXINTERFACES; j++)
struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev);
struct windows_device_priv *priv = _device_priv(dev_handle->dev);
struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle);
-
HANDLE file_handle;
int i;
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (file_handle == INVALID_HANDLE_VALUE) {
usbi_err(ctx, "could not open device %s (interface %d): %s", priv->usb_interface[i].path, i, windows_error_str(0));
- switch(GetLastError()) {
+ switch (GetLastError()) {
case ERROR_FILE_NOT_FOUND: // The device was disconnected
return LIBUSB_ERROR_NO_DEVICE;
case ERROR_ACCESS_DENIED:
if (!WinUSBX[sub_api].Initialize(file_handle, &winusb_handle)) {
handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
err = GetLastError();
- switch(err) {
+ switch (err) {
case ERROR_BAD_COMMAND:
// The device was disconnected
usbi_err(ctx, "could not access interface %d: %s", iface, windows_error_str(0));
if (!WinUSBX[sub_api].GetAssociatedInterface(winusb_handle, (UCHAR)(iface - 1),
&handle_priv->interface_handle[iface].api_handle)) {
handle_priv->interface_handle[iface].api_handle = INVALID_HANDLE_VALUE;
- switch(GetLastError()) {
+ switch (GetLastError()) {
case ERROR_NO_MORE_ITEMS: // invalid iface
return LIBUSB_ERROR_NOT_FOUND;
case ERROR_BAD_COMMAND: // The device was disconnected
static int _hid_get_descriptor(struct hid_device_priv *dev, HANDLE hid_handle, int recipient,
int type, int _index, void *data, size_t *size)
{
- switch(type) {
+ switch (type) {
case LIBUSB_DT_DEVICE:
usbi_dbg("LIBUSB_DT_DEVICE");
return _hid_get_device_descriptor(dev, data, size);
static int hid_init(int sub_api, struct libusb_context *ctx)
{
DLL_GET_HANDLE(hid);
+
DLL_LOAD_FUNC(hid, HidD_GetAttributes, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetHidGuid, TRUE);
DLL_LOAD_FUNC(hid, HidD_GetPreparsedData, TRUE);
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
if (hid_handle == INVALID_HANDLE_VALUE) {
usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0));
- switch(GetLastError()) {
+ switch (GetLastError()) {
case ERROR_FILE_NOT_FOUND: // The device was disconnected
return LIBUSB_ERROR_NO_DEVICE;
case ERROR_ACCESS_DENIED:
HidD_GetSerialNumberString(hid_handle, priv->hid->string[2], sizeof(priv->hid->string[2]));
else
priv->hid->string[2][0] = 0;
- } while(0);
+ } while (0);
if (preparsed_data)
HidD_FreePreparsedData(preparsed_data);
if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED)
return LIBUSB_ERROR_BUSY; // already claimed
-
handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
usbi_dbg("claimed interface %d", iface);
if (wfd.fd < 0)
return LIBUSB_ERROR_NOT_FOUND;
- switch(LIBUSB_REQ_TYPE(setup->RequestType)) {
+ switch (LIBUSB_REQ_TYPE(setup->RequestType)) {
case LIBUSB_REQUEST_TYPE_STANDARD:
- switch(setup->Request) {
+ switch (setup->Request) {
case LIBUSB_REQUEST_GET_DESCRIPTOR:
r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->RequestType),
(setup->Value >> 8) & 0xFF, setup->Value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size);
// http://msdn.microsoft.com/en-us/library/ff545972.aspx
// http://msdn.microsoft.com/en-us/library/ff545982.aspx
#ifndef GUID_DEVINTERFACE_USB_HOST_CONTROLLER
-const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = { 0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27} };
+const GUID GUID_DEVINTERFACE_USB_HOST_CONTROLLER = {0x3ABF6F2D, 0x71C4, 0x462A, {0x8A, 0x92, 0x1E, 0x68, 0x61, 0xE6, 0xAF, 0x27}};
#endif
#ifndef GUID_DEVINTERFACE_USB_DEVICE
-const GUID GUID_DEVINTERFACE_USB_DEVICE = { 0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED} };
+const GUID GUID_DEVINTERFACE_USB_DEVICE = {0xA5DCBF10, 0x6530, 0x11D2, {0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED}};
#endif
#ifndef GUID_DEVINTERFACE_USB_HUB
-const GUID GUID_DEVINTERFACE_USB_HUB = { 0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8} };
+const GUID GUID_DEVINTERFACE_USB_HUB = {0xF18A0E88, 0xC30C, 0x11D0, {0x88, 0x15, 0x00, 0xA0, 0xC9, 0x06, 0xBE, 0xD8}};
#endif
#ifndef GUID_DEVINTERFACE_LIBUSB0_FILTER
-const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9} };
+const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = {0xF9F3FF14, 0xAE21, 0x48A0, {0x8A, 0x25, 0x80, 0x11, 0xA7, 0xA9, 0x31, 0xD9}};
#endif
#define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN)
#define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type))
+#ifndef CTL_CODE
+#define CTL_CODE(DeviceType, Function, Method, Access) \
+ (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
+#endif
+
// The following are used for HID reports IOCTLs
-#define HID_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS)
-#define HID_BUFFER_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
#define HID_IN_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS)
#define HID_OUT_CTL_CODE(id) \
- CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
+ CTL_CODE(FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100)
#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104)
const char* designation; // internal designation (for debug output)
};
+/*
+ * Windows DDK API definitions. Most of it copied from MinGW's includes
+ */
+typedef DWORD DEVNODE, DEVINST;
+typedef DEVNODE *PDEVNODE, *PDEVINST;
+typedef DWORD RETURN_TYPE;
+typedef RETURN_TYPE CONFIGRET;
+
+#define CR_SUCCESS 0x00000000
+
+/* Cfgmgr32.dll interface */
+DLL_DECLARE_HANDLE(Cfgmgr32);
+DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
+DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
+DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
+DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
+
+/* AdvAPI32 dependencies */
+DLL_DECLARE_HANDLE(AdvAPI32);
+DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
+DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
+
/* OLE32 dependency */
DLL_DECLARE_HANDLE(OLE32);
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HRESULT, p, IIDFromString, (LPCOLESTR, LPIID));
/* SetupAPI dependencies */
DLL_DECLARE_HANDLE(SetupAPI);
-DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (const GUID*, PCSTR, HWND, DWORD));
+DLL_DECLARE_FUNC_PREFIXED(WINAPI, HDEVINFO, p, SetupDiGetClassDevsA, (LPCGUID, PCSTR, HWND, DWORD));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInfo, (HDEVINFO, DWORD, PSP_DEVINFO_DATA));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiEnumDeviceInterfaces, (HDEVINFO, PSP_DEVINFO_DATA,
- const GUID*, DWORD, PSP_DEVICE_INTERFACE_DATA));
+ LPCGUID, DWORD, PSP_DEVICE_INTERFACE_DATA));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceInterfaceDetailA, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA,
PSP_DEVICE_INTERFACE_DETAIL_DATA_A, DWORD, PDWORD, PSP_DEVINFO_DATA));
-DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
-DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiGetDeviceRegistryPropertyA, (HDEVINFO,
PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD));
+DLL_DECLARE_FUNC_PREFIXED(WINAPI, BOOL, p, SetupDiDestroyDeviceInfoList, (HDEVINFO));
+DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDevRegKey, (HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM));
DLL_DECLARE_FUNC_PREFIXED(WINAPI, HKEY, p, SetupDiOpenDeviceInterfaceRegKey, (HDEVINFO, PSP_DEVICE_INTERFACE_DATA, DWORD, DWORD));
-/* AdvAPI32 dependencies */
-DLL_DECLARE_HANDLE(AdvAPI32);
-DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegQueryValueExW, (HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD));
-DLL_DECLARE_FUNC_PREFIXED(WINAPI, LONG, p, RegCloseKey, (HKEY));
-
-/*
- * Windows DDK API definitions. Most of it copied from MinGW's includes
- */
-typedef DWORD DEVNODE, DEVINST;
-typedef DEVNODE *PDEVNODE, *PDEVINST;
-typedef DWORD RETURN_TYPE;
-typedef RETURN_TYPE CONFIGRET;
-
-#define CR_SUCCESS 0x00000000
#ifndef USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION
-#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
+#define USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION 260
#endif
#ifndef USB_GET_NODE_CONNECTION_INFORMATION_EX
-#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
+#define USB_GET_NODE_CONNECTION_INFORMATION_EX 274
#endif
#ifndef USB_GET_NODE_CONNECTION_INFORMATION_EX_V2
#define USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 279
#endif
-#ifndef METHOD_BUFFERED
-#define METHOD_BUFFERED 0
-#endif
-#ifndef FILE_ANY_ACCESS
-#define FILE_ANY_ACCESS 0x00000000
-#endif
-#ifndef FILE_DEVICE_UNKNOWN
-#define FILE_DEVICE_UNKNOWN 0x00000022
-#endif
#ifndef FILE_DEVICE_USB
-#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
+#define FILE_DEVICE_USB FILE_DEVICE_UNKNOWN
#endif
-#ifndef CTL_CODE
-#define CTL_CODE(DeviceType, Function, Method, Access) \
- (((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
-#endif
+#define USB_CTL_CODE(id) \
+ CTL_CODE(FILE_DEVICE_USB, (id), METHOD_BUFFERED, FILE_ANY_ACCESS)
+
+#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
+ USB_CTL_CODE(USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION)
+
+#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
+ USB_CTL_CODE(USB_GET_NODE_CONNECTION_INFORMATION_EX)
+
+#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \
+ USB_CTL_CODE(USB_GET_NODE_CONNECTION_INFORMATION_EX_V2)
typedef enum USB_CONNECTION_STATUS {
NoDeviceConnected,
UsbMIParent
} USB_HUB_NODE;
-/* Cfgmgr32.dll interface */
-DLL_DECLARE_HANDLE(Cfgmgr32);
-DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Parent, (PDEVINST, DEVINST, ULONG));
-DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Child, (PDEVINST, DEVINST, ULONG));
-DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Sibling, (PDEVINST, DEVINST, ULONG));
-DLL_DECLARE_FUNC(WINAPI, CONFIGRET, CM_Get_Device_IDA, (DEVINST, PCHAR, ULONG, ULONG));
-
-#define IOCTL_USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION \
- CTL_CODE(FILE_DEVICE_USB, USB_GET_DESCRIPTOR_FROM_NODE_CONNECTION, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX \
- CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
-#define IOCTL_USB_GET_NODE_CONNECTION_INFORMATION_EX_V2 \
- CTL_CODE(FILE_DEVICE_USB, USB_GET_NODE_CONNECTION_INFORMATION_EX_V2, METHOD_BUFFERED, FILE_ANY_ACCESS)
-
// Most of the structures below need to be packed
#include <pshpack1.h>
INT Minor;
INT Micro;
INT Nano;
-} KLIB_VERSION;
-typedef KLIB_VERSION* PKLIB_VERSION;
+} KLIB_VERSION, *PKLIB_VERSION;
typedef BOOL (WINAPI *LibK_GetProcAddress_t)(
PVOID *ProcAddress,
} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS;
DLL_DECLARE_HANDLE(hid);
-DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
DLL_DECLARE_FUNC(WINAPI, VOID, HidD_GetHidGuid, (LPGUID));
+DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA));
DLL_DECLARE_FUNC(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG));