netapi32: Implement DsGetDcNameW.
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
9f20b7f483
commit
510bea7692
|
@ -1,7 +1,7 @@
|
|||
EXTRADEFS = -D_SVRAPI_
|
||||
MODULE = netapi32.dll
|
||||
IMPORTLIB = netapi32
|
||||
IMPORTS = rpcrt4 iphlpapi ws2_32 advapi32
|
||||
IMPORTS = rpcrt4 iphlpapi ws2_32 advapi32 dnsapi
|
||||
|
||||
C_SRCS = \
|
||||
nbcmdqueue.c \
|
||||
|
|
|
@ -1437,12 +1437,15 @@ static const WCHAR Config_NetworkW[] = { 'S','o','f','t','w','a','r','e','\\',
|
|||
/* Initializes global variables and registers the NetBT transport */
|
||||
void NetBTInit(void)
|
||||
{
|
||||
WSADATA wsa_data;
|
||||
HKEY hKey;
|
||||
NetBIOSTransport transport;
|
||||
LONG ret;
|
||||
|
||||
TRACE("\n");
|
||||
|
||||
WSAStartup(MAKEWORD(2, 2), &wsa_data);
|
||||
|
||||
gEnableDNS = TRUE;
|
||||
gBCastQueries = BCAST_QUERIES;
|
||||
gBCastQueryTimeout = BCAST_QUERY_TIMEOUT;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright 2005,2006 Paul Vriens
|
||||
* Copyright 2006 Robert Reif
|
||||
* Copyright 2013 Hans Leidekker for CodeWeavers
|
||||
* Copyright 2020 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -37,6 +38,9 @@
|
|||
#define WIN32_NO_STATUS
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winsock2.h"
|
||||
#include "ws2ipdef.h"
|
||||
#include "windns.h"
|
||||
#include "lm.h"
|
||||
#include "lmaccess.h"
|
||||
#include "atsvc.h"
|
||||
|
@ -56,9 +60,12 @@
|
|||
#include "wine/library.h"
|
||||
#include "wine/list.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "initguid.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(netapi32);
|
||||
|
||||
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
|
||||
|
||||
static char *strdup_unixcp( const WCHAR *str )
|
||||
{
|
||||
char *ret;
|
||||
|
@ -3033,14 +3040,142 @@ NET_API_STATUS WINAPI I_BrowserQueryEmulatedDomains(
|
|||
return ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
DWORD WINAPI DsGetDcNameW(LPCWSTR ComputerName, LPCWSTR AvoidDCName,
|
||||
GUID* DomainGuid, LPCWSTR SiteName, ULONG Flags,
|
||||
PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo)
|
||||
#define NS_MAXDNAME 1025
|
||||
|
||||
static DWORD get_dc_info(const WCHAR *domain, WCHAR *dc, WCHAR *ip)
|
||||
{
|
||||
FIXME("(%s, %s, %s, %s, %08x, %p): stub\n", debugstr_w(ComputerName),
|
||||
debugstr_w(AvoidDCName), debugstr_guid(DomainGuid),
|
||||
debugstr_w(SiteName), Flags, DomainControllerInfo);
|
||||
return ERROR_CALL_NOT_IMPLEMENTED;
|
||||
static const WCHAR pfx[] = {'_','l','d','a','p','.','_','t','c','p','.','d','c','.','_','m','s','d','c','s','.',0};
|
||||
WCHAR name[NS_MAXDNAME];
|
||||
DWORD ret, size;
|
||||
DNS_RECORDW *rec;
|
||||
|
||||
lstrcpyW(name, pfx);
|
||||
lstrcatW(name, domain);
|
||||
|
||||
ret = DnsQuery_W(name, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &rec, NULL);
|
||||
TRACE("DnsQuery_W(%s) => %d\n", wine_dbgstr_w(domain), ret);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
TRACE("target %s, port %d\n", wine_dbgstr_w(rec->Data.Srv.pNameTarget), rec->Data.Srv.wPort);
|
||||
|
||||
lstrcpynW(dc, rec->Data.Srv.pNameTarget, NS_MAXDNAME);
|
||||
DnsRecordListFree(rec, DnsFreeRecordList);
|
||||
|
||||
/* IPv4 */
|
||||
ret = DnsQuery_W(dc, DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &rec, NULL);
|
||||
TRACE("DnsQuery_W(%s) => %d\n", wine_dbgstr_w(dc), ret);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
SOCKADDR_IN addr;
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 0;
|
||||
addr.sin_addr.s_addr = rec->Data.A.IpAddress;
|
||||
size = IP6_ADDRESS_STRING_LENGTH;
|
||||
ret = WSAAddressToStringW((SOCKADDR *)&addr, sizeof(addr), NULL, ip, &size);
|
||||
if (!ret)
|
||||
TRACE("WSAAddressToStringW => %d, %s\n", ret, wine_dbgstr_w(ip));
|
||||
|
||||
DnsRecordListFree(rec, DnsFreeRecordList);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* IPv6 */
|
||||
ret = DnsQuery_W(dc, DNS_TYPE_AAAA, DNS_QUERY_STANDARD, NULL, &rec, NULL);
|
||||
TRACE("DnsQuery_W(%s) => %d\n", wine_dbgstr_w(dc), ret);
|
||||
if (ret == ERROR_SUCCESS)
|
||||
{
|
||||
SOCKADDR_IN6 addr;
|
||||
|
||||
addr.sin6_family = AF_INET6;
|
||||
addr.sin6_port = 0;
|
||||
addr.sin6_scope_id = 0;
|
||||
memcpy(addr.sin6_addr.s6_addr, &rec->Data.AAAA.Ip6Address, sizeof(rec->Data.AAAA.Ip6Address));
|
||||
size = IP6_ADDRESS_STRING_LENGTH;
|
||||
ret = WSAAddressToStringW((SOCKADDR *)&addr, sizeof(addr), NULL, ip, &size);
|
||||
if (!ret)
|
||||
TRACE("WSAAddressToStringW => %d, %s\n", ret, wine_dbgstr_w(ip));
|
||||
|
||||
DnsRecordListFree(rec, DnsFreeRecordList);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD WINAPI DsGetDcNameW(LPCWSTR computer, LPCWSTR domain, GUID *domain_guid,
|
||||
LPCWSTR site, ULONG flags, PDOMAIN_CONTROLLER_INFOW *dc_info)
|
||||
{
|
||||
static const WCHAR pfxW[] = {'\\','\\'};
|
||||
static const WCHAR default_site_nameW[] = {'D','e','f','a','u','l','t','-','F','i','r','s','t','-','S','i','t','e','-','N','a','m','e',0};
|
||||
NTSTATUS status;
|
||||
POLICY_DNS_DOMAIN_INFO *dns_domain_info = NULL;
|
||||
DOMAIN_CONTROLLER_INFOW *info;
|
||||
WCHAR dc[NS_MAXDNAME], ip[IP6_ADDRESS_STRING_LENGTH];
|
||||
DWORD size;
|
||||
|
||||
FIXME("(%s, %s, %s, %s, %08x, %p): semi-stub\n", debugstr_w(computer),
|
||||
debugstr_w(domain), debugstr_guid(domain_guid), debugstr_w(site), flags, dc_info);
|
||||
|
||||
if (!dc_info) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
if (!domain)
|
||||
{
|
||||
LSA_OBJECT_ATTRIBUTES attrs;
|
||||
LSA_HANDLE lsa;
|
||||
|
||||
memset(&attrs, 0, sizeof(attrs));
|
||||
attrs.Length = sizeof(attrs);
|
||||
status = LsaOpenPolicy(NULL, &attrs, POLICY_VIEW_LOCAL_INFORMATION, &lsa);
|
||||
if (status)
|
||||
return LsaNtStatusToWinError(status);
|
||||
|
||||
status = LsaQueryInformationPolicy(lsa, PolicyDnsDomainInformation, (void **)&dns_domain_info);
|
||||
LsaClose(lsa);
|
||||
if (status)
|
||||
return LsaNtStatusToWinError(status);
|
||||
|
||||
domain = dns_domain_info->DnsDomainName.Buffer;
|
||||
}
|
||||
|
||||
status = get_dc_info(domain, dc, ip);
|
||||
if (status) return status;
|
||||
|
||||
size = sizeof(DOMAIN_CONTROLLER_INFOW) + lstrlenW(domain) * sizeof(WCHAR) +
|
||||
sizeof(pfxW) * 2 + (lstrlenW(dc) + 1 + lstrlenW(ip) + 1) * sizeof(WCHAR) +
|
||||
lstrlenW(domain) * sizeof(WCHAR) /* assume forest == domain */ +
|
||||
sizeof(default_site_nameW) * 2;
|
||||
status = NetApiBufferAllocate(size, (void **)&info);
|
||||
if (status != NERR_Success)
|
||||
{
|
||||
LsaFreeMemory(dns_domain_info);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
|
||||
info->DomainControllerName = (WCHAR *)(info + 1);
|
||||
memcpy(info->DomainControllerName, pfxW, sizeof(pfxW));
|
||||
lstrcpyW(info->DomainControllerName + 2, dc);
|
||||
info->DomainControllerAddress = (WCHAR *)((char *)info->DomainControllerName + (strlenW(info->DomainControllerName) + 1) * sizeof(WCHAR));
|
||||
memcpy(info->DomainControllerAddress, pfxW, sizeof(pfxW));
|
||||
lstrcpyW(info->DomainControllerAddress + 2, ip);
|
||||
info->DomainControllerAddressType = DS_INET_ADDRESS;
|
||||
info->DomainGuid = dns_domain_info ? dns_domain_info->DomainGuid : GUID_NULL /* FIXME */;
|
||||
info->DomainName = (WCHAR *)((char *)info->DomainControllerAddress + (strlenW(info->DomainControllerAddress) + 1) * sizeof(WCHAR));
|
||||
lstrcpyW(info->DomainName, domain);
|
||||
info->DnsForestName = (WCHAR *)((char *)info->DomainName + (lstrlenW(info->DomainName) + 1) * sizeof(WCHAR));
|
||||
lstrcpyW(info->DnsForestName, domain);
|
||||
info->DcSiteName = (WCHAR *)((char *)info->DnsForestName + (lstrlenW(info->DnsForestName) + 1) * sizeof(WCHAR));
|
||||
lstrcpyW(info->DcSiteName, default_site_nameW);
|
||||
info->ClientSiteName = (WCHAR *)((char *)info->DcSiteName + sizeof(default_site_nameW));
|
||||
lstrcpyW(info->ClientSiteName, default_site_nameW);
|
||||
info->Flags = DS_DNS_DOMAIN_FLAG | DS_DNS_FOREST_FLAG;
|
||||
|
||||
LsaFreeMemory(dns_domain_info);
|
||||
|
||||
*dc_info = info;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD WINAPI DsGetDcNameA(LPCSTR ComputerName, LPCSTR AvoidDCName,
|
||||
|
|
|
@ -23,6 +23,13 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DS_INET_ADDRESS 1
|
||||
#define DS_NETBIOS_ADDRESS 2
|
||||
|
||||
#define DS_DNS_CONTROLLER_FLAG 0x20000000
|
||||
#define DS_DNS_DOMAIN_FLAG 0x40000000
|
||||
#define DS_DNS_FOREST_FLAG 0x80000000
|
||||
|
||||
#define DS_FORCE_REDISCOVERY 0x00000001
|
||||
#define DS_DIRECTORY_SERVICE_REQUIRED 0x00000010
|
||||
#define DS_DIRECTORY_SERVICE_PREFERRED 0x00000020
|
||||
|
|
Loading…
Reference in New Issue