From b7ab346cf7127755f495dd9036ebea9577cdf352 Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Tue, 19 Nov 2019 14:44:59 +0100 Subject: [PATCH] mountmgr.sys: Add support for querying DHCP parameters on macOS. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- configure | 6 ++ configure.ac | 3 + dlls/mountmgr.sys/Makefile.in | 2 +- dlls/mountmgr.sys/diskarb.c | 167 ++++++++++++++++++++++++++++++++++++++++++ include/config.h.in | 8 ++ 5 files changed, 185 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 483efc02d3a..fb29dcfae5d 100755 --- a/configure +++ b/configure @@ -724,6 +724,7 @@ OPENAL_LIBS COREAUDIO_LIBS SECURITY_LIBS DISKARBITRATION_LIBS +SYSTEMCONFIGURATION_LIBS APPKIT_LIBS CORESERVICES_LIBS APPLICATIONSERVICES_LIBS @@ -7356,6 +7357,8 @@ for ac_header in \ OpenCL/opencl.h \ QuickTime/ImageCompression.h \ Security/Security.h \ + SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h \ + SystemConfiguration/SCNetworkConfiguration.h \ alias.h \ arpa/inet.h \ arpa/nameser.h \ @@ -8655,6 +8658,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu APPKIT_LIBS="-framework AppKit" + SYSTEMCONFIGURATION_LIBS="-framework SystemConfiguration" + WINELOADER_LDFLAGS="-Wl,-pie,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,wine_info.plist" @@ -19841,6 +19846,7 @@ FORCEFEEDBACK_LIBS = $FORCEFEEDBACK_LIBS APPLICATIONSERVICES_LIBS = $APPLICATIONSERVICES_LIBS CORESERVICES_LIBS = $CORESERVICES_LIBS APPKIT_LIBS = $APPKIT_LIBS +SYSTEMCONFIGURATION_LIBS = $SYSTEMCONFIGURATION_LIBS DISKARBITRATION_LIBS = $DISKARBITRATION_LIBS SECURITY_LIBS = $SECURITY_LIBS COREAUDIO_LIBS = $COREAUDIO_LIBS diff --git a/configure.ac b/configure.ac index 64721e96449..22ce5f33a38 100644 --- a/configure.ac +++ b/configure.ac @@ -436,6 +436,8 @@ AC_CHECK_HEADERS(\ OpenCL/opencl.h \ QuickTime/ImageCompression.h \ Security/Security.h \ + SystemConfiguration/SCDynamicStoreCopyDHCPInfo.h \ + SystemConfiguration/SCNetworkConfiguration.h \ alias.h \ arpa/inet.h \ arpa/nameser.h \ @@ -759,6 +761,7 @@ case $host_os in AC_SUBST(APPLICATIONSERVICES_LIBS,"-framework ApplicationServices") AC_SUBST(CORESERVICES_LIBS,"-framework CoreServices") AC_SUBST(APPKIT_LIBS,"-framework AppKit") + AC_SUBST(SYSTEMCONFIGURATION_LIBS,"-framework SystemConfiguration") WINELOADER_LDFLAGS="-Wl,-pie,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,wine_info.plist" diff --git a/dlls/mountmgr.sys/Makefile.in b/dlls/mountmgr.sys/Makefile.in index 738f071390c..e229164280f 100644 --- a/dlls/mountmgr.sys/Makefile.in +++ b/dlls/mountmgr.sys/Makefile.in @@ -3,7 +3,7 @@ IMPORTS = uuid advapi32 ntoskrnl DELAYIMPORTS = user32 iphlpapi EXTRADLLFLAGS = -Wl,--subsystem,native EXTRAINCL = $(DBUS_CFLAGS) $(HAL_CFLAGS) -EXTRALIBS = $(DISKARBITRATION_LIBS) +EXTRALIBS = $(DISKARBITRATION_LIBS) $(SYSTEMCONFIGURATION_LIBS) $(CORESERVICES_LIBS) C_SRCS = \ dbus.c \ diff --git a/dlls/mountmgr.sys/diskarb.c b/dlls/mountmgr.sys/diskarb.c index 9a7616ecc69..66c121e1148 100644 --- a/dlls/mountmgr.sys/diskarb.c +++ b/dlls/mountmgr.sys/diskarb.c @@ -29,8 +29,18 @@ #ifdef HAVE_DISKARBITRATION_DISKARBITRATION_H #include #endif +#if defined(HAVE_SYSTEMCONFIGURATION_SCDYNAMICSTORECOPYDHCPINFO_H) && defined(HAVE_SYSTEMCONFIGURATION_SCNETWORKCONFIGURATION_H) +#include +#include +#endif #include "mountmgr.h" +#define USE_WS_PREFIX +#include "winsock2.h" +#include "ws2ipdef.h" +#include "nldef.h" +#include "netioapi.h" +#include "dhcpcsdk.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(mountmgr); @@ -152,3 +162,160 @@ void initialize_diskarbitration(void) } #endif /* HAVE_DISKARBITRATION_DISKARBITRATION_H */ + +#if defined(HAVE_SYSTEMCONFIGURATION_SCDYNAMICSTORECOPYDHCPINFO_H) && defined(HAVE_SYSTEMCONFIGURATION_SCNETWORKCONFIGURATION_H) + +static UInt8 map_option( ULONG option ) +{ + switch (option) + { + case OPTION_SUBNET_MASK: return 1; + case OPTION_ROUTER_ADDRESS: return 3; + case OPTION_HOST_NAME: return 12; + case OPTION_DOMAIN_NAME: return 15; + case OPTION_BROADCAST_ADDRESS: return 28; + case OPTION_MSFT_IE_PROXY: return 252; + default: + FIXME( "unhandled option %u\n", option ); + return 0; + } +} + +#define IF_NAMESIZE 16 +static BOOL map_adapter_name( const WCHAR *name, WCHAR *unix_name, DWORD len ) +{ + WCHAR buf[IF_NAMESIZE]; + UNICODE_STRING str; + GUID guid; + + RtlInitUnicodeString( &str, name ); + if (!RtlGUIDFromString( &str, &guid )) + { + NET_LUID luid; + if (ConvertInterfaceGuidToLuid( &guid, &luid ) || + ConvertInterfaceLuidToNameW( &luid, buf, ARRAY_SIZE(buf) )) return FALSE; + + name = buf; + } + if (lstrlenW( name ) >= len) return FALSE; + lstrcpyW( unix_name, name ); + return TRUE; +} + +static CFStringRef find_service_id( const WCHAR *adapter ) +{ + SCPreferencesRef prefs; + SCNetworkSetRef set = NULL; + CFArrayRef services = NULL; + CFStringRef id, ret = NULL; + WCHAR unix_name[IF_NAMESIZE]; + CFIndex i; + + if (!map_adapter_name( adapter, unix_name, ARRAY_SIZE(unix_name) )) return NULL; + if (!(prefs = SCPreferencesCreate( NULL, CFSTR("mountmgr.sys"), NULL ))) return NULL; + if (!(set = SCNetworkSetCopyCurrent( prefs ))) goto done; + if (!(services = SCNetworkSetCopyServices( set ))) goto done; + + for (i = 0; i < CFArrayGetCount( services ); i++) + { + SCNetworkServiceRef service; + UniChar buf[IF_NAMESIZE] = {0}; + CFStringRef name; + + service = CFArrayGetValueAtIndex( services, i ); + name = SCNetworkInterfaceGetBSDName( SCNetworkServiceGetInterface(service) ); + if (CFStringGetLength( name ) < ARRAY_SIZE( buf )) + { + CFStringGetCharacters( name, CFRangeMake(0, CFStringGetLength(name)), buf ); + if (!lstrcmpW( buf, unix_name ) && (id = SCNetworkServiceGetServiceID( service ))) + { + ret = CFStringCreateCopy( NULL, id ); + break; + } + } + } + +done: + if (services) CFRelease( services ); + if (set) CFRelease( set ); + CFRelease( prefs ); + return ret; +} + +ULONG get_dhcp_request_param( const WCHAR *adapter, struct mountmgr_dhcp_request_param *param, char *buf, ULONG offset, + ULONG size ) +{ + CFStringRef service_id = find_service_id( adapter ); + CFDictionaryRef dict; + CFDataRef value; + DWORD ret = 0; + CFIndex len; + + param->offset = 0; + param->size = 0; + + if (!service_id) return 0; + if (!(dict = SCDynamicStoreCopyDHCPInfo( NULL, service_id ))) + { + CFRelease( service_id ); + return 0; + } + CFRelease( service_id ); + if (!(value = DHCPInfoGetOptionData( dict, map_option(param->id) ))) + { + CFRelease( dict ); + return 0; + } + len = CFDataGetLength( value ); + + switch (param->id) + { + case OPTION_SUBNET_MASK: + case OPTION_ROUTER_ADDRESS: + case OPTION_BROADCAST_ADDRESS: + { + DWORD *ptr = (DWORD *)(buf + offset); + if (len == sizeof(*ptr) && size >= sizeof(*ptr)) + { + CFDataGetBytes( value, CFRangeMake(0, len), (UInt8 *)ptr ); + param->offset = offset; + param->size = sizeof(*ptr); + TRACE( "returning %08x\n", *ptr ); + } + ret = sizeof(*ptr); + break; + } + case OPTION_HOST_NAME: + case OPTION_DOMAIN_NAME: + case OPTION_MSFT_IE_PROXY: + { + char *ptr = buf + offset; + if (size >= len) + { + CFDataGetBytes( value, CFRangeMake(0, len), (UInt8 *)ptr ); + param->offset = offset; + param->size = len; + TRACE( "returning %s\n", debugstr_an(ptr, len) ); + } + ret = len; + break; + } + default: + FIXME( "option %u not supported\n", param->id ); + break; + } + + CFRelease( dict ); + return ret; +} + +#elif !defined(SONAME_LIBDBUS_1) + +ULONG get_dhcp_request_param( const WCHAR *adapter, struct mountmgr_dhcp_request_param *param, char *buf, ULONG offset, + ULONG size ) +{ + FIXME( "support not compiled in\n" ); + return 0; +} + +#endif diff --git a/include/config.h.in b/include/config.h.in index 858ee9bfd84..41a7cde553d 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -1001,6 +1001,14 @@ /* Define to 1 if you have the `sysinfo' function. */ #undef HAVE_SYSINFO +/* Define to 1 if you have the + header file. */ +#undef HAVE_SYSTEMCONFIGURATION_SCDYNAMICSTORECOPYDHCPINFO_H + +/* Define to 1 if you have the + header file. */ +#undef HAVE_SYSTEMCONFIGURATION_SCNETWORKCONFIGURATION_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_ATTR_H -- 2.11.4.GIT