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.

MXbyHexValidEmail.cpp

// MXbyHexValidEmail sample
// version 2002-08-21
// 
// Demonstrates how to obtain MX records with HexValidEmail.
//
// 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 "HexValidEmail.h"

#import "HexValidEmail.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: MXbyHexValidEmail domain" << endl;
			throw 0;
			}

		CoInitialize( NULL );
		
		// Declare instance of a licensing-aware _com_ptr_t derivative
		HexComPtr< HEX_IIID( IConnectionSync ) > pVE;

		// 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 call below. Your binary will then
		// work without the license file.
//		_bstr_t bstrKey;
//		pVE.RequestLicKey( __uuidof( Connection ), bstrKey );
//		cout << "Runtime license key: " << (TCHAR*)bstrKey << endl;

		// Create an instance of HexValidEmail.Connection
		HRESULT hr = pVE.CreateInstanceLic( __uuidof( Connection ), L"*** Put your runtime license key here ***" );

		// If CreateInstance failed...
		if( FAILED( hr ) )
			{
			cout << "Creation of HexValidEmail.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 == pVE->Error) && (0 == pVE->LicensedProcessors);

		// Set the timeout
		pVE->Timeouts->Item( hexVeTimeoutDnsTotal )->Value = 4000;  // 4 seconds

		// Require MX records
		// This prevents HexValidEmail from allowing domains to just have A records
		// and ensures that only real MX records will be returned in the collection.
		pVE->Options |= hexVeOptionRequireMx;

		// Make up an email address using the supplied domain
		_bstr_t bstrEmail = _bstr_t( L"test@" ) + argv[1];

		// Do the query by validating to DNS level
		pVE->Validate( bstrEmail, hexVeLevelDns );

		// If the query failed for a reason other than finding no MX records...
		if( hexVeErrSuccess != pVE->Error && hexVeErrNoMxForDomain != pVE->Error )
			{
			cout << "MX query for " << argv[1] << " failed with error: " << (TCHAR*)GetVeErrorString( pVE->Error ) << endl;
			throw -1;
			}

		// Write an intro
		cout << "MX records returned for " << argv[1] << ':' << endl;

		// If we didn't get any MX records...
		if( hexVeErrNoMxForDomain == pVE->Error )
			{
			// Say so
			cout << "\t(none)" << endl;
			throw 0;
			}

		// Cache pointer to MxRec collection
		// This is a 1-based collection
		IMxRecsPtr pRecs = pVE->MxRecs;

		IMxRecPtr pMX;
		long lMax = pRecs->Count;

		// For each record in the collection...
		for( long l = 1; l <= lMax; l++ )
			{
			pMX = pRecs->Item( l );

			// Print the record
			cout << '\t' << pMX->Preference << '\t' << (TCHAR*)(pMX->Exchange);

			if( 0 != pMX->Addr )
				cout << " [" << (TCHAR*)(pVE->AddrToString( pMX->Addr )) << ']';

			cout << endl;
			}

		}
	catch( int i )
		{
		iReturn = i;
		}

	CoUninitialize();

	return iReturn;
	}