summaryrefslogtreecommitdiff
path: root/src/md
diff options
context:
space:
mode:
Diffstat (limited to 'src/md')
-rw-r--r--src/md/compiler/classfactory.cpp8
-rw-r--r--src/md/compiler/disp.cpp36
-rw-r--r--src/md/compiler/mdperf.h1
-rw-r--r--src/md/compiler/mdsighelper.h6
-rw-r--r--src/md/compiler/mdutil.cpp4
-rw-r--r--src/md/compiler/mdutil.h4
-rw-r--r--src/md/compiler/mdvalidator.cpp152
-rw-r--r--src/md/compiler/newmerger.cpp6303
-rw-r--r--src/md/compiler/newmerger.h256
-rw-r--r--src/md/compiler/regmeta.cpp32
-rw-r--r--src/md/compiler/regmeta.h21
-rw-r--r--src/md/compiler/regmeta_compilersupport.cpp274
-rw-r--r--src/md/compiler/regmeta_emit.cpp75
-rw-r--r--src/md/compiler/regmeta_vm.cpp179
-rw-r--r--src/md/compiler/wks/CMakeLists.txt4
-rw-r--r--src/md/enc/imptlb.cpp8057
-rw-r--r--src/md/enc/liteweightstgdbrw.cpp28
-rw-r--r--src/md/enc/metamodelenc.cpp25
-rw-r--r--src/md/enc/metamodelrw.cpp25
-rw-r--r--src/md/enc/rwutil.cpp143
-rw-r--r--src/md/enc/stgio.cpp38
-rw-r--r--src/md/enc/stgtiggerstorage.cpp4
-rw-r--r--src/md/enc/wks/CMakeLists.txt2
-rw-r--r--src/md/hotdata/hotdataformat.h2
-rw-r--r--src/md/inc/assemblymdinternaldisp.h705
-rw-r--r--src/md/inc/imptlb.h777
-rw-r--r--src/md/inc/liteweightstgdb.h2
-rw-r--r--src/md/inc/metamodelrw.h4
-rw-r--r--src/md/inc/rwutil.h24
-rw-r--r--src/md/inc/stgio.h4
-rw-r--r--src/md/inc/winmdinterfaces.h8
-rw-r--r--src/md/md_wks.cmake2
-rw-r--r--src/md/runtime/mdfileformat.cpp2
-rw-r--r--src/md/runtime/mdinternaldisp.cpp1614
-rw-r--r--src/md/runtime/metamodel.cpp2
-rw-r--r--src/md/runtime/wks/CMakeLists.txt2
-rw-r--r--src/md/winmd/adapter.cpp2
-rw-r--r--src/md/winmd/inc/adapter.h6
-rw-r--r--src/md/winmd/wks/CMakeLists.txt4
39 files changed, 33 insertions, 18804 deletions
diff --git a/src/md/compiler/classfactory.cpp b/src/md/compiler/classfactory.cpp
index 603f7975aa..338095add3 100644
--- a/src/md/compiler/classfactory.cpp
+++ b/src/md/compiler/classfactory.cpp
@@ -42,14 +42,6 @@ const COCLASS_REGISTER g_CoClasses[] =
{
// pClsid szProgID pfnCreateObject
{ &CLSID_CorMetaDataDispenser, W("CorMetaDataDispenser"), Disp::CreateObject },
-#if !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE) // coreclr doesn't export these
- { &CLSID_CorMetaDataDispenserRuntime, W("CorMetaDataDispenserRuntime"), Disp::CreateObject },
-
- { &CLSID_CorRuntimeHost, W("CorRuntimeHost"), CorHost::CreateObject },
- { &CLSID_CLRRuntimeHost, W("CLRRuntimeHost"), CorHost2::CreateObject },
- { &__uuidof(CLRPrivRuntime), W("CLRPrivRuntime"), CorHost2::CreateObject },
- { &CLSID_TypeNameFactory, NULL, (PFN_CREATE_OBJ)TypeNameFactoryCreateObject },
-#endif // FEATURE_CORECLR && !CROSSGEN_COMPILE
{ NULL, NULL, NULL }
};
diff --git a/src/md/compiler/disp.cpp b/src/md/compiler/disp.cpp
index b091729744..85b71286d2 100644
--- a/src/md/compiler/disp.cpp
+++ b/src/md/compiler/disp.cpp
@@ -16,9 +16,6 @@
#include <corerror.h>
#include <mdlog.h>
#include <mdcommon.h>
-#ifdef FEATURE_COMINTEROP_TLB_SUPPORT
-#include <imptlb.h>
-#endif
#ifdef EnC_SUPPORTED
#define ENC_DELTA_HACK
@@ -95,11 +92,7 @@ Disp::DefineScope(
// Figure out what version of the metadata to emit
if (rclsid == CLSID_CLR_v1_MetaData)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- IfFailGo(E_NOTIMPL);
-#else
optionForNewScope.m_MetadataVersion = MDVersion1;
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
else if (rclsid == CLSID_CLR_v2_MetaData)
{
@@ -200,7 +193,7 @@ static HRESULT DeliverScope(IMDCommon *pMDCommon, REFIID riid, DWORD dwOpenFlags
HRESULT hr;
BEGIN_ENTRYPOINT_NOTHROW;
-#if !defined(FEATURE_METADATA_STANDALONE_WINRT) && defined(FEATURE_COMINTEROP)
+#if defined(FEATURE_COMINTEROP)
IfFailGo((dwOpenFlags & ofNoTransform) ? S_FALSE : CheckIfWinMDAdapterNeeded(pMDCommon));
if (hr == S_OK)
{
@@ -439,13 +432,6 @@ ErrExit:
return hr;
} // Disp::OpenScopeOnMemory
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
-
-#include <metahost.h>
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo * g_pCLRRuntime;
-
-#endif
//*****************************************************************************
// Get the directory where the CLR system resides.
@@ -458,27 +444,11 @@ Disp::GetCORSystemDirectory(
DWORD cchBuffer, // [in] Size of the buffer
DWORD *pcchBuffer) // [out] Number of characters returned
{
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR) && !defined(CROSSGEN_COMPILE)
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // This implies a machine-wide CLR install root, which may not exist for some CLR
- // skus using standalone metadata.
- *pcchBuffer = cchBuffer;
- hr = g_pCLRRuntime->GetRuntimeDirectory(szBuffer, pcchBuffer);
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-#else //!FEATURE_METADATA_IN_VM || FEATURE_CORECLR
-#ifdef FEATURE_CORECLR
UNREACHABLE_MSG("Calling IMetaDataDispenser::GetCORSystemDirectory! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
-#endif //FEATURE_CORECLR
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_IN_VM || FEATURE_CORECLR
} // Disp::GetCORSystemDirectory
HRESULT Disp::FindAssembly( // S_OK or error
@@ -912,7 +882,7 @@ ErrExit:
return hr;
} // Disp::GetOption
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
//---------------------------------------------------------------------------------------
//
@@ -924,7 +894,7 @@ void DeleteMetaData()
LOADEDMODULES::DeleteStatics();
}
-#endif //FEATURE_METADATA_IN_VM || FEATURE_METADATA_STANDALONE_WINRT
+#endif //FEATURE_METADATA_IN_VM
//
// This is the entrypoint for usages of MetaData that need to start with the dispenser (e.g.
diff --git a/src/md/compiler/mdperf.h b/src/md/compiler/mdperf.h
index 77def32d21..a83c8c9ba7 100644
--- a/src/md/compiler/mdperf.h
+++ b/src/md/compiler/mdperf.h
@@ -143,7 +143,6 @@
MD_FUNC(GetCustomAttributeProps)\
MD_FUNC(FindTypeRef)\
MD_FUNC(RefToDefOptimization)\
- MD_FUNC(ProcessFilter)\
MD_FUNC(DefineAssembly)\
MD_FUNC(DefineAssemblyRef)\
MD_FUNC(DefineFile)\
diff --git a/src/md/compiler/mdsighelper.h b/src/md/compiler/mdsighelper.h
index 0d089729bb..49c0752fe3 100644
--- a/src/md/compiler/mdsighelper.h
+++ b/src/md/compiler/mdsighelper.h
@@ -104,13 +104,7 @@ class UnifiedAssemblySigComparer : public MDSigComparer::MDSigComparerBaseType
protected:
RegMeta *m_pRegMeta;
-#ifdef FEATURE_FUSION
- HRESULT _CreateIAssemblyNameFromAssemblyRef(
- mdToken tkAsmRef,
- IAssemblyName **ppAsmName);
-#else
HRESULT _CompareAssemblies(mdToken tkAsmRef1,mdToken tkAsmRef2, BOOL* pfEquivalent);
-#endif
HRESULT _CreateTypeNameFromTypeRef(
mdToken tkTypeRef,
diff --git a/src/md/compiler/mdutil.cpp b/src/md/compiler/mdutil.cpp
index 2e01258bea..0de5ad45ea 100644
--- a/src/md/compiler/mdutil.cpp
+++ b/src/md/compiler/mdutil.cpp
@@ -20,7 +20,7 @@
#include <rwutil.h>
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
LOADEDMODULES * LOADEDMODULES::s_pLoadedModules = NULL;
UTSemReadWrite * LOADEDMODULES::m_pSemReadWrite = NULL;
@@ -363,7 +363,7 @@ ErrExit:
#endif //_DEBUG
-#endif //FEATURE_METADATA_IN_VM || FEATURE_METADATA_STANDALONE_WINRT
+#endif //FEATURE_METADATA_IN_VM
#ifdef FEATURE_METADATA_IN_VM
diff --git a/src/md/compiler/mdutil.h b/src/md/compiler/mdutil.h
index 58cdbf108a..331817ec9a 100644
--- a/src/md/compiler/mdutil.h
+++ b/src/md/compiler/mdutil.h
@@ -61,7 +61,7 @@ public:
}; // class CORPATHService
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
class RegMeta;
@@ -114,6 +114,6 @@ public:
#endif
}; // class LOADEDMODULES
-#endif //FEATURE_METADATA_IN_VM || FEATURE_METADATA_STANDALONE_WINRT
+#endif //FEATURE_METADATA_IN_VM
#endif // __MDUtil__h__
diff --git a/src/md/compiler/mdvalidator.cpp b/src/md/compiler/mdvalidator.cpp
index adcfd51eb3..ce6c14e468 100644
--- a/src/md/compiler/mdvalidator.cpp
+++ b/src/md/compiler/mdvalidator.cpp
@@ -19,9 +19,6 @@
#include "pedecoder.h"
#include "stgio.h"
#include "corhost.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "sstring.h"
#include "nsutilpriv.h"
#include "holder.h"
@@ -5210,7 +5207,7 @@ HRESULT RegMeta::ValidateAssembly(RID rid)
dwFlags = (CorAssemblyFlags) pMiniMd->getFlagsOfAssembly(pRecord);
// Validate the flags
- invalidAssemblyFlags = dwFlags & (~(afPublicKey | afRetargetable | afPA_FullMask | afEnableJITcompileTracking | afDisableJITcompileOptimizer | afContentType_Mask));
+ invalidAssemblyFlags = dwFlags & (~(afPublicKey | afRetargetable | afPA_FullMask | afDebuggableAttributeMask | afContentType_Mask));
// Validate we only set a legal processor architecture flags
// The processor architecture flags were introduced in CLR v2.0.
@@ -7185,123 +7182,7 @@ MDSigComparer::_CompareMethodSignatureHeader(
//*****************************************************************************
//*****************************************************************************
-#ifdef FEATURE_FUSION
-HRESULT
-UnifiedAssemblySigComparer::_CreateIAssemblyNameFromAssemblyRef(
- mdToken tkAsmRef,
- IAssemblyName **ppAsmName)
-{
- HRESULT hr;
-
- void const * pvPublicKey;
- ULONG cbPublicKey;
- ULONG cchName;
- ASSEMBLYMETADATA amd;
- void const * pvHashValue;
- ULONG cbHashValue;
- DWORD dwFlags;
-
- ZeroMemory(&amd, sizeof(amd));
-
- IfFailRet(m_pRegMeta->GetAssemblyRefProps(tkAsmRef,
- NULL,
- NULL,
- NULL,
- 0,
- &cchName,
- &amd,
- NULL,
- NULL,
- NULL));
-
- StackSString ssName;
- StackSString ssLocale;
- amd.szLocale = ssLocale.OpenUnicodeBuffer(amd.cbLocale);
-
- IfFailRet(m_pRegMeta->GetAssemblyRefProps(tkAsmRef,
- &pvPublicKey,
- &cbPublicKey,
- ssName.OpenUnicodeBuffer(cchName),
- cchName,
- &cchName,
- &amd,
- &pvHashValue,
- &cbHashValue,
- &dwFlags));
-
- ssName.CloseBuffer();
- ssLocale.CloseBuffer();
-
- IAssemblyName *pAsmName = NULL;
-
- IfFailRet(CreateAssemblyNameObject(&pAsmName,
- ssName.GetUnicode(),
- CANOF_SET_DEFAULT_VALUES,
- NULL));
-
- // Set the public key token
- IfFailRet(pAsmName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN,
- (LPVOID)pvPublicKey,
- cbPublicKey));
- // Set the culture
- if (amd.cbLocale == 0 || amd.szLocale == NULL)
- {
- IfFailRet(pAsmName->SetProperty(ASM_NAME_CULTURE,
- W("Neutral"),
- sizeof(W("Neutral"))));
- }
- else
- {
- IfFailRet(pAsmName->SetProperty(ASM_NAME_CULTURE,
- amd.szLocale,
- amd.cbLocale));
- }
-
- // Set the major version
- IfFailRet(pAsmName->SetProperty(ASM_NAME_MAJOR_VERSION,
- &amd.usMajorVersion,
- sizeof(amd.usMajorVersion)));
-
- // Set the minor version
- IfFailRet(pAsmName->SetProperty(ASM_NAME_MINOR_VERSION,
- &amd.usMinorVersion,
- sizeof(amd.usMinorVersion)));
-
- // Set the build number
- IfFailRet(pAsmName->SetProperty(ASM_NAME_BUILD_NUMBER,
- &amd.usBuildNumber,
- sizeof(amd.usBuildNumber)));
-
- // Set the revision number
- IfFailRet(pAsmName->SetProperty(ASM_NAME_REVISION_NUMBER,
- &amd.usRevisionNumber,
- sizeof(amd.usRevisionNumber)));
-
- *ppAsmName = pAsmName;
-
- return S_OK;
-}
-
-//*****************************************************************************
-// Define holder to release IAssemblyName on exception.
-//*****************************************************************************
-void UnifiedAssemblySigComparer_IAssemblyNameRelease(IAssemblyName *value)
-{
- if (value != NULL)
- {
- value->Release();
- }
-}
-
-typedef Holder<IAssemblyName*,
- DoNothing<IAssemblyName*>,
- &UnifiedAssemblySigComparer_IAssemblyNameRelease,
- NULL> UnifiedAssemblySigComparer_IAssemblyNameHolder;
-
-#endif // FEATURE_FUSION
-
-#ifndef FEATURE_FUSION
HRESULT UnifiedAssemblySigComparer::_CompareAssemblies(mdToken tkAsmRef1,mdToken tkAsmRef2, BOOL* pfEquivalent)
{
@@ -7417,7 +7298,6 @@ HRESULT UnifiedAssemblySigComparer::_CompareAssemblies(mdToken tkAsmRef1,mdToken
return S_OK;
};
-#endif // FEATURE_FUSION
//*****************************************************************************
//*****************************************************************************
@@ -7523,38 +7403,8 @@ UnifiedAssemblySigComparer::CompareToken(
}
BOOL fEquivalent;
-#ifdef FEATURE_FUSION //move into _CompareAssemblies
- IAssemblyName *pAsmName1 = NULL;
- IfFailRet(_CreateIAssemblyNameFromAssemblyRef(tkParent1, &pAsmName1));
- UnifiedAssemblySigComparer_IAssemblyNameHolder anh1(pAsmName1);
-
- IAssemblyName *pAsmName2 = NULL;
- IfFailRet(_CreateIAssemblyNameFromAssemblyRef(tkParent2, &pAsmName2));
- UnifiedAssemblySigComparer_IAssemblyNameHolder anh2(pAsmName2);
-
- DWORD cchDisplayName = 0;
-
- StackSString ssDisplayName1;
- pAsmName1->GetDisplayName(NULL, &cchDisplayName, NULL);
- IfFailRet(pAsmName1->GetDisplayName(ssDisplayName1.OpenUnicodeBuffer(cchDisplayName), &cchDisplayName, NULL));
- ssDisplayName1.CloseBuffer();
-
- StackSString ssDisplayName2;
- pAsmName2->GetDisplayName(NULL, &cchDisplayName, NULL);
- IfFailRet(pAsmName2->GetDisplayName(ssDisplayName2.OpenUnicodeBuffer(cchDisplayName), &cchDisplayName, NULL));
- ssDisplayName2.CloseBuffer();
-
- AssemblyComparisonResult res;
- IfFailRet(CompareAssemblyIdentity(ssDisplayName1.GetUnicode(),
- TRUE,
- ssDisplayName2.GetUnicode(),
- TRUE,
- &fEquivalent,
- &res));
-#else
// no redirects supported
IfFailRet(_CompareAssemblies(tkParent1,tkParent2,&fEquivalent));
-#endif
if (!fEquivalent)
{
diff --git a/src/md/compiler/newmerger.cpp b/src/md/compiler/newmerger.cpp
deleted file mode 100644
index d5199bb570..0000000000
--- a/src/md/compiler/newmerger.cpp
+++ /dev/null
@@ -1,6303 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//*****************************************************************************
-// NewMerger.cpp
-//
-
-//
-// contains utility code to MD directory
-//
-// This file provides Compiler Support functionality in metadata.
-//*****************************************************************************
-#include "stdafx.h"
-
-#include "newmerger.h"
-#include "regmeta.h"
-
-
-#include "importhelper.h"
-#include "rwutil.h"
-#include "mdlog.h"
-#include <posterror.h>
-#include <sstring.h>
-#include "ndpversion.h"
-
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-#define MODULEDEFTOKEN TokenFromRid(1, mdtModule)
-
-#define COR_MSCORLIB_NAME "mscorlib"
-#define COR_MSCORLIB_TYPEREF {0xb7, 0x7a, 0x5c, 0x56,0x19,0x34,0xe0,0x89}
-
-#define COR_CONSTRUCTOR_METADATA_IDENTIFIER W(".ctor")
-
-#define COR_COMPILERSERVICE_NAMESPACE "System.Runtime.CompilerServices"
-#define COR_EXCEPTIONSERVICE_NAMESPACE "System.Runtime.ExceptionServices"
-#define COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE "SuppressMergeCheckAttribute"
-#define COR_HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE "HandleProcessCorruptedStateExceptionsAttribute"
-#define COR_MISCBITS_NAMESPACE "Microsoft.VisualC"
-#define COR_MISCBITS_ATTRIBUTE "Microsoft.VisualC.MiscellaneousBitsAttribute"
-#define COR_NATIVECPPCLASS_ATTRIBUTE "System.Runtime.CompilerServices.NativeCppClassAttribute"
-
-// MODULE_CA_LOCATION W("System.Runtime.CompilerServices.AssemblyAttributesGoHere")
-#define MODULE_CA_TYPENAME "AssemblyAttributesGoHere" // fake assembly type-ref for hanging Assembly-level CAs off of
-
-//*****************************************************************************
-// BEGIN: Security Critical Attributes and Enumeration
-//*****************************************************************************
-#define COR_SECURITYCRITICALSCOPE_ENUM_W W("System.Security.SecurityCriticalScope")
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_FULL "System.Security.SecurityCriticalAttribute"
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL "System.Security.SecurityTransparentAttribute"
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL "System.Security.SecurityTreatAsSafeAttribute"
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W W("System.Security.SecurityCriticalAttribute")
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL_W W("System.Security.SecurityTransparentAttribute")
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W W("System.Security.SecurityTreatAsSafeAttribute")
-#define COR_SECURITYSAFECRITICAL_ATTRIBUTE_FULL_W W("System.Security.SecuritySafeCriticalAttribute")
-
- // definitions of enumeration for System.Security.SecurityCriticalScope (Explicit or Everything)
-#define COR_SECURITYCRITICAL_CTOR_ARGCOUNT_NO_SCOPE 0
-#define COR_SECURITYCRITICAL_CTOR_ARGCOUNT_SCOPE_EVERYTHING 1
-#define COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE (3)
-#define COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE (5 + sizeof(mdTypeRef) * 1)
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_NAMESPACE "System.Security"
-#define COR_SECURITYCRITICAL_ATTRIBUTE "SecurityCriticalAttribute"
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE_NAMESPACE "System.Security"
-#define COR_SECURITYTRANSPARENT_ATTRIBUTE "SecurityTransparentAttribute"
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_NAMESPACE "System.Security"
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE "SecurityTreatAsSafeAttribute"
-#define COR_SECURITYSAFECRITICAL_ATTRIBUTE "SecuritySafeCriticalAttribute"
-
-
-#define COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING { 0x01, 0x00 ,0x01, 0x00, 0x00, 0x00 ,0x00, 0x00 }
-#define COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EXPLICIT {0x01, 0x00, 0x00 ,0x00}
-#define COR_SECURITYTREATASSAFE_ATTRIBUTE_VALUE {0x01, 0x00, 0x00 ,0x00}
-
-
- // if true, then registry has been read for enabling or disabling SecurityCritical support
-static BOOL g_fRefShouldMergeCriticalChecked = FALSE;
-
-// by default, security critical attributes will be merged (e.g. unmarked CRT marked Critical/TAS)
-// - unless registry config explicitly disables merging
-static BOOL g_fRefShouldMergeCritical = TRUE;
-//*****************************************************************************
-// END: Security Critical Attributes and Enumeration
-//*****************************************************************************
-
-//*****************************************************************************
-// Checks to see if the given type is managed or native. We'll key off of the
-// Custom Attribute "Microsoft.VisualC.MiscellaneousBitsAttribute". If the third
-// byte has the 01000000 bit set then it is an unmanaged type.
-// If we can't find the attribute, we will also check for the presence of the
-// "System.Runtime.CompilerServices.NativeCppClassAttribute" Custom Attribute
-// since the CPP compiler stopped emitting MiscellaneousBitsAttribute in Dev11.
-//*****************************************************************************
-HRESULT IsManagedType(CMiniMdRW* pMiniMd,
- mdTypeDef td,
- BOOL *fIsManagedType)
-{
- // First look for the custom attribute
- HENUMInternal hEnum;
- HRESULT hr = S_OK;
-
- IfFailRet(pMiniMd->CommonEnumCustomAttributeByName(td, COR_MISCBITS_ATTRIBUTE, false, &hEnum));
-
- // If there aren't any custom attributes here, then this must be a managed type
- if (hEnum.m_ulCount > 0)
- {
- // Let's loop through these, and see if any of them have that magical bit set.
- mdCustomAttribute ca;
- CustomAttributeRec *pRec;
- ULONG cbData = 0;
-
- while(HENUMInternal::EnumNext(&hEnum, &ca))
- {
- const BYTE* pData = NULL;
-
- IfFailGo(pMiniMd->GetCustomAttributeRecord(RidFromToken(ca), &pRec));
- IfFailGo(pMiniMd->getValueOfCustomAttribute(pRec, &pData, &cbData));
-
- if (pData != NULL && cbData >=3)
- {
- // See if the magical bit is set to make this an unmanaged type
- if ((*(pData+2)&0x40) > 0)
- {
- // Yes, this is an unmanaged type
- HENUMInternal::ClearEnum(&hEnum);
- *fIsManagedType = FALSE;
- return S_OK;
- }
- }
- }
-
- }
-
- HENUMInternal::ClearEnum(&hEnum);
-
- // If this was emitted by a Dev11+ CPP compiler, we only have NativeCppClassAttribute
- // so let's check for that before calling this a managed class.
- IfFailRet(pMiniMd->CommonEnumCustomAttributeByName(td, COR_NATIVECPPCLASS_ATTRIBUTE, false, &hEnum));
- if (hEnum.m_ulCount > 0)
- {
- // Yes, this is an unmanaged type
- HENUMInternal::ClearEnum(&hEnum);
- *fIsManagedType = FALSE;
- return S_OK;
- }
-
- // Nope, this isn't an unmanaged type.... must be managed
- HENUMInternal::ClearEnum(&hEnum);
- *fIsManagedType = TRUE;
- hr = S_OK;
-ErrExit:
- return hr;
-}// IsManagedType
-
-
-//*****************************************************************************
-// "Is CustomAttribute from certain namespace and assembly" check helper
-// Returns S_OK and fills **ppTypeRefRec.
-// Returns error code or S_FALSE otherwise as not found and fills **ppTypeRefRec with NULL.
-//*****************************************************************************
-HRESULT IsAttributeFromNamespace(
- CMiniMdRW *pMiniMd,
- mdToken tk,
- LPCSTR szNamespace,
- LPCSTR szAssembly,
- TypeRefRec **ppTypeRefRec)
-{
- HRESULT hr = S_OK;
- if(TypeFromToken(tk) == mdtMemberRef)
- {
- MemberRefRec *pMemRefRec;
- IfFailGo(pMiniMd->GetMemberRefRecord(RidFromToken(tk), &pMemRefRec));
- tk = pMiniMd->getClassOfMemberRef(pMemRefRec);
- }
- if(TypeFromToken(tk) == mdtTypeRef)
- {
- TypeRefRec *pTypeRefRec;
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(tk), &pTypeRefRec));
- LPCSTR szTypeRefNamespace;
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pTypeRefRec, &szTypeRefNamespace));
- if (strcmp(szTypeRefNamespace, szNamespace) == 0)
- {
- mdToken tkResTmp = pMiniMd->getResolutionScopeOfTypeRef(pTypeRefRec);
- if (TypeFromToken(tkResTmp) == mdtAssemblyRef)
- {
- AssemblyRefRec *pAsmRefRec;
- IfFailGo(pMiniMd->GetAssemblyRefRecord(RidFromToken(tkResTmp), &pAsmRefRec));
- LPCSTR szAssemblyRefName;
- IfFailGo(pMiniMd->getNameOfAssemblyRef(pAsmRefRec, &szAssemblyRefName));
- if(SString::_stricmp(szAssemblyRefName, szAssembly) == 0)
- {
- *ppTypeRefRec = pTypeRefRec;
- return S_OK;
- }
- }
- }
- }
- // Record not found
- hr = S_FALSE;
-ErrExit:
- *ppTypeRefRec = NULL;
- return hr;
-}
-
-//*****************************************************************************
-// constructor
-//*****************************************************************************
-NEWMERGER::NEWMERGER()
- : m_pRegMetaEmit(0),
- m_pImportDataList(NULL),
- m_optimizeRefToDef(MDRefToDefDefault),
- m_isscsSecurityCritical(ISSCS_Unknown),
- m_isscsSecurityCriticalAllScopes(~ISSCS_Unknown)
-{
- m_pImportDataTail = &(m_pImportDataList);
-#if _DEBUG
- m_iImport = 0;
-#endif // _DEBUG
-} // NEWMERGER::NEWMERGER()
-
-//*****************************************************************************
-// initializer
-//*****************************************************************************
-HRESULT NEWMERGER::Init(RegMeta *pRegMeta)
-{
- HRESULT hr = NOERROR;
- MergeTypeData * pMTD;
-
- m_pRegMetaEmit = pRegMeta;
-
- // burn an entry so that the RID matches the array index
- IfNullGo(pMTD = m_rMTDs.Append());
-
- pMTD->m_bSuppressMergeCheck = false;
- pMTD->m_cMethods = 0;
- pMTD->m_cFields = 0;
- pMTD->m_cEvents = 0;
- pMTD->m_cProperties = 0;
-
-ErrExit:
- return hr;
-} // NEWMERGER::Init
-
-//*****************************************************************************
-// destructor
-//*****************************************************************************
-NEWMERGER::~NEWMERGER()
-{
- if (m_pImportDataList)
- {
- // delete this list and release all AddRef'ed interfaces!
- MergeImportData *pNext;
- for (pNext = m_pImportDataList; pNext != NULL; )
- {
- pNext = m_pImportDataList->m_pNextImportData;
- if (m_pImportDataList->m_pHandler)
- m_pImportDataList->m_pHandler->Release();
- if (m_pImportDataList->m_pHostMapToken)
- m_pImportDataList->m_pHostMapToken->Release();
- if (m_pImportDataList->m_pMDTokenMap)
- delete m_pImportDataList->m_pMDTokenMap;
- m_pImportDataList->m_pRegMetaImport->Release();
- delete m_pImportDataList;
- m_pImportDataList = pNext;
- }
- }
-} // NEWMERGER::~NEWMERGER
-
-//*****************************************************************************
-CMiniMdRW *NEWMERGER::GetMiniMdEmit()
-{
- return &(m_pRegMetaEmit->m_pStgdb->m_MiniMd);
-} // CMiniMdRW *NEWMERGER::GetMiniMdEmit()
-
-//*****************************************************************************
-// Adding a new import
-//*****************************************************************************
-HRESULT NEWMERGER::AddImport(
- IMetaDataImport2 *pImport, // [IN] The scope to be merged.
- IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification
- IUnknown *pHandler) // [IN] An object to receive error notification.
-{
- HRESULT hr = NOERROR;
- MergeImportData *pData;
-
- RegMeta *pRM = static_cast<RegMeta*>(pImport);
-
- // Add a MergeImportData to track the information for this import scope
- pData = new (nothrow) MergeImportData;
- IfNullGo( pData );
- pData->m_pRegMetaImport = pRM;
- pData->m_pRegMetaImport->AddRef();
- pData->m_pHostMapToken = pHostMapToken;
- if (pData->m_pHostMapToken)
- pData->m_pHostMapToken->AddRef();
- if (pHandler)
- {
- pData->m_pHandler = pHandler;
- pData->m_pHandler->AddRef();
- }
- else
- {
- pData->m_pHandler = NULL;
- }
-
- pData->m_pMDTokenMap = NULL;
- pData->m_pNextImportData = NULL;
-#if _DEBUG
- pData->m_iImport = ++m_iImport;
-#endif // _DEBUG
-
- pData->m_tkHandleProcessCorruptedStateCtor = mdTokenNil;
- // add the newly create node to the tail of the list
- *m_pImportDataTail = pData;
- m_pImportDataTail = &(pData->m_pNextImportData);
-
-ErrExit:
-
- return hr;
-} // HRESULT NEWMERGER::AddImport()
-
-HRESULT NEWMERGER::InitMergeTypeData()
-{
- CMiniMdRW *pMiniMdEmit;
- ULONG cTypeDefRecs;
- ULONG i, j;
- bool bSuppressMergeCheck;
-
- ULONG ridStart, ridEnd;
- RID ridMap;
-
- mdToken tkSuppressMergeCheckCtor = mdTokenNil;
- mdToken tkCA;
- mdMethodDef mdEmit;
- mdFieldDef fdEmit;
- mdEvent evEmit;
- mdProperty prEmit;
-
- TypeDefRec *pTypeDefRec;
- EventMapRec *pEventMapRec;
- PropertyMapRec *pPropertyMapRec;
-
- MergeTypeData *pMTD;
-
- HRESULT hr = NOERROR;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- // cache the SuppressMergeCheckAttribute.ctor token
- ImportHelper::FindCustomAttributeCtorByName(
- pMiniMdEmit, COR_MSCORLIB_NAME,
- COR_COMPILERSERVICE_NAMESPACE, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE,
- &tkSuppressMergeCheckCtor);
-
- cTypeDefRecs = pMiniMdEmit->getCountTypeDefs();
- _ASSERTE(m_rMTDs.Count() > 0);
-
- for (i = m_rMTDs.Count(); i <= cTypeDefRecs; i++)
- {
- IfNullGo(pMTD = m_rMTDs.Append());
-
- pMTD->m_cMethods = 0;
- pMTD->m_cFields = 0;
- pMTD->m_cEvents = 0;
- pMTD->m_cProperties = 0;
- pMTD->m_bSuppressMergeCheck = (tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- TokenFromRid(i, mdtTypeDef), tkSuppressMergeCheckCtor,
- NULL, 0, &tkCA));
-
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(i, &pTypeDefRec));
-
- // Count the number methods
- ridStart = pMiniMdEmit->getMethodListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdEmit->getEndMethodListOfTypeDef(i, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetMethodRid(j, (ULONG *)&mdEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- mdEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cMethods++;
- }
- }
-
- // Count the number fields
- ridStart = pMiniMdEmit->getFieldListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdEmit->getEndFieldListOfTypeDef(i, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetFieldRid(j, (ULONG *)&fdEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- fdEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cFields++;
- }
- }
-
- // Count the number of events
- IfFailGo(pMiniMdEmit->FindEventMapFor(i, &ridMap));
- if (!InvalidRid(ridMap))
- {
- IfFailGo(pMiniMdEmit->GetEventMapRecord(ridMap, &pEventMapRec));
- ridStart = pMiniMdEmit->getEventListOfEventMap(pEventMapRec);
- IfFailGo(pMiniMdEmit->getEndEventListOfEventMap(ridMap, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetEventRid(j, (ULONG *)&evEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- evEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cEvents++;
- }
- }
- }
-
- // Count the number of properties
- IfFailGo(pMiniMdEmit->FindPropertyMapFor(i, &ridMap));
- if (!InvalidRid(ridMap))
- {
- IfFailGo(pMiniMdEmit->GetPropertyMapRecord(ridMap, &pPropertyMapRec));
- ridStart = pMiniMdEmit->getPropertyListOfPropertyMap(pPropertyMapRec);
- IfFailGo(pMiniMdEmit->getEndPropertyListOfPropertyMap(ridMap, &ridEnd));
-
- for (j = ridStart; j < ridEnd; j++)
- {
- IfFailGo(pMiniMdEmit->GetPropertyRid(j, (ULONG *)&prEmit));
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdEmit,
- prEmit, tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck)
- {
- pMTD->m_cProperties++;
- }
- }
- }
- }
-
-ErrExit:
- return hr;
-}
-
-//*****************************************************************************
-// Merge now
-//*****************************************************************************
-HRESULT NEWMERGER::Merge(MergeFlags dwMergeFlags, CorRefToDefCheck optimizeRefToDef)
-{
- MergeImportData *pImportData = m_pImportDataList;
- MDTOKENMAP **pPrevMap = NULL;
- MDTOKENMAP *pMDTokenMap;
- HRESULT hr = NOERROR;
- MDTOKENMAP *pCurTKMap;
- int i;
-
-#if _DEBUG
- {
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- LOG((LOGMD, "Merge scope list\n"));
- i = 0;
- for (MergeImportData *pID = m_pImportDataList; pID != NULL; pID = pID->m_pNextImportData)
- {
- WCHAR szScope[1024], szGuid[40];
- GUID mvid;
- ULONG cchScope;
- pID->m_pRegMetaImport->GetScopeProps(szScope, 1024, &cchScope, &mvid);
- szScope[1023] = 0;
- GuidToLPWSTR(mvid, szGuid, 40);
- ++i; // Counter is 1-based.
- LOG((LOGMD, "%3d: %ls : %ls\n", i, szGuid, szScope));
- }
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- }
-#endif // _DEBUG
-
- m_dwMergeFlags = dwMergeFlags;
- m_optimizeRefToDef = optimizeRefToDef;
-
- // check to see if we need to do dup check
- m_fDupCheck = ((m_dwMergeFlags & NoDupCheck) != NoDupCheck);
-
- while (pImportData)
- {
- // Verify that we have a filter for each import scope.
- IfNullGo( pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd.GetFilterTable() );
-
- // cache the SuppressMergeCheckAttribute.ctor token for each import scope
- ImportHelper::FindCustomAttributeCtorByName(
- &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd, COR_MSCORLIB_NAME,
- COR_COMPILERSERVICE_NAMESPACE, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE,
- &pImportData->m_tkSuppressMergeCheckCtor);
-
- // cache the HandleProcessCorruptedStateExceptionsAttribute.ctor token for each import scope
- ImportHelper::FindCustomAttributeCtorByName(
- &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd, COR_MSCORLIB_NAME,
- COR_EXCEPTIONSERVICE_NAMESPACE, COR_HANDLE_PROCESS_CORRUPTED_STATE_EXCEPTION_ATTRIBUTE,
- &pImportData->m_tkHandleProcessCorruptedStateCtor);
-
- // check for security critical attribute in the assembly (i.e. explicit annotations)
- InputScopeSecurityCriticalStatus isscsTemp = CheckInputScopeIsCritical(pImportData, hr);
- IfFailGo(hr);
- // clear the unset flag bits (e.g. if critical, clear transparent bit)
- // whatever bits remain are bits that have been set in all scopes
- if (ISSCS_Unknown == (isscsTemp & ISSCS_SECURITYCRITICAL_FLAGS))
- m_isscsSecurityCriticalAllScopes &= ISSCS_SECURITYCRITICAL_LEGACY;
- else
- m_isscsSecurityCriticalAllScopes &= isscsTemp;
- // set the flag bits (essentially, this allows us to see if _any_ scopes requested a bit)
- m_isscsSecurityCritical |= isscsTemp;
-
- // create the tokenmap class to track metadata token remap for each import scope
- pMDTokenMap = new (nothrow) MDTOKENMAP;
- IfNullGo(pMDTokenMap);
- IfFailGo(pMDTokenMap->Init((IMetaDataImport2*)pImportData->m_pRegMetaImport));
- pImportData->m_pMDTokenMap = pMDTokenMap;
- pImportData->m_pMDTokenMap->m_pMap = pImportData->m_pHostMapToken;
- if (pImportData->m_pHostMapToken)
- pImportData->m_pHostMapToken->AddRef();
- pImportData->m_pMDTokenMap->m_pNextMap = NULL;
- if (pPrevMap)
- *pPrevMap = pImportData->m_pMDTokenMap;
- pPrevMap = &(pImportData->m_pMDTokenMap->m_pNextMap);
- pImportData = pImportData->m_pNextImportData;
- }
-
- // Populate the m_rMTDs with the type info already defined in the emit scope
- IfFailGo( InitMergeTypeData() );
-
- // 1. Merge Module
- IfFailGo( MergeModule( ) );
-
- // 2. Merge TypeDef partially (i.e. only name)
- IfFailGo( MergeTypeDefNamesOnly() );
-
- // 3. Merge ModuleRef property and do ModuleRef to ModuleDef optimization
- IfFailGo( MergeModuleRefs() );
-
- // 4. Merge AssemblyRef.
- IfFailGo( MergeAssemblyRefs() );
-
- // 5. Merge TypeRef with TypeRef to TypeDef optimization
- IfFailGo( MergeTypeRefs() );
-
- // 6. Merge TypeSpec & MethodSpec
- IfFailGo( MergeTypeSpecs() );
-
- // 7. Now Merge the remaining of TypeDef records
- IfFailGo( CompleteMergeTypeDefs() );
-
- // 8. Merge Methods and Fields. Such that Signature translation is respecting the TypeRef to TypeDef optimization.
- IfFailGo( MergeTypeDefChildren() );
-
- // 9. Merge MemberRef with MemberRef to MethodDef/FieldDef optimization
- IfFailGo( MergeMemberRefs( ) );
-
- // 10. Merge InterfaceImpl
- IfFailGo( MergeInterfaceImpls( ) );
-
- // merge all of the remaining in metadata ....
-
- // 11. constant has dependency on property, field, param
- IfFailGo( MergeConstants() );
-
- // 12. field marshal has dependency on param and field
- IfFailGo( MergeFieldMarshals() );
-
- // 13. in ClassLayout, move over the FieldLayout and deal with FieldLayout as well
- IfFailGo( MergeClassLayouts() );
-
- // 14. FieldLayout has dependency on FieldDef.
- IfFailGo( MergeFieldLayouts() );
-
- // 15. FieldRVA has dependency on FieldDef.
- IfFailGo( MergeFieldRVAs() );
-
- // 16. MethodImpl has dependency on MemberRef, MethodDef, TypeRef and TypeDef.
- IfFailGo( MergeMethodImpls() );
-
- // 17. pinvoke depends on MethodDef and ModuleRef
- IfFailGo( MergePinvoke() );
-
- IfFailGo( MergeStandAloneSigs() );
-
- IfFailGo( MergeMethodSpecs() );
-
- IfFailGo( MergeStrings() );
-
- if (m_dwMergeFlags & MergeManifest)
- {
- // keep the manifest!!
- IfFailGo( MergeAssembly() );
- IfFailGo( MergeFiles() );
- IfFailGo( MergeExportedTypes() );
- IfFailGo( MergeManifestResources() );
- }
- else if (m_dwMergeFlags & ::MergeExportedTypes)
- {
- IfFailGo( MergeFiles() );
- IfFailGo( MergeExportedTypes() );
- }
-
- IfFailGo( MergeCustomAttributes() );
- IfFailGo( MergeDeclSecuritys() );
-
-
- // Please don't add any MergeXxx() below here. CustomAttributess must be
- // very late, because custom values are various other types.
-
- // Fixup list cannot be merged. Linker will need to re-emit them.
-
- // Now call back to host for the result of token remap
- //
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // Send token remap information for each import scope
- pCurTKMap = pImportData->m_pMDTokenMap;
- TOKENREC *pRec;
- if (pImportData->m_pHostMapToken)
- {
- for (i = 0; i < pCurTKMap->Count(); i++)
- {
- pRec = pCurTKMap->Get(i);
- if (!pRec->IsEmpty())
- pImportData->m_pHostMapToken->Map(pRec->m_tkFrom, pRec->m_tkTo);
- }
- }
- }
-
- // And last, but not least, let's do Security critical module-level attribute consolidation
- // and metadata fixups.
- IfFailGo( MergeSecurityCriticalAttributes() );
-
-
-
-
-
-#if _DEBUG
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // dump the mapping
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- LOG((LOGMD, "Dumping token remap for one import scope!\n"));
- LOG((LOGMD, "This is the %d import scope for merge!\n", pImportData->m_iImport));
-
- pCurTKMap = pImportData->m_pMDTokenMap;
- TOKENREC *pRec;
- for (i = 0; i < pCurTKMap->Count(); i++)
- {
- pRec = pCurTKMap->Get(i);
- if (!pRec->IsEmpty())
- {
- LOG((LOGMD, " Token 0x%08x ====>>>> Token 0x%08x\n", pRec->m_tkFrom, pRec->m_tkTo));
- }
- }
- LOG((LOGMD, "End dumping token remap!\n"));
- LOG((LOGMD, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
- }
-#endif // _DEBUG
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::Merge()
-
-
-//*****************************************************************************
-// Merge ModuleDef
-//*****************************************************************************
-HRESULT NEWMERGER::MergeModule()
-{
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
- HRESULT hr = NOERROR;
- TOKENREC *pTokenRec;
-
- // we don't really merge Module information but we create a one to one mapping for each module token into the TokenMap
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- // set the current MDTokenMap
-
- pCurTkMap = pImportData->m_pMDTokenMap;
- IfFailGo( pCurTkMap->InsertNotFound(MODULEDEFTOKEN, true, MODULEDEFTOKEN, &pTokenRec) );
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeModule()
-
-
-//*****************************************************************************
-// Merge TypeDef but only Names. This is a partial merge to support TypeRef to TypeDef optimization
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeDefNamesOnly()
-{
- HRESULT hr = NOERROR;
- TypeDefRec *pRecImport = NULL;
- TypeDefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeDef tdEmit;
- mdTypeDef tdImport;
- bool bDuplicate;
- DWORD dwFlags;
- DWORD dwExportFlags;
- NestedClassRec *pNestedRec;
- RID iNestedRec;
- mdTypeDef tdNester;
- TOKENREC *pTokenRec;
-
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountTypeDefs();
-
- // Merge the typedefs
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImport, &szNameImp));
- IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImport, &szNamespaceImp));
-
- // If the class is a Nested class, get the parent token.
- dwFlags = pMiniMdImport->getFlagsOfTypeDef(pRecImport);
- if (IsTdNested(dwFlags))
- {
- IfFailGo(pMiniMdImport->FindNestedClassHelper(TokenFromRid(i, mdtTypeDef), &iNestedRec));
- if (InvalidRid(iNestedRec))
- {
- _ASSERTE(!"Bad state!");
- IfFailGo(META_E_BADMETADATA);
- }
- else
- {
- IfFailGo(pMiniMdImport->GetNestedClassRecord(iNestedRec, &pNestedRec));
- tdNester = pMiniMdImport->getEnclosingClassOfNestedClass(pNestedRec);
- _ASSERTE(!IsNilToken(tdNester));
- IfFailGo(pCurTkMap->Remap(tdNester, &tdNester));
- }
- }
- else
- tdNester = mdTokenNil;
-
- bSuppressMergeCheck = (pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- TokenFromRid(i, mdtTypeDef), pImportData->m_tkSuppressMergeCheckCtor,
- NULL, 0, &tkCA));
-
- // does this TypeDef already exist in the emit scope?
- if ( ImportHelper::FindTypeDefByName(
- pMiniMdEmit,
- szNamespaceImp,
- szNameImp,
- tdNester,
- &tdEmit) == S_OK )
- {
- // Yes, it does
- bDuplicate = true;
-
- // Let's look at their accessiblities.
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(tdEmit), &pRecEmit));
- dwExportFlags = pMiniMdEmit->getFlagsOfTypeDef(pRecEmit);
-
- // Managed types need to have the same accessiblity
- BOOL fManagedType = FALSE;
- IfFailGo(IsManagedType(pMiniMdImport, TokenFromRid(i, mdtTypeDef), &fManagedType));
- if (fManagedType)
- {
- if ((dwFlags&tdVisibilityMask) != (dwExportFlags&tdVisibilityMask))
- {
- CheckContinuableErrorEx(META_E_MISMATCHED_VISIBLITY, pImportData, TokenFromRid(i, mdtTypeDef));
- }
-
- }
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
- if (pMTD->m_bSuppressMergeCheck != bSuppressMergeCheck)
- {
- CheckContinuableErrorEx(META_E_MD_INCONSISTENCY, pImportData, TokenFromRid(i, mdtTypeDef));
- }
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddTypeDefRecord(&pRecEmit, (RID *)&tdEmit));
-
- // make sure the index matches
- _ASSERTE(((mdTypeDef)m_rMTDs.Count()) == tdEmit);
-
- IfNullGo(pMTD = m_rMTDs.Append());
-
- pMTD->m_cMethods = 0;
- pMTD->m_cFields = 0;
- pMTD->m_cEvents = 0;
- pMTD->m_cProperties = 0;
- pMTD->m_bSuppressMergeCheck = bSuppressMergeCheck;
-
- tdEmit = TokenFromRid( tdEmit, mdtTypeDef );
-
- // Set Full Qualified Name.
- IfFailGo( CopyTypeDefPartially( pRecEmit, pMiniMdImport, pRecImport) );
-
- // Create a NestedClass record if the class is a Nested class.
- if (! IsNilToken(tdNester))
- {
- IfFailGo(pMiniMdEmit->AddNestedClassRecord(&pNestedRec, &iNestedRec));
-
- // copy over the information
- IfFailGo( pMiniMdEmit->PutToken(TBL_NestedClass, NestedClassRec::COL_NestedClass,
- pNestedRec, tdEmit));
-
- // tdNester has already been remapped above to the Emit scope.
- IfFailGo( pMiniMdEmit->PutToken(TBL_NestedClass, NestedClassRec::COL_EnclosingClass,
- pNestedRec, tdNester));
- IfFailGo( pMiniMdEmit->AddNestedClassToHash(iNestedRec) );
-
- }
- }
-
- // record the token movement
- tdImport = TokenFromRid(i, mdtTypeDef);
- IfFailGo( pCurTkMap->InsertNotFound(tdImport, bDuplicate, tdEmit, &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeDefNamesOnly()
-
-
-//*****************************************************************************
-// Merge EnclosingType tables
-//*****************************************************************************
-HRESULT NEWMERGER::CopyTypeDefPartially(
- TypeDefRec *pRecEmit, // [IN] the emit record to fill
- CMiniMdRW *pMiniMdImport, // [IN] the importing scope
- TypeDefRec *pRecImp) // [IN] the record to import
-
-{
- HRESULT hr;
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
-
- IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImp, &szNameImp));
- IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImp, &szNamespaceImp));
-
- IfFailGo( pMiniMdEmit->PutString( TBL_TypeDef, TypeDefRec::COL_Name, pRecEmit, szNameImp) );
- IfFailGo( pMiniMdEmit->PutString( TBL_TypeDef, TypeDefRec::COL_Namespace, pRecEmit, szNamespaceImp) );
-
- pRecEmit->SetFlags(pRecImp->GetFlags());
-
- // Don't copy over the extends until TypeRef's remap is calculated
-
-ErrExit:
- return hr;
-
-} // HRESULT NEWMERGER::CopyTypeDefPartially()
-
-
-//*****************************************************************************
-// Merge ModuleRef tables including ModuleRef to ModuleDef optimization
-//*****************************************************************************
-HRESULT NEWMERGER::MergeModuleRefs()
-{
- HRESULT hr = NOERROR;
- ModuleRefRec *pRecImport = NULL;
- ModuleRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdModuleRef mrEmit;
- bool bDuplicate = false;
- TOKENREC *pTokenRec;
- LPCUTF8 szNameImp;
- bool isModuleDef;
-
- MergeImportData *pImportData;
- MergeImportData *pData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountModuleRefs();
-
- // loop through all ModuleRef
- for (i = 1; i <= iCount; i++)
- {
- // only merge those ModuleRefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsModuleRefMarked(TokenFromRid(i, mdtModuleRef)) == false)
- continue;
-
- isModuleDef = false;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetModuleRefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfModuleRef(pRecImport, &szNameImp));
-
- // Only do the ModuleRef to ModuleDef optimization if ModuleRef's name is meaningful!
- if ( szNameImp && szNameImp[0] != '\0')
- {
-
- // Check to see if this ModuleRef has become the ModuleDef token
- for (pData = m_pImportDataList; pData != NULL; pData = pData->m_pNextImportData)
- {
- CMiniMdRW *pMiniMd = &(pData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- ModuleRec *pRec;
- LPCUTF8 szName;
-
- IfFailGo(pMiniMd->GetModuleRecord(MODULEDEFTOKEN, &pRec));
- IfFailGo(pMiniMd->getNameOfModule(pRec, &szName));
- if (szName && szName[0] != '\0' && strcmp(szNameImp, szName) == 0)
- {
- // We found an import Module for merging that has the same name as the ModuleRef
- isModuleDef = true;
- bDuplicate = true;
- mrEmit = MODULEDEFTOKEN; // set the resulting token to ModuleDef Token
- break;
- }
- }
- }
-
- if (isModuleDef == false)
- {
- // does this ModuleRef already exist in the emit scope?
- hr = ImportHelper::FindModuleRef(pMiniMdEmit,
- szNameImp,
- &mrEmit);
- if (hr == S_OK)
- {
- // Yes, it does
- bDuplicate = true;
- }
- else if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddModuleRefRecord(&pRecEmit, (RID*)&mrEmit));
- mrEmit = TokenFromRid(mrEmit, mdtModuleRef);
-
- // Set ModuleRef Name.
- IfFailGo( pMiniMdEmit->PutString(TBL_ModuleRef, ModuleRefRec::COL_Name, pRecEmit, szNameImp) );
- }
- else
- IfFailGo(hr);
- }
-
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtModuleRef),
- bDuplicate,
- mrEmit,
- &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeModuleRefs()
-
-
-//*****************************************************************************
-// Merge AssemblyRef tables
-//*****************************************************************************
-HRESULT NEWMERGER::MergeAssemblyRefs()
-{
- HRESULT hr = NOERROR;
- AssemblyRefRec *pRecImport = NULL;
- AssemblyRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- mdAssemblyRef arEmit;
- bool bDuplicate = false;
- LPCUTF8 szTmp;
- const void *pbTmp;
- ULONG cbTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountAssemblyRefs();
-
- // loope through all the AssemblyRefs.
- for (i = 1; i <= iCount; i++)
- {
- // Compare with the emit scope.
- IfFailGo(pMiniMdImport->GetAssemblyRefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getPublicKeyOrTokenOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- hr = CLDB_E_RECORD_NOTFOUND;
- if (m_fDupCheck)
- {
- LPCSTR szAssemblyRefName;
- LPCSTR szAssemblyRefLocale;
- IfFailGo(pMiniMdImport->getNameOfAssemblyRef(pRecImport, &szAssemblyRefName));
- IfFailGo(pMiniMdImport->getLocaleOfAssemblyRef(pRecImport, &szAssemblyRefLocale));
- hr = ImportHelper::FindAssemblyRef(
- pMiniMdEmit,
- szAssemblyRefName,
- szAssemblyRefLocale,
- pbTmp,
- cbTmp,
- pRecImport->GetMajorVersion(),
- pRecImport->GetMinorVersion(),
- pRecImport->GetBuildNumber(),
- pRecImport->GetRevisionNumber(),
- pRecImport->GetFlags(),
- &arEmit);
- }
- if (hr == S_OK)
- {
- // Yes, it does
- bDuplicate = true;
-
- // <TODO>@FUTURE: more verification?</TODO>
- }
- else if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddAssemblyRefRecord(&pRecEmit, &iRecord));
- arEmit = TokenFromRid(iRecord, mdtAssemblyRef);
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getPublicKeyOrTokenOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_PublicKeyOrToken,
- pRecEmit, pbTmp, cbTmp));
-
- IfFailGo(pMiniMdImport->getNameOfAssemblyRef(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_AssemblyRef, AssemblyRefRec::COL_Name,
- pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getLocaleOfAssemblyRef(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_AssemblyRef, AssemblyRefRec::COL_Locale,
- pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getHashValueOfAssemblyRef(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_HashValue,
- pRecEmit, pbTmp, cbTmp));
-
- }
- else
- IfFailGo(hr);
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtAssemblyRef),
- bDuplicate,
- arEmit,
- &pTokenRec));
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeAssemblyRefs()
-
-
-//*****************************************************************************
-// Merge TypeRef tables also performing TypeRef to TypeDef opitimization. ie.
-// we will not introduce a TypeRef record if we can optimize it to a TypeDef.
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeRefs()
-{
- HRESULT hr = NOERROR;
- TypeRefRec *pRecImport = NULL;
- TypeRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeRef trEmit;
- bool bDuplicate = false;
- TOKENREC *pTokenRec;
- bool isTypeDef;
-
- mdToken tkResImp;
- mdToken tkResEmit;
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountTypeRefs();
-
- // loop through all TypeRef
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeRefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeRefMarked(TokenFromRid(i, mdtTypeRef)) == false)
- continue;
-
- isTypeDef = false;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetTypeRefRecord(i, &pRecImport));
- tkResImp = pMiniMdImport->getResolutionScopeOfTypeRef(pRecImport);
- IfFailGo(pMiniMdImport->getNamespaceOfTypeRef(pRecImport, &szNamespaceImp));
- IfFailGo(pMiniMdImport->getNameOfTypeRef(pRecImport, &szNameImp));
- if (!IsNilToken(tkResImp))
- {
- IfFailGo(pCurTkMap->Remap(tkResImp, &tkResEmit));
- }
- else
- {
- tkResEmit = tkResImp;
- }
-
- // There are some interesting cases to consider here.
- // 1) If the TypeRef's ResolutionScope is a nil token, or is the MODULEDEFTOKEN (current module),
- // then the TypeRef refers to a type in the current scope, so we should find a corresponding
- // TypeDef in the output scope. If we find the TypeDef, we'll remap this TypeRef token
- // to that TypeDef token.
- // If we don't find that TypeDef, or if "TypeRef to TypeDef" optimization is turned off, we'll
- // create the TypeRef in the output scope.
- // 2) If the TypeRef's ResolutionScope has been resolved to a TypeDef, then this TypeRef was part
- // of a nested type definition. In that case, we'd better find a corresponding TypeDef
- // or we have an error.
- if (IsNilToken(tkResEmit) || tkResEmit == MODULEDEFTOKEN || TypeFromToken(tkResEmit) == mdtTypeDef)
- {
- hr = ImportHelper::FindTypeDefByName(
- pMiniMdEmit,
- szNamespaceImp,
- szNameImp,
- (TypeFromToken(tkResEmit) == mdtTypeDef) ? tkResEmit : mdTokenNil,
- &trEmit);
- if (hr == S_OK)
- {
- isTypeDef = true;
-
- // it really does not matter if we set the duplicate to true or false.
- bDuplicate = true;
- }
- }
-
- // If the ResolutionScope was merged as a TypeDef, and this token wasn't found as TypeDef, send the error.
- if (TypeFromToken(tkResEmit) == mdtTypeDef && !isTypeDef)
- {
- // Send the error notification. Use the "continuable error" callback, but even if linker says it is
- // ok, don't continue.
- CheckContinuableErrorEx(META_E_TYPEDEF_MISSING, pImportData, TokenFromRid(i, mdtTypeRef));
- IfFailGo(META_E_TYPEDEF_MISSING);
- }
-
- // If this TypeRef cannot be optmized to a TypeDef or the Ref to Def optimization is turned off, do the following.
- if (!isTypeDef || !((m_optimizeRefToDef & MDTypeRefToDef) == MDTypeRefToDef))
- {
- // does this TypeRef already exist in the emit scope?
- if ( m_fDupCheck && ImportHelper::FindTypeRefByName(
- pMiniMdEmit,
- tkResEmit,
- szNamespaceImp,
- szNameImp,
- &trEmit) == S_OK )
- {
- // Yes, it does
- bDuplicate = true;
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddTypeRefRecord(&pRecEmit, (RID*)&trEmit));
- trEmit = TokenFromRid(trEmit, mdtTypeRef);
-
- // Set ResolutionScope. tkResEmit has already been re-mapped.
- IfFailGo(pMiniMdEmit->PutToken(TBL_TypeRef, TypeRefRec::COL_ResolutionScope,
- pRecEmit, tkResEmit));
-
- // Set Name.
- IfFailGo(pMiniMdEmit->PutString(TBL_TypeRef, TypeRefRec::COL_Name,
- pRecEmit, szNameImp));
- IfFailGo(pMiniMdEmit->AddNamedItemToHash(TBL_TypeRef, trEmit, szNameImp, 0));
-
- // Set Namespace.
- IfFailGo(pMiniMdEmit->PutString(TBL_TypeRef, TypeRefRec::COL_Namespace,
- pRecEmit, szNamespaceImp));
- }
- }
-
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtTypeRef),
- bDuplicate,
- trEmit,
- &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeRefs()
-
-
-//*****************************************************************************
-// copy over the remaining information of partially merged TypeDef records. Right now only
-// extends field is delayed to here. The reason that we delay extends field is because we want
-// to optimize TypeRef to TypeDef if possible.
-//*****************************************************************************
-HRESULT NEWMERGER::CompleteMergeTypeDefs()
-{
- HRESULT hr = NOERROR;
- TypeDefRec *pRecImport = NULL;
- TypeDefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- TOKENREC *pTokenRec;
- mdToken tkExtendsImp;
- mdToken tkExtendsEmit;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountTypeDefs();
-
- // Merge the typedefs
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false)
- continue;
-
- if ( !pCurTkMap->Find(TokenFromRid(i, mdtTypeDef), &pTokenRec) )
- {
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
- if (pTokenRec->m_isDuplicate == false)
- {
- // get the extends token from the import
- IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport));
- tkExtendsImp = pMiniMdImport->getExtendsOfTypeDef(pRecImport);
-
- // map the extends token to an merged token
- IfFailGo( pCurTkMap->Remap(tkExtendsImp, &tkExtendsEmit) );
-
- // set the extends to the merged TypeDef records.
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(pTokenRec->m_tkTo), &pRecEmit));
- IfFailGo(pMiniMdEmit->PutToken(TBL_TypeDef, TypeDefRec::COL_Extends, pRecEmit, tkExtendsEmit));
- }
- else
- {
- // <TODO>@FUTURE: we can check to make sure the import extends maps to the one that is set to the emit scope.
- // Otherwise, it is a error to report to linker.</TODO>
- }
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CompleteMergeTypeDefs()
-
-
-//*****************************************************************************
-// merging TypeSpecs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeSpecs()
-{
- HRESULT hr = NOERROR;
- TypeSpecRec *pRecImport = NULL;
- TypeSpecRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- TOKENREC *pTokenRec;
- mdTypeSpec tsImp;
- mdTypeSpec tsEmit;
- bool fDuplicate;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountTypeSpecs();
-
- // loop through all TypeSpec
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeSpecs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeSpecMarked(TokenFromRid(i, mdtTypeSpec)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetTypeSpecRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getSignatureOfTypeSpec(pRecImport, &pbSig, &cbSig));
-
- // convert tokens contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInFieldSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- hr = CLDB_E_RECORD_NOTFOUND;
- if (m_fDupCheck)
- hr = ImportHelper::FindTypeSpec(
- pMiniMdEmit,
- (PCOR_SIGNATURE) qbSig.Ptr(),
- cbEmit,
- &tsEmit );
-
- if ( hr == S_OK )
- {
- // find a duplicate
- fDuplicate = true;
- }
- else
- {
- // copy over
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddTypeSpecRecord(&pRecEmit, (ULONG *)&tsEmit));
- tsEmit = TokenFromRid(tsEmit, mdtTypeSpec);
- IfFailGo( pMiniMdEmit->PutBlob(
- TBL_TypeSpec,
- TypeSpecRec::COL_Signature,
- pRecEmit,
- (PCOR_SIGNATURE)qbSig.Ptr(),
- cbEmit));
- }
- tsImp = TokenFromRid(i, mdtTypeSpec);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(tsImp, fDuplicate, tsEmit, &pTokenRec) );
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeSpecs()
-
-
-//*****************************************************************************
-// merging Children of TypeDefs. This includes field, method, parameter, property, event
-//*****************************************************************************
-HRESULT NEWMERGER::MergeTypeDefChildren()
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeDef tdEmit;
- mdTypeDef tdImport;
- TOKENREC *pTokenRec;
-
-#if _DEBUG
- TypeDefRec *pRecImport = NULL;
- LPCUTF8 szNameImp;
- LPCUTF8 szNamespaceImp;
-#endif // _DEBUG
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountTypeDefs();
-
- // loop through all TypeDef again to merge/copy Methods, fields, events, and properties
- //
- for (i = 1; i <= iCount; i++)
- {
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(TokenFromRid(i, mdtTypeDef)) == false)
- continue;
-
-#if _DEBUG
- IfFailGo(pMiniMdImport->GetTypeDefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfTypeDef(pRecImport, &szNameImp));
- IfFailGo(pMiniMdImport->getNamespaceOfTypeDef(pRecImport, &szNamespaceImp));
-#endif // _DEBUG
-
- // check to see if the typedef is duplicate or not
- tdImport = TokenFromRid(i, mdtTypeDef);
- if ( pCurTkMap->Find( tdImport, &pTokenRec) == false)
- {
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- tdEmit = pTokenRec->m_tkTo;
- if (pTokenRec->m_isDuplicate == false)
- {
- // now move all of the children records over
- IfFailGo( CopyMethods(pImportData, tdImport, tdEmit) );
- IfFailGo( CopyFields(pImportData, tdImport, tdEmit) );
-
- IfFailGo( CopyEvents(pImportData, tdImport, tdEmit) );
-
- // Property has dependency on events
- IfFailGo( CopyProperties(pImportData, tdImport, tdEmit) );
-
- // Generic Params.
- IfFailGo( CopyGenericParams(pImportData, tdImport, tdEmit) );
- }
- else
- {
- // verify the children records
- IfFailGo( VerifyMethods(pImportData, tdImport, tdEmit) );
- IfFailGo( VerifyFields(pImportData, tdImport, tdEmit) );
- IfFailGo( VerifyEvents(pImportData, tdImport, tdEmit) );
-
- // property has dependency on events
- IfFailGo( VerifyProperties(pImportData, tdImport, tdEmit) );
-
- IfFailGo( VerifyGenericParams(pImportData, tdImport, tdEmit) );
- }
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeTypeDefChildren()
-
-
-//*******************************************************************************
-// Helper to copy an Method record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyMethod(
- MergeImportData *pImportData, // [IN] import scope
- MethodRec *pRecImp, // [IN] the record to import
- MethodRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the fix part of the record
- pRecEmit->Copy(pRecImp);
-
- // copy over the name
- IfFailGo(pMiniMdImp->getNameOfMethod(pRecImp, &szName));
- IfFailGo(pMiniMdEmit->PutString(TBL_Method, MethodRec::COL_Name, pRecEmit, szName));
-
- // copy over the signature
- IfFailGo(pMiniMdImp->getSignatureOfMethod(pRecImp, &pbSig, &cbSig));
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImp, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Method, MethodRec::COL_Signature, pRecEmit, qbSig.Ptr(), cbEmit));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyMethod()
-
-
-//*******************************************************************************
-// Helper to copy an field record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyField(
- MergeImportData *pImportData, // [IN] import scope
- FieldRec *pRecImp, // [IN] the record to import
- FieldRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the fix part of the record
- pRecEmit->SetFlags(pRecImp->GetFlags());
-
- // copy over the name
- IfFailGo(pMiniMdImp->getNameOfField(pRecImp, &szName));
- IfFailGo(pMiniMdEmit->PutString(TBL_Field, FieldRec::COL_Name, pRecEmit, szName));
-
- // copy over the signature
- IfFailGo(pMiniMdImp->getSignatureOfField(pRecImp, &pbSig, &cbSig));
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Emit assembly scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImp, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Field, FieldRec::COL_Signature, pRecEmit, qbSig.Ptr(), cbEmit));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyField()
-
-//*******************************************************************************
-// Helper to copy an field record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyParam(
- MergeImportData *pImportData, // [IN] import scope
- ParamRec *pRecImp, // [IN] the record to import
- ParamRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the fix part of the record
- pRecEmit->Copy(pRecImp);
-
- // copy over the name
- IfFailGo(pMiniMdImp->getNameOfParam(pRecImp, &szName));
- IfFailGo(pMiniMdEmit->PutString(TBL_Param, ParamRec::COL_Name, pRecEmit, szName));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyParam()
-
-//*******************************************************************************
-// Helper to copy an Event record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyEvent(
- MergeImportData *pImportData, // [IN] import scope
- EventRec *pRecImp, // [IN] the record to import
- EventRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- mdToken tkEventTypeImp;
- mdToken tkEventTypeEmit; // could be TypeDef or TypeRef
- LPCUTF8 szName;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- pRecEmit->SetEventFlags(pRecImp->GetEventFlags());
-
- //move over the event name
- IfFailGo(pMiniMdImp->getNameOfEvent(pRecImp, &szName));
- IfFailGo( pMiniMdEmit->PutString(TBL_Event, EventRec::COL_Name, pRecEmit, szName) );
-
- // move over the EventType
- tkEventTypeImp = pMiniMdImp->getEventTypeOfEvent(pRecImp);
- if ( !IsNilToken(tkEventTypeImp) )
- {
- IfFailGo( pCurTkMap->Remap(tkEventTypeImp, &tkEventTypeEmit) );
- IfFailGo(pMiniMdEmit->PutToken(TBL_Event, EventRec::COL_EventType, pRecEmit, tkEventTypeEmit));
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyEvent()
-
-
-//*******************************************************************************
-// Helper to copy a property record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyProperty(
- MergeImportData *pImportData, // [IN] import scope
- PropertyRec *pRecImp, // [IN] the record to import
- PropertyRec *pRecEmit) // [IN] the emit record to fill
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // move over the flag value
- pRecEmit->SetPropFlags(pRecImp->GetPropFlags());
-
- //move over the property name
- IfFailGo(pMiniMdImp->getNameOfProperty(pRecImp, &szName));
- IfFailGo( pMiniMdEmit->PutString(TBL_Property, PropertyRec::COL_Name, pRecEmit, szName) );
-
- // move over the type of the property
- IfFailGo(pMiniMdImp->getTypeOfProperty(pRecImp, &pbSig, &cbSig));
-
- // convert rid contained in signature to new scope
- IfFailGo( ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImp, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit) ); // number of bytes write to cbEmit
-
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Property, PropertyRec::COL_Type, pRecEmit, qbSig.Ptr(), cbEmit));
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyProperty()
-
-
-//*****************************************************************************
-// Copy MethodSemantics for an event or a property
-//*****************************************************************************
-HRESULT NEWMERGER::CopyMethodSemantics(
- MergeImportData *pImportData,
- mdToken tkImport, // Event or property in the import scope
- mdToken tkEmit) // corresponding event or property in the emitting scope
-{
- HRESULT hr = NOERROR;
- MethodSemanticsRec *pRecImport = NULL;
- MethodSemanticsRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- ULONG i;
- ULONG msEmit; // MethodSemantics are just index not tokens
- mdToken tkMethodImp;
- mdToken tkMethodEmit;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnum;
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // copy over the associates
- IfFailGo( pMiniMdImport->FindMethodSemanticsHelper(tkImport, &hEnum) );
- while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &i))
- {
- IfFailGo(pMiniMdImport->GetMethodSemanticsRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddMethodSemanticsRecord(&pRecEmit, &msEmit));
- pRecEmit->SetSemantic(pRecImport->GetSemantic());
-
- // set the MethodSemantics
- tkMethodImp = pMiniMdImport->getMethodOfMethodSemantics(pRecImport);
- IfFailGo( pCurTkMap->Remap(tkMethodImp, &tkMethodEmit) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSemantics, MethodSemanticsRec::COL_Method, pRecEmit, tkMethodEmit));
-
- // set the associate
- _ASSERTE( pMiniMdImport->getAssociationOfMethodSemantics(pRecImport) == tkImport );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSemantics, MethodSemanticsRec::COL_Association, pRecEmit, tkEmit));
-
- // no need to record the movement since it is not a token
- IfFailGo( pMiniMdEmit->AddMethodSemanticsToHash(msEmit) );
- }
-ErrExit:
- HENUMInternal::ClearEnum(&hEnum);
- return hr;
-} // HRESULT NEWMERGER::CopyMethodSemantics()
-
-
-//*****************************************************************************
-// Copy Methods given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyMethods(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- MethodRec *pRecImport = NULL;
- MethodRec *pRecEmit = NULL;
- TypeDefRec *pTypeDefRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG i;
- mdMethodDef mdEmit;
- mdMethodDef mdImp;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getMethodListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndMethodListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the methods yet
- _ASSERTE(pMTD->m_cMethods == 0);
-
- // loop through all Methods
- for (i = ridStart; i < ridEnd; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetMethodRid(i, (ULONG *)&mdImp));
-
- // only merge those MethodDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(TokenFromRid(mdImp, mdtMethodDef)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetMethodRecord(mdImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddMethodRecord(&pRecEmit, (RID *)&mdEmit));
-
- // copy the method content over
- IfFailGo( CopyMethod(pImportData, pRecImport, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddMethodToTypeDef(RidFromToken(tdEmit), mdEmit));
-
- // record the token movement
- mdImp = TokenFromRid(mdImp, mdtMethodDef);
- mdEmit = TokenFromRid(mdEmit, mdtMethodDef);
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- mdEmit,
- tdEmit) );
-
- IfFailGo( pCurTkMap->InsertNotFound(mdImp, false, mdEmit, &pTokenRec) );
-
- // copy over the children
- IfFailGo( CopyParams(pImportData, mdImp, mdEmit) );
- IfFailGo( CopyGenericParams(pImportData, mdImp, mdEmit) );
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- mdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cMethods++;
- }
- }
-
- // make sure we don't count any methods if merge check is suppressed on the type
- _ASSERTE(pMTD->m_cMethods == 0 || !pMTD->m_bSuppressMergeCheck);
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyMethods()
-
-
-//*****************************************************************************
-// Copy Fields given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyFields(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- FieldRec *pRecImport = NULL;
- FieldRec *pRecEmit = NULL;
- TypeDefRec *pTypeDefRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG i;
- mdFieldDef fdEmit;
- mdFieldDef fdImp;
- bool bDuplicate;
- TOKENREC *pTokenRec;
- PCCOR_SIGNATURE pvSigBlob;
- ULONG cbSigBlob;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getFieldListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndFieldListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the methods yet
- _ASSERTE(pMTD->m_cFields == 0);
-
- // loop through all FieldDef of a TypeDef
- for (i = ridStart; i < ridEnd; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldRid(i, (ULONG *)&fdImp));
-
- // only merge those FieldDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(fdImp, mdtFieldDef)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetFieldRecord(fdImp, &pRecImport));
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddFieldRecord(&pRecEmit, (RID *)&fdEmit));
-
- // copy the field content over
- IfFailGo( CopyField(pImportData, pRecImport, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddFieldToTypeDef(RidFromToken(tdEmit), fdEmit));
-
- // record the token movement
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
- fdEmit = TokenFromRid(fdEmit, mdtFieldDef);
- IfFailGo(pMiniMdEmit->getSignatureOfField(pRecEmit, &pvSigBlob, &cbSigBlob));
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- fdEmit,
- tdEmit) );
-
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, false, fdEmit, &pTokenRec) );
-
- // count the number of fields that didn't suppress merge check
- // non-static fields doesn't inherite the suppress merge check attribute from the type
- bSuppressMergeCheck =
- (IsFdStatic(pRecEmit->GetFlags()) && pMTD->m_bSuppressMergeCheck) ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- fdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cFields++;
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyFields()
-
-
-//*****************************************************************************
-// Copy Events given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyEvents(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- RID ridEventMap;
- EventMapRec *pEventMapRec;
- EventRec *pRecImport;
- EventRec *pRecEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdEvent evImp;
- mdEvent evEmit;
- TOKENREC *pTokenRec;
- ULONG iEventMap;
- EventMapRec *pEventMap;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the events yet
- _ASSERTE(pMTD->m_cEvents == 0);
-
- IfFailGo(pMiniMdImport->FindEventMapFor(RidFromToken(tdImport), &ridEventMap));
- if (!InvalidRid(ridEventMap))
- {
- IfFailGo(pMiniMdImport->GetEventMapRecord(ridEventMap, &pEventMapRec));
- ridStart = pMiniMdImport->getEventListOfEventMap(pEventMapRec);
- IfFailGo(pMiniMdImport->getEndEventListOfEventMap(ridEventMap, &ridEnd));
-
- if (ridEnd > ridStart)
- {
- // If there is any event, create the eventmap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddEventMapRecord(&pEventMap, &iEventMap));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_EventMap, EventMapRec::COL_Parent, pEventMap, tdEmit));
- }
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the real event rid
- IfFailGo(pMiniMdImport->GetEventRid(i, (ULONG *)&evImp));
-
- // only merge those Events that are marked
- if ( pMiniMdImport->GetFilterTable()->IsEventMarked(TokenFromRid(evImp, mdtEvent)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetEventRecord(evImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddEventRecord(&pRecEmit, (RID *)&evEmit));
-
- // copy the event record over
- IfFailGo( CopyEvent(pImportData, pRecImport, pRecEmit) );
-
- // Add Event to the EventMap.
- IfFailGo( pMiniMdEmit->AddEventToEventMap(iEventMap, evEmit) );
-
- // record the token movement
- evImp = TokenFromRid(evImp, mdtEvent);
- evEmit = TokenFromRid(evEmit, mdtEvent);
-
- IfFailGo( pCurTkMap->InsertNotFound(evImp, false, evEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, evImp, evEmit) );
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- evImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cEvents++;
- }
- }
- }
-
- // make sure we don't count any events if merge check is suppressed on the type
- _ASSERTE(pMTD->m_cEvents == 0 || !pMTD->m_bSuppressMergeCheck);
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyEvents()
-
-
-//*****************************************************************************
-// Copy Properties given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyProperties(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- RID ridPropertyMap;
- PropertyMapRec *pPropertyMapRec;
- PropertyRec *pRecImport;
- PropertyRec *pRecEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdProperty prImp;
- mdProperty prEmit;
- TOKENREC *pTokenRec;
- ULONG iPropertyMap;
- PropertyMapRec *pPropertyMap;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- mdCustomAttribute tkCA;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // make sure we didn't count the properties yet
- _ASSERTE(pMTD->m_cProperties == 0);
-
- IfFailGo(pMiniMdImport->FindPropertyMapFor(RidFromToken(tdImport), &ridPropertyMap));
- if (!InvalidRid(ridPropertyMap))
- {
- IfFailGo(pMiniMdImport->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec));
- ridStart = pMiniMdImport->getPropertyListOfPropertyMap(pPropertyMapRec);
- IfFailGo(pMiniMdImport->getEndPropertyListOfPropertyMap(ridPropertyMap, &ridEnd));
-
- if (ridEnd > ridStart)
- {
- // If there is any event, create the PropertyMap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddPropertyMapRecord(&pPropertyMap, &iPropertyMap));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_PropertyMap, PropertyMapRec::COL_Parent, pPropertyMap, tdEmit));
- }
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the property rid
- IfFailGo(pMiniMdImport->GetPropertyRid(i, (ULONG *)&prImp));
-
- // only merge those Properties that are marked
- if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(TokenFromRid(prImp, mdtProperty)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetPropertyRecord(prImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddPropertyRecord(&pRecEmit, (RID *)&prEmit));
-
- // copy the property record over
- IfFailGo( CopyProperty(pImportData, pRecImport, pRecEmit) );
-
- // Add Property to the PropertyMap.
- IfFailGo( pMiniMdEmit->AddPropertyToPropertyMap(iPropertyMap, prEmit) );
-
- // record the token movement
- prImp = TokenFromRid(prImp, mdtProperty);
- prEmit = TokenFromRid(prEmit, mdtProperty);
-
- IfFailGo( pCurTkMap->InsertNotFound(prImp, false, prEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, prImp, prEmit) );
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- prImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (!bSuppressMergeCheck) {
- pMTD->m_cProperties++;
- }
- }
- }
-
- // make sure we don't count any properties if merge check is suppressed on the type
- _ASSERTE(pMTD->m_cProperties == 0 || !pMTD->m_bSuppressMergeCheck);
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyProperties()
-
-
-//*****************************************************************************
-// Copy Parameters given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyParams(
- MergeImportData *pImportData,
- mdMethodDef mdImport,
- mdMethodDef mdEmit)
-{
- HRESULT hr = NOERROR;
- ParamRec *pRecImport = NULL;
- ParamRec *pRecEmit = NULL;
- MethodRec *pMethodRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG i;
- mdParamDef pdEmit;
- mdParamDef pdImp;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
-
- IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImport), &pMethodRec));
- ridStart = pMiniMdImport->getParamListOfMethod(pMethodRec);
- IfFailGo(pMiniMdImport->getEndParamListOfMethod(RidFromToken(mdImport), &ridEnd));
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // loop through all InterfaceImpl
- for (i = ridStart; i < ridEnd; i++)
- {
- // Get the param rid
- IfFailGo(pMiniMdImport->GetParamRid(i, (ULONG *)&pdImp));
-
- // only merge those Params that are marked
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(TokenFromRid(pdImp, mdtParamDef)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetParamRecord(pdImp, &pRecImport));
- IfFailGo(pMiniMdEmit->AddParamRecord(&pRecEmit, (RID *)&pdEmit));
-
- // copy the Parameter record over
- IfFailGo( CopyParam(pImportData, pRecImport, pRecEmit) );
-
- // warning!! warning!!
- // We cannot add paramRec to method list until it is fully set.
- // AddParamToMethod will use the ulSequence in the record
- IfFailGo( pMiniMdEmit->AddParamToMethod(RidFromToken(mdEmit), pdEmit));
-
- // record the token movement
- pdImp = TokenFromRid(pdImp, mdtParamDef);
- pdEmit = TokenFromRid(pdEmit, mdtParamDef);
-
- IfFailGo( pCurTkMap->InsertNotFound(pdImp, false, pdEmit, &pTokenRec) );
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyParams()
-
-
-//*****************************************************************************
-// Copy GenericParams given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::CopyGenericParams(
- MergeImportData *pImportData,
- mdToken tkImport,
- mdToken tkEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- GenericParamRec *pRecImport = NULL;
- GenericParamRec *pRecEmit = NULL;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnum;
- mdGenericParam gpImport;
- mdGenericParam gpEmit;
- LPCSTR szGenericParamName;
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo( pMiniMdImport->FindGenericParamHelper(tkImport, &hEnum) );
-
- while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &gpImport))
- {
- // Get the import GenericParam record
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParam);
- IfFailGo(pMiniMdImport->GetGenericParamRecord(RidFromToken(gpImport), &pRecImport));
-
- // Create new emit record.
- IfFailGo(pMiniMdEmit->AddGenericParamRecord(&pRecEmit, (RID *)&gpEmit));
-
- // copy the GenericParam content
- pRecEmit->SetNumber( pRecImport->GetNumber());
- pRecEmit->SetFlags( pRecImport->GetFlags());
-
- IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParam, GenericParamRec::COL_Owner, pRecEmit, tkEmit));
-
- IfFailGo(pMiniMdImport->getNameOfGenericParam(pRecImport, &szGenericParamName));
- IfFailGo( pMiniMdEmit->PutString(TBL_GenericParam, GenericParamRec::COL_Name, pRecEmit, szGenericParamName));
-
- // record the token movement
- gpImport = TokenFromRid(gpImport, mdtGenericParam);
- gpEmit = TokenFromRid(gpEmit, mdtGenericParam);
-
- IfFailGo( pCurTkMap->InsertNotFound(gpImport, false, gpEmit, &pTokenRec) );
-
- // copy over any constraints
- IfFailGo( CopyGenericParamConstraints(pImportData, gpImport, gpEmit) );
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyGenericParams()
-
-
-//*****************************************************************************
-// Copy GenericParamConstraints given a GenericParam
-//*****************************************************************************
-HRESULT NEWMERGER::CopyGenericParamConstraints(
- MergeImportData *pImportData,
- mdGenericParamConstraint tkImport,
- mdGenericParamConstraint tkEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- GenericParamConstraintRec *pRecImport = NULL;
- GenericParamConstraintRec *pRecEmit = NULL;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnum;
- mdGenericParamConstraint gpImport;
- mdGenericParamConstraint gpEmit;
- mdToken tkConstraint;
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo( pMiniMdImport->FindGenericParamConstraintHelper(tkImport, &hEnum) );
-
- while (HENUMInternal::EnumNext(&hEnum, (mdToken *) &gpImport))
- {
- // Get the import GenericParam record
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdImport->GetGenericParamConstraintRecord(RidFromToken(gpImport), &pRecImport));
-
- // Translate the constraint before creating new record.
- tkConstraint = pMiniMdImport->getConstraintOfGenericParamConstraint(pRecImport);
- if (pCurTkMap->Find(tkConstraint, &pTokenRec) == false)
- {
- // This should never fire unless the TypeDefs/Refs weren't merged
- // before this code runs.
- _ASSERTE(!"GenericParamConstraint Constraint not found in MERGER::CopyGenericParamConstraints. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- tkConstraint = pTokenRec->m_tkTo;
-
- // Create new emit record.
- IfFailGo(pMiniMdEmit->AddGenericParamConstraintRecord(&pRecEmit, (RID *)&gpEmit));
-
- // copy the GenericParamConstraint content
- IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParamConstraint, GenericParamConstraintRec::COL_Owner, pRecEmit, tkEmit));
-
- IfFailGo( pMiniMdEmit->PutToken(TBL_GenericParamConstraint, GenericParamConstraintRec::COL_Constraint, pRecEmit, tkConstraint));
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyGenericParamConstraints()
-
-
-//*****************************************************************************
-// Verify GenericParams given a TypeDef
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyGenericParams(
- MergeImportData *pImportData,
- mdToken tkImport,
- mdToken tkEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
- HENUMInternal hEnumImport; // Enumerator for import scope.
- HENUMInternal hEnumEmit; // Enumerator for emit scope.
- ULONG cImport, cEmit; // Count of import & emit records.
- ULONG i; // Enumerating records in import scope.
- ULONG iEmit; // Tracking records in emit scope.
- mdGenericParam gpImport; // Import scope GenericParam token.
- mdGenericParam gpEmit; // Emit scope GenericParam token.
- GenericParamRec *pRecImport = NULL;
- GenericParamRec *pRecEmit = NULL;
- LPCSTR szNameImport; // Name of param in import scope.
- LPCSTR szNameEmit; // Name of param in emit scope.
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // Get enumerators for the input and output scopes.
- IfFailGo(pMiniMdImport->FindGenericParamHelper(tkImport, &hEnumImport));
- IfFailGo(pMiniMdEmit->FindGenericParamHelper(tkEmit, &hEnumEmit));
-
- // The counts should be the same.
- IfFailGo(HENUMInternal::GetCount(&hEnumImport, &cImport));
- IfFailGo(HENUMInternal::GetCount(&hEnumEmit, &cEmit));
-
- if (cImport != cEmit)
- {
- CheckContinuableErrorEx(META_E_GENERICPARAM_INCONSISTENT, pImportData, tkImport);
- // If we are here, the linker says this error is OK.
- }
-
- for (i=iEmit=0; i<cImport; ++i)
- {
- // Get the import GenericParam record
- IfFailGo(HENUMInternal::GetElement(&hEnumImport, i, &gpImport));
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParam);
- IfFailGo(pMiniMdImport->GetGenericParamRecord(RidFromToken(gpImport), &pRecImport));
-
- // Find the emit record. If the import and emit scopes are ordered the same
- // this is easy; otherwise go looking for it.
- // Get the "next" emit record.
- if (iEmit < cEmit)
- {
- IfFailGo(HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParam);
- IfFailGo(pMiniMdEmit->GetGenericParamRecord(RidFromToken(gpEmit), &pRecEmit));
- }
-
- // If the import and emit sequence numbers don't match, go looking.
- // Also, if we would have walked off end of array, go looking.
- if (iEmit >= cEmit || pRecImport->GetNumber() != pRecEmit->GetNumber())
- {
- for (iEmit=0; iEmit<cEmit; ++iEmit)
- {
- IfFailGo( HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParam);
- IfFailGo(pMiniMdEmit->GetGenericParamRecord(RidFromToken(gpEmit), &pRecEmit));
-
- // The one we want?
- if (pRecImport->GetNumber() == pRecEmit->GetNumber())
- break;
- }
- if (iEmit >= cEmit)
- goto Error; // Didn't find it
- }
-
- // Check that these "n'th" GenericParam records match.
-
- // Flags.
- if (pRecImport->GetFlags() != pRecEmit->GetFlags())
- goto Error;
-
- // Name.
- IfFailGo(pMiniMdImport->getNameOfGenericParam(pRecImport, &szNameImport));
- IfFailGo(pMiniMdEmit->getNameOfGenericParam(pRecEmit, &szNameEmit));
- if (strcmp(szNameImport, szNameEmit) != 0)
- goto Error;
-
- // Verify any constraints.
- gpImport = TokenFromRid(gpImport, mdtGenericParam);
- gpEmit = TokenFromRid(gpEmit, mdtGenericParam);
- hr = VerifyGenericParamConstraints(pImportData, gpImport, gpEmit);
-
- if (SUCCEEDED(hr))
- {
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(gpImport, true, gpEmit, &pTokenRec) );
- }
- else
- {
-Error:
- // inconsistent in GenericParams
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_GENERICPARAM_INCONSISTENT, pImportData, tkImport);
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyGenericParams()
-
-
-//*****************************************************************************
-// Verify GenericParamConstraints given a GenericParam
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyGenericParamConstraints(
- MergeImportData *pImportData, // The import scope.
- mdGenericParam gpImport, // Import GenericParam.
- mdGenericParam gpEmit) // Emit GenericParam.
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
- HENUMInternal hEnumImport; // Enumerator for import scope.
- HENUMInternal hEnumEmit; // Enumerator for emit scope.
- ULONG cImport, cEmit; // Count of import & emit records.
- ULONG i; // Enumerating records in import scope.
- ULONG iEmit; // Tracking records in emit scope.
- GenericParamConstraintRec *pRecImport = NULL;
- GenericParamConstraintRec *pRecEmit = NULL;
- MDTOKENMAP *pCurTkMap;
- mdToken tkConstraintImport = mdTokenNil;
- mdToken tkConstraintEmit = mdTokenNil;
-
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pMiniMdEmit = GetMiniMdEmit();
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // Get enumerators for the input and output scopes.
- IfFailGo(pMiniMdImport->FindGenericParamConstraintHelper(gpImport, &hEnumImport));
- IfFailGo(pMiniMdEmit->FindGenericParamConstraintHelper(gpEmit, &hEnumEmit));
-
- // The counts should be the same.
- IfFailGo(HENUMInternal::GetCount(&hEnumImport, &cImport));
- IfFailGo(HENUMInternal::GetCount(&hEnumEmit, &cEmit));
-
- if (cImport != cEmit)
- IfFailGo(META_E_GENERICPARAM_INCONSISTENT); // Different numbers of constraints.
-
- for (i=iEmit=0; i<cImport; ++i)
- {
- // Get the import GenericParam record
- IfFailGo( HENUMInternal::GetElement(&hEnumImport, i, &gpImport));
- _ASSERTE(TypeFromToken(gpImport) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdImport->GetGenericParamConstraintRecord(RidFromToken(gpImport), &pRecImport));
-
- // Get the constraint.
- tkConstraintImport = pMiniMdImport->getConstraintOfGenericParamConstraint(pRecImport);
- if (pCurTkMap->Find(tkConstraintImport, &pTokenRec) == false)
- {
- // This should never fire unless the TypeDefs/Refs weren't merged
- // before this code runs.
- _ASSERTE(!"GenericParamConstraint Constraint not found in MERGER::VerifyGenericParamConstraints. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- tkConstraintImport = pTokenRec->m_tkTo;
-
- // Find the emit record. If the import and emit scopes are ordered the same
- // this is easy; otherwise go looking for it.
- // Get the "next" emit record.
- if (iEmit < cEmit)
- {
- IfFailGo( HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdEmit->GetGenericParamConstraintRecord(RidFromToken(gpEmit), &pRecEmit));
- tkConstraintEmit = pMiniMdEmit->getConstraintOfGenericParamConstraint(pRecEmit);
- }
-
- // If the import and emit constraints don't match, go looking.
- if (iEmit >= cEmit || tkConstraintEmit != tkConstraintImport)
- {
- for (iEmit=0; iEmit<cEmit; ++iEmit)
- {
- IfFailGo( HENUMInternal::GetElement(&hEnumEmit, iEmit, &gpEmit));
- _ASSERTE(TypeFromToken(gpEmit) == mdtGenericParamConstraint);
- IfFailGo(pMiniMdEmit->GetGenericParamConstraintRecord(RidFromToken(gpEmit), &pRecEmit));
- tkConstraintEmit = pMiniMdEmit->getConstraintOfGenericParamConstraint(pRecEmit);
-
- // The one we want?
- if (tkConstraintEmit == tkConstraintImport)
- break;
- }
- if (iEmit >= cEmit)
- {
- IfFailGo(META_E_GENERICPARAM_INCONSISTENT); // Didn't find the constraint
- }
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyGenericParamConstraints()
-
-
-//*****************************************************************************
-// Verify Methods
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyMethods(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- MethodRec *pRecImp;
- MethodRec *pRecEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
-
- TypeDefRec *pTypeDefRec;
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- TOKENREC *pTokenRec;
- mdMethodDef mdImp;
- mdMethodDef mdEmit;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed methods
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getMethodListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndMethodListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // loop through all Methods of the TypeDef
- for (i = ridStart; i < ridEnd; i++)
- {
- IfFailGo(pMiniMdImport->GetMethodRid(i, (ULONG *)&mdImp));
-
- // only verify those Methods that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(TokenFromRid(mdImp, mdtMethodDef)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetMethodRecord(mdImp, &pRecImp));
-
- if (m_fDupCheck == FALSE && tdImport == pImportData->m_pRegMetaImport->m_tdModule) // TokenFromRid(1, mdtTypeDef))
- {
- // No dup check. This is the scenario that we only have one import scope. Just copy over the
- // globals.
- goto CopyMethodLabel;
- }
-
- IfFailGo(pMiniMdImport->getNameOfMethod(pRecImp, &szName));
- IfFailGo(pMiniMdImport->getSignatureOfMethod(pRecImp, &pbSig, &cbSig));
-
- mdImp = TokenFromRid(mdImp, mdtMethodDef);
-
- if ( IsMdPrivateScope( pRecImp->GetFlags() ) )
- {
- // Trigger additive merge
- goto CopyMethodLabel;
- }
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- hr = ImportHelper::FindMethod(
- pMiniMdEmit,
- tdEmit,
- szName,
- (const COR_SIGNATURE *)qbSig.Ptr(),
- cbEmit,
- &mdEmit);
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- mdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck || (tdImport == pImportData->m_pRegMetaImport->m_tdModule))
- {
- // global functions! Make sure that we move over the non-duplicate global function
- // declaration
- //
- if (hr == S_OK)
- {
- // found the duplicate
- IfFailGo( VerifyMethod(pImportData, mdImp, mdEmit) );
- }
- else
- {
-CopyMethodLabel:
- // not a duplicate! Copy over the
- IfFailGo(pMiniMdEmit->AddMethodRecord(&pRecEmit, (RID *)&mdEmit));
-
- // copy the method content over
- IfFailGo( CopyMethod(pImportData, pRecImp, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddMethodToTypeDef(RidFromToken(tdEmit), mdEmit));
-
- // record the token movement
- mdEmit = TokenFromRid(mdEmit, mdtMethodDef);
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- mdEmit,
- tdEmit) );
-
- mdImp = TokenFromRid(mdImp, mdtMethodDef);
- IfFailGo( pCurTkMap->InsertNotFound(mdImp, false, mdEmit, &pTokenRec) );
-
- // copy over the children
- IfFailGo( CopyParams(pImportData, mdImp, mdEmit) );
- IfFailGo( CopyGenericParams(pImportData, mdImp, mdEmit) );
-
- }
- }
- else
- {
- if (hr == S_OK)
- {
- // Good! We are supposed to find a duplicate
- IfFailGo( VerifyMethod(pImportData, mdImp, mdEmit) );
- }
- else
- {
- // Oops! The typedef is duplicated but the method is not!!
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_METHD_NOT_FOUND, pImportData, mdImp);
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cMethods && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_METHOD_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyMethods()
-
-
-//*****************************************************************************
-// verify a duplicated method
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyMethod(
- MergeImportData *pImportData,
- mdMethodDef mdImp, // [IN] the emit record to fill
- mdMethodDef mdEmit) // [IN] the record to import
-{
- HRESULT hr;
- MethodRec *pRecImp;
- MethodRec *pRecEmit;
- TOKENREC *pTokenRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- IfFailGo( pCurTkMap->InsertNotFound(mdImp, true, mdEmit, &pTokenRec) );
-
- IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImp), &pRecImp));
-
- // We need to make sure that the impl flags are propagated .
- // Rules are: if the first method has miForwardRef flag set but the new method does not,
- // we want to disable the miForwardRef flag. If the one found in the emit scope does not have
- // miForwardRef set and the second one doesn't either, we want to make sure that the rest of
- // impl flags are the same.
- //
- if ( !IsMiForwardRef( pRecImp->GetImplFlags() ) )
- {
- IfFailGo(pMiniMdEmit->GetMethodRecord(RidFromToken(mdEmit), &pRecEmit));
- if (!IsMiForwardRef(pRecEmit->GetImplFlags()))
- {
- // make sure the rest of ImplFlags are the same
- if (pRecEmit->GetImplFlags() != pRecImp->GetImplFlags())
- {
- // inconsistent in implflags
- CheckContinuableErrorEx(META_E_METHDIMPL_INCONSISTENT, pImportData, mdImp);
- }
- }
- else
- {
- // propagate the importing ImplFlags
- pRecEmit->SetImplFlags(pRecImp->GetImplFlags());
- }
- }
-
- // verify the children
- IfFailGo( VerifyParams(pImportData, mdImp, mdEmit) );
- IfFailGo( VerifyGenericParams(pImportData, mdImp, mdEmit) );
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyMethod()
-
-
-//*****************************************************************************
-// Verify Fields
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyFields(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- FieldRec *pRecImp;
- FieldRec *pRecEmit;
- mdFieldDef fdImp;
- mdFieldDef fdEmit;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
-
- TypeDefRec *pTypeDefRec;
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed fields
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetTypeDefRecord(RidFromToken(tdImport), &pTypeDefRec));
- ridStart = pMiniMdImport->getFieldListOfTypeDef(pTypeDefRec);
- IfFailGo(pMiniMdImport->getEndFieldListOfTypeDef(RidFromToken(tdImport), &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- // loop through all fields of the TypeDef
- for (i = ridStart; i < ridEnd; i++)
- {
- IfFailGo(pMiniMdImport->GetFieldRid(i, (ULONG *)&fdImp));
-
- // only verify those fields that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(fdImp, mdtFieldDef)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetFieldRecord(fdImp, &pRecImp));
-
- if (m_fDupCheck == FALSE && tdImport == pImportData->m_pRegMetaImport->m_tdModule)
- {
- // No dup check. This is the scenario that we only have one import scope. Just copy over the
- // globals.
- goto CopyFieldLabel;
- }
-
- IfFailGo(pMiniMdImport->getNameOfField(pRecImp, &szName));
- IfFailGo(pMiniMdImport->getSignatureOfField(pRecImp, &pbSig, &cbSig));
-
- if ( IsFdPrivateScope(pRecImp->GetFlags()))
- {
- // Trigger additive merge
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
- goto CopyFieldLabel;
- }
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- hr = ImportHelper::FindField(
- pMiniMdEmit,
- tdEmit,
- szName,
- (const COR_SIGNATURE *)qbSig.Ptr(),
- cbEmit,
- &fdEmit);
-
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
-
- bSuppressMergeCheck =
- (IsFdStatic(pRecImp->GetFlags()) && pMTD->m_bSuppressMergeCheck) ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- fdImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck || (tdImport == pImportData->m_pRegMetaImport->m_tdModule))
- {
- // global data! Make sure that we move over the non-duplicate global function
- // declaration
- //
- if (hr == S_OK)
- {
- // found the duplicate
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, true, fdEmit, &pTokenRec) );
- }
- else
- {
-CopyFieldLabel:
- // not a duplicate! Copy over the
- IfFailGo(pMiniMdEmit->AddFieldRecord(&pRecEmit, (RID *)&fdEmit));
-
- // copy the field record over
- IfFailGo( CopyField(pImportData, pRecImp, pRecEmit) );
-
- IfFailGo( pMiniMdEmit->AddFieldToTypeDef(RidFromToken(tdEmit), fdEmit));
-
- // record the token movement
- fdEmit = TokenFromRid(fdEmit, mdtFieldDef);
- IfFailGo( pMiniMdEmit->AddMemberDefToHash(
- fdEmit,
- tdEmit) );
-
- fdImp = TokenFromRid(fdImp, mdtFieldDef);
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, false, fdEmit, &pTokenRec) );
- }
- }
- else
- {
- if (hr == S_OK)
- {
- // Good! We are supposed to find a duplicate
- IfFailGo( pCurTkMap->InsertNotFound(fdImp, true, fdEmit, &pTokenRec) );
- }
- else
- {
- // Oops! The typedef is duplicated but the field is not!!
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_FIELD_NOT_FOUND, pImportData, fdImp);
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cFields && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_FIELD_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyFields()
-
-
-//*****************************************************************************
-// Verify Events
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyEvents(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- RID ridEventMap, ridEventMapEmit;
- EventMapRec *pEventMapRec;
- EventRec *pRecImport;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdEvent evImport;
- mdEvent evEmit;
- TOKENREC *pTokenRec;
- LPCUTF8 szName;
- mdToken tkType;
- MDTOKENMAP *pCurTkMap;
-
- EventMapRec *pEventMapEmit;
- EventRec *pRecEmit;
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed events
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- IfFailGo(pMiniMdImport->FindEventMapFor(RidFromToken(tdImport), &ridEventMap));
- if (!InvalidRid(ridEventMap))
- {
- // Get a count of records already in emit scope.
- IfFailGo(pMiniMdEmit->FindEventMapFor(RidFromToken(tdEmit), &ridEventMapEmit));
-
- if (InvalidRid(ridEventMapEmit)) {
- // If there is any event, create the eventmap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddEventMapRecord(&pEventMapEmit, &ridEventMapEmit));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_EventMap, EventMapRec::COL_Parent, pEventMapEmit, tdEmit));
- }
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetEventMapRecord(ridEventMap, &pEventMapRec));
- ridStart = pMiniMdImport->getEventListOfEventMap(pEventMapRec);
- IfFailGo(pMiniMdImport->getEndEventListOfEventMap(ridEventMap, &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the property rid
- IfFailGo(pMiniMdImport->GetEventRid(i, (ULONG *)&evImport));
-
- // only verify those Events that are marked
- if ( pMiniMdImport->GetFilterTable()->IsEventMarked(TokenFromRid(evImport, mdtEvent)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetEventRecord(evImport, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfEvent(pRecImport, &szName));
- tkType = pMiniMdImport->getEventTypeOfEvent( pRecImport );
- IfFailGo( pCurTkMap->Remap(tkType, &tkType) );
- evImport = TokenFromRid( evImport, mdtEvent);
-
- hr = ImportHelper::FindEvent(
- pMiniMdEmit,
- tdEmit,
- szName,
- &evEmit);
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- evImport, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck)
- {
-
- if (hr == S_OK )
- {
- // Good. We found the matching event when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(evImport, true, evEmit, &pTokenRec) );
- }
- else
- {
- // not a duplicate! Copy over the
- IfFailGo(pMiniMdEmit->AddEventRecord(&pRecEmit, (RID *)&evEmit));
-
- // copy the event record over
- IfFailGo( CopyEvent(pImportData, pRecImport, pRecEmit) );
-
- // Add Event to the EventMap.
- IfFailGo( pMiniMdEmit->AddEventToEventMap(ridEventMapEmit, evEmit) );
-
- // record the token movement
- evEmit = TokenFromRid(evEmit, mdtEvent);
-
- IfFailGo( pCurTkMap->InsertNotFound(evImport, false, evEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, evImport, evEmit) );
- }
- }
- else
- {
- if (hr == S_OK )
- {
- // Good. We found the matching event when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(evImport, true, evEmit, &pTokenRec) );
- }
- else
- {
- // Oops! The typedef is duplicated but the event is not!!
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_EVENT_NOT_FOUND, pImportData, evImport);
-
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cEvents && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_EVENT_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyEvents()
-
-
-//*****************************************************************************
-// Verify Properties
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyProperties(
- MergeImportData *pImportData,
- mdTypeDef tdImport,
- mdTypeDef tdEmit)
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- RID ridPropertyMap, ridPropertyMapEmit;
- PropertyMapRec *pPropertyMapRec;
- PropertyRec *pRecImport;
- ULONG ridStart;
- ULONG ridEnd;
- ULONG i;
- mdProperty prImp;
- mdProperty prEmit;
- TOKENREC *pTokenRec;
- LPCUTF8 szName;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- MDTOKENMAP *pCurTkMap;
-
- PropertyMapRec *pPropertyMapEmit;
- PropertyRec *pRecEmit;
- MergeTypeData *pMTD;
- BOOL bSuppressMergeCheck;
- ULONG cImport = 0; // count of non-merge check suppressed properties
- mdCustomAttribute tkCA;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- IfFailGo(pMiniMdImport->FindPropertyMapFor(RidFromToken(tdImport), &ridPropertyMap));
- if (!InvalidRid(ridPropertyMap))
- {
- // Get a count of records already in emit scope.
- IfFailGo(pMiniMdEmit->FindPropertyMapFor(RidFromToken(tdEmit), &ridPropertyMapEmit));
-
- if (InvalidRid(ridPropertyMapEmit))
- {
- // If there is any event, create the PropertyMap record in the emit scope
- // Create new record.
- IfFailGo(pMiniMdEmit->AddPropertyMapRecord(&pPropertyMapEmit, &ridPropertyMapEmit));
-
- // Set parent.
- IfFailGo(pMiniMdEmit->PutToken(TBL_PropertyMap, PropertyMapRec::COL_Parent, pPropertyMapEmit, tdEmit));
- }
-
- // Get a count of records in the import scope; prepare to enumerate them.
- IfFailGo(pMiniMdImport->GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec));
- ridStart = pMiniMdImport->getPropertyListOfPropertyMap(pPropertyMapRec);
- IfFailGo(pMiniMdImport->getEndPropertyListOfPropertyMap(ridPropertyMap, &ridEnd));
-
- pMTD = m_rMTDs.Get(RidFromToken(tdEmit));
-
- for (i = ridStart; i < ridEnd; i++)
- {
- // get the property rid
- IfFailGo(pMiniMdImport->GetPropertyRid(i, (ULONG *)&prImp));
-
- // only verify those Properties that are marked
- if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(TokenFromRid(prImp, mdtProperty)) == false)
- continue;
-
- IfFailGo(pMiniMdImport->GetPropertyRecord(prImp, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfProperty(pRecImport, &szName));
- IfFailGo(pMiniMdImport->getTypeOfProperty(pRecImport, &pbSig, &cbSig));
- prImp = TokenFromRid( prImp, mdtProperty);
-
- // convert rid contained in signature to new scope
- IfFailGo( ImportHelper::MergeUpdateTokenInSig(
- NULL, // Emit assembly.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit) ); // number of bytes write to cbEmit
-
- hr = ImportHelper::FindProperty(
- pMiniMdEmit,
- tdEmit,
- szName,
- (PCCOR_SIGNATURE) qbSig.Ptr(),
- cbEmit,
- &prEmit);
-
- bSuppressMergeCheck = pMTD->m_bSuppressMergeCheck ||
- ((pImportData->m_tkSuppressMergeCheckCtor != mdTokenNil) &&
- (S_OK == ImportHelper::FindCustomAttributeByToken(pMiniMdImport,
- prImp, pImportData->m_tkSuppressMergeCheckCtor, NULL, 0, &tkCA)));
-
- if (bSuppressMergeCheck)
- {
- if (hr == S_OK)
- {
- // Good. We found the matching property when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(prImp, true, prEmit, &pTokenRec) );
- }
- else
- {
- IfFailGo(pMiniMdEmit->AddPropertyRecord(&pRecEmit, (RID *)&prEmit));
-
- // copy the property record over
- IfFailGo( CopyProperty(pImportData, pRecImport, pRecEmit) );
-
- // Add Property to the PropertyMap.
- IfFailGo( pMiniMdEmit->AddPropertyToPropertyMap(ridPropertyMapEmit, prEmit) );
-
- // record the token movement
- prEmit = TokenFromRid(prEmit, mdtProperty);
-
- IfFailGo( pCurTkMap->InsertNotFound(prImp, false, prEmit, &pTokenRec) );
-
- // copy over the method semantics
- IfFailGo( CopyMethodSemantics(pImportData, prImp, prEmit) );
- }
- }
- else
- {
- if (hr == S_OK)
- {
- // Good. We found the matching property when we have a duplicate typedef
- IfFailGo( pCurTkMap->InsertNotFound(prImp, true, prEmit, &pTokenRec) );
- }
- else
- {
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_E_PROP_NOT_FOUND, pImportData, prImp);
- }
-
- cImport++;
- }
- }
-
- // The counts should be the same, unless this is <module>
- if (cImport != pMTD->m_cProperties && tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- {
- CheckContinuableErrorEx(META_E_PROPERTY_COUNTS, pImportData, tdImport);
- // If we are here, the linker says this error is OK.
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyProperties()
-
-
-//*****************************************************************************
-// Verify Parameters given a Method
-//*****************************************************************************
-HRESULT NEWMERGER::VerifyParams(
- MergeImportData *pImportData,
- mdMethodDef mdImport,
- mdMethodDef mdEmit)
-{
- HRESULT hr = NOERROR;
- ParamRec *pRecImport = NULL;
- ParamRec *pRecEmit = NULL;
- MethodRec *pMethodRec;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG ridStart, ridEnd;
- ULONG ridStartEmit, ridEndEmit;
- ULONG cImport, cEmit;
- ULONG i, j;
- mdParamDef pdEmit = 0;
- mdParamDef pdImp;
- TOKENREC *pTokenRec;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // Get count of params in import scope; prepare to enumerate.
- IfFailGo(pMiniMdImport->GetMethodRecord(RidFromToken(mdImport), &pMethodRec));
- ridStart = pMiniMdImport->getParamListOfMethod(pMethodRec);
- IfFailGo(pMiniMdImport->getEndParamListOfMethod(RidFromToken(mdImport), &ridEnd));
- cImport = ridEnd - ridStart;
-
- // Get count of params in emit scope; prepare to enumerate.
- IfFailGo(pMiniMdEmit->GetMethodRecord(RidFromToken(mdEmit), &pMethodRec));
- ridStartEmit = pMiniMdEmit->getParamListOfMethod(pMethodRec);
- IfFailGo(pMiniMdEmit->getEndParamListOfMethod(RidFromToken(mdEmit), &ridEndEmit));
- cEmit = ridEndEmit - ridStartEmit;
-
- // The counts should be the same.
- if (cImport != cEmit)
- {
- // That is, unless this is <module>, so get the method's parent.
- mdTypeDef tdImport;
- IfFailGo(pMiniMdImport->FindParentOfMethodHelper(mdImport, &tdImport));
- if (tdImport != pImportData->m_pRegMetaImport->m_tdModule)
- CheckContinuableErrorEx(META_E_PARAM_COUNTS, pImportData, mdImport);
- // If we are here, the linker says this error is OK.
- }
-
- // loop through all Parameters
- for (i = ridStart; i < ridEnd; i++)
- {
- // Get the importing param row
- IfFailGo(pMiniMdImport->GetParamRid(i, (ULONG *)&pdImp));
-
- // only verify those Params that are marked
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(TokenFromRid(pdImp, mdtParamDef)) == false)
- continue;
-
-
- IfFailGo(pMiniMdImport->GetParamRecord(pdImp, &pRecImport));
- pdImp = TokenFromRid(pdImp, mdtParamDef);
-
- // It turns out when we merge a typelib with itself, the emit and import scope
- // has different sequence of parameter
- //
- // find the corresponding emit param row
- for (j = ridStartEmit; j < ridEndEmit; j++)
- {
- IfFailGo(pMiniMdEmit->GetParamRid(j, (ULONG *)&pdEmit));
- IfFailGo(pMiniMdEmit->GetParamRecord(pdEmit, &pRecEmit));
- if (pRecEmit->GetSequence() == pRecImport->GetSequence())
- break;
- }
-
- if (j == ridEndEmit)
- {
- // did not find the corresponding parameter in the emiting scope
- hr = S_OK; // discard old error; new error will be returned from CheckContinuableError
- CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp);
- }
-
- else
- {
- _ASSERTE( pRecEmit->GetSequence() == pRecImport->GetSequence() );
-
- pdEmit = TokenFromRid(pdEmit, mdtParamDef);
-
- // record the token movement
-#ifdef WE_DONT_NEED_TO_CHECK_NAMES__THEY_DONT_AFFECT_ANYTHING
- LPCUTF8 szNameImp;
- LPCUTF8 szNameEmit;
- IfFailGo(pMiniMdImport->getNameOfParam(pRecImport, &szNameImp));
- IfFailGo(pMiniMdEmit->getNameOfParam(pRecEmit, &szNameEmit));
- if (szNameImp && szNameEmit && strcmp(szNameImp, szNameEmit) != 0)
- {
- // parameter name doesn't match
- CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp);
- }
-#endif
- if (pRecEmit->GetFlags() != pRecImport->GetFlags())
- {
- // flags doesn't match
- CheckContinuableErrorEx(META_S_PARAM_MISMATCH, pImportData, pdImp);
- }
-
- // record token movement. This is a duplicate.
- IfFailGo( pCurTkMap->InsertNotFound(pdImp, true, pdEmit, &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::VerifyParams()
-
-
-//*****************************************************************************
-// merging MemberRef
-//*****************************************************************************
-HRESULT NEWMERGER::MergeMemberRefs( )
-{
- HRESULT hr = NOERROR;
- MemberRefRec *pRecImport = NULL;
- MemberRefRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdMemberRef mrEmit;
- mdMemberRef mrImp;
- bool bDuplicate = false;
- TOKENREC *pTokenRec;
- mdToken tkParentImp;
- mdToken tkParentEmit;
-
- LPCUTF8 szNameImp;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
-
- bool isRefOptimizedToDef;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- iCount = pMiniMdImport->getCountMemberRefs();
-
- // loop through all MemberRef
- for (i = 1; i <= iCount; i++)
- {
-
- // only merge those MemberRefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMemberRefMarked(TokenFromRid(i, mdtMemberRef)) == false)
- continue;
-
- isRefOptimizedToDef = false;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetMemberRefRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getNameOfMemberRef(pRecImport, &szNameImp));
- IfFailGo(pMiniMdImport->getSignatureOfMemberRef(pRecImport, &pbSig, &cbSig));
- tkParentImp = pMiniMdImport->getClassOfMemberRef(pRecImport);
-
- IfFailGo( pCurTkMap->Remap(tkParentImp, &tkParentEmit) );
-
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- // We want to know if we can optimize this MemberRef to a FieldDef or MethodDef
- if (TypeFromToken(tkParentEmit) == mdtTypeDef && RidFromToken(tkParentEmit) != 0)
- {
- // The parent of this MemberRef has been successfully optimized to a TypeDef. Then this MemberRef should be
- // be able to optimized to a MethodDef or FieldDef unless one of the parent in the inheritance hierachy
- // is through TypeRef. Then this MemberRef stay as MemberRef. If This is a VarArg calling convention, then
- // we will remap the MemberRef's parent to a MethodDef or stay as TypeRef.
- //
- mdToken tkParent = tkParentEmit;
- mdToken tkMethDefOrFieldDef;
- PCCOR_SIGNATURE pbSigTmp = (const COR_SIGNATURE *) qbSig.Ptr();
-
- while (TypeFromToken(tkParent) == mdtTypeDef && RidFromToken(tkParent) != 0)
- {
- TypeDefRec *pRec;
- hr = ImportHelper::FindMember(pMiniMdEmit, tkParent, szNameImp, pbSigTmp, cbEmit, &tkMethDefOrFieldDef);
- if (hr == S_OK)
- {
- // We have found a match!!
- if (isCallConv(CorSigUncompressCallingConv(pbSigTmp), IMAGE_CEE_CS_CALLCONV_VARARG))
- {
- // The found MethodDef token will replace this MemberRef's parent token
- _ASSERTE(TypeFromToken(tkMethDefOrFieldDef) == mdtMethodDef);
- tkParentEmit = tkMethDefOrFieldDef;
- break;
- }
- else
- {
- // The found MethodDef/FieldDef token will replace this MemberRef token and we won't introduce a MemberRef
- // record.
- //
- mrEmit = tkMethDefOrFieldDef;
- isRefOptimizedToDef = true;
- bDuplicate = true;
- break;
- }
- }
-
- // now walk up to the parent class of tkParent and try to resolve this MemberRef
- IfFailGo(pMiniMdEmit->GetTypeDefRecord(RidFromToken(tkParent), &pRec));
- tkParent = pMiniMdEmit->getExtendsOfTypeDef(pRec);
- }
-
- // When we exit the loop, there are several possibilities:
- // 1. We found a MethodDef/FieldDef to replace the MemberRef
- // 2. We found a MethodDef matches the MemberRef but the MemberRef is VarArg, thus we want to use the MethodDef in the
- // parent column but not replacing it.
- // 3. We exit because we run out the TypeDef on the parent chain. If it is because we encounter a TypeRef, this TypeRef will
- // replace the parent column of the MemberRef. Or we encounter nil token! (This can be unresolved global MemberRef or
- // compiler error to put an undefined MemberRef. In this case, we should just use the old tkParentEmit
- // on the parent column for the MemberRef.
-
- if (TypeFromToken(tkParent) == mdtTypeRef && RidFromToken(tkParent) != 0)
- {
- // we had walked up the parent's chain to resolve it but we have not been successful and got stopped by a TypeRef.
- // Then we will use this TypeRef as the parent of the emit MemberRef record
- //
- tkParentEmit = tkParent;
- }
- }
- else if ((TypeFromToken(tkParentEmit) == mdtMethodDef &&
- !isCallConv(CorSigUncompressCallingConv(pbSig), IMAGE_CEE_CS_CALLCONV_VARARG)) ||
- (TypeFromToken(tkParentEmit) == mdtFieldDef))
- {
- // If the MemberRef's parent is already a non-vararg MethodDef or FieldDef, we can also
- // safely drop the MemberRef
- mrEmit = tkParentEmit;
- isRefOptimizedToDef = true;
- bDuplicate = true;
- }
-
- // If the Ref cannot be optimized to a Def or MemberRef to Def optmization is turned off, do the following.
- if (isRefOptimizedToDef == false || !((m_optimizeRefToDef & MDMemberRefToDef) == MDMemberRefToDef))
- {
- // does this MemberRef already exist in the emit scope?
- if ( m_fDupCheck && ImportHelper::FindMemberRef(
- pMiniMdEmit,
- tkParentEmit,
- szNameImp,
- (const COR_SIGNATURE *) qbSig.Ptr(),
- cbEmit,
- &mrEmit) == S_OK )
- {
- // Yes, it does
- bDuplicate = true;
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddMemberRefRecord(&pRecEmit, (RID *)&mrEmit));
- mrEmit = TokenFromRid( mrEmit, mdtMemberRef );
-
- // Copy over the MemberRef context
- IfFailGo(pMiniMdEmit->PutString(TBL_MemberRef, MemberRefRec::COL_Name, pRecEmit, szNameImp));
- IfFailGo(pMiniMdEmit->PutToken(TBL_MemberRef, MemberRefRec::COL_Class, pRecEmit, tkParentEmit));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_MemberRef, MemberRefRec::COL_Signature, pRecEmit,
- qbSig.Ptr(), cbEmit));
- IfFailGo(pMiniMdEmit->AddMemberRefToHash(mrEmit) );
- }
- }
- // record the token movement
- mrImp = TokenFromRid(i, mdtMemberRef);
- IfFailGo( pCurTkMap->InsertNotFound(mrImp, bDuplicate, mrEmit, &pTokenRec) );
- }
- }
-
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeMemberRefs()
-
-
-//*****************************************************************************
-// merge interface impl
-//*****************************************************************************
-HRESULT NEWMERGER::MergeInterfaceImpls( )
-{
- HRESULT hr = NOERROR;
- InterfaceImplRec *pRecImport = NULL;
- InterfaceImplRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdTypeDef tkParent;
- mdInterfaceImpl iiEmit;
- bool bDuplicate;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountInterfaceImpls();
-
- // loop through all InterfaceImpl
- for (i = 1; i <= iCount; i++)
- {
- // only merge those InterfaceImpls that are marked
- if ( pMiniMdImport->GetFilterTable()->IsInterfaceImplMarked(TokenFromRid(i, mdtInterfaceImpl)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetInterfaceImplRecord(i, &pRecImport));
- tkParent = pMiniMdImport->getClassOfInterfaceImpl(pRecImport);
-
- // does this TypeRef already exist in the emit scope?
- if ( pCurTkMap->Find(tkParent, &pTokenRec) )
- {
- if ( pTokenRec->m_isDuplicate )
- {
- // parent in the emit scope
- mdToken tkParentEmit;
- mdToken tkInterface;
-
- // remap the typedef token
- tkParentEmit = pTokenRec->m_tkTo;
-
- // remap the implemented interface token
- tkInterface = pMiniMdImport->getInterfaceOfInterfaceImpl(pRecImport);
- IfFailGo( pCurTkMap->Remap( tkInterface, &tkInterface) );
-
- // Set duplicate flag
- bDuplicate = true;
-
- // find the corresponding interfaceimpl in the emit scope
- if ( ImportHelper::FindInterfaceImpl(pMiniMdEmit, tkParentEmit, tkInterface, &iiEmit) != S_OK )
- {
- // bad state!! We have a duplicate typedef but the interface impl is not the same!!
-
- // continuable error
- CheckContinuableErrorEx(
- META_E_INTFCEIMPL_NOT_FOUND,
- pImportData,
- TokenFromRid(i, mdtInterfaceImpl));
-
- iiEmit = mdTokenNil;
- }
- }
- else
- {
- // No, it doesn't. Copy it over.
- bDuplicate = false;
- IfFailGo(pMiniMdEmit->AddInterfaceImplRecord(&pRecEmit, (RID *)&iiEmit));
-
- // copy the interfaceimp record over
- IfFailGo( CopyInterfaceImpl( pRecEmit, pImportData, pRecImport) );
- }
- }
- else
- {
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
- // record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtInterfaceImpl),
- bDuplicate,
- TokenFromRid( iiEmit, mdtInterfaceImpl ),
- &pTokenRec) );
- }
- }
-
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeInterfaceImpls()
-
-
-//*****************************************************************************
-// merge all of the constant for field, property, and parameter
-//*****************************************************************************
-HRESULT NEWMERGER::MergeConstants()
-{
- HRESULT hr = NOERROR;
- ConstantRec *pRecImport = NULL;
- ConstantRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG csEmit; // constant value is not a token
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- void const *pValue;
- ULONG cbBlob;
-#if _DEBUG
- ULONG typeParent;
-#endif // _DEBUG
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountConstants();
-
- // loop through all Constants
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetConstantRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfConstant(pRecImport);
-
- // only move those constant over if their parents are marked
- // If MDTOKENMAP::Find returns false, we don't need to copy the constant value over
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- // If the parent is duplicated, no need to move over the constant value
- if ( !pTokenRec->m_isDuplicate )
- {
- IfFailGo(pMiniMdEmit->AddConstantRecord(&pRecEmit, &csEmit));
- pRecEmit->SetType(pRecImport->GetType());
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(TBL_Constant, ConstantRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo) );
-
- // move over the constant blob value
- IfFailGo(pMiniMdImport->getValueOfConstant(pRecImport, (const BYTE **)&pValue, &cbBlob));
- IfFailGo( pMiniMdEmit->PutBlob(TBL_Constant, ConstantRec::COL_Value, pRecEmit, pValue, cbBlob) );
- IfFailGo( pMiniMdEmit->AddConstantToHash(csEmit) );
- }
- else
- {
- // <TODO>@FUTURE: more verification on the duplicate??</TODO>
- }
- }
-#if _DEBUG
- // Include this block only under Debug build. The reason is that
- // the linker chooses all the errors that we report (such as unmatched MethodDef or FieldDef)
- // as a continuable error. It is likely to hit this else while the tkparentImp is marked if there
- // is any error reported earlier!!
- else
- {
- typeParent = TypeFromToken(tkParentImp);
- if (typeParent == mdtFieldDef)
- {
- // FieldDef should not be marked.
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkParentImp) == false)
- continue;
- }
- else if (typeParent == mdtParamDef)
- {
- // ParamDef should not be marked.
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(tkParentImp) == false)
- continue;
- }
- else
- {
- _ASSERTE(typeParent == mdtProperty);
- // Property should not be marked.
- if ( pMiniMdImport->GetFilterTable()->IsPropertyMarked(tkParentImp) == false)
- continue;
- }
-
- // If we come to here, we have a constant whose parent is marked but we could not
- // find it in the map!! Bad state.
-
- _ASSERTE(!"Ignore this error if you have seen error reported earlier! Otherwise bad token map or bad metadata!");
- }
-#endif // _DEBUG
- // Note that we don't need to record the token movement since constant is not a valid token kind.
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeConstants()
-
-
-//*****************************************************************************
-// Merge field marshal information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFieldMarshals()
-{
- HRESULT hr = NOERROR;
- FieldMarshalRec *pRecImport = NULL;
- FieldMarshalRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG fmEmit; // FieldMarhsal is not a token
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- void const *pValue;
- ULONG cbBlob;
-#if _DEBUG
- ULONG typeParent;
-#endif // _DEBUG
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFieldMarshals();
-
- // loop through all TypeRef
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldMarshalRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfFieldMarshal(pRecImport);
-
- // We want to merge only those field marshals that parents are marked.
- // Find will return false if the parent is not marked
- //
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- // If the parent is duplicated, no need to move over the constant value
- if ( !pTokenRec->m_isDuplicate )
- {
- IfFailGo(pMiniMdEmit->AddFieldMarshalRecord(&pRecEmit, &fmEmit));
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(
- TBL_FieldMarshal,
- FieldMarshalRec::COL_Parent,
- pRecEmit,
- pTokenRec->m_tkTo) );
-
- // move over the constant blob value
- IfFailGo(pMiniMdImport->getNativeTypeOfFieldMarshal(pRecImport, (const BYTE **)&pValue, &cbBlob));
- IfFailGo( pMiniMdEmit->PutBlob(TBL_FieldMarshal, FieldMarshalRec::COL_NativeType, pRecEmit, pValue, cbBlob) );
- IfFailGo( pMiniMdEmit->AddFieldMarshalToHash(fmEmit) );
-
- }
- else
- {
- // <TODO>@FUTURE: more verification on the duplicate??</TODO>
- }
- }
-#if _DEBUG
- else
- {
- typeParent = TypeFromToken(tkParentImp);
-
- if (typeParent == mdtFieldDef)
- {
- // FieldDefs should not be marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkParentImp) == false)
- continue;
- }
- else
- {
- _ASSERTE(typeParent == mdtParamDef);
- // ParamDefs should not be marked
- if ( pMiniMdImport->GetFilterTable()->IsParamMarked(tkParentImp) == false)
- continue;
- }
-
- // If we come to here, that is we have a FieldMarshal whose parent is marked and we don't find it
- // in the map!!!
-
- // either bad lookup map or bad metadata
- _ASSERTE(!"Ignore this assert if you have seen error reported earlier. Otherwise, it is bad state!");
- }
-#endif // _DEBUG
- }
- // Note that we don't need to record the token movement since FieldMarshal is not a valid token kind.
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFieldMarshals()
-
-
-//*****************************************************************************
-// Merge class layout information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeClassLayouts()
-{
- HRESULT hr = NOERROR;
- ClassLayoutRec *pRecImport = NULL;
- ClassLayoutRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG iRecord; // class layout is not a token
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- RID ridClassLayout;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountClassLayouts();
-
- // loop through all TypeRef
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetClassLayoutRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfClassLayout(pRecImport);
-
- // only merge those TypeDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsTypeDefMarked(tkParentImp) == false)
- continue;
-
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the parent is not duplicated, just copy over the classlayout information
- IfFailGo(pMiniMdEmit->AddClassLayoutRecord(&pRecEmit, &iRecord));
-
- // copy over the fix part information
- pRecEmit->Copy(pRecImport);
- IfFailGo( pMiniMdEmit->PutToken(TBL_ClassLayout, ClassLayoutRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo));
- IfFailGo( pMiniMdEmit->AddClassLayoutToHash(iRecord) );
- }
- else
- {
-
- IfFailGo(pMiniMdEmit->FindClassLayoutHelper(pTokenRec->m_tkTo, &ridClassLayout));
-
- if (InvalidRid(ridClassLayout))
- {
- // class is duplicated but not class layout info
- CheckContinuableErrorEx(META_E_CLASS_LAYOUT_INCONSISTENT, pImportData, tkParentImp);
- }
- else
- {
- IfFailGo(pMiniMdEmit->GetClassLayoutRecord(RidFromToken(ridClassLayout), &pRecEmit));
- if (pMiniMdImport->getPackingSizeOfClassLayout(pRecImport) != pMiniMdEmit->getPackingSizeOfClassLayout(pRecEmit) ||
- pMiniMdImport->getClassSizeOfClassLayout(pRecImport) != pMiniMdEmit->getClassSizeOfClassLayout(pRecEmit) )
- {
- CheckContinuableErrorEx(META_E_CLASS_LAYOUT_INCONSISTENT, pImportData, tkParentImp);
- }
- }
- }
- }
- else
- {
- // bad lookup map
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // no need to record the index movement. Classlayout is not a token.
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeClassLayouts()
-
-//*****************************************************************************
-// Merge field layout information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFieldLayouts()
-{
- HRESULT hr = NOERROR;
- FieldLayoutRec *pRecImport = NULL;
- FieldLayoutRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG iRecord; // field layout2 is not a token.
- mdToken tkFieldImp;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFieldLayouts();
-
- // loop through all FieldLayout records.
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldLayoutRecord(i, &pRecImport));
- tkFieldImp = pMiniMdImport->getFieldOfFieldLayout(pRecImport);
-
- // only merge those FieldDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(tkFieldImp) == false)
- continue;
-
- if ( pCurTkMap->Find(tkFieldImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the Field is not duplicated, just copy over the FieldLayout information
- IfFailGo(pMiniMdEmit->AddFieldLayoutRecord(&pRecEmit, &iRecord));
-
- // copy over the fix part information
- pRecEmit->Copy(pRecImport);
- IfFailGo( pMiniMdEmit->PutToken(TBL_FieldLayout, FieldLayoutRec::COL_Field, pRecEmit, pTokenRec->m_tkTo));
- IfFailGo( pMiniMdEmit->AddFieldLayoutToHash(iRecord) );
- }
- else
- {
- // <TODO>@FUTURE: more verification??</TODO>
- }
- }
- else
- {
- // bad lookup map
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // no need to record the index movement. fieldlayout2 is not a token.
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFieldLayouts()
-
-
-//*****************************************************************************
-// Merge field RVAs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFieldRVAs()
-{
- HRESULT hr = NOERROR;
- FieldRVARec *pRecImport = NULL;
- FieldRVARec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- ULONG iRecord; // FieldRVA is not a token.
- mdToken tkFieldImp;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFieldRVAs();
-
- // loop through all FieldRVA records.
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetFieldRVARecord(i, &pRecImport));
- tkFieldImp = pMiniMdImport->getFieldOfFieldRVA(pRecImport);
-
- // only merge those FieldDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsFieldMarked(TokenFromRid(tkFieldImp, mdtFieldDef)) == false)
- continue;
-
- if ( pCurTkMap->Find(tkFieldImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the Field is not duplicated, just copy over the FieldRVA information
- IfFailGo(pMiniMdEmit->AddFieldRVARecord(&pRecEmit, &iRecord));
-
- // copy over the fix part information
- pRecEmit->Copy(pRecImport);
- IfFailGo( pMiniMdEmit->PutToken(TBL_FieldRVA, FieldRVARec::COL_Field, pRecEmit, pTokenRec->m_tkTo));
- IfFailGo( pMiniMdEmit->AddFieldRVAToHash(iRecord) );
- }
- else
- {
- // <TODO>@FUTURE: more verification??</TODO>
- }
- }
- else
- {
- // bad lookup map
- _ASSERTE( !"bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // no need to record the index movement. FieldRVA is not a token.
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFieldRVAs()
-
-
-//*****************************************************************************
-// Merge MethodImpl information
-//*****************************************************************************
-HRESULT NEWMERGER::MergeMethodImpls()
-{
- HRESULT hr = NOERROR;
- MethodImplRec *pRecImport = NULL;
- MethodImplRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- RID iRecord;
- mdTypeDef tkClassImp;
- mdToken tkBodyImp;
- mdToken tkDeclImp;
- TOKENREC *pTokenRecClass;
- mdToken tkBodyEmit;
- mdToken tkDeclEmit;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountMethodImpls();
-
- // loop through all the MethodImpls.
- for (i = 1; i <= iCount; i++)
- {
- // only merge those MethodImpls that are marked.
- if ( pMiniMdImport->GetFilterTable()->IsMethodImplMarked(i) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetMethodImplRecord(i, &pRecImport));
- tkClassImp = pMiniMdImport->getClassOfMethodImpl(pRecImport);
- tkBodyImp = pMiniMdImport->getMethodBodyOfMethodImpl(pRecImport);
- tkDeclImp = pMiniMdImport->getMethodDeclarationOfMethodImpl(pRecImport);
-
- if ( pCurTkMap->Find(tkClassImp, &pTokenRecClass))
- {
- // If the TypeDef is duplicated, no need to move over the MethodImpl record.
- if ( !pTokenRecClass->m_isDuplicate )
- {
- // Create a new record and set the data.
-
- // <TODO>@FUTURE: We might want to consider changing the error for the remap into a continuable error.
- // Because we probably can continue merging for more data...</TODO>
-
- IfFailGo( pCurTkMap->Remap(tkBodyImp, &tkBodyEmit) );
- IfFailGo( pCurTkMap->Remap(tkDeclImp, &tkDeclEmit) );
- IfFailGo(pMiniMdEmit->AddMethodImplRecord(&pRecEmit, &iRecord));
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_Class, pRecEmit, pTokenRecClass->m_tkTo) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_MethodBody, pRecEmit, tkBodyEmit) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodImpl, MethodImplRec::COL_MethodDeclaration, pRecEmit, tkDeclEmit) );
- IfFailGo( pMiniMdEmit->AddMethodImplToHash(iRecord) );
- }
- else
- {
- // <TODO>@FUTURE: more verification on the duplicate??</TODO>
- }
- // No need to record the token movement, MethodImpl is not a token.
- }
- else
- {
- // either bad lookup map or bad metadata
- _ASSERTE(!"bad state");
- IfFailGo( META_E_BADMETADATA );
- }
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeMethodImpls()
-
-
-//*****************************************************************************
-// Merge PInvoke
-//*****************************************************************************
-HRESULT NEWMERGER::MergePinvoke()
-{
- HRESULT hr = NOERROR;
- ImplMapRec *pRecImport = NULL;
- ImplMapRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdModuleRef mrImp;
- mdModuleRef mrEmit;
- mdMethodDef mdImp;
- RID mdImplMap;
- TOKENREC *pTokenRecMR;
- TOKENREC *pTokenRecMD;
-
- USHORT usMappingFlags;
- LPCUTF8 szImportName;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountImplMaps();
-
- // loop through all ImplMaps
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetImplMapRecord(i, &pRecImport));
-
- // Get the MethodDef token in the new space.
- mdImp = pMiniMdImport->getMemberForwardedOfImplMap(pRecImport);
-
- // only merge those MethodDefs that are marked
- if ( pMiniMdImport->GetFilterTable()->IsMethodMarked(mdImp) == false)
- continue;
-
- // Get the ModuleRef token in the new space.
- mrImp = pMiniMdImport->getImportScopeOfImplMap(pRecImport);
-
- // map the token to the new scope
- if (pCurTkMap->Find(mrImp, &pTokenRecMR) == false)
- {
- // This should never fire unless the module refs weren't merged
- // before this code ran.
- _ASSERTE(!"Parent ModuleRef not found in MERGER::MergePinvoke. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
- // If the ModuleRef has been remapped to the "module token", we need to undo that
- // for the pinvokeimpl. A pinvoke can only have a ModuleRef for the ImportScope.
- mrEmit = pTokenRecMR->m_tkTo;
- if (mrEmit == MODULEDEFTOKEN)
- { // Yes, the ModuleRef has been remapped to the module token. So,
- // find the ModuleRef in the output scope; if it is not found, add
- // it.
- ModuleRefRec *pModRefImport;
- LPCUTF8 szNameImp;
- IfFailGo(pMiniMdImport->GetModuleRefRecord(RidFromToken(mrImp), &pModRefImport));
- IfFailGo(pMiniMdImport->getNameOfModuleRef(pModRefImport, &szNameImp));
-
- // does this ModuleRef already exist in the emit scope?
- hr = ImportHelper::FindModuleRef(pMiniMdEmit,
- szNameImp,
- &mrEmit);
-
- if (hr == CLDB_E_RECORD_NOTFOUND)
- { // No, it doesn't. Copy it over.
- ModuleRefRec *pModRefEmit;
- IfFailGo(pMiniMdEmit->AddModuleRefRecord(&pModRefEmit, (RID*)&mrEmit));
- mrEmit = TokenFromRid(mrEmit, mdtModuleRef);
-
- // Set ModuleRef Name.
- IfFailGo( pMiniMdEmit->PutString(TBL_ModuleRef, ModuleRefRec::COL_Name, pModRefEmit, szNameImp) );
- }
- else
- IfFailGo(hr);
- }
-
-
- if (pCurTkMap->Find(mdImp, &pTokenRecMD) == false)
- {
- // This should never fire unless the method defs weren't merged
- // before this code ran.
- _ASSERTE(!"Parent MethodDef not found in MERGER::MergePinvoke. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
-
-
- // Get copy of rest of data.
- usMappingFlags = pMiniMdImport->getMappingFlagsOfImplMap(pRecImport);
- IfFailGo(pMiniMdImport->getImportNameOfImplMap(pRecImport, &szImportName));
-
- // If the method associated with PInvokeMap is not duplicated, then don't bother to look up the
- // duplicated PInvokeMap information.
- if (pTokenRecMD->m_isDuplicate == true)
- {
- // Does the correct ImplMap entry exist in the emit scope?
- IfFailGo(pMiniMdEmit->FindImplMapHelper(pTokenRecMD->m_tkTo, &mdImplMap));
- }
- else
- {
- mdImplMap = mdTokenNil;
- }
- if (!InvalidRid(mdImplMap))
- {
- // Verify that the rest of the data is identical, else it's an error.
- IfFailGo(pMiniMdEmit->GetImplMapRecord(mdImplMap, &pRecEmit));
- _ASSERTE(pMiniMdEmit->getMemberForwardedOfImplMap(pRecEmit) == pTokenRecMD->m_tkTo);
- LPCSTR szImplMapImportName;
- IfFailGo(pMiniMdEmit->getImportNameOfImplMap(pRecEmit, &szImplMapImportName));
- if (pMiniMdEmit->getImportScopeOfImplMap(pRecEmit) != mrEmit ||
- pMiniMdEmit->getMappingFlagsOfImplMap(pRecEmit) != usMappingFlags ||
- strcmp(szImplMapImportName, szImportName))
- {
- // Mismatched p-invoke entries are found.
- _ASSERTE(!"Mismatched P-invoke entries during merge. Bad State!");
- IfFailGo(E_FAIL);
- }
- }
- else
- {
- IfFailGo(pMiniMdEmit->AddImplMapRecord(&pRecEmit, &mdImplMap));
-
- // Copy rest of data.
- IfFailGo( pMiniMdEmit->PutToken(TBL_ImplMap, ImplMapRec::COL_MemberForwarded, pRecEmit, pTokenRecMD->m_tkTo) );
- IfFailGo( pMiniMdEmit->PutToken(TBL_ImplMap, ImplMapRec::COL_ImportScope, pRecEmit, mrEmit) );
- IfFailGo( pMiniMdEmit->PutString(TBL_ImplMap, ImplMapRec::COL_ImportName, pRecEmit, szImportName) );
- pRecEmit->SetMappingFlags(usMappingFlags);
- IfFailGo( pMiniMdEmit->AddImplMapToHash(mdImplMap) );
- }
- }
- }
-
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergePinvoke()
-
-
-//*****************************************************************************
-// Merge StandAloneSigs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeStandAloneSigs()
-{
- HRESULT hr = NOERROR;
- StandAloneSigRec *pRecImport = NULL;
- StandAloneSigRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- TOKENREC *pTokenRec;
- mdSignature saImp;
- mdSignature saEmit;
- bool fDuplicate;
- PCCOR_SIGNATURE pbSig;
- ULONG cbSig;
- ULONG cbEmit;
- CQuickBytes qbSig;
- PCOR_SIGNATURE rgSig;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountStandAloneSigs();
-
- // loop through all Signatures
- for (i = 1; i <= iCount; i++)
- {
- // only merge those Signatures that are marked
- if ( pMiniMdImport->GetFilterTable()->IsSignatureMarked(TokenFromRid(i, mdtSignature)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetStandAloneSigRecord(i, &pRecImport));
- IfFailGo(pMiniMdImport->getSignatureOfStandAloneSig(pRecImport, &pbSig, &cbSig));
-
- // This is a signature containing the return type after count of args
- // convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Assembly import scope info.
- pMiniMdImport, // The scope to merge into the emit scope.
- pbSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
- rgSig = ( PCOR_SIGNATURE ) qbSig.Ptr();
-
- hr = ImportHelper::FindStandAloneSig(
- pMiniMdEmit,
- rgSig,
- cbEmit,
- &saEmit );
- if ( hr == S_OK )
- {
- // find a duplicate
- fDuplicate = true;
- }
- else
- {
- // copy over
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddStandAloneSigRecord(&pRecEmit, (ULONG *)&saEmit));
- saEmit = TokenFromRid(saEmit, mdtSignature);
- IfFailGo( pMiniMdEmit->PutBlob(TBL_StandAloneSig, StandAloneSigRec::COL_Signature, pRecEmit, rgSig, cbEmit));
- }
- saImp = TokenFromRid(i, mdtSignature);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(saImp, fDuplicate, saEmit, &pTokenRec) );
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeStandAloneSigs()
-
-//*****************************************************************************
-// Merge MethodSpecs
-//*****************************************************************************
-HRESULT NEWMERGER::MergeMethodSpecs()
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdToken tk;
- ULONG iRecord;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- // Loop through all MethodSpec
- iCount = pMiniMdImport->getCountMethodSpecs();
- for (i=1; i<=iCount; ++i)
- {
- MethodSpecRec *pRecImport;
- MethodSpecRec *pRecEmit;
- TOKENREC *pTokenRecMethod;
- TOKENREC *pTokenRecMethodNew;
- PCCOR_SIGNATURE pvSig;
- ULONG cbSig;
- CQuickBytes qbSig;
- ULONG cbEmit;
-
- // Only copy marked records.
- if (!pMiniMdImport->GetFilterTable()->IsMethodSpecMarked(i))
- continue;
-
- IfFailGo(pMiniMdImport->GetMethodSpecRecord(i, &pRecImport));
- tk = pMiniMdImport->getMethodOfMethodSpec(pRecImport);
-
- // Map the token to the new scope.
- if (pCurTkMap->Find(tk, &pTokenRecMethod) == false)
- {
- // This should never fire unless the TypeDefs/Refs weren't merged
- // before this code runs.
- _ASSERTE(!"MethodSpec method not found in MERGER::MergeGenericsInfo. Bad state!");
- IfFailGo( META_E_BADMETADATA );
- }
- // Copy to output scope.
- IfFailGo(pMiniMdEmit->AddMethodSpecRecord(&pRecEmit, &iRecord));
- IfFailGo( pMiniMdEmit->PutToken(TBL_MethodSpec, MethodSpecRec::COL_Method, pRecEmit, pTokenRecMethod->m_tkTo));
-
- // Copy the signature, translating any embedded tokens.
- IfFailGo(pMiniMdImport->getInstantiationOfMethodSpec(pRecImport, &pvSig, &cbSig));
-
- // ...convert rid contained in signature to new scope
- IfFailGo(ImportHelper::MergeUpdateTokenInSig(
- NULL, // Assembly emit scope.
- pMiniMdEmit, // The emit scope.
- NULL, NULL, 0, // Import assembly scope information.
- pMiniMdImport, // The scope to merge into the emit scope.
- pvSig, // signature from the imported scope
- pCurTkMap, // Internal token mapping structure.
- &qbSig, // [OUT] translated signature
- 0, // start from first byte of the signature
- 0, // don't care how many bytes consumed
- &cbEmit)); // number of bytes write to cbEmit
-
- // ...persist the converted signature
- IfFailGo( pMiniMdEmit->PutBlob(TBL_MethodSpec, MethodSpecRec::COL_Instantiation, pRecEmit, qbSig.Ptr(), cbEmit) );
-
- IfFailGo( pCurTkMap->InsertNotFound(TokenFromRid(i, mdtMethodSpec), false,
- TokenFromRid(iRecord, mdtMethodSpec), &pTokenRecMethodNew) );
- }
- }
-
- ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeMethodSpecs()
-
-//*****************************************************************************
-// Merge DeclSecuritys
-//*****************************************************************************
-HRESULT NEWMERGER::MergeDeclSecuritys()
-{
- HRESULT hr = NOERROR;
- DeclSecurityRec *pRecImport = NULL;
- DeclSecurityRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdToken tkParentImp;
- TOKENREC *pTokenRec;
- void const *pValue;
- ULONG cbBlob;
- mdPermission pmImp;
- mdPermission pmEmit;
- bool fDuplicate;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountDeclSecuritys();
-
- // loop through all DeclSecurity
- for (i = 1; i <= iCount; i++)
- {
- // only merge those DeclSecurities that are marked
- if ( pMiniMdImport->GetFilterTable()->IsDeclSecurityMarked(TokenFromRid(i, mdtPermission)) == false)
- continue;
-
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetDeclSecurityRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfDeclSecurity(pRecImport);
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- if ( !pTokenRec->m_isDuplicate )
- {
- // If the parent is not duplicated, just copy over the custom value
- goto CopyPermission;
- }
- else
- {
- // Try to see if the Permission is there in the emit scope or not.
- // If not, move it over still
- if ( ImportHelper::FindPermission(
- pMiniMdEmit,
- pTokenRec->m_tkTo,
- pRecImport->GetAction(),
- &pmEmit) == S_OK )
- {
- // found a match
- // <TODO>@FUTURE: more verification??</TODO>
- fDuplicate = true;
- }
- else
- {
- // Parent is duplicated but the Permission is not. Still copy over the
- // Permission.
-CopyPermission:
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddDeclSecurityRecord(&pRecEmit, (ULONG *)&pmEmit));
- pmEmit = TokenFromRid(pmEmit, mdtPermission);
-
- pRecEmit->Copy(pRecImport);
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(
- TBL_DeclSecurity,
- DeclSecurityRec::COL_Parent,
- pRecEmit,
- pTokenRec->m_tkTo) );
-
- // move over the CustomAttribute blob value
- IfFailGo(pMiniMdImport->getPermissionSetOfDeclSecurity(pRecImport, (const BYTE **)&pValue, &cbBlob));
- IfFailGo(pMiniMdEmit->PutBlob(
- TBL_DeclSecurity,
- DeclSecurityRec::COL_PermissionSet,
- pRecEmit,
- pValue,
- cbBlob));
- }
- }
- pmEmit = TokenFromRid(pmEmit, mdtPermission);
- pmImp = TokenFromRid(i, mdtPermission);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(pmImp, fDuplicate, pmEmit, &pTokenRec) );
- }
- else
- {
- // bad lookup map
- _ASSERTE(!"bad state");
- IfFailGo( META_E_BADMETADATA );
- }
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeDeclSecuritys()
-
-
-//*****************************************************************************
-// Merge Strings
-//*****************************************************************************
-HRESULT NEWMERGER::MergeStrings()
-{
- HRESULT hr = NOERROR;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- for (UINT32 nIndex = 0; ;)
- {
- MetaData::DataBlob userString;
- UINT32 nNextIndex;
- UINT32 nEmitIndex;
-
- hr = pMiniMdImport->GetUserStringAndNextIndex(
- nIndex,
- &userString,
- &nNextIndex);
- IfFailGo(hr);
- if (hr == S_FALSE)
- { // We reached the last user string
- hr = S_OK;
- break;
- }
- _ASSERTE(hr == S_OK);
-
- // Skip empty strings
- if (userString.IsEmpty())
- {
- nIndex = nNextIndex;
- continue;
- }
-
- if (pMiniMdImport->GetFilterTable()->IsUserStringMarked(TokenFromRid(nIndex, mdtString)) == false)
- {
- // Process next user string in the heap
- nIndex = nNextIndex;
- continue;
- }
-
- IfFailGo(pMiniMdEmit->PutUserString(
- userString,
- &nEmitIndex));
-
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(nIndex, mdtString),
- false,
- TokenFromRid(nEmitIndex, mdtString),
- &pTokenRec));
-
- // Process next user string in the heap
- nIndex = nNextIndex;
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeStrings()
-
-// Helper method to merge the module-level security critical attributes
-// Strips all module-level security critical attribute [that won't be ultimately needed]
-// Returns:
-// FAILED(hr): Failure occurred retrieving metadata or parsing scopes
-// S_OK: Attribute should be merged into final output scope
-// S_FALSE: Attribute should be ignored/dropped from output scope
-HRESULT NEWMERGER::MergeSecurityCriticalModuleLevelAttributes(
- MergeImportData* pImportData, // import scope
- mdToken tkParentImp, // parent token with attribute
- TOKENREC* pTypeRec, // token record of attribute ctor
- mdToken mrSecurityTreatAsSafeAttributeCtor, // 'generic' TAS attribute token
- mdToken mrSecurityTransparentAttributeCtor, // 'generic' Transparent attribute token
- mdToken mrSecurityCriticalExplicitAttributeCtor, // 'generic' Critical attribute token
- mdToken mrSecurityCriticalEverythingAttributeCtor)
-{
- HRESULT hr = S_OK;
-
- // if ANY assembly-level critical attributes were specified, then we'll output
- // one assembly-level Critical(Explicit) attribute only
- // AND if this scope has tags
- if (ISSCS_Unknown != pImportData->m_isscsSecurityCriticalStatus)
- {
- _ASSERTE(ISSCS_Unknown != m_isscsSecurityCritical);
- // drop only assembly-level attributes
- TypeRefRec* pTypeRefRec;
- // metadata emitter
- CMiniMdRW* pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // if compiler is generating a module - then this will be a module token
- LPCSTR szTypeRefName;
- if (tkParentImp == MODULEDEFTOKEN ||
- // otherwise, if merging assemblies, we have a fake type ref called MODULE_CA_LOCATION
- (TypeFromToken(tkParentImp) == mdtTypeRef &&
- (IsAttributeFromNamespace(pMiniMdImport, tkParentImp,
- COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME,
- &pTypeRefRec) == S_OK) &&
- (pMiniMdImport->getNameOfTypeRef(pTypeRefRec, &szTypeRefName) == S_OK) &&
- (strcmp(MODULE_CA_TYPENAME, szTypeRefName) == 0)))
- {
- // drop the TAS attribute (unless all scopes have TAS)
- if ( pTypeRec->m_tkTo == mrSecurityTreatAsSafeAttributeCtor )
- {
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTreatAsSafe) ==
- ISSCS_SecurityTreatAsSafe)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityTreatAsSafe) ==
- ISSCS_SecurityTreatAsSafe);
- return S_OK;
- }
- return S_FALSE;
- }
- // drop the Transparent attribute (unless all scopes have Transparent)
- else if (pTypeRec->m_tkTo == mrSecurityTransparentAttributeCtor)
- {
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTransparent) ==
- ISSCS_SecurityTransparent)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityTransparent) ==
- ISSCS_SecurityTransparent);
- return S_OK;
- }
- return S_FALSE;
- }
- else if (pTypeRec->m_tkTo == mrSecurityCriticalExplicitAttributeCtor)
- {
- // if NOT Critical Everything, then leave the Critical.Explicit attribute
- // the Critical.Explicit attribute will be used as the final global attribute
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) !=
- ISSCS_SecurityCriticalEverything)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityCriticalExplicit) ==
- ISSCS_SecurityCriticalExplicit);
- return S_OK;
- }
- else
- {
- // drop this attribute
- return S_FALSE;
- }
- }
- else if (pTypeRec->m_tkTo == mrSecurityCriticalEverythingAttributeCtor)
- {
- // OPTIMIZATION: if all attributes are Critical.Everything,
- // then leave the global Critical attribute
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) ==
- ISSCS_SecurityCriticalEverything)
- {
- _ASSERTE((pImportData->m_isscsSecurityCriticalStatus & ISSCS_SecurityCriticalEverything) ==
- ISSCS_SecurityCriticalEverything);
- return S_OK;
- }
- else
- {
- // drop this attribute
- return S_FALSE;
- }
- }
- }
- }
-
- return hr;
-} // NEWMERGER::MergeSecurityCriticalModuleLevelAttributes
-
-// HELPER: Retrieve the meta-data info related to SecurityCritical
-HRESULT NEWMERGER::RetrieveStandardSecurityCriticalMetaData(
- mdAssemblyRef& tkMscorlib,
- mdTypeRef& securityEnum,
- BYTE*& rgSigBytesSecurityCriticalEverythingCtor,
- DWORD& dwSigEverythingSize,
- BYTE*& rgSigBytesSecurityCriticalExplicitCtor,
- DWORD& dwSigExplicitSize)
-{
- HRESULT hr = S_OK;
-
- CMiniMdRW* emit = GetMiniMdEmit();
-
- // get typeref for mscorlib
- BYTE pbMscorlibToken[] = COR_MSCORLIB_TYPEREF;
- BYTE* pCurr = rgSigBytesSecurityCriticalEverythingCtor;
-
- IfFailGo(ImportHelper::FindAssemblyRef(emit,
- COR_MSCORLIB_NAME,
- NULL,
- pbMscorlibToken,
- sizeof(pbMscorlibToken),
- asm_rmj,
- asm_rmm,
- asm_rup,
- asm_rpt,
- 0,
- &tkMscorlib));
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(tkMscorlib,
- COR_SECURITYCRITICALSCOPE_ENUM_W,
- &securityEnum));
-
- // build the constructor sig that takes SecurityCriticalScope argument
- if (rgSigBytesSecurityCriticalEverythingCtor)
- {
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = COR_SECURITYCRITICAL_CTOR_ARGCOUNT_SCOPE_EVERYTHING; // one argument to constructor
- *pCurr++ = ELEMENT_TYPE_VOID;
- *pCurr++ = ELEMENT_TYPE_VALUETYPE;
- pCurr += CorSigCompressToken(securityEnum, pCurr);
- dwSigEverythingSize = (DWORD)(pCurr - rgSigBytesSecurityCriticalEverythingCtor);
- _ASSERTE(dwSigEverythingSize <= COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE);
- }
-
- // if Explicit ctor is requested
- if (rgSigBytesSecurityCriticalExplicitCtor)
- {
- // build the constructor sig that has NO arguments
- pCurr = rgSigBytesSecurityCriticalExplicitCtor;
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = COR_SECURITYCRITICAL_CTOR_ARGCOUNT_NO_SCOPE; // no arguments to constructor
- *pCurr++ = ELEMENT_TYPE_VOID;
- dwSigExplicitSize = (DWORD)(pCurr - rgSigBytesSecurityCriticalExplicitCtor);
- _ASSERTE(dwSigExplicitSize <= COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE);
- }
-
-ErrExit:
- return hr;
-} // NEWMERGER::RetrieveStandardSecurityCriticalMetaData
-
-//*****************************************************************************
-// Merge CustomAttributes
-//*****************************************************************************
-HRESULT NEWMERGER::MergeCustomAttributes()
-{
-
- HRESULT hr = NOERROR;
- CustomAttributeRec *pRecImport = NULL;
- CustomAttributeRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- ULONG iCount;
- ULONG i;
- mdToken tkParentImp; // Token of attributed object (parent).
- TOKENREC *pTokenRec; // Parent's remap.
- mdToken tkType; // Token of attribute's type.
- TOKENREC *pTypeRec; // Type's remap.
- void const *pValue; // The actual value.
- ULONG cbBlob; // Size of the value.
- mdToken cvImp;
- mdToken cvEmit;
- bool fDuplicate;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- TypeRefRec *pTypeRefRec;
- ULONG cTypeRefRecs;
- mdToken mrSuppressMergeCheckAttributeCtor = mdTokenNil;
- mdToken mrSecurityCriticalExplicitAttributeCtor = mdTokenNil;
- mdToken mrSecurityCriticalEverythingAttributeCtor = mdTokenNil;
- mdToken mrSecurityTransparentAttributeCtor = mdTokenNil;
- mdToken mrSecurityTreatAsSafeAttributeCtor = mdTokenNil;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- // Find out the TypeRef referring to our library's System.CompilerServices.SuppressMergeCheckAttribute,
- // System.Security.SecurityCriticalAttribute, System.Security.SecurityTransparentAttribute, and
- // System.Security.SecurityTreatAsSafeAttibute
- cTypeRefRecs = pMiniMdEmit->getCountTypeRefs();
-
- { // retrieve global attribute TypeRefs
-
- mdAssemblyRef tkMscorlib = mdTokenNil;
- mdTypeRef securityEnum = mdTokenNil;
-
- NewArrayHolder<BYTE> rgSigBytesSecurityCriticalEverythingCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE]);
- BYTE* pSigBytesSecurityCriticalEverythingCtor = rgSigBytesSecurityCriticalEverythingCtor.GetValue();
- IfFailGo((pSigBytesSecurityCriticalEverythingCtor == NULL)?E_OUTOFMEMORY:S_OK);
- DWORD dwSigEverythingSize = 0;
-
- NewArrayHolder<BYTE> rgSigBytesSecurityCriticalExplicitCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_NO_SCOPE_SIG_MAX_SIZE]);
- BYTE* pSigBytesSecurityCriticalExplicitCtor = rgSigBytesSecurityCriticalExplicitCtor.GetValue();
- IfFailGo((pSigBytesSecurityCriticalExplicitCtor == NULL)?E_OUTOFMEMORY:S_OK);
- DWORD dwSigExplicitSize = 0;
-
- // retrieve security critical metadata info if necessary
- if(ISSCS_Unknown != m_isscsSecurityCritical)
- {
-
- hr = RetrieveStandardSecurityCriticalMetaData(
- tkMscorlib,
- securityEnum,
- pSigBytesSecurityCriticalEverythingCtor,
- dwSigEverythingSize,
- pSigBytesSecurityCriticalExplicitCtor,
- dwSigExplicitSize);
-
- }
-
- // Search for the TypeRef.
- for (i = 1; i <= cTypeRefRecs; i++)
- {
- mdToken tkTmp = TokenFromRid(i,mdtTypeRef);
-
- if (IsAttributeFromNamespace(pMiniMdEmit, tkTmp,
- COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME,
- &pTypeRefRec) == S_OK)
- {
- LPCSTR szNameOfTypeRef;
- IfFailGo(pMiniMdEmit->getNameOfTypeRef(pTypeRefRec, &szNameOfTypeRef));
- if (strcmp(szNameOfTypeRef, COR_SUPPRESS_MERGE_CHECK_ATTRIBUTE) == 0)
- {
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- NULL, 0,
- &mrSuppressMergeCheckAttributeCtor);
- if (S_OK == hr) continue;
- }
- }
- else
- // if we are merging security critical attributes, then look for transparent-related attributes
- if ((ISSCS_Unknown != m_isscsSecurityCritical) &&
- (IsAttributeFromNamespace(pMiniMdEmit, tkTmp,
- COR_SECURITYCRITICAL_ATTRIBUTE_NAMESPACE, COR_MSCORLIB_NAME,
- &pTypeRefRec) == S_OK))
- {
- LPCSTR szNameOfTypeRef;
- IfFailGo(pMiniMdEmit->getNameOfTypeRef(pTypeRefRec, &szNameOfTypeRef));
-
- // look for the SecurityCritical attribute
- if (strcmp(szNameOfTypeRef, COR_SECURITYCRITICAL_ATTRIBUTE) == 0)
- {
- // since the SecurityCritical attribute can be either
- // parameterless constructor or SecurityCriticalScope constructor, we
- // look for both
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- rgSigBytesSecurityCriticalEverythingCtor.GetValue(), dwSigEverythingSize,
- &mrSecurityCriticalEverythingAttributeCtor);
- if (S_OK == hr) continue;
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- rgSigBytesSecurityCriticalExplicitCtor.GetValue(), dwSigExplicitSize,
- &mrSecurityCriticalExplicitAttributeCtor);
- if (S_OK == hr) continue;
- }
- else
- // look for the SecurityTransparent attribute
- if (strcmp(szNameOfTypeRef, COR_SECURITYTRANSPARENT_ATTRIBUTE) == 0)
- {
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- NULL, 0,
- &mrSecurityTransparentAttributeCtor);
- if (S_OK == hr) continue;
- }
- else
- // look for the SecurityTreatAsSafe attribute
- if (strcmp(szNameOfTypeRef, COR_SECURITYTREATASSAFE_ATTRIBUTE) == 0)
- {
- hr = ImportHelper::FindMemberRef(
- pMiniMdEmit, tkTmp,
- COR_CTOR_METHOD_NAME,
- NULL, 0,
- &mrSecurityTreatAsSafeAttributeCtor);
- if (S_OK == hr) continue;
- }
- }
- hr = S_OK; // ignore failures since the attribute may not be used
- }
- }
-
- // Loop over every module scope
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // We know that the filter table is not null here. Tell PREFIX that we know it.
- PREFIX_ASSUME( pMiniMdImport->GetFilterTable() != NULL );
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountCustomAttributes();
-
- // loop through all CustomAttribute
- for (i = 1; i <= iCount; i++)
- {
- // compare it with the emit scope
- IfFailGo(pMiniMdImport->GetCustomAttributeRecord(i, &pRecImport));
- tkParentImp = pMiniMdImport->getParentOfCustomAttribute(pRecImport);
- tkType = pMiniMdImport->getTypeOfCustomAttribute(pRecImport);
- IfFailGo(pMiniMdImport->getValueOfCustomAttribute(pRecImport, (const BYTE **)&pValue, &cbBlob));
-
- // only merge those CustomAttributes that are marked
- if ( pMiniMdImport->GetFilterTable()->IsCustomAttributeMarked(TokenFromRid(i, mdtCustomAttribute)) == false)
- continue;
-
- // Check the type of the CustomAttribute. If it is not marked, then we don't need to move over the CustomAttributes.
- // This will only occur for compiler defined discardable CAs during linking.
- //
- if ( pMiniMdImport->GetFilterTable()->IsTokenMarked(tkType) == false)
- continue;
-
- if ( pCurTkMap->Find(tkParentImp, &pTokenRec) )
- {
- // If the From token type is different from the To token's type, we have optimized the ref to def.
- // In this case, we are dropping the CA associated with the Ref tokens.
- //
- if (TypeFromToken(tkParentImp) == TypeFromToken(pTokenRec->m_tkTo))
- {
-
- // If tkParentImp is a MemberRef and it is also mapped to a MemberRef in the merged scope with a MethodDef
- // parent, then it is a MemberRef optimized to a MethodDef. We are keeping the MemberRef because it is a
- // vararg call. So we can drop CAs on this MemberRef.
- if (TypeFromToken(tkParentImp) == mdtMemberRef)
- {
- MemberRefRec *pTempRec;
- IfFailGo(pMiniMdEmit->GetMemberRefRecord(RidFromToken(pTokenRec->m_tkTo), &pTempRec));
- if (TypeFromToken(pMiniMdEmit->getClassOfMemberRef(pTempRec)) == mdtMethodDef)
- continue;
- }
-
-
- if (! pCurTkMap->Find(tkType, &pTypeRec) )
- {
- _ASSERTE(!"CustomAttribute Type not found in output scope");
- IfFailGo(META_E_BADMETADATA);
- }
-
- // Determine if we need to copy or ignore security-critical-related attributes
- hr = MergeSecurityCriticalModuleLevelAttributes(
- pImportData, tkParentImp, pTypeRec,
- mrSecurityTreatAsSafeAttributeCtor, mrSecurityTransparentAttributeCtor,
- mrSecurityCriticalExplicitAttributeCtor,
- mrSecurityCriticalEverythingAttributeCtor);
- IfFailGo(hr);
- // S_FALSE means skip attribute
- if (hr == S_FALSE) continue;
- // S_OK means consider copying attribute
-
- // if it's the SuppressMergeCheckAttribute, don't copy it
- if ( pTypeRec->m_tkTo == mrSuppressMergeCheckAttributeCtor )
- {
- continue;
- }
-
- if ( pTokenRec->m_isDuplicate)
- {
- // Try to see if the custom value is there in the emit scope or not.
- // If not, move it over still
- hr = ImportHelper::FindCustomAttributeByToken(
- pMiniMdEmit,
- pTokenRec->m_tkTo,
- pTypeRec->m_tkTo,
- pValue,
- cbBlob,
- &cvEmit);
-
- if ( hr == S_OK )
- {
- // found a match
- // <TODO>@FUTURE: more verification??</TODO>
- fDuplicate = true;
- }
- else
- {
- TypeRefRec *pAttributeTypeRefRec;
- // We need to allow additive merge on TypeRef for CustomAttributes because compiler
- // could build module but not assembly. They are hanging of Assembly level CAs on a bogus
- // TypeRef.
- // Also allow additive merge for CAs from CompilerServices and Microsoft.VisualC
- if (tkParentImp == MODULEDEFTOKEN
- || TypeFromToken(tkParentImp) == mdtTypeRef
- || (IsAttributeFromNamespace(pMiniMdImport, tkType,
- COR_COMPILERSERVICE_NAMESPACE, COR_MSCORLIB_NAME,
- &pAttributeTypeRefRec) == S_OK)
- || (IsAttributeFromNamespace(pMiniMdImport, tkType,
- COR_MISCBITS_NAMESPACE, COR_MISCBITS_NAMESPACE,
- &pAttributeTypeRefRec) == S_OK))
- {
- // clear the error
- hr = NOERROR;
-
- // custom value of module token! Copy over the custom value
- goto CopyCustomAttribute;
- }
-
- // another case to support additive merge if the CA on MehtodDef is
- // HandleProcessCorruptedStateExceptionsAttribute
- if ( TypeFromToken(tkParentImp) == mdtMethodDef && tkType == pImportData->m_tkHandleProcessCorruptedStateCtor)
- {
- // clear the error
- hr = NOERROR;
-
- // custom value of module token! Copy over the custom value
- goto CopyCustomAttribute;
- }
- CheckContinuableErrorEx(META_E_MD_INCONSISTENCY, pImportData, TokenFromRid(i, mdtCustomAttribute));
- }
- }
- else
- {
-CopyCustomAttribute:
- if ((m_dwMergeFlags & DropMemberRefCAs) && TypeFromToken(pTokenRec->m_tkTo) == mdtMemberRef)
- {
- // CustomAttributes associated with MemberRef. If the parent of MemberRef is a MethodDef or FieldDef, drop
- // the custom attribute.
- MemberRefRec *pMemberRefRec;
- IfFailGo(pMiniMdEmit->GetMemberRefRecord(RidFromToken(pTokenRec->m_tkTo), &pMemberRefRec));
- mdToken mrParent = pMiniMdEmit->getClassOfMemberRef(pMemberRefRec);
- if (TypeFromToken(mrParent) == mdtMethodDef || TypeFromToken(mrParent) == mdtFieldDef)
- {
- // Don't bother to copy over
- continue;
- }
- }
-
- // Parent is duplicated but the custom value is not. Still copy over the
- // custom value.
- fDuplicate = false;
- IfFailGo(pMiniMdEmit->AddCustomAttributeRecord(&pRecEmit, (ULONG *)&cvEmit));
- cvEmit = TokenFromRid(cvEmit, mdtCustomAttribute);
-
- // set the parent
- IfFailGo( pMiniMdEmit->PutToken(TBL_CustomAttribute, CustomAttributeRec::COL_Parent, pRecEmit, pTokenRec->m_tkTo) );
- // set the type
- IfFailGo( pMiniMdEmit->PutToken(TBL_CustomAttribute, CustomAttributeRec::COL_Type, pRecEmit, pTypeRec->m_tkTo));
-
- // move over the CustomAttribute blob value
- IfFailGo(pMiniMdImport->getValueOfCustomAttribute(pRecImport, (const BYTE **)&pValue, &cbBlob));
-
- IfFailGo( pMiniMdEmit->PutBlob(TBL_CustomAttribute, CustomAttributeRec::COL_Value, pRecEmit, pValue, cbBlob));
- IfFailGo( pMiniMdEmit->AddCustomAttributesToHash(cvEmit) );
- }
- cvEmit = TokenFromRid(cvEmit, mdtCustomAttribute);
- cvImp = TokenFromRid(i, mdtCustomAttribute);
-
- // Record the token movement
- IfFailGo( pCurTkMap->InsertNotFound(cvImp, pTokenRec->m_isDuplicate, cvEmit, &pTokenRec) );
- }
- }
- else
- {
-
- // either bad lookup map or bad metadata
- _ASSERTE(!"Bad state");
- IfFailGo( META_E_BADMETADATA );
- }
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeCustomAttributes()
-
-//*******************************************************************************
-// Helper to check if input scope has assembly-level security transparent awareness (either SecurityTransparent or SecurityCritical)
-// SIDE EFFECT: pImportData->m_isscsSecurityCriticalStatus will be explicitly set [same value as return value]
-// SecurityCritical.Explicit attribute injection occurs for all scopes that have tags (e.g. NOT ISSCS_Unknown)
-// If the tagged scopes are all SecurityCritical.Everything, then the final attribute should be SecurityCritical.Everything
-// anyway. Otherwise, at least one SecurityCritical.Explicit tag will be used/injected
-//*******************************************************************************
-InputScopeSecurityCriticalStatus NEWMERGER::CheckInputScopeIsCritical(MergeImportData* pImportData, HRESULT& hr)
-{
- hr = S_OK;
-
- // the attribute should be in a known state no matter how we return from this function
- // default to no attribute explicitly specified
- pImportData->m_isscsSecurityCriticalStatus = ISSCS_Unknown;
-
- mdTypeRef fakeModuleTypeRef = mdTokenNil;
- mdAssemblyRef tkMscorlib = mdTokenNil;
-
- // TODO: Should we remove the ability to disable merging critical attributes?
- if (g_fRefShouldMergeCriticalChecked == FALSE)
- {
- // shouldn't require thread safety lock
- g_fRefShouldMergeCritical = (CLRConfig::GetConfigValue(CLRConfig::EXTERNAL_MergeCriticalAttributes) != 0);
- g_fRefShouldMergeCriticalChecked = TRUE;
- }
-
- // return no merge needed, if the merge critical attribute setting is not enabled.
- if (!g_fRefShouldMergeCritical) return ISSCS_Unknown;
-
- // get typeref for mscorlib
- BYTE pbMscorlibToken[] = COR_MSCORLIB_TYPEREF;
-
- CMiniMdRW* pImportedMiniMd = &pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd;
-
- if (S_OK != ImportHelper::FindAssemblyRef(pImportedMiniMd,
- COR_MSCORLIB_NAME,
- NULL,
- pbMscorlibToken,
- sizeof(pbMscorlibToken),
- asm_rmj,
- asm_rmm,
- asm_rup,
- asm_rpt,
- 0,
- &tkMscorlib))
- {
- // there isn't an mscorlib ref here... we can't have the security critical attribute
- return ISSCS_Unknown;
- }
-
- if (S_OK != ImportHelper::FindTypeRefByName(pImportedMiniMd,
- tkMscorlib,
- COR_COMPILERSERVICE_NAMESPACE,
- MODULE_CA_TYPENAME,
- &fakeModuleTypeRef))
- {
- // for now let use the fake module ref as the assembly def
- fakeModuleTypeRef = 0x000001;
- }
-
- // Check the input scope for TreatAsSafe
- if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL,
- NULL,
- NULL))
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityTreatAsSafe;
- }
-
- // Check the input scope for security transparency awareness
- // For example, the assembly is marked SecurityTransparent, SecurityCritical(Explicit), or SecurityCritical(Everything)
-
-
- const void *pbData = NULL; // [OUT] Put pointer to data here.
- ULONG cbData = 0; // number of bytes in pbData
-
- // Check if the SecurityTransparent attribute is present
- if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYTRANSPARENT_ATTRIBUTE_FULL,
- NULL,
- NULL))
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityTransparent;
- }
- else
- // Check if the SecurityCritical attribute is present
- if (S_OK == ImportHelper::GetCustomAttributeByName(pImportedMiniMd,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYCRITICAL_ATTRIBUTE_FULL,
- &pbData,
- &cbData))
- {
- // find out if critical everything or explicit
-
- // default to critical
- pImportData->m_isscsSecurityCriticalStatus = ISSCS_SecurityCritical;
-
- BYTE rgSecurityCriticalEverythingCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING;
- // if value is non-0 (i.e. 1), then mark as SecurityCritical everything, otherwise, explicit
- if (NULL != pbData && cbData == 8 &&
- memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0)
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityCriticalEverything;
- }
- else
- {
- pImportData->m_isscsSecurityCriticalStatus |= ISSCS_SecurityCriticalExplicit;
- }
- }
-
- return pImportData->m_isscsSecurityCriticalStatus;
-} // HRESULT NEWMERGER::CheckInputScopeIsCritical()
-
-//*******************************************************************************
-// Helper to merge security critical annotations across assemblies and types
-//*******************************************************************************
-HRESULT NEWMERGER::MergeSecurityCriticalAttributes()
-{
- // if no assembly-level critical attributes were specified, then none are needed,
- // and no need to do special attribute merging
- if (ISSCS_Unknown == m_isscsSecurityCritical)
- {
- return S_OK;
- }
- // or if the global-scope already has TAS/Critical.Everything, then ignore individual type fixes
- else if ((ISSCS_SECURITYCRITICAL_LEGACY & m_isscsSecurityCriticalAllScopes) == ISSCS_SECURITYCRITICAL_LEGACY)
- {
- return S_OK;
- }
-
- HRESULT hr = S_OK;
-
- CMiniMdRW* emit = GetMiniMdEmit();
- // The attribute we want to decorate all of the types with has not been defined.
- mdMemberRef tkSecurityCriticalEverythingAttribute = mdTokenNil;
- mdMemberRef tkSecurityTreatAsSafeAttribute = mdTokenNil;
- mdMemberRef tkSecuritySafeCriticalAttribute = mdTokenNil;
-
- mdAssemblyRef tkMscorlib = mdTokenNil;
- mdTypeRef fakeModuleTypeRef = mdTokenNil;
- mdTypeRef securityEnum = mdTokenNil;
-
- DWORD dwSigSize;
- BYTE* rgSigBytesSecurityCriticalExplicitCtor = 0;
- DWORD dwSigSize_TEMP;
-
- BYTE rgSigBytesTreatAsSafeCtor[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID};
-
- BYTE rgSecurityCriticalEverythingCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EVERYTHING;
-
-
- mdTypeRef tkSecurityCriticalEverythingAttributeType = mdTokenNil;
- mdTypeRef tkSecurityTreatAsSafeAttributeType = mdTokenNil;
-
- NewArrayHolder<BYTE> rgSigBytesSecurityCriticalEverythingCtor(new (nothrow)BYTE[COR_SECURITYCRITICAL_CTOR_SCOPE_SIG_MAX_SIZE]);
- BYTE* pSigBytesSecurityCriticalEverythingCtor = rgSigBytesSecurityCriticalEverythingCtor.GetValue();
- IfFailGo((pSigBytesSecurityCriticalEverythingCtor == NULL)?E_OUTOFMEMORY:S_OK);
-
- IfFailGo(RetrieveStandardSecurityCriticalMetaData(
- tkMscorlib,
- securityEnum,
- pSigBytesSecurityCriticalEverythingCtor,
- dwSigSize,
- rgSigBytesSecurityCriticalExplicitCtor,
- dwSigSize_TEMP));
-
- if (S_OK != ImportHelper::FindTypeRefByName(emit,
- tkMscorlib,
- COR_COMPILERSERVICE_NAMESPACE,
- MODULE_CA_TYPENAME,
- &fakeModuleTypeRef))
- {
- // for now let use the fake module ref as the assembly def
- fakeModuleTypeRef = 0x000001;
- }
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(
- tkMscorlib, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W, &tkSecurityCriticalEverythingAttributeType));
-
- IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityCriticalEverythingAttributeType,
- COR_CONSTRUCTOR_METADATA_IDENTIFIER,
- rgSigBytesSecurityCriticalEverythingCtor.GetValue(),
- dwSigSize,
- &tkSecurityCriticalEverythingAttribute));
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(
- tkMscorlib, COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W,
- &tkSecurityTreatAsSafeAttributeType));
-
- IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityTreatAsSafeAttributeType,
- COR_CONSTRUCTOR_METADATA_IDENTIFIER,
- rgSigBytesTreatAsSafeCtor,
- sizeof(rgSigBytesTreatAsSafeCtor),
- &tkSecurityTreatAsSafeAttribute));
-
-
- // place this block in a new scope so that we can safely goto past it
- {
- mdTypeRef tkSecuritySafeCriticalAttributeType = mdTokenNil;
- if (FAILED (hr = m_pRegMetaEmit->DefineTypeRefByName(tkMscorlib, COR_SECURITYSAFECRITICAL_ATTRIBUTE_FULL_W,
- &tkSecuritySafeCriticalAttributeType)))
- {
- _ASSERTE(!"Couldn't Emit a Typeref for SafeCritical attribute");
- return hr;
- }
-
- BYTE rgSigBytesSafeCriticalCtor[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID};
- if (FAILED(hr = m_pRegMetaEmit->DefineMemberRef(tkSecuritySafeCriticalAttributeType,
- W(".ctor"),
- rgSigBytesSafeCriticalCtor,
- sizeof(rgSigBytesSafeCriticalCtor),
- &tkSecuritySafeCriticalAttribute)))
- {
- _ASSERTE(!"Couldn't Emit a MemberRef for SafeCritical attribute .ctor");
- return hr;
- }
- }
-
-
- for (MergeImportData* pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // if the import is marked TAS, then we need to explicitly mark each type as TAS
- // if the import is marked Crit/Everything, then we need to explicitly mark each type as Crit
- // if the import is not marked at all, then we need to explicitly mark each type TAS/Crit
-
- // if the import is marked ONLY Crit/Explicit or ONLY Transparent then we can ignore it
- if (ISSCS_SecurityTransparent == pImportData->m_isscsSecurityCriticalStatus ||
- ISSCS_SecurityCriticalExplicit == pImportData->m_isscsSecurityCriticalStatus) continue;
-
- // Run through the scopes that need to have their types decorated with this attribute
- MDTOKENMAP*pCurTKMap = pImportData->m_pMDTokenMap;
- BYTE rgTreatAsSafeCtorValue[] = COR_SECURITYTREATASSAFE_ATTRIBUTE_VALUE;
-
- BOOL fMarkEachTokenAsCritical = FALSE;
- // if the import is unmarked or marked Crit/Everything,
- // then we need to explicitly mark each token as Crit
- // Unless the the global scope already has SecurityCritical.Everything
- if (((ISSCS_SecurityCriticalEverything & m_isscsSecurityCriticalAllScopes) != ISSCS_SecurityCriticalEverything) &&
- (((ISSCS_SecurityCriticalEverything & pImportData->m_isscsSecurityCriticalStatus) == ISSCS_SecurityCriticalEverything ) ||
-
- // OR this scope is NOT transparent or critical-explicit
- (ISSCS_SecurityTransparent & pImportData->m_isscsSecurityCriticalStatus) == 0 ||
- (ISSCS_SecurityCritical & pImportData->m_isscsSecurityCriticalStatus) == 0 ||
-
- // OR this scope is UNKNOWN
- (ISSCS_Unknown == (ISSCS_SECURITYCRITICAL_FLAGS & pImportData->m_isscsSecurityCriticalStatus))))
- {
- fMarkEachTokenAsCritical = TRUE;
- }
-
- BOOL fMarkEachTokenAsSafe = FALSE;
- // if the import is unmarked or marked TAS,
- // then we need to explicitly mark each token as TAS
- // Unless the the global scope already has SecurityTreatAsSafe
- if (((ISSCS_SecurityTreatAsSafe & m_isscsSecurityCriticalAllScopes) != ISSCS_SecurityTreatAsSafe) &&
- ((ISSCS_SecurityTreatAsSafe & pImportData->m_isscsSecurityCriticalStatus) ||
- ISSCS_Unknown == (pImportData->m_isscsSecurityCriticalStatus & ISSCS_SECURITYCRITICAL_FLAGS)))
- {
- fMarkEachTokenAsSafe = TRUE;
- }
-
- BYTE rgSafeCriticalCtorValue[] = {0x01, 0x00, 0x00 ,0x00};
-
- for (int i = 0; i < pCurTKMap->Count(); i++)
- {
- TOKENREC* pRec = pCurTKMap->Get(i);
- BOOL fInjectSecurityAttributes = FALSE;
-
- // skip empty records
- if (pRec->IsEmpty()) continue;
-
- // If this scope contained a typeref that was resolved to a typedef, let's not mark it. We'll let the owner
- // of the actual typedef decide if that type should be marked.
- if ((TypeFromToken(pRec->m_tkFrom) == mdtTypeRef) && (TypeFromToken(pRec->m_tkTo) == mdtTypeDef))
- continue;
-
- // Same for method refs/method defs
- if ((TypeFromToken(pRec->m_tkFrom) == mdtMemberRef) && (TypeFromToken(pRec->m_tkTo) == mdtMethodDef))
- continue;
-
- // check for typedefs, but don't put this on the global typedef
- if ((TypeFromToken(pRec->m_tkTo) == mdtTypeDef) && (pRec->m_tkTo != TokenFromRid(1, mdtTypeDef)))
- {
- // by default we will inject
- fInjectSecurityAttributes = TRUE;
- // except for Enums
- DWORD dwClassAttrs = 0;
- mdTypeRef crExtends = mdTokenNil;
-
- if (FAILED(hr = m_pRegMetaEmit->GetTypeDefProps(pRec->m_tkTo, NULL, NULL, 0 , &dwClassAttrs, &crExtends)))
- {
- // TODO: should we fail ??
- }
-
- // check for Enum types
- if (!IsNilToken(crExtends) && (TypeFromToken(crExtends)==mdtTypeRef))
- {
- // get the namespace and the name for this token
- CMiniMdRW *pMiniMd = GetMiniMdEmit();
- TypeRefRec *pTypeRefRec;
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(crExtends), &pTypeRefRec));
- LPCSTR szNamespace;
- LPCSTR szName;
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pTypeRefRec, &szNamespace));;
- IfFailGo(pMiniMd->getNameOfTypeRef(pTypeRefRec, &szName));
- // check for System.Enum
- BOOL bIsEnum = (!strcmp(szNamespace,"System"))&&(!strcmp(szName,"Enum"));
- if (bIsEnum)
- {
- fInjectSecurityAttributes = FALSE;
- }
- }
- }
- else // check for global method defs
- if (TypeFromToken(pRec->m_tkTo) == mdtMethodDef)
- {
- int isGlobal = 0;
- if (!FAILED(m_pRegMetaEmit->IsGlobal(pRec->m_tkTo, &isGlobal)))
- {
- // check for global methods
- if (isGlobal != 0)
- {
- fInjectSecurityAttributes = TRUE;
- }
- }
- }
-
- if (fInjectSecurityAttributes)
- {
- // check to see if the token already has a custom attribute
- const void *pbData = NULL; // [OUT] Put pointer to data here.
- ULONG cbData = 0;
-
- if (fMarkEachTokenAsCritical)
- {
- // Check if the Type already has SecurityCritical
- BOOL fInjectSecurityCriticalEverything = TRUE;
- if (S_OK == m_pRegMetaEmit->GetCustomAttributeByName(pRec->m_tkTo, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W, &pbData, &cbData))
- {
- // if value is non-0 (i.e. 1), then it is SecurityCritical.Everything - so do not inject another
- fInjectSecurityCriticalEverything = !(NULL != pbData && cbData == 8 &&
- memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0);
- }
-
- // either inject or overwrite SecurityCritical.Everything
- if (fInjectSecurityCriticalEverything)
- {
- IfFailGo(m_pRegMetaEmit->DefineCustomAttribute(
- pRec->m_tkTo, tkSecurityCriticalEverythingAttribute,
- rgSecurityCriticalEverythingCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough)
- sizeof(rgSecurityCriticalEverythingCtorValue), // Length of your custom attribute data
- NULL));
- }
- }
-
- // If the Type does NOT already have TAS then add it
- if (fMarkEachTokenAsSafe &&
- S_OK != m_pRegMetaEmit->GetCustomAttributeByName(pRec->m_tkTo, COR_SECURITYTREATASSAFE_ATTRIBUTE_FULL_W, &pbData, &cbData))
- {
- IfFailGo(m_pRegMetaEmit->DefineCustomAttribute(
- pRec->m_tkTo, tkSecurityTreatAsSafeAttribute,
- rgTreatAsSafeCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough)
- sizeof(rgTreatAsSafeCtorValue), // Length of your custom attribute data
- NULL));
- }
-
- hr = m_pRegMetaEmit->DefineCustomAttribute(pRec->m_tkTo, tkSecuritySafeCriticalAttribute,
- rgSafeCriticalCtorValue, // Use this if you need specific custom attribute data (presence of the attribute isn't enough)
- sizeof(rgSafeCriticalCtorValue), // Length of your custom attribute data
- NULL);
-
- }
- }
- }
-
- // If the global scope is not Transparent, we should emit SecurityCritical.Explicit || Everything
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityTransparent) != ISSCS_SecurityTransparent &&
- (m_isscsSecurityCritical & ISSCS_SecurityCriticalEverything) != ISSCS_SecurityCriticalExplicit)
- {
- BOOL fEmitSecurityEverything = FALSE;
- // in the case of Unmarked and TAS/Unmarked, we need to emit the SecurityCritical.Everything attribute
- // if it hasn't already been emitted
- if ((m_isscsSecurityCriticalAllScopes & ISSCS_SecurityCriticalEverything) ==
- ISSCS_SecurityCriticalEverything)
- {
- fEmitSecurityEverything = TRUE;
- }
- // otherwise, emit the SecurityCritical.Explicit attribute
-
- BOOL fSecurityCriticalExists = FALSE;
- // check to see if the assembly already has the appropriate SecurityCritical attribute
- // [from one of the input scopes]
- const void *pbData = NULL;
- ULONG cbData = 0;
- if (S_OK == ImportHelper::GetCustomAttributeByName(emit,
- fakeModuleTypeRef, // This is the assembly def token
- COR_SECURITYCRITICAL_ATTRIBUTE_FULL,
- &pbData,
- &cbData))
- {
- // find out if critical everything or explicit
- // default to critical
- // if value is non-0 (i.e. 1), then mark as SecurityCritical everything, otherwise, explicit
- if (NULL != pbData && cbData == 8 &&
- memcmp(rgSecurityCriticalEverythingCtorValue, pbData, cbData) == 0)
- {
- if (!fEmitSecurityEverything)
- {
- _ASSERTE(!"Unexpected SecurityCritical.Everything attribute detected");
- IfFailGo(META_E_BADMETADATA);
- }
- }
- else
- {
- if (fEmitSecurityEverything)
- {
- _ASSERTE(!"Unexpected SecurityCritical.Explicit attribute detected");
- IfFailGo(META_E_BADMETADATA);
- }
- }
- fSecurityCriticalExists = TRUE;
- }
-
- if (!fSecurityCriticalExists)
- {
- // retrieve the type and CustomAttribute
- mdCustomAttribute tkSecurityCriticalAttributeExplicit;
-
- mdTypeRef tkSecurityCriticalExplicitAttributeType = mdTokenNil;
-
- IfFailGo(m_pRegMetaEmit->DefineTypeRefByName(
- tkMscorlib, COR_SECURITYCRITICAL_ATTRIBUTE_FULL_W,
- &tkSecurityCriticalExplicitAttributeType));
-
- BYTE rgSigBytesSecurityCriticalExplicitCtorLocal[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0x00, ELEMENT_TYPE_VOID};
- BYTE rgSecurityCriticalExplicitCtorValue[] = COR_SECURITYCRITICAL_ATTRIBUTE_VALUE_EXPLICIT;
-
- IfFailGo(m_pRegMetaEmit->DefineMemberRef(tkSecurityCriticalExplicitAttributeType,
- COR_CONSTRUCTOR_METADATA_IDENTIFIER,
- rgSigBytesSecurityCriticalExplicitCtorLocal,
- sizeof(rgSigBytesSecurityCriticalExplicitCtorLocal),
- &tkSecurityCriticalAttributeExplicit));
-
- IfFailGo(m_pRegMetaEmit->DefineCustomAttribute(
- fakeModuleTypeRef,
- fEmitSecurityEverything?tkSecurityCriticalEverythingAttribute:tkSecurityCriticalAttributeExplicit,
- fEmitSecurityEverything?rgSecurityCriticalEverythingCtorValue:rgSecurityCriticalExplicitCtorValue,
- fEmitSecurityEverything?sizeof(rgSecurityCriticalEverythingCtorValue):sizeof(rgSecurityCriticalExplicitCtorValue),
- NULL));
-
- }
- }
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeSecurityCriticalAttributes()
-
-//*******************************************************************************
-// Helper to copy an InterfaceImpl record
-//*******************************************************************************
-HRESULT NEWMERGER::CopyInterfaceImpl(
- InterfaceImplRec *pRecEmit, // [IN] the emit record to fill
- MergeImportData *pImportData, // [IN] the importing context
- InterfaceImplRec *pRecImp) // [IN] the record to import
-{
- HRESULT hr;
- mdToken tkParent;
- mdToken tkInterface;
- CMiniMdRW *pMiniMdEmit = GetMiniMdEmit();
- CMiniMdRW *pMiniMdImp;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdImp = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
-
- tkParent = pMiniMdImp->getClassOfInterfaceImpl(pRecImp);
- tkInterface = pMiniMdImp->getInterfaceOfInterfaceImpl(pRecImp);
-
- IfFailGo( pCurTkMap->Remap(tkParent, &tkParent) );
- IfFailGo( pCurTkMap->Remap(tkInterface, &tkInterface) );
-
- IfFailGo( pMiniMdEmit->PutToken( TBL_InterfaceImpl, InterfaceImplRec::COL_Class, pRecEmit, tkParent) );
- IfFailGo( pMiniMdEmit->PutToken( TBL_InterfaceImpl, InterfaceImplRec::COL_Interface, pRecEmit, tkInterface) );
-
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::CopyInterfaceImpl()
-
-
-//*****************************************************************************
-// Merge Assembly table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeAssembly()
-{
- HRESULT hr = NOERROR;
- AssemblyRec *pRecImport = NULL;
- AssemblyRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- const BYTE *pbTmp;
- ULONG cbTmp;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- if (!pMiniMdImport->getCountAssemblys())
- goto ErrExit; // There is no Assembly in the import scope to merge.
-
- // Copy the Assembly map record to the Emit scope and send a token remap notifcation
- // to the client. No duplicate checking needed since the Assembly can be present in
- // only one scope and there can be atmost one entry.
- IfFailGo(pMiniMdImport->GetAssemblyRecord(1, &pRecImport));
- IfFailGo(pMiniMdEmit->AddAssemblyRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getPublicKeyOfAssembly(pRecImport, &pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_Assembly, AssemblyRec::COL_PublicKey, pRecEmit,
- pbTmp, cbTmp));
-
- IfFailGo(pMiniMdImport->getNameOfAssembly(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_Assembly, AssemblyRec::COL_Name, pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getLocaleOfAssembly(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_Assembly, AssemblyRec::COL_Locale, pRecEmit, szTmp));
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(1, mdtAssembly),
- false,
- TokenFromRid(iRecord, mdtAssembly),
- &pTokenRec));
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeAssembly()
-
-
-
-
-//*****************************************************************************
-// Merge File table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeFiles()
-{
- HRESULT hr = NOERROR;
- FileRec *pRecImport = NULL;
- FileRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- const void *pbTmp;
- ULONG cbTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountFiles();
-
- // Loop through all File records and copy them to the Emit scope.
- // Since there can only be one File table in all the scopes combined,
- // there isn't any duplicate checking that needs to be done.
- for (i = 1; i <= iCount; i++)
- {
- IfFailGo(pMiniMdImport->GetFileRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddFileRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getNameOfFile(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_File, FileRec::COL_Name, pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getHashValueOfFile(pRecImport, (const BYTE **)&pbTmp, &cbTmp));
- IfFailGo(pMiniMdEmit->PutBlob(TBL_File, FileRec::COL_HashValue, pRecEmit, pbTmp, cbTmp));
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtFile),
- false,
- TokenFromRid(iRecord, mdtFile),
- &pTokenRec));
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeFiles()
-
-
-//*****************************************************************************
-// Merge ExportedType table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeExportedTypes()
-{
- HRESULT hr = NOERROR;
- ExportedTypeRec *pRecImport = NULL;
- ExportedTypeRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- mdToken tkTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountExportedTypes();
-
- // Loop through all ExportedType records and copy them to the Emit scope.
- // Since there can only be one ExportedType table in all the scopes combined,
- // there isn't any duplicate checking that needs to be done.
- for (i = 1; i <= iCount; i++)
- {
- IfFailGo(pMiniMdImport->GetExportedTypeRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddExportedTypeRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getTypeNameOfExportedType(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeName, pRecEmit, szTmp));
-
- IfFailGo(pMiniMdImport->getTypeNamespaceOfExportedType(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeNamespace, pRecEmit, szTmp));
-
- tkTmp = pMiniMdImport->getImplementationOfExportedType(pRecImport);
- IfFailGo(pCurTkMap->Remap(tkTmp, &tkTmp));
- IfFailGo(pMiniMdEmit->PutToken(TBL_ExportedType, ExportedTypeRec::COL_Implementation,
- pRecEmit, tkTmp));
-
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtExportedType),
- false,
- TokenFromRid(iRecord, mdtExportedType),
- &pTokenRec));
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeExportedTypes()
-
-
-//*****************************************************************************
-// Merge ManifestResource table
-//*****************************************************************************
-HRESULT NEWMERGER::MergeManifestResources()
-{
- HRESULT hr = NOERROR;
- ManifestResourceRec *pRecImport = NULL;
- ManifestResourceRec *pRecEmit = NULL;
- CMiniMdRW *pMiniMdImport;
- CMiniMdRW *pMiniMdEmit;
- LPCUTF8 szTmp;
- mdToken tkTmp;
- ULONG iCount;
- ULONG i;
- ULONG iRecord;
- TOKENREC *pTokenRec;
-
- MergeImportData *pImportData;
- MDTOKENMAP *pCurTkMap;
-
- pMiniMdEmit = GetMiniMdEmit();
-
- for (pImportData = m_pImportDataList; pImportData != NULL; pImportData = pImportData->m_pNextImportData)
- {
- // for each import scope
- pMiniMdImport = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
-
- // set the current MDTokenMap
- pCurTkMap = pImportData->m_pMDTokenMap;
- iCount = pMiniMdImport->getCountManifestResources();
-
- // Loop through all ManifestResource records and copy them to the Emit scope.
- // Since there can only be one ManifestResource table in all the scopes combined,
- // there isn't any duplicate checking that needs to be done.
- for (i = 1; i <= iCount; i++)
- {
- IfFailGo(pMiniMdImport->GetManifestResourceRecord(i, &pRecImport));
- IfFailGo(pMiniMdEmit->AddManifestResourceRecord(&pRecEmit, &iRecord));
-
- pRecEmit->Copy(pRecImport);
-
- IfFailGo(pMiniMdImport->getNameOfManifestResource(pRecImport, &szTmp));
- IfFailGo(pMiniMdEmit->PutString(TBL_ManifestResource, ManifestResourceRec::COL_Name,
- pRecEmit, szTmp));
-
- tkTmp = pMiniMdImport->getImplementationOfManifestResource(pRecImport);
- IfFailGo(pCurTkMap->Remap(tkTmp, &tkTmp));
- IfFailGo(pMiniMdEmit->PutToken(TBL_ManifestResource, ManifestResourceRec::COL_Implementation,
- pRecEmit, tkTmp));
-
- // record the token movement.
- IfFailGo(pCurTkMap->InsertNotFound(
- TokenFromRid(i, mdtManifestResource),
- false,
- TokenFromRid(iRecord, mdtManifestResource),
- &pTokenRec));
- }
- }
-ErrExit:
- return hr;
-} // HRESULT NEWMERGER::MergeManifestResources()
-
-
-
-
-
-//*****************************************************************************
-// Error handling. Call back to host to see what they want to do.
-//*****************************************************************************
-HRESULT NEWMERGER::OnError(
- HRESULT hrIn, // The error HR we're reporting.
- MergeImportData *pImportData, // The input scope with the error.
- mdToken token) // The token with the error.
-{
- // This function does a QI and a Release on every call. However, it should be
- // called very infrequently, and lets the scope just keep a generic handler.
- IMetaDataError *pIErr = NULL;
- IUnknown *pHandler = pImportData->m_pHandler;
- CMiniMdRW *pMiniMd = &(pImportData->m_pRegMetaImport->m_pStgdb->m_MiniMd);
- CQuickArray<WCHAR> rName; // Name of the TypeDef in unicode.
- LPCUTF8 szTypeName;
- LPCUTF8 szNSName;
- TypeDefRec *pTypeRec;
- int iLen; // Length of a name.
- mdToken tkParent;
- HRESULT hr = NOERROR;
-
- if (pHandler && pHandler->QueryInterface(IID_IMetaDataError, (void**)&pIErr)==S_OK)
- {
- switch (hrIn)
- {
-
- case META_E_PARAM_COUNTS:
- case META_E_METHD_NOT_FOUND:
- case META_E_METHDIMPL_INCONSISTENT:
- {
- LPCUTF8 szMethodName;
- MethodRec *pMethodRec;
-
- // Method name.
- _ASSERTE(TypeFromToken(token) == mdtMethodDef);
- IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(token), &pMethodRec));
- IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName);
- IfNullGo(wzMethodName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfMethodHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzMethodName, token);
- break;
- }
- case META_E_FIELD_NOT_FOUND:
- {
- LPCUTF8 szFieldName;
- FieldRec *pFieldRec;
-
- // Field name.
- _ASSERTE(TypeFromToken(token) == mdtFieldDef);
- IfFailGo(pMiniMd->GetFieldRecord(RidFromToken(token), &pFieldRec));
- IfFailGo(pMiniMd->getNameOfField(pFieldRec, &szFieldName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzFieldName, szFieldName);
- IfNullGo(wzFieldName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfFieldHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzFieldName, token);
- break;
- }
- case META_E_EVENT_NOT_FOUND:
- {
- LPCUTF8 szEventName;
- EventRec *pEventRec;
-
- // Event name.
- _ASSERTE(TypeFromToken(token) == mdtEvent);
- IfFailGo(pMiniMd->GetEventRecord(RidFromToken(token), &pEventRec));
- IfFailGo(pMiniMd->getNameOfEvent(pEventRec, &szEventName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzEventName, szEventName);
- IfNullGo(wzEventName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfEventHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzEventName, token);
- break;
- }
- case META_E_PROP_NOT_FOUND:
- {
- LPCUTF8 szPropertyName;
- PropertyRec *pPropertyRec;
-
- // Property name.
- _ASSERTE(TypeFromToken(token) == mdtProperty);
- IfFailGo(pMiniMd->GetPropertyRecord(RidFromToken(token), &pPropertyRec));
- IfFailGo(pMiniMd->getNameOfProperty(pPropertyRec, &szPropertyName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzPropertyName, szPropertyName);
- IfNullGo(wzPropertyName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfPropertyHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), wzPropertyName, token);
- break;
- }
- case META_S_PARAM_MISMATCH:
- {
- LPCUTF8 szMethodName;
- MethodRec *pMethodRec;
- mdToken tkMethod;
-
- // Method name.
- _ASSERTE(TypeFromToken(token) == mdtParamDef);
- IfFailGo( pMiniMd->FindParentOfParamHelper(token, &tkMethod) );
- IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(tkMethod), &pMethodRec));
- IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName);
- IfNullGo(wzMethodName);
-
- // Type and its name.
- IfFailGo( pMiniMd->FindParentOfMethodHelper(token, &tkParent) );
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- // use the error hresult so that we can post the correct error.
- PostError(META_E_PARAM_MISMATCH, wzMethodName, (LPWSTR) rName.Ptr(), token);
- break;
- }
- case META_E_INTFCEIMPL_NOT_FOUND:
- {
- InterfaceImplRec *pRec; // The InterfaceImpl
- mdToken tkIface; // Token of the implemented interface.
- CQuickArray<WCHAR> rIface; // Name of the Implemented Interface in unicode.
- TypeRefRec *pRef; // TypeRef record when II is a typeref.
- InterfaceImplRec *pInterfaceImplRec;
-
- // Get the record.
- _ASSERTE(TypeFromToken(token) == mdtInterfaceImpl);
- IfFailGo(pMiniMd->GetInterfaceImplRecord(RidFromToken(token), &pRec));
- // Get the name of the class.
- tkParent = pMiniMd->getClassOfInterfaceImpl(pRec);
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkParent), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- // Get the name of the implemented interface.
- IfFailGo(pMiniMd->GetInterfaceImplRecord(RidFromToken(token), &pInterfaceImplRec));
- tkIface = pMiniMd->getInterfaceOfInterfaceImpl(pInterfaceImplRec);
- if (TypeFromToken(tkIface) == mdtTypeDef)
- { // If it is a typedef...
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(tkIface), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- }
- else
- { // If it is a typeref...
- _ASSERTE(TypeFromToken(tkIface) == mdtTypeRef);
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(tkIface), &pRef));
- IfFailGo(pMiniMd->getNameOfTypeRef(pRef, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pRef, &szNSName));
- }
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rIface.ReSizeNoThrow(iLen+1));
- ns::MakePath(rIface.Ptr(), iLen+1, szNSName, szTypeName);
-
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), (LPWSTR)rIface.Ptr(), token);
- break;
- }
- case META_E_CLASS_LAYOUT_INCONSISTENT:
- case META_E_METHOD_COUNTS:
- case META_E_FIELD_COUNTS:
- case META_E_EVENT_COUNTS:
- case META_E_PROPERTY_COUNTS:
- {
- // get the type name.
- _ASSERTE(TypeFromToken(token) == mdtTypeDef);
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(token), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), token);
- break;
- }
- case META_E_GENERICPARAM_INCONSISTENT:
- {
- // If token is type, get type name; if method, get method name.
- LPWSTR wzName;
- LPCUTF8 szMethodName;
- MethodRec *pMethodRec;
-
- if ((TypeFromToken(token) == mdtMethodDef))
- {
- // Get the method name.
- IfFailGo(pMiniMd->GetMethodRecord(RidFromToken(token), &pMethodRec));
- IfFailGo(pMiniMd->getNameOfMethod(pMethodRec, &szMethodName));
- MAKE_WIDEPTR_FROMUTF8_NOTHROW(wzMethodName, szMethodName);
- IfNullGo(wzMethodName);
- wzName = wzMethodName;
- }
- else
- {
- // Get the type name.
- _ASSERTE(TypeFromToken(token) == mdtTypeDef);
- IfFailGo(pMiniMd->GetTypeDefRecord(RidFromToken(token), &pTypeRec));
- IfFailGo(pMiniMd->getNameOfTypeDef(pTypeRec, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeDef(pTypeRec, &szNSName));
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
- wzName = (LPWSTR)rName.Ptr();
- }
-
- PostError(hrIn, wzName, token);
- break;
- }
- case META_E_TYPEDEF_MISSING:
- {
- TypeRefRec *pRef; // TypeRef record when II is a typeref.
-
- // Get the record.
- _ASSERTE(TypeFromToken(token) == mdtTypeRef);
- IfFailGo(pMiniMd->GetTypeRefRecord(RidFromToken(token), &pRef));
- IfFailGo(pMiniMd->getNameOfTypeRef(pRef, &szTypeName));
- IfFailGo(pMiniMd->getNamespaceOfTypeRef(pRef, &szNSName));
-
- // Put namespace + name together.
- iLen = ns::GetFullLength(szNSName, szTypeName);
- IfFailGo(rName.ReSizeNoThrow(iLen+1));
- ns::MakePath(rName.Ptr(), iLen+1, szNSName, szTypeName);
-
-
- PostError(hrIn, (LPWSTR) rName.Ptr(), token);
- break;
- }
- default:
- {
- PostError(hrIn, token);
- break;
- }
- }
- hr = pIErr->OnError(hrIn, token);
- }
- else
- hr = S_FALSE;
-ErrExit:
- if (pIErr)
- pIErr->Release();
- return (hr);
-} // NEWMERGER::OnError
-
-#endif //FEATURE_METADATA_EMIT_ALL
diff --git a/src/md/compiler/newmerger.h b/src/md/compiler/newmerger.h
deleted file mode 100644
index fc89ab7f61..0000000000
--- a/src/md/compiler/newmerger.h
+++ /dev/null
@@ -1,256 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//*****************************************************************************
-// NewMerger.h
-//
-
-//
-// Contains utility code for MD directory
-//
-//*****************************************************************************
-#ifndef __NEWMERGER__h__
-#define __NEWMERGER__h__
-
-class RegMeta;
-
-class MDTOKENMAP;
-
-// module-level awareness of Security critical annotions
-typedef BYTE InputScopeSecurityCriticalStatus;
-#define ISSCS_Unknown 0x0
-#define ISSCS_SecurityCritical 0x1
-#define ISSCS_SecurityCriticalEverything (ISSCS_SecurityCritical | 0x2)
-#define ISSCS_SecurityCriticalExplicit (ISSCS_SecurityCritical)
-#define ISSCS_SecurityTransparent 0x4
-#define ISSCS_SecurityTreatAsSafe 0x8
-#define ISSCS_SECURITYCRITICAL_LEGACY (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTreatAsSafe)
-#define ISSCS_SECURITYCRITICAL_FLAGS (ISSCS_SecurityCriticalEverything | ISSCS_SecurityTransparent)
-
-//*********************************************************************
-// MergeImportData
-//*********************************************************************
-class MergeImportData
-{
-public:
- RegMeta *m_pRegMetaImport;
- IUnknown *m_pHandler;
- IMapToken *m_pHostMapToken;
- MDTOKENMAP *m_pMDTokenMap;
- MergeImportData *m_pNextImportData;
-
- mdMemberRef m_tkSuppressMergeCheckCtor; // caches the SuppressMergeCheckAttribute's .ctor token
- mdMemberRef m_tkHandleProcessCorruptedStateCtor; // caches the memberRef token to HandleProcessCorruptedStateExceptionsAttribute's .ctor token
-
- // import contains assembly-level SecurityTransparent or SecurityCritical
- InputScopeSecurityCriticalStatus m_isscsSecurityCriticalStatus;
-#if _DEBUG
- int m_iImport; // debug only. This is the ith import for merge.
-#endif // _DEBUG
-};
-
-//*********************************************************************
-// MergeTypeData
-//*********************************************************************
-struct MergeTypeData
-{
- ULONG m_cMethods;
- ULONG m_cFields;
- ULONG m_cEvents;
- ULONG m_cProperties;
- BOOL m_bSuppressMergeCheck;
-};
-
-
-//*********************************************************************
-// Class to handle merge
-//*********************************************************************
-class NEWMERGER
-{
- friend class RegMeta;
-public:
- NEWMERGER();
- ~NEWMERGER();
-
- HRESULT Init(RegMeta *pRegMetaDest);
-
- HRESULT AddImport(
- IMetaDataImport2 *pImport, // [IN] The scope to be merged.
- IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification
- IUnknown *pHandler); // [IN] An object to receive to receive error notification.
-
- HRESULT Merge(MergeFlags flags, CorRefToDefCheck optimizeRefToDef);
-
-protected:
-
- CMiniMdRW *GetMiniMdEmit();
-
- HRESULT InitMergeTypeData();
-
- HRESULT MergeTypeDefNamesOnly();
- HRESULT MergeModuleRefs();
- HRESULT MergeAssemblyRefs();
- HRESULT MergeTypeRefs();
- HRESULT CompleteMergeTypeDefs();
-
- HRESULT CopyTypeDefPartially(
- TypeDefRec *pRecEmit, // [IN] the emit record to fill
- CMiniMdRW *pMiniMdImport, // [IN] the importing scope
- TypeDefRec *pRecImp); // [IN] the record to import
-
- // helpers for merging tables
- HRESULT MergeModule( );
- HRESULT MergeTypeDefChildren();
- HRESULT MergeInterfaceImpls( );
- HRESULT MergeMemberRefs( );
- HRESULT MergePinvoke();
-
- HRESULT MergeConstants( );
- HRESULT MergeCustomAttributes( );
- HRESULT MergeFieldMarshals( );
- HRESULT MergeDeclSecuritys( );
- HRESULT MergeClassLayouts( );
- HRESULT MergeFieldLayouts( );
- HRESULT MergeFieldRVAs();
- HRESULT MergeMethodImpls( );
- HRESULT MergeStandAloneSigs();
- HRESULT MergeMethodSpecs();
- HRESULT MergeTypeSpecs();
- HRESULT MergeSourceFiles( );
- HRESULT MergeBlocks( );
- HRESULT MergeScopes( );
- HRESULT MergeLocalVariables( );
- HRESULT MergeStrings( );
-
- HRESULT MergeAssembly();
- HRESULT MergeFiles();
- HRESULT MergeExportedTypes();
- HRESULT MergeManifestResources();
-
- // helpers for SecurityCritical-related merging
- InputScopeSecurityCriticalStatus CheckInputScopeIsCritical(MergeImportData* pImportData, HRESULT& hr);
- HRESULT RetrieveStandardSecurityCriticalMetaData(
- mdAssemblyRef& tkMscorlib,
- mdTypeRef& securityEnum,
- BYTE*& rgSigBytesSecurityCriticalEverythingCtor,
- DWORD& dwSigEverythingSize,
- BYTE*& rgSigBytesSecurityCriticalExplicitCtor,
- DWORD& dwSigExplicitSize);
-
- HRESULT MergeSecurityCriticalModuleLevelAttributes(
- MergeImportData* pImportData,
- mdToken tkParentImp, TOKENREC* pTypeRec,
- mdToken mrSecurityTreatAsSafeAttributeCtor,
- mdToken mrSecurityTransparentAttributeCtor,
- mdToken mrSecurityCriticalExplicitAttributeCtor,
- mdToken mrSecurityCriticalEverythingAttributeCtor);
- HRESULT MergeSecurityCriticalAttributes();
-
- // copy over a interfaceimpl record
- HRESULT CopyInterfaceImpl(
- InterfaceImplRec *pRecEmit, // [IN] the emit record to fill
- MergeImportData *pImportData, // [IN] the importing context
- InterfaceImplRec *pRecImp); // [IN] the record to import
-
- // verification helpers
- HRESULT VerifyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit);
- HRESULT VerifyGenericParams(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT VerifyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit);
-
- // Copy helpers
- HRESULT CopyMethods(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyFields(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyEvents(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyProperties(MergeImportData *pImportData, mdTypeDef tdImp, mdTypeDef tdEmit);
- HRESULT CopyParams(MergeImportData *pImportData, mdMethodDef mdImp, mdMethodDef mdEmit);
- HRESULT CopyGenericParams(MergeImportData *pImportData, mdToken tkImp, mdToken tkEmit);
- HRESULT CopyGenericParamConstraints(MergeImportData *pImportData, mdGenericParam gpImp, mdGenericParam gpEmit);
-
- HRESULT CopyMethod(
- MergeImportData *pImportData, // [IN] import scope
- MethodRec *pRecImp, // [IN] the record to import
- MethodRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyField(
- MergeImportData *pImportData, // [IN] import scope
- FieldRec *pRecImp, // [IN] the record to import
- FieldRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyEvent(
- MergeImportData *pImportData, // [IN] import scope
- EventRec *pRecImp, // [IN] the record to import
- EventRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyProperty(
- MergeImportData *pImportData, // [IN] import scope
- PropertyRec *pRecImp, // [IN] the record to import
- PropertyRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyParam(
- MergeImportData *pImportData, // [IN] import scope
- ParamRec *pRecImp, // [IN] the record to import
- ParamRec *pRecEmit); // [IN] the emit record to fill
-
- HRESULT CopyMethodSemantics(
- MergeImportData *pImportData,
- mdToken tkImport, // Event or property in the import scope
- mdToken tkEmit); // corresponding event or property in the emitting scope
-
- HRESULT VerifyMethod(
- MergeImportData *pImportData,
- mdMethodDef mdImp, // [IN] the emit record to fill
- mdMethodDef mdEmit); // [IN] the record to import
-
- HRESULT OnError(HRESULT hr, MergeImportData *pImportData, mdToken token);
-
-private:
- RegMeta *m_pRegMetaEmit;
- MergeImportData *m_pImportDataList;
- MergeImportData **m_pImportDataTail;
- MergeFlags m_dwMergeFlags;
- BOOL m_fDupCheck;
- CorRefToDefCheck m_optimizeRefToDef;
- // the combined value of the Security Critical input scopes (e.g. UNION of each scope's attributes)
- // if ANY of the scopes have a bit set, then we must do some merging
- InputScopeSecurityCriticalStatus m_isscsSecurityCritical;
- // the common values of the Security Critical input scopes (e.g. INTERSECTION of each scope's attributes)
- // if all scopes have the same bit set, then we can emit one bit at the final output scope
- InputScopeSecurityCriticalStatus m_isscsSecurityCriticalAllScopes;
-
- CDynArray<MergeTypeData> m_rMTDs;
-#if _DEBUG
- int m_iImport; // debug only. To count how many import scopes to be merged.
-#endif // _DEBUG
-};
-
-
-#define CheckContinuableErrorEx(EXPR, HANDLER, TOKEN) \
-{ \
- HRESULT hrOnErr, hrExpr; \
- hrExpr = EXPR; \
- \
- hrOnErr = OnError(hrExpr, HANDLER, TOKEN); \
- if (hrOnErr != S_OK) \
- { \
- if (hrOnErr == S_FALSE) \
- { \
- hr = hrExpr; \
- } \
- else if (SUCCEEDED(hrOnErr)) \
- { \
- hr = E_UNEXPECTED; \
- } \
- else if (FAILED(hrOnErr)) \
- { \
- hr = hrOnErr; \
- } \
- IfFailGo(hr); \
- } \
-}
-
-
-#endif // __NEWMERGER__h__
diff --git a/src/md/compiler/regmeta.cpp b/src/md/compiler/regmeta.cpp
index feb1cdd31b..f591a6e01b 100644
--- a/src/md/compiler/regmeta.cpp
+++ b/src/md/compiler/regmeta.cpp
@@ -59,9 +59,6 @@ RegMeta::RegMeta() :
m_fIsTypeDefDirty(false),
m_fIsMemberDefDirty(false),
m_fStartedEE(false),
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- m_pCorHost(NULL),
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
m_pAppDomain(NULL),
m_OpenFlags(0),
m_cRef(0),
@@ -167,10 +164,6 @@ RegMeta::~RegMeta()
if (m_fStartedEE)
{
m_pAppDomain->Release();
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- m_pCorHost->Stop();
- m_pCorHost->Release();
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
}
if (m_pFilterManager != NULL)
@@ -284,11 +277,6 @@ RegMeta::CreateNewMD()
INDEBUG(m_pStgdb->m_MiniMd.Debug_SetLock(m_pSemReadWrite);)
}
-#ifdef FEATURE_METADATA_EMIT_ALL
- // initialize the embedded merger
- m_newMerger.Init(this);
-#endif //FEATURE_METADATA_EMIT_ALL
-
ErrExit:
return hr;
} // RegMeta::CreateNewMD
@@ -347,11 +335,6 @@ HRESULT RegMeta::OpenExistingMD(
if (!IsOfReOpen(dwOpenFlags))
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- // initialize the embedded merger
- m_newMerger.Init(this);
-#endif //FEATURE_METADATA_EMIT_ALL
-
// There must always be a Global Module class and its the first entry in
// the TypeDef table.
m_tdModule = TokenFromRid(1, mdtTypeDef);
@@ -405,11 +388,6 @@ HRESULT RegMeta::OpenExistingMD(
if (!IsOfReOpen(dwOpenFlags))
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- // initialize the embedded merger
- m_newMerger.Init(this);
-#endif //FEATURE_METADATA_EMIT_ALL
-
// There must always be a Global Module class and its the first entry in
// the TypeDef table.
m_tdModule = TokenFromRid(1, mdtTypeDef);
@@ -556,12 +534,10 @@ RegMeta::QueryInterface(
*ppUnk = static_cast<IMetaDataTables2 *>(this);
}
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
else if (riid == IID_IMetaDataInfo)
{
*ppUnk = static_cast<IMetaDataInfo *>(this);
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
#ifdef FEATURE_METADATA_EMIT
else if (riid == IID_IMetaDataEmit)
@@ -581,12 +557,6 @@ RegMeta::QueryInterface(
}
#endif //FEATURE_METADATA_EMIT
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
- else if (riid == IID_IMetaDataValidate)
- {
- *ppUnk = (IMetaDataValidate *)this;
- }
-#endif //defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
#ifdef FEATURE_METADATA_EMIT_ALL
else if (riid == IID_IMetaDataFilter)
@@ -698,7 +668,6 @@ ErrExit:
return hr;
} // RegMeta::QueryInterface
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
//---------------------------------------------------------------------------------------
//
@@ -794,7 +763,6 @@ ErrExit:
return hr;
} // RegMeta::GetFileMapping
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
//------------------------------------------------------------------------------
// Metadata dump
diff --git a/src/md/compiler/regmeta.h b/src/md/compiler/regmeta.h
index cb7bae17b5..04456d8548 100644
--- a/src/md/compiler/regmeta.h
+++ b/src/md/compiler/regmeta.h
@@ -20,16 +20,11 @@
#include "../inc/mdlog.h"
#include "utsem.h"
-#include "newmerger.h"
-
#include "rwutil.h"
#include "mdperf.h"
#include <ivehandler.h>
#include "sigparser.h"
-#ifdef FEATURE_FUSION
-#include "fusion.h"
-#endif
#include "winmdinterfaces.h"
@@ -155,9 +150,7 @@ class RegMeta :
public IMetaDataAssemblyImport,
public IMetaDataTables2
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
, public IMetaDataInfo
-#endif
#ifdef FEATURE_METADATA_EMIT
, public IMetaDataEmit2
@@ -188,7 +181,6 @@ class RegMeta :
#endif
, public IMDCommon
{
- friend class NEWMERGER;
friend class CImportTlb;
friend class MDInternalRW;
friend class MDInternalRO;
@@ -1492,7 +1484,6 @@ public:
const void **ppv, // [OUT] put pointer to MD stream here.
ULONG *pcb); // [OUT] put size of the stream here.
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
//*****************************************************************************
// IMetaDataInfo
@@ -1511,7 +1502,6 @@ public:
ULONGLONG * pcbData, // [out] Size of the mapped memory region..
DWORD * pdwMappingType); // [out] Type of file mapping (code:CorFileMapping).
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
#if defined(FEATURE_METADATA_IN_VM) && defined(FEATURE_PREJIT)
@@ -1633,8 +1623,6 @@ protected:
}
HRESULT PreSave();
- HRESULT ProcessFilter();
- HRESULT ProcessFilterWorker();
// Initialize the EE
HRESULT StartupEE();
@@ -2026,18 +2014,12 @@ protected:
bool m_fIsTypeDefDirty; // This flag is set when the TypeRef to TypeDef map is not valid
bool m_fIsMemberDefDirty; // This flag is set when the MemberRef to MemberDef map is not valid
bool m_fStartedEE; // Set when EE runtime has been started up.
-#ifdef FEATURE_INCLUDE_ALL_INTERFACES
- ICorRuntimeHost *m_pCorHost; // Hosting environment for EE runtime.
-#endif // FEATURE_INCLUDE_ALL_INTERFACES
IUnknown *m_pAppDomain; // AppDomain in which managed security code will be run.
private:
ULONG m_OpenFlags; // Open time flags.
LONG m_cRef; // Ref count.
-#ifdef FEATURE_METADATA_EMIT_ALL
- NEWMERGER m_newMerger; // class for handling merge
-#endif //FEATURE_METADATA_EMIT_ALL
IUnknown *m_pFreeThreadedMarshaler; // FreeThreadedMarshaler
#ifdef FEATURE_METADATA_PERF_STATS
@@ -2059,9 +2041,6 @@ private:
CorValidatorModuleType m_ModuleType;
IVEHandler *m_pVEHandler;
-#ifndef FEATURE_CORECLR
- ValidateRecordFunction m_ValidateRecordFunctionTable[TBL_COUNT];
-#endif
CCustAttrHash m_caHash; // Hashed list of custom attribute types seen.
bool m_bKeepKnownCa; // Should all known CA's be kept?
diff --git a/src/md/compiler/regmeta_compilersupport.cpp b/src/md/compiler/regmeta_compilersupport.cpp
index 0bea06699b..571f9288b6 100644
--- a/src/md/compiler/regmeta_compilersupport.cpp
+++ b/src/md/compiler/regmeta_compilersupport.cpp
@@ -49,35 +49,7 @@ STDMETHODIMP RegMeta::Merge( // S_OK or error.
IMapToken *pHostMapToken, // [IN] Host IMapToken interface to receive token remap notification
IUnknown *pHandler) // [IN] An object to receive to receive error notification.
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- HRESULT hr = NOERROR;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- IMetaDataImport2 *pI2=NULL;
-
- LOG((LOGMD, "RegMeta::Merge(0x%08x, 0x%08x)\n", pImport, pHandler));
- START_MD_PERF();
- LOCKWRITE();
-
- IfFailGo(VerifyNotWinMD(pImport, "IMetaDataEmit::Merge(): merging with a .winmd file not supported."));
-
- IfFailGo(pImport->QueryInterface(IID_IMetaDataImport2, (void**)&pI2));
- m_hasOptimizedRefToDef = false;
-
- // track this import
- IfFailGo( m_newMerger.AddImport(pI2, pHostMapToken, pHandler) );
-
-ErrExit:
- if (pI2)
- pI2->Release();
- STOP_MD_PERF(Merge);
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
-#else //!FEATURE_METADATA_EMIT_ALL
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_EMIT_ALL
} // RegMeta::Merge
@@ -86,32 +58,7 @@ ErrExit:
//*****************************************************************************
STDMETHODIMP RegMeta::MergeEnd() // S_OK or error.
{
-#ifdef FEATURE_METADATA_EMIT_ALL
- HRESULT hr = NOERROR;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- LOG((LOGMD, "RegMeta::MergeEnd()\n"));
- START_MD_PERF();
- LOCKWRITE();
- // Merge happens here!!
-
- // <REVISIT_TODO>bug 16719. Merge itself is doing a lots of small changes in literally
- // dozens of places. It would be to hard to maintain and would cause code
- // bloat to auto-grow the tables. So instead, we've opted to just expand
- // the world right away and avoid the trouble.</REVISIT_TODO>
- IfFailGo(m_pStgdb->m_MiniMd.ExpandTables());
-
- IfFailGo(m_newMerger.Merge(m_OptionValue.m_MergeOptions, m_OptionValue.m_RefToDefCheck) );
-
-ErrExit:
- STOP_MD_PERF(MergeEnd);
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
-#else //!FEATURE_METADATA_EMIT_ALL
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_EMIT_ALL
} // RegMeta::MergeEnd
@@ -282,225 +229,4 @@ ErrExit:
#endif //!FEATURE_METADATA_EMIT_ALL
} // RegMeta::ResetENCLog
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-// Helper for code:RegMeta::ProcessFilter
-HRESULT RegMeta::ProcessFilterWorker()
-{
- HRESULT hr = S_OK;
-
- CMiniMdRW *pMiniMd; // The MiniMd with the data.
- RegMeta *pMetaNew = NULL;
- CMapToken *pMergeMap = NULL;
- IMapToken *pMapNew = NULL;
- MergeTokenManager *pCompositHandler = NULL;
- IMapToken *pHostMapToken = NULL;
-
- // For convenience.
- pMiniMd = &(m_pStgdb->m_MiniMd);
- IfNullGo( pMiniMd->GetFilterTable() );
- _ASSERTE(pMiniMd->GetFilterTable()->Count() != 0); // caller verified this
-
- // Yes, client has used filter to specify what are the metadata needed.
- // We will create another instance of RegMeta and make this module an imported module
- // to be merged into the new RegMeta. We will provide the handler to track all of the token
- // movements. We will replace the merged light weight stgdb to this RegMeta..
- // Then we will need to fix up the MergeTokenManager with this new movement.
- // The reason that we decide to choose this approach is because it will be more complicated
- // and very likely less efficient to fix up the signature blob pool and then compact all of the pools!
- //
-
- // Create a new RegMeta.
- pMetaNew = new (nothrow) RegMeta();
- IfNullGo( pMetaNew );
- pMetaNew->AddRef();
- IfFailGo(pMetaNew->SetOption(&m_OptionValue));
-
-
- // Remember the open type.
- IfFailGo(pMetaNew->CreateNewMD());
- IfFailGo(pMetaNew->AddToCache());
-
- // Ignore the error return by setting handler
- hr = pMetaNew->SetHandler(m_pHandler);
-
- // create the IMapToken to receive token remap information from merge
- pMergeMap = new (nothrow) CMapToken;
- IfNullGo( pMergeMap );
-
- // use merge to filter out the unneeded data. But we need to keep COMType and also need to drop off the
- // CustomAttributes that associated with MemberRef with parent MethodDef
- //
- pMetaNew->m_hasOptimizedRefToDef = false;
- IfFailGo( pMetaNew->m_newMerger.AddImport(this, pMergeMap, NULL) );
- IfFailGo( pMetaNew->m_pStgdb->m_MiniMd.ExpandTables());
- IfFailGo( pMetaNew->m_newMerger.Merge((MergeFlags)(MergeManifest | DropMemberRefCAs | NoDupCheck), MDRefToDefDefault) );
-
- // Now we need to recalculate the token movement
- //
- if (m_newMerger.m_pImportDataList)
- {
-
- // This is the case the filter is applied to merged emit scope. We need calculate how this implicit merge
- // affects the original merge remap. Basically we need to walk all the m_pTkMapList in the merger and replace
- // the to token to the most recent to token.
- //
- MDTOKENMAP *pMDTokenMapList;
-
- pMDTokenMapList = m_newMerger.m_pImportDataList->m_pMDTokenMap;
-
- MDTOKENMAP *pMap;
- TOKENREC *pTKRec;
- ULONG i;
- mdToken tkFinalTo;
- ModuleRec *pMod;
- ModuleRec *pModNew;
- LPCUTF8 szName;
-
- // update each import map from merge to have the m_tkTo points to the final mapped to token
- for (pMap = pMDTokenMapList; pMap; pMap = pMap->m_pNextMap)
- {
- // update each record
- for (i = 0; i < (ULONG) (pMap->Count()); i++)
- {
- TOKENREC *pRecTo;
- pTKRec = pMap->Get(i);
- if ( pMergeMap->Find( pTKRec->m_tkTo, &pRecTo ) )
- {
- // This record is kept by the filter and the tkTo is changed
- pRecTo->m_isFoundInImport = true;
- tkFinalTo = pRecTo->m_tkTo;
- pTKRec->m_tkTo = tkFinalTo;
- pTKRec->m_isDeleted = false;
-
- // send the notification now. Because after merge, we may have everything in order and
- // won't send another set of notification.
- //
- LOG((LOGMD, "TokenRemap in RegMeta::ProcessFilter (IMapToken 0x%08x): from 0x%08x to 0x%08x\n", pMap->m_pMap, pTKRec->m_tkFrom, pTKRec->m_tkTo));
-
- pMap->m_pMap->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo);
- }
- else
- {
- // This record is pruned by the filter upon save
- pTKRec->m_isDeleted = true;
- }
- }
- }
-
- // now walk the pMergeMap and check to see if there is any entry that is not set to true for m_isFoundInImport.
- // These are the records that from calling DefineXXX methods directly on the Emitting scope!
- if (m_pHandler)
- m_pHandler->QueryInterface(IID_IMapToken, (void **)&pHostMapToken);
- if (pHostMapToken)
- {
- for (i = 0; i < (ULONG) (pMergeMap->m_pTKMap->Count()); i++)
- {
- pTKRec = pMergeMap->m_pTKMap->Get(i);
- if (pTKRec->m_isFoundInImport == false)
- {
- LOG((LOGMD, "TokenRemap in RegMeta::ProcessFilter (default IMapToken 0x%08x): from 0x%08x to 0x%08x\n", pHostMapToken, pTKRec->m_tkFrom, pTKRec->m_tkTo));
-
- // send the notification on the IMapToken from SetHandler of this RegMeta
- pHostMapToken->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo);
- }
- }
- }
-
- // Preserve module name across merge.
- IfFailGo(m_pStgdb->m_MiniMd.GetModuleRecord(1, &pMod));
- IfFailGo(pMetaNew->m_pStgdb->m_MiniMd.GetModuleRecord(1, &pModNew));
- IfFailGo(m_pStgdb->m_MiniMd.getNameOfModule(pMod, &szName));
- IfFailGo(pMetaNew->m_pStgdb->m_MiniMd.PutString(TBL_Module, ModuleRec::COL_Name, pModNew, szName));
-
- // now swap the stgdb but keep the merger...
- _ASSERTE( !IsOfExternalStgDB(m_OpenFlags) );
-
- CLiteWeightStgdbRW * pStgdbTmp = m_pStgdb;
- m_pStgdb = pMetaNew->m_pStgdb;
- pMetaNew->m_pStgdb = pStgdbTmp;
- // Update RuntimeVersion string pointers to point to the owning RegMeta string (the strings are 2 copies of the same string content)
- m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = m_OptionValue.m_RuntimeVersion;
- pMetaNew->m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = pMetaNew->m_OptionValue.m_RuntimeVersion;
- }
- else
- {
- // swap the Stgdb
- CLiteWeightStgdbRW * pStgdbTmp = m_pStgdb;
- m_pStgdb = pMetaNew->m_pStgdb;
- pMetaNew->m_pStgdb = pStgdbTmp;
- // Update RuntimeVersion string pointers to point to the owning RegMeta string (the strings are 2 copies of the same string content)
- m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = m_OptionValue.m_RuntimeVersion;
- pMetaNew->m_pStgdb->m_MiniMd.m_OptionValue.m_RuntimeVersion = pMetaNew->m_OptionValue.m_RuntimeVersion;
-
- // Client either open an existing scope and apply the filter mechanism, or client define the scope and then
- // apply the filter mechanism.
-
- // In this case, host better has supplied the handler!!
- _ASSERTE( m_bRemap && m_pHandler);
- IfFailGo( m_pHandler->QueryInterface(IID_IMapToken, (void **) &pMapNew) );
-
-
- {
- // Send the notification of token movement now because after merge we may not move tokens again
- // and thus no token notification will be send.
- MDTOKENMAP *pMap = pMergeMap->m_pTKMap;
- TOKENREC *pTKRec;
- ULONG i;
-
- for (i=0; i < (ULONG) (pMap->Count()); i++)
- {
- pTKRec = pMap->Get(i);
- pMap->m_pMap->Map(pTKRec->m_tkFrom, pTKRec->m_tkTo);
- }
-
- }
-
-
- // What we need to do here is create a IMapToken that will replace the original handler. This new IMapToken
- // upon called will first map the from token to the most original from token.
- //
- pCompositHandler = new (nothrow) MergeTokenManager(pMergeMap->m_pTKMap, NULL);
- IfNullGo( pCompositHandler );
-
- // now update the following field to hold on to the real IMapToken supplied by our client by SetHandler
- if (pMergeMap->m_pTKMap->m_pMap)
- pMergeMap->m_pTKMap->m_pMap->Release();
- _ASSERTE(pMapNew);
- pMergeMap->m_pTKMap->m_pMap = pMapNew;
-
- // ownership transferred
- pMergeMap = NULL;
- pMapNew = NULL;
-
- // now you want to replace all of the IMapToken set by calling SetHandler to this new MergeTokenManager
- IfFailGo( m_pStgdb->m_MiniMd.SetHandler(pCompositHandler) );
-
- m_pHandler = pCompositHandler;
-
- // ownership transferred
- pCompositHandler = NULL;
- }
-
- // Force a ref to def optimization because the remap information was stored in the thrown away CMiniMdRW
- m_hasOptimizedRefToDef = false;
- IfFailGo( RefToDefOptimization() );
-
-ErrExit:
- if (pHostMapToken)
- pHostMapToken->Release();
- if (pMetaNew)
- pMetaNew->Release();
- if (pMergeMap)
- pMergeMap->Release();
- if (pCompositHandler)
- pCompositHandler->Release();
- if (pMapNew)
- pMapNew->Release();
-
- return hr;
-} // RegMeta::ProcessFilter
-
-#endif //FEATURE_METADATA_EMIT_ALL
-
#endif //FEATURE_METADATA_EMIT
diff --git a/src/md/compiler/regmeta_emit.cpp b/src/md/compiler/regmeta_emit.cpp
index 22d2979343..d3268fec8a 100644
--- a/src/md/compiler/regmeta_emit.cpp
+++ b/src/md/compiler/regmeta_emit.cpp
@@ -279,13 +279,6 @@ STDMETHODIMP RegMeta::GetSaveSize( // S_OK or error.
IfFailGo(m_pFilterManager->Mark(TokenFromRid(iCount, mdtAssembly)));
}
}
-#ifdef FEATURE_METADATA_EMIT_ALL
- else if (m_newMerger.m_pImportDataList)
- {
- // always pipe through another pass of merge to drop unnecessary ref for linker.
- MarkAll();
- }
-#endif //FEATURE_METADATA_EMIT_ALL
IfFailGo(PreSave());
@@ -734,7 +727,6 @@ HRESULT RegMeta::PreSave() // Return code.
HRESULT hr = S_OK; // A result.
CMiniMdRW *pMiniMd; // The MiniMd with the data.
unsigned bRemapOld = m_bRemap;
- MergeTokenManager *ptkMgr = NULL;
// For convenience.
pMiniMd = &(m_pStgdb->m_MiniMd);
@@ -745,21 +737,6 @@ HRESULT RegMeta::PreSave() // Return code.
if (m_bSaveOptimized)
goto ErrExit;
-#ifdef FEATURE_METADATA_EMIT_ALL
- if (m_newMerger.m_pImportDataList != NULL)
- {
- // This is the linker scenario. We we have IMap for each scope. We will create an instance of our own mapper
- // who knows how to send notification back to host!
-
- // cache the host provided handler to the end our MergeTokenManager
-
- ptkMgr = new (nothrow) MergeTokenManager(m_newMerger.m_pImportDataList->m_pMDTokenMap, m_pHandler);
- IfNullGo(ptkMgr);
- hr = m_pStgdb->m_MiniMd.SetHandler(ptkMgr);
- _ASSERTE(SUCCEEDED(hr));
- }
-#endif //FEATURE_METADATA_EMIT_ALL
-
IfFailGo(RefToDefOptimization());
// we need to update MethodImpl table here with ref to def result
@@ -808,19 +785,7 @@ HRESULT RegMeta::PreSave() // Return code.
}
}
}
-
-#ifdef FEATURE_METADATA_EMIT_ALL
- IfFailGo(ProcessFilter());
-
- if (m_newMerger.m_pImportDataList != NULL)
- {
- // Allocate a token mapper object that will be used for phase 1 if there is not Handler but
- // linker has provided the IMapToken
- //
- m_bRemap = true;
- }
-#endif //FEATURE_METADATA_EMIT_ALL
-
+
// reget the minimd because it can be swapped in the call of ProcessFilter
pMiniMd = &(m_pStgdb->m_MiniMd);
@@ -831,13 +796,6 @@ HRESULT RegMeta::PreSave() // Return code.
IfFailGo(m_pStgdb->m_MiniMd.PreSave(m_ReorderingOptions, m_pCorProfileData));
ErrExit:
- if (ptkMgr != NULL)
- {
- // recovery the initial state
- hr = m_pStgdb->m_MiniMd.SetHandler(NULL);
- ptkMgr->Release();
- }
-
m_bRemap = bRemapOld;
return hr;
@@ -1008,37 +966,6 @@ ErrExit:
return hr;
} // RegMeta::RefToDefOptimization
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-//*****************************************************************************
-// Process filter
-//*****************************************************************************
-HRESULT RegMeta::ProcessFilter()
-{
- HRESULT hr = S_OK;
-
- CMiniMdRW *pMiniMd; // The MiniMd with the data.
-
- START_MD_PERF();
-
- // For convenience.
- pMiniMd = &(m_pStgdb->m_MiniMd);
- IfNullGo( pMiniMd->GetFilterTable() );
- if ( pMiniMd->GetFilterTable()->Count() == 0 )
- {
- // there is no filter
- goto ErrExit;
- }
- hr = ProcessFilterWorker();
-
-ErrExit:
- STOP_MD_PERF(ProcessFilter);
-
- return hr;
-} // RegMeta::ProcessFilter
-
-#endif //FEATURE_METADATA_EMIT_ALL
-
//*****************************************************************************
// Define a TypeRef given the fully qualified name.
//*****************************************************************************
diff --git a/src/md/compiler/regmeta_vm.cpp b/src/md/compiler/regmeta_vm.cpp
index beebb08b5c..a4d9397b0e 100644
--- a/src/md/compiler/regmeta_vm.cpp
+++ b/src/md/compiler/regmeta_vm.cpp
@@ -29,23 +29,6 @@
#include <metamodelrw.h>
-#ifndef FEATURE_CORECLR
-
-#include <metahost.h>
-
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo *g_pCLRRuntime;
-
-#ifdef FEATURE_METADATA_EMIT_ALL
-
-#include "iappdomainsetup.h"
-
-// {27FFF232-A7A8-40dd-8D4A-734AD59FCD41}
-EXTERN_GUID(IID_IAppDomainSetup, 0x27FFF232, 0xA7A8, 0x40dd, 0x8D, 0x4A, 0x73, 0x4A, 0xD5, 0x9F, 0xCD, 0x41);
-
-#endif //FEATURE_METADATA_EMIT_ALL
-
-#endif // !FEATURE_CORECLR
#define DEFINE_CUSTOM_NODUPCHECK 1
@@ -66,7 +49,7 @@ EXTERN_GUID(IID_IAppDomainSetup, 0x27FFF232, 0xA7A8, 0x40dd, 0x8D, 0x4A, 0x73, 0
//*****************************************************************************
HRESULT RegMeta::AddToCache()
{
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
HRESULT hr = S_OK;
// The ref count must be > 0 before the module is published, else another
@@ -83,9 +66,9 @@ ErrExit:
m_bCached = false;
}
return hr;
-#else //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#else // FEATURE_METADATA_IN_VM
return S_OK;
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
} // RegMeta::AddToCache
@@ -97,13 +80,13 @@ HRESULT RegMeta::FindCachedReadOnlyEntry(
DWORD dwOpenFlags, // Flags the new file is opened with.
RegMeta **ppMeta) // Put found RegMeta here.
{
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
return LOADEDMODULES::FindCachedReadOnlyEntry(szName, dwOpenFlags, ppMeta);
-#else //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#else // FEATURE_METADATA_IN_VM
// No cache support in standalone version.
*ppMeta = NULL;
return S_FALSE;
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
} // RegMeta::FindCachedReadOnlyEntry
@@ -117,90 +100,8 @@ HRESULT RegMeta::FindCachedReadOnlyEntry(
//*****************************************************************************
HRESULT RegMeta::StartupEE()
{
-#ifdef FEATURE_CORECLR
UNREACHABLE_MSG_RET("About to CoCreateInstance! This code should not be "
"reachable or needs to be reimplemented for CoreCLR!");
-#else // !FEATURE_CORECLR
-
- struct Param
- {
- RegMeta *pThis;
- IUnknown *pSetup;
- IAppDomainSetup *pDomainSetup;
- bool fDoneStart;
- HRESULT hr;
- } param;
- param.pThis = this;
- param.pSetup = NULL;
- param.pDomainSetup = NULL;
- param.fDoneStart = false;
- param.hr = S_OK;
-
- PAL_TRY(Param *, pParam, &param)
- {
- HRESULT hr = S_OK;
-
- DWORD dwBuffer[1 + (MAX_LONGPATH+1) * sizeof(WCHAR) / sizeof(DWORD) + 1];
- BSTR bstrDir = NULL;
-
- // Create a hosting environment.
- IfFailGo(g_pCLRRuntime->GetInterface(
- CLSID_CorRuntimeHost,
- IID_ICorRuntimeHost,
- (void **)&pParam->pThis->m_pCorHost));
-
- // Startup the runtime.
- IfFailGo(pParam->pThis->m_pCorHost->Start());
- pParam->fDoneStart = true;
-
- // Create an AppDomain Setup so we can set the AppBase.
- IfFailGo(pParam->pThis->m_pCorHost->CreateDomainSetup(&pParam->pSetup));
-
- // Get the current directory (place it in a BSTR).
- bstrDir = (BSTR)(dwBuffer + 1);
- if ((dwBuffer[0] = (WszGetCurrentDirectory(MAX_LONGPATH + 1, bstrDir) * sizeof(WCHAR))))
- {
- // QI for the IAppDomainSetup interface.
- IfFailGo(pParam->pSetup->QueryInterface(IID_IAppDomainSetup,
- (void**)&pParam->pDomainSetup));
-
- // Set the AppBase.
- pParam->pDomainSetup->put_ApplicationBase(bstrDir);
- }
-
- // Create a new AppDomain.
- IfFailGo(pParam->pThis->m_pCorHost->CreateDomainEx(W("Compilation Domain"),
- pParam->pSetup,
- NULL,
- &pParam->pThis->m_pAppDomain));
-
- // That's it, we're all set up.
- _ASSERTE(pParam->pThis->m_pAppDomain != NULL);
- pParam->pThis->m_fStartedEE = true;
-
- ErrExit:
- pParam->hr = hr;
- }
- PAL_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- _ASSERTE(!"Unexpected exception setting up hosting environment for security attributes");
- param.hr = E_FAIL;
- }
- PAL_ENDTRY
-
- // Cleanup temporary resources.
- if (m_pAppDomain && FAILED(param.hr))
- m_pAppDomain->Release();
- if (param.pDomainSetup)
- param.pDomainSetup->Release();
- if (param.pSetup)
- param.pSetup->Release();
- if (param.fDoneStart && FAILED(param.hr))
- m_pCorHost->Stop();
- if (m_pCorHost && FAILED(param.hr))
- m_pCorHost->Release();
- return param.hr;
-#endif // FEATURE_CORECLR
}
#endif //FEATURE_METADATA_EMIT_ALL
@@ -471,72 +372,16 @@ RegMeta::ResolveTypeRef(
goto ErrExit;
}
-#ifndef FEATURE_CORECLR
- wcscpy_s(rcModule, _MAX_PATH, wzNameSpace);
-
- //******************
- // Try to find the module on CORPATH
- //******************
-
- if ((wcsncmp(rcModule, W("System."), 16) != 0) &&
- (wcsncmp(rcModule, W("System/"), 16) != 0))
- {
- // only go through regular CORPATH lookup by fully qualified class name when
- // it is not System.*
- hr = CORPATHService::GetClassFromCORPath(
- rcModule,
- tr,
- pMiniMd,
- riid,
- ppIScope,
- ptd);
- }
- else
- {
- // force it to look for System.* in mscorlib.dll
- hr = S_FALSE;
- }
-
- if (hr == S_FALSE)
- {
- LPWSTR szTmp;
- WszSearchPath(
- NULL,
- W("mscorlib.dll"),
- NULL,
- sizeof(rcModule) / sizeof(rcModule[0]),
- rcModule,
- &szTmp);
-
- //*******************
- // Last desperate try!!
- //*******************
-
- // Use the file name "mscorlib:
- IfFailGo(CORPATHService::FindTypeDef(
- rcModule,
- tr,
- pMiniMd,
- riid,
- ppIScope,
- ptd));
- if (hr == S_FALSE)
- {
- IfFailGo(META_E_CANNOTRESOLVETYPEREF);
- }
- }
-#else //FEATURE_CORECLR
IfFailGo(META_E_CANNOTRESOLVETYPEREF);
-#endif //FEATURE_CORECLR
ErrExit:
STOP_MD_PERF(ResolveTypeRef);
END_ENTRYPOINT_NOTHROW;
return hr;
-#else //!FEATURE_METADATA_IN_VM
+#else // FEATURE_METADATA_IN_VM
return E_NOTIMPL;
-#endif //!FEATURE_METADATA_IN_VM
+#endif // FEATURE_METADATA_IN_VM
} // RegMeta::ResolveTypeRef
@@ -551,11 +396,11 @@ ULONG RegMeta::Release()
CONTRACT_VIOLATION (SOToleranceViolation);
BEGIN_CLEANUP_ENTRYPOINT;
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
_ASSERTE(!m_bCached || LOADEDMODULES::IsEntryInList(this));
#else
_ASSERTE(!m_bCached);
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
BOOL bCached = m_bCached;
ULONG cRef = InterlockedDecrement(&m_cRef);
// NOTE: 'this' may be unsafe after this point, if the module is cached, and
@@ -570,7 +415,7 @@ ULONG RegMeta::Release()
// discovered the module, so this thread can now safely delete it.
delete this;
}
-#if defined(FEATURE_METADATA_IN_VM) || defined(FEATURE_METADATA_STANDALONE_WINRT)
+#if defined(FEATURE_METADATA_IN_VM)
else if (LOADEDMODULES::RemoveModuleFromLoadedList(this))
{ // If the module was cached, RemoveModuleFromLoadedList() will try to
// safely un-publish the module, and if it succeeds, no other thread
@@ -578,7 +423,7 @@ ULONG RegMeta::Release()
m_bCached = false;
delete this;
}
-#endif //!FEATURE_METADATA_IN_VM && !FEATURE_METADATA_STANDALONE_WINRT
+#endif // FEATURE_METADATA_IN_VM
}
END_CLEANUP_ENTRYPOINT
diff --git a/src/md/compiler/wks/CMakeLists.txt b/src/md/compiler/wks/CMakeLists.txt
index 6bf6c80868..eb39ca7972 100644
--- a/src/md/compiler/wks/CMakeLists.txt
+++ b/src/md/compiler/wks/CMakeLists.txt
@@ -1,4 +1,6 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDCOMPILER_SOURCES)
-add_library_clr(mdcompiler_wks ${MDCOMPILER_SOURCES}) \ No newline at end of file
+add_library_clr(mdcompiler_wks ${MDCOMPILER_SOURCES})
diff --git a/src/md/enc/imptlb.cpp b/src/md/enc/imptlb.cpp
deleted file mode 100644
index faeb0d9882..0000000000
--- a/src/md/enc/imptlb.cpp
+++ /dev/null
@@ -1,8057 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-// ===========================================================================
-// File: ImpTlb.CPP
-//
-
-//
-
-// ---------------------------------------------------------------
-// Who When What
-// ---------------------------------------------------------------
-// WGE 970906 Created
-//
-// ===========================================================================
-#include "stdafx.h"
-
-#include "imptlb.h"
-#include <posterror.h>
-#include <strongname.h>
-#include <nsutilpriv.h>
-
-#include "..\compiler\regmeta.h"
-#include "..\compiler\importhelper.h"
-#include "tlbutils.h" // For GenerateMangledTypeName().
-#include <tlbimpexp.h>
-#include "sstring.h"
-#include "strsafe.h"
-
-#include <metahost.h>
-
-// Pointer to the activated CLR interface provided by the shim.
-extern ICLRRuntimeInfo *g_pCLRRuntime;
-
-#ifdef wcsncmp
- #undef wcsncmp
-#endif
-#ifdef wcsncpy
- #undef wcsncpy
-#endif
-
-// deprecated: use the secureCrt replacements
-// _CRTIMP int __cdecl wcsncmp(const wchar_t *, const wchar_t *, size_t);
-// _CRTIMP wchar_t * __cdecl wcsncpy(wchar_t *, const wchar_t *, size_t);
-
-#define S_CONVERSION_LOSS _HRESULT_TYPEDEF_(3) // Non-error code meaning a conversion lost information.
-
-#define ADD_ITF_MEMBERS_TO_CLASS // Define to add interface members to the CoClass.
-#define ITF_MEMBER_RESOLUTION_NAMEONLY // Define to ignore signatures when looking for collisions (ie, when defined
- // void Foo(int) and void Foo(String) collide).
-
-// defines controlling ctor of non-creatable objects.
-#define NONCREATABLE_CTOR_VISIBILITY mdAssem // Define to a visibility flag.
-
-#define MAX_CLASSNAME_SIZE 1024
-
-#ifndef lengthof
-#define lengthof(rg) (sizeof(rg)/sizeof(rg[0]))
-#endif
-
-#ifndef IfNullGo
-#define IfNullGo(x) do {if (!(x)) IfFailGo(E_OUTOFMEMORY);} while (0)
-#endif
-
-#define BUILD_CUSTOM_ATTRIBUTE(type,bytes) {*reinterpret_cast<UNALIGNED type*>(__pca) = bytes; __pca += sizeof(type); _ASSERTE(__pca-__ca <= sizeof(__ca));}
-#define INIT_CUSTOM_ATTRIBUTE(n) {_ASSERTE((n) <= (sizeof(__ca)-sizeof(SHORT)));__pca = __ca; BUILD_CUSTOM_ATTRIBUTE(USHORT,1);}
-#define SIZEOF_CUSTOM_ATTRIBUTE() ((ULONG) (__pca - __ca))
-#define PTROF_CUSTOM_ATTRIBUTE() (&__ca[0])
-#define DECLARE_CUSTOM_ATTRIBUTE(n) BYTE __ca[(n)+sizeof(SHORT)*2], *__pca;__pca=__ca; INIT_CUSTOM_ATTRIBUTE(n);
-#define APPEND_STRING_TO_CUSTOM_ATTRIBUTE(str) {int l = (int)strlen(str); __pca=(BYTE*)CPackedLen::PutLength(__pca,l);memcpy(__pca,str,l);__pca+=l;}
-#define FINISH_CUSTOM_ATTRIBUTE() {BUILD_CUSTOM_ATTRIBUTE(short,0);}
-
-#define DECLARE_DYNLEN_CUSTOM_ATTRIBUTE(n) CQuickArray<BYTE> __tmpCAArray; IfFailGo(__tmpCAArray.ReSizeNoThrow(n + sizeof(SHORT)*2)); BYTE *__ca, *__pca; __ca = __tmpCAArray.Ptr(); __pca=__ca; BUILD_CUSTOM_ATTRIBUTE(USHORT,1);
-#define BUILD_DYNLEN_CUSTOM_ATTRIBUTE(type,bytes) {*reinterpret_cast<UNALIGNED type*>(__pca) = bytes; __pca += sizeof(type); _ASSERTE(__pca-__ca <= (int)__tmpCAArray.Size());}
-#define FINISH_DYNLEN_CUSTOM_ATTRIBUTE() {BUILD_DYNLEN_CUSTOM_ATTRIBUTE(short,0);}
-
-#define APPEND_WIDE_STRING_TO_CUSTOM_ATTRIBUTE(str) \
-{ \
- CQuickArray<char> __tmpStr; \
- int __cStr = WszWideCharToMultiByte(CP_ACP, 0, str, -1, 0, 0, NULL, NULL); \
- IfFailGo(__tmpStr.ReSizeNoThrow(__cStr)); \
- __cStr = WszWideCharToMultiByte(CP_ACP, 0, str, -1, __tmpStr.Ptr(), __cStr, NULL, NULL); \
- __pca=(BYTE*)CPackedLen::PutLength(__pca,__cStr); \
- memcpy(__pca,__tmpStr.Ptr(),__cStr); \
- __pca+=__cStr; \
-}
-
-// The maximum number of bytes the encoding of a DWORD can take.
-#define DWORD_MAX_CB 4
-
-// The maximum number of bytes the encoding of a DWORD can take.
-#define STRING_OVERHEAD_MAX_CB 4
-
-// Use the unused variant types m_knowntypes for common types.
-#define VT_SLOT_FOR_GUID VT_EMPTY
-#define VT_SLOT_FOR_IENUMERABLE VT_NULL
-#define VT_SLOT_FOR_MULTICASTDEL VT_I2
-#define VT_SLOT_FOR_TYPE VT_I4
-#define VT_SLOT_FOR_STRINGBUF VT_I8
-
-static LPCWSTR szObject = W("System.Object");
-static LPCWSTR szValueType = W("System.ValueType");
-static LPCWSTR szEnum = W("System.Enum");
-
-static LPCWSTR TLB_CLASSLIB_ARRAY = {W("System.Array")};
-static LPCWSTR TLB_CLASSLIB_DATE = {W("System.DateTime")};
-static LPCWSTR TLB_CLASSLIB_DECIMAL = {W("System.Decimal")};
-static LPCWSTR TLB_CLASSLIB_VARIANT = {W("System.Variant")};
-static LPCWSTR TLB_CLASSLIB_GUID = {W("System.Guid")};
-static LPCWSTR TLB_CLASSLIB_IENUMERABLE = {W("System.Collections.IEnumerable")};
-static LPCWSTR TLB_CLASSLIB_MULTICASTDELEGATE = {W("System.MulticastDelegate")};
-static LPCWSTR TLB_CLASSLIB_TYPE = {W("System.Type")};
-static LPCWSTR TLB_CLASSLIB_STRINGBUFFER = {W("System.Text.StringBuilder")};
-
-static LPCWSTR COM_STDOLE2 = {W("StdOle")};
-static LPCWSTR COM_GUID = {W("GUID")};
-
-static const LPCWSTR PROP_DECORATION_GET = {W("get_")};
-static const LPCWSTR PROP_DECORATION_SET = {W("set_")};
-static const LPCWSTR PROP_DECORATION_LET = {W("let_")};
-static const int PROP_DECORATION_LEN = 4;
-
-static const LPCWSTR DLL_EXTENSION = {W(".dll")};
-static const int DLL_EXTENSION_LEN = 4;
-static const LPCWSTR EXE_EXTENSION = {W(".exe")};
-static const int EXE_EXTENSION_LEN = 4;
-
-static LPCWSTR const OBJECT_INITIALIZER_NAME = {W(".ctor")};
-static const int OBJECT_INITIALIZER_FLAGS = mdPublic | mdSpecialName;
-static const int OBJECT_INITIALIZER_IMPL_FLAGS = miNative | miRuntime | miInternalCall;
-static const int NONCREATABLE_OBJECT_INITIALIZER_FLAGS = NONCREATABLE_CTOR_VISIBILITY | mdSpecialName;
-
-static const COR_SIGNATURE OBJECT_INITIALIZER_SIG[3] = {
- (IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS), 0, ELEMENT_TYPE_VOID };
-
-static const int DEFAULT_INTERFACE_FUNC_FLAGS = mdPublic | mdVirtual | mdAbstract | mdHideBySig | mdNewSlot;
-static const int DEFAULT_PROPERTY_FUNC_FLAGS = mdPublic | mdVirtual | mdAbstract | mdHideBySig | mdSpecialName | mdNewSlot;
-static const int DEFAULT_CONST_FIELD_FLAGS = fdPublic | fdStatic | fdLiteral;
-static const int DEFAULT_RECORD_FIELD_FLAGS = fdPublic;
-static const int DELEGATE_INVOKE_FUNC_FLAGS = mdPublic | mdVirtual;
-
-static const int DEFAULT_ITF_FUNC_IMPL_FLAGS = miNative | miRuntime | miInternalCall;
-
-static const WCHAR VTBL_GAP_FUNCTION[] = {W("_VtblGap")};
-static const int VTBL_GAP_FUNCTION_FLAGS = mdPublic | mdSpecialName;
-static const int VTBL_GAP_FUNC_IMPL_FLAGS = miRuntime;
-static const COR_SIGNATURE VTBL_GAP_SIGNATURE[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT, 0, ELEMENT_TYPE_VOID};
-static const LPCWSTR VTBL_GAP_FORMAT_1 = {W("%ls%d")};
-static const LPCWSTR VTBL_GAP_FORMAT_N = {W("%ls%d_%d")};
-
-static const LPCWSTR ENUM_TYPE_NAME = {COR_ENUM_FIELD_NAME_W};
-static const DWORD ENUM_TYPE_FLAGS = fdPublic;
-static const COR_SIGNATURE ENUM_TYPE_SIGNATURE[] = {IMAGE_CEE_CS_CALLCONV_FIELD, ELEMENT_TYPE_I4};
-static const DWORD ENUM_TYPE_SIGNATURE_SIZE = lengthof(ENUM_TYPE_SIGNATURE);
-
-static const LPCWSTR DYNAMIC_NAMESPACE_NAME = {W("DynamicModule")};
-
-static const LPCWSTR UNSAFE_ITF_PREFIX = {W("Unsafe.")};
-
-static const LPCWSTR GET_ENUMERATOR_MEMBER_NAME = {W("GetEnumerator")};
-
-static const WCHAR CLASS_SUFFIX[] = {W("Class")};
-static const DWORD CLASS_SUFFIX_LENGTH = lengthof(CLASS_SUFFIX);
-static const WCHAR EVENT_ITF_SUFFIX[] = {W("_Event")};
-static const DWORD EVENT_ITF_SUFFIX_LENGTH = lengthof(EVENT_ITF_SUFFIX);
-static const WCHAR EVENT_PROVIDER_SUFFIX[] = {W("_EventProvider")};
-static const DWORD EVENT_PROVIDER_SUFFIX_LENGTH = lengthof(EVENT_ITF_SUFFIX);
-static const WCHAR EVENT_HANDLER_SUFFIX[] = {W("EventHandler")};
-static const DWORD EVENT_HANDLER_SUFFIX_LENGTH = lengthof(EVENT_HANDLER_SUFFIX);
-
-static const WCHAR EVENT_ADD_METH_PREFIX[] = {W("add_")};
-static const DWORD EVENT_ADD_METH_PREFIX_LENGTH = lengthof(EVENT_ADD_METH_PREFIX);
-static const WCHAR EVENT_REM_METH_PREFIX[] = {W("remove_")};
-static const DWORD EVENT_REM_METH_PREFIX_LENGTH = lengthof(EVENT_REM_METH_PREFIX);
-
-static const WCHAR DELEGATE_INVOKE_METH_NAME[] = {W("Invoke")};
-static const DWORD DELEGATE_INVOKE_METH_NAME_LENGTH = lengthof(EVENT_ADD_METH_PREFIX);
-
-// {C013B386-CC3E-4b6d-9B67-A3AE97274BBE}
-static const GUID FREE_STATUS_GUID =
-{ 0xc013b386, 0xcc3e, 0x4b6d, { 0x9b, 0x67, 0xa3, 0xae, 0x97, 0x27, 0x4b, 0xbe } };
-
-// {C013B387-CC3E-4b6d-9B67-A3AE97274BBE}
-static const GUID DELETED_STATUS_GUID =
-{ 0xc013b387, 0xcc3e, 0x4b6d, { 0x9b, 0x67, 0xa3, 0xae, 0x97, 0x27, 0x4b, 0xbe } };
-
-// {C013B388-CC3E-4b6d-9B67-A3AE97274BBE}
-static const GUID USED_STATUS_GUID =
-{ 0xc013b388, 0xcc3e, 0x4b6d, { 0x9b, 0x67, 0xa3, 0xae, 0x97, 0x27, 0x4b, 0xbe } };
-
-static const GUID IID_IEnumerable =
-{ 0x496b0abe, 0xcdee, 0x11d3, { 0x88, 0xe8, 0x00, 0x90, 0x27, 0x54, 0xc4, 0x3a } };
-
-
- #define STRUCTLAYOUT tdSequentialLayout
-// ULONG_MAX is a flag meaning "don't convert".
-static const ULONG rdwTypeFlags[] = {
- tdPublic | tdSealed, // TKIND_ENUM = 0,
- tdPublic | tdSealed | tdBeforeFieldInit | STRUCTLAYOUT, // TKIND_RECORD = TKIND_ENUM + 1,
- tdPublic | tdAbstract, // TKIND_MODULE = TKIND_RECORD + 1,
- tdPublic | tdInterface | tdAbstract | tdImport, // TKIND_INTERFACE = TKIND_MODULE + 1,
- tdPublic | tdInterface | tdAbstract | tdImport, // TKIND_DISPATCH = TKIND_INTERFACE + 1,
- tdPublic | tdImport, // TKIND_COCLASS = TKIND_DISPATCH + 1,
- tdPublic | tdImport, // TKIND_ALIAS = TKIND_COCLASS + 1,
- tdPublic | tdSealed | tdExplicitLayout, // TKIND_UNION = TKIND_ALIAS + 1,
- ULONG_MAX, // TKIND_MAX = TKIND_UNION + 1
-};
-static const LPCWSTR g_szTypekind[] = {
- W("Enum "),
- W("Record "),
- W("Module "),
- W("Interface "),
- W("Dispinterface"),
- W("Coclass "),
- W("Alias "),
- W("Union "),
-};
-
-#define NATIVE_TYPE_NONE ((CorNativeType)(NATIVE_TYPE_MAX+1))
-
-#define NON_CONVERTED_PARAMS_FLAGS (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)
-
-
-//*****************************************************************************
-// External declarations.
-//*****************************************************************************
-extern mdAssemblyRef DefineAssemblyRefForImportedTypeLib(
- void *pAssembly, // Assembly importing the typelib.
- void *pvModule, // Module importing the typelib.
- IUnknown *pIMeta, // IMetaData* from import module.
- IUnknown *pIUnk, // IUnknown to referenced Assembly.
- BSTR *pwzNamespace, // The namespace of the resolved assembly.
- BSTR *pwzAsmName, // The name of the resolved assembly.
- Assembly **AssemblyRef); // The resolved assembly.
-
-extern mdAssemblyRef DefineAssemblyRefForExportedAssembly(
- LPCWSTR szFullName, // Assembly full name.
- IUnknown *pIMeta); // Metadata emit interface.
-
-static HRESULT _UnpackVariantToConstantBlob(VARIANT *pvar, BYTE *pcvType, void **pvValue, __int64 *pd);
-static INT64 _DoubleDateToTicks(const double d);
-static HRESULT TryGetFuncDesc(ITypeInfo *pITI, int i, FUNCDESC **ppFunc);
-
-//*****************************************************************************
-// Class factory.
-//*****************************************************************************
-CImportTlb* CImportTlb::CreateImporter(
- LPCWSTR szLibrary,
- ITypeLib *pitlb,
- BOOL bGenerateTCEAdapters,
- BOOL bUnsafeInterfaces,
- BOOL bSafeArrayAsSystemArray,
- BOOL bTransformDispRetVals,
- BOOL bPreventClassMembers,
- BOOL bSerializableValueClasses)
-{
- return new (nothrow) CImportTlb(szLibrary, pitlb, bGenerateTCEAdapters, bUnsafeInterfaces, bSafeArrayAsSystemArray, bTransformDispRetVals, bPreventClassMembers, bSerializableValueClasses);
-} // CImportTlb* CImportTlb::CreateImporter()
-
-//*****************************************************************************
-// Default constructor.
-//*****************************************************************************
-CImportTlb::CImportTlb()
- : m_szLibrary(NULL),
- m_pITLB(NULL),
- m_bGenerateTCEAdapters(false),
- m_bSafeArrayAsSystemArray(false),
- m_bTransformDispRetVals(false),
- m_bPreventClassMembers(false),
- m_bSerializableValueClasses(false),
- m_pEmit(NULL),
- m_pImport(NULL),
- m_pITI(NULL),
- m_pOrigITI(NULL),
- m_psAttr(NULL),
- m_arSystem(mdAssemblyRefNil),
- m_Notify(NULL),
- m_trValueType(0),
- m_trEnum(0),
- m_bUnsafeInterfaces(FALSE),
- m_tkSuppressCheckAttr(mdTokenNil),
- m_tdHasDefault(0),
- m_szName(NULL),
- m_szMember(NULL),
- m_wzNamespace(NULL),
- m_tkInterface(0),
- m_szInterface(NULL),
- m_pMemberNames(NULL),
- m_cMemberProps(0),
- m_ImplIface(eImplIfaceNone)
-{
- // Clear the known types array. The values will be lazily initialized.
- memset(m_tkKnownTypes, 0, sizeof(m_tkKnownTypes));
- memset(m_tkAttr, 0, sizeof(m_tkAttr));
-} // CImportTlb::CImportTlb()
-
-//*****************************************************************************
-// Complex constructor.
-//*****************************************************************************
-CImportTlb::CImportTlb(
- LPCWSTR szLibrary, // Name of library being imported.
- ITypeLib *pitlb, // The type library to import from.
- BOOL bGenerateTCEAdapters, // A flag indicating if the TCE adapters are being generated.
- BOOL bUnsafeInterfaces, // A flag indicating that runtime security checks should be disabled
- BOOL bSafeArrayAsSystemArray,// A flag indicating whether to import SAFEARRAY's as System.Array's.
- BOOL bTransformDispRetVals, // A flag indicating if we should do [out,retval] transformation on disp only itfs.
- BOOL bPreventClassMembers, // A flag indicating if we should add members to CoClasses.
- BOOL bSerializableValueClasses) // A flag indicating if we should mark value classes serializable.
- : m_szLibrary(szLibrary),
- m_pITLB(pitlb),
- m_bGenerateTCEAdapters(bGenerateTCEAdapters),
- m_bUnsafeInterfaces(bUnsafeInterfaces),
- m_bSafeArrayAsSystemArray(bSafeArrayAsSystemArray),
- m_bTransformDispRetVals(bTransformDispRetVals),
- m_bPreventClassMembers(bPreventClassMembers),
- m_bSerializableValueClasses(bSerializableValueClasses),
- m_pEmit(0),
- m_pImport(0),
- m_pITI(0),
- m_pOrigITI(0),
- m_psAttr(0),
- m_arSystem(mdAssemblyRefNil),
- m_Notify(0),
- m_trValueType(0),
- m_trEnum(0),
- m_tkSuppressCheckAttr(mdTokenNil),
- m_tdHasDefault(0),
- m_szName(0),
- m_szMember(0),
- m_wzNamespace(0),
- m_tkInterface(0),
- m_szInterface(0),
- m_pMemberNames(0),
- m_cMemberProps(0),
- m_ImplIface(eImplIfaceNone)
-{
- if (pitlb)
- pitlb->AddRef();
-
- // Clear the known types array. The values will be lazily initialized.
- memset(m_tkKnownTypes, 0, sizeof(m_tkKnownTypes));
- memset(m_tkAttr, 0, sizeof(m_tkAttr));
-
-#if defined(TLB_STATS)
- m_bStats = QueryPerformanceFrequency(&m_freqVal);
-#endif
-} // CImportTlb::CImportTlb()
-
-//*****************************************************************************
-// Destructor.
-//*****************************************************************************
-CImportTlb::~CImportTlb()
-{
- if (m_pEmit)
- m_pEmit->Release();
- if (m_pImport)
- m_pImport->Release();
- if (m_pITLB)
- m_pITLB->Release();
- if (m_Notify)
- m_Notify->Release();
-
- if (m_wzNamespace)
- ::SysFreeString(m_wzNamespace);
-} // CImportTlb::~CImportTlb()
-
-
-//*****************************************************************************
-// Allow the user to specify a namespace to be used in the conversion.
-//*****************************************************************************
-HRESULT CImportTlb::SetNamespace(
- WCHAR const *pNamespace)
-{
- HRESULT hr=S_OK; // A result.
-
- IfNullGo(m_wzNamespace=::SysAllocString(pNamespace));
-
-ErrExit:
-
- return hr;
-} // HRESULT CImportTlb::SetNamespace()
-
-//*****************************************************************************
-// Allow the user to specify a notification object to be used in the conversion.
-//*****************************************************************************
-HRESULT CImportTlb::SetNotification(
- ITypeLibImporterNotifySink *pNotify)
-{
- _ASSERTE(m_Notify == 0);
- m_Notify = pNotify;
- pNotify->AddRef();
-
- return S_OK;
-} // HRESULT CImportTlb::SetNotification()
-
-//*****************************************************************************
-// Allow the user to specify the MetaData scope to be used in the conversion.
-//*****************************************************************************
-HRESULT CImportTlb::SetMetaData(
- IUnknown *pIUnk)
-{
- HRESULT hr;
- _ASSERTE(m_pEmit == 0);
- IfFailGo(pIUnk->QueryInterface(IID_IMetaDataEmit2, (void**)&m_pEmit));
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::SetMetaData()
-
-//*****************************************************************************
-// Import a TypeLibrary into a CompLib.
-//*****************************************************************************
-HRESULT CImportTlb::Import()
-{
-#ifndef DACCESS_COMPILE
- HRESULT hr; // A result.
- mdModule md; // Module token.
- VARIANT vt = {0}; // For setting options.
- ITypeLib2 *pITLB2 = 0; // To get custom attributes.
- IMetaDataDispenserEx *pDisp = 0; // To create export scope.
- TLIBATTR *psAttr=0; // The library's attributes.
- BSTR szLibraryName = 0; // The library's name.
- LPCWSTR wzFile; // The filename of the typelib (no path).
- LPCWSTR wzSource; // Source of the typelib, for CA.
-
- _ASSERTE(m_Notify);
-
- // Quick sanity check.
- if (!m_pITLB)
- return (E_INVALIDARG);
-
- // Check to see if the type library implements ITypeLib2.
- if (m_pITLB->QueryInterface(IID_ITypeLib2, (void **)&pITLB2) != S_OK)
- pITLB2 = 0;
-
- // If custom attribute for namespace exists, use it.
- if (pITLB2)
- {
- VARIANT vt;
- VariantInit(&vt);
- if (pITLB2->GetCustData(GUID_ManagedName, &vt) == S_OK)
- {
- if (V_VT(&vt) == VT_BSTR)
- {
- // If there already was a namespace set, release it.
- if (m_wzNamespace)
- SysFreeString(m_wzNamespace);
-
- // If the namespace ends with .dll then remove the extension.
- LPWSTR pDest = wcsstr(vt.bstrVal, DLL_EXTENSION);
- if (pDest && (pDest[DLL_EXTENSION_LEN] == 0 || pDest[DLL_EXTENSION_LEN] == ' '))
- *pDest = 0;
-
- if (!pDest)
- {
- // If the namespace ends with .exe then remove the extension.
- pDest = wcsstr(vt.bstrVal, EXE_EXTENSION);
- if (pDest && (pDest[EXE_EXTENSION_LEN] == 0 || pDest[EXE_EXTENSION_LEN] == ' '))
- *pDest = 0;
- }
-
- if (pDest)
- {
- // We removed the extension so re-allocate a string of the new length.
- m_wzNamespace = SysAllocString(vt.bstrVal);
- SysFreeString(vt.bstrVal);
- IfNullGo(m_wzNamespace);
- }
- else
- {
- // There was no extension to remove so we can use the string returned
- // by GetCustData().
- m_wzNamespace = vt.bstrVal;
- }
- }
- else
- {
- VariantClear(&vt);
- }
- }
- }
-
- // Use the namespace name if we don't know the filename.
- if (!m_szLibrary)
- m_szLibrary = m_wzNamespace;
-
- // If the typelib was exported from COM+ to begin with, don't import it.
- if (pITLB2)
- {
- ::VariantInit(&vt);
- hr = pITLB2->GetCustData(GUID_ExportedFromComPlus, &vt);
- if (vt.vt != VT_EMPTY)
- {
- if (0)
- {
- // com emulates option is ON
- }
- else
- {
- IfFailGo(PostError(TLBX_E_CIRCULAR_IMPORT, m_szLibrary));
- }
- }
- }
-
- _ASSERTE(m_pEmit);
- IfFailGo(m_pEmit->QueryInterface(IID_IMetaDataImport2, (void **)&m_pImport));
-
- // Initialize the reserved names map.
- IfFailGo(m_ReservedNames.Init());
-
- // Initialize the default interface to class interface map for the TLB being imported.
- IfFailGo(m_DefItfToClassItfMap.Init(m_pITLB, m_wzNamespace));
-
- // Create the Object classref record and AssemblyRef for mscorlib.dll.
- IfFailGo(_DefineSysRefs());
-
- // Create the library record.
- IfFailGo(_NewLibraryObject());
-
- // Note that this was imported.
- IfFailGo(m_pITLB->GetLibAttr(&psAttr));
- if (SUCCEEDED(::QueryPathOfRegTypeLib(psAttr->guid, psAttr->wMajorVerNum, psAttr->wMinorVerNum, psAttr->lcid, &szLibraryName)))
- wzSource = szLibraryName;
- else
- wzSource = m_szLibrary;
-
- // We can't base the decision on SYSKIND. For example, we can have a SYS_WIN64 tlb loaded as 32-bit with 4-byte aligned pointers.
- m_cbVtableSlot = 0;
-
- IfFailGo(m_pImport->GetModuleFromScope(&md));
- // Skip the path or drive info
- wzFile = wcsrchr(wzSource, W('\\'));
- if (wzFile == 0)
- { // That's odd, should have been a fully qualified path. Just use an empty string.
- wzFile = W("");
- }
- else
- { // skip leading backslash
- wzFile++;
- }
-
- // Convert the typelib.
- IfFailGo(ConvertTypeLib());
-
-ErrExit:
- if (psAttr)
- m_pITLB->ReleaseTLibAttr(psAttr);
- if (szLibraryName)
- ::SysFreeString(szLibraryName);
- if (pITLB2)
- pITLB2->Release();
- if (pDisp)
- pDisp->Release();
-
- return (hr);
-#else
- DacNotImpl();
- return E_NOTIMPL;
-#endif // #ifndef DACCESS_COMPILE
-} // HRESULT CImportTlb::Import()
-
-//*****************************************************************************
-// Create the Complib to represent the TypeLib.
-//*****************************************************************************
-HRESULT CImportTlb::_NewLibraryObject()
-{
- HRESULT hr; // A result.
- TLIBATTR * psAttr=0; // The library's attributes.
- BSTR szLibraryName=0; // The library's name.
- CQuickArray<WCHAR> rScopeName; // The name of the scope.
-
- // Information about the library.
- IfFailGo(m_pITLB->GetLibAttr(&psAttr));
- IfFailGo(m_pITLB->GetDocumentation(MEMBERID_NIL, &szLibraryName, 0, 0, 0));
-
- // Create the scope name by using the typelib name and adding .dll.
- IfFailGo(rScopeName.ReSizeNoThrow(SysStringLen(szLibraryName) + 5 * sizeof(WCHAR)));
- StringCchPrintf(rScopeName.Ptr(), rScopeName.Size(), W("%s.dll"), szLibraryName);
-
- IfFailGo(m_pEmit->SetModuleProps(rScopeName.Ptr()));
-
-ErrExit:
- if (psAttr)
- m_pITLB->ReleaseTLibAttr(psAttr);
-
- if (szLibraryName)
- ::SysFreeString(szLibraryName);
-
- return (hr);
-} // HRESULT CImportTlb::_NewLibraryObject()
-
-//*****************************************************************************
-// Define an assembly ref for mscorlib, typeref for Object.
-//*****************************************************************************
-HRESULT CImportTlb::_DefineSysRefs()
-{
- HRESULT hr; // A result.
- WCHAR szPath[_MAX_PATH];
- WCHAR szDrive[_MAX_DRIVE];
- WCHAR szDir[_MAX_PATH];
- DWORD dwLen; // Length of system directory name.
- IMetaDataDispenserEx *pDisp = 0; // To import mscorlib.
- IMetaDataAssemblyImport *pAImp = 0; // To read mscorlib assembly.
- IMetaDataAssemblyEmit *pAEmit = 0; // To create mscorlib assembly ref.
- ASSEMBLYMETADATA amd = {0}; // Assembly metadata.
- mdToken tk; // A token.
- const void *pvPublicKey; // Public key.
- ULONG cbPublicKey; // Length of public key.
- BYTE *pbToken=0; // Compressed token for public key.
- ULONG cbToken; // Length of token.
- ULONG ulHashAlg; // Hash algorithm.
- DWORD dwFlags; // Assembly flags.
-
- // Get the dispenser.
- IfFailGo(g_pCLRRuntime->GetInterface(
- CLSID_CorMetaDataDispenser,
- IID_IMetaDataDispenserEx,
- (void **)&pDisp));
-
- // Get the name of mscorlib.
- //@todo: define, function, etc., instead of hard coded "mscorlib"
- dwLen = lengthof(szPath) - 13; // allow space for "mscorlib" ".dll" "\0"
- IfFailGo(pDisp->GetCORSystemDirectory(szPath, dwLen, &dwLen));
- SplitPath(szPath, szDrive, _MAX_DRIVE, szDir, _MAX_PATH, 0, 0, 0, 0);
- MakePath(szPath, szDrive, szDir, W("mscorlib"), W(".dll"));
-
- // Open the scope, get the details.
- IfFailGo(pDisp->OpenScope(szPath, 0, IID_IMetaDataAssemblyImport, (IUnknown**)&pAImp));
- IfFailGo(pAImp->GetAssemblyFromScope(&tk));
- IfFailGo(pAImp->GetAssemblyProps(tk, &pvPublicKey,&cbPublicKey, &ulHashAlg,
- szPath,lengthof(szPath),&dwLen, &amd, &dwFlags));
-
- if (!StrongNameTokenFromPublicKey((BYTE*)(pvPublicKey),cbPublicKey, &pbToken,&cbToken))
- {
- hr = StrongNameErrorInfo();
- goto ErrExit;
- }
- dwFlags &= ~afPublicKey;
-
- // Define the assembly ref.
- IfFailGo(m_pEmit->QueryInterface(IID_IMetaDataAssemblyEmit, (void**)&pAEmit));
- IfFailGo(pAEmit->DefineAssemblyRef(pbToken,cbToken, szPath, &amd,0,0,dwFlags, &m_arSystem));
-
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, szObject, &m_trObject));
-
- m_tkKnownTypes[VT_DISPATCH] = m_trObject;
- m_tkKnownTypes[VT_UNKNOWN] = m_trObject;
- m_tkKnownTypes[VT_VARIANT] = m_trObject;
-
-ErrExit:
- if (pbToken)
- StrongNameFreeBuffer(pbToken);
- if (pDisp)
- pDisp->Release();
- if (pAEmit)
- pAEmit->Release();
- if (pAImp)
- pAImp->Release();
-
- return hr;
-} // HRESULT CImportTlb::_DefineSysRefs()
-
-//*****************************************************************************
-// Lazily get the token for a CustomAttribute.
-//*****************************************************************************
-HRESULT CImportTlb::GetAttrType(
- int attr, // The attribute for which the type is desired.
- mdToken *pTk) // Put the type here.
-{
- HRESULT hr = S_OK; // A result.
- mdTypeRef tr; // An intermediate typeref.
- DWORD dwSigSize; // The size of the sig for special sigs.
- DWORD dwMaxSigSize; // The max size of the special sig.
- COR_SIGNATURE *pSig; // Pointer to the start of the sig,
- COR_SIGNATURE *pCurr; // Current sig pointer.
- mdTypeRef trType; // The typeref for System.Type.
-
- _ASSERTE(attr >= 0);
- _ASSERTE(attr < ATTR_COUNT);
-
- //@todo: globally define these names.
-#define INTEROP_ATTRIBUTE(x) static COR_SIGNATURE x##_SIG[] = INTEROP_##x##_SIG;
-#define INTEROP_ATTRIBUTE_SPECIAL(x)
- INTEROP_ATTRIBUTES();
-#undef INTEROP_ATTRIBUTE
-#undef INTEROP_ATTRIBUTE_SPECIAL
-#define INTEROP_ATTRIBUTE(x) \
- case ATTR_##x: \
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, INTEROP_##x##_TYPE_W, &tr)); \
- IfFailGo(m_pEmit->DefineMemberRef(tr, W(".ctor"), x##_SIG, lengthof(x##_SIG), &m_tkAttr[attr])); \
- break;
-#define INTEROP_ATTRIBUTE_SPECIAL(x)
-
- if (IsNilToken(m_tkAttr[attr]))
- {
- switch (attr)
- {
- INTEROP_ATTRIBUTES();
-
- case ATTR_COMEVENTINTERFACE:
- {
- // Retrieve token for System.Type.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_TYPE, &trType));
-
- // Build the sig.
- dwMaxSigSize = 5 + sizeof(mdTypeRef) * 2;
- pSig = (COR_SIGNATURE*)_alloca(dwMaxSigSize);
- pCurr = pSig;
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = 2;
- *pCurr++ = ELEMENT_TYPE_VOID;
- *pCurr++ = ELEMENT_TYPE_CLASS;
- pCurr += CorSigCompressToken(trType, pCurr);
- *pCurr++ = ELEMENT_TYPE_CLASS;
- pCurr += CorSigCompressToken(trType, pCurr);
- dwSigSize = (DWORD)(pCurr - pSig);
- _ASSERTE(dwSigSize <= dwMaxSigSize);
-
- // Declare the typeref and the member ref for the CA.
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, INTEROP_COMEVENTINTERFACE_TYPE_W, &tr)); \
- IfFailGo(m_pEmit->DefineMemberRef(tr, W(".ctor"), pSig, dwSigSize, &m_tkAttr[attr])); \
- break;
- }
-
- case ATTR_COCLASS:
- {
- // Retrieve token for System.Type.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_TYPE, &trType));
-
- // Build the sig.
- dwMaxSigSize = 4 + sizeof(mdTypeRef);
- pSig = (COR_SIGNATURE*)_alloca(dwMaxSigSize);
- pCurr = pSig;
- *pCurr++ = IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS;
- *pCurr++ = 1;
- *pCurr++ = ELEMENT_TYPE_VOID;
- *pCurr++ = ELEMENT_TYPE_CLASS;
- pCurr += CorSigCompressToken(trType, pCurr);
- dwSigSize = (DWORD)(pCurr - pSig);
- _ASSERTE(dwSigSize <= dwMaxSigSize);
-
- // Declare the typeref and the member ref for the CA.
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, INTEROP_COCLASS_TYPE_W, &tr)); \
- IfFailGo(m_pEmit->DefineMemberRef(tr, W(".ctor"), pSig, dwSigSize, &m_tkAttr[attr])); \
- break;
- }
- }
- }
-#undef INTEROP_ATTRIBUTE
-#undef INTEROP_ATTRIBUTE_SPECIAL
-
- *pTk = m_tkAttr[attr];
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::GetAttrType()
-
-//*****************************************************************************
-// Create the TypeDefs.
-//*****************************************************************************
-HRESULT
-CImportTlb::ConvertTypeLib()
-{
- HRESULT hr;
- int cTi; // Count of TypeInfos.
- int i; // Loop control.
-
- // How many TypeInfos?
- IfFailGo(cTi = m_pITLB->GetTypeInfoCount());
-
- // Iterate over them.
- for (i = 0; i < cTi; ++i)
- {
- // Get the TypeInfo.
- hr = m_pITLB->GetTypeInfo(i, &m_pITI);
- if (SUCCEEDED(hr))
- {
- // Save up the original TypeInfo (may be later alias-resolved).
- _ASSERTE(m_pOrigITI == NULL);
- m_pOrigITI = m_pITI;
- m_pOrigITI->AddRef();
-
- // Retrieve the attributes of the type info.
- IfFailGo(m_pITI->GetTypeAttr(&m_psAttr));
-
- // Convert the TypeInfo.
- hr = ConvertTypeInfo();
- if (FAILED(hr))
- {
- if (hr == CEE_E_CVTRES_NOT_FOUND || hr == TLBX_I_RESOLVEREFFAILED)
- { // Reflection emit is broken, no need to try to continue.
- goto ErrExit;
- }
-
- BSTR szTypeInfoName = NULL;
- hr = m_pITI->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0);
- if (SUCCEEDED(hr))
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, szTypeInfoName);
- }
- else
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO_UNNAMED, i);
- }
- if (szTypeInfoName != NULL)
- ::SysFreeString(szTypeInfoName);
-#if defined(_DEBUG)
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_TlbImp_BreakOnErr))
- _ASSERTE(!"Invalid type");
-#endif
- }
-
- // Release for next TypeInfo.
- m_pOrigITI->Release();
- m_pOrigITI = NULL;
-
- m_pITI->ReleaseTypeAttr(m_psAttr);
- m_psAttr = NULL;
- m_pITI->Release();
- m_pITI = NULL;
- }
- }
-
-ErrExit:
- if (m_pOrigITI != NULL)
- {
- m_pOrigITI->Release();
- m_pOrigITI = NULL;
- }
-
- if (m_psAttr != NULL)
- {
- m_pITI->ReleaseTypeAttr(m_psAttr);
- m_psAttr = NULL;
- }
- if (m_pITI != NULL)
- {
- m_pITI->Release();
- m_pITI = NULL;
- }
- return hr;
-} // CImportTlb::ConvertTypeLib
-
-//*****************************************************************************
-// Convert a single ITypeInfo into the scope.
-//*****************************************************************************
-HRESULT CImportTlb::ConvertTypeInfo() // S_OK or error.
-{
- HRESULT hr; // A result.
- BSTR bstrManagedName=0; // Managed name (or part thereof).
- CQuickArray<WCHAR> qbClassName; // The name of the class.
- ULONG ulFlags; // TypeDef flags.
- WORD wTypeInfoFlags; // TypeInfo flags. Alias flags, if an alias.
- mdToken tkAttr; // Attribute type for flags.
- TYPEKIND tkindAlias; // TYPEKIND of an aliased TypeInfo.
- GUID guid; // GUID of the typeinfo.
- BOOL bConversionLoss=false; // If true, info was lost converting sigs.
- mdToken tkParent; // Parent of the typedef.
- mdToken td; // For looking up a TypeDef.
- ITypeInfo2 *pITI2=0; // For getting custom value.
-
-#if defined(TLB_STATS)
- WCHAR rcStats[16]; // Buffer for stats.
- LARGE_INTEGER __startVal;
- QueryPerformanceCounter(&__startVal);
-#endif
-
- m_tdTypeDef = mdTypeDefNil;
-
- // Get some information about the TypeInfo.
- IfFailGo(m_pITI->GetDocumentation(MEMBERID_NIL, &m_szName, 0, 0, 0));
-
-#if defined(_DEBUG)
- LPWSTR strShouldBreakOnTypeName = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_TlbImp_BreakOnTypeImport);
- if ((NULL != strShouldBreakOnTypeName) && (wcsncmp(strShouldBreakOnTypeName, m_szName, MAX_CLASSNAME_LENGTH) == 0))
- _ASSERTE(!"MD_TlbImp_BreakOnTypeImport");
-#endif
-
- // Assume that we will be able to convert the typeinfo.
- guid = m_psAttr->guid;
- wTypeInfoFlags = m_psAttr->wTypeFlags;
-
- // If this typeinfo is an alias, see what it is an alias for. If for a built-in
- // type, we will just skip it. If for a user-defined type, we will duplicate
- // that definition under this alias' name and guid.
- if (m_psAttr->typekind == TKIND_ALIAS)
- {
- hr = _ResolveTypeDescAliasTypeKind(m_pITI, &m_psAttr->tdescAlias, &tkindAlias);
- IfFailGo(hr);
- if (hr == S_OK)
- {
- TYPEDESC tdesc = m_psAttr->tdescAlias;
- m_pITI->ReleaseTypeAttr(m_psAttr);
- m_pITI->Release();
-
- IfFailGo(_ResolveTypeDescAlias(m_pOrigITI, &tdesc, &m_pITI, &m_psAttr, &guid));
- // Now m_pOrigITI refers to the alias whereas m_pITI is the TypeInfo of the aliased type.
-
- // We should no longer have an alias.
- _ASSERTE(m_psAttr->typekind == tkindAlias);
- _ASSERTE(tkindAlias != TKIND_ALIAS);
-
- ulFlags = rdwTypeFlags[tkindAlias];
- }
- else
- ulFlags = ULONG_MAX;
- }
- else
- {
- ulFlags = rdwTypeFlags[m_psAttr->typekind];
- }
-
- // Figure out the name.
-
- // If the type info is for a CoClass, we need to decorate the name.
- if (m_psAttr->typekind == TKIND_COCLASS)
- {
- // Generate a mangled name for the component.
- IfFailGo(GetManagedNameForCoClass(m_pOrigITI, qbClassName));
- m_szMngName = qbClassName.Ptr();
- }
- else
- {
- IfFailGo(GetManagedNameForTypeInfo(m_pOrigITI, m_wzNamespace, NULL, &bstrManagedName));
- m_szMngName = bstrManagedName;
- }
-
- if (m_psAttr->typekind == TKIND_INTERFACE ||
- (m_psAttr->typekind == TKIND_DISPATCH && m_psAttr->wTypeFlags & TYPEFLAG_FDUAL))
- {
- // If the interface is not derived from IUnknown, or not an interface, we can't convert it.
- if (IsIUnknownDerived(m_pITI, m_psAttr) != S_OK)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_NOTIUNKNOWN, m_szName);
- ulFlags = ULONG_MAX;
- }
- // If the interface is not derived from IDispatch, but claims to be [dual], give a warning but convert it.
- if ((m_psAttr->wTypeFlags & TYPEFLAG_FDUAL) && IsIDispatchDerived(m_pITI, m_psAttr) != S_OK)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_DUAL_NOT_DISPATCH, m_szName);
- }
- }
- else
- if (m_psAttr->typekind == TKIND_MODULE)
- { // If module has no vars, skip it. We currently don't import module functions.
- if (m_psAttr->cVars == 0)
- ulFlags = ULONG_MAX;
- }
-
- // If something we can convert...
- if (ulFlags != ULONG_MAX)
- {
- // Interfaces derive from nil...
- if (IsTdInterface(ulFlags))
- tkParent = mdTypeDefNil;
- else // ... enums from Enum, ...
- if (m_psAttr->typekind == TKIND_ENUM)
- {
- if (IsNilToken(m_trEnum))
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, szEnum, &m_trEnum));
- tkParent = m_trEnum;
- }
- else // ... structs from ValueType, ...
- if (m_psAttr->typekind == TKIND_RECORD || m_psAttr->typekind == TKIND_UNION)
- {
- if (IsNilToken(m_trValueType))
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, szValueType, &m_trValueType));
- tkParent = m_trValueType;
- }
- else // ... and classes derive from Object.
- tkParent = m_trObject;
-
- // The typelib importer generates metadata into an empty ReflectionEmit scope. Because
- // RE manages type names itself, duplicate checking is turned off. Because of user-defined
- // names (via CUSTOM), it is possible for the user to declare a duplicate. So,
- // before adding the new type, check for duplicates.
- hr = m_pImport->FindTypeDefByName(m_szMngName, mdTypeDefNil, &td);
- if (hr != CLDB_E_RECORD_NOTFOUND)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_DUPLICATE_TYPE_NAME, m_szMngName);
- IfFailGo(TLBX_E_DUPLICATE_TYPE_NAME);
- }
-
- // Create the typedef.
- IfFailGo(m_pEmit->DefineTypeDef(m_szMngName, ulFlags, tkParent, 0, &m_tdTypeDef));
- IfFailGo(_AddGuidCa(m_tdTypeDef, guid));
-
- // Save the typeinfo flags.
- if (wTypeInfoFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBTYPE, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, wTypeInfoFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- // Mark unsafe interfaces (suppressed security runtime checks).
- if (m_bUnsafeInterfaces)
- {
- if (m_tkSuppressCheckAttr == mdTokenNil)
- {
- mdTypeRef tr;
- COR_SIGNATURE rSig[] = {IMAGE_CEE_CS_CALLCONV_DEFAULT_HASTHIS, 0, ELEMENT_TYPE_VOID};
- IfFailGo(m_pEmit->DefineTypeRefByName(m_arSystem, COR_SUPPRESS_UNMANAGED_CODE_CHECK_ATTRIBUTE, &tr));
- IfFailGo(m_pEmit->DefineMemberRef(tr, COR_CTOR_METHOD_NAME_W, rSig, lengthof(rSig), &m_tkSuppressCheckAttr));
- }
-
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, m_tkSuppressCheckAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Fill in the details depending on the type of the TypeInfo.
- switch (m_psAttr->typekind)
- {
- case TKIND_ENUM:
- hr = ConvEnum(m_pITI, m_psAttr);
- break;
-
- case TKIND_RECORD:
- hr = ConvRecord(m_pITI, m_psAttr, FALSE);
- break;
-
- case TKIND_UNION:
- hr = ConvRecord(m_pITI, m_psAttr, TRUE);
- break;
-
- case TKIND_MODULE:
- hr = ConvModule(m_pITI, m_psAttr);
- break;
-
- case TKIND_INTERFACE:
- hr = ConvIface(m_pITI, m_psAttr);
- break;
-
- case TKIND_DISPATCH:
- hr = ConvDispatch(m_pITI, m_psAttr);
- break;
-
- case TKIND_COCLASS:
- hr = ConvCoclass(m_pITI, m_psAttr);
- break;
-
- case TKIND_ALIAS:
- _ASSERTE(!"Alias should have been resolved!");
- break;
-
- default:
- _ASSERTE(!"Unexpected TYPEKIND");
- break;
- }
- if (FAILED(hr))
- goto ErrExit;
-
- if (hr == S_CONVERSION_LOSS)
- {
- bConversionLoss = true;
- IfFailGo(GetAttrType(ATTR_COMCONVERSIONLOSS, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(),SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
- else
- hr = S_OK;
-
-#if defined(TLB_STATS)
- LARGE_INTEGER __stopVal;
- QueryPerformanceCounter(&__stopVal);
- DWORD __delta;
- __delta = (DWORD)(__stopVal.QuadPart - __startVal.QuadPart);
- StringCchPrintf(rcStats, COUNTOF(rcStats), W(" %.2f"),
- ((float)__delta*1000)/(float)m_freqVal.QuadPart);
-#endif
-
- // Report that this type has been converted.
- ReportEvent(NOTIF_TYPECONVERTED, TLBX_I_TYPEINFO_IMPORTED, m_szName);
-
-ErrExit:
- if (pITI2)
- pITI2->Release();
- if (m_szName)
- ::SysFreeString(m_szName), m_szName = 0;
- if (bstrManagedName)
- ::SysFreeString(bstrManagedName);
- return (hr);
-} // HRESULT CImportTlb::ConvertTypeInfo()
-
-
-//*****************************************************************************
-// Determine if the type explicitly implements IEnumerable.
-//*****************************************************************************
-HRESULT CImportTlb::ExplicitlyImplementsIEnumerable(
- ITypeInfo *pITI, // ITypeInfo* to check for IEnumerable.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL fLookupPartner) // Flag indicating if we should look at the partner itf.
-{
- HREFTYPE href; // HREFTYPE of an implemented interface.
- ITypeInfo *pItiIface=0; // ITypeInfo for an interface.
- TYPEATTR *psAttrIface=0; // TYPEATTR for an interface.
- BOOL fFoundImpl = FALSE;
- int i = 0;
- HRESULT hr = S_OK;
- ITypeInfo* pITISelf2 = NULL;
- TYPEATTR psAttrSelf2;
- int ImplFlags = 0;
-
- // Look through each of the implemented/inherited interfaces
- for (i=0; i<psAttr->cImplTypes && !fFoundImpl; ++i)
- {
- // Get an interface
- IfFailGo(pITI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pItiIface));
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
- IfFailGo(pITI->GetImplTypeFlags(i, &ImplFlags));
-
- if (!(ImplFlags & IMPLTYPEFLAG_FSOURCE))
- {
- hr = ExplicitlyImplementsIEnumerable(pItiIface, psAttrIface, TRUE);
- if (hr == S_OK)
- fFoundImpl = TRUE;
-
- // Check this interface for the IEnumerable.
- if (psAttrIface->guid == IID_IEnumerable)
- fFoundImpl = TRUE;
- }
-
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- pItiIface->Release();
- pItiIface = 0;
- }
-
- if ( fLookupPartner && (pITI->GetRefTypeOfImplType(-1, &href) == S_OK) )
- {
- IfFailGo(pITI->GetRefTypeInfo(href, &pItiIface));
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
-
- hr = ExplicitlyImplementsIEnumerable(pItiIface, psAttrIface, FALSE);
- if (hr == S_OK)
- fFoundImpl = TRUE;
-
- // Check this interface for the IEnumerable.
- if (psAttrIface->guid == IID_IEnumerable)
- fFoundImpl = TRUE;
- }
-
-
-ErrExit:
- if (psAttrIface)
- pItiIface->ReleaseTypeAttr(psAttrIface);
- if (pItiIface)
- pItiIface->Release();
-
- return (fFoundImpl) ? S_OK : S_FALSE;
-}
-
-
-//*****************************************************************************
-// Convert the details for a coclass.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-HRESULT CImportTlb::ConvCoclass( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr) // TYPEATTR of TypeInfo.
-{
- BOOL fHadDefaultItf = FALSE;
- HRESULT hr; // A result.
- int i; // Loop control.
- HREFTYPE href; // HREFTYPE of an implemented interface.
- ITypeInfo *pItiIface=0; // ITypeInfo for an interface.
- TYPEATTR *psAttrIface=0; // TYPEATTR for an interface.
- int ImplFlags; // ImplType flags.
- mdToken tkIface; // Token for an interface.
- CQuickArray<mdToken> rImpls; // Array of implemented interfaces.
- CQuickArray<mdToken> rEvents; // Array of implemented event interfaces.
- CQuickArray<mdToken> rTmpImpls; // Temporary array of impls.
- CQuickArray<ITypeInfo*> rImplTypes; // Array of implemented ITypeInfo*s.
- CQuickArray<ITypeInfo*> rSrcTypes; // Array of source ITypeInfo*s.
- int ixSrc; // Index into rSrcTypes for source interfaces.
- int ixImpl; // Index into rImpls for implemented interface.
- int ixTmpImpl; // Index into rTmpImpls.
- mdToken mdCtor; // Dummy token for the object initializer.
- mdToken tkAttr; // Token for custom attribute type.
- mdToken token; // Dummy token for typeref.
- BOOL fInheritsIEnum = FALSE;
-
-#ifdef _DEBUG
- int bImplIEnumerable=0; // If true, the class implements IEnumerable.
-#endif
-
- // Size the rImpls and rSrcs arrays large enough for impls, events, the IEnumerable itf and two ending nulls.
- IfFailGo(rImpls.ReSizeNoThrow(psAttr->cImplTypes+2));
- memset(rImpls.Ptr(), 0, (psAttr->cImplTypes+2)*sizeof(mdToken));
- IfFailGo(rEvents.ReSizeNoThrow(psAttr->cImplTypes+1));
- memset(rEvents.Ptr(), 0, (psAttr->cImplTypes+1)*sizeof(mdToken));
- IfFailGo(rTmpImpls.ReSizeNoThrow(psAttr->cImplTypes+3));
- memset(rTmpImpls.Ptr(), 0, (psAttr->cImplTypes+3)*sizeof(mdToken));
- IfFailGo(rImplTypes.ReSizeNoThrow(psAttr->cImplTypes+2));
- memset(rImplTypes.Ptr(), 0, (psAttr->cImplTypes+2)*sizeof(ITypeInfo*));
- IfFailGo(rSrcTypes.ReSizeNoThrow(psAttr->cImplTypes+1));
- memset(rSrcTypes.Ptr(), 0, (psAttr->cImplTypes+1)*sizeof(ITypeInfo*));
- ixImpl = -1;
- ixSrc = -1;
- ixTmpImpl = -1;
-
- if (ExplicitlyImplementsIEnumerable(pITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // Build the list of implemented and event interfaces.
- // The EE cares about implemented interfaces, so we convert them to actual
- // tokens and add them to the typedef. VB cares about event interfaces,
- // but we are going to add a list of typeref names as a custom attribute.
- // We can't build the list as we go along, because the default may not
- // be the first event source. So, we store tokens for the implemented
- // interfaces, but ITypeInfo*s for the event sources.
- for (i=0; i<psAttr->cImplTypes; ++i)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pItiIface));
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
- IfFailGo(pITI->GetImplTypeFlags(i, &ImplFlags));
-
- // If the interface is derived from IUnknown, or not an interface, we can't use it as an interface.
- // Don't add explicit IUnknown or IDispatch.
- if ((IsIUnknownDerived(pItiIface, psAttrIface) != S_OK && psAttrIface->typekind != TKIND_DISPATCH) ||
- psAttrIface->guid == IID_IDispatch ||
- psAttrIface->guid == IID_IUnknown)
- {
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- pItiIface->Release();
- pItiIface = 0;
- continue;
- }
-
- // Add the event to the impls list or the events list.
- if (ImplFlags & IMPLTYPEFLAG_FSOURCE)
- {
- // Get the token for the event interface.
- IfFailGo(_GetTokenForEventItf(pItiIface, &tkIface));
-
- // If we've already marked this CoClass as implementing this source interface, don't do so again.
- for (int iCheck=0; iCheck <= ixSrc; iCheck++)
- {
- if (rEvents[iCheck] == tkIface)
- goto LoopEnd;
- }
-
- // Add the source interface to the list of source interfaces.
- ++ixSrc;
-
- // If this is explicitly the default source interface...
- if (ImplFlags & IMPLTYPEFLAG_FDEFAULT)
- {
- // Put the def source ITypeInfo at the head of the list of source
- // ITypeInfo's.
- for (int ix = ixSrc; ix > 0; --ix)
- {
- rSrcTypes[ix] = rSrcTypes[ix-1];
- rEvents[ix] = rEvents[ix-1];
- }
- rEvents[0] = tkIface;
- rSrcTypes[0] = pItiIface;
- }
- else
- {
- rEvents[ixSrc] = tkIface;
- rSrcTypes[ixSrc] = pItiIface;
- }
- }
- else
- {
- // Get the token for the interface.
- IfFailGo(_GetTokenForTypeInfo(pItiIface, FALSE, &tkIface));
-
- // If we've already marked this CoClass as implementing this interface, don't do so again.
- for (int iCheck=0; iCheck <= ixImpl; iCheck++)
- {
- if (rImpls[iCheck] == tkIface)
- goto LoopEnd;
- }
-
- // Add the implemented interface to the list of implemented interfaces.
- ++ixImpl;
-
- // If this is explicitly the default interface...
- if (ImplFlags & IMPLTYPEFLAG_FDEFAULT)
- {
- fHadDefaultItf = TRUE;
- // Put the new interface at the start of the list.
- for (int ix=ixImpl; ix > 0; --ix)
- {
- rImpls[ix] = rImpls[ix-1];
- rImplTypes[ix] = rImplTypes[ix-1];
- }
- rImpls[0] = tkIface;
- rImplTypes[0] = pItiIface;
- }
- else
- {
- rImpls[ixImpl] = tkIface;
- rImplTypes[ixImpl] = pItiIface;
- }
- }
-
-LoopEnd:
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- pItiIface = 0; // Pointer now owned by array.
- }
-
- // Create an interface that will represent the class.
- IfFailGo(_CreateClassInterface(pITI, rImplTypes[0], rImpls[0], rEvents[0], &tkIface));
-
- // Create a temporary array of interface tokens.
- if (fHadDefaultItf)
- {
- // default interface should be the first interface
- rTmpImpls[++ixTmpImpl] = rImpls[0];
- rTmpImpls[++ixTmpImpl] = tkIface;
- }
- else
- {
- rTmpImpls[++ixTmpImpl] = tkIface;
- if (ixImpl >= 0)
- rTmpImpls[++ixTmpImpl] = rImpls[0];
- }
- if (ixSrc >= 0)
- rTmpImpls[++ixTmpImpl] = rEvents[0];
- if (ixImpl >= 0)
- {
- memcpy(&rTmpImpls[ixTmpImpl + 1], &rImpls[1], ixImpl * sizeof(mdTypeRef));
- ixTmpImpl += ixImpl;
- }
- if (ixSrc >= 0)
- {
- memcpy(&rTmpImpls[ixTmpImpl + 1], &rEvents[1], ixSrc * sizeof(mdTypeRef));
- ixTmpImpl += ixSrc;
- }
-
- // Check to see if the default interface has a member with a DISPID of DISPID_NEWENUM.
- BOOL fIEnumFound = FALSE;
- if (ixImpl >= 0)
- {
- // The ITypeInfo for the default interface had better be set.
- _ASSERTE(rImplTypes[0]);
-
- if ( (!fInheritsIEnum) && (HasNewEnumMember(rImplTypes[0]) == S_OK) )
- {
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkIface));
- rTmpImpls[++ixTmpImpl] = tkIface;
- fIEnumFound = TRUE;
- }
- }
-
- // Else Check to see if the IEnumerable Custom Value exists on the CoClass.
- if (!fIEnumFound)
- {
- BOOL CVExists = FALSE;
- _ForceIEnumerableCVExists(pITI, &CVExists);
- if (CVExists && !fInheritsIEnum)
- {
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkIface));
- rTmpImpls[++ixTmpImpl] = tkIface;
- fIEnumFound = TRUE;
- }
- }
-
- // Add the implemented interfaces and event interfaces to the TypeDef.
- IfFailGo(m_pEmit->SetTypeDefProps(m_tdTypeDef, ULONG_MAX/*Classflags*/,
- ULONG_MAX, (mdToken*)rTmpImpls.Ptr()));
-
- // Create an initializer for the class.
- ULONG ulFlags;
- if (psAttr->wTypeFlags & TYPEFLAG_FCANCREATE)
- ulFlags = OBJECT_INITIALIZER_FLAGS;
- else
- ulFlags = NONCREATABLE_OBJECT_INITIALIZER_FLAGS;
- {
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, OBJECT_INITIALIZER_NAME, ulFlags,
- OBJECT_INITIALIZER_SIG, sizeof(OBJECT_INITIALIZER_SIG), 0/*rva*/, OBJECT_INITIALIZER_IMPL_FLAGS/*flags*/, &mdCtor));
- }
-
- // Set ClassInterfaceType.None on the generated class.
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- BUILD_CUSTOM_ATTRIBUTE(short, clsIfNone);
- IfFailGo(GetAttrType(ATTR_CLASSINTERFACE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
-
-
- if (!m_bPreventClassMembers)
- {
- // Iterate over the implemented interfaces, and add the members to the coclass.
- m_ImplIface = eImplIfaceDefault;
- for (i=0; i<=ixImpl; ++i)
- {
- _ASSERTE(rImplTypes[i]);
-
- // Interface info.
- m_tkInterface = rImpls[i];
- pItiIface = rImplTypes[i];
- rImplTypes[i] = 0; // ownership transferred.
-
- // Get interface name for decoration.
- if (m_szInterface)
- ::SysFreeString(m_szInterface), m_szInterface = 0;
- IfFailGo(pItiIface->GetDocumentation(MEMBERID_NIL, &m_szInterface, 0,0,0));
-
- // Add the interface members to the coclass.
- IfFailGo(pItiIface->GetTypeAttr(&psAttrIface));
- switch (psAttrIface->typekind)
- {
- case TKIND_DISPATCH:
- hr = ConvDispatch(pItiIface, psAttrIface, false);
- break;
- case TKIND_INTERFACE:
- hr = ConvIface(pItiIface, psAttrIface, false);
- break;
- default:
- hr = S_OK;
- _ASSERTE(!"Unexpected typekind for implemented interface");
- }
- pItiIface->ReleaseTypeAttr(psAttrIface);
- psAttrIface = 0;
- IfFailGo(hr);
- m_ImplIface = eImplIface;
- rImplTypes[i] = pItiIface;
- pItiIface = 0; // ownership transferred back.
- }
-
- // Add the methods of the event interfaces to the class.
- for (i=0; i<=ixSrc; ++i)
- IfFailGo(_AddSrcItfMembersToClass(rEvents[i]));
- }
-
- // If there are source interfaces, add a custom value for that.
- if (ixSrc >= 0)
- {
- CQuickArray<char> rEvents; // Output buffer.
- int cbCur; // Current location in output buffer.
- int cbReq; // Size of an individual piece.
- CQuickArray<WCHAR> rEvent;
-
- // Save 6 bytes at the beginning of the buffer for the custom attribute prolog and
- // the string length. The string length may require 1, 2, or 4 bytes to express.
- cbCur = 6;
-
- // For each event interface...
- for (int ix=0; ix <= ixSrc; ++ix)
- {
- pItiIface = rSrcTypes[ix];
- rSrcTypes[ix] = 0;
-
- // Get the typeref name for the interface.
- for(;;)
- {
- int cchReq;
- IfFailGo(_GetTokenForTypeInfo(pItiIface, FALSE, &token, rEvent.Ptr(), (int)rEvent.MaxSize(), &cchReq, TRUE));
- if (cchReq <= (int)rEvent.MaxSize())
- break;
- IfFailGo(rEvent.ReSizeNoThrow(cchReq));
- }
-
- // Append to the buffer. See how much space is required, get it.
- cbReq = WszWideCharToMultiByte(CP_UTF8,0, rEvent.Ptr(),-1, 0,0, 0,0);
-
- // make sure we have enough space for the extra terminating 0 and for the 00 00 suffix
- size_t cbNewSize;
- if (!ClrSafeInt<size_t>::addition(cbCur, cbReq, cbNewSize) ||
- !ClrSafeInt<size_t>::addition(cbNewSize, 3, cbNewSize))
- {
- IfFailGo(COR_E_OVERFLOW);
- }
- if (cbNewSize > rEvents.MaxSize())
- {
- IfFailGo(rEvents.ReSizeNoThrow(cbNewSize));
- }
- // Do the conversion.
- WszWideCharToMultiByte(CP_UTF8,0, rEvent.Ptr(),-1, rEvents.Ptr()+cbCur,cbReq, 0,0);
- cbCur += cbReq;
- pItiIface->Release();
- }
- pItiIface = 0;
-
- // Add an extra terminating 0.
- *(rEvents.Ptr()+cbCur) = 0;
- ++cbCur;
-
- // Now build the custom attribute.
- int iLen = cbCur - 6;
- char *pBytes = rEvents.Ptr();
-
- // Length may be encoded with less the 4 bytes.
- int lenPad = 4 - CPackedLen::Size(iLen);
- _ASSERTE(lenPad >= 0);
-
- pBytes += lenPad;
- cbCur -= lenPad;
-
- // Prologue.
- pBytes[0] = 0x01;
- pBytes[1] = 0x00;
-
- CPackedLen::PutLength(pBytes + 2, iLen);
-
- // Zero named properties/fields.
- pBytes[cbCur + 0] = 0x00;
- pBytes[cbCur + 1] = 0x00;
- cbCur += 2;
-
- // Finally, store it.
- IfFailGo(GetAttrType(ATTR_COMSOURCEINTERFACES, &tkAttr));
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, pBytes, cbCur, 0));
- }
-
-ErrExit:
- if (psAttrIface)
- pItiIface->ReleaseTypeAttr(psAttrIface);
- if (pItiIface)
- pItiIface->Release();
- // Clean up any left-over ITypeInfo*.
- for (ULONG ix=0; ix < rImplTypes.Size(); ++ix)
- if (rImplTypes[ix])
- (rImplTypes[ix])->Release();
- for (ULONG ix=0; ix < rSrcTypes.Size(); ++ix)
- if (rSrcTypes[ix])
- (rSrcTypes[ix])->Release();
- m_tkInterface = 0;
- if (m_szInterface)
- ::SysFreeString(m_szInterface), m_szInterface = 0;
- m_ImplIface = eImplIfaceNone;
- return (hr);
-} // HRESULT CImportTlb::ConvCoclass()
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-//*****************************************************************************
-// Convert an enum to a class with fields that have default values.
-//*****************************************************************************
-HRESULT CImportTlb::ConvEnum( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr) // TYPEATTR of TypeInfo.
-{
- HRESULT hr; // A result.
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
- mdFieldDef mdField; // The FieldDef for the enum's type.
-
- // Create the field definition for the enum type. Always import as an __int32.
- IfFailGo(m_pEmit->DefineField(m_tdTypeDef, ENUM_TYPE_NAME, ENUM_TYPE_FLAGS, ENUM_TYPE_SIGNATURE,ENUM_TYPE_SIGNATURE_SIZE,
- 0,0, -1, &mdField));
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
- // Do the conversion.
- IfFailGo(_ConvConstant(pITI, psVar, true/*enum member*/));
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- hr = S_OK;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return (hr);
-} // HRESULT CImportTlb::ConvEnum()
-
-//*****************************************************************************
-// Convert a record to a class with fields.
-//*****************************************************************************
-HRESULT CImportTlb::ConvRecord( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL bUnion) // Convert as a union?
-{
- HRESULT hr=S_OK; // A result.
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
- mdFieldDef mdField; // Token for a given field.
- CQuickArray<COR_FIELD_OFFSET> rLayout; // Array for layout information.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- // Unions with embedded Object Types can't really be converted. Just reserve correct size.
- if (bUnion && (HasObjectFields(pITI, psAttr) == S_OK))
- {
- IfFailGo(m_pEmit->SetClassLayout(m_tdTypeDef, psAttr->cbAlignment, 0, psAttr->cbSizeInstance));
- goto ErrExit;
- }
-
- // Prepare for layout info.
- IfFailGo(rLayout.ReSizeNoThrow(psAttr->cVars+1));
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
- // Do the conversion.
- IfFailGo(_ConvField(pITI, psVar, &mdField, bUnion));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- // Save the layout info.
- rLayout[i].ridOfField = mdField;
- rLayout[i].ulOffset = psVar->oInst;
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- // If it is a union, Save the layout information.
- if (bUnion)
- {
- rLayout[psAttr->cVars].ridOfField = mdFieldDefNil;
- IfFailGo(m_pEmit->SetClassLayout(m_tdTypeDef, psAttr->cbAlignment, rLayout.Ptr(), -1));
- }
- else // Not a union. Preserve the alignment.
- IfFailGo(m_pEmit->SetClassLayout(m_tdTypeDef, psAttr->cbAlignment, 0, -1));
-
- // If we are marking these as serializable - do so now.
- if (m_bSerializableValueClasses)
- {
- mdToken tkAttr;
- IfFailGo(GetAttrType(ATTR_SERIALIZABLE, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(),SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return (hr);
-} // HRESULT CImportTlb::ConvRecord()
-
-//*****************************************************************************
-// Convert an module to a class with fields that have default values.
-// @FUTURE: convert methods as PInvoke methods.
-//*****************************************************************************
-HRESULT CImportTlb::ConvModule( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr) // TYPEATTR of TypeInfo.
-{
- HRESULT hr; // A result.
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
- // Do the conversion.
- IfFailGo(_ConvConstant(pITI, psVar));
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- hr = S_OK;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return (hr);
-} // HRESULT CImportTlb::ConvModule()
-
-//*****************************************************************************
-// Convert metadata for an interface.
-//*****************************************************************************
-HRESULT CImportTlb::ConvIface( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL bVtblGapFuncs) // Vtable gap functions?
-{
- HRESULT hr; // A result.
- ITypeInfo *pITIBase=0; // ITypeInfo* of base interface.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- ITypeInfo *pITISelf2=0; // ITypeInfo* of partner.
- TYPEATTR *psAttrSelf2=0; // TYPEATTR of partner.
- mdToken tkImpls[3]={0,0,0}; // Token of implemented interfaces.
- int ixImpls = 0; // Index of current implemented interface.
- HREFTYPE href; // href of base interface.
- mdToken tkIface; // Token for an interface.
- BOOL fInheritsIEnum = FALSE;
-
- // If there is a partner interface, prefer it.
- if (pITI->GetRefTypeOfImplType(-1, &href) == S_OK)
- {
- IfFailGo(pITI->GetRefTypeInfo(href, &pITISelf2));
- IfFailGo(pITISelf2->GetTypeAttr(&psAttrSelf2));
- }
-
- // Base interface?
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // If this interface extends something other than IDispatch or IUnknown, record that
- // fact as an "implemented interface".
- if (psAttrBase->guid != IID_IDispatch && psAttrBase->guid != IID_IUnknown)
- {
- // Get Token of the base interface.
- IfFailGo(_GetTokenForTypeInfo(pITIBase, FALSE, &tkImpls[ixImpls++]));
- }
- else
- { // Maybe we're "funky"...
- if (pITISelf2)
- {
- pITIBase->ReleaseTypeAttr(psAttrBase);
- pITIBase->Release();
- pITIBase = 0;
- psAttrBase = 0;
-
- if (psAttrSelf2->cImplTypes == 1)
- {
- IfFailGo(pITISelf2->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITISelf2->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- if (psAttrBase->guid != IID_IDispatch && psAttrBase->guid != IID_IUnknown)
- {
- // Get Token of the base interface.
- IfFailGo(_GetTokenForTypeInfo(pITIBase, FALSE, &tkImpls[ixImpls++]));
- }
- }
- else
- {
- BSTR szTypeInfoName;
- pITISelf2->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0);
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, szTypeInfoName);
- SysFreeString(szTypeInfoName);
-
- IfFailGo(TLBX_E_INVALID_TYPEINFO);
- }
- }
- }
-
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
-
- if (ExplicitlyImplementsIEnumerable(pITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // If this interface has a NewEnum member then have it implement IEnumerable.
- if ( (!fInheritsIEnum) && (HasNewEnumMember(pITI) == S_OK) )
- {
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkIface));
- tkImpls[ixImpls++] = tkIface;
- }
-
- // If not processing an implemented interface, add additional interface properties.
- if (m_ImplIface == eImplIfaceNone)
- {
- // Set base interface as an implemented interface.
- if (tkImpls[0])
- IfFailGo(m_pEmit->SetTypeDefProps(m_tdTypeDef, ULONG_MAX/*flags*/, ULONG_MAX/*extends*/, tkImpls));
-
- // If the interface is not derived from IDispatch mark it as IUnknown based.
- if (IsIDispatchDerived(pITI, psAttr) == S_FALSE)
- {
- mdMemberRef mr;
- // Note that this is a vtable, but not IDispatch derived.
- // Custom attribute buffer.
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- // Set up the attribute.
- BUILD_CUSTOM_ATTRIBUTE(short, ifVtable);
- // Store the attribute
- IfFailGo(GetAttrType(ATTR_INTERFACETYPE, &mr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, mr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
- }
-
- // Convert the members on the interface (and base interfaces).
- // If this interface had a "funky partner", base the conversion on that.
- if (pITISelf2)
- IfFailGo(_ConvIfaceMembers(pITISelf2, psAttrSelf2, bVtblGapFuncs, psAttr->wTypeFlags & TYPEFLAG_FDUAL, fInheritsIEnum));
- else
- IfFailGo(_ConvIfaceMembers(pITI, psAttr, bVtblGapFuncs, psAttr->wTypeFlags & TYPEFLAG_FDUAL, fInheritsIEnum));
-
-ErrExit:
- if (psAttrSelf2)
- pITISelf2->ReleaseTypeAttr(psAttrSelf2);
- if (pITISelf2)
- pITISelf2->Release();
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::ConvIface()
-
-//*****************************************************************************
-// Convert the metadata for a dispinterface. Try to convert as a normal
-// interface.
-//*****************************************************************************
-HRESULT CImportTlb::ConvDispatch( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TYPEATTR of TypeInfo.
- BOOL bVtblGapFuncs) // Vtable gap functions for interface implementations?
-{
- HRESULT hr; // A result.
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- mdMemberRef mr; // MemberRef for custom value.
- DWORD attr[2] = {0x00010001, 0x00000002};
- BYTE bIface = ifDispatch; // Custom value means "dispinterface"
- BOOL fInheritsIEnum = FALSE;
-
- // If this is a dual interface, treat it like a normal interface.
- if ((psAttr->wTypeFlags & TYPEFLAG_FDUAL))
- {
- hr = ConvIface(pITI, psAttr, bVtblGapFuncs);
- goto ErrExit;
- }
-
- if (ExplicitlyImplementsIEnumerable(pITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // If there is a vtable view of this interface (funky dispinterface).
- // @FUTURE: what would be really nice here would be an alias mechanism, so that we could
- // just point this dispinterface to that other interface, in those situations that it
- // is dual. OTOH, that is probably pretty rare, because if that other interface
- // were dual, why would the dispinterface even be needed?
- if (pITI->GetRefTypeOfImplType(-1, &href) == S_OK)
- {
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
- IfFailGo(_ConvIfaceMembers(pITIBase, psAttrBase, bVtblGapFuncs, TRUE, fInheritsIEnum));
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- goto ErrExit;
- }
-
- // If not processing an implemented interface, mark the interface type.
- if (m_ImplIface == eImplIfaceNone)
- {
- // If this interface has a NewEnum member then have it implement IEnumerable.
- if ((S_OK == HasNewEnumMember(pITI)) && !fInheritsIEnum)
- {
- mdToken tkImpl[2] = {0,0};
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_IENUMERABLE, &tkImpl[0]));
- IfFailGo(m_pEmit->SetTypeDefProps(m_tdTypeDef, ULONG_MAX, ULONG_MAX, tkImpl));
- }
-
- // Note that this is a dispinterface.
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- // Set up the attribute.
- BUILD_CUSTOM_ATTRIBUTE(short, ifDispatch);
- // Store the attribute
- IfFailGo(GetAttrType(ATTR_INTERFACETYPE, &mr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, mr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- IfFailGo(_ConvDispatchMembers(pITI, psAttr, fInheritsIEnum));
-
-ErrExit:
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::ConvDispatch()
-
-//*****************************************************************************
-// Determine if an interface is derived from IUnknown.
-//*****************************************************************************
-HRESULT CImportTlb::IsIUnknownDerived(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr) // The ITypeInfo's TYPEATTR
-{
- HRESULT hr=S_OK; // A result.
-
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
-
- // This should never be called on CoClasses.
- _ASSERTE(psAttr->typekind != TKIND_COCLASS);
-
- // If IDispatch or IUnknown, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IUnknown) || IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // IUnknow derived if base interface is.
- hr = IsIUnknownDerived(pITIBase, psAttrBase);
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IUnknown, not IDispatch. Not very COM-ish, so don't try to handle.
- hr = S_FALSE;
- }
-
-ErrExit:
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::IsIUnknownDerived()
-
-//*****************************************************************************
-// Determine if an interface is derived from IDispatch. Note that a pure
-// dispinterface doesn't derive from IDispatch.
-//*****************************************************************************
-HRESULT CImportTlb::IsIDispatchDerived(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr) // The ITypeInfo's TYPEATTR
-{
- HRESULT hr=S_OK; // A result.
-
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
-
- // If IDispatch, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- goto ErrExit;
- }
-
- if (psAttr->typekind == TKIND_DISPATCH)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(-1, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // IDispatch derived if base interface is.
- hr = IsIDispatchDerived(pITIBase, psAttrBase);
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
-
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- // IDispatch derived if base interface is.
- hr = IsIDispatchDerived(pITIBase, psAttrBase);
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IDispatch. Done.
- hr = S_FALSE;
- }
-
-ErrExit:
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- return (hr);
-} // HRESULT CImportTlb::IsIDispatchDerived()
-
-//*****************************************************************************
-// Determine if an interface has a member with a DISPID of DISPID_NEWENUM.
-//*****************************************************************************
-HRESULT CImportTlb::HasNewEnumMember( // S_OK if has NewEnum, S_FALSE otherwise.
- ITypeInfo *pItfTI) // The interface in question.
-{
- HRESULT hr = S_OK; // A result.
- BOOL bHasNewEnumMember=FALSE;// If true, has a NewEnum
- TYPEATTR *pAttr = NULL; // A TypeInfo's typeattr
- FUNCDESC *pFuncDesc = NULL; // A Function's FuncDesc
- VARDESC *pVarDesc = NULL; // A properties VarDesc
- int i; // Loop control.
- ITypeInfo *pITISelf2=0; // Partner interface.
- HREFTYPE href; // HREF of partner.
- WCHAR IEnumCA[] = W("{CD2BC5C9-F452-4326-B714-F9C539D4DA58}");
-
-
- // If there is a partner interface, prefer it.
- if (pItfTI->GetRefTypeOfImplType(-1, &href) == S_OK)
- {
- IfFailGo(pItfTI->GetRefTypeInfo(href, &pITISelf2));
- pItfTI = pITISelf2;
- }
-
- // Retrieve the attributes of the interface.
- IfFailGo(pItfTI->GetTypeAttr(&pAttr));
-
- if ((pAttr->typekind == TKIND_DISPATCH) || ((pAttr->typekind == TKIND_INTERFACE) && (IsIDispatchDerived(pItfTI, pAttr) == S_OK)))
- {
- // Check to see if the ForceIEnumerable custom value exists on the type
- _ForceIEnumerableCVExists(pItfTI, &bHasNewEnumMember);
-
- // Check to see if the interface has a function with a DISPID of DISPID_NEWENUM.
- for (i = 0; i < pAttr->cFuncs; i++)
- {
- IfFailGo(TryGetFuncDesc(pItfTI, i, &pFuncDesc));
-
- if (FuncIsNewEnum(pItfTI, pFuncDesc, i) == S_OK)
- {
- // Throw a warning if we find more than one func with DISPID_NEWENUM.
- if (bHasNewEnumMember == TRUE)
- {
- BSTR ObjectName;
- pItfTI->GetDocumentation(-1, &ObjectName, NULL, NULL, NULL);
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, ObjectName);
- SysFreeString(ObjectName);
- }
-
- // The interface has a function with a DISPID of DISPID_NEWENUM.
- bHasNewEnumMember = TRUE;
- break;
- }
-
- pItfTI->ReleaseFuncDesc(pFuncDesc);
- pFuncDesc = NULL;
- }
-
- // Check to see if the interface as a property with a DISPID of DISPID_NEWENUM.
- for (i = 0; i < pAttr->cVars; i++)
- {
- IfFailGo(pItfTI->GetVarDesc(i, &pVarDesc));
-
- if (PropertyIsNewEnum(pItfTI, pVarDesc, i) == S_OK)
- {
- // Throw a warning if we find more than one func with DISPID_NEWENUM.
- if (bHasNewEnumMember == TRUE)
- {
- BSTR ObjectName;
- pItfTI->GetDocumentation(-1, &ObjectName, NULL, NULL, NULL);
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_INVALID_TYPEINFO, ObjectName);
- SysFreeString(ObjectName);
- }
-
- // The interface has a property with a DISPID of DISPID_NEWENUM.
- bHasNewEnumMember = TRUE;
- break;
- }
-
- pItfTI->ReleaseVarDesc(pVarDesc);
- pVarDesc = NULL;
- }
- }
- else
- {
- // Check to see if the ForceIEnumerable custom value exists on the type
- // If it does, spit out a warning.
- _ForceIEnumerableCVExists(pItfTI, &bHasNewEnumMember);
-
- if (bHasNewEnumMember)
- {
- // Invalid custom attribute on the iface.
- BSTR CustomValue = SysAllocString((const WCHAR*)&IEnumCA[0]);
- BSTR ObjectName;
- pItfTI->GetDocumentation(-1, &ObjectName, NULL, NULL, NULL);
-
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_IENUM_CA_ON_IUNK, CustomValue, ObjectName);
-
- SysFreeString(CustomValue);
- SysFreeString(ObjectName);
-
- bHasNewEnumMember = FALSE;
- }
- }
-
- hr = bHasNewEnumMember ? S_OK : S_FALSE;
-
-ErrExit:
- if (pAttr)
- pItfTI->ReleaseTypeAttr(pAttr);
- if (pFuncDesc)
- pItfTI->ReleaseFuncDesc(pFuncDesc);
- if (pVarDesc)
- pItfTI->ReleaseVarDesc(pVarDesc);
- if (pITISelf2)
- pITISelf2->Release();
- return hr;
-} // HRESULT CImportTlb::HasNewEnumMember(ITypeInfo *pItfTI)
-
-//*****************************************************************************
-// Determine if a given function is a valid NewEnum member.
-//*****************************************************************************
-HRESULT CImportTlb::FuncIsNewEnum( // S_OK if the function is the NewEnum member S_FALSE otherwise.
- ITypeInfo *pITI, // The ITypeInfo that contains the function.
- FUNCDESC *pFuncDesc, // The function in question.
- DWORD index) // The function index
-{
-
- HRESULT hr = S_OK;
- BOOL bIsValidNewEnum = FALSE;
- TYPEDESC* pType = NULL;
- TYPEATTR* pAttr = NULL;
- ITypeInfo* pITIUD = NULL;
- long lDispSet = 0;
-
- _GetDispIDCA(pITI, index, &lDispSet, TRUE);
-
- if ((pFuncDesc->memid == DISPID_NEWENUM) || (lDispSet == DISPID_NEWENUM))
- {
- if (pFuncDesc->funckind == FUNC_DISPATCH)
- {
- if ((pFuncDesc->invkind == INVOKE_PROPERTYGET) || (pFuncDesc->invkind == INVOKE_FUNC))
- {
- if (pFuncDesc->cParams == 0)
- {
- pType = &pFuncDesc->elemdescFunc.tdesc;
- }
- else if ((m_bTransformDispRetVals) && (pFuncDesc->cParams == 1) && (pFuncDesc->lprgelemdescParam[0].paramdesc.wParamFlags & PARAMFLAG_FRETVAL))
- {
- pType = pFuncDesc->lprgelemdescParam[0].tdesc.lptdesc;
- }
- }
- }
- else if (pFuncDesc->funckind == FUNC_PUREVIRTUAL)
- {
- if ((pFuncDesc->cParams == 1) &&
- ((pFuncDesc->invkind == INVOKE_PROPERTYGET) || (pFuncDesc->invkind == INVOKE_FUNC)) &&
- (pFuncDesc->lprgelemdescParam[0].paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
- (pFuncDesc->lprgelemdescParam[0].tdesc.vt == VT_PTR))
- {
- pType = pFuncDesc->lprgelemdescParam[0].tdesc.lptdesc;
- }
- }
-
- if (pType)
- {
- if (pType->vt == VT_UNKNOWN || pType->vt == VT_DISPATCH)
- {
- // The member returns an IUnknown * or an IDispatch * which is valid.
- bIsValidNewEnum = TRUE;
- }
- else if (pType->vt == VT_PTR)
- {
- pType = pType->lptdesc;
- if (pType->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIUD));
- IfFailGo(pITIUD->GetTypeAttr(&pAttr));
- if (IsEqualGUID(pAttr->guid, IID_IEnumVARIANT) ||
- IsEqualGUID(pAttr->guid, IID_IUnknown) ||
- IsEqualGUID(pAttr->guid, IID_IDispatch))
- {
- // The member returns a valid interface type for a NewEnum member.
- bIsValidNewEnum = TRUE;
- }
- }
- }
- }
- }
-
-ErrExit:
- if (pAttr)
- pITIUD->ReleaseTypeAttr(pAttr);
- if (pITIUD)
- pITIUD->Release();
-
- if (FAILED(hr))
- return hr;
- else
- return bIsValidNewEnum ? S_OK : S_FALSE;
-} // HRESULT CImportTlb::FuncIsNewEnum(FUNCDESC *pFuncDesc)
-
-//*****************************************************************************
-// Determine if a given function is a valid NewEnum member.
-//*****************************************************************************
-HRESULT CImportTlb::PropertyIsNewEnum( // S_OK if the function is the NewEnum member S_FALSE otherwise.
- ITypeInfo *pITI, // The ITypeInfo that contains the property.
- VARDESC *pVarDesc, // The function in question.
- DWORD index) // The property index.
-{
- HRESULT hr = S_OK;
- BOOL bIsValidNewEnum = FALSE;
- TYPEDESC* pType = NULL;
- TYPEATTR* pAttr = NULL;
- ITypeInfo* pITIUD = NULL;
- long lDispSet = 0;
-
- _GetDispIDCA(pITI, index, &lDispSet, FALSE);
-
- if ( ((pVarDesc->memid == DISPID_NEWENUM) || (lDispSet == DISPID_NEWENUM)) &&
- (pVarDesc->elemdescVar.paramdesc.wParamFlags & PARAMFLAG_FRETVAL) &&
- (pVarDesc->wVarFlags & VARFLAG_FREADONLY))
- {
- pType = &pVarDesc->elemdescVar.tdesc;
- if (pType->vt == VT_UNKNOWN || pType->vt == VT_DISPATCH)
- {
- // The member returns an IUnknown * or an IDispatch * which is valid.
- bIsValidNewEnum = TRUE;
- }
- else if (pType->vt == VT_PTR)
- {
- pType = pType->lptdesc;
- if (pType->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIUD));
- IfFailGo(pITIUD->GetTypeAttr(&pAttr));
- if (IsEqualGUID(pAttr->guid, IID_IEnumVARIANT) ||
- IsEqualGUID(pAttr->guid, IID_IUnknown) ||
- IsEqualGUID(pAttr->guid, IID_IDispatch))
- {
- // The member returns a valid interface type for a NewEnum member.
- bIsValidNewEnum = TRUE;
- }
- }
- }
- }
-
-ErrExit:
- if (pAttr)
- pITIUD->ReleaseTypeAttr(pAttr);
- if (pITIUD)
- pITIUD->Release();
-
- if (FAILED(hr))
- return hr;
- else
- return bIsValidNewEnum ? S_OK : S_FALSE;
-} // HRESULT CImportTlb::FuncIsNewEnum(FUNCDESC *pFuncDesc)
-
-//*****************************************************************************
-// Determine is a TypeInfo has any object fields.
-//*****************************************************************************
-HRESULT CImportTlb::HasObjectFields( // S_OK, S_FALSE, or error.
- ITypeInfo *pITI, // The TypeInfo in question.
- TYPEATTR *psAttr) // Attributes of the typeinfo.
-{
- HRESULT hr; // A result.
-
- int i; // Loop control.
- VARDESC *psVar=0; // VARDESC for a member.
-
- // Iterate over the vars.
- for (i=0; i<psAttr->cVars; ++i)
- {
- // Get variable information.
- IfFailGo(pITI->GetVarDesc(i, &psVar));
-
- // See if it is an object type.
- IfFailGo(IsObjectType(pITI, &psVar->elemdescVar.tdesc));
- // If result is S_FALSE, not an Object; keep looking.
- if (hr == S_OK)
- goto ErrExit;
-
- // Release for next var.
- pITI->ReleaseVarDesc(psVar);
- psVar = 0;
- }
-
- hr = S_FALSE;
-
-ErrExit:
- if (psVar)
- pITI->ReleaseVarDesc(psVar);
- return hr;
-} // HRESULT CImportTlb::HasObjectFields()
-
-//*****************************************************************************
-// Is a given type an Object type?
-//*****************************************************************************
-HRESULT CImportTlb::IsObjectType( // S_OK, S_FALSE, or error.
- ITypeInfo *pITI, // The TypeInfo in question.
- const TYPEDESC *pType) // The type.
-{
- HRESULT hr; // A result.
- TYPEDESC tdTemp; // Copy of TYPEDESC, for R/W.
- ITypeInfo *pITIAlias=0; // Typeinfo of the aliased type.
- TYPEATTR *psAttrAlias=0; // TYPEATTR of the aliased typeinfo.
- int bObjectField=false; // The question to be answered.
- int iByRef=0; // Indirection.
-
- // Strip off leading VT_PTR and VT_BYREF
- while (pType->vt == VT_PTR)
- pType = pType->lptdesc, ++iByRef;
- if (pType->vt & VT_BYREF)
- {
- tdTemp = *pType;
- tdTemp.vt &= ~VT_BYREF;
- pType = &tdTemp;
- ++iByRef;
- }
-
- // Determine if the field is/has object type.
- switch (pType->vt)
- {
- case VT_PTR:
- _ASSERTE(!"Should not have VT_PTR here");
- break;
-
- // These are object types.
- case VT_BSTR:
- case VT_DISPATCH:
- case VT_VARIANT:
- case VT_UNKNOWN:
- case VT_SAFEARRAY:
- case VT_LPSTR:
- case VT_LPWSTR:
- bObjectField = true;
- break;
-
- // A user-defined may or may not be/contain Object type.
- case VT_USERDEFINED:
- // User defined type. Get the TypeInfo.
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIAlias));
- IfFailGo(pITIAlias->GetTypeAttr(&psAttrAlias));
-
- // Some user defined class. Is it a value class, or a VOS class?
- switch (psAttrAlias->typekind)
- {
- // Alias -- Is the aliased thing an Object type?
- case TKIND_ALIAS:
- hr = IsObjectType(pITIAlias, &psAttrAlias->tdescAlias);
- goto ErrExit;
- // Record/Enum/Union -- Does it contain an Object type?
- case TKIND_RECORD:
- case TKIND_ENUM:
- case TKIND_UNION:
- // Byref/Ptrto record is Object. Contained record might be.
- if (iByRef)
- bObjectField = true;
- else
- {
- hr = HasObjectFields(pITIAlias, psAttrAlias);
- goto ErrExit;
- }
- break;
- // Class/Interface -- An Object Type.
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- case TKIND_COCLASS:
- bObjectField = true;
- break;
- default:
- //case TKIND_MODULE: -- can't pass one of these as a parameter.
- _ASSERTE(!"Unexpected typekind for user defined type");
- bObjectField = true;
- } // switch (psAttrAlias->typekind)
- break;
-
- case VT_CY:
- case VT_DATE:
- case VT_DECIMAL:
- // Pointer to the value type is an object. Contained one isn't.
- if (iByRef)
- bObjectField = true;
- else
- bObjectField = false;
- break;
-
- // A fixed array is an Object type.
- case VT_CARRAY:
- bObjectField = true;
- break;
-
- // Other types I4, etc., are not Object types.
- default:
- bObjectField = false;
- break;
- } // switch (vt=pType->vt)
-
-
- hr = bObjectField ? S_OK : S_FALSE;
-
-ErrExit:
- if (psAttrAlias)
- pITIAlias->ReleaseTypeAttr(psAttrAlias);
- if (pITIAlias)
- pITIAlias->Release();
-
- return hr;
-} // HRESULT CImportTlb::IsObjectType()
-
-//*****************************************************************************
-// Convert the functions on an interface. Convert the functions on the
-// base interface first, because in COM Classic, parent's functions are also
-// in the derived interface's vtable.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvIfaceMembers(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr, // The ITypeInfo's TYPEATTR
- BOOL bVtblGapFuncs, // Add functions for vtblGaps?
- BOOL bAddDispIds, // Add DispIds to the member?
- BOOL bInheritsIEnum) // Inherits from IEnumerable.
-{
- HRESULT hr=S_OK; // A result.
- int i; // Loop control.
- FUNCDESC *psFunc=0; // FUNCDESC for a member.
-
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- _ASSERTE( (psAttr->typekind == TKIND_INTERFACE) || (psAttr->typekind == TKIND_DISPATCH) );
-
- // If IDispatch or IUnknown, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IUnknown) || IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- m_Slot = (psAttr->cbSizeVft / m_cbVtableSlot);
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- IfFailGo(_ConvIfaceMembers(pITIBase, psAttrBase, bVtblGapFuncs, bAddDispIds, bInheritsIEnum));
-
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IUnknown, not IDispatch. We shouldn't be here.
- m_Slot = 0;
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- _ASSERTE(!"Interface does not derive from IUnknown.");
- }
-
- // Loop over functions.
- IfFailGo(_FindFirstUserMethod(pITI, psAttr, &i));
- IfFailGo(BuildMemberList(pITI, i, psAttr->cFuncs, bInheritsIEnum));
-
- BOOL bAllowIEnum = !bInheritsIEnum;
- for (i=0; i<(int)m_MemberList.Size(); ++i)
- {
- // Convert the function.
- IfFailGo(_ConvFunction(pITI, &m_MemberList[i], bVtblGapFuncs, bAddDispIds, FALSE, &bAllowIEnum));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
-
- // Add the property info.
- IfFailGo(_ConvPropertiesForFunctions(pITI, psAttr));
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- // Release FuncDescs.
- FreeMemberList(pITI);
-
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- if (psFunc)
- pITI->ReleaseFuncDesc(psFunc);
- return (hr);
-} // HRESULT CImportTlb::_ConvIfaceMembers()
-
-//*****************************************************************************
-// Convert the functions on a source interface to add_ and remove_ method.
-// Convert the functions on the base interface first, because in COM Classic,
-// parent's functions are also in the derived interface's vtable.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvSrcIfaceMembers(
- ITypeInfo *pITI, // The containing ITypeInfo.
- TYPEATTR *psAttr, // The ITypeInfo's TYPEATTR
- BOOL fInheritsIEnum)
-{
- HRESULT hr=S_OK; // A result.
- int i; // Loop control.
- FUNCDESC *psFunc=0; // FUNCDESC for a member.
- HREFTYPE href; // Base interface href.
- ITypeInfo *pITIBase=0; // Base interface ITypeInfo.
- TYPEATTR *psAttrBase=0; // TYPEATTR of base interface.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- _ASSERTE( (psAttr->typekind == TKIND_INTERFACE) || (psAttr->typekind == TKIND_DISPATCH) );
-
- // If IDispatch or IUnknown, we've recursed far enough.
- if (IsEqualGUID(psAttr->guid, IID_IUnknown) || IsEqualGUID(psAttr->guid, IID_IDispatch))
- {
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- m_Slot = (psAttr->cbSizeVft / m_cbVtableSlot);
- goto ErrExit;
- }
-
- // Handle base interface.
- if (psAttr->cImplTypes == 1)
- {
- IfFailGo(pITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pITI->GetRefTypeInfo(href, &pITIBase));
- IfFailGo(pITIBase->GetTypeAttr(&psAttrBase));
-
- IfFailGo(_ConvSrcIfaceMembers(pITIBase, psAttrBase, fInheritsIEnum));
- pITIBase->ReleaseTypeAttr(psAttrBase);
- psAttrBase = 0;
- pITIBase->Release();
- pITIBase = 0;
- }
- else
- { // No base interface, not IUnknown, not IDispatch. We shouldn't be here.
- m_Slot = 0;
- if (m_cbVtableSlot == 0)
- {
- m_cbVtableSlot = psAttr->cbSizeInstance;
- }
- _ASSERTE(!"Interface does not derive from IUnknown.");
- }
-
- // Loop over functions.
- IfFailGo(_FindFirstUserMethod(pITI, psAttr, &i));
- IfFailGo(BuildMemberList(pITI, i, psAttr->cFuncs, fInheritsIEnum));
-
- // If we have any properties, we want to skip them. Should we add gaps?
- if (m_cMemberProps != 0)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_NO_PROPS_IN_EVENTS, m_szName);
- bConversionLoss = true;
- }
-
- for (i = m_cMemberProps; i<(int)m_MemberList.Size(); ++i)
- {
- // Convert the function.
- IfFailGo(_GenerateEvent(pITI, &m_MemberList[i], fInheritsIEnum));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- // Release FuncDescs.
- FreeMemberList(pITI);
-
- if (psAttrBase)
- pITIBase->ReleaseTypeAttr(psAttrBase);
- if (pITIBase)
- pITIBase->Release();
- if (psFunc)
- pITI->ReleaseFuncDesc(psFunc);
- return (hr);
-} // HRESULT CImportTlb::_ConvIfaceMembers()
-
-//*****************************************************************************
-// Add the property definitions for property functions.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvPropertiesForFunctions(
- ITypeInfo *pITI, // ITypeInfo* being converted.
- TYPEATTR *psAttr) // TypeAttr for the typeinfo.
-{
- HRESULT hr=S_OK; // A result.
- int ix; // Loop control.
- int ix2; // More loop control.
- mdProperty pd; // A property token.
- USHORT ms; // Some method's semantics.
- mdToken tk; // A method's token.
- mdMethodDef mdFuncs[6] ={0}; // Array of setter, getter, other.
- FUNCDESC *psF=0; // FUNCDESC of Get, Put, or PutRef.
- TYPEDESC *pProperty; // TYPEDESC of property type.
- BOOL bPropRetval; // Is the property type a [retval]?
- ULONG ixValue; // Index of the value parameter for putters.
- int ixVarArg; // Index of vararg param, if any.
- CQuickBytes qbComSig; // new signature
- BYTE *pbSig; // Pointer into the signature.
- ULONG sigFlags; // Signature handling flags.
- ULONG cbTotal; // Size of the signature.
- ULONG cb; // Size of a signature element.
- LPWSTR pszName; // Possibly decorated name of property.
- CQuickArray<WCHAR> qbName; // Buffer for name decoration.
- int iSrcParam; // Param count, as looping through params.
- int cDestParams; // Count of destination params.
- CQuickArray<BYTE> qbDummyNativeTypeBuf; // A dummy native type array.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
- BOOL bNewEnumMember=FALSE; // Is this a NewEnum property?
- BOOL bConversionLoss=FALSE; // Was some type not fully converted?
- int cFound; // Functions found matching a given property.
-
- // Using semantics as an index, so be sure array is big enough.
- _ASSERTE(lengthof(mdFuncs) > msOther);
-
- for (ix=m_cMemberProps; ix<(int)m_MemberList.Size(); ++ix)
- { // See if this one needs to be processed.
- if (m_MemberList[ix].m_mdFunc == 0)
- continue;
-
- MemberInfo *pMember = &m_MemberList[ix];
- pMember->GetFuncInfo(tk, ms);
-
- // Get the name.
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember = 0;
- IfFailGo(pITI->GetDocumentation(pMember->m_psFunc->memid, &m_szMember, 0,0,0));
-
- // Found one. Put in the right slot.
- _ASSERTE(ms == msGetter || ms == msSetter || ms==msOther);
- mdFuncs[msSetter] = mdFuncs[msGetter] = mdFuncs[msOther] = 0;
- mdFuncs[ms] = tk;
- pMember->m_mdFunc = 0;
-
- // Look for related functions.
- cFound = 1;
- for (ix2=ix+1; ix2<(int)m_MemberList.Size(); ++ix2)
- {
- MemberInfo *pMember2 = &m_MemberList[ix2];
- if (pMember2->m_mdFunc != 0 && pMember2->m_psFunc->memid == pMember->m_psFunc->memid)
- { // Found a related function.
- pMember2->GetFuncInfo(tk, ms);
- _ASSERTE(ms == msGetter || ms == msSetter || ms==msOther);
- _ASSERTE(mdFuncs[ms] == 0);
- mdFuncs[ms] = tk;
- pMember2->m_mdFunc = 0;
- // If have found all three, don't bother looking for more.
- if (++cFound == 3)
- break;
- }
- }
-
- // Build the signature for the property.
- hr = _GetFunctionPropertyInfo(pMember->m_psFunc, &ms, &psF, &pProperty, &bPropRetval, TRUE, m_szMember);
-
- // The function really should have a property associated with it, to get here. Check anyway.
- _ASSERTE(pProperty);
- if (!pProperty)
- continue;
-
- // Some sort of property accessor.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE + 1));
- pbSig = (BYTE *)qbComSig.Ptr();
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_PROPERTY, pbSig);
- // Count of parameters.
-
- // If this is a getter, see if there is a retval.
- if (psF->invkind == INVOKE_PROPERTYGET)
- { // Examine each param, and count all except the [retval].
- for (cDestParams=iSrcParam=0; iSrcParam<psF->cParams; ++iSrcParam)
- {
- if ((psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS) == 0)
- ++cDestParams;
- }
- // There is no new value param for getters.
- ixValue = -1;
- }
- else
- {
- // This is a putter, so 1 param is new value, others are indices (or lcid).
- for (cDestParams=iSrcParam=0; iSrcParam<psF->cParams-1; ++iSrcParam)
- {
- if ((psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS) == 0)
- ++cDestParams;
- }
- // The last parameter is the new value.
- ixValue = psF->cParams - 1;
- }
-
- //-------------------------------------------------------------------------
- // See if there is a vararg param.
- ixVarArg = psF->cParams + 1;
- if (psF->cParamsOpt == -1)
- {
- // If this is a PROPERTYPUT or PROPERTYPUTREF, skip the last non-retval parameter (it
- // is the new value to be set).
- BOOL bPropVal = (psF->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)) ? TRUE : FALSE;
- // Find the vararg param.
- for (iSrcParam=psF->cParams-1; iSrcParam>=0; --iSrcParam)
- {
- // The count of optional params does not include any lcid params, nor does
- // it include the return value, so skip those.
- if ((psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)) != 0)
- continue;
- // If haven't yet seen the property value, this param is it, so skip it, too.
- if (bPropVal)
- {
- bPropVal = FALSE;
- continue;
- }
- ixVarArg = iSrcParam;
- break;
- } // for (iSrcParam=cParams-1...
- }
-
- // Put in the count of index parameters.
- _ASSERTE(cDestParams >= 0);
- cb = CorSigCompressData(cDestParams, &pbSig[cbTotal]);
- cbTotal += cb;
-
- // Create the signature for the property type.
- sigFlags = SIG_ELEM | (bPropRetval ? SIG_RET : (SigFlags)0);
- IfFailGo(_ConvSignature(pITI, pProperty, sigFlags, qbComSig, cbTotal, &cbTotal, qbDummyNativeTypeBuf, 0, &iNativeOfs, bNewEnumMember));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Fill in the "index" part of the property's signature.
- for (iSrcParam=0; iSrcParam<psF->cParams; ++iSrcParam)
- {
- if (psF->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS)
- continue;
- if (iSrcParam == static_cast<int>(ixValue))
- continue;
- sigFlags = SIG_FUNC | SIG_USE_BYREF;
- if (iSrcParam == ixVarArg)
- sigFlags |= SIG_VARARG;
- IfFailGo(_ConvSignature(pITI, &psF->lprgelemdescParam[iSrcParam].tdesc, sigFlags, qbComSig, cbTotal, &cbTotal, qbDummyNativeTypeBuf, 0, &iNativeOfs, bNewEnumMember));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
-
- // Get the property name. Add interface name and make unique, if needed.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(m_szMember)+2));
- wcscpy_s(qbName.Ptr(), wcslen(m_szMember)+2, m_szMember);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtProperty));
- pszName = qbName.Ptr();
-
- // Define the property.
- IfFailGo(m_pEmit->DefineProperty(m_tdTypeDef, pszName, 0/*dwFlags*/,
- (PCCOR_SIGNATURE) qbComSig.Ptr(), cbTotal, 0, 0, -1,
- mdFuncs[msSetter], mdFuncs[msGetter], &mdFuncs[msOther],
- &pd));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the dispid CA on the property.
- long lDispSet = 1;
- _SetDispIDCA(pITI, pMember->m_iMember, psF->memid, pd, TRUE, &lDispSet, TRUE);
-
- // If this property is default property, add a custom attribute to the class.
- if (lDispSet == DISPID_VALUE)
- IfFailGo(_AddDefaultMemberCa(m_tdTypeDef, m_szMember));
- }
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, pProperty, pd));
- }
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
-
- return hr;
-} // HRESULT CImportTlb::_ConvPropertiesForFunctions()
-
-//*****************************************************************************
-// Convert the vars and functions of a dispinterface. Vars actually turn
-// into a getter and possibly a setter.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvDispatchMembers(
- ITypeInfo *pITI, // ITypeInfo* to convert.
- TYPEATTR *psAttr, // TypeAttr of ITypeInfo.
- BOOL fInheritsIEnum)
-{
- HRESULT hr; // A result.
- int i; // Loop control.
- BOOL bConversionLoss=FALSE; // If true, some attributes were lost on conversion.
-
- IfFailGo(_FindFirstUserMethod(pITI, psAttr, &i));
- IfFailGo(BuildMemberList(pITI, i, psAttr->cFuncs, fInheritsIEnum));
-
- // Dispatch members really have no slot.
- m_Slot = 0;
-
- // Loop over properties.
- for (i=0; i<m_cMemberProps; ++i)
- {
- IfFailGo(_ConvProperty(pITI, &m_MemberList[i]));
- }
-
- // Loop over functions.
- BOOL bAllowIEnum = !fInheritsIEnum;
- for (; i<(int)m_MemberList.Size(); ++i)
- {
- // Get variable information.
- IfFailGo(_ConvFunction(pITI, &m_MemberList[i], FALSE, TRUE, FALSE, &bAllowIEnum));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = TRUE;
- }
-
- // Add the property info.
- IfFailGo(_ConvPropertiesForFunctions(pITI, psAttr));
-
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- // Free the func descs.
- FreeMemberList(pITI);
-
- return (hr);
-} // HRESULT CImportTlb::_ConvDispatchMembers()
-
-//*****************************************************************************
-// Examine the functions on an interface, and skip the first 3 or first 7
-// if the functions are IUnknown or IDispatch members.
-//*****************************************************************************
-HRESULT CImportTlb::_FindFirstUserMethod(
- ITypeInfo *pITI, // The Typedef to examine.
- TYPEATTR *psAttr, // TYPEATTR for the typedef.
- int *pIx) // Put index of first user function here.
-{
- HRESULT hr = S_OK; // A result.
- int i; // Loop control.
- FUNCDESC *psFunc=0; // FUNCDESC for a member.
- BSTR szName=0; // A function's name.
-
- // Note: this is a terrible workaround, but in some situations the methods from IUnknown / IDispatch will
- // show up as though native dispatch functions.
- i = 0;
- if (psAttr->cFuncs >= 3)
- {
- IfFailGo(TryGetFuncDesc(pITI, i, &psFunc));
- if (psFunc->memid == 0x60000000 &&
- psFunc->elemdescFunc.tdesc.vt == VT_VOID &&
- psFunc->cParams == 2 &&
- psFunc->lprgelemdescParam[0].tdesc.vt == VT_PTR && // -> VT_USERDEFINED
- psFunc->lprgelemdescParam[1].tdesc.vt == VT_PTR && // -> VT_PTR -> VT_VOID
- SUCCEEDED(pITI->GetDocumentation(psFunc->memid, &szName, 0,0,0)) &&
- (wcscmp(szName, W("QueryInterface")) == 0) )
- i = 3;
- pITI->ReleaseFuncDesc(psFunc);
- psFunc=0;
- if (szName)
- ::SysFreeString(szName);
- szName = 0;
- if (psAttr->cFuncs >= 7)
- {
- IfFailGo(TryGetFuncDesc(pITI, i, &psFunc));
- if (psFunc->memid == 0x60010000 &&
- psFunc->elemdescFunc.tdesc.vt == VT_VOID &&
- psFunc->cParams == 1 &&
- psFunc->lprgelemdescParam[0].tdesc.vt == VT_PTR && // -> VT_UINT
- SUCCEEDED(pITI->GetDocumentation(psFunc->memid, &szName, 0,0,0)) &&
- (wcscmp(szName, W("GetTypeInfoCount")) == 0) )
- i = 7;
- pITI->ReleaseFuncDesc(psFunc);
- psFunc=0;
- if (szName)
- ::SysFreeString(szName);
- szName = 0;
- }
- }
-
- *pIx = i;
-
-ErrExit:
- if (psFunc)
- pITI->ReleaseFuncDesc(psFunc);
- if (szName)
- ::SysFreeString(szName);
- return (hr);
-} // HRESULT CImportTlb::_FindFirstUserMethod()
-
-//*****************************************************************************
-// Given a FUNCDESC that is has INVOKE_PROPERTY* decoration, determine
-// the role of the function, and the property signature type.
-//*****************************************************************************
-HRESULT CImportTlb::_GetFunctionPropertyInfo(
- FUNCDESC *psFunc, // Function for which to get info.
- USHORT *pSemantics, // Put appropriate semantics here.
- FUNCDESC **ppSig, // Put FUNCDESC for signature here.
- TYPEDESC **ppProperty, // Put TYPEDESC for return here.
- BOOL *pbRetval, // If true, the type is [retval]
- BOOL fUseLastParam, // If true, default to the last parameter as the return value
- BSTR strName) // Name of the property
-{
- FUNCDESC *psTmp; // FUNCDESC for some method.
- FUNCDESC *psGet=0; // FUNCDESC for Get method defining a property.
- FUNCDESC *psPut=0; // FUNCDESC for Put method defining a property.
- FUNCDESC *psPutRef=0; // FUNCDESC for PutRef method defining a property.
- FUNCDESC *psF; // A FUNCDESC.
- TYPEDESC *pReturn=0; // The FUNCDESC's return type.
- int cFound=0; // Count of functions found.
- int i; // Loop control.
- HRESULT hr = S_OK;
-
- if (psFunc->invkind & INVOKE_PROPERTYGET)
- { // A "Get", so return type is property type.
- *ppSig = psFunc;
- *pSemantics = msGetter;
- }
- else
- {
- _ASSERTE(psFunc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF));
- // Search for the "best" method from which to grab the signature. We prefer the Get(),
- // Followed by the Put(), followed by the PutRef()
- // Also look for Put() and PutRef(), so we can
- for (int iFunc=0; iFunc<(int)m_MemberList.Size() && cFound<3; ++iFunc)
- {
- // Get a FUNCDESC from the list.
- psTmp = m_MemberList[iFunc].m_psFunc;
-
- // Is it for the same func?
- if (psTmp->memid != psFunc->memid)
- continue;
-
- // Is it the Get()? If so, it is the one we want.
- if (psTmp->invkind & INVOKE_PROPERTYGET)
- {
- psGet = psTmp;
- ++cFound;
- continue;
- }
-
- // Is it the Put()? Use it if we don't find a Get().
- if (psTmp->invkind & INVOKE_PROPERTYPUT)
- {
- psPut = psTmp;
- ++cFound;
- continue;
- }
-
- // Is it the PutRef()? Keep track of it.
- if (psTmp->invkind & INVOKE_PROPERTYPUTREF)
- {
- psPutRef = psTmp;
- ++cFound;
- }
- }
- // Get the best FUNCDESC for the signature.
- *ppSig = psGet ? psGet : (psPut ? psPut : psFunc);
-
- // Determine whether this is a the "Set" or "VB specific Let" function.
- if (psFunc->invkind & INVOKE_PROPERTYPUTREF)
- { // This function is the PROPERTYPUTREF. Make it the setter. If
- // there is also a PROPERTYPUT, it will be the "letter".
- *pSemantics = msSetter;
- }
- else
- { // We are looking at the PROPERTYPUT function (the "Let" function in native VB6.).
-
- // If there is also a PROPERTYPUTREF, make this the "VB Specific Let" function.
- if (psPutRef)
- { // A PPROPERTYPUTREF also exists, so make this the "Let" function.
- *pSemantics = msOther;
- }
- else
- { // There is no PROPERTYPUTREF, so make this the setter.
- *pSemantics = msSetter;
- }
- }
- }
-
- // Occasionally there is a property with no discernable type. In that case, lose the
- // property on conversion.
-
- // Determine the type of the property, based on the "best" accessor.
- psF = *ppSig;
- *pbRetval = FALSE;
- if (psF->invkind & INVOKE_PROPERTYGET)
- { // look for [retval].
- for (i=psF->cParams-1; i>=0; --i)
- {
- if (psF->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
- { // will consume a level of indirection (later).
- *pbRetval = TRUE;
- pReturn = &psF->lprgelemdescParam[i].tdesc;
- break;
- }
- }
- // If no [retval], check return type.
- if (!pReturn && psF->elemdescFunc.tdesc.vt != VT_VOID && psF->elemdescFunc.tdesc.vt != VT_HRESULT)
- pReturn = &psF->elemdescFunc.tdesc;
-
- if (fUseLastParam)
- {
- // We may have stripped the [retval] if this is a disp-only interface. Just use the last parameter.
- if (!pReturn && (psF->cParams > 0))
- pReturn = &psF->lprgelemdescParam[psF->cParams-1].tdesc;
- }
- else
- {
- // If there is no type, don't try to set the getter.
- if (pReturn && pReturn->vt == VT_VOID)
- pReturn = NULL;
- }
-
- if (!pReturn)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_PROPGET_WITHOUT_RETURN, strName, m_szMngName);
- }
- }
- else
- { // Find lastmost param that isn't [retval]. (Should be the last param, but it is
- // possible to write an IDL with a PROPERTYPUT that has a [retval].
- for (i=psF->cParams-1; i>=0; --i)
- {
- if ((psF->lprgelemdescParam[psF->cParams-1].paramdesc.wParamFlags & PARAMFLAG_FRETVAL) == 0)
- {
- { // First, and possibly only, param.
- pReturn = &psF->lprgelemdescParam[i].tdesc;
- break;
- }
- }
- }
- }
-
-//ErrExit:
- if (pReturn == 0)
- *pSemantics = 0;
- *ppProperty = pReturn;
-
- return hr;
-} // HRESULT CImportTlb::_GetFunctionPropertyInfo()
-
-//*****************************************************************************
-// Convert a function description to metadata entries.
-//
-// This can be rather involved. If the function is a INVOKE_PROPERTY*,
-// determine if it will be converted as a COM+ property, and if so, which
-// of up to three functions will be selected to provide the property
-// signature.
-// The function return type is found by scaning the parameters looking for
-// [retval]s.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-HRESULT CImportTlb::_ConvFunction(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember, // iNFO for the function.
- BOOL bVtblGapFuncs, // Add functions for vtblGaps?
- BOOL bAddDispIds, // Add DispIds to the member?
- BOOL bDelegateInvokeMeth, // Convert function for a delegate invoke
- BOOL* bAllowIEnum) // Allowed to change this function to GetEnumerator
-{
- HRESULT hr; // A result.
- int iSrcParam; // Param count, as looping through params.
- int iDestParam; // Param count, as looping through params.
- int cDestParams; // Count of destination params.
- int ixOpt; // Index of first param that is optional due to cParamsOpt.
- int ixVarArg; // Index of vararg param, if any.
- mdMethodDef mdFunc; // Token of new member.
- BSTR szTypeName=0; // Name of the type.
- DWORD dwFlags=0; // Member flags.
- DWORD dwImplFlags=0; // The impl flags.
- WCHAR *pszName=0; // Possibly decorated name of member.
- CQuickArray<WCHAR> qbName; // Buffer for decorated name.
- TYPEDESC *pReturn=0; // Return type.
- int bRetval=false; // Is the return result a [retval] parameter?
- int ixRetval; // Which param is the [retval]?
- TYPEDESC *pReturnRetval=0; // Return type from [retval] (incl. indirection).
- WORD wRetFlags=0; // Return type flags.
- ULONG offset=0; // Offset of function
- BSTR *rszParamNames=0; // Parameter names.
- UINT iNames; // Count of actual names.
- CQuickBytes qbComSig; // new signature
- BYTE *pbSig; // Pointer into the signature.
- ULONG sigFlags; // Signature handling flags.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- CQuickArray<BYTE> qbDummyNativeTypeBuf; // A dummy native type array.
- CQuickArray<ULONG> qbNativeOfs; // Offset of native type for each param.
- CQuickArray<ULONG> qbNativeLen; // Length of native type for each param.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
- ULONG iNewNativeOfs=0; // New offset in native type buffer.
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Size of the signature.
- int bOleCall=false; // Is the implementation OLE style?(HRESULT or IDispatch)
- USHORT msSemantics=0; // Property's methodsemantics.
- WCHAR szSpecial[40]; // To build name of special function.
- mdToken tkAttr; // Token for custom attribute type.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- enum {ParamRetval=-1, ParamNone=-2};
- int iParamError=ParamNone; // Index of param with conversion error.
- BOOL bNewEnumMember = FALSE; // A flag indicating if the member is the NewEnum member.
- int iLCIDParam = -1; // Index of the LCID parameter.
- FUNCDESC *psFunc = pMember->m_psFunc;
-
- // If we might insert vtable gaps, then we'd better have initialized the vtable slot size.
- _ASSERTE(!bVtblGapFuncs || (m_cbVtableSlot != 0));
-
- // Retrieve the member name from the member info.
- IfNullGo(m_szMember = SysAllocString(bDelegateInvokeMeth ? DELEGATE_INVOKE_METH_NAME : pMember->m_pName));
-
-#ifdef _DEBUG
- LPWSTR funcName = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_TlbImpShouldBreakOnConvFunction);
- if (funcName)
- {
- if (wcscmp(funcName, pMember->m_pName) == 0)
- _ASSERTE(!"TlbImpBreakOnConvFunction");
-
- delete [] funcName;
- }
-#endif //_DEBUG
-
- // Determine if the member is the new enum member.
- if ((*bAllowIEnum))
- {
- bNewEnumMember = FuncIsNewEnum(pITI, psFunc, pMember->m_iMember) == S_OK;
-
- // Once a method is converted in this interface, don't convert any more.
- if (bNewEnumMember)
- *bAllowIEnum = FALSE;
- }
-
-
- // We should NEVER have a new enum member when we are dealing with a delegate invoke meth.
- if (bNewEnumMember && bDelegateInvokeMeth)
- {
- // Get the real name of the method
- BSTR szTypeInfoName = NULL;
- BSTR szMemberName = NULL;
- hr = m_pITI->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0);
- if (FAILED(hr))
- szTypeInfoName = SysAllocString(W("???"));
-
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_EVENT_WITH_NEWENUM, szTypeInfoName);
-
- SysFreeString(szMemberName);
- SysFreeString(szTypeInfoName);
-
- IfFailGo(TLBX_E_EVENT_WITH_NEWENUM);
- }
-
- // If there is a gap in the vtable, emit a special function.
- if (bVtblGapFuncs)
- {
- if ((psFunc->oVft / m_cbVtableSlot) != m_Slot)
- {
- ULONG n = psFunc->oVft / m_cbVtableSlot;
- // Make sure slot numbers are monotonically increasing.
- if (n < m_Slot)
- {
- IfFailGo(pITI->GetDocumentation(MEMBERID_NIL, &szTypeName, 0, 0, 0));
- IfFailGo(PostError(TLBX_E_BAD_VTABLE, m_szMember, szTypeName, m_szLibrary));
- }
-
- n -= m_Slot;
- if (n == 1)
- _snwprintf_s(szSpecial, lengthof(szSpecial), lengthof(szSpecial) - 1, VTBL_GAP_FORMAT_1, VTBL_GAP_FUNCTION, m_Slot);
- else
- _snwprintf_s(szSpecial, lengthof(szSpecial), lengthof(szSpecial) - 1, VTBL_GAP_FORMAT_N, VTBL_GAP_FUNCTION, m_Slot, n);
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, szSpecial, VTBL_GAP_FUNCTION_FLAGS, VTBL_GAP_SIGNATURE,sizeof(VTBL_GAP_SIGNATURE),
- 0/* rva*/, VTBL_GAP_FUNC_IMPL_FLAGS, &mdFunc));
- m_Slot += n;
- }
- // What we will expect next time.
- ++m_Slot;
- }
-
- //-------------------------------------------------------------------------
- // Determine the return type.
- // If this is an hresult function, prepare to munge return, params.
- if (psFunc->elemdescFunc.tdesc.vt == VT_HRESULT)
- {
- bOleCall = true;
- }
- else
- {
- if ((psFunc->elemdescFunc.tdesc.vt != VT_VOID) && (psFunc->elemdescFunc.tdesc.vt != VT_HRESULT))
- pReturn = &psFunc->elemdescFunc.tdesc;
- }
-
- // Look for [RETVAL].
- for (iSrcParam=0; iSrcParam<psFunc->cParams; ++iSrcParam)
- {
- if (psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & PARAMFLAG_FRETVAL)
- {
- // If already have a return, or a DISPATCH function, error.
- if (pReturn != 0)
- { // Unexpected return found.
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_AMBIGUOUS_RETURN, m_szName, m_szMember);
- IfFailGo(TLBX_E_AMBIGUOUS_RETURN);
- }
- else
- { // Found a return type.
- wRetFlags = psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags;
- pReturn = &psFunc->lprgelemdescParam[iSrcParam].tdesc;
- bRetval = true;
- ixRetval = iSrcParam;
- }
- break;
- }
- }
-
- // Check to see if there is an LCID parameter.
- for (iSrcParam=0;iSrcParam<psFunc->cParams;iSrcParam++)
- {
- if (psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & PARAMFLAG_FLCID)
- {
- if (iLCIDParam != -1)
- IfFailGo(PostError(TLBX_E_MULTIPLE_LCIDS, m_szName, m_szMember));
- iLCIDParam = iSrcParam;
- }
- }
-
- //-------------------------------------------------------------------------
- // Size buffers to accomodate parameters.
- // Resize the native type length array.
- IfFailGo(qbNativeBuf.ReSizeNoThrow(1));
- IfFailGo(qbNativeLen.ReSizeNoThrow(psFunc->cParams + 1));
- IfFailGo(qbNativeOfs.ReSizeNoThrow(psFunc->cParams + 1));
- memset(qbNativeLen.Ptr(), 0, (psFunc->cParams + 1)*sizeof(int));
- memset(qbNativeOfs.Ptr(), 0, (psFunc->cParams + 1)*sizeof(int));
-
- // resize to make room for calling convention and count of argument
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE + 1));
- pbSig = (BYTE *)qbComSig.Ptr();
-
- //-------------------------------------------------------------------------
- // Determine which params need to be marked optional, by virtue of cParamsOpt count.
- if (psFunc->cParamsOpt == 0)
- ixVarArg = ixOpt = psFunc->cParams + 1;
- else
- {
- if (psFunc->cParamsOpt == -1)
- { // Varargs.
- ixVarArg = ixOpt = psFunc->cParams + 1;
- // If this is a PROPERTYPUT or PROPERTYPUTREF, skip the last non-retval parameter (it
- // is the new value to be set).
- BOOL bPropVal = (psFunc->invkind & (INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)) ? TRUE : FALSE;
- // Find the vararg param.
- for (iSrcParam=psFunc->cParams-1; iSrcParam>=0; --iSrcParam)
- {
- // The count of optional params does not include any lcid params, nor does
- // it include the return value, so skip those.
- if ((psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)) != 0)
- continue;
- // If haven't yet seen the property value, this param is it, so skip it, too.
- if (bPropVal)
- {
- bPropVal = FALSE;
- continue;
- }
- ixVarArg = iSrcParam;
- break;
- } // for (iSrcParam=cParams-1...
- }
- else
- { // ixOpt will be index of first optional parameter.
- short cOpt = psFunc->cParamsOpt;
- ixOpt = 0;
- ixVarArg = psFunc->cParams + 1;
- for (iSrcParam=psFunc->cParams-1; iSrcParam>=0; --iSrcParam)
- {
- // The count of optional params does not include any lcid params, nor does
- // it include the return value, so skip those.
- if ((psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & (PARAMFLAG_FRETVAL|PARAMFLAG_FLCID)) == 0)
- {
- if (--cOpt == 0)
- {
- ixOpt = iSrcParam;
- break;
- }
- }
- } // for (iSrcParam=cParams-1...
- }
- }
-
-
- //-------------------------------------------------------------------------
- // Get the parameter names.
- rszParamNames = reinterpret_cast<BSTR*>(_alloca((psFunc->cParams+1) * sizeof(BSTR*)));
-
- // Get list of names.
- IfFailGo(pITI->GetNames(psFunc->memid, rszParamNames, psFunc->cParams+1, &iNames));
-
- // zero name pointer for non-named params.
- for (iSrcParam=iNames; iSrcParam<=psFunc->cParams; ++iSrcParam)
- rszParamNames[iSrcParam] = 0;
-
- //-------------------------------------------------------------------------
- // Convert the calling convention, param count, and return type.
- cDestParams = psFunc->cParams;
- if (bRetval)
- --cDestParams;
- if (iLCIDParam != -1)
- --cDestParams;
-
- if (pReturn)
- {
- // Param count
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- cb = CorSigCompressData(cDestParams, &(pbSig[cbTotal]));
- cbTotal += cb;
- // Return type or [retval].
- if (bRetval)
- sigFlags = (SigFlags)(wRetFlags & SIG_FLAGS_MASK) | SIG_FUNC, iParamError=ixRetval;
- else
- sigFlags = SIG_FUNC, iParamError=ParamRetval;
- IfFailGo(_ConvSignature(pITI, pReturn, sigFlags, qbComSig, cbTotal, &cbTotal, qbNativeBuf, iNativeOfs, &iNewNativeOfs, bNewEnumMember));
- qbNativeLen[0] = iNewNativeOfs - iNativeOfs;
- qbNativeOfs[0] = iNativeOfs;
- iNativeOfs = iNewNativeOfs;
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
- else
- { // No return value
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- cb = CorSigCompressData(cDestParams, &(pbSig[cbTotal]));
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &pbSig[cbTotal]);
- cbTotal += cb;
- }
-
- //-------------------------------------------------------------------------
- // Translate each parameter.
- for (iSrcParam=0, iDestParam=0; iSrcParam<psFunc->cParams; ++iSrcParam)
- {
- if (!(psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS))
- {
- sigFlags = (SigFlags)(psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & SIG_FLAGS_MASK) | SIG_FUNC | SIG_USE_BYREF;
- if (iSrcParam == ixVarArg)
- sigFlags |= SIG_VARARG;
- iParamError = iSrcParam;
- IfFailGo(_ConvSignature(pITI, &psFunc->lprgelemdescParam[iSrcParam].tdesc, sigFlags, qbComSig, cbTotal, &cbTotal, qbNativeBuf, iNativeOfs, &iNewNativeOfs, bNewEnumMember));
- qbNativeLen[iDestParam+1] = iNewNativeOfs - iNativeOfs;
- qbNativeOfs[iDestParam+1] = iNativeOfs;
- iNativeOfs = iNewNativeOfs;
- iDestParam++;
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- }
- }
- iParamError = ParamNone;
-
- //-------------------------------------------------------------------------
- // Get the previously decorated name. Add interface name and make unique.
- if (bDelegateInvokeMeth)
- {
- pszName = (WCHAR*)DELEGATE_INVOKE_METH_NAME;
- }
- else
- {
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(pMember->m_pName)+2));
- wcscpy_s(qbName.Ptr(), wcslen(pMember->m_pName)+2, pMember->m_pName);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtMethodDef));
- pszName = qbName.Ptr();
- }
-
- // Determine the function's semantics, flags and impl flags.
- if (!bDelegateInvokeMeth)
- {
- msSemantics = pMember->m_msSemantics;
- dwImplFlags = DEFAULT_ITF_FUNC_IMPL_FLAGS;
- dwFlags = msSemantics ? DEFAULT_PROPERTY_FUNC_FLAGS : DEFAULT_INTERFACE_FUNC_FLAGS;
- // If processing an implemented interface, remove the abstract bit. Methods on classes are not abstract.
- if (m_ImplIface != eImplIfaceNone)
- dwFlags &= ~mdAbstract;
- }
- else
- {
- msSemantics = 0;
- dwImplFlags = miRuntime;
- dwFlags = DELEGATE_INVOKE_FUNC_FLAGS;
- }
-
- //-------------------------------------------------------------------------
- // Create the function definition in the metadata.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, pszName, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal,
- 0 /* rva*/, dwImplFlags | (bOleCall ? 0 : miPreserveSig), &mdFunc));
-
- // If the method is part of a property, save info to set up the property.
- if (msSemantics)
- pMember->SetFuncInfo(mdFunc, msSemantics);
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Add the DispIds if the flag is set.
- long lDispSet = 1;
- _SetDispIDCA(pITI, pMember->m_iMember, psFunc->memid, mdFunc, bAddDispIds, &lDispSet, TRUE);
-
- // If this method is the default, and not a property accessor, add a custom attribute to the class.
- if (lDispSet == DISPID_VALUE && msSemantics == 0)
- IfFailGo(_AddDefaultMemberCa(m_tdTypeDef, m_szMember));
- }
-
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(int));
-
- // If this method has an LCID then set the LCIDConversion attribute.
- if (iLCIDParam != -1)
- {
- // Dispid for the function.
- BUILD_CUSTOM_ATTRIBUTE(int, iLCIDParam);
- IfFailGo(GetAttrType(ATTR_LCIDCONVERSION, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdFunc, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Save the func flags for anyone that needs typelib's flags.
- if (psFunc->wFuncFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBFUNC, &tkAttr));
- INIT_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, psFunc->wFuncFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdFunc, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- //-------------------------------------------------------------------------
- // Convert the param info for the return type.
- if (pReturn)
- { // store return value parameter as sequence 0
- if (bRetval)
- {
- hr = _IsAlias(pITI, &psFunc->lprgelemdescParam[ixRetval].tdesc);
- IfFailGo(hr);
- if (qbNativeLen[0] || hr == S_OK)
- {
- IfFailGo(_ConvParam(pITI, mdFunc, 0, &psFunc->lprgelemdescParam[ixRetval], ParamNormal, 0 /*rszParamNames[ixRetval+1]*/,
- &qbNativeBuf[qbNativeOfs[0]], qbNativeLen[0]));
- }
- }
- else
- {
- hr = _IsAlias(pITI, &psFunc->elemdescFunc.tdesc);
- IfFailGo(hr);
- if (qbNativeLen[0] || hr == S_OK)
- {
- IfFailGo(_ConvParam(pITI, mdFunc, 0, &psFunc->elemdescFunc, ParamNormal, 0,
- &qbNativeBuf[qbNativeOfs[0]], qbNativeLen[0]));
- }
- }
- }
-
- //-------------------------------------------------------------------------
- // Convert parameter info (flags, native type, default value).
- for (iSrcParam=iDestParam=0; iSrcParam<psFunc->cParams; ++iSrcParam)
- {
- if ((psFunc->lprgelemdescParam[iSrcParam].paramdesc.wParamFlags & NON_CONVERTED_PARAMS_FLAGS) == 0)
- {
- ParamOpts opt = ParamNormal;
- if (iSrcParam >= ixOpt)
- opt = ParamOptional;
- else
- if (iSrcParam == ixVarArg)
- opt = ParamVarArg;
- iDestParam++;
- IfFailGo(_ConvParam(pITI, mdFunc, iDestParam, &psFunc->lprgelemdescParam[iSrcParam], opt, rszParamNames[iSrcParam + 1],
- &qbNativeBuf[qbNativeOfs[iDestParam]], qbNativeLen[iDestParam]));
- }
- }
-
-
- //-------------------------------------------------------------------------
- // If processing an implemented interface, set up MethodImpls.
- if (m_ImplIface != eImplIfaceNone)
- {
- // Define a memberref on the implemented interface.
- mdToken mrItfMember;
- IfFailGo(m_pEmit->DefineMemberRef(m_tkInterface, pMember->m_pName, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, &mrItfMember));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdFunc, mrItfMember));
- }
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_ARGS, m_szName, m_szMember);
- }
-
-ErrExit:
- // Special case for typeload load failures -- they're very hard to diagnose.
- if (hr == TYPE_E_CANTLOADLIBRARY)
- {
- if (iParamError >= 0 && iParamError < psFunc->cParams && rszParamNames[iParamError+1])
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_PARAM_ERROR_NAMED, m_szName, rszParamNames[iParamError+1], m_szMember);
- else
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_PARAM_ERROR_UNNAMED, m_szName, iParamError, m_szMember);
- }
- if (rszParamNames)
- {
- for (iSrcParam=0; iSrcParam<=psFunc->cParams; ++iSrcParam)
- if (rszParamNames[iSrcParam])
- ::SysFreeString(rszParamNames[iSrcParam]);
- }
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- if (szTypeName)
- ::SysFreeString(szTypeName);
-
- return (hr);
-} // HRESULT CImportTlb::_ConvFunction()
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-
-HRESULT CImportTlb::_SetHiddenCA(mdTypeDef token)
-{
- mdToken tkAttr;
- HRESULT hr = S_OK;
-
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(short));
- BUILD_CUSTOM_ATTRIBUTE(short, TYPEFLAG_FHIDDEN);
- IfFailGo(GetAttrType(ATTR_TYPELIBTYPE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- m_pEmit->DefineCustomAttribute(token, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0);
-
-ErrExit:
- return S_OK;
-}
-
-HRESULT CImportTlb::_ForceIEnumerableCVExists(ITypeInfo* pITI, BOOL* CVExists)
-{
- ITypeInfo2 *pITI2 = 0;
- *CVExists = FALSE;
- HRESULT hr = S_OK;
-
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- if (pITI2)
- {
- VARIANT vCustomData;
- VariantInit(&vCustomData);
-
- IfFailGo(pITI2->GetCustData(GUID_ForceIEnumerable, &vCustomData));
-
- if (V_VT(&vCustomData) != VT_EMPTY)
- *CVExists = TRUE;
-
- VariantClear(&vCustomData);
- }
-
-ErrExit:
- if (pITI2)
- pITI2->Release();
-
- return S_OK;
-}
-
-
-HRESULT CImportTlb::_GetDispIDCA(
- ITypeInfo* pITI,
- int iMember,
- long* lDispSet,
- BOOL bFunc
- )
-{
- ITypeInfo2 *pITI2=0; // For getting custom value.
- HRESULT hr = S_OK;
- long lDispId = DISPID_UNKNOWN;
-
- // Get the ITypeInfo2 interface if possible
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- if (pITI2)
- {
- VARIANT vCustomData;
- VariantInit(&vCustomData);
-
- if (bFunc)
- IfFailGo(pITI2->GetFuncCustData(iMember, GUID_DispIdOverride, &vCustomData));
- else
- IfFailGo(pITI2->GetVarCustData(iMember, GUID_DispIdOverride, &vCustomData));
-
- if ((V_VT(&vCustomData) == VT_I2) || (V_VT(&vCustomData) == VT_I4))
- {
- hr = VariantChangeType(&vCustomData, &vCustomData, 0, VT_I4);
- if (hr == S_OK)
- lDispId = vCustomData.lVal;
- }
-
- VariantClear(&vCustomData);
- }
-
-ErrExit:
- if (lDispSet != NULL)
- *lDispSet = lDispId;
-
- if (pITI2)
- pITI2->Release();
-
- return S_OK;
-}
-
-
-
-HRESULT CImportTlb::_SetDispIDCA(
- ITypeInfo* pITI,
- int iMember,
- long lDispId,
- mdToken func,
- BOOL fAlwaysAdd,
- long* lDispSet,
- BOOL bFunc
- )
-{
- WCHAR DispIDCA[] = W("{CD2BC5C9-F452-4326-B714-F9C539D4DA58}");
- ITypeInfo2 *pITI2=0; // For getting custom value.
- HRESULT hr = S_OK;
-
- // Get the ITypeInfo2 interface if possible
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- if (pITI2)
- {
- VARIANT vCustomData;
- VariantInit(&vCustomData);
-
- if (bFunc)
- IfFailGo(pITI2->GetFuncCustData(iMember, GUID_DispIdOverride, &vCustomData));
- else
- IfFailGo(pITI2->GetVarCustData(iMember, GUID_DispIdOverride, &vCustomData));
-
- if ((V_VT(&vCustomData) == VT_I2) || (V_VT(&vCustomData) == VT_I4))
- {
- hr = VariantChangeType(&vCustomData, &vCustomData, 0, VT_I4);
- if (hr == S_OK)
- {
- lDispId = vCustomData.lVal;
- fAlwaysAdd = true;
- }
- }
- else if (V_VT(&vCustomData) != VT_EMPTY)
- {
- // Invalid Variant type on the data - spit out a warning.
- BSTR CustomValue = SysAllocString((const WCHAR*)&DispIDCA[0]);
- BSTR ObjectName;
- IfFailGo(pITI2->GetDocumentation(iMember+1, &ObjectName, NULL, NULL, NULL));
-
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_NON_INTEGRAL_CA_TYPE, CustomValue, ObjectName);
-
- SysFreeString(CustomValue);
- SysFreeString(ObjectName);
- }
-
- VariantClear(&vCustomData);
- }
-
- // Set the dispid CA on the property.
- if (fAlwaysAdd)
- {
- mdToken tkAttr;
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(DISPID));
- BUILD_CUSTOM_ATTRIBUTE(DISPID, lDispId);
- IfFailGo(GetAttrType(ATTR_DISPID, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(func, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
-ErrExit:
- if (lDispSet != NULL)
- {
- *lDispSet = lDispId;
- }
-
- if (pITI2)
- pITI2->Release();
-
- return S_OK;
-}
-
-
-HRESULT CImportTlb::_CheckForPropertyCustomAttributes(ITypeInfo* pITI, int index, INVOKEKIND* ikind)
-{
- HRESULT hr;
- VARIANT vCustomData;
- ITypeInfo2* pITI2 = 0;
- BOOL found = FALSE;
-
- VariantInit(&vCustomData);
-
- // Get the ITypeInfo2 interface if possible
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
- if (pITI2)
- {
- // First, check for PropGet
- hr = pITI2->GetFuncCustData(index, GUID_PropGetCA, &vCustomData);
- IfFailGo(hr);
- if (V_VT(&vCustomData) != VT_EMPTY)
- {
- *ikind = INVOKE_PROPERTYGET;
- found = TRUE;
- goto ErrExit;
- }
-
- // Second, check for PropPut
- VariantClear(&vCustomData);
- hr = pITI2->GetFuncCustData(index, GUID_PropPutCA, &vCustomData);
- IfFailGo(hr);
- if (V_VT(&vCustomData) != VT_EMPTY)
- {
- *ikind = INVOKE_PROPERTYPUT;
- found = TRUE;
- goto ErrExit;
- }
- }
-
-ErrExit:
- VariantClear(&vCustomData);
-
- if (pITI2)
- pITI2->Release();
-
- if (found)
- return S_OK;
-
- return S_FALSE;
-}
-
-//*****************************************************************************
-// Generate an event with an add and remove method
-//*****************************************************************************
-HRESULT CImportTlb::_GenerateEvent(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember, // Info for the function
- BOOL fInheritsIEnum)
-{
- HRESULT hr = S_OK; // A result.
- mdMethodDef mdAdd; // Token of add_XXX method.
- mdMethodDef mdRemove; // Token of remove_XXX method.
- CQuickArray<WCHAR> qbName; // Buffer for decorated name.
- CQuickArray<BYTE> qbSig; // The signature.
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Size of the signature.
- mdTypeDef tdDelegate; // The delegate type def.
- mdEvent tkEvent; // The token for the event.
-
- // If this method is a property method, then skip the event.
- // Also look at the property semantic - it might be we couldn't import this as a property
- // and fell back to a method.
- if ((pMember->m_psFunc->invkind != INVOKE_FUNC) && (pMember->m_msSemantics != 0))
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_W_NO_PROPS_IN_EVENTS, m_szName);
- return S_CONVERSION_LOSS;
- }
-
- // Generate the delegate.
- IfFailGo(_GenerateEventDelegate(pITI, pMember, &tdDelegate, fInheritsIEnum));
-
- // Generate the sig for the add and remove methods.
- IfFailGo(qbSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2 + 1));
- cbTotal = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, qbSig.Ptr());
- cb = CorSigCompressData(1, &(qbSig[cbTotal]));
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_CLASS, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressToken(tdDelegate, &qbSig[cbTotal]);
- cbTotal += cb;
-
- // Generate the add method.
- IfFailGo(qbName.ReSizeNoThrow(EVENT_ADD_METH_PREFIX_LENGTH + wcslen(pMember->m_pName) + 1));
- StringCchPrintf(qbName.Ptr(), qbName.Size(), W("%s%s"), EVENT_ADD_METH_PREFIX, pMember->m_pName);
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, qbName.Ptr(), DEFAULT_INTERFACE_FUNC_FLAGS,
- qbSig.Ptr(), cbTotal, 0 /* rva*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdAdd));
-
- // Generate the remove method.
- IfFailGo(qbName.ReSizeNoThrow(EVENT_REM_METH_PREFIX_LENGTH + wcslen(pMember->m_pName) + 1));
- StringCchPrintf(qbName.Ptr(), qbName.Size(), W("%s%s"), EVENT_REM_METH_PREFIX, pMember->m_pName);
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, qbName.Ptr(), DEFAULT_INTERFACE_FUNC_FLAGS,
- qbSig.Ptr(), cbTotal, 0 /* rva*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdRemove));
-
- // Define the event itself.
- IfFailGo(m_pEmit->DefineEvent(m_tdTypeDef, pMember->m_pName, 0, tdDelegate,
- mdAdd, mdRemove, mdTokenNil, NULL, &tkEvent));
-
-ErrExit:
-
- return (hr);
-} // HRESULT CImportTlb::_GenerateEvent()
-
-//*****************************************************************************
-// Generate an add and remove method
-//*****************************************************************************
-HRESULT CImportTlb::_GenerateEventDelegate(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember, // Info for the source interface func
- mdTypeDef *ptd, // The output typedef.
- BOOL fInheritsIEnum)
-{
- HRESULT hr = S_OK; // A result.
- BSTR bstrSrcItfName = NULL; // The name of the source interface.
- CQuickArray<WCHAR> qbEventHandlerName; // The name of the event handler.
- BSTR szOldName = NULL; // The old value m_tdTypeDef.
- mdTypeDef tdOldTypeDef = NULL; // The old value m_szName.
- CQuickArray<BYTE> qbSig; // The signature.
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Total size of signature.
- mdMethodDef mdFunc; // The defined function.
- mdTypeRef trMulticastDelegate; // The type ref for System.MulticastDelegate.
- mdToken tkAttr; // Custom attribute type.
-
- // Store the old values of the ITypeInfo name and of the current type def.
- szOldName = m_szName;
- tdOldTypeDef = m_tdTypeDef;
- m_szName = NULL;
-
- // Retrieve the full name of the source interface.
- IfFailGo(GetManagedNameForTypeInfo(pITI, m_wzNamespace, NULL, &bstrSrcItfName));
-
- // Generate a unique name for the event handler which will be of the form:
- // <SrcItfName>_<MethodName>_EventHandler<PotentialSuffix>
- IfFailGo(qbEventHandlerName.ReSizeNoThrow(wcslen(bstrSrcItfName) + wcslen(pMember->m_pName) + EVENT_HANDLER_SUFFIX_LENGTH + 6));
- StringCchPrintf(qbEventHandlerName.Ptr(), qbEventHandlerName.Size(), W("%s_%s%s"), bstrSrcItfName, pMember->m_pName, EVENT_HANDLER_SUFFIX);
- IfFailGo(GenerateUniqueTypeName(qbEventHandlerName));
-
- // Set the information on the current type.
- IfNullGo(m_szName = SysAllocString(qbEventHandlerName.Ptr()));
-
- // Retrieve the parent type ref.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_MULTICASTDEL, &trMulticastDelegate));
-
- // Create the typedef for the event interface.
- IfFailGo(m_pEmit->DefineTypeDef(m_szName, tdPublic | tdSealed, trMulticastDelegate, NULL, &m_tdTypeDef));
-
- // Hide the interface from Object Browsers (EventHandler)
- _SetHiddenCA(m_tdTypeDef);
-
- // Make the interface ComVisible(false).
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, FALSE);
- IfFailGo(GetAttrType(ATTR_COMVISIBLE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Generate the sig for the constructor.
- IfFailGo(qbSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2 + 1));
- cbTotal = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, qbSig.Ptr());
- cb = CorSigCompressData(2, &(qbSig[cbTotal]));
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_OBJECT, &qbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressData(ELEMENT_TYPE_U, &qbSig[cbTotal]);
- cbTotal += cb;
-
- // Generate the constructor.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, OBJECT_INITIALIZER_NAME, OBJECT_INITIALIZER_FLAGS,
- qbSig.Ptr(), cbTotal, 0 /* rva*/, miRuntime, &mdFunc));
-
- // Generate the invoke method.
- BOOL bAllowIEnum = !fInheritsIEnum;
- IfFailGo(_ConvFunction(pITI, pMember, FALSE, FALSE, TRUE, &bAllowIEnum));
-
- // Set the output typedef.
- *ptd = m_tdTypeDef;
-
-ErrExit:
- if (m_szName)
- ::SysFreeString(m_szName);
- if (m_szMember)
- ::SysFreeString(m_szMember); m_szMember=0;
- if (bstrSrcItfName)
- ::SysFreeString(bstrSrcItfName);
-
- // Restore the initial values for the ITypeInfo name and the type def.
- m_szName = szOldName;
- m_tdTypeDef = tdOldTypeDef;
-
- return (hr);
-} // HRESULT CImportTlb::_GenerateEventDelegate()
-
-//*****************************************************************************
-//*****************************************************************************
-struct MDTOKENHASH : HASHLINK
-{
- mdToken tkKey;
- mdToken tkData;
-}; // struct MDTOKENHASH : HASHLINK
-
-class CTokenHash : public CChainedHash<MDTOKENHASH>
-{
-public:
- virtual bool InUse(MDTOKENHASH *pItem)
- { return (pItem->tkKey != NULL); }
-
- virtual void SetFree(MDTOKENHASH *pItem)
- {
- pItem->tkKey = NULL;
- pItem->tkKey = NULL;
- }
-
- virtual ULONG Hash(const void *pData)
- {
- // Do case-insensitive hash
- return (ULONG)(ULONG_PTR)pData;
- }
-
- virtual int Cmp(const void *pData, void *pItem){
- return (mdToken)(ULONG_PTR)pData != reinterpret_cast<MDTOKENHASH*>(pItem)->tkKey;
- }
-}; // CTokenHash : public CChainedHash<MDTOKENHASH>
-
-//*****************************************************************************
-// Copy methods and events from a source interface to a class that sources the
-// given interface.
-//*****************************************************************************
-HRESULT CImportTlb::_AddSrcItfMembersToClass( // S_OK or error.
- mdTypeRef trSrcItf) // Typeref of the source interface.
-{
- HRESULT hr=S_OK; // A result.
- ULONG i; // Generic counter.
- HCORENUM MemberEnum = NULL; // The enum of members.
- ULONG cMembers = 0; // Temp count of members.
- mdTypeDef tdSrcItf; // A type def to the interface.
- mdEvent tkItfEvent; // The token of the interface event.
- mdEvent tkClassEvent; // The token of the class event.
- mdToken tkEventType; // The event type.
- mdMethodDef mdItfMethod; // The method def of the interface method.
- mdMethodDef mdAddMethod; // The add method.
- mdMethodDef mdRemoveMethod; // The remove method.
- mdMethodDef mdFireMethod; // The fire method.
- mdMethodDef mdClassMethod; // The method def of the class method.
- CQuickArray<mdMethodDef> qbOtherMethods; // The other methods for the property.
- ULONG cchOtherMethods; // The cound of other methods.
- CQuickArray<WCHAR> qbMemberName; // Name of the member.
- CQuickArray<WCHAR> qbEventItfFullName; // Full name of the event interface.
- CQuickArray<WCHAR> qbEventItfName; // Name of the event interface.
- ULONG cchName; // Length of a name, in wide chars.
- ULONG ItfMemberAttr; // The attributes of the interface member.
- ULONG ItfMemberImplFlags; // The impl flags of the interface member.
- PCCOR_SIGNATURE ItfMemberSig; // The signature of the interface member.
- ULONG ItfMemberSigSize; // The size of the member signature.
- mdMemberRef mrItfMember; // A member ref to the interface member def.
- BSTR bstrSrcItfName = NULL; // The name of the CoClass.
- mdAssemblyRef ar; // The assembly ref.
- CTokenHash ItfMDToClassMDMap; // The interface MD to class MD map.
- MDTOKENHASH * pItem; // An item in the token hashtable.
-
- // Retrieve the name of the event interface.
- do {
- IfFailGo(m_pImport->GetTypeRefProps(
- trSrcItf,
- &ar,
- qbEventItfFullName.Ptr(),
- (ULONG)qbEventItfFullName.MaxSize(),
- &cchName));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbEventItfFullName.ReSizeNoThrow(cchName));
- continue;
- }
- break;
- } while (1);
- IfFailGo(qbEventItfName.ReSizeNoThrow(cchName));
- ns::SplitPath(qbEventItfFullName.Ptr(), NULL, 0, qbEventItfName.Ptr(), (int)qbEventItfName.Size());
-
- // Resolve the typeref to a typedef.
- IfFailGo(m_pImport->FindTypeDefByName(qbEventItfFullName.Ptr(), mdTokenNil, &tdSrcItf));
-
- // Define methods and method impl's for all the methods in the interface.
- while ((hr = m_pImport->EnumMethods(&MemberEnum, tdSrcItf, &mdItfMethod, 1, &cMembers)) == S_OK)
- {
- // Retrieve the method properties.
- do {
- IfFailGo(m_pImport->GetMethodProps(
- mdItfMethod,
- NULL,
- qbMemberName.Ptr(),
- (ULONG)qbMemberName.MaxSize(),
- &cchName,
- &ItfMemberAttr,
- &ItfMemberSig,
- &ItfMemberSigSize,
- NULL,
- &ItfMemberImplFlags));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbMemberName.ReSizeNoThrow(cchName));
- continue;
- }
- break;
- } while (1);
-
- // Define a member ref on the class to the interface member def.
- IfFailGo(m_pEmit->DefineMemberRef(trSrcItf, qbMemberName.Ptr(), ItfMemberSig, ItfMemberSigSize, &mrItfMember));
-
- // Generate a unique name for the class member.
- IfFailGo(GenerateUniqueMemberName(qbMemberName, NULL, 0, qbEventItfName.Ptr(), mdtMethodDef));
-
- // Define a member on the class.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, qbMemberName.Ptr(), ItfMemberAttr & ~mdAbstract,
- ItfMemberSig, ItfMemberSigSize, 0/*rva*/, ItfMemberImplFlags, &mdClassMethod));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdClassMethod, mrItfMember));
-
- // Add the interface member to the map.
- if ((pItem = ItfMDToClassMDMap.Add((const void *)(ULONG_PTR)mdItfMethod)) == NULL)
- IfFailGo(E_FAIL);
- PREFIX_ASSUME(pItem != NULL);
- pItem->tkKey = mdItfMethod;
- pItem->tkData = mdClassMethod;
- }
- IfFailGo(hr);
-
- m_pImport->CloseEnum(MemberEnum);
- MemberEnum = NULL;
-
- // Define all the events in the interface on the class.
- while ((hr = m_pImport->EnumEvents(&MemberEnum, tdSrcItf, &tkItfEvent, 1, &cMembers)) == S_OK)
- {
- // Retrieve the properties of the property.
- do {
- IfFailGo(m_pImport->GetEventProps(
- tkItfEvent,
- NULL,
- qbMemberName.Ptr(),
- (ULONG)qbMemberName.MaxSize(),
- &cchName,
- &ItfMemberAttr,
- &tkEventType,
- &mdAddMethod,
- &mdRemoveMethod,
- &mdFireMethod,
- qbOtherMethods.Ptr(),
- (ULONG)qbOtherMethods.MaxSize(),
- &cchOtherMethods));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbMemberName.ReSizeNoThrow(cchName));
- IfFailGo(qbOtherMethods.ReSizeNoThrow(cchOtherMethods));
- continue;
- }
- break;
- } while (1);
-
- // NULL terminate the array of other methods.
- IfFailGo(qbOtherMethods.ReSizeNoThrow(cchOtherMethods + 1));
- qbOtherMethods[cchOtherMethods] = NULL;
-
- // Replace all the interface method def's with the equivalent class method def's.
- if (!IsNilToken(mdAddMethod))
- {
- pItem = ItfMDToClassMDMap.Find((const void *)(ULONG_PTR)mdAddMethod);
- _ASSERTE(pItem);
- mdAddMethod = pItem->tkData;
- }
- if (!IsNilToken(mdRemoveMethod))
- {
- pItem = ItfMDToClassMDMap.Find((const void *)(ULONG_PTR)mdRemoveMethod);
- _ASSERTE(pItem);
- mdRemoveMethod = pItem->tkData;
- }
- _ASSERTE(IsNilToken(mdFireMethod));
- _ASSERTE(cchOtherMethods == 0);
-
- // Generate a unique name for the event.
- IfFailGo(GenerateUniqueMemberName(qbMemberName, NULL, 0, qbEventItfName.Ptr(), mdtEvent));
-
- // Define property on the class.
- IfFailGo(m_pEmit->DefineEvent(m_tdTypeDef, qbMemberName.Ptr(), ItfMemberAttr,
- tkEventType, mdAddMethod, mdRemoveMethod, mdFireMethod, qbOtherMethods.Ptr(), &tkClassEvent));
- }
- IfFailGo(hr);
-
- m_pImport->CloseEnum(MemberEnum);
- MemberEnum = NULL;
-
-ErrExit:
- if (MemberEnum)
- m_pImport->CloseEnum(MemberEnum);
- if (bstrSrcItfName)
- ::SysFreeString(bstrSrcItfName);
-
- return hr;
-
-#undef ITF_MEMBER_SIG
-#undef ITF_MEMBER_SIG_SIZE
-} // HRESULT CImportTlb::_AddSrcItfMembersToClass()
-
-//*****************************************************************************
-// Compare the two signatures ignoring the return type. If the signatures
-// match then TRUE will be returned, FALSE will be returned otherwise.
-// This method assumes the two signatures are in the same scope.
-//*****************************************************************************
-HRESULT CImportTlb::CompareSigsIgnoringRetType(
- PCCOR_SIGNATURE pbSig1, // The 1st method signature.
- ULONG cbSig1, // Size of the 1st method signature.
- PCCOR_SIGNATURE pbSig2, // The 2nd method signature.
- ULONG cbSig2) // Size of the 2nd method signature.
-{
- HRESULT hr = S_OK;
- PCCOR_SIGNATURE pbSig1Start;
- PCCOR_SIGNATURE pbSig2Start;
- ULONG Sig1ParamCount;
- ULONG Sig2ParamCount;
- ULONG cbSig1RetType;
- ULONG cbSig2RetType;
-
- // Save the start of the signatures.
- pbSig1Start = pbSig1;
- pbSig2Start = pbSig2;
-
- // Skip the calling conventions.
- CorSigUncompressData(pbSig1);
- CorSigUncompressData(pbSig2);
-
- // Compare the param count.
- Sig1ParamCount = CorSigUncompressData(pbSig1);
- Sig2ParamCount = CorSigUncompressData(pbSig2);
- if (Sig1ParamCount != Sig2ParamCount)
- return S_FALSE;
-
- // Skip the return type.
- cbSig1RetType = cbSig1 - (ULONG)(pbSig1 - pbSig1Start);
- IfFailGo(_CountBytesOfOneArg(pbSig1, &cbSig1RetType));
- pbSig1 += cbSig1RetType;
- cbSig2RetType = cbSig2 - (ULONG)(pbSig2 - pbSig2Start);
- IfFailGo(_CountBytesOfOneArg(pbSig2, &cbSig2RetType));
- pbSig2 += cbSig2RetType;
-
- // Update the remaining sig sizes.
- cbSig1 -= (ULONG) (pbSig1 - pbSig1Start);
- cbSig2 -= (ULONG) (pbSig2 - pbSig2Start);
-
- // If the remaining sig sizes are different then the sigs don't match.
- if (cbSig1 != cbSig2)
- return S_FALSE;
-
- // Compare the rest of the sigs using memcmp.
- if (memcmp(pbSig1, pbSig2, cbSig1) != 0)
- return S_FALSE;
-
- // The parameters match.
- return S_OK;
-
-ErrExit:
- // An error occurred.
- return hr;
-} // HRESULT CImportTlb::CompareSigsIgnoringRetType()
-
-//*****************************************************************************
-// Look up a method in the emit scope. This lookup method does not take the
-// return type into account when comparing using a sig. So 2 methods with
-// the same name, same parameters and a different return type will be
-// considered the same.
-//*****************************************************************************
-HRESULT CImportTlb::FindMethod( // S_OK or CLDB_E_RECORD_NOTFOUND, or error.
- mdTypeDef td, // The method typedef.
- LPCWSTR szName, // The method name.
- PCCOR_SIGNATURE pbReqSig, // The method signature.
- ULONG cbReqSig, // Size of the method signature.
- mdMethodDef *pmb) // Put the method here.
-{
- HRESULT hr = S_OK; // A result.
- PCCOR_SIGNATURE pbFoundSig = NULL;
- ULONG cbFoundSig = 0;
- ULONG MethodAttr;
- ULONG MethodImplFlags;
- mdMethodDef md;
- CQuickArray<WCHAR> qbMethodName;
- HCORENUM MethodEnum = NULL;
- ULONG cMethods = 0;
- ULONG cchName;
- BOOL bMethodFound = FALSE;
-
- // Go through all the methods on the class looking for one with the
- // same name and same parameters.
- while ((hr = m_pImport->EnumMethods(&MethodEnum, td, &md, 1, &cMethods)) == S_OK)
- {
- // Retrieve the method properties.
- do {
- IfFailGo(m_pImport->GetMethodProps(
- md,
- NULL,
- qbMethodName.Ptr(),
- (ULONG)qbMethodName.MaxSize(),
- &cchName,
- &MethodAttr,
- &pbFoundSig,
- &cbFoundSig,
- NULL,
- &MethodImplFlags));
- if (hr == CLDB_S_TRUNCATION)
- {
- IfFailGo(qbMethodName.ReSizeNoThrow(cchName));
- continue;
- }
- break;
- } while (1);
-
- // Compare the name of the method.
- if (wcscmp(szName, qbMethodName.Ptr()) != 0)
- continue;
-
- // If the signature of the requested method is specified, then compare
- // the signature against the signature of the found method ignoring
- // the return type.
- if (pbReqSig)
- {
- IfFailGo(hr = CompareSigsIgnoringRetType(pbReqSig, cbReqSig, pbFoundSig, cbFoundSig));
- if (hr == S_FALSE)
- continue;
- }
-
- // We have found the member.
- bMethodFound = TRUE;
- break;
- }
- IfFailGo(hr);
-
-ErrExit:
- if (MethodEnum)
- m_pImport->CloseEnum(MethodEnum);
-
- return bMethodFound ? S_OK : CLDB_E_RECORD_NOTFOUND;
-}
-
-//*****************************************************************************
-// Look up a property in the emit scope.
-//*****************************************************************************
-HRESULT CImportTlb::FindProperty( // S_OK or CLDB_E_RECORD_NOTFOUND, or error.
- mdTypeDef td, // The property typedef.
- LPCWSTR szName, // The property name.
- PCCOR_SIGNATURE pbSig, // The property signature.
- ULONG cbSig, // Size of the property signature.
- mdProperty *ppr) // Put the property here.
-{
- HRESULT hr; // A result.
- RegMeta *pRegMeta = (RegMeta*)(m_pEmit);
- LPUTF8 szNameAnsi;
-
- if (szName == NULL)
- {
- return CLDB_E_RECORD_NOTFOUND;
- }
- UTF8STR(szName, szNameAnsi);
-
- hr = ImportHelper::FindProperty(
- &(pRegMeta->GetMiniStgdb()->m_MiniMd),
- m_tdTypeDef,
- szNameAnsi,
- pbSig,
- cbSig,
- ppr);
- return hr;
-} // HRESULT CImportTlb::FindProperty()
-
-//*****************************************************************************
-// Look up a event in the emit scope.
-//*****************************************************************************
-HRESULT CImportTlb::FindEvent( // S_OK or CLDB_E_RECORD_NOTFOUND, or error.
- mdTypeDef td, // The event typedef.
- LPCWSTR szName, // The event name.
- mdEvent *pev) // Put the event here.
-{
- HRESULT hr; // A result.
- RegMeta *pRegMeta = (RegMeta*)(m_pEmit);
- LPUTF8 szNameAnsi;
-
- if (szName == NULL)
- {
- return CLDB_E_RECORD_NOTFOUND;
- }
- UTF8STR(szName, szNameAnsi);
-
- hr = ImportHelper::FindEvent(
- &(pRegMeta->GetMiniStgdb()->m_MiniMd),
- m_tdTypeDef,
- szNameAnsi,
- pev);
- return hr;
-} // HRESULT CImportTlb::FindEvent()
-
-//*****************************************************************************
-// Checks to see if the specified TYPEDESC is an alias.
-//*****************************************************************************
-HRESULT CImportTlb::_IsAlias(
- ITypeInfo *pITI, // The ITypeInfo containing the TYPEDESC.
- TYPEDESC *pTypeDesc) // The token of the param, field, etc.
-{
- HRESULT hr = S_FALSE; // A result.
- ITypeInfo *pTypeITI=0; // The ITypeInfo of the type.
- ITypeLib *pTypeTLB=0; // The TLB that contains the type.
- TYPEATTR *psTypeAttr=0; // TYPEATTR of the type.
-
- // Drill down to the actual type that is pointed to.
- while (pTypeDesc->vt == VT_PTR)
- pTypeDesc = pTypeDesc->lptdesc;
-
- // If the parameter is an alias then we need to add a custom attribute to the
- // parameter that describes the alias.
- if (pTypeDesc->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pTypeDesc->hreftype, &pTypeITI));
- IfFailGo(pTypeITI->GetTypeAttr(&psTypeAttr));
- if (psTypeAttr->typekind == TKIND_ALIAS)
- {
- hr = S_OK;
- }
- }
-
-ErrExit:
- if (psTypeAttr)
- pTypeITI->ReleaseTypeAttr(psTypeAttr);
- if (pTypeITI)
- pTypeITI->Release();
- return hr;
-} // HRESULT CImportTlb::_IsAlias()
-
-//*****************************************************************************
-// Add alias information if the TYPEDESC represents an alias.
-//*****************************************************************************
-HRESULT CImportTlb::_HandleAliasInfo(
- ITypeInfo *pITI, // The ITypeInfo containing the TYPEDESC.
- TYPEDESC *pTypeDesc, // The TYPEDESC.
- mdToken tk) // The token of the param, field, etc.
-{
- HRESULT hr = S_OK; // A result.
- ITypeInfo *pTypeITI=0; // The ITypeInfo of the type.
- ITypeLib *pTypeTLB=0; // The TLB that contains the type.
- TYPEATTR *psTypeAttr=0; // TYPEATTR of the type.
- BSTR bstrAliasTypeName=0; // The name of the alias type.
- BSTR bstrAliasTypeLibName=0; // The name of the typelib that contains the alias type.
-
- // Drill down to the actual type that is pointed to.
- while (pTypeDesc->vt == VT_PTR)
- pTypeDesc = pTypeDesc->lptdesc;
-
- // If the parameter is an alias then we need to add a custom attribute to the
- // parameter that describes the alias.
- if (pTypeDesc->vt == VT_USERDEFINED)
- {
- IfFailGo(pITI->GetRefTypeInfo(pTypeDesc->hreftype, &pTypeITI));
- IfFailGo(pTypeITI->GetTypeAttr(&psTypeAttr));
- if (psTypeAttr->typekind == TKIND_ALIAS)
- {
- // Retrieve the name of the alias type.
- IfFailGo(pTypeITI->GetContainingTypeLib(&pTypeTLB, NULL));
- IfFailGo(GetNamespaceOfRefTlb(pTypeTLB, &bstrAliasTypeLibName, NULL));
- IfFailGo(GetManagedNameForTypeInfo(pTypeITI, bstrAliasTypeLibName, NULL, &bstrAliasTypeName));
-
- // Add the ComAliasName CA to the parameter.
- _AddStringCa(ATTR_COMALIASNAME, tk, bstrAliasTypeName);
- }
- }
-
-ErrExit:
- if (psTypeAttr)
- pTypeITI->ReleaseTypeAttr(psTypeAttr);
- if (pTypeITI)
- pTypeITI->Release();
- if (pTypeTLB)
- pTypeTLB->Release();
- if (bstrAliasTypeLibName)
- ::SysFreeString(bstrAliasTypeLibName);
- if (bstrAliasTypeName)
- ::SysFreeString(bstrAliasTypeName);
- return hr;
-} // HRESULT CImportTlb::_HandleAliasInfo()
-
-//*****************************************************************************
-// Convert one of a function's parameters.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvParam(
- ITypeInfo *pITI, // Containing TypeInfo.
- mdMethodDef mdFunc, // Owning member.
- int iSequence, // Parameter sequence.
- const ELEMDESC *pdesc, // Param flags, default value.
- ParamOpts paramOpts, // Is param normal, optional, or vararg?
- LPCWSTR szName, // Name of the parameter.
- BYTE *pbNative, // Native type info, if any.
- ULONG cbNative) // Size of native type info.
-{
- HRESULT hr; // A result.
- mdParamDef pdParam; // Token of the parameter.
- DWORD dwFlags; // Param flags.
- USHORT Sequence = static_cast<USHORT>(iSequence);
- BYTE cvType = ELEMENT_TYPE_VOID; // ELEMENT_TYPE_* flag for constant value
- void *pcvValue=0; // constant value blob
- __int64 d; // For cases where value is a date.
- int bDecimal=0; // If true, constant is a decimal.
- mdToken tkAttr; // For custom attribute token.
- DECIMAL decVal; // Decimal constant value.
-
- // Compute the flags. Only make sense on non-return params.
- dwFlags = 0;
- if (iSequence > 0)
- {
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FIN)
- dwFlags |= pdIn;
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FOUT)
- dwFlags |= pdOut;
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FOPT)
- dwFlags |= pdOptional;
- if (paramOpts == ParamOptional)
- dwFlags |= pdOptional;
- }
-
- // Get any default values. Return type, param with iSequence==0, has no default.
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT && iSequence != 0)
- {
- switch (pdesc->paramdesc.pparamdescex->varDefaultValue.vt)
- {
- case VT_CY:
- case VT_DECIMAL:
- case VT_DATE:
- case VT_UNKNOWN:
- case VT_DISPATCH:
- break;
- default:
- // This workaround is because a typelib can store anything that can convert to VT_I4 with a value of 0
- // for the default value of an interface pointer. But, a VT_I2(0) confuses the consumers
- // of the managed wrapper dll. So, if it is an interface on the unmanaged side, make
- // the constant value an ET_CLASS.
- if (cbNative > 0 && (*pbNative == NATIVE_TYPE_INTF ||
- *pbNative == NATIVE_TYPE_IUNKNOWN ||
- *pbNative == NATIVE_TYPE_IDISPATCH))
- {
- cvType = ELEMENT_TYPE_CLASS;
- pcvValue = 0;
- }
- else
- IfFailGo( _UnpackVariantToConstantBlob(&pdesc->paramdesc.pparamdescex->varDefaultValue, &cvType, &pcvValue, &d) );
- }
- }
-
- // Create the param definition.
- IfFailGo(m_pEmit->DefineParam(mdFunc, iSequence, szName, dwFlags, cvType, pcvValue, -1, &pdParam));
-
- // Add the native type if it there is any.
- if (cbNative > 0)
- IfFailGo(m_pEmit->SetFieldMarshal(pdParam, (PCCOR_SIGNATURE) pbNative, cbNative));
-
- if (pdesc->paramdesc.wParamFlags & PARAMFLAG_FHASDEFAULT && iSequence != 0)
- {
- switch (pdesc->paramdesc.pparamdescex->varDefaultValue.vt)
- {
- case VT_CY:
- IfFailGo(VarDecFromCy(pdesc->paramdesc.pparamdescex->varDefaultValue.cyVal, &decVal));
- IfFailGo(DecimalCanonicalize(&decVal));
- goto StoreDecimal;
- case VT_DECIMAL:
- // If there is a decimal constant value, set it as a custom attribute.
- {
- decVal = pdesc->paramdesc.pparamdescex->varDefaultValue.decVal;
- StoreDecimal:
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE)+sizeof(BYTE)+sizeof(UINT)+sizeof(UINT)+sizeof(UINT));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.scale);
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.sign);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Hi32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Mid32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Lo32);
- IfFailGo(GetAttrType(ATTR_DECIMALVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DATE:
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(__int64));
- __int64 date = _DoubleDateToTicks(pdesc->paramdesc.pparamdescex->varDefaultValue.date);
- BUILD_CUSTOM_ATTRIBUTE(__int64, date);
- IfFailGo(GetAttrType(ATTR_DATETIMEVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_UNKNOWN:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IUNKNOWNVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DISPATCH:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IDISPATCHVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- default:
- break;
- }
- }
-
- // Add the alias information if the param is an alias.
- IfFailGo(_HandleAliasInfo(pITI, (TYPEDESC*)&pdesc->tdesc, pdParam));
-
- // If a vararg param, set the custom attribute.
- if (paramOpts == ParamVarArg)
- {
- mdToken tkAttribute;
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(GetAttrType(ATTR_PARAMARRAY, &tkAttribute));
- IfFailGo(m_pEmit->DefineCustomAttribute(pdParam, tkAttribute, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::_ConvParam()
-
-//*****************************************************************************
-// Convert a constant into a field with a default value.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvConstant(
- ITypeInfo *pITI, // Containing TypeInfo.
- VARDESC *psVar, // VARDESC for the property.
- BOOL bEnumMember) // If true, type is containing class.
-{
- HRESULT hr; // A result.
- mdFieldDef mdField; // Token of the new field.
- DWORD dwFlags; // Member flags.
- CQuickBytes qbComSig; // The COM+ Signature of the field.
- ULONG cb, cbTotal;
- BYTE cvType = ELEMENT_TYPE_VOID; // E_T_Type for constant value
- void *pcvValue; // Pointer to constant value data.
- mdToken tkAttr; // Type for custom attribute.
- __int64 d; // For cases where value is a date.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- BYTE *pbSig; // Pointer to signature bytes.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG cbNative = 0; // Size of native type.
- int bDecimal = 0; // If the value is a decimal.
- DECIMAL decVal; // Decimal constant value.
-
- // Information about the member.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // resize to make room for calling convention and count of argument
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 4));
- pbSig = (BYTE *)qbComSig.Ptr();
-
- // Compute properties.
- dwFlags = DEFAULT_CONST_FIELD_FLAGS;
-
- // Build the signature.
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_FIELD, pbSig);
- if (bEnumMember)
- {
- cb = CorSigCompressData(ELEMENT_TYPE_VALUETYPE, &pbSig[cbTotal]);
- cbTotal += cb;
- cb = CorSigCompressToken(m_tdTypeDef, reinterpret_cast<ULONG*>(&pbSig[cbTotal]));
- cbTotal += cb;
- }
- else
- {
- // Use the conversion function to get the signature.
- ULONG cbSave = cbTotal;
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_FLAGS_NONE, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &cbNative, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- if (psVar->elemdescVar.tdesc.vt == VT_DATE)
- {
- // But for dates, convert it as float -- DateTime is reported as R4 in a typelib!
- cbTotal = cbSave;
- cb = CorSigCompressData(ELEMENT_TYPE_R4, &pbSig[cbTotal]);
- cbTotal += cb;
- }
- }
-
- // Get the default value.
- switch (psVar->lpvarValue->vt)
- {
- case VT_CY:
- case VT_DECIMAL:
- case VT_DATE:
- case VT_UNKNOWN:
- case VT_DISPATCH:
- break;
- default:
- // This workaround is because a typelib can store anything that can convert to VT_I4 with a value of 0
- // for the default value of an interface pointer. But, a VT_I2(0) confuses the consumers
- // of the managed wrapper dll. So, if it is an interface on the unmanaged side, make
- // the constant value an ET_CLASS.
- BYTE *pbNative = NULL;
- pbNative = qbNativeBuf.Ptr();
- if (cbNative > 0 && (*pbNative == NATIVE_TYPE_INTF ||
- *pbNative == NATIVE_TYPE_IUNKNOWN ||
- *pbNative == NATIVE_TYPE_IDISPATCH))
- {
- cvType = ELEMENT_TYPE_CLASS;
- pcvValue = 0;
- }
- else
- IfFailGo( _UnpackVariantToConstantBlob(psVar->lpvarValue, &cvType, &pcvValue, &d) );
- }
-
- // Create the field definition.
- IfFailGo(m_pEmit->DefineField(m_tdTypeDef, m_szMember, dwFlags, (PCCOR_SIGNATURE)pbSig, cbTotal,
- cvType, pcvValue, -1, &mdField));
-
- switch (psVar->lpvarValue->vt)
- {
- case VT_CY:
- IfFailGo(VarDecFromCy(psVar->lpvarValue->cyVal, &decVal));
- IfFailGo(DecimalCanonicalize(&decVal));
- goto StoreDecimal;
- case VT_DECIMAL:
- // If there is a decimal constant value, set it as a custom attribute.
- {
- decVal = psVar->lpvarValue->decVal;
- StoreDecimal:
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE)+sizeof(BYTE)+sizeof(UINT)+sizeof(UINT)+sizeof(UINT));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.scale);
- BUILD_CUSTOM_ATTRIBUTE(BYTE, decVal.sign);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Hi32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Mid32);
- BUILD_CUSTOM_ATTRIBUTE(UINT, decVal.Lo32);
- IfFailGo(GetAttrType(ATTR_DECIMALVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DATE:
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(__int64));
- __int64 date = _DoubleDateToTicks(psVar->lpvarValue->date);
- BUILD_CUSTOM_ATTRIBUTE(__int64, date);
- IfFailGo(GetAttrType(ATTR_DATETIMEVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_UNKNOWN:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IUNKNOWNVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- case VT_DISPATCH:
- {
- DECLARE_CUSTOM_ATTRIBUTE(0);
- IfFailGo(GetAttrType(ATTR_IDISPATCHVALUE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
- break;
- default:
- break;
- }
-
- // Save the field flags.
- if (psVar->wVarFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBVAR, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, psVar->wVarFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(mdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- // Set up the native description, if any.
- if (cbNative > 0)
- IfFailGo(m_pEmit->SetFieldMarshal(mdField, (PCCOR_SIGNATURE) qbNativeBuf.Ptr(), cbNative));
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, mdField));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_FIELD, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvConstant()
-
-//*****************************************************************************
-// Convert a (record) field into a member.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvField(
- ITypeInfo *pITI, // Containing TypeInfo.
- VARDESC *psVar, // VARDESC for the property.
- mdFieldDef *pmdField, // Put field token here.
- BOOL bUnion) // Convert as a union?
-{
- HRESULT hr; // A result.
- DWORD dwFlags; // Member flags.
- CQuickBytes qbComSig; // The COM+ Signature of the field.
- ULONG cb, cbTotal; // Size of a sig element, signature.
- BYTE *pbSig; // Pointer to signature bytes.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG cbNative; // Size of native type.
- mdToken tkAttr; // CustomAttribute type.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
-
- // Information about the member.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // Compute properties.
- dwFlags = DEFAULT_RECORD_FIELD_FLAGS;
-
- // resize to make room for calling convention and count of argument
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2));
- pbSig = (BYTE *)qbComSig.Ptr();
-
- // Build the signature.
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_FIELD, pbSig);
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_FIELD, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &cbNative, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Create the field definition.
- IfFailGo(m_pEmit->DefineField(m_tdTypeDef, m_szMember, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal,
- ELEMENT_TYPE_VOID, NULL, -1, pmdField));
-
- // Save the field flags.
- if (psVar->wVarFlags)
- {
- IfFailGo(GetAttrType(ATTR_TYPELIBVAR, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(WORD));
- BUILD_CUSTOM_ATTRIBUTE(WORD, psVar->wVarFlags);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(*pmdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- if (bConversionLoss)
- {
- IfFailGo(GetAttrType(ATTR_COMCONVERSIONLOSS, &tkAttr));
- DECLARE_CUSTOM_ATTRIBUTE(0);
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(*pmdField, tkAttr, PTROF_CUSTOM_ATTRIBUTE(),SIZEOF_CUSTOM_ATTRIBUTE(),0));
- }
-
- // Set up the native description, if any.
- if (cbNative > 0)
- IfFailGo(m_pEmit->SetFieldMarshal(*pmdField, (PCCOR_SIGNATURE) qbNativeBuf.Ptr(), cbNative));
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, *pmdField));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_FIELD, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvField()
-
-//*****************************************************************************
-// Convert a dispatch property into a pair of get/set functions.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvProperty(
- ITypeInfo *pITI, // Containing TypeInfo.
- MemberInfo *pMember) // VARDESC for the property.
-{
- HRESULT hr; // A result.
- mdMethodDef mdFuncGet; // A get function.
- mdMethodDef mdFuncSet; // A set function.
- mdProperty pdProperty; // Property on the two functions.
- DWORD dwFlags; // Function flags.
- WCHAR *pszName=0; // Decorated name of member.
- CQuickArray<WCHAR> qbName; // Buffer for decorated name.
- CQuickBytes qbComSig; // com signature buffer
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Total size of signature.
- BYTE *pbSig; // Pointer to signature buffer.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
- VARDESC *psVar = pMember->m_psVar;
-
- // Check to see if the property is the NewEnum member.
- if (PropertyIsNewEnum(pITI, psVar, pMember->m_iMember) == S_OK)
- return _ConvNewEnumProperty(pITI, psVar, pMember);
-
- // Get the name.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // Create the get signature.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2));
- pbSig = reinterpret_cast<BYTE*>(qbComSig.Ptr());
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- // Getter takes zero parameters.
- cb = CorSigCompressData(0, &(pbSig[cb]));
- cbTotal += cb;
- // Getter returns the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Getter properties.
- dwFlags = DEFAULT_PROPERTY_FUNC_FLAGS;
- // If processing an implemented interface, remove the abstract bit. Methods on classes are not abstract.
- if (m_ImplIface != eImplIfaceNone)
- dwFlags &= ~mdAbstract;
-
- // Get the previously decorated name. Add interface name and make unique.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(pMember->m_pName)+2));
- wcscpy_s(qbName.Ptr(), wcslen(pMember->m_pName)+2, pMember->m_pName);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtMethodDef));
- pszName = qbName.Ptr();
-
- // Create the get Accessor.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, pszName, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(), cbTotal,
- 0/*RVA*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdFuncGet));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the Dispid CA.
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, mdFuncGet, TRUE, NULL, FALSE);
- }
-
- // If processing an implemented interface, set up MethodImpls.
- if (m_ImplIface != eImplIfaceNone)
- {
- // Define a memberref on the implemented interface.
- mdToken mrItfMember;
- IfFailGo(m_pEmit->DefineMemberRef(m_tkInterface, pMember->m_pName, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, &mrItfMember));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdFuncGet, mrItfMember));
- }
-
- // If not a read-only var, create the setter.
- if ((psVar->wVarFlags & VARFLAG_FREADONLY) == 0)
- {
- // Create the setter signature.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 3));
- pbSig = reinterpret_cast<BYTE*>(qbComSig.Ptr());
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
- // Setter takes one parameter.
- cb = CorSigCompressData(1, &(pbSig[cb]));
- cbTotal += cb;
- // Setter returns nothing.
- cb = CorSigCompressData(ELEMENT_TYPE_VOID, &pbSig[cbTotal]);
- cbTotal += cb;
- // Setter takes the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Setter properties.
- dwFlags = DEFAULT_PROPERTY_FUNC_FLAGS;
- // If processing an implemented interface, remove the abstract bit. Methods on classes are not abstract.
- if (m_ImplIface != eImplIfaceNone)
- dwFlags &= ~mdAbstract;
-
- // Get the previously decorated name. Add interface name and make unique.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(pMember->m_pName2)+2));
- wcscpy_s(qbName.Ptr(), wcslen(pMember->m_pName2)+2, pMember->m_pName2);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtMethodDef));
- pszName = qbName.Ptr();
-
- // Create the setter Accessor.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, pszName, dwFlags, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal,
- 0/*RVA*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdFuncSet));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the Dispid CA.
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, mdFuncSet, TRUE, NULL, FALSE);
- }
-
- // If processing an implemented interface, set up MethodImpls.
- if (m_ImplIface != eImplIfaceNone)
- {
- // Define a memberref on the implemented interface.
- mdToken mrItfMember;
- IfFailGo(m_pEmit->DefineMemberRef(m_tkInterface, pMember->m_pName2, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, &mrItfMember));
-
- // Define a method impl.
- IfFailGo(m_pEmit->DefineMethodImpl(m_tdTypeDef, mdFuncSet, mrItfMember));
- }
- }
- else
- { // read-only, setter method is nil.
- mdFuncSet = mdMethodDefNil;
- }
-
- // Create the property signature: 'type', or <fieldcallconv><type>
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_PROPERTY, pbSig);
- cb = CorSigCompressData(0, &(pbSig[cb]));
- cbTotal += cb;
- // Property is just the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, FALSE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Get the property name. Add interface name and make unique, if needed.
- // m_szInterface should be non-null if processing an implemented interface; should be null otherwise.
- _ASSERTE(m_ImplIface == eImplIfaceNone || m_szInterface != 0);
- IfFailGo(qbName.ReSizeNoThrow(wcslen(m_szMember)+2));
- wcscpy_s(qbName.Ptr(), wcslen(m_szMember)+2, m_szMember);
- IfFailGo(GenerateUniqueMemberName(qbName, (PCCOR_SIGNATURE)qbComSig.Ptr(), cbTotal, m_szInterface, mdtProperty));
- pszName = qbName.Ptr();
-
- // Set up the Property on the two methods.
- IfFailGo(m_pEmit->DefineProperty(m_tdTypeDef, pszName, 0/*dwFlags*/, (PCCOR_SIGNATURE) qbComSig.Ptr(),cbTotal, ELEMENT_TYPE_VOID, NULL/*default*/, -1,
- mdFuncSet, mdFuncGet, NULL, &pdProperty));
-
- // Handle dispids for non-implemented interfaces, and for default interface
- if (m_ImplIface != eImplIface)
- {
- // Set the Dispid CA on the property.
- long lDispSet = 1;
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, pdProperty, TRUE, &lDispSet, FALSE);
-
- // If this property is default property, add a custom attribute to the class.
- if (lDispSet == DISPID_VALUE)
- IfFailGo(_AddDefaultMemberCa(m_tdTypeDef, m_szMember));
- }
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, pdProperty));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_ARGS, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvProperty()
-
-//*****************************************************************************
-// Convert the NewEnum dispatch property into the GetEnumerator method.
-//*****************************************************************************
-HRESULT CImportTlb::_ConvNewEnumProperty(
- ITypeInfo *pITI, // Containing TypeInfo.
- VARDESC *psVar, // VARDESC for the property.
- MemberInfo *pMember)
-{
- HRESULT hr; // A result.
- mdMethodDef mdGetEnum; // The GetEnumerator method.
- CQuickBytes qbComSig; // com signature buffer
- ULONG cb; // Size of an element.
- ULONG cbTotal = 0; // Total size of signature.
- BYTE *pbSig; // Pointer to signature buffer.
- BOOL bConversionLoss=false; // If true, some attributes were lost on conversion.
- CQuickArray<BYTE> qbNativeBuf; // Native type buffer.
- ULONG iNativeOfs=0; // Current offset in native type buffer.
-
- // Get the name.
- IfFailGo(pITI->GetDocumentation(psVar->memid, &m_szMember, 0,0,0));
-
- // Create the GetEnumerator signature.
- IfFailGo(qbComSig.ReSizeNoThrow(CB_MAX_ELEMENT_TYPE * 2));
- pbSig = reinterpret_cast<BYTE*>(qbComSig.Ptr());
- cbTotal = cb = CorSigCompressData((ULONG)IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS, pbSig);
-
- // GetEnumerator takes zero parameters.
- cb = CorSigCompressData(0, &(pbSig[cb]));
- cbTotal += cb;
-
- // Getter returns the property type.
- IfFailGo(_ConvSignature(pITI, &psVar->elemdescVar.tdesc, SIG_ELEM, qbComSig, cbTotal, &cbTotal, qbNativeBuf, 0, &iNativeOfs, TRUE));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
-
- // Create the GetEnumerator method.
- IfFailGo(m_pEmit->DefineMethod(m_tdTypeDef, GET_ENUMERATOR_MEMBER_NAME, DEFAULT_INTERFACE_FUNC_FLAGS, (PCCOR_SIGNATURE) qbComSig.Ptr(), cbTotal,
- 0/*RVA*/, DEFAULT_ITF_FUNC_IMPL_FLAGS, &mdGetEnum));
-
- // Set the Dispid CA.
- _SetDispIDCA(pITI, pMember->m_iMember, psVar->memid, mdGetEnum, TRUE, NULL, FALSE);
-
- // Add the alias information if the type is an alias.
- IfFailGo(_HandleAliasInfo(pITI, &psVar->elemdescVar.tdesc, mdGetEnum));
-
- if (bConversionLoss)
- {
- hr = S_CONVERSION_LOSS;
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_I_UNCONVERTABLE_ARGS, m_szName, m_szMember);
- }
-
-ErrExit:
- if (m_szMember)
- ::SysFreeString(m_szMember), m_szMember=0;
- return (hr);
-} // HRESULT CImportTlb::_ConvNewEnumProperty()
-
-//*****************************************************************************
-// Given an ITypeLib*, come up with a namespace name. Use the typelib name
-// unless there is one specified via custom attribute.
-//
-// NOTE: This returns the member variable m_wzNamespace if the typelib
-// is the importing typelib. That must not be freed!
-//*****************************************************************************
-HRESULT CImportTlb::GetNamespaceOfRefTlb(
- ITypeLib *pITLB, // TypeLib for which to get namespace name.
- BSTR *pwzNamespace, // Put the name here.
- CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap) // Put def itf to class itf map here.
-{
- mdAssemblyRef arDummy;
- BSTR wzAsmName = NULL;
- HRESULT hr = S_OK;
-
- // If already resolved, just return assembly ref.
- if (!m_LibRefs.Find(pITLB, &arDummy, pwzNamespace, &wzAsmName, NULL, ppDefItfToClassItfMap))
- {
- // Add a reference to the typelib.
- IfFailGo(_AddTlbRef(pITLB, &arDummy, pwzNamespace, &wzAsmName, ppDefItfToClassItfMap));
- }
-
-ErrExit:
- if (wzAsmName)
- ::SysFreeString(wzAsmName);
-
- return hr;
-} // HRESULT CImportTlb::GetNamespaceOfRefTlb()
-
-//*****************************************************************************
-// Given a TYPEDESC, resolve the USERDEFINED to the TYPEKIND.
-//*****************************************************************************
-HRESULT CImportTlb::_ResolveTypeDescAliasTypeKind(
- ITypeInfo *pITIAlias, // The typeinfo containing the typedesc.
- TYPEDESC *ptdesc, // The typedesc.
- TYPEKIND *ptkind) // Put the aliased typekind.
-{
- HRESULT hr; // A result.
- ITypeInfo *pTIResolved=0; // The resolved ITypeInfo.
- TYPEATTR *psResolved=0; // The resolved TypeInfo's TYPEATTR
-
- if (ptdesc->vt != VT_USERDEFINED)
- {
- *ptkind = TKIND_MAX;
- return S_FALSE;
- }
-
- hr = _ResolveTypeDescAlias(pITIAlias, ptdesc, &pTIResolved, &psResolved);
- if (hr == S_OK)
- *ptkind = psResolved->typekind;
- else
- *ptkind = TKIND_MAX;
-
- if (psResolved)
- pTIResolved->ReleaseTypeAttr(psResolved);
- if (pTIResolved)
- pTIResolved->Release();
-
- return hr;
-} // HRESULT CImportTlb::_ResolveTypeDescAliasTypeKind()
-
-//*****************************************************************************
-// Given a TYPEDESC in a TypeInfo, eliminate aliases (get to the aliased
-// type).
-//*****************************************************************************
-HRESULT CImportTlb::_ResolveTypeDescAlias(
- ITypeInfo *pITIAlias, // The typeinfo containing the typedesc.
- const TYPEDESC *ptdesc, // The typedesc.
- ITypeInfo **ppTIResolved, // Put the aliased ITypeInfo here.
- TYPEATTR **ppsAttrResolved, // Put the ITypeInfo's TYPEATTR here.
- GUID *pGuid) // Caller may want aliased object's guid.
-{
- HRESULT hr; // A result.
- ITypeInfo *pITI=0; // Referenced typeinfo.
- TYPEATTR *psAttr=0; // TYPEATTR of referenced typeinfo.
-
- // If the TDESC isn't a USERDEFINED, it is already resolved.
- if (ptdesc->vt != VT_USERDEFINED)
- {
- *ppTIResolved = pITIAlias;
- pITIAlias->AddRef();
- // Need to addref the [out] psAttr. Only way to do it:
- IfFailGo(pITIAlias->GetTypeAttr(ppsAttrResolved));
- hr = S_FALSE;
- goto ErrExit;
- }
-
- // The TYPEDESC is a USERDEFINED. Get the TypeInfo.
- IfFailGo(pITIAlias->GetRefTypeInfo(ptdesc->hreftype, &pITI));
- IfFailGo(pITI->GetTypeAttr(&psAttr));
-
- // If the caller needs the aliased object's guid, get it now.
- if (pGuid && *pGuid == GUID_NULL && psAttr->guid != GUID_NULL)
- *pGuid = psAttr->guid;
-
- // If the userdefined typeinfo is not itself an alias, then it is what the alias aliases.
- // Also, if the userdefined typeinfo is an alias to a builtin type, then the builtin
- // type is what the alias aliases.
- if (psAttr->typekind != TKIND_ALIAS || psAttr->tdescAlias.vt != VT_USERDEFINED)
- {
- *ppsAttrResolved = psAttr;
- *ppTIResolved = pITI;
- if (psAttr->typekind == TKIND_ALIAS)
- hr = S_FALSE;
- psAttr = 0;
- pITI = 0;
- goto ErrExit;
- }
-
- // The userdefined type was itself an alias to a userdefined type. Alias to what?
- hr = _ResolveTypeDescAlias(pITI, &psAttr->tdescAlias, ppTIResolved, ppsAttrResolved, pGuid);
-
-ErrExit:
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
- if (pITI)
- pITI->Release();
- return hr;
-} // HRESULT CImportTlb::_ResolveTypeDescAlias()
-
-//*****************************************************************************
-// Create the TypeInfo records (AKA classes, AKA critters).
-//*****************************************************************************
-HRESULT CImportTlb::GetKnownTypeToken(
- VARTYPE vt, // The type for which the token is desired.
- mdTypeRef *ptr) // Put the token here.
-{
- HRESULT hr = S_OK; // A result.
-
- _ASSERTE(
- (vt >= VT_CY && vt <= VT_DECIMAL) || (vt == VT_SAFEARRAY) || (vt == VT_SLOT_FOR_GUID) ||
- (vt == VT_SLOT_FOR_IENUMERABLE) || (vt == VT_SLOT_FOR_MULTICASTDEL) || (vt == VT_SLOT_FOR_TYPE) ||
- (vt == VT_SLOT_FOR_STRINGBUF));
-
- // If it has already been added, just return it.
- if (m_tkKnownTypes[vt])
- {
- *ptr = m_tkKnownTypes[vt];
- goto ErrExit;
- }
-
- // Not yet created, so create the typeref now.
- switch (vt)
- {
- //=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
- // WARNING: the VT_EMPTY slot is used for System.GUID!!
- case VT_SLOT_FOR_GUID:
- _ASSERTE(VT_SLOT_FOR_GUID == VT_EMPTY);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_GUID, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_GUID])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_NULL slot is used for System.Collections.IEnumerable!!
- case VT_SLOT_FOR_IENUMERABLE:
- _ASSERTE(VT_SLOT_FOR_IENUMERABLE == VT_NULL);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_IENUMERABLE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_IENUMERABLE])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_I2 slot is used for System.MulticastDelegate!!
- case VT_SLOT_FOR_MULTICASTDEL:
- _ASSERTE(VT_SLOT_FOR_MULTICASTDEL == VT_I2);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_MULTICASTDELEGATE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_MULTICASTDEL])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_I4 slot is used for System.Type!!
- case VT_SLOT_FOR_TYPE:
- _ASSERTE(VT_SLOT_FOR_TYPE == VT_I4);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_TYPE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_TYPE])); // Put mdTypeRef here
- break;
-
- // WARNING: the VT_I8 slot is used for System.Text.StringBuilder!!
- case VT_SLOT_FOR_STRINGBUF:
- _ASSERTE(VT_SLOT_FOR_STRINGBUF == VT_I8);
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_STRINGBUFFER, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SLOT_FOR_STRINGBUF])); // Put mdTypeRef here
- break;
-
- case VT_CY:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_DECIMAL, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_CY])); // Put mdTypeRef here
- break;
-
- case VT_DATE:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_DATE, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_DATE])); // Put mdTypeRef here
- break;
-
- case VT_DECIMAL:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_DECIMAL, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_DECIMAL])); // Put mdTypeRef here
- break;
-
- case VT_SAFEARRAY:
- IfFailGo(m_TRMap.DefineTypeRef(
- m_pEmit, // The emit scope.
- m_arSystem, // The system assemblyref.
- TLB_CLASSLIB_ARRAY, // URL of the TypeDef, wide chars.
- &m_tkKnownTypes[VT_SAFEARRAY])); // Put mdTypeRef here
- break;
-
- default:
- _ASSERTE(!"Unknown type in GetKnownTypes");
- IfFailGo(E_INVALIDARG);
- }
-
- _ASSERTE(!IsNilToken(m_tkKnownTypes[vt]));
- *ptr = m_tkKnownTypes[vt];
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::GetKnownTypeToken()
-
-
-//*****************************************************************************
-// Given an ITypeInfo for a coclass, return an ITypeInfo for the default
-// interface. This is either the explicitly marked default, or the first
-// non-source interface.
-//*****************************************************************************
-HRESULT CImportTlb::GetDefaultInterface( // Error, S_OK or S_FALSE.
- ITypeInfo *pCoClassTI, // The TypeInfo of the coclass.
- ITypeInfo **pDefaultItfTI) // The returned default interface.
-{
- HRESULT hr; // A result
- HREFTYPE href; // HREFTYPE of an implemented interface.
- INT ImplFlags; // ImplType flags.
- ITypeInfo *pITI=NULL; // ITypeInfo for an interface.
- TYPEATTR *pCoClassTypeAttr; // The type attributes of the coclass.
- int NumInterfaces; // The number of interfaces on the coclass.
- int i; // A counter.
-
- // Initialize the default interface to NULL.
- *pDefaultItfTI = NULL;
-
- // Retrieve the number of interfaces the coclass has
- IfFailGo(pCoClassTI->GetTypeAttr(&pCoClassTypeAttr));
- NumInterfaces = pCoClassTypeAttr->cImplTypes;
- pCoClassTI->ReleaseTypeAttr(pCoClassTypeAttr);
-
- for (i=0; i < NumInterfaces; i++)
- {
- IfFailGo(pCoClassTI->GetImplTypeFlags(i, &ImplFlags));
-
- if ((ImplFlags & (IMPLTYPEFLAG_FSOURCE | IMPLTYPEFLAG_FDEFAULT)) == IMPLTYPEFLAG_FDEFAULT)
- {
- // We have found a default interface.
- if (*pDefaultItfTI)
- (*pDefaultItfTI)->Release();
-
- IfFailGo(pCoClassTI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pCoClassTI->GetRefTypeInfo(href, pDefaultItfTI));
- break;
- }
- else if (!(ImplFlags & IMPLTYPEFLAG_FSOURCE) && !(*pDefaultItfTI))
- {
- // If this is the first normal interface we encounter then we need to
- // hang on to it in case we don't find any default interfaces. If that
- // happens then this is the one that will be returned.
- IfFailGo(pCoClassTI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pCoClassTI->GetRefTypeInfo(href, pDefaultItfTI));
- }
- }
-
- // Return either S_OK or S_FALSE depending on if we have found a default interface.
- if (*pDefaultItfTI)
- return S_OK;
- else
- return S_FALSE;
-
-ErrExit:
- if (pITI)
- pITI->Release();
-
- return hr;
-} // HRESULT CImportTlb::GetDefaultInterface()
-
-//*****************************************************************************
-// Given a TypeInfo, return a TypeDef/TypeRef token.
-//*****************************************************************************
-HRESULT CImportTlb::_GetTokenForTypeInfo(
- ITypeInfo *pITI, // ITypeInfo for which to get token.
- BOOL bConvDefItfToClassItf, // If TRUE, convert the def itf to its class itf.
- mdToken *pToken, // Put the token here.
- __out_ecount (chTypeRef) __out_opt LPWSTR pszTypeRef, // Optional, put the name here.
- int chTypeRef, // Size of the name buffer in characters.
- int *pchTypeRef, // Optional, put size of name here.
- BOOL bAsmQualifiedName) // Assembly qualified name or not?
-{
- HRESULT hr; // A result.
- ITypeLib *pITLB=0; // Containing typelib.
- BSTR bstrNamespace=0; // Namespace of the type.
- BSTR bstrFullName=0; // Fully qualified name of type.
- BSTR bstrTempName=0; // Temp name.
- BSTR bstrAsmName=0; // Assembly name.
- LPCWSTR strTypeName=0; // The type name.
- mdAssemblyRef ar; // The typelib's assembly ref.
- TYPEATTR* psAttr = 0; // The TYPEATTR for the type info.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // The default interface to class interface map.
-
- // Get the library.
- IfFailGo(pITI->GetContainingTypeLib(&pITLB, 0));
-
- // Resolve the external reference.
- IfFailGo(_AddTlbRef(pITLB, &ar, &bstrNamespace, &bstrAsmName, &pDefItfToClassItfMap));
-
- // If are converting default interfaces to class interfaces, then check
- // to see if we need to do the convertion for the current ITypeInfo.
- if (bConvDefItfToClassItf)
- {
- // Retrieve the TYPEATTR.
- IfFailGo(pITI->GetTypeAttr(&psAttr));
-
- // If we are dealing with an interface, then check to see if there
- // is a class interface we should use.
- if (psAttr->typekind == TKIND_INTERFACE || psAttr->typekind == TKIND_DISPATCH)
- {
- strTypeName = pDefItfToClassItfMap->GetClassItfName(psAttr->guid);
- }
- }
-
- // If we haven't found a class interface, then use the current interface.
- if (!strTypeName)
- {
- // Get the name of the typeinfo.
- IfFailGo(GetManagedNameForTypeInfo(pITI, bstrNamespace, NULL, &bstrFullName));
- strTypeName = bstrFullName;
- }
-
- // Give name back to caller, if desired.
- if (pszTypeRef)
- wcsncpy_s(pszTypeRef, chTypeRef, strTypeName, chTypeRef-1);
- if (pchTypeRef)
- *pchTypeRef = (int)(wcslen(pszTypeRef) + 1);
-
- // Define the TypeRef (will return any existing typeref).
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, ar, strTypeName, pToken));
-
- // If the caller desires an assembly qualified name, then provide it.
- if (bAsmQualifiedName)
- {
- int cchAsmQualifiedName = SysStringLen(bstrFullName) + SysStringLen(bstrAsmName) + 2;
- IfNullGo(bstrTempName = ::SysAllocStringLen(0, cchAsmQualifiedName));
- ns::MakeAssemblyQualifiedName(bstrTempName, cchAsmQualifiedName + 1, bstrFullName, SysStringLen(bstrFullName), bstrAsmName, SysStringLen(bstrAsmName));
- SysFreeString(bstrFullName);
- bstrFullName = bstrTempName;
- }
-
- // Give name back to caller, if desired.
- if (pszTypeRef)
- wcsncpy_s(pszTypeRef, chTypeRef, bstrFullName, chTypeRef-1);
- if (pchTypeRef)
- *pchTypeRef = (int)(wcslen(pszTypeRef) + 1);
-
-ErrExit:
- if (bstrNamespace)
- ::SysFreeString(bstrNamespace);
- if (bstrFullName)
- ::SysFreeString(bstrFullName);
- if (bstrAsmName)
- ::SysFreeString(bstrAsmName);
- if (pITLB)
- pITLB->Release();
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
-
- return (hr);
-} // HRESULT CImportTlb::_GetTokenForTypeInfo()
-
-//*****************************************************************************
-// Given a TypeInfo for a source interface, creates a new event interface
-// if none exists or returns an existing one.
-//*****************************************************************************
-HRESULT CImportTlb::_GetTokenForEventItf(ITypeInfo *pSrcItfITI, mdTypeRef *ptr)
-{
-#ifndef DACCESS_COMPILE
- HRESULT hr = S_OK; // A result.
- ImpTlbEventInfo* pEventInfo; // The event information.
- BSTR bstrSrcItfName = NULL; // The name of the CoClass.
- CQuickArray<WCHAR> qbEventItfName; // The name of the event interface.
- CQuickArray<WCHAR> qbEventProviderName; // The name of the event provider.
- mdToken tkAttr; // Custom attribute type.
- BSTR szOldName = NULL; // The old value m_tdTypeDef.
- mdTypeDef tdOldTypeDef = NULL; // The old value m_szName.
- TYPEATTR* psAttr = 0; // The TYPEATTR for the source interface.
- mdTypeRef trEventItf; // A type ref to the event interface.
- ITypeLib* pTypeTLB; // The typelib containing this interface.
- mdAssemblyRef ar; // Dummy AssmRef.
- BSTR wzNamespace=0; // Namespace of the event interface assembly.
- BSTR wzAsmName=0; // Assembly name of the event interface assembly.
- Assembly* SrcItfAssembly=0; // The Source Event Interface assembly.
- CQuickArray<WCHAR> qbSrcItfName; // The name of the source interface.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // The default interface to class interface map.
- BOOL fInheritsIEnum = FALSE;
-
- // Retrieve the namespace of the typelib containing this source interface.
- IfFailGo(pSrcItfITI->GetContainingTypeLib(&pTypeTLB, NULL));
-
- // Resolve the external reference.
- IfFailGo(_AddTlbRef(pTypeTLB, &ar, &wzNamespace, &wzAsmName, &pDefItfToClassItfMap));
-
- // Get the assembly + namespace the source interface resides in.
- // May return all NULL - indicating the importing assembly.
- m_LibRefs.Find(pTypeTLB, &ar, &wzNamespace, &wzAsmName, &SrcItfAssembly, NULL);
- if (SrcItfAssembly == NULL)
- SrcItfAssembly = m_pAssembly;
-
- // Retrieve the full name of the source interface.
- if (wzNamespace)
- IfFailGo(GetManagedNameForTypeInfo(pSrcItfITI, (WCHAR*)wzNamespace, NULL, &bstrSrcItfName));
- else
- IfFailGo(GetManagedNameForTypeInfo(pSrcItfITI, m_wzNamespace, NULL, &bstrSrcItfName));
-
- // Start by looking up the event information for the source itf type info.
- pEventInfo = m_EventInfoMap.FindEventInfo(bstrSrcItfName);
- if (pEventInfo)
- {
- SysFreeString(bstrSrcItfName);
- *ptr = pEventInfo->trEventItf;
- return S_OK;
- }
-
- // Store the old values of the ITypeInfo name and of the current type def.
- szOldName = m_szName;
- tdOldTypeDef = m_tdTypeDef;
- m_szName = NULL;
-
- // Get some information about the TypeInfo.
- IfFailGo(pSrcItfITI->GetDocumentation(MEMBERID_NIL, &m_szName, 0, 0, 0));
- IfFailGo(pSrcItfITI->GetTypeAttr(&psAttr));
-
- if (ExplicitlyImplementsIEnumerable(pSrcItfITI, psAttr) == S_OK)
- fInheritsIEnum = TRUE;
-
- // Generate a unique name for the event interface which will be of the form:
- // <ImportingAssemblyNamespace>.<SrcItfName>_Event<PotentialSuffix>
-
- // Strip the namespace
- IfFailGo(qbSrcItfName.ReSizeNoThrow(wcslen(bstrSrcItfName) + 2));
- ns::SplitPath((WCHAR*)bstrSrcItfName, NULL, 0, qbSrcItfName.Ptr(), (int)wcslen(bstrSrcItfName) + 1);
-
- // Add the namespace of the importing typelib and the event suffix
- IfFailGo(qbEventItfName.ReSizeNoThrow(qbSrcItfName.Size() + wcslen(m_wzNamespace) + EVENT_ITF_SUFFIX_LENGTH + 7));
- StringCchPrintf(qbEventItfName.Ptr(), qbEventItfName.Size(), W("%s.%s%s"), m_wzNamespace, qbSrcItfName.Ptr(), EVENT_ITF_SUFFIX);
- IfFailGo(GenerateUniqueTypeName(qbEventItfName));
-
- // Generate a unique name for the event provider which will be of the form:
- // <ImportingAssemblyNamespace>.<SrcItfName>_EventProvider<PotentialSuffix>
-
- // Add the namespace of the imporing typelib and the event suffix
- IfFailGo(qbEventProviderName.ReSizeNoThrow(qbSrcItfName.Size() + wcslen(m_wzNamespace) + EVENT_PROVIDER_SUFFIX_LENGTH + 7));
- StringCchPrintf(qbEventProviderName.Ptr(), qbEventProviderName.Size(), W("%s.%s%s"), m_wzNamespace, qbSrcItfName.Ptr(), EVENT_PROVIDER_SUFFIX);
- IfFailGo(GenerateUniqueTypeName(qbEventProviderName));
-
- // Add the event provider as a reserved name.
- m_ReservedNames.AddReservedName(qbEventProviderName.Ptr());
-
- // Create the typedef for the event interface.
- IfFailGo(m_pEmit->DefineTypeDef(qbEventItfName.Ptr(), tdPublic | tdInterface | tdAbstract, mdTypeDefNil, NULL, &m_tdTypeDef));
-
- // Hide the event interface from the VB object browser (_Event)
- _SetHiddenCA(m_tdTypeDef);
-
- // Make the interface ComVisible(false).
- {
- DECLARE_CUSTOM_ATTRIBUTE(sizeof(BYTE));
- BUILD_CUSTOM_ATTRIBUTE(BYTE, FALSE);
- IfFailGo(GetAttrType(ATTR_COMVISIBLE, &tkAttr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Set the ComEventInterface CA on the interface.
- {
- CQuickBytes asmQualifiedSrcItfName;
- if (!ns::MakeAssemblyQualifiedName(asmQualifiedSrcItfName, bstrSrcItfName, wzAsmName))
- IfFailGo(E_OUTOFMEMORY);
- DECLARE_DYNLEN_CUSTOM_ATTRIBUTE(wcslen((WCHAR*)asmQualifiedSrcItfName.Ptr()) + 5 + wcslen(qbEventProviderName.Ptr()) + 5);
- APPEND_WIDE_STRING_TO_CUSTOM_ATTRIBUTE((WCHAR*)asmQualifiedSrcItfName.Ptr());
- APPEND_WIDE_STRING_TO_CUSTOM_ATTRIBUTE(qbEventProviderName.Ptr());
- IfFailGo(GetAttrType(ATTR_COMEVENTINTERFACE, &tkAttr));
- FINISH_DYNLEN_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(m_tdTypeDef, tkAttr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
- }
-
- // Add the add_XXX and remove_XXX methods to the event interface.
- IfFailGo(_ConvSrcIfaceMembers(pSrcItfITI, psAttr, fInheritsIEnum));
-
- // Define a typeref for the event interface.
- IfFailGo(m_pEmit->DefineTypeRefByName(TokenFromRid(1, mdtModule), qbEventItfName.Ptr(), &trEventItf));
-
- // Add the event info to the map.
- IfFailGo(m_EventInfoMap.AddEventInfo(bstrSrcItfName, trEventItf, qbEventItfName.Ptr(), qbEventProviderName.Ptr(), SrcItfAssembly));
-
- // Set the out type ref.
- *ptr = trEventItf;
-
-ErrExit:
- if (bstrSrcItfName)
- ::SysFreeString(bstrSrcItfName);
- if (m_szName)
- ::SysFreeString(m_szName);
- if (psAttr)
- pSrcItfITI->ReleaseTypeAttr(psAttr);
- if (pTypeTLB)
- pTypeTLB->Release();
-
- // Restore the initial values for the ITypeInfo name and the type def.
- m_szName = szOldName;
- m_tdTypeDef = tdOldTypeDef;
-
- return (hr);
-#else
- DacNotImpl();
- return E_NOTIMPL;
-#endif // #ifndef DACCESS_COMPILE
-} // HRESULT CImportTlb::_GetTokenForEventItf()
-
-//*****************************************************************************
-// Creates an interface with the same name as the class and which implements
-// the default interface and the default event interface.
-//*****************************************************************************
-HRESULT CImportTlb::_CreateClassInterface(ITypeInfo *pCoClassITI, ITypeInfo *pDefItfITI, mdTypeRef trDefItf, mdTypeRef rtDefEvItf, mdToken *ptr)
-{
- HRESULT hr = S_OK; // A result.
- CQuickArray<mdToken> rImpls; // Array of implemented interfaces.
- int ixImpl = -1; // Index into rImpls for implemented interface.
- mdTypeDef tdTypeDef; // The class interface typedef.
- BSTR bstrFullName = NULL; // The name of the CoClass.
- TYPEATTR *psAttrIface=0; // TYPEATTR for an interface.
- CQuickArray<WCHAR> qbClassName; // The name of the class.
-
- IfFailGo(rImpls.ReSizeNoThrow(3));
- memset(rImpls.Ptr(), 0, 3 * sizeof(mdToken));
- if (trDefItf)
- rImpls[++ixImpl] = trDefItf;
- if (rtDefEvItf)
- rImpls[++ixImpl] = rtDefEvItf;
-
- // Retrieve the TypeAttr for the interface.
- if (pDefItfITI)
- IfFailGo(pDefItfITI->GetTypeAttr(&psAttrIface));
-
- // Retrieve the name of the CoClass (use the original name if this is an alias).
- IfFailGo(GetManagedNameForTypeInfo(m_pOrigITI, m_wzNamespace, NULL, &bstrFullName));
-
- // Create the typedef.
- IfFailGo(m_pEmit->DefineTypeDef(bstrFullName, rdwTypeFlags[TKIND_INTERFACE], mdTypeDefNil, 0, &tdTypeDef));
-
- // Set the IID to the IID of the default interface.
- IfFailGo(_AddGuidCa(tdTypeDef, psAttrIface ? psAttrIface->guid : GUID_NULL));
-
- // Add the CoClass CA to the interface.
- _AddStringCa(ATTR_COCLASS, tdTypeDef, m_szMngName);
-
- // Add the implemented interfaces and event interfaces to the TypeDef.
- IfFailGo(m_pEmit->SetTypeDefProps(tdTypeDef, ULONG_MAX/*Classflags*/,
- ULONG_MAX, (mdToken*)rImpls.Ptr()));
-
- // Set the out type def.
- *ptr = tdTypeDef;
-
-ErrExit:
- if (bstrFullName)
- ::SysFreeString(bstrFullName);
- if (psAttrIface)
- pDefItfITI->ReleaseTypeAttr(psAttrIface);
-
- return (hr);
-} // HRESULT CImportTlb::_CreateClassInterface()
-
-//*****************************************************************************
-// Creates an interface with the same name as the class and which implements
-// the default interface and the default event interface.
-//*****************************************************************************
-HRESULT CImportTlb::GetManagedNameForCoClass(ITypeInfo *pITI, CQuickArray<WCHAR> &qbClassName)
-{
- HRESULT hr = S_OK; // A result.
- BSTR bstrFullName=0; // Fully qualified name of type.
-
- // Retrieve the name of the CoClass.
- IfFailGo(GetManagedNameForTypeInfo(pITI, m_wzNamespace, NULL, &bstrFullName));
-
- // Resize the class name to accomodate the Class and potential suffix.
- IfFailGo(qbClassName.ReSizeNoThrow(wcslen(bstrFullName) + CLASS_SUFFIX_LENGTH + 6));
-
- // Set the class name to the CoClass name suffixed with Class.
- StringCchPrintf(qbClassName.Ptr(), qbClassName.Size(), W("%s%s"), bstrFullName, CLASS_SUFFIX);
-
- // Generate a unique name for the class.
- IfFailGo(GenerateUniqueTypeName(qbClassName));
-
-ErrExit:
- if (bstrFullName)
- ::SysFreeString(bstrFullName);
-
- return (hr);
-} // HRESULT CImportTlb::GetManagedNameForCoClass()
-
-//*****************************************************************************
-// Creates an interface with the same name as the class and which implements
-// the default interface and the default event interface.
-//*****************************************************************************
-HRESULT CImportTlb::GenerateUniqueTypeName(CQuickArray<WCHAR> &qbTypeName)
-{
- HRESULT hr = S_OK; // A result.
- WCHAR *pSuffix=0; // Location for suffix.
- size_t cchSuffix;
- WCHAR *pName=0; // The name without the namespace.
- int iSuffix=2; // Starting value for suffix.
- mdToken td; // For looking up a TypeDef.
- BSTR szTypeInfoName=0; // Name of a typeinfo.
- ITypeInfo *pITI=0; // A typeinfo.
-
- // Resize the class name to accomodate the Class and potential suffix.
- IfFailGo(qbTypeName.ReSizeNoThrow(wcslen(qbTypeName.Ptr()) + 6));
-
- // Set the suffix pointer.
- pSuffix = qbTypeName.Ptr() + wcslen(qbTypeName.Ptr());
- cchSuffix = qbTypeName.Size() - wcslen(qbTypeName.Ptr());
-
- // Set the name pointer.
- WCHAR* pTemp = ns::FindSep(qbTypeName.Ptr());
- if (pTemp == NULL)
- pName = qbTypeName.Ptr();
- else
- pName = pTemp + 1;
-
- // Attempt to find a class name that is not in use.
- for (;;)
- {
- // First check to see if the type name is in use in the metadata we
- // have emitted so far.
- hr = m_pImport->FindTypeDefByName(qbTypeName.Ptr(), mdTypeDefNil, &td);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- // It is not in use in the metadata but we still need to check the
- // typelib because the type might not have been emitted yet.
- USHORT cReq = 4;
- USHORT cFound = cReq;
- BOOL bTypeInTlb = FALSE;
- CQuickArray<ITypeInfo *> qbTI;
- CQuickArray<MEMBERID> qbMemId;
-
- // Retrieve all the instances of the name in the typelib.
- do
- {
- // Double the number of requested names.
- cReq *= 2;
-
- // Resize the array's to accomodate the resquested names.
- IfFailGo(qbTI.ReSizeNoThrow(cReq));
- IfFailGo(qbMemId.ReSizeNoThrow(cReq));
-
- // Request the names.
- cFound = cReq;
- IfFailGo(m_pITLB->FindName(pName, 0, qbTI.Ptr(), qbMemId.Ptr(), &cFound));
-
- // Release all the ITypeInfo's.
- for (int i = 0; i < cFound; i++)
- qbTI[i]->Release();
- }
- while (cReq == cFound);
-
- // Check to see if one of the instances of the name is for a type.
- for (int i = 0; i < cFound; i++)
- {
- if (qbMemId[i] == MEMBERID_NIL)
- {
- bTypeInTlb = TRUE;
- break;
- }
- }
-
- // If the type name exists in the typelib, but we didn't find it as a type,
- // we still need to do a deeper check, due to how FindName() works.
- if (!bTypeInTlb && cFound > 0)
- {
- int cTi; // Count of TypeInfos.
- int i; // Loop control.
-
- //@todo: this iterates over every typeinfo every time! We could cache
- // the names, and skip the types already converted. However, this should
- // be pretty rare.
-
- // How many TypeInfos?
- IfFailGo(cTi = m_pITLB->GetTypeInfoCount());
-
- // Iterate over them.
- for (i=0; i<cTi; ++i)
- {
- // Get the TypeInfo, and its name.
- IfFailGo(m_pITLB->GetTypeInfo(i, &pITI));
- IfFailGo(pITI->GetDocumentation(MEMBERID_NIL, &szTypeInfoName, 0, 0, 0));
- if (wcscmp(pName, szTypeInfoName) == 0)
- {
- bTypeInTlb = TRUE;
- break;
- }
-
- // Release for next TypeInfo.
- ::SysFreeString(szTypeInfoName);
- szTypeInfoName = 0;
- pITI->Release();
- pITI = 0;
- }
- }
-
- // The type name is not in the typelib and not in the metadata then we still
- // need to check to see if is a reserved name.
- if (!bTypeInTlb)
- {
- if (!m_ReservedNames.IsReservedName(qbTypeName.Ptr()))
- {
- // The name is not a reserved name so we can use it.
- break;
- }
- }
- }
- IfFailGo(hr);
-
- // Append the new suffix to the class name.
- StringCchPrintf(pSuffix, cchSuffix, W("_%i"), iSuffix++);
- }
-
-ErrExit:
- if (szTypeInfoName)
- ::SysFreeString(szTypeInfoName);
- if (pITI)
- pITI->Release();
- return (hr);
-} // HRESULT CImportTlb::GenerateUniqueTypeName()
-
-//*****************************************************************************
-// Generate a unique member name based on the interface member name.
-//*****************************************************************************
-HRESULT CImportTlb::GenerateUniqueMemberName(// S_OK or error
- CQuickArray<WCHAR> &qbMemberName, // Original name of member.
- PCCOR_SIGNATURE pSig, // Signature of the member.
- ULONG cSig, // Length of the signature.
- LPCWSTR szPrefix, // Possible prefix for decoration.
- mdToken type) // Is it a property? (Not a method?)
-{
- HRESULT hr; // A result.
- mdToken tkMember; // Dummy location for token.
- WCHAR *pSuffix=0; // Location for suffix.
- size_t cchSuffix = 0;
- int iSuffix=2; // Starting value for suffix.
-
- // Try to find a member name that is not already in use.
- for (;;)
- { // See if this is (finally) a unique member or property.
- switch (type)
- {
- case mdtProperty:
- hr = FindProperty(m_tdTypeDef, qbMemberName.Ptr(), 0, 0, &tkMember);
- // If name is OK as property, check that there is no method or
- // property with the name.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindMethod(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindEvent(m_tdTypeDef, qbMemberName.Ptr(), &tkMember);
- break;
- case mdtMethodDef:
- hr = FindMethod(m_tdTypeDef, qbMemberName.Ptr(), pSig, cSig, &tkMember);
- // If name is OK as method, check that there is no property or
- // event with the name.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindProperty(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindEvent(m_tdTypeDef, qbMemberName.Ptr(), &tkMember);
- break;
- case mdtEvent:
- hr = FindEvent(m_tdTypeDef, qbMemberName.Ptr(), &tkMember);
- // If name is OK as event, check that there is no property or
- // method with the name.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindProperty(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- if (hr == CLDB_E_RECORD_NOTFOUND)
- hr = FindMethod(m_tdTypeDef, qbMemberName.Ptr(), 0,0, &tkMember);
- break;
- default:
- // Unexpected type. Make noise, but let it pass.
- _ASSERTE(!"Unexpected token type in GenerateUniqueMemberName");
- hr = CLDB_E_RECORD_NOTFOUND;
- }
-
- // If name was not found, it is unique.
- if (hr == CLDB_E_RECORD_NOTFOUND)
- {
- hr = S_OK;
- goto ErrExit;
- }
- // Test for failure.
- IfFailGo(hr);
-
- // Make a test decoration.
- if (szPrefix)
- {
- size_t iLenPrefix, iLenName;
- iLenPrefix = wcslen(szPrefix);
- iLenName = wcslen(qbMemberName.Ptr());
- IfFailGo(qbMemberName.ReSizeNoThrow(iLenName + iLenPrefix + 2));
- // Shift by prefix length, plus '_'. Note use of overlap-safe move.
- memmove(&qbMemberName[iLenPrefix+1], &qbMemberName[0], (iLenName+1)*sizeof(WCHAR));
- wcscpy_s(qbMemberName.Ptr(), iLenPrefix + 1, szPrefix);
- qbMemberName[iLenPrefix] = W('_');
- szPrefix = 0;
- // Try again with prefix before trying a suffix.
- continue;
- }
- if (!pSuffix)
- {
- IfFailGo(qbMemberName.ReSizeNoThrow(wcslen(qbMemberName.Ptr()) + 6));
- pSuffix = qbMemberName.Ptr() + wcslen(qbMemberName.Ptr());
- cchSuffix = qbMemberName.Size() - wcslen(qbMemberName.Ptr());
- }
- StringCchPrintf(pSuffix, cchSuffix, W("_%i"), iSuffix++);
- }
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::GenerateUniqueMemberName()
-
-//*****************************************************************************
-// Convert a TYPEDESC to a COM+ signature.
-//
-// Conversion rules:
-// integral types are converted as-is.
-// strings to strings, with native type decoration.
-// VT_UNKNOWN, VT_DISPATCH as ref class (ie, Object)
-// VT_PTR -> VT_USERDEFINED interface as Object
-// VT_USERDEFINED record as value type.
-//
-// With SIG_FUNC:
-// PTR to valuetype depends on other flags:
-// [IN] or [RETVAL] valuetype + NATIVE_TYPE_LPSTRUCT
-// [OUT] or [IN, OUT] byref valuetype
-// PTR to integral type:
-// [IN] @todo: see atti
-// [OUT] [IN, OUT] byref type
-// [RETVAL] type
-// PTR to object
-// [IN] @todo: see atti
-// [OUT] [IN, OUT] byref object
-// [RETVAL] object
-//
-// With SIG_FIELD:
-// PTR to integral type adds ELEMENT_TYPE_PTR.
-//
-// Conversion proceeds in three steps.
-// 1) Parse the COM type info. Accumulate VT_PTR and VT_BYREF into a count
-// of indirections. Follow TKIND_ALIAS to determine the ultimate aliased
-// type, and for non-user-defined types, convert that ultimate type.
-// Collect array sizes and udt names. Determine element type and native
-// type.
-// 2) Normalize to COM+ types. Determine if there is conversion loss.
-// 3) Emit the COM+ signature. Recurse to handle array types. Add native
-// type info if there is any.
-//*****************************************************************************
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
-#endif
-HRESULT CImportTlb::_ConvSignature( // S_OK, S_CONVERSION_LOSS, or error.
- ITypeInfo *pITI, // [IN] The typeinfo containing the TYPEDESC.
- const TYPEDESC *pType, // [IN] The TYPEDESC to convert.
- ULONG Flags, // [IN] Flags describing the TYPEDESC.
- CQuickBytes &qbSigBuf, // [IN, OUT] A CQuickBytes containing the signature.
- ULONG cbSig, // [IN] Where to start building the signature.
- ULONG *pcbSig, // [OUT] Where the signature ends (ix of first byte past; where to start next).
- CQuickArray<BYTE> &qbNativeTypeBuf, // [IN, OUT] A CQuickBytes containing the native type.
- ULONG cbNativeType, // [IN] Where to start building the native type.
- ULONG *pcbNativeType, // [OUT] Where the native type ends (ix of first byte past; where to start next).
- BOOL bNewEnumMember, // [IN] A flag indicating if the member is the NewEnum member.
- int iByRef) // [IN] ByRef count of caller (for recursive calls).
-{
- HRESULT hr=S_OK; // A result.
- TYPEDESC tdTemp; // Copy of TYPEDESC, for R/W.
- VARTYPE vt; // The typelib signature element.
- int bByRef=false; // If true, convert first pointer as "ELEMENT_TYPE_BYREF".
- COR_SIGNATURE et=0; // The COM+ signature element.
- mdToken tk=0; // Token from some COM+ signature element.
- ULONG nt=NATIVE_TYPE_NONE; // Native type decoration.
- ITypeInfo *pITIAlias=0; // Typeinfo of the aliased type.
- TYPEATTR *psAttrAlias=0; // TYPEATTR of the aliased typeinfo.
- ITypeInfo *pITIUD=0; // TypeInfo of an aliased UserDefined type.
- ITypeLib *pITLBUD=0; // TypeLib of an aliased UserDefined type.
- BSTR bstrNamespace=0; // Namespace name.
- BSTR bstrName=0; // UserDefined name.
- int bConversionLoss=false; // If true, the conversion was lossy.
- BYTE *pbSig; // Byte pointer for easy pointer math.
- ULONG cb; // Size of a signature element.
- ULONG cElems=0; // Count of elements in an array.
- int i; // Loop control.
- TYPEATTR *psAttr = 0; // The TYPEATTR for the user defined type being converted.
- const StdConvertibleItfInfo *pConvertionInfo = 0; // The standard convertible interface information.
- CQuickArray<BYTE> qbNestedNativeType;// A native type buffer used for array sig convertion.
- ULONG iNestedNativeTypeOfs=0; // A native type offset.
- ULONG nested=NATIVE_TYPE_NONE; // A nested native type.
-
- // VT_ to ELEMENT_TYPE_ translation table.
- struct VtSig
- {
- CorElementType et;
- CorNativeType nt;
- short flags;
- };
-
- // The VARIANT_TYPE to sig mapping table.
- static const VtSig
- _VtInfo[MAX_TLB_VT] =
- {
- // Relies on {0} initializing the entire sub-structure to 0.
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_EMPTY = 0
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_NULL = 1
- {ELEMENT_TYPE_I2, NATIVE_TYPE_NONE, 0}, // VT_I2 = 2
- {ELEMENT_TYPE_I4, NATIVE_TYPE_NONE, 0}, // VT_I4 = 3
- {ELEMENT_TYPE_R4, NATIVE_TYPE_NONE, 0}, // VT_R4 = 4
- {ELEMENT_TYPE_R8, NATIVE_TYPE_NONE, 0}, // VT_R8 = 5
- {ELEMENT_TYPE_VALUETYPE,NATIVE_TYPE_CURRENCY, 0}, // VT_CY = 6
- {ELEMENT_TYPE_VALUETYPE,NATIVE_TYPE_NONE, 0}, // VT_DATE = 7
- {ELEMENT_TYPE_STRING, NATIVE_TYPE_BSTR, 0}, // VT_BSTR = 8
- {ELEMENT_TYPE_OBJECT, NATIVE_TYPE_IDISPATCH, 0}, // VT_DISPATCH = 9
- {ELEMENT_TYPE_I4, NATIVE_TYPE_ERROR, 0}, // VT_ERROR = 10 scode
- {ELEMENT_TYPE_BOOLEAN, NATIVE_TYPE_NONE, 0}, // VT_BOOL = 11
- {ELEMENT_TYPE_OBJECT, NATIVE_TYPE_STRUCT, 0}, // VT_VARIANT = 12
- {ELEMENT_TYPE_OBJECT, NATIVE_TYPE_IUNKNOWN, 0}, // VT_UNKNOWN = 13
- {ELEMENT_TYPE_VALUETYPE,NATIVE_TYPE_NONE, 0}, // VT_DECIMAL = 14
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // = 15
- {ELEMENT_TYPE_I1, NATIVE_TYPE_NONE, 0}, // VT_I1 = 16
- {ELEMENT_TYPE_U1, NATIVE_TYPE_NONE, 0}, // VT_UI1 = 17
- {ELEMENT_TYPE_U2, NATIVE_TYPE_NONE, 0}, // VT_UI2 = 18
- {ELEMENT_TYPE_U4, NATIVE_TYPE_NONE, 0}, // VT_UI4 = 19
- {ELEMENT_TYPE_I8, NATIVE_TYPE_NONE, 0}, // VT_I8 = 20
- {ELEMENT_TYPE_U8, NATIVE_TYPE_NONE, 0}, // VT_UI8 = 21
-
- // it would be nice to convert these as I and U, with NT_I4 and NT_U4, but that doesn't work.
- {ELEMENT_TYPE_I4, NATIVE_TYPE_NONE, 0}, // VT_INT = 22 INT is I4 on win32
- {ELEMENT_TYPE_U4, NATIVE_TYPE_NONE, 0}, // VT_UINT = 23 UINT is UI4 on win32
-
- {ELEMENT_TYPE_VOID, NATIVE_TYPE_NONE, 0}, // VT_VOID = 24
-
- {ELEMENT_TYPE_I4, NATIVE_TYPE_ERROR, 0}, // VT_HRESULT = 25
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_PTR = 26
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_SAFEARRAY = 27
- {ELEMENT_TYPE_SZARRAY, NATIVE_TYPE_FIXEDARRAY, 0}, // VT_CARRAY = 28
- {ELEMENT_TYPE_MAX, NATIVE_TYPE_NONE, 0}, // VT_USERDEFINED = 29
- {ELEMENT_TYPE_STRING, NATIVE_TYPE_LPSTR, 0}, // VT_LPSTR = 30
- {ELEMENT_TYPE_STRING, NATIVE_TYPE_LPWSTR, 0}, // VT_LPWSTR = 31
- };
-
- _ASSERTE(pType && pcbSig && pcbNativeType);
-
- //-------------------------------------------------------------------------
- // Parse COM signature
-
- // Strip off leading VT_PTR and VT_BYREF
- while (pType->vt == VT_PTR)
- pType = pType->lptdesc, ++iByRef;
- if (pType->vt & VT_BYREF)
- {
- tdTemp = *pType;
- tdTemp.vt &= ~VT_BYREF;
- ++iByRef;
- pType = &tdTemp;
- }
-
- // Determine the element type, and possibly the token and/or native type.
- switch (vt=pType->vt)
- {
- case VT_PTR:
- _ASSERTE(!"Should not have VT_PTR here");
- break;
-
- // These are all known types (plus GUID).
- case VT_CY:
- case VT_DATE:
- case VT_DECIMAL:
- IfFailGo(GetKnownTypeToken(vt, &tk));
- et = _VtInfo[vt].et;
- nt = _VtInfo[vt].nt;
- break;
-
- case VT_SAFEARRAY:
- if (m_bSafeArrayAsSystemArray && !IsSigVarArg(Flags))
- {
- IfFailGo(GetKnownTypeToken(vt, &tk));
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_SAFEARRAY;
- }
- else
- {
- IfFailGo(GetKnownTypeToken(vt, &tk));
- et = ELEMENT_TYPE_SZARRAY;
- nt = NATIVE_TYPE_SAFEARRAY;
- }
- break;
-
- case VT_USERDEFINED:
- // Resolve the alias to the ultimate aliased type.
- IfFailGo(_ResolveTypeDescAlias(pITI, pType, &pITIAlias, &psAttrAlias));
-
- // If the aliased type was built-in, convert that built-in type.
- if (psAttrAlias->typekind == TKIND_ALIAS)
- { // Recurse to follow the alias chain.
- _ASSERTE(psAttrAlias->tdescAlias.vt != VT_USERDEFINED);
- hr = _ConvSignature(pITIAlias, &psAttrAlias->tdescAlias, Flags, qbSigBuf, cbSig, pcbSig, qbNativeTypeBuf, cbNativeType, pcbNativeType, bNewEnumMember, iByRef);
- goto ErrExit;
- }
-
- // If the type is a coclass then we need to retrieve the default interface and
- // substitute it for the coclass. Look up on the resolved alias, because it is
- // that class that has a default interface.
- if (psAttrAlias->typekind == TKIND_COCLASS)
- {
- ITypeInfo *pDefaultItf = NULL;
- hr = GetDefaultInterface(pITIAlias, &pDefaultItf);
- if ((hr != S_OK) || !pDefaultItf)
- {
- hr = E_UNEXPECTED;
- goto ErrExit;
- }
-
- pITIUD = pDefaultItf;
- }
- else
- { // USERDEFINED class/interface/record/union/enum. Retrieve the type
- // info for the user defined type. Note: use the TKIND_ALIAS typeinfo
- // itself for this conversion (not the aliased type) to preserve
- // names, lib locations, etc.
- IfFailGo(pITI->GetRefTypeInfo(pType->hreftype, &pITIUD));
- }
-
- // pITIUD points to the typeinfo for which we'll create a signature.
- IfFailGo(pITIUD->GetDocumentation(MEMBERID_NIL, &bstrName, 0,0,0));
- IfFailGo(pITIUD->GetContainingTypeLib(&pITLBUD, 0));
- IfFailGo(pITIUD->GetTypeAttr(&psAttr));
- IfFailGo(GetNamespaceNameForTypeLib(pITLBUD, &bstrNamespace));
-
- // If the "User Defined Type" is GUID in StdOle2, convert to M.R.GUID
- if (SString::_wcsicmp(bstrNamespace, COM_STDOLE2) == 0 && wcscmp(bstrName, COM_GUID) == 0)
- { // Classlib valuetype GUID.
- et = ELEMENT_TYPE_VALUETYPE;
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_GUID, &tk));
- }
- else
- { // Some user defined class. Is it a value class, or a VOS class?
- tk = 0;
- switch (psAttrAlias->typekind)
- {
- case TKIND_RECORD:
- case TKIND_ENUM:
- case TKIND_UNION:
- et = ELEMENT_TYPE_VALUETYPE;
- break;
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- case TKIND_COCLASS:
- // A pointer to a user defined type of interface/dispatch/coclass
- // is a straight COM+ object (the ref is implicit), so eliminate
- // one byref count for those.
- // Somehow, there are typelibs written with ([out, retval] IFoo *pOut);
- if (iByRef <= 0)
- {
- // convert to an int.
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- break;
- }
- else
- {
- --iByRef;
-
- // Check for references to Stdole2.IUnknown or Stdole2.IDispatch.
- if (psAttr->guid == IID_IUnknown)
- {
- vt = VT_UNKNOWN;
- goto IsReallyUnknown;
- }
- else if (psAttr->guid == IID_IDispatch)
- {
- vt = VT_DISPATCH;
- goto IsReallyUnknown;
- }
-
- // Check to see if this user defined type is one of the standard ones
- // we generate custom marshalers for.
- pConvertionInfo = GetConvertionInfoFromNativeIID(psAttr->guid);
- if (pConvertionInfo)
- {
- // Convert the UTF8 string to unicode.
- int MngTypeNameStrLen = (int)(strlen(pConvertionInfo->m_strMngTypeName) + 1);
- WCHAR *strFullyQualifiedMngTypeName = (WCHAR *)_alloca(MngTypeNameStrLen * sizeof(WCHAR));
- int ret = WszMultiByteToWideChar(CP_UTF8, 0, pConvertionInfo->m_strMngTypeName, MngTypeNameStrLen, strFullyQualifiedMngTypeName, MngTypeNameStrLen);
- _ASSERTE(ret != 0);
- if (!ret)
- IfFailGo(HRESULT_FROM_GetLastError());
-
- // Create a TypeRef to the marshaller.
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, strFullyQualifiedMngTypeName, &tk));
-
- // The type is a standard interface that we need to convert.
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_CUSTOMMARSHALER;
- break;
- }
- }
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_INTF;
- break;
- default:
- //case TKIND_MODULE: -- can't pass one of these as a parameter.
- //case TKIND_ALIAS: -- should already be resolved.
- _ASSERTE(!"Unexpected typekind for user defined type");
- et = ELEMENT_TYPE_END;
- } // switch (psAttrAlias->typekind)
- }
- break;
-
- IsReallyUnknown:
- case VT_UNKNOWN:
- case VT_DISPATCH:
- // If the NewEnum member, retrieve the custom marshaler information for IEnumVARIANT.
- if (bNewEnumMember && (pConvertionInfo=GetConvertionInfoFromNativeIID(IID_IEnumVARIANT)))
- {
- // Convert the UTF8 string to unicode.
- int MngTypeNameStrLen = (int)(strlen(pConvertionInfo->m_strMngTypeName) + 1);
- WCHAR *strFullyQualifiedMngTypeName = (WCHAR *)_alloca(MngTypeNameStrLen * sizeof(WCHAR));
- int ret = WszMultiByteToWideChar(CP_UTF8, 0, pConvertionInfo->m_strMngTypeName, MngTypeNameStrLen, strFullyQualifiedMngTypeName, MngTypeNameStrLen);
- _ASSERTE(ret != 0);
- if (!ret)
- IfFailGo(HRESULT_FROM_GetLastError());
-
- // Create a TypeRef to the marshaller.
- IfFailGo(m_TRMap.DefineTypeRef(m_pEmit, m_arSystem, strFullyQualifiedMngTypeName, &tk));
-
- // The type is a standard interface that we need to convert.
- et = ELEMENT_TYPE_CLASS;
- nt = NATIVE_TYPE_CUSTOMMARSHALER;
- }
- else
- {
- et = _VtInfo[vt].et;
- nt = _VtInfo[vt].nt;
- }
- break;
-
- case VT_CARRAY:
- // Determine the count of elements.
- for (cElems=1, i=0; i<pType->lpadesc->cDims; ++i)
- cElems *= pType->lpadesc->rgbounds[i].cElements;
-
- // Set the native type based on weither we are dealing with a field or a method sig.
- if (IsSigField(Flags))
- {
- nt = NATIVE_TYPE_FIXEDARRAY;
- }
- else
- {
- nt = NATIVE_TYPE_ARRAY;
- }
-
- // Set the element type.
- et = _VtInfo[vt].et;
- break;
-
- case VT_BOOL:
- // Special case for VARIANT_BOOL: If a field of a struct or union, convert
- // as ET_I2.
- if (IsSigField(Flags))
- vt = VT_I2;
- // Fall through to default case.
-
- default:
- if (vt > VT_LPWSTR)
- {
- ReportEvent(NOTIF_CONVERTWARNING, TLBX_E_BAD_VT_TYPE, vt, m_szName, m_szMember);
- IfFailGo(PostError(TLBX_E_BAD_VT_TYPE, vt, m_szName, m_szMember));
- }
- _ASSERTE(vt <= VT_LPWSTR && _VtInfo[vt].et != ELEMENT_TYPE_MAX);
-#ifdef _PREFAST_
-#pragma warning(push)
-#pragma warning(disable:26000) // "Disable PREFast/espX warning about buffer overflow"
-#endif
- et = _VtInfo[vt].et;
- nt = _VtInfo[vt].nt;
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
- break;
- } // switch (vt=pType->vt)
-
- //-------------------------------------------------------------------------
- // Normalize to COM+ types.
-
- // At this point the type, flags, and pointer nesting are known. Is this a legal combination?
- // If not, what is the appropriate "simplifing assumption"?
-
- if (et == ELEMENT_TYPE_VOID)
- {
- if (IsSigField(Flags))
- { // A void as a field. No byref.
- iByRef = 0;
- }
- else
- {
- // Param or return type. "void *" -> ET_I, "void **", "void ***",... -> ET_BYREF ET_I
- if (iByRef > 1)
- iByRef = 1;
- else
- if (iByRef == 1)
- iByRef = 0;
- }
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- }
-
- if (et == ELEMENT_TYPE_STRING && iByRef == 0 && !IsSigField(Flags) && IsSigOut(Flags))
- {
- // This is an [out] or [in, out] string parameter without indirections.
- if (vt == VT_BSTR)
- {
- // [in, out] System.String does not make much sense. Managed strings are
- // immutable and we do not have BSTR <-> StringBuilder marshaling support.
- // Convert them to IntPtr.
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- }
- else
- {
- _ASSERTE(vt == VT_LPSTR || vt == VT_LPWSTR);
-
- // [in, out] C-strings and wide strings have a lossless conversion to StringBuilder.
- IfFailGo(GetKnownTypeToken(VT_SLOT_FOR_STRINGBUF, &tk));
- et = ELEMENT_TYPE_CLASS;
-
- // nt already has the right value
- _ASSERTE(nt == (vt == VT_LPSTR ? NATIVE_TYPE_LPSTR : NATIVE_TYPE_LPWSTR));
- }
- }
-
- if (iByRef)
- {
- if (et == ELEMENT_TYPE_VALUETYPE && iByRef >= 2)
- {
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- }
- else
- {
- switch (Flags & SIG_TYPE_MASK)
- {
- case SIG_FIELD:
- // If ptr to valuetype or class type, we can't handle it.
- if (et == ELEMENT_TYPE_END ||
- et == ELEMENT_TYPE_CLASS ||
- et == ELEMENT_TYPE_OBJECT ||
- et == ELEMENT_TYPE_VALUETYPE)
- {
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- }
- break;
- case SIG_FUNC:
- // Pointer to value type?
- if (et == ELEMENT_TYPE_VALUETYPE)
- {
- // For [retval], eat one level of indirection; otherwise turn one into BYREF
- if (IsSigOutRet(Flags))
- { // [out, retval], so reduce one level of indirection.
- --iByRef;
- }
- else
- { // Favor BYREF over NATIVE_TYPE_LPSTRUCT
- if (IsSigUseByref(Flags))
- {
- bByRef = true;
- --iByRef;
- }
- if (iByRef > 0)
- {
- nt = NATIVE_TYPE_LPSTRUCT;
- --iByRef;
- }
- }
- }
- else // Pointer to Object or base type.
- {
- if (IsSigRet(Flags))
- { // [retval] so consume one indirection.
- _ASSERTE(iByRef > 0);
- --iByRef;
- }
- if (iByRef > 0 && IsSigUseByref(Flags))
- {
- bByRef = true;
- --iByRef;
- }
- }
- break;
- case SIG_ELEM:
- // This case comes up when a property type is from a [retval].
- if (IsSigRet(Flags))
- {
- if (iByRef > 0)
- --iByRef;
- }
- break;
- }
- }
- } // if (iByRef)
-
- //-------------------------------------------------------------------------
- // We don't want any ET_PTR, so if there are any byref counts left, bail.
- if (iByRef)
- {
- bConversionLoss = true;
- tk = 0;
- et = ELEMENT_TYPE_I;
- nt = NATIVE_TYPE_NONE;
- iByRef = 0;
- bByRef = false;
- }
-
- //-------------------------------------------------------------------------
- // Build COM+ signature.
-
- // Type has been analyzed, and possibly modified. Emit the COM+ signature.
- _ASSERTE(et != ELEMENT_TYPE_MAX);
- _ASSERTE(et != ELEMENT_TYPE_END);
-
- // If it is a pointer to something, emit that now.
- if (bByRef || iByRef)
- {
- // Size the array to hold the elements.
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE * (iByRef+(bByRef?1:0))));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
-
- // Put in any leading "BYREF"
- if (bByRef)
- {
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
- cb = CorSigCompressData(ELEMENT_TYPE_BYREF, &pbSig[cbSig]);
- cbSig += cb;
- }
-
- // Put in the "PTR"s.
- while (iByRef-- > 0)
- {
- cb = CorSigCompressData(ELEMENT_TYPE_PTR, &pbSig[cbSig]);
- cbSig += cb;
- }
- }
-
- // Emit the type.
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
- cb = CorSigCompressData(et, &pbSig[cbSig]);
- cbSig += cb;
-
- // Add the class type, the array information, etc.
- switch (et)
- {
- case ELEMENT_TYPE_CLASS:
- case ELEMENT_TYPE_VALUETYPE:
- // Size the array to hold the token.
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
-
- // If the token hasn't been resolved yet, do that now.
- if (tk == 0)
- {
- _ASSERTE(pITIUD);
- IfFailGo(_GetTokenForTypeInfo(pITIUD, TRUE, &tk));
- }
- cb = CorSigCompressToken(tk, reinterpret_cast<ULONG*>(&pbSig[cbSig]));
- cbSig += cb;
- break;
-
- case ELEMENT_TYPE_SZARRAY:
- // map to SZARRAY <subtype>
- IfFailGo(qbSigBuf.ReSizeNoThrow(cbSig + CB_MAX_ELEMENT_TYPE));
- pbSig = reinterpret_cast<BYTE*>(qbSigBuf.Ptr());
- // Recurse on the type.
- IfFailGo(_ConvSignature(pITI, &pType->lpadesc->tdescElem, SIG_ELEM, qbSigBuf, cbSig, &cbSig, qbNestedNativeType, 0, &iNestedNativeTypeOfs, bNewEnumMember));
- if (hr == S_CONVERSION_LOSS)
- bConversionLoss = true;
- break;
-
- case VT_DISPATCH:
- case VT_UNKNOWN:
- default:
- _ASSERTE(tk == 0);
- // et, nt assigned above.
- break;
- } // switch (et)
-
- // Do any native type info.
- if (nt != NATIVE_TYPE_NONE)
- {
- if (iNestedNativeTypeOfs > 0)
- CorSigUncompressData(reinterpret_cast<PCCOR_SIGNATURE>(qbNestedNativeType.Ptr()), &nested);
-
- if (nt == NATIVE_TYPE_FIXEDARRAY)
- {
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB * 2 + DWORD_MAX_CB));
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
- cbNativeType += CorSigCompressData(cElems, &qbNativeTypeBuf[cbNativeType]);
- if (nested == NATIVE_TYPE_BSTR || nested == NATIVE_TYPE_LPWSTR || nested == NATIVE_TYPE_LPSTR)
- { // Use the nested type.
- cbNativeType += CorSigCompressData(nested, &qbNativeTypeBuf[cbNativeType]);
- }
- else
- { // Use a default sub type.
- cbNativeType += CorSigCompressData(NATIVE_TYPE_MAX, &qbNativeTypeBuf[cbNativeType]);
- }
- }
- else if (nt == NATIVE_TYPE_ARRAY)
- {
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB * 2 + DWORD_MAX_CB * 2));
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
- if (nested == NATIVE_TYPE_BSTR || nested == NATIVE_TYPE_LPWSTR || nested == NATIVE_TYPE_LPSTR)
- { // Use the nested type.
- cbNativeType += CorSigCompressData(nested, &qbNativeTypeBuf[cbNativeType]);
- }
- else
- { // Use a default sub type.
- cbNativeType += CorSigCompressData(NATIVE_TYPE_MAX, &qbNativeTypeBuf[cbNativeType]);
- }
- // Use zero for param index.
- cbNativeType += CorSigCompressData(0, &qbNativeTypeBuf[cbNativeType]);
- // Use count from typelib for elem count.
- cbNativeType += CorSigCompressData(cElems, &qbNativeTypeBuf[cbNativeType]);
- }
- else if (nt == NATIVE_TYPE_SAFEARRAY)
- {
- BOOL bPtrArray = FALSE;
- CQuickArray<WCHAR> rTemp;
- CQuickArray<char> rTypeName;
- LPUTF8 strTypeName = "";
- TYPEDESC *pTypeDesc = &pType->lpadesc->tdescElem;
- VARTYPE ArrayElemVT = pTypeDesc->vt;
-
- if (ArrayElemVT == VT_PTR)
- {
- bPtrArray = TRUE;
- pTypeDesc = pType->lpadesc->tdescElem.lptdesc;
- ArrayElemVT = pTypeDesc->vt;
- if ((ArrayElemVT != VT_USERDEFINED) && (ArrayElemVT != VT_VOID))
- {
- // We do not support deep marshalling pointers.
- ArrayElemVT = VT_INT;
- bConversionLoss = TRUE;
- }
- }
-
- // If we are dealing with a safe array of user defined types and if we
- // are importing safe array's as System.Array then add the SafeArrayUserDefSubType.
- if (ArrayElemVT == VT_USERDEFINED)
- {
- // Resolve the alias to the ultimate aliased type.
- IfFailGo(_ResolveTypeDescAlias(pITI, pTypeDesc, &pITIAlias, &psAttrAlias));
-
- // If the type is a coclass then we need to retrieve the default interface and
- // substitute it for the coclass. Look up on the resolved alias, because it is
- // that class that has a default interface.
- if (psAttrAlias->typekind == TKIND_COCLASS)
- {
- ITypeInfo *pDefaultItf = NULL;
- hr = GetDefaultInterface(pITIAlias, &pDefaultItf);
- if ((hr != S_OK) || !pDefaultItf)
- {
- hr = E_UNEXPECTED;
- goto ErrExit;
- }
-
- pITIUD = pDefaultItf;
- }
- else
- { // USERDEFINED interface/record/union/enum. Retrieve the type
- // info for the user defined type. Note: use the TKIND_ALIAS typeinfo
- // itself for this conversion (not the aliased type) to preserve
- // names, lib locations, etc.
- IfFailGo(pITI->GetRefTypeInfo(pTypeDesc->hreftype, &pITIUD));
- }
-
- // pITIUD points to the typeinfo for which we'll create a signature.
- IfFailGo(pITIUD->GetTypeAttr(&psAttr));
-
- // Get the typeref name for the type.
- for(;;)
- {
- int cchReq;
- mdToken tkDummy;
- IfFailGo(_GetTokenForTypeInfo(pITIUD, TRUE, &tkDummy, rTemp.Ptr(), (int)rTemp.MaxSize(), &cchReq, TRUE));
- if (cchReq <= (int)rTemp.MaxSize())
- break;
- IfFailGo(rTemp.ReSizeNoThrow(cchReq));
- }
-
- // Convert the type name to UTF8.
- ULONG cbReq = WszWideCharToMultiByte(CP_UTF8, 0, rTemp.Ptr(), -1, 0, 0, 0, 0);
- IfFailGo(rTypeName.ReSizeNoThrow(cbReq + 1));
- WszWideCharToMultiByte(CP_UTF8, 0, rTemp.Ptr(), -1, rTypeName.Ptr(), cbReq, 0, 0);
-
- // Determine the safe array element VT.
- switch (psAttrAlias->typekind)
- {
- case TKIND_RECORD:
- case TKIND_ENUM:
- case TKIND_UNION:
- if (bPtrArray)
- {
- ArrayElemVT = VT_INT;
- bConversionLoss = TRUE;
- }
- else
- {
- ArrayElemVT = psAttrAlias->typekind == TKIND_ENUM ? VT_I4 : VT_RECORD;
- strTypeName = rTypeName.Ptr();
- }
- break;
-
- case TKIND_INTERFACE:
- case TKIND_DISPATCH:
- case TKIND_COCLASS:
- if (!bPtrArray)
- {
- ArrayElemVT = VT_INT;
- bConversionLoss = TRUE;
- }
- else
- {
- if (IsIDispatchDerived(pITIUD, psAttr) == S_FALSE)
- ArrayElemVT = VT_UNKNOWN;
- else
- ArrayElemVT = VT_DISPATCH;
- strTypeName = rTypeName.Ptr();
- }
- break;
- }
-
- // If we are not converting the SAFEARRAY to a System.Array, then
- // we don't need to encode the name of the user defined type.
- if (!m_bSafeArrayAsSystemArray)
- strTypeName = "";
- }
-
- // Make sure the native type buffer is large enough.
- ULONG TypeNameStringLen = (ULONG)strlen(strTypeName);
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB * 2 + DWORD_MAX_CB + TypeNameStringLen + STRING_OVERHEAD_MAX_CB));
-
- // Add the native type to the native type info.
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
-
- // Add the VARTYPE of the array.
- cbNativeType += CorSigCompressData(ArrayElemVT, &qbNativeTypeBuf[cbNativeType]);
-
- // Add the type name to the native type info.
- BYTE *pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], TypeNameStringLen);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
- memcpy(&qbNativeTypeBuf[cbNativeType], strTypeName, TypeNameStringLen);
- cbNativeType += TypeNameStringLen;
- }
- else if (nt == NATIVE_TYPE_CUSTOMMARSHALER)
- {
- // Calculate the length of each string and then the total length of the native type info.
- ULONG MarshalerTypeNameStringLen = (ULONG)strlen(pConvertionInfo->m_strCustomMarshalerTypeName);
- ULONG CookieStringLen = (ULONG)strlen(pConvertionInfo->m_strCookie);
- ULONG TotalNativeTypeLen = MarshalerTypeNameStringLen + CookieStringLen;
- BYTE *pNativeType = 0;
-
- // Make sure the native type buffer is large enough.
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB + TotalNativeTypeLen + STRING_OVERHEAD_MAX_CB * 4));
-
- // Add the native type to the native type info.
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
-
- // Add an empty string for the typelib guid.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], 0);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
-
- // Add an empty string for the unmanaged type name.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], 0);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
-
- // Add the name of the custom marshaler to the native type info.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], MarshalerTypeNameStringLen);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
- memcpy(&qbNativeTypeBuf[cbNativeType], pConvertionInfo->m_strCustomMarshalerTypeName, MarshalerTypeNameStringLen);
- cbNativeType += MarshalerTypeNameStringLen;
-
- // Add the cookie to the native type info.
- pNativeType = (BYTE*)CPackedLen::PutLength(&qbNativeTypeBuf[cbNativeType], CookieStringLen);
- cbNativeType += (ULONG)(pNativeType - &qbNativeTypeBuf[cbNativeType]);
- memcpy(&qbNativeTypeBuf[cbNativeType], pConvertionInfo->m_strCookie, CookieStringLen);
- cbNativeType += CookieStringLen;
- }
- else
- {
- IfFailGo(qbNativeTypeBuf.ReSizeNoThrow(cbNativeType + NATIVE_TYPE_MAX_CB + 1));
- cbNativeType += CorSigCompressData(nt, &qbNativeTypeBuf[cbNativeType]);
- }
- }
-
- // Return the size of the native type to the caller.
- *pcbNativeType = cbNativeType;
-
- // Return size to caller.
- *pcbSig = cbSig;
-
- // If there was a conversion loss, change the return code.
- if (bConversionLoss)
- hr = S_CONVERSION_LOSS;
-
-ErrExit:
- if (bstrNamespace)
- ::SysFreeString(bstrNamespace);
- if (bstrName)
- ::SysFreeString(bstrName);
- if(psAttrAlias)
- pITIAlias->ReleaseTypeAttr(psAttrAlias);
- if (pITIAlias)
- pITIAlias->Release();
- if (psAttr)
- pITIUD->ReleaseTypeAttr(psAttr);
- if (pITIUD)
- pITIUD->Release();
- if (pITLBUD)
- pITLBUD->Release();
-
- return hr;
-} // HRESULT CImportTlb::_ConvSignature()
-#ifdef _PREFAST_
-#pragma warning(pop)
-#endif
-
-//*****************************************************************************
-// Build a sorted list of functions to convert. (Sort by vtable offset.)
-//*****************************************************************************
-HRESULT CImportTlb::BuildMemberList(
- ITypeInfo *pITI, // TypeInfo with functions.
- int iStart, // First function to take.
- int iEnd, // Last function to take.
- BOOL bInheritsIEnum) // Inherits from IEnumerable.
-{
- HRESULT hr; // A result.
- int bNeedSort = false; // If true, need to sort the array.
- int ix = 0; // Loop counter.
- int oVftPrev = -1; // To see if oVft is increasing.
- TYPEATTR *psAttr = 0; // TypeAttr for pITI.
- FUNCDESC *psFunc; // A FUNCDESC.
- LPWSTR pszName; // Working pointer for name.
- BSTR bstrName=0; // Name from typelib.
- ITypeInfo2 *pITI2=0; // To get custom attributes.
- VARIANT vt; // Variant type.
- BOOL bFunctionToGetter; // Did a given getter come from a managed function?
-
- ::VariantInit(&vt);
-
- IfFailGo(pITI->GetTypeAttr(&psAttr));
- pITI->QueryInterface(IID_ITypeInfo2, reinterpret_cast<void**>(&pITI2));
-
- // Get the vars.
- IfFailGo(m_MemberList.ReSizeNoThrow(psAttr->cVars + iEnd - iStart));
- memset(m_MemberList.Ptr(), 0, m_MemberList.Size()*sizeof(MemberInfo));
- for (ix=0; ix<psAttr->cVars; ++ix)
- {
- IfFailGo(pITI->GetVarDesc(ix, &(m_MemberList[ix].m_psVar)));
- m_MemberList[ix].m_iMember = ix;
- }
- m_cMemberProps = psAttr->cVars;
-
- // Get the funcs.
- for (; iStart<iEnd; ++iStart, ++ix)
- {
- IfFailGo(TryGetFuncDesc(pITI, iStart, &(m_MemberList[ix].m_psFunc)));
- psFunc = m_MemberList[ix].m_psFunc;
- if (psFunc->oVft < oVftPrev)
- bNeedSort = true;
- oVftPrev = psFunc->oVft;
- m_MemberList[ix].m_iMember = iStart;
- }
-
- if (bNeedSort)
- {
- class Sorter : public CQuickSort<MemberInfo>
- {
- typedef CImportTlb::MemberInfo MemberInfo;
- public:
- Sorter(MemberInfo *p, int n) : CQuickSort<MemberInfo>(p,n) {}
- virtual int Compare(MemberInfo *p1, MemberInfo *p2)
- {
- if (p1->m_psFunc->oVft < p2->m_psFunc->oVft)
- return -1;
- if (p1->m_psFunc->oVft == p2->m_psFunc->oVft)
- return 0;
- return 1;
- }
- };
- Sorter sorter(m_MemberList.Ptr()+m_cMemberProps, (int)m_MemberList.Size()-m_cMemberProps);
- sorter.Sort();
- // Check for duplicates.
- oVftPrev = -1;
- for (ix=m_cMemberProps; ix<(int)m_MemberList.Size(); ++ix)
- {
- if (m_MemberList[ix].m_psFunc->oVft == oVftPrev)
- {
- hr = TLBX_E_BAD_VTABLE;
- break;
- }
- oVftPrev = m_MemberList[ix].m_psFunc->oVft;
- }
- }
-
- // Build the list of unique names.
- m_pMemberNames = new (nothrow) CWCHARPool;
- IfNullGo(m_pMemberNames);
-
- // Property names. No possibility of collisions.
- for (ix=0; ix<m_cMemberProps; ++ix)
- {
- IfFailGo(pITI->GetDocumentation(m_MemberList[ix].m_psVar->memid, &bstrName, 0,0,0));
- IfNullGo(pszName = m_pMemberNames->Alloc((ULONG)wcslen(bstrName)+PROP_DECORATION_LEN+1));
- wcscpy_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, PROP_DECORATION_GET);
- wcscat_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, bstrName);
- m_MemberList[ix].m_pName = pszName;
- if ((m_MemberList[ix].m_psVar->wVarFlags & VARFLAG_FREADONLY) == 0)
- {
- IfNullGo(pszName = m_pMemberNames->Alloc((ULONG)wcslen(bstrName)+PROP_DECORATION_LEN+1));
- wcscpy_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, PROP_DECORATION_SET);
- wcscat_s(pszName, wcslen(bstrName)+PROP_DECORATION_LEN+1, bstrName);
- m_MemberList[ix].m_pName2 = pszName;
- }
- ::SysFreeString(bstrName);
- bstrName = 0;
- }
-
- // Function names. Because of get_/set_ decoration, collisions are possible.
- for (ix=m_cMemberProps; ix<(int)m_MemberList.Size(); ++ix)
- {
- int bNewEnumMember = FALSE;
-
- // Build a name based on invkind.
- psFunc = m_MemberList[ix].m_psFunc;
-
- // Unless we are doing the [out, retval] transformation for disp only interfaces,
- // we need to clear the [retval] flag.
- if (!m_bTransformDispRetVals)
- {
- if (psFunc->funckind == FUNC_DISPATCH)
- { // If [RETVAL] is set, clear it.
- for (int i=0; i<psFunc->cParams; ++i)
- if ((psFunc->lprgelemdescParam[i].paramdesc.wParamFlags & PARAMFLAG_FRETVAL) != 0)
- psFunc->lprgelemdescParam[i].paramdesc.wParamFlags &= ~PARAMFLAG_FRETVAL;
- }
- }
-
- BOOL bExplicitManagedName = FALSE;
- if ( (!bNewEnumMember) && (!bInheritsIEnum) && (FuncIsNewEnum(pITI, psFunc, m_MemberList[ix].m_iMember) == S_OK) )
- {
- // The member is the new enum member so set its name to GetEnumerator.
- IfNullGo(bstrName = SysAllocString(GET_ENUMERATOR_MEMBER_NAME));
- bNewEnumMember = TRUE;
-
- // To prevent additional methods from implementing the NewEnum method, we mark the interface
- bInheritsIEnum = TRUE;
- }
- else
- {
- // If the managed name custom value is set for this member, then use it.
- if (pITI2)
- {
- hr = pITI2->GetFuncCustData(m_MemberList[ix].m_iMember, GUID_ManagedName, &vt);
- if (hr == S_OK && vt.vt == VT_BSTR)
- {
- IfNullGo(bstrName = SysAllocString(vt.bstrVal));
- bExplicitManagedName = TRUE;
- }
- ::VariantClear(&vt);
- }
-
- if (!bstrName)
- IfFailGo(pITI->GetDocumentation(psFunc->memid, &bstrName, 0,0,0));
- }
-
- // If this is a property getter, see if it was originally a function.
- bFunctionToGetter = FALSE;
- if (psFunc->invkind == INVOKE_PROPERTYGET && pITI2)
- {
- hr = pITI2->GetFuncCustData(m_MemberList[ix].m_iMember, GUID_Function2Getter, &vt);
- if (hr == S_OK && vt.vt == VT_I4 && vt.lVal == 1)
- bFunctionToGetter = TRUE;
- ::VariantClear(&vt);
- }
-
-
- // Check for the propget and propset custom attributes if this not already a property.
- if ( (psFunc->invkind & (INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF)) == 0 )
- {
- INVOKEKIND ikind;
- if (S_OK == _CheckForPropertyCustomAttributes(pITI, m_MemberList[ix].m_iMember, &ikind))
- psFunc->invkind = ikind;
- }
-
-
- // If this is a property accessor, but not the 'new enum member', and not
- // originally from a managed function (that was exported as a getter),
- // decorate the name appropriately. If the managed name was set explicitly by
- // the Guid_ManagedName attribute, then don't try an decorate it.
- ULONG nChars = 0;
- if (!bExplicitManagedName && (psFunc->invkind & (INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF) && !bNewEnumMember && !bFunctionToGetter))
- {
- nChars = (ULONG)wcslen(bstrName)+PROP_DECORATION_LEN+1;
- IfNullGo(pszName = m_pMemberNames->Alloc(nChars));
-
- USHORT msSemantics=0; // Property's methodsemantics.
- FUNCDESC *psF; // FUNCDESC of Get, Put, or PutRef.
- TYPEDESC *pProperty; // TYPEDESC of property type.
- BOOL bPropRetval; // Is the property type a [retval]?
- IfFailGo(_GetFunctionPropertyInfo(psFunc, &msSemantics, &psF, &pProperty, &bPropRetval, FALSE, bstrName));
-
- m_MemberList[ix].m_msSemantics = msSemantics;
- switch(msSemantics)
- {
- case msGetter:
- wcscpy_s(pszName, nChars, PROP_DECORATION_GET);
- break;
- case msSetter:
- wcscpy_s(pszName, nChars, PROP_DECORATION_SET);
- break;
- case msOther:
- wcscpy_s(pszName, nChars, PROP_DECORATION_LET);
- break;
- default:
- _ASSERTE(msSemantics == 0);
- *pszName = 0;
- break;
- }
- wcscat_s(pszName, nChars, bstrName);
- }
- else
- {
- nChars = (ULONG)wcslen(bstrName)+1;
- IfNullGo(pszName = m_pMemberNames->Alloc(nChars));
- wcscpy_s(pszName, nChars, bstrName);
- }
-
- // Check for name collision, restore original name if collision occurs.
- for (int index=0; index<ix; index++)
- {
- if ( (m_MemberList[index].m_pName) && (wcscmp(pszName, m_MemberList[index].m_pName) == 0) )
- {
- wcscpy_s(pszName, nChars, bstrName);
- m_MemberList[ix].m_msSemantics = 0;
- }
- }
-
- // Save the unique name.
- m_MemberList[ix].m_pName = pszName;
- ::SysFreeString(bstrName);
- bstrName = 0;
- }
-
-ErrExit:
- if (pITI2)
- pITI2->Release();
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
- if (bstrName)
- ::SysFreeString(bstrName);
- ::VariantClear(&vt);
- return hr;
-} // HRESULT CImportTlb::BuildMemberList()
-
-//*****************************************************************************
-// Free the list built in BuildMemberList().
-//*****************************************************************************
-HRESULT CImportTlb::FreeMemberList(
- ITypeInfo *pITI) // TypeInfo with functions.
-{
- int ix; // Loop control.
- for (ix=0; ix<m_cMemberProps; ++ix)
- pITI->ReleaseVarDesc(m_MemberList[ix].m_psVar);
- m_cMemberProps = 0;
- for (; ix<(int)m_MemberList.Size(); ++ix)
- pITI->ReleaseFuncDesc(m_MemberList[ix].m_psFunc);
- m_MemberList.Shrink(0);
- if (m_pMemberNames)
- {
- delete m_pMemberNames;
- m_pMemberNames = 0;
- }
- return S_OK;
-} // HRESULT CImportTlb::FreeMemberList()
-
-//*****************************************************************************
-// Set a GUID CustomAttribute on an object.
-//*****************************************************************************
-HRESULT CImportTlb::_AddGuidCa( // S_OK or error.
- mdToken tkObj, // Object to be attributed.
- REFGUID guid) // The GUID.
-{
- HRESULT hr; // A result.
- mdMemberRef mr; // MemberRef for GUID CA.
- WCHAR wzGuid[40]; // Buffer for Guid, Unicode.
- CHAR szGuid[40]; // Buffer for Guid, Ansi.
- DECLARE_CUSTOM_ATTRIBUTE(40);
-
- // If GUID_NULL, don't store it.
- if (guid == GUID_NULL)
- return S_OK;
-
- // Get the GUID as a string.
- // ----+----1----+----2----+----3----+----4
- // {12345678-1234-1234-1234-123456789012}
- GuidToLPWSTR(guid, wzGuid, lengthof(wzGuid));
- _ASSERTE(wzGuid[37] == W('}'));
- wzGuid[37] = W('\0');
- WszWideCharToMultiByte(CP_UTF8, 0, wzGuid+1,-1, szGuid,sizeof(szGuid), 0,0);
-
- // Put it in the Custom Attribute.
- APPEND_STRING_TO_CUSTOM_ATTRIBUTE(szGuid);
-
- // Store the attribute
- IfFailGo(GetAttrType(ATTR_GUID, &mr));
- FINISH_CUSTOM_ATTRIBUTE();
- IfFailGo(m_pEmit->DefineCustomAttribute(tkObj, mr, PTROF_CUSTOM_ATTRIBUTE(), SIZEOF_CUSTOM_ATTRIBUTE(), 0));
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::_AddGuidCa()
-
-//*****************************************************************************
-// Add a default member as a custom attribute.
-//*****************************************************************************
-HRESULT CImportTlb::_AddDefaultMemberCa(// S_OK or error.
- mdToken tkObj, // TypeDef with default member.
- LPCWSTR wzName) // Name of the default member.
-{
- // Only set once per typedef.
- if (tkObj == m_tdHasDefault)
- return S_OK;
- m_tdHasDefault = tkObj;
-
- return _AddStringCa(ATTR_DEFAULTMEMBER, tkObj, wzName);
-} // HRESULT CImportTlb::_AddDefaultMemberCa()
-
-//*****************************************************************************
-// Add a string custom attribute of the given type to the token.
-//*****************************************************************************
-HRESULT CImportTlb::_AddStringCa( // S_OK or error.
- int attr, // The type of the CA.
- mdToken tk, // Token to add the CA to.
- LPCWSTR wzString) // String to put in the CA.
-{
- HRESULT hr = S_OK; // A result.
- mdMemberRef mr; // MemberRef for DefaultMember CA.
- BYTE *pca; // Pointer to custom attribute.
- BYTE *ca; // Pointer to custom attribute.
- int wzLen; // Length of wide string.
- int len; // Length of the string.
- CQuickArray<BYTE> buf;
-
- if (wzString == NULL)
- {
- hr = E_INVALIDARG;
- goto ErrExit;
- }
-
- // Prolog, up to 4 bytes length, string, epilog
- wzLen = (int)wcslen(wzString);
- len = WszWideCharToMultiByte(CP_UTF8,0, wzString, wzLen, 0,0, 0,0);
- IfFailGo(buf.ReSizeNoThrow(2 + 4 + len + 2));
- ca = pca = buf.Ptr();
-
- // Add prolog.
- *reinterpret_cast<UNALIGNED USHORT*>(pca) = 1;
- pca += sizeof(USHORT);
-
- // Add length.
- pca = reinterpret_cast<BYTE*>(CPackedLen::PutLength(pca, len));
-
- // Add string.
- WszWideCharToMultiByte(CP_UTF8,0, wzString, wzLen, reinterpret_cast<char*>(pca), len, 0, 0);
- pca += len;
-
- // Add epilog.
- *reinterpret_cast<UNALIGNED USHORT*>(pca) = 0;
- pca += sizeof(USHORT);
-
- // Store the attribute
- IfFailGo(GetAttrType(attr, &mr));
- IfFailGo(m_pEmit->DefineCustomAttribute(tk, mr, ca, (ULONG)(pca-ca), 0));
-
-ErrExit:
- return hr;
-} // HRESULT CImportTlb::_AddStringCa()
-
-//*****************************************************************************
-// Add a referenced typelib to the list of referenced typelibs. Check if
-// it is "this" typelib first.
-//*****************************************************************************
-HRESULT CImportTlb::_AddTlbRef( // S_OK or error.
- ITypeLib *pITLB, // The referenced typelib.
- mdAssemblyRef *par, // The AssemblyRef in this module.
- BSTR *pwzNamespace, // The namespace contained in the resolved assembly.
- BSTR *pwzAsmName, // The name of the resolved assembly.
- CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap) // The default interface to class interface map.
-{
- HRESULT hr = S_OK; // A result.
- IUnknown *pIUnk=0; // IUnknown for external assembly.
- mdAssemblyRef ar=0; // Assembly ref in the module containing the typeref.
- ITypeLib2 *pITLB2=0; // To get custom attributes.
- VARIANT vt; // Variant type.
- Assembly* ResolvedAssembly=0; // The resolved assembly.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // Temp def itf to class itf map.
-
- // Validate the arguments.
- _ASSERTE(pITLB && par && pwzNamespace && pwzAsmName);
-
- // Initialize the out parameters to NULL.
- *par = mdTokenNil;
- *pwzNamespace = NULL;
- *pwzAsmName = NULL;
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = NULL;
-
- ::VariantInit(&vt);
-
- // If not the importing typelib, add it to the list.
- if (pITLB == m_pITLB)
- { // Not an external assembly.
- //*par = mdAssemblyRefNil;
- *par = TokenFromRid(1, mdtModule);
- IfNullGo(*pwzNamespace = SysAllocStringLen(m_wzNamespace, SysStringLen(m_wzNamespace)));
- *pwzAsmName = NULL;
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = &m_DefItfToClassItfMap;
- return S_OK;
- }
-
- // If already resolved, just return assembly ref.
- if (m_LibRefs.Find(pITLB, par, pwzNamespace, pwzAsmName, NULL, ppDefItfToClassItfMap))
- return S_OK;
-
- // See if the typelib was exported, in which case it already has assembly ref information.
- if (pITLB->QueryInterface(IID_ITypeLib2, reinterpret_cast<void**>(&pITLB2)) == S_OK)
- {
- hr = pITLB2->GetCustData(GUID_ExportedFromComPlus, &vt);
- if (vt.vt == VT_BSTR)
- {
- // Use the CA data to get a reference.
- //CQuickArray<BYTE> rBuf;
- //int iLen;
- // The buffer should have been converted with CP_ACP, and should convert back directly.
- //IfFailGo(rBuf.ReSizeNoThrow(iLen=::SysStringLen(vt.bstrVal)));
- //if (iLen=WszWideCharToMultiByte(CP_ACP,0, vt.bstrVal,iLen, (char*)rBuf.Ptr(),iLen, 0,0))
- {
- // Define the assembly ref for the exported assembly.
- //ar = DefineAssemblyRefForExportedAssembly(rBuf.Ptr(),(DWORD)rBuf.Size(), m_pEmit);
- ar = DefineAssemblyRefForExportedAssembly(vt.bstrVal, m_pEmit);
-
- // Retrieve the namespace from the typelib.
- IfFailGo(GetNamespaceNameForTypeLib(pITLB, pwzNamespace));
-
- // Set the assembly name.
- IfNullGo(*pwzAsmName = SysAllocStringLen(vt.bstrVal, SysStringLen(vt.bstrVal)));
- }
- }
- }
-
- // If it wasn't directly converted to a reference, callback to the resolver.
- if (IsNilToken(ar))
- {
- // Get the assembly for that typelib.
- if (FAILED(m_Notify->ResolveRef(pITLB, &pIUnk)))
- IfFailGo(TLBX_I_RESOLVEREFFAILED);
-
- // If a NULL assembly was returned, then stop converting the type but
- // continue the import.
- if (pIUnk == NULL)
- IfFailGo(TLBX_E_INVALID_TYPEINFO);
-
- // Create an assembly ref in local assembly for referenced assembly.
- ar = DefineAssemblyRefForImportedTypeLib(m_pAssembly, m_pModule, m_pEmit, pIUnk, pwzNamespace, pwzAsmName, &ResolvedAssembly);
- }
-
- // Make sure the ref was resolved before adding to cache.
- if (IsNilToken(ar))
- IfFailGo(TLBX_I_RESOLVEREFFAILED);
-
- // Add the TLB to the list of references.
- IfFailGo(m_LibRefs.Add(pITLB, this, ar, *pwzNamespace, *pwzAsmName, ResolvedAssembly, &pDefItfToClassItfMap));
-
- // Set the output parameters.
- *par = ar;
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = pDefItfToClassItfMap;
-
-ErrExit:
- if (FAILED(hr))
- {
- if (*pwzNamespace)
- {
- SysFreeString(*pwzNamespace);
- *pwzNamespace = NULL;
- }
- if (*pwzAsmName)
- {
- SysFreeString(*pwzAsmName);
- *pwzAsmName = NULL;
- }
- }
- if (pIUnk)
- pIUnk->Release();
- if (pITLB2)
- pITLB2->Release();
- VariantClear(&vt);
-
- return hr;
-} // HRESULT CImportTlb::_AddTlbRef()
-
-//*****************************************************************************
-// Error reporting helper.
-//*****************************************************************************
-HRESULT CImportTlb::ReportEvent( // Returns the original HR.
- int ev, // The event kind.
- int hrRpt, // HR.
- ...) // Variable args.
-{
- HRESULT hr; // A result.
- va_list marker; // User text.
- BSTR bstrBuf=0; // BSTR for bufferrr.
- BSTR bstrMsg=0; // BSTR for message.
- const int iSize = 1024; // Message size;
-
- // We need a BSTR anyway for the call to ReportEvent, so just allocate a
- // big one for the buffer.
- IfNullGo(bstrBuf = ::SysAllocStringLen(0, iSize));
-
- // Format the message.
- va_start(marker, hrRpt);
- hr = FormatRuntimeErrorVa(bstrBuf, iSize, hrRpt, marker);
- va_end(marker);
-
- // Display it.
- IfNullGo(bstrMsg = ::SysAllocString(bstrBuf));
- m_Notify->ReportEvent(static_cast<ImporterEventKind>(ev), hrRpt, bstrMsg);
-
-ErrExit:
- // Clean up.
- if (bstrBuf)
- ::SysFreeString(bstrBuf);
- if (bstrMsg)
- ::SysFreeString(bstrMsg);
- return hrRpt;
-} // HRESULT CImportTlb::ReportEvent()
-
-//*****************************************************************************
-// Helper function to perform the shared functions of creating a TypeRef.
-//*****************************************************************************
-HRESULT CImpTlbTypeRef::DefineTypeRef( // S_OK or error.
- IMetaDataEmit *pEmit, // Emit interface.
- mdAssemblyRef ar, // The system assemblyref.
- const LPCWSTR szURL, // URL of the TypeDef, wide chars.
- mdTypeRef *ptr) // Put mdTypeRef here
-{
- HRESULT hr = S_OK; // A result.
- LPCWSTR szLookup; // The name to look up.
- mdToken tkNester; // Token of enclosing class.
-
- // If the name contains a '+', this is a nested type. The first part becomes
- // the resolution scope for the part after the '+'.
- szLookup = wcsrchr(szURL, NESTED_SEPARATOR_WCHAR);
- if (szLookup)
- {
- CQuickArray<WCHAR> qbName;
- IfFailGo(qbName.ReSizeNoThrow(szLookup - szURL + 1));
- wcsncpy_s(qbName.Ptr(), (szLookup - szURL + 1), szURL, szLookup - szURL);
- IfFailGo(DefineTypeRef(pEmit, ar, qbName.Ptr(), &tkNester));
- ar = tkNester;
- ++szLookup;
- }
- else
- szLookup = szURL;
-
- // Look for the item in the map.
- CImpTlbTypeRef::TokenOfTypeRefHashKey sSearch, *pMapped;
-
- sSearch.tkResolutionScope = ar;
- sSearch.szName = szLookup;
- pMapped = m_Map.Find(&sSearch);
-
- if (pMapped)
- {
- *ptr = pMapped->tr;
- goto ErrExit;
- }
-
- // Wasn't found, create a new one and add to the map.
- hr = pEmit->DefineTypeRefByName(ar, szLookup, ptr);
- if (SUCCEEDED(hr))
- {
- sSearch.tr = *ptr;
- pMapped = m_Map.Add(&sSearch);
- IfNullGo(pMapped);
- }
-
-ErrExit:
- return (hr);
-} // HRESULT CImpTlbTypeRef::DefineTypeRef()
-
-//*****************************************************************************
-// Free the held typelibs in the list of imported typelibs.
-//*****************************************************************************
-CImpTlbLibRef::~CImpTlbLibRef()
-{
- for (ULONG i = 0; i < Size(); i++)
- {
- SysFreeString(operator[](i).szNameSpace);
- delete operator[](i).pDefItfToClassItfMap;
- }
-} // CImpTlbLibRef::~CImpTlbLibRef()
-
-//*****************************************************************************
-// Add a new typelib reference to the list.
-//*****************************************************************************
-HRESULT CImpTlbLibRef::Add(
- ITypeLib *pITLB,
- CImportTlb *pImporter,
- mdAssemblyRef ar,
- BSTR wzNamespace,
- BSTR wzAsmName,
- Assembly* assm,
- CImpTlbDefItfToClassItfMap **ppMap)
-{
- HRESULT hr = S_OK; // A result.
- TLIBATTR *pAttr=0; // A typelib attribute.
- ULONG i; // Index.
- CTlbRef *pTlbRef=0; // A pointer to the TlbRef struct.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap = NULL; // ptr to the default interface to class interface map.
-
- // Validate the arguments.
- _ASSERTE(wzNamespace);
- _ASSERTE(wzAsmName);
-
- IfFailGo(pITLB->GetLibAttr(&pAttr));
-
-#if defined(_DEBUG)
- for (i=0; i<Size(); ++i)
- {
- if (operator[](i).guid == pAttr->guid)
- {
- _ASSERTE(!"External TypeLib already referenced");
- goto ErrExit;
- }
- }
-#else
- i = (ULONG)Size();
-#endif
-
- // Allocate and initialize the default interface to class interface map.
- pDefItfToClassItfMap = new (nothrow) CImpTlbDefItfToClassItfMap();
- IfNullGo(pDefItfToClassItfMap);
- IfFailGo(pDefItfToClassItfMap->Init(pITLB, wzNamespace));
-
- // Attemp to resize the array.
- IfFailGo(ReSizeNoThrow(i+1));
- pTlbRef = &operator[](i);
- pTlbRef->guid = pAttr->guid;
- pTlbRef->ar = ar;
- IfNullGo(pTlbRef->szNameSpace = SysAllocString(wzNamespace));
- IfNullGo(pTlbRef->szAsmName = SysAllocString(wzAsmName));
- pTlbRef->pDefItfToClassItfMap = pDefItfToClassItfMap;
- pTlbRef->Asm = assm;
-
-ErrExit:
- if (pAttr)
- pITLB->ReleaseTLibAttr(pAttr);
- if (FAILED(hr))
- {
- if (pTlbRef && pTlbRef->szNameSpace)
- SysFreeString(pTlbRef->szNameSpace);
- if (pTlbRef && pTlbRef->szAsmName)
- SysFreeString(pTlbRef->szAsmName);
- delete pDefItfToClassItfMap;
- }
- else
- {
- *ppMap = pDefItfToClassItfMap;
- }
-
- return hr;
-} // void CImpTlbLibRef::Add()
-
-//*****************************************************************************
-// Find an existing typelib reference.
-//*****************************************************************************
-int CImpTlbLibRef::Find(
- ITypeLib *pITLB,
- mdAssemblyRef *par,
- BSTR *pwzNamespace,
- BSTR *pwzAsmName,
- Assembly** assm,
- CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap)
-{
- HRESULT hr; // A result.
- TLIBATTR *pAttr=0; // A typelib attribute.
- int rslt = FALSE; // Return result.
- ULONG i; // Loop control.
-
- _ASSERTE(pwzNamespace);
- _ASSERTE(pwzAsmName);
-
- // Initalize the out parameters to NULL.
- *pwzNamespace = NULL;
- *pwzAsmName = NULL;
-
- if (assm)
- *assm = NULL;
-
- IfFailGo(pITLB->GetLibAttr(&pAttr));
-
- for (i=0; i<Size(); ++i)
- {
- if (operator[](i).guid == pAttr->guid)
- {
- *par = operator[](i).ar;
- IfNullGo(*pwzNamespace = SysAllocString(operator[](i).szNameSpace));
- IfNullGo(*pwzAsmName = SysAllocString(operator[](i).szAsmName));
- if (ppDefItfToClassItfMap)
- *ppDefItfToClassItfMap = operator[](i).pDefItfToClassItfMap;
- if (assm)
- *assm = operator[](i).Asm;
- rslt = TRUE;
- goto ErrExit;
- }
- }
-
-ErrExit:
- if (FAILED(hr))
- {
- if (*pwzNamespace)
- SysFreeString(*pwzNamespace);
- if (*pwzAsmName)
- SysFreeString(*pwzAsmName);
- }
- if (pAttr)
- pITLB->ReleaseTLibAttr(pAttr);
- return rslt;
-} // void CImpTlbLibRef::Find()
-
-//*****************************************************************************
-// unpack variant to an ELEMENT_TYPE_* plus a blob value
-// If VT_BOOL, it is a two-byte value.
-//*****************************************************************************
-HRESULT _UnpackVariantToConstantBlob(VARIANT *pvar, BYTE *pcvType, void **pvValue, __int64 *pd)
-{
- HRESULT hr = NOERROR;
-
- switch (pvar->vt)
- {
- case VT_BOOL:
- *pcvType = ELEMENT_TYPE_BOOLEAN;
- *((VARIANT_BOOL **)pvValue) = &(pvar->boolVal);
- break;
- case VT_I1:
- *pcvType = ELEMENT_TYPE_I1;
- *((CHAR **)pvValue) = &(pvar->cVal);
- break;
- case VT_UI1:
- *pcvType = ELEMENT_TYPE_U1;
- *((BYTE **)pvValue) = &(pvar->bVal);
- break;
- case VT_I2:
- *pcvType = ELEMENT_TYPE_I2;
- *((SHORT **)pvValue) = &(pvar->iVal);
- break;
- case VT_UI2:
- *pcvType = ELEMENT_TYPE_U2;
- *((USHORT **)pvValue) = &(pvar->uiVal);
- break;
- case VT_I4:
- case VT_INT:
- *pcvType = ELEMENT_TYPE_I4;
- *((LONG **)pvValue) = &(pvar->lVal);
- break;
- case VT_UI4:
- case VT_UINT:
- *pcvType = ELEMENT_TYPE_U4;
- *((ULONG **)pvValue) = &(pvar->ulVal);
- break;
- case VT_R4:
- *pcvType = ELEMENT_TYPE_R4;
- *((float **)pvValue) = &(pvar->fltVal);
- break;
- case VT_I8:
- *pcvType = ELEMENT_TYPE_I8;
- *((LONGLONG **)pvValue) = &(pvar->cyVal.int64);
- break;
- case VT_R8:
- *pcvType = ELEMENT_TYPE_R8;
- *((double **)pvValue) = &(pvar->dblVal);
- break;
- case VT_BSTR:
- *pcvType = ELEMENT_TYPE_STRING;
- *((BSTR *)pvValue) = pvar->bstrVal;
- break;
-
- case VT_DATE:
- *pcvType = ELEMENT_TYPE_I8;
- *pd = _DoubleDateToTicks(pvar->date);
- *((LONGLONG **)pvValue) = pd;
- break;
- case VT_UNKNOWN:
- case VT_DISPATCH:
- *pcvType = ELEMENT_TYPE_CLASS;
- _ASSERTE(pvar->punkVal == NULL);
- *((IUnknown ***)pvValue) = &(pvar->punkVal);
- break;
- default:
- _ASSERTE(!"Not a valid type to specify default value!");
- IfFailGo( META_E_BAD_INPUT_PARAMETER );
- break;
- }
-ErrExit:
- return hr;
-} // HRESULT _UnpackVariantToConstantBlob()
-
-//*****************************************************************************
-// Stolen from classlib.
-//*****************************************************************************
-INT64 _DoubleDateToTicks(const double d)
-{
- const INT64 MillisPerSecond = 1000;
- const INT64 MillisPerDay = MillisPerSecond * 60 * 60 * 24;
- const INT64 TicksPerMillisecond = 10000;
- const INT64 TicksPerSecond = TicksPerMillisecond * 1000;
- const INT64 TicksPerMinute = TicksPerSecond * 60;
- const INT64 TicksPerHour = TicksPerMinute * 60;
- const INT64 TicksPerDay = TicksPerHour * 24;
- const int DaysPer4Years = 365 * 4 + 1;
- const int DaysPer100Years = DaysPer4Years * 25 - 1;
- const int DaysPer400Years = DaysPer100Years * 4 + 1;
- const int DaysTo1899 = DaysPer400Years * 4 + DaysPer100Years * 3 - 367;
- const INT64 DoubleDateOffset = DaysTo1899 * TicksPerDay;
- const int DaysTo10000 = DaysPer400Years * 25 - 366;
- const INT64 MaxMillis = DaysTo10000 * MillisPerDay;
-
- INT64 millis = (INT64)(d * MillisPerDay + (d >= 0? 0.5: -0.5));
- if (millis < 0) millis -= (millis % MillisPerDay) * 2;
- millis += DoubleDateOffset / TicksPerMillisecond;
- if (millis < 0 || millis >= MaxMillis) {
- return 0;
- }
- return millis * TicksPerMillisecond;
-} // INT64 _DoubleDateToTicks()
-
-
-//*****************************************************************************
-// Wrapper for GetFuncDesc to catch errors.
-//*****************************************************************************
-static HRESULT TryGetFuncDesc( // S_OK or error.
- ITypeInfo *pITI, // ITypeInfo with function.
- int i, // Function index.
- FUNCDESC **ppFunc) // Put FUNCDESC here.
-{
- HRESULT hr; // A return code.
- __try
- {
- hr = pITI->GetFuncDesc(i, ppFunc);
- }
- __except(1)
- {
- hr = PostError(TLBX_E_TLB_EXCEPTION, _exception_code());
- }
-
- return hr;
-} // static HRESULT TryGetFuncDesc()
-
-//*****************************************************************************
-// Implementation of a hashed ResolutionScope+Name to TypeRef map.
-//*****************************************************************************
-void CImpTlbTypeRef::CTokenOfTypeRefHash::Clear()
-{
-#if defined(_DEBUG)
- // printf("Name to TypeRef cache: %d buckets, %d used, %d collisions\n", Buckets(), Count(), Collisions());
-#endif
- CClosedHash<class TokenOfTypeRefHashKey>::Clear();
-} // void CImpTlbTypeRef::CTokenOfTypeRefHash::Clear()
-
-unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Hash(const TokenOfTypeRefHashKey *pData)
-{
- // Starting value for hash.
- ULONG hash = 5381;
-
- // Hash in the resolution scope token.
- const BYTE *pbData = reinterpret_cast<const BYTE *>(&pData->tkResolutionScope);
- int iSize = 4;
- while (--iSize >= 0)
- {
- hash = ((hash << 5) + hash) ^ *pbData;
- ++pbData;
- }
-
- // Hash in the typeref name.
- LPCWSTR szStr = pData->szName;
- int c;
- while ((c = *szStr) != 0)
- {
- hash = ((hash << 5) + hash) ^ c;
- ++szStr;
- }
-
- return hash;
-} // unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Hash()
-
-unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Compare(const TokenOfTypeRefHashKey *p1, TokenOfTypeRefHashKey *p2)
-{
- // Resolution scopes are fast to compare.
- if (p1->tkResolutionScope < p2->tkResolutionScope)
- return -1;
- if (p1->tkResolutionScope > p2->tkResolutionScope)
- return 1;
- // But if they are the same, compare the names.
- return wcscmp(p1->szName, p2->szName);
-} // unsigned int CImpTlbTypeRef::CTokenOfTypeRefHash::Compare()
-
-CImpTlbTypeRef::CTokenOfTypeRefHash::ELEMENTSTATUS CImpTlbTypeRef::CTokenOfTypeRefHash::Status(TokenOfTypeRefHashKey *p)
-{
- if (p->tkResolutionScope == static_cast<mdToken>(FREE))
- return (FREE);
- if (p->tkResolutionScope == static_cast<mdToken>(DELETED))
- return (DELETED);
- return (USED);
-} // CImpTlbTypeRef::CTokenOfTypeRefHash::ELEMENTSTATUS CImpTlbTypeRef::CTokenOfTypeRefHash::Status()
-
-void CImpTlbTypeRef::CTokenOfTypeRefHash::SetStatus(TokenOfTypeRefHashKey *p, ELEMENTSTATUS s)
-{
- p->tkResolutionScope = static_cast<mdToken>(s);
-} // void CImpTlbTypeRef::CTokenOfTypeRefHash::SetStatus()
-
-void *CImpTlbTypeRef::CTokenOfTypeRefHash::GetKey(TokenOfTypeRefHashKey *p)
-{
- return p;
-} // void *CImpTlbTypeRef::CTokenOfTypeRefHash::GetKey()
-
-CImpTlbTypeRef::TokenOfTypeRefHashKey* CImpTlbTypeRef::CTokenOfTypeRefHash::Add(const TokenOfTypeRefHashKey *pData)
-{
- LPWSTR pName;
- const void *pvData = pData;
- TokenOfTypeRefHashKey *pNew = Super::Add(const_cast<void*>(pvData));
- if (pNew == 0)
- return 0;
- pNew->szName = pName = m_Names.Alloc((ULONG)wcslen(pData->szName)+1);
- if (pNew->szName == 0)
- return 0;
- wcscpy_s(pName, wcslen(pData->szName)+1, pData->szName);
- pNew->tkResolutionScope = pData->tkResolutionScope;
- pNew->tr = pData->tr;
-
- return pNew;
-} // TokenOfTypeRefHashKey* CImpTlbTypeRef::CTokenOfTypeRefHash::Add()
-
-//*****************************************************************************
-// Implementation of a hashed ITypeInfo * source interface to event information
-// map.
-//*****************************************************************************
-HRESULT CImpTlbEventInfoMap::AddEventInfo(LPCWSTR szSrcItfName, mdTypeRef trEventItf, LPCWSTR szEventItfName, LPCWSTR szEventProviderName, Assembly* SrcItfAssembly)
-{
- ImpTlbEventInfo sNew;
- sNew.szSrcItfName = szSrcItfName;
- sNew.trEventItf = trEventItf;
- sNew.szEventItfName = szEventItfName;
- sNew.szEventProviderName = szEventProviderName;
- sNew.SrcItfAssembly = SrcItfAssembly;
- return Add(&sNew) != NULL ? S_OK : E_OUTOFMEMORY;
-} // BOOL CImpTlbEventInfoMap::AddEventInfo()
-
-ImpTlbEventInfo *CImpTlbEventInfoMap::FindEventInfo(LPCWSTR szSrcItfName)
-{
- ImpTlbEventInfo sSearch, *pMapped;
- sSearch.szSrcItfName = szSrcItfName;
- pMapped = Find(&sSearch);
- return pMapped;
-} // ImpTlbEventInfo *CImpTlbEventInfoMap::FindEventInfo()
-
-HRESULT CImpTlbEventInfoMap::GetEventInfoList(CQuickArray<ImpTlbEventInfo*> &qbEvInfoList)
-{
- HRESULT hr = S_OK;
- int cCurrEvInfo = 0;
-
- // Resise the event info list.
- IfFailGo(qbEvInfoList.ReSizeNoThrow(Count()));
-
- // Retrieve the first event info.
- ImpTlbEventInfo *pEvInfo = GetFirst();
-
- // Add all the event info's to the list.
- while (pEvInfo)
- {
- qbEvInfoList[cCurrEvInfo++] = pEvInfo;
- pEvInfo = GetNext(pEvInfo);
- }
-
-ErrExit:
- return hr;
-} // HRESULT CImpTlbEventInfoMap::GetEventInfoList()
-
-unsigned int CImpTlbEventInfoMap::Hash(const ImpTlbEventInfo *pData)
-{
- // Starting value for hash.
- ULONG hash = 5381;
-
- // Hash in the source interface name.
- LPCWSTR szStr = pData->szSrcItfName;
- int c;
- while ((c = *szStr) != 0)
- {
- hash = ((hash << 5) + hash) ^ c;
- ++szStr;
- }
-
- return hash;
-} // unsigned int CImpTlbEventInfoMap::Hash()
-
-unsigned int CImpTlbEventInfoMap::Compare(const ImpTlbEventInfo *p1, ImpTlbEventInfo *p2)
-{
- // Compare the source interface names.
- return wcscmp(p1->szSrcItfName, p2->szSrcItfName);
-} // unsigned int CImpTlbEventInfoMap::Compare()
-
-CImpTlbEventInfoMap::ELEMENTSTATUS CImpTlbEventInfoMap::Status(ImpTlbEventInfo *p)
-{
- if (p->szSrcItfName == reinterpret_cast<LPCWSTR>(FREE))
- return (FREE);
- if (p->szSrcItfName == reinterpret_cast<LPCWSTR>(DELETED))
- return (DELETED);
- return (USED);
-} // CImpTlbEventInfoMap::ELEMENTSTATUS CImpTlbEventInfoMap::Status()
-
-void CImpTlbEventInfoMap::SetStatus(ImpTlbEventInfo *p, ELEMENTSTATUS s)
-{
- p->szSrcItfName = reinterpret_cast<LPCWSTR>(s);
-} // void CImpTlbEventInfoMap::SetStatus()
-
-void *CImpTlbEventInfoMap::GetKey(ImpTlbEventInfo *p)
-{
- return p;
-} // void *CImpTlbEventInfoMap::GetKey()
-
-ImpTlbEventInfo* CImpTlbEventInfoMap::Add(const ImpTlbEventInfo *pData)
-{
- // Add the new entry to the map.
- const void *pvData = pData;
- ImpTlbEventInfo *pNew = Super::Add(const_cast<void*>(pvData));
- if (pNew == 0)
- return 0;
-
- // Copy the source interface name.
- pNew->szSrcItfName = m_Names.Alloc((ULONG)wcslen(pData->szSrcItfName)+1);
- if (pNew->szSrcItfName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szSrcItfName, wcslen(pData->szSrcItfName)+1, pData->szSrcItfName);
-
- // Copy the event interface type def.
- pNew->trEventItf = pData->trEventItf;
-
- // Copy the event interface name.
- pNew->szEventItfName = m_Names.Alloc((ULONG)wcslen(pData->szEventItfName)+1);
- if (pNew->szEventItfName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szEventItfName, wcslen(pData->szEventItfName)+1, pData->szEventItfName);
-
- // Copy the event provider name.
- pNew->szEventProviderName = m_Names.Alloc((ULONG)wcslen(pData->szEventProviderName)+1);
- if (pNew->szEventProviderName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szEventProviderName, wcslen(pData->szEventProviderName)+1, pData->szEventProviderName);
-
- // Copy the Source Interface Assembly pointer
- pNew->SrcItfAssembly = pData->SrcItfAssembly;
-
- // Return the new entry.
- return pNew;
-} // ImpTlbEventInfo* CImpTlbEventInfoMap::Add()
-
-CImpTlbDefItfToClassItfMap::CImpTlbDefItfToClassItfMap()
-: CClosedHash<class ImpTlbClassItfInfo>(101)
-, m_bstrNameSpace(NULL)
-{
-}
-
-CImpTlbDefItfToClassItfMap::~CImpTlbDefItfToClassItfMap()
-{
- Clear();
- if (m_bstrNameSpace)
- {
- ::SysFreeString(m_bstrNameSpace);
- m_bstrNameSpace = NULL;
- }
-}
-
-HRESULT CImpTlbDefItfToClassItfMap::Init(ITypeLib *pTlb, BSTR bstrNameSpace)
-{
- HRESULT hr; // A result.
- int cTi; // Count of TypeInfos.
- int i; // Loop control.
- TYPEATTR *psAttr=0; // TYPEATTR for the ITypeInfo.
- TYPEATTR *psDefItfAttr=0; // TYPEATTR for the default interface.
- ITypeInfo *pITI=0; // The ITypeInfo.
- ITypeInfo *pDefItfITI=0; // The ITypeInfo for the default interface.
-
- // Save the namespace.
- IfNullGo(m_bstrNameSpace = SysAllocString(bstrNameSpace));
-
- // How many TypeInfos?
- IfFailGo(cTi = pTlb->GetTypeInfoCount());
-
- // Iterate over them.
- for (i = 0; i < cTi; ++i)
- {
- // Get the TypeInfo.
- hr = pTlb->GetTypeInfo(i, &pITI);
- if (SUCCEEDED(hr))
- {
- // Retrieve the attributes of the type info.
- IfFailGo(pITI->GetTypeAttr(&psAttr));
-
- // If we are dealing with a CoClass, then set up the default interface to
- // class interface mapping.
- if (psAttr->typekind == TKIND_COCLASS)
- IfFailGo(AddCoClassInterfaces(pITI, psAttr));
-
- // Release for next TypeInfo.
- if (psAttr)
- {
- pITI->ReleaseTypeAttr(psAttr);
- psAttr = 0;
- }
- if (pITI)
- {
- pITI->Release();
- pITI = 0;
- }
- }
- }
-
-ErrExit:
- if (psAttr)
- pITI->ReleaseTypeAttr(psAttr);
- if (pITI)
- pITI->Release();
-
- return (hr);
-}
-
-HRESULT CImpTlbDefItfToClassItfMap::AddCoClassInterfaces(ITypeInfo *pCoClassITI, TYPEATTR *pCoClassTypeAttr)
-{
- HRESULT hr; // A result
- HREFTYPE href; // HREFTYPE of an implemented interface.
- INT ImplFlags; // ImplType flags.
- int NumInterfaces; // The number of interfaces on the coclass.
- int i; // A counter.
- ITypeInfo *pItfITI=0; // The ITypeInfo for the current interface.
- ITypeInfo *pBaseItfITI=0; // The ITypeInfo for the base interface.
- TYPEATTR *psItfAttr=0; // TYPEATTR for the interface.
- BSTR bstrClassItfName=0; // The name of the class interface.
-
- // Retrieve the name of the CoClass.
- IfFailGo(GetManagedNameForTypeInfo(pCoClassITI, m_bstrNameSpace, NULL, &bstrClassItfName));
-
- // Retrieve the default interface for the CoClass.
- IfFailGo(CImportTlb::GetDefaultInterface(pCoClassITI, &pItfITI));
-
- // If there is a default interface, then add it to the map.
- if (hr == S_OK)
- {
- // Retrieve the attributes of the default interface type info.
- IfFailGo(pItfITI->GetTypeAttr(&psItfAttr));
-
- // If there already is a CoClass that implements this
- // interface then we do not want to do the mapping.
- ImpTlbClassItfInfo sSearch, *pMapped;
- sSearch.ItfIID = psItfAttr->guid;
- pMapped = Find(&sSearch);
- if (pMapped)
- {
- // There already is a CoClass that implements the interface so
- // we set the class itf name to NULL to indicate not to do the def
- // itf to class itf convertion for this interface.
- pMapped->szClassItfName = NULL;
- }
- else
- {
- // Unless the default interface is IUnknown or IDispatch, add the
- // def itf to class itf entry to the map.
- if (psItfAttr->guid != IID_IUnknown && psItfAttr->guid != IID_IDispatch)
- {
- ImpTlbClassItfInfo sNew;
- sNew.ItfIID = psItfAttr->guid;
- sNew.szClassItfName = bstrClassItfName;
- IfNullGo(Add(&sNew));
- }
- }
-
- // Release for next interface.
- pItfITI->ReleaseTypeAttr(psItfAttr);
- psItfAttr = 0;
- pItfITI->Release();
- pItfITI = 0;
- }
-
- // Retrieve the number of interfaces the coclass has
- NumInterfaces = pCoClassTypeAttr->cImplTypes;
-
- // Go through all the interfaces and add them to the map.
- for (i=0; i < NumInterfaces; i++)
- {
- // Get the impl flags.
- IfFailGo(pCoClassITI->GetImplTypeFlags(i, &ImplFlags));
-
- // If this is an implemented interface.
- if (!(ImplFlags & IMPLTYPEFLAG_FSOURCE))
- {
- IfFailGo(pCoClassITI->GetRefTypeOfImplType(i, &href));
- IfFailGo(pCoClassITI->GetRefTypeInfo(href, &pItfITI));
-
- do
- {
- // Retrieve the attributes of the interface type info.
- IfFailGo(pItfITI->GetTypeAttr(&psItfAttr));
-
- // If there already is a CoClass that implements this
- // interface then we do not want to do the mapping.
- ImpTlbClassItfInfo sSearch, *pMapped;
- sSearch.ItfIID = psItfAttr->guid;
- pMapped = Find(&sSearch);
- if (pMapped)
- {
- // There already is a CoClass that implements the interface. If that
- // CoClass is not the current one, then we we set the class itf name
- // to NULL to indicate not to do the def itf to class itf convertion
- // for this interface.
- if (pMapped->szClassItfName && wcscmp(pMapped->szClassItfName, bstrClassItfName) != 0)
- pMapped->szClassItfName = NULL;
- }
- else
- {
- // Add an entry with a NULL name to prevent future substitutions.
- ImpTlbClassItfInfo sNew;
- sNew.ItfIID = psItfAttr->guid;
- sNew.szClassItfName = NULL;
- IfNullGo(Add(&sNew));
- }
-
- // If there is a base interface, then handle it also.
- if (psItfAttr->cImplTypes == 1)
- {
- IfFailGo(pItfITI->GetRefTypeOfImplType(0, &href));
- IfFailGo(pItfITI->GetRefTypeInfo(href, &pBaseItfITI));
- }
-
- // Release for next interface.
- if (psItfAttr)
- {
- pItfITI->ReleaseTypeAttr(psItfAttr);
- psItfAttr = 0;
- }
- if (pItfITI)
- {
- pItfITI->Release();
- pItfITI = 0;
- }
-
- // Set the current interface to the base interface.
- pItfITI = pBaseItfITI;
- pBaseItfITI = 0;
- }
- while(pItfITI);
- }
- }
-
-ErrExit:
- if (psItfAttr)
- pItfITI->ReleaseTypeAttr(psItfAttr);
- if (pItfITI)
- pItfITI->Release();
- if (bstrClassItfName)
- ::SysFreeString(bstrClassItfName);
-
- return hr;
-}
-
-LPCWSTR CImpTlbDefItfToClassItfMap::GetClassItfName(IID &rItfIID)
-{
- ImpTlbClassItfInfo sSearch, *pMapped;
- sSearch.ItfIID = rItfIID;
- pMapped = Find(&sSearch);
- return pMapped ? pMapped->szClassItfName : NULL;
-}
-
-unsigned int CImpTlbDefItfToClassItfMap::Hash(const ImpTlbClassItfInfo *pData)
-{
- // Starting value for hash.
- ULONG hash = 5381;
-
- // Hash in the IID.
- const BYTE *pbData = reinterpret_cast<const BYTE *>(&pData->ItfIID);
- int iSize = sizeof(IID);
- while (--iSize >= 0)
- {
- hash = ((hash << 5) + hash) ^ *pbData;
- ++pbData;
- }
-
- return hash;
-} // unsigned int CImpTlbDefItfToClassItfMap::Hash()
-
-unsigned int CImpTlbDefItfToClassItfMap::Compare(const ImpTlbClassItfInfo *p1, ImpTlbClassItfInfo *p2)
-{
- // Compare the IID's.
- return memcmp(&p1->ItfIID, &p2->ItfIID, sizeof(IID));
-} // unsigned int CImpTlbEventInfoMap::Compare()
-
-CImpTlbDefItfToClassItfMap::ELEMENTSTATUS CImpTlbDefItfToClassItfMap::Status(ImpTlbClassItfInfo *p)
-{
- if (IsEqualGUID(p->ItfIID, FREE_STATUS_GUID))
- {
- return (FREE);
- }
- else if (IsEqualGUID(p->ItfIID, DELETED_STATUS_GUID))
- {
- return (DELETED);
- }
- return (USED);
-} // CImpTlbDefItfToClassItfMap::ELEMENTSTATUS CImpTlbEventInfoMap::Status()
-
-void CImpTlbDefItfToClassItfMap::SetStatus(ImpTlbClassItfInfo *p, ELEMENTSTATUS s)
-{
- if (s == FREE)
- {
- p->ItfIID = FREE_STATUS_GUID;
- }
- else if (s == DELETED)
- {
- p->ItfIID = DELETED_STATUS_GUID;
- }
- else
- {
- _ASSERTE(!"Invalid status!");
- }
-} // void CImpTlbDefItfToClassItfMap::SetStatus()
-
-void *CImpTlbDefItfToClassItfMap::GetKey(ImpTlbClassItfInfo *p)
-{
- return p;
-} // void *CImpTlbDefItfToClassItfMap::GetKey()
-
-ImpTlbClassItfInfo* CImpTlbDefItfToClassItfMap::Add(const ImpTlbClassItfInfo *pData)
-{
- // Add the new entry to the map.
- const void *pvData = pData;
- ImpTlbClassItfInfo *pNew = Super::Add(const_cast<void*>(pvData));
- if (pNew == 0)
- return 0;
-
- // Copy the IID.
- pNew->ItfIID = pData->ItfIID;
-
- // Copy the class interface name.
- if (pData->szClassItfName)
- {
- pNew->szClassItfName = m_Names.Alloc((ULONG)wcslen(pData->szClassItfName)+1);
- if (pNew->szClassItfName == 0)
- return 0;
- wcscpy_s((LPWSTR)pNew->szClassItfName, wcslen(pData->szClassItfName)+1, pData->szClassItfName);
- }
- else
- {
- pNew->szClassItfName = NULL;
- }
-
- // Return the new entry.
- return pNew;
-} // ImpTlbEventInfo* CImpTlbEventInfoMap::Add()
-
-// EOF =======================================================================
diff --git a/src/md/enc/liteweightstgdbrw.cpp b/src/md/enc/liteweightstgdbrw.cpp
index 12779f59c0..9bd923c931 100644
--- a/src/md/enc/liteweightstgdbrw.cpp
+++ b/src/md/enc/liteweightstgdbrw.cpp
@@ -339,12 +339,7 @@ HRESULT CLiteWeightStgdbRW::OpenForRead(
// If we're taking ownership of this memory.....
if (IsOfTakeOwnership(dwFlags))
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- // Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
- IfFailGo(E_INVALIDARG);
-#else
dmOpenFlags = (DBPROPMODE)(dmOpenFlags | DBPROP_TMODEF_SHAREDMEM);
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
}
#ifdef FEATURE_METADATA_LOAD_TRUSTED_IMAGES
if (IsOfTrustedImage(dwFlags))
@@ -1251,28 +1246,5 @@ BOOL
CLiteWeightStgdbRW::IsValidFileNameLength(
const WCHAR * wszFileName)
{
-#ifdef FEATURE_CORECLR
return TRUE;
-#else
- static const WCHAR const_wszLongPathPrefix[] = W("\\\\?\\");
-
- if (wszFileName == NULL)
- {
- return TRUE;
- }
- size_t cchFileName = wcslen(wszFileName);
- if (cchFileName < _MAX_PATH)
- {
- return TRUE;
- }
- if (SString::_wcsnicmp(wszFileName, const_wszLongPathPrefix, _countof(const_wszLongPathPrefix) - 1) != 0)
- { // Path does not have long path prefix \\?\ (as required by CreateFile API)
- return FALSE;
- }
- if (cchFileName < 32767)
- { // Limit for the long path length as defined in CreateFile API
- return TRUE;
- }
- return FALSE;
-#endif
} // CLiteWeightStgdbRW::IsValidFileNameLength
diff --git a/src/md/enc/metamodelenc.cpp b/src/md/enc/metamodelenc.cpp
index 4d972827ca..7460d580dc 100644
--- a/src/md/enc/metamodelenc.cpp
+++ b/src/md/enc/metamodelenc.cpp
@@ -263,18 +263,6 @@ CMiniMdRW::ApplyDelta(
return E_INVALIDARG;
}
-#ifndef FEATURE_CORECLR
- // Verify that the delta is based on the base.
- IfFailGo(mdDelta.getEncBaseIdOfModule(pModDelta, &GuidDelta));
- IfFailGo(getEncBaseIdOfModule(pModBase,&GuidBase));
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas) &&
- (GuidDelta != GuidBase))
- {
- _ASSERTE(!"The Delta MetaData is based on a different generation than the current MetaData.");
- return E_INVALIDARG;
- }
-#endif //!FEATURE_CORECLR
// Let the other md prepare for sparse records.
IfFailGo(mdDelta.StartENCMap());
@@ -390,19 +378,6 @@ ErrExit:
HRESULT hrReturn = hr;
IfFailRet(mdDelta.EndENCMap());
-#ifndef FEATURE_CORECLR
- if (SUCCEEDED(hrReturn) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_DeltaCheck) &&
- CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- {
- GUID GuidNewBase;
-
- // We'll use the delta's 'delta guid' for our new base guid
- IfFailRet(mdDelta.getEncIdOfModule(pModDelta, &GuidNewBase));
-
- IfFailRet(PutGuid(TBL_Module, ModuleRec::COL_EncBaseId, pModBase, GuidNewBase));
- }
-#endif //!FEATURE_CORECLR
return hrReturn;
} // CMiniMdRW::ApplyDelta
diff --git a/src/md/enc/metamodelrw.cpp b/src/md/enc/metamodelrw.cpp
index f9002b6fa9..6a3bc327ef 100644
--- a/src/md/enc/metamodelrw.cpp
+++ b/src/md/enc/metamodelrw.cpp
@@ -4317,11 +4317,6 @@ CMiniMdRW::SaveHotPoolsToStream(
UINT32 *pnPoolDirSize,
UINT32 *pnHeapsSavedSize)
{
-// @todo: Triton workaround: FEATURE_METADATA_STANDALNE_WINRT_RO is supposed to disable FEATURE_PREJIT - remove this #if once we figure out how to get that working in the CoreClr build.
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- _ASSERTE(!"SaveHotPoolsToStream: This method not supported in RoMetadata.dll");
- return E_NOTIMPL;
-#else // FEATURE_METADATA_STANDALONE_WINRT_RO
HRESULT hr = S_OK;
UINT32 rgHeapSavedSize[MDPoolCount] = { 0, 0, 0, 0 };
@@ -4393,7 +4388,6 @@ CMiniMdRW::SaveHotPoolsToStream(
}
return S_OK;
-#endif //FEATURE_METADATA_STANDALONE_WINRT_RO
} // CMiniMdRW::SaveHotPoolsToStream
// write hot data of specific blob
@@ -4406,11 +4400,6 @@ CMiniMdRW::SaveHotPoolToStream(
MetaData::HotHeapWriter *pHotHeapWriter,
UINT32 *pnSavedSize)
{
-// @todo: Triton workaround: FEATURE_METADATA_STANDALNE_WINRT_RO is supposed to disable FEATURE_PREJIT - remove this #if once we figure out how to get that working in the CoreClr build.
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- _ASSERTE(!"SaveHotPoolToStream: This method not supported in RoMetadata.dll");
- return E_NOTIMPL;
-#else //FEATURE_METADATA_STANDALONE_WINRT_RO
_ASSERTE(pProfileData != NULL);
@@ -4435,7 +4424,6 @@ CMiniMdRW::SaveHotPoolToStream(
}
return S_OK;
-#endif // FEATURE_METADATA_STANDALONE_WINRT_RO
} // CMiniMdRW::SaveHotPoolToStream
#endif //FEATURE_PREJIT
@@ -8228,19 +8216,6 @@ CMiniMdRW::ResetENCLog()
// Get the module record.
IfFailGo(GetModuleRecord(1, &pMod));
-#ifndef FEATURE_CORECLR
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- { // Update the ENC Guids
- GUID encid;
- // Copy EncId as BaseId.
- ULONG uVal = GetCol(TBL_Module, ModuleRec::COL_EncId, pMod);
- IfFailGo(PutCol(TBL_Module, ModuleRec::COL_EncBaseId, pMod, uVal));
-
- // Allocate a new GUID for EncId.
- IfFailGo(CoCreateGuid(&encid));
- IfFailGo(PutGuid(TBL_Module, ModuleRec::COL_EncId, pMod, encid));
- }
-#endif //!FEATURE_CORECLR
// Reset the pool deltas
m_StringHeap.StartNewEnCSession();
diff --git a/src/md/enc/rwutil.cpp b/src/md/enc/rwutil.cpp
index 874d972716..a00eddb3f1 100644
--- a/src/md/enc/rwutil.cpp
+++ b/src/md/enc/rwutil.cpp
@@ -952,149 +952,6 @@ ErrExit:
-
-//*********************************************************************************************************
-//
-// Merge Token manager's constructor
-//
-//*********************************************************************************************************
-MergeTokenManager::MergeTokenManager(MDTOKENMAP *pTkMapList, IUnknown *pHandler)
-{
- m_cRef = 1;
- m_pTkMapList = pTkMapList;
- m_pDefaultHostRemap = NULL;
- if (pHandler)
- pHandler->QueryInterface(IID_IMapToken, (void **) &m_pDefaultHostRemap);
-} // TokenManager::TokenManager()
-
-
-
-//*********************************************************************************************************
-//
-// Merge Token manager's destructor
-//
-//*********************************************************************************************************
-MergeTokenManager::~MergeTokenManager()
-{
- if (m_pDefaultHostRemap)
- m_pDefaultHostRemap->Release();
-} // TokenManager::~TokenManager()
-
-
-
-
-ULONG MergeTokenManager::AddRef()
-{
- return InterlockedIncrement(&m_cRef);
-} // TokenManager::AddRef()
-
-
-
-ULONG MergeTokenManager::Release()
-{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef)
- delete this;
- return (cRef);
-} // TokenManager::Release()
-
-
-HRESULT MergeTokenManager::QueryInterface(REFIID riid, void **ppUnk)
-{
- if (ppUnk == NULL)
- return E_INVALIDARG;
-
- if (IsEqualIID(riid, IID_IMapToken))
- {
- //*ppUnk = (IUnknown *) (IMapToken *) this;
- // it should return the accurate type requested,
- // if IUnknown is returned, it will finally converted to IMapToken*
- *ppUnk = (IMapToken *) this;
- }
- else if (IsEqualIID(riid, IID_IUnknown))
- {
- // add query handling for IUnknown
- // this upcasting (converting a derived-class
- // reference or pointer to a base-class) is safe
- *ppUnk = (IUnknown *) this;
- }
- else
- {
- *ppUnk = NULL;
- return (E_NOINTERFACE);
- }
-
- AddRef();
- return (S_OK);
-} // TokenManager::QueryInterface
-
-
-
-//*********************************************************************************************************
-//
-// Token manager keep tracks a list of tokenmaps. Each tokenmap corresponding
-// to an imported scope. Note that with this, we do have problem in how to
-// tell linker regarding the token movement when the token is added by Define
-// rather than merge. This should be fixed with new merge implementation.
-// The tkImp is the old tokens in the emit scope, tkEmit is the new token in the
-// emit scope. We need to find the token from an import scope that is resolved
-// to the tkImp. We then need to tell linker about this token movement.
-// If we don't find any import scope which generates the tkImp token, that is
-// this tkImp is generated by calling DefinXXX directly on the final merged scope.
-// Then we use the default host remap to send the notification.
-//
-//*********************************************************************************************************
-HRESULT MergeTokenManager::Map(mdToken tkImp, mdToken tkEmit)
-{
- HRESULT hr = NOERROR;
- MDTOKENMAP *pTkMapList = m_pTkMapList;
- bool fFoundInImport = false;
- int iPosition;
- TOKENREC *pRec;
-
- _ASSERTE(m_pTkMapList);
- while ( pTkMapList )
- {
- // FindWithToToken will return the first match with the To token.
- // pTkMapList is sorted with To token. It might contain several From tokens
- // that map to the To token due to ref to def optimiation. Make sure that
- // all notification is sent to all of these From tokens.
- //
- if ( pTkMapList->FindWithToToken(tkImp, &iPosition) )
- {
- // make sure that we don't walk over the last entry
- while (iPosition < pTkMapList->Count())
- {
- pRec = pTkMapList->Get(iPosition);
- if (pRec->m_tkTo != tkImp)
- {
- // we are done!
- break;
- }
-
- // more matching record...
- fFoundInImport = true;
- if (pTkMapList->m_pMap)
- hr = pTkMapList->m_pMap->Map(pRec->m_tkFrom, tkEmit);
- _ASSERTE(SUCCEEDED(hr));
- IfFailGo( hr );
- iPosition++;
- }
- }
- pTkMapList = pTkMapList->m_pNextMap;
- }
-
- if (fFoundInImport == false && m_pDefaultHostRemap)
- {
- // use the default remap to send the notification
- IfFailGo( m_pDefaultHostRemap->Map(tkImp, tkEmit) );
- }
-ErrExit:
- return hr;
-}
-
-
-
//*********************************************************************************************************
//
// CMapToken's constructor
diff --git a/src/md/enc/stgio.cpp b/src/md/enc/stgio.cpp
index 27d5ff2c5d..9dea3cb689 100644
--- a/src/md/enc/stgio.cpp
+++ b/src/md/enc/stgio.cpp
@@ -42,17 +42,10 @@
#include "pedecoder.inl"
//********** Types. ***********************************************************
-#if !defined(FEATURE_METADATA_STANDALONE_WINRT_RO)
#define SMALL_ALLOC_MAP_SIZE (64 * 1024) // 64 kb is the minimum size of virtual
// memory you can allocate, so anything
// less is a waste of VM resources.
-#else //FEATURE_METADATA_STANDALONE_WINRT_RO
-// RoMetadata.dll is required to call CreateFileMapping on all WinMD files (even small ones) to use
-// Code Intergrity checks on Win8 - see code:#EnableCodeIntegrity
-#define SMALL_ALLOC_MAP_SIZE 0
-
-#endif //FEATURE_METADATA_STANDALONE_WINRT_RO
#define MIN_WRITE_CACHE_BYTES (16 * 1024) // 16 kb for a write back cache
@@ -154,7 +147,6 @@ HRESULT StgIO::Open( // Return code.
m_pData = (void *) pbBuff;
m_cbData = cbBuff;
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// All access to data will be by memory provided.
if ((fFlags & DBPROP_TMODEF_SHAREDMEM) == DBPROP_TMODEF_SHAREDMEM)
{
@@ -163,7 +155,6 @@ HRESULT StgIO::Open( // Return code.
m_iType = STGIO_SHAREDMEM;
}
else
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
{
m_iType = STGIO_MEM;
}
@@ -359,7 +350,6 @@ void StgIO::Close()
{
switch (m_iType)
{
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// Free any allocated memory.
case STGIO_SHAREDMEM:
if (m_pBaseData != NULL)
@@ -368,7 +358,6 @@ void StgIO::Close()
m_pBaseData = NULL;
break;
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_MEM:
case STGIO_HFILEMEM:
@@ -538,9 +527,7 @@ HRESULT StgIO::Read( // Return code.
// Simply copy the data from our data.
case STGIO_MEM:
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_SHAREDMEM:
-#endif
case STGIO_HFILEMEM:
{
_ASSERTE(m_pData && m_cbData);
@@ -686,9 +673,7 @@ HRESULT StgIO::Seek( // New offset.
break;
case STGIO_MEM:
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_SHAREDMEM:
-#endif
case STGIO_HFILEMEM:
case STGIO_HMODULE:
{
@@ -770,9 +755,7 @@ HRESULT StgIO::MapFileToMem( // Return code.
if (IsBackingStore() ||
IsMemoryMapped() ||
(m_iType == STGIO_MEM) ||
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
(m_iType == STGIO_SHAREDMEM) ||
-#endif
(m_iType == STGIO_HFILEMEM))
{
ptr = m_pData;
@@ -854,24 +837,13 @@ HRESULT StgIO::MapFileToMem( // Return code.
_ASSERTE(m_hMapping == 0);
DWORD dwProtectionFlags = PAGE_READONLY;
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- //#EnableCodeIntegrity
- // RoMetadata.dll is required to always map (WinMD) files with SEC_IMAGE to enable Code Integrity checkes on Win8
- // Note: MidlRtMd.dll cannot do the same, because it runs on pre-Win8 OS versions where SEC_IMAGE-mapping will likely
- // refuse WinMD files (they are Win8+ only in PE headers)
- dwProtectionFlags |= SEC_IMAGE;
-#endif
if ((m_hMapping = WszCreateFileMapping(m_hFile, pAttributes, dwProtectionFlags,
0, 0, nullptr)) == 0)
{
return (MapFileError(GetLastError()));
}
-#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
- m_mtMappedType = MTYPE_IMAGE;
-#else // FEATURE_METADATA_STANDALONE_WINRT_RO
m_mtMappedType = MTYPE_FLAT;
-#endif // FEATURE_METADATA_STANDALONE_WINRT_RO
// Check to see if the memory already exists, in which case we have
// no guarantees it is the right piece of data.
if (GetLastError() == ERROR_ALREADY_EXISTS)
@@ -958,7 +930,6 @@ ErrExit:
HRESULT StgIO::ReleaseMappingObject() // Return code.
{
// Check type first.
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
if (m_iType != STGIO_SHAREDMEM)
{
_ASSERTE(FALSE);
@@ -982,7 +953,6 @@ HRESULT StgIO::ReleaseMappingObject() // Return code.
VERIFY(CloseHandle(m_hMapping));
m_hMapping = 0;
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
return S_OK;
}
@@ -998,7 +968,6 @@ HRESULT StgIO::SetBaseRange( // Return code.
void *pbStart, // Start of file data.
ULONG cbSize) // How big is the range.
{
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
if (m_iType == STGIO_SHAREDMEM)
{
// The base range must be inside of the current range.
@@ -1006,7 +975,6 @@ HRESULT StgIO::SetBaseRange( // Return code.
_ASSERTE(((LONG_PTR) pbStart >= (LONG_PTR) m_pBaseData));
_ASSERTE(((LONG_PTR) pbStart + cbSize <= (LONG_PTR) m_pBaseData + m_cbData));
}
-#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
// Save the base range per user request.
m_pData = pbStart;
@@ -1117,9 +1085,7 @@ HRESULT StgIO::GetPtrForMem( // Return code.
// Memory version or memory mapped file work the same way.
else if (IsMemoryMapped() ||
(m_iType == STGIO_MEM) ||
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
(m_iType == STGIO_SHAREDMEM) ||
-#endif
(m_iType == STGIO_HFILEMEM))
{
if (!(cbStart <= m_cbData))
@@ -1245,9 +1211,7 @@ HRESULT StgIO::WriteToDisk( // Return code.
// We cannot write to fixed read/only memory or LoadLibrary module.
case STGIO_HMODULE:
case STGIO_MEM:
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
case STGIO_SHAREDMEM:
-#endif
_ASSERTE(0);
hr = BadError(E_UNEXPECTED);
break;
@@ -1384,9 +1348,7 @@ int StgIO::IsAlignedPtr(ULONG_PTR Value, int iAlignment)
void *ptrStart = NULL;
if ((m_iType == STGIO_STREAM) ||
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
(m_iType == STGIO_SHAREDMEM) ||
-#endif
(m_iType == STGIO_MEM))
{
return ((Value - (ULONG_PTR) m_pData) % iAlignment == 0);
diff --git a/src/md/enc/stgtiggerstorage.cpp b/src/md/enc/stgtiggerstorage.cpp
index 436b3d72e3..2c8420d02d 100644
--- a/src/md/enc/stgtiggerstorage.cpp
+++ b/src/md/enc/stgtiggerstorage.cpp
@@ -138,9 +138,6 @@ TiggerStorage::GetDefaultVersion(
if (g_pDefaultVersion == NULL)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- g_pDefaultVersion = "";
-#else //!FEATURE_METADATA_STANDALONE_WINRT
#ifndef DACCESS_COMPILE
HRESULT hr;
@@ -170,7 +167,6 @@ TiggerStorage::GetDefaultVersion(
#else
DacNotImpl();
#endif //DACCESS_COMPILE
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
*ppVersion = g_pDefaultVersion;
diff --git a/src/md/enc/wks/CMakeLists.txt b/src/md/enc/wks/CMakeLists.txt
index df7664187d..2c0a2b1af5 100644
--- a/src/md/enc/wks/CMakeLists.txt
+++ b/src/md/enc/wks/CMakeLists.txt
@@ -1,4 +1,6 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDRUNTIMERW_SOURCES)
add_library_clr(mdruntimerw_wks ${MDRUNTIMERW_SOURCES})
diff --git a/src/md/hotdata/hotdataformat.h b/src/md/hotdata/hotdataformat.h
index 0823010611..3431d18deb 100644
--- a/src/md/hotdata/hotdataformat.h
+++ b/src/md/hotdata/hotdataformat.h
@@ -35,7 +35,7 @@ namespace MetaData
// #HotMetaData
// To help with startup time, we create a section of metadata that is only that meta-data that was touched
// durring IBC profiling. Given an offset into a pool this checks if we have any hot data associated with
-// it. If we do we return a poitner to it, otherwse we return NULL.
+// it. If we do we return a pointer to it, otherwse we return NULL.
#include <pshpack1.h>
diff --git a/src/md/inc/assemblymdinternaldisp.h b/src/md/inc/assemblymdinternaldisp.h
index 91b7d2cc29..8e8017ee9b 100644
--- a/src/md/inc/assemblymdinternaldisp.h
+++ b/src/md/inc/assemblymdinternaldisp.h
@@ -14,710 +14,5 @@
#include "../runtime/mdinternalro.h"
-#ifdef FEATURE_FUSION
-
-#include "fusionpriv.h"
-
-struct CORCOMPILE_VERSION_INFO;
-struct CORCOMPILE_DEPENDENCY;
-
-//*****************************************************************************
-// This class can support the IMetaDataAssemblyImport and some funcationalities
-// of IMetaDataImport on the internal import interface (IMDInternalImport).
-//*****************************************************************************
-class AssemblyMDInternalImport :
- public IMetaDataAssemblyImport,
- public IMetaDataImport2,
-#ifdef FEATURE_PREJIT
- public IGetIMDInternalImport,
-#endif //FEATURE_PREJIT
- public ISNAssemblySignature
-#ifdef FEATURE_PREJIT
- , public INativeImageInstallInfo
-#endif // FEATURE_PREJIT
-{
-public:
- AssemblyMDInternalImport(IMDInternalImport *pMDInternalImport);
- ~AssemblyMDInternalImport();
-
- // *** IUnknown methods ***
- STDMETHODIMP QueryInterface(REFIID riid, void** ppUnk);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- // *** IMetaDataAssemblyImport methods ***
- STDMETHODIMP GetAssemblyProps ( // S_OK or error.
- mdAssembly mda, // [IN] The Assembly for which to get the properties.
- const void **ppbPublicKey, // [OUT] Pointer to the public key.
- ULONG *pcbPublicKey, // [OUT] Count of bytes in the public key.
- ULONG *pulHashAlgId, // [OUT] Hash Algorithm.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- DWORD *pdwAssemblyFlags); // [OUT] Flags.
-
- STDMETHODIMP GetAssemblyRefProps ( // S_OK or error.
- mdAssemblyRef mdar, // [IN] The AssemblyRef for which to get the properties.
- const void **ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token.
- ULONG *pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- const void **ppbHashValue, // [OUT] Hash blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the hash blob.
- DWORD *pdwAssemblyRefFlags); // [OUT] Flags.
-
- STDMETHODIMP GetFileProps ( // S_OK or error.
- mdFile mdf, // [IN] The File for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- const void **ppbHashValue, // [OUT] Pointer to the Hash Value Blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the Hash Value Blob.
- DWORD *pdwFileFlags); // [OUT] Flags.
-
- STDMETHODIMP GetExportedTypeProps ( // S_OK or error.
- mdExportedType mdct, // [IN] The ExportedType for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef or mdExportedType.
- mdTypeDef *ptkTypeDef, // [OUT] TypeDef token within the file.
- DWORD *pdwExportedTypeFlags); // [OUT] Flags.
-
- STDMETHODIMP GetManifestResourceProps ( // S_OK or error.
- mdManifestResource mdmr, // [IN] The ManifestResource for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ManifestResource.
- DWORD *pdwOffset, // [OUT] Offset to the beginning of the resource within the file.
- DWORD *pdwResourceFlags); // [OUT] Flags.
-
- STDMETHODIMP EnumAssemblyRefs ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdAssemblyRef rAssemblyRefs[], // [OUT] Put AssemblyRefs here.
- ULONG cMax, // [IN] Max AssemblyRefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP EnumFiles ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdFile rFiles[], // [OUT] Put Files here.
- ULONG cMax, // [IN] Max Files to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP EnumExportedTypes ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdExportedType rExportedTypes[], // [OUT] Put ExportedTypes here.
- ULONG cMax, // [IN] Max ExportedTypes to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP EnumManifestResources ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdManifestResource rManifestResources[], // [OUT] Put ManifestResources here.
- ULONG cMax, // [IN] Max Resources to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHODIMP GetAssemblyFromScope ( // S_OK or error
- mdAssembly *ptkAssembly); // [OUT] Put token here.
-
- STDMETHODIMP FindExportedTypeByName ( // S_OK or error
- LPCWSTR szName, // [IN] Name of the ExportedType.
- mdToken mdtExportedType, // [IN] ExportedType for the enclosing class.
- mdExportedType *ptkExportedType); // [OUT] Put the ExportedType token here.
-
- STDMETHODIMP FindManifestResourceByName ( // S_OK or error
- LPCWSTR szName, // [IN] Name of the ManifestResource.
- mdManifestResource *ptkManifestResource); // [OUT] Put the ManifestResource token here.
-
- STDMETHOD_(void, CloseEnum)(
- HCORENUM hEnum); // Enum to be closed.
-
- STDMETHODIMP FindAssembliesByName ( // S_OK or error
- LPCWSTR szAppBase, // [IN] optional - can be NULL
- LPCWSTR szPrivateBin, // [IN] optional - can be NULL
- LPCWSTR szAssemblyName, // [IN] required - this is the assembly you are requesting
- IUnknown *ppIUnk[], // [OUT] put IMetaDataAssemblyImport pointers here
- ULONG cMax, // [IN] The max number to put
- ULONG *pcAssemblies); // [OUT] The number of assemblies returned.
-
- // *** IMetaDataImport methods ***
- STDMETHOD(CountEnum)(HCORENUM hEnum, ULONG *pulCount);
- STDMETHOD(ResetEnum)(HCORENUM hEnum, ULONG ulPos);
- STDMETHOD(EnumTypeDefs)(HCORENUM *phEnum, mdTypeDef rTypeDefs[],
- ULONG cMax, ULONG *pcTypeDefs);
- STDMETHOD(EnumInterfaceImpls)(HCORENUM *phEnum, mdTypeDef td,
- mdInterfaceImpl rImpls[], ULONG cMax,
- ULONG* pcImpls);
- STDMETHOD(EnumTypeRefs)(HCORENUM *phEnum, mdTypeRef rTypeRefs[],
- ULONG cMax, ULONG* pcTypeRefs);
-
- STDMETHOD(FindTypeDefByName)( // S_OK or error.
- LPCWSTR szTypeDef, // [IN] Name of the Type.
- mdToken tkEnclosingClass, // [IN] TypeDef/TypeRef for Enclosing class.
- mdTypeDef *ptd); // [OUT] Put the TypeDef token here.
-
- STDMETHOD(GetScopeProps)(
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Put the name here.
- ULONG cchName, // [IN] Size of name buffer in wide chars.
- ULONG * pchName, // [OUT] Put size of name (wide chars) here.
- GUID * pMvid); // [OUT, OPTIONAL] Put MVID here.
-
- STDMETHOD(GetModuleFromScope)( // S_OK.
- mdModule *pmd); // [OUT] Put mdModule token here.
-
- STDMETHOD(GetTypeDefProps)(
- mdTypeDef td, // [IN] TypeDef token for inquiry.
- __out_ecount_part_opt(cchTypeDef, *pchTypeDef)
- LPWSTR wszTypeDef, // [OUT] Put name here.
- ULONG cchTypeDef, // [IN] size of name buffer in wide chars.
- ULONG * pchTypeDef, // [OUT] put size of name (wide chars) here.
- DWORD * pdwTypeDefFlags, // [OUT] Put flags here.
- mdToken * ptkExtends); // [OUT] Put base class TypeDef/TypeRef here.
-
- STDMETHOD(GetInterfaceImplProps)( // S_OK or error.
- mdInterfaceImpl iiImpl, // [IN] InterfaceImpl token.
- mdTypeDef *pClass, // [OUT] Put implementing class token here.
- mdToken *ptkIface); // [OUT] Put implemented interface token here.
-
- STDMETHOD(GetTypeRefProps)(
- mdTypeRef tr, // [IN] TypeRef token.
- mdToken * ptkResolutionScope, // [OUT] Resolution scope, ModuleRef or AssemblyRef.
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Name of the TypeRef.
- ULONG cchName, // [IN] Size of buffer.
- ULONG * pchName); // [OUT] Size of Name.
-
- STDMETHOD(ResolveTypeRef)(mdTypeRef tr, REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd);
-
- STDMETHOD(EnumMembers)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMembersWithName)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethods)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdMethodDef rMethods[], // [OUT] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethodsWithName)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdMethodDef rMethods[], // [OU] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumFields)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdFieldDef rFields[], // [OUT] Put FieldDefs here.
- ULONG cMax, // [IN] Max FieldDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumFieldsWithName)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdFieldDef rFields[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
-
- STDMETHOD(EnumParams)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdParamDef rParams[], // [OUT] Put ParamDefs here.
- ULONG cMax, // [IN] Max ParamDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMemberRefs)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tkParent, // [IN] Parent token to scope the enumeration.
- mdMemberRef rMemberRefs[], // [OUT] Put MemberRefs here.
- ULONG cMax, // [IN] Max MemberRefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethodImpls)( // S_OK, S_FALSE, or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdToken rMethodBody[], // [OUT] Put Method Body tokens here.
- mdToken rMethodDecl[], // [OUT] Put Method Declaration tokens here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(EnumPermissionSets)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] if !NIL, token to scope the enumeration.
- DWORD dwActions, // [IN] if !0, return only these actions.
- mdPermission rPermission[], // [OUT] Put Permissions here.
- ULONG cMax, // [IN] Max Permissions to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(FindMember)(
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdToken *pmb); // [OUT] matching memberdef
-
- STDMETHOD(FindMethod)(
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMethodDef *pmb); // [OUT] matching memberdef
-
- STDMETHOD(FindField)(
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdFieldDef *pmb); // [OUT] matching memberdef
-
- STDMETHOD(FindMemberRef)(
- mdTypeRef td, // [IN] given typeRef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMemberRef *pmr); // [OUT] matching memberref
-
- STDMETHOD (GetMethodProps)(
- mdMethodDef mb, // The method for which to get props.
- mdTypeDef * pClass, // Put method's class here.
- __out_ecount_part_opt(cchMethod, *pchMethod)
- LPWSTR wszMethod, // Put method's name here.
- ULONG cchMethod, // Size of szMethod buffer in wide chars.
- ULONG * pchMethod, // Put actual size here.
- DWORD * pdwAttr, // Put flags here.
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG * pcbSigBlob, // [OUT] actual size of signature blob
- ULONG * pulCodeRVA, // [OUT] codeRVA
- DWORD * pdwImplFlags); // [OUT] Impl. Flags
-
- STDMETHOD(GetMemberRefProps)(
- mdMemberRef mr, // [IN] given memberref
- mdToken * ptk, // [OUT] Put classref or classdef here.
- __out_ecount_part_opt(cchMember, *pchMember)
- LPWSTR wszMember, // [OUT] buffer to fill for member's name
- ULONG cchMember, // [IN] the count of char of szMember
- ULONG * pchMember, // [OUT] actual count of char in member name
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to meta data blob value
- ULONG * pbSig); // [OUT] actual size of signature blob
-
- STDMETHOD(EnumProperties)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdProperty rProperties[], // [OUT] Put Properties here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcProperties); // [OUT] Put # put here.
-
- STDMETHOD(EnumEvents)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdEvent rEvents[], // [OUT] Put events here.
- ULONG cMax, // [IN] Max events to put.
- ULONG *pcEvents); // [OUT] Put # put here.
-
- STDMETHOD(GetEventProps)( // S_OK, S_FALSE, or error.
- mdEvent ev, // [IN] event token
- mdTypeDef *pClass, // [OUT] typedef containing the event declarion.
- LPCWSTR szEvent, // [OUT] Event name
- ULONG cchEvent, // [IN] the count of wchar of szEvent
- ULONG *pchEvent, // [OUT] actual count of wchar for event's name
- DWORD *pdwEventFlags, // [OUT] Event flags.
- mdToken *ptkEventType, // [OUT] EventType class
- mdMethodDef *pmdAddOn, // [OUT] AddOn method of the event
- mdMethodDef *pmdRemoveOn, // [OUT] RemoveOn method of the event
- mdMethodDef *pmdFire, // [OUT] Fire method of the event
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the event
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod); // [OUT] total number of other method of this event
-
- STDMETHOD(EnumMethodSemantics)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdToken rEventProp[], // [OUT] Put Event/Property here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcEventProp); // [OUT] Put # put here.
-
- STDMETHOD(GetMethodSemantics)( // S_OK, S_FALSE, or error.
- mdMethodDef mb, // [IN] method token
- mdToken tkEventProp, // [IN] event/property token.
- DWORD *pdwSemanticsFlags); // [OUT] the role flags for the method/propevent pair
-
- STDMETHOD(GetClassLayout) (
- mdTypeDef td, // [IN] give typedef
- DWORD *pdwPackSize, // [OUT] 1, 2, 4, 8, or 16
- COR_FIELD_OFFSET rFieldOffset[], // [OUT] field offset array
- ULONG cMax, // [IN] size of the array
- ULONG *pcFieldOffset, // [OUT] needed array size
- ULONG *pulClassSize); // [OUT] the size of the class
-
- STDMETHOD(GetFieldMarshal) (
- mdToken tk, // [IN] given a field's memberdef
- PCCOR_SIGNATURE *ppvNativeType, // [OUT] native type of this field
- ULONG *pcbNativeType); // [OUT] the count of bytes of *ppvNativeType
-
- STDMETHOD(GetRVA)( // S_OK or error.
- mdToken tk, // Member for which to set offset
- ULONG *pulCodeRVA, // The offset
- DWORD *pdwImplFlags); // the implementation flags
-
- STDMETHOD(GetPermissionSetProps) (
- mdPermission pm, // [IN] the permission token.
- DWORD *pdwAction, // [OUT] CorDeclSecurity.
- void const **ppvPermission, // [OUT] permission blob.
- ULONG *pcbPermission); // [OUT] count of bytes of pvPermission.
-
- STDMETHOD(GetSigFromToken)( // S_OK or error.
- mdSignature mdSig, // [IN] Signature token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to token.
- ULONG *pcbSig); // [OUT] return size of signature.
-
- STDMETHOD(GetModuleRefProps)(
- mdModuleRef mur, // [IN] moduleref token.
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] buffer to fill with the moduleref name.
- ULONG cchName, // [IN] size of szName in wide characters.
- ULONG * pchName); // [OUT] actual count of characters in the name.
-
- STDMETHOD(EnumModuleRefs)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdModuleRef rModuleRefs[], // [OUT] put modulerefs here.
- ULONG cmax, // [IN] max memberrefs to put.
- ULONG *pcModuleRefs); // [OUT] put # put here.
-
- STDMETHOD(GetTypeSpecFromToken)( // S_OK or error.
- mdTypeSpec typespec, // [IN] TypeSpec token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to TypeSpec signature
- ULONG *pcbSig); // [OUT] return size of signature.
-
- STDMETHOD(GetNameFromToken)( // <TODO>Not Recommended! May be removed!</TODO>
- mdToken tk, // [IN] Token to get name from. Must have a name.
- MDUTF8CSTR *pszUtf8NamePtr); // [OUT] Return pointer to UTF8 name in heap.
-
- STDMETHOD(EnumUnresolvedMethods)( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken rMethods[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens); // [OUT] Put # put here.
-
- STDMETHOD(GetUserString)(
- mdString stk, // [IN] String token.
- __out_ecount_part_opt(cchString, *pchString)
- LPWSTR wszString, // [OUT] Copy of string.
- ULONG cchString, // [IN] Max chars of room in szString.
- ULONG * pchString); // [OUT] How many chars in actual string.
-
- STDMETHOD(GetPinvokeMap)(
- mdToken tk, // [IN] FieldDef or MethodDef.
- DWORD * pdwMappingFlags, // [OUT] Flags used for mapping.
- __out_ecount_part_opt(cchImportName, *pchImportName)
- LPWSTR wszImportName, // [OUT] Import name.
- ULONG cchImportName, // [IN] Size of the name buffer.
- ULONG * pchImportName, // [OUT] Actual number of characters stored.
- mdModuleRef * pmrImportDLL); // [OUT] ModuleRef token for the target DLL.
-
- STDMETHOD(EnumSignatures)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdSignature rSignatures[], // [OUT] put signatures here.
- ULONG cmax, // [IN] max signatures to put.
- ULONG *pcSignatures); // [OUT] put # put here.
-
- STDMETHOD(EnumTypeSpecs)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdTypeSpec rTypeSpecs[], // [OUT] put TypeSpecs here.
- ULONG cmax, // [IN] max TypeSpecs to put.
- ULONG *pcTypeSpecs); // [OUT] put # put here.
-
- STDMETHOD(EnumUserStrings)( // S_OK or error.
- HCORENUM *phEnum, // [IN/OUT] pointer to the enum.
- mdString rStrings[], // [OUT] put Strings here.
- ULONG cmax, // [IN] max Strings to put.
- ULONG *pcStrings); // [OUT] put # put here.
-
- STDMETHOD(GetParamForMethodIndex)( // S_OK or error.
- mdMethodDef md, // [IN] Method token.
- ULONG ulParamSeq, // [IN] Parameter sequence.
- mdParamDef *ppd); // [IN] Put Param token here.
-
- STDMETHOD(EnumCustomAttributes)( // S_OK or error.
- HCORENUM *phEnum, // [IN, OUT] COR enumerator.
- mdToken tk, // [IN] Token to scope the enumeration, 0 for all.
- mdToken tkType, // [IN] Type of interest, 0 for all.
- mdCustomAttribute rCustomAttributes[], // [OUT] Put custom attribute tokens here.
- ULONG cMax, // [IN] Size of rCustomAttributes.
- ULONG *pcCustomAttributes); // [OUT, OPTIONAL] Put count of token values here.
-
- STDMETHOD(GetCustomAttributeProps)( // S_OK or error.
- mdCustomAttribute cv, // [IN] CustomAttribute token.
- mdToken *ptkObj, // [OUT, OPTIONAL] Put object token here.
- mdToken *ptkType, // [OUT, OPTIONAL] Put AttrType token here.
- void const **ppBlob, // [OUT, OPTIONAL] Put pointer to data here.
- ULONG *pcbSize); // [OUT, OPTIONAL] Put size of date here.
-
- STDMETHOD(FindTypeRef)(
- mdToken tkResolutionScope, // [IN] ModuleRef, AssemblyRef or TypeRef.
- LPCWSTR szName, // [IN] TypeRef Name.
- mdTypeRef *ptr); // [OUT] matching TypeRef.
-
- STDMETHOD(GetMemberProps)(
- mdToken mb, // The member for which to get props.
- mdTypeDef * pClass, // Put member's class here.
- __out_ecount_part_opt(cchMember, *pchMember)
- LPWSTR wszMember, // Put member's name here.
- ULONG cchMember, // Size of szMember buffer in wide chars.
- ULONG * pchMember, // Put actual size here
- DWORD * pdwAttr, // Put flags here.
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG * pcbSigBlob, // [OUT] actual size of signature blob
- ULONG * pulCodeRVA, // [OUT] codeRVA
- DWORD * pdwImplFlags, // [OUT] Impl. Flags
- DWORD * pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT * ppValue, // [OUT] constant value
- ULONG * pcchValue); // [OUT] size of constant string in chars, 0 for non-strings.
-
- STDMETHOD(GetFieldProps)(
- mdFieldDef mb, // The field for which to get props.
- mdTypeDef * pClass, // Put field's class here.
- __out_ecount_part_opt(cchField, *pchField)
- LPWSTR szField, // Put field's name here.
- ULONG cchField, // Size of szField buffer in wide chars.
- ULONG * pchField, // Put actual size here.
- DWORD * pdwAttr, // Put flags here.
- PCCOR_SIGNATURE * ppvSigBlob, // [OUT] point to the blob value of meta data.
- ULONG * pcbSigBlob, // [OUT] actual size of signature blob.
- DWORD * pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*.
- UVCP_CONSTANT * ppValue, // [OUT] constant value.
- ULONG * pcchValue); // [OUT] size of constant string in chars, 0 for non-strings.
-
- STDMETHOD(GetPropertyProps)( // S_OK, S_FALSE, or error.
- mdProperty prop, // [IN] property token
- mdTypeDef *pClass, // [OUT] typedef containing the property declarion.
- LPCWSTR szProperty, // [OUT] Property name
- ULONG cchProperty, // [IN] the count of wchar of szProperty
- ULONG *pchProperty, // [OUT] actual count of wchar for property name
- DWORD *pdwPropFlags, // [OUT] property flags.
- PCCOR_SIGNATURE *ppvSig, // [OUT] property type. pointing to meta data internal blob
- ULONG *pbSig, // [OUT] count of bytes in *ppvSig
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppDefaultValue, // [OUT] constant value
- ULONG *pcchDefaultValue, // [OUT] size of constant string in chars, 0 for non-strings.
- mdMethodDef *pmdSetter, // [OUT] setter method of the property
- mdMethodDef *pmdGetter, // [OUT] getter method of the property
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the property
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod); // [OUT] total number of other method of this property
-
- STDMETHOD(GetParamProps)(
- mdParamDef tk, // [IN]The Parameter.
- mdMethodDef * pmd, // [OUT] Parent Method token.
- ULONG * pulSequence, // [OUT] Parameter sequence.
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Put name here.
- ULONG cchName, // [OUT] Size of name buffer.
- ULONG * pchName, // [OUT] Put actual size of name here.
- DWORD * pdwAttr, // [OUT] Put flags here.
- DWORD * pdwCPlusTypeFlag, // [OUT] Flag for value type. selected ELEMENT_TYPE_*.
- UVCP_CONSTANT * ppValue, // [OUT] Constant value.
- ULONG * pcchValue); // [OUT] size of constant string in chars, 0 for non-strings.
-
- STDMETHOD(GetCustomAttributeByName)( // S_OK or error.
- mdToken tkObj, // [IN] Object with Custom Attribute.
- LPCWSTR szName, // [IN] Name of desired Custom Attribute.
- const void **ppData, // [OUT] Put pointer to data here.
- ULONG *pcbData); // [OUT] Put size of data here.
-
- STDMETHOD_(BOOL, IsValidToken)( // True or False.
- mdToken tk); // [IN] Given token.
-
- STDMETHOD(GetNestedClassProps)( // S_OK or error.
- mdTypeDef tdNestedClass, // [IN] NestedClass token.
- mdTypeDef *ptdEnclosingClass); // [OUT] EnclosingClass token.
-
- STDMETHOD(GetNativeCallConvFromSig)( // S_OK or error.
- void const *pvSig, // [IN] Pointer to signature.
- ULONG cbSig, // [IN] Count of signature bytes.
- ULONG *pCallConv); // [OUT] Put calling conv here (see CorPinvokemap).
-
- STDMETHOD(IsGlobal)( // S_OK or error.
- mdToken pd, // [IN] Type, Field, or Method token.
- int *pbGlobal); // [OUT] Put 1 if global, 0 otherwise.
-
-//*****************************************************************************
-// IMetaDataImport2 methods
-//*****************************************************************************
- STDMETHOD(GetMethodSpecProps)(
- mdMethodSpec mi, // [IN] The method instantiation
- mdToken *tkParent, // [OUT] MethodDef or MemberRef
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob); // [OUT] actual size of signature blob
-
- STDMETHOD(GetGenericParamProps)(
- mdGenericParam gp, // [IN] GenericParam
- ULONG * pulParamSeq, // [OUT] Index of the type parameter
- DWORD * pdwParamFlags, // [OUT] Flags, for future use (e.g. variance)
- mdToken * ptOwner, // [OUT] Owner (TypeDef or MethodDef)
- DWORD * pdwReserved, // [OUT] For future use (e.g. non-type parameters)
- __out_ecount_part_opt(cchName, *pchName)
- LPWSTR wszName, // [OUT] Put name here
- ULONG cchName, // [IN] Size of buffer
- ULONG * pchName); // [OUT] Put size of name (wide chars) here.
-
- STDMETHOD(GetGenericParamConstraintProps)( // S_OK or error.
- mdGenericParamConstraint gpc, // [IN] GenericParamConstraint
- mdGenericParam *ptGenericParam, // [OUT] GenericParam that is constrained
- mdToken *ptkConstraintType); // [OUT] TypeDef/Ref/Spec constraint
-
- STDMETHOD(EnumGenericParams)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] TypeDef or MethodDef whose generic parameters are requested
- mdGenericParam rGenericParams[], // [OUT] Put GenericParams here.
- ULONG cMax, // [IN] Max GenericParams to put.
- ULONG *pcGenericParams); // [OUT] Put # put here.
-
- STDMETHOD(EnumGenericParamConstraints)( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdGenericParam tk, // [IN] GenericParam whose constraints are requested
- mdGenericParamConstraint rGenericParamConstraints[], // [OUT] Put GenericParamConstraints here.
- ULONG cMax, // [IN] Max GenericParamConstraints to put.
- ULONG *pcGenericParamConstraints); // [OUT] Put # put here.
-
- STDMETHOD(EnumMethodSpecs)(
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] MethodDef or MemberRef whose MethodSpecs are requested
- mdMethodSpec rMethodSpecs[], // [OUT] Put MethodSpecs here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcMethodSpecs); // [OUT] Put actual count here.
-
- STDMETHOD(GetPEKind)( // S_OK or error.
- DWORD* pdwPEKind, // [OUT] The kind of PE (0 - not a PE)
- DWORD* pdwMachine); // [OUT] Machine as defined in NT header
-
- STDMETHOD(GetVersionString)(
- __out_ecount_part_opt(ccBufSize, *pccBufSize)
- LPWSTR pwzBuf, // Put version string here.
- DWORD ccBufSize, // [in] Size of the buffer, in wide chars.
- DWORD * pccBufSize); // [out] Size of the version string, wide chars, including terminating nul.
-
-
- // *** ISNAssemblySignature methods ***
-
- STDMETHOD(GetSNAssemblySignature)( // S_OK or error.
- BYTE *pbSig, // [IN, OUT] Buffer to write signature
- DWORD *pcbSig); // [IN, OUT] Size of buffer, bytes written
-
-
-#ifdef FEATURE_PREJIT
- // *** IGetIMDInternalImport methods ***
-
- STDMETHOD(GetIMDInternalImport) (
- IMDInternalImport ** ppIMDInternalImport);
-
- // *** INativeImageInstallInfo ***
-
- STDMETHOD (GetSignature) (
- CORCOMPILE_NGEN_SIGNATURE * pNgenSign
- );
-
- STDMETHOD (GetVersionInfo) (
- CORCOMPILE_VERSION_INFO * pVersionInfo
- );
-
-
- STDMETHOD (GetILSignature) (
- CORCOMPILE_ASSEMBLY_SIGNATURE * pILSign
- );
-
- STDMETHOD (GetConfigMask) (
- DWORD * pConfigMask
- );
-
- STDMETHOD (EnumDependencies) (
- HCORENUM * phEnum,
- INativeImageDependency *rDeps[],
- ULONG cMax,
- DWORD * pdwCount
- );
-
- STDMETHOD (GetDependency) (
- const CORCOMPILE_NGEN_SIGNATURE *pcngenSign,
- CORCOMPILE_DEPENDENCY *pDep
- );
-
-
-#endif // FEATURE_PREJIT
-
- //------------ setters for privates -----------
- void SetHandle(HCORMODULE hHandle)
- {
- RuntimeAddRefHandle(hHandle);
- m_pHandle = hHandle;
- }
-
- void SetPEKind(DWORD dwPEKind)
- {
- m_dwPEKind = dwPEKind;
- }
-
- void SetMachine(DWORD dwMachine)
- {
- m_dwMachine = dwMachine;
- }
-
- void SetVersionString(const char* szVersionString)
- {
- m_szVersionString = szVersionString;
- }
-
- void SetBase(LPVOID base)
- {
- m_pBase = base;
- }
-
-#ifdef FEATURE_PREJIT
- void SetZapVersionInfo(CORCOMPILE_VERSION_INFO * info, CORCOMPILE_DEPENDENCY * pDeps, COUNT_T cDeps)
- {
- m_pZapVersionInfo = info;
- m_pZapDependencies = pDeps;
- m_cZapDependencies = cDeps;
- }
-#endif // FEATURE_PREJIT
-
-private:
- LONG m_cRef;
- HCORMODULE m_pHandle; // Handle to a cached PE image
- LPVOID m_pBase; // File mapping (if runtime is not inited)
-#ifdef FEATURE_PREJIT
- struct CORCOMPILE_VERSION_INFO * m_pZapVersionInfo; // Zap image information
- struct CORCOMPILE_DEPENDENCY * m_pZapDependencies; // Zap Dependancies directory
- COUNT_T m_cZapDependencies;
-#endif // FEATURE_PREJIT
- IMDInternalImport * m_pMDInternalImport;
- DWORD m_dwPEKind;
- DWORD m_dwMachine;
- const char * m_szVersionString;
-#ifdef _DEBUG
- IMetaDataAssemblyImport * m_pDebugMDImport;
-#endif //_DEBUG
-};
-
-#endif // FEATURE_FUSION
#endif // __AssemblyMDInternalDispenser__h__
diff --git a/src/md/inc/imptlb.h b/src/md/inc/imptlb.h
deleted file mode 100644
index ba2981a415..0000000000
--- a/src/md/inc/imptlb.h
+++ /dev/null
@@ -1,777 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-//*****************************************************************************
-// File: imptlb.h
-//
-
-//
-// TypeLib importer.
-//*****************************************************************************
-#ifndef __imptlb_h__
-#define __imptlb_h__
-
-#ifndef FEATURE_COMINTEROP
-#error FEATURE_COMINTEROP is required for this file
-#endif // FEATURE_COMINTEROP
-#ifndef FEATURE_COMINTEROP_TLB_SUPPORT
-#error FEATURE_COMINTEROP_TLB_SUPPORT is required for this file
-#endif // FEATURE_COMINTEROP_TLB_SUPPORT
-
-//#define TLB_STATS
-
-#define MAX_TLB_VT VT_LPWSTR + 1
-#define MAX_INIT_SIG 3
-#define MAX_COM_GUID_SIG 6
-#define MAX_COM_ADDLISTENER_SIG 8
-#define MAX_COM_REMOVELISTENER_SIG 8
-#define CB_MAX_ELEMENT_TYPE 4
-
-// Forward declarations.
-struct ITypeLibImporterNotifySink;
-class Assembly;
-class Module;
-class CImportTlb;
-
-//*****************************************************************************
-// Class to perform memory management. Memory is not moved as the heap is
-// expanded, and all of the allocations are cleaned up in the destructor.
-//*****************************************************************************
-class CWCHARPool : public StgPool
-{
-public:
- CWCHARPool() : StgPool()
- {
- HRESULT hr = InitNew();
- _ASSERTE(hr == S_OK);
- }
-
- // Allocate some bytes from the pool.
- WCHAR * Alloc(ULONG nChars)
- {
- BYTE *pRslt;
- // Convert from characters to bytes.
- nChars *= sizeof(WCHAR);
- if (nChars > GetCbSegAvailable())
- if (!Grow(nChars))
- return 0;
- pRslt = GetNextLocation();
- SegAllocate(nChars);
- return (WCHAR*)pRslt;
- }
-}; // class CDescPool : public StgPool
-
-
-//*****************************************************************************
-// This helper method is used to track an url to typeref token. This makes
-// defining new typerefs faster.
-//*****************************************************************************
-class CImpTlbTypeRef
-{
-public:
- CImpTlbTypeRef() { }
- ~CImpTlbTypeRef() { m_Map.Clear(); }
-
- //*****************************************************************************
- // Look for an existing typeref in the map and return if found. If not found,
- // then create a new one and add it to the map for later.
- //*****************************************************************************
- HRESULT DefineTypeRef( // S_OK or error.
- IMetaDataEmit *pEmit, // Emit interface.
- mdAssemblyRef ar, // Containing assembly.
- const LPCWSTR szURL, // URL of the TypeDef, wide chars.
- mdTypeRef *ptr); // Put mdTypeRef here
-
- class TokenOfTypeRefHashKey
- {
- public:
- mdToken tkResolutionScope; // TypeRef's resolution scope.
- LPCWSTR szName; // TypeRef's name.
- mdTypeRef tr; // The TypeRef's token.
- };
-
-private:
-
- class CTokenOfTypeRefHash : public CClosedHash<class TokenOfTypeRefHashKey>
- {
- public:
- typedef CClosedHash<class TokenOfTypeRefHashKey> Super;
- typedef TokenOfTypeRefHashKey T;
-
- CTokenOfTypeRefHash() : CClosedHash<class TokenOfTypeRefHashKey>(101) {}
- ~CTokenOfTypeRefHash() { Clear(); }
-
- virtual void Clear();
-
- unsigned int Hash(const void *pData) {return Hash((const T*)pData);}
- unsigned int Hash(const T *pData);
-
- unsigned int Compare(const void *p1, BYTE *p2) {return Compare((const T*)p1, (T*)p2);}
- unsigned int Compare(const T *p1, T *p2);
-
- ELEMENTSTATUS Status(BYTE *p) {return Status((T*)p);}
- ELEMENTSTATUS Status(T *p);
-
- void SetStatus(BYTE *p, ELEMENTSTATUS s) {SetStatus((T*)p, s);}
- void SetStatus(T *p, ELEMENTSTATUS s);
-
- void* GetKey(BYTE *p) {return GetKey((T*)p);}
- void *GetKey(T *p);
-
- T* Add(const T *pData);
-
- CWCHARPool m_Names; // Heap of names.
- };
-
- CTokenOfTypeRefHash m_Map; // Map of namespace to token.
-};
-
-
-//*****************************************************************************
-// This helper class is used to track source interface ITypeInfo*'s to event
-// information.
-//*****************************************************************************
-class ImpTlbEventInfo
-{
-public:
- LPCWSTR szSrcItfName; // The source interface name (the key).
- mdTypeRef trEventItf; // The event interface typedef.
- LPCWSTR szEventItfName; // The event interface name.
- LPCWSTR szEventProviderName; // The event provider name.
- Assembly* SrcItfAssembly; // The assembly where source interface resides.
-};
-
-class CImpTlbEventInfoMap : protected CClosedHash<class ImpTlbEventInfo>
-{
-public:
- typedef CClosedHash<class ImpTlbEventInfo> Super;
- typedef ImpTlbEventInfo T;
-
- CImpTlbEventInfoMap() : CClosedHash<class ImpTlbEventInfo>(101) {}
- ~CImpTlbEventInfoMap() { Clear(); }
-
- HRESULT AddEventInfo(LPCWSTR szSrcItfName, mdTypeRef trEventItf, LPCWSTR szEventItfName, LPCWSTR szEventProviderName, Assembly* SrcItfAssembly);
- ImpTlbEventInfo *FindEventInfo(LPCWSTR szSrcItfName);
-
- HRESULT GetEventInfoList(CQuickArray<ImpTlbEventInfo*> &qbEvInfoList);
-
-private:
- unsigned int Hash(const void *pData) {return Hash((const T*)pData);}
- unsigned int Hash(const T *pData);
-
- unsigned int Compare(const void *p1, BYTE *p2) {return Compare((const T*)p1, (T*)p2);}
- unsigned int Compare(const T *p1, T *p2);
-
- ELEMENTSTATUS Status(BYTE *p) {return Status((T*)p);}
- ELEMENTSTATUS Status(T *p);
-
- void SetStatus(BYTE *p, ELEMENTSTATUS s) {SetStatus((T*)p, s);}
- void SetStatus(T *p, ELEMENTSTATUS s);
-
- void* GetKey(BYTE *p) {return GetKey((T*)p);}
- void *GetKey(T *p);
-
- T* Add(const T *pData);
-
- CWCHARPool m_Names; // Heap of names.
-};
-
-
-#if defined(_UNICODE) || defined(UNICODE)
-#define _tHashString(szStr) HashString(szStr)
-#else
-#define _tHashString(szStr) HashStringA(szStr)
-#endif
-
-
-
-//*****************************************************************************
-// This helper template is used by the TStringMap to track an item by its
-// character name.
-//*****************************************************************************
-template <class T> class TStringMapItem : HASHENTRY
-{
-public:
- TStringMapItem() :
- m_szString(0)
- {
- LIMITED_METHOD_CONTRACT;
- }
- ~TStringMapItem()
- {
- LIMITED_METHOD_CONTRACT;
- delete [] m_szString;
- }
-
- HRESULT SetString(LPCTSTR szValue)
- {
- WRAPPER_NO_CONTRACT;
- int iLen = (int)(::_tcslen(szValue) + 1);
- if ((m_szString = new TCHAR[iLen]) == 0)
- return (OutOfMemory());
- ::_tcscpy_s((TCHAR*)m_szString, iLen, szValue);
- return (S_OK);
- }
-
-public:
- LPTSTR m_szString; // Key data.
- T m_value; // Value for this key.
-};
-
-
-//*****************************************************************************
-// IMPORTANT: This data structure is deprecated, please do not add any new uses.
-// The hashtable implementation that should be used instead is code:SHash.
-// If code:SHash does not work for you, talk to mailto:clrdeag.
-//*****************************************************************************
-// This template provides a map from string to item, determined by the template
-// type passed in.
-//*****************************************************************************
-template <class T, int iBuckets=17, class TAllocator=CNewData, int iMaxSize=4096>
-class TStringMap :
- protected CHashTableAndData<TAllocator>
-{
- typedef CHashTableAndData<TAllocator> Super;
-
-public:
- typedef TStringMapItem<T> TItemType;
- typedef TStringMapItem<long> TOffsetType;
-
-#ifndef DACCESS_COMPILE
-
- TStringMap() :
- CHashTableAndData<TAllocator>(iBuckets)
- {
- LIMITED_METHOD_CONTRACT;
- }
-
-//*****************************************************************************
-// This is the second part of construction where we do all of the work that
-// can fail. We also take the array of structs here because the calling class
-// presumably needs to allocate it in its NewInit.
-//*****************************************************************************
- HRESULT NewInit() // Return status.
- {
- WRAPPER_NO_CONTRACT;
- return (CHashTableAndData<TAllocator>::NewInit(
- CNewData::GrowSize(0)/sizeof(TItemType),
- sizeof(TItemType),
- iMaxSize));
- }
-
-//*****************************************************************************
-// For each item still allocated, invoke its dtor so it frees up anything it
-// holds onto.
-//*****************************************************************************
- void Clear()
- {
- WRAPPER_NO_CONTRACT;
- HASHFIND sSrch;
- TItemType *p = (TItemType *) FindFirstEntry(&sSrch);
-
- while (p != 0)
- {
- // Call dtor on the item, since m_value is contained the scalar
- // dtor will get called.
- p->~TStringMapItem<T>();
- p = (TItemType *) FindNextEntry(&sSrch);
- }
- CHashTableAndData<TAllocator>::Clear();
- }
-
-#endif // #ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// Retrieve an item by name.
-//*****************************************************************************
- T *GetItem( // Null or object.
- LPCTSTR szKey) // What to do the lookup on.
- {
- WRAPPER_NO_CONTRACT;
- TItemType sInfo;
- TItemType *ptr; // Working pointer.
-
- // Create a key.
- sInfo.m_szString = (LPTSTR) szKey;
-
- // Look it up in the hash table.
- ptr = (TItemType *) Super::Find( _tHashString(szKey), (SIZE_T) &sInfo);
-
- // Don't let dtor free our string.
- sInfo.m_szString = 0;
-
- // If pointer found, return to caller. To handle T's that have
- // an operator &(), find raw address without going through &m_value.
- if (ptr)
- return ((T *) ((BYTE *) ptr + offsetof(TOffsetType, m_value)));
- else
- return (0);
- }
-
-//*****************************************************************************
-// Initialize an iterator and return the first item.
-//*****************************************************************************
- TItemType *FindFirstEntry(
- HASHFIND *psSrch)
- {
- WRAPPER_NO_CONTRACT;
- TItemType *ptr = (TItemType *) Super::FindFirstEntry(psSrch);
-
- return (ptr);
- }
-
-//*****************************************************************************
-// Return the next item, via an iterator.
-//*****************************************************************************
- TItemType *FindNextEntry(
- HASHFIND *psSrch)
- {
- WRAPPER_NO_CONTRACT;
- TItemType *ptr = (TItemType *) Super::FindNextEntry(psSrch);
-
- return (ptr);
- }
-
-#ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// Add an item to the list.
-//*****************************************************************************
- HRESULT AddItem( // S_OK, or S_FALSE.
- LPCTSTR szKey, // The key value for the item.
- T &item) // Thing to add.
- {
- WRAPPER_NO_CONTRACT;
- TItemType *ptr; // Working pointer.
-
- // Allocate an entry in the hash table.
- if ((ptr = (TItemType *) this->Add( _tHashString(szKey))) == 0)
- return (OutOfMemory());
-
- // Fill the record.
- if (ptr->SetString(szKey) < 0)
- {
- DelItem(ptr);
- return (OutOfMemory());
- }
-
- // Call the placement new operator on the item so it can init itself.
- // To handle T's that have an operator &(), find raw address without
- // going through &m_value.
- T *p = new ((void *) ((BYTE *) ptr + offsetof(TOffsetType, m_value))) T;
- *p = item;
- return (S_OK);
- }
-
-//*****************************************************************************
-// Delete an item.
-//*****************************************************************************
- void DelItem(
- LPCTSTR szKey) // What to delete.
- {
- WRAPPER_NO_CONTRACT;
- TItemType sInfo;
- TItemType *ptr; // Working pointer.
-
- // Create a key.
- sInfo.m_szString = (LPTSTR) szKey;
-
- // Look it up in the hash table.
- ptr = (TItemType *) this->Find( _tHashString(szKey), (BYTE *) &sInfo);
-
- // Don't let dtor free our string.
- sInfo.m_szString = 0;
-
- // If found, delete.
- if (ptr)
- DelItem(ptr);
- }
-
-#endif // #ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// Compare the keys for two collections.
-//*****************************************************************************
- BOOL Cmp( // 0 or != 0.
- SIZE_T data, // Raw key data on lookup.
- const HASHENTRY *pElement) // The element to compare data against.
- {
- LIMITED_METHOD_DAC_CONTRACT;
- TItemType *p = (TItemType *) (size_t) pElement;
- return (::_tcscmp(((TItemType *) data)->m_szString, p->m_szString));
- }
-
-private:
- void DelItem(
- TItemType *pItem) // Entry to delete.
- {
- WRAPPER_NO_CONTRACT;
- // Need to destruct this item.
- pItem->~TStringMapItem<T>();
- CHashTableAndData<TAllocator>::Delete( HashString(pItem->m_szString), (HASHENTRY *)(void *)pItem);
- }
-};
-
-class CImpTlbReservedNames
-{
-public:
- CImpTlbReservedNames() {}
- ~CImpTlbReservedNames() {/*m_StringMap.Clear();*/}
-
-#ifndef DACCESS_COMPILE
- HRESULT Init() {return m_StringMap.NewInit();}
-
- void AddReservedName(LPCWSTR szName) {BOOL flag = TRUE; m_StringMap.AddItem(szName, flag);}
-#endif
- BOOL IsReservedName(LPCWSTR szName) {return m_StringMap.GetItem(szName) != 0;}
-
-private:
- TStringMap<BOOL> m_StringMap;
-};
-
-
-//*****************************************************************************
-// Helper class to keep track of the mappings from default interfaces to
-// class interfaces.
-//*****************************************************************************
-class ImpTlbClassItfInfo
-{
-public:
- IID ItfIID; // The IID of the interface.
- LPCWSTR szClassItfName; // The class interface name.
-};
-
-class CImpTlbDefItfToClassItfMap : protected CClosedHash<class ImpTlbClassItfInfo>
-{
-public:
- typedef CClosedHash<class ImpTlbClassItfInfo> Super;
- typedef ImpTlbClassItfInfo T;
-
- CImpTlbDefItfToClassItfMap();
- ~CImpTlbDefItfToClassItfMap();
-
- HRESULT Init(ITypeLib *pTlb, BSTR bstrNameSpace);
-
- LPCWSTR GetClassItfName(IID &rItfIID);
-
-private:
- HRESULT AddCoClassInterfaces(ITypeInfo *pCoClassITI, TYPEATTR *pCoClassTypeAttr);
-
- unsigned int Hash(const void *pData) {return Hash((const T*)pData);}
- unsigned int Hash(const T *pData);
-
- unsigned int Compare(const void *p1, BYTE *p2) {return Compare((const T*)p1, (T*)p2);}
- unsigned int Compare(const T *p1, T *p2);
-
- ELEMENTSTATUS Status(BYTE *p) {return Status((T*)p);}
- ELEMENTSTATUS Status(T *p);
-
- void SetStatus(BYTE *p, ELEMENTSTATUS s) {SetStatus((T*)p, s);}
- void SetStatus(T *p, ELEMENTSTATUS s);
-
- void* GetKey(BYTE *p) {return GetKey((T*)p);}
- void *GetKey(T *p);
-
- T* Add(const T *pData);
-
- CWCHARPool m_Names; // Heap of names.
- BSTR m_bstrNameSpace; // Namespace of the typelib.
-};
-
-
-//*****************************************************************************
-// Helper class to keep track of imported typelibs. Typically, a typelib
-// imports only 2 or 3 other typelibs, so a simple array is used.
-//*****************************************************************************
-struct CTlbRef
-{
- GUID guid; // GUID of referenced typelib.
- mdAssemblyRef ar; // AssemblyRef for the module containing reference.
- BSTR szNameSpace; // The namespace of the types contained in the assembly.
- BSTR szAsmName; // The assembly name.
- Assembly* Asm; // The assembly.
- CImpTlbDefItfToClassItfMap *pDefItfToClassItfMap; // The default interface to class interface map.
-
- ~CTlbRef()
- {
- SysFreeString(szNameSpace);
- SysFreeString(szAsmName);
- delete pDefItfToClassItfMap;
- }
-};
-
-class CImpTlbLibRef : public CQuickArray<CTlbRef>
-{
- typedef CQuickArray<CTlbRef> base;
-public:
- CImpTlbLibRef() {base::Shrink(0);}
- ~CImpTlbLibRef();
-
- HRESULT Add(ITypeLib *pITLB, CImportTlb *pImporter, mdAssemblyRef ar, BSTR wzNamespace, BSTR wzAsmName, Assembly* assm, CImpTlbDefItfToClassItfMap **ppMap);
- int Find(ITypeLib *pITLB, mdAssemblyRef *par, BSTR *pwzNamespace, BSTR *pwzAsmName, Assembly** assm, CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap);
-};
-
-
-class CImportTlb
-{
-public:
- static CImportTlb* CreateImporter(LPCWSTR szLibrary, ITypeLib *pitlb, BOOL bGenerateTCEAdapters, BOOL bUnsafeInterfaces, BOOL bSafeArrayAsSystemArray, BOOL bTransformDispRetVals, BOOL bPreventClassMembers, BOOL bSerializableValueClasses);
-
- CImportTlb();
- CImportTlb(LPCWSTR szLibrary, ITypeLib *pitlb, BOOL bGenerateTCEAdapters, BOOL bUnsafeInterfaces, BOOL bSafeArrayAsSystemArray, BOOL bTransformDispRetVals, BOOL bPreventClassMembers, BOOL bSerializableValueClasses);
- ~CImportTlb();
-
- HRESULT Import();
- HRESULT SetNamespace(WCHAR const *pNamespace);
- WCHAR *GetNamespace() {return m_wzNamespace;}
- HRESULT SetNotification(ITypeLibImporterNotifySink *pINotify);
- HRESULT SetMetaData(IUnknown *pIUnk);
- void SetAssembly(Assembly *pAssembly) {m_pAssembly = pAssembly;}
- void SetModule(Module *pModule) {m_pModule = pModule;}
- HRESULT GetNamespaceOfRefTlb(ITypeLib *pITLB, BSTR *pwzNamespace, CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap);
- HRESULT GetEventInfoList(CQuickArray<ImpTlbEventInfo*> &qbEvInfoList) {return m_EventInfoMap.GetEventInfoList(qbEvInfoList);}
-
- static HRESULT GetDefaultInterface(ITypeInfo *pCoClassTI, ITypeInfo **pDefaultItfTI);
-
-protected:
-
- struct MemberInfo
- {
- union
- {
- FUNCDESC *m_psFunc; // Pointer to FuncDesc.
- VARDESC *m_psVar; // Pointer to VarDesc.
- };
- LPWSTR m_pName; // Function/Prop's name, possibly decorated.
- int m_iMember; // The index of the member in the ITypeInfo.
- union
- {
- LPWSTR m_pName2; // Prop's second name, if any.
- mdToken m_mdFunc; // Function's token & semantics, if not property.
- USHORT m_msSemantics; // Semantics only.
- };
- void SetFuncInfo(mdMethodDef mdFunc, USHORT msSemantics) {m_mdFunc = RidFromToken(mdFunc) | (msSemantics<<24);}
- void GetFuncInfo(mdMethodDef &mdFunc, USHORT &msSemantics) {mdFunc = m_mdFunc&0xffffff | mdtMethodDef; msSemantics = m_mdFunc>>24;}
- };
-
-
- HRESULT ConvertTypeLib();
- HRESULT ConvertTypeInfo();
-
- HRESULT ExplicitlyImplementsIEnumerable(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL fLookupPartner = TRUE);
-
- HRESULT _NewLibraryObject();
- HRESULT ConvCoclass(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT ConvEnum(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT ConvRecord(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bUnion);
- HRESULT ConvIface(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bVtblGaps=true);
- HRESULT ConvDispatch(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bVtblGaps=true);
- HRESULT ConvModule(ITypeInfo *pITI, TYPEATTR *psAttr);
-
- HRESULT IsIUnknownDerived(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT IsIDispatchDerived(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT HasNewEnumMember(ITypeInfo *pItfTI);
- HRESULT FuncIsNewEnum(ITypeInfo *pITI, FUNCDESC *pFuncDesc, DWORD index);
- HRESULT PropertyIsNewEnum(ITypeInfo *pITI, VARDESC *pVarDesc, DWORD index);
-
- HRESULT HasObjectFields(ITypeInfo *pITI, TYPEATTR *psAttr);
- HRESULT IsObjectType(ITypeInfo *pITI, const TYPEDESC *pType);
- HRESULT CompareSigsIgnoringRetType(PCCOR_SIGNATURE pbSig1, ULONG cbSig1, PCCOR_SIGNATURE pbSig2, ULONG cbSig2);
-
- HRESULT FindMethod(mdTypeDef td, LPCWSTR szName, PCCOR_SIGNATURE pbSig, ULONG cbSig, mdMethodDef *pmb);
- HRESULT FindProperty(mdTypeDef td, LPCWSTR szName, PCCOR_SIGNATURE pSig, ULONG cbSig, mdProperty *pPr);
- HRESULT FindEvent(mdTypeDef td, LPCWSTR szName, mdProperty *pEv);
-
- HRESULT ReportEvent(int ev, int hr, ...);
-
- HRESULT _DefineSysRefs();
- HRESULT _GetNamespaceName(ITypeLib *pITLB, BSTR *pwzNamespace);
- HRESULT _GetTokenForTypeInfo(ITypeInfo *pITI, BOOL bConvDefItfToClassItf, mdToken *pToken, __out_ecount (chTypeRef) __out_opt LPWSTR pszTypeRef=0, int chTypeRef=0, int *pchTypeRef=0, BOOL bAsmQualifiedName = FALSE);
-
- HRESULT _FindFirstUserMethod(ITypeInfo *pITI, TYPEATTR *psAttr, int *pIx);
- HRESULT _ResolveTypeDescAliasTypeKind(ITypeInfo *pITIAlias, TYPEDESC *ptdesc, TYPEKIND *ptkind);
- HRESULT _ResolveTypeDescAlias(ITypeInfo *pITIAlias, const TYPEDESC *ptdesc, ITypeInfo **ppTIResolved, TYPEATTR **ppsAttrResolved, GUID *pGuid=0);
-
- HRESULT _SetHiddenCA(mdTypeDef token);
- HRESULT _ForceIEnumerableCVExists(ITypeInfo* pITI, BOOL* CVExists);
- HRESULT _SetDispIDCA(ITypeInfo* pITI, int iMember, long lDispId, mdToken func, BOOL fAlwaysAdd, long* lDispSet, BOOL bFunc);
- HRESULT _GetDispIDCA(ITypeInfo* pITI, int iMember, long* lDispSet, BOOL bFunc);
- HRESULT _CheckForPropertyCustomAttributes(ITypeInfo* pITI, int index, INVOKEKIND* ikind);
-
- HRESULT _ConvIfaceMembers(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL bVtblGaps, BOOL bAddDispIds, BOOL bInheritsIEnum);
- HRESULT _ConvSrcIfaceMembers(ITypeInfo *pITI, TYPEATTR* psAttr, BOOL fInheritsIEnum);
- HRESULT _ConvDispatchMembers(ITypeInfo *pITI, TYPEATTR *psAttr, BOOL fInheritsIEnum);
- HRESULT _GetFunctionPropertyInfo(FUNCDESC *psFunc, USHORT *pSemantics, FUNCDESC **ppSig, TYPEDESC **ppProperty, BOOL *pbRetval, BOOL fUseLastParam, BSTR strName);
- HRESULT _ConvFunction(ITypeInfo *pITI, MemberInfo *pMember, int bVtblGapFuncs, BOOL bAddDispIds, BOOL bDelegateInvokeMeth, BOOL* bAllowIEnum);
- HRESULT _GenerateEvent(ITypeInfo *pITI, MemberInfo *pMember, BOOL fInheritsIEnum);
- HRESULT _GenerateEventDelegate(ITypeInfo *pITI, MemberInfo *pMember, mdTypeDef *ptd, BOOL fInheritsIEnum);
- HRESULT _AddSrcItfMembersToClass(mdTypeRef trSrcItf);
-
- HRESULT _ConvPropertiesForFunctions(ITypeInfo *pITI, TYPEATTR *psAttr);
- enum ParamOpts{ParamNormal=0, ParamOptional, ParamVarArg};
- HRESULT _ConvParam(ITypeInfo *pITI, mdMethodDef mbFunc, int iSequence, const ELEMDESC *pdesc, ParamOpts paramOpts, const WCHAR *pszName, BYTE *pbNative, ULONG cbNative);
- HRESULT _ConvConstant(ITypeInfo *pITI, VARDESC *psVar, BOOL bEnumMember=false);
- HRESULT _ConvField(ITypeInfo *pITI, VARDESC *psVar, mdFieldDef *pmdField, BOOL bUnion);
- HRESULT _ConvProperty(ITypeInfo *pITI, MemberInfo *pMember);
- HRESULT _ConvNewEnumProperty(ITypeInfo *pITI, VARDESC *psVar, MemberInfo *pMember);
-
- HRESULT _HandleAliasInfo(ITypeInfo *pITI, TYPEDESC *pTypeDesc, mdToken tk);
-
- HRESULT _AddTlbRef(ITypeLib *pITLB, mdAssemblyRef *par, BSTR *pwzNamespace, BSTR *pwzAsmName, CImpTlbDefItfToClassItfMap **ppDefItfToClassItfMap);
-
- HRESULT _AddGuidCa(mdToken tkObj, REFGUID guid);
- HRESULT _AddDefaultMemberCa(mdToken tkObj, LPCWSTR szName);
-
- HRESULT _AddStringCa(int attr, mdToken tk, LPCWSTR wzString);
-
- HRESULT GetKnownTypeToken(VARTYPE vt, mdTypeRef *ptr);
-
- HRESULT _GetTokenForEventItf(ITypeInfo *pSrcItfITI, mdTypeRef *ptr);
- HRESULT _CreateClassInterface(ITypeInfo *pCoClassITI, ITypeInfo *pDefItfITI, mdTypeRef trDefItf, mdTypeRef rtDefEvItf, mdToken *ptr);
-
- HRESULT GetManagedNameForCoClass(ITypeInfo *pITI, CQuickArray<WCHAR> &qbClassName);
- HRESULT GenerateUniqueTypeName(CQuickArray<WCHAR> &qbTypeName);
- HRESULT GenerateUniqueMemberName(CQuickArray<WCHAR> &qbMemberName, PCCOR_SIGNATURE pSig, ULONG SigSize, LPCWSTR szPrefix, mdToken type);
- HRESULT _IsAlias(ITypeInfo *pITI, TYPEDESC *pTypeDesc);
-
- HRESULT GetDefMemberName(ITypeInfo *pITI, BOOL bItfQualified, CQuickArray<WCHAR> &qbDefMemberName);
-
- enum SigFlags {
- // These match the typelib values
- SIG_IN = 0x0001, // Input param.
- SIG_OUT = 0x0002, // Output param.
- SIG_RET = 0x0008, // Retval. Currently unused.
- SIG_OPT = 0x0010, // Optional param. Currently unused.
- SIG_FLAGS_MASK = 0x001b, // Mask of flags from TypeLib PARAMFLAGs
-
- SIG_FUNC = 0x0100, // Convert signature for function.
- SIG_FIELD = 0x0200, // Convert signature for field.
- SIG_ELEM = 0x0300, // Convert signature for sub element (eg, array of X).
- SIG_TYPE_MASK = 0x0300,
-
- SIG_USE_BYREF = 0x1000, // If set convert one ptr as E_T_BYREF.
- SIG_VARARG = 0x4000, // If set, this is a paramarray type. Use szArray, not System.Array.
-
- SIG_FLAGS_NONE = 0 // '0' of this enum type.
- };
-
- #define IsSigIn(flags) ((flags & SIG_IN) == SIG_IN)
- #define IsSigOut(flags) ((flags & SIG_OUT) == SIG_OUT)
- #define IsSigRet(flags) ((flags & SIG_RET) == SIG_RET)
- #define IsSigOpt(flags) ((flags & SIG_OPT) == SIG_OPT)
- #define IsSigOutRet(flags) ((flags & (SIG_OUT|SIG_RET)) == (SIG_OUT|SIG_RET))
-
- #define IsSigFunc(flags) ((flags & SIG_TYPE_MASK) == SIG_FUNC)
- #define IsSigField(flags) ((flags & SIG_TYPE_MASK) == SIG_FIELD)
- #define IsSigElem(flags) ((flags & SIG_TYPE_MASK) == SIG_ELEM)
-
- #define IsSigUseByref(flags) ((flags & SIG_USE_BYREF) == SIG_USE_BYREF)
- #define IsSigVarArg(flags) ((flags & SIG_VARARG) == SIG_VARARG)
-
- HRESULT _ConvSignature(ITypeInfo *pITI, const TYPEDESC *pType, ULONG Flags, CQuickBytes &qbSigBuf, ULONG cbSig, ULONG *pcbSig, CQuickArray<BYTE> &qbNativeTypeBuf, ULONG cbNativeType, ULONG *pcbNativeType, BOOL bNewEnumMember, int iByRef=0);
-
- // For handling out-of-order vtables.
- CQuickArray<MemberInfo> m_MemberList;
- CWCHARPool *m_pMemberNames;
- int m_cMemberProps; // Count of props in memberlist.
- HRESULT BuildMemberList(ITypeInfo *pITI, int iStart, int iEnd, BOOL bInheritsIEnum);
- HRESULT FreeMemberList(ITypeInfo *pITI);
-
- // List of predefined token types for custom attributes.
-#define INTEROP_ATTRIBUTES() \
- INTEROP_ATTRIBUTE(DISPID) \
- INTEROP_ATTRIBUTE(CLASSINTERFACE) \
- INTEROP_ATTRIBUTE(INTERFACETYPE) \
- INTEROP_ATTRIBUTE(TYPELIBTYPE) \
- INTEROP_ATTRIBUTE(TYPELIBVAR) \
- INTEROP_ATTRIBUTE(TYPELIBFUNC) \
- INTEROP_ATTRIBUTE(COMSOURCEINTERFACES) \
- INTEROP_ATTRIBUTE(COMCONVERSIONLOSS) \
- INTEROP_ATTRIBUTE(GUID) \
- INTEROP_ATTRIBUTE(DEFAULTMEMBER) \
- INTEROP_ATTRIBUTE(COMALIASNAME) \
- INTEROP_ATTRIBUTE(PARAMARRAY) \
- INTEROP_ATTRIBUTE(LCIDCONVERSION) \
- INTEROP_ATTRIBUTE(DECIMALVALUE) \
- INTEROP_ATTRIBUTE(DATETIMEVALUE) \
- INTEROP_ATTRIBUTE(IUNKNOWNVALUE) \
- INTEROP_ATTRIBUTE(IDISPATCHVALUE) \
- INTEROP_ATTRIBUTE(COMVISIBLE) \
- INTEROP_ATTRIBUTE(SERIALIZABLE) \
- INTEROP_ATTRIBUTE_SPECIAL(COMEVENTINTERFACE) \
- INTEROP_ATTRIBUTE_SPECIAL(COCLASS) \
-
-#define INTEROP_ATTRIBUTE(x) ATTR_##x,
-#define INTEROP_ATTRIBUTE_SPECIAL(x) ATTR_##x,
- enum {INTEROP_ATTRIBUTES()
- // Last value gives array size.
- ATTR_COUNT};
-#undef INTEROP_ATTRIBUTE
-#undef INTEROP_ATTRIBUTE_SPECIAL
-
- mdToken m_tkAttr[ATTR_COUNT];
- HRESULT GetAttrType(int attr, mdToken *ptk);
-
- // look up table for known type
- mdTypeRef m_tkKnownTypes[MAX_TLB_VT];
-
- LPCWSTR m_szLibrary; // Name of typelib being imported.
- BOOL m_bGenerateTCEAdapters; // A flag indicating if the TCE adapters are being generated or not.
- BOOL m_bUnsafeInterfaces; // A flag indicating whether runtime security checks should be disabled on an interface
- BOOL m_bSafeArrayAsSystemArray; // A flag indicating whether to import SAFEARRAY's as System.Array's.
- BOOL m_bTransformDispRetVals; // A flag indicating if we should do [out,retval] transformation on disp only itfs.
- BOOL m_bPreventClassMembers; // A flag indicating if we should add members to CoClasses.
- BOOL m_bSerializableValueClasses; // A flag indicating if we should mark value classes as serializable.
- mdMemberRef m_tkSuppressCheckAttr; // Cached ctor for security check custom attribute
- ITypeLib *m_pITLB; // Typelib being imported.
- IMetaDataEmit2 *m_pEmit; // Emit API Interface pointer.
- IMetaDataImport2 *m_pImport; // Import API Interface pointer.
-
- BSTR m_wzNamespace; // Namespace of the created TypeDefs.
- mdTypeRef m_trObject; // Token of System.Object.
- mdTypeRef m_trValueType; // Token of System.ValueType.
- mdTypeRef m_trEnum; // Token of System.Enum.
- mdAssemblyRef m_arSystem; // AssemblyRef for classlib.
-
- ITypeInfo *m_pITI; // "Current" ITypeInfo being converted.
- ITypeInfo *m_pOrigITI; // Original "Current" ITypeInfo being converted,
- // represents TKIND_ALIAS or is equal to m_pITI.
-
- TYPEATTR *m_psAttr; // "TYPEATTR" of current ITypeInfo.
-
- BSTR m_szName; // Name of original current ITypeInfo.
- BSTR m_szMember; // Name of current Member (method or field).
- LPWSTR m_szMngName; // Full name of the managed type.
-
- ULONG m_cbVtableSlot; // Size of a vtable slot.
- ULONG m_Slot; // "Current" vtbl index within an interface.
-
- void *m_psClass; // "Current" class record.
- mdTypeDef m_tdTypeDef; // Current TypeDef.
- mdTypeDef m_tdHasDefault; // Most recent TypeDef with a default.
- enum {eImplIfaceNone, eImplIfaceDefault, eImplIface} m_ImplIface;
- mdToken m_tkInterface; // Interface being added to a coclass.
- BSTR m_szInterface; // Interface name for decoration.
-
- CImpTlbTypeRef m_TRMap; // Typeref map.
- CImpTlbLibRef m_LibRefs; // Referenced typelibs.
- CImpTlbDefItfToClassItfMap m_DefItfToClassItfMap; // The default interface to class interface map.
-
- CImpTlbReservedNames m_ReservedNames; // Reserved names.
- CImpTlbEventInfoMap m_EventInfoMap; // Map of event info's.
-
- ITypeLibImporterNotifySink *m_Notify; // Notification object.
- Assembly *m_pAssembly; // Containing assembly.
- Module *m_pModule; // Module we are emiting into.
-
-#if defined(TLB_STATS)
- LARGE_INTEGER m_freqVal; // Frequency of perf counter.
- BOOL m_bStats; // If true, collect timings.
-#endif // TLB_STATS
-};
-
-
-
-#endif
-
-//-eof-************************************************************************
diff --git a/src/md/inc/liteweightstgdb.h b/src/md/inc/liteweightstgdb.h
index 1234524731..057e29d1ca 100644
--- a/src/md/inc/liteweightstgdb.h
+++ b/src/md/inc/liteweightstgdb.h
@@ -66,8 +66,6 @@ protected:
friend class CorMetaDataScope;
friend class COR;
friend class RegMeta;
- friend class MERGER;
- friend class NEWMERGER;
friend class MDInternalRO;
friend class MDInternalRW;
};
diff --git a/src/md/inc/metamodelrw.h b/src/md/inc/metamodelrw.h
index 6e00d3cf3e..c2d24db8a5 100644
--- a/src/md/inc/metamodelrw.h
+++ b/src/md/inc/metamodelrw.h
@@ -1420,10 +1420,6 @@ public:
void EnableDeltaMetadataGeneration()
{
_ASSERTE(m_OptionValue.m_UpdateMode == MDUpdateENC);
-#ifndef FEATURE_CORECLR
- if (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_MD_UseMinimalDeltas))
- m_OptionValue.m_UpdateMode = MDUpdateDelta;
-#endif //!FEATURE_CORECLR
}
void DisableDeltaMetadataGeneration() {m_OptionValue.m_UpdateMode = MDUpdateENC;}
diff --git a/src/md/inc/rwutil.h b/src/md/inc/rwutil.h
index 5d7f98919c..81966b7fb9 100644
--- a/src/md/inc/rwutil.h
+++ b/src/md/inc/rwutil.h
@@ -181,30 +181,6 @@ private:
//*********************************************************************
//
-// Merge Token manager. This class is created in GetSaveSize as an agent to
-// notify linker regarding token movements. It does not have the ability to
-// keep track token movement.
-//
-//*********************************************************************
-class MergeTokenManager : public IMapToken
-{
-public:
- STDMETHODIMP QueryInterface(REFIID riid, PVOID *pp);
- STDMETHODIMP_(ULONG) AddRef();
- STDMETHODIMP_(ULONG) Release();
- STDMETHODIMP Map(mdToken tkImp, mdToken tkEmit);
- MergeTokenManager(MDTOKENMAP *pTkMapList, IUnknown *pHandler);
- virtual ~MergeTokenManager();
-private:
- LONG m_cRef;
- MDTOKENMAP *m_pTkMapList;
- IMapToken *m_pDefaultHostRemap;
-};
-
-
-
-//*********************************************************************
-//
// This CMapToken class implemented the IMapToken. It is used in RegMeta for
// filter process. This class can track all of the tokens are mapped. It also
// supplies a Find function.
diff --git a/src/md/inc/stgio.h b/src/md/inc/stgio.h
index 96a2f1dddb..2ec873d4c8 100644
--- a/src/md/inc/stgio.h
+++ b/src/md/inc/stgio.h
@@ -46,10 +46,8 @@ enum DBPROPMODE
{ DBPROP_TMODEF_READ = 0x1,
DBPROP_TMODEF_WRITE = 0x2,
DBPROP_TMODEF_EXCLUSIVE = 0x4,
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
DBPROP_TMODEF_SHAREDMEM = 0x8,
-#endif
DBPROP_TMODEF_CREATE = 0x10,
DBPROP_TMODEF_FAILIFTHERE = 0x20,
DBPROP_TMODEF_SLOWSAVE = 0x100,
@@ -77,10 +75,8 @@ enum STGIOTYPE
STGIO_HMODULE = 2, // The file was loaded via LoadLibrary as module.
STGIO_STREAM = 3, // Stream pointer has data.
STGIO_MEM = 4, // In memory pointer has data.
-#ifndef FEATURE_METADATA_STANDALONE_WINRT_RO
// Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
STGIO_SHAREDMEM = 5, // Shared memory handle.
-#endif
STGIO_HFILEMEM = 6 // Handle open, but memory allocated.
};
diff --git a/src/md/inc/winmdinterfaces.h b/src/md/inc/winmdinterfaces.h
index 4233e615d3..47f43df083 100644
--- a/src/md/inc/winmdinterfaces.h
+++ b/src/md/inc/winmdinterfaces.h
@@ -103,15 +103,7 @@ HRESULT VerifyNotWinMDHelper(IUnknown *pUnknown
,int line
#endif //_DEBUG
);
-#if defined(FEATURE_METADATA_IN_VM) && !defined(FEATURE_CORECLR)
-#ifdef _DEBUG
-#define VerifyNotWinMD(pUnknown, assertMsg) VerifyNotWinMDHelper(pUnknown, assertMsg, __FILE__, __LINE__)
-#else
-#define VerifyNotWinMD(pUnknown, assertMsg) VerifyNotWinMDHelper(pUnknown)
-#endif
-#else
#define VerifyNotWinMD(pUnknown, assertMsg) S_OK
-#endif // FEATURE_METADATA_IN_VM
#endif //__WINMDINTERFACES_H__
diff --git a/src/md/md_wks.cmake b/src/md/md_wks.cmake
index ab9df6c667..4d72c55a14 100644
--- a/src/md/md_wks.cmake
+++ b/src/md/md_wks.cmake
@@ -3,4 +3,4 @@ add_definitions(-DFEATURE_METADATA_INTERNAL_APIS)
add_definitions(-DFEATURE_METADATA_IN_VM)
if(WIN32)
add_definitions(-DFEATURE_METADATA_VERIFY_LAYOUTS)
-endif(WIN32) \ No newline at end of file
+endif(WIN32)
diff --git a/src/md/runtime/mdfileformat.cpp b/src/md/runtime/mdfileformat.cpp
index 2edd2e0292..844dc3cfae 100644
--- a/src/md/runtime/mdfileformat.cpp
+++ b/src/md/runtime/mdfileformat.cpp
@@ -77,7 +77,6 @@ MDFormat::VerifySignature(
}
}
-#if !defined(FEATURE_METADATA_STANDALONE_WINRT)
// Only a specific version of the 0.x format is supported by this code
// in order to support the NT 5 beta clients which used this format.
if (pSig->GetMajorVer() == FILE_VER_MAJOR_v0)
@@ -89,7 +88,6 @@ MDFormat::VerifySignature(
}
}
else
-#endif // !defined(FEATURE_METADATA_STANDALONE_WINRT)
// There is currently no code to migrate an old format of the 1.x. This
// would be added only under special circumstances.
if ((pSig->GetMajorVer() != FILE_VER_MAJOR) || (pSig->GetMinorVer() != FILE_VER_MINOR))
diff --git a/src/md/runtime/mdinternaldisp.cpp b/src/md/runtime/mdinternaldisp.cpp
index 1f5725ff01..e6e25a2110 100644
--- a/src/md/runtime/mdinternaldisp.cpp
+++ b/src/md/runtime/mdinternaldisp.cpp
@@ -112,11 +112,6 @@ CheckFileFormat(
}
else if (strcmp(pStream->GetName(), ENC_MODEL_STREAM_A) == 0)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- Debug_ReportError("ENC model stream #- is not supported.");
- hr = CLDB_E_FILE_CORRUPT;
- goto ErrExit;
-#else //!FEATURE_METADATA_STANDALONE_WINRT
// Validate that only one of compressed/uncompressed is present.
if (*pFormat != MDFormat_Invalid)
{ // Already found a good stream.
@@ -126,21 +121,14 @@ CheckFileFormat(
}
// Found the ENC meta data stream.
*pFormat = MDFormat_ReadWrite;
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
else if (strcmp(pStream->GetName(), SCHEMA_STREAM_A) == 0)
{
-#ifdef FEATURE_METADATA_STANDALONE_WINRT
- Debug_ReportError("Schema stream #Schema is not supported.");
- hr = CLDB_E_FILE_CORRUPT;
- goto ErrExit;
-#else //!FEATURE_METADATA_STANDALONE_WINRT
// Found the uncompressed format
*pFormat = MDFormat_ICR;
// keep going. We may find the compressed format later.
// If so, we want to use the compressed format.
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
}
// Pick off the next stream if there is one.
@@ -228,1607 +216,5 @@ ErrExit:
} // GetMDInternalInterface
-#ifdef FEATURE_FUSION
-
-#ifndef DACCESS_COMPILE
-
-//*****************************************************************************
-// GetAssemblyMDInternalImport.
-// Instantiating an instance of AssemblyMDInternalImport.
-// This class can support the IMetaDataAssemblyImport and some functionalities
-// of IMetaDataImport on the internal import interface (IMDInternalImport).
-//*****************************************************************************
-STDAPI GetAssemblyMDInternalImport( // Return code.
- LPCWSTR szFileName, // [in] The scope to open.
- REFIID riid, // [in] The interface desired.
- IUnknown **ppIUnk) // [out] Return interface on success.
-{
- return GetAssemblyMDInternalImportEx(szFileName, riid, MDInternalImport_Default, ppIUnk);
-}
-
-STDAPI GetAssemblyMDInternalImportEx( // Return code.
- LPCWSTR szFileName, // [in] The scope to open.
- REFIID riid, // [in] The interface desired.
- MDInternalImportFlags flags, // [in] Flags to control opening the assembly
- IUnknown **ppIUnk, // [out] Return interface on success.
- HANDLE hFile)
-{
- HRESULT hr;
-
- if (!szFileName || !szFileName[0] || !ppIUnk)
- return E_INVALIDARG;
-
- // Sanity check the name.
- if (wcslen(szFileName) >= _MAX_PATH)
- return E_INVALIDARG;
-
- if (memcmp(szFileName, W("file:"), 10) == 0)
- szFileName = &szFileName[5];
-
- HCORMODULEHolder hModule;
- DWORD dwFileLength;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- IfFailGoto(RuntimeOpenImageInternal(szFileName, &hModule, &dwFileLength, flags, hFile), ErrAsmExpected);
-
- IfFailGo(GetAssemblyMDInternalImportHelper(hModule, riid, flags, ppIUnk));
-
-
-ErrAsmExpected:
- if(hr == COR_E_BADIMAGEFORMAT)
- hr = COR_E_ASSEMBLYEXPECTED;
-
-ErrExit:
-;
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-HRESULT GetAssemblyMDInternalImportFromImage(
- HCORMODULE hImage,
- REFIID riid,
- IUnknown **ppIUnk)
-{
-
- HRESULT hr;
-
- IfFailGo(GetAssemblyMDInternalImportHelper(hImage, riid, MDInternalImport_Default, ppIUnk));
-
-ErrExit:
- return hr;
-}
-
-STDAPI GetAssemblyMDInternalImportByStream( // Return code.
- IStream *pIStream, // [in] The IStream for the file
- UINT64 AssemblyId, // [in] Unique Id for the assembly
- REFIID riid, // [in] The interface desired.
- IUnknown **ppIUnk) // [out] Return interface on success.
-{
- return GetAssemblyMDInternalImportByStreamEx(pIStream, AssemblyId, riid, MDInternalImport_Default, ppIUnk);
-}
-
-STDAPI GetAssemblyMDInternalImportByStreamEx( // Return code.
- IStream *pIStream, // [in] The IStream for the file
- UINT64 AssemblyId, // [in] Unique Id for the assembly
- REFIID riid, // [in] The interface desired.
- MDInternalImportFlags flags, // [in[ Flags to control opening the assembly
- IUnknown **ppIUnk) // [out] Return interface on success.
-{
- if (!pIStream || !ppIUnk)
- return E_INVALIDARG;
-
- HRESULT hr;
- DWORD dwFileLength;
- HCORMODULEHolder hModule;
-
- BEGIN_SO_INTOLERANT_CODE_NO_THROW_CHECK_THREAD(return COR_E_STACKOVERFLOW);
-
- IfFailGoto(RuntimeOpenImageByStream(pIStream, AssemblyId, 0, &hModule, &dwFileLength, flags), ErrAsmExpected);
-
- IfFailGo(GetAssemblyMDInternalImportHelper(hModule, riid, flags, ppIUnk));
-
-
-ErrAsmExpected:
- if(hr == COR_E_BADIMAGEFORMAT)
- hr = COR_E_ASSEMBLYEXPECTED;
-
-ErrExit:
- ;
- END_SO_INTOLERANT_CODE;
-
- return hr;
-}
-
-
-HRESULT GetAssemblyMDInternalImportHelper(HCORMODULE hModule,
- REFIID riid,
- MDInternalImportFlags flags,
- IUnknown **ppIUnk)
-{
- AssemblyMDInternalImport *pAssemblyMDInternalImport = NULL;
- HRESULT hr;
- LPVOID base;
- PEDecoder pe;
- IfFailGoto(RuntimeGetImageBase(hModule,&base,TRUE,NULL), ErrAsmExpected);
-
- if (base!=NULL)
- IfFailGoto(pe.Init(base), ErrAsmExpected);
- else
- {
- COUNT_T lgth;
- IfFailGoto(RuntimeGetImageBase(hModule,&base,FALSE,&lgth), ErrAsmExpected);
- pe.Init(base, lgth);
- }
-
- // Both of these need to pass.
- if (!pe.HasCorHeader() || !pe.CheckCorHeader())
- IfFailGo(COR_E_ASSEMBLYEXPECTED);
- // Only one of these needs to.
- if (!pe.CheckILFormat() && !pe.CheckNativeFormat())
- IfFailGo(COR_E_BADIMAGEFORMAT);
-
- COUNT_T cbMetaData;
- LPCVOID pMetaData;
- pMetaData = pe.GetMetadata(&cbMetaData);
-
- // Get the IL metadata.
- IMDInternalImport *pMDInternalImport;
- IfFailGo(RuntimeGetMDInternalImport(hModule, flags, &pMDInternalImport));
- if (pMDInternalImport == NULL)
- IfFailGo(E_OUTOFMEMORY);
-
- _ASSERTE(pMDInternalImport);
- pAssemblyMDInternalImport = new (nothrow) AssemblyMDInternalImport (pMDInternalImport);
- if (!pAssemblyMDInternalImport) {
- pMDInternalImport->Release();
- IfFailGo(E_OUTOFMEMORY);
- }
-
- { // identify PE kind and machine type, plus the version string location
- DWORD dwKind=0;
- DWORD dwMachine=0;
- RuntimeGetImageKind(hModule,&dwKind,&dwMachine);
- pAssemblyMDInternalImport->SetPEKind(dwKind);
- pAssemblyMDInternalImport->SetMachine(dwMachine);
-
- {
- LPCSTR pString = NULL;
- IfFailGo(GetImageRuntimeVersionString((PVOID)pMetaData, &pString));
-
- pAssemblyMDInternalImport->SetVersionString(pString);
- }
-
- }
-
- pAssemblyMDInternalImport->SetHandle(hModule);
-
-#ifdef FEATURE_PREJIT
- // Check for zap header for INativeImageInstallInfo
- // Dont do this if we are returning the IL metadata as CORCOMPILE_DEPENDENCY
- // references the native image metadata, not the IL metadata.
-
- if (pe.HasNativeHeader() && !(flags & MDInternalImport_ILMetaData))
- {
- CORCOMPILE_VERSION_INFO *pNativeVersionInfo = pe.GetNativeVersionInfo();
-
- COUNT_T cDeps;
- CORCOMPILE_DEPENDENCY *pDeps = pe.GetNativeDependencies(&cDeps);
-
- pAssemblyMDInternalImport->SetZapVersionInfo(pNativeVersionInfo, pDeps, cDeps);
- }
-#endif // FEATURE_PREJIT
-
- IfFailGo(pAssemblyMDInternalImport->QueryInterface(riid, (void**)ppIUnk));
-
- return hr;
-
-ErrAsmExpected:
- if(hr == COR_E_BADIMAGEFORMAT)
- hr = COR_E_ASSEMBLYEXPECTED;
-
-ErrExit:
-
- if (pAssemblyMDInternalImport)
- delete pAssemblyMDInternalImport;
-
- return hr;
-}
-
-AssemblyMDInternalImport::AssemblyMDInternalImport (IMDInternalImport *pMDInternalImport)
-: m_cRef(0),
- m_pHandle(0),
- m_pBase(NULL),
-#ifdef FEATURE_PREJIT
- m_pZapVersionInfo(NULL),
-#endif // FEATURE_PREJIT
- m_pMDInternalImport(pMDInternalImport),
- m_dwPEKind(0),
- m_dwMachine(0),
- m_szVersionString("")
-{
- _ASSERTE(m_pMDInternalImport);
-} // AssemblyMDInternalImport
-
-AssemblyMDInternalImport::~AssemblyMDInternalImport ()
-{
- m_pMDInternalImport->Release();
-
- if (m_pBase)
- {
- UnmapViewOfFile(m_pBase);
- m_pBase = NULL;
- CloseHandle(m_pHandle);
- }
- else if(m_pHandle)
- {
- HRESULT hr;
- hr = RuntimeReleaseHandle(m_pHandle);
- _ASSERTE(SUCCEEDED(hr));
- }
-
- m_pHandle = NULL;
-}
-
-ULONG AssemblyMDInternalImport::AddRef()
-{
- return InterlockedIncrement(&m_cRef);
-} // ULONG AssemblyMDInternalImport::AddRef()
-
-ULONG AssemblyMDInternalImport::Release()
-{
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef)
- {
- VALIDATE_BACKOUT_STACK_CONSUMPTION;
- delete this;
- }
- return (cRef);
-} // ULONG AssemblyMDInternalImport::Release()
-
-HRESULT AssemblyMDInternalImport::QueryInterface(REFIID riid, void **ppUnk)
-{
- *ppUnk = 0;
-
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *) (IMetaDataAssemblyImport *) this;
- else if (riid == IID_IMetaDataAssemblyImport)
- *ppUnk = (IMetaDataAssemblyImport *) this;
- else if (riid == IID_IMetaDataImport)
- *ppUnk = (IMetaDataImport *) this;
- else if (riid == IID_IMetaDataImport2)
- *ppUnk = (IMetaDataImport2 *) this;
- else if (riid == IID_ISNAssemblySignature)
- *ppUnk = (ISNAssemblySignature *) this;
-#ifdef FEATURE_PREJIT
- else if (riid == IID_IGetIMDInternalImport)
- *ppUnk = (IGetIMDInternalImport *) this;
- else if (riid == IID_INativeImageInstallInfo && m_pZapVersionInfo)
- *ppUnk = (INativeImageInstallInfo *) this;
-#endif // FEATURE_PREJIT
- else
- return (E_NOINTERFACE);
- AddRef();
- return (S_OK);
-}
-
-
-STDMETHODIMP AssemblyMDInternalImport::GetAssemblyProps ( // S_OK or error.
- mdAssembly mda, // [IN] The Assembly for which to get the properties.
- const void **ppbPublicKey, // [OUT] Pointer to the public key.
- ULONG *pcbPublicKey, // [OUT] Count of bytes in the public key.
- ULONG *pulHashAlgId, // [OUT] Hash Algorithm.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- DWORD *pdwAssemblyFlags) // [OUT] Flags.
-{
- HRESULT hr;
- LPCSTR _szName;
- AssemblyMetaDataInternal _AssemblyMetaData;
-
- _AssemblyMetaData.ulProcessor = 0;
- _AssemblyMetaData.ulOS = 0;
-
- IfFailRet(m_pMDInternalImport->GetAssemblyProps(
- mda, // [IN] The Assembly for which to get the properties.
- ppbPublicKey, // [OUT] Pointer to the public key.
- pcbPublicKey, // [OUT] Count of bytes in the public key.
- pulHashAlgId, // [OUT] Hash Algorithm.
- &_szName, // [OUT] Buffer to fill with name.
- &_AssemblyMetaData, // [OUT] Assembly MetaData.
- pdwAssemblyFlags)); // [OUT] Flags.
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- if (pMetaData)
- {
- pMetaData->usMajorVersion = _AssemblyMetaData.usMajorVersion;
- pMetaData->usMinorVersion = _AssemblyMetaData.usMinorVersion;
- pMetaData->usBuildNumber = _AssemblyMetaData.usBuildNumber;
- pMetaData->usRevisionNumber = _AssemblyMetaData.usRevisionNumber;
- pMetaData->ulProcessor = 0;
- pMetaData->ulOS = 0;
-
- pMetaData->cbLocale = WszMultiByteToWideChar(CP_UTF8, 0, _AssemblyMetaData.szLocale, -1, pMetaData->szLocale, pMetaData->cbLocale);
- if (pMetaData->cbLocale == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetAssemblyRefProps ( // S_OK or error.
- mdAssemblyRef mdar, // [IN] The AssemblyRef for which to get the properties.
- const void **ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token.
- ULONG *pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData.
- const void **ppbHashValue, // [OUT] Hash blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the hash blob.
- DWORD *pdwAssemblyRefFlags) // [OUT] Flags.
-{
- HRESULT hr;
- LPCSTR _szName;
- AssemblyMetaDataInternal _AssemblyMetaData;
-
- _AssemblyMetaData.ulProcessor = 0;
- _AssemblyMetaData.ulOS = 0;
-
- IfFailRet(m_pMDInternalImport->GetAssemblyRefProps(
- mdar, // [IN] The Assembly for which to get the properties.
- ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token.
- pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token.
- &_szName, // [OUT] Buffer to fill with name.
- &_AssemblyMetaData, // [OUT] Assembly MetaData.
- ppbHashValue, // [OUT] Hash blob.
- pcbHashValue, // [OUT] Count of bytes in the hash blob.
- pdwAssemblyRefFlags)); // [OUT] Flags.
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- pMetaData->usMajorVersion = _AssemblyMetaData.usMajorVersion;
- pMetaData->usMinorVersion = _AssemblyMetaData.usMinorVersion;
- pMetaData->usBuildNumber = _AssemblyMetaData.usBuildNumber;
- pMetaData->usRevisionNumber = _AssemblyMetaData.usRevisionNumber;
- pMetaData->ulProcessor = 0;
- pMetaData->ulOS = 0;
-
- pMetaData->cbLocale = WszMultiByteToWideChar(CP_UTF8, 0, _AssemblyMetaData.szLocale, -1, pMetaData->szLocale, pMetaData->cbLocale);
- if (pMetaData->cbLocale == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetFileProps ( // S_OK or error.
- mdFile mdf, // [IN] The File for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- const void **ppbHashValue, // [OUT] Pointer to the Hash Value Blob.
- ULONG *pcbHashValue, // [OUT] Count of bytes in the Hash Value Blob.
- DWORD *pdwFileFlags) // [OUT] Flags.
-{
- HRESULT hr;
- LPCSTR _szName;
- IfFailRet(m_pMDInternalImport->GetFileProps(
- mdf,
- &_szName,
- ppbHashValue,
- pcbHashValue,
- pdwFileFlags));
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetExportedTypeProps ( // S_OK or error.
- mdExportedType mdct, // [IN] The ExportedType for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef or mdExportedType.
- mdTypeDef *ptkTypeDef, // [OUT] TypeDef token within the file.
- DWORD *pdwExportedTypeFlags) // [OUT] Flags.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetManifestResourceProps ( // S_OK or error.
- mdManifestResource mdmr, // [IN] The ManifestResource for which to get the properties.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Buffer to fill with name.
- ULONG cchName, // [IN] Size of buffer in wide chars.
- ULONG *pchName, // [OUT] Actual # of wide chars in name.
- mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ManifestResource.
- DWORD *pdwOffset, // [OUT] Offset to the beginning of the resource within the file.
- DWORD *pdwResourceFlags) // [OUT] Flags.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumAssemblyRefs ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdAssemblyRef rAssemblyRefs[], // [OUT] Put AssemblyRefs here.
- ULONG cMax, // [IN] Max AssemblyRefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum);
- HRESULT hr = NOERROR;
- HENUMInternal *pEnum;
-
- if (*ppmdEnum == NULL)
- {
- // create the enumerator.
- IfFailGo(HENUMInternal::CreateSimpleEnum(
- mdtAssemblyRef,
- 0,
- 1,
- &pEnum));
-
- IfFailGo(m_pMDInternalImport->EnumInit(mdtAssemblyRef, 0, pEnum));
-
- // set the output parameter.
- *ppmdEnum = pEnum;
- }
- else
- {
- pEnum = *ppmdEnum;
- }
-
- // we can only fill the minimum of what the caller asked for or what we have left.
- IfFailGo(HENUMInternal::EnumWithCount(pEnum, cMax, rAssemblyRefs, pcTokens));
-ErrExit:
- HENUMInternal::DestroyEnumIfEmpty(ppmdEnum);
-
- return hr;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumFiles ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdFile rFiles[], // [OUT] Put Files here.
- ULONG cMax, // [IN] Max Files to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- HENUMInternal **ppmdEnum = reinterpret_cast<HENUMInternal **> (phEnum);
- HRESULT hr = NOERROR;
- HENUMInternal *pEnum;
-
- if (*ppmdEnum == NULL)
- {
- // create the enumerator.
- IfFailGo(HENUMInternal::CreateSimpleEnum(
- mdtFile,
- 0,
- 1,
- &pEnum));
-
- IfFailGo(m_pMDInternalImport->EnumInit(mdtFile, 0, pEnum));
-
- // set the output parameter.
- *ppmdEnum = pEnum;
- }
- else
- {
- pEnum = *ppmdEnum;
- }
-
- // we can only fill the minimum of what the caller asked for or what we have left.
- IfFailGo(HENUMInternal::EnumWithCount(pEnum, cMax, rFiles, pcTokens));
-
-ErrExit:
- HENUMInternal::DestroyEnumIfEmpty(ppmdEnum);
- return hr;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumExportedTypes ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdExportedType rExportedTypes[], // [OUT] Put ExportedTypes here.
- ULONG cMax, // [IN] Max ExportedTypes to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumManifestResources ( // S_OK or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdManifestResource rManifestResources[], // [OUT] Put ManifestResources here.
- ULONG cMax, // [IN] Max Resources to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetAssemblyFromScope ( // S_OK or error
- mdAssembly *ptkAssembly) // [OUT] Put token here.
-{
- return m_pMDInternalImport->GetAssemblyFromScope (ptkAssembly);
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindExportedTypeByName (// S_OK or error
- LPCWSTR szName, // [IN] Name of the ExportedType.
- mdToken mdtExportedType, // [IN] ExportedType for the enclosing class.
- mdExportedType *ptkExportedType) // [OUT] Put the ExportedType token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindManifestResourceByName ( // S_OK or error
- LPCWSTR szName, // [IN] Name of the ManifestResource.
- mdManifestResource *ptkManifestResource) // [OUT] Put the ManifestResource token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-void AssemblyMDInternalImport::CloseEnum (
- HCORENUM hEnum) // Enum to be closed.
-{
- HENUMInternal *pmdEnum = reinterpret_cast<HENUMInternal *> (hEnum);
-
- if (pmdEnum == NULL)
- return;
-
- HENUMInternal::DestroyEnum(pmdEnum);
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindAssembliesByName ( // S_OK or error
- LPCWSTR szAppBase, // [IN] optional - can be NULL
- LPCWSTR szPrivateBin, // [IN] optional - can be NULL
- LPCWSTR szAssemblyName, // [IN] required - this is the assembly you are requesting
- IUnknown *ppIUnk[], // [OUT] put IMetaDataAssemblyImport pointers here
- ULONG cMax, // [IN] The max number to put
- ULONG *pcAssemblies) // [OUT] The number of assemblies returned.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::CountEnum (HCORENUM hEnum, ULONG *pulCount)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::ResetEnum (HCORENUM hEnum, ULONG ulPos)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumTypeDefs (HCORENUM *phEnum, mdTypeDef rTypeDefs[],
- ULONG cMax, ULONG *pcTypeDefs)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumInterfaceImpls (HCORENUM *phEnum, mdTypeDef td,
- mdInterfaceImpl rImpls[], ULONG cMax,
- ULONG* pcImpls)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumTypeRefs (HCORENUM *phEnum, mdTypeRef rTypeRefs[],
- ULONG cMax, ULONG* pcTypeRefs)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindTypeDefByName ( // S_OK or error.
- LPCWSTR szTypeDef, // [IN] Name of the Type.
- mdToken tkEnclosingClass, // [IN] TypeDef/TypeRef for Enclosing class.
- mdTypeDef *ptd) // [OUT] Put the TypeDef token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetScopeProps ( // S_OK or error.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Put the name here.
- ULONG cchName, // [IN] Size of name buffer in wide chars.
- ULONG *pchName, // [OUT] Put size of name (wide chars) here.
- GUID *pmvid) // [OUT, OPTIONAL] Put MVID here.
-{
- HRESULT hr;
- LPCSTR _szName;
-
- if (!m_pMDInternalImport->IsValidToken(m_pMDInternalImport->GetModuleFromScope()))
- return COR_E_BADIMAGEFORMAT;
-
- IfFailRet(m_pMDInternalImport->GetScopeProps(&_szName, pmvid));
-
- if (pchName != NULL)
- {
- *pchName = WszMultiByteToWideChar(CP_UTF8, 0, _szName, -1, szName, cchName);
- if (*pchName == 0)
- {
- return HRESULT_FROM_GetLastError();
- }
- }
-
- return S_OK;
-
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetModuleFromScope ( // S_OK.
- mdModule *pmd) // [OUT] Put mdModule token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetTypeDefProps ( // S_OK or error.
- mdTypeDef td, // [IN] TypeDef token for inquiry.
- __out_ecount (cchTypeDef) LPWSTR szTypeDef, // [OUT] Put name here.
- ULONG cchTypeDef, // [IN] size of name buffer in wide chars.
- ULONG *pchTypeDef, // [OUT] put size of name (wide chars) here.
- DWORD *pdwTypeDefFlags, // [OUT] Put flags here.
- mdToken *ptkExtends) // [OUT] Put base class TypeDef/TypeRef here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetInterfaceImplProps ( // S_OK or error.
- mdInterfaceImpl iiImpl, // [IN] InterfaceImpl token.
- mdTypeDef *pClass, // [OUT] Put implementing class token here.
- mdToken *ptkIface) // [OUT] Put implemented interface token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetTypeRefProps ( // S_OK or error.
- mdTypeRef tr, // [IN] TypeRef token.
- mdToken *ptkResolutionScope, // [OUT] Resolution scope, ModuleRef or AssemblyRef.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Name of the TypeRef.
- ULONG cchName, // [IN] Size of buffer.
- ULONG *pchName) // [OUT] Size of Name.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::ResolveTypeRef (mdTypeRef tr, REFIID riid, IUnknown **ppIScope, mdTypeDef *ptd)
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMembers ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMembersWithName ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdToken rMembers[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethods ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdMethodDef rMethods[], // [OUT] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodsWithName ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdMethodDef rMethods[], // [OU] Put MethodDefs here.
- ULONG cMax, // [IN] Max MethodDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumFields ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- mdFieldDef rFields[], // [OUT] Put FieldDefs here.
- ULONG cMax, // [IN] Max FieldDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumFieldsWithName ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef cl, // [IN] TypeDef to scope the enumeration.
- LPCWSTR szName, // [IN] Limit results to those with this name.
- mdFieldDef rFields[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-
-STDMETHODIMP AssemblyMDInternalImport::EnumParams ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdParamDef rParams[], // [OUT] Put ParamDefs here.
- ULONG cMax, // [IN] Max ParamDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMemberRefs ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tkParent, // [IN] Parent token to scope the enumeration.
- mdMemberRef rMemberRefs[], // [OUT] Put MemberRefs here.
- ULONG cMax, // [IN] Max MemberRefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodImpls ( // S_OK, S_FALSE, or error
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdToken rMethodBody[], // [OUT] Put Method Body tokens here.
- mdToken rMethodDecl[], // [OUT] Put Method Declaration tokens here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumPermissionSets ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] if !NIL, token to scope the enumeration.
- DWORD dwActions, // [IN] if !0, return only these actions.
- mdPermission rPermission[], // [OUT] Put Permissions here.
- ULONG cMax, // [IN] Max Permissions to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindMember (
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdToken *pmb) // [OUT] matching memberdef
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindMethod (
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMethodDef *pmb) // [OUT] matching memberdef
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindField (
- mdTypeDef td, // [IN] given typedef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdFieldDef *pmb) // [OUT] matching memberdef
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindMemberRef (
- mdTypeRef td, // [IN] given typeRef
- LPCWSTR szName, // [IN] member name
- PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature
- ULONG cbSigBlob, // [IN] count of bytes in the signature blob
- mdMemberRef *pmr) // [OUT] matching memberref
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMethodProps (
- mdMethodDef mb, // The method for which to get props.
- mdTypeDef *pClass, // Put method's class here.
- __out_ecount (cchMethod) LPWSTR szMethod, // Put method's name here.
- ULONG cchMethod, // Size of szMethod buffer in wide chars.
- ULONG *pchMethod, // Put actual size here
- DWORD *pdwAttr, // Put flags here.
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob, // [OUT] actual size of signature blob
- ULONG *pulCodeRVA, // [OUT] codeRVA
- DWORD *pdwImplFlags) // [OUT] Impl. Flags
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMemberRefProps ( // S_OK or error.
- mdMemberRef mr, // [IN] given memberref
- mdToken *ptk, // [OUT] Put classref or classdef here.
- __out_ecount (cchMember) LPWSTR szMember, // [OUT] buffer to fill for member's name
- ULONG cchMember, // [IN] the count of char of szMember
- ULONG *pchMember, // [OUT] actual count of char in member name
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to meta data blob value
- ULONG *pbSig) // [OUT] actual size of signature blob
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumProperties ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdProperty rProperties[], // [OUT] Put Properties here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcProperties) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumEvents ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdTypeDef td, // [IN] TypeDef to scope the enumeration.
- mdEvent rEvents[], // [OUT] Put events here.
- ULONG cMax, // [IN] Max events to put.
- ULONG *pcEvents) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetEventProps ( // S_OK, S_FALSE, or error.
- mdEvent ev, // [IN] event token
- mdTypeDef *pClass, // [OUT] typedef containing the event declarion.
- LPCWSTR szEvent, // [OUT] Event name
- ULONG cchEvent, // [IN] the count of wchar of szEvent
- ULONG *pchEvent, // [OUT] actual count of wchar for event's name
- DWORD *pdwEventFlags, // [OUT] Event flags.
- mdToken *ptkEventType, // [OUT] EventType class
- mdMethodDef *pmdAddOn, // [OUT] AddOn method of the event
- mdMethodDef *pmdRemoveOn, // [OUT] RemoveOn method of the event
- mdMethodDef *pmdFire, // [OUT] Fire method of the event
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the event
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod) // [OUT] total number of other method of this event
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodSemantics ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdMethodDef mb, // [IN] MethodDef to scope the enumeration.
- mdToken rEventProp[], // [OUT] Put Event/Property here.
- ULONG cMax, // [IN] Max properties to put.
- ULONG *pcEventProp) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMethodSemantics ( // S_OK, S_FALSE, or error.
- mdMethodDef mb, // [IN] method token
- mdToken tkEventProp, // [IN] event/property token.
- DWORD *pdwSemanticsFlags) // [OUT] the role flags for the method/propevent pair
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetClassLayout (
- mdTypeDef td, // [IN] give typedef
- DWORD *pdwPackSize, // [OUT] 1, 2, 4, 8, or 16
- COR_FIELD_OFFSET rFieldOffset[], // [OUT] field offset array
- ULONG cMax, // [IN] size of the array
- ULONG *pcFieldOffset, // [OUT] needed array size
- ULONG *pulClassSize) // [OUT] the size of the class
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetFieldMarshal (
- mdToken tk, // [IN] given a field's memberdef
- PCCOR_SIGNATURE *ppvNativeType, // [OUT] native type of this field
- ULONG *pcbNativeType) // [OUT] the count of bytes of *ppvNativeType
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetRVA ( // S_OK or error.
- mdToken tk, // Member for which to set offset
- ULONG *pulCodeRVA, // The offset
- DWORD *pdwImplFlags) // the implementation flags
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPermissionSetProps (
- mdPermission pm, // [IN] the permission token.
- DWORD *pdwAction, // [OUT] CorDeclSecurity.
- void const **ppvPermission, // [OUT] permission blob.
- ULONG *pcbPermission) // [OUT] count of bytes of pvPermission.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetSigFromToken ( // S_OK or error.
- mdSignature mdSig, // [IN] Signature token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to token.
- ULONG *pcbSig) // [OUT] return size of signature.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetModuleRefProps ( // S_OK or error.
- mdModuleRef mur, // [IN] moduleref token.
- __out_ecount (cchName) LPWSTR szName, // [OUT] buffer to fill with the moduleref name.
- ULONG cchName, // [IN] size of szName in wide characters.
- ULONG *pchName) // [OUT] actual count of characters in the name.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumModuleRefs ( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdModuleRef rModuleRefs[], // [OUT] put modulerefs here.
- ULONG cmax, // [IN] max memberrefs to put.
- ULONG *pcModuleRefs) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetTypeSpecFromToken ( // S_OK or error.
- mdTypeSpec typespec, // [IN] TypeSpec token.
- PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to TypeSpec signature
- ULONG *pcbSig) // [OUT] return size of signature.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetNameFromToken ( // Not Recommended! May be removed!
- mdToken tk, // [IN] Token to get name from. Must have a name.
- MDUTF8CSTR *pszUtf8NamePtr) // [OUT] Return pointer to UTF8 name in heap.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumUnresolvedMethods ( // S_OK, S_FALSE, or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken rMethods[], // [OUT] Put MemberDefs here.
- ULONG cMax, // [IN] Max MemberDefs to put.
- ULONG *pcTokens) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetUserString ( // S_OK or error.
- mdString stk, // [IN] String token.
- __out_ecount (cchString) LPWSTR szString, // [OUT] Copy of string.
- ULONG cchString, // [IN] Max chars of room in szString.
- ULONG *pchString) // [OUT] How many chars in actual string.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPinvokeMap ( // S_OK or error.
- mdToken tk, // [IN] FieldDef or MethodDef.
- DWORD *pdwMappingFlags, // [OUT] Flags used for mapping.
- __out_ecount (cchImportName) LPWSTR szImportName, // [OUT] Import name.
- ULONG cchImportName, // [IN] Size of the name buffer.
- ULONG *pchImportName, // [OUT] Actual number of characters stored.
- mdModuleRef *pmrImportDLL) // [OUT] ModuleRef token for the target DLL.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumSignatures ( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdSignature rSignatures[], // [OUT] put signatures here.
- ULONG cmax, // [IN] max signatures to put.
- ULONG *pcSignatures) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumTypeSpecs ( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] pointer to the enum.
- mdTypeSpec rTypeSpecs[], // [OUT] put TypeSpecs here.
- ULONG cmax, // [IN] max TypeSpecs to put.
- ULONG *pcTypeSpecs) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumUserStrings ( // S_OK or error.
- HCORENUM *phEnum, // [IN/OUT] pointer to the enum.
- mdString rStrings[], // [OUT] put Strings here.
- ULONG cmax, // [IN] max Strings to put.
- ULONG *pcStrings) // [OUT] put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetParamForMethodIndex ( // S_OK or error.
- mdMethodDef md, // [IN] Method token.
- ULONG ulParamSeq, // [IN] Parameter sequence.
- mdParamDef *ppd) // [IN] Put Param token here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumCustomAttributes ( // S_OK or error.
- HCORENUM *phEnum, // [IN, OUT] COR enumerator.
- mdToken tk, // [IN] Token to scope the enumeration, 0 for all.
- mdToken tkType, // [IN] Type of interest, 0 for all.
- mdCustomAttribute rCustomAttributes[], // [OUT] Put custom attribute tokens here.
- ULONG cMax, // [IN] Size of rCustomAttributes.
- ULONG *pcCustomAttributes) // [OUT, OPTIONAL] Put count of token values here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetCustomAttributeProps ( // S_OK or error.
- mdCustomAttribute cv, // [IN] CustomAttribute token.
- mdToken *ptkObj, // [OUT, OPTIONAL] Put object token here.
- mdToken *ptkType, // [OUT, OPTIONAL] Put AttrType token here.
- void const **ppBlob, // [OUT, OPTIONAL] Put pointer to data here.
- ULONG *pcbSize) // [OUT, OPTIONAL] Put size of date here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::FindTypeRef (
- mdToken tkResolutionScope, // [IN] ModuleRef, AssemblyRef or TypeRef.
- LPCWSTR szName, // [IN] TypeRef Name.
- mdTypeRef *ptr) // [OUT] matching TypeRef.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMemberProps (
- mdToken mb, // The member for which to get props.
- mdTypeDef *pClass, // Put member's class here.
- __out_ecount (cchMember) LPWSTR szMember, // Put member's name here.
- ULONG cchMember, // Size of szMember buffer in wide chars.
- ULONG *pchMember, // Put actual size here
- DWORD *pdwAttr, // Put flags here.
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob, // [OUT] actual size of signature blob
- ULONG *pulCodeRVA, // [OUT] codeRVA
- DWORD *pdwImplFlags, // [OUT] Impl. Flags
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppValue, // [OUT] constant value
- ULONG *pcchValue) // [OUT] size of constant string in chars, 0 for non-strings.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetFieldProps (
- mdFieldDef mb, // The field for which to get props.
- mdTypeDef *pClass, // Put field's class here.
- __out_ecount (cchField) LPWSTR szField, // Put field's name here.
- ULONG cchField, // Size of szField buffer in wide chars.
- ULONG *pchField, // Put actual size here
- DWORD *pdwAttr, // Put flags here.
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob, // [OUT] actual size of signature blob
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppValue, // [OUT] constant value
- ULONG *pcchValue) // [OUT] size of constant string in chars, 0 for non-strings.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPropertyProps ( // S_OK, S_FALSE, or error.
- mdProperty prop, // [IN] property token
- mdTypeDef *pClass, // [OUT] typedef containing the property declarion.
- LPCWSTR szProperty, // [OUT] Property name
- ULONG cchProperty, // [IN] the count of wchar of szProperty
- ULONG *pchProperty, // [OUT] actual count of wchar for property name
- DWORD *pdwPropFlags, // [OUT] property flags.
- PCCOR_SIGNATURE *ppvSig, // [OUT] property type. pointing to meta data internal blob
- ULONG *pbSig, // [OUT] count of bytes in *ppvSig
- DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected ELEMENT_TYPE_*
- UVCP_CONSTANT *ppDefaultValue, // [OUT] constant value
- ULONG *pcchDefaultValue, // [OUT] size of constant string in chars, 0 for non-strings.
- mdMethodDef *pmdSetter, // [OUT] setter method of the property
- mdMethodDef *pmdGetter, // [OUT] getter method of the property
- mdMethodDef rmdOtherMethod[], // [OUT] other method of the property
- ULONG cMax, // [IN] size of rmdOtherMethod
- ULONG *pcOtherMethod) // [OUT] total number of other method of this property
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetParamProps ( // S_OK or error.
- mdParamDef tk, // [IN]The Parameter.
- mdMethodDef *pmd, // [OUT] Parent Method token.
- ULONG *pulSequence, // [OUT] Parameter sequence.
- __out_ecount (cchName) LPWSTR szName, // [OUT] Put name here.
- ULONG cchName, // [OUT] Size of name buffer.
- ULONG *pchName, // [OUT] Put actual size of name here.
- DWORD *pdwAttr, // [OUT] Put flags here.
- DWORD *pdwCPlusTypeFlag, // [OUT] Flag for value type. selected ELEMENT_TYPE_*.
- UVCP_CONSTANT *ppValue, // [OUT] Constant value.
- ULONG *pcchValue) // [OUT] size of constant string in chars, 0 for non-strings.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetCustomAttributeByName ( // S_OK or error.
- mdToken tkObj, // [IN] Object with Custom Attribute.
- LPCWSTR szName, // [IN] Name of desired Custom Attribute.
- const void **ppData, // [OUT] Put pointer to data here.
- ULONG *pcbData) // [OUT] Put size of data here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-BOOL AssemblyMDInternalImport::IsValidToken ( // True or False.
- mdToken tk) // [IN] Given token.
-{
- _ASSERTE(!"NYI");
- return FALSE;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetNestedClassProps ( // S_OK or error.
- mdTypeDef tdNestedClass, // [IN] NestedClass token.
- mdTypeDef *ptdEnclosingClass) // [OUT] EnclosingClass token.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetNativeCallConvFromSig ( // S_OK or error.
- void const *pvSig, // [IN] Pointer to signature.
- ULONG cbSig, // [IN] Count of signature bytes.
- ULONG *pCallConv) // [OUT] Put calling conv here (see CorPinvokemap).
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::IsGlobal ( // S_OK or error.
- mdToken pd, // [IN] Type, Field, or Method token.
- int *pbGlobal) // [OUT] Put 1 if global, 0 otherwise.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetMethodSpecProps(
- mdMethodSpec mi, // [IN] The method instantiation
- mdToken *tkParent, // [OUT] MethodDef or MemberRef
- PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data
- ULONG *pcbSigBlob) // [OUT] actual size of signature blob
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-// *** ISNAssemblySignature methods ***
-
-STDMETHODIMP AssemblyMDInternalImport::GetSNAssemblySignature(
- BYTE *pbSig, // [IN, OUT] Buffer to write signature
- DWORD *pcbSig) // [IN, OUT] Size of buffer, bytes written
-{
- return RuntimeGetAssemblyStrongNameHashForModule(m_pHandle, this, pbSig, pcbSig);
-}
-
-
-#include "strongname.h"
-
-#ifdef FEATURE_PREJIT
-// *** IGetIMDInternalImport ***
-STDMETHODIMP AssemblyMDInternalImport::GetIMDInternalImport(
- IMDInternalImport ** pIMDInternalImport)
-{
- m_pMDInternalImport->AddRef();
- *pIMDInternalImport = m_pMDInternalImport;
- return S_OK;
-}
-
-
-
-// ===========================================================================
-
-class CNativeImageDependency : public INativeImageDependency
-{
-public:
- CNativeImageDependency(CORCOMPILE_DEPENDENCY * pDependency)
- : m_cRef(1), m_pDependency(pDependency)
- {
- }
-
- ~CNativeImageDependency()
- {
- }
-
- //
- // IUnknown
- //
-
- STDMETHODIMP_(ULONG) AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
- STDMETHODIMP_(ULONG) Release()
- {
- ULONG cRef = InterlockedDecrement(&m_cRef);
- if (!cRef)
- delete this;
- return (cRef);
- }
-
- STDMETHODIMP QueryInterface(REFIID riid, void **ppUnk)
- {
- *ppUnk = 0;
-
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *) (IMetaDataAssemblyImport *) this;
- else if (riid == IID_INativeImageDependency)
- *ppUnk = (INativeImageDependency *) this;
- else
- return (E_NOINTERFACE);
- AddRef();
- return (S_OK);
- }
-
- //
- // INativeImageDependency
- //
-
- STDMETHODIMP GetILAssemblyRef(mdAssemblyRef * pAssemblyRef)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pAssemblyRef = m_pDependency->dwAssemblyRef;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- STDMETHODIMP GetILAssemblyDef(
- mdAssemblyRef * ppAssemblyDef,
- CORCOMPILE_ASSEMBLY_SIGNATURE * pSign)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *ppAssemblyDef = m_pDependency->dwAssemblyDef;
- *pSign = m_pDependency->signAssemblyDef;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- STDMETHODIMP GetNativeAssemblyDef(CORCOMPILE_NGEN_SIGNATURE * pNativeSign)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pNativeSign = m_pDependency->signNativeImage;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
- STDMETHODIMP GetPEKind(PEKIND *pPEKind)
- {
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pPEKind = PEKIND((m_pDependency->dependencyInfo & CORCOMPILE_DEPENDENCY_PEKIND_MASK) >> CORCOMPILE_DEPENDENCY_PEKIND_SHIFT);
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
- }
-
-protected:
-
- LONG m_cRef;
- CORCOMPILE_DEPENDENCY * m_pDependency;
-};
-
-// ===========================================================================
-// *** INativeImageInstallInfo ***
-// ===========================================================================
-
-STDMETHODIMP AssemblyMDInternalImport::GetSignature(CORCOMPILE_NGEN_SIGNATURE * pNgenSign)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pNgenSign = m_pZapVersionInfo->signature;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetVersionInfo(CORCOMPILE_VERSION_INFO * pVersionInfo)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pVersionInfo = *m_pZapVersionInfo;
- END_ENTRYPOINT_NOTHROW;
- return S_OK;
-}
-
-
-
-STDMETHODIMP AssemblyMDInternalImport::GetILSignature(CORCOMPILE_ASSEMBLY_SIGNATURE * pILSign)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pILSign = m_pZapVersionInfo->sourceAssembly;
- END_ENTRYPOINT_NOTHROW;
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetConfigMask(DWORD * pConfigMask)
-{
- BEGIN_ENTRYPOINT_NOTHROW;
-
- *pConfigMask = m_pZapVersionInfo->wConfigFlags;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumDependencies (
- HCORENUM * phEnum, // [IN/OUT] - Pointer to the enum
- INativeImageDependency *rDeps[], // [OUT]
- ULONG cMax, // Max dependancies to enumerate in this iteration
- DWORD * pdwCount // [OUT] - Number of dependancies actually enumerated
- )
-{
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- CORCOMPILE_DEPENDENCY * pDependenciesEnd = m_pZapDependencies + m_cZapDependencies;
-
- CORCOMPILE_DEPENDENCY * pNextDependency;
-
- // Is the enum just being initialized, or are we walking an existing one?
- if ((*phEnum) == NULL)
- pNextDependency = m_pZapDependencies;
- else
- pNextDependency = (CORCOMPILE_DEPENDENCY *)(*phEnum);
-
- DWORD count;
- for (count = 0;
- pNextDependency < pDependenciesEnd && count < cMax;
- count++, pNextDependency++)
- {
- CNativeImageDependency * pDep = new (nothrow) CNativeImageDependency(pNextDependency);
- IfNullGo( pDep );
-
- rDeps[count] = pDep;
- }
-
- *phEnum = (HCORENUM)(pNextDependency < pDependenciesEnd) ? pNextDependency : NULL;
- *pdwCount = count;
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-STDMETHODIMP AssemblyMDInternalImport::GetDependency (
- const CORCOMPILE_NGEN_SIGNATURE *pcngenSign, // [IN] ngenSig of dependency you want
- CORCOMPILE_DEPENDENCY *pDep // [OUT] matching dependency
- )
-{
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- _ASSERTE(pcngenSign != NULL);
- _ASSERTE(*pcngenSign != INVALID_NGEN_SIGNATURE);
- _ASSERTE(pDep != NULL);
-
- CORCOMPILE_DEPENDENCY * pDependenciesEnd = m_pZapDependencies + m_cZapDependencies;
- CORCOMPILE_DEPENDENCY * pNextDependency = m_pZapDependencies;
- while (pNextDependency != pDependenciesEnd)
- {
- if (pNextDependency->signNativeImage == *pcngenSign)
- {
- *pDep = *pNextDependency;
- hr = S_OK;
- goto ErrExit;
- }
- pNextDependency++;
- }
- hr = S_FALSE;
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-
-#endif // FEATURE_PREJIT
-
-
-//*****************************************************************************
-// IMetaDataImport2 methods
-//*****************************************************************************
-STDMETHODIMP AssemblyMDInternalImport::GetGenericParamProps( // S_OK or error.
- mdGenericParam gp, // [IN] GenericParam
- ULONG *pulParamSeq, // [OUT] Index of the type parameter
- DWORD *pdwParamFlags, // [OUT] Flags, for future use (e.g. variance)
- mdToken *ptOwner, // [OUT] Owner (TypeDef or MethodDef)
- DWORD *reserved, // [OUT] For future use (e.g. non-type parameters)
- __out_ecount (cchName) LPWSTR wzname, // [OUT] Put name here
- ULONG cchName, // [IN] Size of buffer
- ULONG *pchName) // [OUT] Put size of name (wide chars) here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetGenericParamConstraintProps( // S_OK or error.
- mdGenericParamConstraint gpc, // [IN] GenericParamConstraint
- mdGenericParam *ptGenericParam, // [OUT] GenericParam that is constrained
- mdToken *ptkConstraintType) // [OUT] TypeDef/Ref/Spec constraint
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumGenericParams( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] TypeDef or MethodDef whose generic parameters are requested
- mdGenericParam rGenericParams[], // [OUT] Put GenericParams here.
- ULONG cMax, // [IN] Max GenericParams to put.
- ULONG *pcGenericParams) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumGenericParamConstraints( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdGenericParam tk, // [IN] GenericParam whose constraints are requested
- mdGenericParamConstraint rGenericParamConstraints[], // [OUT] Put GenericParamConstraints here.
- ULONG cMax, // [IN] Max GenericParamConstraints to put.
- ULONG *pcGenericParamConstraints) // [OUT] Put # put here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::EnumMethodSpecs( // S_OK or error.
- HCORENUM *phEnum, // [IN|OUT] Pointer to the enum.
- mdToken tk, // [IN] MethodDef or MemberRef whose MethodSpecs are requested
- mdMethodSpec rMethodSpecs[], // [OUT] Put MethodSpecs here.
- ULONG cMax, // [IN] Max tokens to put.
- ULONG *pcMethodSpecs) // [OUT] Put actual count here.
-{
- _ASSERTE(!"NYI");
- return E_NOTIMPL;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetPEKind( // S_OK or error.
- DWORD* pdwPEKind, // [OUT] The kind of PE (0 - not a PE)
- DWORD* pdwMachine) // [OUT] Machine as defined in NT header
-{
- HRESULT hr = S_OK;
- if(pdwPEKind) *pdwPEKind = m_dwPEKind;
- if(pdwMachine) *pdwMachine = m_dwMachine;
- return hr;
-}
-
-STDMETHODIMP AssemblyMDInternalImport::GetVersionString( // S_OK or error.
- __out_ecount (ccBufSize) LPWSTR pwzBuf, // Put version string here.
- DWORD ccBufSize, // [in] size of the buffer, in wide chars
- DWORD *pccBufSize) // [out] Size of the version string, wide chars, including terminating nul.
-{
- HRESULT hr=S_OK;
- DWORD L = WszMultiByteToWideChar(CP_UTF8,0,m_szVersionString,-1,pwzBuf,ccBufSize);
- if(ccBufSize < L)
- hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
-
- if(pccBufSize) *pccBufSize = L;
- return hr;
-}
-
-#endif //!DACCESS_COMPILE
-
-#endif // FEATURE_FUSION
#endif //FEATURE_METADATA_INTERNAL_APIS
diff --git a/src/md/runtime/metamodel.cpp b/src/md/runtime/metamodel.cpp
index 293e5b6b5e..83addc6d6c 100644
--- a/src/md/runtime/metamodel.cpp
+++ b/src/md/runtime/metamodel.cpp
@@ -519,7 +519,6 @@ CMiniMdBase::SchemaPopulate(
{
// No it's not. Is this an older version that we support?
-#ifndef FEATURE_METADATA_STANDALONE_WINRT
// Is this v1.0?
if ((m_Schema.m_major == METAMODEL_MAJOR_VER_V1_0) &&
(m_Schema.m_minor == METAMODEL_MINOR_VER_V1_0))
@@ -535,7 +534,6 @@ CMiniMdBase::SchemaPopulate(
m_TableDefs[TBL_GenericParam].m_pColDefs = BYTEARRAY_TO_COLDES(s_GenericParamCol);
}
else
-#endif //!FEATURE_METADATA_STANDALONE_WINRT
{ // We don't support this version of the metadata
Debug_ReportError("Unsupported version of MetaData.");
return PostError(CLDB_E_FILE_OLDVER, m_Schema.m_major, m_Schema.m_minor);
diff --git a/src/md/runtime/wks/CMakeLists.txt b/src/md/runtime/wks/CMakeLists.txt
index 9a1f72ed25..3e2a8cc6be 100644
--- a/src/md/runtime/wks/CMakeLists.txt
+++ b/src/md/runtime/wks/CMakeLists.txt
@@ -1,5 +1,7 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDRUNTIME_SOURCES)
add_library_clr(mdruntime_wks ${MDRUNTIME_SOURCES})
diff --git a/src/md/winmd/adapter.cpp b/src/md/winmd/adapter.cpp
index 2c9dd1b9fd..d4e95b7f8b 100644
--- a/src/md/winmd/adapter.cpp
+++ b/src/md/winmd/adapter.cpp
@@ -1185,14 +1185,12 @@ void WinMDAdapter::GetExtraAssemblyRefProps(FrameworkAssemblyIndex index,
if (ppPublicKeytoken)
{
-#ifdef FEATURE_CORECLR
if (index == FrameworkAssembly_Mscorlib)
{
*ppPublicKeytoken = g_rbTheSilverlightPlatformKeyToken;
*pTokenLength = sizeof(g_rbTheSilverlightPlatformKeyToken);
}
else
-#endif
{
if (index == FrameworkAssembly_SystemNumericsVectors || index == FrameworkAssembly_SystemRuntime || index == FrameworkAssembly_SystemObjectModel)
{
diff --git a/src/md/winmd/inc/adapter.h b/src/md/winmd/inc/adapter.h
index e42992f81f..cc422017b6 100644
--- a/src/md/winmd/inc/adapter.h
+++ b/src/md/winmd/inc/adapter.h
@@ -236,14 +236,12 @@ public:
if (pusRevisionNumber != nullptr)
*pusRevisionNumber = VER_ASSEMBLYBUILD_QFE;
-#ifdef FEATURE_CORECLR
// Under CoreCLR, we replace the ECMA key in the mscorlib assembly ref with the CoreCLR platform public key token
if (ppbPublicKeyOrToken != nullptr)
{
*ppbPublicKeyOrToken = g_rbTheSilverlightPlatformKeyToken;
*pcbPublicKeyOrToken = _countof(g_rbTheSilverlightPlatformKeyToken);
}
-#endif
}
else if (RidFromToken(mdar) > m_rawAssemblyRefCount)
{
@@ -632,11 +630,7 @@ public:
case FrameworkAssembly_SystemRuntimeWindowsRuntimeUIXaml:
return "System.Runtime.WindowsRuntime.UI.Xaml";
case FrameworkAssembly_SystemNumericsVectors:
-#ifdef FEATURE_CORECLR
return "System.Numerics.Vectors";
-#else
- return "System.Numerics";
-#endif
default:
_ASSERTE(!"Invalid AssemblyRef token!");
return NULL;
diff --git a/src/md/winmd/wks/CMakeLists.txt b/src/md/winmd/wks/CMakeLists.txt
index 139b68b28c..defcc1d51d 100644
--- a/src/md/winmd/wks/CMakeLists.txt
+++ b/src/md/winmd/wks/CMakeLists.txt
@@ -1,4 +1,6 @@
include(../../md_wks.cmake)
+add_definitions(-DFEATURE_METADATA_EMIT_ALL)
+
add_precompiled_header(stdafx.h ../stdafx.cpp MDWINMD_SOURCES)
-add_library_clr(mdwinmd_wks ${MDWINMD_SOURCES}) \ No newline at end of file
+add_library_clr(mdwinmd_wks ${MDWINMD_SOURCES})