2 * Plug and Play support for hid devices found through udev
4 * Copyright 2016 CodeWeavers, Aric Stewart
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
33 #define NONAMELESSUNION
36 #define WIN32_NO_STATUS
42 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(plugplay
);
50 static struct udev
*udev_context
= NULL
;
51 static DRIVER_OBJECT
*udev_driver_obj
= NULL
;
53 static DWORD
get_sysattr_dword(struct udev_device
*dev
, const char *sysattr
, int base
)
55 const char *attr
= udev_device_get_sysattr_value(dev
, sysattr
);
58 WARN("Could not get %s from device\n", sysattr
);
61 return strtol(attr
, NULL
, base
);
64 static WCHAR
*get_sysattr_string(struct udev_device
*dev
, const char *sysattr
)
66 const char *attr
= udev_device_get_sysattr_value(dev
, sysattr
);
71 WARN("Could not get %s from device\n", sysattr
);
74 len
= MultiByteToWideChar(CP_UNIXCP
, 0, attr
, -1, NULL
, 0);
75 if ((dst
= HeapAlloc(GetProcessHeap(), 0, len
* sizeof(WCHAR
))))
76 MultiByteToWideChar(CP_UNIXCP
, 0, attr
, -1, dst
, len
);
80 static void try_add_device(struct udev_device
*dev
)
82 DWORD vid
= 0, pid
= 0, version
= 0;
83 struct udev_device
*usbdev
;
88 if (!(devnode
= udev_device_get_devnode(dev
)))
91 if ((fd
= open(devnode
, O_RDWR
)) == -1)
93 WARN("Unable to open udev device %s: %s\n", debugstr_a(devnode
), strerror(errno
));
98 usbdev
= udev_device_get_parent_with_subsystem_devtype(dev
, "usb", "usb_device");
101 vid
= get_sysattr_dword(usbdev
, "idVendor", 16);
102 pid
= get_sysattr_dword(usbdev
, "idProduct", 16);
103 version
= get_sysattr_dword(usbdev
, "version", 10);
104 serial
= get_sysattr_string(usbdev
, "serial");
107 TRACE("Found udev device %s (vid %04x, pid %04x, version %u, serial %s)\n",
108 debugstr_a(devnode
), vid
, pid
, version
, debugstr_w(serial
));
110 HeapFree(GetProcessHeap(), 0, serial
);
113 static void build_initial_deviceset(void)
115 struct udev_enumerate
*enumerate
;
116 struct udev_list_entry
*devices
, *dev_list_entry
;
118 enumerate
= udev_enumerate_new(udev_context
);
121 WARN("Unable to create udev enumeration object\n");
125 if (udev_enumerate_add_match_subsystem(enumerate
, "hidraw") < 0)
126 WARN("Failed to add subsystem 'hidraw' to enumeration\n");
128 if (udev_enumerate_scan_devices(enumerate
) < 0)
129 WARN("Enumeration scan failed\n");
131 devices
= udev_enumerate_get_list_entry(enumerate
);
132 udev_list_entry_foreach(dev_list_entry
, devices
)
134 struct udev_device
*dev
;
137 path
= udev_list_entry_get_name(dev_list_entry
);
138 if ((dev
= udev_device_new_from_syspath(udev_context
, path
)))
141 udev_device_unref(dev
);
145 udev_enumerate_unref(enumerate
);
148 NTSTATUS WINAPI
udev_driver_init(DRIVER_OBJECT
*driver
, UNICODE_STRING
*registry_path
)
150 TRACE("(%p, %s)\n", driver
, debugstr_w(registry_path
->Buffer
));
152 if (!(udev_context
= udev_new()))
154 ERR("Can't create udev object\n");
155 return STATUS_UNSUCCESSFUL
;
158 udev_driver_obj
= driver
;
159 driver
->MajorFunction
[IRP_MJ_PNP
] = common_pnp_dispatch
;
161 build_initial_deviceset();
162 return STATUS_SUCCESS
;
167 NTSTATUS WINAPI
udev_driver_init(DRIVER_OBJECT
*driver
, UNICODE_STRING
*registry_path
)
169 WARN("Wine was compiled without UDEV support\n");
170 return STATUS_NOT_IMPLEMENTED
;
173 #endif /* HAVE_UDEV */