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