[PATCH v6 0/2] MR10272: wbemprox: Correct IP address order when calling Win32_NetworkAdapterConfiguration.
A Ruby application obtains network adapter IP information by calling the **Win32_NetworkAdapterConfiguration** class. However, the order of IPv4 and IPv6 addresses retrieved on Windows differs from that retrieved when running on Wine, which causes Ruby applications running on Wine to malfunction. A test demo was written that calls the **Win32_NetworkAdapterConfiguration** class to obtain network adapter information. It was run on Windows and on Wine respectively, and the results are as follows. demo:[demo.cpp](/uploads/4dcde05e7d177f0e7d7d5e2d3d95d449/demo.cpp) The results of running on Windows: {width=357 height=153} The results of running on Wine: {width=363 height=66} -- v6: wbemprox/tests: Test the IP address order obtained by calling Win32_NetworkAdapterConfiguration. https://gitlab.winehq.org/wine/wine/-/merge_requests/10272
From: Zhao Yi <zhaoyi@uniontech.com> Signed-off-by: Zhao Yi <zhaoyi@uniontech.com> --- dlls/wbemprox/builtin.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c index 70d0364dfe9..36528098ec1 100644 --- a/dlls/wbemprox/builtin.c +++ b/dlls/wbemprox/builtin.c @@ -3359,20 +3359,34 @@ static struct array *get_ipaddress( IP_ADAPTER_UNICAST_ADDRESS_LH *list ) } for (address = list; address; address = address->Next) { + if (address->Address.lpSockaddr->sa_family != AF_INET) + continue; buflen = ARRAY_SIZE( buf ); if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength, - NULL, buf, &buflen) || !(ptr[i++] = wcsdup( buf ))) - { - for (; i > 0; i--) free( ptr[i - 1] ); - free( ptr ); - free( ret ); - return NULL; - } + NULL, buf, &buflen ) || !(ptr[i++] = wcsdup( buf ))) + goto error; } + + for (address = list; address; address = address->Next) + { + if (address->Address.lpSockaddr->sa_family != AF_INET6) + continue; + buflen = ARRAY_SIZE( buf ); + if (WSAAddressToStringW( address->Address.lpSockaddr, address->Address.iSockaddrLength, + NULL, buf, &buflen ) || !(ptr[i++] = wcsdup( buf ))) + goto error; + } + ret->elem_size = sizeof(*ptr); ret->count = count; ret->ptr = ptr; return ret; + +error: + for (; i > 0; i--) free( ptr[i - 1] ); + free( ptr ); + free( ret ); + return NULL; } static struct array *get_ipsubnet( IP_ADAPTER_UNICAST_ADDRESS_LH *list ) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10272
From: Zhao Yi <zhaoyi@uniontech.com> Signed-off-by: Zhao Yi <zhaoyi@uniontech.com> --- dlls/wbemprox/tests/query.c | 57 +++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index 59d1ff49042..74b3ee53dca 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -368,6 +368,61 @@ static void test_IEnumWbemClassObject_Next( IWbemServices *services ) SysFreeString( wql ); } +static const WCHAR *get_ip_type(const WCHAR *ip) +{ + const WCHAR *dot_pos; + const WCHAR *colon_pos; + + if (!ip) return L"Invalid"; + + dot_pos = wcschr(ip, L'.'); + colon_pos = wcschr(ip, L':'); + + if (dot_pos && colon_pos) return L"Unknown"; + if (dot_pos) return L"IPv4"; + else if (colon_pos) return L"IPv6"; + + return L"Unknown"; +} + +static void check_ip_address_oreder( ULONG line, IWbemClassObject *obj ) +{ + CIMTYPE type = 0xdeadbeef; + VARIANT val; + HRESULT hr; + + VariantInit( &val ); + hr = IWbemClassObject_Get( obj, L"IPAddress", 0, &val, &type, NULL ); + if (hr != S_OK) + { + win_skip( "IPAddress not available\n" ); + VariantClear( &val ); + return; + } + + if (V_VT( &val ) == (VT_BSTR | VT_ARRAY)) + { + SAFEARRAY *sa; + LONG bound = -1, j; + BSTR ip_str; + sa = V_ARRAY( &val ); + SafeArrayGetUBound( sa, 1, &bound ); + if (bound >= 0) + { + trace( "%s\n", wine_dbgstr_w(L"IPAddress:") ); + for (j = 0; j <= bound; j++) + { + SafeArrayGetElement( sa, &j, &ip_str ); + trace( "[%02lu]: %s\n", j + 1, wine_dbgstr_w(ip_str) ); + if (j == 0) ok( wcscmp(L"IPv4", get_ip_type(ip_str)) == 0, "%lu: unexpected ip address order %s\n", line, wine_dbgstr_w(ip_str) ); + SysFreeString( ip_str ); + } + } + } + + VariantClear( &val ); +} + static void _check_property( ULONG line, IWbemClassObject *obj, const WCHAR *prop, VARTYPE vartype, CIMTYPE cimtype, BOOL nullable) { @@ -405,6 +460,7 @@ static void _check_property( ULONG line, IWbemClassObject *obj, const WCHAR *pro } #define check_property(a,b,c,d) _check_property(__LINE__,a,b,c,d,FALSE) #define check_property_nullable(a,b,c,d) _check_property(__LINE__,a,b,c,d,TRUE) +#define check_ip_address_oreder(a) check_ip_address_oreder(__LINE__,a) static void test_Win32_Service( IWbemServices *services ) { @@ -1536,6 +1592,7 @@ static void test_Win32_NetworkAdapterConfiguration( IWbemServices *services ) check_property( obj, L"Index", VT_I4, CIM_UINT32 ); check_property( obj, L"IPEnabled", VT_BOOL, CIM_BOOLEAN ); check_property_nullable( obj, L"DNSDomain", VT_BSTR, CIM_STRING ); + check_ip_address_oreder( obj ); IWbemClassObject_Release( obj ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10272
On Thu Mar 12 08:04:54 2026 +0000, Zhao Yi wrote:
Thank you for your review comments. I will make revisions later. done
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10272#note_131955
Hans Leidekker (@hans) commented about dlls/wbemprox/tests/query.c:
+ const WCHAR *dot_pos; + const WCHAR *colon_pos; + + if (!ip) return L"Invalid"; + + dot_pos = wcschr(ip, L'.'); + colon_pos = wcschr(ip, L':'); + + if (dot_pos && colon_pos) return L"Unknown"; + if (dot_pos) return L"IPv4"; + else if (colon_pos) return L"IPv6"; + + return L"Unknown"; +} + +static void check_ip_address_oreder( ULONG line, IWbemClassObject *obj ) `check_ip_address_oreder -> check_ip_address_order`
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10272#note_131956
On Thu Mar 12 08:47:42 2026 +0000, Hans Leidekker wrote:
`check_ip_address_oreder -> check_ip_address_order` Sorry, it was a typo. I will correct it.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10272#note_131957
participants (3)
-
Hans Leidekker (@hans) -
Zhao Yi -
Zhao Yi (@Zhaoyi)