#include "StdAfx.h"
#include "dnsfirewall_public.h"
#include "WS2InterceptDLL.h"
#include "DnsMessageWB.h"
#include "DnsResorceRecord.h"
#include "commrcfg.h"
#include "Trace.h"
#include "DnsResorceRecord.tmh"


CDnsResorceRecord::CDnsResorceRecord(void)
: m_pNext(NULL)
, m_sName(_T(""))
, m_wType(0)
, m_wClass(0)
, m_wDataLength(0)
, m_dwTtl(0)
, m_dwReserved(0)
, m_pDnsRecordData(NULL)
, m_nStartPositionIndex(0)
, m_sRRTypeName(_T(""))
{
    m_unDnsRecordFlags.DW = 0;
}


CDnsResorceRecord::~CDnsResorceRecord(void)
{
    if (NULL == m_pDnsRecordData)
    {
        TraceEvents(
            TRACE_LEVEL_WARNING,
            TRACE_DNS_RESORCE_RECORD,
            "%!FUNC! line:%!LINE! %!LEVEL! Exit (NULL == m_pDnsRecordData)"
            );
        return;
    }
    switch(m_wType)
    {
    case DNS_TYPE_SOA:
        {
            PDNS_SOA_DATA   pSoaData = &m_pDnsRecordData->SOA;
            if(NULL != pSoaData->pNameAdministrator)
            {
                free(pSoaData->pNameAdministrator);
                pSoaData->pNameAdministrator = NULL;
            }
            if(NULL != pSoaData->pNamePrimaryServer)
            {
                free(pSoaData->pNamePrimaryServer);
                pSoaData->pNamePrimaryServer = NULL;
            }
        }
        break;
    case DNS_TYPE_NS:
    case DNS_TYPE_MD:
    case DNS_TYPE_MF:
    case DNS_TYPE_CNAME:
    case DNS_TYPE_MB:
    case DNS_TYPE_MG:
    case DNS_TYPE_MR:
    case DNS_TYPE_PTR:
    case DNS_TYPE_DNAME:
        {
            PDNS_PTR_DATA   pDnsPtrData = &m_pDnsRecordData->PTR;
            if(NULL != pDnsPtrData->pNameHost)
            {
                free(pDnsPtrData->pNameHost);
                pDnsPtrData->pNameHost = NULL;
            }
        }
        break;
    case DNS_TYPE_MINFO:
    case DNS_TYPE_RP:
        {
            PDNS_MINFO_DATA pDnsMinfoData = &m_pDnsRecordData->MINFO;
            if(NULL != pDnsMinfoData->pNameErrorsMailbox)
            {
                free(pDnsMinfoData->pNameErrorsMailbox);
                pDnsMinfoData->pNameErrorsMailbox = NULL;
            }
            if(NULL != pDnsMinfoData->pNameMailbox)
            {
                free(pDnsMinfoData->pNameMailbox);
                pDnsMinfoData->pNameMailbox = NULL;
            }
        }
        break;
    case DNS_TYPE_MX:
    case DNS_TYPE_AFSDB:
    case DNS_TYPE_RT:
    case DNS_TYPE_KX:
        {
            PDNS_MX_DATA pDnsMxData = &m_pDnsRecordData->MX;
            if(NULL != pDnsMxData->pNameExchange)
            {
                free(pDnsMxData->pNameExchange);
                pDnsMxData->pNameExchange = NULL;
            }
        }
        break;
    case DNS_TYPE_SIG:
    case DNS_TYPE_RRSIG:
        {
            PDNS_SIG_DATA   pDnsSigData = &m_pDnsRecordData->SIG;
            if(NULL != pDnsSigData->pNameSigner)
            {
                free(pDnsSigData->pNameSigner);
                pDnsSigData->pNameSigner = NULL;
            }
        }
        break;
    case DNS_TYPE_NXT:
    case DNS_TYPE_NSEC:
        {
            PDNS_NSEC_DATA  pDnsNsecData = &m_pDnsRecordData->NSEC;
            if(NULL != pDnsNsecData->pNextDomainName)
            {
                free(pDnsNsecData->pNextDomainName);
                pDnsNsecData->pNextDomainName = NULL;
            }
        }
        break;
    case DNS_TYPE_SRV:
        {
            PDNS_SRV_DATA   pDnsSrvData = &m_pDnsRecordData->SRV;
            if(NULL != pDnsSrvData->pNameTarget)
            {
                free(pDnsSrvData->pNameTarget);
                pDnsSrvData->pNameTarget = NULL;
            }
        }
        break;
    case DNS_TYPE_NAPTR:
        {
            PDNS_NAPTR_DATA pDnsNaptrData = &m_pDnsRecordData->NAPTR;
            if(NULL != pDnsNaptrData->pReplacement)
            {
                free(pDnsNaptrData->pReplacement);
                pDnsNaptrData->pReplacement = NULL;
            }
            if(NULL != pDnsNaptrData->pRegularExpression)
            {
                free(pDnsNaptrData->pRegularExpression);
                pDnsNaptrData->pRegularExpression = NULL;
            }
            if(NULL != pDnsNaptrData->pService)
            {
                free(pDnsNaptrData->pService);
                pDnsNaptrData->pService = NULL;
            }
            if(NULL != pDnsNaptrData->pFlags)
            {
                free(pDnsNaptrData->pFlags);
                pDnsNaptrData->pFlags = NULL;
            }
        }
        break;
    case DNS_TYPE_TEXT:
    case DNS_TYPE_HINFO:
    case DNS_TYPE_ISDN:
    case DNS_TYPE_X25:
        {
            PDNS_TXT_DATA   pDnsTxtData = &m_pDnsRecordData->TXT;
            int     nStringCount = (int)pDnsTxtData->dwStringCount;
            int     i;
            PWSTR   *pStringArray = pDnsTxtData->pStringArray;
            for(i=nStringCount-1;i>=0;i--)
            {
                if(NULL != pStringArray[i])
                {
                    free(pStringArray[i]);
                    pStringArray[i] = NULL;
                }
            }
        }
        break;
    case DNS_TYPE_TKEY:
        {
            PDNS_TKEY_DATA  pDnsTkeyData = &m_pDnsRecordData->TKEY;
            if(NULL != pDnsTkeyData->pOtherData)
            {
                free(pDnsTkeyData->pOtherData);
                pDnsTkeyData->pOtherData = NULL;
            }
            if(NULL != pDnsTkeyData->pKey)
            {
                free(pDnsTkeyData->pKey);
                pDnsTkeyData->pKey = NULL;
            }
            if(NULL != pDnsTkeyData->pNameAlgorithm)
            {
                free(pDnsTkeyData->pNameAlgorithm);
                pDnsTkeyData->pNameAlgorithm = NULL;
            }
        }
        break;
    case DNS_TYPE_TSIG:
        {
            PDNS_TSIG_DATA  pDnsTsigData = &m_pDnsRecordData->TSIG;
            if(NULL != pDnsTsigData->pOtherData)
            {
                free(pDnsTsigData->pOtherData);
                pDnsTsigData->pOtherData = NULL;
            }
            if(NULL != pDnsTsigData->pSignature)
            {
                free(pDnsTsigData->pSignature);
                pDnsTsigData->pSignature = NULL;
            }
            if(NULL != pDnsTsigData->pNameAlgorithm)
            {
                free(pDnsTsigData->pNameAlgorithm);
                pDnsTsigData->pNameAlgorithm = NULL;
            }
        }
        break;
    case DNS_TYPE_WINSR:
        {
            PDNS_WINSR_DATA pDnsWinsrData = &m_pDnsRecordData->WINSR;
            if(NULL != pDnsWinsrData->pNameResultDomain)
            {
                free(pDnsWinsrData->pNameResultDomain);
                pDnsWinsrData->pNameResultDomain = NULL;
            }
        }
        break;
    }
    free(m_pDnsRecordData);
    m_pDnsRecordData = NULL;
}


