CONVENGN.CPP

// --convengn.cpp--------------------------------------------------------------- 
//
// Conversion engine code. This file defines the CEDKConvEng class which
// defines the top level behavior of the conversion engine.
//
// Copyright (C) Microsoft Corp. 1986-1996. All Rights Reserved.
//
// -----------------------------------------------------------------------------

#include "convincl.h"
#include "convengn.chk"

//$--CEDKConvEng::CEDKConvEng----------------------------------------------------
//
// DESCRIPTION: constructor for CEDKConvEng. Required because CEDKConvEng has contained
// objects with CTORs.
//
// INPUT: none
//
// RETURNS: nothing
//
//------------------------------------------------------------------------------
CEDKConvEng::CEDKConvEng()
{
DEBUGPRIVATE("CEDKConvEng::CEDKConvEng()\n");
}

//$--CEDKConvEng::HrEDKInitialize---------------------------------------------------
//
// DESCRIPITON: Initialize the conversion engine.
//
// INPUT: hEventSource -- event source handle
//
// RETURNS: HRESULT -- NOERROR if successful,
// E_INVALIDARG if bad input
// E_FAIL otherwise.
//
//------------------------------------------------------------------------------
HRESULT CEDKConvEng::HrEDKInitialize( // RETURNS: HRESULT
IN HANDLE hEventSource) // event source handle
{
HRESULT hr = NOERROR;

DEBUGPRIVATE("CEDKConvEng::HrEDKInitialize()\n");

// check input parameters
hr = CHK_CEDKConvEng_HrEDKInitialize(hEventSource);

if ( FAILED(hr) )
{
RETURN(hr);
}

m_hEventSource = hEventSource;

hr = m_crRegistry.HrEDKInitialize();

RETURN(hr);

}

//$--CEDKConvEng::HrEDKConvert------------------------------------------------------
//
// DESCRIPTION: Search for a suitable conversion. If a suitable conversion is
// found, invoke it.
//
// INPUT: pEnv -- environment of the conversion
// pszContentClass -- class of source to be converted
// pContentIn -- source to be converted
// pContentOut -- converted object
//
// OUTPUT:
// crResult -- result
//
// RETURNS: HRESULT -- NOERROR if successful,
// E_INVALIDARG if bad input
// E_FAIL otherwise.
//
//------------------------------------------------------------------------------
HRESULT CEDKConvEng::HrEDKConvert( // RETURNS: HRESULT
IN PEDKCNVENV pEnv, // environment of the conversion
IN LPCWSTR pszContentClass, // class of source to be converted.
IN PVOID pContentIn, // source to be converted.
IN PVOID pContentOut, // converted object
OUT EDKCNVRES & crResult) // result.
{
HRESULT hr = NOERROR; // return code
BOOL bFoundAtLeastOneCandidate = FALSE;
LPCWSTR pszConversionPoint = NULL; // conversion point wide string

DEBUGPRIVATE("CEDKConvEng::HrEDKConvert()\n");

// check input parameters
hr = CHK_CEDKConvEng_HrEDKConvert(pEnv, pszContentClass, pContentIn, pContentOut,
crResult);

if ( FAILED(hr) )
{
RETURN(hr);
}

m_bFoundAtLeastOneAccept = FALSE;

//
// Find all candidate converters
//

//
// start search.
//

crResult = GCR_NO_CANDIDATE;

if(pEnv != NULL)
{
pszConversionPoint = pEnv->pszConversionPoint;
}

hr = m_crRegistry.HrEDKSearchOpen(pszConversionPoint, pszContentClass, m_pepConverter);

if( FAILED(hr) )
{
goto cleanup;
}

while( TRUE )
{
// Find next candidate conversion DLL.
hr = m_crRegistry.HrEDKSearchNext();

if ( FAILED(hr) )
{
// no more candidate DLLs.
// break;
break;
}

crResult = GCR_CANNOT_CONVERT;

bFoundAtLeastOneCandidate = TRUE;

//
// Display some debug info.
//
#ifdef DEBUG
// _tprintf( TEXT(" Attempting converter for class %ls\n"), pszContentClass );
m_pepConverter->EDKDump();
#endif

//
// Attempt the conversion.
//

hr = HrEDKAttemptConversion(
pEnv,
pszContentClass,
pszConversionPoint,
pContentIn,
pContentOut,
crResult);

if(FAILED(hr)) // catastrophic error.
{
goto cleanup;
}

if(crResult == GCR_OK ) // conversion happened.
{
goto cleanup;
}

} // end while

//
// Detect and report the case when no candidates found.
//

if(!bFoundAtLeastOneCandidate)
{
EventLogMsgW(
MESGXLAT_CNV_NO_CANDIDATE, // event identfier
2, // # of strings
pszConversionPoint, // string 1
pszContentClass,
0); // # of error codes
}

//
// Detect and report the case when candidates found but won't accept.
//

if(bFoundAtLeastOneCandidate && !m_bFoundAtLeastOneAccept)
{
WCHAR szRcTmp[(sizeof(HRESULT)+1)*2] = {0};

swprintf(szRcTmp, L"%08lx", hr);

EventLogMsgW(
MESGXLAT_CNV_NO_ACCEPT, // event identifier
4, // # of strings
m_pepConverter->pszDllName(), // string 1
pszConversionPoint, // string 2
pszContentClass,
szRcTmp,
0); // # of error codes
}

cleanup:

m_crRegistry.EDKSearchClose();

if(hr == EDK_E_END_OF_FILE) // just couldn't find a converter. Only returned by Find/Next
{
crResult = GCR_NO_CANDIDATE;

hr = HR_LOG(NOERROR);
}

RETURN(hr);

}

