每个小工程都原有一个高达上的目的, 刚开始本打算写个自动更新hosts的程序, 功能你懂的.
好不容易实现了socket手动查询DNS发现大微软竟然提供了DNSAPI, 顿时哭瞎在厕所...
于是安静的查了查发现中文资料少的可怜, 于是操起吾这三级半的英语折腾起来. 一下便是折腾的一点点小成功.
DnsApi有很多接口, 详见MS官方. 这里主要说说DnsQueryEx()这个接口.
1. DnsQueryEx function
DnsQueryEx方法是DNS命名空间的异步通用查询接口,它提供给开发者进行DNS查询解析.跟DnsQuery一样, DnsQueryEx也可进行同步查询.
语法
DNS_STATUS WINAPI DnsQueryEx(
_In_ PDNS_QUERY_REQUEST<span style="white-space:pre"> </span>pQueryRequest,
_Inout_ PDNS_QUERY_RESULT<span style="white-space:pre"> </span>pQueryResults,
_Inout_opt_ PDNS_QUERY_CANCEL<span style="white-space:pre"> </span>pCancelHandle
);
参数
pQueryRequest [in]
指向DNS_QUERY_REQUEST结构的指针,其中包含了查询请求相关信息.
注意:如果将该结构中的pQueryCompleteCallback 设置为NULL,则DnsQueryEx将进行同步查询,否则为异步查询.
pQueryResults [in, out]
指向DNS_QUERY_RESULT结构的指针,其中包含了查询结果.调用前(input),结构中的version成员必须赋值为DNS_QUERY_REQUEST_VERSION1并且所有成员必须初始化为NULL.查询结束后(output),除version外的成员将被填充查询结果数据.
注意:对于异步查询,在DNS_QUERY_COMPLETION_ROUTINE回调函数被调用前,应用程序不应释放该参数.当查询结束后,查询结果(DNS_QUERY_RESULT)中指向DNS_RECORDS(RR)结构的指针应该通过调用DnsRecordListFree()接口释放.
pCancelHandle [in, out,optional]
指向DNS_QUERY_CANCEL结构的指针,该参数可被用于取消一个正在进行的异步查询.
注意:在DNS_QUERY_COMPLETION_ROUTINE 回调函数被调用前,应用程序不应释放该参数.
返回值
DnsQueryEx接口返回值可以为下列值:
Return code
Description
ERROR_SUCCESS
成功.
ERROR_INVALID_PARAMETER
pQueryRequest 或pQueryRequest 参数未初始化,或包含了错误的版本号
DNS RCODE
发生了RCODE错误,错误号参考RCODE
DNS_INFO_NO_RECORDS
响应中无记录.
DNS_REQUEST_PENDING
异步查询尚未结束.
注意
如果DnsQueryEx完成同步查询(即,函数返回值中没有DNS_REQUEST_PENDING),那么pQueryResults 中的pQueryRecords 成员包含一个指向DNS_RECORDS列表的指针,并且DnsQueryEx将返回成功或失败.
满足下列条件调用DnsQueryEx将进行同步查询,并且不使用DNS回调函数.
- DNS_QUERY_COMPLETION_ROUTINE回调函数被忽略, 即pQueryRequest参数中的pQueryCompleteCallback 成员被置为NULL.
- 请求本地名称,并且A或者AAAA类型资源记录(RR).
- 调用DnsQueryEx查询一个IPv4或IPv6地址.
- 调用DnsQueryEx返回错误.
如果调用DnsQueryEx完成异步查询,查询结果将通过DNS_QUERY_COMPLETION_ROUTINE回调函数中的pQueryRequest参数取得,pQueryResults中的QueryStatus成员将包含DNS_REQUEST_PENDING,并且DnsQueryEx返回DNS_REQUEST_PENDING.应用程序应该关注pQueryResults , DNS回调成功时它会被传入DnsQueryEx.应用程序可以使用pCancelHandle 取消一个异步查询,该参数在调用DnsQueryEx后得到.
调用DnsQueryEx进行异步查询并且pQueryContext 为有效值,DNS_QUERY_COMPLETION_ROUTINE回调函数被调用后,pCancelHandle 才会被返回.
注意:调用DnsQueryEx完成异步查询后,DNS_QUERY_COMPLETION_ROUTINE回调函数将在同一处理流程内返回并通知应用程序.