CDnsResorceRecord::CDnsResorceRecord(CDnsResorceRecord& rSourceRR)
: m_pNext(NULL)
, m_sName(rSourceRR.m_sName)
, m_wType(rSourceRR.m_wType)
, m_wClass(rSourceRR.m_wClass)
, m_wDataLength(rSourceRR.m_wDataLength)
, m_dwTtl(rSourceRR.m_dwTtl)
, m_dwReserved(0)
, m_pDnsRecordData(NULL)
, m_nStartPositionIndex(0)
, m_sRRTypeName(rSourceRR.m_sRRTypeName)
{
    {
        int     nStringLength = m_sName.GetLength();
        if((nStringLength > 0) && (m_sName[nStringLength - 1] != _T('.')))
        {
            m_sName += _T('.');
        }
    }
    m_unDnsRecordFlags.DW = rSourceRR.m_unDnsRecordFlags.DW;
    m_pDnsRecordData = (PDNS_DATA)malloc(m_wDataLength);
    RtlCopyMemory(
        m_pDnsRecordData,
        rSourceRR.m_pDnsRecordData,
        m_wDataLength
        );
    switch(m_wType)
    {
    case DNS_TYPE_SOA:
        {
            PWSTR   pDomainName = NULL;
            CString sNamePrimaryServer;
            CString sNameAdministrator;
            int     nStringLength;
            PDNS_SOA_DATA   pSoaData = &m_pDnsRecordData->SOA;
            PDNS_SOA_DATA   pSoaDataSource = &rSourceRR.m_pDnsRecordData->SOA;
            sNamePrimaryServer = pSoaDataSource->pNamePrimaryServer;
            nStringLength = sNamePrimaryServer.GetLength();
            if(nStringLength > 0)
            {
                if(sNamePrimaryServer[nStringLength -1] != _T('.'))
                {
                    sNamePrimaryServer += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNamePrimaryServer);
            }
            pSoaData->pNamePrimaryServer = pDomainName;
            pDomainName = NULL;
            sNameAdministrator = pSoaDataSource->pNameAdministrator;
            nStringLength = sNameAdministrator.GetLength();
            if(nStringLength > 0)
            {
                if(sNameAdministrator[nStringLength -1] != _T('.'))
                {
                    sNameAdministrator += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameAdministrator);
            }
            pSoaData->pNameAdministrator = pDomainName;
        }
        break;
    case DNS_TYPE_PTR:
    case DNS_TYPE_NS:
    case DNS_TYPE_MD:
    case DNS_TYPE_MF:
    case DNS_TYPE_CNAME:
    case DNS_TYPE_MB:
    case DNS_TYPE_MG:
    case DNS_TYPE_MR:
    case DNS_TYPE_DNAME:
        {
            PDNS_PTR_DATA   pDnsPtrData = &m_pDnsRecordData->PTR;
            PDNS_PTR_DATA   pDnsPtrDataSource = &rSourceRR.m_pDnsRecordData->PTR;
            PWSTR   pDomainName = NULL;
            CString sNameHost;
            int     nStringLength;
            sNameHost = pDnsPtrDataSource->pNameHost;
            nStringLength = sNameHost.GetLength();
            if(nStringLength > 0)
            {
                if(sNameHost[nStringLength -1] != _T('.'))
                {
                    sNameHost += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameHost);
            }
            pDnsPtrData->pNameHost = pDomainName;
        }
        break;
    case DNS_TYPE_MINFO:
    case DNS_TYPE_RP:
        {
            PDNS_MINFO_DATA pDnsMinfoData = &m_pDnsRecordData->MINFO;
            PDNS_MINFO_DATA pDnsMinfoDataSource = &rSourceRR.m_pDnsRecordData->MINFO;
            PWSTR   pDomainName = NULL;
            CString sNameMailbox;
            CString sNameErrorsMailbox;
            int     nStringLength;
            sNameMailbox = pDnsMinfoDataSource->pNameMailbox;
            nStringLength = sNameMailbox.GetLength();
            if(nStringLength > 0)
            {
                if(sNameMailbox[nStringLength -1] != _T('.'))
                {
                    sNameMailbox += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameMailbox);
            }
            pDnsMinfoData->pNameMailbox = pDomainName;
            sNameErrorsMailbox = pDnsMinfoDataSource->pNameErrorsMailbox;
            nStringLength = sNameErrorsMailbox.GetLength();
            if(nStringLength > 0)
            {
                if(sNameErrorsMailbox[nStringLength -1] != _T('.'))
                {
                    sNameErrorsMailbox += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameErrorsMailbox);
            }
            pDnsMinfoData->pNameErrorsMailbox = pDomainName;
        }
        break;
    case DNS_TYPE_MX:
    case DNS_TYPE_AFSDB:
    case DNS_TYPE_RT:
    case DNS_TYPE_KX:
        {
            PDNS_MX_DATA pDnsMxData = &m_pDnsRecordData->MX;
            PDNS_MX_DATA pDnsMxDataSource = &rSourceRR.m_pDnsRecordData->MX;
            PWSTR   pDomainName = NULL;
            CString sNameExchange;
            int     nStringLength;
            sNameExchange = pDnsMxDataSource->pNameExchange;
            nStringLength = sNameExchange.GetLength();
            if(nStringLength > 0)
            {
                if(sNameExchange[nStringLength -1] != _T('.'))
                {
                    sNameExchange += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameExchange);
            }
            pDnsMxData->pNameExchange = pDomainName;
        }
        break;
    case DNS_TYPE_KEY:
    case DNS_TYPE_SIG:
    case DNS_TYPE_RRSIG:
        {
            PDNS_SIG_DATA   pDnsSigData = &m_pDnsRecordData->SIG;
            PDNS_SIG_DATA   pDnsSigDataSoutce = &rSourceRR.m_pDnsRecordData->SIG;
            PWSTR   pDomainName = NULL;
            CString sNameSigner;
            int     nStringLength;
            sNameSigner = pDnsSigDataSoutce->pNameSigner;
            nStringLength = sNameSigner.GetLength();
            if(nStringLength > 0)
            {
                if(sNameSigner[nStringLength -1] != _T('.'))
                {
                    sNameSigner += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameSigner);
            }
            pDnsSigData->pNameSigner = pDomainName;
        }
        break;
    case DNS_TYPE_NXT:
    case DNS_TYPE_NSEC:
        {
            PDNS_NSEC_DATA  pDnsNsecData = &m_pDnsRecordData->NSEC;
            PDNS_NSEC_DATA  pDnsNsecDataSource = &rSourceRR.m_pDnsRecordData->NSEC;
            PWSTR   pDomainName = NULL;
            CString sNameNext;
            int     nStringLength;
            sNameNext = pDnsNsecDataSource->pNextDomainName;
            nStringLength = sNameNext.GetLength();
            if(nStringLength > 0)
            {
                if(sNameNext[nStringLength -1] != _T('.'))
                {
                    sNameNext += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameNext);
            }
            pDnsNsecData->pNextDomainName = pDomainName;
        }
        break;
    case DNS_TYPE_SRV:
        {
            PDNS_SRV_DATA   pDnsSrvData = &m_pDnsRecordData->SRV;
            PDNS_SRV_DATA   pDnsSrvDataSource = &rSourceRR.m_pDnsRecordData->SRV;
            PWSTR   pDomainName = NULL;
            CString sNameTarget;
            int     nStringLength;
            sNameTarget = pDnsSrvDataSource->pNameTarget;
            nStringLength = sNameTarget.GetLength();
            if(nStringLength > 0)
            {
                if(sNameTarget[nStringLength -1] != _T('.'))
                {
                    sNameTarget += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sNameTarget);
            }
            pDnsSrvData->pNameTarget = pDomainName;
        }
        break;
    case DNS_TYPE_NAPTR:
        {
            PDNS_NAPTR_DATA pDnsNaptrData = &m_pDnsRecordData->NAPTR;
            PDNS_NAPTR_DATA pDnsNaptrDataSource = &rSourceRR.m_pDnsRecordData->NAPTR;
            PWSTR   pDomainName = NULL;
            CString sReplacement;
            PWSTR   wsStringValue = NULL;
            CString sStringValue;
            int     nStringLength;
            sStringValue = pDnsNaptrDataSource->pFlags;
            nStringLength = sStringValue.GetLength();
            if(nStringLength > 0)
            {
                wsStringValue = _wcsdup((LPCWSTR)sStringValue);
            }
            pDnsNaptrData->pFlags = wsStringValue;
            sStringValue = CString();
            wsStringValue = NULL;
            sStringValue = pDnsNaptrDataSource->pService;
            nStringLength = sStringValue.GetLength();
            if(nStringLength > 0)
            {
                wsStringValue = _wcsdup((LPCWSTR)sStringValue);
            }
            pDnsNaptrData->pService = wsStringValue;
            sStringValue = CString();
            wsStringValue = NULL;
            sStringValue = pDnsNaptrDataSource->pRegularExpression;
            nStringLength = sStringValue.GetLength();
            if(nStringLength > 0)
            {
                wsStringValue = _wcsdup(wsStringValue);
            }
            pDnsNaptrData->pRegularExpression = wsStringValue;
            sReplacement = pDnsNaptrDataSource->pReplacement;
            nStringLength = sReplacement.GetLength();
            if(nStringLength > 0)
            {
                if(sReplacement[nStringLength -1] != _T('.'))
                {
                    sReplacement += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sReplacement);
            }
            pDnsNaptrData->pReplacement = pDomainName;
        }
        break;
    case DNS_TYPE_TEXT:
    case DNS_TYPE_HINFO:
    case DNS_TYPE_ISDN:
    case DNS_TYPE_X25:
        {
            PDNS_TXT_DATA   pDnsTxtData = &m_pDnsRecordData->TXT;
            PDNS_TXT_DATA   pDnsTxtDataSource = &rSourceRR.m_pDnsRecordData->TXT;
            DWORD   dwStringCount = pDnsTxtData->dwStringCount;
            DWORD   i;
            for(i=0;i<dwStringCount;i++)
            {
                CString sStringValue;
                PWSTR   wsStringValue = NULL;
                int     nStringLength;
                sStringValue = pDnsTxtDataSource->pStringArray[i];
                nStringLength = sStringValue.GetLength();
                if(nStringLength > 0)
                {
                    wsStringValue = _wcsdup((LPCWSTR)sStringValue);
                }
                pDnsTxtData->pStringArray[i] = wsStringValue;
            }
        }
        break;
    case DNS_TYPE_TKEY:
//typedef struct                        -- непонятно что и зачем, и как это соответствует формату TKEY RR,
//{                                     -- а так как нам важно востановливыть данные из DNS_RECORD то установим
//                                      -- следующее соответствие полей:
//    PWSTR           pNameAlgorithm;      -- Algorithm
//    PBYTE           pAlgorithmPacket;    -- NULL
//    PBYTE           pKey;                -- Key Data
//    PBYTE           pOtherData;          -- Other Data
//    DWORD           dwCreateTime;        -- Inception
//    DWORD           dwExpireTime;        -- Expiration
//    WORD            wMode;               -- Mode
//    WORD            wError;              -- Error
//    WORD            wKeyLength;          -- Key Size
//    WORD            wOtherLength;        -- Other Size
//    UCHAR           cAlgNameLength;      -- 0
//    BOOL            bPacketPointers;     -- ? FALSE
//}
//DNS_TKEY_DATAW, *PDNS_TKEY_DATAW;
      //Field       Type         Comment
      //-----       ----         -------

      //NAME         domain      see description below
      //TTYPE        u_int16_t   TKEY = 249
      //CLASS        u_int16_t   ignored, SHOULD be 255 (ANY)
      //TTL          u_int32_t   ignored, SHOULD be zero
      //RDLEN        u_int16_t   size of RDATA
      //RDATA:
      // Algorithm:   domain
      // Inception:   u_int32_t
      // Expiration:  u_int32_t
      // Mode:        u_int16_t
      // Error:       u_int16_t
      // Key Size:    u_int16_t
      // Key Data:    octet-stream
      // Other Size:  u_int16_t
      // Other Data:  octet-stream  undefined by this specification
        {
            PDNS_TKEY_DATA  pDnsTkeyData = &m_pDnsRecordData->TKEY;
            PDNS_TKEY_DATA  pDnsTkeyDataSource = &rSourceRR.m_pDnsRecordData->TKEY;
            PWSTR   pDomainName = NULL;
            CString sDomainName;
            int     nStringLength;
            sDomainName = pDnsTkeyDataSource->pNameAlgorithm;
            nStringLength = sDomainName.GetLength();
            if(nStringLength > 0)
            {
                if(sDomainName[nStringLength -1] != _T('.'))
                {
                    sDomainName += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sDomainName);
            }
            pDnsTkeyData->pNameAlgorithm = pDomainName;
            pDnsTkeyData->wKeyLength = pDnsTkeyDataSource->wKeyLength;
            if(pDnsTkeyData->wKeyLength > 0)
            {
                PBYTE pByteData = (PBYTE)malloc(pDnsTkeyData->wKeyLength);
                RtlCopyMemory(
                    pByteData,
                    pDnsTkeyDataSource->pKey,
                    pDnsTkeyData->wKeyLength
                    );
                pDnsTkeyData->pKey = pByteData;
            }
            pDnsTkeyData->wOtherLength = pDnsTkeyDataSource->wOtherLength;
            if(pDnsTkeyDataSource->wOtherLength > 0)
            {
                PBYTE pByteData = (PBYTE)malloc(pDnsTkeyDataSource->wOtherLength);
                RtlCopyMemory(
                    pByteData,
                    pDnsTkeyDataSource->pOtherData,
                    pDnsTkeyDataSource->wOtherLength
                    );
                pDnsTkeyData->pOtherData = pByteData;
            }
        }
        break;
    case DNS_TYPE_TSIG:
//typedef struct                        -- непонятно что и зачем, и как это соответствует формату TSIG RR,
//{                                     -- а так как нам важно востановливыть данные из DNS_RECORD то установим
//                                      -- следующее соответствие полей:
//    PWSTR           pNameAlgorithm;      -- Algorithm Name
//    PBYTE           pAlgorithmPacket;    -- NULL
//    PBYTE           pSignature;          -- MAC
//    PBYTE           pOtherData;          -- Other Data
//    LONGLONG        i64CreateTime;       -- Time Signed
//    WORD            wFudgeTime;          -- Fudge
//    WORD            wOriginalXid;        -- Original ID
//    WORD            wError;              -- Error
//    WORD            wSigLength;          -- MAC Size
//    WORD            wOtherLength;        -- Other Len
//    UCHAR           cAlgNameLength;      -- 0
//    BOOL            bPacketPointers;     -- ? FALSE
//}
//DNS_TSIG_DATAW, *PDNS_TSIG_DATAW;
      //Field Name       Data Type      Notes
      //--------------------------------------------------------------
      //Algorithm Name   domain-name    Name of the algorithm
      //                                in domain name syntax.
      //Time Signed      u_int48_t      seconds since 1-Jan-70 UTC.
      //Fudge            u_int16_t      seconds of error permitted
      //                                in Time Signed.
      //MAC Size         u_int16_t      number of octets in MAC.
      //MAC              octet stream   defined by Algorithm Name.
      //Original ID      u_int16_t      original message ID
      //Error            u_int16_t      expanded RCODE covering
      //                                TSIG processing.
      //Other Len        u_int16_t      length, in octets, of
      //                                Other m_pDnsRecordData->
      //Other Data       octet stream   empty unless Error == BADTIME
        {
            PDNS_TSIG_DATA  pDnsTsigData = &m_pDnsRecordData->TSIG;
            PDNS_TSIG_DATA  pDnsTsigDataSource = &rSourceRR.m_pDnsRecordData->TSIG;
            PWSTR   pDomainName = NULL;
            CString sDomainName;
            int     nStringLength;
            int     nDataSize;
            PBYTE   pByteData;
            sDomainName = pDnsTsigDataSource->pNameAlgorithm;
            nStringLength = sDomainName.GetLength();
            if(nStringLength > 0)
            {
                if(sDomainName[nStringLength -1] != _T('.'))
                {
                    sDomainName += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sDomainName);
            }
            pDnsTsigData->pNameAlgorithm = pDomainName;
            nDataSize = (int)pDnsTsigDataSource->wSigLength;
            pDnsTsigData->wSigLength = (WORD)nDataSize;
            if(nDataSize > 0)
            {
                pByteData = (PBYTE)malloc(nDataSize);
                RtlCopyMemory(
                    pByteData,
                    pDnsTsigDataSource->pSignature,
                    nDataSize
                    );
                pDnsTsigData->pSignature = pByteData;
            }
            nDataSize = (int)pDnsTsigDataSource->wOtherLength;
            pDnsTsigData->wOtherLength = (WORD)nDataSize;
            if(nDataSize > 0)
            {
                pByteData = (PBYTE)malloc(nDataSize);
                RtlCopyMemory(
                    pByteData,
                    pDnsTsigDataSource->pOtherData,
                    nDataSize
                    );
                pDnsTsigData->pOtherData = pByteData;
            }
        }
        break;
    case DNS_TYPE_WINSR:
        {
            PDNS_WINSR_DATA pDnsWinsrData = &m_pDnsRecordData->WINSR;
            PDNS_WINSR_DATA pDnsWinsrDataSource = &rSourceRR.m_pDnsRecordData->WINSR;
            PWSTR   pDomainName = NULL;
            CString sDomainName;
            int     nStringLength;
            sDomainName = pDnsWinsrDataSource->pNameResultDomain;
            nStringLength = sDomainName.GetLength();
            if(nStringLength > 0)
            {
                if(sDomainName[nStringLength -1] != _T('.'))
                {
                    sDomainName += _T('.');
                    nStringLength++;
                }
                pDomainName = _wcsdup((LPCWSTR)sDomainName);
            }
            if (NULL != pDnsWinsrData->pNameResultDomain)
            {
                free((void*) pDnsWinsrData->pNameResultDomain);
            }
            pDnsWinsrData->pNameResultDomain = pDomainName;
        }
        break;
    }
    //DumpResorceRecord();
}


