mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
222 lines
5.2 KiB
222 lines
5.2 KiB
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992-1995 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and related
|
|
// electronic documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
|
|
#ifdef AFXCTL_CORE2_SEG
|
|
#pragma code_seg(AFXCTL_CORE2_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdTarget::EnableTypeLib - locks the typelib cache for this class
|
|
|
|
void CCmdTarget::EnableTypeLib()
|
|
{
|
|
AfxLockGlobals(CRIT_TYPELIBCACHE);
|
|
|
|
CTypeLibCache* pTypeLibCache = GetTypeLibCache();
|
|
ASSERT(pTypeLibCache != NULL); // must override GetTypeLibCache
|
|
|
|
if (pTypeLibCache != NULL)
|
|
pTypeLibCache->Lock(); // will be unlocked in OnFinalRelease
|
|
|
|
AfxUnlockGlobals(CRIT_TYPELIBCACHE);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CCmdTarget::GetTypeInfoOfGuid - Returns typeinfo
|
|
|
|
HRESULT CCmdTarget::GetTypeInfoOfGuid(LCID lcid, REFGUID guid,
|
|
LPTYPEINFO* ppTypeInfo)
|
|
{
|
|
USES_CONVERSION;
|
|
|
|
AfxLockGlobals(CRIT_TYPELIBCACHE);
|
|
|
|
HRESULT hr = TYPE_E_CANTLOADLIBRARY;
|
|
CTypeLibCache* pTypeLibCache = GetTypeLibCache();
|
|
LPTYPELIB pTypeLib = NULL;
|
|
|
|
// If type info is already cached, just return it.
|
|
if (pTypeLibCache->LookupTypeInfo(lcid, guid, ppTypeInfo))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
else
|
|
{
|
|
// If type library isn't already cached, try to locate it.
|
|
if (!pTypeLibCache->Lookup(lcid, &pTypeLib))
|
|
{
|
|
// First, try getting the subclass to load the type library
|
|
// (normally this goes through LoadRegTypeLib).
|
|
|
|
if (FAILED(GetTypeLib(lcid, &pTypeLib)))
|
|
{
|
|
AFX_MANAGE_STATE(m_pModuleState);
|
|
|
|
// If that failed, try loading the type library from our own
|
|
// resources.
|
|
|
|
TCHAR szPath[_MAX_PATH];
|
|
GetModuleFileName(AfxGetInstanceHandle(), szPath, _MAX_PATH);
|
|
|
|
if (FAILED(LoadTypeLib(T2COLE(szPath), &pTypeLib)))
|
|
pTypeLib = NULL;
|
|
}
|
|
|
|
pTypeLibCache->Cache(lcid, pTypeLib);
|
|
}
|
|
|
|
// If we got a type library, extract the requested type info.
|
|
if (pTypeLib != NULL)
|
|
{
|
|
hr = pTypeLib->GetTypeInfoOfGuid(guid, ppTypeInfo);
|
|
pTypeLib->Release();
|
|
pTypeLibCache->CacheTypeInfo(lcid, guid, *ppTypeInfo);
|
|
}
|
|
}
|
|
|
|
AfxUnlockGlobals(CRIT_TYPELIBCACHE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AfxGetTypeLibCache
|
|
|
|
CTypeLibCache* AFXAPI AfxGetTypeLibCache(const GUID* pTypeLibID)
|
|
{
|
|
AFX_MODULE_STATE* pModuleState = AfxGetModuleState();
|
|
ASSERT(pModuleState != NULL);
|
|
|
|
if (pModuleState->m_pTypeLibCacheMap == NULL)
|
|
{
|
|
const GUID* pCachedTypeLibID = pModuleState->m_typeLibCache.m_pTypeLibID;
|
|
|
|
if (pCachedTypeLibID == NULL)
|
|
{
|
|
// Cache not initialized yet; initialize it now
|
|
pModuleState->m_typeLibCache.m_pTypeLibID = pTypeLibID;
|
|
return &pModuleState->m_typeLibCache;
|
|
}
|
|
else if (pCachedTypeLibID == pTypeLibID)
|
|
{
|
|
// This is the cache we need; return it
|
|
return &pModuleState->m_typeLibCache;
|
|
}
|
|
else
|
|
{
|
|
// Another cache is needed; initialize the map
|
|
pModuleState->m_pTypeLibCacheMap = new CMapPtrToPtr;
|
|
pModuleState->m_pTypeLibCacheMap->SetAt(
|
|
(void*)(const void*)pModuleState->m_typeLibCache.m_pTypeLibID,
|
|
&pModuleState->m_typeLibCache);
|
|
|
|
// FALL THRU
|
|
}
|
|
}
|
|
|
|
ASSERT(pModuleState->m_pTypeLibCacheMap != NULL);
|
|
|
|
// Try to locate cache in the map
|
|
CTypeLibCache* pCache;
|
|
if (!pModuleState->m_pTypeLibCacheMap->Lookup((void*)(const void*)pTypeLibID,
|
|
(void*&)pCache))
|
|
{
|
|
// Create new cache and add it to the map
|
|
pCache = new CTypeLibCache;
|
|
pCache->m_pTypeLibID = pTypeLibID;
|
|
pModuleState->m_pTypeLibCacheMap->SetAt((void*)(const void*)pTypeLibID, pCache);
|
|
}
|
|
|
|
ASSERT(pCache != NULL);
|
|
ASSERT(pCache->m_pTypeLibID == pTypeLibID);
|
|
return pCache;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTypeLibCache
|
|
// (Note: CTypeLibCache::Unlock is implemented in afxstate.cpp)
|
|
|
|
void CTypeLibCache::Lock()
|
|
{
|
|
ASSERT(m_cRef >= 0);
|
|
|
|
if (m_cRef == 0)
|
|
m_lcid = (LCID)-1;
|
|
|
|
InterlockedIncrement(&m_cRef);
|
|
}
|
|
|
|
BOOL CTypeLibCache::Lookup(LCID lcid, LPTYPELIB* pptlib)
|
|
{
|
|
if ((m_lcid != -1) && (m_lcid == lcid))
|
|
{
|
|
ASSERT(m_ptlib != NULL);
|
|
*pptlib = m_ptlib;
|
|
m_ptlib->AddRef();
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
*pptlib = NULL;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
void CTypeLibCache::Cache(LCID lcid, LPTYPELIB ptlib)
|
|
{
|
|
if (ptlib != NULL)
|
|
{
|
|
m_lcid = lcid;
|
|
m_guidInfo = GUID_NULL;
|
|
RELEASE(m_ptinfo);
|
|
RELEASE(m_ptlib);
|
|
m_ptlib = ptlib;
|
|
m_ptlib->AddRef();
|
|
}
|
|
}
|
|
|
|
BOOL CTypeLibCache::LookupTypeInfo(LCID lcid, REFGUID guid,
|
|
LPTYPEINFO* pptinfo)
|
|
{
|
|
if ((m_lcid != -1) && (m_lcid == lcid) && (m_ptinfo != NULL) &&
|
|
IsEqualGUID(m_guidInfo, guid))
|
|
{
|
|
ASSERT(m_ptlib != NULL);
|
|
ASSERT(m_ptinfo != NULL);
|
|
*pptinfo = m_ptinfo;
|
|
m_ptinfo->AddRef();
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
*pptinfo = NULL;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
void CTypeLibCache::CacheTypeInfo(LCID lcid, REFGUID guid, LPTYPEINFO ptinfo)
|
|
{
|
|
if ((ptinfo != NULL) && (m_lcid == lcid))
|
|
{
|
|
m_guidInfo = guid;
|
|
RELEASE(m_ptinfo);
|
|
m_ptinfo = ptinfo;
|
|
m_ptinfo->AddRef();
|
|
}
|
|
}
|