DWORD VmDnsDuplicateNSRecord( PVMDNS_RECORD pSrc, PVMDNS_RECORD *ppDest ) { DWORD dwError = 0; PVMDNS_RECORD pRecord = NULL; BAIL_ON_VMDNS_INVALID_POINTER(pSrc, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppDest, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_RECORD), (void**)&pRecord); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCopyNSRecord(pSrc, pRecord); BAIL_ON_VMDNS_ERROR(dwError); *ppDest = pRecord; pRecord = NULL; cleanup: return dwError; error: VMDNS_FREE_RECORD(pRecord); if (ppDest) { *ppDest = NULL; } goto cleanup; }
DWORD VmDnsRpcDuplicatePtrRecord( PVMDNS_RECORD pSrc, PVMDNS_RECORD *ppDest ) { DWORD dwError = 0; PVMDNS_RECORD pRecord = NULL; BAIL_ON_VMDNS_INVALID_POINTER(pSrc, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppDest, dwError); dwError = VmDnsRpcAllocateMemory(sizeof(VMDNS_RECORD), (PVOID*)&pRecord); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsRpcCopyPtrRecord(pSrc, pRecord); BAIL_ON_VMDNS_ERROR(dwError); *ppDest = pRecord; pRecord = NULL; cleanup: return dwError; error: VmDnsRpcClearPtrRecord(pRecord); VmDnsRpcFreeMemory(pRecord); if (ppDest) { *ppDest = NULL; } goto cleanup; }
DWORD VmDnsPropertyListAddList( PVMDNS_PROPERTY_LIST pDestList, PVMDNS_PROPERTY_LIST pSrcList ) { DWORD dwError = 0; DWORD i = 0; DWORD dwPropertyListSize = 0; BAIL_ON_VMDNS_INVALID_POINTER(pDestList, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pSrcList, dwError); if (pSrcList->dwCurrentSize == 0) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } dwPropertyListSize = VmDnsPropertyListGetSize(pSrcList); for (i = 0; i < dwPropertyListSize; i++) { dwError = VmDnsPropertyListAdd(pDestList, pSrcList->ppProperties[i]); BAIL_ON_VMDNS_ERROR(dwError); } cleanup: return dwError; error: goto cleanup; }
DWORD VmDnsParseRecordType( PSTR pszRecordType, VMDNS_RR_TYPE* pType ) { DWORD idx = 0; DWORD dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_INVALID_POINTER(pszRecordType, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pType, dwError); for (; idx < gRecordTypeMapSize; ++idx) { if (!VmDnsStringCompareA(pszRecordType, gRecordTypeMap[idx].pszName, FALSE)) { *pType = gRecordTypeMap[idx].type; dwError = ERROR_SUCCESS; break; } } cleanup: return dwError; error: goto cleanup; }
DWORD VmDnsCreateSoaRecord( PVMDNS_ZONE_INFO pZoneInfo, PVMDNS_RECORD* ppRecord ) { DWORD dwError = 0; PVMDNS_RECORD pRecord = NULL; PSTR pszName = NULL; PSTR pszPrimaryDnsName = NULL; PSTR pszRName = NULL; BAIL_ON_VMDNS_INVALID_POINTER(pZoneInfo, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppRecord, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_RECORD), (void**)&pRecord); BAIL_ON_VMDNS_ERROR(dwError); pRecord->dwType = VMDNS_RR_TYPE_SOA; dwError = VmDnsAllocateStringA(VMDNS_SOA_RECORD_NAME, &pszName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateStringA(pZoneInfo->pszPrimaryDnsSrvName, &pszPrimaryDnsName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateStringA(pZoneInfo->pszRName, &pszRName); BAIL_ON_VMDNS_ERROR(dwError); pRecord->pszName = pszName; pRecord->iClass = VMDNS_CLASS_IN; pRecord->Data.SOA.pNameAdministrator = pszRName; pRecord->Data.SOA.pNamePrimaryServer = pszPrimaryDnsName; pRecord->Data.SOA.dwDefaultTtl = pZoneInfo->minimum; pRecord->Data.SOA.dwExpire = pZoneInfo->expire; pRecord->Data.SOA.dwRefresh = pZoneInfo->refreshInterval; pRecord->Data.SOA.dwRetry = pZoneInfo->retryInterval; pRecord->Data.SOA.dwSerialNo = pZoneInfo->serial; pszName = NULL; pszRName = NULL; *ppRecord = pRecord; cleanup: return dwError; error: VmDnsFreeMemory(pszName); VmDnsFreeMemory(pszRName); VMDNS_FREE_RECORD(pRecord); goto cleanup; }
DWORD VmDnsAllocateRWLock( PVMDNS_RWLOCK* ppLock ) { DWORD dwError = 0; PVMDNS_RWLOCK pLock = NULL; BAIL_ON_VMDNS_INVALID_POINTER(ppLock, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_RWLOCK), (void**)&pLock); BAIL_ON_VMDNS_ERROR(dwError); dwError = pthread_rwlock_init(&pLock->rwLock, NULL); dwError = POSIX_TO_WIN32_ERROR(dwError); BAIL_ON_VMDNS_ERROR(dwError); dwError = pthread_key_create(&pLock->readKey, VmDnsFreeLockCount); dwError = POSIX_TO_WIN32_ERROR(dwError); BAIL_ON_VMDNS_ERROR(dwError); dwError = pthread_key_create(&pLock->writeKey, VmDnsFreeLockCount); dwError = POSIX_TO_WIN32_ERROR(dwError); BAIL_ON_VMDNS_ERROR(dwError); *ppLock = pLock; cleanup: return dwError; error: VMDNS_SAFE_FREE_MEMORY(pLock); goto cleanup; }
DWORD VmDnsForwarderInit( PVMDNS_FORWARDER_CONTEXT* ppForwarder ) { DWORD dwError = ERROR_SUCCESS; PVMDNS_FORWARDER_CONTEXT pForwarderContext = NULL; BAIL_ON_VMDNS_INVALID_POINTER(ppForwarder, dwError); dwError = VmDnsAllocateMemory( sizeof(VMDNS_FORWARDER_CONTEXT), (PVOID*)&pForwarderContext); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsAllocateRWLock(&pForwarderContext->pLock); BAIL_ON_VMDNS_ERROR(dwError); *ppForwarder = pForwarderContext; cleanup: return dwError; error: if (pForwarderContext) { VmDnsForwarderCleanup(pForwarderContext); } goto cleanup; }
DWORD VmDnsGetForwarderAtIndex( PVMDNS_FORWARDER_CONTEXT pForwarder, DWORD dwIndex, PSTR* ppszForwarder ) { DWORD dwError = 0; PSTR pszForwarder = NULL; BOOL bLocked = FALSE; BAIL_ON_VMDNS_INVALID_POINTER(pForwarder, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppszForwarder, dwError); VMDNS_LOCKREAD(pForwarder->pLock); bLocked = TRUE; if (dwIndex >= pForwarder->dwCount) { dwError = ERROR_INVALID_INDEX; BAIL_ON_VMDNS_ERROR(dwError); } dwError = VmDnsAllocateStringA( pForwarder->pForwarderEntries[dwIndex]->pszForwarder, &pszForwarder ); BAIL_ON_VMDNS_ERROR(dwError); *ppszForwarder = pszForwarder; cleanup: if (bLocked) { VMDNS_UNLOCKREAD(pForwarder->pLock); } return dwError; error: if (ppszForwarder) { *ppszForwarder = NULL; } VMDNS_SAFE_FREE_STRINGA(pszForwarder); goto cleanup; }
DWORD VmDnsPropertyListAdd( PVMDNS_PROPERTY_LIST pList, PVMDNS_PROPERTY_OBJECT pProperty ) { PVMDNS_PROPERTY_OBJECT *pNewList = NULL; DWORD dwError = 0; BAIL_ON_VMDNS_INVALID_POINTER(pList, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pProperty, dwError); if (pList->dwCurrentSize >= pList->dwMaxSize) { pList->dwMaxSize = 2 * pList->dwMaxSize; dwError = VmDnsAllocateMemory( sizeof(PVMDNS_PROPERTY_OBJECT) * pList->dwMaxSize, (PVOID*)&pNewList); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsCopyMemory( pNewList, sizeof(PVMDNS_PROPERTY_OBJECT) * pList->dwMaxSize, pList->ppProperties, sizeof(PVMDNS_PROPERTY_OBJECT) * pList->dwCurrentSize); BAIL_ON_VMDNS_ERROR(dwError); VMDNS_SAFE_FREE_MEMORY(pList->ppProperties); pList->ppProperties = pNewList; pNewList = NULL; } VmDnsPropertyObjectAddRef(pProperty); pList->ppProperties[pList->dwCurrentSize] = pProperty; ++pList->dwCurrentSize; cleanup: return dwError; error: VMDNS_SAFE_FREE_MEMORY(pNewList); goto cleanup; }
DWORD VmDnsSetForwarders( PVMDNS_FORWARDER_CONTEXT pForwarder, DWORD dwCount, PSTR* ppszForwarders ) { DWORD dwError = 0; DWORD dwCurrentCount, i = 0; BOOL bLocked = FALSE; BAIL_ON_VMDNS_INVALID_POINTER(pForwarder, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppszForwarders, dwError); VMDNS_LOCKWRITE(pForwarder->pLock); bLocked = TRUE; dwCurrentCount = pForwarder->dwCount; for (i = 0; i < dwCurrentCount; ++i) { VmDnsFreeForwarderEntry(pForwarder->pForwarderEntries[i]); } pForwarder->dwCount = 0; for (i = 0; i < dwCount; ++i) { dwError = VmDnsForwarderAppend( pForwarder, ppszForwarders[i]); BAIL_ON_VMDNS_ERROR(dwError); } cleanup: if (bLocked) { VMDNS_UNLOCKWRITE(pForwarder->pLock); } return dwError; error: goto cleanup; }
DWORD VmDnsGetForwarders_inlock( PVMDNS_FORWARDER_CONTEXT pForwarder, PSTR** pppszForwarders, PDWORD pdwCount ) { DWORD dwError = 0; PSTR* pszForwarders = NULL; DWORD dwCount = 0, i = 0; BAIL_ON_VMDNS_INVALID_POINTER(pForwarder, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pppszForwarders, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pdwCount, dwError); dwCount = pForwarder->dwCount; dwError = VmDnsAllocateMemory( (dwCount + 1) * sizeof(PSTR), (PVOID*)&pszForwarders); BAIL_ON_VMDNS_ERROR(dwError); for (; i < dwCount; ++i) { dwError = VmDnsAllocateStringA( pForwarder->pForwarderEntries[i]->pszForwarder, &pszForwarders[i]); BAIL_ON_VMDNS_ERROR(dwError); } *pdwCount = dwCount; *pppszForwarders = pszForwarders; cleanup: return dwError; error: VmDnsFreeStringArrayA(pszForwarders); goto cleanup; }
DWORD VmDnsRpcCopyZoneInfo( PVMDNS_ZONE_INFO pZoneInfoSrc, PVMDNS_ZONE_INFO pZoneInfoDest ) { DWORD dwError = ERROR_SUCCESS; BAIL_ON_VMDNS_INVALID_POINTER(pZoneInfoSrc, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pZoneInfoDest, dwError); dwError = VmDnsRpcAllocateStringA(pZoneInfoSrc->pszName, &pZoneInfoDest->pszName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsRpcAllocateStringA(pZoneInfoSrc->pszPrimaryDnsSrvName, &pZoneInfoDest->pszPrimaryDnsSrvName); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsRpcAllocateStringA(pZoneInfoSrc->pszRName, &pZoneInfoDest->pszRName); BAIL_ON_VMDNS_ERROR(dwError); pZoneInfoDest->dwFlags = pZoneInfoSrc->dwFlags; pZoneInfoDest->dwZoneType = pZoneInfoSrc->dwZoneType; pZoneInfoDest->expire = pZoneInfoSrc->expire; pZoneInfoDest->minimum = pZoneInfoSrc->minimum; pZoneInfoDest->refreshInterval = pZoneInfoSrc->refreshInterval; pZoneInfoDest->retryInterval = pZoneInfoSrc->retryInterval; pZoneInfoDest->serial = pZoneInfoSrc->serial; cleanup: return dwError; error: VmDnsRpcFreeMemory(pZoneInfoDest->pszName); VmDnsRpcFreeMemory(pZoneInfoDest->pszPrimaryDnsSrvName); VmDnsRpcFreeMemory(pZoneInfoDest->pszRName); VmDnsRpcFreeMemory(pZoneInfoDest); goto cleanup; }
DWORD VmDnsGenerateRtrNameFromIp( PCSTR pszIPAddress, int* pnFamily, PSTR* ppszPtrName ) { DWORD dwError = 0; DWORD dwAddr = 0; PSTR pszPtrName = NULL; struct addrinfo *pAddrInfo = NULL; BYTE* pByte = NULL; BAIL_ON_VMDNS_INVALID_POINTER(pszIPAddress, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppszPtrName, dwError); if (getaddrinfo(pszIPAddress, NULL, NULL, &pAddrInfo)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (pAddrInfo->ai_family == AF_INET) { dwAddr = (DWORD)((struct sockaddr_in *)pAddrInfo->ai_addr)->sin_addr.s_addr; // See RFC 1035 for name format // In short, record name is octets in reverse order appened with "in-addr.arpa". // Example: 11.1.193.128.in-addr.arpa dwError = VmDnsAllocateStringPrintfA( &pszPtrName, "%d.%d.%d.%d%s", (dwAddr & 0xFF000000) >> 24, (dwAddr & 0xFF0000) >> 16, (dwAddr & 0xFF00) >> 8, (dwAddr & 0xFF), PTR_NAME_SUFFIX_IP4 ); BAIL_ON_VMDNS_ERROR(dwError); }
DWORD VmDnsRecordGetCN( PVMDNS_RECORD pRecord, PSTR* ppStr ) { DWORD idx = 0; DWORD dwError = ERROR_SUCCESS; BAIL_ON_VMDNS_INVALID_POINTER(pRecord, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppStr, dwError); dwError = VmDnsFindRecordMethods(pRecord, &idx); if(!dwError) { dwError = gRecordMethods[idx].pfnGetCN(pRecord, ppStr); } cleanup: return dwError; error: goto cleanup; }
DWORD VmDnsRpcCopyRecord( PVMDNS_RECORD pRecord, PVMDNS_RECORD pDest ) { DWORD idx = 0; DWORD dwError = ERROR_SUCCESS; BAIL_ON_VMDNS_INVALID_POINTER(pRecord, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pDest, dwError); dwError = VmDnsFindRecordMethods(pRecord, &idx); if(!dwError) { dwError = gRecordMethods[idx].pfnRpcCopy(pRecord, pDest); } cleanup: return dwError; error: goto cleanup; }
static DWORD _DeleteForwarder( PVMDNS_SERVER_CONTEXT pServerContext, PCSTR pszForwarder, PCSTR pszZone ) { DWORD dwError = 0; dwError = VmDnsValidateContext(pServerContext); BAIL_ON_VMDNS_ERROR(dwError); BAIL_ON_VMDNS_INVALID_POINTER(pszForwarder, dwError); DCETHREAD_TRY { if (pszZone) { dwError = VmDnsRpcDeleteZoneForwarder( pServerContext->hBinding, (PDNS_STRING)pszForwarder, (PDNS_STRING)pszZone); } else { dwError = VmDnsRpcDeleteForwarder( pServerContext->hBinding, (PDNS_STRING)pszForwarder); } } DCETHREAD_CATCH_ALL(THIS_CATCH) { dwError = VmDnsRpcGetErrorCode(THIS_CATCH); } DCETHREAD_ENDTRY; BAIL_ON_VMDNS_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }
DWORD VmDnsPropertyListCreate( PVMDNS_PROPERTY_LIST *ppList ) { DWORD dwError = 0; PVMDNS_PROPERTY_LIST pList = NULL; BAIL_ON_VMDNS_INVALID_POINTER(ppList, dwError); dwError = VmDnsAllocateMemory(sizeof(VMDNS_PROPERTY_LIST), (PVOID*)&pList); BAIL_ON_VMDNS_ERROR(dwError); pList->dwCurrentSize = 0; pList->dwMaxSize = 10; dwError = VmDnsAllocateMemory( sizeof(PVMDNS_PROPERTY_OBJECT)* pList->dwMaxSize, (PVOID*)&pList->ppProperties); BAIL_ON_VMDNS_ERROR(dwError); pList->nRefCount = 1; *ppList = pList; cleanup: return dwError; error: if (ppList) { *ppList = NULL; } VmDnsPropertyListRelease(pList); goto cleanup; }
DWORD VmDnsParseServiceProtocol( PSTR pszServiceType, VMDNS_SERVICE_PROTOCOL* pProtocol, PSTR* ppszName ) { DWORD idx = 0; DWORD dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_INVALID_POINTER(pszServiceType, dwError); for (; idx < gProtocolNameMapSize; ++idx) { if (!VmDnsStringCompareA(pszServiceType, gProtocolNameMap[idx].pszUserFriendlyName, FALSE)) { dwError = ERROR_SUCCESS; if (pProtocol) { *pProtocol = gProtocolNameMap[idx].protocol; } if (ppszName) { dwError = VmDnsAllocateStringA(gProtocolNameMap[idx].pszName, ppszName); } break; } } cleanup: return dwError; error: goto cleanup; }
DWORD VmDnsGenerateReversZoneNameFromNetworkId( PCSTR pszNetworkId, PSTR* ppszZone ) { DWORD dwError = 0; PSTR pszPtrName = NULL; PSTR pszZone = NULL; PCHAR pLength = NULL; int length = 0; int family = AF_INET; BAIL_ON_VMDNS_INVALID_POINTER(pszNetworkId, dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppszZone, dwError); pLength = VmDnsStringChrA(pszNetworkId, '/'); if (!pLength || !*(pLength + 1)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } *pLength = '\0'; ++pLength; length = atoi(pLength); dwError = VmDnsGenerateRtrNameFromIp(pszNetworkId, &family, &pszPtrName); BAIL_ON_VMDNS_ERROR(dwError); if (family != AF_INET && family != AF_INET6) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } if (family == AF_INET) { if (length != 8 && length != 16 && length != 24) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } pszZone = pszPtrName; while (length < 32 && *pszZone) { pszZone = VmDnsStringChrA(pszZone, '.'); if (!pszZone) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } ++pszZone; length += 8; } if (!*pszZone) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } } else { if (length >= 128 || length <= 0) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } pszZone = pszPtrName + 64 - length/2; } dwError = VmDnsAllocateStringA(pszZone, ppszZone); BAIL_ON_VMDNS_ERROR(dwError); cleanup: return dwError; error: goto cleanup; }
DWORD VmDnsDeleteForwarder( PVMDNS_FORWARDER_CONTEXT pForwarder, PCSTR pszForwarder ) { DWORD dwError = 0; DWORD index = 0; BOOL bLocked = FALSE; PSTR* ppszForwarders = NULL; DWORD dwCount = 0; BAIL_ON_VMDNS_INVALID_POINTER(pForwarder, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pszForwarder, dwError); VMDNS_LOCKWRITE(pForwarder->pLock); bLocked = TRUE; index = VmDnsForwarderLookup( pForwarder, pszForwarder); if (index != -1) { dwError = VmDnsForwarderRemoveAt( pForwarder, index); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsGetForwarders_inlock( pForwarder, &ppszForwarders, &dwCount); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsStoreSaveForwarders( pForwarder->dwCount, ppszForwarders); BAIL_ON_VMDNS_ERROR(dwError); } else { dwError = ERROR_NOT_FOUND; BAIL_ON_VMDNS_ERROR(dwError); } cleanup: if (ppszForwarders) { VmDnsFreeStringCountedArrayA(ppszForwarders, dwCount); } if (bLocked) { VMDNS_UNLOCKWRITE(pForwarder->pLock); } return dwError; error: goto cleanup; }
DWORD VmDnsAddForwarder( PVMDNS_FORWARDER_CONTEXT pForwarder, PCSTR pszForwarder ) { DWORD dwError = 0; BOOL bLocked = FALSE; PSTR* ppszForwarders = NULL; DWORD dwCount = 0; BAIL_ON_VMDNS_INVALID_POINTER(pForwarder, dwError); BAIL_ON_VMDNS_INVALID_POINTER(pszForwarder, dwError); if (!VmDnsValidateForwarder(pszForwarder)) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDNS_ERROR(dwError); } VMDNS_LOCKWRITE(pForwarder->pLock); bLocked = TRUE; int index = VmDnsForwarderLookup( pForwarder, pszForwarder); if (index < 0) { dwError = VmDnsForwarderAppend( pForwarder, pszForwarder); BAIL_ON_VMDNS_ERROR(dwError); VMDNS_UNLOCKWRITE(pForwarder->pLock); bLocked = FALSE; dwError = VmDnsGetForwarders_inlock( pForwarder, &ppszForwarders, &dwCount); BAIL_ON_VMDNS_ERROR(dwError); dwError = VmDnsStoreSaveForwarders( pForwarder->dwCount, ppszForwarders); BAIL_ON_VMDNS_ERROR(dwError); } else { dwError = ERROR_ALREADY_EXISTS; BAIL_ON_VMDNS_ERROR(dwError); } cleanup: if (ppszForwarders) { VmDnsFreeStringCountedArrayA(ppszForwarders, dwCount); } if (bLocked) { VMDNS_UNLOCKWRITE(pForwarder->pLock); } return dwError; error: goto cleanup; }
static DWORD _GetForwarders( PVMDNS_SERVER_CONTEXT pServerContext, PCSTR pszZone, PVMDNS_FORWARDERS* ppForwarders ) { DWORD dwError = 0; PVMDNS_FORWARDERS pDnsForwarders = NULL; PVMDNS_FORWARDERS pDnsForwardersOutput = NULL; PSTR* ppszForwarders = NULL; DWORD dwCount = 0; dwError = VmDnsValidateContext(pServerContext); BAIL_ON_VMDNS_ERROR(dwError); BAIL_ON_VMDNS_INVALID_POINTER(ppForwarders, dwError); DCETHREAD_TRY { if (pszZone) { dwError = VmDnsRpcGetZoneForwarders( pServerContext->hBinding, (PDNS_STRING)pszZone, &pDnsForwarders); } else { dwError = VmDnsRpcGetForwarders( pServerContext->hBinding, &pDnsForwarders); } } DCETHREAD_CATCH_ALL(THIS_CATCH) { dwError = VmDnsRpcGetErrorCode(THIS_CATCH); } DCETHREAD_ENDTRY; BAIL_ON_VMDNS_ERROR(dwError); if (pDnsForwarders) { DWORD i = 0; PSTR szTemp = NULL; if (pDnsForwarders->dwCount > 0) { dwError = VmDnsAllocateMemory( pDnsForwarders->dwCount * sizeof(PSTR), (PVOID*)&ppszForwarders); BAIL_ON_VMDNS_ERROR(dwError); for (i = 0; i < pDnsForwarders->dwCount; ++i) { dwError = VmDnsAllocateStringA( pDnsForwarders->ppszName[i], &szTemp ); BAIL_ON_VMDNS_ERROR(dwError); ppszForwarders[i] = szTemp; ++dwCount; } } dwError = VmDnsAllocateMemory( sizeof(VMDNS_FORWARDERS), (PVOID*)&pDnsForwardersOutput); BAIL_ON_VMDNS_ERROR(dwError); pDnsForwardersOutput->dwCount = pDnsForwarders->dwCount; pDnsForwardersOutput->ppszName = ppszForwarders; } *ppForwarders = pDnsForwardersOutput; cleanup: if (pDnsForwarders) { VmDnsRpcFreeForwarders(pDnsForwarders); } return dwError; error: if (ppszForwarders) { VmDnsFreeStringCountedArrayA(ppszForwarders, dwCount); } if (pDnsForwardersOutput) { VMDNS_SAFE_FREE_MEMORY(pDnsForwardersOutput); } goto cleanup; }