bool CDnsResorceRecord::FillFromBuffer(PCHAR& pCurrentBufferPoint, CDnsMessageWB& rOwner)
{
    WORD    wDataLength;
    bool    bOutBufer = false;
    m_sName = rOwner.GetDomainName(m_sName, pCurrentBufferPoint);
    INLINE_HTONS(m_wType, *((PWORD) pCurrentBufferPoint));
    pCurrentBufferPoint += 2;
    if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
    {
        TraceEvents(
            TRACE_LEVEL_WARNING,
            TRACE_DNS_RESORCE_RECORD,
            "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
            );
        return false;
    }
    INLINE_HTONS(m_wClass,*((PWORD)pCurrentBufferPoint));
    pCurrentBufferPoint += 2;
    if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
    {
        TraceEvents(
            TRACE_LEVEL_WARNING,
            TRACE_DNS_RESORCE_RECORD,
            "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
            );
        return false;
    }
    INLINE_NTOHL(m_dwTtl,*((PDWORD)pCurrentBufferPoint));
    pCurrentBufferPoint += 4;
    if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
    {
        TraceEvents(
            TRACE_LEVEL_WARNING,
            TRACE_DNS_RESORCE_RECORD,
            "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
            );
        return false;
    }
    INLINE_HTONS(wDataLength,*((PWORD)pCurrentBufferPoint));
    pCurrentBufferPoint += 2;
    if(rOwner.GetRestBytes(pCurrentBufferPoint, wDataLength) < 0)
    {
        TraceEvents(
            TRACE_LEVEL_WARNING,
            TRACE_DNS_RESORCE_RECORD,
            "%!FUNC! line:%!LINE! %!LEVEL! Exit (rOwner.GetRestBytes(pCurrentBufferPoint, wDataLength) < 0)"
            );
        return false;
    }
    m_sRRTypeName = CDnsMessageWB::GetRRTypeName(m_wType);
    switch(m_wType)
    {
    case DNS_TYPE_NULL:
        {
			PDNS_NULL_DATA pDnsNullData;
            m_wDataLength = DNS_NULL_RECORD_LENGTH(wDataLength);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
			pDnsNullData = (PDNS_NULL_DATA)m_pDnsRecordData;
			pDnsNullData->dwByteCount = wDataLength;
        }
        break;
    case DNS_TYPE_KEY:
//typedef struct                       -- структура в "WinDNS.h" не такая как в документации
//{
//    WORD            wFlags;
//    BYTE            chProtocol;
//    BYTE            chAlgorithm;
//    WORD            wKeyLength;
//    WORD            wPad;            // keep byte field aligned
//    BYTE            Key[1];
//}
//DNS_KEY_DATA, *PDNS_KEY_DATA, DNS_DNSKEY_DATA, *PDNS_DNSKEY_DATA;
   //                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3   -- RFC3445
   // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   //|              flags            |   protocol    |   algorithm   |
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   //|                                                               /
   ///                        public key                             /
   ///                                                               /
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    case DNS_TYPE_DNSKEY:
   //                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3   -- RFC4034
   // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   //|              Flags            |    Protocol   |   Algorithm   |
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   ///                                                               /
   ///                            Public Key                         /
   ///                                                               /
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
        {
            SHORT   nByteCount;
            if(rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0)
            {
                m_wDataLength = DNS_KEY_RECORD_LENGTH(0);
                m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
                RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
                break;
            }
            nByteCount = (SHORT)wDataLength - 4;
            if(nByteCount < 0)
            {
                nByteCount = 0;
            }
            m_wDataLength = DNS_KEY_RECORD_LENGTH(nByteCount);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
            m_pDnsRecordData->KEY.wKeyLength = (WORD)nByteCount;
        }
        break;
    case DNS_TYPE_OPT:
        {
//typedef struct
//{                                <-- пропущено поле OPTION-CODE (WORD)  RFC 2671
//    WORD            wDataLength;
//    WORD            wPad;            // keep byte field aligned
//    BYTE            Data[1];
//}
//DNS_OPT_DATA, *PDNS_OPT_DATA;
  //              +0 (MSB)                            +1 (LSB)
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  //0: |                          OPTION-CODE                          |
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  //2: |                         OPTION-LENGTH                         |
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  //4: |                                                               |
  //   /                          OPTION-DATA                          /
  //   /                                                               /
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
            WORD    wByteCount;
            if(rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0)
            {
                m_wDataLength = DNS_OPTD_RECORD_LENGTH(0);
                m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
                RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
                break;
            }
            INLINE_NTOHS(wByteCount,*((PWORD)(pCurrentBufferPoint + 2)));
            m_wDataLength = DNS_OPTD_RECORD_LENGTH(wByteCount);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_SIG:
//typedef struct
//{
//    WORD            wTypeCovered;
//    BYTE            chAlgorithm;
//    BYTE            chLabelCount;
//    DWORD           dwOriginalTtl;
//    DWORD           dwExpiration;
//    DWORD           dwTimeSigned;
//    WORD            wKeyTag;
//    WORD            wSignatureLength;
//    PWSTR           pNameSigner;
//    BYTE            Signature[1];
//}
//DNS_SIG_DATAW, *PDNS_SIG_DATAW, DNS_RRSIG_DATAW, *PDNS_RRSIG_DATAW;
    case DNS_TYPE_RRSIG:
        {
            PCHAR   pDataPoint = pCurrentBufferPoint + 18;
            CString sNameSigner;
            SHORT   nByteCount;
            if(rOwner.GetRestBytes(pCurrentBufferPoint, 18) < 0)
            {
                m_wDataLength = DNS_SIG_RECORD_LENGTH(0);
                m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
                RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
                break;
            }
            sNameSigner = rOwner.GetDomainName(sNameSigner, pDataPoint);
            nByteCount = (SHORT) wDataLength - (SHORT) (pDataPoint - pCurrentBufferPoint);
            if(nByteCount < 0)
            {
                nByteCount = 0;
            }
            m_wDataLength = DNS_SIG_RECORD_LENGTH(nByteCount);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_NXT:
   //                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
   // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   //|                  next domain name                             /
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   //|                    type bit map                               /
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
    case DNS_TYPE_NSEC:
   //                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
   // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   ///                      Next Domain Name                         /  -- интерпретация битовой карты типов NSEC отличается
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  -- от интерпретации NXT но структура RR одинакова,
   ///                       Type Bit Maps                           /  -- поэтому будем воспринимать запись как DNS_NSEC_DATA
   //+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+  -- в обох случаях
        {
            PDNS_NSEC_DATA  pDnsNsecData;
            PCHAR   pDataPoint = pCurrentBufferPoint;
            CString sNameNext;
            SHORT   nByteCount;
            sNameNext = rOwner.GetDomainName(sNameNext, pDataPoint);
            nByteCount = (SHORT) wDataLength - (SHORT) (pDataPoint - pCurrentBufferPoint);
            if(nByteCount < 0)
            {
                nByteCount = 0;
            }
            m_wDataLength = DNS_NSEC_RECORD_LENGTH(nByteCount);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
			pDnsNsecData = (PDNS_NSEC_DATA)m_pDnsRecordData;
			pDnsNsecData->wTypeBitMapsLength = nByteCount;
        }
        break;
    case DNS_TYPE_TEXT:
    case DNS_TYPE_HINFO:
    case DNS_TYPE_ISDN:
    case DNS_TYPE_X25:
        {
            PBYTE   pStrings = (PBYTE)pCurrentBufferPoint;
            WORD    i = 0;
            DWORD   dwStringCount = 0;
            do
            {
                WORD    nStringLength = (WORD)pStrings[i];
                if(nStringLength == 0)
                {
                    break;
                }
                dwStringCount++;
                i += nStringLength + 1;
                if(i >= wDataLength)
                {
                    break;
                }
            } while(true);
            m_wDataLength = (WORD)DNS_TEXT_RECORD_LENGTH(dwStringCount);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
            m_pDnsRecordData->TXT.dwStringCount = dwStringCount;
        }
        break;
    case DNS_TYPE_DS:
        {
            SHORT   nByteCount;
            if(rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0)
            {
                m_wDataLength = DNS_DS_RECORD_LENGTH(0);
                m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
                RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
                break;
            }
            nByteCount = (SHORT)wDataLength - 4;
            if(nByteCount < 0)
            {
                nByteCount = 0;
            }
            m_wDataLength = DNS_DS_RECORD_LENGTH(nByteCount);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
            m_pDnsRecordData->DS.wDigestLength = (WORD)nByteCount;
        }
        break;
    case DNS_TYPE_DHCID:
        {
            m_wDataLength = DNS_DHCID_RECORD_LENGTH(wDataLength);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
            m_pDnsRecordData->DHCID.dwByteCount = (DWORD)wDataLength;
        }
        break;
    //case DNS_TYPE_NSEC3:
    //    {
    //        m_wDataLength = DNS_NSEC3_RECORD_LENGTH(wDataLength);
    //        m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
    //        RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
    //        m_pDnsRecordData->NSEC3.dwByteCount = (DWORD) wDataLength;
    //    }
    //    break;
    case DNS_TYPE_SOA:
        {
            m_wDataLength = sizeof(DNS_SOA_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_PTR:
    case DNS_TYPE_NS:
    case DNS_TYPE_MD:
    case DNS_TYPE_MF:
    case DNS_TYPE_CNAME:
    case DNS_TYPE_MB:
    case DNS_TYPE_MG:
    case DNS_TYPE_MR:
    case DNS_TYPE_DNAME:
        {
            m_wDataLength = sizeof(DNS_PTR_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_MINFO:
    case DNS_TYPE_RP:
        {
            m_wDataLength = sizeof(DNS_MINFO_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_MX:
    case DNS_TYPE_AFSDB:
    case DNS_TYPE_RT:
    case DNS_TYPE_KX:
        {
            m_wDataLength = sizeof(DNS_MX_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_SRV:
        {
            m_wDataLength = sizeof(DNS_SRV_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_NAPTR:
        {
            m_wDataLength = sizeof(DNS_NAPTR_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_TKEY:
        {
            m_wDataLength = sizeof(DNS_TKEY_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_TSIG:
        {
            m_wDataLength = sizeof(DNS_TSIG_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_WINSR:
        {
            m_wDataLength = sizeof(DNS_WINSR_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    case DNS_TYPE_LOC:
        {
            m_wDataLength = sizeof(DNS_LOC_DATA);
            m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
            RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
        }
        break;
    default:
        m_wDataLength = wDataLength;
        m_pDnsRecordData = (PDNS_DATA) malloc(m_wDataLength);
        RtlZeroMemory(m_pDnsRecordData, m_wDataLength);
    }
    m_unDnsRecordFlags.S.CharSet = DnsCharSetUnicode;
    switch(m_wType)
    {
    case DNS_TYPE_SOA:
        {
            PWSTR   pDomainName = NULL;
            CString sNamePrimaryServer;
            CString sNameAdministrator;
            int     nStringLength;
            PDNS_SOA_DATA   pSoaData = &m_pDnsRecordData->SOA;
            DWORD   dwValue;
            bool    bNewSerialNo = false;
            sNamePrimaryServer = rOwner.GetDomainName(sNamePrimaryServer, pCurrentBufferPoint);
            nStringLength = sNamePrimaryServer.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNamePrimaryServer);
            }
            pSoaData->pNamePrimaryServer = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDomainName = NULL;
            sNameAdministrator = rOwner.GetDomainName(sNameAdministrator, pCurrentBufferPoint);
            nStringLength = sNameAdministrator.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameAdministrator);
            }
            pSoaData->pNameAdministrator = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pSoaData->dwSerialNo = dwValue;
            bNewSerialNo = (theApp.m_dwSerialNo != dwValue);
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pSoaData->dwRefresh = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pSoaData->dwRetry = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pSoaData->dwExpire = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            pSoaData->dwDefaultTtl = dwValue;
            if(DnsNameCompare_W(
                (PCWSTR) theApp.m_pDnsZoneRecord->m_sName,
                (PCWSTR)m_sName
                ) && bNewSerialNo)
            {
                PDNS_SOA_DATA   pSoaDataDistanation = &theApp.m_pDnsZoneRecord->m_pDnsRecordData->SOA;
                BOOL            bRet;
                if (NULL != pSoaDataDistanation->pNameAdministrator)
                {
                    free(pSoaDataDistanation->pNameAdministrator);
                }
                if (NULL != pSoaDataDistanation->pNamePrimaryServer)
                {
                    free(pSoaDataDistanation->pNamePrimaryServer);
                }
                RtlCopyMemory(
                    pSoaDataDistanation,
                    pSoaData,
                    m_wDataLength
                    );
                sNamePrimaryServer = pSoaData->pNamePrimaryServer;
                nStringLength = sNamePrimaryServer.GetLength();
                pDomainName = NULL;
                if(nStringLength > 0)
                {
                    pDomainName = _wcsdup((LPCWSTR)sNamePrimaryServer);
                }
                pSoaDataDistanation->pNamePrimaryServer = pDomainName;
                sNameAdministrator = pSoaData->pNameAdministrator;
                nStringLength = sNameAdministrator.GetLength();
                pDomainName = NULL;
                if(nStringLength > 0)
                {
                    pDomainName = _wcsdup((LPCWSTR)sNameAdministrator);
                }
                pSoaDataDistanation->pNameAdministrator = pDomainName;
                theApp.m_dwSerialNo = pSoaData->dwSerialNo;
                bRet = WriteConfigString(
                    _T("service_settings"),
                    _T("pNamePrimaryServer"),
                    sNamePrimaryServer
                    );
                bRet = WriteConfigString(
                    _T("service_settings"),
                    _T("pNameAdministrator"),
                    sNameAdministrator
                    );
                bRet = WriteConfigInt(
                    _T("service_settings"),
                    _T("dwSerialNo"),
                    pSoaData->dwSerialNo
                    );
                bRet = WriteConfigInt(
                    _T("service_settings"),
                    _T("dwRefresh"),
                    pSoaData->dwRefresh
                    );
                bRet = WriteConfigInt(
                    _T("service_settings"),
                    _T("dwRetry"),
                    pSoaData->dwRetry
                    );
                bRet = WriteConfigInt(
                    _T("service_settings"),
                    _T("dwExpire"),
                    pSoaData->dwExpire
                    );
                bRet = WriteConfigInt(
                    _T("service_settings"),
                    _T("dwDefaultTtl"),
                    pSoaData->dwDefaultTtl
                    );
                //bRet = WriteConfigInt(
                //    _T("service_settings"),
                //    _T("dwFlags"),
                //    dwFlags
                //    );
                //bRet = WriteConfigInt(
                //    _T("service_settings"),
                //    _T("dwTtl"),
                //    dwTtl
                //    );
            }
        }
        break;
    case DNS_TYPE_PTR:
    case DNS_TYPE_NS:
    case DNS_TYPE_MD:
    case DNS_TYPE_MF:
    case DNS_TYPE_CNAME:
    case DNS_TYPE_MB:
    case DNS_TYPE_MG:
    case DNS_TYPE_MR:
    case DNS_TYPE_DNAME:
        {
            PDNS_PTR_DATA   pDnsPtrData = &m_pDnsRecordData->PTR;
            PWSTR   pDomainName = NULL;
            CString sNameHost;
            int     nStringLength;
            sNameHost = rOwner.GetDomainName(sNameHost, pCurrentBufferPoint);
            nStringLength = sNameHost.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameHost);
            }
            pDnsPtrData->pNameHost = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_NULL:
        {
            PDNS_NULL_DATA  pDnsNullData = &m_pDnsRecordData->Null;
            pDnsNullData->dwByteCount = wDataLength;
            RtlCopyMemory(
                pDnsNullData->Data,
                pCurrentBufferPoint,
                wDataLength
                );
            pCurrentBufferPoint += wDataLength;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_MINFO:
    case DNS_TYPE_RP:
        {
            PDNS_MINFO_DATA pDnsMinfoData = &m_pDnsRecordData->MINFO;
            PWSTR   pDomainName = NULL;
            CString sNameMailbox;
            CString sNameErrorsMailbox;
            int     nStringLength;
            sNameMailbox = rOwner.GetDomainName(sNameMailbox, pCurrentBufferPoint);
            nStringLength = sNameMailbox.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameMailbox);
            }
            pDnsMinfoData->pNameMailbox = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDomainName = NULL;
            sNameErrorsMailbox = rOwner.GetDomainName(sNameErrorsMailbox, pCurrentBufferPoint);
            nStringLength = sNameErrorsMailbox.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameErrorsMailbox);
            }
            pDnsMinfoData->pNameErrorsMailbox = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_MX:
    case DNS_TYPE_AFSDB:
    case DNS_TYPE_RT:
    case DNS_TYPE_KX:
        {
            PDNS_MX_DATA pDnsMxData = &m_pDnsRecordData->MX;
            PWSTR   pDomainName = NULL;
            CString sNameExchange;
            int     nStringLength;
            WORD    wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsMxData->wPreference = wValue;
            sNameExchange = rOwner.GetDomainName(sNameExchange, pCurrentBufferPoint);
            nStringLength = sNameExchange.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameExchange);
            }
            pDnsMxData->pNameExchange = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_KEY:
//typedef struct                       -- структура в "WinDNS.h" не такая как в документации
//{
//    WORD            wFlags;
//    BYTE            chProtocol;
//    BYTE            chAlgorithm;
//    WORD            wKeyLength;
//    WORD            wPad;            // keep byte field aligned
//    BYTE            Key[1];
//}
//DNS_KEY_DATA, *PDNS_KEY_DATA, DNS_DNSKEY_DATA, *PDNS_DNSKEY_DATA;
    case DNS_TYPE_DNSKEY:
        {
            PDNS_KEY_DATA   pDnsKeyData = &m_pDnsRecordData->KEY;
            WORD    wValue;
            WORD    wByteCount = pDnsKeyData->wKeyLength;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsKeyData->wFlags = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsKeyData->chProtocol = (BYTE)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsKeyData->chAlgorithm = (BYTE)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            if(wByteCount > 0)
            {
                RtlCopyMemory(
                    pDnsKeyData->Key,
                    pCurrentBufferPoint,
                    wByteCount
                    );
                pCurrentBufferPoint += wByteCount;
                if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
                {
                    TraceEvents(
                        TRACE_LEVEL_WARNING,
                        TRACE_DNS_RESORCE_RECORD,
                        "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                        );
                    return false;
                }
            }
        }
        break;
    case DNS_TYPE_SIG:
    case DNS_TYPE_RRSIG:
        {
            PDNS_SIG_DATA   pDnsSigData = &m_pDnsRecordData->SIG;
            PWSTR   pDomainName = NULL;
            CString sNameSigner;
            int     nStringLength;
            WORD    wValue;
            DWORD   dwValue;
            PCHAR   pDataPoint = pCurrentBufferPoint;
            SHORT   nByteCount;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsSigData->wTypeCovered = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsSigData->chAlgorithm = (BYTE)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsSigData->chLabelCount = (BYTE)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsSigData->dwOriginalTtl = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsSigData->dwExpiration = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsSigData->dwTimeSigned = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            pDnsSigData->wKeyTag = wValue;
            sNameSigner = rOwner.GetDomainName(sNameSigner, pCurrentBufferPoint);
            nStringLength = sNameSigner.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameSigner);
            }
            pDnsSigData->pNameSigner = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            nByteCount = (SHORT)wDataLength - (SHORT)(pCurrentBufferPoint - pDataPoint);
            if(nByteCount <= 0)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (nByteCount <= 0)"
                    );
                return false;
            }
            RtlCopyMemory(
                pDnsSigData->Signature,
                pCurrentBufferPoint,
                nByteCount
                );
            pCurrentBufferPoint += nByteCount;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_NXT:
    case DNS_TYPE_NSEC:
        {
            PDNS_NSEC_DATA  pDnsNsecData = &m_pDnsRecordData->NSEC;
            PWSTR   pDomainName = NULL;
            CString sNameNext;
            int     nStringLength;
            WORD    wByteCount;
            sNameNext = rOwner.GetDomainName(sNameNext, pCurrentBufferPoint);
            nStringLength = sNameNext.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameNext);
            }
            pDnsNsecData->pNextDomainName = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            wByteCount = pDnsNsecData->wTypeBitMapsLength;
            if(wByteCount == 0)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (wByteCount == 0)"
                    );
                return false;
            }
            RtlCopyMemory(
                pDnsNsecData->TypeBitMaps,
                pCurrentBufferPoint,
                wByteCount
                );
            pCurrentBufferPoint += wByteCount;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_SRV:
        {
            PDNS_SRV_DATA   pDnsSrvData = &m_pDnsRecordData->SRV;
            PWSTR   pDomainName = NULL;
            CString sNameTarget;
            int     nStringLength;
            WORD    wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsSrvData->wPriority = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsSrvData->wWeight = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsSrvData->wPort = wValue;
            sNameTarget = rOwner.GetDomainName(sNameTarget, pCurrentBufferPoint);
            nStringLength = sNameTarget.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sNameTarget);
            }
            pDnsSrvData->pNameTarget = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_NAPTR:
        {
            PDNS_NAPTR_DATA pDnsNaptrData = &m_pDnsRecordData->NAPTR;
            PWSTR   pDomainName = NULL;
            CString sReplacement;
            PWSTR   wsStringValue = NULL;
            CString sStringValue;
            int     nStringLength;
            WORD    wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsNaptrData->wOrder = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsNaptrData->wPreference = wValue;
            sStringValue = rOwner.GetCharSTRING(sStringValue, pCurrentBufferPoint);
            nStringLength = sStringValue.GetLength();
            if(nStringLength > 0)
            {
                wsStringValue = _wcsdup((LPCWSTR)sStringValue);
            }
            pDnsNaptrData->pFlags = wsStringValue;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            sStringValue = CString();
            wsStringValue = NULL;
            sStringValue = rOwner.GetCharSTRING(sStringValue, pCurrentBufferPoint);
            nStringLength = sStringValue.GetLength();
            if(nStringLength > 0)
            {
                wsStringValue = _wcsdup((LPCWSTR)sStringValue);
            }
            pDnsNaptrData->pService = wsStringValue;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            sStringValue = CString();
            wsStringValue = NULL;
            sStringValue = rOwner.GetCharSTRING(sStringValue, pCurrentBufferPoint);
            nStringLength = sStringValue.GetLength();
            if(nStringLength > 0)
            {
                wsStringValue = _wcsdup(wsStringValue);
            }
            pDnsNaptrData->pRegularExpression = wsStringValue;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            sReplacement = rOwner.GetDomainName(sReplacement, pCurrentBufferPoint);
            nStringLength = sReplacement.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sReplacement);
            }
            pDnsNaptrData->pReplacement = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_OPT:
        {
//typedef struct
//{                                <-- пропущено поле OPTION-CODE (WORD)  RFC 2671
//    WORD            wDataLength;
//    WORD            wPad;            // keep byte field aligned  <==> OPTION-CODE
//    BYTE            Data[1];
//}
//DNS_OPT_DATA, *PDNS_OPT_DATA;
  //              +0 (MSB)                            +1 (LSB)
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  //0: |                          OPTION-CODE                          |
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  //2: |                         OPTION-LENGTH                         |
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
  //4: |                                                               |
  //   /                          OPTION-DATA                          /
  //   /                                                               /
  //   +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
            PDNS_OPTD_DATA  pDnsOptdData = &m_pDnsRecordData->OPT;
            WORD    wValue;
            int     nDataLength;
            PCHAR   pDataPoint = pCurrentBufferPoint;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                break;
            }
            INLINE_NTOHS(wValue,*((PWORD)pDataPoint));
            pDataPoint += 2;
            pDnsOptdData->wOptionCode = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pDataPoint));
            pDataPoint += 2;
            pDnsOptdData->wDataLength = wValue;
            nDataLength = (int)wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, wValue) < 0);
            if(bOutBufer)
            {
                nDataLength = (int)((pCurrentBufferPoint + wDataLength) - pDataPoint);
                pDnsOptdData->wDataLength = (nDataLength > 0) ? (WORD)nDataLength : 0 ;
            }
            if(nDataLength > 0)
            {
                RtlCopyMemory(
                    pDnsOptdData->Data,
                    pDataPoint,
                    nDataLength
                    );
            }
            pCurrentBufferPoint += wDataLength;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_TEXT:
    case DNS_TYPE_HINFO:
    case DNS_TYPE_ISDN:
    case DNS_TYPE_X25:
        {
            PDNS_TXT_DATA   pDnsTxtData = &m_pDnsRecordData->TXT;
            DWORD   dwStringCount = pDnsTxtData->dwStringCount;
            DWORD   i;
            for(i=0;i<dwStringCount;i++)
            {
                CString sStringValue;
                PWSTR   wsStringValue = NULL;
                int     nStringLength;
                sStringValue = rOwner.GetCharSTRING(sStringValue, pCurrentBufferPoint);
                nStringLength = sStringValue.GetLength();
                if(nStringLength > 0)
                {
                    wsStringValue = _wcsdup((LPCWSTR)sStringValue);
                }
                pDnsTxtData->pStringArray[i] = wsStringValue;
                if(bOutBufer)
                {
                    TraceEvents(
                        TRACE_LEVEL_WARNING,
                        TRACE_DNS_RESORCE_RECORD,
                        "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                        );
                    return false;
                }
            }
        }
        break;
    case DNS_TYPE_DS:
        {
            PDNS_DS_DATA    pDnsDsData = &m_pDnsRecordData->DS;
            WORD    wValue;
            WORD    wDigestLength = pDnsDsData->wDigestLength;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsDsData->wKeyTag = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsDsData->chAlgorithm = (BYTE)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsDsData->chDigestType = (BYTE)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            if(wDigestLength > 0)
            {
                RtlCopyMemory(
                    pDnsDsData->Digest,
                    pCurrentBufferPoint,
                    wDigestLength
                    );
            }
            pCurrentBufferPoint += wDigestLength;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_TKEY:
//typedef struct                        -- непонятно что и зачем, и как это соответствует формату TKEY RR,
//{                                     -- а так как нам важно востановливыть данные из DNS_RECORD то установим
//                                      -- следующее соответствие полей:
//    PWSTR           pNameAlgorithm;      -- Algorithm
//    PBYTE           pAlgorithmPacket;    -- NULL
//    PBYTE           pKey;                -- Key Data
//    PBYTE           pOtherData;          -- Other Data
//    DWORD           dwCreateTime;        -- Inception
//    DWORD           dwExpireTime;        -- Expiration
//    WORD            wMode;               -- Mode
//    WORD            wError;              -- Error
//    WORD            wKeyLength;          -- Key Size
//    WORD            wOtherLength;        -- Other Size
//    UCHAR           cAlgNameLength;      -- 0
//    BOOL            bPacketPointers;     -- ? FALSE
//}
//DNS_TKEY_DATAW, *PDNS_TKEY_DATAW;
      //Field       Type         Comment
      //-----       ----         -------

      //NAME         domain      see description below
      //TTYPE        u_int16_t   TKEY = 249
      //CLASS        u_int16_t   ignored, SHOULD be 255 (ANY)
      //TTL          u_int32_t   ignored, SHOULD be zero
      //RDLEN        u_int16_t   size of RDATA
      //RDATA:
      // Algorithm:   domain
      // Inception:   u_int32_t
      // Expiration:  u_int32_t
      // Mode:        u_int16_t
      // Error:       u_int16_t
      // Key Size:    u_int16_t
      // Key Data:    octet-stream
      // Other Size:  u_int16_t
      // Other Data:  octet-stream  undefined by this specification
        {
            PDNS_TKEY_DATA  pDnsTkeyData = &m_pDnsRecordData->TKEY;
            PWSTR   pDomainName = NULL;
            CString sDomainName;
            int     nStringLength;
            WORD    wValue;
            DWORD   dwValue;
            int     nDataSize;
            PBYTE   pByteData;
            sDomainName = rOwner.GetDomainName(sDomainName, pCurrentBufferPoint);
            nStringLength = sDomainName.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sDomainName);
            }
            pDnsTkeyData->pNameAlgorithm = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsTkeyData->dwCreateTime = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsTkeyData->dwExpireTime = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsTkeyData->wMode = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsTkeyData->wError = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, wValue) < 0);
            nDataSize = (int)wValue;
            if(bOutBufer)
            {
                nDataSize = rOwner.GetRestBytes(pCurrentBufferPoint, 0);
            }
            pDnsTkeyData->wKeyLength = (WORD)nDataSize;
            if(nDataSize > 0)
            {
                pByteData = (PBYTE)malloc(nDataSize);
                RtlCopyMemory(
                    pByteData,
                    pCurrentBufferPoint,
                    nDataSize
                    );
                pDnsTkeyData->pKey = pByteData;
            }
            pCurrentBufferPoint += nDataSize;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, wValue) < 0);
            nDataSize = (int)wValue;
            if(bOutBufer)
            {
                nDataSize = rOwner.GetRestBytes(pCurrentBufferPoint, 0);
            }
            pDnsTkeyData->wOtherLength = (WORD)nDataSize;
            if(nDataSize > 0)
            {
                pByteData = (PBYTE)malloc(nDataSize);
                RtlCopyMemory(
                    pByteData,
                    pCurrentBufferPoint,
                    nDataSize
                    );
                pDnsTkeyData->pOtherData = pByteData;
            }
            pCurrentBufferPoint += nDataSize;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_TSIG:
