dnsapi: Implement DnsRecord{CopyEx,ListFree,SetCopyEx}.
This commit is contained in:
parent
12ae5d4e4b
commit
686bcd29c1
|
@ -24,11 +24,46 @@ static inline void *dns_alloc( SIZE_T size )
|
|||
return HeapAlloc( GetProcessHeap(), 0, size );
|
||||
}
|
||||
|
||||
static inline void *dns_zero_alloc( SIZE_T size )
|
||||
{
|
||||
return HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
|
||||
}
|
||||
|
||||
static inline void dns_free( LPVOID mem )
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, mem );
|
||||
}
|
||||
|
||||
static inline LPSTR dns_strdup_a( LPCSTR src )
|
||||
{
|
||||
LPSTR dst;
|
||||
|
||||
if (!src) return NULL;
|
||||
dst = dns_alloc( (lstrlenA( src ) + 1) * sizeof(char) );
|
||||
if (dst) lstrcpyA( dst, src );
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline char *dns_strdup_u( const char *src )
|
||||
{
|
||||
char *dst;
|
||||
|
||||
if (!src) return NULL;
|
||||
dst = dns_alloc( (strlen( src ) + 1) * sizeof(char) );
|
||||
if (dst) strcpy( dst, src );
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline LPWSTR dns_strdup_w( LPCWSTR src )
|
||||
{
|
||||
LPWSTR dst;
|
||||
|
||||
if (!src) return NULL;
|
||||
dst = dns_alloc( (lstrlenW( src ) + 1) * sizeof(WCHAR) );
|
||||
if (dst) lstrcpyW( dst, src );
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline LPWSTR dns_strdup_aw( LPCSTR str )
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
|
@ -40,3 +75,65 @@ static inline LPWSTR dns_strdup_aw( LPCSTR str )
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline LPWSTR dns_strdup_uw( const char *str )
|
||||
{
|
||||
LPWSTR ret = NULL;
|
||||
if (str)
|
||||
{
|
||||
DWORD len = MultiByteToWideChar( CP_UTF8, 0, str, -1, NULL, 0 );
|
||||
if ((ret = dns_alloc( len * sizeof(WCHAR) )))
|
||||
MultiByteToWideChar( CP_UTF8, 0, str, -1, ret, len );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline LPSTR dns_strdup_wa( LPCWSTR str )
|
||||
{
|
||||
LPSTR ret = NULL;
|
||||
if (str)
|
||||
{
|
||||
DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
|
||||
if ((ret = dns_alloc( len )))
|
||||
WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *dns_strdup_wu( LPCWSTR str )
|
||||
{
|
||||
LPSTR ret = NULL;
|
||||
if (str)
|
||||
{
|
||||
DWORD len = WideCharToMultiByte( CP_UTF8, 0, str, -1, NULL, 0, NULL, NULL );
|
||||
if ((ret = dns_alloc( len )))
|
||||
WideCharToMultiByte( CP_UTF8, 0, str, -1, ret, len, NULL, NULL );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char *dns_strdup_au( LPCSTR src )
|
||||
{
|
||||
char *dst = NULL;
|
||||
LPWSTR ret = dns_strdup_aw( src );
|
||||
|
||||
if (ret)
|
||||
{
|
||||
dst = dns_strdup_wu( ret );
|
||||
dns_free( ret );
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
static inline LPSTR dns_strdup_ua( const char *src )
|
||||
{
|
||||
LPSTR dst = NULL;
|
||||
LPWSTR ret = dns_strdup_uw( src );
|
||||
|
||||
if (ret)
|
||||
{
|
||||
dst = dns_strdup_wa( ret );
|
||||
dns_free( ret );
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
|
|
@ -84,10 +84,10 @@
|
|||
@ stub DnsRecordBuild_UTF8
|
||||
@ stub DnsRecordBuild_W
|
||||
@ stdcall DnsRecordCompare(ptr ptr)
|
||||
@ stub DnsRecordCopyEx
|
||||
@ stub DnsRecordListFree
|
||||
@ stdcall DnsRecordCopyEx(ptr long long)
|
||||
@ stdcall DnsRecordListFree(ptr long)
|
||||
@ stub DnsRecordSetCompare
|
||||
@ stub DnsRecordSetCopyEx
|
||||
@ stdcall DnsRecordSetCopyEx(ptr long long)
|
||||
@ stub DnsRecordSetDetach
|
||||
@ stub DnsRecordStringForType
|
||||
@ stub DnsRecordStringForWritableType
|
||||
|
|
|
@ -362,3 +362,308 @@ BOOL WINAPI DnsRecordCompare( PDNS_RECORD r1, PDNS_RECORD r2 )
|
|||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LPVOID dns_strcpyX( LPCVOID src, DNS_CHARSET in, DNS_CHARSET out )
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
case DnsCharSetUnicode:
|
||||
{
|
||||
switch (out)
|
||||
{
|
||||
case DnsCharSetUnicode: return dns_strdup_w( src );
|
||||
case DnsCharSetUtf8: return dns_strdup_wu( src );
|
||||
case DnsCharSetAnsi: return dns_strdup_wa( src );
|
||||
default:
|
||||
WARN( "unhandled target charset: %d\n", out );
|
||||
break;
|
||||
}
|
||||
}
|
||||
case DnsCharSetUtf8:
|
||||
switch (out)
|
||||
{
|
||||
case DnsCharSetUnicode: return dns_strdup_uw( src );
|
||||
case DnsCharSetUtf8: return dns_strdup_u( src );
|
||||
case DnsCharSetAnsi: return dns_strdup_ua( src );
|
||||
default:
|
||||
WARN( "unhandled target charset: %d\n", out );
|
||||
break;
|
||||
}
|
||||
case DnsCharSetAnsi:
|
||||
switch (out)
|
||||
{
|
||||
case DnsCharSetUnicode: return dns_strdup_aw( src );
|
||||
case DnsCharSetUtf8: return dns_strdup_au( src );
|
||||
case DnsCharSetAnsi: return dns_strdup_a( src );
|
||||
default:
|
||||
WARN( "unhandled target charset: %d\n", out );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN( "unhandled source charset: %d\n", in );
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DnsRecordCopyEx [DNSAPI.@]
|
||||
*
|
||||
*/
|
||||
PDNS_RECORD WINAPI DnsRecordCopyEx( PDNS_RECORD src, DNS_CHARSET in, DNS_CHARSET out )
|
||||
{
|
||||
DNS_RECORD *dst;
|
||||
unsigned int i, size;
|
||||
|
||||
TRACE( "(%p,%d,%d)\n", src, in, out );
|
||||
|
||||
size = FIELD_OFFSET(DNS_RECORD, Data) + src->wDataLength;
|
||||
dst = dns_zero_alloc( size );
|
||||
if (!dst) return NULL;
|
||||
|
||||
memcpy( dst, src, size );
|
||||
|
||||
if (src->Flags.S.CharSet == DnsCharSetUtf8 ||
|
||||
src->Flags.S.CharSet == DnsCharSetAnsi ||
|
||||
src->Flags.S.CharSet == DnsCharSetUnicode) in = src->Flags.S.CharSet;
|
||||
|
||||
dst->Flags.S.CharSet = out;
|
||||
dst->pName = dns_strcpyX( src->pName, in, out );
|
||||
if (!dst->pName) goto error;
|
||||
|
||||
switch (src->wType)
|
||||
{
|
||||
case DNS_TYPE_HINFO:
|
||||
case DNS_TYPE_ISDN:
|
||||
case DNS_TYPE_TEXT:
|
||||
case DNS_TYPE_X25:
|
||||
{
|
||||
for (i = 0; i < src->Data.TXT.dwStringCount; i++)
|
||||
{
|
||||
dst->Data.TXT.pStringArray[i] =
|
||||
dns_strcpyX( src->Data.TXT.pStringArray[i], in, out );
|
||||
|
||||
if (!dst->Data.TXT.pStringArray[i])
|
||||
{
|
||||
for (--i; i >= 0; i--)
|
||||
dns_free( dst->Data.TXT.pStringArray[i] );
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_MINFO:
|
||||
case DNS_TYPE_RP:
|
||||
{
|
||||
dst->Data.MINFO.pNameMailbox =
|
||||
dns_strcpyX( src->Data.MINFO.pNameMailbox, in, out );
|
||||
if (!dst->Data.MINFO.pNameMailbox) goto error;
|
||||
|
||||
dst->Data.MINFO.pNameErrorsMailbox =
|
||||
dns_strcpyX( src->Data.MINFO.pNameErrorsMailbox, in, out );
|
||||
if (!dst->Data.MINFO.pNameErrorsMailbox)
|
||||
{
|
||||
dns_free( dst->Data.MINFO.pNameMailbox );
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_AFSDB:
|
||||
case DNS_TYPE_RT:
|
||||
case DNS_TYPE_MX:
|
||||
{
|
||||
dst->Data.MX.pNameExchange =
|
||||
dns_strcpyX( src->Data.MX.pNameExchange, in, out );
|
||||
if (!dst->Data.MX.pNameExchange) goto error;
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_NXT:
|
||||
{
|
||||
dst->Data.NXT.pNameNext =
|
||||
dns_strcpyX( src->Data.NXT.pNameNext, in, out );
|
||||
if (!dst->Data.NXT.pNameNext) goto error;
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_CNAME:
|
||||
case DNS_TYPE_MB:
|
||||
case DNS_TYPE_MD:
|
||||
case DNS_TYPE_MF:
|
||||
case DNS_TYPE_MG:
|
||||
case DNS_TYPE_MR:
|
||||
case DNS_TYPE_NS:
|
||||
case DNS_TYPE_PTR:
|
||||
{
|
||||
dst->Data.PTR.pNameHost =
|
||||
dns_strcpyX( src->Data.PTR.pNameHost, in, out );
|
||||
if (!dst->Data.PTR.pNameHost) goto error;
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_SIG:
|
||||
{
|
||||
dst->Data.SIG.pNameSigner =
|
||||
dns_strcpyX( src->Data.SIG.pNameSigner, in, out );
|
||||
if (!dst->Data.SIG.pNameSigner) goto error;
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_SOA:
|
||||
{
|
||||
dst->Data.SOA.pNamePrimaryServer =
|
||||
dns_strcpyX( src->Data.SOA.pNamePrimaryServer, in, out );
|
||||
if (!dst->Data.SOA.pNamePrimaryServer) goto error;
|
||||
|
||||
dst->Data.SOA.pNameAdministrator =
|
||||
dns_strcpyX( src->Data.SOA.pNameAdministrator, in, out );
|
||||
if (!dst->Data.SOA.pNameAdministrator)
|
||||
{
|
||||
dns_free( dst->Data.SOA.pNamePrimaryServer );
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_SRV:
|
||||
{
|
||||
dst->Data.SRV.pNameTarget =
|
||||
dns_strcpyX( src->Data.SRV.pNameTarget, in, out );
|
||||
if (!dst->Data.SRV.pNameTarget) goto error;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return dst;
|
||||
|
||||
error:
|
||||
dns_free( dst->pName );
|
||||
dns_free( dst );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DnsRecordListFree [DNSAPI.@]
|
||||
*
|
||||
*/
|
||||
void WINAPI DnsRecordListFree( PDNS_RECORD list, DNS_FREE_TYPE type )
|
||||
{
|
||||
DNS_RECORD *r, *next;
|
||||
unsigned int i;
|
||||
|
||||
TRACE( "(%p,%d)\n", list, type );
|
||||
|
||||
if (!list) return;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DnsFreeRecordList:
|
||||
{
|
||||
for (r = list; (list = r); r = next)
|
||||
{
|
||||
dns_free( r->pName );
|
||||
|
||||
switch (r->wType)
|
||||
{
|
||||
case DNS_TYPE_HINFO:
|
||||
case DNS_TYPE_ISDN:
|
||||
case DNS_TYPE_TEXT:
|
||||
case DNS_TYPE_X25:
|
||||
{
|
||||
for (i = 0; i < r->Data.TXT.dwStringCount; i++)
|
||||
dns_free( r->Data.TXT.pStringArray[i] );
|
||||
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_MINFO:
|
||||
case DNS_TYPE_RP:
|
||||
{
|
||||
dns_free( r->Data.MINFO.pNameMailbox );
|
||||
dns_free( r->Data.MINFO.pNameErrorsMailbox );
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_AFSDB:
|
||||
case DNS_TYPE_RT:
|
||||
case DNS_TYPE_MX:
|
||||
{
|
||||
dns_free( r->Data.MX.pNameExchange );
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_NXT:
|
||||
{
|
||||
dns_free( r->Data.NXT.pNameNext );
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_CNAME:
|
||||
case DNS_TYPE_MB:
|
||||
case DNS_TYPE_MD:
|
||||
case DNS_TYPE_MF:
|
||||
case DNS_TYPE_MG:
|
||||
case DNS_TYPE_MR:
|
||||
case DNS_TYPE_NS:
|
||||
case DNS_TYPE_PTR:
|
||||
{
|
||||
dns_free( r->Data.PTR.pNameHost );
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_SIG:
|
||||
{
|
||||
dns_free( r->Data.SIG.pNameSigner );
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_SOA:
|
||||
{
|
||||
dns_free( r->Data.SOA.pNamePrimaryServer );
|
||||
dns_free( r->Data.SOA.pNameAdministrator );
|
||||
break;
|
||||
}
|
||||
case DNS_TYPE_SRV:
|
||||
{
|
||||
dns_free( r->Data.SRV.pNameTarget );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
next = r->pNext;
|
||||
dns_free( r );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DnsFreeFlat:
|
||||
case DnsFreeParsedMessageFields:
|
||||
{
|
||||
FIXME( "unhandled free type: %d\n", type );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
WARN( "unknown free type: %d\n", type );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DnsRecordSetCopyEx [DNSAPI.@]
|
||||
*
|
||||
*/
|
||||
PDNS_RECORD WINAPI DnsRecordSetCopyEx( PDNS_RECORD src_set, DNS_CHARSET in, DNS_CHARSET out )
|
||||
{
|
||||
DNS_RRSET dst_set;
|
||||
DNS_RECORD *src, *dst;
|
||||
|
||||
TRACE( "(%p,%d,%d)\n", src_set, in, out );
|
||||
|
||||
DNS_RRSET_INIT( dst_set );
|
||||
|
||||
for (src = src_set; (src_set = src); src = src_set->pNext)
|
||||
{
|
||||
dst = DnsRecordCopyEx( src, in, out );
|
||||
if (!dst)
|
||||
{
|
||||
DNS_RRSET_TERMINATE( dst_set );
|
||||
DnsRecordListFree( dst_set.pFirstRR, DnsFreeRecordList );
|
||||
return NULL;
|
||||
}
|
||||
DNS_RRSET_ADD( dst_set, dst );
|
||||
}
|
||||
|
||||
DNS_RRSET_TERMINATE( dst_set );
|
||||
return dst_set.pFirstRR;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue