You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
887 lines
19 KiB
887 lines
19 KiB
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
dconvert.c
|
|
|
|
Abstract:
|
|
|
|
Domain Name System (DNS) Server -- Admin Client Library
|
|
|
|
RPC record conversion routines.
|
|
Convert DNS_RECORD records into RPC buffer.
|
|
|
|
Author:
|
|
|
|
Jing Chen (t-jingc) June, 1998
|
|
reverse functions of rconvert.c
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include "dnsclip.h"
|
|
|
|
|
|
//
|
|
// size of string in RPC format
|
|
//
|
|
|
|
#define STRING_UTF8_BUF_SIZE( string, fUnicode ) \
|
|
Dns_GetBufferLengthForStringCopy( \
|
|
(string), \
|
|
0, \
|
|
((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|
DnsCharSetUtf8 )
|
|
|
|
//
|
|
// Writing strings to RPC buffer format
|
|
//
|
|
|
|
#define WRITE_STRING_TO_RPC_BUF(buf, psz, len, funicode) \
|
|
Dns_StringCopy( \
|
|
(buf), \
|
|
NULL, \
|
|
(psz), \
|
|
(len), \
|
|
((funicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|
DnsCharSetUtf8 )
|
|
|
|
|
|
//
|
|
// size of name in RPC format
|
|
//
|
|
|
|
#define NAME_UTF8_BUF_SIZE( string, fUnicode ) \
|
|
Dns_GetBufferLengthForStringCopy( \
|
|
(string), \
|
|
0, \
|
|
((fUnicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|
DnsCharSetUtf8 )
|
|
|
|
|
|
//
|
|
// Writing names to RPC buffer format
|
|
//
|
|
|
|
#define WRITE_NAME_TO_RPC_BUF(buf, psz, len, funicode) \
|
|
Dns_StringCopy( \
|
|
(buf), \
|
|
NULL, \
|
|
(psz), \
|
|
(len), \
|
|
((funicode) ? DnsCharSetUnicode : DnsCharSetUtf8), \
|
|
DnsCharSetUtf8 )
|
|
|
|
|
|
//
|
|
// Private protos
|
|
//
|
|
|
|
PDNS_RPC_RECORD
|
|
Rpc_AllocateRecord(
|
|
IN DWORD BufferLength
|
|
);
|
|
|
|
|
|
|
|
//
|
|
// RPC buffer conversion functions
|
|
//
|
|
|
|
PDNS_RPC_RECORD
|
|
ADnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert A record from DNS Record to RPC buffer.
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
|
|
DNS_ASSERT( pRR->wDataLength == sizeof(IP_ADDRESS) );
|
|
|
|
prpcRR = Rpc_AllocateRecord( sizeof(IP_ADDRESS) );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
prpcRR->Data.A.ipAddress = pRR->Data.A.IpAddress;
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
PtrDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Process PTR compatible record from wire.
|
|
Includes: NS, PTR, CNAME, MB, MR, MG, MD, MF
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
DWORD length;
|
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|
|
|
//
|
|
// PTR data is another domain name
|
|
//
|
|
// determine required buffer length and allocate
|
|
//
|
|
|
|
length = NAME_UTF8_BUF_SIZE(pRR->Data.PTR.pNameHost, funicode);
|
|
|
|
prpcRR = Rpc_AllocateRecord( sizeof(DNS_RPC_NAME) + length );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// write hostname into buffer, immediately following PTR data struct
|
|
//
|
|
|
|
prpcRR->Data.PTR.nameNode.cchNameLength = (UCHAR)length;
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
prpcRR->Data.PTR.nameNode.achName, // buffer
|
|
pRR->Data.PTR.pNameHost,
|
|
0,
|
|
funicode );
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
SoaDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert SOA record from DNS Record to RPC buffer.
|
|
|
|
Arguments:
|
|
|
|
pRR - ptr to record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
DWORD length1;
|
|
DWORD length2;
|
|
PDNS_RPC_NAME pnamePrimary;
|
|
PDNS_RPC_NAME pnameAdmin;
|
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|
|
|
|
|
//
|
|
// determine required buffer length and allocate
|
|
//
|
|
|
|
length1 = NAME_UTF8_BUF_SIZE( pRR->Data.SOA.pNamePrimaryServer, funicode );
|
|
|
|
length2 = NAME_UTF8_BUF_SIZE( pRR->Data.SOA.pNameAdministrator, funicode );
|
|
|
|
prpcRR = Rpc_AllocateRecord(
|
|
SIZEOF_SOA_FIXED_DATA + sizeof(DNS_RPC_NAME) * 2 +
|
|
length1 + length2 );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// copy fixed fields
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
(PCHAR) & prpcRR->Data.SOA.dwSerialNo,
|
|
(PCHAR) & pRR->Data.SOA.dwSerialNo,
|
|
SIZEOF_SOA_FIXED_DATA );
|
|
|
|
//
|
|
// copy names into RR buffer
|
|
// - primary server immediately follows SOA data struct
|
|
// - responsible party follows primary server
|
|
//
|
|
|
|
pnamePrimary = &prpcRR->Data.SOA.namePrimaryServer;
|
|
pnamePrimary->cchNameLength = (UCHAR) length1;
|
|
|
|
pnameAdmin = DNS_GET_NEXT_NAME( pnamePrimary );
|
|
pnameAdmin->cchNameLength = (UCHAR) length2;
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
pnamePrimary->achName,
|
|
pRR->Data.Soa.pNamePrimaryServer,
|
|
0,
|
|
funicode );
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
pnameAdmin->achName,
|
|
pRR->Data.Soa.pNameAdministrator,
|
|
0,
|
|
funicode );
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
TxtDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Read TXT compatible record from wire.
|
|
Includes: TXT, X25, HINFO, ISDN
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
DWORD bufLength;
|
|
DWORD length;
|
|
INT count;
|
|
PCHAR pch;
|
|
PCHAR * ppstring;
|
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|
|
|
//
|
|
// determine required buffer length and allocate
|
|
// - allocate space for each string
|
|
// - and ptr for each string
|
|
//
|
|
|
|
bufLength = 0;
|
|
count = pRR->Data.TXT.dwStringCount;
|
|
ppstring = pRR->Data.TXT.pStringArray;
|
|
|
|
while ( count-- )
|
|
{
|
|
length = STRING_UTF8_BUF_SIZE( *ppstring++, funicode );
|
|
bufLength += sizeof(DNS_RPC_NAME) + length;
|
|
}
|
|
|
|
// allocate
|
|
|
|
prpcRR = Rpc_AllocateRecord( bufLength );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// go back through list copying strings to buffer
|
|
// - ptrs to strings are saved to argv like data section
|
|
// ppstring walks through this section
|
|
// - first string written immediately following data section
|
|
// - each subsequent string immediately follows predecessor
|
|
// pchbuffer keeps ptr to position to write strings
|
|
//
|
|
// JBUGBUG: a mess
|
|
//
|
|
|
|
pch = (PCHAR) &prpcRR->Data.TXT;
|
|
ppstring = pRR->Data.TXT.pStringArray;
|
|
count = pRR->Data.TXT.dwStringCount;
|
|
|
|
while ( count-- )
|
|
{
|
|
length = STRING_UTF8_BUF_SIZE( *ppstring, funicode );
|
|
(UCHAR) *pch++ += (UCHAR) length; //+1 for TXT type only
|
|
|
|
length = WRITE_STRING_TO_RPC_BUF(
|
|
pch,
|
|
*ppstring++,
|
|
0,
|
|
funicode );
|
|
pch += length;
|
|
#if DBG
|
|
DNS_PRINT((
|
|
"Read text string %s\n",
|
|
* (ppstring - 1) ));
|
|
#endif
|
|
}
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
MinfoDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Read MINFO record from wire.
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
DWORD length1;
|
|
DWORD length2;
|
|
PDNS_RPC_NAME prpcName1;
|
|
PDNS_RPC_NAME prpcName2;
|
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|
|
|
//
|
|
// determine required buffer length and allocate
|
|
//
|
|
|
|
length1 = NAME_UTF8_BUF_SIZE( pRR->Data.MINFO.pNameMailbox, funicode );
|
|
length2 = NAME_UTF8_BUF_SIZE( pRR->Data.MINFO.pNameErrorsMailbox, funicode );
|
|
|
|
prpcRR = Rpc_AllocateRecord( sizeof(DNS_RPC_NAME) * 2 + length1 + length2 );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// copy names into RR buffer
|
|
// - mailbox immediately follows MINFO data struct
|
|
// - errors mailbox immediately follows primary server
|
|
//
|
|
|
|
prpcName1 = &prpcRR->Data.MINFO.nameMailBox;
|
|
prpcName1->cchNameLength = (UCHAR) length1;
|
|
|
|
prpcName2 = DNS_GET_NEXT_NAME( prpcName1);
|
|
prpcName2->cchNameLength = (UCHAR) length2;
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
prpcName1->achName,
|
|
pRR->Data.MINFO.pNameMailbox,
|
|
0,
|
|
funicode );
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
prpcName2->achName,
|
|
pRR->Data.MINFO.pNameErrorsMailbox,
|
|
0,
|
|
funicode );
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
MxDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
convert MX compatible record.
|
|
Includes: MX, RT, AFSDB
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
PDNS_RPC_NAME prpcName;
|
|
DWORD length;
|
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|
|
|
//
|
|
// determine required buffer length and allocate
|
|
//
|
|
|
|
length = NAME_UTF8_BUF_SIZE( pRR->Data.MX.pNameExchange, funicode );
|
|
|
|
prpcRR = Rpc_AllocateRecord(
|
|
SIZEOF_MX_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// copy preference
|
|
//
|
|
|
|
prpcRR->Data.MX.wPreference = pRR->Data.MX.wPreference;
|
|
|
|
//
|
|
// write hostname into buffer, immediately following MX struct
|
|
//
|
|
|
|
prpcName = &prpcRR->Data.MX.nameExchange;
|
|
prpcName->cchNameLength = (UCHAR) length;
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
prpcName->achName,
|
|
pRR->Data.MX.pNameExchange,
|
|
0,
|
|
funicode );
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
FlatDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert memory copy compatible record.
|
|
Includes AAAA and WINS types.
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
DWORD bufLength;
|
|
|
|
//
|
|
// determine required buffer length and allocate
|
|
//
|
|
|
|
bufLength = pRR->wDataLength;
|
|
|
|
prpcRR = Rpc_AllocateRecord( bufLength );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// copy packet data to record
|
|
//
|
|
|
|
RtlCopyMemory(
|
|
& prpcRR->Data,
|
|
& pRR->Data,
|
|
bufLength );
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
SrvDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
convert SRV record.
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
PDNS_RPC_NAME prpcName;
|
|
DWORD length;
|
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|
|
|
//
|
|
// determine required buffer length and allocate
|
|
//
|
|
|
|
length = NAME_UTF8_BUF_SIZE( pRR->Data.SRV.pNameTarget, funicode );
|
|
|
|
prpcRR = Rpc_AllocateRecord(
|
|
SIZEOF_SRV_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// copy SRV fixed fields
|
|
//
|
|
|
|
prpcRR->Data.SRV.wPriority = pRR->Data.SRV.wPriority;
|
|
prpcRR->Data.SRV.wWeight = pRR->Data.SRV.wWeight;
|
|
prpcRR->Data.SRV.wPort = pRR->Data.SRV.wPort;
|
|
|
|
//
|
|
// write hostname into buffer, immediately following SRV struct
|
|
//
|
|
|
|
prpcName = &prpcRR->Data.SRV.nameTarget;
|
|
prpcName->cchNameLength = (UCHAR) length;
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
prpcName->achName,
|
|
pRR->Data.SRV.pNameTarget,
|
|
0,
|
|
funicode );
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
NbstatDnsRecordConvert(
|
|
IN PDNS_RECORD pRR
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Read WINSR record from wire.
|
|
|
|
Arguments:
|
|
|
|
pRR - record being read
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRR;
|
|
PDNS_RPC_NAME prpcName;
|
|
DWORD length;
|
|
BOOL funicode = IS_UNICODE_RECORD( pRR );
|
|
|
|
|
|
//
|
|
// determine required buffer length and allocate
|
|
//
|
|
|
|
length = NAME_UTF8_BUF_SIZE( pRR->Data.WINSR.pNameResultDomain, funicode );
|
|
|
|
prpcRR = Rpc_AllocateRecord(
|
|
SIZEOF_NBSTAT_FIXED_DATA + sizeof(DNS_RPC_NAME) + length );
|
|
if ( !prpcRR )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// copy WINSR fixed fields
|
|
//
|
|
|
|
prpcRR->Data.WINSR.dwMappingFlag = pRR->Data.WINSR.dwMappingFlag;
|
|
prpcRR->Data.WINSR.dwLookupTimeout = pRR->Data.WINSR.dwLookupTimeout;
|
|
prpcRR->Data.WINSR.dwCacheTimeout = pRR->Data.WINSR.dwCacheTimeout;
|
|
|
|
//
|
|
// write hostname into buffer, immediately following WINSR struct
|
|
//
|
|
|
|
prpcName = &prpcRR->Data.WINSR.nameResultDomain;
|
|
prpcName->cchNameLength = (UCHAR) length;
|
|
|
|
WRITE_NAME_TO_RPC_BUF(
|
|
prpcName->achName,
|
|
pRR->Data.WINSR.pNameResultDomain,
|
|
0,
|
|
funicode );
|
|
|
|
return prpcRR;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Jump table for DNS_RECORD => RPC buffer conversion.
|
|
//
|
|
|
|
typedef PDNS_RPC_RECORD (* RECORD_TO_RPC_CONVERT_FUNCTION)( PDNS_RECORD );
|
|
|
|
RECORD_TO_RPC_CONVERT_FUNCTION RecordToRpcConvertTable[] =
|
|
{
|
|
NULL, // ZERO
|
|
ADnsRecordConvert, // A
|
|
PtrDnsRecordConvert, // NS
|
|
PtrDnsRecordConvert, // MD
|
|
PtrDnsRecordConvert, // MF
|
|
PtrDnsRecordConvert, // CNAME
|
|
SoaDnsRecordConvert, // SOA
|
|
PtrDnsRecordConvert, // MB
|
|
PtrDnsRecordConvert, // MG
|
|
PtrDnsRecordConvert, // MR
|
|
NULL, // NULL
|
|
FlatDnsRecordConvert, // WKS
|
|
PtrDnsRecordConvert, // PTR
|
|
TxtDnsRecordConvert, // HINFO
|
|
MinfoDnsRecordConvert, // MINFO
|
|
MxDnsRecordConvert, // MX
|
|
TxtDnsRecordConvert, // TXT
|
|
MinfoDnsRecordConvert, // RP
|
|
MxDnsRecordConvert, // AFSDB
|
|
TxtDnsRecordConvert, // X25
|
|
TxtDnsRecordConvert, // ISDN
|
|
MxDnsRecordConvert, // RT
|
|
NULL, // NSAP
|
|
NULL, // NSAPPTR
|
|
NULL, // SIG
|
|
NULL, // KEY
|
|
NULL, // PX
|
|
NULL, // GPOS
|
|
FlatDnsRecordConvert, // AAAA
|
|
NULL, // 29
|
|
NULL, // 30
|
|
NULL, // 31
|
|
NULL, // 32
|
|
SrvDnsRecordConvert, // SRV
|
|
|
|
//
|
|
// NOTE: last type indexed by type ID MUST be set
|
|
// as MAX_SELF_INDEXED_TYPE #define in record.h
|
|
// (see note above in record info table)
|
|
|
|
// note these follow, but require OFFSET_TO_WINS_RR subtraction
|
|
// from actual type value
|
|
|
|
NULL, // DNS_TYPE_ATMA
|
|
NULL, // 0x0023
|
|
NULL, // 0x0024
|
|
NULL, // 0x0025
|
|
NULL, // 0x0026
|
|
NULL, // 0x0027
|
|
NULL, // 0x0028
|
|
|
|
NULL, // DNS_TYPE_TKEY
|
|
NULL, // DNS_TYPE_TSIG
|
|
|
|
FlatDnsRecordConvert, // WINS
|
|
NbstatDnsRecordConvert // WINS-R
|
|
};
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
Rpc_AllocateRecord(
|
|
IN DWORD BufferLength
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allocate RPC record structure.
|
|
|
|
Arguments:
|
|
|
|
wBufferLength - desired buffer length (beyond structure header)
|
|
|
|
Return Value:
|
|
|
|
Ptr to buffer.
|
|
NULL on error.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prr;
|
|
|
|
if ( BufferLength > MAXWORD )
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
prr = ALLOCATE_HEAP( SIZEOF_DNS_RPC_RECORD_HEADER + BufferLength );
|
|
if ( !prr )
|
|
{
|
|
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
|
return NULL;
|
|
}
|
|
|
|
// set datalength to buffer length
|
|
|
|
prr->wDataLength = (WORD) BufferLength;
|
|
|
|
return( prr );
|
|
}
|
|
|
|
|
|
|
|
|
|
PDNS_RPC_RECORD
|
|
DnsConvertRecordToRpcBuffer(
|
|
IN PDNS_RECORD pRecord
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Convert standard DNS record to RPC buffer.
|
|
|
|
Arguments:
|
|
|
|
pRecord -- DNS Record to be converted.
|
|
|
|
//fUnicode -- flag, write records into unicode
|
|
|
|
Return Value:
|
|
|
|
Ptr to new RPC buffer if successful.
|
|
NULL on failure.
|
|
|
|
--*/
|
|
{
|
|
PDNS_RPC_RECORD prpcRecord;
|
|
WORD index;
|
|
WORD type;
|
|
RECORD_TO_RPC_CONVERT_FUNCTION pFunc;
|
|
|
|
|
|
DNS_ASSERT( DNS_IS_DWORD_ALIGNED(pRecord) );
|
|
IF_DNSDBG( RPC2 )
|
|
{
|
|
DNS_PRINT((
|
|
"Enter DnsConvertRecordToRpcBuffer()\n"
|
|
" pRecord = %p\n",
|
|
pRecord ));
|
|
}
|
|
|
|
//
|
|
// convert record
|
|
// set unicode flag if converting
|
|
//
|
|
|
|
type = pRecord->wType;
|
|
index = INDEX_FOR_TYPE( type );
|
|
DNS_ASSERT( index <= MAX_RECORD_TYPE_INDEX );
|
|
|
|
if ( !index || !(pFunc = RecordToRpcConvertTable[ index ]) )
|
|
{
|
|
// if unknown type try flat record copy -- best we can
|
|
// do to protect if server added new types since admin built
|
|
|
|
DNS_PRINT((
|
|
"ERROR: no DNS_RECORD to RPC conversion routine for type %d.\n"
|
|
" using flat conversion routine.\n",
|
|
type ));
|
|
pFunc = FlatDnsRecordConvert;
|
|
}
|
|
|
|
prpcRecord = (*pFunc)( pRecord );
|
|
if ( ! prpcRecord )
|
|
{
|
|
DNS_PRINT((
|
|
"ERROR: Record build routine failure for record type %d.\n"
|
|
" status = %p\n\n",
|
|
type,
|
|
GetLastError() ));
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// fill out record structure
|
|
//
|
|
|
|
prpcRecord->wType = type;
|
|
prpcRecord->dwTtlSeconds = pRecord->dwTtl;
|
|
|
|
IF_DNSDBG( INIT )
|
|
{
|
|
DNS_PRINT(( "New RPC buffer built\n" ));
|
|
}
|
|
|
|
|
|
IF_DNSDBG( RPC2 )
|
|
{
|
|
DNS_PRINT((
|
|
"Finished DnsConvertRpcBufferToRecords()" ));
|
|
}
|
|
|
|
return prpcRecord;
|
|
}
|
|
|
|
//
|
|
// End dconvert.c
|
|
//
|