CONVDLLC.CPP

// --convdllc.cpp-------------------------------------------------------------- 
//
// Conversion DLL cache source code.
//
// Copyright (C) Microsoft Corp., 1986-1996. All rights reserved.
//
// ----------------------------------------------------------------------------

#include "convincl.h"
#include "convdllc.chk"

//$--CDllCache::CDllCache()----------------------------------------------------
//
// DESCRIPTION: constructor
//
// INPUT: none
//
// RETURNS; nothing
//
//-----------------------------------------------------------------------------
CDllCache::CDllCache()
{
DEBUGPRIVATE("CDllCache::CDllCache()\n");

ZeroMemory(m_rgSDllCache, sizeof(m_rgSDllCache));
}

//$--CDllCache::~CDllCache()----------------------------------------------------
//
// DESCRIPTION: destructor
//
// INPUT: none
//
// RETURNS; nothing
//
//-----------------------------------------------------------------------------
CDllCache::~CDllCache()
{
UINT iDll = 0; // index into DLL cache
SDllCache * pDll = NULL; // current DLL pointer

DEBUGPRIVATE("CDllCache::~CDllCache()\n");

// Unload any loaded DLLs
for ( iDll = 0; iDll < nCachedDlls; iDll++ )
{
// get current DLL pointer
pDll = m_rgSDllCache[iDll];

// See if its valid
if ( pDll != NULL )
{
// unload the DLL
ASSERTERROR(pDll->hInst != NULL, "Bad pDll->hInst");
(VOID)FreeLibrary(pDll->hInst);

// Free the DLL cache entry
delete pDll;

pDll = NULL; // null out pointer
}

} // end for each cached DLL

}

//$--CDllCache::HrAdd----------------------------------------------------------
//
// DESCRIPTION: Loads DLL and adds it to the cache.
//
// INPUT: lpwszDllName -- DLL name
//
// RETURNS: HRESULT -- NOERROR if successful,
// E_INVALIDARG if bad input
// E_OUTOFMEMORY if memory problems.
// E_FAIL otherwise.
//
// ----------------------------------------------------------------------------
HRESULT CDllCache::HrAdd(
IN LPWSTR lpwszDllName) // DLL to add
{
HRESULT hr = NOERROR;
SDllCache * pDllCur = NULL; // current cached DLL pointer
UINT iDll = 0; // index into DLL cache
BOOL fLoaded = FALSE; // TRUE if DLL loaded

DEBUGPRIVATE("CDllCache::HrAdd()\n");

// check input parameters
hr = CHK_CDllCache_HrAdd(lpwszDllName);

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

// Find next empty space in the DLL cache
for ( iDll = 0; iDll < nCachedDlls; iDll++ )
{
pDllCur = m_rgSDllCache[iDll];

if ( pDllCur == NULL )
{
// found an place for this DLL.
pDllCur = new SDllCache; // allocate new cache entry

if ( pDllCur == NULL )
{
hr = HR_LOG(E_OUTOFMEMORY);

goto cleanup;
}

// fill in DLL entry information.
lstrcpyW(pDllCur->lpwszName, lpwszDllName); // copy DLL name

// Load DLL
pDllCur->hInst = LoadLibraryW(lpwszDllName);

if ( pDllCur->hInst == NULL )
{
hr = HR_LOG(E_FAIL);

goto cleanup;
}

// Save DLL entry information in the cache.
m_rgSDllCache[iDll] = pDllCur;

fLoaded = TRUE; // DLL is now loaded

break;

} // end if found space

// Otherwise, make sure that this DLL isn't already loaded.
else if ( lstrcmpiW(pDllCur->lpwszName, lpwszDllName) == 0 )
{
// Dll already here.
ASSERTERROR(pDllCur->hInst != NULL, "Bad pDllCur->hInst");

fLoaded = TRUE;

// We are done!
break;
}
} // end for

// handle case where can't load DLL
if ( fLoaded == FALSE )
{
hr = HR_LOG(E_FAIL);

goto cleanup;
}

cleanup:

RETURN(hr);

}

//$--CDllCache::HrFind------------------------------------------------
//
// DESCRIPTION: Finds instance handle of DLL in cache.
//
// INPUT: lpwszDllName -- DLL name
//
// OUTPUT: phInst -- pointer to DLL instance handle
//
// RETURNS: HRESULT -- NOERROR if successful,
// E_INVALIDARG if bad input
// E_FAIL otherwise.
//
// ----------------------------------------------------------------------------
HRESULT CDllCache::HrFind(
IN LPWSTR lpwszDllName, // DLL to find
OUT HINSTANCE * phInst) // pointer to DLL instance handle
{
HRESULT hr = NOERROR;
SDllCache * pDllCur = NULL; // current cached DLL pointer
UINT iDll = 0; // index into DLL cache
BOOL fFound = FALSE; // TRUE if DLL is currently cached

DEBUGPRIVATE("CDllCache::HrFind()\n");

// check input parameters
hr = CHK_CDllCache_HrFind(lpwszDllName, phInst);

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

// intialize output parameter
*phInst = NULL;

// See if this DLL is already loaded and determine the index
// of least used DLL in cache
for ( iDll = 0; iDll < nCachedDlls; iDll++ )
{
// get pointer to current DLL.
pDllCur = m_rgSDllCache[iDll];

// See if it is a valid pointer
if ( pDllCur == NULL )
{
// No more cached DLLs
break;
}

// See if this DLL is already loaded
if ( lstrcmpiW(lpwszDllName, pDllCur->lpwszName) == 0 )
{
// found DLL
fFound = TRUE;

// Succeeded.
// Set our output variable
*phInst = pDllCur->hInst;

// done
break;
}
} // end for each DLL in cache

// See if DLL was found
if ( fFound == FALSE )
{
hr = HR_LOG(E_FAIL);

goto cleanup;

} // end if DLL not loaded.

cleanup:

RETURN(hr);

}