diff options
Diffstat (limited to 'lib/irs/win32/resconf.c')
-rw-r--r-- | lib/irs/win32/resconf.c | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/lib/irs/win32/resconf.c b/lib/irs/win32/resconf.c new file mode 100644 index 0000000..3b46b8e --- /dev/null +++ b/lib/irs/win32/resconf.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) Internet Systems Consortium, Inc. ("ISC") + * + * SPDX-License-Identifier: MPL-2.0 + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, you can obtain one at https://mozilla.org/MPL/2.0/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +/* + * Note that on Win32 there is normally no resolv.conf since all information + * is stored in the registry. Therefore there is no ordering like the + * contents of resolv.conf. Since the "search" or "domain" keyword, on + * Win32 if a search list is found it is used, otherwise the domain name + * is used since they are mutually exclusive. The search list can be entered + * in the DNS tab of the "Advanced TCP/IP settings" window under the same place + * that you add your nameserver list. + */ + +#define HAVE_GET_WIN32_NAMESERVERS 1 + +#include "../resconf.c" +#include <iphlpapi.h> + +#define TCPIP_SUBKEY "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters" + +isc_result_t +get_win32_searchlist(irs_resconf_t *conf) { + isc_result_t result = ISC_R_SUCCESS; + HKEY hKey; + char searchlist[MAX_PATH]; + DWORD searchlen = MAX_PATH; + LSTATUS status; + char *cp; + + REQUIRE(conf != NULL); + + memset(searchlist, 0, MAX_PATH); + status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TCPIP_SUBKEY, 0, KEY_READ, + &hKey); + if (status != ERROR_SUCCESS) { + return (ISC_R_SUCCESS); + } + + status = RegQueryValueEx(hKey, "SearchList", NULL, NULL, + (LPBYTE)searchlist, &searchlen); + RegCloseKey(hKey); + if (status != ERROR_SUCCESS) { + return (ISC_R_SUCCESS); + } + + cp = strtok((char *)searchlist, ", \0"); + while (cp != NULL) { + result = add_search(conf, cp); + if (result != ISC_R_SUCCESS) { + break; + } + cp = strtok(NULL, ", \0"); + } + return (result); +} + +isc_result_t +get_win32_nameservers(irs_resconf_t *conf) { + isc_result_t result; + FIXED_INFO *FixedInfo; + ULONG BufLen = sizeof(FIXED_INFO); + DWORD dwRetVal; + IP_ADDR_STRING *pIPAddr; + + REQUIRE(conf != NULL); + + FixedInfo = (FIXED_INFO *)GlobalAlloc(GPTR, BufLen); + if (FixedInfo == NULL) { + return (ISC_R_NOMEMORY); + } + dwRetVal = GetNetworkParams(FixedInfo, &BufLen); + if (dwRetVal == ERROR_BUFFER_OVERFLOW) { + GlobalFree(FixedInfo); + FixedInfo = GlobalAlloc(GPTR, BufLen); + if (FixedInfo == NULL) { + return (ISC_R_NOMEMORY); + } + dwRetVal = GetNetworkParams(FixedInfo, &BufLen); + } + if (dwRetVal != ERROR_SUCCESS) { + GlobalFree(FixedInfo); + return (ISC_R_FAILURE); + } + + result = get_win32_searchlist(conf); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + + if (ISC_LIST_EMPTY(conf->searchlist) && + strlen(FixedInfo->DomainName) > 0) + { + result = add_search(conf, FixedInfo->DomainName); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + } + + /* Get the list of nameservers */ + pIPAddr = &FixedInfo->DnsServerList; + while (pIPAddr) { + if (conf->numns >= RESCONFMAXNAMESERVERS) { + break; + } + + result = add_server(conf->mctx, pIPAddr->IpAddress.String, + &conf->nameservers); + if (result != ISC_R_SUCCESS) { + break; + } + conf->numns++; + pIPAddr = pIPAddr->Next; + } + +cleanup: + if (FixedInfo != NULL) { + GlobalFree(FixedInfo); + } + return (result); +} |