372 lines
10 KiB
C++
372 lines
10 KiB
C++
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1998 - 1999
|
|
//
|
|
// File: dnsutil.h
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
#ifndef _DNSUTIL_H
|
|
#define _DNSUTIL_H
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// C++ helper classes wrapping the raw DNS RPC API's
|
|
|
|
#define DNS_TYPE_UNK DNS_TYPE_NULL // we treat the two as the same
|
|
|
|
#ifdef USE_NDNC
|
|
typedef enum
|
|
{
|
|
none = 0, // not AD integrated
|
|
forest,
|
|
domain,
|
|
w2k,
|
|
custom
|
|
} ReplicationType;
|
|
#endif
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// macros defining the DNS server version
|
|
|
|
#define DNS_SRV_MAJOR_VERSION(dw) (LOBYTE(LOWORD(dw)))
|
|
#define DNS_SRV_MINOR_VERSION(dw) (HIBYTE(LOWORD(dw)))
|
|
#define DNS_SRV_BUILD_NUMBER(dw) (HIWORD(dw))
|
|
|
|
#define DNS_SRV_MAJOR_VERSION_NT_4 (0x4)
|
|
#define DNS_SRV_MAJOR_VERSION_NT_5 (0x5)
|
|
#define DNS_SRV_MINOR_VERSION_WIN2K (0x0)
|
|
#define DNS_SRV_MINOR_VERSION_WHISTLER (0x1)
|
|
#define DNS_SRV_BUILD_NUMBER_WHISTLER (2230)
|
|
#define DNS_SRV_BUILD_NUMBER_WHISTLER_NEW_SECURITY_SETTINGS (2474)
|
|
#define DNS_SRV_VERSION_NT_4 DNS_SRV_MAJOR_VERSION_NT_4
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// MACROS & DEFINES
|
|
|
|
#define MAX_DNS_NAME_LEN 255
|
|
|
|
// record enumeration
|
|
|
|
#define NEXT_DWORD(cb) ((cb + 3) & ~3)
|
|
//#define IS_DWORD_ALIGNED(pv) (((int)(void *)pv & 3) == 0)
|
|
#define DNS_SIZE_OF_DNS_RPC_RR(pDnsRecord)\
|
|
(SIZEOF_DNS_RPC_RECORD_HEADER + pDnsRecord->wDataLength)
|
|
#define DNS_NEXT_RECORD(pDnsRecord) \
|
|
(DNS_RPC_RECORD *)((BYTE*)pDnsRecord + ((DNS_SIZE_OF_DNS_RPC_RR(pDnsRecord) + 3) & ~3))
|
|
|
|
// RR field manipulation
|
|
//#define INET_NTOA(s) (inet_ntoa (*(in_addr *)&(s)))
|
|
#define REVERSE_WORD_BYTES(w) \
|
|
MAKEWORD(HIBYTE(w), LOBYTE(w))
|
|
|
|
// DNS keywords
|
|
#define INADDR_ARPA_SUFFIX _T(".in-addr.arpa")
|
|
#define ARPA_SUFFIX _T(".arpa")
|
|
#define IP6_INT_SUFFIX _T(".ipv6.int")
|
|
|
|
#define AUTOCREATED_0 _T("0.in-addr.arpa")
|
|
#define AUTOCREATED_127 _T("127.in-addr.arpa")
|
|
#define AUTOCREATED_255 _T("255.in-addr.arpa")
|
|
|
|
|
|
// formatting of IPv4 address to string
|
|
extern LPCWSTR g_szIpStringFmt;
|
|
|
|
#define IP_STRING_MAX_LEN 20 // safe size for a wsprintf buffer
|
|
#define IP_STRING_FMT_ARGS(x) \
|
|
FOURTH_IPADDRESS(x), THIRD_IPADDRESS(x), SECOND_IPADDRESS(x), FIRST_IPADDRESS(x)
|
|
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// macros and functions for UTF8 <-> UNICODE conversion
|
|
// modified from the ATL 1.1 ones in atlbase.h
|
|
|
|
|
|
inline LPWSTR WINAPI DnsUtf8ToWHelper(LPWSTR lpw, LPCSTR lpa, int nChars)
|
|
{
|
|
_ASSERTE(lpa != NULL);
|
|
_ASSERTE(lpw != NULL);
|
|
// verify that no illegal character present
|
|
// since lpw was allocated based on the size of lpa
|
|
// don't worry about the number of chars
|
|
lpw[0] = '\0';
|
|
MultiByteToWideChar(CP_UTF8, 0, lpa, -1, lpw, nChars);
|
|
return lpw;
|
|
}
|
|
|
|
inline LPSTR WINAPI DnsWToUtf8Helper(LPSTR lpa, LPCWSTR lpw, int nChars)
|
|
{
|
|
_ASSERTE(lpw != NULL);
|
|
_ASSERTE(lpa != NULL);
|
|
// verify that no illegal character present
|
|
// since lpa was allocated based on the size of lpw
|
|
// don't worry about the number of chars
|
|
lpa[0] = '\0';
|
|
WideCharToMultiByte(CP_UTF8, 0, lpw, -1, lpa, nChars, NULL, NULL);
|
|
return lpa;
|
|
}
|
|
|
|
inline void WINAPI DnsUtf8ToWCStringHelper(CString& sz, LPCSTR lpa, int nBytes)
|
|
{
|
|
if ( (lpa == NULL) || (nBytes <= 0) )
|
|
{
|
|
sz.Empty();
|
|
return;
|
|
}
|
|
// allocate buffer in string (worst case scenario + NULL)
|
|
int nWideChars = nBytes + 1;
|
|
LPWSTR lpw = sz.GetBuffer(nWideChars);
|
|
int nWideCharsLen = MultiByteToWideChar(CP_UTF8, 0, lpa, nBytes, lpw, nWideChars);
|
|
sz.ReleaseBuffer(nWideCharsLen);
|
|
}
|
|
|
|
#define UTF8_LEN lstrlenA
|
|
|
|
#define UTF8_TO_W(lpa) (\
|
|
((LPCSTR)lpa == NULL) ? NULL : (\
|
|
_convert = (lstrlenA(lpa)+1),\
|
|
DnsUtf8ToWHelper((LPWSTR) alloca(_convert*2), lpa, _convert)))
|
|
|
|
#define W_TO_UTF8(lpw) (\
|
|
((LPCWSTR)lpw == NULL) ? NULL : (\
|
|
_convert = (lstrlenW(lpw)+1)*4,\
|
|
DnsWToUtf8Helper((LPSTR) alloca(_convert), lpw, _convert)))
|
|
|
|
#define UTF8_TO_CW(lpa) ((LPCWSTR)UTF8_TO_W(lpa))
|
|
#define W_TO_CUTF8(lpw) ((LPCSTR)W_TO_UTF8(lpw))
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// estimate UTF8 len of a UNICODE string
|
|
|
|
inline int UTF8StringLen(LPCWSTR lpszWideString)
|
|
{
|
|
USES_CONVERSION;
|
|
LPSTR lpszUTF8 = W_TO_UTF8(lpszWideString);
|
|
return UTF8_LEN(lpszUTF8);
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// General Purpose Utility Functions
|
|
|
|
WORD CharToNumber(WCHAR ch);
|
|
BYTE HexCharToByte(WCHAR ch);
|
|
|
|
BOOL IsValidIPString(LPCWSTR lpsz);
|
|
DNS_STATUS ValidateDnsNameAgainstServerFlags(LPCWSTR lpszName,
|
|
DNS_NAME_FORMAT format,
|
|
DWORD serverNameChecking);
|
|
DWORD IPStringToAddr(LPCWSTR lpsz);
|
|
|
|
inline void FormatIpAddress(LPWSTR lpszBuf, DWORD dwIpAddr)
|
|
{
|
|
wsprintf(lpszBuf, g_szIpStringFmt, IP_STRING_FMT_ARGS(dwIpAddr));
|
|
}
|
|
|
|
inline void FormatIpAddress(CString& szBuf, DWORD dwIpAddr)
|
|
{
|
|
LPWSTR lpszBuf = szBuf.GetBuffer(IP_STRING_MAX_LEN);
|
|
wsprintf(lpszBuf, g_szIpStringFmt, IP_STRING_FMT_ARGS(dwIpAddr));
|
|
szBuf.ReleaseBuffer();
|
|
}
|
|
|
|
|
|
void ReverseString(LPWSTR p, LPWSTR q);
|
|
int ReverseIPString(LPWSTR lpsz);
|
|
|
|
BOOL RemoveInAddrArpaSuffix(LPWSTR lpsz);
|
|
|
|
BOOL IsValidDnsZoneName(CString& szName, BOOL bFwd);
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// definitions and helper functions for IPv6 format
|
|
|
|
void FormatIPv6Addr(CString& szAddr, IPV6_ADDRESS* ipv6Addr);
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
// flags for different states and options of DNS objects
|
|
// use LOWORD only because used in CTreeNode::m_dwNodeFlags
|
|
|
|
#define TN_FLAG_DNS_RECORD_FULL_NAME (0x01) // use full name to display resource records
|
|
#define TN_FLAG_DNS_RECORD_SHOW_TTL (0x02) // show TLL in record properties
|
|
|
|
|
|
typedef CArray<IP_ADDRESS,IP_ADDRESS> CIpAddressArray;
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// CBlob
|
|
template <class T> class CBlob
|
|
{
|
|
public:
|
|
CBlob()
|
|
{
|
|
m_pData = NULL;
|
|
m_nSize = 0;
|
|
}
|
|
~CBlob()
|
|
{
|
|
Empty();
|
|
}
|
|
UINT GetSize() { return m_nSize;}
|
|
T* GetData() { return m_pData;}
|
|
void Set(T* pData, UINT nSize)
|
|
{
|
|
ASSERT(pData != NULL);
|
|
Empty();
|
|
m_pData = (BYTE*)malloc(sizeof(T)*nSize);
|
|
ASSERT(m_pData != NULL);
|
|
if (m_pData != NULL)
|
|
{
|
|
m_nSize = nSize;
|
|
memcpy(m_pData, pData, sizeof(T)*nSize);
|
|
}
|
|
}
|
|
UINT Get(T* pData)
|
|
{
|
|
ASSERT(pData != NULL);
|
|
memcpy(pData, m_pData, sizeof(T)*m_nSize);
|
|
return m_nSize;
|
|
}
|
|
void Empty()
|
|
{
|
|
if (m_pData != NULL)
|
|
{
|
|
free(m_pData);
|
|
m_pData = NULL;
|
|
m_nSize = 0;
|
|
}
|
|
}
|
|
|
|
private:
|
|
T* m_pData;
|
|
UINT m_nSize;
|
|
};
|
|
|
|
typedef CBlob<BYTE> CByteBlob;
|
|
typedef CBlob<WORD> CWordBlob;
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// CDNSServerInfoEx
|
|
|
|
// definitions for the extended server flags (NT 5.0) only
|
|
#define SERVER_REGKEY_ARR_SIZE 6
|
|
|
|
#define SERVER_REGKEY_ARR_INDEX_NO_RECURSION 0
|
|
#define SERVER_REGKEY_ARR_INDEX_BIND_SECONDARIES 1
|
|
#define SERVER_REGKEY_ARR_INDEX_STRICT_FILE_PARSING 2
|
|
#define SERVER_REGKEY_ARR_INDEX_ROUND_ROBIN 3
|
|
#define SERVER_REGKEY_ARR_LOCAL_NET_PRIORITY 4
|
|
#define SERVER_REGKEY_ARR_CACHE_POLLUTION 5
|
|
|
|
|
|
extern LPCSTR _DnsServerRegkeyStringArr[];
|
|
|
|
class CDNSServerInfoEx : public CObjBase
|
|
{
|
|
public:
|
|
CDNSServerInfoEx();
|
|
~CDNSServerInfoEx();
|
|
DNS_STATUS Query(LPCTSTR lpszServerName);
|
|
|
|
BOOL HasData(){ return m_pServInfo != NULL;}
|
|
void FreeInfo();
|
|
|
|
// obtained from DnsGetServerInfo() RPC call (NT 4.0)
|
|
DNS_RPC_SERVER_INFO* m_pServInfo;
|
|
// error codes for query
|
|
DNS_STATUS m_errServInfo;
|
|
|
|
private:
|
|
void QueryRegKeyOptionsHelper(LPCSTR lpszAnsiServerName);
|
|
|
|
};
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// CDNSZoneInfoEx
|
|
|
|
class CDNSZoneInfoEx : public CObjBase
|
|
{
|
|
public:
|
|
CDNSZoneInfoEx();
|
|
~CDNSZoneInfoEx();
|
|
DNS_STATUS Query(LPCTSTR lpszServerName, LPCTSTR lpszZoneName, DWORD dwServerVersion);
|
|
|
|
BOOL HasData(){ return m_pZoneInfo != NULL;}
|
|
void FreeInfo();
|
|
|
|
// struct obtained from DnssrvGetZoneInfo() 5.0 RPC call (NT 4.0 format)
|
|
DNS_RPC_ZONE_INFO* m_pZoneInfo;
|
|
// obtained from DnssrvQueryZoneDwordProperty() (NT 5.0)
|
|
// UINT m_nAllowsDynamicUpdate;
|
|
|
|
// error codes for query
|
|
DNS_STATUS m_errZoneInfo;
|
|
// DNS_STATUS m_errAllowsDynamicUpdate;
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
//////////////////// ERROR MESSAGES HANDLING //////////////////////////////////
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
int DNSMessageBox(LPCTSTR lpszText, UINT nType = MB_OK);
|
|
int DNSMessageBox(UINT nIDPrompt, UINT nType = MB_OK);
|
|
|
|
int DNSErrorDialog(DNS_STATUS err, LPCTSTR lpszErrorMsg = NULL);
|
|
int DNSErrorDialog(DNS_STATUS err, UINT nErrorMsgID);
|
|
void DNSDisplaySystemError(DWORD dwErr);
|
|
void DNSCreateErrorMessage(DNS_STATUS err, UINT nErrorMsgID, CString& refszMessage);
|
|
|
|
int DNSConfirmOperation(UINT nMsgID, CTreeNode* p);
|
|
|
|
class CDNSErrorInfo
|
|
{
|
|
public:
|
|
static BOOL GetErrorString(DNS_STATUS err, CString& szError);
|
|
static BOOL GetErrorStringFromTable(DNS_STATUS err, CString& szError);
|
|
static BOOL GetErrorStringFromWin32(DNS_STATUS err, CString& szError);
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// Security KEY, SIG 6-bit values to base64 character mapping
|
|
//
|
|
#define SECURITY_PAD_CHAR (L'=')
|
|
WCHAR Dns_SecurityBase64CharToBits(IN WCHAR wch64);
|
|
|
|
DNS_STATUS Dns_SecurityBase64StringToKey(OUT PBYTE pKey,
|
|
OUT PDWORD pKeyLength,
|
|
IN PWSTR pchString,
|
|
IN DWORD cchLength);
|
|
|
|
PWSTR Dns_SecurityKeyToBase64String(IN PBYTE pKey,
|
|
IN DWORD KeyLength,
|
|
OUT PWSTR pchBuffer);
|
|
|
|
DNS_STATUS Dns_SecurityHexToKey(OUT PBYTE pKey,
|
|
OUT PDWORD pKeyLength,
|
|
IN PWSTR pchString,
|
|
IN DWORD cchLength);
|
|
|
|
void Dns_SecurityKeyToHexString(PBYTE pKey,
|
|
DWORD KeyLength,
|
|
CString& strref);
|
|
|
|
void TimetToFileTime( time_t t, LPFILETIME pft );
|
|
DWORD FileTimeToTimet(FILETIME* pft);
|
|
void ConvertTTLToSystemTime(TIME_ZONE_INFORMATION*,
|
|
DWORD dwTTL,
|
|
SYSTEMTIME* pSysTime);
|
|
DWORD ConvertSystemTimeToTTL(SYSTEMTIME* pSysTime);
|
|
BOOL ConvertTTLToLocalTimeString(const DWORD dwTTL,
|
|
CString& strref);
|
|
#endif // _DNSUTIL_H
|