[PATCH 6/6] dnsapi: Add support for DnsConfigSearchList.

Huw Davies huw at codeweavers.com
Tue Aug 3 03:20:23 CDT 2021


This doesn't appear to be implemented on Windows, however it will be
needed by iphlpapi.dll.

Signed-off-by: Huw Davies <huw at codeweavers.com>
---
 dlls/dnsapi/dnsapi.h    |  2 +
 dlls/dnsapi/libresolv.c | 81 +++++++++++++++++++++++++++++++++++++++++
 dlls/dnsapi/query.c     |  4 +-
 dlls/nsiproxy.sys/ip.c  |  3 +-
 4 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/dlls/dnsapi/dnsapi.h b/dlls/dnsapi/dnsapi.h
index 168c37282bd..5b4fc1019e2 100644
--- a/dlls/dnsapi/dnsapi.h
+++ b/dlls/dnsapi/dnsapi.h
@@ -121,12 +121,14 @@ static inline char *strdup_ua( const char *src )
 
 extern const char *type_to_str( unsigned short ) DECLSPEC_HIDDEN;
 
+extern DNS_STATUS CDECL resolv_get_searchlist( DNS_TXT_DATAW *, DWORD * ) DECLSPEC_HIDDEN;
 extern DNS_STATUS CDECL resolv_get_serverlist( USHORT, DNS_ADDR_ARRAY *, DWORD * ) DECLSPEC_HIDDEN;
 extern DNS_STATUS CDECL resolv_query( const char *, WORD, DWORD, DNS_RECORDA ** ) DECLSPEC_HIDDEN;
 extern DNS_STATUS CDECL resolv_set_serverlist( const IP4_ARRAY * ) DECLSPEC_HIDDEN;
 
 struct resolv_funcs
 {
+    DNS_STATUS (CDECL *get_searchlist)( DNS_TXT_DATAW *list, DWORD *len );
     DNS_STATUS (CDECL *get_serverlist)( USHORT family, DNS_ADDR_ARRAY *addrs, DWORD *len );
     DNS_STATUS (CDECL *query)( const char *name, WORD type, DWORD options, DNS_RECORDA **result );
     DNS_STATUS (CDECL *set_serverlist)( const IP4_ARRAY *addrs );
diff --git a/dlls/dnsapi/libresolv.c b/dlls/dnsapi/libresolv.c
index b0374927b6d..7e545cf36fb 100644
--- a/dlls/dnsapi/libresolv.c
+++ b/dlls/dnsapi/libresolv.c
@@ -61,6 +61,54 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dnsapi);
 
+static CPTABLEINFO unix_cptable;
+static ULONG unix_cp = CP_UTF8;
+
+static DWORD WINAPI get_unix_codepage_once( RTL_RUN_ONCE *once, void *param, void **context )
+{
+    static const WCHAR wineunixcpW[] = { 'W','I','N','E','U','N','I','X','C','P',0 };
+    UNICODE_STRING name, value;
+    WCHAR value_buffer[13];
+    SIZE_T size;
+    void *ptr;
+
+    RtlInitUnicodeString( &name, wineunixcpW );
+    value.Buffer = value_buffer;
+    value.MaximumLength = sizeof(value_buffer);
+    if (!RtlQueryEnvironmentVariable_U( NULL, &name, &value ))
+        RtlUnicodeStringToInteger( &value, 10, &unix_cp );
+    if (unix_cp != CP_UTF8 && !NtGetNlsSectionPtr( 11, unix_cp, NULL, &ptr, &size ))
+        RtlInitCodePageTable( ptr, &unix_cptable );
+    return TRUE;
+}
+
+static BOOL get_unix_codepage( void )
+{
+    static RTL_RUN_ONCE once = RTL_RUN_ONCE_INIT;
+
+    return !RtlRunOnceExecuteOnce( &once, get_unix_codepage_once, NULL, NULL );
+}
+
+static DWORD dnsapi_umbstowcs( const char *src, WCHAR *dst, DWORD dstlen )
+{
+    DWORD srclen = strlen( src ) + 1;
+    DWORD len;
+
+    get_unix_codepage();
+
+    if (unix_cp == CP_UTF8)
+    {
+        RtlUTF8ToUnicodeN( dst, dstlen, &len, src, srclen );
+        return len;
+    }
+    else
+    {
+        len = srclen * sizeof(WCHAR);
+        if (dst) RtlCustomCPToUnicodeN( &unix_cptable, dst, dstlen, &len, src, srclen );
+        return len;
+    }
+}
+
 static const char *debugstr_type( unsigned short type )
 {
     const char *str;
@@ -229,6 +277,38 @@ static DNS_STATUS map_h_errno( int error )
     }
 }
 
