Skip to content

Commit

Permalink
Fixed problems with DNS struct alignment and added XML docs with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dahall committed Jun 28, 2020
1 parent 88856b5 commit 79c9061
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 58 deletions.
4 changes: 2 additions & 2 deletions PInvoke/DnsApi/WinDns.Funcs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public static void DNS_BYTE_FLIP_HEADER_COUNTS(ref DNS_MESSAGE_BUFFER mBuf)
// pCancelHandle );
[DllImport(Lib.Dnsapi, SetLastError = false, ExactSpelling = true)]
[PInvokeData("windns.h", MSDNShortId = "E5F422AA-D4E6-4F9F-A57C-608CE9317658")]
public static extern DNS_STATUS DnsCancelQuery(in DNS_QUERY_CANCEL pCancelHandle);
public static extern DNS_STATUS DnsCancelQuery(ref DNS_QUERY_CANCEL pCancelHandle);

/// <summary>
/// The <c>DnsExtractRecordsFromMessage</c> function type extracts resource records (RR) from a DNS message, and stores those
Expand Down Expand Up @@ -687,7 +687,7 @@ public static extern DNS_STATUS DnsQueryConfig(DNS_CONFIG_TYPE Config, DNS_CONFI
// 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, out DNS_QUERY_CANCEL pCancelHandle);
public static extern DNS_STATUS DnsQueryEx(in DNS_QUERY_REQUEST pQueryRequest, ref DNS_QUERY_RESULT pQueryResults, ref DNS_QUERY_CANCEL pCancelHandle);

/// <summary>The <c>DnsRecordCompare</c> function compares two DNS resource records (RR).</summary>
/// <param name="pRecord1">A pointer to a DNS_RECORD structure that contains the first DNS RR of the comparison pair.</param>
Expand Down
159 changes: 111 additions & 48 deletions PInvoke/DnsApi/WinDns.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,34 +129,39 @@ public enum DNS_CONFIG_TYPE
DnsConfigPrimaryDomainName_UTF8,

/// <summary>Not currently available.</summary>
// Unimplemented
DnsConfigAdapterDomainName_W,

/// <summary>Not currently available.</summary>
// Unimplemented
DnsConfigAdapterDomainName_A,

/// <summary>Not currently available.</summary>
// Unimplemented
DnsConfigAdapterDomainName_UTF8,

/// <summary>For configuring a DNS Server list on Windows 2000.</summary>
[CorrespondingType(typeof(IP4_ARRAY))]
DnsConfigDnsServerList,

/// <summary>Not currently available.</summary>
// Unimplemented
DnsConfigSearchList,

/// <summary>Not currently available.</summary>
// Unimplemented
DnsConfigAdapterInfo,

/// <summary>Specifies that primary host name registration is enabled on Windows 2000.</summary>
[CorrespondingType(typeof(uint))]
// Unimplemented [CorrespondingType(typeof(uint))]
DnsConfigPrimaryHostNameRegistrationEnabled,

/// <summary>Specifies that adapter host name registration is enabled on Windows 2000.</summary>
[CorrespondingType(typeof(uint))]
// Unimplemented [CorrespondingType(typeof(uint))]
DnsConfigAdapterHostNameRegistrationEnabled,

/// <summary>Specifies configuration of the maximum number of address registrations on Windows 2000.</summary>
[CorrespondingType(typeof(uint))]
// Unimplemented [CorrespondingType(typeof(uint))]
DnsConfigAddressRegistrationMaxCount,

/// <summary>
Expand Down Expand Up @@ -299,61 +304,105 @@ public enum DNS_PROXY_INFORMATION_TYPE
[Flags]
public enum DNS_QUERY_OPTIONS : uint
{
/// <summary/>
/// <summary>Standard query.</summary>
DNS_QUERY_STANDARD = 0x00000000,

/// <summary/>
/// <summary>Returns truncated results. Does not retry under TCP.</summary>
DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 0x00000001,

/// <summary/>
/// <summary>Uses TCP only for the query.</summary>
DNS_QUERY_USE_TCP_ONLY = 0x00000002,

/// <summary/>
/// <summary>
/// Directs the DNS server to perform an iterative query (specifically directs the DNS server not to perform recursive
/// resolution to resolve the query).
/// </summary>
DNS_QUERY_NO_RECURSION = 0x00000004,

/// <summary/>
/// <summary>Bypasses the resolver cache on the lookup.</summary>
DNS_QUERY_BYPASS_CACHE = 0x00000008,

/// <summary/>
/// <summary>
/// Directs DNS to perform a query on the local cache only.Windows 2000 Server and Windows 2000 Professional: This value is not
/// supported. For similar functionality, use DNS_QUERY_CACHE_ONLY.
/// </summary>
DNS_QUERY_NO_WIRE_QUERY = 0x00000010,

/// <summary/>
/// <summary>Directs DNS to ignore the local name.Windows 2000 Server and Windows 2000 Professional: This value is not supported.</summary>
DNS_QUERY_NO_LOCAL_NAME = 0x00000020,

/// <summary/>
/// <summary>
/// Prevents the DNS query from consulting the HOSTS file.Windows 2000 Server and Windows 2000 Professional: This value is not supported.
/// </summary>
DNS_QUERY_NO_HOSTS_FILE = 0x00000040,

/// <summary/>
/// <summary>
/// Prevents the DNS query from using NetBT for resolution.Windows 2000 Server and Windows 2000 Professional: This value is not supported.
/// </summary>
DNS_QUERY_NO_NETBT = 0x00000080,

/// <summary/>
/// <summary>
/// Directs DNS to perform a query using the network only, bypassing local information.Windows 2000 Server and Windows 2000
/// Professional: This value is not supported.
/// </summary>
DNS_QUERY_WIRE_ONLY = 0x00000100,

/// <summary/>
/// <summary>
/// Directs DNS to return the entire DNS response message.Windows 2000 Server and Windows 2000 Professional: This value is not supported.
/// </summary>
DNS_QUERY_RETURN_MESSAGE = 0x00000200,

/// <summary/>
/// <summary>
/// Prevents the query from using DNS and uses only Local Link Multicast Name Resolution (LLMNR).Windows Vista and Windows
/// Server 2008 or later.: This value is supported.
/// </summary>
DNS_QUERY_MULTICAST_ONLY = 0x00000400,

/// <summary/>
DNS_QUERY_NO_MULTICAST = 0x00000800,

/// <summary/>
/// <summary>Prevents the DNS response from attaching suffixes to the submitted name in a name resolution process.</summary>
DNS_QUERY_TREAT_AS_FQDN = 0x00001000,

/// <summary/>
/// <summary>
/// Windows 7 only: Do not send A type queries if IPv4 addresses are not available on an interface and do not send AAAA type
/// queries if IPv6 addresses are not available.
/// </summary>
DNS_QUERY_ADDRCONFIG = 0x00002000,

/// <summary/>
/// <summary>
/// Windows 7 only: Query both AAAA and A type records and return results for each. Results for A type records are mapped into
/// AAAA type.
/// </summary>
DNS_QUERY_DUAL_ADDR = 0x00004000,

/// <summary>Undocumented flag used by ipconfig to display DNS cache.</summary>
DNS_QUERY_LOCAL = 0x00008000,

/// <summary/>
/// <summary>
/// Waits for a full timeout to collect all the responses from the Local Link. If not set, the default behavior is to return
/// with the first response.Windows Vista and Windows Server 2008 or later.: This value is supported.
/// </summary>
DNS_QUERY_MULTICAST_WAIT = 0x00020000,

/// <summary>
/// Directs a test using the local machine hostname to verify name uniqueness on the same Local Link.Collects all responses even
/// if normal LLMNR Sender behavior is not enabled.Windows Vista and Windows Server 2008 or later.: This value is supported.
/// </summary>
DNS_QUERY_MULTICAST_VERIFY = 0x00040000,

/// <summary>
/// If set, and if the response contains multiple records, records are stored with the TTL corresponding to the minimum value
/// TTL from among all records. When this option is set, "Do not change the TTL of individual records" in the returned record
/// set is not modified.
/// </summary>
DNS_QUERY_DONT_RESET_TTL_VALUES = 0x00100000,

/// <summary/>
/// <summary>
/// Disables International Domain Name (IDN) encoding support in the DnsQuery, DnsQueryEx, DnsModifyRecordsInSet, and
/// DnsReplaceRecordSet APIs. All punycode names are treated as ASCII and will be ASCII encoded on the wire. All non-ASCII names
/// are encoded in UTF8 on the wire. Windows 8 or later.: This value is supported.
/// </summary>
DNS_QUERY_DISABLE_IDN_ENCODING = 0x00200000,

/// <summary/>
Expand All @@ -365,7 +414,7 @@ public enum DNS_QUERY_OPTIONS : uint
/// <summary/>
DNS_QUERY_DNSSEC_CHECKING_DISABLED = 0x02000000,

/// <summary/>
/// <summary>Reserved.</summary>
DNS_QUERY_RESERVED = 0xf0000000,
}

Expand Down Expand Up @@ -704,37 +753,42 @@ public enum DNS_TYPE : ushort
[Flags]
public enum DNS_UPDATE : uint
{
/// <summary/>
/// <summary>Uses the default behavior, which is specified in the registry, for secure dynamic DNS updates.</summary>
DNS_UPDATE_SECURITY_USE_DEFAULT = 0x00000000,

/// <summary/>
/// <summary>Does not attempt secure dynamic updates.</summary>
DNS_UPDATE_SECURITY_OFF = 0x00000010,

/// <summary/>
/// <summary>Attempts non-secure dynamic update; if refused, attempts secure dynamic update.</summary>
DNS_UPDATE_SECURITY_ON = 0x00000020,

/// <summary/>
/// <summary>Attempts secure dynamic updates only.</summary>
DNS_UPDATE_SECURITY_ONLY = 0x00000100,

/// <summary/>
/// <summary>Caches the security context for use in future transactions.</summary>
DNS_UPDATE_CACHE_SECURITY_CONTEXT = 0x00000200,

/// <summary/>
/// <summary>Uses credentials of the local computer account.</summary>
DNS_UPDATE_TEST_USE_LOCAL_SYS_ACCT = 0x00000400,

/// <summary/>
/// <summary>Does not use cached security context.</summary>
DNS_UPDATE_FORCE_SECURITY_NEGO = 0x00000800,

/// <summary/>
/// <summary>Sends DNS updates to all multi-master DNS servers.</summary>
DNS_UPDATE_TRY_ALL_MASTER_SERVERS = 0x00001000,

/// <summary/>
/// <summary>
/// Do not update adapters where dynamic DNS updates are disabled. Windows 2000 Server with SP2 or later.: This value is supported.
/// </summary>
DNS_UPDATE_SKIP_NO_UPDATE_ADAPTERS = 0x00002000,

/// <summary/>
/// <summary>
/// Register CNAME records on a remote server in addition to the local DNS server.Windows 2000 Server with SP2 or later.: This
/// value is supported.
/// </summary>
DNS_UPDATE_REMOTE_SERVER = 0x00004000,

/// <summary/>
/// <summary>Reserved for future use.</summary>
DNS_UPDATE_RESERVED = 0xffff0000,
}

Expand Down Expand Up @@ -1717,12 +1771,15 @@ public struct DNS_QUERY_REQUEST
/// </summary>
public DNS_TYPE QueryType;

// Hack to make this the right size even though the enum is a UInt32.
private ulong _QueryOptions;

/// <summary>
/// A value that contains a bitmap of DNS Query Options to use in the DNS query. Options can be combined and all options
/// override <c>DNS_QUERY_STANDARD</c>
/// </summary>
public DNS_QUERY_OPTIONS QueryOptions;
public DNS_QUERY_OPTIONS QueryOptions { get => (DNS_QUERY_OPTIONS)_QueryOptions; set => _QueryOptions = (ulong)value; }

/// <summary>Query options padding.</summary>
public uint QueryOptionsHigh;

Expand Down Expand Up @@ -1854,8 +1911,10 @@ public struct DNS_RECORD
/// <summary>Reserved. Do not use.</summary>
public uint dwReserved;

// The next entries are contrived so that the structure works on either 32 or 64 systems. The total size of the variable is 40 bytes on X86 and 56 on X64.
// The next entries are contrived so that the structure works on either 32 or 64 systems. The total size of the variable is 40
// bytes on X86 and 56 on X64.
private IntPtr _Data;

private IntPtr _fillPtr1;
private IntPtr _fillPtr2;
private IntPtr _fillPtr3;
Expand Down Expand Up @@ -3052,11 +3111,11 @@ public struct MDNS_QUERY_REQUEST
/// <summary>A value representing the type of the records to be queried. See DNS_RECORD_TYPE for possible values.</summary>
public DNS_TYPE QueryType;

// Hack to make this the right size even though the enum is a UInt32.
private ulong _QueryOptions;

/// <summary>A value representing the query options. <c>DNS_QUERY_STANDARD</c> is the only supported value.</summary>
public DNS_QUERY_OPTIONS QueryOptions;

/// <summary>Query options padding.</summary>
public uint QueryOptionsHigh;
public DNS_QUERY_OPTIONS QueryOptions { get => (DNS_QUERY_OPTIONS)_QueryOptions; set => _QueryOptions = (ulong)value; }

/// <summary>
/// A value that contains the interface index over which the service is to be advertised. If is 0, then all interfaces will be considered.
Expand Down Expand Up @@ -3159,16 +3218,11 @@ private T PopulateFetch<T>(ref T value)
}
}

