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 | |
29 | template <class MiniMd> class CLiteWeightStgdb; |
30 | class CMiniMdRW; |
31 | class MDInternalRO; |
32 | class CMiniMd : public CMiniMdTemplate<CMiniMd> |
33 | { |
34 | public: |
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 | |
79 | protected: |
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 | |
100 | protected: |
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 | |