using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.Ws2_32;
using DNS_STATUS = Vanara.PInvoke.Win32Error;
using IP4_ADDRESS = Vanara.PInvoke.Ws2_32.IN_ADDR;
using IP6_ADDRESS = Vanara.PInvoke.Ws2_32.IN6_ADDR;
namespace Vanara.PInvoke
{
/// Functions, structures and constants from windns.h.
public static partial class DnsApi
{
/// The DNS_QUERY_COMPLETION_ROUTINE callback is used to asynchronously return the results of a DNS query.
/// A pointer to a user context.
/// A pointer to a DNS_QUERY_RESULT structure that contains the DNS query results from a call to DnsQueryEx.
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nc-windns-dns_query_completion_routine DNS_QUERY_COMPLETION_ROUTINE
// DnsQueryCompletionRoutine; void DnsQueryCompletionRoutine( PVOID pQueryContext, PDNS_QUERY_RESULT pQueryResults ) {...}
[PInvokeData("windns.h", MSDNShortId = "35D78208-FFC1-48B0-8267-EE583DE2D783")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DNS_QUERY_COMPLETION_ROUTINE([In] IntPtr pQueryContext, ref DNS_QUERY_RESULT pQueryResults);
/// Used to asynchronously return the results of a DNS-SD query.
/// A value that contains the status associated with this particular set of results.
/// A pointer to the user context that was passed to DnsServiceBrowse.
///
/// A pointer to a DNS_RECORD structure that contains a list of records describing a discovered service on the network. If not ,
/// then you are responsible for freeing the returned RR sets using DnsRecordListFree.
///
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nc-windns-dns_service_browse_callback DNS_SERVICE_BROWSE_CALLBACK
// DnsServiceBrowseCallback; void DnsServiceBrowseCallback( DWORD Status, PVOID pQueryContext, PDNS_RECORD pDnsRecord ) {...}
[PInvokeData("windns.h")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DNS_SERVICE_BROWSE_CALLBACK(uint Status, [In] IntPtr pQueryContext, IntPtr pDnsRecord);
/// Used to notify your application that service registration has completed.
/// A value that contains the status of the registration.
/// A pointer to the user context that was passed to DnsServiceRegister.
///
/// A pointer to a DNS_SERVICE_INSTANCE structure that describes the service that was registered. If not , then you are responsible
/// for freeing the data using DnsServiceFreeInstance.
///
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nc-windns-dns_service_register_complete DNS_SERVICE_REGISTER_COMPLETE
// DnsServiceRegisterComplete; void DnsServiceRegisterComplete( DWORD Status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance ) {...}
[PInvokeData("windns.h")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DNS_SERVICE_REGISTER_COMPLETE(uint Status, [In] IntPtr pQueryContext, [In] IntPtr pInstance);
/// Used to asynchronously return the results of a service resolve operation.
/// A value that contains the status associated with this particular set of results.
/// A pointer to the user context that was passed to DnsServiceResolve.
///
/// A pointer to a DNS_SERVICE_INSTANCE structure that contains detailed information about a service on the network. If not , then
/// you are responsible for freeing the data using DnsServiceFreeInstance.
///
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nc-windns-dns_service_resolve_complete DNS_SERVICE_RESOLVE_COMPLETE
// DnsServiceResolveComplete; void DnsServiceResolveComplete( DWORD Status, PVOID pQueryContext, PDNS_SERVICE_INSTANCE pInstance ) {...}
[PInvokeData("windns.h")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void DNS_SERVICE_RESOLVE_COMPLETE(uint Status, [In] IntPtr pQueryContext, [In] IntPtr pInstance);
/// Used to asynchronously return the results of an mDNS query.
/// A pointer to the user context that was passed to DnsServiceBrowse.
/// A pointer to the MDNS_QUERY_HANDLE structure that was passed to DnsStartMulticastQuery.
///
/// A pointer to a DNS_QUERY_RESULT structure that contains the query results. Your application is responsible for freeing the
/// contained in this structure using DnsRecordListFree.
///
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nc-windns-mdns_query_callback MDNS_QUERY_CALLBACK MdnsQueryCallback;
// void MdnsQueryCallback( PVOID pQueryContext, PMDNS_QUERY_HANDLE pQueryHandle, PDNS_QUERY_RESULT pQueryResults ) {...}
[PInvokeData("windns.h")]
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
public delegate void MDNS_QUERY_CALLBACK(IntPtr pQueryContext, IntPtr pQueryHandle, IntPtr pQueryResults);
/// Byte flip DNS header to\from host order.
/// The DNS_MESSAGE_BUFFER instance whose values are to be flipped.
[PInvokeData("windns.h")]
public static void DNS_BYTE_FLIP_HEADER_COUNTS(ref DNS_MESSAGE_BUFFER mBuf)
{
INLINE_HTONS(ref mBuf.MessageHead.Xid);
INLINE_HTONS(ref mBuf.MessageHead.QuestionCount);
INLINE_HTONS(ref mBuf.MessageHead.AnswerCount);
INLINE_HTONS(ref mBuf.MessageHead.NameServerCount);
INLINE_HTONS(ref mBuf.MessageHead.AdditionalCount);
static void INLINE_HTONS(ref ushort value) => value = (ushort)((value << 8) | (value >> 8));
}
///
///
/// The DnsAcquireContextHandle function type acquires a context handle to a set of credentials. Like many DNS functions, the
/// DnsAcquireContextHandle function type is implemented in multiple forms to facilitate different character encoding. Based
/// on the character encoding involved, use one of the following functions:
///
///
/// -
/// DnsAcquireContextHandle_A (_A for ANSI encoding)
///
/// -
/// DnsAcquireContextHandle_W (_W for Unicode encoding)
///
///
///
///
/// A flag that indicates the character encoding. Set to TRUE for Unicode, FALSE for ANSI.
///
///
/// A pointer to a SEC_WINNT_AUTH_IDENTITY_W structure or a SEC_WINNT_AUTH_IDENTITY_A structure that contains the name,
/// domain, and password of the account to be used in a secure dynamic update. If CredentialFlags is set to TRUE, Credentials
/// points to a SEC_WINNT_AUTH_IDENTITY_W structure; otherwise, Credentials points to a SEC_WINNT_AUTH_IDENTITY_A
/// structure. If not specified, the credentials of the calling service are used. This parameter is optional.
///
/// A pointer to a handle pointing to the returned credentials.
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsacquirecontexthandle_w DNS_STATUS
// DnsAcquireContextHandle_W( DWORD CredentialFlags, PVOID Credentials, PHANDLE pContext );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsAcquireContextHandle_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "9a820165-2f78-44f4-b49f-dc7a2b6fb4e5")]
public static extern DNS_STATUS DnsAcquireContextHandle([MarshalAs(UnmanagedType.Bool)] bool CredentialFlags, [In, Optional] IntPtr Credentials, out SafeHDNSCONTEXT pContext);
/// The DnsCancelQuery function can be used to cancel a pending query to the DNS namespace.
///
/// A pointer to a DNS_QUERY_CANCEL structure used to cancel an asynchronous DNS query. The structure must have been returned in the
/// pCancelHandle parameter of a previous call to DnsQueryEx.
///
///
/// Returns success confirmation upon successful completion. Otherwise, it returns the appropriate DNS-specific error code as
/// defined in Winerror.h.
///
///
///
/// DnsCancelQuery does not wait for a query to complete before cancelling. Therefore, applications should track pending
/// queries through their DNS_QUERY_COMPLETION_ROUTINE DNS callbacks.
///
/// pCancelHandle is valid until the DNS_QUERY_COMPLETION_ROUTINE DNS callback is invoked and DnsCancelQuery completes.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnscancelquery DNS_STATUS DnsCancelQuery( PDNS_QUERY_CANCEL
// pCancelHandle );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "E5F422AA-D4E6-4F9F-A57C-608CE9317658")]
public static extern DNS_STATUS DnsCancelQuery(ref DNS_QUERY_CANCEL pCancelHandle);
///
/// The DnsExtractRecordsFromMessage function type extracts resource records (RR) from a DNS message, and stores those
/// records in a DNS_RECORD structure. Like many DNS functions, the DnsExtractRecordsFromMessage function type is implemented
/// in multiple forms to facilitate different character encoding.
///
/// A pointer to a DNS_MESSAGE_BUFFER structure that contains the DNS response message.
/// The size, in bytes, of the message in pDnsBuffer.
///
/// A pointer to a DNS_RECORD structure that contains the list of extracted RRs. To free these records, use the DnsRecordListFree function.
///
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
///
/// The DnsExtractRecordsFromMessage function is designed to operate on messages in host byte order. As such, received
/// messages should be converted from network byte order to host byte order before extraction, or before retransmission onto the
/// network. Use the DNS_BYTE_FLIP_HEADER_COUNTS macro to change byte ordering.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsextractrecordsfrommessage_w DNS_STATUS
// DnsExtractRecordsFromMessage_W( PDNS_MESSAGE_BUFFER pDnsBuffer, WORD wMessageLength, PDNS_RECORD *ppRecord );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsExtractRecordsFromMessage_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "0179bf3e-9243-4dd7-a2ab-e2f6f4bf4b82")]
public static extern DNS_STATUS DnsExtractRecordsFromMessage([In] IntPtr pDnsBuffer, ushort wMessageLength, out SafeDnsRecordList ppRecord);
/// The DnsFree function frees memory allocated for DNS records that was obtained using the DnsQuery function.
/// A pointer to the DNS data to be freed.
///
/// A value that specifies the type of DNS data in pData. For more information and a list of values, see the DNS_FREE_TYPE enumeration.
///
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsfree void DnsFree( _Frees_ptr_opt_ PVOID pData,
// DNS_FREE_TYPE FreeType );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "32baa672-2106-4c4a-972a-f7f79996b613")]
public static extern void DnsFree(IntPtr pData, DNS_FREE_TYPE FreeType);
/// Frees an array of custom servers that was returned from DnsGetApplicationSettings.
///
/// Type: _Inout_ DWORD*
///
/// A pointer to a DWORD that contains the number of servers present in the array pointed to by ppServers. This will be set
/// to 0 after the function call.
///
///
///
/// Type: _Inout_ DNS_CUSTOM_SERVER**
///
/// A pointer to an array of DNS_CUSTOM_SERVER that contains pcServers elements. This will be set to NULL after the function call.
///
///
/// None
///
/// To avoid memory leaks, you must call DnsFreeCustomServers on the servers returned by DnsGetApplicationSettings via its
/// pSettings parameter.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsfreecustomservers
// void DnsFreeCustomServers( DWORD *pcServers, DNS_CUSTOM_SERVER **ppServers );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "NF:windns.DnsFreeCustomServers", MinClient = PInvokeClient.Windows11)]
public static extern void DnsFreeCustomServers(ref uint pcServers, ref IntPtr ppServers);
///
/// The DnsFreeProxyName function frees memory allocated for the proxyName member of a DNS_PROXY_INFORMATION structure
/// obtained using the DnsGetProxyInformation function.
///
/// A pointer to the proxyName string to be freed.
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsfreeproxyname void DnsFreeProxyName( _Frees_ptr_opt_ PWSTR
// proxyName );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "4c69d548-3bb5-4609-9fc5-3a829a285956")]
public static extern void DnsFreeProxyName(IntPtr proxyName);
/// Retrieves the per-application DNS settings.
///
/// Type: _Out_ DWORD*
///
/// After the function call, this will point to the number of custom DNS servers that the application has configured. If there are
/// no custom servers configured, or if the function fails, then this will be set to 0.
///
///
///
/// Type: _Outptr_result_buffer_(*pcServers) DNS_CUSTOM_SERVER**
///
/// After the function call, this will point to the array of DNS custom servers that are configured for the application. If the
/// application has no servers configured, or if the function fails, then this will be set to NULL.
///
///
///
/// Type: _Out_opt_ DNS_APPLICATION_SETTINGS*
/// A pointer to a DNS_APPLICATION_SETTINGS object, populated with the application settings.
///
/// A DWORD containing ERROR_SUCCESS on success, or an error code on failure.
///
/// To avoid memory leaks, you must call DnsFreeCustomServers on the servers returned by DnsGetApplicationSettings via its
/// pSettings parameter.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsgetapplicationsettings
// DWORD DnsGetApplicationSettings( DWORD *pcServers, DNS_CUSTOM_SERVER **ppDefaultServers, DNS_APPLICATION_SETTINGS *pSettings );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "NF:windns.DnsGetApplicationSettings", MinClient = PInvokeClient.Windows11)]
public static extern Win32Error DnsGetApplicationSettings(out uint pcServers, out IntPtr ppDefaultServers, out DNS_APPLICATION_SETTINGS pSettings);
/// Retrieves the per-application DNS settings.
///
/// After the function call, this will point to the array of DNS custom servers that are configured for the application. If the
/// application has no servers configured, or if the function fails, then this will be set to NULL.
///
/// A pointer to a DNS_APPLICATION_SETTINGS object, populated with the application settings.
/// A DWORD containing ERROR_SUCCESS on success, or an error code on failure.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsgetapplicationsettings
// DWORD DnsGetApplicationSettings( DWORD *pcServers, DNS_CUSTOM_SERVER **ppDefaultServers, DNS_APPLICATION_SETTINGS *pSettings );
[PInvokeData("windns.h", MSDNShortId = "NF:windns.DnsGetApplicationSettings", MinClient = PInvokeClient.Windows11)]
public static Win32Error DnsGetApplicationSettings(out DNS_CUSTOM_SERVER[] ppDefaultServers, out DNS_APPLICATION_SETTINGS pSettings)
{
var err = DnsGetApplicationSettings(out var c, out var p, out pSettings);
if (err.Failed) { ppDefaultServers = null; return err; }
try
{
ppDefaultServers = p.ToArray((int)c);
}
finally
{
DnsFreeCustomServers(ref c, ref p);
}
return err;
}
/// Gets a list of cached domain names in the DNS client.
/// The cached data list.
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DnsGetCacheDataTable(out SafeDnsCacheDataTable ppCacheData);
///
/// The DnsGetProxyInformation function returns the proxy information for a DNS server's name resolution policy table.
///
/// A pointer to a string that represents the name of the DNS server whose proxy information is returned.
/// A pointer to a DNS_PROXY_INFORMATION structure that contains the proxy information for hostName.
///
/// A pointer to a DNS_PROXY_INFORMATION structure that contains the default proxy information for hostName. This proxy information
/// is for the wildcard DNS policy.
///
/// Reserved. Do not use.
/// Reserved. Do not use.
///
/// The DnsGetProxyInformation function returns the appropriate DNS-specific error code as defined in Winerror.h. The
/// following are possible return values:
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsgetproxyinformation DWORD DnsGetProxyInformation( PCWSTR
// hostName, DNS_PROXY_INFORMATION *proxyInformation, DNS_PROXY_INFORMATION *defaultProxyInformation, DNS_PROXY_COMPLETION_ROUTINE
// completionRoutine, void *completionContext );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "fdc8eb09-e071-4f03-974a-2b11a657ab18")]
public static extern Win32Error DnsGetProxyInformation([MarshalAs(UnmanagedType.LPWStr)] string hostName, ref DNS_PROXY_INFORMATION proxyInformation, ref DNS_PROXY_INFORMATION defaultProxyInformation,
IntPtr completionRoutine = default, IntPtr completionContext = default);
///
/// The DnsGetProxyInformation function returns the proxy information for a DNS server's name resolution policy table.
///
/// A pointer to a string that represents the name of the DNS server whose proxy information is returned.
/// A pointer to a DNS_PROXY_INFORMATION structure that contains the proxy information for hostName.
///
/// A pointer to a DNS_PROXY_INFORMATION structure that contains the default proxy information for hostName. This proxy information
/// is for the wildcard DNS policy.
///
/// Reserved. Do not use.
/// Reserved. Do not use.
///
/// The DnsGetProxyInformation function returns the appropriate DNS-specific error code as defined in Winerror.h. The
/// following are possible return values:
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsgetproxyinformation DWORD DnsGetProxyInformation( PCWSTR
// hostName, DNS_PROXY_INFORMATION *proxyInformation, DNS_PROXY_INFORMATION *defaultProxyInformation, DNS_PROXY_COMPLETION_ROUTINE
// completionRoutine, void *completionContext );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "fdc8eb09-e071-4f03-974a-2b11a657ab18")]
public static extern Win32Error DnsGetProxyInformation([MarshalAs(UnmanagedType.LPWStr)] string hostName, ref DNS_PROXY_INFORMATION proxyInformation, IntPtr defaultProxyInformation = default,
IntPtr completionRoutine = default, IntPtr completionContext = default);
///
/// The DnsModifyRecordsInSet function adds, modifies or removes a Resource Record (RR) set that may have been previously
/// registered with DNS servers.
///
/// A pointer to the DNS_RECORD structure that contains the RRs to be added to the RR set.
/// A pointer to the DNS_RECORD structure that contains the RRs to be deleted from the RR set.
///
/// A value that contains a bitmap of DNS Update Options. Options can be combined and all options override DNS_UPDATE_SECURITY_USE_DEFAULT.
///
///
/// A handle to the credentials of a specific account. Used when secure dynamic update is required. This parameter is optional.
///
/// This parameter is reserved for future use and must be set to NULL.
/// This parameter is reserved for future use and must be set to NULL.
///
/// Returns success confirmation upon successful completion. Otherwise, it returns the appropriate DNS-specific error code as
/// defined in Winerror.h.
///
///
/// The DnsModifyRecordsInSet function type executes in the following steps.
///
/// -
///
/// Records specified in pDeleteRecords are deleted. If pDeleteRecords is empty or does not contain records that exist in the
/// current set, the DnsModifyRecordsInSet function goes to the next step.
///
///
/// -
/// Records specified in pAddRecords are added. If pAddRecords is empty, the operation completes without adding any records.
///
///
///
/// To add a new record, provide no records in pDeleteRecords, and provide the record to be added in pAddRecords. To modify a
/// record, specify the record being modified in pDeleteRecords, then add the modified version of that record by placing it in
/// pAddRecords. To delete records, specify only records to be deleted. Multiple records can be added or deleted in a single call to
/// DnsModifyRecordsInSet; however, the value of the pName member in each DNS_RECORD must be the same or the call will
/// fail. If a record specified in pAddRecords is already present, no change occurs.
///
/// If no server list is specified, the default name server is queried.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsmodifyrecordsinset_a DNS_STATUS DnsModifyRecordsInSet_A(
// PDNS_RECORD pAddRecords, PDNS_RECORD pDeleteRecords, DWORD Options, HANDLE hCredentials, PVOID pExtraList, PVOID pReserved );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsModifyRecordsInSet_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "4287b4e1-a7a2-4b73-b5bb-21bc639bae73")]
public static extern DNS_STATUS DnsModifyRecordsInSet(in DNS_RECORD pAddRecords, in DNS_RECORD pDeleteRecords, DNS_UPDATE Options, [Optional] IntPtr hCredentials, [In, Out, Optional] IntPtr pExtraList, IntPtr pReserved = default);
///
/// The DnsModifyRecordsInSet function adds, modifies or removes a Resource Record (RR) set that may have been previously
/// registered with DNS servers.
///
/// A pointer to the DNS_RECORD structure that contains the RRs to be added to the RR set.
/// A pointer to the DNS_RECORD structure that contains the RRs to be deleted from the RR set.
///
/// A value that contains a bitmap of DNS Update Options. Options can be combined and all options override DNS_UPDATE_SECURITY_USE_DEFAULT.
///
///
/// A handle to the credentials of a specific account. Used when secure dynamic update is required. This parameter is optional.
///
/// This parameter is reserved for future use and must be set to NULL.
/// This parameter is reserved for future use and must be set to NULL.
///
/// Returns success confirmation upon successful completion. Otherwise, it returns the appropriate DNS-specific error code as
/// defined in Winerror.h.
///
///
/// The DnsModifyRecordsInSet function type executes in the following steps.
///
/// -
///
/// Records specified in pDeleteRecords are deleted. If pDeleteRecords is empty or does not contain records that exist in the
/// current set, the DnsModifyRecordsInSet function goes to the next step.
///
///
/// -
/// Records specified in pAddRecords are added. If pAddRecords is empty, the operation completes without adding any records.
///
///
///
/// To add a new record, provide no records in pDeleteRecords, and provide the record to be added in pAddRecords. To modify a
/// record, specify the record being modified in pDeleteRecords, then add the modified version of that record by placing it in
/// pAddRecords. To delete records, specify only records to be deleted. Multiple records can be added or deleted in a single call to
/// DnsModifyRecordsInSet; however, the value of the pName member in each DNS_RECORD must be the same or the call will
/// fail. If a record specified in pAddRecords is already present, no change occurs.
///
/// If no server list is specified, the default name server is queried.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsmodifyrecordsinset_a DNS_STATUS DnsModifyRecordsInSet_A(
// PDNS_RECORD pAddRecords, PDNS_RECORD pDeleteRecords, DWORD Options, HANDLE hCredentials, PVOID pExtraList, PVOID pReserved );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsModifyRecordsInSet_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "4287b4e1-a7a2-4b73-b5bb-21bc639bae73")]
public static extern DNS_STATUS DnsModifyRecordsInSet([In] IntPtr pAddRecords, [In] IntPtr pDeleteRecords, DNS_UPDATE Options, [Optional] IntPtr hCredentials, [In, Out, Optional] IntPtr pExtraList, IntPtr pReserved = default);
/// The DnsNameCompare function compares two DNS names.
///
///
/// Returns TRUE if the compared names are equivalent, FALSE if they are not.
///
/// Name comparisons are not case sensitive, and trailing dots are ignored.
///
/// As with other DNS comparison functions, the DnsNameCompare function deems different encoding as an immediate indication
/// of differing values, and as such, the same names with different characters encoding will not be reported identically.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsnamecompare_w BOOL DnsNameCompare_W( PCWSTR pName1, PCWSTR
// pName2 );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsNameCompare_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "4a1512b3-8273-4632-9426-daa36456bce3")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DnsNameCompare(string pName1, string pName2);
///
///
/// The DnsQuery function type is the generic query interface to the DNS namespace, and provides application developers with
/// a DNS query resolution interface.
///
/// Windows 8: The DnsQueryEx function should be used if an application requires asynchronous querries to the DNS namespace.
///
/// A pointer to a string that represents the DNS name to query.
///
/// A value that represents the Resource Record (RR)DNS Record Type that is queried. wType determines the format of data
/// pointed to by ppQueryResultsSet. For example, if the value of wType is DNS_TYPE_A, the format of data
/// pointed to by ppQueryResultsSet is DNS_A_DATA.
///
///
/// A value that contains a bitmap of DNS Query Options to use in the DNS query. Options can be combined and all options override DNS_QUERY_STANDARD.
///
/// This parameter is reserved for future use and must be set to NULL.
///
/// Optional. A pointer to a pointer that points to the list of RRs that comprise the response. For more information, see the
/// Remarks section.
///
/// This parameter is reserved for future use and must be set to NULL.
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
///
///
/// Applications that call the DnsQuery function build a query using a fully qualified DNS name and Resource Record (RR)
/// type, and set query options depending on the type of service desired. When the DNS_QUERY_STANDARD option is set, DNS uses
/// the resolver cache, queries first with UDP, then retries with TCP if the response is truncated, and requests that the server to
/// perform recursive resolution on behalf of the client to resolve the query.
///
/// Applications must free returned RR sets with the DnsRecordListFree function.
///
/// Note When calling one of the DnsQuery function types, be aware that a DNS server may return multiple records in
/// response to a query. A computer that is multihomed, for example, will receive multiple A records for the same IP address. The
/// caller must use as many of the returned records as necessary.
///
///
/// Consider the following scenario, in which multiple returned records require additional activity on behalf of the application: A
/// DnsQuery_A function call is made for a multihomed computer and the application finds that the address associated with the
/// first A record is not responding. The application should then attempt to use other IP addresses specified in the (additional) A
/// records returned from the DnsQuery_A function call.
///
/// If the lpstrName parameter is set to NULL, the DnsQuery function fails with the error INVALID_PARAMETER.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsquery_a DNS_STATUS DnsQuery_A( PCSTR pszName, WORD wType,
// DWORD Options, PVOID pExtra, PDNS_RECORD *ppQueryResults, PVOID *pReserved );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsQuery_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "3d810b76-cea1-4904-9b5a-c2566b332c2c")]
public static extern DNS_STATUS DnsQuery(string pszName, DNS_TYPE wType, DNS_QUERY_OPTIONS Options, [In, Out, Optional] IntPtr pExtra,
out SafeDnsRecordList ppQueryResults, IntPtr pReserved = default);
///
///
/// The DnsQuery function type is the generic query interface to the DNS namespace, and provides application developers with
/// a DNS query resolution interface.
///
/// Windows 8: The DnsQueryEx function should be used if an application requires asynchronous querries to the DNS namespace.
///
/// A pointer to a string that represents the DNS name to query.
///
/// A value that represents the Resource Record (RR)DNS Record Type that is queried. wType determines the format of data
/// pointed to by ppQueryResultsSet. For example, if the value of wType is DNS_TYPE_A, the format of data
/// pointed to by ppQueryResultsSet is DNS_A_DATA.
///
///
/// A value that contains a bitmap of DNS Query Options to use in the DNS query. Options can be combined and all options override DNS_QUERY_STANDARD.
///
/// This parameter is reserved for future use and must be set to NULL.
///
/// Optional. A pointer to a pointer that points to the list of RRs that comprise the response. For more information, see the
/// Remarks section.
///
/// This parameter is reserved for future use and must be set to NULL.
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
///
///
/// Applications that call the DnsQuery function build a query using a fully qualified DNS name and Resource Record (RR)
/// type, and set query options depending on the type of service desired. When the DNS_QUERY_STANDARD option is set, DNS uses
/// the resolver cache, queries first with UDP, then retries with TCP if the response is truncated, and requests that the server to
/// perform recursive resolution on behalf of the client to resolve the query.
///
/// Applications must free returned RR sets with the DnsRecordListFree function.
///
/// Note When calling one of the DnsQuery function types, be aware that a DNS server may return multiple records in
/// response to a query. A computer that is multihomed, for example, will receive multiple A records for the same IP address. The
/// caller must use as many of the returned records as necessary.
///
///
/// Consider the following scenario, in which multiple returned records require additional activity on behalf of the application: A
/// DnsQuery_A function call is made for a multihomed computer and the application finds that the address associated with the
/// first A record is not responding. The application should then attempt to use other IP addresses specified in the (additional) A
/// records returned from the DnsQuery_A function call.
///
/// If the lpstrName parameter is set to NULL, the DnsQuery function fails with the error INVALID_PARAMETER.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsquery_a DNS_STATUS DnsQuery_A( PCSTR pszName, WORD wType,
// DWORD Options, PVOID pExtra, PDNS_RECORD *ppQueryResults, PVOID *pReserved );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsQuery_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "3d810b76-cea1-4904-9b5a-c2566b332c2c")]
public static extern DNS_STATUS DnsQuery(string pszName, DNS_TYPE wType, DNS_QUERY_OPTIONS Options, [In, Out, Optional] IntPtr pExtra,
IntPtr ppQueryResults = default, IntPtr pReserved = default);
///
/// The DnsQueryConfig function enables application programmers to query for the configuration of the local computer or a
/// specific adapter.
///
/// A DNS_CONFIG_TYPE value that specifies the configuration type of the information to be queried.
///
///
/// A value that specifies whether to allocate memory for the configuration information. Set Flag to DNS_CONFIG_FLAG_ALLOC to
/// allocate memory; otherwise, set it to 0.
///
/// Note Free the allocated memory with LocalFree.
///
/// A pointer to a string that represents the adapter name against which the query is run.
/// Reserved for future use.
///
///
/// A pointer to a buffer that receives the query response. The following table shows the data type of the buffer for each of the
/// Config parameter values.
///
///
///
/// Config parameter
/// Data type of buffer
///
/// -
/// DnsConfigPrimaryDomainName_W
/// PWCHAR
///
/// -
/// DnsConfigPrimaryDomainName_A
/// PCHAR
///
/// -
/// DnsConfigPrimaryDomainName_UTF8
/// PCHAR
///
/// -
/// DnsConfigAdapterDomainName_W
/// Not implemented
///
/// -
/// DnsConfigAdapterDomainName_A
/// Not implemented
///
/// -
/// DnsConfigAdapterDomainName_UTF8
/// Not implemented
///
/// -
/// DnsConfigDnsServerList
/// IP4_ARRAY
///
/// -
/// DnsConfigSearchList
/// Not implemented
///
/// -
/// DnsConfigAdapterInfo
/// Not implemented
///
/// -
/// DnsConfigPrimaryHostNameRegistrationEnabled
/// DWORD
///
/// -
/// DnsConfigAdapterHostNameRegistrationEnabled
/// DWORD
///
/// -
/// DnsConfigAddressRegistrationMaxCount
/// DWORD
///
/// -
/// DnsConfigHostName_W
/// PWCHAR
///
/// -
/// DnsConfigHostName_A
/// PCHAR
///
/// -
/// DnsConfigHostName_UTF8
/// PCHAR
///
/// -
/// DnsConfigFullHostName_W
/// PWCHAR
///
/// -
/// DnsConfigFullHostName_A
/// PCHAR
///
/// -
/// DnsConfigFullHostName_UTF8
/// PCHAR
///
///
///
///
/// The length of the buffer, in bytes. If the buffer provided is not sufficient, an error is returned and pBufferLength contains
/// the minimum necessary buffer size. Ignored on input if Flag is set to TRUE.
///
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsqueryconfig DNS_STATUS DnsQueryConfig( DNS_CONFIG_TYPE
// Config, DWORD Flag, PCWSTR pwsAdapterName, PVOID pReserved, PVOID pBuffer, PDWORD pBufLen );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "83de7df8-7e89-42fe-b609-1dc173afc9df")]
public static extern DNS_STATUS DnsQueryConfig(DNS_CONFIG_TYPE Config, DNS_CONFIG_FLAG Flag, [Optional, MarshalAs(UnmanagedType.LPWStr)] string pwsAdapterName,
[In, Optional] IntPtr pReserved, IntPtr pBuffer, ref uint pBufLen);
///
///
/// The DnsQueryEx function is the asynchronous generic query interface to the DNS namespace, and provides application
/// developers with a DNS query resolution interface.
///
/// Like DnsQuery, DnsQueryEx can be used to make synchronous queries to the DNS namespace as well.
///
///
/// A pointer to a DNS_QUERY_REQUEST structure that contains the query request information.
///
/// Note By omitting the DNS_QUERY_COMPLETION_ROUTINE callback from the pQueryCompleteCallback member of this
/// structure, DnsQueryEx is called synchronously.
///
///
///
///
/// A pointer to a DNS_QUERY_RESULT structure that contains the results of the query. On input, the version member of
/// pQueryResults must be DNS_QUERY_REQUEST_VERSION1 and all other members should be NULL. On output, the remaining
/// members will be filled as part of the query complete.
///
///
/// Note For asynchronous queries, an application should not free this structure until the DNS_QUERY_COMPLETION_ROUTINE
/// callback is invoked. When the query completes, the DNS_QUERY_RESULT structure contains a pointer to a list of DNS_RECORDS that
/// should be freed using DnsRecordListFree.
///
///
///
/// A pointer to a DNS_QUERY_CANCEL structure that can be used to cancel a pending asynchronous query.
/// Note An application should not free this structure until the DNS_QUERY_COMPLETION_ROUTINE callback is invoked.
///
///
/// The DnsQueryEx function has the following possible return values:
///
///
/// Return code
/// Description
///
/// -
/// ERROR_SUCCESS
/// The call was successful.
///
/// -
/// ERROR_INVALID_PARAMETER
/// Either the pQueryRequest or pQueryRequest parameters are uninitialized or contain the wrong version.
///
/// -
/// DNS RCODE
/// The call resulted in an RCODE error.
///
/// -
/// DNS_INFO_NO_RECORDS
/// No records in the response.
///
/// -
/// DNS_REQUEST_PENDING
/// The query will be completed asynchronously.
///
///
///
///
///
/// If a call to DnsQueryEx completes synchronously (i.e., the function return value is not DNS_REQUEST_PENDING), the
/// pQueryRecords member of pQueryResults contains a pointer to a list of DNS_RECORDS and DnsQueryEx will return
/// either error or success.
///
/// The following conditions invoke a synchronous call to DnsQueryEx and do not utilize the DNS callback:
///
/// -
/// The DNS_QUERY_COMPLETION_ROUTINE callback is omitted from the pQueryCompleteCallback member of pQueryRequest.
///
/// -
/// A query is for the local machine name and A or AAAA type Resource Records (RR).
///
/// -
/// A call to DnsQueryEx queries an IPv4 or IPv6 address.
///
/// -
/// A call to DnsQueryEx returns in error.
///
///
///
/// If a call to DnsQueryEx completes asynchronously, the results of the query are returned by the
/// DNS_QUERY_COMPLETION_ROUTINE callback in pQueryRequest, the QueryStatus member of pQueryResults contains
/// DNS_REQUEST_PENDING, and DnsQueryEx returns DNS_REQUEST_PENDING. Applications should track the
/// pQueryResults structure that is passed into DnsQueryEx until the DNS callback succeeds. Applications can cancel an
/// asynchronous query using the pCancelHandle handle returned by DnsQueryEx.
///
///
/// pCancelHandle returned from an asynchronous call to DnsQueryEx and pQueryContext is valid until the
/// DNS_QUERY_COMPLETION_ROUTINE DNS callback is invoked.
///
///
/// Note Applications are notified of asynchronous DnsQueryEx completion through the DNS_QUERY_COMPLETION_ROUTINE
/// callback within the same process context.
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsqueryex DNS_STATUS DnsQueryEx( PDNS_QUERY_REQUEST
// pQueryRequest, PDNS_QUERY_RESULT pQueryResults, PDNS_QUERY_CANCEL pCancelHandle );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "22664B9A-5010-42E7-880B-8D5B16A9F2DC")]
public static extern DNS_STATUS DnsQueryEx(in DNS_QUERY_REQUEST pQueryRequest, ref DNS_QUERY_RESULT pQueryResults, ref DNS_QUERY_CANCEL pCancelHandle);
/// The DnsRecordCompare function compares two DNS resource records (RR).
/// A pointer to a DNS_RECORD structure that contains the first DNS RR of the comparison pair.
/// A pointer to a DNS_RECORD structure that contains the second DNS RR of the comparison pair.
/// Returns TRUE if the compared records are equivalent, FALSE if they are not.
///
/// When comparing records, DNS RRs that are stored using different character encoding are treated by the DnsRecordCompare
/// function as different, even if the records are otherwise equivalent.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordcompare BOOL DnsRecordCompare( PDNS_RECORD pRecord1,
// PDNS_RECORD pRecord2 );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "c4449a23-d6d3-4f27-a963-a84144983e5e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DnsRecordCompare(in DNS_RECORD pRecord1, in DNS_RECORD pRecord2);
/// The DnsRecordCompare function compares two DNS resource records (RR).
/// A pointer to a DNS_RECORD structure that contains the first DNS RR of the comparison pair.
/// A pointer to a DNS_RECORD structure that contains the second DNS RR of the comparison pair.
/// Returns TRUE if the compared records are equivalent, FALSE if they are not.
///
/// When comparing records, DNS RRs that are stored using different character encoding are treated by the DnsRecordCompare
/// function as different, even if the records are otherwise equivalent.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordcompare BOOL DnsRecordCompare( PDNS_RECORD pRecord1,
// PDNS_RECORD pRecord2 );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "c4449a23-d6d3-4f27-a963-a84144983e5e")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DnsRecordCompare([In] IntPtr pRecord1, [In] IntPtr pRecord2);
///
/// The DnsRecordCopyEx function creates a copy of a specified resource record (RR). The DnsRecordCopyEx function is
/// also capable of converting the character encoding during the copy operation.
///
/// A pointer to a DNS_RECORD structure that contains the RR to be copied.
/// A DNS_CHARSET value that specifies the character encoding of the source RR.
/// A DNS_CHARSET value that specifies the character encoding required of the destination record.
/// Successful execution returns a pointer to the (newly created) destination record. Otherwise, returns null.
/// The CharSetIn parameter is used only if the character encoding of the source RR is not specified in pRecord.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordcopyex PDNS_RECORD DnsRecordCopyEx( PDNS_RECORD
// pRecord, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "b5a74799-75fc-4489-9efa-c15b2def2ae7")]
public static extern IntPtr DnsRecordCopyEx(in DNS_RECORD pRecord, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut);
///
/// The DnsRecordCopyEx function creates a copy of a specified resource record (RR). The DnsRecordCopyEx function is
/// also capable of converting the character encoding during the copy operation.
///
/// A pointer to a DNS_RECORD structure that contains the RR to be copied.
/// A DNS_CHARSET value that specifies the character encoding of the source RR.
/// A DNS_CHARSET value that specifies the character encoding required of the destination record.
/// Successful execution returns a pointer to the (newly created) destination record. Otherwise, returns null.
/// The CharSetIn parameter is used only if the character encoding of the source RR is not specified in pRecord.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordcopyex PDNS_RECORD DnsRecordCopyEx( PDNS_RECORD
// pRecord, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "b5a74799-75fc-4489-9efa-c15b2def2ae7")]
public static extern IntPtr DnsRecordCopyEx([In] IntPtr pRecord, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut);
/// The DnsRecordListFree function frees memory allocated for DNS records obtained using the DnsQuery function.
/// A pointer to a DNS_RECORD structure that contains the list of DNS records to be freed.
///
/// A specifier of how the record list should be freed. The only type currently supported is a deep freeing of the entire record
/// list. For more information and a list of values, see the DNS_FREE_TYPE enumeration.
///
/// None
///
/// The DnsRecordListFree function can be used to free memory allocated from query results obtained using a DnsQuery function
/// call; it cannot free memory allocated for DNS record lists created manually.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordlistfree void DnsRecordListFree( p, t );
[PInvokeData("windns.h", MSDNShortId = "fc4c0cb4-646f-4946-8f07-b5a858f7064a")]
public static void DnsRecordListFree(IntPtr p, DNS_FREE_TYPE t = DNS_FREE_TYPE.DnsFreeRecordList) => DnsFree(p, t);
/// The DnsRecordSetCompare function compares two RR sets.
/// A pointer to a DNS_RECORD structure that contains the first DNS RR set of the comparison pair.
/// A pointer to a DNS_RECORD structure that contains the second DNS resource record set of the comparison pair.
///
/// A pointer to a DNS_RECORD pointer that contains the list of resource records built as a result of the arithmetic performed on
/// them: pRRSet1 minus pRRSet2.
///
///
/// A pointer to a DNS_RECORD pointer that contains the list of resource records built as a result of the arithmetic performed on
/// them: pRRSet2 minus pRRSet1.
///
/// Returns TRUE if the compared record sets are equivalent, FALSE if they are not.
///
/// When comparing record sets, DNS resource records that are stored using different character encoding are treated by the
/// DnsRecordSetCompare function as equivalent. Contrast this to the DnsRecordCompare function, in which equivalent records
/// with different encoding are not returned as equivalent records.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordsetcompare BOOL DnsRecordSetCompare( PDNS_RECORD
// pRR1, PDNS_RECORD pRR2, PDNS_RECORD *ppDiff1, PDNS_RECORD *ppDiff2 );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "008cf2ba-ccb2-430a-85d9-68d424b6938f")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DnsRecordSetCompare(in DNS_RECORD pRR1, in DNS_RECORD pRR2, out IntPtr ppDiff1, out IntPtr ppDiff2);
/// The DnsRecordSetCompare function compares two RR sets.
/// A pointer to a DNS_RECORD structure that contains the first DNS RR set of the comparison pair.
/// A pointer to a DNS_RECORD structure that contains the second DNS resource record set of the comparison pair.
///
/// A pointer to a DNS_RECORD pointer that contains the list of resource records built as a result of the arithmetic performed on
/// them: pRRSet1 minus pRRSet2.
///
///
/// A pointer to a DNS_RECORD pointer that contains the list of resource records built as a result of the arithmetic performed on
/// them: pRRSet2 minus pRRSet1.
///
/// Returns TRUE if the compared record sets are equivalent, FALSE if they are not.
///
/// When comparing record sets, DNS resource records that are stored using different character encoding are treated by the
/// DnsRecordSetCompare function as equivalent. Contrast this to the DnsRecordCompare function, in which equivalent records
/// with different encoding are not returned as equivalent records.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordsetcompare BOOL DnsRecordSetCompare( PDNS_RECORD
// pRR1, PDNS_RECORD pRR2, PDNS_RECORD *ppDiff1, PDNS_RECORD *ppDiff2 );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "008cf2ba-ccb2-430a-85d9-68d424b6938f")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DnsRecordSetCompare([In] IntPtr pRR1, [In] IntPtr pRR2, out IntPtr ppDiff1, out IntPtr ppDiff2);
///
/// The DnsRecordSetCopyEx function creates a copy of a specified resource record set. The DnsRecordSetCopyEx function
/// is also capable of converting the character encoding during the copy operation.
///
/// A pointer to a DNS_RECORD structure that contains the resource record set to be copied.
/// A DNS_CHARSET value that specifies the character encoding of the source resource record set.
/// A DNS_CHARSET value that specifies the character encoding required of the destination record set.
/// Successful execution returns a pointer to the newly created destination record set. Otherwise, it returns null.
///
/// The CharSetIn parameter is used only if the character encoding of the source resource record set is not specified in pRecordSet.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordsetcopyex PDNS_RECORD DnsRecordSetCopyEx(
// PDNS_RECORD pRecordSet, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "bdf9d6b4-b9d7-4886-8ea6-1e1f4dbcc99a")]
public static extern IntPtr DnsRecordSetCopyEx(in DNS_RECORD pRecordSet, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut);
///
/// The DnsRecordSetCopyEx function creates a copy of a specified resource record set. The DnsRecordSetCopyEx function
/// is also capable of converting the character encoding during the copy operation.
///
/// A pointer to a DNS_RECORD structure that contains the resource record set to be copied.
/// A DNS_CHARSET value that specifies the character encoding of the source resource record set.
/// A DNS_CHARSET value that specifies the character encoding required of the destination record set.
/// Successful execution returns a pointer to the newly created destination record set. Otherwise, it returns null.
///
/// The CharSetIn parameter is used only if the character encoding of the source resource record set is not specified in pRecordSet.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordsetcopyex PDNS_RECORD DnsRecordSetCopyEx(
// PDNS_RECORD pRecordSet, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "bdf9d6b4-b9d7-4886-8ea6-1e1f4dbcc99a")]
public static extern IntPtr DnsRecordSetCopyEx([In] IntPtr pRecordSet, DNS_CHARSET CharSetIn, DNS_CHARSET CharSetOut);
/// The DnsRecordSetDetach function detaches the first record set from a specified list of DNS records.
///
/// A pointer, on input, to a DNS_RECORD structure that contains the list prior to the detachment of the first DNS record in the
/// list of DNS records. A pointer, on output to a DNS_RECORD structure that contains the list subsequent to the detachment
/// of the DNS record.
///
/// On return, the DnsRecordSetDetach function points to the detached DNS record set.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordsetdetach PDNS_RECORD DnsRecordSetDetach(
// PDNS_RECORD pRecordList );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "434dc11f-19a9-434f-a024-9cdbb560f24c")]
public static extern IntPtr DnsRecordSetDetach(in DNS_RECORD pRecordList);
/// The DnsRecordSetDetach function detaches the first record set from a specified list of DNS records.
///
/// A pointer, on input, to a DNS_RECORD structure that contains the list prior to the detachment of the first DNS record in the
/// list of DNS records. A pointer, on output to a DNS_RECORD structure that contains the list subsequent to the detachment
/// of the DNS record.
///
/// On return, the DnsRecordSetDetach function points to the detached DNS record set.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsrecordsetdetach PDNS_RECORD DnsRecordSetDetach(
// PDNS_RECORD pRecordList );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "434dc11f-19a9-434f-a024-9cdbb560f24c")]
public static extern IntPtr DnsRecordSetDetach([In] IntPtr pRecordList);
/// The DnsReleaseContextHandle function releases memory used to store the credentials of a specific account.
/// The credentials handle of a specific account.
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsreleasecontexthandle void DnsReleaseContextHandle( HANDLE
// hContext );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "08a5fa73-4583-4e87-bddb-09bfbfe1b36f")]
public static extern void DnsReleaseContextHandle(HDNSCONTEXT hContext);
/// The DnsReplaceRecordSet function type replaces an existing resource record (RR) set.
///
/// A pointer to a DNS_RECORD structure that contains the RR set that replaces the existing set. The specified RR set is replaced
/// with the contents of pNewSet. To delete a RR set, specify the set in pNewSet, but set RDATA to NULL.
///
///
/// A value that contains a bitmap of DNS Update Options. Options can be combined and all options override DNS_UPDATE_SECURITY_USE_DEFAULT.
///
///
/// The handle to the credentials of a specific account. Used when secure dynamic update is required. This parameter is optional.
///
/// This parameter is reserved for future use and must be set to NULL.
/// This parameter is reserved for future use and must be set to NULL.
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsreplacerecordseta DNS_STATUS DnsReplaceRecordSetA(
// PDNS_RECORD pReplaceSet, DWORD Options, HANDLE hContext, PVOID pExtraInfo, PVOID pReserved );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsReplaceRecordSetW", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "7b99f440-72fa-4cf4-9267-98f436e99a50")]
public static extern DNS_STATUS DnsReplaceRecordSet(in DNS_RECORD pReplaceSet, DNS_UPDATE Options, [Optional] HDNSCONTEXT hContext, IntPtr pExtraInfo = default, IntPtr pReserved = default);
/// The DnsReplaceRecordSet function type replaces an existing resource record (RR) set.
///
/// A pointer to a DNS_RECORD structure that contains the RR set that replaces the existing set. The specified RR set is replaced
/// with the contents of pNewSet. To delete a RR set, specify the set in pNewSet, but set RDATA to NULL.
///
///
/// A value that contains a bitmap of DNS Update Options. Options can be combined and all options override DNS_UPDATE_SECURITY_USE_DEFAULT.
///
///
/// The handle to the credentials of a specific account. Used when secure dynamic update is required. This parameter is optional.
///
/// This parameter is reserved for future use and must be set to NULL.
/// This parameter is reserved for future use and must be set to NULL.
///
/// Returns success confirmation upon successful completion. Otherwise, returns the appropriate DNS-specific error code as defined
/// in Winerror.h.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsreplacerecordseta DNS_STATUS DnsReplaceRecordSetA(
// PDNS_RECORD pReplaceSet, DWORD Options, HANDLE hContext, PVOID pExtraInfo, PVOID pReserved );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsReplaceRecordSetW", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "7b99f440-72fa-4cf4-9267-98f436e99a50")]
public static extern DNS_STATUS DnsReplaceRecordSet([In] IntPtr pReplaceSet, DNS_UPDATE Options, [Optional] HDNSCONTEXT hContext, IntPtr pExtraInfo = default, IntPtr pReserved = default);
/// Used to initiate a DNS-SD discovery for services running on the local network.
/// A pointer to a DNS_SERVICE_BROWSE_REQUEST structure that contains the browse request information.
///
/// A pointer to a DNS_SERVICE_CANCEL structure that can be used to cancel a pending asynchronous browsing operation. This handle
/// must remain valid until the query is canceled.
///
///
/// If successful, returns DNS_REQUEST_PENDING; otherwise, returns the appropriate DNS-specific error code as defined in .
/// For extended error information, call GetLastError.
///
/// This function is asynchronous. As services are being discovered, the browse callback will be invoked for each result.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsservicebrowse DNS_STATUS DnsServiceBrowse(
// PDNS_SERVICE_BROWSE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsServiceBrowse(in DNS_SERVICE_BROWSE_REQUEST pRequest, out DNS_SERVICE_CANCEL pCancel);
/// Used to cancel a running DNS-SD discovery query.
///
/// A pointer to the DNS_SERVICE_CANCEL structure that was passed to the DnsServiceBrowse call that is to be cancelled.
///
///
/// If successful, returns ERROR_SUCCESS; otherwise, returns the appropriate DNS-specific error code as defined in . For
/// extended error information, call GetLastError.
///
/// Canceling the query causes one further invocation of the browse callback, with status ERROR_CANCELLED.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsservicebrowsecancel DNS_STATUS DnsServiceBrowseCancel(
// PDNS_SERVICE_CANCEL pCancelHandle );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsServiceBrowseCancel(in DNS_SERVICE_CANCEL pCancelHandle);
/// Used to build a DNS_SERVICE_INSTANCE structure from data that describes it.
/// A string that represents the name of the service.
/// A string that represents the name of the host of the service.
/// A pointer to an IP4_ADDRESS structure that represents the service-associated IPv4 address.
/// A pointer to an IP6_ADDRESS structure that represents the service-associated IPv6 address.
/// A value that represents the port on which the service is running.
/// A value that represents the service priority.
/// A value that represents the service weight.
/// The number of properties—defines the number of elements in the arrays of the and parameters.
/// A pointer to an array of string values that represent the property keys.
/// A pointer to an array of string values that represent the corresponding property values.
///
/// A pointer to a newly allocated DNS_SERVICE_INSTANCE structure, built from the passed-in parameters. Your application is
/// responsible for freeing the associated memory by calling DnsServiceFreeInstance.
///
/// The dwInterfaceIndex field of the returned structure is set to 0.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsserviceconstructinstance PDNS_SERVICE_INSTANCE
// DnsServiceConstructInstance( PCWSTR pServiceName, PCWSTR pHostName, PIP4_ADDRESS pIp4, PIP6_ADDRESS pIp6, WORD wPort, WORD
// wPriority, WORD wWeight, DWORD dwPropertiesCount, PCWSTR *keys, PCWSTR *values );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern SafePDNS_SERVICE_INSTANCE DnsServiceConstructInstance([MarshalAs(UnmanagedType.LPWStr)] string pServiceName,
[MarshalAs(UnmanagedType.LPWStr)] string pHostName, in IP4_ADDRESS pIp4, in IP6_ADDRESS pIp6, ushort wPort, ushort wPriority,
ushort wWeight, uint dwPropertiesCount, [In, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] keys,
[In, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] values);
/// Used to build a DNS_SERVICE_INSTANCE structure from data that describes it.
/// A string that represents the name of the service.
/// A string that represents the name of the host of the service.
/// A pointer to an IP4_ADDRESS structure that represents the service-associated IPv4 address.
/// A pointer to an IP6_ADDRESS structure that represents the service-associated IPv6 address.
/// A value that represents the port on which the service is running.
/// A value that represents the service priority.
/// A value that represents the service weight.
/// The number of properties—defines the number of elements in the arrays of the and parameters.
/// A pointer to an array of string values that represent the property keys.
/// A pointer to an array of string values that represent the corresponding property values.
///
/// A pointer to a newly allocated DNS_SERVICE_INSTANCE structure, built from the passed-in parameters. Your application is
/// responsible for freeing the associated memory by calling DnsServiceFreeInstance.
///
/// The dwInterfaceIndex field of the returned structure is set to 0.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsserviceconstructinstance PDNS_SERVICE_INSTANCE
// DnsServiceConstructInstance( PCWSTR pServiceName, PCWSTR pHostName, PIP4_ADDRESS pIp4, PIP6_ADDRESS pIp6, WORD wPort, WORD
// wPriority, WORD wWeight, DWORD dwPropertiesCount, PCWSTR *keys, PCWSTR *values );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern SafePDNS_SERVICE_INSTANCE DnsServiceConstructInstance([MarshalAs(UnmanagedType.LPWStr)] string pServiceName,
[MarshalAs(UnmanagedType.LPWStr)] string pHostName, [In, Optional] IntPtr pIp4, [In, Optional] IntPtr pIp6, ushort wPort, ushort wPriority,
ushort wWeight, uint dwPropertiesCount, [In, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] keys,
[In, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] string[] values);
/// Used to copy a DNS_SERVICE_INSTANCE structure.
/// A pointer to the DNS_SERVICE_INSTANCE structure that is to be copied.
///
/// A pointer to a newly allocated DNS_SERVICE_INSTANCE structure that's a copy of . Your application is responsible for freeing the
/// associated memory by calling DnsServiceFreeInstance.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsservicecopyinstance PDNS_SERVICE_INSTANCE
// DnsServiceCopyInstance( PDNS_SERVICE_INSTANCE pOrig );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern SafePDNS_SERVICE_INSTANCE DnsServiceCopyInstance(SafePDNS_SERVICE_INSTANCE pOrig);
/// Used to remove a registered service.
/// A pointer to the DNS_SERVICE_REGISTER_REQUEST structure that was used to register the service.
/// Must be .
///
/// If successful, returns DNS_REQUEST_PENDING; otherwise, returns the appropriate DNS-specific error code as defined in
/// Winerror.h. For extended error information, call GetLastError.
///
///
/// This function is asynchronous. The callback will be invoked when the deregistration is completed, with a copy of the
/// DNS_SERVICE_INSTANCE structure that was passed to DnsServiceRegister when the service was registered.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsservicederegister DWORD DnsServiceDeRegister(
// PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsServiceDeRegister(in DNS_SERVICE_REGISTER_REQUEST pRequest, in DNS_SERVICE_CANCEL pCancel);
/// Used to free the resources associated with a DNS_SERVICE_INSTANCE structure.
/// A pointer to the DNS_SERVICE_INSTANCE structure that is to be freed.
/// None
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsservicefreeinstance void DnsServiceFreeInstance(
// PDNS_SERVICE_INSTANCE pInstance );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern void DnsServiceFreeInstance(IntPtr pInstance);
/// Used to register a discoverable service on this device.
///
/// A pointer to a DNS_SERVICE_REGISTER_REQUEST structure that contains information about the service to be registered.
///
///
/// An optional (it can be ) pointer to a DNS_SERVICE_CANCEL structure that can be used to cancel a pending asynchronous
/// registration operation. If not , then this handle must remain valid until the registration is canceled.
///
///
/// If successful, returns DNS_REQUEST_PENDING; otherwise, returns the appropriate DNS-specific error code as defined in .
/// For extended error information, call GetLastError.
///
///
/// This function is asynchronous. The registration callback will be called once the registration succeeds. To deregister the
/// service, call DnsServiceDeRegister. The registration is tied to the lifetime of the calling process. If the process goes away,
/// the service will be automatically deregistered.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsserviceregister DWORD DnsServiceRegister(
// PDNS_SERVICE_REGISTER_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsServiceRegister(in DNS_SERVICE_REGISTER_REQUEST pRequest, out DNS_SERVICE_CANCEL pCancel);
/// Used to cancel a pending registration operation.
///
/// A pointer to the DNS_SERVICE_CANCEL structure that was passed to the DnsServiceRegister call that is to be cancelled.
///
///
/// If successful, returns ERROR_SUCCESS. Returns ERROR_CANCELLED if the operation was already cancelled, or
/// ERROR_INVALID_PARAMETER if the handle is invalid.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsserviceregistercancel DWORD DnsServiceRegisterCancel(
// PDNS_SERVICE_CANCEL pCancelHandle );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsServiceRegisterCancel(in DNS_SERVICE_CANCEL pCancelHandle);
/// Used to obtain more information about a service advertised on the local network.
/// A pointer to a DNS_SERVICE_RESOLVE_REQUEST structure that contains the resolve request information.
///
/// A pointer to a DNS_SERVICE_CANCEL structure that can be used to cancel a pending asynchronous resolve operation. This handle
/// must remain valid until the query is canceled.
///
///
/// If successful, returns DNS_REQUEST_PENDING; otherwise, returns the appropriate DNS-specific error code as defined in .
/// For extended error information, call GetLastError.
///
///
/// This function is asynchronous. Upon completion, the resolve callback will be invoked for each result. In contrast to
/// DnsServiceBrowse—which returns the service name as a minimum— DnsServiceResolve can be used to retrieve additional
/// information, such as hostname, IP address, and TEXT records.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsserviceresolve DNS_STATUS DnsServiceResolve(
// PDNS_SERVICE_RESOLVE_REQUEST pRequest, PDNS_SERVICE_CANCEL pCancel );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsServiceResolve(in DNS_SERVICE_RESOLVE_REQUEST pRequest, out DNS_SERVICE_CANCEL pCancel);
/// Used to cancel a running DNS-SD resolve query.
///
/// A pointer to the DNS_SERVICE_CANCEL structure that was passed to the DnsServiceResolve call that is to be cancelled.
///
///
/// If successful, returns ERROR_SUCCESS; otherwise, returns the appropriate DNS-specific error code as defined in . For
/// extended error information, call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsserviceresolvecancel DNS_STATUS DnsServiceResolveCancel(
// PDNS_SERVICE_CANCEL pCancelHandle );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsServiceResolveCancel(in DNS_SERVICE_CANCEL pCancelHandle);
///
/// Configures per-application DNS settings. This includes the ability to set per-application DNS servers either as fallback to the
/// system configured servers, or exclusively.
///
///
/// Type: _In_ DWORD
/// The number of custom DNS servers present in the pServers parameter.
///
///
/// Type: _In_reads_(cServers) DNS_CUSTOM_SERVER*
/// An array of DNS_CUSTOM_SERVER that contains cServers elements. If cServers is 0, then this must be NULL.
///
///
/// Type: _In_opt_ DNS_APPLICATION_SETTINGS*
/// A pointer to a DNS_APPLICATION_SETTINGS object describing additional settings for custom DNS servers.
///
/// If this is NULL, then the custom DNS servers passed to the API will be used as fallback to the system-configured ones.
///
///
/// If this points to a DNS_APPLICATION_SETTINGS object that has the DNS_APP_SETTINGS_EXCLUSIVE_SERVERS flag set in its Flags
/// member, then it means use the custom DNS servers exclusively.
///
///
/// A DWORD containing ERROR_SUCCESS on success, or an error code on failure.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnssetapplicationsettings
// DWORD DnsSetApplicationSettings( DWORD cServers, const DNS_CUSTOM_SERVER *pServers, const DNS_APPLICATION_SETTINGS *pSettings );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "NF:windns.DnsSetApplicationSettings", MinClient = PInvokeClient.Windows11)]
public static extern Win32Error DnsSetApplicationSettings(uint cServers,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] DNS_CUSTOM_SERVER[] pServers, in DNS_APPLICATION_SETTINGS pSettings);
///
/// Configures per-application DNS settings. This includes the ability to set per-application DNS servers either as fallback to the
/// system configured servers, or exclusively.
///
///
/// Type: _In_ DWORD
/// The number of custom DNS servers present in the pServers parameter.
///
///
/// Type: _In_reads_(cServers) DNS_CUSTOM_SERVER*
/// An array of DNS_CUSTOM_SERVER that contains cServers elements. If cServers is 0, then this must be NULL.
///
///
/// Type: _In_opt_ DNS_APPLICATION_SETTINGS*
/// A pointer to a DNS_APPLICATION_SETTINGS object describing additional settings for custom DNS servers.
///
/// If this is NULL, then the custom DNS servers passed to the API will be used as fallback to the system-configured ones.
///
///
/// If this points to a DNS_APPLICATION_SETTINGS object that has the DNS_APP_SETTINGS_EXCLUSIVE_SERVERS flag set in its Flags
/// member, then it means use the custom DNS servers exclusively.
///
///
/// A DWORD containing ERROR_SUCCESS on success, or an error code on failure.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnssetapplicationsettings
// DWORD DnsSetApplicationSettings( DWORD cServers, const DNS_CUSTOM_SERVER *pServers, const DNS_APPLICATION_SETTINGS *pSettings );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "NF:windns.DnsSetApplicationSettings", MinClient = PInvokeClient.Windows11)]
public static extern Win32Error DnsSetApplicationSettings(uint cServers,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] DNS_CUSTOM_SERVER[] pServers, [In, Optional] IntPtr pSettings);
/// Used to register a discoverable service on this device.
/// A pointer to an MDNS_QUERY_REQUEST structure that contains information about the query to be performed.
///
/// A pointer to an MDNS_QUERY_HANDLE structure that will be populated with the necessary data. This structure is to be passed later
/// to DnsStopMulticastQuery to stop the query.
///
///
/// If successful, returns ERROR_SUCCESS; otherwise, returns the appropriate DNS-specific error code as defined in . For
/// extended error information, call GetLastError.
///
///
/// This function is asynchronous. The query runs indefinitely, until DnsStopMulticastQuery is called. For each response from the
/// network, the query callback will be invoked with the appropriate status and results.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsstartmulticastquery DNS_STATUS DnsStartMulticastQuery(
// PMDNS_QUERY_REQUEST pQueryRequest, PMDNS_QUERY_HANDLE pHandle );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsStartMulticastQuery(in MDNS_QUERY_REQUEST pQueryRequest, out MDNS_QUERY_HANDLE pHandle);
/// Used to stop a running DnsStartMulticastQuery operation.
///
/// A pointer to the MDNS_QUERY_HANDLE structure that was passed to the DnsStartMulticastQuery call that is to be stopped.
///
///
/// If successful, returns ERROR_SUCCESS; otherwise, returns the appropriate DNS-specific error code as defined in . For
/// extended error information, call GetLastError.
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsstopmulticastquery DNS_STATUS DnsStopMulticastQuery(
// PMDNS_QUERY_HANDLE pHandle );
[DllImport(Lib.Dnsapi, SetLastError = true, ExactSpelling = true)]
[PInvokeData("windns.h")]
public static extern DNS_STATUS DnsStopMulticastQuery(in MDNS_QUERY_HANDLE pHandle);
/// The DnsValidateName function validates the status of a specified DNS name.
///
///
/// The DnsValidateName function has the following possible return values:
///
///
/// To verify the status of the Computer Host (single label), use the DnsValidateName function type with
/// DnsNameHostnameLabel in Format.
///
///
/// The DnsValidateName function works in a progression when determining whether an error exists with a given DNS name, and
/// returns upon finding its first error. Therefore, a DNS name that has multiple, different errors may be reported as having the
/// first error, and could be corrected and resubmitted, only then to find the second error.
///
/// The DnsValidateName function searches for errors as follows:
///
/// -
/// Returns ERROR_INVALID_NAME if the DNS name:
///
/// -
///
/// Next, DnsValidateName returns DNS_ERROR_NUMERIC_NAME if the full DNS name consists of only numeric characters
/// (0-9) or the first label of the DNS name consists of only numeric characters (0-9), unless Format is set to DnsNameDomainLabel
/// or DnsNameDomain.
///
///
/// -
/// Then, DnsValidateName returns DNS_ERROR_NON_RFC_NAME if the DNS name:
///
/// -
/// Next, DnsValidateName returns DNS_ERROR_INVALID_NAME_CHAR if the DNS name:
///
///
///
/// Note If DnsValidateName returns DNS_ERROR_NON_RFC_NAME, the error should be handled as a warning that not
/// all DNS servers will accept the name. When this error is received, note that the DNS Server does accept the submitted name, if
/// appropriately configured (default configuration accepts the name as submitted when DNS_ERROR_NON_RFC_NAME is returned),
/// but other DNS server software may not. Windows DNS servers do handle NON_RFC_NAMES.If DnsValidateName returns any
/// of the following errors, pszName should be handled as an invalid host name:
///
///
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsvalidatename_w DNS_STATUS DnsValidateName_W( PCWSTR
// pszName, DNS_NAME_FORMAT Format );
[DllImport(Lib.Dnsapi, SetLastError = false, EntryPoint = "DnsValidateName_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "efdbd217-6936-42c1-a1eb-8655a62513ee")]
public static extern DNS_STATUS DnsValidateName([MarshalAs(UnmanagedType.LPWStr)] string pszName, DNS_NAME_FORMAT Format);
/// The DnsValidateServerStatus function validates an IP address as a suitable DNS server.
/// A pointer to a SOCKADDR that contains the DNS server IPv4 or IPv6 address to be examined.
///
/// A pointer to a Unicode string that represents the fully qualified domain name (FQDN) of the owner of the record set that is queried.
///
///
/// A pointer to a DWORD that represents the query validation status.
///
///
/// Value
/// Meaning
///
/// -
/// ERROR_SUCCESS
/// No errors. The call was successful.
///
/// -
/// DNS_VALSVR_ERROR_INVALID_ADDR
/// server IP address was invalid.
///
/// -
/// DNS_VALSVR_ERROR_INVALID_NAME
/// queryName FQDN was invalid.
///
/// -
/// DNS_VALSVR_ERROR_UNREACHABLE
/// DNS server was unreachable.
///
/// -
/// DNS_VALSVR_ERROR_NO_RESPONSE
/// Timeout waiting for the DNS server response.
///
/// -
/// DNS_VALSVR_ERROR_NO_AUTH
/// DNS server was not authoritative or queryName was not found.
///
/// -
/// DNS_VALSVR_ERROR_REFUSED
/// DNS server refused the query.
///
/// -
/// DNS_VALSVR_ERROR_NO_TCP
///
/// The TCP query did not return ERROR_SUCCESS after the validation system had already completed a successful query to the DNS
/// server using UDP.
///
///
/// -
/// DNS_VALSVR_ERROR_UNKNOWN
/// An unknown error occurred.
///
///
///
/// The DnsValidateServerStatus function has the following possible return values:
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnsvalidateserverstatus DNS_STATUS DnsValidateServerStatus(
// PSOCKADDR server, PCWSTR queryName, PDWORD serverStatus );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "5b362d05-87b2-44dd-8198-bcb5ab5a64f6")]
public static extern DNS_STATUS DnsValidateServerStatus([In] SOCKADDR server, [Optional, MarshalAs(UnmanagedType.LPWStr)] string queryName, out DnsServerStatus serverStatus);
///
/// The DnsWriteQuestionToBuffer function type creates a DNS query message and stores it in a DNS_MESSAGE_BUFFER structure.
///
/// A pointer to a DNS_MESSAGE_BUFFER structure that contains a DNS query message stored in a buffer.
///
/// The size, in bytes, of the buffer allocated to store pDnsBuffer. If the buffer size is insufficient to contain the message,
/// FALSE is returned and pdwBufferSize contains the minimum required buffer size.
///
/// A pointer to a string that represents the name of the owner of the record set being queried.
///
/// A value that represents the RR DNS Record Type. wType determines the format of Data. For example, if the value of
/// wType is DNS_TYPE_A, the data type of Data is DNS_A_DATA.
///
/// A value that specifies the unique DNS query identifier.
///
/// A BOOL that specifies whether recursive name query should be used by the DNS name server. Set to TRUE to request
/// recursive name query, FALSE to request iterative name query.
///
/// Returns TRUE upon successful execution, otherwise FALSE.
// https://docs.microsoft.com/en-us/windows/win32/api/windns/nf-windns-dnswritequestiontobuffer_w BOOL DnsWriteQuestionToBuffer_W(
// PDNS_MESSAGE_BUFFER pDnsBuffer, PDWORD pdwBufferSize, PCWSTR pszName, WORD wType, WORD Xid, BOOL fRecursionDesired );
[DllImport(Lib.Dnsapi, SetLastError = true, EntryPoint = "DnsWriteQuestionToBuffer_W", CharSet = CharSet.Unicode)]
[PInvokeData("windns.h", MSDNShortId = "9aa853aa-d9b5-41e3-a82a-c25de199924d")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DnsWriteQuestionToBuffer([In, Out] IntPtr pDnsBuffer, ref uint pdwBufferSize, [MarshalAs(UnmanagedType.LPWStr)] string pszName,
DNS_TYPE wType, ushort Xid, [MarshalAs(UnmanagedType.Bool)] bool fRecursionDesired);
/// Provides a handle to a DNS Context.
[StructLayout(LayoutKind.Sequential)]
public struct HDNSCONTEXT : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public HDNSCONTEXT(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static HDNSCONTEXT NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(HDNSCONTEXT h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator HDNSCONTEXT(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(HDNSCONTEXT h1, HDNSCONTEXT h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(HDNSCONTEXT h1, HDNSCONTEXT h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is HDNSCONTEXT h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// Provides a for a list of allocated DNS_CACHE_ENTRY values that is disposed using .
public class SafeDnsCacheDataTable : SafeHANDLE, IEnumerable
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
public SafeDnsCacheDataTable(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeDnsCacheDataTable() : base() { }
/// Returns an enumerator that iterates through the collection.
/// A that can be used to iterate through the collection.
public IEnumerator GetEnumerator() => handle.LinkedListToIEnum(r => r.pNext).GetEnumerator();
/// Returns an enumerator that iterates through a collection.
/// An object that can be used to iterate through the collection.
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
///
protected override bool InternalReleaseHandle()
{
// From https://stackoverflow.com/questions/31889957/memory-leak-when-using-dnsgetcachedatatable
var p = handle;
while (p != IntPtr.Zero)
{
var s = p.ToStructure();
DnsFree((IntPtr)s.pszName, DNS_FREE_TYPE.DnsFreeFlat);
DnsFree(p, DNS_FREE_TYPE.DnsFreeFlat);
p = s.pNext;
}
return true;
}
}
/// Provides a for a DNS record list that is disposed using .
public class SafeDnsRecordList : SafeHANDLE, IEnumerable
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeDnsRecordList(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeDnsRecordList() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator IntPtr(SafeDnsRecordList h) => h.handle;
/// Returns an enumerator that iterates through the collection.
/// A that can be used to iterate through the collection.
///
public IEnumerator GetEnumerator() => handle.LinkedListToIEnum(r => r.pNext).GetEnumerator();
/// Gets a sequence of pointers to each of the records.
/// Record pointers.
public IEnumerable GetRecordPointers()
{
var p = handle;
while (p != IntPtr.Zero)
{
yield return p;
p = p.ToStructure().pNext;
}
}
/// Returns an enumerator that iterates through a collection.
/// An object that can be used to iterate through the collection.
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
///
protected override bool InternalReleaseHandle() { DnsRecordListFree(handle); return true; }
}
/// Provides a for that is disposed using .
public class SafeHDNSCONTEXT : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
///
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
///
public SafeHDNSCONTEXT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeHDNSCONTEXT() : base() { }
/// Performs an explicit conversion from to .
/// The safe handle instance.
/// The resulting instance from the conversion.
public static explicit operator IntPtr(SafeHDNSCONTEXT h) => h.handle;
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator HDNSCONTEXT(SafeHDNSCONTEXT h) => h.handle;
///
protected override bool InternalReleaseHandle() { DnsReleaseContextHandle(handle); return true; }
}
internal class DnsProxyStringMem : ISimpleMemoryMethods
{
private bool self = false;
/// Gets a handle to a memory allocation of the specified size.
/// The size, in bytes, of memory to allocate.
/// A memory handle.
public IntPtr AllocMem(int size) { self = true; return Marshal.AllocCoTaskMem(size); }
/// Frees the memory associated with a handle.
/// A memory handle.
public void FreeMem(IntPtr hMem) { if (self) Marshal.FreeCoTaskMem(hMem); else DnsFreeProxyName(hMem); }
/// Locks the memory of a specified handle and gets a pointer to it.
/// A memory handle.
/// A pointer to the locked memory.
public IntPtr LockMem(IntPtr hMem) => hMem;
/// Unlocks the memory of a specified handle.
/// A memory handle.
public void UnlockMem(IntPtr hMem) { }
}
}
}