//typedef struct                        -- непонятно что и зачем, и как это соответствует формату TSIG RR,
//{                                     -- а так как нам важно востановливыть данные из DNS_RECORD то установим
//                                      -- следующее соответствие полей:
//    PWSTR           pNameAlgorithm;      -- Algorithm Name
//    PBYTE           pAlgorithmPacket;    -- NULL
//    PBYTE           pSignature;          -- MAC
//    PBYTE           pOtherData;          -- Other Data
//    LONGLONG        i64CreateTime;       -- Time Signed
//    WORD            wFudgeTime;          -- Fudge
//    WORD            wOriginalXid;        -- Original ID
//    WORD            wError;              -- Error
//    WORD            wSigLength;          -- MAC Size
//    WORD            wOtherLength;        -- Other Len
//    UCHAR           cAlgNameLength;      -- 0
//    BOOL            bPacketPointers;     -- ? FALSE
//}
//DNS_TSIG_DATAW, *PDNS_TSIG_DATAW;
      //Field Name       Data Type      Notes
      //--------------------------------------------------------------
      //Algorithm Name   domain-name    Name of the algorithm
      //                                in domain name syntax.
      //Time Signed      u_int48_t      seconds since 1-Jan-70 UTC.
      //Fudge            u_int16_t      seconds of error permitted
      //                                in Time Signed.
      //MAC Size         u_int16_t      number of octets in MAC.
      //MAC              octet stream   defined by Algorithm Name.
      //Original ID      u_int16_t      original message ID
      //Error            u_int16_t      expanded RCODE covering
      //                                TSIG processing.
      //Other Len        u_int16_t      length, in octets, of
      //                                Other m_pDnsRecordData->
      //Other Data       octet stream   empty unless Error == BADTIME
        {
            PDNS_TSIG_DATA  pDnsTsigData = &m_pDnsRecordData->TSIG;
            PWSTR   pDomainName = NULL;
            CString sDomainName;
            int     nStringLength;
            WORD    wValue;
            LONGLONG    i64CreateTime;
            int     nDataSize;
            PBYTE   pByteData;
            sDomainName = rOwner.GetDomainName(sDomainName, pCurrentBufferPoint);
            nStringLength = sDomainName.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sDomainName);
            }
            pDnsTsigData->pNameAlgorithm = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 6) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHQ(i64CreateTime,(*((PQWORD)pCurrentBufferPoint) << 16));
            pCurrentBufferPoint += 6;
            pDnsTsigData->i64CreateTime = i64CreateTime;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            pDnsTsigData->wFudgeTime = wValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, wValue) < 0);
            nDataSize = (int)wValue;
            if(bOutBufer)
            {
                nDataSize = rOwner.GetRestBytes(pCurrentBufferPoint, 0);
            }
            pDnsTsigData->wSigLength = (WORD)nDataSize;
            if(nDataSize > 0)
            {
                pByteData = (PBYTE)malloc(nDataSize);
                RtlCopyMemory(
                    pByteData,
                    pCurrentBufferPoint,
                    nDataSize
                    );
                pDnsTsigData->pSignature = pByteData;
            }
            pCurrentBufferPoint += nDataSize;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 2) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHS(wValue,*((PWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 2;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, wValue) < 0);
            nDataSize = (int)wValue;
            if(bOutBufer)
            {
                nDataSize = rOwner.GetRestBytes(pCurrentBufferPoint, 0);
            }
            pDnsTsigData->wOtherLength = (WORD)nDataSize;
            if(nDataSize > 0)
            {
                pByteData = (PBYTE)malloc(nDataSize);
                RtlCopyMemory(
                    pByteData,
                    pCurrentBufferPoint,
                    nDataSize
                    );
                pDnsTsigData->pOtherData = pByteData;
            }
            pCurrentBufferPoint += nDataSize;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_WINS:
        {
            PDNS_WINS_DATA  pDnsWinsData = &m_pDnsRecordData->WINS;
            DWORD   dwValue;
            DWORD   i;
            DWORD   cWinsServerCount;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsWinsData->dwMappingFlag = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsWinsData->dwLookupTimeout = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsWinsData->dwCacheTimeout = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            cWinsServerCount = dwValue;
            pDnsWinsData->cWinsServerCount = cWinsServerCount;
            for(i=0;i<cWinsServerCount;i++)
            {
                bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
                if(bOutBufer)
                {
                    TraceEvents(
                        TRACE_LEVEL_WARNING,
                        TRACE_DNS_RESORCE_RECORD,
                        "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                        );
                    return false;
                }
                dwValue = *((PDWORD)pCurrentBufferPoint);
                pDnsWinsData->WinsServers[i] = dwValue;
                pCurrentBufferPoint += 4;
            }
        }
        break;
    case DNS_TYPE_WINSR:
        {
            PDNS_WINSR_DATA pDnsWinsrData = &m_pDnsRecordData->WINSR;
            DWORD   dwValue;
            PWSTR   pDomainName = NULL;
            CString sDomainName;
            int     nStringLength;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsWinsrData->dwMappingFlag = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsWinsrData->dwLookupTimeout = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsWinsrData->dwCacheTimeout = dwValue;
            sDomainName = rOwner.GetDomainName(sDomainName, pCurrentBufferPoint);
            nStringLength = sDomainName.GetLength();
            if(nStringLength > 0)
            {
                pDomainName = _wcsdup((LPCWSTR)sDomainName);
            }
            pDnsWinsrData->pNameResultDomain = pDomainName;
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
        }
        break;
    case DNS_TYPE_DHCID:
        {
            PDNS_DHCID_DATA pDnsDhcidData = &m_pDnsRecordData->DHCID;
            pDnsDhcidData->dwByteCount = (DWORD)wDataLength;
            if(wDataLength > 0)
            {
                RtlCopyMemory(
                    pDnsDhcidData->DHCID,
                    pCurrentBufferPoint,
                    wDataLength
                    );
                pCurrentBufferPoint += wDataLength;
                if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
                {
                    TraceEvents(
                        TRACE_LEVEL_WARNING,
                        TRACE_DNS_RESORCE_RECORD,
                        "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))"
                        );
                    return false;
                }
            }
        }
        break;
    case DNS_TYPE_LOC:
        {
            PDNS_LOC_DATA   pDnsLocData = &m_pDnsRecordData->LOC;
            DWORD   dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsLocData->wVersion = (WORD)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsLocData->wSize = (WORD)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsLocData->wHorPrec = (WORD)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 1) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            pDnsLocData->wVerPrec = (WORD)*pCurrentBufferPoint;
            pCurrentBufferPoint++;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsLocData->dwLatitude = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsLocData->dwLongitude = dwValue;
            bOutBufer = (rOwner.GetRestBytes(pCurrentBufferPoint, 4) < 0);
            if(bOutBufer)
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (bOutBufer)"
                    );
                return false;
            }
            INLINE_NTOHL(dwValue,*((PDWORD)pCurrentBufferPoint));
            pCurrentBufferPoint += 4;
            pDnsLocData->dwAltitude = dwValue;
        }
        break;
    default:
        if(wDataLength > 0)
        {
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) + wDataLength <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) + wDataLength <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
            RtlCopyMemory(
                m_pDnsRecordData,
                pCurrentBufferPoint,
                wDataLength
                );
            pCurrentBufferPoint += wDataLength;
            if(!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) <= rOwner.m_nParsedMessageLength))
            {
                TraceEvents(
                    TRACE_LEVEL_WARNING,
                    TRACE_DNS_RESORCE_RECORD,
                    "%!FUNC! line:%!LINE! %!LEVEL! Exit (!((int)(pCurrentBufferPoint - rOwner.m_pParsedMessage) + wDataLength <= rOwner.m_nParsedMessageLength))"
                    );
                return false;
            }
        }
    }
    //DumpResorceRecord();
    return true;
}