internal class PDNS_MESSAGE_BUFFER : SafeAnysizeStructBase<DNS_MESSAGE_BUFFER>
{
public PDNS_MESSAGE_BUFFER(IntPtr allocatedMemory, SizeT size) : base(allocatedMemory, size, false) { }

protected override int GetArrayLength(in DNS_MESSAGE_BUFFER local) => Size - 12;
}

internal class DNS_MESSAGE_BUFFER_Marshaler : IVanaraMarshaler
{
public DNS_MESSAGE_BUFFER_Marshaler() { }
public DNS_MESSAGE_BUFFER_Marshaler()
{
}

SizeT IVanaraMarshaler.GetNativeSize() => Marshal.SizeOf(typeof(DNS_MESSAGE_BUFFER));

Expand All @@ -3182,6 +3236,15 @@ object IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocat
}
}

internal class PDNS_MESSAGE_BUFFER : SafeAnysizeStructBase<DNS_MESSAGE_BUFFER>
{
public PDNS_MESSAGE_BUFFER(IntPtr allocatedMemory, SizeT size) : base(allocatedMemory, size, false)
{
}

protected override int GetArrayLength(in DNS_MESSAGE_BUFFER local) => Size - 12;
}

internal class SafeDNS_NSEC3_DATA : SafeAnysizeStructBase<DNS_NSEC3_DATA>
{
internal SafeDNS_NSEC3_DATA(DNS_NSEC3_DATA value) : base(baseSz)
Expand Down Expand Up @@ -3217,4 +3280,4 @@ object IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocat
}
}
}
}
}
2 changes: 1 addition & 1 deletion UnitTests/PInvoke/DnsApi/DnsApi.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
Expand Down
Loading

4 comments on commit 79c9061

@NN---
Copy link
Contributor

@NN--- NN--- commented on 79c9061 Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Does it work well now ?

@dahall
Copy link
Owner Author

@dahall dahall commented on 79c9061 Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. All the tests work

@NN---
Copy link
Contributor

@NN--- NN--- commented on 79c9061 Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about using Google DNS address 8.8.8.8 for test ?

@dahall
Copy link
Owner Author

@dahall dahall commented on 79c9061 Jun 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. I'll make the change when I get to the project next. Also, all these changes were pushed as part of 3.2.11 to NuGet.

Please sign in to comment.