From: Rémi Bernon rbernon@codeweavers.com
Changes by Paul Gofman to the original patch: - validate device_path length before copying in SetupDiOpenDeviceInterfaceW(); - don't use DIGCF_PRESENT flag. --- dlls/setupapi/devinst.c | 72 +++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 17 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c index 5a4e72b6771..275b6d363c0 100644 --- a/dlls/setupapi/devinst.c +++ b/dlls/setupapi/devinst.c @@ -3656,29 +3656,67 @@ done: /*********************************************************************** * SetupDiOpenDeviceInterfaceW (SETUPAPI.@) */ -BOOL WINAPI SetupDiOpenDeviceInterfaceW( - HDEVINFO DeviceInfoSet, - PCWSTR DevicePath, - DWORD OpenFlags, - PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) -{ - FIXME("%p %s %08lx %p\n", - DeviceInfoSet, debugstr_w(DevicePath), OpenFlags, DeviceInterfaceData); +BOOL WINAPI SetupDiOpenDeviceInterfaceW(HDEVINFO devinfo, const WCHAR *device_path, + DWORD flags, SP_DEVICE_INTERFACE_DATA *iface_data) +{ + SP_DEVINFO_DATA device_data = {.cbSize = sizeof(device_data)}; + WCHAR instance_id[MAX_PATH], *tmp; + struct device_iface *iface; + struct device *device; + + TRACE("%p %s %#lx %p\n", devinfo, debugstr_w(device_path), flags, iface_data); + + if (flags) + FIXME("flags %#lx not implemented\n", flags); + + if (!device_path || wcslen(device_path) >= MAX_PATH) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + wcscpy(instance_id, device_path + 4); + if ((tmp = wcsrchr(instance_id, '#'))) *tmp = 0; + while ((tmp = wcschr(instance_id, '#'))) *tmp = '\'; + + if (!SetupDiGetClassDevsExW(NULL, instance_id, NULL, DIGCF_DEVICEINTERFACE | DIGCF_ALLCLASSES, + devinfo, NULL, NULL)) + return FALSE; + if (!SetupDiOpenDeviceInfoW(devinfo, instance_id, NULL, 0, &device_data)) + return FALSE; + + if (!(device = get_device(devinfo, &device_data))) + return FALSE; + LIST_FOR_EACH_ENTRY(iface, &device->interfaces, struct device_iface, entry) + { + if (iface->symlink && !wcsicmp(device_path, iface->symlink)) + { + copy_device_iface_data(iface_data, iface); + return TRUE; + } + } + return FALSE; }
/*********************************************************************** * SetupDiOpenDeviceInterfaceA (SETUPAPI.@) */ -BOOL WINAPI SetupDiOpenDeviceInterfaceA( - HDEVINFO DeviceInfoSet, - PCSTR DevicePath, - DWORD OpenFlags, - PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData) -{ - FIXME("%p %s %08lx %p\n", DeviceInfoSet, - debugstr_a(DevicePath), OpenFlags, DeviceInterfaceData); - return FALSE; +BOOL WINAPI SetupDiOpenDeviceInterfaceA(HDEVINFO devinfo, const char *device_path, + DWORD flags, SP_DEVICE_INTERFACE_DATA *iface_data) +{ + WCHAR device_pathW[MAX_PATH]; + + TRACE("%p %s %#lx %p\n", devinfo, debugstr_a(device_path), flags, iface_data); + + if (!device_path || strlen(device_path) >= MAX_PATH) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + MultiByteToWideChar(CP_ACP, 0, device_path, -1, device_pathW, ARRAY_SIZE(device_pathW)); + return SetupDiOpenDeviceInterfaceW(devinfo, device_pathW, flags, iface_data); }
/***********************************************************************