void CDnsResorceRecord::DumpResorceRecord()
{
    CString sSectionName;
    TCHAR   szIpAddress[128];
    PTSTR   pAddrEnd;
    DWORD   i;
    TraceEvents(
        TRACE_LEVEL_INFORMATION,
        TRACE_DNS_RECORD_DUMP,
        "Dump Resorce Record:"
        );
    switch (m_unDnsRecordFlags.S.Section)
    {
    case DnsSectionQuestion:
        sSectionName = _T("DnsSectionQuestion");
        break;
    case DnsSectionAnswer:
        sSectionName = _T("DnsSectionAnswer");
        break;
    case DnsSectionAuthority:
        sSectionName = _T("DnsSectionAuthority");
        break;
    case DnsSectionAddtional:
        sSectionName = _T("DnsSectionAddtional");
        break;
    default:
        sSectionName.Format(
            _T("unknown (%u)"),
            m_unDnsRecordFlags.S.Section
            );
        break;
    }
    TraceEvents(
        TRACE_LEVEL_INFORMATION,
        TRACE_DNS_RECORD_DUMP,
        "    Section Name = \"%ws\"",
        (LPCTSTR) sSectionName
        );
    TraceEvents(
        TRACE_LEVEL_INFORMATION,
        TRACE_DNS_RECORD_DUMP,
        "    NAME = \"%ws\"",
        (LPCTSTR) m_sName
        );
    TraceEvents(
        TRACE_LEVEL_INFORMATION,
        TRACE_DNS_RECORD_DUMP,
        "    TYPE = %ws",
        (LPCTSTR) m_sRRTypeName
        );
    TraceEvents(
        TRACE_LEVEL_INFORMATION,
        TRACE_DNS_RECORD_DUMP,
        "    CLASS = %hu",
        m_wClass
        );
    TraceEvents(
        TRACE_LEVEL_INFORMATION,
        TRACE_DNS_RECORD_DUMP,
        "    TTL = %u",
        m_dwTtl
        );
    TraceEvents(
        TRACE_LEVEL_INFORMATION,
        TRACE_DNS_RECORD_DUMP,
        "    RDLENGTH = %hu",
        m_wDataLength
        );
    switch (m_wType)
    {
    case DNS_TYPE_ZERO:
        break;
    case DNS_TYPE_A:
        pAddrEnd = RtlIpv4AddressToString(
            (IN_ADDR*) &m_pDnsRecordData->A.IpAddress,
            szIpAddress
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    A.IpAddress = %ws",
            szIpAddress
            );
        break;
    case DNS_TYPE_NS:
    case DNS_TYPE_MD:
    case DNS_TYPE_MF:
    case DNS_TYPE_CNAME:
    case DNS_TYPE_PTR:
    case DNS_TYPE_MB:
    case DNS_TYPE_MG:
    case DNS_TYPE_MR:
    case DNS_TYPE_DNAME:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    PTR.pNameHost = \"%ws\"",
            m_pDnsRecordData->PTR.pNameHost
            );
        break;
    case DNS_TYPE_SOA:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SOA.pNamePrimaryServer = \"%ws\"",
            m_pDnsRecordData->SOA.pNamePrimaryServer
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SOA.pNameAdministrator = \"%ws\"",
            m_pDnsRecordData->SOA.pNameAdministrator
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SOA.dwSerialNo = %u",
            m_pDnsRecordData->SOA.dwSerialNo
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SOA.dwRefresh = %u",
            m_pDnsRecordData->SOA.dwRefresh
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SOA.dwRetry = %u",
            m_pDnsRecordData->SOA.dwRetry
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SOA.dwExpire = %u",
            m_pDnsRecordData->SOA.dwExpire
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SOA.dwDefaultTtl = %u",
            m_pDnsRecordData->SOA.dwDefaultTtl
            );
        break;
    case DNS_TYPE_NULL:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    Null.dwByteCount = %u",
            m_pDnsRecordData->Null.dwByteCount
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    Null.Data = %p",
            m_pDnsRecordData->Null.Data
            );
        break;
    case DNS_TYPE_WKS:
        pAddrEnd = RtlIpv4AddressToString(
            (IN_ADDR*) &m_pDnsRecordData->WKS.IpAddress,
            szIpAddress
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WKS.IpAddress = %ws",
            szIpAddress
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WKS.chProtocol = %u",
            (DWORD) m_pDnsRecordData->WKS.chProtocol
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WKS.BitMask = %p",
            m_pDnsRecordData->WKS.BitMask
            );
        break;
    case DNS_TYPE_HINFO:
    case DNS_TYPE_TEXT:
    case DNS_TYPE_X25:
    case DNS_TYPE_ISDN:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    TXT.dwStringCount = %u",
            (DWORD) m_pDnsRecordData->TXT.dwStringCount
            );
        for (i = 0; i < m_pDnsRecordData->TXT.dwStringCount; i++)
        {
            TraceEvents(
                TRACE_LEVEL_INFORMATION,
                TRACE_DNS_RECORD_DUMP,
                "    TXT.pStringArray[%u] = \"%ws\"",
                i,
                m_pDnsRecordData->TXT.pStringArray[i]
                );
        }
        break;
    case DNS_TYPE_MINFO:
    case DNS_TYPE_RP:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    MINFO.pNameMailbox = \"%ws\"",
            m_pDnsRecordData->MINFO.pNameMailbox
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    MINFO.pNameErrorsMailbox = \"%ws\"",
            m_pDnsRecordData->MINFO.pNameErrorsMailbox
            );
        break;
    case DNS_TYPE_MX:
    case DNS_TYPE_AFSDB:
    case DNS_TYPE_RT:
    case DNS_TYPE_KX:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    MX.wPreference = %hu",
            m_pDnsRecordData->MX.wPreference
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    MX.pNameExchange = \"%ws\"",
            m_pDnsRecordData->MX.pNameExchange
            );
        break;
    case DNS_TYPE_NSAP:
        break;
    case DNS_TYPE_NSAPPTR:
        break;
    case DNS_TYPE_SIG:
    case DNS_TYPE_RRSIG:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.wTypeCovered = %hu",
            m_pDnsRecordData->SIG.wTypeCovered
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.chAlgorithm = %u",
            (DWORD) m_pDnsRecordData->SIG.chAlgorithm
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.chLabelCount = %u",
            (DWORD) m_pDnsRecordData->SIG.chLabelCount
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.dwOriginalTtl = %u",
            m_pDnsRecordData->SIG.dwOriginalTtl
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.dwExpiration = %u",
            m_pDnsRecordData->SIG.dwExpiration
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.dwTimeSigned = %u",
            m_pDnsRecordData->SIG.dwTimeSigned
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.wKeyTag = %hu",
            m_pDnsRecordData->SIG.wKeyTag
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.wSignatureLength = %hu",
            m_pDnsRecordData->SIG.wSignatureLength
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.pNameSigner = \"%ws\"",
            m_pDnsRecordData->SIG.pNameSigner
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SIG.Signature = %p",
            m_pDnsRecordData->SIG.Signature
            );
        break;
    case DNS_TYPE_KEY:
    case DNS_TYPE_DNSKEY:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    KEY.wFlags = 0x%04hx",
            m_pDnsRecordData->KEY.wFlags
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    KEY.chProtocol = %u",
            (DWORD) m_pDnsRecordData->KEY.chProtocol
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    KEY.chAlgorithm = %u",
            (DWORD) m_pDnsRecordData->KEY.chAlgorithm
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    KEY.wKeyLength = %hu",
            m_pDnsRecordData->KEY.wKeyLength
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    KEY.Key = %p",
            m_pDnsRecordData->KEY.Key
            );
        break;
    case DNS_TYPE_PX:
        break;
    case DNS_TYPE_GPOS:
        break;
    case DNS_TYPE_AAAA:
        pAddrEnd = RtlIpv6AddressToString(
            (const IN6_ADDR*) &m_pDnsRecordData->AAAA.Ip6Address,
            szIpAddress
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    AAAA.Ip6Address = %ws",
            szIpAddress
            );
        break;
    case DNS_TYPE_LOC:
        break;
    case DNS_TYPE_NXT:
    case DNS_TYPE_NSEC:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NSEC.pNextDomainName = \"%ws\"",
            m_pDnsRecordData->NSEC.pNextDomainName
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NSEC.wTypeBitMapsLength = %hu",
            m_pDnsRecordData->NSEC.wTypeBitMapsLength
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NSEC.TypeBitMaps = %p",
            m_pDnsRecordData->NSEC.TypeBitMaps
            );
        break;
    case DNS_TYPE_EID:
        break;
    case DNS_TYPE_NIMLOC:
        break;
    case DNS_TYPE_SRV:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SRV.pNameTarget = \"%ws\"",
            m_pDnsRecordData->SRV.pNameTarget
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SRV.wPriority = %hu",
            m_pDnsRecordData->SRV.wPriority
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SRV.wWeight = %hu",
            m_pDnsRecordData->SRV.wWeight
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    SRV.wPort = %hu",
            m_pDnsRecordData->SRV.wPort
            );
        break;
    case DNS_TYPE_ATMA:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    ATMA.AddressType = %u",
            (DWORD) m_pDnsRecordData->ATMA.AddressType
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    ATMA.Address = %p",
            m_pDnsRecordData->ATMA.Address
            );
        break;
    case DNS_TYPE_NAPTR:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NAPTR.wOrder = %hu",
            m_pDnsRecordData->NAPTR.wOrder
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NAPTR.wPreference = %hu",
            m_pDnsRecordData->NAPTR.wPreference
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NAPTR.pFlags = \"%ws\"",
            m_pDnsRecordData->NAPTR.pFlags
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NAPTR.pService = \"%ws\"",
            m_pDnsRecordData->NAPTR.pService
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NAPTR.pRegularExpression = \"%ws\"",
            m_pDnsRecordData->NAPTR.pRegularExpression
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    NAPTR.pReplacement = \"%ws\"",
            m_pDnsRecordData->NAPTR.pReplacement
            );
        break;
    case DNS_TYPE_CERT:
        break;
    case DNS_TYPE_A6:
        break;
    case DNS_TYPE_SINK:
        break;
    case DNS_TYPE_OPT:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    OPT.wOptionCode = %hu",
            m_pDnsRecordData->OPT.wOptionCode
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    OPT.wDataLength = %hu",
            m_pDnsRecordData->OPT.wDataLength
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    OPT.Data = %p",
            m_pDnsRecordData->OPT.Data
            );
        break;
    case DNS_TYPE_DS:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    DS.wKeyTag = %hu",
            m_pDnsRecordData->DS.wKeyTag
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    DS.chAlgorithm = %u",
            (DWORD) m_pDnsRecordData->DS.chAlgorithm
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    DS.chDigestType = %u",
            (DWORD) m_pDnsRecordData->DS.chDigestType
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    DS.wDigestLength = %hu",
            m_pDnsRecordData->DS.wDigestLength
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    DS.Digest = %p",
            m_pDnsRecordData->DS.Digest
            );
        break;
    case DNS_TYPE_DHCID:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    DHCID.dwByteCount = %u",
            m_pDnsRecordData->DHCID.dwByteCount
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    DHCID.DHCID = %p",
            m_pDnsRecordData->DHCID.DHCID
            );
        break;
    case DNS_TYPE_NSEC3:
        break;
    case DNS_TYPE_NSEC3PARAM:
        break;
    case DNS_TYPE_UINFO:
        break;
    case DNS_TYPE_UID:
        break;
    case DNS_TYPE_GID:
        break;
    case DNS_TYPE_UNSPEC:
        break;
    case DNS_TYPE_ADDRS:
        break;
    case DNS_TYPE_TKEY:
        break;
    case DNS_TYPE_TSIG:
        break;
    case DNS_TYPE_IXFR:
        break;
    case DNS_TYPE_AXFR:
        break;
    case DNS_TYPE_MAILB:
        break;
    case DNS_TYPE_MAILA:
        break;
    case DNS_TYPE_ALL:
        break;
    case DNS_TYPE_WINS:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINS.dwMappingFlag = 0x%08x",
            m_pDnsRecordData->WINS.dwMappingFlag
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINS.dwLookupTimeout = %u",
            m_pDnsRecordData->WINS.dwLookupTimeout
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINS.dwCacheTimeout = %u",
            m_pDnsRecordData->WINS.dwCacheTimeout
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINS.cWinsServerCount = %u",
            m_pDnsRecordData->WINS.cWinsServerCount
            );
        for (i = 0; i < m_pDnsRecordData->WINS.cWinsServerCount; i++)
        {
            pAddrEnd = RtlIpv4AddressToString(
                (IN_ADDR*) &m_pDnsRecordData->WINS.WinsServers[i],
                szIpAddress
                );
            TraceEvents(
                TRACE_LEVEL_INFORMATION,
                TRACE_DNS_RECORD_DUMP,
                "    WINS.WinsServers[%u] = %ws",
                i,
                szIpAddress
                );
        }
        break;
    case DNS_TYPE_WINSR:
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINSR.dwMappingFlag = 0x%08x",
            m_pDnsRecordData->WINSR.dwMappingFlag
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINSR.dwLookupTimeout = %u",
            m_pDnsRecordData->WINSR.dwLookupTimeout
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINSR.pNameResultDomain = \"%ws\"",
            m_pDnsRecordData->WINSR.pNameResultDomain
            );
        TraceEvents(
            TRACE_LEVEL_INFORMATION,
            TRACE_DNS_RECORD_DUMP,
            "    WINSR.dwCacheTimeout = %u",
            m_pDnsRecordData->WINSR.dwCacheTimeout
            );
        break;
    default:
        break;
    }
}
