1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
// 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.
//*****************************************************************************
// MetaModelRO.h -- header file for Read-Only compressed COM+ metadata.
//
//
// Used by the EE.
//
//*****************************************************************************
#ifndef _METAMODELRO_H_
#define _METAMODELRO_H_
#if _MSC_VER >= 1100
# pragma once
#endif
#include "metamodel.h"
#include "../heaps/export.h"
#include "../tables/export.h"
//*****************************************************************************
// A read-only MiniMd. This is the fastest and smallest possible MiniMd,
// and as such, is the preferred EE metadata provider.
//*****************************************************************************
template <class MiniMd> class CLiteWeightStgdb;
class CMiniMdRW;
class MDInternalRO;
class CMiniMd : public CMiniMdTemplate<CMiniMd>
{
public:
friend class CLiteWeightStgdb<CMiniMd>;
friend class CMiniMdTemplate<CMiniMd>;
friend class CMiniMdRW;
friend class MDInternalRO;
__checkReturn
HRESULT InitOnMem(void *pBuf, ULONG ulBufLen);
__checkReturn
HRESULT PostInit(int iLevel); // higher number : more checking
// Returns TRUE if token (tk) is valid.
// For user strings, consideres 0 as valid token.
BOOL _IsValidToken(
mdToken tk) // [IN] token to be checked
{
if (TypeFromToken(tk) == mdtString)
{
return m_UserStringHeap.IsValidIndex(RidFromToken(tk));
}
// Base type doesn't know about user string blob (yet)
return _IsValidTokenBase(tk);
} // CMiniMdRO::_IsValidToken
__checkReturn
FORCEINLINE HRESULT GetUserString(ULONG nIndex, MetaData::DataBlob *pData)
{
MINIMD_POSSIBLE_INTERNAL_POINTER_EXPOSED();
return m_UserStringHeap.GetBlob(nIndex, pData);
}
#ifdef FEATURE_PREJIT
void DisableHotDataUsage()
{
MetaData::HotHeap emptyHotHeap;
// Initialize hot data again with empty heap to disable their usage
m_StringHeap.InitializeHotData(emptyHotHeap);
m_BlobHeap.InitializeHotData(emptyHotHeap);
m_UserStringHeap.InitializeHotData(emptyHotHeap);
m_GuidHeap.InitializeHotData(emptyHotHeap);
// Disable usage of hot table data (throw it away)
m_pHotTablesDirectory = NULL;
}
#endif //FEATURE_PREJIT
protected:
// Table info.
MetaData::TableRO m_Tables[TBL_COUNT];
#ifdef FEATURE_PREJIT
struct MetaData::HotTablesDirectory * m_pHotTablesDirectory;
#endif //FEATURE_PREJIT
__checkReturn
HRESULT InitializeTables(MetaData::DataBlob tablesData);
__checkReturn
virtual HRESULT vSearchTable(ULONG ixTbl, CMiniColDef sColumn, ULONG ulTarget, RID *pRid);
__checkReturn
virtual HRESULT vSearchTableNotGreater(ULONG ixTbl, CMiniColDef sColumn, ULONG ulTarget, RID *pRid);
// Heaps
MetaData::StringHeapRO m_StringHeap;
MetaData::BlobHeapRO m_BlobHeap;
MetaData::BlobHeapRO m_UserStringHeap;
MetaData::GuidHeapRO m_GuidHeap;
protected:
//*************************************************************************
// Overridables -- must be provided in derived classes.
__checkReturn
FORCEINLINE HRESULT Impl_GetString(UINT32 nIndex, __out LPCSTR *pszString)
{ return m_StringHeap.GetString(nIndex, pszString); }
__checkReturn
HRESULT Impl_GetStringW(ULONG ix, __inout_ecount (cchBuffer) LPWSTR szOut, ULONG cchBuffer, ULONG *pcchBuffer);
__checkReturn
FORCEINLINE HRESULT Impl_GetGuid(UINT32 nIndex, GUID *pTargetGuid)
{
HRESULT hr;
GUID UNALIGNED *pSourceGuid;
IfFailRet(m_GuidHeap.GetGuid(
nIndex,
&pSourceGuid));
// Add void* casts so that the compiler can't make assumptions about alignment.
CopyMemory((void *)pTargetGuid, (void *)pSourceGuid, sizeof(GUID));
SwapGuid(pTargetGuid);
return S_OK;
}
__checkReturn
FORCEINLINE HRESULT Impl_GetBlob(UINT32 nIndex, __out MetaData::DataBlob *pData)
{ return m_BlobHeap.GetBlob(nIndex, pData); }
__checkReturn
FORCEINLINE HRESULT Impl_GetRow(
UINT32 nTableIndex,
UINT32 nRowIndex,
__deref_out_opt BYTE **ppRecord)
{
_ASSERTE(nTableIndex < TBL_COUNT);
return m_Tables[nTableIndex].GetRecord(
nRowIndex,
ppRecord,
m_TableDefs[nTableIndex].m_cbRec,
m_Schema.m_cRecs[nTableIndex],
#ifdef FEATURE_PREJIT
m_pHotTablesDirectory,
#endif //FEATURE_PREJIT
nTableIndex);
}
// Count of rows in tbl2, pointed to by the column in tbl.
__checkReturn
HRESULT Impl_GetEndRidForColumn(
UINT32 nTableIndex,
RID nRowIndex,
CMiniColDef &def, // Column containing the RID into other table.
UINT32 nTargetTableIndex, // The other table.
RID *pEndRid);
__checkReturn
FORCEINLINE HRESULT Impl_SearchTable(ULONG ixTbl, CMiniColDef sColumn, ULONG ixCol, ULONG ulTarget, RID *pFoundRid)
{
return vSearchTable(ixTbl, sColumn, ulTarget, pFoundRid);
}
// given a rid to the Property table, find an entry in PropertyMap table that contains the back pointer
// to its typedef parent
__checkReturn
HRESULT FindPropertyMapParentOfProperty(RID rid, RID *pFoundRid)
{
return vSearchTableNotGreater(TBL_PropertyMap, _COLDEF(PropertyMap,PropertyList), rid, pFoundRid);
}
__checkReturn
HRESULT FindParentOfPropertyHelper(
mdProperty pr,
mdTypeDef *ptd)
{
HRESULT hr = NOERROR;
RID ridPropertyMap;
PropertyMapRec *pRec;
IfFailRet(FindPropertyMapParentOfProperty(RidFromToken(pr), &ridPropertyMap));
IfFailRet(GetPropertyMapRecord(ridPropertyMap, &pRec));
*ptd = getParentOfPropertyMap( pRec );
RidToToken(*ptd, mdtTypeDef);
return hr;
} // HRESULT CMiniMdRW::FindParentOfPropertyHelper()
// given a rid to the Event table, find an entry in EventMap table that contains the back pointer
// to its typedef parent
__checkReturn
HRESULT FindEventMapParentOfEvent(RID rid, RID *pFoundRid)
{
return vSearchTableNotGreater(TBL_EventMap, _COLDEF(EventMap, EventList), rid, pFoundRid);
}
__checkReturn
HRESULT FindParentOfEventHelper(
mdEvent pr,
mdTypeDef *ptd)
{
HRESULT hr = NOERROR;
RID ridEventMap;
EventMapRec *pRec;
IfFailRet(FindEventMapParentOfEvent(RidFromToken(pr), &ridEventMap));
IfFailRet(GetEventMapRecord(ridEventMap, &pRec));
*ptd = getParentOfEventMap( pRec );
RidToToken(*ptd, mdtTypeDef);
return hr;
} // HRESULT CMiniMdRW::FindParentOfEventHelper()
FORCEINLINE int Impl_IsRo()
{ return 1; }
//*************************************************************************
__checkReturn
HRESULT CommonEnumCustomAttributeByName( // S_OK or error.
mdToken tkObj, // [IN] Object with Custom Attribute.
LPCUTF8 szName, // [IN] Name of desired Custom Attribute.
bool fStopAtFirstFind, // [IN] just find the first one
HENUMInternal* phEnum); // enumerator to fill up
__checkReturn
HRESULT CommonGetCustomAttributeByNameEx( // S_OK or error.
mdToken tkObj, // [IN] Object with Custom Attribute.
LPCUTF8 szName, // [IN] Name of desired Custom Attribute.
mdCustomAttribute *ptkCA, // [OUT] put custom attribute token here
const void **ppData, // [OUT] Put pointer to data here.
ULONG *pcbData); // [OUT] Put size of data here.
public:
virtual BOOL IsWritable()
{
return FALSE;
}
}; // class CMiniMd
#endif // _METAMODELRO_H_
|