//$--CEDKConvEng::HrEDKAttemptConversion--------------------------------------------
//
// DESCRIPTION: Attempt a particular conversion.
//
// INPUT: pEnv -- environment of the conversion
// pszContentClass -- class of source to be converted
// pszConversionPoint -- where the conversion happened
// pContentIn -- source to be converted
// pContentOut -- converted object
//
// OUTPUT:
// crResult -- result
//
// RETURNS: HRESULT -- NOERROR if successful,
// E_INVALIDARG if bad input,
// E_FAIL otherwise.
//
//------------------------------------------------------------------------------
HRESULT CEDKConvEng::HrEDKAttemptConversion(
IN PEDKCNVENV pEnv, // environment of the convrsion
IN LPCWSTR pszContentClass, // class of source to be converted.
IN LPCWSTR pszConversionPoint, // where the conversion happened.
IN PVOID pContentIn, // source to be converted.
IN PVOID pContentOut, // converted object
OUT EDKCNVRES & crResult) // result.
{
HRESULT hr = NOERROR; // return code
CEDKConvDll cDll(m_pepConverter, m_hEventSource); // conversion DLL

DEBUGPRIVATE("CEDKConvEng::HrEDKAttemptConversion()\n");

// check input parameters
hr = CHK_CEDKConvEng_HrEDKAttemptConversion(pEnv, pszContentClass, pszConversionPoint,
pContentIn, pContentOut, crResult);

if ( FAILED(hr) )
{
RETURN(hr);
}

//
// Make a connection to the DLL.
//
hr = cDll.HrEDKLoad();

if(SUCCEEDED(hr))
{
BOOL bAmCandidate = FALSE;

//
// Can this DLL handle the message class?
//
hr = cDll.HrEDKQueryCapability(pEnv, pszContentClass, pContentIn, bAmCandidate);

if(SUCCEEDED(hr) && bAmCandidate)
{
m_bFoundAtLeastOneAccept = TRUE;

//
// Yes, try to perform the conversion.
//

hr = cDll.HrEDKConvert(
pEnv, pszContentClass, pContentIn, pContentOut, crResult);

if(FAILED(hr))
{
crResult = GCR_CONVERSION_FAILED;

//
// Report conversion failure
//

{
WCHAR szRcTmp[(sizeof(HRESULT)+1)*2] = {0};

swprintf(szRcTmp, L"%08lx", hr);

EventLogMsgW(
MESGXLAT_CNV_CONVERT_FAIL, // event identifier
4, // # of strings
m_pepConverter->pszDllName(), // string 1
pszConversionPoint, // string 2
pszContentClass,
szRcTmp,
0); // # of error codes
}

}
}
else
{
if(FAILED(hr))
{
//
// Report query failure
//

{
WCHAR szRcTmp[(sizeof(HRESULT)+1)*2] = {0};

swprintf(szRcTmp, L"%08lx", hr);

EventLogMsgW(
MESGXLAT_CNV_QUERY_FAIL, // event identifier
4, // # of strings
m_pepConverter->pszDllName(), // string 1
pszConversionPoint, // string 2
pszContentClass,
szRcTmp,
0); // # of error codes
}

}
}
}
else
{
crResult = GCR_CANNOT_LOAD;
}

// Don't unload DLL. The DLL cache takes care of this,
// when appropriate.

RETURN(hr);

}


//$--CEDKConvEng::HrEDKUninitialize-------------------------------------------------
//
// DESCRIPTION: Uninitialize a conversion engine.
//
// INPUT: none
//
// RETURNS: HRESULT -- NOERROR if successful,
// E_FAIL otherwise.
//
//------------------------------------------------------------------------------
HRESULT CEDKConvEng::HrEDKUninitialize()
{
DEBUGPRIVATE("CEDKConvEng::HrEDKUninitialize()\n");

RETURN(NOERROR);
}