Wine-Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 19 participants
- 84525 discussions
[PATCH] winebus.sys: Convert the product strings to unicode on the unix-side.
by Huw Davies Oct. 5, 2021
by Huw Davies Oct. 5, 2021
Oct. 5, 2021
This avoids keeping two copies of each string.
It also fixes a regression on macOS from commit 9d4b70473c147b
that incorrectly treated a CFStringRef as a char ptr.
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/winebus.sys/bus_iohid.c | 17 +++++++++++-----
dlls/winebus.sys/bus_sdl.c | 15 +++++++++-----
dlls/winebus.sys/bus_udev.c | 38 ++++++++++++++++++++++++------------
dlls/winebus.sys/main.c | 24 ++++++++---------------
dlls/winebus.sys/unixlib.c | 12 ++++++------
dlls/winebus.sys/unixlib.h | 6 +++---
6 files changed, 64 insertions(+), 48 deletions(-)
diff --git a/dlls/winebus.sys/bus_iohid.c b/dlls/winebus.sys/bus_iohid.c
index a450402e87b..4412a4bf6dd 100644
--- a/dlls/winebus.sys/bus_iohid.c
+++ b/dlls/winebus.sys/bus_iohid.c
@@ -130,6 +130,13 @@ static struct iohid_device *find_device_from_iohid(IOHIDDeviceRef IOHIDDevice)
return NULL;
}
+static void CFStringToWSTR(CFStringRef cstr, LPWSTR wstr, int length)
+{
+ int len = min(CFStringGetLength(cstr), length - 1);
+ CFStringGetCharacters(cstr, CFRangeMake(0, len), (UniChar*)wstr);
+ wstr[len] = 0;
+}
+
static DWORD CFNumberToDWORD(CFNumberRef num)
{
int dwNum = 0;
@@ -265,10 +272,10 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
struct device_desc desc =
{
.input = -1,
- .serialnumber = {"0000"},
+ .serialnumber = {'0','0','0','0',0},
};
struct iohid_device *impl;
- CFStringRef str = NULL;
+ CFStringRef str;
desc.vid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDVendorIDKey)));
desc.pid = CFNumberToDWORD(IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductIDKey)));
@@ -283,11 +290,11 @@ static void handle_DeviceMatchingCallback(void *context, IOReturn result, void *
IOHIDDeviceScheduleWithRunLoop(IOHIDDevice, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDManufacturerKey));
- if (str) lstrcpynA(desc.manufacturer, str, sizeof(desc.manufacturer));
+ if (str) CFStringToWSTR(str, desc.manufacturer, ARRAY_SIZE(desc.manufacturer));
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDProductKey));
- if (str) lstrcpynA(desc.product, str, sizeof(desc.product));
+ if (str) CFStringToWSTR(str, desc.product, ARRAY_SIZE(desc.product));
str = IOHIDDeviceGetProperty(IOHIDDevice, CFSTR(kIOHIDSerialNumberKey));
- if (str) lstrcpynA(desc.serialnumber, str, sizeof(desc.serialnumber));
+ if (str) CFStringToWSTR(str, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
if (IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_GamePad) ||
IOHIDDeviceConformsTo(IOHIDDevice, kHIDPage_GenericDesktop, kHIDUsage_GD_Joystick))
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 33386a80a34..4e4f275fbc9 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -51,6 +51,7 @@
#include "wine/debug.h"
#include "wine/hid.h"
+#include "wine/unixlib.h"
#include "unix_private.h"
@@ -589,8 +590,8 @@ static void sdl_add_device(unsigned int index)
struct device_desc desc =
{
.input = -1,
- .manufacturer = {"SDL"},
- .serialnumber = {"0000"},
+ .manufacturer = {'S','D','L',0},
+ .serialnumber = {'0','0','0','0',0},
};
struct sdl_device *impl;
@@ -598,6 +599,8 @@ static void sdl_add_device(unsigned int index)
SDL_JoystickID id;
SDL_JoystickGUID guid;
SDL_GameController *controller = NULL;
+ const char *str;
+ char guid_str[33];
if ((joystick = pSDL_JoystickOpen(index)) == NULL)
{
@@ -608,8 +611,9 @@ static void sdl_add_device(unsigned int index)
if (options.map_controllers && pSDL_IsGameController(index))
controller = pSDL_GameControllerOpen(index);
- if (controller) lstrcpynA(desc.product, pSDL_GameControllerName(controller), sizeof(desc.product));
- else lstrcpynA(desc.product, pSDL_JoystickName(joystick), sizeof(desc.product));
+ if (controller) str = pSDL_GameControllerName(controller);
+ else str = pSDL_JoystickName(joystick);
+ if (str) ntdll_umbstowcs(str, strlen(str) + 1, desc.product, ARRAY_SIZE(desc.product));
id = pSDL_JoystickInstanceID(joystick);
@@ -626,7 +630,8 @@ static void sdl_add_device(unsigned int index)
}
guid = pSDL_JoystickGetGUID(joystick);
- pSDL_JoystickGetGUIDString(guid, desc.serialnumber, sizeof(desc.serialnumber));
+ pSDL_JoystickGetGUIDString(guid, guid_str, sizeof(guid_str));
+ ntdll_umbstowcs(guid_str, strlen(guid_str) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
if (controller) desc.is_gamepad = TRUE;
else
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 3db261b2404..90213b7cd5b 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -73,6 +73,7 @@
#include "wine/debug.h"
#include "wine/hid.h"
+#include "wine/unixlib.h"
#ifdef HAS_PROPER_INPUT_HEADER
# include "hidusage.h"
@@ -945,8 +946,10 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
if (!strncmp(ptr, "HID_UNIQ=", 9))
{
+ char buffer[MAX_PATH];
if (desc->serialnumber[0]) continue;
- sscanf(ptr, "HID_UNIQ=%256s\n", desc->serialnumber);
+ if (sscanf(ptr, "HID_UNIQ=%256s\n", buffer) == 1)
+ ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc->serialnumber, ARRAY_SIZE(desc->serialnumber));
}
if (!strncmp(ptr, "HID_PHYS=", 9) || !strncmp(ptr, "PHYS=\"", 6))
{
@@ -970,13 +973,13 @@ static void get_device_subsystem_info(struct udev_device *dev, char const *subsy
}
if (!desc->manufacturer[0] && (tmp = udev_device_get_sysattr_value(dev, "manufacturer")))
- lstrcpynA(desc->manufacturer, tmp, sizeof(desc->manufacturer));
+ ntdll_umbstowcs(tmp, strlen(tmp) + 1, desc->manufacturer, ARRAY_SIZE(desc->manufacturer));
if (!desc->product[0] && (tmp = udev_device_get_sysattr_value(dev, "product")))
- lstrcpynA(desc->product, tmp, sizeof(desc->product));
+ ntdll_umbstowcs(tmp, strlen(tmp) + 1, desc->product, ARRAY_SIZE(desc->product));
if (!desc->serialnumber[0] && (tmp = udev_device_get_sysattr_value(dev, "serial")))
- lstrcpynA(desc->serialnumber, tmp, sizeof(desc->serialnumber));
+ ntdll_umbstowcs(tmp, strlen(tmp) + 1, desc->serialnumber, ARRAY_SIZE(desc->serialnumber));
}
static void udev_add_device(struct udev_device *dev)
@@ -1017,17 +1020,22 @@ static void udev_add_device(struct udev_device *dev)
subsystem = udev_device_get_subsystem(dev);
if (!strcmp(subsystem, "hidraw"))
{
- if (!desc.manufacturer[0]) strcpy(desc.manufacturer, "hidraw");
+ static const WCHAR hidraw[] = {'h','i','d','r','a','w',0};
+ char product[MAX_PATH];
+
+ if (!desc.manufacturer[0]) memcpy(desc.manufacturer, hidraw, sizeof(hidraw));
#ifdef HAVE_LINUX_HIDRAW_H
- if (!desc.product[0] && ioctl(fd, HIDIOCGRAWNAME(sizeof(desc.product) - 1), desc.product) < 0)
- desc.product[0] = 0;
+ if (!desc.product[0] && ioctl(fd, HIDIOCGRAWNAME(sizeof(product) - 1), product) >= 0)
+ ntdll_umbstowcs(product, strlen(product) + 1, desc.product, ARRAY_SIZE(desc.product));
#endif
}
#ifdef HAS_PROPER_INPUT_HEADER
else if (!strcmp(subsystem, "input"))
{
+ static const WCHAR evdev[] = {'e','v','d','e','v',0};
struct input_id device_id = {0};
+ char buffer[MAX_PATH];
if (ioctl(fd, EVIOCGID, &device_id) < 0)
WARN("ioctl(EVIOCGID) failed: %d %s\n", errno, strerror(errno));
@@ -1038,17 +1046,21 @@ static void udev_add_device(struct udev_device *dev)
desc.version = device_id.version;
}
- if (!desc.manufacturer[0]) strcpy(desc.manufacturer, "evdev");
+ if (!desc.manufacturer[0]) memcpy(desc.manufacturer, evdev, sizeof(evdev));
- if (!desc.product[0] && ioctl(fd, EVIOCGNAME(sizeof(desc.product) - 1), desc.product) <= 0)
- desc.product[0] = 0;
+ if (!desc.product[0] && ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), buffer) > 0)
+ ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.product, ARRAY_SIZE(desc.product));
- if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(desc.serialnumber)), desc.serialnumber) < 0)
- desc.serialnumber[0] = 0;
+ if (!desc.serialnumber[0] && ioctl(fd, EVIOCGUNIQ(sizeof(buffer)), buffer) >= 0)
+ ntdll_umbstowcs(buffer, strlen(buffer) + 1, desc.serialnumber, ARRAY_SIZE(desc.serialnumber));
}
#endif
- if (!desc.serialnumber[0]) strcpy(desc.serialnumber, "0000");
+ if (!desc.serialnumber[0])
+ {
+ static const WCHAR zeros[] = {'0','0','0','0',0};
+ memcpy(desc.serialnumber, zeros, sizeof(zeros));
+ }
if (is_xbox_gamepad(desc.vid, desc.pid))
desc.is_gamepad = TRUE;
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index b5130a7908e..6a4695cd3be 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -70,10 +70,6 @@ struct device_extension
struct device_desc desc;
DWORD index;
- WCHAR manufacturer[MAX_PATH];
- WCHAR product[MAX_PATH];
- WCHAR serialnumber[MAX_PATH];
-
BYTE *last_report;
DWORD last_report_size;
BOOL last_report_read;
@@ -180,11 +176,11 @@ static DWORD get_device_index(struct device_desc *desc)
static WCHAR *get_instance_id(DEVICE_OBJECT *device)
{
struct device_extension *ext = (struct device_extension *)device->DeviceExtension;
- DWORD len = wcslen(ext->serialnumber) + 33;
+ DWORD len = wcslen(ext->desc.serialnumber) + 33;
WCHAR *dst;
if ((dst = ExAllocatePool(PagedPool, len * sizeof(WCHAR))))
- swprintf(dst, len, L"%i&%s&%x&%i", ext->desc.version, ext->serialnumber, ext->desc.uid, ext->index);
+ swprintf(dst, len, L"%i&%s&%x&%i", ext->desc.version, ext->desc.serialnumber, ext->desc.uid, ext->index);
return dst;
}
@@ -299,10 +295,6 @@ static DEVICE_OBJECT *bus_create_hid_device(struct device_desc *desc, struct uni
ext->buffer_size = 0;
ext->unix_device = unix_device;
- MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.manufacturer, -1, ext->manufacturer, MAX_PATH);
- MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.product, -1, ext->product, MAX_PATH);
- MultiByteToWideChar(CP_UNIXCP, 0, ext->desc.serialnumber, -1, ext->serialnumber, MAX_PATH);
-
InitializeListHead(&ext->irp_queue);
InitializeCriticalSection(&ext->cs);
ext->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": cs");
@@ -894,19 +886,19 @@ static NTSTATUS hid_get_device_string(DEVICE_OBJECT *device, DWORD index, WCHAR
switch (index)
{
case HID_STRING_ID_IMANUFACTURER:
- len = (wcslen(ext->manufacturer) + 1) * sizeof(WCHAR);
+ len = (wcslen(ext->desc.manufacturer) + 1) * sizeof(WCHAR);
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
- else memcpy(buffer, ext->manufacturer, len);
+ else memcpy(buffer, ext->desc.manufacturer, len);
return STATUS_SUCCESS;
case HID_STRING_ID_IPRODUCT:
- len = (wcslen(ext->product) + 1) * sizeof(WCHAR);
+ len = (wcslen(ext->desc.product) + 1) * sizeof(WCHAR);
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
- else memcpy(buffer, ext->product, len);
+ else memcpy(buffer, ext->desc.product, len);
return STATUS_SUCCESS;
case HID_STRING_ID_ISERIALNUMBER:
- len = (wcslen(ext->serialnumber) + 1) * sizeof(WCHAR);
+ len = (wcslen(ext->desc.serialnumber) + 1) * sizeof(WCHAR);
if (len > buffer_len) return STATUS_BUFFER_TOO_SMALL;
- else memcpy(buffer, ext->serialnumber, len);
+ else memcpy(buffer, ext->desc.serialnumber, len);
return STATUS_SUCCESS;
}
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 29537170df7..d14fb30d917 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -114,9 +114,9 @@ static const struct device_desc mouse_device_desc =
.vid = 0x845e,
.pid = 0x0001,
.input = -1,
- .manufacturer = {"The Wine Project"},
- .product = {"Wine HID mouse"},
- .serialnumber = {"0000"},
+ .manufacturer = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0},
+ .product = {'W','i','n','e',' ','H','I','D',' ','m','o','u','s','e',0},
+ .serialnumber = {'0','0','0','0',0},
};
static NTSTATUS mouse_device_create(void *args)
@@ -184,9 +184,9 @@ static const struct device_desc keyboard_device_desc =
.vid = 0x845e,
.pid = 0x0002,
.input = -1,
- .manufacturer = {"The Wine Project"},
- .product = {"Wine HID keyboard"},
- .serialnumber = {"0000"},
+ .manufacturer = {'T','h','e',' ','W','i','n','e',' ','P','r','o','j','e','c','t',0},
+ .product = {'W','i','n','e',' ','H','I','D',' ','k','e','y','b','o','a','r','d',0},
+ .serialnumber = {'0','0','0','0',0},
};
static NTSTATUS keyboard_device_create(void *args)
diff --git a/dlls/winebus.sys/unixlib.h b/dlls/winebus.sys/unixlib.h
index 317599571c2..e3996838c61 100644
--- a/dlls/winebus.sys/unixlib.h
+++ b/dlls/winebus.sys/unixlib.h
@@ -39,9 +39,9 @@ struct device_desc
DWORD uid;
BOOL is_gamepad;
- char manufacturer[MAX_PATH];
- char product[MAX_PATH];
- char serialnumber[MAX_PATH];
+ WCHAR manufacturer[MAX_PATH];
+ WCHAR product[MAX_PATH];
+ WCHAR serialnumber[MAX_PATH];
};
struct sdl_bus_options
--
2.25.1
2
1
[PATCH 1/7] d3d10/effect: Remove fixme from D3D10CreateEffectFromMemory().
by Nikolay Sivov Oct. 5, 2021
by Nikolay Sivov Oct. 5, 2021
Oct. 5, 2021
It's definitely not complete, but it's not a stub.
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/d3d10/effect.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/d3d10/effect.c b/dlls/d3d10/effect.c
index 5a5f9f37e6d..c135c76811d 100644
--- a/dlls/d3d10/effect.c
+++ b/dlls/d3d10/effect.c
@@ -8631,7 +8631,7 @@ HRESULT WINAPI D3D10CreateEffectFromMemory(void *data, SIZE_T data_size, UINT fl
ID3D10Effect *pool = NULL;
HRESULT hr;
- FIXME("data %p, data_size %lu, flags %#x, device %p, effect_pool %p, effect %p stub!\n",
+ TRACE("data %p, data_size %lu, flags %#x, device %p, effect_pool %p, effect %p.\n",
data, data_size, flags, device, effect_pool, effect);
if (!(flags & D3D10_EFFECT_COMPILE_CHILD_EFFECT) != !effect_pool)
--
2.33.0
3
18
Oct. 5, 2021
Advertising support of the periodic effect types only for now.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/winebus.sys/bus_sdl.c | 20 ++++-
dlls/winebus.sys/bus_udev.c | 19 +++-
dlls/winebus.sys/hid.c | 151 +++++++++++++++++++++++++++++++-
dlls/winebus.sys/unix_private.h | 21 ++++-
dlls/winebus.sys/unixlib.c | 14 +++
5 files changed, 220 insertions(+), 5 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index 33386a80a34..9c2112f8e56 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -174,7 +174,8 @@ static void set_hat_value(struct unix_device *iface, int index, int value)
static BOOL descriptor_add_haptic(struct sdl_device *impl)
{
- USHORT i;
+ USHORT i, count = 0;
+ USAGE usages[16];
if (!pSDL_JoystickIsHaptic(impl->sdl_joystick) ||
!(impl->sdl_haptic = pSDL_HapticOpenFromJoystick(impl->sdl_joystick)))
@@ -200,7 +201,13 @@ static BOOL descriptor_add_haptic(struct sdl_device *impl)
if ((impl->effect_support & EFFECT_SUPPORT_PHYSICAL))
{
- if (!hid_device_add_physical(&impl->unix_device))
+ /* SDL_HAPTIC_SQUARE doesn't exist */
+ if (impl->effect_support & SDL_HAPTIC_SINE) usages[count++] = PID_USAGE_ET_SINE;
+ if (impl->effect_support & SDL_HAPTIC_TRIANGLE) usages[count++] = PID_USAGE_ET_TRIANGLE;
+ if (impl->effect_support & SDL_HAPTIC_SAWTOOTHUP) usages[count++] = PID_USAGE_ET_SAWTOOTH_UP;
+ if (impl->effect_support & SDL_HAPTIC_SAWTOOTHDOWN) usages[count++] = PID_USAGE_ET_SAWTOOTH_DOWN;
+
+ if (!hid_device_add_physical(&impl->unix_device, usages, count))
return FALSE;
}
@@ -471,6 +478,14 @@ static NTSTATUS sdl_device_physical_effect_control(struct unix_device *iface, BY
return STATUS_SUCCESS;
}
+static NTSTATUS sdl_device_physical_effect_update(struct unix_device *iface, BYTE index,
+ struct effect_params *params)
+{
+ FIXME("iface %p, index %u, params %p stub!\n", iface, index, params);
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
static const struct hid_device_vtbl sdl_device_vtbl =
{
sdl_device_destroy,
@@ -479,6 +494,7 @@ static const struct hid_device_vtbl sdl_device_vtbl =
sdl_device_haptics_start,
sdl_device_physical_device_control,
sdl_device_physical_effect_control,
+ sdl_device_physical_effect_update,
};
static BOOL set_report_from_joystick_event(struct sdl_device *impl, SDL_Event *event)
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 3db261b2404..d63c9aab589 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -567,6 +567,8 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
BYTE ffbits[(FF_MAX+7)/8];
struct ff_effect effect;
USAGE_AND_PAGE usage;
+ USHORT count = 0;
+ USAGE usages[16];
INT i, button_count, abs_count, rel_count, hat_count;
const BYTE *device_usage = what_am_I(dev);
struct lnxev_device *impl = lnxev_impl_from_unix_device(iface);
@@ -664,7 +666,13 @@ static NTSTATUS build_report_descriptor(struct unix_device *iface, struct udev_d
for (i = 0; i < FF_MAX; ++i) if (test_bit(ffbits, i)) break;
if (i != FF_MAX)
{
- if (!hid_device_add_physical(iface))
+ if (test_bit(ffbits, FF_SINE)) usages[count++] = PID_USAGE_ET_SINE;
+ if (test_bit(ffbits, FF_SQUARE)) usages[count++] = PID_USAGE_ET_SQUARE;
+ if (test_bit(ffbits, FF_TRIANGLE)) usages[count++] = PID_USAGE_ET_TRIANGLE;
+ if (test_bit(ffbits, FF_SAW_UP)) usages[count++] = PID_USAGE_ET_SAWTOOTH_UP;
+ if (test_bit(ffbits, FF_SAW_DOWN)) usages[count++] = PID_USAGE_ET_SAWTOOTH_DOWN;
+
+ if (!hid_device_add_physical(iface, usages, count))
return STATUS_NO_MEMORY;
}
@@ -916,6 +924,14 @@ static NTSTATUS lnxev_device_physical_effect_control(struct unix_device *iface,
return STATUS_SUCCESS;
}
+static NTSTATUS lnxev_device_physical_effect_update(struct unix_device *iface, BYTE index,
+ struct effect_params *params)
+{
+ FIXME("iface %p, index %u, params %p stub!\n", iface, index, params);
+
+ return STATUS_NOT_IMPLEMENTED;
+}
+
static const struct hid_device_vtbl lnxev_device_vtbl =
{
lnxev_device_destroy,
@@ -924,6 +940,7 @@ static const struct hid_device_vtbl lnxev_device_vtbl =
lnxev_device_haptics_start,
lnxev_device_physical_device_control,
lnxev_device_physical_effect_control,
+ lnxev_device_physical_effect_update,
};
#endif /* HAS_PROPER_INPUT_HEADER */
diff --git a/dlls/winebus.sys/hid.c b/dlls/winebus.sys/hid.c
index 4ddee27cff9..72d358e6ad7 100644
--- a/dlls/winebus.sys/hid.c
+++ b/dlls/winebus.sys/hid.c
@@ -426,12 +426,27 @@ static const USAGE pid_effect_control_usages[] =
PID_USAGE_OP_EFFECT_START_SOLO,
PID_USAGE_OP_EFFECT_STOP,
};
+
+struct pid_effect_update
+{
+ BYTE index;
+ BYTE type_index;
+ UINT16 duration;
+ UINT16 trigger_repeat_interval;
+ UINT16 sample_period;
+ UINT16 start_delay;
+ BYTE gain;
+ BYTE trigger_button;
+ BYTE enable_bits;
+ BYTE direction[2];
+};
#include "poppack.h"
-BOOL hid_device_add_physical(struct unix_device *iface)
+BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count)
{
struct hid_report_descriptor *desc = &iface->hid_report_descriptor;
const BYTE device_control_report = ++desc->next_report_id[HidP_Output];
+ struct hid_device_state *state = &iface->hid_device_state;
const BYTE device_control_header[] =
{
USAGE_PAGE(1, HID_USAGE_PAGE_PID),
@@ -488,6 +503,95 @@ BOOL hid_device_add_physical(struct unix_device *iface)
OUTPUT(1, Data|Var|Abs),
END_COLLECTION,
};
+
+ const BYTE effect_update_report = ++desc->next_report_id[HidP_Output];
+ const BYTE effect_update_header[] =
+ {
+ /* Set effect properties */
+ USAGE(1, PID_USAGE_SET_EFFECT_REPORT),
+ COLLECTION(1, Logical),
+ REPORT_ID(1, effect_update_report),
+
+ USAGE(1, PID_USAGE_EFFECT_BLOCK_INDEX),
+ LOGICAL_MAXIMUM(1, 0x7f),
+ LOGICAL_MINIMUM(1, 0x00),
+ REPORT_SIZE(1, 8),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs),
+
+ USAGE(1, PID_USAGE_EFFECT_TYPE),
+ COLLECTION(1, Logical),
+ };
+ const BYTE effect_update_footer[] =
+ {
+ LOGICAL_MINIMUM(1, 1),
+ LOGICAL_MAXIMUM(1, count),
+ REPORT_SIZE(1, 8),
+ OUTPUT(1, Data|Ary|Abs),
+ END_COLLECTION,
+
+ USAGE(1, PID_USAGE_DURATION),
+ USAGE(1, PID_USAGE_TRIGGER_REPEAT_INTERVAL),
+ USAGE(1, PID_USAGE_SAMPLE_PERIOD),
+ USAGE(1, PID_USAGE_START_DELAY),
+ UNIT(2, 0x1003), /* Eng Lin:Time */
+ UNIT_EXPONENT(1, -3), /* 10^-3 */
+ LOGICAL_MINIMUM(1, 0),
+ LOGICAL_MAXIMUM(2, 0x7fff),
+ PHYSICAL_MINIMUM(1, 0),
+ PHYSICAL_MAXIMUM(2, 0x7fff),
+ REPORT_SIZE(1, 16),
+ REPORT_COUNT(1, 4),
+ OUTPUT(1, Data|Var|Abs),
+ PHYSICAL_MAXIMUM(1, 0),
+ UNIT_EXPONENT(1, 0),
+ UNIT(1, 0), /* None */
+
+ USAGE(1, PID_USAGE_GAIN),
+ LOGICAL_MAXIMUM(1, 0x7f),
+ REPORT_SIZE(1, 8),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs),
+
+ USAGE(1, PID_USAGE_TRIGGER_BUTTON),
+ LOGICAL_MAXIMUM(2, state->button_count),
+ REPORT_SIZE(1, 8),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs|Null),
+
+ USAGE(1, PID_USAGE_AXES_ENABLE),
+ COLLECTION(1, Logical),
+ USAGE(4, (HID_USAGE_PAGE_GENERIC<<16)|HID_USAGE_GENERIC_X),
+ USAGE(4, (HID_USAGE_PAGE_GENERIC<<16)|HID_USAGE_GENERIC_Y),
+ LOGICAL_MAXIMUM(1, 1),
+ REPORT_SIZE(1, 1),
+ REPORT_COUNT(1, 2),
+ OUTPUT(1, Data|Var|Abs),
+ END_COLLECTION,
+ USAGE(1, PID_USAGE_DIRECTION_ENABLE),
+ REPORT_COUNT(1, 1),
+ OUTPUT(1, Data|Var|Abs),
+ REPORT_COUNT(1, 5),
+ OUTPUT(1, Cnst|Var|Abs), /* 5-bit pad */
+
+ USAGE(1, PID_USAGE_DIRECTION),
+ COLLECTION(1, Logical),
+ USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|1),
+ USAGE(4, (HID_USAGE_PAGE_ORDINAL<<16)|2),
+ UNIT(1, 0x14), /* Eng Rot:Angular Pos */
+ UNIT_EXPONENT(1, -2),
+ LOGICAL_MINIMUM(1, 0),
+ LOGICAL_MAXIMUM(2, 0x00ff),
+ PHYSICAL_MAXIMUM(4, 36000),
+ REPORT_SIZE(1, 8),
+ REPORT_COUNT(1, 2),
+ OUTPUT(1, Data|Var|Abs),
+ END_COLLECTION,
+ PHYSICAL_MAXIMUM(1, 0),
+ UNIT_EXPONENT(1, 0),
+ UNIT(1, 0), /* None */
+ END_COLLECTION,
+ };
ULONG i;
if (!hid_report_descriptor_append(desc, device_control_header, sizeof(device_control_header)))
@@ -510,8 +614,22 @@ BOOL hid_device_add_physical(struct unix_device *iface)
if (!hid_report_descriptor_append(desc, effect_control_footer, sizeof(effect_control_footer)))
return FALSE;
+ if (!hid_report_descriptor_append(desc, effect_update_header, sizeof(effect_update_header)))
+ return FALSE;
+ for (i = 0; i < count; ++i)
+ {
+ if (!hid_report_descriptor_append_usage(desc, usages[i]))
+ return FALSE;
+ }
+ if (!hid_report_descriptor_append(desc, effect_update_footer, sizeof(effect_update_footer)))
+ return FALSE;
+
+ /* HID nary collection indexes start at 1 */
+ memcpy(iface->hid_physical.effect_types + 1, usages, count * sizeof(*usages));
+
iface->hid_physical.device_control_report = device_control_report;
iface->hid_physical.effect_control_report = effect_control_report;
+ iface->hid_physical.effect_update_report = effect_update_report;
return TRUE;
}
@@ -602,6 +720,37 @@ static void hid_device_set_output_report(struct unix_device *iface, HID_XFER_PAC
else
io->Status = iface->hid_vtbl->physical_effect_control(iface, report->index, control, report->iterations);
}
+ else if (packet->reportId == physical->effect_update_report)
+ {
+ struct pid_effect_update *report = (struct pid_effect_update *)(packet->reportBuffer + 1);
+ struct effect_params *params = iface->hid_physical.effect_params + report->index;
+ USAGE effect_type;
+
+ io->Information = sizeof(*report) + 1;
+ if (packet->reportBufferLen < io->Information)
+ io->Status = STATUS_BUFFER_TOO_SMALL;
+ else if (report->type_index >= ARRAY_SIZE(iface->hid_physical.effect_types))
+ io->Status = STATUS_INVALID_PARAMETER;
+ else if (!(effect_type = iface->hid_physical.effect_types[report->type_index]))
+ io->Status = STATUS_INVALID_PARAMETER;
+ else
+ {
+ params->effect_type = effect_type;
+ params->duration = report->duration;
+ params->trigger_repeat_interval = report->trigger_repeat_interval;
+ params->sample_period = report->sample_period;
+ params->start_delay = report->start_delay;
+ params->gain = report->gain;
+ params->trigger_button = report->trigger_button == 0xff ? 0 : report->trigger_button;
+ params->axis_enabled[0] = (report->enable_bits & 1) != 0;
+ params->axis_enabled[1] = (report->enable_bits & 2) != 0;
+ params->direction_enabled = (report->enable_bits & 4) != 0;
+ params->direction[0] = report->direction[0];
+ params->direction[1] = report->direction[1];
+
+ io->Status = iface->hid_vtbl->physical_effect_update(iface, report->index, params);
+ }
+ }
else
{
io->Information = 0;
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index 2446b8de4a7..125ee600eb6 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -29,6 +29,20 @@
#include "wine/list.h"
+struct effect_params
+{
+ USAGE effect_type;
+ UINT16 duration;
+ UINT16 trigger_repeat_interval;
+ UINT16 sample_period;
+ UINT16 start_delay;
+ BYTE gain;
+ BYTE trigger_button;
+ BOOL axis_enabled[2];
+ BOOL direction_enabled;
+ BYTE direction[2];
+};
+
struct raw_device_vtbl
{
void (*destroy)(struct unix_device *iface);
@@ -49,6 +63,7 @@ struct hid_device_vtbl
USHORT rumble_intensity, USHORT buzz_intensity);
NTSTATUS (*physical_device_control)(struct unix_device *iface, USAGE control);
NTSTATUS (*physical_effect_control)(struct unix_device *iface, BYTE index, USAGE control, BYTE iterations);
+ NTSTATUS (*physical_effect_update)(struct unix_device *iface, BYTE index, struct effect_params *params);
};
struct hid_report_descriptor
@@ -91,8 +106,12 @@ struct hid_haptics
struct hid_physical
{
+ USAGE effect_types[32];
+ struct effect_params effect_params[256];
+
BYTE device_control_report;
BYTE effect_control_report;
+ BYTE effect_update_report;
};
struct hid_device_state
@@ -161,7 +180,7 @@ extern BOOL hid_device_add_axes(struct unix_device *iface, BYTE count, USAGE usa
const USAGE *usages, BOOL rel, LONG min, LONG max) DECLSPEC_HIDDEN;
extern BOOL hid_device_add_haptics(struct unix_device *iface) DECLSPEC_HIDDEN;
-extern BOOL hid_device_add_physical(struct unix_device *iface) DECLSPEC_HIDDEN;
+extern BOOL hid_device_add_physical(struct unix_device *iface, USAGE *usages, USHORT count) DECLSPEC_HIDDEN;
extern BOOL hid_device_set_abs_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
extern BOOL hid_device_set_rel_axis(struct unix_device *iface, ULONG index, LONG value) DECLSPEC_HIDDEN;
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 29537170df7..c9d5fa5fd43 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -99,6 +99,12 @@ static NTSTATUS mouse_physical_effect_control(struct unix_device *iface, BYTE in
return STATUS_NOT_SUPPORTED;
}
+static NTSTATUS mouse_physical_effect_update(struct unix_device *iface, BYTE index,
+ struct effect_params *params)
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
static const struct hid_device_vtbl mouse_vtbl =
{
mouse_destroy,
@@ -107,6 +113,7 @@ static const struct hid_device_vtbl mouse_vtbl =
mouse_haptics_start,
mouse_physical_device_control,
mouse_physical_effect_control,
+ mouse_physical_effect_update,
};
static const struct device_desc mouse_device_desc =
@@ -169,6 +176,12 @@ static NTSTATUS keyboard_physical_effect_control(struct unix_device *iface, BYTE
return STATUS_NOT_SUPPORTED;
}
+static NTSTATUS keyboard_physical_effect_update(struct unix_device *iface, BYTE index,
+ struct effect_params *params)
+{
+ return STATUS_NOT_SUPPORTED;
+}
+
static const struct hid_device_vtbl keyboard_vtbl =
{
keyboard_destroy,
@@ -177,6 +190,7 @@ static const struct hid_device_vtbl keyboard_vtbl =
keyboard_haptics_start,
keyboard_physical_device_control,
keyboard_physical_effect_control,
+ keyboard_physical_effect_update,
};
static const struct device_desc keyboard_device_desc =
--
2.33.0
2
8
[PATCH 1/6] winexinput.sys: Fix casing of "Xbox One for Windows" product string.
by Rémi Bernon Oct. 5, 2021
by Rémi Bernon Oct. 5, 2021
Oct. 5, 2021
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
This is a series of patches from Proton, improving the compatibility for
some popular controllers.
dlls/winexinput.sys/main.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/winexinput.sys/main.c b/dlls/winexinput.sys/main.c
index 79c566e7cc8..56d60f55570 100644
--- a/dlls/winexinput.sys/main.c
+++ b/dlls/winexinput.sys/main.c
@@ -325,11 +325,11 @@ static const struct device_strings device_strings[] =
{
{ .id = L"VID_045E&PID_028E", .product = L"Controller (XBOX 360 For Windows)" },
{ .id = L"VID_045E&PID_028F", .product = L"Controller (XBOX 360 For Windows)" },
- { .id = L"VID_045E&PID_02D1", .product = L"Controller (XBOX One For Windows)" },
- { .id = L"VID_045E&PID_02DD", .product = L"Controller (XBOX One For Windows)" },
- { .id = L"VID_045E&PID_02E3", .product = L"Controller (XBOX One For Windows)" },
- { .id = L"VID_045E&PID_02EA", .product = L"Controller (XBOX One For Windows)" },
- { .id = L"VID_045E&PID_02FD", .product = L"Controller (XBOX One For Windows)" },
+ { .id = L"VID_045E&PID_02D1", .product = L"Controller (Xbox One For Windows)" },
+ { .id = L"VID_045E&PID_02DD", .product = L"Controller (Xbox One For Windows)" },
+ { .id = L"VID_045E&PID_02E3", .product = L"Controller (Xbox One For Windows)" },
+ { .id = L"VID_045E&PID_02EA", .product = L"Controller (Xbox One For Windows)" },
+ { .id = L"VID_045E&PID_02FD", .product = L"Controller (Xbox One For Windows)" },
{ .id = L"VID_045E&PID_0719", .product = L"Controller (XBOX 360 For Windows)" },
};
--
2.33.0
1
5
Oct. 5, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/iphlpapi/icmp.c | 58 -----------------------------------
dlls/iphlpapi/iphlpapi_main.c | 23 ++++++++++++++
2 files changed, 23 insertions(+), 58 deletions(-)
diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c
index 8ef03219e52..6441d7dd8ad 100644
--- a/dlls/iphlpapi/icmp.c
+++ b/dlls/iphlpapi/icmp.c
@@ -353,64 +353,6 @@ done:
* Exported Routines.
*/
-/***********************************************************************
- * Icmp6CreateFile (IPHLPAPI.@)
- */
-HANDLE WINAPI Icmp6CreateFile(VOID)
-{
- icmp_t* icp;
-
- int sid=socket(AF_INET6,SOCK_RAW,IPPROTO_ICMPV6);
- if (sid < 0)
- {
- /* Some systems (e.g. Linux 3.0+ and Mac OS X) support
- non-privileged ICMP via SOCK_DGRAM type. */
- sid=socket(AF_INET6,SOCK_DGRAM,IPPROTO_ICMPV6);
- }
- if (sid < 0) {
- ERR_(winediag)("Failed to use ICMPV6 (network ping), this requires special permissions.\n");
- SetLastError(ERROR_ACCESS_DENIED);
- return INVALID_HANDLE_VALUE;
- }
-
- icp=HeapAlloc(GetProcessHeap(), 0, sizeof(*icp));
- if (icp==NULL) {
- close(sid);
- SetLastError(IP_NO_RESOURCES);
- return INVALID_HANDLE_VALUE;
- }
- icp->sid=sid;
- icp->default_opts.OptionsSize=IP_OPTS_UNKNOWN;
- return (HANDLE)icp;
-}
-
-
-/***********************************************************************
- * Icmp6SendEcho2 (IPHLPAPI.@)
- */
-DWORD WINAPI Icmp6SendEcho2(
- HANDLE IcmpHandle,
- HANDLE Event,
- PIO_APC_ROUTINE ApcRoutine,
- PVOID ApcContext,
- struct sockaddr_in6* SourceAddress,
- struct sockaddr_in6* DestinationAddress,
- LPVOID RequestData,
- WORD RequestSize,
- PIP_OPTION_INFORMATION RequestOptions,
- LPVOID ReplyBuffer,
- DWORD ReplySize,
- DWORD Timeout
- )
-{
- FIXME("(%p, %p, %p, %p, %p, %p, %p, %d, %p, %p, %d, %d): stub\n", IcmpHandle, Event,
- ApcRoutine, ApcContext, SourceAddress, DestinationAddress, RequestData,
- RequestSize, RequestOptions, ReplyBuffer, ReplySize, Timeout);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
-
/***********************************************************************
* IcmpCreateFile (IPHLPAPI.@)
*/
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index 9e525a2116c..2286c732383 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -4555,3 +4555,26 @@ DWORD WINAPI IcmpParseReplies( void *reply, DWORD reply_size )
if (!num_pkts) SetLastError( icmp_reply->Status );
return num_pkts;
}
+
+/***********************************************************************
+ * Icmp6CreateFile (IPHLPAPI.@)
+ */
+HANDLE WINAPI Icmp6CreateFile( void )
+{
+ FIXME( "stub\n" );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return INVALID_HANDLE_VALUE;
+}
+
+/***********************************************************************
+ * Icmp6SendEcho2 (IPHLPAPI.@)
+ */
+DWORD WINAPI Icmp6SendEcho2( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc_routine, void *apc_ctxt,
+ struct sockaddr_in6 *src, struct sockaddr_in6 *dst, void *request, WORD request_size,
+ IP_OPTION_INFORMATION *opts, void *reply, DWORD reply_size, DWORD timeout )
+{
+ FIXME( "(%p, %p, %p, %p, %p, %p, %p, %d, %p, %p, %d, %d): stub\n", handle, event,
+ apc_routine, apc_ctxt, src, dst, request, request_size, opts, reply, reply_size, timeout );
+ SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
+ return 0;
+}
--
2.23.0
1
0
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/iphlpapi/iphlpapi.spec | 2 +-
dlls/iphlpapi/iphlpapi_main.c | 14 ++++++++++
dlls/iphlpapi/tests/iphlpapi.c | 49 ++++++++++++++++++++++++----------
3 files changed, 50 insertions(+), 15 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi.spec b/dlls/iphlpapi/iphlpapi.spec
index 6c51548b6e3..ce188084c01 100644
--- a/dlls/iphlpapi/iphlpapi.spec
+++ b/dlls/iphlpapi/iphlpapi.spec
@@ -157,7 +157,7 @@
@ stdcall Icmp6SendEcho2(ptr ptr ptr ptr ptr ptr ptr long ptr ptr long long)
@ stdcall IcmpCloseHandle(ptr)
@ stdcall IcmpCreateFile()
-@ stub IcmpParseReplies
+@ stdcall IcmpParseReplies(ptr long)
@ stdcall IcmpSendEcho2Ex(ptr ptr ptr ptr long long ptr long ptr ptr long long)
@ stdcall IcmpSendEcho2(ptr ptr ptr ptr long ptr long ptr ptr long long)
@ stdcall IcmpSendEcho(ptr long ptr long ptr ptr long long)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index d52441f022a..9e525a2116c 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -2,6 +2,7 @@
* iphlpapi dll implementation
*
* Copyright (C) 2003,2006 Juan Lang
+ * Copyright 2021 Huw Davies
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -4541,3 +4542,16 @@ DWORD WINAPI ParseNetworkString(const WCHAR *str, DWORD type,
return ERROR_INVALID_PARAMETER;
}
+
+/******************************************************************
+ * IcmpParseReplies (IPHLPAPI.@)
+ */
+DWORD WINAPI IcmpParseReplies( void *reply, DWORD reply_size )
+{
+ ICMP_ECHO_REPLY *icmp_reply = reply;
+ DWORD num_pkts = icmp_reply->Reserved;
+
+ icmp_reply->Reserved = 0;
+ if (!num_pkts) SetLastError( icmp_reply->Status );
+ return num_pkts;
+}
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c
index 223d6d270cb..080feb364f9 100644
--- a/dlls/iphlpapi/tests/iphlpapi.c
+++ b/dlls/iphlpapi/tests/iphlpapi.c
@@ -1043,20 +1043,40 @@ static void testIcmpSendEcho(void)
IcmpCloseHandle(icmp);
}
-/*
-still-to-be-tested NT4-onward functions:
-CreateIpForwardEntry
-DeleteIpForwardEntry
-CreateIpNetEntry
-DeleteIpNetEntry
-GetFriendlyIfIndex
-GetRTTAndHopCount
-SetIfEntry
-SetIpForwardEntry
-SetIpNetEntry
-SetIpStatistics
-SetIpTTL
-*/
+static void testIcmpParseReplies( void )
+{
+ ICMP_ECHO_REPLY reply = { 0 };
+ DWORD ret;
+
+ SetLastError( 0xdeadbeef );
+ ret = IcmpParseReplies( &reply, sizeof(reply) );
+ ok( ret == 0, "ret %d\n", ret );
+ ok( GetLastError() == 0, "gle %d\n", GetLastError() );
+
+ reply.Status = 12345;
+ SetLastError( 0xdeadbeef );
+ ret = IcmpParseReplies( &reply, sizeof(reply) );
+ ok( ret == 0, "ret %d\n", ret );
+ ok( GetLastError() == 12345, "gle %d\n", GetLastError() );
+ ok( reply.Status == 12345, "status %d\n", reply.Status );
+
+ reply.Reserved = 1;
+ SetLastError( 0xdeadbeef );
+ ret = IcmpParseReplies( &reply, sizeof(reply) );
+ ok( ret == 1, "ret %d\n", ret );
+ ok( GetLastError() == 0xdeadbeef, "gle %d\n", GetLastError() );
+ ok( reply.Status == 12345, "status %d\n", reply.Status );
+ ok( !reply.Reserved, "reserved %d\n", reply.Reserved );
+
+ reply.Reserved = 3;
+ SetLastError( 0xdeadbeef );
+ ret = IcmpParseReplies( &reply, sizeof(reply) );
+ ok( ret == 3, "ret %d\n", ret );
+ ok( GetLastError() == 0xdeadbeef, "gle %d\n", GetLastError() );
+ ok( reply.Status == 12345, "status %d\n", reply.Status );
+ ok( !reply.Reserved, "reserved %d\n", reply.Reserved );
+}
+
static void testWinNT4Functions(void)
{
testGetNumberOfInterfaces();
@@ -1076,6 +1096,7 @@ static void testWinNT4Functions(void)
testGetUdpTable();
testSetTcpEntry();
testIcmpSendEcho();
+ testIcmpParseReplies();
}
static void testGetInterfaceInfo(void)
--
2.23.0
1
0
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/iphlpapi/iphlpapi_main.c | 216 +++++++++++++++++-----------------
1 file changed, 105 insertions(+), 111 deletions(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c
index ae356dc7b8c..d52441f022a 100644
--- a/dlls/iphlpapi/iphlpapi_main.c
+++ b/dlls/iphlpapi/iphlpapi_main.c
@@ -24,7 +24,6 @@
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
-#define USE_WS_PREFIX
#include "winsock2.h"
#include "winternl.h"
#include "ws2ipdef.h"
@@ -45,11 +44,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(iphlpapi);
-#ifndef INADDR_NONE
-#define INADDR_NONE ~0UL
-#endif
-#define INADDR_ANY 0UL
-
#define CHARS_IN_GUID 39
static const WCHAR device_tcpip[] = {'\\','D','E','V','I','C','E','\\','T','C','P','I','P','_',0};
@@ -58,8 +52,8 @@ DWORD WINAPI AllocateAndGetIpAddrTableFromStack( MIB_IPADDRTABLE **table, BOOL s
static const NPI_MODULEID *ip_module_id( USHORT family )
{
- if (family == WS_AF_INET) return &NPI_MS_IPV4_MODULEID;
- if (family == WS_AF_INET6) return &NPI_MS_IPV6_MODULEID;
+ if (family == AF_INET) return &NPI_MS_IPV4_MODULEID;
+ if (family == AF_INET6) return &NPI_MS_IPV6_MODULEID;
return NULL;
}
@@ -230,7 +224,7 @@ DWORD WINAPI CreateProxyArpEntry(DWORD dwAddress, DWORD dwMask, DWORD dwIfIndex)
return ERROR_NOT_SUPPORTED;
}
-static char *debugstr_ipv6(const struct WS_sockaddr_in6 *sin, char *buf)
+static char *debugstr_ipv6(const struct sockaddr_in6 *sin, char *buf)
{
const IN6_ADDR *addr = &sin->sin6_addr;
char *p = buf;
@@ -263,14 +257,14 @@ static BOOL map_address_6to4( const SOCKADDR_IN6 *addr6, SOCKADDR_IN *addr4 )
{
ULONG i;
- if (addr6->sin6_family != WS_AF_INET6) return FALSE;
+ if (addr6->sin6_family != AF_INET6) return FALSE;
for (i = 0; i < 5; i++)
if (addr6->sin6_addr.u.Word[i]) return FALSE;
if (addr6->sin6_addr.u.Word[5] != 0xffff) return FALSE;
- addr4->sin_family = WS_AF_INET;
+ addr4->sin_family = AF_INET;
addr4->sin_port = addr6->sin6_port;
addr4->sin_addr.S_un.S_addr = addr6->sin6_addr.u.Word[6] << 16 | addr6->sin6_addr.u.Word[7];
memset( &addr4->sin_zero, 0, sizeof(addr4->sin_zero) );
@@ -290,7 +284,7 @@ static BOOL find_src_address( MIB_IPADDRTABLE *table, const SOCKADDR_IN *dst, SO
/* take the first address */
if (table->table[i].dwIndex == row.dwForwardIfIndex)
{
- src->sin6_family = WS_AF_INET6;
+ src->sin6_family = AF_INET6;
src->sin6_port = 0;
src->sin6_flowinfo = 0;
for (j = 0; j < 5; j++) src->sin6_addr.u.Word[j] = 0;
@@ -353,7 +347,7 @@ DWORD WINAPI CreateSortedAddressPairs( const PSOCKADDR_IN6 src_list, DWORD src_c
char buf[46];
FIXME( "source address for %s not found\n", debugstr_ipv6(&dst_list[i], buf) );
memset( pairs[i].SourceAddress, 0, sizeof(*pairs[i].SourceAddress) );
- pairs[i].SourceAddress->sin6_family = WS_AF_INET6;
+ pairs[i].SourceAddress->sin6_family = AF_INET6;
}
pairs[i].DestinationAddress = ptr++;
@@ -565,7 +559,7 @@ static DWORD get_wins_servers( SOCKADDR_INET **servers )
size = sizeof(buf);
if (!RegQueryValueExA( key, values[i], NULL, NULL, (LPBYTE)buf, &size ))
if (!RtlIpv4StringToAddressA( buf, TRUE, NULL, addrs + count ) &&
- addrs[count].WS_s_addr != INADDR_NONE && addrs[count].WS_s_addr != INADDR_ANY)
+ addrs[count].s_addr != INADDR_NONE && addrs[count].s_addr != INADDR_ANY)
count++;
}
RegCloseKey( key );
@@ -576,7 +570,7 @@ static DWORD get_wins_servers( SOCKADDR_INET **servers )
if (!*servers) return 0;
for (i = 0; i < count; i++)
{
- (*servers)[i].Ipv4.sin_family = WS_AF_INET;
+ (*servers)[i].Ipv4.sin_family = AF_INET;
(*servers)[i].Ipv4.sin_addr = addrs[i];
}
}
@@ -690,21 +684,21 @@ DWORD WINAPI GetAdaptersInfo( IP_ADAPTER_INFO *info, ULONG *size )
cursor->Next = extra_ip_addrs++;
cursor = cursor->Next;
}
- ConvertLengthToIpv4Mask( uni_rw[uni].on_link_prefix, &mask.WS_s_addr );
+ ConvertLengthToIpv4Mask( uni_rw[uni].on_link_prefix, &mask.s_addr );
ip_addr_string_init( cursor, &uni_keys[uni].addr, &mask, 0 );
}
if (!cursor)
{
- mask.WS_s_addr = INADDR_ANY;
+ mask.s_addr = INADDR_ANY;
ip_addr_string_init( &info->IpAddressList, &mask, &mask, 0 );
}
- gw.WS_s_addr = INADDR_ANY;
- mask.WS_s_addr = INADDR_NONE;
+ gw.s_addr = INADDR_ANY;
+ mask.s_addr = INADDR_NONE;
for (fwd = 0; fwd < fwd_count; fwd++)
{ /* find the first router on this interface */
if (fwd_keys[fwd].luid.Value == if_keys[i].Value &&
- fwd_keys[fwd].next_hop.WS_s_addr != INADDR_ANY &&
+ fwd_keys[fwd].next_hop.s_addr != INADDR_ANY &&
!fwd_keys[fwd].prefix_len)
{
gw = fwd_keys[fwd].next_hop;
@@ -720,7 +714,7 @@ DWORD WINAPI GetAdaptersInfo( IP_ADAPTER_INFO *info, ULONG *size )
ip_addr_string_init( &info->SecondaryWinsServer, NULL, NULL, 0 );
if (info->HaveWins)
{
- mask.WS_s_addr = INADDR_NONE;
+ mask.s_addr = INADDR_NONE;
ip_addr_string_init( &info->PrimaryWinsServer, &wins_servers[0].Ipv4.sin_addr, &mask, 0 );
if (wins_server_count > 1)
ip_addr_string_init( &info->SecondaryWinsServer, &wins_servers[1].Ipv4.sin_addr, &mask, 0 );
@@ -897,25 +891,25 @@ static void adapters_addresses_copy( IP_ADAPTER_ADDRESSES *dst, IP_ADAPTER_ADDRE
static BOOL sockaddr_is_loopback( SOCKADDR *sock )
{
- if (sock->sa_family == WS_AF_INET)
+ if (sock->sa_family == AF_INET)
{
SOCKADDR_IN *sin = (SOCKADDR_IN *)sock;
- return (sin->sin_addr.WS_s_addr & 0xff) == 127;
+ return (sin->sin_addr.s_addr & 0xff) == 127;
}
- else if (sock->sa_family == WS_AF_INET6)
+ else if (sock->sa_family == AF_INET6)
{
SOCKADDR_IN6 *sin6 = (SOCKADDR_IN6 *)sock;
- return WS_IN6_IS_ADDR_LOOPBACK( &sin6->sin6_addr );
+ return IN6_IS_ADDR_LOOPBACK( &sin6->sin6_addr );
}
return FALSE;
}
static BOOL sockaddr_is_linklocal( SOCKADDR *sock )
{
- if (sock->sa_family == WS_AF_INET6)
+ if (sock->sa_family == AF_INET6)
{
SOCKADDR_IN6 *sin6 = (SOCKADDR_IN6 *)sock;
- return WS_IN6_IS_ADDR_LINKLOCAL( &sin6->sin6_addr );
+ return IN6_IS_ADDR_LINKLOCAL( &sin6->sin6_addr );
}
return FALSE;
}
@@ -934,8 +928,8 @@ static DWORD unicast_addresses_alloc( IP_ADAPTER_ADDRESSES *aa, ULONG family, UL
struct nsi_ip_unicast_dynamic *dyn;
struct nsi_ip_unicast_static *stat;
IP_ADAPTER_UNICAST_ADDRESS *addr, **next;
- DWORD err, count, i, key_size = (family == WS_AF_INET) ? sizeof(*key4) : sizeof(*key6);
- DWORD sockaddr_size = (family == WS_AF_INET) ? sizeof(SOCKADDR_IN) : sizeof(SOCKADDR_IN6);
+ DWORD err, count, i, key_size = (family == AF_INET) ? sizeof(*key4) : sizeof(*key6);
+ DWORD sockaddr_size = (family == AF_INET) ? sizeof(SOCKADDR_IN) : sizeof(SOCKADDR_IN6);
NET_LUID *luid;
void *key;
@@ -954,7 +948,7 @@ static DWORD unicast_addresses_alloc( IP_ADAPTER_ADDRESSES *aa, ULONG family, UL
{
key4 = (struct nsi_ipv4_unicast_key *)key + i;
key6 = (struct nsi_ipv6_unicast_key *)key + i;
- luid = (family == WS_AF_INET) ? &key4->luid : &key6->luid;
+ luid = (family == AF_INET) ? &key4->luid : &key6->luid;
if (luid->Value != aa->Luid.Value) continue;
addr = heap_alloc_zero( sizeof(*addr) + sockaddr_size );
if (!addr)
@@ -966,7 +960,7 @@ static DWORD unicast_addresses_alloc( IP_ADAPTER_ADDRESSES *aa, ULONG family, UL
addr->Address.lpSockaddr = (SOCKADDR *)(addr + 1);
addr->Address.iSockaddrLength = sockaddr_size;
addr->Address.lpSockaddr->sa_family = family;
- if (family == WS_AF_INET)
+ if (family == AF_INET)
{
SOCKADDR_IN *in = (SOCKADDR_IN *)addr->Address.lpSockaddr;
in->sin_addr = key4->addr;
@@ -1003,8 +997,8 @@ static DWORD gateway_and_prefix_addresses_alloc( IP_ADAPTER_ADDRESSES *aa, ULONG
struct nsi_ipv6_forward_key *key6;
IP_ADAPTER_GATEWAY_ADDRESS *gw, **gw_next;
IP_ADAPTER_PREFIX *prefix, **prefix_next;
- DWORD err, count, i, prefix_len, key_size = (family == WS_AF_INET) ? sizeof(*key4) : sizeof(*key6);
- DWORD sockaddr_size = (family == WS_AF_INET) ? sizeof(SOCKADDR_IN) : sizeof(SOCKADDR_IN6);
+ DWORD err, count, i, prefix_len, key_size = (family == AF_INET) ? sizeof(*key4) : sizeof(*key6);
+ DWORD sockaddr_size = (family == AF_INET) ? sizeof(SOCKADDR_IN) : sizeof(SOCKADDR_IN6);
SOCKADDR_INET sockaddr;
NET_LUID *luid;
void *key;
@@ -1024,15 +1018,15 @@ static DWORD gateway_and_prefix_addresses_alloc( IP_ADAPTER_ADDRESSES *aa, ULONG
{
key4 = (struct nsi_ipv4_forward_key *)key + i;
key6 = (struct nsi_ipv6_forward_key *)key + i;
- luid = (family == WS_AF_INET) ? &key4->luid : &key6->luid;
+ luid = (family == AF_INET) ? &key4->luid : &key6->luid;
if (luid->Value != aa->Luid.Value) continue;
if (flags & GAA_FLAG_INCLUDE_ALL_GATEWAYS)
{
memset( &sockaddr, 0, sizeof(sockaddr) );
- if (family == WS_AF_INET)
+ if (family == AF_INET)
{
- if (key4->next_hop.WS_s_addr != 0)
+ if (key4->next_hop.s_addr != 0)
{
sockaddr.si_family = family;
sockaddr.Ipv4.sin_addr = key4->next_hop;
@@ -1068,9 +1062,9 @@ static DWORD gateway_and_prefix_addresses_alloc( IP_ADAPTER_ADDRESSES *aa, ULONG
if (flags & GAA_FLAG_INCLUDE_PREFIX)
{
memset( &sockaddr, 0, sizeof(sockaddr) );
- if (family == WS_AF_INET)
+ if (family == AF_INET)
{
- if (!key4->next_hop.WS_s_addr)
+ if (!key4->next_hop.s_addr)
{
sockaddr.si_family = family;
sockaddr.Ipv4.sin_addr = key4->prefix;
@@ -1119,15 +1113,15 @@ static DWORD call_families( DWORD (*fn)( IP_ADAPTER_ADDRESSES *aa, ULONG family,
{
DWORD err;
- if (family != WS_AF_INET)
+ if (family != AF_INET)
{
- err = fn( aa, WS_AF_INET6, flags );
+ err = fn( aa, AF_INET6, flags );
if (err) return err;
}
- if (family != WS_AF_INET6)
+ if (family != AF_INET6)
{
- err = fn( aa, WS_AF_INET, flags );
+ err = fn( aa, AF_INET, flags );
if (err) return err;
}
return err;
@@ -1135,8 +1129,8 @@ static DWORD call_families( DWORD (*fn)( IP_ADAPTER_ADDRESSES *aa, ULONG family,
static DWORD dns_servers_query_code( ULONG family )
{
- if (family == WS_AF_INET) return DnsConfigDnsServersIpv4;
- if (family == WS_AF_INET6) return DnsConfigDnsServersIpv6;
+ if (family == AF_INET) return DnsConfigDnsServersIpv4;
+ if (family == AF_INET6) return DnsConfigDnsServersIpv6;
return DnsConfigDnsServersUnspec;
}
@@ -1336,11 +1330,11 @@ ULONG WINAPI DECLSPEC_HOTPATCH GetAdaptersAddresses( ULONG family, ULONG flags,
*/
DWORD WINAPI GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex)
{
- struct WS_sockaddr_in sa_in;
+ struct sockaddr_in sa_in;
memset(&sa_in, 0, sizeof(sa_in));
- sa_in.sin_family = WS_AF_INET;
+ sa_in.sin_family = AF_INET;
sa_in.sin_addr.S_un.S_addr = dwDestAddr;
- return GetBestInterfaceEx((struct WS_sockaddr *)&sa_in, pdwBestIfIndex);
+ return GetBestInterfaceEx((struct sockaddr *)&sa_in, pdwBestIfIndex);
}
/******************************************************************
@@ -1356,7 +1350,7 @@ DWORD WINAPI GetBestInterface(IPAddr dwDestAddr, PDWORD pdwBestIfIndex)
* Success: NO_ERROR
* Failure: error code from winerror.h
*/
-DWORD WINAPI GetBestInterfaceEx(struct WS_sockaddr *pDestAddr, PDWORD pdwBestIfIndex)
+DWORD WINAPI GetBestInterfaceEx(struct sockaddr *pDestAddr, PDWORD pdwBestIfIndex)
{
DWORD ret;
@@ -1366,8 +1360,8 @@ DWORD WINAPI GetBestInterfaceEx(struct WS_sockaddr *pDestAddr, PDWORD pdwBestIfI
else {
MIB_IPFORWARDROW ipRow;
- if (pDestAddr->sa_family == WS_AF_INET) {
- ret = GetBestRoute(((struct WS_sockaddr_in *)pDestAddr)->sin_addr.S_un.S_addr, 0, &ipRow);
+ if (pDestAddr->sa_family == AF_INET) {
+ ret = GetBestRoute(((struct sockaddr_in *)pDestAddr)->sin_addr.S_un.S_addr, 0, &ipRow);
if (ret == ERROR_SUCCESS)
*pdwBestIfIndex = ipRow.dwForwardIfIndex;
} else {
@@ -1495,7 +1489,7 @@ static void icmp_stats_ex_to_icmp_stats( MIBICMPSTATS_EX *stats_ex, MIBICMPSTATS
DWORD WINAPI GetIcmpStatistics( MIB_ICMP *stats )
{
MIB_ICMP_EX stats_ex;
- DWORD err = GetIcmpStatisticsEx( &stats_ex, WS_AF_INET );
+ DWORD err = GetIcmpStatisticsEx( &stats_ex, AF_INET );
if (err) return err;
@@ -1984,7 +1978,7 @@ DWORD WINAPI GetIpAddrTable( MIB_IPADDRTABLE *table, ULONG *size, BOOL sort )
if (!!loopback != (keys[i].luid.Info.IfType == MIB_IF_TYPE_LOOPBACK)) continue;
- row->dwAddr = keys[i].addr.WS_s_addr;
+ row->dwAddr = keys[i].addr.s_addr;
ConvertInterfaceLuidToIndex( &keys[i].luid, &row->dwIndex );
ConvertLengthToIpv4Mask( rw[i].on_link_prefix, &row->dwMask );
row->dwBCastAddr = 1;
@@ -2098,10 +2092,10 @@ DWORD WINAPI GetIpForwardTable( MIB_IPFORWARDTABLE *table, ULONG *size, BOOL sor
{
MIB_IPFORWARDROW *row = table->table + i;
- row->dwForwardDest = keys[i].prefix.WS_s_addr;
+ row->dwForwardDest = keys[i].prefix.s_addr;
ConvertLengthToIpv4Mask( keys[i].prefix_len, &row->dwForwardMask );
row->dwForwardPolicy = 0;
- row->dwForwardNextHop = keys[i].next_hop.WS_s_addr;
+ row->dwForwardNextHop = keys[i].next_hop.s_addr;
row->u1.dwForwardType = row->dwForwardNextHop ? MIB_IPROUTE_TYPE_INDIRECT : MIB_IPROUTE_TYPE_DIRECT;
if (!row->dwForwardNextHop) /* find the interface's addr */
{
@@ -2109,7 +2103,7 @@ DWORD WINAPI GetIpForwardTable( MIB_IPFORWARDTABLE *table, ULONG *size, BOOL sor
{
if (uni_keys[addr].luid.Value == keys[i].luid.Value)
{
- row->dwForwardNextHop = uni_keys[addr].addr.WS_s_addr;
+ row->dwForwardNextHop = uni_keys[addr].addr.s_addr;
break;
}
}
@@ -2178,7 +2172,7 @@ static void forward_row2_fill( MIB_IPFORWARD_ROW2 *row, USHORT fam, void *key, s
struct nsi_ipv4_forward_dynamic *dyn4 = (struct nsi_ipv4_forward_dynamic *)dyn;
struct nsi_ipv6_forward_dynamic *dyn6 = (struct nsi_ipv6_forward_dynamic *)dyn;
- if (fam == WS_AF_INET)
+ if (fam == AF_INET)
{
row->InterfaceLuid = key4->luid;
row->DestinationPrefix.Prefix.Ipv4.sin_family = fam;
@@ -2236,19 +2230,19 @@ DWORD WINAPI GetIpForwardTable2( ADDRESS_FAMILY family, MIB_IPFORWARD_TABLE2 **t
struct nsi_ip_forward_rw *rw[2] = { NULL, NULL };
void *dyn[2] = { NULL, NULL };
struct nsi_ip_forward_static *stat[2] = { NULL, NULL };
- static const USHORT fam[2] = { WS_AF_INET, WS_AF_INET6 };
+ static const USHORT fam[2] = { AF_INET, AF_INET6 };
static const DWORD key_size[2] = { sizeof(struct nsi_ipv4_forward_key), sizeof(struct nsi_ipv6_forward_key) };
static const DWORD dyn_size[2] = { sizeof(struct nsi_ipv4_forward_dynamic), sizeof(struct nsi_ipv6_forward_dynamic) };
DWORD err = ERROR_SUCCESS, i, size, count[2] = { 0, 0 };
TRACE( "%u, %p\n", family, table );
- if (!table || (family != WS_AF_INET && family != WS_AF_INET6 && family != WS_AF_UNSPEC))
+ if (!table || (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC))
return ERROR_INVALID_PARAMETER;
for (i = 0; i < 2; i++)
{
- if (family != WS_AF_UNSPEC && family != fam[i]) continue;
+ if (family != AF_UNSPEC && family != fam[i]) continue;
err = NsiAllocateAndGetTable( 1, ip_module_id( fam[i] ), NSI_IP_FORWARD_TABLE, key + i, key_size[i],
(void **)rw + i, sizeof(**rw), dyn + i, dyn_size[i],
@@ -2347,7 +2341,7 @@ DWORD WINAPI GetIpNetTable( MIB_IPNETTABLE *table, ULONG *size, BOOL sort )
memcpy( row->bPhysAddr, rw[i].phys_addr, row->dwPhysAddrLen );
memset( row->bPhysAddr + row->dwPhysAddrLen, 0,
sizeof(row->bPhysAddr) - row->dwPhysAddrLen );
- row->dwAddr = keys[i].addr.WS_s_addr;
+ row->dwAddr = keys[i].addr.s_addr;
switch (dyn->state)
{
case NlnsUnreachable:
@@ -2404,7 +2398,7 @@ static void ipnet_row2_fill( MIB_IPNET_ROW2 *row, USHORT fam, void *key, struct
struct nsi_ipv4_neighbour_key *key4 = (struct nsi_ipv4_neighbour_key *)key;
struct nsi_ipv6_neighbour_key *key6 = (struct nsi_ipv6_neighbour_key *)key;
- if (fam == WS_AF_INET)
+ if (fam == AF_INET)
{
row->Address.Ipv4.sin_family = fam;
row->Address.Ipv4.sin_port = 0;
@@ -2445,18 +2439,18 @@ DWORD WINAPI GetIpNetTable2( ADDRESS_FAMILY family, MIB_IPNET_TABLE2 **table )
void *key[2] = { NULL, NULL };
struct nsi_ip_neighbour_rw *rw[2] = { NULL, NULL };
struct nsi_ip_neighbour_dynamic *dyn[2] = { NULL, NULL };
- static const USHORT fam[2] = { WS_AF_INET, WS_AF_INET6 };
+ static const USHORT fam[2] = { AF_INET, AF_INET6 };
static const DWORD key_size[2] = { sizeof(struct nsi_ipv4_neighbour_key), sizeof(struct nsi_ipv6_neighbour_key) };
DWORD err = ERROR_SUCCESS, i, size, count[2] = { 0, 0 };
TRACE( "%u, %p\n", family, table );
- if (!table || (family != WS_AF_INET && family != WS_AF_INET6 && family != WS_AF_UNSPEC))
+ if (!table || (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC))
return ERROR_INVALID_PARAMETER;
for (i = 0; i < 2; i++)
{
- if (family != WS_AF_UNSPEC && family != fam[i]) continue;
+ if (family != AF_UNSPEC && family != fam[i]) continue;
err = NsiAllocateAndGetTable( 1, ip_module_id( fam[i] ), NSI_IP_NEIGHBOUR_TABLE, key + i, key_size[i],
(void **)rw + i, sizeof(**rw), (void **)dyn + i, sizeof(**dyn),
@@ -2508,7 +2502,7 @@ err:
*/
DWORD WINAPI GetIpStatistics( MIB_IPSTATS *stats )
{
- return GetIpStatisticsEx( stats, WS_AF_INET );
+ return GetIpStatisticsEx( stats, AF_INET );
}
/******************************************************************
@@ -2802,7 +2796,7 @@ BOOL WINAPI GetRTTAndHopCount(IPAddr DestIpAddress, PULONG HopCount, ULONG MaxHo
*/
DWORD WINAPI GetTcpStatistics( MIB_TCPSTATS *stats )
{
- return GetTcpStatisticsEx( stats, WS_AF_INET );
+ return GetTcpStatisticsEx( stats, AF_INET );
}
/******************************************************************
@@ -2886,27 +2880,27 @@ static DWORD tcp_table_size( ULONG family, ULONG table_class, DWORD row_count, D
case TCP_TABLE_BASIC_LISTENER:
case TCP_TABLE_BASIC_CONNECTIONS:
case TCP_TABLE_BASIC_ALL:
- *row_size = (family == WS_AF_INET) ? sizeof(MIB_TCPROW) : sizeof(MIB_TCP6ROW);
- return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE, table[row_count]) :
+ *row_size = (family == AF_INET) ? sizeof(MIB_TCPROW) : sizeof(MIB_TCP6ROW);
+ return (family == AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE, table[row_count]) :
FIELD_OFFSET(MIB_TCP6TABLE, table[row_count]);
case TCP_TABLE_OWNER_PID_LISTENER:
case TCP_TABLE_OWNER_PID_CONNECTIONS:
case TCP_TABLE_OWNER_PID_ALL:
- *row_size = (family == WS_AF_INET) ? sizeof(MIB_TCPROW_OWNER_PID) : sizeof(MIB_TCP6ROW_OWNER_PID);
- return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE_OWNER_PID, table[row_count]) :
+ *row_size = (family == AF_INET) ? sizeof(MIB_TCPROW_OWNER_PID) : sizeof(MIB_TCP6ROW_OWNER_PID);
+ return (family == AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE_OWNER_PID, table[row_count]) :
FIELD_OFFSET(MIB_TCP6TABLE_OWNER_PID, table[row_count]);
case TCP_TABLE_OWNER_MODULE_LISTENER:
case TCP_TABLE_OWNER_MODULE_CONNECTIONS:
case TCP_TABLE_OWNER_MODULE_ALL:
- *row_size = (family == WS_AF_INET) ? sizeof(MIB_TCPROW_OWNER_MODULE) : sizeof(MIB_TCP6ROW_OWNER_MODULE);
- return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table[row_count]) :
+ *row_size = (family == AF_INET) ? sizeof(MIB_TCPROW_OWNER_MODULE) : sizeof(MIB_TCP6ROW_OWNER_MODULE);
+ return (family == AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE_OWNER_MODULE, table[row_count]) :
FIELD_OFFSET(MIB_TCP6TABLE_OWNER_MODULE, table[row_count]);
case TCP_TABLE2:
- *row_size = (family == WS_AF_INET) ? sizeof(MIB_TCPROW2) : sizeof(MIB_TCP6ROW2);
- return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE2, table[row_count]) :
+ *row_size = (family == AF_INET) ? sizeof(MIB_TCPROW2) : sizeof(MIB_TCP6ROW2);
+ return (family == AF_INET) ? FIELD_OFFSET(MIB_TCPTABLE2, table[row_count]) :
FIELD_OFFSET(MIB_TCP6TABLE2, table[row_count]);
default:
@@ -2919,7 +2913,7 @@ static void tcp_row_fill( void *table, DWORD num, ULONG family, ULONG table_clas
struct nsi_tcp_conn_key *key, struct nsi_tcp_conn_dynamic *dyn,
struct nsi_tcp_conn_static *stat )
{
- if (family == WS_AF_INET)
+ if (family == AF_INET)
{
switch (table_class)
{
@@ -2929,9 +2923,9 @@ static void tcp_row_fill( void *table, DWORD num, ULONG family, ULONG table_clas
{
MIB_TCPROW *row = ((MIB_TCPTABLE *)table)->table + num;
row->u.dwState = dyn->state;
- row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+ row->dwLocalAddr = key->local.Ipv4.sin_addr.s_addr;
row->dwLocalPort = key->local.Ipv4.sin_port;
- row->dwRemoteAddr = key->remote.Ipv4.sin_addr.WS_s_addr;
+ row->dwRemoteAddr = key->remote.Ipv4.sin_addr.s_addr;
row->dwRemotePort = key->remote.Ipv4.sin_port;
return;
}
@@ -2941,9 +2935,9 @@ static void tcp_row_fill( void *table, DWORD num, ULONG family, ULONG table_clas
{
MIB_TCPROW_OWNER_PID *row = ((MIB_TCPTABLE_OWNER_PID *)table)->table + num;
row->dwState = dyn->state;
- row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+ row->dwLocalAddr = key->local.Ipv4.sin_addr.s_addr;
row->dwLocalPort = key->local.Ipv4.sin_port;
- row->dwRemoteAddr = key->remote.Ipv4.sin_addr.WS_s_addr;
+ row->dwRemoteAddr = key->remote.Ipv4.sin_addr.s_addr;
row->dwRemotePort = key->remote.Ipv4.sin_port;
row->dwOwningPid = stat->pid;
return;
@@ -2954,9 +2948,9 @@ static void tcp_row_fill( void *table, DWORD num, ULONG family, ULONG table_clas
{
MIB_TCPROW_OWNER_MODULE *row = ((MIB_TCPTABLE_OWNER_MODULE *)table)->table + num;
row->dwState = dyn->state;
- row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+ row->dwLocalAddr = key->local.Ipv4.sin_addr.s_addr;
row->dwLocalPort = key->local.Ipv4.sin_port;
- row->dwRemoteAddr = key->remote.Ipv4.sin_addr.WS_s_addr;
+ row->dwRemoteAddr = key->remote.Ipv4.sin_addr.s_addr;
row->dwRemotePort = key->remote.Ipv4.sin_port;
row->dwOwningPid = stat->pid;
row->liCreateTimestamp.QuadPart = stat->create_time;
@@ -2968,9 +2962,9 @@ static void tcp_row_fill( void *table, DWORD num, ULONG family, ULONG table_clas
{
MIB_TCPROW2 *row = ((MIB_TCPTABLE2 *)table)->table + num;
row->dwState = dyn->state;
- row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+ row->dwLocalAddr = key->local.Ipv4.sin_addr.s_addr;
row->dwLocalPort = key->local.Ipv4.sin_port;
- row->dwRemoteAddr = key->remote.Ipv4.sin_addr.WS_s_addr;
+ row->dwRemoteAddr = key->remote.Ipv4.sin_addr.s_addr;
row->dwRemotePort = key->remote.Ipv4.sin_port;
row->dwOwningPid = stat->pid;
row->dwOffloadState = 0; /* FIXME */
@@ -3141,7 +3135,7 @@ static DWORD get_extended_tcp_table( void *table, DWORD *size, BOOL sort, ULONG
int (*fn)(const void *, const void *);
DWORD offset;
- if (family == WS_AF_INET) fn = tcp_row_cmp;
+ if (family == AF_INET) fn = tcp_row_cmp;
else if (row_size == sizeof(MIB_TCP6ROW)) fn = tcp6_row_basic_cmp;
else fn = tcp6_row_owner_cmp;
@@ -3191,7 +3185,7 @@ DWORD WINAPI GetExtendedTcpTable( void *table, DWORD *size, BOOL sort, ULONG fam
DWORD WINAPI GetTcpTable( MIB_TCPTABLE *table, DWORD *size, BOOL sort )
{
TRACE( "table %p, size %p, sort %d\n", table, size, sort );
- return get_extended_tcp_table( table, size, sort, WS_AF_INET, TCP_TABLE_BASIC_ALL );
+ return get_extended_tcp_table( table, size, sort, AF_INET, TCP_TABLE_BASIC_ALL );
}
/******************************************************************
@@ -3200,7 +3194,7 @@ DWORD WINAPI GetTcpTable( MIB_TCPTABLE *table, DWORD *size, BOOL sort )
ULONG WINAPI GetTcp6Table( MIB_TCP6TABLE *table, ULONG *size, BOOL sort )
{
TRACE( "table %p, size %p, sort %d\n", table, size, sort );
- return get_extended_tcp_table( table, size, sort, WS_AF_INET6, TCP_TABLE_BASIC_ALL );
+ return get_extended_tcp_table( table, size, sort, AF_INET6, TCP_TABLE_BASIC_ALL );
}
/******************************************************************
@@ -3209,7 +3203,7 @@ ULONG WINAPI GetTcp6Table( MIB_TCP6TABLE *table, ULONG *size, BOOL sort )
ULONG WINAPI GetTcpTable2( MIB_TCPTABLE2 *table, ULONG *size, BOOL sort )
{
TRACE( "table %p, size %p, sort %d\n", table, size, sort );
- return get_extended_tcp_table( table, size, sort, WS_AF_INET, TCP_TABLE2 );
+ return get_extended_tcp_table( table, size, sort, AF_INET, TCP_TABLE2 );
}
/******************************************************************
@@ -3218,7 +3212,7 @@ ULONG WINAPI GetTcpTable2( MIB_TCPTABLE2 *table, ULONG *size, BOOL sort )
ULONG WINAPI GetTcp6Table2( MIB_TCP6TABLE2 *table, ULONG *size, BOOL sort )
{
TRACE( "table %p, size %p, sort %d\n", table, size, sort );
- return get_extended_tcp_table( table, size, sort, WS_AF_INET6, TCP_TABLE2 );
+ return get_extended_tcp_table( table, size, sort, AF_INET6, TCP_TABLE2 );
}
static DWORD allocate_tcp_table( void **table, BOOL sort, HANDLE heap, DWORD flags,
@@ -3248,7 +3242,7 @@ DWORD WINAPI AllocateAndGetTcpTableFromStack( MIB_TCPTABLE **table, BOOL sort, H
if (!table) return ERROR_INVALID_PARAMETER;
- return allocate_tcp_table( (void **)table, sort, heap, flags, WS_AF_INET, TCP_TABLE_BASIC_ALL );
+ return allocate_tcp_table( (void **)table, sort, heap, flags, AF_INET, TCP_TABLE_BASIC_ALL );
}
/******************************************************************
@@ -3259,7 +3253,7 @@ DWORD WINAPI AllocateAndGetTcpExTableFromStack( void **table, BOOL sort, HANDLE
TRACE( "table %p, sort %d, heap %p, flags 0x%08x, family %u\n", table, sort, heap, flags, family );
if (!table || !ip_module_id( family )) return ERROR_INVALID_PARAMETER;
- if (family == WS_AF_INET6) return ERROR_NOT_SUPPORTED;
+ if (family == AF_INET6) return ERROR_NOT_SUPPORTED;
return allocate_tcp_table( table, sort, heap, flags, family, TCP_TABLE_OWNER_PID_ALL );
}
@@ -3274,7 +3268,7 @@ DWORD WINAPI AllocateAndGetTcpExTableFromStack( void **table, BOOL sort, HANDLE
*/
DWORD WINAPI GetUdpStatistics( MIB_UDPSTATS *stats )
{
- return GetUdpStatisticsEx( stats, WS_AF_INET );
+ return GetUdpStatisticsEx( stats, AF_INET );
}
/******************************************************************
@@ -3324,7 +3318,7 @@ DWORD WINAPI GetUdpStatisticsEx( MIB_UDPSTATS *stats, DWORD family )
*/
DWORD WINAPI GetUdpTable( MIB_UDPTABLE *table, DWORD *size, BOOL sort )
{
- return GetExtendedUdpTable( table, size, sort, WS_AF_INET, UDP_TABLE_BASIC, 0 );
+ return GetExtendedUdpTable( table, size, sort, AF_INET, UDP_TABLE_BASIC, 0 );
}
/******************************************************************
@@ -3332,7 +3326,7 @@ DWORD WINAPI GetUdpTable( MIB_UDPTABLE *table, DWORD *size, BOOL sort )
*/
DWORD WINAPI GetUdp6Table( MIB_UDP6TABLE *table, DWORD *size, BOOL sort )
{
- return GetExtendedUdpTable( table, size, sort, WS_AF_INET6, UDP_TABLE_BASIC, 0 );
+ return GetExtendedUdpTable( table, size, sort, AF_INET6, UDP_TABLE_BASIC, 0 );
}
static DWORD udp_table_size( ULONG family, ULONG table_class, DWORD row_count, DWORD *row_size )
@@ -3340,18 +3334,18 @@ static DWORD udp_table_size( ULONG family, ULONG table_class, DWORD row_count, D
switch (table_class)
{
case UDP_TABLE_BASIC:
- *row_size = (family == WS_AF_INET) ? sizeof(MIB_UDPROW) : sizeof(MIB_UDP6ROW);
- return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE, table[row_count]) :
+ *row_size = (family == AF_INET) ? sizeof(MIB_UDPROW) : sizeof(MIB_UDP6ROW);
+ return (family == AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE, table[row_count]) :
FIELD_OFFSET(MIB_UDP6TABLE, table[row_count]);
case UDP_TABLE_OWNER_PID:
- *row_size = (family == WS_AF_INET) ? sizeof(MIB_UDPROW_OWNER_PID) : sizeof(MIB_UDP6ROW_OWNER_PID);
- return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table[row_count]) :
+ *row_size = (family == AF_INET) ? sizeof(MIB_UDPROW_OWNER_PID) : sizeof(MIB_UDP6ROW_OWNER_PID);
+ return (family == AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE_OWNER_PID, table[row_count]) :
FIELD_OFFSET(MIB_UDP6TABLE_OWNER_PID, table[row_count]);
case UDP_TABLE_OWNER_MODULE:
- *row_size = (family == WS_AF_INET) ? sizeof(MIB_UDPROW_OWNER_MODULE) : sizeof(MIB_UDP6ROW_OWNER_MODULE);
- return (family == WS_AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE_OWNER_MODULE, table[row_count]) :
+ *row_size = (family == AF_INET) ? sizeof(MIB_UDPROW_OWNER_MODULE) : sizeof(MIB_UDP6ROW_OWNER_MODULE);
+ return (family == AF_INET) ? FIELD_OFFSET(MIB_UDPTABLE_OWNER_MODULE, table[row_count]) :
FIELD_OFFSET(MIB_UDP6TABLE_OWNER_MODULE, table[row_count]);
default:
@@ -3364,21 +3358,21 @@ static void udp_row_fill( void *table, DWORD num, ULONG family, ULONG table_clas
struct nsi_udp_endpoint_key *key,
struct nsi_udp_endpoint_static *stat )
{
- if (family == WS_AF_INET)
+ if (family == AF_INET)
{
switch (table_class)
{
case UDP_TABLE_BASIC:
{
MIB_UDPROW *row = ((MIB_UDPTABLE *)table)->table + num;
- row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+ row->dwLocalAddr = key->local.Ipv4.sin_addr.s_addr;
row->dwLocalPort = key->local.Ipv4.sin_port;
return;
}
case UDP_TABLE_OWNER_PID:
{
MIB_UDPROW_OWNER_PID *row = ((MIB_UDPTABLE_OWNER_PID *)table)->table + num;
- row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+ row->dwLocalAddr = key->local.Ipv4.sin_addr.s_addr;
row->dwLocalPort = key->local.Ipv4.sin_port;
row->dwOwningPid = stat->pid;
return;
@@ -3386,7 +3380,7 @@ static void udp_row_fill( void *table, DWORD num, ULONG family, ULONG table_clas
case UDP_TABLE_OWNER_MODULE:
{
MIB_UDPROW_OWNER_MODULE *row = ((MIB_UDPTABLE_OWNER_MODULE *)table)->table + num;
- row->dwLocalAddr = key->local.Ipv4.sin_addr.WS_s_addr;
+ row->dwLocalAddr = key->local.Ipv4.sin_addr.s_addr;
row->dwLocalPort = key->local.Ipv4.sin_port;
row->dwOwningPid = stat->pid;
row->liCreateTimestamp.QuadPart = stat->create_time;
@@ -3510,7 +3504,7 @@ DWORD WINAPI GetExtendedUdpTable( void *table, DWORD *size, BOOL sort, ULONG fam
int (*fn)(const void *, const void *);
DWORD offset = udp_table_size( family, table_class, 0, &row_size );
- if (family == WS_AF_INET) fn = udp_row_cmp;
+ if (family == AF_INET) fn = udp_row_cmp;
else fn = udp6_row_cmp;
qsort( (BYTE *)table + offset, num, row_size, fn );
@@ -3532,7 +3526,7 @@ DWORD WINAPI AllocateAndGetUdpTableFromStack( MIB_UDPTABLE **table, BOOL sort, H
{
*table = HeapAlloc( heap, flags, size );
if (!*table) return ERROR_NOT_ENOUGH_MEMORY;
- err = GetExtendedUdpTable( *table, &size, sort, WS_AF_INET, UDP_TABLE_BASIC, 0 );
+ err = GetExtendedUdpTable( *table, &size, sort, AF_INET, UDP_TABLE_BASIC, 0 );
if (!err) break;
HeapFree( heap, flags, *table );
*table = NULL;
@@ -3547,7 +3541,7 @@ static void unicast_row_fill( MIB_UNICASTIPADDRESS_ROW *row, USHORT fam, void *k
struct nsi_ipv4_unicast_key *key4 = (struct nsi_ipv4_unicast_key *)key;
struct nsi_ipv6_unicast_key *key6 = (struct nsi_ipv6_unicast_key *)key;
- if (fam == WS_AF_INET)
+ if (fam == AF_INET)
{
row->Address.Ipv4.sin_family = fam;
row->Address.Ipv4.sin_port = 0;
@@ -3600,7 +3594,7 @@ DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
if (err) return err;
}
- if (row->Address.si_family == WS_AF_INET)
+ if (row->Address.si_family == AF_INET)
{
key4.luid = row->InterfaceLuid;
key4.addr = row->Address.Ipv4.sin_addr;
@@ -3608,7 +3602,7 @@ DWORD WINAPI GetUnicastIpAddressEntry(MIB_UNICASTIPADDRESS_ROW *row)
key = &key4;
key_size = sizeof(key4);
}
- else if (row->Address.si_family == WS_AF_INET6)
+ else if (row->Address.si_family == AF_INET6)
{
key6.luid = row->InterfaceLuid;
key6.addr = row->Address.Ipv6.sin6_addr;
@@ -3629,18 +3623,18 @@ DWORD WINAPI GetUnicastIpAddressTable(ADDRESS_FAMILY family, MIB_UNICASTIPADDRES
struct nsi_ip_unicast_rw *rw[2] = { NULL, NULL };
struct nsi_ip_unicast_dynamic *dyn[2] = { NULL, NULL };
struct nsi_ip_unicast_static *stat[2] = { NULL, NULL };
- static const USHORT fam[2] = { WS_AF_INET, WS_AF_INET6 };
+ static const USHORT fam[2] = { AF_INET, AF_INET6 };
static const DWORD key_size[2] = { sizeof(struct nsi_ipv4_unicast_key), sizeof(struct nsi_ipv6_unicast_key) };
DWORD err, i, size, count[2] = { 0, 0 };
TRACE( "%u, %p\n", family, table );
- if (!table || (family != WS_AF_INET && family != WS_AF_INET6 && family != WS_AF_UNSPEC))
+ if (!table || (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC))
return ERROR_INVALID_PARAMETER;
for (i = 0; i < 2; i++)
{
- if (family != WS_AF_UNSPEC && family != fam[i]) continue;
+ if (family != AF_UNSPEC && family != fam[i]) continue;
err = NsiAllocateAndGetTable( 1, ip_module_id( fam[i] ), NSI_IP_UNICAST_TABLE, key + i, key_size[i],
(void **)rw + i, sizeof(**rw), (void **)dyn + i, sizeof(**dyn),
--
2.23.0
1
0
Oct. 5, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/nsiproxy.sys/device.c | 16 ++++++++++++++--
dlls/nsiproxy.sys/icmp_echo.c | 31 +++++++++++++++++++++++++++++--
dlls/nsiproxy.sys/nsi.c | 1 +
dlls/nsiproxy.sys/unix_private.h | 1 +
4 files changed, 45 insertions(+), 4 deletions(-)
diff --git a/dlls/nsiproxy.sys/device.c b/dlls/nsiproxy.sys/device.c
index 6461071c395..90a7a3ded7c 100644
--- a/dlls/nsiproxy.sys/device.c
+++ b/dlls/nsiproxy.sys/device.c
@@ -58,6 +58,7 @@ static NTSTATUS nsiproxy_call( unsigned int code, void *args )
enum unix_calls
{
+ icmp_cancel_listen,
icmp_close,
icmp_listen,
icmp_send_echo,
@@ -191,12 +192,23 @@ static inline HANDLE irp_set_icmp_handle( IRP *irp, HANDLE handle )
static void WINAPI icmp_echo_cancel( DEVICE_OBJECT *device, IRP *irp )
{
+ HANDLE handle;
+
TRACE( "device %p, irp %p.\n", device, irp );
IoReleaseCancelSpinLock( irp->CancelIrql );
- /* FIXME: at the moment just let the request thread bail */
- return;
+ EnterCriticalSection( &nsiproxy_cs );
+
+ /* If the handle is not set, either the irp is still
+ in the request queue, in which case the request thread will
+ cancel it, or the irp has already finished. If the handle
+ does exist then notify the listen thread. In all cases the irp
+ will be completed elsewhere. */
+ handle = irp_get_icmp_handle( irp );
+ if (handle) nsiproxy_call( icmp_cancel_listen, handle );
+
+ LeaveCriticalSection( &nsiproxy_cs );
}
static NTSTATUS nsiproxy_icmp_echo( IRP *irp )
diff --git a/dlls/nsiproxy.sys/icmp_echo.c b/dlls/nsiproxy.sys/icmp_echo.c
index cef5c04a6c7..999b53186c2 100644
--- a/dlls/nsiproxy.sys/icmp_echo.c
+++ b/dlls/nsiproxy.sys/icmp_echo.c
@@ -100,6 +100,7 @@ struct icmp_data
{
LARGE_INTEGER send_time;
int socket;
+ int cancel_pipe[2];
unsigned short id;
unsigned short seq;
const struct family_ops *ops;
@@ -522,8 +523,14 @@ static NTSTATUS icmp_data_create( ADDRESS_FAMILY win_family, struct icmp_data **
if (ops->family == AF_INET) ops = &ipv4_linux_ping;
#endif
}
- data->ops = ops;
+ if (pipe( data->cancel_pipe ))
+ {
+ close( data->socket );
+ free( data );
+ return STATUS_ACCESS_DENIED;
+ }
+ data->ops = ops;
*icmp_data = data;
return STATUS_SUCCESS;
}
@@ -531,6 +538,8 @@ static NTSTATUS icmp_data_create( ADDRESS_FAMILY win_family, struct icmp_data **
static void icmp_data_free( struct icmp_data *data )
{
close( data->socket );
+ close( data->cancel_pipe[0] );
+ close( data->cancel_pipe[1] );
free( data );
}
@@ -668,7 +677,7 @@ NTSTATUS icmp_listen( void *args )
{
struct icmp_listen_params *params = args;
struct icmp_data *data;
- struct pollfd fds[1];
+ struct pollfd fds[2];
NTSTATUS status;
int ret;
@@ -677,9 +686,17 @@ NTSTATUS icmp_listen( void *args )
fds[0].fd = data->socket;
fds[0].events = POLLIN;
+ fds[1].fd = data->cancel_pipe[0];
+ fds[1].events = POLLIN;
while ((ret = poll( fds, ARRAY_SIZE(fds), get_timeout( data->send_time, params->timeout ) )) > 0)
{
+ if (fds[1].revents & POLLIN)
+ {
+ TRACE( "cancelled\n" );
+ return STATUS_CANCELLED;
+ }
+
status = recv_msg( data, params );
if (status == STATUS_RETRY) continue;
return status;
@@ -694,6 +711,16 @@ NTSTATUS icmp_listen( void *args )
return set_reply_ip_status( params, errno_to_ip_status( errno ) );
}
+NTSTATUS icmp_cancel_listen( void *args )
+{
+ HANDLE handle = args;
+ struct icmp_data *data = handle_data( handle );
+
+ if (!data) return STATUS_INVALID_PARAMETER;
+ write( data->cancel_pipe[1], "x", 1 );
+ return STATUS_SUCCESS;
+}
+
NTSTATUS icmp_close( void *args )
{
HANDLE handle = args;
diff --git a/dlls/nsiproxy.sys/nsi.c b/dlls/nsiproxy.sys/nsi.c
index b92de7a9a11..fa997d2fe36 100644
--- a/dlls/nsiproxy.sys/nsi.c
+++ b/dlls/nsiproxy.sys/nsi.c
@@ -147,6 +147,7 @@ static NTSTATUS unix_nsi_get_parameter_ex( void *args )
const unixlib_entry_t __wine_unix_call_funcs[] =
{
+ icmp_cancel_listen,
icmp_close,
icmp_listen,
icmp_send_echo,
diff --git a/dlls/nsiproxy.sys/unix_private.h b/dlls/nsiproxy.sys/unix_private.h
index 855c06011f9..ffb48cc7380 100644
--- a/dlls/nsiproxy.sys/unix_private.h
+++ b/dlls/nsiproxy.sys/unix_private.h
@@ -157,6 +157,7 @@ static inline int ascii_strcasecmp( const char *s1, const char *s2 )
return ascii_strncasecmp( s1, s2, -1 );
}
+NTSTATUS icmp_cancel_listen( void *args ) DECLSPEC_HIDDEN;
NTSTATUS icmp_close( void *args ) DECLSPEC_HIDDEN;
NTSTATUS icmp_listen( void *args ) DECLSPEC_HIDDEN;
NTSTATUS icmp_send_echo( void *args ) DECLSPEC_HIDDEN;
--
2.23.0
1
0
Oct. 5, 2021
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/nsiproxy.sys/icmp_echo.c | 63 ++++++++++++++++++++++++++++++++++-
1 file changed, 62 insertions(+), 1 deletion(-)
diff --git a/dlls/nsiproxy.sys/icmp_echo.c b/dlls/nsiproxy.sys/icmp_echo.c
index abcccdb4c73..cef5c04a6c7 100644
--- a/dlls/nsiproxy.sys/icmp_echo.c
+++ b/dlls/nsiproxy.sys/icmp_echo.c
@@ -297,6 +297,30 @@ static BOOL ipv4_linux_ping_parse_ip_hdr( struct msghdr *msg, int recvd,
static int ipv4_parse_icmp_hdr_( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size,
struct nsiproxy_icmp_echo_reply *reply, int ping_socket )
{
+ static const IP_STATUS unreach_codes[] =
+ {
+ IP_DEST_NET_UNREACHABLE, /* ICMP_UNREACH_NET */
+ IP_DEST_HOST_UNREACHABLE, /* ICMP_UNREACH_HOST */
+ IP_DEST_PROT_UNREACHABLE, /* ICMP_UNREACH_PROTOCOL */
+ IP_DEST_PORT_UNREACHABLE, /* ICMP_UNREACH_PORT */
+ IP_PACKET_TOO_BIG, /* ICMP_UNREACH_NEEDFRAG */
+ IP_BAD_ROUTE, /* ICMP_UNREACH_SRCFAIL */
+ IP_DEST_NET_UNREACHABLE, /* ICMP_UNREACH_NET_UNKNOWN */
+ IP_DEST_HOST_UNREACHABLE, /* ICMP_UNREACH_HOST_UNKNOWN */
+ IP_DEST_HOST_UNREACHABLE, /* ICMP_UNREACH_ISOLATED */
+ IP_DEST_NET_UNREACHABLE, /* ICMP_UNREACH_NET_PROHIB */
+ IP_DEST_HOST_UNREACHABLE, /* ICMP_UNREACH_HOST_PROHIB */
+ IP_DEST_NET_UNREACHABLE, /* ICMP_UNREACH_TOSNET */
+ IP_DEST_HOST_UNREACHABLE, /* ICMP_UNREACH_TOSHOST */
+ IP_DEST_HOST_UNREACHABLE, /* ICMP_UNREACH_FILTER_PROHIB */
+ IP_DEST_HOST_UNREACHABLE, /* ICMP_UNREACH_HOST_PRECEDENCE */
+ IP_DEST_HOST_UNREACHABLE /* ICMP_UNREACH_PRECEDENCE_CUTOFF */
+ };
+ const struct ip_hdr *orig_ip_hdr;
+ const struct icmp_hdr *orig_icmp_hdr;
+ int orig_ip_hdr_len;
+ IP_STATUS status;
+
switch (icmp->type)
{
case ICMP4_ECHO_REPLY:
@@ -306,11 +330,48 @@ static int ipv4_parse_icmp_hdr_( struct icmp_data *data, struct icmp_hdr *icmp,
reply->status = IP_SUCCESS;
return icmp_size - sizeof(*icmp);
- /* FIXME: handle other icmp messages */
+ case ICMP4_DST_UNREACH:
+ if (icmp->code < ARRAY_SIZE(unreach_codes))
+ status = unreach_codes[icmp->code];
+ else
+ status = IP_DEST_HOST_UNREACHABLE;
+ break;
+
+ case ICMP4_TIME_EXCEEDED:
+ if (icmp->code == 1) /* ICMP_TIMXCEED_REASS */
+ status = IP_TTL_EXPIRED_REASSEM;
+ else
+ status = IP_TTL_EXPIRED_TRANSIT;
+ break;
+
+ case ICMP4_PARAM_PROB:
+ status = IP_PARAM_PROBLEM;
+ break;
+
+ case ICMP4_SOURCE_QUENCH:
+ status = IP_SOURCE_QUENCH;
+ break;
default:
return -1;
}
+
+ /* Check that the appended packet is really ours -
+ * all handled icmp replies have an 8-byte header
+ * followed by the original ip hdr. */
+ if (icmp_size < sizeof(*icmp) + sizeof(*orig_ip_hdr)) return -1;
+ orig_ip_hdr = (struct ip_hdr *)(icmp + 1);
+ if (orig_ip_hdr->v_hl >> 4 != 4 || orig_ip_hdr->protocol != IPPROTO_ICMP) return -1;
+ orig_ip_hdr_len = (orig_ip_hdr->v_hl & 0xf) << 2;
+ if (icmp_size < sizeof(*icmp) + orig_ip_hdr_len + sizeof(*orig_icmp_hdr)) return -1;
+ orig_icmp_hdr = (const struct icmp_hdr *)((const BYTE *)orig_ip_hdr + orig_ip_hdr_len);
+ if (orig_icmp_hdr->type != ICMP4_ECHO_REQUEST ||
+ orig_icmp_hdr->code != 0 ||
+ (!ping_socket && orig_icmp_hdr->un.echo.id != data->id) ||
+ orig_icmp_hdr->un.echo.sequence != data->seq) return -1;
+
+ reply->status = status;
+ return 0;
}
static int ipv4_parse_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size,
--
2.23.0
1
0
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/nsiproxy.sys/icmp_echo.c | 205 +++++++++++++++++++++++++++++++++-
1 file changed, 203 insertions(+), 2 deletions(-)
diff --git a/dlls/nsiproxy.sys/icmp_echo.c b/dlls/nsiproxy.sys/icmp_echo.c
index afb48fc72e3..abcccdb4c73 100644
--- a/dlls/nsiproxy.sys/icmp_echo.c
+++ b/dlls/nsiproxy.sys/icmp_echo.c
@@ -233,6 +233,100 @@ static void ipv4_linux_ping_set_socket_opts( struct icmp_data *data, struct icmp
}
#endif
+static int ipv4_reply_buffer_len( int reply_len )
+{
+ return sizeof(struct ip_hdr) + sizeof(struct icmp_hdr) + reply_len - sizeof(struct nsiproxy_icmp_echo_reply);
+}
+
+#ifdef __linux__
+static int ipv4_linux_ping_reply_buffer_len( int reply_len )
+{
+ return sizeof(struct icmp_hdr) + reply_len - sizeof(struct nsiproxy_icmp_echo_reply);
+}
+#endif
+
+static BOOL ipv4_parse_ip_hdr( struct msghdr *msg, int recvd,
+ int *ip_hdr_len, struct nsiproxy_icmp_echo_reply *reply, void **opts )
+{
+ struct ip_hdr *ip_hdr;
+
+ if (recvd < sizeof(*ip_hdr)) return FALSE;
+ ip_hdr = msg->msg_iov[0].iov_base;
+ if (ip_hdr->v_hl >> 4 != 4 || ip_hdr->protocol != IPPROTO_ICMP) return FALSE;
+ *ip_hdr_len = (ip_hdr->v_hl & 0xf) << 2;
+ if (*ip_hdr_len < sizeof(*ip_hdr)) return FALSE;
+ *opts = ip_hdr + 1;
+ reply->opts.ttl = ip_hdr->ttl;
+ reply->opts.tos = ip_hdr->tos;
+ reply->opts.flags = ip_hdr->frag_off >> 13;
+ reply->opts.options_size = *ip_hdr_len - sizeof(*ip_hdr);
+
+ return TRUE;
+}
+
+#ifdef __linux__
+static BOOL ipv4_linux_ping_parse_ip_hdr( struct msghdr *msg, int recvd,
+ int *ip_hdr_len, struct nsiproxy_icmp_echo_reply *reply, void **opts )
+{
+ struct cmsghdr *cmsg;
+
+ *ip_hdr_len = 0;
+ *opts = NULL;
+ reply->opts.ttl = 0;
+ reply->opts.tos = 0;
+ reply->opts.flags = 0;
+ reply->opts.options_size = 0; /* FIXME from IP_OPTIONS but will require checking for space in the reply */
+
+ for (cmsg = CMSG_FIRSTHDR( msg ); cmsg; cmsg = CMSG_NXTHDR( msg, cmsg ))
+ {
+ if (cmsg->cmsg_level != IPPROTO_IP) continue;
+ switch (cmsg->cmsg_type)
+ {
+ case IP_TTL:
+ reply->opts.ttl = *(BYTE *)CMSG_DATA( cmsg );
+ break;
+ case IP_TOS:
+ reply->opts.tos = *(BYTE *)CMSG_DATA( cmsg );
+ break;
+ }
+ }
+ return TRUE;
+}
+#endif
+
+static int ipv4_parse_icmp_hdr_( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size,
+ struct nsiproxy_icmp_echo_reply *reply, int ping_socket )
+{
+ switch (icmp->type)
+ {
+ case ICMP4_ECHO_REPLY:
+ if ((!ping_socket && icmp->un.echo.id != data->id) ||
+ icmp->un.echo.sequence != data->seq) return -1;
+
+ reply->status = IP_SUCCESS;
+ return icmp_size - sizeof(*icmp);
+
+ /* FIXME: handle other icmp messages */
+
+ default:
+ return -1;
+ }
+}
+
+static int ipv4_parse_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size,
+ struct nsiproxy_icmp_echo_reply *reply )
+{
+ return ipv4_parse_icmp_hdr_( data, icmp, icmp_size, reply, 0 );
+}
+
+#ifdef __linux__
+static int ipv4_linux_ping_parse_icmp_hdr( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_size,
+ struct nsiproxy_icmp_echo_reply *reply )
+{
+ return ipv4_parse_icmp_hdr_( data, icmp, icmp_size, reply, 1 );
+}
+#endif
+
struct family_ops
{
int family;
@@ -240,6 +334,11 @@ struct family_ops
void (*init_icmp_hdr)( struct icmp_data *data, struct icmp_hdr *icmp_hdr );
unsigned short (*chksum)( BYTE *data, unsigned int count );
void (*set_socket_opts)( struct icmp_data *data, struct icmp_send_echo_params *params );
+ int (*reply_buffer_len)( int reply_len );
+ BOOL (*parse_ip_hdr)( struct msghdr *msg, int recvd,
+ int *ip_hdr_len, struct nsiproxy_icmp_echo_reply *reply, void **opts );
+ int (*parse_icmp_hdr)( struct icmp_data *data, struct icmp_hdr *icmp, int icmp_len,
+ struct nsiproxy_icmp_echo_reply *reply );
};
static const struct family_ops ipv4 =
@@ -249,6 +348,9 @@ static const struct family_ops ipv4 =
ipv4_init_icmp_hdr,
chksum,
ipv4_set_socket_opts,
+ ipv4_reply_buffer_len,
+ ipv4_parse_ip_hdr,
+ ipv4_parse_icmp_hdr,
};
#ifdef __linux__
@@ -260,6 +362,9 @@ static const struct family_ops ipv4_linux_ping =
ipv4_init_icmp_hdr,
null_chksum,
ipv4_linux_ping_set_socket_opts,
+ ipv4_linux_ping_reply_buffer_len,
+ ipv4_linux_ping_parse_ip_hdr,
+ ipv4_linux_ping_parse_icmp_hdr,
};
#endif
@@ -302,6 +407,34 @@ static int SOCKADDR_INET_to_sockaddr( const SOCKADDR_INET *in, struct sockaddr *
return 0;
}
+static BOOL sockaddr_to_SOCKADDR_INET( const struct sockaddr *in, SOCKADDR_INET *out )
+{
+ switch (in->sa_family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in *sa = (struct sockaddr_in *)in;
+
+ out->Ipv4.sin_family = WS_AF_INET;
+ out->Ipv4.sin_port = sa->sin_port;
+ out->Ipv4.sin_addr.WS_s_addr = sa->sin_addr.s_addr;
+ return TRUE;
+ }
+ case AF_INET6:
+ {
+ struct sockaddr_in6 *sa = (struct sockaddr_in6 *)in;
+
+ out->Ipv6.sin6_family = WS_AF_INET6;
+ out->Ipv6.sin6_port = sa->sin6_port;
+ out->Ipv6.sin6_flowinfo = sa->sin6_flowinfo;
+ memcpy( out->Ipv6.sin6_addr.WS_s6_addr, sa->sin6_addr.s6_addr, sizeof(sa->sin6_addr.s6_addr) );
+ out->Ipv6.sin6_scope_id = sa->sin6_scope_id;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
static NTSTATUS icmp_data_create( ADDRESS_FAMILY win_family, struct icmp_data **icmp_data )
{
struct icmp_data *data;
@@ -404,11 +537,78 @@ static int get_timeout( LARGE_INTEGER start, DWORD timeout )
return min( (end.QuadPart - now.QuadPart) / 10000, INT_MAX );
}
+static ULONG get_rtt( LARGE_INTEGER start )
+{
+ LARGE_INTEGER now;
+
+ NtQueryPerformanceCounter( &now, NULL );
+ return (now.QuadPart - start.QuadPart) / 10000;
+}
+
+static NTSTATUS recv_msg( struct icmp_data *data, struct icmp_listen_params *params )
+{
+ struct nsiproxy_icmp_echo_reply *reply = (struct nsiproxy_icmp_echo_reply *)params->reply;
+ struct sockaddr_storage addr;
+ struct iovec iov[1];
+ BYTE cmsg_buf[1024];
+ struct msghdr msg = { .msg_name = &addr, .msg_namelen = sizeof(addr),
+ .msg_iov = iov, .msg_iovlen = ARRAY_SIZE(iov),
+ .msg_control = cmsg_buf, .msg_controllen = sizeof(cmsg_buf) };
+ int ip_hdr_len, recvd, reply_buf_len, data_size;
+ char *reply_buf;
+ void *opts;
+ struct icmp_hdr *icmp_hdr;
+
+ reply_buf_len = data->ops->reply_buffer_len( params->reply_len );
+ reply_buf = malloc( reply_buf_len );
+ if (!reply_buf) return STATUS_NO_MEMORY;
+
+ iov[0].iov_base = reply_buf;
+ iov[0].iov_len = reply_buf_len;
+
+ recvd = recvmsg( data->socket, &msg, 0 );
+ TRACE( "recvmsg() rets %d errno %d addr_len %d iovlen %d msg_flags %x\n",
+ recvd, errno, msg.msg_namelen, (int)iov[0].iov_len, msg.msg_flags );
+
+ if (!data->ops->parse_ip_hdr( &msg, recvd, &ip_hdr_len, reply, &opts )) goto skip;
+ if (recvd < ip_hdr_len + sizeof(*icmp_hdr)) goto skip;
+
+ icmp_hdr = (struct icmp_hdr *)(reply_buf + ip_hdr_len);
+ if ((data_size = data->ops->parse_icmp_hdr( data, icmp_hdr, recvd - ip_hdr_len, reply )) < 0) goto skip;
+ reply->data_size = data_size;
+ if (reply->data_size && msg.msg_flags & MSG_TRUNC)
+ {
+ free( reply_buf );
+ return set_reply_ip_status( params, IP_GENERAL_FAILURE );
+ }
+
+ sockaddr_to_SOCKADDR_INET( (struct sockaddr *)&addr, &reply->addr );
+ reply->round_trip_time = get_rtt( data->send_time );
+ reply->num_of_pkts = 1;
+ reply->opts.options_offset = sizeof(*reply);
+ reply->data_offset = sizeof(*reply) + ((reply->opts.options_size + 3) & ~3);
+ if (reply->opts.options_size)
+ memcpy( (char *)reply + reply->opts.options_offset, opts, reply->opts.options_size );
+ if (reply->opts.options_size & 3)
+ memset( (char *)reply + reply->opts.options_offset + reply->opts.options_size, 0, 4 - (reply->opts.options_size & 3) );
+ if (reply->data_size)
+ memcpy( (char *)reply + reply->data_offset, icmp_hdr + 1, reply->data_size );
+
+ params->reply_len = reply->data_offset + reply->data_size;
+ free( reply_buf );
+ return STATUS_SUCCESS;
+
+skip:
+ free( reply_buf );
+ return STATUS_RETRY;
+}
+
NTSTATUS icmp_listen( void *args )
{
struct icmp_listen_params *params = args;
struct icmp_data *data;
struct pollfd fds[1];
+ NTSTATUS status;
int ret;
data = handle_data( params->handle );
@@ -419,8 +619,9 @@ NTSTATUS icmp_listen( void *args )
while ((ret = poll( fds, ARRAY_SIZE(fds), get_timeout( data->send_time, params->timeout ) )) > 0)
{
- /* FIXME */
- return STATUS_NOT_SUPPORTED;
+ status = recv_msg( data, params );
+ if (status == STATUS_RETRY) continue;
+ return status;
}
if (!ret) /* timeout */
--
2.23.0
1
0