⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simplednsclient.cpp

📁 发送邮件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*=========================================================================== 
    (c) Copyright 2000, Emmanuel KARTMANN, all rights reserved
  =========================================================================== 
    File           : SimpleDNSClient.cpp
    $Header: $
    Author         : Emmanuel KARTMANN <emmanuel@kartmann.org>
    Creation       : Monday 1/31/00 3:51:31 PM
    Remake         : 
  ------------------------------- Description ------------------------------- 

           Implementation of the CSimpleDNSClient

  ------------------------------ Modifications ------------------------------ 
    $Log: $  
  =========================================================================== 
*/

#include "stdafx.h"
#include "SimpleDNSResolver.h"
#include "SimpleDNSClient.h"
#include "WindowsErrorText.h"
#include "InternetStandards.h"

/////////////////////////////////////////////////////////////////////////////
// CSimpleDNSClient: Public (Exported) methods

STDMETHODIMP CSimpleDNSClient::InterfaceSupportsErrorInfo(REFIID riid)
{
	static const IID* arr[] = 
	{
		&IID_ISimpleDNSClient
	};
	for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
	{
        if (IsEqualGUID((REFGUID)*arr[i],(REFGUID)riid))
			return S_OK;
	}
	return S_FALSE;
}

STDMETHODIMP CSimpleDNSClient::Resolve(BSTR BSearchedName, VARIANT *pvFoundNames, BSTR BResourceClass, BSTR BResourceType)
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState())

    HRESULT hReturnCode = FALSE; // Failure

    DNS_STATUS nStatus = 0;
    WORD wType = 0;
    PIP4_ARRAY pSrvList = NULL;      // pointer to IP4_ARRAY structure
    PDNS_RECORD pDnsRecords = NULL;
    PVOID pReserved = NULL;
    CString szSearchedName;
    CString szFoundNames;

    // Convert parameters and init output

    szSearchedName = BSearchedName;
    if (szSearchedName == "") {
        SetError("Invalid resource name (empty): ", ERROR_INVALID_PARAMETER);
        return(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
    }

    wType = CInternetStandards::GetResourceTypeFromString((LPCTSTR)_bstr_t(BResourceType));
    if (wType == DNS_INVALID_RESOURCE_TYPE) {
        CString szErrorMessage = "Invalid DNS Resource Type ";
        szErrorMessage+= CString((LPCTSTR)_bstr_t(BResourceType));
        szErrorMessage+=": ";
        SetError(szErrorMessage, ERROR_INVALID_PARAMETER);
        return(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
    }
    // TODO: hanlde non-internet type (how? There's no such parameter in MS API...)
    int nClass = CInternetStandards::GetResourceClassFromString((LPCTSTR)_bstr_t(BResourceClass));
    if (nClass != DNS_CLASS_INTERNET) {
        CString szErrorMessage = "Invalid DNS Resource Class (only C_IN is supported): ";
        SetError(szErrorMessage, ERROR_INVALID_PARAMETER);
        return(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
    }

    // If request is a reverse (address->name) lookup (type PTR), then silently convert
    // request to a in-arpa format
    if (wType == DNS_TYPE_PTR) {
	    unsigned long addr = inet_addr(szSearchedName);
	    if (addr != INADDR_NONE) {
            char *p = (char *)&addr;
            szSearchedName.Format("%u.%u.%u.%u.in-addr.arpa",
                                  ((unsigned)p[3] & 0xff),  // CAUTION: reverse byte order (p[3]...p[0])
                                  ((unsigned)p[2] & 0xff),
                                  ((unsigned)p[1] & 0xff),
                                  ((unsigned)p[0] & 0xff));
        } else {
            // Must be an address for a PTR request: error
            SetError("Invalid resource name (empty): ", ERROR_INVALID_PARAMETER);
            return(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
        }
    }
    LPCTSTR lpstrName = szSearchedName;

    // use all known servers (or use method FindAllDNSServers if empty)
    if (m_szServerAddresses == "") {
        m_szServerAddresses = FindAllDNSServers();
    }

    BOOL bNoServer = TRUE;
    CStringList oServerList;
    CString szServerAddress;
    BuildListFromString(m_szServerAddresses, oServerList);
    POSITION pServer = oServerList.GetHeadPosition();
    int i=0;

    pSrvList = (PIP4_ARRAY) LocalAlloc(LPTR,sizeof(IP4_ARRAY));
    if (!pSrvList) {
        DWORD dwLastError = GetLastError();
        SetError("Memory Allocation Error:" , dwLastError);
        hReturnCode = HRESULT_FROM_WIN32(dwLastError);
    } else {

/* 
 ****

  WARNING: if the DNS server is non-standard, the option flag fOptions must NOT be 
           equal to DNS_QUERY_STANDARD, but to DNS_QUERY_BYPASS_CACHE.
           Thanks to Thomas Heike (t.heike@lit.lineas.de) for his help on this...
 ****
*/
        DWORD fOptions = DNS_QUERY_STANDARD;
        while (pServer != NULL) {
            szServerAddress = oServerList.GetNext(pServer);
            // Convert dotted notation into address (4 bytes)
            // Store it in configuration (memory)
            pSrvList->AddrCount = 1;
            pSrvList->AddrArray[0] = inet_addr(szServerAddress);
            bNoServer = FALSE;
            fOptions = DNS_QUERY_BYPASS_CACHE;
            // TODO: store all servers in IP4_ARRAY (how??? there's only one element is array!)
            // For now, exit loop after 1st server
            break;
        }
        if (bNoServer) {
            CString szErrorMessage = "Invalid DNS server addresses \"";
            szErrorMessage+=m_szServerAddresses;
            szErrorMessage+="\": ";
            SetError(szErrorMessage, ERROR_INVALID_PARAMETER);
            return(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
        }
        // Send query to DNS Server and fetch reply
        nStatus = DnsQuery(lpstrName,
                           wType,
                           fOptions,
                           pSrvList,
                           &pDnsRecords,
                           NULL);

        if (nStatus) {
            DWORD dwLastError = nStatus;
            SetError("DNS Resolution failure: ", dwLastError);
            hReturnCode = HRESULT_FROM_WIN32(dwLastError);
        } else {

            switch(wType) {

            // A (IP v4 address)
            case DNS_TYPE_A: 
                {
                    // convert address into string (dotted notation) and add to result
                    do {
                        IN_ADDR ipaddr;
                        ipaddr.S_un.S_addr = (pDnsRecords->Data.A.IpAddress);
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, inet_ntoa(ipaddr), szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // PTR (reverse lookup: address->name)
            case DNS_TYPE_PTR: 
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.PTR.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // MX (Mail eXchanger)
            case DNS_TYPE_MX: 
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.MX.pNameExchange, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // AFSDB (RFC 1183)
            case DNS_TYPE_AFSDB: 
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.AFSDB.pNameExchange, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // RT (RFC 1183)
            case DNS_TYPE_RT: 
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.RT.pNameExchange, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // CNAME (Canonical Name)
            case DNS_TYPE_CNAME: 
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.NS.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // NS (Name Server)
            case DNS_TYPE_NS: 
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.NS.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // SOA (start of authority)
            case DNS_TYPE_SOA:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.SOA.pNamePrimaryServer, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // MB 
            case DNS_TYPE_MB:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.MB.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // MD 
            case DNS_TYPE_MD:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.MD.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // MF 
            case DNS_TYPE_MF:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.MF.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // MG 
            case DNS_TYPE_MG:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.MG.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // MR 
            case DNS_TYPE_MR:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.MR.pNameHost, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // MINFO (mail information)
            case DNS_TYPE_MINFO:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.MINFO.pNameMailbox, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // RP (Responsible Person)
            case DNS_TYPE_RP:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.RP.pNameMailbox, szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // HINFO 
            case DNS_TYPE_HINFO:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.HINFO.pStringArray[1], szFoundNames);
                        }
                        pDnsRecords = pDnsRecords->pNext;
                    } while (pDnsRecords);
                }
                break;

            // ISDN 
            case DNS_TYPE_ISDN:
                {
                    do {
                        if (pDnsRecords->Flags.S.Section == DNSREC_ANSWER) {
                            AppendResult(wType, pDnsRecords->wType, pDnsRecords->Data.ISDN.pStringArray[1], szFoundNames);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -