diff --git a/PInvoke/DnsApi/CorrelationReport.md b/PInvoke/DnsApi/CorrelationReport.md new file mode 100644 index 00000000..ee3d39f4 --- /dev/null +++ b/PInvoke/DnsApi/CorrelationReport.md @@ -0,0 +1,91 @@ +## Correlation report for dnsapi.dll +### Methods (100% complete, 33 of 33 functions) +Native Method | Header | Managed Method +--- | --- | --- +[DnsAcquireContextHandle_](https://www.google.com/search?num=5&q=DnsAcquireContextHandle_A+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsAcquireContextHandle](https://github.com/dahall/Vanara/search?l=C%23&q=DnsAcquireContextHandle) +[DnsCancelQuery](http://msdn2.microsoft.com/en-us/library/E5F422AA-D4E6-4F9F-A57C-608CE9317658) | windns.h | [Vanara.PInvoke.DnsApi.DnsCancelQuery](https://github.com/dahall/Vanara/search?l=C%23&q=DnsCancelQuery) +[DnsExtractRecordsFromMessage_W](http://msdn2.microsoft.com/en-us/library/0179bf3e-9243-4dd7-a2ab-e2f6f4bf4b82) | windns.h | [Vanara.PInvoke.DnsApi.DnsExtractRecordsFromMessage](https://github.com/dahall/Vanara/search?l=C%23&q=DnsExtractRecordsFromMessage) +[DnsFree](http://msdn2.microsoft.com/en-us/library/32baa672-2106-4c4a-972a-f7f79996b613) | windns.h | [Vanara.PInvoke.DnsApi.DnsFree](https://github.com/dahall/Vanara/search?l=C%23&q=DnsFree) +[DnsFreeProxyName](http://msdn2.microsoft.com/en-us/library/4c69d548-3bb5-4609-9fc5-3a829a285956) | windns.h | [Vanara.PInvoke.DnsApi.DnsFreeProxyName](https://github.com/dahall/Vanara/search?l=C%23&q=DnsFreeProxyName) +[DnsGetProxyInformation](http://msdn2.microsoft.com/en-us/library/fdc8eb09-e071-4f03-974a-2b11a657ab18) | windns.h | [Vanara.PInvoke.DnsApi.DnsGetProxyInformation](https://github.com/dahall/Vanara/search?l=C%23&q=DnsGetProxyInformation) +[DnsModifyRecordsInSet_](https://www.google.com/search?num=5&q=DnsModifyRecordsInSet_A+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsModifyRecordsInSet](https://github.com/dahall/Vanara/search?l=C%23&q=DnsModifyRecordsInSet) +[DnsNameCompare_](https://www.google.com/search?num=5&q=DnsNameCompare_A+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsNameCompare](https://github.com/dahall/Vanara/search?l=C%23&q=DnsNameCompare) +[DnsQuery_](https://www.google.com/search?num=5&q=DnsQuery_A+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsQuery](https://github.com/dahall/Vanara/search?l=C%23&q=DnsQuery) +[DnsQueryConfig](http://msdn2.microsoft.com/en-us/library/83de7df8-7e89-42fe-b609-1dc173afc9df) | windns.h | [Vanara.PInvoke.DnsApi.DnsQueryConfig](https://github.com/dahall/Vanara/search?l=C%23&q=DnsQueryConfig) +[DnsQueryEx](http://msdn2.microsoft.com/en-us/library/22664B9A-5010-42E7-880B-8D5B16A9F2DC) | windns.h | [Vanara.PInvoke.DnsApi.DnsQueryEx](https://github.com/dahall/Vanara/search?l=C%23&q=DnsQueryEx) +[DnsRecordCompare](http://msdn2.microsoft.com/en-us/library/c4449a23-d6d3-4f27-a963-a84144983e5e) | windns.h | [Vanara.PInvoke.DnsApi.DnsRecordCompare](https://github.com/dahall/Vanara/search?l=C%23&q=DnsRecordCompare) +[DnsRecordCopyEx](http://msdn2.microsoft.com/en-us/library/b5a74799-75fc-4489-9efa-c15b2def2ae7) | windns.h | [Vanara.PInvoke.DnsApi.DnsRecordCopyEx](https://github.com/dahall/Vanara/search?l=C%23&q=DnsRecordCopyEx) +[DnsRecordSetCompare](http://msdn2.microsoft.com/en-us/library/008cf2ba-ccb2-430a-85d9-68d424b6938f) | windns.h | [Vanara.PInvoke.DnsApi.DnsRecordSetCompare](https://github.com/dahall/Vanara/search?l=C%23&q=DnsRecordSetCompare) +[DnsRecordSetCopyEx](http://msdn2.microsoft.com/en-us/library/bdf9d6b4-b9d7-4886-8ea6-1e1f4dbcc99a) | windns.h | [Vanara.PInvoke.DnsApi.DnsRecordSetCopyEx](https://github.com/dahall/Vanara/search?l=C%23&q=DnsRecordSetCopyEx) +[DnsRecordSetDetach](http://msdn2.microsoft.com/en-us/library/434dc11f-19a9-434f-a024-9cdbb560f24c) | windns.h | [Vanara.PInvoke.DnsApi.DnsRecordSetDetach](https://github.com/dahall/Vanara/search?l=C%23&q=DnsRecordSetDetach) +[DnsReleaseContextHandle](http://msdn2.microsoft.com/en-us/library/08a5fa73-4583-4e87-bddb-09bfbfe1b36f) | windns.h | [Vanara.PInvoke.DnsApi.DnsReleaseContextHandle](https://github.com/dahall/Vanara/search?l=C%23&q=DnsReleaseContextHandle) +[DnsReplaceRecordSet](https://www.google.com/search?num=5&q=DnsReplaceRecordSetA+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsReplaceRecordSet](https://github.com/dahall/Vanara/search?l=C%23&q=DnsReplaceRecordSet) +[DnsServiceBrowse](https://www.google.com/search?num=5&q=DnsServiceBrowse+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceBrowse](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceBrowse) +[DnsServiceBrowseCancel](https://www.google.com/search?num=5&q=DnsServiceBrowseCancel+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceBrowseCancel](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceBrowseCancel) +[DnsServiceConstructInstance](https://www.google.com/search?num=5&q=DnsServiceConstructInstance+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceConstructInstance](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceConstructInstance) +[DnsServiceCopyInstance](https://www.google.com/search?num=5&q=DnsServiceCopyInstance+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceCopyInstance](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceCopyInstance) +[DnsServiceDeRegister](https://www.google.com/search?num=5&q=DnsServiceDeRegister+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceDeRegister](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceDeRegister) +[DnsServiceFreeInstance](https://www.google.com/search?num=5&q=DnsServiceFreeInstance+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceFreeInstance](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceFreeInstance) +[DnsServiceRegister](https://www.google.com/search?num=5&q=DnsServiceRegister+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceRegister](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceRegister) +[DnsServiceRegisterCancel](https://www.google.com/search?num=5&q=DnsServiceRegisterCancel+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceRegisterCancel](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceRegisterCancel) +[DnsServiceResolve](https://www.google.com/search?num=5&q=DnsServiceResolve+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceResolve](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceResolve) +[DnsServiceResolveCancel](https://www.google.com/search?num=5&q=DnsServiceResolveCancel+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsServiceResolveCancel](https://github.com/dahall/Vanara/search?l=C%23&q=DnsServiceResolveCancel) +[DnsStartMulticastQuery](https://www.google.com/search?num=5&q=DnsStartMulticastQuery+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsStartMulticastQuery](https://github.com/dahall/Vanara/search?l=C%23&q=DnsStartMulticastQuery) +[DnsStopMulticastQuery](https://www.google.com/search?num=5&q=DnsStopMulticastQuery+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsStopMulticastQuery](https://github.com/dahall/Vanara/search?l=C%23&q=DnsStopMulticastQuery) +[DnsValidateName_](https://www.google.com/search?num=5&q=DnsValidateName_A+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DnsValidateName](https://github.com/dahall/Vanara/search?l=C%23&q=DnsValidateName) +[DnsValidateServerStatus](http://msdn2.microsoft.com/en-us/library/5b362d05-87b2-44dd-8198-bcb5ab5a64f6) | windns.h | [Vanara.PInvoke.DnsApi.DnsValidateServerStatus](https://github.com/dahall/Vanara/search?l=C%23&q=DnsValidateServerStatus) +[DnsWriteQuestionToBuffer_W](http://msdn2.microsoft.com/en-us/library/9aa853aa-d9b5-41e3-a82a-c25de199924d) | windns.h | [Vanara.PInvoke.DnsApi.DnsWriteQuestionToBuffer](https://github.com/dahall/Vanara/search?l=C%23&q=DnsWriteQuestionToBuffer) +### Structures +Native Structure | Header | Managed Structure +--- | --- | --- +[DNS_A_DATA](http://msdn2.microsoft.com/en-us/library/0fd21930-1319-4ae7-b46f-2b744f4faae9) | windns.h | [Vanara.PInvoke.DnsApi.DNS_A_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_A_DATA) +[DNS_AAAA_DATA](http://msdn2.microsoft.com/en-us/library/0bc48e86-368c-431c-b67a-b7689dca8d3c) | windns.h | [Vanara.PInvoke.DnsApi.DNS_AAAA_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_AAAA_DATA) +[DNS_ADDR](http://msdn2.microsoft.com/en-us/library/c14e6fc0-34b3-40e8-b9b8-61e4aea01677) | windns.h | [Vanara.PInvoke.DnsApi.DNS_ADDR](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_ADDR) +[DNS_ADDR_ARRAY](http://msdn2.microsoft.com/en-us/library/5FD7F28B-D1A6-4731-ACB9-A7BB23CC1FB4) | windns.h | [Vanara.PInvoke.DnsApi.DNS_ADDR_ARRAY](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_ADDR_ARRAY) +[DNS_ATMA_DATA](http://msdn2.microsoft.com/en-us/library/09df3990-36bd-4656-b5cd-792e521adf9d) | windns.h | [Vanara.PInvoke.DnsApi.DNS_ATMA_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_ATMA_DATA) +[DNS_DHCID_DATA](http://msdn2.microsoft.com/en-us/library/868846bc-9f63-4bb3-ac8d-cea34232bb41) | windns.h | [Vanara.PInvoke.DnsApi.DNS_DHCID_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_DHCID_DATA) +[DNS_DS_DATA](http://msdn2.microsoft.com/en-us/library/8624cc27-feb5-4e4a-8970-40aa1d43960e) | windns.h | [Vanara.PInvoke.DnsApi.DNS_DS_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_DS_DATA) +[DNS_HEADER](http://msdn2.microsoft.com/en-us/library/e5bf19a1-4c71-482d-a075-1e149f94505b) | windns.h | [Vanara.PInvoke.DnsApi.DNS_HEADER](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_HEADER) +[DNS_KEY_DATA](http://msdn2.microsoft.com/en-us/library/d7d60322-4d06-4c57-b181-c6a38e09e1ef) | windns.h | [Vanara.PInvoke.DnsApi.DNS_KEY_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_KEY_DATA) +[DNS_LOC_DATA](http://msdn2.microsoft.com/en-us/library/c1e05479-17f0-4993-8dcf-02036989d6dc) | windns.h | [Vanara.PInvoke.DnsApi.DNS_LOC_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_LOC_DATA) +[DNS_MESSAGE_BUFFER](http://msdn2.microsoft.com/en-us/library/2a6fdf8f-ac30-4e32-9cde-67d41ddef8af) | windns.h | [Vanara.PInvoke.DnsApi.DNS_MESSAGE_BUFFER](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_MESSAGE_BUFFER) +[DNS_MINFO_DATA](http://msdn2.microsoft.com/en-us/library/cd392b48-734f-462b-b893-855f07c30575) | windns.h | [Vanara.PInvoke.DnsApi.DNS_MINFO_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_MINFO_DATA) +[DNS_MX_DATA](http://msdn2.microsoft.com/en-us/library/72a0b42e-a7af-42d2-b672-cf06d0b5d1ba) | windns.h | [Vanara.PInvoke.DnsApi.DNS_MX_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_MX_DATA) +[DNS_NAPTR_DATA](http://msdn2.microsoft.com/en-us/library/8f576efb-4ef3-4fc0-8cf5-d373460a3b3c) | windns.h | [Vanara.PInvoke.DnsApi.DNS_NAPTR_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_NAPTR_DATA) +[DNS_NSEC_DATA](http://msdn2.microsoft.com/en-us/library/ea446732-bc6a-4597-b164-11bfd77c07f2) | windns.h | [Vanara.PInvoke.DnsApi.DNS_NSEC_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_NSEC_DATA) +[DNS_NSEC3_DATA](https://www.google.com/search?num=5&q=DNS_NSEC3_DATA+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_NSEC3_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_NSEC3_DATA) +[DNS_NSEC3PARAM_DATA](https://www.google.com/search?num=5&q=DNS_NSEC3PARAM_DATA+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_NSEC3PARAM_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_NSEC3PARAM_DATA) +[DNS_NULL_DATA](http://msdn2.microsoft.com/en-us/library/c31e468f-8efd-4173-bc2c-442ee4df737f) | windns.h | [Vanara.PInvoke.DnsApi.DNS_NULL_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_NULL_DATA) +[DNS_NXT_DATA](http://msdn2.microsoft.com/en-us/library/0e5370c2-30d3-4bb7-85a0-f4412f5572fd) | windns.h | [Vanara.PInvoke.DnsApi.DNS_NXT_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_NXT_DATA) +[DNS_OPT_DATA](http://msdn2.microsoft.com/en-us/library/a8e23127-a625-4206-abe8-0787b4ac0f30) | windns.h | [Vanara.PInvoke.DnsApi.DNS_OPT_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_OPT_DATA) +[DNS_PROXY_INFORMATION](http://msdn2.microsoft.com/en-us/library/cfe7653f-7e68-4e50-ba67-bd441f837ef8) | windns.h | [Vanara.PInvoke.DnsApi.DNS_PROXY_INFORMATION](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_PROXY_INFORMATION) +[DNS_PTR_DATA](http://msdn2.microsoft.com/en-us/library/8b7f8898-ac91-46da-876c-889c427068a3) | windns.h | [Vanara.PInvoke.DnsApi.DNS_PTR_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_PTR_DATA) +[DNS_QUERY_CANCEL](http://msdn2.microsoft.com/en-us/library/543C6F9B-3200-44F6-A2B7-A5C7F5A927DB) | windns.h | [Vanara.PInvoke.DnsApi.DNS_QUERY_CANCEL](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_QUERY_CANCEL) +[DNS_QUERY_REQUEST](http://msdn2.microsoft.com/en-us/library/9C382800-DE71-4481-AC8D-9F89D6F59EE6) | windns.h | [Vanara.PInvoke.DnsApi.DNS_QUERY_REQUEST](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_QUERY_REQUEST) +[DNS_QUERY_RESULT](http://msdn2.microsoft.com/en-us/library/03EB1DC2-FAB0-45C5-B438-E8FFDD218F09) | windns.h | [Vanara.PInvoke.DnsApi.DNS_QUERY_RESULT](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_QUERY_RESULT) +[DNS_RECORD](http://msdn2.microsoft.com/en-us/library/ab7b96a5-346f-4e01-bb2a-885f44764590) | windns.h | [Vanara.PInvoke.DnsApi.DNS_RECORD](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_RECORD) +[DNS_RECORD_FLAGS](http://msdn2.microsoft.com/en-us/library/53c1c8bc-20b0-4b15-b2b6-9c9854f73ee3) | windns.h | [Vanara.PInvoke.DnsApi.DNS_RECORD_FLAGS](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_RECORD_FLAGS) +[DNS_RRSET](http://msdn2.microsoft.com/en-us/library/bd87a8db-ca27-490b-85f4-912297b77a2b) | windns.h | [Vanara.PInvoke.DnsApi.DNS_RRSET](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_RRSET) +[DNS_SERVICE_BROWSE_REQUEST](https://www.google.com/search?num=5&q=DNS_SERVICE_BROWSE_REQUEST+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SERVICE_BROWSE_REQUEST](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SERVICE_BROWSE_REQUEST) +[DNS_SERVICE_BROWSE_REQUEST_CALLBACK](https://www.google.com/search?num=5&q=DNS_SERVICE_BROWSE_REQUEST_CALLBACK+site%3Amicrosoft.com) | | [Vanara.PInvoke.DnsApi.DNS_SERVICE_BROWSE_REQUEST.DNS_SERVICE_BROWSE_REQUEST_CALLBACK](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SERVICE_BROWSE_REQUEST_CALLBACK) +[DNS_SERVICE_CANCEL](https://www.google.com/search?num=5&q=DNS_SERVICE_CANCEL+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SERVICE_CANCEL](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SERVICE_CANCEL) +[DNS_SERVICE_INSTANCE](https://www.google.com/search?num=5&q=DNS_SERVICE_INSTANCE+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SERVICE_INSTANCE](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SERVICE_INSTANCE) +[DNS_SERVICE_REGISTER_REQUEST](https://www.google.com/search?num=5&q=DNS_SERVICE_REGISTER_REQUEST+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SERVICE_REGISTER_REQUEST](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SERVICE_REGISTER_REQUEST) +[DNS_SERVICE_RESOLVE_REQUEST](https://www.google.com/search?num=5&q=DNS_SERVICE_RESOLVE_REQUEST+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SERVICE_RESOLVE_REQUEST](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SERVICE_RESOLVE_REQUEST) +[DNS_SIG_DATA](http://msdn2.microsoft.com/en-us/library/09c2f515-acc1-402f-8e62-a0d273031633) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SIG_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SIG_DATA) +[DNS_SOA_DATA](http://msdn2.microsoft.com/en-us/library/715cbb70-91fe-47ac-a713-1fe0701d4f8c) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SOA_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SOA_DATA) +[DNS_SRV_DATA](http://msdn2.microsoft.com/en-us/library/212db7ac-a5e3-4e58-b1c2-0eb551403dfc) | windns.h | [Vanara.PInvoke.DnsApi.DNS_SRV_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_SRV_DATA) +[DNS_TKEY_DATA](http://msdn2.microsoft.com/en-us/library/4dad3449-3e41-47d9-89c2-10fa6e51573b) | windns.h | [Vanara.PInvoke.DnsApi.DNS_TKEY_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_TKEY_DATA) +[DNS_TLSA_DATA](https://www.google.com/search?num=5&q=DNS_TLSA_DATA+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_TLSA_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_TLSA_DATA) +[DNS_TSIG_DATA](http://msdn2.microsoft.com/en-us/library/32077169-d319-45c0-982f-8d470cd70111) | windns.h | [Vanara.PInvoke.DnsApi.DNS_TSIG_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_TSIG_DATA) +[DNS_TXT_DATA](http://msdn2.microsoft.com/en-us/library/3ff643e2-d736-45d5-8cf8-ab5e63caf44b) | windns.h | [Vanara.PInvoke.DnsApi.DNS_TXT_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_TXT_DATA) +[DNS_UNKNOWN_DATA](https://www.google.com/search?num=5&q=DNS_UNKNOWN_DATA+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.DNS_UNKNOWN_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_UNKNOWN_DATA) +[DNS_WINS_DATA](http://msdn2.microsoft.com/en-us/library/df41c397-e662-42b4-9193-6776f9071898) | windns.h | [Vanara.PInvoke.DnsApi.DNS_WINS_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_WINS_DATA) +[DNS_WINSR_DATA](http://msdn2.microsoft.com/en-us/library/a7e79e30-905f-42a5-a4de-02d71adfe95e) | windns.h | [Vanara.PInvoke.DnsApi.DNS_WINSR_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_WINSR_DATA) +[DNS_WIRE_QUESTION](http://msdn2.microsoft.com/en-us/library/50498f20-0896-4471-8355-edd997aa4bcd) | windns.h | [Vanara.PInvoke.DnsApi.DNS_WIRE_QUESTION](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_WIRE_QUESTION) +[DNS_WIRE_RECORD](http://msdn2.microsoft.com/en-us/library/fb36930c-dd43-427a-8034-078c99497a3e) | windns.h | [Vanara.PInvoke.DnsApi.DNS_WIRE_RECORD](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_WIRE_RECORD) +[DNS_WKS_DATA](http://msdn2.microsoft.com/en-us/library/94477345-74e7-40bf-a75b-e4bf67f1c17b) | windns.h | [Vanara.PInvoke.DnsApi.DNS_WKS_DATA](https://github.com/dahall/Vanara/search?l=C%23&q=DNS_WKS_DATA) +[HDNSCONTEXT](https://www.google.com/search?num=5&q=HDNSCONTEXT+site%3Amicrosoft.com) | | [Vanara.PInvoke.DnsApi.HDNSCONTEXT](https://github.com/dahall/Vanara/search?l=C%23&q=HDNSCONTEXT) +[IP4_ARRAY](http://msdn2.microsoft.com/en-us/library/4273a739-129c-4951-b6df-aef4332ce0cb) | windns.h | [Vanara.PInvoke.DnsApi.IP4_ARRAY](https://github.com/dahall/Vanara/search?l=C%23&q=IP4_ARRAY) +[MDNS_QUERY_HANDLE](https://www.google.com/search?num=5&q=MDNS_QUERY_HANDLE+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.MDNS_QUERY_HANDLE](https://github.com/dahall/Vanara/search?l=C%23&q=MDNS_QUERY_HANDLE) +[MDNS_QUERY_REQUEST](https://www.google.com/search?num=5&q=MDNS_QUERY_REQUEST+site%3Amicrosoft.com) | windns.h | [Vanara.PInvoke.DnsApi.MDNS_QUERY_REQUEST](https://github.com/dahall/Vanara/search?l=C%23&q=MDNS_QUERY_REQUEST) diff --git a/PInvoke/DnsApi/Vanara.PInvoke.DnsApi.csproj b/PInvoke/DnsApi/Vanara.PInvoke.DnsApi.csproj new file mode 100644 index 00000000..54b9e9ed --- /dev/null +++ b/PInvoke/DnsApi/Vanara.PInvoke.DnsApi.csproj @@ -0,0 +1,29 @@ + + + + DnsApi.dll + + + PInvoke API (methods, structures and constants imported from Windows DnsApi.dll. + $(AssemblyName) + net20;net35;net40;net45;netstandard2.0;netcoreapp2.0;netcoreapp2.1;netcoreapp3.0;netcoreapp3.1 + Vanara.PInvoke.DnsApi + $(AssemblyName) + pinvoke;vanara;net-extensions;interop;DnsApi;windows dns;dns + True + Currently implements: + +Functions +DnsAcquireContextHandle_, DnsCancelQuery, DnsExtractRecordsFromMessage_W, DnsFree, DnsFreeProxyName, DnsGetProxyInformation, DnsModifyRecordsInSet_, DnsNameCompare_, DnsQuery_, DnsQueryConfig, DnsQueryEx, DnsRecordCompare, DnsRecordCopyEx, DnsRecordSetCompare, DnsRecordSetCopyEx, DnsRecordSetDetach, DnsReleaseContextHandle, DnsReplaceRecordSet, DnsServiceBrowse, DnsServiceBrowseCancel, DnsServiceConstructInstance, DnsServiceCopyInstance, DnsServiceDeRegister, DnsServiceFreeInstance, DnsServiceRegister, DnsServiceRegisterCancel, DnsServiceResolve, DnsServiceResolveCancel, DnsStartMulticastQuery, DnsStopMulticastQuery, DnsValidateName_, DnsValidateServerStatus, DnsWriteQuestionToBuffer_W + +Structures +DNS_A_DATA, DNS_AAAA_DATA, DNS_ADDR, DNS_ADDR_ARRAY, DNS_ATMA_DATA, DNS_DHCID_DATA, DNS_DS_DATA, DNS_HEADER, DNS_KEY_DATA, DNS_LOC_DATA, DNS_MESSAGE_BUFFER, DNS_MINFO_DATA, DNS_MX_DATA, DNS_NAPTR_DATA, DNS_NSEC_DATA, DNS_NSEC3_DATA, DNS_NSEC3PARAM_DATA, DNS_NULL_DATA, DNS_NXT_DATA, DNS_OPT_DATA, DNS_PROXY_INFORMATION, DNS_PTR_DATA, DNS_QUERY_CANCEL, DNS_QUERY_REQUEST, DNS_QUERY_RESULT, DNS_RECORD, DNS_RECORD_FLAGS, DNS_RRSET, DNS_SERVICE_BROWSE_REQUEST, DNS_SERVICE_CANCEL, DNS_SERVICE_INSTANCE, DNS_SERVICE_REGISTER_REQUEST, DNS_SERVICE_RESOLVE_REQUEST, DNS_SIG_DATA, DNS_SOA_DATA, DNS_SRV_DATA, DNS_TKEY_DATA, DNS_TLSA_DATA, DNS_TSIG_DATA, DNS_TXT_DATA, DNS_UNKNOWN_DATA, DNS_WINS_DATA, DNS_WINSR_DATA, DNS_WIRE_QUESTION, DNS_WIRE_RECORD, DNS_WKS_DATA, IP4_ARRAY, MDNS_QUERY_HANDLE, MDNS_QUERY_REQUEST, HDNSCONTEXT, DNS_SERVICE_BROWSE_REQUEST_CALLBACK + + + + + + + + + \ No newline at end of file diff --git a/PInvoke/DnsApi/WinDns.Funcs.cs b/PInvoke/DnsApi/WinDns.Funcs.cs new file mode 100644 index 00000000..02201321 --- /dev/null +++ b/PInvoke/DnsApi/WinDns.Funcs.cs @@ -0,0 +1,1397 @@ +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")] + public delegate void DNS_QUERY_COMPLETION_ROUTINE([In] HDNSCONTEXT pQueryContext, in 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")] + public delegate void DNS_SERVICE_BROWSE_CALLBACK(uint Status, [In] HDNSCONTEXT pQueryContext, in DNS_RECORD 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")] + public delegate void DNS_SERVICE_REGISTER_COMPLETE(uint Status, [In] HDNSCONTEXT pQueryContext, in DNS_SERVICE_INSTANCE 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")] + public delegate void DNS_SERVICE_RESOLVE_COMPLETE(uint Status, [In] HDNSCONTEXT pQueryContext, in DNS_SERVICE_INSTANCE 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")] + public delegate void MDNS_QUERY_CALLBACK(HDNSCONTEXT pQueryContext, in MDNS_QUERY_HANDLE pQueryHandle, in DNS_QUERY_RESULT 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(in 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); + + /// + /// 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); + + /// + /// 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, out 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); + + /// 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 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 HDNSCONTEXT(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 HDNSCONTEXT(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 : false; + + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// + public IntPtr DangerousGetHandle() => handle; + } + + /// 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 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; + public Func AllocMem => s => { self = true; return Marshal.AllocCoTaskMem(s); }; + public Action FreeMem => p => { if (self) Marshal.FreeCoTaskMem(p); else DnsFreeProxyName(p); }; + } + } +} \ No newline at end of file diff --git a/PInvoke/DnsApi/WinDns.cs b/PInvoke/DnsApi/WinDns.cs new file mode 100644 index 00000000..0825550b --- /dev/null +++ b/PInvoke/DnsApi/WinDns.cs @@ -0,0 +1,3160 @@ +using System; +using System.Linq; +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 + { + /// Defines the maximum sockaddr length for DNS addresses + public const int DNS_ADDR_MAX_SOCKADDR_LENGTH = 32; + + /// + public const int DNS_ATMA_MAX_ADDR_LENGTH = 20; + + /// + public const int DNS_MAX_NAME_BUFFER_LENGTH = 256; + + /// + public const uint DNS_QUERY_REQUEST_VERSION1 = 0x1; + + /// + public const uint DNS_QUERY_REQUEST_VERSION2 = 0x2; + + /// The format of the ATM address in Address. + [PInvokeData("windns.h", MSDNShortId = "09df3990-36bd-4656-b5cd-792e521adf9d")] + public enum ATMA : byte + { + /// + /// An address of the form: +358.400.1234567\0. The null-terminated hex characters map one-to-one into the ATM address with + /// arbitrarily placed "." separators. The '+' indicates it is an E.164 format address. Its length is less than + /// DNS_ATMA_MAX_ADDR_LENGTH bytes. + /// + DNS_ATMA_FORMAT_E164 = 1, + + /// + /// An address of the form: 39.246f.123456789abcdefa0123.00123456789a.00. It is a 40 hex character address mapped to 20 octets + /// with arbitrarily placed "." separators. Its length is exactly DNS_ATMA_AESA_ADDR_LENGTH bytes. + /// + DNS_ATMA_FORMAT_AESA = 2, + } + + /// The DNS_CHARSET enumeration specifies the character set used. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ne-windns-dns_charset typedef enum _DNS_CHARSET { DnsCharSetUnknown, + // DnsCharSetUnicode, DnsCharSetUtf8, DnsCharSetAnsi } DNS_CHARSET; + [PInvokeData("windns.h", MSDNShortId = "2674a4e5-c3e2-4a25-bd6f-1fc6b4db3012")] + public enum DNS_CHARSET + { + /// The character set is unknown. + DnsCharSetUnknown, + + /// The character set is Unicode. + DnsCharSetUnicode, + + /// The character set is UTF8. + DnsCharSetUtf8, + + /// The character set is ANSI. + DnsCharSetAnsi, + } + + /// A value that represents the RR DNS Record Class. + [PInvokeData("windns.h")] + public enum DNS_CLASS : ushort + { + /// + DNS_CLASS_INTERNET = 0x0001, + + /// + DNS_CLASS_CSNET = 0x0002, + + /// + DNS_CLASS_CHAOS = 0x0003, + + /// + DNS_CLASS_HESIOD = 0x0004, + + /// + DNS_CLASS_NONE = 0x00fe, + + /// + DNS_CLASS_ALL = 0x00ff, + + /// + DNS_CLASS_ANY = 0x00ff, + + /// + DNS_CLASS_UNICAST_RESPONSE = 0x8000 + } + + /// A value that specifies whether to allocate memory for the configuration information. + [PInvokeData("windns.h", MSDNShortId = "83de7df8-7e89-42fe-b609-1dc173afc9df")] + [Flags] + public enum DNS_CONFIG_FLAG : uint + { + /// Set Flag to DNS_CONFIG_FLAG_ALLOC to allocate memory; otherwise, set it to 0. + DNS_CONFIG_FLAG_ALLOC = 1 + } + + /// The DNS_CONFIG_TYPE enumeration provides DNS configuration type information. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ne-windns-dns_config_type typedef enum { DnsConfigPrimaryDomainName_W, + // DnsConfigPrimaryDomainName_A, DnsConfigPrimaryDomainName_UTF8, DnsConfigAdapterDomainName_W, DnsConfigAdapterDomainName_A, + // DnsConfigAdapterDomainName_UTF8, DnsConfigDnsServerList, DnsConfigSearchList, DnsConfigAdapterInfo, + // DnsConfigPrimaryHostNameRegistrationEnabled, DnsConfigAdapterHostNameRegistrationEnabled, DnsConfigAddressRegistrationMaxCount, + // DnsConfigHostName_W, DnsConfigHostName_A, DnsConfigHostName_UTF8, DnsConfigFullHostName_W, DnsConfigFullHostName_A, + // DnsConfigFullHostName_UTF8, DnsConfigNameServer } DNS_CONFIG_TYPE; + [PInvokeData("windns.h", MSDNShortId = "e0f0cc05-dcfe-48df-8dbd-e756cfa69154")] + public enum DNS_CONFIG_TYPE + { + /// For use with Unicode on Windows 2000. + [CorrespondingType(typeof(string))] + [CorrespondingType(typeof(StrPtrUni))] + DnsConfigPrimaryDomainName_W, + + /// For use with ANSI on Windows 2000. + [CorrespondingType(typeof(StrPtrAnsi))] + DnsConfigPrimaryDomainName_A, + + /// For use with UTF8 on Windows 2000. + DnsConfigPrimaryDomainName_UTF8, + + /// Not currently available. + DnsConfigAdapterDomainName_W, + + /// Not currently available. + DnsConfigAdapterDomainName_A, + + /// Not currently available. + DnsConfigAdapterDomainName_UTF8, + + /// For configuring a DNS Server list on Windows 2000. + [CorrespondingType(typeof(IP4_ARRAY))] + DnsConfigDnsServerList, + + /// Not currently available. + DnsConfigSearchList, + + /// Not currently available. + DnsConfigAdapterInfo, + + /// Specifies that primary host name registration is enabled on Windows 2000. + [CorrespondingType(typeof(uint))] + DnsConfigPrimaryHostNameRegistrationEnabled, + + /// Specifies that adapter host name registration is enabled on Windows 2000. + [CorrespondingType(typeof(uint))] + DnsConfigAdapterHostNameRegistrationEnabled, + + /// Specifies configuration of the maximum number of address registrations on Windows 2000. + [CorrespondingType(typeof(uint))] + DnsConfigAddressRegistrationMaxCount, + + /// + /// Specifies configuration of the host name in Unicode on Windows XP, Windows Server 2003, and later versions of Windows. + /// + [CorrespondingType(typeof(string))] + [CorrespondingType(typeof(StrPtrUni))] + DnsConfigHostName_W, + + /// Specifies configuration of the host name in ANSI on Windows XP, Windows Server 2003, and later versions of Windows. + [CorrespondingType(typeof(StrPtrAnsi))] + DnsConfigHostName_A, + + /// Specifies configuration of the host name in UTF8 on Windows XP, Windows Server 2003, and later versions of Windows. + DnsConfigHostName_UTF8, + + /// + /// Specifies configuration of the full host name (fully qualified domain name) in Unicode on Windows XP, Windows Server 2003, + /// and later versions of Windows. + /// + [CorrespondingType(typeof(string))] + [CorrespondingType(typeof(StrPtrUni))] + DnsConfigFullHostName_W, + + /// + /// Specifies configuration of the full host name (fully qualified domain name) in ANSI on Windows XP, Windows Server 2003, and + /// later versions of Windows. + /// + [CorrespondingType(typeof(StrPtrAnsi))] + DnsConfigFullHostName_A, + + /// + /// Specifies configuration of the full host name (fully qualified domain name) in UTF8 on Windows XP, Windows Server 2003, and + /// later versions of Windows. + /// + DnsConfigFullHostName_UTF8, + + /// + DnsConfigNameServer, + } + + /// The DNS_FREE_TYPE enumeration specifies the type of data to free. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ne-windns-dns_free_type typedef enum { DnsFreeFlat, DnsFreeRecordList, + // DnsFreeParsedMessageFields } DNS_FREE_TYPE; + [PInvokeData("windns.h", MSDNShortId = "976982a1-08f1-4c67-b823-1eea34f0c643")] + public enum DNS_FREE_TYPE + { + /// The data freed is a flat structure. + DnsFreeFlat, + + /// + /// The data freed is a Resource Record list, and includes subfields of the DNS_RECORD structure. Resources freed include + /// structures returned by the DnsQuery and DnsRecordSetCopyEx functions. + /// + DnsFreeRecordList, + + /// The data freed is a parsed message field. + DnsFreeParsedMessageFields, + } + + /// The DNS_NAME_FORMAT enumeration specifies name format information for DNS. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ne-windns-dns_name_format typedef enum _DNS_NAME_FORMAT { + // DnsNameDomain, DnsNameDomainLabel, DnsNameHostnameFull, DnsNameHostnameLabel, DnsNameWildcard, DnsNameSrvRecord, + // DnsNameValidateTld } DNS_NAME_FORMAT; + [PInvokeData("windns.h", MSDNShortId = "f6f1cff3-4bff-4a07-bbc6-5255030b4164")] + public enum DNS_NAME_FORMAT + { + /// The name format is a DNS domain. + DnsNameDomain, + + /// The name format is a DNS domain label. + DnsNameDomainLabel, + + /// The name format is a full DNS host name. + DnsNameHostnameFull, + + /// The name format is a DNS host label. + DnsNameHostnameLabel, + + /// The name format is a DNS wildcard. + DnsNameWildcard, + + /// The name format is a DNS SRV record. + DnsNameSrvRecord, + + /// Windows 7 or later: The name format is a DNS domain or a full DNS host name. + DnsNameValidateTld, + } + + /// A value representing the type of the query. + [PInvokeData("windns.h")] + public enum DNS_OPCODE : ushort + { + /// + DNS_OPCODE_QUERY = 0, + + /// + DNS_OPCODE_IQUERY = 1, + + /// + DNS_OPCODE_SERVER_STATUS = 2, + + /// + DNS_OPCODE_UNKNOWN = 3, + + /// + DNS_OPCODE_NOTIFY = 4, + + /// + DNS_OPCODE_UPDATE = 5, + } + + /// + /// The DNS_PROXY_INFORMATION_TYPE enumeration defines the proxy information type in the DNS_PROXY_INFORMATION structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ne-windns-dns_proxy_information_type typedef enum + // DNS_PROXY_INFORMATION_TYPE { DNS_PROXY_INFORMATION_DIRECT, DNS_PROXY_INFORMATION_DEFAULT_SETTINGS, + // DNS_PROXY_INFORMATION_PROXY_NAME, DNS_PROXY_INFORMATION_DOES_NOT_EXIST } ; + [PInvokeData("windns.h", MSDNShortId = "983d38f3-3ee7-4df6-a9ff-f908f250020f")] + public enum DNS_PROXY_INFORMATION_TYPE + { + /// The type is bypass proxy information. + DNS_PROXY_INFORMATION_DIRECT, + + /// The type is the user's default browser proxy settings. + DNS_PROXY_INFORMATION_DEFAULT_SETTINGS, + + /// The type is defined by the proxyName member of the DNS_PROXY_INFORMATION structure. + DNS_PROXY_INFORMATION_PROXY_NAME, + + /// + /// The type does not exist. DNS policy does not have proxy information for this name space. This type is used if no wildcard + /// policy exists and there is no default proxy information. + /// + DNS_PROXY_INFORMATION_DOES_NOT_EXIST, + } + + /// A value representing the query options. + [PInvokeData("windns.h")] + public enum DNS_QUERY_OPTIONS : ulong + { + /// + DNS_QUERY_STANDARD = 0x00000000, + + /// + DNS_QUERY_ACCEPT_TRUNCATED_RESPONSE = 0x00000001, + + /// + DNS_QUERY_USE_TCP_ONLY = 0x00000002, + + /// + DNS_QUERY_NO_RECURSION = 0x00000004, + + /// + DNS_QUERY_BYPASS_CACHE = 0x00000008, + + /// + DNS_QUERY_NO_WIRE_QUERY = 0x00000010, + + /// + DNS_QUERY_NO_LOCAL_NAME = 0x00000020, + + /// + DNS_QUERY_NO_HOSTS_FILE = 0x00000040, + + /// + DNS_QUERY_NO_NETBT = 0x00000080, + + /// + DNS_QUERY_WIRE_ONLY = 0x00000100, + + /// + DNS_QUERY_RETURN_MESSAGE = 0x00000200, + + /// + DNS_QUERY_MULTICAST_ONLY = 0x00000400, + + /// + DNS_QUERY_NO_MULTICAST = 0x00000800, + + /// + DNS_QUERY_TREAT_AS_FQDN = 0x00001000, + + /// + DNS_QUERY_ADDRCONFIG = 0x00002000, + + /// + DNS_QUERY_DUAL_ADDR = 0x00004000, + + /// + DNS_QUERY_DONT_RESET_TTL_VALUES = 0x00100000, + + /// + DNS_QUERY_DISABLE_IDN_ENCODING = 0x00200000, + + /// + DNS_QUERY_APPEND_MULTILABEL = 0x00800000, + + /// + DNS_QUERY_DNSSEC_OK = 0x01000000, + + /// + DNS_QUERY_DNSSEC_CHECKING_DISABLED = 0x02000000, + + /// + DNS_QUERY_RESERVED = 0xf0000000, + } + + /// An error or response code, expressed in expanded RCODE format. + [PInvokeData("windns.h", MSDNShortId = "4dad3449-3e41-47d9-89c2-10fa6e51573b")] + public enum DNS_RCODE : ushort + { + /// No error. + DNS_RCODE_NOERROR = 0, + + /// Format error. + DNS_RCODE_FORMERR = 1, + + /// Server failure. + DNS_RCODE_SERVFAIL = 2, + + /// Name error + DNS_RCODE_NXDOMAIN = 3, + + /// Not implemented. + DNS_RCODE_NOTIMPL = 4, + + /// Connection refused. + DNS_RCODE_REFUSED = 5, + + /// Domain name should not exist. + DNS_RCODE_YXDOMAIN = 6, + + /// Resource Record (RR) set should not exist. + DNS_RCODE_YXRRSET = 7, + + /// RR set does not exist + DNS_RCODE_NXRRSET = 8, + + /// Not authoritative for zone + DNS_RCODE_NOTAUTH = 9, + + /// Name not in zone + DNS_RCODE_NOTZONE = 10, + + /// Bad version. + DNS_RCODE_BADVERS = 16, + + /// The pSignature of the DNS_TSIG_DATA RR is bad. + DNS_RCODE_BADSIG = 16, + + /// The pKey field is bad. + DNS_RCODE_BADKEY = 17, + + /// A timestamp is bad. + DNS_RCODE_BADTIME = 18, + } + + /// + /// The DNS_SECTION enumeration is used in record flags, and as an index into DNS wire message header section counts. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ne-windns-dns_section typedef enum _DnsSection { DnsSectionQuestion, + // DnsSectionAnswer, DnsSectionAuthority, DnsSectionAddtional } DNS_SECTION; + [PInvokeData("windns.h", MSDNShortId = "d51ef2c7-c2bb-4eed-a026-a559460352b6")] + public enum DNS_SECTION + { + /// The DNS section specified is a DNS question. + DnsSectionQuestion, + + /// The DNS section specified is a DNS answer. + DnsSectionAnswer, + + /// The DNS section specified indicates a DNS authority. + DnsSectionAuthority, + + /// The DNS section specified is additional DNS information. + DnsSectionAddtional, + } + + /// A scheme used for key agreement or the purpose of the TKEY DNS Message. + [PInvokeData("windns.h", MSDNShortId = "4dad3449-3e41-47d9-89c2-10fa6e51573b")] + public enum DNS_TKEY_MODE : ushort + { + /// The key is assigned by the DNS server and is not negotiated. + DNS_TKEY_MODE_SERVER_ASSIGN = 1, + + /// The Diffie-Hellman key exchange algorithm is used to negotiate the key. + DNS_TKEY_MODE_DIFFIE_HELLMAN = 2, + + /// The key is exchanged through Generic Security Services-Application Program Interface (GSS-API) negotiation. + DNS_TKEY_MODE_GSS = 3, + + /// The key is assigned by the DNS resolver and is not negotiated. + DNS_TKEY_MODE_RESOLVER_ASSIGN = 4, + } + + /// DNS record types. + [PInvokeData("windns.h")] + public enum DNS_TYPE : ushort + { + /// + [CorrespondingType(typeof(DNS_A_DATA))] + DNS_TYPE_A = 0x0001, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_NS = 0x0002, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_MD = 0x0003, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_MF = 0x0004, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_CNAME = 0x0005, + + /// + [CorrespondingType(typeof(DNS_SOA_DATA))] + DNS_TYPE_SOA = 0x0006, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_MB = 0x0007, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_MG = 0x0008, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_MR = 0x0009, + + /// + [CorrespondingType(typeof(DNS_NULL_DATA))] + DNS_TYPE_NULL = 0x000a, + + /// + [CorrespondingType(typeof(DNS_WKS_DATA))] + DNS_TYPE_WKS = 0x000b, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_PTR = 0x000c, + + /// + [CorrespondingType(typeof(DNS_TXT_DATA))] + DNS_TYPE_HINFO = 0x000d, + + /// + [CorrespondingType(typeof(DNS_MINFO_DATA))] + DNS_TYPE_MINFO = 0x000e, + + /// + [CorrespondingType(typeof(DNS_MX_DATA))] + DNS_TYPE_MX = 0x000f, + + /// + [CorrespondingType(typeof(DNS_TXT_DATA))] + DNS_TYPE_TEXT = 0x0010, + + /// + [CorrespondingType(typeof(DNS_MINFO_DATA))] + DNS_TYPE_RP = 0x0011, + + /// + [CorrespondingType(typeof(DNS_MX_DATA))] + DNS_TYPE_AFSDB = 0x0012, + + /// + [CorrespondingType(typeof(DNS_TXT_DATA))] + DNS_TYPE_X25 = 0x0013, + + /// + [CorrespondingType(typeof(DNS_TXT_DATA))] + DNS_TYPE_ISDN = 0x0014, + + /// + [CorrespondingType(typeof(DNS_MX_DATA))] + DNS_TYPE_RT = 0x0015, + + /// + DNS_TYPE_NSAP = 0x0016, + + /// + DNS_TYPE_NSAPPTR = 0x0017, + + /// + [CorrespondingType(typeof(DNS_SIG_DATA))] + DNS_TYPE_SIG = 0x0018, + + /// + [CorrespondingType(typeof(DNS_KEY_DATA))] + DNS_TYPE_KEY = 0x0019, + + /// + DNS_TYPE_PX = 0x001a, + + /// + DNS_TYPE_GPOS = 0x001b, + + /// + [CorrespondingType(typeof(DNS_AAAA_DATA))] + DNS_TYPE_AAAA = 0x001c, + + /// + [CorrespondingType(typeof(DNS_LOC_DATA))] + DNS_TYPE_LOC = 0x001d, + + /// + [CorrespondingType(typeof(DNS_NXT_DATA))] + DNS_TYPE_NXT = 0x001e, + + /// + DNS_TYPE_EID = 0x001f, + + /// + DNS_TYPE_NIMLOC = 0x0020, + + /// + [CorrespondingType(typeof(DNS_SRV_DATA))] + DNS_TYPE_SRV = 0x0021, + + /// + [CorrespondingType(typeof(DNS_ATMA_DATA))] + DNS_TYPE_ATMA = 0x0022, + + /// + [CorrespondingType(typeof(DNS_NAPTR_DATA))] + DNS_TYPE_NAPTR = 0x0023, + + /// + DNS_TYPE_KX = 0x0024, + + /// + DNS_TYPE_CERT = 0x0025, + + /// + DNS_TYPE_A6 = 0x0026, + + /// + [CorrespondingType(typeof(DNS_PTR_DATA))] + DNS_TYPE_DNAME = 0x0027, + + /// + DNS_TYPE_SINK = 0x0028, + + /// + [CorrespondingType(typeof(DNS_OPT_DATA))] + DNS_TYPE_OPT = 0x0029, + + /// + [CorrespondingType(typeof(DNS_DS_DATA))] + DNS_TYPE_DS = 0x002b, + + /// + DNS_TYPE_RRSIG = 0x002e, + + /// + [CorrespondingType(typeof(DNS_NSEC_DATA))] + DNS_TYPE_NSEC = 0x002f, + + /// + DNS_TYPE_DNSKEY = 0x0030, + + /// + [CorrespondingType(typeof(DNS_DHCID_DATA))] + DNS_TYPE_DHCID = 0x0031, + + /// + [CorrespondingType(typeof(DNS_NSEC3_DATA))] + DNS_TYPE_NSEC3 = 0x0032, + + /// + [CorrespondingType(typeof(DNS_NSEC3PARAM_DATA))] + DNS_TYPE_NSEC3PARAM = 0x0033, + + /// + [CorrespondingType(typeof(DNS_TLSA_DATA))] + DNS_TYPE_TLSA = 0x0034, + + /// + DNS_TYPE_UINFO = 0x0064, + + /// + DNS_TYPE_UID = 0x0065, + + /// + DNS_TYPE_GID = 0x0066, + + /// + DNS_TYPE_UNSPEC = 0x0067, + + /// + DNS_TYPE_ADDRS = 0x00f8, + + /// + [CorrespondingType(typeof(DNS_TKEY_DATA))] + DNS_TYPE_TKEY = 0x00f9, + + /// + [CorrespondingType(typeof(DNS_TSIG_DATA))] + DNS_TYPE_TSIG = 0x00fa, + + /// + DNS_TYPE_IXFR = 0x00fb, + + /// + DNS_TYPE_AXFR = 0x00fc, + + /// + DNS_TYPE_MAILB = 0x00fd, + + /// + DNS_TYPE_MAILA = 0x00fe, + + /// + DNS_TYPE_ALL = 0x00ff, + + /// + DNS_TYPE_ANY = 0x00ff, + + /// + [CorrespondingType(typeof(DNS_WINS_DATA))] + DNS_TYPE_WINS = 0xff01, + + /// + [CorrespondingType(typeof(DNS_WINSR_DATA))] + DNS_TYPE_WINSR = 0xff02, + + /// + [CorrespondingType(typeof(DNS_WINSR_DATA))] + DNS_TYPE_NBSTAT = (DNS_TYPE_WINSR), + } + + /// A value that contains a bitmap of DNS Update Options. + [PInvokeData("windns.h", MSDNShortId = "7b99f440-72fa-4cf4-9267-98f436e99a50")] + [Flags] + public enum DNS_UPDATE : uint + { + /// + DNS_UPDATE_SECURITY_USE_DEFAULT = 0x00000000, + + /// + DNS_UPDATE_SECURITY_OFF = 0x00000010, + + /// + DNS_UPDATE_SECURITY_ON = 0x00000020, + + /// + DNS_UPDATE_SECURITY_ONLY = 0x00000100, + + /// + DNS_UPDATE_CACHE_SECURITY_CONTEXT = 0x00000200, + + /// + DNS_UPDATE_TEST_USE_LOCAL_SYS_ACCT = 0x00000400, + + /// + DNS_UPDATE_FORCE_SECURITY_NEGO = 0x00000800, + + /// + DNS_UPDATE_TRY_ALL_MASTER_SERVERS = 0x00001000, + + /// + DNS_UPDATE_SKIP_NO_UPDATE_ADAPTERS = 0x00002000, + + /// + DNS_UPDATE_REMOTE_SERVER = 0x00004000, + + /// + DNS_UPDATE_RESERVED = 0xffff0000, + } + + /// The WINS mapping flag that specifies whether the record must be included in zone replication. + [PInvokeData("windns.h", MSDNShortId = "df41c397-e662-42b4-9193-6776f9071898")] + public enum DNS_WINS_FLAG : uint + { + /// Record is not local, replicate across zones. + DNS_WINS_FLAG_SCOPE = 0x80000000, + + /// Record is local, do not replicate. + DNS_WINS_FLAG_LOCAL = 0x00010000, + } + + /// Represents the query validation status. + [PInvokeData("windns.h", MSDNShortId = "5b362d05-87b2-44dd-8198-bcb5ab5a64f6")] + public enum DnsServerStatus : uint + { + /// No errors. The call was successful. + ERROR_SUCCESS = 0, + + /// server IP address was invalid. + DNS_VALSVR_ERROR_INVALID_ADDR = 0x01, + + /// queryName FQDN was invalid. + DNS_VALSVR_ERROR_INVALID_NAME = 0x02, + + /// DNS server was unreachable. + DNS_VALSVR_ERROR_UNREACHABLE = 0x03, + + /// Timeout waiting for the DNS server response. + DNS_VALSVR_ERROR_NO_RESPONSE = 0x04, + + /// DNS server was not authoritative or queryName was not found. + DNS_VALSVR_ERROR_NO_AUTH = 0x05, + + /// DNS server refused the query. + DNS_VALSVR_ERROR_REFUSED = 0x06, + + /// + /// 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_NO_TCP = 0x10, + + /// An unknown error occurred. + DNS_VALSVR_ERROR_UNKNOWN = 0xFF, + } + + /// The DNS_A_DATA structure represents a DNS address (A) record as specified in section 3.4.1 of RFC 1035. + /// + /// The DNS_A_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_a_data typedef struct { IP4_ADDRESS IpAddress; } + // DNS_A_DATA, *PDNS_A_DATA; + [PInvokeData("windns.h", MSDNShortId = "0fd21930-1319-4ae7-b46f-2b744f4faae9")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_A_DATA + { + /// An IP4_ADDRESS data type that contains an IPv4 address. + public IP4_ADDRESS IpAddress; + } + + /// The DNS_AAAA_DATA structure represents a DNS IPv6 (AAAA) record as specified in RFC 3596. + /// + /// The DNS_AAAA_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_aaaa_data typedef struct { IP6_ADDRESS Ip6Address; } + // DNS_AAAA_DATA, *PDNS_AAAA_DATA; + [PInvokeData("windns.h", MSDNShortId = "0bc48e86-368c-431c-b67a-b7689dca8d3c")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_AAAA_DATA + { + /// An IP6_ADDRESS data type that contains an IPv6 address. + public IP6_ADDRESS Ip6Address; + } + + /// A DNS_ADDR structure stores an IPv4 or IPv6 address. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_addr typedef struct _DnsAddr { CHAR + // MaxSa[DNS_ADDR_MAX_SOCKADDR_LENGTH]; DWORD DnsAddrUserDword[8]; } DNS_ADDR, *PDNS_ADDR; + [PInvokeData("windns.h", MSDNShortId = "c14e6fc0-34b3-40e8-b9b8-61e4aea01677")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_ADDR + { + /// + /// A value that contains the socket IP address. It is a sockaddr_in structure if the address is IPv4 and a sockaddr_in6 + /// structure if the address is IPv6. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = DNS_ADDR_MAX_SOCKADDR_LENGTH)] + public byte[] MaxSa; + + /// Reserved. Must be 0. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] + public uint[] DnsAddrUserDword; + } + + /// The DNS_ADDR_ARRAY structure stores an array of IPv4 or IPv6 addresses. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_addr_array typedef struct _DnsAddrArray { DWORD MaxCount; + // DWORD AddrCount; DWORD Tag; WORD Family; WORD WordReserved; DWORD Flags; DWORD MatchFlag; DWORD Reserved1; DWORD Reserved2; + // DNS_ADDR AddrArray[]; } DNS_ADDR_ARRAY, *PDNS_ADDR_ARRAY; + [PInvokeData("windns.h", MSDNShortId = "5FD7F28B-D1A6-4731-ACB9-A7BB23CC1FB4")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(AddrCount))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_ADDR_ARRAY + { + /// Indicates, the size, in bytes, of this structure. + public uint MaxCount; + + /// Indicates the number of DNS_ADDR structures contained in the AddrArray member. + public uint AddrCount; + + /// Reserved. Do not use. + public uint Tag; + + /// + /// A value that specifies the IP family. Possible values are: + /// + /// + /// Value + /// Meaning + /// + /// + /// AF_INET6 + /// IPv6 + /// + /// + /// AF_INET + /// IPv4 + /// + /// + /// + public ADDRESS_FAMILY Family; + + /// Reserved. Do not use. + public ushort WordReserved; + + /// Reserved. Do not use. + public uint Flags; + + /// Reserved. Do not use. + public uint MatchFlag; + + /// Reserved. Do not use. + public uint Reserved1; + + /// Reserved. Do not use. + public uint Reserved2; + + /// An array of DNS_ADDR structures that each contain an IP address. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public DNS_ADDR[] AddrArray; + } + + /// The DNS_ATMA_DATA structure represents a DNS ATM address (ATMA) resource record (RR). + /// + /// The DNS_ATMA_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_atma_data typedef struct { BYTE AddressType; BYTE + // Address[DNS_ATMA_MAX_ADDR_LENGTH]; } DNS_ATMA_DATA, *PDNS_ATMA_DATA; + [PInvokeData("windns.h", MSDNShortId = "09df3990-36bd-4656-b5cd-792e521adf9d")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_ATMA_DATA + { + /// + /// The format of the ATM address in Address. The possible values for AddressType are: + /// + /// + /// Value + /// Meaning + /// + /// + /// DNS_ATMA_FORMAT_AESA + /// + /// An address of the form: 39.246f.123456789abcdefa0123.00123456789a.00. It is a 40 hex character address mapped to 20 octets + /// with arbitrarily placed "." separators. Its length is exactly DNS_ATMA_AESA_ADDR_LENGTH bytes. + /// + /// + /// + /// DNS_ATMA_FORMAT_E164 + /// + /// An address of the form: +358.400.1234567\0. The null-terminated hex characters map one-to-one into the ATM address with + /// arbitrarily placed "." separators. The '+' indicates it is an E.164 format address. Its length is less than + /// DNS_ATMA_MAX_ADDR_LENGTH bytes. + /// + /// + /// + /// + public ATMA AddressType; + + /// A BYTE array that contains the ATM address whose format is specified by AddressType. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = DNS_ATMA_MAX_ADDR_LENGTH)] + public byte[] Address; + } + + /// + /// The DNS_DHCID_DATA structure represents a DNS Dynamic Host Configuration Protocol Information (DHCID) resource record + /// (RR) as specified in section 3 of RFC 4701. + /// + /// + /// The DNS_DHCID_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_dhcid_data typedef struct { DWORD dwByteCount; #if ... + // BYTE DHCID[]; #else BYTE DHCID[1]; #endif } DNS_DHCID_DATA, *PDNS_DHCID_DATA; + [PInvokeData("windns.h", MSDNShortId = "868846bc-9f63-4bb3-ac8d-cea34232bb41")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(dwByteCount))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_DHCID_DATA + { + /// The length, in bytes, of DHCID. + public uint dwByteCount; + + /// + /// A BYTE array that contains the DHCID client, domain, and SHA-256 digest information as specified in section 4 of RFC 2671. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] DHCID; + } + + /// + /// The DNS_DS_DATA structure represents a DS resource record (RR) as specified in section 2 of RFC 4034 and is used to + /// verify the contents of DNS_DNSKEY_DATA. + /// + /// + /// The DNS_DS_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_ds_data typedef struct { WORD wKeyTag; BYTE chAlgorithm; + // BYTE chDigestType; WORD wDigestLength; WORD wPad; #if ... BYTE Digest[]; #else BYTE Digest[1]; #endif } DNS_DS_DATA, *PDNS_DS_DATA; + [PInvokeData("windns.h", MSDNShortId = "8624cc27-feb5-4e4a-8970-40aa1d43960e")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(wDigestLength))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_DS_DATA + { + /// + /// A value that represents the method to choose which public key is used to verify Signature in DNS_RRSIG_DATA as + /// specified in Appendix B of RFC 4034. This value is identical to the wKeyTag field in DNS_RRSIG_DATA. + /// + public ushort wKeyTag; + + /// + /// A value that specifies the algorithm defined by DNS_DNSKEY_DATA. The possible values are shown in the following table. + /// + /// + /// Value + /// Meaning + /// + /// + /// 1 + /// RSA/MD5 (RFC 2537) + /// + /// + /// 2 + /// Diffie-Hellman (RFC 2539) + /// + /// + /// 3 + /// DSA (RFC 2536) + /// + /// + /// 4 + /// Elliptic curve cryptography + /// + /// + /// 5 + /// RSA/SHA-1 (RFC 3110) + /// + /// + /// + public byte chAlgorithm; + + /// + /// + /// A value that specifies the cryptographic algorithm used to generate Digest. The possible values are shown in the + /// following table. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 1 + /// SHA-1 (RFC 3174) + /// + /// + /// + public byte chDigestType; + + /// + /// The length, in bytes. of the message digest in Digest. This value is determined by the algorithm type in chDigestType. + /// + public ushort wDigestLength; + + /// Reserved for padding. Do not use. + public ushort wPad; + + /// + /// A BYTE array that contains a cryptographic digest of the DNSKEY RR and RDATA as specified in section 5.1.4 of RFC + /// 4034. Its length is determined by wDigestLength. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Digest; + } + + /// + /// The DNS_HEADER structure contains DNS header information used when sending DNS messages as specified in section 4.1.1 of + /// RFC 1035. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_header typedef struct _DNS_HEADER { WORD Xid; BYTE + // RecursionDesired : 1; BYTE Truncation : 1; BYTE Authoritative : 1; BYTE Opcode : 4; BYTE IsResponse : 1; BYTE ResponseCode : 4; + // BYTE CheckingDisabled : 1; BYTE AuthenticatedData : 1; BYTE Reserved : 1; BYTE RecursionAvailable : 1; WORD QuestionCount; WORD + // AnswerCount; WORD NameServerCount; WORD AdditionalCount; } DNS_HEADER, *PDNS_HEADER; + [PInvokeData("windns.h", MSDNShortId = "e5bf19a1-4c71-482d-a075-1e149f94505b")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_HEADER + { + /// A value that specifies the unique DNS message identifier. + public ushort Xid; + + private ushort flags; + + /// + /// A value that specifies whether recursive name query should be used by the DNS name server. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0x00 + /// Do not use recursive name query. + /// + /// + /// 0x01 + /// Use recursive name query. + /// + /// + /// + public bool RecursionDesired { get => BitHelper.GetBit(flags, 0); set => BitHelper.SetBit(ref flags, 0, value); } + + /// + /// A value that specifies whether the DNS message has been truncated. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0x00 + /// The message is not truncated. + /// + /// + /// 0x01 + /// The message is truncated. + /// + /// + /// + public bool Truncation { get => BitHelper.GetBit(flags, 1); set => BitHelper.SetBit(ref flags, 1, value); } + + /// + /// + /// A value that specifies whether the DNS server from which the DNS message is being sent is authoritative for the domain + /// name's zone. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 0x00 + /// The DNS server is not authoritative in the zone. + /// + /// + /// 0x01 + /// The DNS server is authoritative in the zone. + /// + /// + /// + public bool Authoritative { get => BitHelper.GetBit(flags, 2); set => BitHelper.SetBit(ref flags, 2, value); } + + /// + /// A value that specifies the operation code to be taken on the DNS message as defined in section 4.1.1 of RFC 1035 as the + /// OPCODE field. + /// + public ushort Opcode { get => BitHelper.GetBits(flags, 3, 4); set => BitHelper.SetBits(ref flags, 3, 4, value); } + + /// + /// A value that specifies whether the DNS message is a query or a response message. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0x00 + /// The DNS message is a query. + /// + /// + /// 0x01 + /// The DNS message is a response. + /// + /// + /// + public bool IsResponse { get => BitHelper.GetBit(flags, 7); set => BitHelper.SetBit(ref flags, 7, value); } + + /// The DNS Response Code of the message. + public ushort ResponseCode { get => BitHelper.GetBits(flags, 8, 4); set => BitHelper.SetBits(ref flags, 8, 4, value); } + + /// + /// Windows 7 or later: A value that specifies whether checking is supported by the DNS resolver. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0x00 + /// Checking is enabled on the DNS resolver. + /// + /// + /// 0x01 + /// Checking is disabled on the DNS resolver. + /// + /// + /// + public bool CheckingDisabled { get => BitHelper.GetBit(flags, 12); set => BitHelper.SetBit(ref flags, 12, value); } + + /// + /// + /// Windows 7 or later: A value that specifies whether the DNS data following the DNS_HEADER is authenticated by the DNS server. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 0x00 + /// The DNS data is not authenticated. + /// + /// + /// 0x01 + /// The DNS data is authenticated. + /// + /// + /// + public bool AuthenticatedData { get => BitHelper.GetBit(flags, 13); set => BitHelper.SetBit(ref flags, 13, value); } + + /// Reserved. Do not use. + public bool Reserved { get => BitHelper.GetBit(flags, 14); set => BitHelper.SetBit(ref flags, 14, value); } + + /// + /// A value that specifies whether recursive name query is supported by the DNS name server. + /// + /// + /// Value + /// Meaning + /// + /// + /// 0x00 + /// Recursive name query is not supported. + /// + /// + /// 0x01 + /// Recursive name query is supported. + /// + /// + /// + public bool RecursionAvailable { get => BitHelper.GetBit(flags, 15); set => BitHelper.SetBit(ref flags, 15, value); } + + /// The number of queries contained in the question section of the DNS message. + public ushort QuestionCount; + + /// The number of resource records (RRs) contained in the answer section of the DNS message. + public ushort AnswerCount; + + /// + /// The number of DNS name server RRs contained in the authority section of the DNS message. This value is the number of DNS + /// name servers the message has traversed in its search for resolution. + /// + public ushort NameServerCount; + + /// Reserved. Do not use. + public ushort AdditionalCount; + } + + /// The DNS_KEY_DATA structure represents a DNS key (KEY) resource record (RR) as specified in RFC 3445. + /// + /// + /// The DNS_KEY_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + /// The DNS_DNSKEY_DATA structure represents a DNSKEY resource record as specified in section 2 of RFC 4034. + /// The DNS_DNSKEY_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + /// The value of the wFlags member for DNS_DNSKEY_DATA is a set of flags that specify key properties as described in section + /// 2.1.1 of RFC 4034. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_key_data typedef struct { WORD wFlags; BYTE chProtocol; + // BYTE chAlgorithm; WORD wKeyLength; WORD wPad; #if ... BYTE Key[]; #else BYTE Key[1]; #endif } DNS_KEY_DATA, *PDNS_KEY_DATA, + // DNS_DNSKEY_DATA, *PDNS_DNSKEY_DATA; + [PInvokeData("windns.h", MSDNShortId = "d7d60322-4d06-4c57-b181-c6a38e09e1ef")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(wKeyLength))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_KEY_DATA + { + /// A set of flags that specify whether this is a zone key as described in section 4 of RFC 3445. + public ushort wFlags; + + /// + /// + /// A value that specifies the protocol with which Key can be used. The possible values are shown in the following table. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 3 + /// Domain Name System Security Extensions (DNSSEC) + /// + /// + /// + public byte chProtocol; + + /// + /// A value that specifies the algorithm to use with Key. The possible values are shown in the following table. + /// + /// + /// Value + /// Meaning + /// + /// + /// 1 + /// RSA/MD5 (RFC 2537) + /// + /// + /// 2 + /// Diffie-Hellman (RFC 2539) + /// + /// + /// 3 + /// DSA (RFC 2536) + /// + /// + /// 4 + /// Elliptic curve cryptography + /// + /// + /// 5 + /// RSA/SHA-1 (RFC 3110). DNS_DNSKEY_DATA only. + /// + /// + /// + public byte chAlgorithm; + + /// The length, in bytes, of Key. This value is determined by the algorithm type in chAlgorithm. + public ushort wKeyLength; + + /// Reserved. Do not use. + public ushort wPad; + + /// + /// A BYTE array that contains the public key for the algorithm in chAlgorithm, represented in base 64, as + /// described in Appendix A of RFC 2535. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Key; + } + + /// The DNS_LOC_DATA structure represents a DNS location (LOC) resource record (RR) as specified in RFC 1876. + /// + /// The DNS_LOC_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_loc_data typedef struct { WORD wVersion; WORD wSize; WORD + // wHorPrec; WORD wVerPrec; DWORD dwLatitude; DWORD dwLongitude; DWORD dwAltitude; } DNS_LOC_DATA, *PDNS_LOC_DATA; + [PInvokeData("windns.h", MSDNShortId = "c1e05479-17f0-4993-8dcf-02036989d6dc")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_LOC_DATA + { + /// The version number of the representation. Must be zero. + public ushort wVersion; + + /// The diameter of a sphere enclosing the described entity, defined as "SIZE" in section 2 of RFC 1876. + public ushort wSize; + + /// The horizontal data precision, defined as "HORIZ PRE" in section 2 of RFC 1876. + public ushort wHorPrec; + + /// The vertical data precision, defined as "VERT PRE" in section 2 of RFC 1876. + public ushort wVerPrec; + + /// The latitude of the center of the sphere, defined as "LATITUDE" in section 2 of RFC 1876. + public uint dwLatitude; + + /// The longitude of the center of the sphere, defined as "LONGITUDE" in section 2 of RFC 1876. + public uint dwLongitude; + + /// The altitude of the center of the sphere, defined as "ALTITUDE" in section 2 of RFC 1876. + public uint dwAltitude; + } + + /// The DNS_MESSAGE_BUFFER structure stores message information for DNS queries. + /// + /// + /// The DNS_MESSAGE_BUFFER is used by the system to store DNS query information, and make that information available through + /// various DNS function calls. + /// + /// + /// The DnsWriteQuestionToBuffer method should be used to write a DNS query into a DNS_MESSAGE_BUFFER structure and the + /// DnsExtractRecordsFromMessage method should be used to read the DNS RRs from a DNS_MESSAGE_BUFFER. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_message_buffer typedef struct _DNS_MESSAGE_BUFFER { + // DNS_HEADER MessageHead; CHAR MessageBody[1]; } DNS_MESSAGE_BUFFER, *PDNS_MESSAGE_BUFFER; + [PInvokeData("windns.h", MSDNShortId = "2a6fdf8f-ac30-4e32-9cde-67d41ddef8af")] + [VanaraMarshaler(typeof(DNS_MESSAGE_BUFFER_Marshaler))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_MESSAGE_BUFFER + { + /// A DNS_HEADER structure that contains the header for the DNS message. + public DNS_HEADER MessageHead; + + /// An array of characters that comprises the DNS query or resource records (RR). + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] MessageBody; + } + + /// + /// The DNS_MINFO_DATA structure represents a DNS mail information (MINFO) record as specified in section 3.3.7 of RFC 1035. + /// + /// + /// The DNS_MINFO_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_minfo_dataa typedef struct { PSTR pNameMailbox; PSTR + // pNameErrorsMailbox; } DNS_MINFO_DATAA, *PDNS_MINFO_DATAA; + [PInvokeData("windns.h", MSDNShortId = "cd392b48-734f-462b-b893-855f07c30575")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_MINFO_DATA + { + /// + /// A pointer to a string that represents the fully qualified domain name (FQDN) of the mailbox responsible for the mailing list + /// or mailbox specified in the record's owner name. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pNameMailbox; + + /// + /// A pointer to a string that represents the FQDN of the mailbox to receive error messages related to the mailing list. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pNameErrorsMailbox; + } + + /// + /// The DNS_MX_DATA structure represents a DNS mail exchanger (MX) record as specified in section 3.3.9 of RFC 1035. + /// + /// + /// The DNS_MX_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_mx_dataa typedef struct { PSTR pNameExchange; WORD + // wPreference; WORD Pad; } DNS_MX_DATAA, *PDNS_MX_DATAA; + [PInvokeData("windns.h", MSDNShortId = "72a0b42e-a7af-42d2-b672-cf06d0b5d1ba")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_MX_DATA + { + /// + /// A pointer to a string that represents the fully qualified domain name (FQDN) of the host willing to act as a mail exchange. + /// + [MarshalAs(UnmanagedType.LPTStr)] + public string pNameExchange; + + /// A preference given to this resource record among others of the same owner. Lower values are preferred. + public ushort wPreference; + + /// Reserved for padding. Do not use. + public ushort Pad; + } + + /// + /// The DNS_NAPTR_DATA structure represents a Naming Authority Pointer (NAPTR) DNS Resource Record (RR) as specified in RFC 2915. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_naptr_dataw typedef struct { WORD wOrder; WORD + // wPreference; PWSTR pFlags; PWSTR pService; PWSTR pRegularExpression; PWSTR pReplacement; } DNS_NAPTR_DATAW, *PDNS_NAPTR_DATAW; + [PInvokeData("windns.h", MSDNShortId = "8f576efb-4ef3-4fc0-8cf5-d373460a3b3c")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_NAPTR_DATA + { + /// A value that determines the NAPTR RR processing order as defined in section 2 of RFC 2915. + public ushort wOrder; + + /// + /// A value that determines the NAPTR RR processing order for records with the same wOrder value as defined in section 2 + /// of RFC 2915. + /// + public ushort wPreference; + + /// + /// A pointer to a string that represents a set of NAPTR RR flags which determine the interpretation and processing of NAPTR + /// record fields as defined in section 2 of RFC 2915. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string pFlags; + + /// + /// A pointer to a string that represents the available services in this rewrite path as defined in section 2 of RFC 2915. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string pService; + + /// A pointer to a string that represents a substitution expression as defined in sections 2 and 3 of RFC 2915. + [MarshalAs(UnmanagedType.LPTStr)] public string pRegularExpression; + + /// A pointer to a string that represents the next NAPTR query name as defined in section 2 of RFC 2915. + [MarshalAs(UnmanagedType.LPTStr)] public string pReplacement; + } + + /// The DNS_NSEC_DATA structure represents an NSEC resource record (RR) as specified in section 4 of RFC 4034. + /// + /// The DNS_NSEC_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_nsec_dataa typedef struct { PSTR pNextDomainName; WORD + // wTypeBitMapsLength; WORD wPad; #if ... BYTE TypeBitMaps[]; #else BYTE TypeBitMaps[1]; #endif } DNS_NSEC_DATAA, *PDNS_NSEC_DATAA; + [PInvokeData("windns.h", MSDNShortId = "ea446732-bc6a-4597-b164-11bfd77c07f2")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(wTypeBitMapsLength))] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_NSEC_DATA + { + /// + /// A pointer to a string that represents the authoritative owner name of the next domain in the canonical ordering of the zone + /// as specified in section 4.1.1 of RFC 4034. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string pNextDomainName; + + /// The length, in bytes, of TypeBitMaps. + public ushort wTypeBitMapsLength; + + /// Reserved. Do not use. + public ushort wPad; + + /// + /// A BYTE array that contains a bitmap that specifies which RR types are supported by the NSEC RR owner. Each bit in the + /// array corresponds to a DNS Record Type as defined in section in section 4.1.2 of RFC 4034. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] TypeBitMaps; + } + + /// Undocumented. + [PInvokeData("windns.h")] + [VanaraMarshaler(typeof(SafeDNS_NSEC3_DATAMarshaler))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_NSEC3_DATA + { + /// + public byte chAlgorithm; + + /// + public byte bFlags; + + /// + public ushort wIterations; + + /// + public byte bSaltLength; + + /// + public byte bHashLength; + + /// + public ushort wTypeBitMapsLength; + + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] chData; + } + + /// Undocumented. + [PInvokeData("windns.h")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(bSaltLength))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_NSEC3PARAM_DATA + { + /// + public byte chAlgorithm; + + /// + public byte bFlags; + + /// + public ushort wIterations; + + /// + public byte bSaltLength; + + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] bPad; // keep salt field aligned + + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] pbSalt; + } + + /// + /// The DNS_NULL_DATA structure represents NULL data for a DNS resource record as specified in section 3.3.10 of RFC 1035. + /// + /// + /// The DNS_NULL_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_null_data typedef struct { DWORD dwByteCount; #if ... + // BYTE Data[]; #else BYTE Data[1]; #endif } DNS_NULL_DATA, *PDNS_NULL_DATA; + [PInvokeData("windns.h", MSDNShortId = "c31e468f-8efd-4173-bc2c-442ee4df737f")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(dwByteCount))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_NULL_DATA + { + /// The number of bytes represented in Data. + public uint dwByteCount; + + /// Null data. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Data; + } + + /// + /// The DNS_NXT_DATA structure represents a DNS next (NXT) resource record (RR) as specified in section 5 of RFC 2535. + /// + /// + /// The DNS_NXT_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_nxt_dataa typedef struct { PSTR pNameNext; WORD + // wNumTypes; #if ... WORD wTypes[]; #else WORD wTypes[1]; #endif } DNS_NXT_DATAA, *PDNS_NXT_DATAA; + [PInvokeData("windns.h", MSDNShortId = "0e5370c2-30d3-4bb7-85a0-f4412f5572fd")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(wNumTypes))] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_NXT_DATA + { + /// A pointer to a string that represents the name of the next domain. + [MarshalAs(UnmanagedType.LPTStr)] public string pNameNext; + + /// The number of elements in the wTypes array. wNumTypes must be 2 or greater but cannot exceed 8. + public ushort wNumTypes; + + /// + /// A BYTE array that contains a bitmap which specifies the RR types that are present in the next domain. Each bit in the + /// array corresponds to a DNS Record Type as defined in section 5.2 of RFC 2535. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public ushort[] wTypes; + } + + /// + /// The DNS_OPT_DATA structure represents a DNS Option (OPT) resource record (RR) as specified in section 4 of RFC 2671. + /// + /// + /// The DNS_OPT_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_opt_data typedef struct { WORD wDataLength; WORD wPad; + // #if ... BYTE Data[]; #else BYTE Data[1]; #endif } DNS_OPT_DATA, *PDNS_OPT_DATA; + [PInvokeData("windns.h", MSDNShortId = "a8e23127-a625-4206-abe8-0787b4ac0f30")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(wDataLength))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_OPT_DATA + { + /// The length, in bytes, of Data. + public ushort wDataLength; + + /// Reserved. Do not use. + public ushort wPad; + + /// A BYTE array that contains variable transport level information as specified in section 4 of RFC 2671. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Data; + } + + /// + /// The DNS_PROXY_INFORMATION structure contains the proxy information for a DNS server's name resolution policy table. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_proxy_information typedef struct DNS_PROXY_INFORMATION { + // ULONG version; DNS_PROXY_INFORMATION_TYPE proxyInformationType; PWSTR proxyName; } DNS_PROXY_INFORMATION; + [PInvokeData("windns.h", MSDNShortId = "cfe7653f-7e68-4e50-ba67-bd441f837ef8")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_PROXY_INFORMATION + { + /// A value that specifies the structure version. This value must be 1. + public uint version; + + /// A DNS_PROXY_INFORMATION_TYPE enumeration that contains the proxy information type. + public DNS_PROXY_INFORMATION_TYPE proxyInformationType; + + /// + /// + /// A pointer to a string that contains the proxy server name if proxyInformationType is + /// DNS_PROXY_INFORMATION_PROXY_NAME. Otherwise, this member is ignored. + /// + /// Note To free this string, use the DnsFreeProxyName function. + /// + public IntPtr proxyName; + + /// + public override string ToString() => $"{proxyInformationType}{(proxyInformationType == DNS_PROXY_INFORMATION_TYPE.DNS_PROXY_INFORMATION_PROXY_NAME ? $" {StringHelper.GetString(proxyName, CharSet.Unicode)}" : "")}"; + } + + /// The DNS_PTR_DATA structure represents a DNS pointer (PTR) record as specified in section 3.3.12 of RFC 1035. + /// + /// The DNS_PTR_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_ptr_dataa typedef struct { PSTR pNameHost; } + // DNS_PTR_DATAA, *PDNS_PTR_DATAA; + [PInvokeData("windns.h", MSDNShortId = "8b7f8898-ac91-46da-876c-889c427068a3")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_PTR_DATA + { + /// A pointer to a string that represents the pointer (PTR) record data. + [MarshalAs(UnmanagedType.LPTStr)] public string pNameHost; + } + + /// A DNS_QUERY_CANCEL structure can be used to cancel an asynchronous DNS query. + /// This structure is returned in the pCancelHandle parameter from a previous call to DnsQueryEx. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_query_cancel typedef struct _DNS_QUERY_CANCEL { CHAR + // Reserved[32]; } DNS_QUERY_CANCEL, *PDNS_QUERY_CANCEL; + [PInvokeData("windns.h", MSDNShortId = "543C6F9B-3200-44F6-A2B7-A5C7F5A927DB")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_QUERY_CANCEL + { + /// Contains a handle to the asynchronous query to cancel. Applications must not modify this value. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] + public byte[] Reserved; + } + + /// The DNS_QUERY_REQUEST structure contains the DNS query parameters used in a call to DnsQueryEx. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_query_request typedef struct _DNS_QUERY_REQUEST { ULONG + // Version; PCWSTR QueryName; WORD QueryType; ULONG64 QueryOptions; PDNS_ADDR_ARRAY pDnsServerList; ULONG InterfaceIndex; + // PDNS_QUERY_COMPLETION_ROUTINE pQueryCompletionCallback; PVOID pQueryContext; } DNS_QUERY_REQUEST, *PDNS_QUERY_REQUEST; + [PInvokeData("windns.h", MSDNShortId = "9C382800-DE71-4481-AC8D-9F89D6F59EE6")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_QUERY_REQUEST + { + /// + /// The structure version must be one of the following: + /// DNS_QUERY_REQUEST_VERSION1 (1) + /// + public uint Version; + + /// + /// A pointer to a string that represents the DNS name to query. + /// Note If QueryName is NULL, the query is for the local machine name. + /// + [MarshalAs(UnmanagedType.LPWStr)] public string QueryName; + + /// + /// A value that represents the Resource Record (RR) DNS Record Type that is queried. QueryType determines the format of + /// data pointed to by pQueryRecords returned in the DNS_QUERY_RESULT structure. For example, if the value of + /// wType is DNS_TYPE_A, the format of data pointed to by pQueryRecords is DNS_A_DATA. + /// + public DNS_TYPE QueryType; + + /// + /// 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 + /// + public DNS_QUERY_OPTIONS QueryOptions; + + /// A pointer to a DNS_ADDR_ARRAY structure that contains a list of DNS servers to use in the query. + public IntPtr pDnsServerList; + + /// + /// A value that contains the interface index over which the query is sent. If InterfaceIndex is 0, all interfaces will + /// be considered. + /// + public uint InterfaceIndex; + + /// + /// + /// A pointer to a DNS_QUERY_COMPLETION_ROUTINE callback that is used to return the results of an asynchronous query from a call + /// to DnsQueryEx. + /// + /// Note If NULL, DnsQueryEx is called synchronously. + /// + [MarshalAs(UnmanagedType.FunctionPtr)] + public DNS_QUERY_COMPLETION_ROUTINE pQueryCompletionCallback; + + /// A pointer to a user context. + public HDNSCONTEXT pQueryContext; + } + + /// A DNS_QUERY_RESULT structure contains the DNS query results returned from a call to DnsQueryEx. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_query_result typedef struct _DNS_QUERY_RESULT { ULONG + // Version; DNS_STATUS QueryStatus; ULONG64 QueryOptions; PDNS_RECORD pQueryRecords; PVOID Reserved; } DNS_QUERY_RESULT, *PDNS_QUERY_RESULT; + [PInvokeData("windns.h", MSDNShortId = "03EB1DC2-FAB0-45C5-B438-E8FFDD218F09")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_QUERY_RESULT + { + /// + /// The structure version must be one of the following: + /// DNS_QUERY_REQUEST_VERSION1 (1) + /// + public uint Version; + + /// + /// The return status of the call to DnsQueryEx. + /// + /// If the query was completed asynchronously and this structure was returned directly from DnsQueryEx, QueryStatus + /// contains DNS_REQUEST_PENDING. + /// + /// + /// If the query was completed synchronously or if this structure was returned by the DNS_QUERY_COMPLETION_ROUTINE DNS callback, + /// QueryStatus contains ERROR_SUCCESS if successful or the appropriate DNS-specific error code as defined in Winerror.h. + /// + /// + public DNS_STATUS QueryStatus; + + /// + /// A value that contains a bitmap of DNS Query Options that were used in the DNS query. Options can be combined and all options + /// override DNS_QUERY_STANDARD + /// + public ulong QueryOptions; + + /// + /// A pointer to a DNS_RECORD structure. + /// + /// If the query was completed asynchronously and this structure was returned directly from DnsQueryEx, pQueryRecords is NULL. + /// + /// + /// If the query was completed synchronously or if this structure was returned by the DNS_QUERY_COMPLETION_ROUTINE DNS callback, + /// pQueryRecords contains a list of Resource Records (RR) that comprise the response. + /// + /// Note Applications must free returned RR sets with the DnsRecordListFree function. + /// + public IntPtr pQueryRecords; + + /// + public IntPtr Reserved; + } + + /// The DNS_RECORD structure stores a DNS resource record (RR). + /// + /// When building a DNS_RECORD list as an input argument for the various DNS update routines found in the DNS API, all flags + /// in the DNS_RECORD structure should be set to zero. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_recorda typedef struct _DnsRecordA { struct _DnsRecordA + // *pNext; PSTR pName; WORD wType; WORD wDataLength; union { DWORD DW; DNS_RECORD_FLAGS S; } Flags; DWORD dwTtl; DWORD dwReserved; + // union { DNS_A_DATA A; DNS_SOA_DATAA SOA; DNS_SOA_DATAA Soa; DNS_PTR_DATAA PTR; DNS_PTR_DATAA Ptr; DNS_PTR_DATAA NS; DNS_PTR_DATAA + // Ns; DNS_PTR_DATAA CNAME; DNS_PTR_DATAA Cname; DNS_PTR_DATAA DNAME; DNS_PTR_DATAA Dname; DNS_PTR_DATAA MB; DNS_PTR_DATAA Mb; + // DNS_PTR_DATAA MD; DNS_PTR_DATAA Md; DNS_PTR_DATAA MF; DNS_PTR_DATAA Mf; DNS_PTR_DATAA MG; DNS_PTR_DATAA Mg; DNS_PTR_DATAA MR; + // DNS_PTR_DATAA Mr; DNS_MINFO_DATAA MINFO; DNS_MINFO_DATAA Minfo; DNS_MINFO_DATAA RP; DNS_MINFO_DATAA Rp; DNS_MX_DATAA MX; + // DNS_MX_DATAA Mx; DNS_MX_DATAA AFSDB; DNS_MX_DATAA Afsdb; DNS_MX_DATAA RT; DNS_MX_DATAA Rt; DNS_TXT_DATAA HINFO; DNS_TXT_DATAA + // Hinfo; DNS_TXT_DATAA ISDN; DNS_TXT_DATAA Isdn; DNS_TXT_DATAA TXT; DNS_TXT_DATAA Txt; DNS_TXT_DATAA X25; DNS_NULL_DATA Null; + // DNS_WKS_DATA WKS; DNS_WKS_DATA Wks; DNS_AAAA_DATA AAAA; DNS_KEY_DATA KEY; DNS_KEY_DATA Key; DNS_SIG_DATAA SIG; DNS_SIG_DATAA Sig; + // DNS_ATMA_DATA ATMA; DNS_ATMA_DATA Atma; DNS_NXT_DATAA NXT; DNS_NXT_DATAA Nxt; DNS_SRV_DATAA SRV; DNS_SRV_DATAA Srv; + // DNS_NAPTR_DATAA NAPTR; DNS_NAPTR_DATAA Naptr; DNS_OPT_DATA OPT; DNS_OPT_DATA Opt; DNS_DS_DATA DS; DNS_DS_DATA Ds; DNS_RRSIG_DATAA + // RRSIG; DNS_RRSIG_DATAA Rrsig; DNS_NSEC_DATAA NSEC; DNS_NSEC_DATAA Nsec; DNS_DNSKEY_DATA DNSKEY; DNS_DNSKEY_DATA Dnskey; + // DNS_TKEY_DATAA TKEY; DNS_TKEY_DATAA Tkey; DNS_TSIG_DATAA TSIG; DNS_TSIG_DATAA Tsig; DNS_WINS_DATA WINS; DNS_WINS_DATA Wins; + // DNS_WINSR_DATAA WINSR; DNS_WINSR_DATAA WinsR; DNS_WINSR_DATAA NBSTAT; DNS_WINSR_DATAA Nbstat; DNS_DHCID_DATA DHCID; + // DNS_NSEC3_DATA NSEC3; DNS_NSEC3_DATA Nsec3; DNS_NSEC3PARAM_DATA NSEC3PARAM; DNS_NSEC3PARAM_DATA Nsec3Param; DNS_TLSA_DATA TLSA; + // DNS_TLSA_DATA Tlsa; DNS_UNKNOWN_DATA UNKNOWN; DNS_UNKNOWN_DATA Unknown; PBYTE pDataPtr; } Data; } DNS_RECORDA, *PDNS_RECORDA; + [PInvokeData("windns.h", MSDNShortId = "ab7b96a5-346f-4e01-bb2a-885f44764590")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode, Size = 88)] + public struct DNS_RECORD + { + /// A pointer to the next DNS_RECORD structure. + public IntPtr pNext; + + /// + /// A pointer to a string that represents the domain name of the record set. This must be in the string format that corresponds + /// to the function called, such as ANSI, Unicode, or UTF8. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string pName; + + /// + /// 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. + /// + public DNS_TYPE wType; + + /// + /// The length, in bytes, of Data. For fixed-length data types, this value is the size of the corresponding data type, + /// such as sizeof(DNS_A_DATA). For the non-fixed data types, use one of the following macros to determine the length of + /// the data: + /// + public ushort wDataLength; + + /// A set of flags in the form of a DNS_RECORD_FLAGS structure. + public DNS_RECORD_FLAGS Flags; + + /// The DNS RR's Time To Live value (TTL), in seconds. + public uint dwTtl; + + /// Reserved. Do not use. + public uint dwReserved; + + /// The DNS RR data type is determined by wType and is one of the following members: + private IntPtr _Data; + + /// Gets the data value based on the value of . + /// The value of . + public object Data + { + get + { + if (wType == 0 || wDataLength == 0) return null; + var type = CorrespondingTypeAttribute.GetCorrespondingTypes(wType, CorrespondingAction.GetSet).FirstOrDefault(); + var ptr = DataPtr; + return type is null ? ptr : ptr.Convert(wDataLength, type, CharSet.Unicode); + } + set + { + DataPtr.Write(value); + wDataLength = (ushort)Marshal.SizeOf(value); + } + } + + private IntPtr DataPtr + { + get + { + unsafe + { + fixed (void* p = &pNext) + { + return (IntPtr)((byte*)p + 32); + } + } + } + } + + /* + /// The DNS RR data type is determined by wType and is one of the following members: + [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)] + public struct DNS_RECORD_DATA + { + /// The RR data type is DNS_A_DATA. The value of wType is DNS_TYPE_A. + [FieldOffset(0)] public DNS_A_DATA A; + + /// The RR data type is DNS_SOA_DATA. The value of wType is DNS_TYPE_SOA. + [FieldOffset(0)] public DNS_SOA_DATA SOA; + + /// The RR data type is DNS_SOA_DATA. The value of wType is DNS_TYPE_SOA. + [FieldOffset(0)] public DNS_SOA_DATA Soa; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA PTR; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Ptr; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA NS; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Ns; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA CNAME; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Cname; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA DNAME; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Dname; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA MB; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Mb; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA MD; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Md; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA MF; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Mf; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA MG; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Mg; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA MR; + + /// The RR data type is DNS_PTR_DATA. The value of wType is DNS_TYPE_PTR. + [FieldOffset(0)] public DNS_PTR_DATA Mr; + + /// The RR data type is DNS_MINFO_DATA. The value of wType is DNS_TYPE_MINFO. + [FieldOffset(0)] public DNS_MINFO_DATA MINFO; + + /// The RR data type is DNS_MINFO_DATA. The value of wType is DNS_TYPE_MINFO. + [FieldOffset(0)] public DNS_MINFO_DATA Minfo; + + /// The RR data type is DNS_MINFO_DATA. The value of wType is DNS_TYPE_MINFO. + [FieldOffset(0)] public DNS_MINFO_DATA RP; + + /// The RR data type is DNS_MINFO_DATA. The value of wType is DNS_TYPE_MINFO. + [FieldOffset(0)] public DNS_MINFO_DATA Rp; + + /// The RR data type is DNS_MX_DATA. The value of wType is DNS_TYPE_MX. + [FieldOffset(0)] public DNS_MX_DATA MX; + + /// The RR data type is DNS_MX_DATA. The value of wType is DNS_TYPE_MX. + [FieldOffset(0)] public DNS_MX_DATA Mx; + + /// The RR data type is DNS_MX_DATA. The value of wType is DNS_TYPE_MX. + [FieldOffset(0)] public DNS_MX_DATA AFSDB; + + /// The RR data type is DNS_MX_DATA. The value of wType is DNS_TYPE_MX. + [FieldOffset(0)] public DNS_MX_DATA Afsdb; + + /// The RR data type is DNS_MX_DATA. The value of wType is DNS_TYPE_MX. + [FieldOffset(0)] public DNS_MX_DATA RT; + + /// The RR data type is DNS_MX_DATA. The value of wType is DNS_TYPE_MX. + [FieldOffset(0)] public DNS_MX_DATA Rt; + + /// The RR data type is DNS_TXT_DATA. The value of wType is DNS_TYPE_TXT. + [FieldOffset(0)] public DNS_TXT_DATA HINFO; + + /// The RR data type is DNS_TXT_DATA. The value of wType is DNS_TYPE_TXT. + [FieldOffset(0)] public DNS_TXT_DATA Hinfo; + + /// The RR data type is DNS_TXT_DATA. The value of wType is DNS_TYPE_TXT. + [FieldOffset(0)] public DNS_TXT_DATA ISDN; + + /// The RR data type is DNS_TXT_DATA. The value of wType is DNS_TYPE_TXT. + [FieldOffset(0)] public DNS_TXT_DATA Isdn; + + /// The RR data type is DNS_TXT_DATA. The value of wType is DNS_TYPE_TXT. + [FieldOffset(0)] public DNS_TXT_DATA TXT; + + /// The RR data type is DNS_TXT_DATA. The value of wType is DNS_TYPE_TXT. + [FieldOffset(0)] public DNS_TXT_DATA Txt; + + /// The RR data type is DNS_TXT_DATA. The value of wType is DNS_TYPE_TXT. + [FieldOffset(0)] public DNS_TXT_DATA X25; + + /// The RR data type is DNS_NULL_DATA. The value of wType is DNS_TYPE_NULL. + [FieldOffset(0)] public DNS_NULL_DATA Null; + + /// The RR data type is DNS_WKS_DATA. The value of wType is DNS_TYPE_WKS. + [FieldOffset(0)] public DNS_WKS_DATA WKS; + + /// The RR data type is DNS_WKS_DATA. The value of wType is DNS_TYPE_WKS. + [FieldOffset(0)] public DNS_WKS_DATA Wks; + + /// The RR data type is DNS_AAAA_DATA. The value of wType is DNS_TYPE_AAAA. + [FieldOffset(0)] public DNS_AAAA_DATA AAAA; + + /// The RR data type is DNS_KEY_DATA. The value of wType is DNS_TYPE_KEY. + [FieldOffset(0)] public DNS_KEY_DATA KEY; + + /// The RR data type is DNS_KEY_DATA. The value of wType is DNS_TYPE_KEY. + [FieldOffset(0)] public DNS_KEY_DATA Key; + + /// The RR data type is DNS_SIG_DATA. The value of wType is DNS_TYPE_SIG. + [FieldOffset(0)] public DNS_SIG_DATA SIG; + + /// The RR data type is DNS_SIG_DATA. The value of wType is DNS_TYPE_SIG. + [FieldOffset(0)] public DNS_SIG_DATA Sig; + + /// The RR data type is DNS_ATMA_DATA. The value of wType is DNS_TYPE_ATMA. + [FieldOffset(0)] public DNS_ATMA_DATA ATMA; + + /// The RR data type is DNS_ATMA_DATA. The value of wType is DNS_TYPE_ATMA. + [FieldOffset(0)] public DNS_ATMA_DATA Atma; + + /// The RR data type is DNS_NXT_DATA. The value of wType is DNS_TYPE_NXT. + [FieldOffset(0)] public DNS_NXT_DATA NXT; + + /// The RR data type is DNS_NXT_DATA. The value of wType is DNS_TYPE_NXT. + [FieldOffset(0)] public DNS_NXT_DATA Nxt; + + /// The RR data type is DNS_SRV_DATA. The value of wType is DNS_TYPE_SRV. + [FieldOffset(0)] public DNS_SRV_DATA SRV; + + /// The RR data type is DNS_SRV_DATA. The value of wType is DNS_TYPE_SRV. + [FieldOffset(0)] public DNS_SRV_DATA Srv; + + /// The RR data type is DNS_NAPTR_DATA. The value of wType is DNS_TYPE_NAPTR. + [FieldOffset(0)] public DNS_NAPTR_DATA NAPTR; + + /// The RR data type is DNS_NAPTR_DATA. The value of wType is DNS_TYPE_NAPTR. + [FieldOffset(0)] public DNS_NAPTR_DATA Naptr; + + /// The RR data type is DNS_OPT_DATA. The value of wType is DNS_TYPE_OPT. + [FieldOffset(0)] public DNS_OPT_DATA OPT; + + /// The RR data type is DNS_OPT_DATA. The value of wType is DNS_TYPE_OPT. + [FieldOffset(0)] public DNS_OPT_DATA Opt; + + /// The RR data type is DNS_DS_DATA. The value of wType is DNS_TYPE_DS. + [FieldOffset(0)] public DNS_DS_DATA DS; + + /// The RR data type is DNS_DS_DATA. The value of wType is DNS_TYPE_DS. + [FieldOffset(0)] public DNS_DS_DATA Ds; + + /// The RR data type is DNS_SIG_DATA. The value of wType is DNS_TYPE_RRSIG. + [FieldOffset(0)] public DNS_SIG_DATA RRSIG; + + /// The RR data type is DNS_SIG_DATA. The value of wType is DNS_TYPE_RRSIG. + [FieldOffset(0)] public DNS_SIG_DATA Rrsig; + + /// The RR data type is DNSEC_DATA. The value of wType is DNS_TYPEEC. + [FieldOffset(0)] public DNS_NSEC_DATA NSEC; + + /// The RR data type is DNSEC_DATA. The value of wType is DNS_TYPEEC. + [FieldOffset(0)] public DNS_NSEC_DATA Nsec; + + /// The RR data type is DNS_DNSKEY_DATA. The value of wType is DNS_TYPE_DNSKEY. + [FieldOffset(0)] public DNS_KEY_DATA DNSKEY; + + /// The RR data type is DNS_DNSKEY_DATA. The value of wType is DNS_TYPE_DNSKEY. + [FieldOffset(0)] public DNS_KEY_DATA Dnskey; + + /// The RR data type is DNS_TKEY_DATA. The value of wType is DNS_TYPE_TKEY. + [FieldOffset(0)] public DNS_TKEY_DATA TKEY; + + /// The RR data type is DNS_TKEY_DATA. The value of wType is DNS_TYPE_TKEY. + [FieldOffset(0)] public DNS_TKEY_DATA Tkey; + + /// The RR data type is DNS_TSIG_DATA. The value of wType is DNS_TYPE_TSIG. + [FieldOffset(0)] public DNS_TSIG_DATA TSIG; + + /// The RR data type is DNS_TSIG_DATA. The value of wType is DNS_TYPE_TSIG. + [FieldOffset(0)] public DNS_TSIG_DATA Tsig; + + /// The RR data type is DNS_WINS_DATA. The value of wType is DNS_TYPE_WINS. + [FieldOffset(0)] public DNS_WINS_DATA WINS; + + /// The RR data type is DNS_WINS_DATA. The value of wType is DNS_TYPE_WINS. + [FieldOffset(0)] public DNS_WINS_DATA Wins; + + /// The RR data type is DNS_WINSR_DATA. The value of wType is DNS_TYPE_WINSR. + [FieldOffset(0)] public DNS_WINSR_DATA WINSR; + + /// The RR data type is DNS_WINSR_DATA. The value of wType is DNS_TYPE_WINSR. + [FieldOffset(0)] public DNS_WINSR_DATA WinsR; + + /// The RR data type is DNS_WINSR_DATA. The value of wType is DNS_TYPE_WINSR. + [FieldOffset(0)] public DNS_WINSR_DATA NBSTAT; + + /// The RR data type is DNS_WINSR_DATA. The value of wType is DNS_TYPE_WINSR. + [FieldOffset(0)] public DNS_WINSR_DATA Nbstat; + + /// The RR data type is DNS_DHCID_DATA. The value of wType is DNS_TYPE_DHCID. + [FieldOffset(0)] public DNS_DHCID_DATA DHCID; + + /// The RR data type is DNS_NSEC3_DATA. The value of wType is DNS_TYPEEC3. + [FieldOffset(0)] public DNS_NSEC3_DATA NSEC3; + + /// The RR data type is DNS_NSEC3_DATA. The value of wType is DNS_TYPEEC3. + [FieldOffset(0)] public DNS_NSEC3_DATA Nsec3; + + /// The RR data type is DNS_NSEC3PARAM_DATA. The value of wType is DNS_TYPEEC3PARAM. + [FieldOffset(0)] public DNS_NSEC3PARAM_DATA NSEC3PARAM; + + /// The RR data type is DNS_NSEC3PARAM_DATA. The value of wType is DNS_TYPEEC3PARAM. + [FieldOffset(0)] public DNS_NSEC3PARAM_DATA Nsec3Param; + + /// The RR data type is DNS_TLSA_DATA. The value of wType is DNS_TYPE_TLSA. + [FieldOffset(0)] public DNS_TLSA_DATA TLSA; + + /// The RR data type is DNS_TLSA_DATA. The value of wType is DNS_TYPE_TLSA. + [FieldOffset(0)] public DNS_TLSA_DATA Tlsa; + + /// The RR data type is DNS_UNKNOWN_DATA. The value of wType is DNS_TYPE_UNKNOWN. + [FieldOffset(0)] public DNS_UNKNOWN_DATA UNKNOWN; + + /// The RR data type is DNS_UNKNOWN_DATA. The value of wType is DNS_TYPE_UNKNOWN. + [FieldOffset(0)] public DNS_UNKNOWN_DATA Unknown; + + /// + [FieldOffset(0)] public IntPtr pDataPtr; + } + */ + } + + /// The DNS_RECORD_FLAGS structure is used to set flags for use in the DNS_RECORD structure. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_record_flags typedef struct _DnsRecordFlags { DWORD + // Section : 2; DWORD Delete : 1; DWORD CharSet : 2; DWORD Unused : 3; DWORD Reserved : 24; } DNS_RECORD_FLAGS; + [PInvokeData("windns.h", MSDNShortId = "53c1c8bc-20b0-4b15-b2b6-9c9854f73ee3")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_RECORD_FLAGS + { + /// A value that contains a bitmap of DNS Record Flags. + public uint DW; + + /// A DNS_SECTION value that specifies the section of interest returned from the DnsQuery function call. + public uint Section { get => BitHelper.GetBits(DW, 0, 2); set => BitHelper.SetBits(ref DW, 0, 2, value); } + + /// Reserved. Do not use. + public bool Delete { get => BitHelper.GetBit(DW, 2); set => BitHelper.SetBit(ref DW, 2, value); } + + /// A DNS_CHARSET value that specifies the character set used in the associated function call. + public uint CharSet { get => BitHelper.GetBits(DW, 3, 2); set => BitHelper.SetBits(ref DW, 3, 2, value); } + + /// Reserved. Do not use. + public uint Unused { get => BitHelper.GetBits(DW, 5, 3); set => BitHelper.SetBits(ref DW, 5, 3, value); } + } + + /// The DNS_RRSET structure contains information about a DNS Resource Record (RR) set. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_rrset typedef struct _DnsRRSet { PDNS_RECORD pFirstRR; + // PDNS_RECORD pLastRR; } DNS_RRSET, *PDNS_RRSET; + [PInvokeData("windns.h", MSDNShortId = "bd87a8db-ca27-490b-85f4-912297b77a2b")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_RRSET + { + /// A pointer to a DNS_RECORD structure that contains the first DNS RR in the set. + public IntPtr pFirstRR; + + /// A pointer to a DNS_RECORD structure that contains the last DNS RR in the set. + public IntPtr pLastRR; + } + + /// Contains the query parameters used in a call to DnsServiceBrowse. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_service_browse_request typedef struct + // _DNS_SERVICE_BROWSE_REQUEST { ULONG Version; ULONG InterfaceIndex; PCWSTR QueryName; union { PDNS_SERVICE_BROWSE_CALLBACK + // pBrowseCallback; DNS_QUERY_COMPLETION_ROUTINE *pBrowseCallbackV2; }; PVOID pQueryContext; } DNS_SERVICE_BROWSE_REQUEST, *PDNS_SERVICE_BROWSE_REQUEST; + [PInvokeData("windns.h")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_SERVICE_BROWSE_REQUEST + { + /// + /// The structure version must be either DNS_QUERY_REQUEST_VERSION1 or DNS_QUERY_REQUEST_VERSION2. The value + /// determines which of or is active. + /// + public uint Version; + + /// + /// A value that contains the interface index over which the query is sent. If is 0, then all interfaces will be considered. + /// + public uint InterfaceIndex; + + /// + /// A pointer to a string that represents the service type whose matching services you wish to browse for. It takes the + /// generalized form "_<ServiceType>._<TransportProtocol>.local". For example, "_http._tcp.local", which defines a + /// query to browse for http services on the local link. + /// + [MarshalAs(UnmanagedType.LPWStr)] public string QueryName; + + /// The callback function based on . + public DNS_SERVICE_BROWSE_REQUEST_CALLBACK Callback; + + /// The callback function based on . + [StructLayout(LayoutKind.Explicit)] + public struct DNS_SERVICE_BROWSE_REQUEST_CALLBACK + { + /// + /// A pointer to a function (of type DNS_SERVICE_BROWSE_CALLBACK) that represents the callback to be invoked asynchronously. + /// This field is used if is DNS_QUERY_REQUEST_VERSION1. + /// + [FieldOffset(0), MarshalAs(UnmanagedType.FunctionPtr)] public DNS_SERVICE_BROWSE_CALLBACK pBrowseCallback; + + /// + /// A pointer to a function (of type DNS_QUERY_COMPLETION_ROUTINE) that represents the callback to be invoked + /// asynchronously. This field is used if is DNS_QUERY_REQUEST_VERSION2. + /// + [FieldOffset(0), MarshalAs(UnmanagedType.FunctionPtr)] public DNS_QUERY_COMPLETION_ROUTINE pBrowseCallbackV2; + } + + /// A pointer to a user context. + public HDNSCONTEXT pQueryContext; + } + + /// Used to cancel an asynchronous DNS-SD operation. + /// This structure is returned in the parameter from a previous call to DnsServiceBrowse, DnsServiceRegister, or DnsServiceResolve. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_service_cancel typedef struct _DNS_SERVICE_CANCEL { PVOID + // reserved; } DNS_SERVICE_CANCEL, *PDNS_SERVICE_CANCEL; + [PInvokeData("windns.h")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_SERVICE_CANCEL + { + /// + /// Contains a handle associated with the asynchronous operation to cancel. Your application must not modify this value. + /// + public IntPtr reserved; + } + + /// Represents a DNS service running on the network. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_service_instance typedef struct _DNS_SERVICE_INSTANCE { + // #if ... DNSSD_RPC_STRING pszInstanceName; #else LPWSTR pszInstanceName; #endif #if ... DNSSD_RPC_STRING pszHostName; #else LPWSTR + // pszHostName; #endif IP4_ADDRESS *ip4Address; IP6_ADDRESS *ip6Address; WORD wPort; WORD wPriority; WORD wWeight; DWORD + // dwPropertyCount; #if ... DNSSD_RPC_STRING *keys; #if ... DNSSD_RPC_STRING *values; #else PWSTR *keys; #endif #else PWSTR *values; + // #endif DWORD dwInterfaceIndex; } DNS_SERVICE_INSTANCE, *PDNS_SERVICE_INSTANCE; + [PInvokeData("windns.h")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_SERVICE_INSTANCE + { + /// + /// A string that represents the service name. This is a fully qualified domain name that begins with a service name, and ends + /// with ".local". It takes the generalized form "<ServiceName>._<ServiceType>._<TransportProtocol>.local". + /// For example, "MyMusicServer._http._tcp.local". + /// + [MarshalAs(UnmanagedType.LPWStr)] public string pszInstanceName; + + /// A string that represents the name of the host of the service. + [MarshalAs(UnmanagedType.LPWStr)] public string pszHostName; + + /// A pointer to an IP4_ADDRESS structure that represents the service-associated IPv4 address. + public IntPtr ip4Address; + + /// A pointer to an IP6_ADDRESS structure that represents the service-associated IPv6 address. + public IntPtr ip6Address; + + /// A value that represents the port on which the service is running. + public ushort wPort; + + /// A value that represents the service priority. + public ushort wPriority; + + /// A value that represents the service weight. + public ushort wWeight; + + /// The number of properties—defines the number of elements in the arrays of the and parameters. + public uint dwPropertyCount; + + /// + public IntPtr keys; + + /// + public IntPtr values; + + /// A value that contains the interface index on which the service was discovered. + public uint dwInterfaceIndex; + } + + /// + /// Contains the information necessary to advertise a service using DnsServiceRegister, or to stop advertising it using DnsServiceDeRegister. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_service_register_request typedef struct + // _DNS_SERVICE_REGISTER_REQUEST { ULONG Version; ULONG InterfaceIndex; PDNS_SERVICE_INSTANCE pServiceInstance; + // PDNS_SERVICE_REGISTER_COMPLETE pRegisterCompletionCallback; PVOID pQueryContext; HANDLE hCredentials; BOOL unicastEnabled; } + // DNS_SERVICE_REGISTER_REQUEST, *PDNS_SERVICE_REGISTER_REQUEST; + [PInvokeData("windns.h")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_SERVICE_REGISTER_REQUEST + { + /// The structure version must be DNS_QUERY_REQUEST_VERSION1. + public uint Version; + + /// + /// A value that contains the interface index over which the service is to be advertised. If is 0, then all interfaces will be considered. + /// + public uint InterfaceIndex; + + /// A pointer to a DNS_SERVICE_INSTANCE structure that describes the service to be registered. + public IntPtr pServiceInstance; + + /// A pointer to a function (of type DNS_SERVICE_REGISTER_COMPLETE) that represents the callback to be invoked asynchronously. + [MarshalAs(UnmanagedType.FunctionPtr)] + public DNS_SERVICE_REGISTER_COMPLETE pRegisterCompletionCallback; + + /// A pointer to a user context. + public HDNSCONTEXT pQueryContext; + + /// Not used. + public HANDLE hCredentials; + + /// + /// if the DNS protocol should be used to advertise the service; if the mDNS + /// protocol should be used. + /// + [MarshalAs(UnmanagedType.Bool)] public bool unicastEnabled; + } + + /// + /// Contains the query parameters used in a call to DnsServiceResolve. Use that function, and this structure, after you've found a + /// specific service name that you'd like to connect to. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_service_resolve_request typedef struct + // _DNS_SERVICE_RESOLVE_REQUEST { ULONG Version; ULONG InterfaceIndex; PWSTR QueryName; PDNS_SERVICE_RESOLVE_COMPLETE + // pResolveCompletionCallback; PVOID pQueryContext; } DNS_SERVICE_RESOLVE_REQUEST, *PDNS_SERVICE_RESOLVE_REQUEST; + [PInvokeData("windns.h")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_SERVICE_RESOLVE_REQUEST + { + /// The structure version must be DNS_QUERY_REQUEST_VERSION1. + public uint Version; + + /// + /// A value that contains the interface index over which the query is sent. If is 0, then all interfaces will be considered. + /// + public uint InterfaceIndex; + + /// + /// A pointer to a string that represents the service name. This is a fully qualified domain name that begins with a service + /// name, and ends with ".local". It takes the generalized form + /// "<ServiceName>._<ServiceType>._<TransportProtocol>.local". For example, "MyMusicServer._http._tcp.local". + /// + [MarshalAs(UnmanagedType.LPWStr)] public string QueryName; + + /// A pointer to a function (of type DNS_SERVICE_RESOLVE_COMPLETE) that represents the callback to be invoked asynchronously. + [MarshalAs(UnmanagedType.FunctionPtr)] + public DNS_SERVICE_RESOLVE_COMPLETE pResolveCompletionCallback; + + /// A pointer to a user context. + public HDNSCONTEXT pQueryContext; + } + + /// + /// The DNS_RRSIG_DATA structure represents a DNS Security Extensions (DNSSEC) cryptographic signature (SIG) resource record + /// (RR) as specified in RFC 4034. + /// + /// + /// The DNS_RRSIG_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_sig_dataa typedef struct { WORD wTypeCovered; BYTE + // chAlgorithm; BYTE chLabelCount; DWORD dwOriginalTtl; DWORD dwExpiration; DWORD dwTimeSigned; WORD wKeyTag; WORD wSignatureLength; + // PSTR pNameSigner; #if ... BYTE Signature[]; #else BYTE Signature[1]; #endif } DNS_SIG_DATAA, *PDNS_SIG_DATAA, DNS_RRSIG_DATAA, *PDNS_RRSIG_DATAA; + [PInvokeData("windns.h", MSDNShortId = "09c2f515-acc1-402f-8e62-a0d273031633")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(wSignatureLength))] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_SIG_DATA + { + /// The DNS Record Type of the signed RRs. + public ushort wTypeCovered; + + /// + /// + /// A value that specifies the algorithm used to generate Signature. The possible values are shown in the following table. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 1 + /// RSA/MD5 (RFC 2537) + /// + /// + /// 2 + /// Diffie-Hellman (RFC 2539) + /// + /// + /// 3 + /// DSA (RFC 2536) + /// + /// + /// 4 + /// Elliptic curve cryptography + /// + /// + /// 5 + /// RSA/SHA-1 (RFC 3110) + /// + /// + /// + public byte chAlgorithm; + + /// The number of labels in the original signature RR owner name as specified in section 3.1.3 of RFC 4034. + public byte chLabelCount; + + /// The Time-to-Live (TTL) value of the RR set signed by Signature. + public uint dwOriginalTtl; + + /// + /// The expiration date of Signature, expressed in seconds since the beginning of January 1, 1970, Greenwich Mean Time + /// (GMT), excluding leap seconds. + /// + public uint dwExpiration; + + /// + /// The date and time at which Signature becomes valid, expressed in seconds since the beginning of January 1, 1970, + /// Greenwich Mean Time (GMT), excluding leap seconds. + /// + public uint dwTimeSigned; + + /// + /// A value that represents the method to choose which public key is used to verify Signature as specified Appendix B of + /// RFC 4034. + /// + public ushort wKeyTag; + + /// + public ushort wSignatureLength; + + /// A pointer to a string that represents the name of the Signature generator. + [MarshalAs(UnmanagedType.LPTStr)] public string pNameSigner; + + /// A BYTE array that contains the RR set signature as specified in section 3.1.8 of RFC 4034. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] Signature; + } + + /// + /// The DNS_SOA_DATA structure represents a DNS start of authority (SOA) record as specified in section 3.3.13 of RFC 1035. + /// + /// + /// The DNS_SOA_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_soa_dataa typedef struct { PSTR pNamePrimaryServer; PSTR + // pNameAdministrator; DWORD dwSerialNo; DWORD dwRefresh; DWORD dwRetry; DWORD dwExpire; DWORD dwDefaultTtl; } DNS_SOA_DATAA, *PDNS_SOA_DATAA; + [PInvokeData("windns.h", MSDNShortId = "715cbb70-91fe-47ac-a713-1fe0701d4f8c")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_SOA_DATA + { + /// + /// A pointer to a string that represents the name of the authoritative DNS server for the zone to which the record belongs. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string pNamePrimaryServer; + + /// A pointer to a string that represents the name of the responsible party for the zone to which the record belongs. + [MarshalAs(UnmanagedType.LPTStr)] public string pNameAdministrator; + + /// The serial number of the SOA record. + public uint dwSerialNo; + + /// The time, in seconds, before the zone containing this record should be refreshed. + public uint dwRefresh; + + /// The time, in seconds, before retrying a failed refresh of the zone to which this record belongs. + public uint dwRetry; + + /// The time, in seconds, before an unresponsive zone is no longer authoritative. + public uint dwExpire; + + /// + /// The lower limit on the time, in seconds, that a DNS server or caching resolver are allowed to cache any resource records + /// (RR) from the zone to which this record belongs. + /// + public uint dwDefaultTtl; + } + + /// The DNS_SRV_DATA structure represents a DNS service (SRV) record as specified in RFC 2782. + /// + /// The DNS_SRV_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_srv_dataa typedef struct { PSTR pNameTarget; WORD + // wPriority; WORD wWeight; WORD wPort; WORD Pad; } DNS_SRV_DATAA, *PDNS_SRV_DATAA; + [PInvokeData("windns.h", MSDNShortId = "212db7ac-a5e3-4e58-b1c2-0eb551403dfc")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_SRV_DATA + { + /// A pointer to a string that represents the target host. + [MarshalAs(UnmanagedType.LPTStr)] public string pNameTarget; + + /// + /// The priority of the target host specified in pNameTarget. Lower numbers imply higher priority to clients attempting + /// to use this service. + /// + public ushort wPriority; + + /// + /// The relative weight of the target host in pNameTarget to other hosts with the same wPriority. The chances of + /// using this host should be proportional to its weight. + /// + public ushort wWeight; + + /// The port used on the target host for this service. + public ushort wPort; + + /// Reserved for padding. Do not use. + public ushort Pad; + } + + /// + /// The DNS_TKEY_DATA structure represents a DNS TKEY resource record, used to establish and delete an algorithm's + /// shared-secret keys between a DNS resolver and server as specified in RFC 2930. + /// + /// + /// The DNS_TKEY_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_tkey_dataa typedef struct { PSTR pNameAlgorithm; PBYTE + // pAlgorithmPacket; PBYTE pKey; PBYTE pOtherData; DWORD dwCreateTime; DWORD dwExpireTime; WORD wMode; WORD wError; WORD wKeyLength; + // WORD wOtherLength; UCHAR cAlgNameLength; BOOL bPacketPointers; } DNS_TKEY_DATAA, *PDNS_TKEY_DATAA; + [PInvokeData("windns.h", MSDNShortId = "4dad3449-3e41-47d9-89c2-10fa6e51573b")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_TKEY_DATA + { + /// A pointer to a string that represents the name of the key as defined in section 2.1 of RFC 2930. + [MarshalAs(UnmanagedType.LPTStr)] public string pNameAlgorithm; + + /// + /// A pointer to a string representing the name of the algorithm as defined in section 2.3 of RFC 2930. pKey is used to + /// derive the algorithm specific keys. + /// + public IntPtr pAlgorithmPacket; + + /// A pointer to the variable-length shared-secret key. + public IntPtr pKey; + + /// Reserved. Do not use. + public IntPtr pOtherData; + + /// + /// The date and time at which the key was created, expressed in seconds since the beginning of January 1, 1970, Greenwich Mean + /// Time (GMT), excluding leap seconds. + /// + public uint dwCreateTime; + + /// + /// The expiration date of the key, expressed in seconds since the beginning of January 1, 1970, Greenwich Mean Time (GMT), + /// excluding leap seconds. + /// + public uint dwExpireTime; + + /// + /// + /// A scheme used for key agreement or the purpose of the TKEY DNS Message. Possible values for wMode are listed below: + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// DNS_TKEY_MODE_SERVER_ASSIGN + /// The key is assigned by the DNS server and is not negotiated. + /// + /// + /// DNS_TKEY_MODE_DIFFIE_HELLMAN + /// The Diffie-Hellman key exchange algorithm is used to negotiate the key. + /// + /// + /// DNS_TKEY_MODE_GSS + /// The key is exchanged through Generic Security Services-Application Program Interface (GSS-API) negotiation. + /// + /// + /// DNS_TKEY_MODE_RESOLVER_ASSIGN + /// The key is assigned by the DNS resolver and is not negotiated. + /// + /// + /// + public DNS_TKEY_MODE wMode; + + /// + /// An error, expressed in expanded RCODE format that covers TSIG and TKEY RR processing. + /// + /// + /// Value + /// Meaning + /// + /// + /// DNS_RCODE_BADSIG + /// The pSignature of the DNS_TSIG_DATA RR is bad. + /// + /// + /// DNS_RCODE_BADKEY + /// The pKey field is bad. + /// + /// + /// DNS_RCODE_BADTIME + /// A timestamp is bad. + /// + /// + /// + public DNS_RCODE wError; + + /// Length, in bytes, of the pKey member. + public ushort wKeyLength; + + /// The length, in bytes, of the pOtherData member. + public ushort wOtherLength; + + /// The length, in bytes, of the pNameAlgorithm member. + public byte cAlgNameLength; + + /// Reserved. Do not use. + [MarshalAs(UnmanagedType.Bool)] public bool bPacketPointers; + } + + /// Undocumented. + [PInvokeData("windns.h")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(bCertificateAssociationDataLength))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_TLSA_DATA + { + /// + public byte bCertUsage; + + /// + public byte bSelector; + + /// + public byte bMatchingType; + + /// + public ushort bCertificateAssociationDataLength; + + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] + public byte[] bPad; // keep certificate association data field aligned + + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] bCertificateAssociationData; + } + + /// + /// The DNS_TSIG_DATA structure represents a secret key transaction authentication (TSIG) resource record (RR) as specified + /// in RFC 2845 and RFC 3645. + /// + /// + /// The DNS_TSIG_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_tsig_dataa typedef struct { PSTR pNameAlgorithm; PBYTE + // pAlgorithmPacket; PBYTE pSignature; PBYTE pOtherData; LONGLONG i64CreateTime; WORD wFudgeTime; WORD wOriginalXid; WORD wError; + // WORD wSigLength; WORD wOtherLength; UCHAR cAlgNameLength; BOOL bPacketPointers; } DNS_TSIG_DATAA, *PDNS_TSIG_DATAA; + [PInvokeData("windns.h", MSDNShortId = "32077169-d319-45c0-982f-8d470cd70111")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_TSIG_DATA + { + /// + /// A pointer to a string that represents the name of the key used to generate pSignature as defined in section 2.3 of + /// RFC 2845. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string pNameAlgorithm; + + /// + /// + /// A pointer to a string that represents the name of the algorithm used to generate pSignature as defined in section 2.3 + /// of RFC 2845. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// "gss.microsoft.com" + /// + /// Windows 2000 Server only: Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS (GSS-API) as + /// defined in RFC 3645. + /// + /// + /// + /// "gss-tsig" + /// Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS (GSS-API) as defined in RFC 3645. + /// + /// + /// + public IntPtr pAlgorithmPacket; + + /// + /// A pointer to the Message Authentication Code (MAC) generated by the algorithm in pAlgorithmPacket. The length, in + /// bytes, and composition of pSignature are determined by pAlgorithmPacket. + /// + public IntPtr pSignature; + + /// + /// If wError contains the RCODE, BADTIME, pOtherData is a BYTE array that contains the server's current + /// time, otherwise it is NULL. Time is expressed in seconds since the beginning of January 1, 1970, Greenwich Mean Time + /// (GMT), excluding leap seconds. + /// + public IntPtr pOtherData; + + /// + /// The time pSignature was generated, expressed in seconds since the beginning of January 1, 1970, Greenwich Mean Time + /// (GMT), excluding leap seconds. + /// + public int i64CreateTime; + + /// The time, in seconds, i64CreateTime may be in error. + public ushort wFudgeTime; + + /// The Xid identifier of the original message. + public ushort wOriginalXid; + + /// + /// An error, expressed in expanded RCODE format that covers TSIG and TKEY RR processing. + /// + /// + /// Value + /// Meaning + /// + /// + /// DNS_RCODE_BADSIG + /// The pSignature field is bad. + /// + /// + /// DNS_RCODE_BADKEY + /// The pKey field of the DNS_TKEY_DATA RR is bad. + /// + /// + /// DNS_RCODE_BADTIME + /// A timestamp is bad. + /// + /// + /// + public DNS_RCODE wError; + + /// The length, in bytes, of the pSignature member. + public ushort wSigLength; + + /// The length, in bytes, of the pOtherData member. + public ushort wOtherLength; + + /// The length, in bytes, of the pAlgorithmPacket member. + public byte cAlgNameLength; + + /// Reserved for future use. Do not use. + [MarshalAs(UnmanagedType.Bool)] public bool bPacketPointers; + } + + /// The DNS_TXT_DATA structure represents a DNS text (TXT) record as specified in section 3.3.14 of RFC 1035. + /// + /// The DNS_TXT_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_txt_dataa typedef struct { DWORD dwStringCount; #if ... + // PSTR pStringArray[]; #else PSTR pStringArray[1]; #endif } DNS_TXT_DATAA, *PDNS_TXT_DATAA; + [PInvokeData("windns.h", MSDNShortId = "3ff643e2-d736-45d5-8cf8-ab5e63caf44b")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(dwStringCount))] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_TXT_DATA + { + /// The number of strings represented in pStringArray. + public uint dwStringCount; + + /// An array of strings representing the descriptive text of the TXT resource record. + [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.LPTStr, SizeConst = 1)] + public string[] pStringArray; + } + + /// Undocumented. + [PInvokeData("windns.h")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(dwByteCount))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_UNKNOWN_DATA + { + /// + public uint dwByteCount; + + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public byte[] bData; + } + + /// The DNS_WINS_DATA structure represents a DNS Windows Internet Name Service (WINS) record. + /// + /// The DNS_WINS_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_wins_data typedef struct { DWORD dwMappingFlag; DWORD + // dwLookupTimeout; DWORD dwCacheTimeout; DWORD cWinsServerCount; IP4_ADDRESS WinsServers[1]; } DNS_WINS_DATA, *PDNS_WINS_DATA; + [PInvokeData("windns.h", MSDNShortId = "df41c397-e662-42b4-9193-6776f9071898")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(cWinsServerCount))] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_WINS_DATA + { + /// + /// + /// The WINS mapping flag that specifies whether the record must be included in zone replication. dwMappingFlag must be + /// one of these mutually exclusive values: + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// DNS_WINS_FLAG_SCOPE + /// Record is not local, replicate across zones. + /// + /// + /// DNS_WINS_FLAG_LOCAL + /// Record is local, do not replicate. + /// + /// + /// + public DNS_WINS_FLAG dwMappingFlag; + + /// The time, in seconds, that a DNS Server attempts resolution using WINS lookup. + public uint dwLookupTimeout; + + /// The time, in seconds, that a DNS Server using WINS lookup may cache the WINS Server's response. + public uint dwCacheTimeout; + + /// The number of WINS Servers listed in WinsServers. + public uint cWinsServerCount; + + /// An array of IP4_ARRAY structures that contain the IPv4 address of the WINS lookup Servers. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public IP4_ADDRESS[] WinsServers; + } + + /// The DNS_WINSR_DATA structure represents a DNS Windows Internet Name Service reverse-lookup (WINSR) record. + /// + /// The DNS_WINSR_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_winsr_dataa typedef struct { DWORD dwMappingFlag; DWORD + // dwLookupTimeout; DWORD dwCacheTimeout; PSTR pNameResultDomain; } DNS_WINSR_DATAA, *PDNS_WINSR_DATAA; + [PInvokeData("windns.h", MSDNShortId = "a7e79e30-905f-42a5-a4de-02d71adfe95e")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct DNS_WINSR_DATA + { + /// + /// + /// The WINS mapping flag that specifies whether the record must be included into the zone replication. dwMappingFlag + /// must be one of these mutually exclusive values: + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// DNS_WINS_FLAG_SCOPE + /// Record is not local, replicate across zones. + /// + /// + /// DNS_WINS_FLAG_LOCAL + /// Record is local, do not replicate. + /// + /// + /// + public DNS_WINS_FLAG dwMappingFlag; + + /// The time, in seconds, that a DNS Server attempts resolution using WINS lookup. + public uint dwLookupTimeout; + + /// The time, in seconds, that a DNS Server using WINS lookup may cache the WINS Server's response. + public uint dwCacheTimeout; + + /// A pointer to a string that represents the domain name to append to the name returned by a WINS reverse-lookup. + [MarshalAs(UnmanagedType.LPTStr)] public string pNameResultDomain; + } + + /// + /// The DNS_WIRE_QUESTION structure contains information about a DNS question transmitted across the network as specified in + /// section 4.1.2 of RFC 1035.. + /// + /// When constructing a DNS message, the question name must precede the DNS_WIRE_QUESTION structure. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_wire_question typedef struct _DNS_WIRE_QUESTION { WORD + // QuestionType; WORD QuestionClass; } DNS_WIRE_QUESTION, *PDNS_WIRE_QUESTION; + [PInvokeData("windns.h", MSDNShortId = "50498f20-0896-4471-8355-edd997aa4bcd")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_WIRE_QUESTION + { + /// A value that represents the question section's DNS Question Type. + public ushort QuestionType; + + /// A value that represents the question section's DNS Question Class. + public ushort QuestionClass; + } + + /// + /// The DNS_WIRE_RECORD structure contains information about a DNS wire record transmitted across the network as specified in + /// section 4.1.3 of RFC 1035. + /// + /// + /// When constructing a DNS message, the DNS_WIRE_RECORD structure is immediately followed by the record data and is preceded + /// by the DNS RR's domain name. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_wire_record typedef struct _DNS_WIRE_RECORD { WORD + // RecordType; WORD RecordClass; DWORD TimeToLive; WORD DataLength; } DNS_WIRE_RECORD, *PDNS_WIRE_RECORD; + [PInvokeData("windns.h", MSDNShortId = "fb36930c-dd43-427a-8034-078c99497a3e")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_WIRE_RECORD + { + /// + /// A value that represents the RR DNS Response Type. RecordType determines the format of record data that follows the + /// DNS_WIRE_RECORD structure. For example, if the value of RecordType is DNS_TYPE_A, the data type of + /// record data is DNS_A_DATA. + /// + public DNS_TYPE RecordType; + + /// A value that represents the RR DNS Record Class. + public DNS_CLASS RecordClass; + + /// The DNS Resource Record's Time To Live value (TTL), in seconds. + public uint TimeToLive; + + /// The length, in bytes, of the DNS record data that follows the DNS_WIRE_RECORD. + public ushort DataLength; + } + + /// + /// The DNS_WKS_DATA structure represents a DNS well-known services (WKS) record as specified in section 3.4.2 of RFC 1035. + /// + /// + /// The DNS_WKS_DATA structure is used in conjunction with the DNS_RECORD structure to programmatically manage DNS entries. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-dns_wks_data typedef struct { IP4_ADDRESS IpAddress; UCHAR + // chProtocol; BYTE BitMask[1]; } DNS_WKS_DATA, *PDNS_WKS_DATA; + [PInvokeData("windns.h", MSDNShortId = "94477345-74e7-40bf-a75b-e4bf67f1c17b")] + [StructLayout(LayoutKind.Sequential)] + public struct DNS_WKS_DATA + { + /// An IP4_ADDRESS data type that contains the IPv4 address for this resource record (RR). + public IP4_ADDRESS IpAddress; + + /// + /// A value that represents the IP protocol for this RR as defined in RFC 1010. + /// Transmission Control Protocol (TCP) (6) + /// User Datagram Protocol (UDP) (17) + /// + public byte chProtocol; + + /// + /// A variable-length bitmask whose bits correspond to the port number of well known services offered by the protocol specified + /// in chProtocol. The bitmask has one bit for every port of the supported protocol, but must be a multiple of a + /// BYTE. Bit 0 corresponds to port 1, bit 1 corresponds to port 2, and so forth for a maximum of 1024 bits. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] + public byte[] BitMask; + } + + /// The IP4_ARRAY structure stores an array of IPv4 addresses. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-ip4_array typedef struct _IP4_ARRAY { DWORD AddrCount; #if + // ... IP4_ADDRESS AddrArray[]; #else IP4_ADDRESS AddrArray[1]; #endif } IP4_ARRAY, *PIP4_ARRAY; + [PInvokeData("windns.h", MSDNShortId = "4273a739-129c-4951-b6df-aef4332ce0cb")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(AddrCount))] + [StructLayout(LayoutKind.Sequential)] + public struct IP4_ARRAY + { + /// The number of IPv4 addresses in AddrArray. + public uint AddrCount; + + /// An array of IP4_ADDRESS data types that contains a list of IPv4 address. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public IP4_ADDRESS[] AddrArray; + } + + /// Contains information related to an ongoing MDNS query. Your application must not modify its contents. + /// This structure is for internal use only. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-mdns_query_handle typedef struct _MDNS_QUERY_HANDLE { WCHAR + // nameBuf[DNS_MAX_NAME_BUFFER_LENGTH]; WORD wType; PVOID pSubscription; PVOID pWnfCallbackParams; ULONG stateNameData[2]; } + // MDNS_QUERY_HANDLE, *PMDNS_QUERY_HANDLE; + [PInvokeData("windns.h")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct MDNS_QUERY_HANDLE + { + /// A value representing the queried name. + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = DNS_MAX_NAME_BUFFER_LENGTH)] public string nameBuf; + + /// A value representing the type of the query. + public DNS_OPCODE wType; + + /// Reserved. Do not use. + public IntPtr pSubscription; + + /// Reserved. Do not use. + public IntPtr pWnfCallbackParams; + + /// Reserved. Do not use. + public ulong stateNameData; + } + + /// Contains the necessary information to perform an mDNS query. + // https://docs.microsoft.com/en-us/windows/win32/api/windns/ns-windns-mdns_query_request typedef struct _MDNS_QUERY_REQUEST { ULONG + // Version; ULONG ulRefCount; PCWSTR Query; WORD QueryType; ULONG64 QueryOptions; ULONG InterfaceIndex; PMDNS_QUERY_CALLBACK + // pQueryCallback; PVOID pQueryContext; BOOL fAnswerReceived; ULONG ulResendCount; } MDNS_QUERY_REQUEST, *PMDNS_QUERY_REQUEST; + [PInvokeData("windns.h")] + [StructLayout(LayoutKind.Sequential)] + public struct MDNS_QUERY_REQUEST + { + /// The structure version must be DNS_QUERY_REQUEST_VERSION1. + public uint Version; + + /// Reserved. Do not use. + public uint ulRefCount; + + /// A string representing the name to be queried over mDNS. + [MarshalAs(UnmanagedType.LPWStr)] public string Query; + + /// A value representing the type of the records to be queried. See DNS_RECORD_TYPE for possible values. + public DNS_TYPE QueryType; + + /// A value representing the query options. DNS_QUERY_STANDARD is the only supported value. + public DNS_QUERY_OPTIONS QueryOptions; + + /// + /// A value that contains the interface index over which the service is to be advertised. If is 0, then all interfaces will be considered. + /// + public uint InterfaceIndex; + + /// + /// A pointer to a function (of type MDNS_QUERY_CALLBACK) that represents the callback to be invoked asynchronously whenever + /// mDNS results are available. + /// + [MarshalAs(UnmanagedType.FunctionPtr)] + public MDNS_QUERY_CALLBACK pQueryCallback; + + /// A pointer to a user context. + public HDNSCONTEXT pQueryContext; + + /// Reserved. Do not use. + [MarshalAs(UnmanagedType.Bool)] public bool fAnswerReceived; + + /// Reserved. Do not use. + public uint ulResendCount; + } + + /// Represents a DNS service running on the network. + [PInvokeData("windns.h")] + public class SafePDNS_SERVICE_INSTANCE : SafeHANDLE + { + private uint _dwInterfaceIndex; + private IP4_ADDRESS? _ip4Address; + private IP6_ADDRESS? _ip6Address; + private string[] _keys; + private string _pszHostName; + private string _pszInstanceName; + private string[] _values; + private ushort _wPort; + private ushort _wPriority; + private ushort _wWeight; + private bool populated = false; + + /// A value that contains the interface index on which the service was discovered. + public uint dwInterfaceIndex => PopulateFetch(ref _dwInterfaceIndex); + + /// A pointer to an IP4_ADDRESS structure that represents the service-associated IPv4 address. + public IP4_ADDRESS? ip4Address => PopulateFetch(ref _ip4Address); + + /// A pointer to an IP6_ADDRESS structure that represents the service-associated IPv6 address. + public IP6_ADDRESS? ip6Address => PopulateFetch(ref _ip6Address); + + /// + public string[] keys => PopulateFetch(ref _keys); + + /// A string that represents the name of the host of the service. + public string pszHostName => PopulateFetch(ref _pszHostName); + + /// + /// A string that represents the service name. This is a fully qualified domain name that begins with a service name, and ends + /// with ".local". It takes the generalized form "<ServiceName>._<ServiceType>._<TransportProtocol>.local". + /// For example, "MyMusicServer._http._tcp.local". + /// + public string pszInstanceName => PopulateFetch(ref _pszInstanceName); + + /// + public string[] values => PopulateFetch(ref _values); + + /// A value that represents the port on which the service is running. + public ushort wPort => PopulateFetch(ref _wPort); + + /// A value that represents the service priority. + public ushort wPriority => PopulateFetch(ref _wPriority); + + /// A value that represents the service weight. + public ushort wWeight => PopulateFetch(ref _wWeight); + + /// Performs an implicit conversion from to . + /// The instance. + /// The resulting instance from the conversion. + public static implicit operator IntPtr(SafePDNS_SERVICE_INSTANCE instance) => instance.handle; + + /// + protected override bool InternalReleaseHandle() { DnsServiceFreeInstance(handle); return true; } + + private T PopulateFetch(ref T value) + { + if (!populated && !IsInvalid && !IsClosed) + { + var val = handle.ToStructure(); + _pszInstanceName = val.pszInstanceName; + _pszHostName = val.pszHostName; + _ip4Address = val.ip4Address.ToNullableStructure(); + _ip6Address = val.ip6Address.ToNullableStructure(); + _wPort = val.wPort; + _wPriority = val.wPriority; + _wWeight = val.wWeight; + _keys = val.keys.ToStringEnum((int)val.dwPropertyCount, CharSet.Unicode).ToArray(); + _values = val.values.ToStringEnum((int)val.dwPropertyCount, CharSet.Unicode).ToArray(); + _dwInterfaceIndex = val.dwInterfaceIndex; + populated = true; + } + return value; + } + } + + internal class PDNS_MESSAGE_BUFFER : SafeAnysizeStructBase + { + 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() { } + + SizeT IVanaraMarshaler.GetNativeSize() => Marshal.SizeOf(typeof(DNS_MESSAGE_BUFFER)); + + SafeAllocatedMemoryHandle IVanaraMarshaler.MarshalManagedToNative(object managedObject) => SafeCoTaskMemHandle.Null; + + object IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocatedBytes) + { + if (pNativeData == IntPtr.Zero) return null; + using var s = new PDNS_MESSAGE_BUFFER(pNativeData, allocatedBytes); + return s.Value; + } + } + + internal class SafeDNS_NSEC3_DATA : SafeAnysizeStructBase + { + internal SafeDNS_NSEC3_DATA(DNS_NSEC3_DATA value) : base(baseSz) + { + ToNative(value); + } + + internal SafeDNS_NSEC3_DATA(IntPtr allocatedMemory, SizeT size) : base(allocatedMemory, size, false) + { + if (allocatedMemory == IntPtr.Zero) throw new ArgumentNullException(nameof(allocatedMemory)); + if (baseSz > size) throw new OutOfMemoryException(); + } + + protected override int GetArrayLength(in DNS_NSEC3_DATA local) => local.bSaltLength + local.bHashLength + local.wTypeBitMapsLength; + } + + internal class SafeDNS_NSEC3_DATAMarshaler : IVanaraMarshaler + { + /// Initializes a new instance of the class. + /// The . + public SafeDNS_NSEC3_DATAMarshaler(string _) { } + + SizeT IVanaraMarshaler.GetNativeSize() => Marshal.SizeOf(typeof(DNS_NSEC3_DATA)); + + SafeAllocatedMemoryHandle IVanaraMarshaler.MarshalManagedToNative(object managedObject) => + managedObject is null ? SafeCoTaskMemHandle.Null : (SafeAllocatedMemoryHandle)new SafeDNS_NSEC3_DATA((DNS_NSEC3_DATA)managedObject); + + object IVanaraMarshaler.MarshalNativeToManaged(IntPtr pNativeData, SizeT allocatedBytes) + { + if (pNativeData == IntPtr.Zero) return null; + using var s = new SafeDNS_NSEC3_DATA(pNativeData, allocatedBytes); + return s.Value; + } + } + } +} \ No newline at end of file diff --git a/PInvoke/Shared/Lib.cs b/PInvoke/Shared/Lib.cs index 41597b14..d538776f 100644 --- a/PInvoke/Shared/Lib.cs +++ b/PInvoke/Shared/Lib.cs @@ -36,6 +36,9 @@ /// The cryptui.dll public const string CryptUI = "cryptui.dll"; + /// The dnsapi.dll + public const string Dnsapi = "dnsapi.dll"; + /// The DWM API public const string DwmApi = "dwmapi.dll"; diff --git a/UnitTests/PInvoke/DnsApi/DnsApi.csproj b/UnitTests/PInvoke/DnsApi/DnsApi.csproj new file mode 100644 index 00000000..b24b7dcf --- /dev/null +++ b/UnitTests/PInvoke/DnsApi/DnsApi.csproj @@ -0,0 +1,80 @@ + + + + + Debug + AnyCPU + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49} + Library + Properties + UnitTest.PInvoke.DnsApi + v4.7.2 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + x64 + true + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + x64 + + + + + + + {241f73ee-9298-45c9-b869-a045dff94c03} + Vanara.Core + + + {15023e19-86a7-40c7-838e-21eeb15a63af} + Vanara.PInvoke.DnsApi + + + {a5e519e9-feba-4fe3-93a5-b8269bef72f4} + Vanara.PInvoke.Shared + + + {74D00C4C-DA94-4046-B3CD-318FECDE3794} + Vanara.PInvoke.Ws2_32 + + + {a96cff10-0967-429a-8700-4a86c97c5603} + Shared + + + + + 3.12.0 + + + 3.15.1 + + + + + + + + \ No newline at end of file diff --git a/UnitTests/PInvoke/DnsApi/DnsApiTests.cs b/UnitTests/PInvoke/DnsApi/DnsApiTests.cs new file mode 100644 index 00000000..607df3aa --- /dev/null +++ b/UnitTests/PInvoke/DnsApi/DnsApiTests.cs @@ -0,0 +1,232 @@ +using ICSharpCode.Decompiler.IL; +using NUnit.Framework; +using System; +using System.Linq; +using System.Runtime.InteropServices; +using System.Threading; +using Vanara.Extensions; +using Vanara.InteropServices; +using Vanara.PInvoke.Tests; +using static Vanara.PInvoke.DnsApi; + +namespace Vanara.PInvoke.Tests +{ + public class DnsApiTests + { + const int DNS_REQUEST_PENDING = 0x00002522; + private const string dnsSvr = "c1dns.cableone.net"; + private const string dnsSvrIp = "24.116.0.53"; + + [Test] + public void DnsAcquireContextHandleTest() + { + Assert.That(DnsAcquireContextHandle(true, default, out var ctx), ResultIs.Successful); + Assert.That(ctx, ResultIs.ValidHandle); + Assert.That(() => ctx.Dispose(), Throws.Nothing); + } + + [Test] + public void DnsExtractRecordsFromMessageTest() + { + using var mem = new SafeHGlobalHandle(64); + Assert.That(DnsExtractRecordsFromMessage(mem, (ushort)(uint)mem.Size, out var results), ResultIs.Successful); + } + + [Test] + public void DnsGetProxyInformationTest() + { + var pi = new DNS_PROXY_INFORMATION { version = 1 }; + var rpi = new DNS_PROXY_INFORMATION { version = 1 }; + Assert.That(DnsGetProxyInformation(dnsSvr, ref pi, ref rpi), ResultIs.Successful); + if (pi.proxyName != default) + DnsFreeProxyName(pi.proxyName); + if (rpi.proxyName != default) + DnsFreeProxyName(rpi.proxyName); + } + + [Test] + public void DnsModifyRecordsInSetTest() + { + Assert.That(DnsQuery(dnsSvr, DNS_TYPE.DNS_TYPE_ALL, 0, default, out var results), ResultIs.Successful); + Assert.That(results, ResultIs.ValidHandle); + Assert.That(DnsModifyRecordsInSet(results, default, DNS_UPDATE.DNS_UPDATE_SECURITY_USE_DEFAULT), ResultIs.Successful); + } + + [Test] + public void DnsNameCompareTest() + { + Assert.That(DnsNameCompare(dnsSvr, dnsSvr), Is.True); + } + + [Test] + public void DnsQueryTest() + { + Assert.That(DnsQuery(dnsSvr, DNS_TYPE.DNS_TYPE_ALL, 0, default, out var results), ResultIs.Successful); + Assert.That(results, ResultIs.ValidHandle); + results.ToArray().WriteValues(); + } + + [Test] + public void DnsQueryConfigTest([Values] DNS_CONFIG_TYPE ctype) + { + var type = CorrespondingTypeAttribute.GetCorrespondingTypes(ctype, CorrespondingAction.GetSet).FirstOrDefault(); + if (type is null || type == typeof(StrPtrAnsi)) Assert.Pass($"{ctype} Ignored"); + var sz = 1024U; + using var mem = new SafeCoTaskMemHandle(sz); + Assert.That(DnsQueryConfig(ctype, 0, null, default, mem, ref sz), ResultIs.Successful); + mem.DangerousGetHandle().Convert(sz, type, CharSet.Unicode).WriteValues(); + } + + [Test] + public void DnsQueryExTest() + { + bool callbackCalled = false; + var req = new DNS_QUERY_REQUEST + { + Version = DNS_QUERY_REQUEST_VERSION1, + QueryName = dnsSvr, + QueryOptions = DNS_QUERY_OPTIONS.DNS_QUERY_STANDARD, + QueryType = DNS_TYPE.DNS_TYPE_ALL, + pQueryCompletionCallback = Callback + }; + var res = new DNS_QUERY_RESULT { Version = DNS_QUERY_REQUEST_VERSION1 }; + Assert.That(DnsQueryEx(req, ref res, out var cancel), ResultIs.Value((Win32Error)DNS_REQUEST_PENDING)); + Thread.Sleep(500); + if (!callbackCalled) + Assert.That(DnsCancelQuery(cancel), ResultIs.Successful); + Assert.That(callbackCalled, Is.True); + if (res.pQueryRecords != default) + DnsRecordListFree(res.pQueryRecords); + + void Callback(HDNSCONTEXT pQueryContext, in DNS_QUERY_RESULT pQueryResults) + { + callbackCalled = true; + } + } + + [Test] + public void DnsRecordCompareTest() + { + var r1 = new DNS_RECORD { pName = dnsSvr, wType = DNS_TYPE.DNS_TYPE_A, Data = new DNS_A_DATA { IpAddress = 0xFFFFFF0U } }; + Assert.That(DnsRecordCompare(r1, r1), Is.True); + } + + [Test] + public void DnsRecordSetCompareTest() + { + Assert.That(DnsQuery(dnsSvr, DNS_TYPE.DNS_TYPE_ALL, 0, default, out var results), ResultIs.Successful); + Assert.That(DnsRecordSetCompare(results, results, out var p1, out var p2), ResultIs.Successful); + } + + [Test] + public void DnsServiceBrowseTest() + { + bool callbackCalled = false, qcallbackCalled = false, rcallbackCalled = false; + Assert.That(DnsAcquireContextHandle(true, default, out var ctx), ResultIs.Successful); + var br = new DNS_SERVICE_BROWSE_REQUEST + { + Version = DNS_QUERY_REQUEST_VERSION1, + QueryName = "_windns-example._udp", + pQueryContext = ctx + }; + br.Callback.pBrowseCallback = Callback; + Assert.That(DnsServiceBrowse(br, out var cancel), ResultIs.Value((Win32Error)DNS_REQUEST_PENDING)); + //Thread.Sleep(500); + //if (!callbackCalled) + // Assert.That(DnsServiceBrowseCancel(cancel), ResultIs.Successful); + + var queryRequest = new MDNS_QUERY_REQUEST + { + Version = DNS_QUERY_REQUEST_VERSION1, + Query = "_windns-example._udp.local", + QueryType = DNS_TYPE.DNS_TYPE_PTR, + QueryOptions = DNS_QUERY_OPTIONS.DNS_QUERY_STANDARD, + pQueryCallback = QueryCallback + }; + Assert.That(DnsStartMulticastQuery(queryRequest, out var queryHandle), ResultIs.Successful); + Thread.Sleep(5000); + if (!qcallbackCalled) + DnsStopMulticastQuery(queryHandle); + Assert.IsTrue(qcallbackCalled); + Assert.IsTrue(rcallbackCalled); + + void Callback(uint Status, HDNSCONTEXT pQueryContext, in DNS_RECORD pDnsRecord) + { + callbackCalled = true; + } + + void QueryCallback(HDNSCONTEXT pQueryContext, in MDNS_QUERY_HANDLE pQueryHandle, in DNS_QUERY_RESULT pQueryResults) + { + qcallbackCalled = true; + using var recs = new SafeDnsRecordList(pQueryResults.pQueryRecords); + var rec = recs.FirstOrDefault(); + if (rec.wDataLength == 0) + return; + var resolveRequest = new DNS_SERVICE_RESOLVE_REQUEST + { + Version = DNS_QUERY_REQUEST_VERSION1, + QueryName = rec.Data is DNS_PTR_DATA d ? d.pNameHost : null, + pResolveCompletionCallback = ResolveCallback, + }; + Assert.That(DnsServiceResolve(resolveRequest, out var cancel), ResultIs.Value((Win32Error)DNS_REQUEST_PENDING)); + Thread.Sleep(5000); + if (!rcallbackCalled) + Assert.That(DnsServiceResolveCancel(cancel), ResultIs.Successful); + } + + void ResolveCallback(uint Status, HDNSCONTEXT pQueryContext, in DNS_SERVICE_INSTANCE pInstance) + { + rcallbackCalled = true; + } + } + + [Test] + public void DnsServiceRegisterTest() + { + SafePDNS_SERVICE_INSTANCE si; + Assert.That(si = DnsServiceConstructInstance("initial._windns-example._udp.local", "example.com", IntPtr.Zero, IntPtr.Zero, 1, 0, 0, 0, null, null), ResultIs.ValidHandle); + + var callbackCalled = false; + Assert.That(DnsAcquireContextHandle(true, default, out var ctx), ResultIs.Successful); + var sr = new DNS_SERVICE_REGISTER_REQUEST + { + Version = DNS_QUERY_REQUEST_VERSION1, + pQueryContext = ctx, + pRegisterCompletionCallback = Callback, + pServiceInstance = si, + }; + Assert.That(DnsServiceRegister(sr, out var cancel), ResultIs.Value((Win32Error)DNS_REQUEST_PENDING)); + Thread.Sleep(500); + if (!callbackCalled) + Assert.That(DnsServiceRegisterCancel(cancel), ResultIs.Successful); + Assert.That(DnsServiceDeRegister(sr, cancel), ResultIs.Value((Win32Error)DNS_REQUEST_PENDING)); + + void Callback(uint Status, HDNSCONTEXT pQueryContext, in DNS_SERVICE_INSTANCE pInstance) => callbackCalled = true; + } + + [Test] + public void DnsValidateNameTest() + { + Assert.That(DnsValidateName(dnsSvr, DNS_NAME_FORMAT.DnsNameHostnameFull), ResultIs.Successful); + } + + [Test] + public void DnsValidateServerStatusTest() + { + Assert.That(DnsValidateServerStatus(new Ws2_32.SOCKADDR(System.Net.IPAddress.Parse(dnsSvrIp)), null, out var stat), ResultIs.Successful); + Assert.That(stat, Is.EqualTo(DnsServerStatus.ERROR_SUCCESS)); + } + + [Test] + public void DnsWriteQuestionToBufferTest() + { + var sz = 64U; + using var mem = new SafeHGlobalHandle(sz); + Assert.That(DnsWriteQuestionToBuffer(mem, ref sz, "microsoft", DNS_TYPE.DNS_TYPE_A, 1, true), Is.True); + var buf = mem.ToStructure(); + DNS_BYTE_FLIP_HEADER_COUNTS(ref buf); + buf.WriteValues(); + TestContext.Write(string.Join(":", mem.ToArray((int)sz - 12, 12))); + } + } +} \ No newline at end of file diff --git a/Vanara.sln b/Vanara.sln index 5548c7d8..9e978823 100644 --- a/Vanara.sln +++ b/Vanara.sln @@ -215,6 +215,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WlanApi", "UnitTests\PInvok EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WcmApi", "UnitTests\PInvoke\WcmApi\WcmApi.csproj", "{35B95D64-CC7E-48B4-B104-4886411531AC}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vanara.PInvoke.DnsApi", "PInvoke\DnsApi\Vanara.PInvoke.DnsApi.csproj", "{15023E19-86A7-40C7-838E-21EEB15A63AF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DnsApi", "UnitTests\PInvoke\DnsApi\DnsApi.csproj", "{5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug (no Unit Tests)|Any CPU = Debug (no Unit Tests)|Any CPU @@ -683,6 +687,18 @@ Global {35B95D64-CC7E-48B4-B104-4886411531AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {35B95D64-CC7E-48B4-B104-4886411531AC}.Debug|Any CPU.Build.0 = Debug|Any CPU {35B95D64-CC7E-48B4-B104-4886411531AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15023E19-86A7-40C7-838E-21EEB15A63AF}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU + {15023E19-86A7-40C7-838E-21EEB15A63AF}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU + {15023E19-86A7-40C7-838E-21EEB15A63AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {15023E19-86A7-40C7-838E-21EEB15A63AF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {15023E19-86A7-40C7-838E-21EEB15A63AF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {15023E19-86A7-40C7-838E-21EEB15A63AF}.Release|Any CPU.Build.0 = Release|Any CPU + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49}.Debug (no Unit Tests)|Any CPU.ActiveCfg = Debug|Any CPU + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49}.Debug (no Unit Tests)|Any CPU.Build.0 = Debug|Any CPU + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -773,6 +789,8 @@ Global {141B6B19-6F07-4644-B72D-B189E49030BF} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90} {F8E02C7E-99E9-4C99-B63D-E678BC43C734} = {385CAD2D-0A5E-4F80-927B-D5499D126B90} {35B95D64-CC7E-48B4-B104-4886411531AC} = {385CAD2D-0A5E-4F80-927B-D5499D126B90} + {15023E19-86A7-40C7-838E-21EEB15A63AF} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90} + {5B4ADAFE-DCCC-40BC-9A9E-8086E57E8B49} = {385CAD2D-0A5E-4F80-927B-D5499D126B90} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}