Windows 11中GetNameInfoW API无法解析中文计算机名的问题咨询
问题分析与结论
核心现象梳理:
- 相同代码在Windows 10(22H2)中可通过
GetNameInfoW正常反向解析含中文的AD主机名,但在Windows 11(23H2)中返回错误10014(WSAEFAULT) - 所有终端通过
nslookup均可正常解析中文主机名,证明AD DC的DNS反向区域配置无问题
错误原因定位
错误码10014对应WSAEFAULT,通常指向参数内存地址无效,但你的代码在Windows 10上运行正常,可排除参数逻辑错误。结合nslookup正常的现象,问题根源是Windows 11的Winsock API对国际化域名(IDN)的处理逻辑发生了变化:
- Windows 10的
GetNameInfoW在AD环境下处理非ASCII主机名时,会自动兼容IDN解析流程; - Windows 11的
GetNameInfoW调整了DNS查询路径或IDN处理规则,导致使用NI_NAMEREQD标志时无法正确解析含非ASCII字符的反向条目。而nslookup依赖独立的DNS客户端API(如DnsQueryEx),不受此限制。
验证与修复方案
1. 临时验证:移除NI_NAMEREQD标志
修改GetNameInfoW的调用参数,去掉强制要求返回主机名的NI_NAMEREQD标志:
if (GetNameInfoW((struct sockaddr*)&sa, sizeof(sa), host, NI_MAXHOST, NULL, 0, 0) == 0) { std::wcout << "hostname: " << host << std::endl; }
若修改后能正常返回中文主机名,即可确认是NI_NAMEREQD在Windows 11上的兼容性问题。
2. 稳定替代方案:使用DNS原生API
直接调用Windows DNS客户端API(如DnsQueryEx)实现反向解析,绕过GetNameInfoW的限制,示例代码片段:
#include <windns.h> void dnsReverseLookup(const char* ip) { DNS_QUERY_REQUEST request = {0}; DNS_QUERY_RESULT result = {0}; std::string reverseIp = std::string(ip) + ".in-addr.arpa"; request.Version = DNS_QUERY_REQUEST_VERSION1; request.QueryName = reverseIp.c_str(); request.QueryType = DNS_TYPE_PTR; request.Options = DNS_QUERY_STANDARD; DWORD status = DnsQueryEx(&request, &result); if (status == ERROR_SUCCESS) { if (result.pQueryRecords && result.pQueryRecords->wType == DNS_TYPE_PTR) { PDNS_RECORD ptrRecord = result.pQueryRecords; std::wcout << "hostname: " << ptrRecord->Data.PTR.pNameHost << std::endl; } DnsRecordListFree(result.pQueryRecords, DnsFreeRecordList); } else { std::cerr << "DNS query failed: " << status << std::endl; } }
编译时需链接dnsapi.lib。
结论
这是Windows 11 Winsock API的兼容性问题,不属于代码逻辑错误。微软在Windows 11的Winsock组件中调整了IDN解析逻辑,导致GetNameInfoW在特定条件下无法处理非ASCII反向DNS条目,而nslookup使用的独立DNS客户端API不受此影响。
内容的提问来源于stack exchange,提问作者SermonJr
相关产品推荐
相关产品推荐

