Note: This is not the complete source code--just the main source file.
You can download the full source (with include files) from our sample code archive by clicking on the diskette icons.
// MXbyHexDns sample
// version 2002-08-21
//
// Demonstrates how to obtain MX records with HexDns.
//
// History:
// 2002-08-21 Created
//
// Copyright 2002 Hexillion Technologies. All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND/OR
// FITNESS FOR A PARTICULAR PURPOSE.
#include "stdafx.h"
#include <iostream>
#include "HexComPtr.h"
#include "HexDns.h"
#import "HexDns.dll" no_namespace
using namespace std;
int main(int argc, char* argv[])
{
int iReturn = 0;
try
{
// If we don't have one argument (aside from utility name)...
if( 2 != argc )
{
// Display usage and exit
cout << "Usage: MXbyHexDns domain" << endl;
throw 0;
}
CoInitialize( NULL );
// Declare instance of a licensing-aware _com_ptr_t derivative
HexComPtr< HEX_IIID( IConnectionSync ) > pDns;
// Use this code to get your runtime license key while your license
// file is in place. Then comment the code out and put the runtime
// key in the CreateInstanceLic calls below. Your binary will then
// work without the license file.
// _bstr_t bstrKey;
// pDns.RequestLicKey( __uuidof( Connection ), bstrKey );
// cout << "Runtime license key: " << (TCHAR*)bstrKey << endl;
// Create an instance of HexDns.Connection
HRESULT hr = pDns.CreateInstanceLic( __uuidof( Connection ), L"*** Put your runtime license key here ***" );
// If CreateInstance failed...
if( FAILED( hr ) )
{
cout << "Creation of HexDns.Connection instance failed. HRESULT=0x" << hex << hr << endl;
throw -1;
}
// You know you're using the runtime license when the Error property and
// LicensedProcessors property are both zero
bool bUsingRuntimeKey = (0 == pDns->Error) && (0 == pDns->LicensedProcessors);
// Get an instance of HexDns.Lookup for converting IP addresses to strings
HexComPtr< HEX_IIID( ILookupSync ) > pLkup;
hr = pLkup.CreateInstanceLic( __uuidof( LookUp ), L"*** Put your runtime license key here ***" );
// If CreateInstance failed...
if( FAILED( hr ) )
{
cout << "Creation of HexDns.Lookup instance failed. HRESULT=0x" << hex << hr << endl;
throw -1;
}
// If HexDns couldn't find local nameservers for some reason...
if( 0 == pDns->ServerAddrs->Count )
{
cout << "HexDns could not find local nameservers." << endl;
throw -1;
}
// Set the timeout
pDns->Timeout = 4000; // 4 seconds
// Do the query
IMessagePtr pMsg = pDns->Query( argv[1], hexDnsTypeMX, hexDnsClassIN );
// If the query failed...
if( hexDnsErrSuccess != pDns->Error )
{
cout << "MX query for " << argv[1] << " failed with error: " << (TCHAR*)GetDnsErrorString( pDns->Error ) << endl;
throw -1;
}
// If the server returned an error...
if( hexDnsMsgRcodeSuccess != pMsg->ResponseCode )
{
cout << "The nameserver returned an error: " << (TCHAR*)GetMsgRcodeString( pMsg->ResponseCode ) << endl;
throw -1;
}
// Write an intro
cout << "MX records returned for " << argv[1] << ':' << endl;
// Cache pointers to returned record collections
// These are 1-based collections
IRecordsPtr pAnswers = pMsg->AnswerRecords;
IRecordsPtr pAdditionals = pMsg->AddtlRecords;
long lMaxAns = pAnswers->Count;
long lMaxAdd = pAdditionals->Count;
long lAddr;
int iCount = 0;
IRecordPtr pRec;
IRecordInMxPtr pMX;
// For each record in the Answers section...
for( long l = 1; l <= lMaxAns; l++ )
{
pRec = pAnswers->Item( l );
// If it's an MX record (and not, say, a CNAME record)...
if( hexDnsTypeMX == pRec->Type )
{
iCount++;
pMX = (IRecordInMxPtr)pRec;
// Loop through the Additionals section looking for a corresponding A record
lAddr = 0;
for( long m = 1; m <= lMaxAdd; m++ )
{
IRecordPtr pRecAdd = pAdditionals->Item( m );
// If it's an A record with the name of the exchanger...
if( hexDnsTypeA == pRecAdd->Type &&
pRecAdd->Name == pMX->Exchange )
{
// Grab the address
lAddr = ((IRecordInAPtr)pRecAdd)->Addr;
break;
}
}
// Print the record
cout << '\t' << pMX->Preference << '\t' << (TCHAR*)(pMX->Exchange);
if( 0 != lAddr )
cout << " [" << (TCHAR*)(pLkup->AddrToString( lAddr )) << ']';
cout << endl;
}
}
// If we didn't get any MX records...
if( 0 == iCount )
// Say so
cout << "\t(none)" << endl;
}
catch( int i )
{
iReturn = i;
}
CoUninitialize();
return iReturn;
}