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 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_REQUEST3 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 value indicating whether this memory supports locking. /// if lockable; otherwise, . bool ISimpleMemoryMethods.Lockable => 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 bool UnlockMem(IntPtr hMem) => false; } } }