I'm trying to get DNS TXT data:
#include <Windows.h>
#include <WinDNS.h>
#include <winsock.h>
#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "Dnsapi.lib")
#include <iostream>
#include <string>
using namespace std;
const std::string dnsAddress = "8.8.8.8";
int main()
{
IP4_ARRAY dnsServerIp;
dnsServerIp.AddrCount = 1;
dnsServerIp.AddrArray[0] = inet_addr(dnsAddress.data());
const std::wstring domain = L"mydomain.com";
DNS_RECORD* dnsRecord = nullptr;
auto error = DnsQuery(domain.data(), DNS_TYPE_TEXT, DNS_QUERY_BYPASS_CACHE, &dnsServerIp, &dnsRecord, NULL);
if (!error) {
if (dnsRecord) {
cout << "DNS TXT strings count: " << dnsRecord->Data.TXT.dwStringCount << endl;
for (size_t i = 0; i < dnsRecord->Data.TXT.dwStringCount; i) {
wcout << i << L": " << std::wstring(dnsRecord->Data.TXT.pStringArray[i]) << endl;
}
DnsRecordListFree(dnsRecord, DnsFreeRecordListDeep);
}
}
}
With this code I always have dnsRecord->Data.TXT.dwStringCount == 1
and it prints the first line only. I've found that WinDNS.h
normally defines array for one line:
typedef struct
{
DWORD dwStringCount;
#ifdef MIDL_PASS
[size_is(dwStringCount)] PWSTR pStringArray[];
#else
PWSTR pStringArray[1];
#endif
}
DNS_TXT_DATAW, *PDNS_TXT_DATAW;
What does this MIDL_PASS
macro mean? When I enable it I get a lot of compile errors like identifier not found
, attribute not found
etc.`
CodePudding user response:
DNSQuery
can return multiple records, each with multiple strings. You need to enumerate the list of returned records as well as the strings within them.
DNS_RECORD* pResult = dnsRecord;
while (pResult != nullptr)
{
if (pResult->wType == DNS_TYPE_TEXT)
{
DNS_TXT_DATAW* pData = &pResult->Data.TXT;
for (DWORD s = 0; s < pData->dwStringCount; s )
{
// do something with pData->pStringArray[s]
}
}
pResult = pResult->pNext;
}