+DNS_STATUS CDECL resolv_get_searchlist( DNS_TXT_DATAW *list, DWORD *len )
+{
+    DWORD i, needed, str_needed = 0;
+    char *ptr, *end;
+
+    init_resolver();
+
+    for (i = 0; i < MAXDNSRCH + 1 && _res.dnsrch[i]; i++)
+        str_needed += dnsapi_umbstowcs( _res.dnsrch[i], NULL, 0 );
+
+    needed = FIELD_OFFSET(DNS_TXT_DATAW, pStringArray[i]) + str_needed;
+
+    if (!list || *len < needed)
+    {
+        *len = needed;
+        return !list ? ERROR_SUCCESS : ERROR_MORE_DATA;
+    }
+
+    *len = needed;
+    list->dwStringCount = i;
+
+    ptr = (char *)(list->pStringArray + i);
+    end = ptr + str_needed;
+    for (i = 0; i < MAXDNSRCH + 1 && _res.dnsrch[i]; i++)
+    {
+        list->pStringArray[i] = (WCHAR *)ptr;
+        ptr += dnsapi_umbstowcs( _res.dnsrch[i], list->pStringArray[i], end - ptr );
+    }
+    return ERROR_SUCCESS;
+}
+
+
 static inline int filter( unsigned short sin_family, USHORT family )
 {
     if (sin_family != AF_INET && sin_family != AF_INET6) return TRUE;
@@ -851,6 +931,7 @@ exit:
 
 static const struct resolv_funcs funcs =
 {
+    resolv_get_searchlist,
     resolv_get_serverlist,
     resolv_query,
     resolv_set_serverlist
diff --git a/dlls/dnsapi/query.c b/dlls/dnsapi/query.c
index 9900166aeb8..3155c93b360 100644
--- a/dlls/dnsapi/query.c
+++ b/dlls/dnsapi/query.c
@@ -343,7 +343,6 @@ DNS_STATUS WINAPI DnsQueryConfig( DNS_CONFIG_TYPE config, DWORD flag, PCWSTR ada
     case DnsConfigAdapterDomainName_A:
     case DnsConfigAdapterDomainName_W:
     case DnsConfigAdapterDomainName_UTF8:
-    case DnsConfigSearchList:
     case DnsConfigAdapterInfo:
     case DnsConfigPrimaryHostNameRegistrationEnabled:
     case DnsConfigAdapterHostNameRegistrationEnabled:
@@ -358,6 +357,9 @@ DNS_STATUS WINAPI DnsQueryConfig( DNS_CONFIG_TYPE config, DWORD flag, PCWSTR ada
     case DnsConfigDnsServersIpv6:
         return resolv_funcs->get_serverlist( AF_INET6, buffer, len );
 
+    case DnsConfigSearchList:
+        return resolv_funcs->get_searchlist( buffer, len );
+
     default:
         WARN( "unknown config type: %d\n", config );
         break;
diff --git a/dlls/nsiproxy.sys/ip.c b/dlls/nsiproxy.sys/ip.c
index dbd019c8442..fa88b8e0819 100644
--- a/dlls/nsiproxy.sys/ip.c
+++ b/dlls/nsiproxy.sys/ip.c
@@ -470,7 +470,8 @@ static NTSTATUS ipv6_forward_enumerate_all( void *key_data, DWORD key_size, void
                                             void *static_data, DWORD static_size, DWORD_PTR *count )
 {
     FIXME( "not implemented\n" );
-    return STATUS_NOT_IMPLEMENTED;
+    *count = 0;
+    return STATUS_SUCCESS;
 }
 
 static struct module_table ipv4_tables[] =
-- 
2.23.0




More information about the wine-devel mailing list