summaryrefslogtreecommitdiff
path: root/src/debug/daccess/inspect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/debug/daccess/inspect.cpp')
-rw-r--r--src/debug/daccess/inspect.cpp3840
1 files changed, 3840 insertions, 0 deletions
diff --git a/src/debug/daccess/inspect.cpp b/src/debug/daccess/inspect.cpp
new file mode 100644
index 0000000000..5276626dcb
--- /dev/null
+++ b/src/debug/daccess/inspect.cpp
@@ -0,0 +1,3840 @@
+// 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: inspect.cpp
+//
+
+//
+// ClrData object inspection.
+//
+//*****************************************************************************
+
+#include "stdafx.h"
+
+
+HRESULT
+InitFieldIter(DeepFieldDescIterator* fieldIter,
+ TypeHandle typeHandle,
+ bool canHaveFields,
+ ULONG32 flags,
+ IXCLRDataTypeInstance* fromType)
+{
+ // Currently we can't filter on kinds so
+ // require them all.
+ if ((flags & ~CLRDATA_FIELD_ALL_FIELDS) != 0 ||
+ (flags & CLRDATA_TYPE_ALL_KINDS) != CLRDATA_TYPE_ALL_KINDS ||
+ (flags & CLRDATA_FIELD_ALL_LOCATIONS) == 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ if (!canHaveFields)
+ {
+ // Leave default empty initialization.
+ return S_OK;
+ }
+
+ int fieldIterFlags = ApproxFieldDescIterator::ALL_FIELDS;
+
+ if ((flags & CLRDATA_FIELD_FROM_INSTANCE) == 0)
+ {
+ fieldIterFlags &= ~ApproxFieldDescIterator::INSTANCE_FIELDS;
+ }
+ if ((flags & CLRDATA_FIELD_FROM_STATIC) == 0)
+ {
+ fieldIterFlags &= ~ApproxFieldDescIterator::STATIC_FIELDS;
+ }
+
+ bool includeParents;
+
+ if ((flags & CLRDATA_FIELD_IS_INHERITED) == 0)
+ {
+ if (fromType)
+ {
+ typeHandle = ((ClrDataTypeInstance*)fromType)->GetTypeHandle();
+ }
+ includeParents = false;
+ }
+ else if (fromType)
+ {
+ return E_INVALIDARG;
+ }
+ else
+ {
+ includeParents = true;
+ }
+
+ if (typeHandle.IsNull() ||
+ !typeHandle.GetMethodTable() ||
+ !typeHandle.IsRestored())
+ {
+ return E_INVALIDARG;
+ }
+
+ fieldIter->Init(typeHandle.GetMethodTable(), fieldIterFlags, includeParents);
+
+ return S_OK;
+}
+
+ULONG32
+GetTypeFieldValueFlags(TypeHandle typeHandle,
+ FieldDesc* fieldDesc,
+ ULONG32 otherFlags,
+ bool isDeref)
+{
+ otherFlags &= ~(CLRDATA_VALUE_IS_PRIMITIVE |
+ CLRDATA_VALUE_IS_VALUE_TYPE |
+ CLRDATA_VALUE_IS_STRING |
+ CLRDATA_VALUE_IS_ARRAY |
+ CLRDATA_VALUE_IS_REFERENCE |
+ CLRDATA_VALUE_IS_POINTER |
+ CLRDATA_VALUE_IS_ENUM);
+
+ CorElementType eltType;
+
+ if (fieldDesc)
+ {
+ eltType = fieldDesc->GetFieldType();
+ }
+ else
+ {
+ _ASSERTE(!typeHandle.IsNull());
+ eltType = typeHandle.GetInternalCorElementType();
+ }
+
+ if (!isDeref && CorTypeInfo::IsObjRef_NoThrow(eltType))
+ {
+ otherFlags |= CLRDATA_VALUE_IS_REFERENCE;
+ }
+ else if (typeHandle.IsEnum())
+ {
+ otherFlags |= CLRDATA_VALUE_IS_ENUM;
+ }
+ else if (eltType == ELEMENT_TYPE_STRING)
+ {
+ otherFlags |= CLRDATA_VALUE_IS_STRING;
+ }
+ else if (eltType == ELEMENT_TYPE_PTR)
+ {
+ otherFlags |= CLRDATA_VALUE_IS_POINTER;
+ }
+ else if (CorTypeInfo::IsPrimitiveType_NoThrow(eltType))
+ {
+ otherFlags |= CLRDATA_VALUE_IS_PRIMITIVE;
+ }
+ else if (typeHandle.IsArray())
+ {
+ otherFlags |= CLRDATA_VALUE_IS_ARRAY;
+ }
+ else if (typeHandle.IsValueType())
+ {
+ otherFlags |= CLRDATA_VALUE_IS_VALUE_TYPE;
+ }
+ else if (eltType == ELEMENT_TYPE_CLASS)
+ {
+ //
+ // Perform extra checks to identify well-known classes.
+ //
+
+ if ((&g_Mscorlib)->IsClass(typeHandle.GetMethodTable(), CLASS__STRING))
+ {
+ otherFlags |= CLRDATA_VALUE_IS_STRING;
+ }
+ }
+
+ if (fieldDesc)
+ {
+ otherFlags &= ~(CLRDATA_VALUE_IS_LITERAL |
+ CLRDATA_VALUE_FROM_INSTANCE |
+ CLRDATA_VALUE_FROM_TASK_LOCAL |
+ CLRDATA_VALUE_FROM_STATIC);
+
+ if ((isDeref ||
+ (otherFlags & CLRDATA_VALUE_IS_REFERENCE) == 0) &&
+ IsFdLiteral(fieldDesc->GetAttributes()))
+ {
+ otherFlags |= CLRDATA_VALUE_IS_LITERAL;
+ }
+
+ if (fieldDesc->IsStatic())
+ {
+ otherFlags |= CLRDATA_VALUE_FROM_STATIC;
+ }
+ else if (fieldDesc->IsThreadStatic())
+ {
+ otherFlags |= CLRDATA_VALUE_FROM_TASK_LOCAL;
+ }
+ else
+#ifdef FEATURE_REMOTING
+ if (!fieldDesc->IsContextStatic())
+#endif
+ {
+ otherFlags |= CLRDATA_VALUE_FROM_INSTANCE;
+ }
+ }
+
+ return otherFlags;
+}
+
+//----------------------------------------------------------------------------
+//
+// ClrDataValue.
+//
+//----------------------------------------------------------------------------
+
+ClrDataValue::ClrDataValue(ClrDataAccess* dac,
+ AppDomain* appDomain,
+ Thread* thread,
+ ULONG32 flags,
+ TypeHandle typeHandle,
+ ULONG64 baseAddr,
+ ULONG32 numLocs,
+ NativeVarLocation* locs)
+{
+ m_dac = dac;
+ m_dac->AddRef();
+ m_instanceAge = m_dac->m_instanceAge;
+ m_refs = 1;
+ m_appDomain = appDomain;
+ m_thread = thread;
+ m_flags = flags;
+ m_typeHandle = typeHandle;
+ m_baseAddr = baseAddr;
+ m_numLocs = numLocs;
+ if (numLocs)
+ {
+ memcpy(m_locs, locs, numLocs * sizeof(m_locs[0]));
+ }
+
+ if (numLocs && (m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
+ {
+ m_totalSize = sizeof(TADDR);
+ }
+ else
+ {
+ m_totalSize = 0;
+ for (ULONG32 i = 0; i < m_numLocs; i++)
+ {
+ m_totalSize += m_locs[i].size;
+ }
+ }
+}
+
+ClrDataValue::~ClrDataValue(void)
+{
+ m_dac->Release();
+}
+
+STDMETHODIMP
+ClrDataValue::QueryInterface(THIS_
+ IN REFIID interfaceId,
+ OUT PVOID* iface)
+{
+ if (IsEqualIID(interfaceId, IID_IUnknown) ||
+ IsEqualIID(interfaceId, __uuidof(IXCLRDataValue)))
+ {
+ AddRef();
+ *iface = static_cast<IUnknown*>
+ (static_cast<IXCLRDataValue*>(this));
+ return S_OK;
+ }
+ else
+ {
+ *iface = NULL;
+ return E_NOINTERFACE;
+ }
+}
+
+STDMETHODIMP_(ULONG)
+ClrDataValue::AddRef(THIS)
+{
+ return InterlockedIncrement(&m_refs);
+}
+
+STDMETHODIMP_(ULONG)
+ClrDataValue::Release(THIS)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ LONG newRefs = InterlockedDecrement(&m_refs);
+ if (newRefs == 0)
+ {
+ delete this;
+ }
+ return newRefs;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetFlags(
+ /* [out] */ ULONG32 *flags)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ *flags = m_flags;
+ status = S_OK;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetAddress(
+ /* [out] */ CLRDATA_ADDRESS *address)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // This query can only be answered if there's a
+ // single non-register address.
+ if (m_numLocs == 1 &&
+ !m_locs[0].contextReg)
+ {
+ *address = TO_CDADDR(m_locs[0].addr);
+ status = S_OK;
+ }
+ else
+ {
+ status = E_NOINTERFACE;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetSize(
+ /* [out] */ ULONG64 *size)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_totalSize)
+ {
+ *size = m_totalSize;
+ status = S_OK;
+ }
+ else
+ {
+ status = E_NOINTERFACE;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT
+ClrDataValue::IntGetBytes(
+ /* [in] */ ULONG32 bufLen,
+ /* [size_is][out] */ BYTE buffer[ ])
+{
+ HRESULT status;
+
+ NativeVarLocation* loc = m_locs;
+ for (ULONG32 i = 0; i < m_numLocs; i++)
+ {
+ if (loc->contextReg)
+ {
+ memcpy(buffer, (void*)(ULONG_PTR)loc->addr, loc->size);
+ buffer += loc->size;
+ }
+ else
+ {
+ ULONG32 done;
+
+ _ASSERTE(FitsIn<ULONG32>(loc->size));
+ status = m_dac->m_pTarget->
+ ReadVirtual(loc->addr, buffer, static_cast<ULONG32>(loc->size),
+ &done);
+ if (status != S_OK)
+ {
+ return CORDBG_E_READVIRTUAL_FAILURE;
+ }
+ if (done != loc->size)
+ {
+ return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
+ }
+
+ buffer += loc->size;
+ }
+
+ loc++;
+ }
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetBytes(
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *dataSize,
+ /* [size_is][out] */ BYTE buffer[ ])
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (!m_totalSize)
+ {
+ status = E_NOINTERFACE;
+ goto Exit;
+ }
+
+ if (dataSize)
+ {
+ _ASSERTE(FitsIn<ULONG32>(m_totalSize));
+ *dataSize = static_cast<ULONG32>(m_totalSize);
+ }
+
+ if (bufLen < m_totalSize)
+ {
+ status = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
+ goto Exit;
+ }
+
+ status = IntGetBytes(bufLen, buffer);
+
+ Exit: ;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::SetBytes(
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *dataSize,
+ /* [size_is][in] */ BYTE buffer[ ])
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ NativeVarLocation* loc = NULL;
+
+ if (!m_totalSize)
+ {
+ status = E_NOINTERFACE;
+ goto Exit;
+ }
+
+ if (dataSize)
+ {
+ _ASSERTE(FitsIn<ULONG32>(m_totalSize));
+ *dataSize = static_cast<ULONG32>(m_totalSize);
+ }
+
+ if (bufLen < m_totalSize)
+ {
+ status = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
+ goto Exit;
+ }
+
+ loc = m_locs;
+ for (ULONG32 i = 0; i < m_numLocs; i++)
+ {
+ if (loc->contextReg)
+ {
+ // XXX Microsoft - Context update?
+ // memcpy(buffer, (void*)(ULONG_PTR)loc->addr, loc->size);
+ // buffer += loc->size;
+ // until drew decides, return notimpl
+ status = E_NOTIMPL;
+ goto Exit;
+ }
+ else
+ {
+ _ASSERT(FitsIn<ULONG32>(loc->size));
+ status = m_dac->m_pMutableTarget->
+ WriteVirtual(loc->addr, buffer, static_cast<ULONG32>(loc->size));
+ if (status != S_OK)
+ {
+ goto Exit;
+ }
+
+ buffer += loc->size;
+ }
+
+ loc++;
+ }
+
+ status = S_OK;
+
+ Exit: ;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetType(
+ /* [out] */ IXCLRDataTypeInstance **typeInstance)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if ((m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
+ {
+ *typeInstance = NULL;
+ status = S_FALSE;
+ }
+ else if (!m_appDomain ||
+ m_typeHandle.IsNull())
+ {
+ status = E_NOTIMPL;
+ }
+ else
+ {
+ *typeInstance = new (nothrow)
+ ClrDataTypeInstance(m_dac, m_appDomain, m_typeHandle);
+ status = *typeInstance ? S_OK : E_OUTOFMEMORY;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetNumFields(
+ /* [out] */ ULONG32 *numFields)
+{
+ // XXX Microsoft - Obsolete method, never implemented.
+ return E_UNEXPECTED;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetFieldByIndex(
+ /* [in] */ ULONG32 index,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ mdFieldDef *token)
+{
+ // XXX Microsoft - Obsolete method, never implemented.
+ return E_UNEXPECTED;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetNumFields2(
+ /* [in] */ ULONG32 flags,
+ /* [in] */ IXCLRDataTypeInstance *fromType,
+ /* [out] */ ULONG32 *numFields)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ DeepFieldDescIterator fieldIter;
+
+ if ((status = InitFieldIter(&fieldIter, m_typeHandle, CanHaveFields(),
+ flags, fromType)) == S_OK)
+ {
+ *numFields = fieldIter.Count();
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::StartEnumFields(
+ /* [in] */ ULONG32 flags,
+ /* [in] */ IXCLRDataTypeInstance *fromType,
+ /* [out] */ CLRDATA_ENUM *handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::
+ CdStartField(NULL,
+ 0,
+ flags,
+ fromType,
+ m_typeHandle,
+ NULL,
+ mdTypeDefNil,
+ m_baseAddr,
+ m_thread,
+ NULL,
+ m_appDomain,
+ NULL,
+ NULL,
+ handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::EnumField(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 nameBufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ mdFieldDef *token)
+{
+ return EnumField2(handle, field, nameBufLen, nameLen, nameBuf,
+ NULL, token);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::EnumField2(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 nameBufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ IXCLRDataModule** tokenScope,
+ /* [out] */ mdFieldDef *token)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdNextField(m_dac, handle, NULL, NULL, field,
+ nameBufLen, nameLen, nameBuf,
+ tokenScope, token);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::EndEnumFields(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::StartEnumFieldsByName(
+ /* [in] */ LPCWSTR name,
+ /* [in] */ ULONG32 nameFlags,
+ /* [in] */ ULONG32 fieldFlags,
+ /* [in] */ IXCLRDataTypeInstance *fromType,
+ /* [out] */ CLRDATA_ENUM *handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::
+ CdStartField(name,
+ nameFlags,
+ fieldFlags,
+ fromType,
+ m_typeHandle,
+ NULL,
+ mdTypeDefNil,
+ m_baseAddr,
+ m_thread,
+ NULL,
+ m_appDomain,
+ NULL,
+ NULL,
+ handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::EnumFieldByName(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [out] */ IXCLRDataValue **field,
+ /* [out] */ mdFieldDef *token)
+{
+ return EnumFieldByName2(handle, field, NULL, token);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::EnumFieldByName2(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [out] */ IXCLRDataValue **field,
+ /* [out] */ IXCLRDataModule** tokenScope,
+ /* [out] */ mdFieldDef *token)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdNextField(m_dac, handle, NULL, NULL, field,
+ 0, NULL, NULL,
+ tokenScope, token);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::EndEnumFieldsByName(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetFieldByToken(
+ /* [in] */ mdFieldDef token,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
+{
+ return GetFieldByToken2(NULL, token, field, bufLen, nameLen, nameBuf);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetFieldByToken2(
+ /* [in] */ IXCLRDataModule* tokenScope,
+ /* [in] */ mdFieldDef token,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ DeepFieldDescIterator fieldIter;
+
+ if ((status = InitFieldIter(&fieldIter, m_typeHandle, CanHaveFields(),
+ CLRDATA_VALUE_ALL_FIELDS, NULL)) == S_OK)
+ {
+ FieldDesc* fieldDesc;
+
+ status = E_INVALIDARG;
+ while ((fieldDesc = fieldIter.Next()))
+ {
+ if ((!tokenScope ||
+ PTR_HOST_TO_TADDR(((ClrDataModule*)tokenScope)->
+ GetModule()) ==
+ PTR_HOST_TO_TADDR(fieldDesc->GetModule())) &&
+ fieldDesc->GetMemberDef() == token)
+ {
+ status = NewFromSubField(fieldDesc,
+ fieldIter.
+ IsFieldFromParentClass() ?
+ CLRDATA_VALUE_IS_INHERITED : 0,
+ NULL, field,
+ bufLen, nameLen, nameBuf,
+ NULL, NULL);
+ break;
+ }
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT
+ClrDataValue::GetRefAssociatedValue(IXCLRDataValue** assocValue)
+{
+ HRESULT status;
+
+ if (m_typeHandle.IsNull())
+ {
+ return E_NOINTERFACE;
+ }
+
+ TADDR refAddr;
+
+ _ASSERTE(m_totalSize == sizeof(refAddr));
+
+ if ((status = IntGetBytes(sizeof(refAddr),
+ (PBYTE)&refAddr)) != S_OK)
+ {
+ return status;
+ }
+
+ // We assume that objrefs always refer
+ // to objects so there is no ref chain.
+ ULONG32 valueFlags =
+ GetTypeFieldValueFlags(m_typeHandle, NULL,
+ m_flags & CLRDATA_VALUE_ALL_LOCATIONS, true);
+
+ NativeVarLocation loc;
+
+ loc.addr = TO_CDADDR(refAddr);
+ // XXX Microsoft - Good way to get the right size for everything?
+ loc.size = (m_typeHandle.GetMethodTable())->GetBaseSize();
+ loc.contextReg = false;
+
+ *assocValue = new (nothrow)
+ ClrDataValue(m_dac,
+ m_appDomain,
+ m_thread,
+ valueFlags,
+ m_typeHandle,
+ loc.addr,
+ 1,
+ &loc);
+ return *assocValue ? S_OK : E_OUTOFMEMORY;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetAssociatedValue(
+ /* [out] */ IXCLRDataValue **assocValue)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_numLocs && (m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
+ {
+ status = GetRefAssociatedValue(assocValue);
+ }
+ else
+ {
+ status = E_NOINTERFACE;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetAssociatedType(
+ /* [out] */ IXCLRDataTypeInstance **assocType)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ TypeHandle dacType;
+
+ if ((m_flags & CLRDATA_VALUE_IS_REFERENCE) != 0)
+ {
+ dacType = m_typeHandle;
+ }
+ else if ((m_flags & CLRDATA_VALUE_IS_ARRAY) != 0)
+ {
+ ArrayBase* arrayBase = PTR_ArrayBase(CLRDATA_ADDRESS_TO_TADDR(m_baseAddr));
+ dacType = arrayBase->GetArrayElementTypeHandle();
+ }
+
+ if (dacType.IsNull())
+ {
+ status = E_NOINTERFACE;
+ }
+ else
+ {
+ *assocType = new (nothrow)
+ ClrDataTypeInstance(m_dac,
+ m_appDomain,
+ dacType);
+ status = *assocType ? S_OK : E_OUTOFMEMORY;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetString(
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *strLen,
+ /* [size_is][out] */ __out_ecount_part(bufLen, *strLen) WCHAR str[ ])
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if ((m_flags & CLRDATA_VALUE_IS_STRING) != 0)
+ {
+ STRINGREF message = STRINGREF(TO_TADDR(m_baseAddr));
+
+ PWSTR msgStr = DacInstantiateStringW((TADDR)message->GetBuffer(),
+ message->GetStringLength(),
+ true);
+
+ if (strLen)
+ {
+ *strLen = static_cast<ULONG32>(wcslen(msgStr) + 1);
+ }
+ status = StringCchCopy(str, bufLen, msgStr) == S_OK ?
+ S_OK : S_FALSE;
+ }
+ else
+ {
+ status = E_INVALIDARG;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetArrayProperties(
+ /* [out] */ ULONG32 *rank,
+ /* [out] */ ULONG32 *totalElements,
+ /* [in] */ ULONG32 numDim,
+ /* [size_is][out] */ ULONG32 dims[ ],
+ /* [in] */ ULONG32 numBases,
+ /* [size_is][out] */ LONG32 bases[ ])
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if ((m_flags & CLRDATA_VALUE_IS_ARRAY) != 0)
+ {
+ ArrayBase* arrayBase = PTR_ArrayBase(CLRDATA_ADDRESS_TO_TADDR(m_baseAddr));
+ unsigned baseRank = arrayBase->GetRank();
+ unsigned i;
+
+ if (rank)
+ {
+ *rank = baseRank;
+ }
+
+ if (totalElements)
+ {
+ *totalElements = arrayBase->GetNumComponents();
+ }
+
+ if (numDim)
+ {
+ PTR_INT32 bounds = arrayBase->GetBoundsPtr();
+
+ for (i = 0; i < baseRank; i++)
+ {
+ if (i < numDim)
+ {
+ dims[i] = bounds[i];
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ if (numBases)
+ {
+ PTR_INT32 lowBounds = arrayBase->GetLowerBoundsPtr();
+
+ for (i = 0; i < baseRank; i++)
+ {
+ if (i < numBases)
+ {
+ bases[i] = lowBounds[i];
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ status = S_OK;
+ }
+ else
+ {
+ status = E_INVALIDARG;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetArrayElement(
+ /* [in] */ ULONG32 numInd,
+ /* [size_is][in] */ LONG32 indices[ ],
+ /* [out] */ IXCLRDataValue **value)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ PTR_INT32 bounds, lowBounds;
+ TypeHandle eltType;
+
+ if ((m_flags & CLRDATA_VALUE_IS_ARRAY) == 0)
+ {
+ status = E_INVALIDARG;
+ goto Exit;
+ }
+
+ ArrayBase* arrayBase;
+ unsigned baseRank;
+
+ arrayBase = PTR_ArrayBase(CLRDATA_ADDRESS_TO_TADDR(m_baseAddr));
+ baseRank = arrayBase->GetRank();
+ if (numInd != baseRank)
+ {
+ status = E_INVALIDARG;
+ goto Exit;
+ }
+
+ eltType = arrayBase->GetArrayElementTypeHandle();
+ if (eltType.IsNull())
+ {
+ status = E_INVALIDARG;
+ goto Exit;
+ }
+
+ unsigned dim;
+ ULONG64 offs;
+ SIZE_T dimSize;
+
+ dim = baseRank;
+ offs = TO_CDADDR(PTR_TO_TADDR(arrayBase->GetDataPtr()));
+ dimSize = arrayBase->GetComponentSize();
+ bounds = arrayBase->GetBoundsPtr();
+ lowBounds = arrayBase->GetLowerBoundsPtr();
+
+ while (dim-- > 0)
+ {
+ if (indices[dim] < lowBounds[dim])
+ {
+ status = E_INVALIDARG;
+ goto Exit;
+ }
+
+ UINT32 uindex = (UINT32)(indices[dim] - lowBounds[dim]);
+ if (uindex >= (UINT32)bounds[dim])
+ {
+ status = E_INVALIDARG;
+ goto Exit;
+ }
+
+ offs += dimSize * uindex;
+
+ dimSize *= (UINT64)bounds[dim];
+ }
+
+ NativeVarLocation loc;
+
+ loc.addr = offs;
+ loc.size = eltType.GetSize();
+ loc.contextReg = false;
+
+ *value = new (nothrow)
+ ClrDataValue(m_dac, m_appDomain, m_thread,
+ GetTypeFieldValueFlags(eltType, NULL, 0, false),
+ eltType, offs, 1, &loc);
+ status = *value ? S_OK : E_OUTOFMEMORY;
+
+ Exit: ;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetNumLocations(
+ /* [out] */ ULONG32* numLocs)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ *numLocs = m_numLocs;
+ status = S_OK;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::GetLocationByIndex(
+ /* [in] */ ULONG32 loc,
+ /* [out] */ ULONG32* flags,
+ /* [out] */ CLRDATA_ADDRESS* arg)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (loc < m_numLocs)
+ {
+ if (m_locs[loc].contextReg)
+ {
+ *flags = CLRDATA_VLOC_REGISTER;
+ *arg = 0;
+ }
+ else
+ {
+ *flags = CLRDATA_VLOC_MEMORY;
+ *arg = TO_CDADDR(m_locs[loc].addr);
+ }
+
+ status = S_OK;
+ }
+ else
+ {
+ status = E_INVALIDARG;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataValue::Request(
+ /* [in] */ ULONG32 reqCode,
+ /* [in] */ ULONG32 inBufferSize,
+ /* [size_is][in] */ BYTE *inBuffer,
+ /* [in] */ ULONG32 outBufferSize,
+ /* [size_is][out] */ BYTE *outBuffer)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ switch(reqCode)
+ {
+ case CLRDATA_REQUEST_REVISION:
+ if (inBufferSize != 0 ||
+ inBuffer ||
+ outBufferSize != sizeof(ULONG32))
+ {
+ status = E_INVALIDARG;
+ }
+ else
+ {
+ *(ULONG32*)outBuffer = 3;
+ status = S_OK;
+ }
+ break;
+
+ default:
+ status = E_INVALIDARG;
+ break;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT
+ClrDataValue::NewFromFieldDesc(ClrDataAccess* dac,
+ AppDomain* appDomain,
+ ULONG32 flags,
+ FieldDesc* fieldDesc,
+ ULONG64 objBase,
+ Thread* tlsThread,
+ ClrDataValue** value,
+ IXCLRDataValue** pubValue,
+ ULONG32 nameBufRetLen,
+ ULONG32 *nameLenRet,
+ __out_ecount_part_opt(nameBufRetLen, *nameLenRet) WCHAR nameBufRet[ ],
+ IXCLRDataModule** tokenScopeRet,
+ mdFieldDef *tokenRet)
+{
+ HRESULT status;
+ ClrDataValue* field;
+ ULONG numLocs = 1;
+ NativeVarLocation varLoc, *locs = &varLoc;
+ ULONG64 baseAddr;
+ LPCUTF8 szFieldName;
+
+ status = fieldDesc->GetName_NoThrow(&szFieldName);
+ if (status != S_OK)
+ {
+ return status;
+ }
+
+ status = ConvertUtf8(
+ szFieldName,
+ nameBufRetLen,
+ nameLenRet,
+ nameBufRet);
+ if (status != S_OK)
+ {
+ return status;
+ }
+
+ if (tokenRet != NULL)
+ {
+ *tokenRet = fieldDesc->GetMemberDef();
+ }
+
+ if (fieldDesc->GetEnclosingMethodTable()->ContainsGenericVariables())
+ {
+ // This field is for a generic type definition and
+ // so doesn't have a real location. Produce
+ // a placeholder no-data value.
+ numLocs = 0;
+ locs = NULL;
+ baseAddr = 0;
+ }
+ else if (fieldDesc->IsThreadStatic())
+ {
+ if (!tlsThread)
+ {
+ return E_INVALIDARG;
+ }
+
+ baseAddr =
+ TO_CDADDR(tlsThread->GetStaticFieldAddrNoCreate(fieldDesc, NULL));
+ }
+#ifdef FEATURE_REMOTING
+ else if (fieldDesc->IsContextStatic())
+ {
+ // XXX Microsoft - Microsoft says Context is going away.
+ return E_NOTIMPL;
+ }
+#endif
+ else if (fieldDesc->IsStatic())
+ {
+ baseAddr = TO_CDADDR
+ (PTR_TO_TADDR(fieldDesc->GetStaticAddressHandle
+ (fieldDesc->GetBaseInDomain(appDomain))));
+ }
+ else
+ {
+ // objBase is basically a CLRDATA_ADDRESS, which is a pointer-sized target address sign-extened to
+ // 64-bit. We need to get a TADDR here, which is a pointer-size unsigned value.
+ baseAddr = TO_CDADDR(PTR_TO_TADDR(fieldDesc->GetAddress(PTR_VOID(CLRDATA_ADDRESS_TO_TADDR(objBase)))));
+ }
+
+ if (locs)
+ {
+ locs->addr = baseAddr;
+ locs->size = fieldDesc->GetSize();
+ locs->contextReg = false;
+ }
+
+ TypeHandle typeHandle = fieldDesc->LookupFieldTypeHandle();
+
+ // We allow no-type situations for reference fields
+ // as they can still be useful even though they cannot
+ // be expanded. This is also a common case where the
+ // referred-to type may not be loaded if the field
+ // is holding null.
+ if (typeHandle.IsNull() && !fieldDesc->IsObjRef())
+ {
+ return E_INVALIDARG;
+ }
+
+ flags = GetTypeFieldValueFlags(typeHandle, fieldDesc, flags, false);
+
+ if (tokenScopeRet)
+ {
+ *tokenScopeRet = new (nothrow)
+ ClrDataModule(dac, fieldDesc->GetModule());
+ if (!*tokenScopeRet)
+ {
+ return E_OUTOFMEMORY;
+ }
+ }
+
+ field = new (nothrow) ClrDataValue(dac,
+ appDomain,
+ tlsThread,
+ flags,
+ typeHandle,
+ baseAddr,
+ numLocs,
+ locs);
+ if (value)
+ {
+ *value = field;
+ }
+ if (pubValue)
+ {
+ *pubValue = field;
+ }
+
+ if (!field)
+ {
+ if (tokenScopeRet)
+ {
+ delete (ClrDataModule*)*tokenScopeRet;
+ }
+ return E_OUTOFMEMORY;
+ }
+
+ return S_OK;
+}
+
+//----------------------------------------------------------------------------
+//
+// ClrDataTypeDefinition.
+//
+//----------------------------------------------------------------------------
+
+ClrDataTypeDefinition::ClrDataTypeDefinition(ClrDataAccess* dac,
+ Module* module,
+ mdTypeDef token,
+ TypeHandle typeHandle)
+{
+ m_dac = dac;
+ m_dac->AddRef();
+ m_instanceAge = m_dac->m_instanceAge;
+ m_refs = 1;
+ m_module = module;
+ m_token = token;
+ m_typeHandle = typeHandle;
+}
+
+ClrDataTypeDefinition::~ClrDataTypeDefinition(void)
+{
+ m_dac->Release();
+}
+
+STDMETHODIMP
+ClrDataTypeDefinition::QueryInterface(THIS_
+ IN REFIID interfaceId,
+ OUT PVOID* iface)
+{
+ if (IsEqualIID(interfaceId, IID_IUnknown) ||
+ IsEqualIID(interfaceId, __uuidof(IXCLRDataTypeDefinition)))
+ {
+ AddRef();
+ *iface = static_cast<IUnknown*>
+ (static_cast<IXCLRDataTypeDefinition*>(this));
+ return S_OK;
+ }
+ else
+ {
+ *iface = NULL;
+ return E_NOINTERFACE;
+ }
+}
+
+STDMETHODIMP_(ULONG)
+ClrDataTypeDefinition::AddRef(THIS)
+{
+ return InterlockedIncrement(&m_refs);
+}
+
+STDMETHODIMP_(ULONG)
+ClrDataTypeDefinition::Release(THIS)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ LONG newRefs = InterlockedDecrement(&m_refs);
+ if (newRefs == 0)
+ {
+ delete this;
+ }
+ return newRefs;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetModule(
+ /* [out] */ IXCLRDataModule **mod)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ *mod = new (nothrow)
+ ClrDataModule(m_dac, m_module);
+ status = *mod ? S_OK : E_OUTOFMEMORY;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::StartEnumMethodDefinitions(
+ /* [out] */ CLRDATA_ENUM* handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = MetaEnum::New(m_module,
+ mdtMethodDef,
+ m_token,
+ NULL,
+ NULL,
+ handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EnumMethodDefinition(
+ /* [in, out] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataMethodDefinition **methodDefinition)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ mdMethodDef token;
+
+ if ((status = MetaEnum::CdNextToken(handle, &token)) == S_OK)
+ {
+ status = ClrDataMethodDefinition::
+ NewFromModule(m_dac,
+ m_module,
+ token,
+ NULL,
+ methodDefinition);
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EndEnumMethodDefinitions(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = MetaEnum::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::StartEnumMethodDefinitionsByName(
+ /* [in] */ LPCWSTR name,
+ /* [in] */ ULONG32 flags,
+ /* [out] */ CLRDATA_ENUM* handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdStartMethod(name,
+ flags,
+ m_module,
+ m_token,
+ NULL,
+ NULL,
+ NULL,
+ handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EnumMethodDefinitionByName(
+ /* [out][in] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataMethodDefinition **method)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ mdMethodDef token;
+
+ if ((status = SplitName::CdNextMethod(handle, &token)) == S_OK)
+ {
+ status = ClrDataMethodDefinition::
+ NewFromModule(m_dac,
+ m_module,
+ token,
+ NULL,
+ method);
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EndEnumMethodDefinitionsByName(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetMethodDefinitionByToken(
+ /* [in] */ mdMethodDef token,
+ /* [out] */ IXCLRDataMethodDefinition **methodDefinition)
+{
+ HRESULT status;
+
+ // This isn't critically necessary but it prevents
+ // an assert in the metadata code.
+ if (TypeFromToken(token) != mdtMethodDef)
+ {
+ return E_INVALIDARG;
+ }
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = ClrDataMethodDefinition::
+ NewFromModule(m_dac,
+ m_module,
+ token,
+ NULL,
+ methodDefinition);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::StartEnumInstances(
+ /* [in] */ IXCLRDataAppDomain* appDomain,
+ /* [out] */ CLRDATA_ENUM *handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // XXX Microsoft.
+ status = E_NOTIMPL;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EnumInstance(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [out] */ IXCLRDataTypeInstance **instance)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // XXX Microsoft.
+ status = E_NOTIMPL;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EndEnumInstances(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // XXX Microsoft.
+ status = E_NOTIMPL;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetNumFields(
+ /* [in] */ ULONG32 flags,
+ /* [out] */ ULONG32 *numFields)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_typeHandle.IsNull())
+ {
+ status = E_NOTIMPL;
+ }
+ else
+ {
+ DeepFieldDescIterator fieldIter;
+
+ if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
+ flags, NULL)) == S_OK)
+ {
+ *numFields = fieldIter.Count();
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::StartEnumFields(
+ /* [in] */ ULONG32 flags,
+ /* [out] */ CLRDATA_ENUM *handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_typeHandle.IsNull())
+ {
+ *handle = 0;
+ status = E_NOTIMPL;
+ }
+ else
+ {
+ status = SplitName::
+ CdStartField(NULL,
+ 0,
+ flags,
+ NULL,
+ m_typeHandle,
+ NULL,
+ mdTypeDefNil,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ handle);
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EnumField(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [in] */ ULONG32 nameBufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ IXCLRDataTypeDefinition **type,
+ /* [out] */ ULONG32 *flags,
+ /* [out] */ mdFieldDef *token)
+{
+ return EnumField2(handle, nameBufLen, nameLen, nameBuf,
+ type, flags, NULL, token);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EnumField2(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [in] */ ULONG32 nameBufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ IXCLRDataTypeDefinition **type,
+ /* [out] */ ULONG32 *flags,
+ /* [out] */ IXCLRDataModule** tokenScope,
+ /* [out] */ mdFieldDef *token)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdNextField(m_dac, handle, type, flags, NULL,
+ nameBufLen, nameLen, nameBuf,
+ tokenScope, token);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EndEnumFields(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::StartEnumFieldsByName(
+ /* [in] */ LPCWSTR name,
+ /* [in] */ ULONG32 nameFlags,
+ /* [in] */ ULONG32 fieldFlags,
+ /* [out] */ CLRDATA_ENUM *handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_typeHandle.IsNull())
+ {
+ *handle = 0;
+ status = E_NOTIMPL;
+ }
+ else
+ {
+ status = SplitName::
+ CdStartField(name,
+ nameFlags,
+ fieldFlags,
+ NULL,
+ m_typeHandle,
+ NULL,
+ mdTypeDefNil,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ handle);
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EnumFieldByName(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [out] */ IXCLRDataTypeDefinition **type,
+ /* [out] */ ULONG32 *flags,
+ /* [out] */ mdFieldDef *token)
+{
+ return EnumFieldByName2(handle, type, flags, NULL, token);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EnumFieldByName2(
+ /* [out][in] */ CLRDATA_ENUM *handle,
+ /* [out] */ IXCLRDataTypeDefinition **type,
+ /* [out] */ ULONG32 *flags,
+ /* [out] */ IXCLRDataModule** tokenScope,
+ /* [out] */ mdFieldDef *token)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdNextField(m_dac, handle, type, flags, NULL,
+ 0, NULL, NULL,
+ tokenScope, token);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::EndEnumFieldsByName(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetFieldByToken(
+ /* [in] */ mdFieldDef token,
+ /* [in] */ ULONG32 nameBufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ IXCLRDataTypeDefinition **type,
+ /* [out] */ ULONG32 *flags)
+{
+ return GetFieldByToken2(NULL, token, nameBufLen, nameLen, nameBuf,
+ type, flags);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetFieldByToken2(
+ /* [in] */ IXCLRDataModule* tokenScope,
+ /* [in] */ mdFieldDef token,
+ /* [in] */ ULONG32 nameBufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(nameBufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ IXCLRDataTypeDefinition **type,
+ /* [out] */ ULONG32 *flags)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ DeepFieldDescIterator fieldIter;
+
+ if (m_typeHandle.IsNull())
+ {
+ status = E_NOTIMPL;
+ goto Exit;
+ }
+
+ if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
+ CLRDATA_VALUE_ALL_FIELDS, NULL)) == S_OK)
+ {
+ FieldDesc* fieldDesc;
+
+ status = E_INVALIDARG;
+ while ((fieldDesc = fieldIter.Next()))
+ {
+ if ((!tokenScope ||
+ PTR_HOST_TO_TADDR(((ClrDataModule*)tokenScope)->
+ GetModule()) ==
+ PTR_HOST_TO_TADDR(fieldDesc->GetModule())) &&
+ fieldDesc->GetMemberDef() == token)
+ {
+ if (flags)
+ {
+ *flags = GetTypeFieldValueFlags(m_typeHandle,
+ fieldDesc,
+ fieldIter.IsFieldFromParentClass() ?
+ CLRDATA_VALUE_IS_INHERITED : 0,
+ false);
+ }
+
+ status = ConvertUtf8(fieldDesc->GetName(),
+ nameBufLen, nameLen, nameBuf);
+
+ if (SUCCEEDED(status) && type)
+ {
+ TypeHandle fieldTypeHandle =
+ fieldDesc->LookupFieldTypeHandle();
+ *type = new (nothrow)
+ ClrDataTypeDefinition(m_dac,
+ fieldTypeHandle.GetModule(),
+ fieldTypeHandle.
+ GetMethodTable()->GetCl(),
+ fieldTypeHandle);
+ status = *type ? S_OK : E_OUTOFMEMORY;
+ }
+
+ break;
+ }
+ }
+ }
+
+ Exit: ;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetName(
+ /* [in] */ ULONG32 flags,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
+{
+ HRESULT status = S_OK;
+
+ if (flags != 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ char classNameBuf[MAX_CLASSNAME_LENGTH];
+
+ if (m_typeHandle.IsNull())
+ {
+ if ((status =
+ GetFullClassNameFromMetadata(m_module->GetMDImport(),
+ m_token,
+ NumItems(classNameBuf),
+ classNameBuf)) == S_OK)
+ {
+ status = ConvertUtf8(classNameBuf, bufLen, nameLen, nameBuf);
+ }
+ }
+ else
+ {
+ StackSString ssClassNameBuf;
+ m_typeHandle.GetName(ssClassNameBuf);
+ if (wcsncpy_s(nameBuf, bufLen, ssClassNameBuf.GetUnicode(), _TRUNCATE) == STRUNCATE)
+ {
+ status = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+ }
+ if (nameLen != NULL)
+ {
+ size_t cchName = ssClassNameBuf.GetCount() + 1;
+ if (FitsIn<ULONG32>(cchName))
+ {
+ *nameLen = (ULONG32) cchName;
+ }
+ else
+ {
+ status = COR_E_OVERFLOW;
+ }
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetTokenAndScope(
+ /* [out] */ mdTypeDef *token,
+ /* [out] */ IXCLRDataModule **mod)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = S_OK;
+
+ if (token)
+ {
+ *token = m_token;
+ }
+
+ if (mod)
+ {
+ *mod = new (nothrow)
+ ClrDataModule(m_dac, m_module);
+ status = *mod ? S_OK : E_OUTOFMEMORY;
+ }
+
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetCorElementType(
+ /* [out] */ CorElementType *type)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_typeHandle.IsNull())
+ {
+ status = E_NOTIMPL;
+ }
+ else
+ {
+ *type = m_typeHandle.GetInternalCorElementType();
+ status = S_OK;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetFlags(
+ /* [out] */ ULONG32 *flags)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ *flags = CLRDATA_TYPE_DEFAULT;
+ status = S_OK;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetBase(
+ /* [out] */ IXCLRDataTypeDefinition **base)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ mdTypeDef token;
+ TypeHandle typeHandle;
+
+ if (m_typeHandle.IsNull())
+ {
+ ULONG attr;
+
+ status = m_module->GetMDImport()->GetTypeDefProps(m_token, &attr, &token);
+ if (FAILED(status))
+ {
+ goto Exit;
+ }
+ }
+ else
+ {
+ typeHandle = m_typeHandle.GetParent();
+ if (typeHandle.IsNull() ||
+ !typeHandle.GetMethodTable())
+ {
+ status = E_NOINTERFACE;
+ goto Exit;
+ }
+
+ token = typeHandle.GetMethodTable()->GetCl();
+ }
+
+ *base = new (nothrow)
+ ClrDataTypeDefinition(m_dac, m_module, token, typeHandle);
+ status = *base ? S_OK : E_OUTOFMEMORY;
+
+ Exit: ;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetArrayRank(
+ /* [out] */ ULONG32* rank)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_typeHandle.IsNull())
+ {
+ status = E_NOTIMPL;
+ }
+ else
+ {
+ MethodTable* pMT = m_typeHandle.GetMethodTable();
+
+ if (!m_typeHandle.IsArray() ||
+ (pMT == NULL))
+ {
+ status = E_NOINTERFACE;
+ }
+ else
+ {
+ *rank = pMT->GetRank();
+ status = S_OK;
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::IsSameObject(
+ /* [in] */ IXCLRDataTypeDefinition* type)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (m_typeHandle.IsNull())
+ {
+ status = (PTR_HOST_TO_TADDR(m_module) ==
+ PTR_HOST_TO_TADDR(((ClrDataTypeDefinition*)type)->
+ m_module) &&
+ m_token == ((ClrDataTypeDefinition*)type)->m_token) ?
+ S_OK : S_FALSE;
+ }
+ else
+ {
+ status = (m_typeHandle.AsTAddr() ==
+ ((ClrDataTypeDefinition*)type)->m_typeHandle.AsTAddr()) ?
+ S_OK : S_FALSE;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::GetTypeNotification(
+ /* [out] */ ULONG32* flags)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // XXX Microsoft.
+ status = E_NOTIMPL;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::SetTypeNotification(
+ /* [in] */ ULONG32 flags)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // XXX Microsoft.
+ status = E_NOTIMPL;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeDefinition::Request(
+ /* [in] */ ULONG32 reqCode,
+ /* [in] */ ULONG32 inBufferSize,
+ /* [size_is][in] */ BYTE *inBuffer,
+ /* [in] */ ULONG32 outBufferSize,
+ /* [size_is][out] */ BYTE *outBuffer)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ switch(reqCode)
+ {
+ case CLRDATA_REQUEST_REVISION:
+ if (inBufferSize != 0 ||
+ inBuffer ||
+ outBufferSize != sizeof(ULONG32))
+ {
+ status = E_INVALIDARG;
+ }
+ else
+ {
+ *(ULONG32*)outBuffer = 2;
+ status = S_OK;
+ }
+ break;
+
+ default:
+ status = E_INVALIDARG;
+ break;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT
+ClrDataTypeDefinition::NewFromModule(ClrDataAccess* dac,
+ Module* module,
+ mdTypeDef token,
+ ClrDataTypeDefinition** typeDef,
+ IXCLRDataTypeDefinition** pubTypeDef)
+{
+ // The type may not be loaded yet so the
+ // absence of a TypeHandle is not fatal.
+ // If the type isn't loaded a metadata-query
+ // TypeDefinition is produced.
+ TypeHandle typeHandle = module->LookupTypeDef(token);
+ if (!typeHandle.IsNull() &&
+ !typeHandle.IsRestored())
+ {
+ // The type isn't fully usable so just go with metadata.
+ typeHandle = TypeHandle();
+ }
+
+ ClrDataTypeDefinition* def = new (nothrow)
+ ClrDataTypeDefinition(dac, module, token, typeHandle);
+ if (!def)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ PREFIX_ASSUME(typeDef || pubTypeDef);
+
+ if (typeDef)
+ {
+ *typeDef = def;
+ }
+ if (pubTypeDef)
+ {
+ *pubTypeDef = def;
+ }
+
+ return S_OK;
+}
+
+//----------------------------------------------------------------------------
+//
+// ClrDataTypeInstance.
+//
+//----------------------------------------------------------------------------
+
+ClrDataTypeInstance::ClrDataTypeInstance(ClrDataAccess* dac,
+ AppDomain* appDomain,
+ TypeHandle typeHandle)
+{
+ m_dac = dac;
+ m_dac->AddRef();
+ m_instanceAge = m_dac->m_instanceAge;
+ m_refs = 1;
+ m_appDomain = appDomain;
+ m_typeHandle = typeHandle;
+}
+
+ClrDataTypeInstance::~ClrDataTypeInstance(void)
+{
+ m_dac->Release();
+}
+
+STDMETHODIMP
+ClrDataTypeInstance::QueryInterface(THIS_
+ IN REFIID interfaceId,
+ OUT PVOID* iface)
+{
+ if (IsEqualIID(interfaceId, IID_IUnknown) ||
+ IsEqualIID(interfaceId, __uuidof(IXCLRDataTypeInstance)))
+ {
+ AddRef();
+ *iface = static_cast<IUnknown*>
+ (static_cast<IXCLRDataTypeInstance*>(this));
+ return S_OK;
+ }
+ else
+ {
+ *iface = NULL;
+ return E_NOINTERFACE;
+ }
+}
+
+STDMETHODIMP_(ULONG)
+ClrDataTypeInstance::AddRef(THIS)
+{
+ return InterlockedIncrement(&m_refs);
+}
+
+STDMETHODIMP_(ULONG)
+ClrDataTypeInstance::Release(THIS)
+{
+ SUPPORTS_DAC_HOST_ONLY;
+ LONG newRefs = InterlockedDecrement(&m_refs);
+ if (newRefs == 0)
+ {
+ delete this;
+ }
+ return newRefs;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::StartEnumMethodInstances(
+ /* [out] */ CLRDATA_ENUM* handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (!m_typeHandle.GetMethodTable())
+ {
+ *handle = 0;
+ status = S_FALSE;
+ goto Exit;
+ }
+
+ status = MetaEnum::New(m_typeHandle.GetModule(),
+ mdtMethodDef,
+ m_typeHandle.GetCl(),
+ NULL,
+ NULL,
+ handle);
+
+ Exit: ;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EnumMethodInstance(
+ /* [in, out] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataMethodInstance **method)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ for (;;)
+ {
+ mdMethodDef token;
+
+ if ((status = MetaEnum::CdNextToken(handle, &token)) != S_OK)
+ {
+ break;
+ }
+
+ // If the method doesn't have a MethodDesc or hasn't
+ // been JIT'ed yet it's not an instance and should
+ // just be skipped.
+ if ((status = ClrDataMethodInstance::
+ NewFromModule(m_dac,
+ m_appDomain,
+ m_typeHandle.GetModule(),
+ token,
+ NULL,
+ method)) != E_INVALIDARG)
+ {
+ break;
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EndEnumMethodInstances(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = MetaEnum::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::StartEnumMethodInstancesByName(
+ /* [in] */ LPCWSTR name,
+ /* [in] */ ULONG32 flags,
+ /* [out] */ CLRDATA_ENUM* handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ if (!m_typeHandle.GetMethodTable())
+ {
+ *handle = 0;
+ status = S_FALSE;
+ goto Exit;
+ }
+
+ status = SplitName::CdStartMethod(name,
+ flags,
+ m_typeHandle.GetModule(),
+ m_typeHandle.GetCl(),
+ m_appDomain,
+ NULL,
+ NULL,
+ handle);
+
+ Exit: ;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EnumMethodInstanceByName(
+ /* [out][in] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataMethodInstance **method)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ for (;;)
+ {
+ mdMethodDef token;
+
+ if ((status = SplitName::CdNextMethod(handle, &token)) != S_OK)
+ {
+ break;
+ }
+
+ // If the method doesn't have a MethodDesc or hasn't
+ // been JIT'ed yet it's not an instance and should
+ // just be skipped.
+ if ((status = ClrDataMethodInstance::
+ NewFromModule(m_dac,
+ m_appDomain,
+ m_typeHandle.GetModule(),
+ token,
+ NULL,
+ method)) != E_INVALIDARG)
+ {
+ break;
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EndEnumMethodInstancesByName(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetNumStaticFields(
+ /* [out] */ ULONG32 *numFields)
+{
+ return GetNumStaticFields2(INH_STATIC, numFields);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetStaticFieldByIndex(
+ /* [in] */ ULONG32 index,
+ /* [in] */ IXCLRDataTask *tlsTask,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ mdFieldDef *token)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ DeepFieldDescIterator fieldIter;
+
+ if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
+ INH_STATIC, NULL)) == S_OK)
+ {
+ ULONG32 count = 0;
+ FieldDesc* fieldDesc;
+
+ status = E_INVALIDARG;
+ while ((fieldDesc = fieldIter.Next()))
+ {
+ if (count++ == index)
+ {
+ Thread* tlsThread = tlsTask ?
+ ((ClrDataTask*)tlsTask)->GetThread() : NULL;
+
+ status = ClrDataValue::
+ NewFromFieldDesc(m_dac,
+ m_appDomain,
+ fieldIter.IsFieldFromParentClass() ?
+ CLRDATA_VALUE_IS_INHERITED : 0,
+ fieldDesc,
+ 0,
+ tlsThread,
+ NULL,
+ field,
+ bufLen,
+ nameLen,
+ nameBuf,
+ NULL,
+ token);
+ break;
+ }
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::StartEnumStaticFieldsByName(
+ /* [in] */ LPCWSTR name,
+ /* [in] */ ULONG32 flags,
+ /* [in] */ IXCLRDataTask* tlsTask,
+ /* [out] */ CLRDATA_ENUM* handle)
+{
+ return StartEnumStaticFieldsByName2(name, flags, INH_STATIC, tlsTask,
+ handle);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EnumStaticFieldByName(
+ /* [out][in] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataValue **value)
+{
+ return EnumStaticFieldByName2(handle, value);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EndEnumStaticFieldsByName(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ return EndEnumStaticFieldsByName2(handle);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetNumStaticFields2(
+ /* [in] */ ULONG32 flags,
+ /* [out] */ ULONG32 *numFields)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ DeepFieldDescIterator fieldIter;
+
+ if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
+ flags, NULL)) == S_OK)
+ {
+ *numFields = fieldIter.Count();
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::StartEnumStaticFields(
+ /* [in] */ ULONG32 flags,
+ /* [in] */ IXCLRDataTask* tlsTask,
+ /* [out] */ CLRDATA_ENUM* handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::
+ CdStartField(NULL,
+ 0,
+ flags,
+ NULL,
+ m_typeHandle,
+ NULL,
+ mdTypeDefNil,
+ 0,
+ NULL,
+ tlsTask,
+ m_appDomain,
+ NULL,
+ NULL,
+ handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EnumStaticField(
+ /* [out][in] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataValue **value)
+{
+ return EnumStaticField2(handle, value, 0, NULL, NULL,
+ NULL, NULL);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EnumStaticField2(
+ /* [out][in] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataValue **value,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ],
+ /* [out] */ IXCLRDataModule** tokenScope,
+ /* [out] */ mdFieldDef *token)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdNextField(m_dac, handle, NULL, NULL, value,
+ bufLen, nameLen, nameBuf,
+ tokenScope, token);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EndEnumStaticFields(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::StartEnumStaticFieldsByName2(
+ /* [in] */ LPCWSTR name,
+ /* [in] */ ULONG32 nameFlags,
+ /* [in] */ ULONG32 fieldFlags,
+ /* [in] */ IXCLRDataTask* tlsTask,
+ /* [out] */ CLRDATA_ENUM* handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::
+ CdStartField(name,
+ nameFlags,
+ fieldFlags,
+ NULL,
+ m_typeHandle,
+ NULL,
+ mdTypeDefNil,
+ 0,
+ NULL,
+ tlsTask,
+ m_appDomain,
+ NULL,
+ NULL,
+ handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EnumStaticFieldByName2(
+ /* [out][in] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataValue **value)
+{
+ return EnumStaticFieldByName3(handle, value, NULL, NULL);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EnumStaticFieldByName3(
+ /* [out][in] */ CLRDATA_ENUM* handle,
+ /* [out] */ IXCLRDataValue **value,
+ /* [out] */ IXCLRDataModule** tokenScope,
+ /* [out] */ mdFieldDef *token)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdNextField(m_dac, handle, NULL, NULL, value,
+ 0, NULL, NULL,
+ tokenScope, token);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::EndEnumStaticFieldsByName2(
+ /* [in] */ CLRDATA_ENUM handle)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = SplitName::CdEnd(handle);
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetStaticFieldByToken(
+ /* [in] */ mdFieldDef token,
+ /* [in] */ IXCLRDataTask *tlsTask,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
+{
+ return GetStaticFieldByToken2(NULL, token, tlsTask, field,
+ bufLen, nameLen, nameBuf);
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetStaticFieldByToken2(
+ /* [in] */ IXCLRDataModule* tokenScope,
+ /* [in] */ mdFieldDef token,
+ /* [in] */ IXCLRDataTask *tlsTask,
+ /* [out] */ IXCLRDataValue **field,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ DeepFieldDescIterator fieldIter;
+
+ if ((status = InitFieldIter(&fieldIter, m_typeHandle, true,
+ INH_STATIC, NULL)) == S_OK)
+ {
+ FieldDesc* fieldDesc;
+
+ status = E_INVALIDARG;
+ while ((fieldDesc = fieldIter.Next()))
+ {
+ if ((!tokenScope ||
+ PTR_HOST_TO_TADDR(((ClrDataModule*)tokenScope)->
+ GetModule()) ==
+ PTR_HOST_TO_TADDR(fieldDesc->GetModule())) &&
+ fieldDesc->GetMemberDef() == token)
+ {
+ Thread* tlsThread = tlsTask ?
+ ((ClrDataTask*)tlsTask)->GetThread() : NULL;
+
+ status = ClrDataValue::
+ NewFromFieldDesc(m_dac,
+ m_appDomain,
+ fieldIter.IsFieldFromParentClass() ?
+ CLRDATA_VALUE_IS_INHERITED : 0,
+ fieldDesc,
+ 0,
+ tlsThread,
+ NULL,
+ field,
+ bufLen,
+ nameLen,
+ nameBuf,
+ NULL,
+ NULL);
+ break;
+ }
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetName(
+ /* [in] */ ULONG32 flags,
+ /* [in] */ ULONG32 bufLen,
+ /* [out] */ ULONG32 *nameLen,
+ /* [size_is][out] */ __out_ecount_part_opt(bufLen, *nameLen) WCHAR nameBuf[ ])
+{
+ HRESULT status = S_OK;
+
+ if (flags != 0)
+ {
+ return E_INVALIDARG;
+ }
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ StackSString ssClassNameBuf;
+
+#ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
+ PAL_CPP_TRY
+ {
+#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
+
+ m_typeHandle.GetName(ssClassNameBuf);
+
+#ifdef FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
+ }
+ PAL_CPP_CATCH_ALL
+ {
+ // if metadata is unavailable try the DAC's MdCache
+ ssClassNameBuf.Clear();
+ PTR_MethodTable pMT = m_typeHandle.AsMethodTable();
+ if (pMT != NULL)
+ {
+ if (!DacMdCacheGetEEName(dac_cast<TADDR>(pMT), ssClassNameBuf))
+ {
+ ssClassNameBuf.Clear();
+ }
+ }
+ if (ssClassNameBuf.IsEmpty())
+ {
+ PAL_CPP_RETHROW;
+ }
+ }
+ PAL_CPP_ENDTRY
+#endif // FEATURE_MINIMETADATA_IN_TRIAGEDUMPS
+
+ if (wcsncpy_s(nameBuf, bufLen, ssClassNameBuf.GetUnicode(), _TRUNCATE) == STRUNCATE)
+ {
+ status = HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
+ }
+ if (nameLen != NULL)
+ {
+ size_t cchName = ssClassNameBuf.GetCount() + 1;
+ if (FitsIn<ULONG32>(cchName))
+ {
+ *nameLen = (ULONG32) cchName;
+ }
+ else
+ {
+ status = COR_E_OVERFLOW;
+ }
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetModule(
+ /* [out] */ IXCLRDataModule **mod)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ *mod = new (nothrow)
+ ClrDataModule(m_dac, m_typeHandle.GetModule());
+ status = *mod ? S_OK : E_OUTOFMEMORY;
+
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetDefinition(
+ /* [out] */ IXCLRDataTypeDefinition **typeDefinition)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ TypeHandle defType;
+
+ if (m_typeHandle.IsArray() || m_typeHandle.IsFnPtrType())
+ {
+ // Arrays don't necessarily have metadata so
+ // we can't rely on being able to look up
+ // a definition that way.
+
+ // Also ByRef and FUNC_PTR does not have typedef token backing it.
+
+ // Instead, just use the same type handle.
+ // XXX Microsoft - Generics issues?
+
+ // Question - what does the GetCl return return here? The underlying element type?
+ // If so, we are lossing informaiton.
+ //
+ defType = m_typeHandle;
+ *typeDefinition = new (nothrow)
+ ClrDataTypeDefinition(m_dac,
+ defType.GetModule(),
+ defType.GetCl(),
+ defType);
+ }
+
+ else if (m_typeHandle.IsTypeDesc() && m_typeHandle.AsTypeDesc()->HasTypeParam())
+ {
+ // HasTypeParam is true for - ParamTypeDesc (ARRAY, SZARRAY, BYREF, PTR)
+ defType = m_typeHandle.AsTypeDesc()->GetTypeParam();
+
+ // The DefinitionType won't contain ByRef, PTR.
+ *typeDefinition = new (nothrow)
+ ClrDataTypeDefinition(m_dac,
+ defType.GetModule(),
+ defType.GetCl(),
+ defType);
+ }
+ else
+ {
+ // @TODO:: Should this be only for generic?
+ //
+ defType = m_typeHandle.GetModule()->
+ LookupTypeDef(m_typeHandle.GetCl());
+ *typeDefinition = new (nothrow)
+ ClrDataTypeDefinition(m_dac,
+ m_typeHandle.GetModule(),
+ m_typeHandle.GetCl(),
+ defType);
+ }
+
+ status = *typeDefinition ? S_OK : E_OUTOFMEMORY;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetFlags(
+ /* [out] */ ULONG32 *flags)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ *flags = CLRDATA_TYPE_DEFAULT;
+ status = S_OK;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetBase(
+ /* [out] */ IXCLRDataTypeInstance **base)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ *base = new (nothrow)
+ ClrDataTypeInstance(m_dac, m_appDomain, m_typeHandle.GetParent());
+ status = *base ? S_OK : E_OUTOFMEMORY;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::IsSameObject(
+ /* [in] */ IXCLRDataTypeInstance* type)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ status = (PTR_HOST_TO_TADDR(m_appDomain) ==
+ PTR_HOST_TO_TADDR(((ClrDataTypeInstance*)type)->
+ m_appDomain) &&
+ m_typeHandle == ((ClrDataTypeInstance*)type)->
+ m_typeHandle) ?
+ S_OK : S_FALSE;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetNumTypeArguments(
+ /* [out] */ ULONG32 *numTypeArgs)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // XXX Microsoft.
+ status = E_NOTIMPL;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::GetTypeArgumentByIndex(
+ /* [in] */ ULONG32 index,
+ /* [out] */ IXCLRDataTypeInstance **typeArg)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ // XXX Microsoft.
+ status = E_NOTIMPL;
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT STDMETHODCALLTYPE
+ClrDataTypeInstance::Request(
+ /* [in] */ ULONG32 reqCode,
+ /* [in] */ ULONG32 inBufferSize,
+ /* [size_is][in] */ BYTE *inBuffer,
+ /* [in] */ ULONG32 outBufferSize,
+ /* [size_is][out] */ BYTE *outBuffer)
+{
+ HRESULT status;
+
+ DAC_ENTER_SUB(m_dac);
+
+ EX_TRY
+ {
+ switch(reqCode)
+ {
+ case CLRDATA_REQUEST_REVISION:
+ if (inBufferSize != 0 ||
+ inBuffer ||
+ outBufferSize != sizeof(ULONG32))
+ {
+ status = E_INVALIDARG;
+ }
+ else
+ {
+ *(ULONG32*)outBuffer = 2;
+ status = S_OK;
+ }
+ break;
+
+ default:
+ status = E_INVALIDARG;
+ break;
+ }
+ }
+ EX_CATCH
+ {
+ if (!DacExceptionFilter(GET_EXCEPTION(), m_dac, &status))
+ {
+ EX_RETHROW;
+ }
+ }
+ EX_END_CATCH(SwallowAllExceptions)
+
+ DAC_LEAVE();
+ return status;
+}
+
+HRESULT
+ClrDataTypeInstance::NewFromModule(ClrDataAccess* dac,
+ AppDomain* appDomain,
+ Module* module,
+ mdTypeDef token,
+ ClrDataTypeInstance** typeInst,
+ IXCLRDataTypeInstance** pubTypeInst)
+{
+ TypeHandle typeHandle = module->LookupTypeDef(token);
+ if (typeHandle.IsNull() ||
+ !typeHandle.IsRestored())
+ {
+ return E_INVALIDARG;
+ }
+
+ ClrDataTypeInstance* inst = new (nothrow)
+ ClrDataTypeInstance(dac, appDomain, typeHandle);
+ if (!inst)
+ {
+ return E_OUTOFMEMORY;
+ }
+
+ PREFIX_ASSUME(typeInst || pubTypeInst);
+
+ if (typeInst)
+ {
+ *typeInst = inst;
+ }
+ if (pubTypeInst)
+ {
+ *pubTypeInst = inst;
+ }
+
+ return S_OK;
+}
+
+