/****************************************************************************** * DnsQuery_W [DNSAPI.@] * */ DNS_STATUS WINAPI DnsQuery_W( PCWSTR name, WORD type, DWORD options, PVOID servers, PDNS_RECORDW *result, PVOID *reserved ) { char *nameU; DNS_RECORDA *resultA; DNS_STATUS status; TRACE( "(%s,%s,0x%08x,%p,%p,%p)\n", debugstr_w(name), dns_type_to_str( type ), options, servers, result, reserved ); if (!name || !result) return ERROR_INVALID_PARAMETER; nameU = dns_strdup_wu( name ); if (!nameU) return ERROR_NOT_ENOUGH_MEMORY; status = DnsQuery_UTF8( nameU, type, options, servers, &resultA, reserved ); if (status == ERROR_SUCCESS) { *result = (DNS_RECORDW *)DnsRecordSetCopyEx( (DNS_RECORD *)resultA, DnsCharSetUtf8, DnsCharSetUnicode ); if (!*result) status = ERROR_NOT_ENOUGH_MEMORY; DnsRecordListFree( (DNS_RECORD *)resultA, DnsFreeRecordList ); } dns_free( nameU ); return status; }
std::vector<double> Pinger::runPingProcessInstance(const uint16_t requestCount, const double delay){ std::vector<double> result; this->progressMutex.lock(); this->progress = 0; this->progressMutex.unlock(); double progressStep = 1.0 / requestCount; WSADATA wsaData; int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if(iResult != 0) throw std::runtime_error("WSAStartup failed"); PDNS_RECORD dnsResultPtr; DNS_STATUS dnsStatus = DnsQuery_UTF8(this->host.c_str(), DNS_TYPE_A, DNS_QUERY_STANDARD, nullptr, &dnsResultPtr, nullptr); if(dnsStatus != DNS_RCODE_NOERROR) throw std::runtime_error("DnsQuery error"); IP4_ADDRESS ip = dnsResultPtr->Data.A.IpAddress; HANDLE hIcmp = IcmpCreateFile(); if(hIcmp == INVALID_HANDLE_VALUE) throw std::runtime_error("IcmpCreateFile error"); char SendData[32]; DWORD ReplySize = sizeof(ICMP_ECHO_REPLY) + sizeof(SendData); LPVOID ReplyBuffer = reinterpret_cast<LPVOID>(malloc(ReplySize)); if(ReplyBuffer == nullptr) throw std::runtime_error("malloc error"); std::chrono::duration<int, std::milli> pingDelay(static_cast<int>(delay * 1000)); for(uint32_t i = 0; i < requestCount && this->stopFlag == false; ++i){ auto lastTime = std::chrono::high_resolution_clock::now(); DWORD resIcmp = IcmpSendEcho(hIcmp, ip, SendData, sizeof(SendData), nullptr, ReplyBuffer, ReplySize, 1000); if(resIcmp == 0) throw std::runtime_error("IcmpSendEcho error"); PICMP_ECHO_REPLY pReply = reinterpret_cast<PICMP_ECHO_REPLY>(ReplyBuffer); result.push_back(pReply->RoundTripTime); this->progressMutex.lock(); if(this->progress + progressStep <= 1.0){//если шагов больше чем requestCount - не переполняем счетчик this->progress += progressStep; } this->progressMutex.unlock(); if(i < requestCount) std::this_thread::sleep_until(lastTime + pingDelay); } if(this->stopFlag == false){ this->progressMutex.lock(); this->progress = 1.0; this->progressMutex.unlock(); } return result; }
DNS::HostMap DNS::resolve( const std::string& service, const std::string& proto, const std::string& domain, const LogSink& logInstance ) { const std::string dname = "_" + service + "._" + proto + "." + domain; bool error = false; DNS::HostMap servers; DNS_RECORD* pRecord = NULL; DNS_STATUS status = DnsQuery_UTF8( dname.c_str(), DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &pRecord, NULL ); if( status == ERROR_SUCCESS ) { // NOTE: DnsQuery_UTF8 and DnsQuery_A really should have been defined with // PDNS_RECORDA instead of PDNS_RECORD, since that's what it is (even with _UNICODE defined). // We'll correct for that mistake with a cast. DNS_RECORDA* pRec = (DNS_RECORDA*)pRecord; do { if( pRec->wType == DNS_TYPE_SRV ) { servers[pRec->Data.SRV.pNameTarget] = pRec->Data.SRV.wPort; } pRec = pRec->pNext; } while( pRec != NULL ); DnsRecordListFree( pRecord, DnsFreeRecordList ); } else { logInstance.warn( LogAreaClassDns, "DnsQuery_UTF8() failed: " + util::int2string( status ) ); error = true; } if( error || !servers.size() ) { servers = defaultHostMap( domain, logInstance ); } return servers; }