[PATCH v4 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} -- v4: 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/Makefile.in | 2 +- dlls/wbemprox/tests/query.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/dlls/wbemprox/tests/Makefile.in b/dlls/wbemprox/tests/Makefile.in index ba603031c2c..38f7b4b6eb8 100644 --- a/dlls/wbemprox/tests/Makefile.in +++ b/dlls/wbemprox/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = wbemprox.dll -IMPORTS = uuid oleaut32 ole32 user32 advapi32 +IMPORTS = uuid oleaut32 ole32 user32 advapi32 ws2_32 SOURCES = \ query.c \ diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c index 59d1ff49042..00023f70a5e 100644 --- a/dlls/wbemprox/tests/query.c +++ b/dlls/wbemprox/tests/query.c @@ -19,6 +19,7 @@ #define COBJMACROS #include <stdio.h> +#include <ws2tcpip.h> #include "windows.h" #include "ocidl.h" #include "sddl.h" @@ -368,6 +369,16 @@ static void test_IEnumWbemClassObject_Next( IWbemServices *services ) SysFreeString( wql ); } +const WCHAR* get_ip_type(const WCHAR* ip) { + struct sockaddr_in sa; + struct sockaddr_in6 sa6; + + if (InetPtonW(AF_INET, ip, &(sa.sin_addr)) == 1) return L"IPv4"; + else if (InetPtonW(AF_INET6, ip, &(sa6.sin6_addr)) == 1) return L"IPv6"; + + return L"Unknow"; +} + static void _check_property( ULONG line, IWbemClassObject *obj, const WCHAR *prop, VARTYPE vartype, CIMTYPE cimtype, BOOL nullable) { @@ -398,6 +409,27 @@ static void _check_property( ULONG line, IWbemClassObject *obj, const WCHAR *pro case VT_BOOL: trace( "%s: %d\n", wine_dbgstr_w(prop), V_BOOL(&val) ); break; + case VT_ARRAY | VT_BSTR: + if (wcscmp(L"IPAddress",prop) == 0) + { + 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"IPAddresse:") ); + 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 ); + } + } + } + break; default: break; } @@ -1536,6 +1568,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_property( obj, L"IPAddress", VT_ARRAY | VT_BSTR, CIM_FLAG_ARRAY | CIM_STRING ); IWbemClassObject_Release( obj ); } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10272
- Fix compile warning -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10272#note_131818
Hans Leidekker (@hans) commented about dlls/wbemprox/tests/query.c:
SysFreeString( wql ); }
+const WCHAR* get_ip_type(const WCHAR* ip) { + struct sockaddr_in sa; + struct sockaddr_in6 sa6; + + if (InetPtonW(AF_INET, ip, &(sa.sin_addr)) == 1) return L"IPv4"; + else if (InetPtonW(AF_INET6, ip, &(sa6.sin6_addr)) == 1) return L"IPv6"; + + return L"Unknow"; +}
There's no need to use winsock functions, you can just check for '.' or ':' in the address. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10272#note_131822
Hans Leidekker (@hans) commented about dlls/wbemprox/tests/query.c:
+ 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"IPAddresse:") ); + 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 ); + } + } + } Please put this in test_Win32_NetworkAdapterConfiguration().
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/10272#note_131823
participants (3)
-
Hans Leidekker (@hans) -
Zhao Yi -
Zhao Yi (@Zhaoyi)