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 | // File: MDInternalRO.CPP |
6 | // |
7 | |
8 | // Notes: |
9 | // |
10 | // |
11 | // =========================================================================== |
12 | #include "stdafx.h" |
13 | #include "mdinternalro.h" |
14 | #include "metamodelro.h" |
15 | #include "liteweightstgdb.h" |
16 | #include "corhlpr.h" |
17 | #include "../compiler/regmeta.h" |
18 | #include "caparser.h" |
19 | |
20 | #ifdef FEATURE_METADATA_INTERNAL_APIS |
21 | |
22 | __checkReturn |
23 | HRESULT _FillMDDefaultValue( |
24 | BYTE bType, |
25 | void const *pValue, |
26 | ULONG cbValue, |
27 | MDDefaultValue *pMDDefaultValue); |
28 | |
29 | #ifndef DACCESS_COMPILE |
30 | __checkReturn |
31 | HRESULT TranslateSigHelper( // S_OK or error. |
32 | IMDInternalImport *pImport, // [IN] import scope. |
33 | IMDInternalImport *pAssemImport, // [IN] import assembly scope. |
34 | const void *pbHashValue, // [IN] hash value for the import assembly. |
35 | ULONG cbHashValue, // [IN] count of bytes in the hash value. |
36 | PCCOR_SIGNATURE pbSigBlob, // [IN] signature in the importing scope |
37 | ULONG cbSigBlob, // [IN] count of bytes of signature |
38 | IMetaDataAssemblyEmit *pAssemEmit, // [IN] assembly emit scope. |
39 | IMetaDataEmit *emit, // [IN] emit interface |
40 | CQuickBytes *pqkSigEmit, // [OUT] buffer to hold translated signature |
41 | ULONG *pcbSig); // [OUT] count of bytes in the translated signature |
42 | #endif //!DACCESS_COMPILE |
43 | |
44 | __checkReturn |
45 | HRESULT GetInternalWithRWFormat( |
46 | LPVOID pData, |
47 | ULONG cbData, |
48 | DWORD flags, // [IN] MDInternal_OpenForRead or MDInternal_OpenForENC |
49 | REFIID riid, // [in] The interface desired. |
50 | void **ppIUnk); // [out] Return interface on success. |
51 | |
52 | // forward declaration |
53 | __checkReturn |
54 | HRESULT MDApplyEditAndContinue( // S_OK or error. |
55 | IMDInternalImport **ppIMD, // [in, out] The metadata to be updated. |
56 | IMDInternalImportENC *pDeltaMD); // [in] The delta metadata. |
57 | |
58 | |
59 | //***************************************************************************** |
60 | // Constructor |
61 | //***************************************************************************** |
62 | MDInternalRO::MDInternalRO() |
63 | : m_pMethodSemanticsMap(0), |
64 | m_cRefs(1) |
65 | { |
66 | } // MDInternalRO::MDInternalRO |
67 | |
68 | |
69 | |
70 | //***************************************************************************** |
71 | // Destructor |
72 | //***************************************************************************** |
73 | MDInternalRO::~MDInternalRO() |
74 | { |
75 | m_LiteWeightStgdb.Uninit(); |
76 | if (m_pMethodSemanticsMap) |
77 | delete[] m_pMethodSemanticsMap; |
78 | m_pMethodSemanticsMap = 0; |
79 | } // MDInternalRO::~MDInternalRO |
80 | |
81 | //***************************************************************************** |
82 | // IUnknown |
83 | //***************************************************************************** |
84 | ULONG MDInternalRO::AddRef() |
85 | { |
86 | return InterlockedIncrement(&m_cRefs); |
87 | } // MDInternalRO::AddRef |
88 | |
89 | ULONG MDInternalRO::Release() |
90 | { |
91 | ULONG cRef = InterlockedDecrement(&m_cRefs); |
92 | if (cRef == 0) |
93 | delete this; |
94 | return cRef; |
95 | } // MDInternalRO::Release |
96 | |
97 | __checkReturn |
98 | HRESULT MDInternalRO::QueryInterface(REFIID riid, void **ppUnk) |
99 | { |
100 | *ppUnk = 0; |
101 | |
102 | if (riid == IID_IUnknown) |
103 | *ppUnk = this; // ! QI for IID_IUnknown must return MDInternalRO. ConvertRO2RW() has dependency on this. |
104 | else if (riid == IID_IMDInternalImport) |
105 | *ppUnk = (IMDInternalImport *)this; |
106 | else if (riid == IID_IMDCommon) |
107 | *ppUnk = (IMDCommon *)this; |
108 | else |
109 | return E_NOINTERFACE; |
110 | AddRef(); |
111 | return S_OK; |
112 | } // MDInternalRO::QueryInterface |
113 | |
114 | |
115 | //***************************************************************************** |
116 | // Initialize |
117 | //***************************************************************************** |
118 | __checkReturn |
119 | HRESULT MDInternalRO::Init( |
120 | LPVOID pData, // points to meta data section in memory |
121 | ULONG cbData) // count of bytes in pData |
122 | { |
123 | m_tdModule = COR_GLOBAL_PARENT_TOKEN; |
124 | |
125 | extern HRESULT _CallInitOnMemHelper(CLiteWeightStgdb<CMiniMd> *pStgdb, ULONG cbData, LPCVOID pData); |
126 | |
127 | return _CallInitOnMemHelper(&m_LiteWeightStgdb, cbData, (BYTE*) pData); |
128 | } // MDInternalRO::Init |
129 | |
130 | #ifndef DACCESS_COMPILE |
131 | //***************************************************************************** |
132 | // Given a scope, determine whether imported from a typelib. |
133 | //***************************************************************************** |
134 | __checkReturn |
135 | HRESULT MDInternalRO::TranslateSigWithScope( |
136 | IMDInternalImport* pAssemImport, // [IN] import assembly scope. |
137 | const void* pbHashValue, // [IN] hash value for the import assembly. |
138 | ULONG cbHashValue, // [IN] count of bytes in the hash value. |
139 | PCCOR_SIGNATURE pbSigBlob, // [IN] signature in the importing scope |
140 | ULONG cbSigBlob, // [IN] count of bytes of signature |
141 | IMetaDataAssemblyEmit* pAssemEmit, // [IN] assembly emit scope. |
142 | IMetaDataEmit* emit, // [IN] emit interface |
143 | CQuickBytes* pqkSigEmit, // [OUT] buffer to hold translated signature |
144 | ULONG* pcbSig) // [OUT] count of bytes in the translated signature |
145 | { |
146 | return TranslateSigHelper( |
147 | this, |
148 | pAssemImport, |
149 | pbHashValue, |
150 | cbHashValue, |
151 | pbSigBlob, |
152 | cbSigBlob, |
153 | pAssemEmit, |
154 | emit, |
155 | pqkSigEmit, |
156 | pcbSig); |
157 | } // MDInternalRO::TranslateSigWithScope |
158 | #endif // DACCESS_COMPILE |
159 | |
160 | __checkReturn |
161 | HRESULT MDInternalRO::GetTypeDefRefTokenInTypeSpec(// return S_FALSE if enclosing type does not have a token |
162 | mdTypeSpec tkTypeSpec, // [IN] TypeSpec token to look at |
163 | mdToken *tkEnclosedToken) // [OUT] The enclosed type token |
164 | { |
165 | return m_LiteWeightStgdb.m_MiniMd.GetTypeDefRefTokenInTypeSpec(tkTypeSpec, tkEnclosedToken); |
166 | } // MDInternalRO::GetTypeDefRefTokenInTypeSpec |
167 | |
168 | #ifndef DACCESS_COMPILE |
169 | //***************************************************************************** |
170 | // Given a scope, return the number of tokens in a given table |
171 | //***************************************************************************** |
172 | ULONG MDInternalRO::GetCountWithTokenKind( // return hresult |
173 | DWORD tkKind) // [IN] pass in the kind of token. |
174 | { |
175 | ULONG ulCount = m_LiteWeightStgdb.m_MiniMd.CommonGetRowCount(tkKind); |
176 | if (tkKind == mdtTypeDef) |
177 | { |
178 | // Remove global typedef from the count of typedefs (and handle the case where there is no global typedef) |
179 | if (ulCount > 0) |
180 | ulCount--; |
181 | } |
182 | return ulCount; |
183 | } // MDInternalRO::GetCountWithTokenKind |
184 | #endif //!DACCESS_COMPILE |
185 | |
186 | //******************************************************************************* |
187 | // Enumerator helpers |
188 | //******************************************************************************* |
189 | |
190 | |
191 | //***************************************************************************** |
192 | // enumerator init for typedef |
193 | //***************************************************************************** |
194 | __checkReturn |
195 | HRESULT MDInternalRO::EnumTypeDefInit( // return hresult |
196 | HENUMInternal *phEnum) // [OUT] buffer to fill for enumerator data |
197 | { |
198 | HRESULT hr = NOERROR; |
199 | |
200 | _ASSERTE(phEnum); |
201 | |
202 | memset(phEnum, 0, sizeof(HENUMInternal)); |
203 | phEnum->m_tkKind = mdtTypeDef; |
204 | phEnum->m_EnumType = MDSimpleEnum; |
205 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountTypeDefs(); |
206 | |
207 | // Skip over the global model typedef |
208 | // |
209 | // phEnum->u.m_ulCur : the current rid that is not yet enumerated |
210 | // phEnum->u.m_ulStart : the first rid that will be returned by enumerator |
211 | // phEnum->u.m_ulEnd : the last rid that will be returned by enumerator |
212 | phEnum->u.m_ulStart = phEnum->u.m_ulCur = 2; |
213 | phEnum->u.m_ulEnd = phEnum->m_ulCount + 1; |
214 | if (phEnum->m_ulCount > 0) |
215 | phEnum->m_ulCount --; |
216 | |
217 | return hr; |
218 | } // MDInternalRO::EnumTypeDefInit |
219 | |
220 | |
221 | //***************************************************************************** |
222 | // get the number of typedef in a scope |
223 | //***************************************************************************** |
224 | ULONG MDInternalRO::EnumTypeDefGetCount( |
225 | HENUMInternal *phEnum) // [IN] the enumerator to retrieve information |
226 | { |
227 | _ASSERTE(phEnum->m_tkKind == mdtTypeDef); |
228 | return phEnum->m_ulCount; |
229 | } // MDInternalRO::EnumTypeDefGetCount |
230 | |
231 | |
232 | //***************************************************************************** |
233 | // enumerator for typedef |
234 | //***************************************************************************** |
235 | bool MDInternalRO::EnumTypeDefNext( // return hresult |
236 | HENUMInternal *phEnum, // [IN] input enum |
237 | mdTypeDef *ptd) // [OUT] return token |
238 | { |
239 | _ASSERTE(phEnum && ptd); |
240 | |
241 | if (phEnum->u.m_ulCur >= phEnum->u.m_ulEnd) |
242 | return false; |
243 | |
244 | *ptd = phEnum->u.m_ulCur++; |
245 | RidToToken(*ptd, mdtTypeDef); |
246 | return true; |
247 | } // MDInternalRO::EnumTypeDefNext |
248 | |
249 | |
250 | //***************************************** |
251 | // Reset the enumerator to the beginning. |
252 | //***************************************** |
253 | void MDInternalRO::EnumTypeDefReset( |
254 | HENUMInternal *phEnum) // [IN] the enumerator to be reset |
255 | { |
256 | _ASSERTE(phEnum); |
257 | _ASSERTE( phEnum->m_EnumType == MDSimpleEnum ); |
258 | |
259 | // not using CRCURSOR |
260 | phEnum->u.m_ulCur = phEnum->u.m_ulStart; |
261 | } // MDInternalRO::EnumTypeDefReset |
262 | |
263 | |
264 | //***************************************** |
265 | // Close the enumerator. Only for read/write mode that we need to close the cursor. |
266 | // Hopefully with readonly mode, it will be a no-op |
267 | //***************************************** |
268 | void MDInternalRO::EnumTypeDefClose( |
269 | HENUMInternal *phEnum) // [IN] the enumerator to be closed |
270 | { |
271 | _ASSERTE( phEnum->m_EnumType == MDSimpleEnum ); |
272 | } // MDInternalRO::EnumTypeDefClose |
273 | |
274 | |
275 | //***************************************************************************** |
276 | // Enumerator init for MethodImpl. The second HENUMInternal* parameter is |
277 | // only used for the R/W version of the MetaData. |
278 | //***************************************************************************** |
279 | __checkReturn |
280 | HRESULT MDInternalRO::EnumMethodImplInit( // return hresult |
281 | mdTypeDef td, // [IN] TypeDef over which to scope the enumeration. |
282 | HENUMInternal *phEnumBody, // [OUT] buffer to fill for enumerator data for MethodBody tokens. |
283 | HENUMInternal *phEnumDecl) // [OUT] buffer to fill for enumerator data for MethodDecl tokens. |
284 | { |
285 | return EnumInit(TBL_MethodImpl << 24, td, phEnumBody); |
286 | } // MDInternalRO::EnumMethodImplInit |
287 | |
288 | //***************************************************************************** |
289 | // get the number of MethodImpls in a scope |
290 | //***************************************************************************** |
291 | ULONG MDInternalRO::EnumMethodImplGetCount( |
292 | HENUMInternal *phEnumBody, // [IN] MethodBody enumerator. |
293 | HENUMInternal *phEnumDecl) // [IN] MethodDecl enumerator. |
294 | { |
295 | _ASSERTE(phEnumBody && ((phEnumBody->m_tkKind >> 24) == TBL_MethodImpl)); |
296 | return phEnumBody->m_ulCount; |
297 | } // MDInternalRO::EnumMethodImplGetCount |
298 | |
299 | |
300 | //***************************************************************************** |
301 | // enumerator for MethodImpl. |
302 | //***************************************************************************** |
303 | __checkReturn |
304 | HRESULT |
305 | MDInternalRO::EnumMethodImplNext( // return hresult |
306 | HENUMInternal *phEnumBody, // [IN] input enum for MethodBody |
307 | HENUMInternal *phEnumDecl, // [IN] input enum for MethodDecl |
308 | mdToken *ptkBody, // [OUT] return token for MethodBody |
309 | mdToken *ptkDecl) // [OUT] return token for MethodDecl |
310 | { |
311 | HRESULT hr; |
312 | MethodImplRec *pRecord; |
313 | |
314 | _ASSERTE(phEnumBody && ((phEnumBody->m_tkKind >> 24) == TBL_MethodImpl)); |
315 | _ASSERTE(ptkBody && ptkDecl); |
316 | |
317 | if (phEnumBody->u.m_ulCur >= phEnumBody->u.m_ulEnd) |
318 | { |
319 | return S_FALSE; |
320 | } |
321 | |
322 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodImplRecord(phEnumBody->u.m_ulCur, &pRecord)); |
323 | *ptkBody = m_LiteWeightStgdb.m_MiniMd.getMethodBodyOfMethodImpl(pRecord); |
324 | *ptkDecl = m_LiteWeightStgdb.m_MiniMd.getMethodDeclarationOfMethodImpl(pRecord); |
325 | phEnumBody->u.m_ulCur++; |
326 | |
327 | return S_OK; |
328 | } // MDInternalRO::EnumMethodImplNext |
329 | |
330 | //***************************************** |
331 | // Reset the enumerator to the beginning. |
332 | //***************************************** |
333 | void MDInternalRO::EnumMethodImplReset( |
334 | HENUMInternal *phEnumBody, // [IN] MethodBody enumerator. |
335 | HENUMInternal *phEnumDecl) // [IN] MethodDecl enumerator. |
336 | { |
337 | _ASSERTE(phEnumBody && ((phEnumBody->m_tkKind >> 24) == TBL_MethodImpl)); |
338 | _ASSERTE(phEnumBody->m_EnumType == MDSimpleEnum); |
339 | |
340 | phEnumBody->u.m_ulCur = phEnumBody->u.m_ulStart; |
341 | } // MDInternalRO::EnumMethodImplReset |
342 | |
343 | |
344 | //***************************************** |
345 | // Close the enumerator. |
346 | //***************************************** |
347 | void MDInternalRO::EnumMethodImplClose( |
348 | HENUMInternal *phEnumBody, // [IN] MethodBody enumerator. |
349 | HENUMInternal *phEnumDecl) // [IN] MethodDecl enumerator. |
350 | { |
351 | _ASSERTE(phEnumBody && ((phEnumBody->m_tkKind >> 24) == TBL_MethodImpl)); |
352 | _ASSERTE(phEnumBody->m_EnumType == MDSimpleEnum); |
353 | } // MDInternalRO::EnumMethodImplClose |
354 | |
355 | |
356 | //****************************************************************************** |
357 | // enumerator for global functions |
358 | //****************************************************************************** |
359 | __checkReturn |
360 | HRESULT MDInternalRO::EnumGlobalFunctionsInit( // return hresult |
361 | HENUMInternal *phEnum) // [OUT] buffer to fill for enumerator data |
362 | { |
363 | return EnumInit(mdtMethodDef, m_tdModule, phEnum); |
364 | } |
365 | |
366 | |
367 | //****************************************************************************** |
368 | // enumerator for global Fields |
369 | //****************************************************************************** |
370 | __checkReturn |
371 | HRESULT MDInternalRO::EnumGlobalFieldsInit( // return hresult |
372 | HENUMInternal *phEnum) // [OUT] buffer to fill for enumerator data |
373 | { |
374 | return EnumInit(mdtFieldDef, m_tdModule, phEnum); |
375 | } |
376 | |
377 | |
378 | //***************************************** |
379 | // Enumerator initializer |
380 | //***************************************** |
381 | __checkReturn |
382 | HRESULT MDInternalRO::EnumInit( // return S_FALSE if record not found |
383 | DWORD tkKind, // [IN] which table to work on |
384 | mdToken tkParent, // [IN] token to scope the search |
385 | HENUMInternal *phEnum) // [OUT] the enumerator to fill |
386 | { |
387 | HRESULT hr = S_OK; |
388 | ULONG ulMax = 0; |
389 | |
390 | // Vars for query. |
391 | _ASSERTE(phEnum); |
392 | HENUMInternal::ZeroEnum(phEnum); |
393 | |
394 | // cache the tkKind and the scope |
395 | phEnum->m_tkKind = TypeFromToken(tkKind); |
396 | |
397 | TypeDefRec *pRec; |
398 | |
399 | phEnum->m_EnumType = MDSimpleEnum; |
400 | |
401 | switch (TypeFromToken(tkKind)) |
402 | { |
403 | case mdtFieldDef: |
404 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetTypeDefRecord(RidFromToken(tkParent), &pRec)); |
405 | phEnum->u.m_ulStart = m_LiteWeightStgdb.m_MiniMd.getFieldListOfTypeDef(pRec); |
406 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndFieldListOfTypeDef(RidFromToken(tkParent), &(phEnum->u.m_ulEnd))); |
407 | break; |
408 | |
409 | case mdtMethodDef: |
410 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetTypeDefRecord(RidFromToken(tkParent), &pRec)); |
411 | phEnum->u.m_ulStart = m_LiteWeightStgdb.m_MiniMd.getMethodListOfTypeDef(pRec); |
412 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndMethodListOfTypeDef(RidFromToken(tkParent), &(phEnum->u.m_ulEnd))); |
413 | break; |
414 | |
415 | case mdtGenericParam: |
416 | _ASSERTE(TypeFromToken(tkParent) == mdtTypeDef || TypeFromToken(tkParent) == mdtMethodDef); |
417 | |
418 | if (TypeFromToken(tkParent) != mdtTypeDef && TypeFromToken(tkParent) != mdtMethodDef) |
419 | IfFailGo(CLDB_E_FILE_CORRUPT); |
420 | |
421 | if (TypeFromToken(tkParent) == mdtTypeDef) |
422 | { |
423 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getGenericParamsForTypeDef( |
424 | RidFromToken(tkParent), |
425 | &phEnum->u.m_ulEnd, |
426 | &(phEnum->u.m_ulStart))); |
427 | } |
428 | else |
429 | { |
430 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getGenericParamsForMethodDef( |
431 | RidFromToken(tkParent), |
432 | &phEnum->u.m_ulEnd, |
433 | &(phEnum->u.m_ulStart))); |
434 | } |
435 | break; |
436 | |
437 | case mdtGenericParamConstraint: |
438 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getGenericParamConstraintsForGenericParam( |
439 | RidFromToken(tkParent), |
440 | &phEnum->u.m_ulEnd, |
441 | &phEnum->u.m_ulStart)); |
442 | break; |
443 | |
444 | case mdtInterfaceImpl: |
445 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getInterfaceImplsForTypeDef(RidFromToken(tkParent), &phEnum->u.m_ulEnd, &phEnum->u.m_ulStart)); |
446 | break; |
447 | |
448 | case mdtProperty: |
449 | RID ridPropertyMap; |
450 | PropertyMapRec *pPropertyMapRec; |
451 | |
452 | // get the starting/ending rid of properties of this typedef |
453 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindPropertyMapFor(RidFromToken(tkParent), &ridPropertyMap)); |
454 | if (!InvalidRid(ridPropertyMap)) |
455 | { |
456 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetPropertyMapRecord(ridPropertyMap, &pPropertyMapRec)); |
457 | phEnum->u.m_ulStart = m_LiteWeightStgdb.m_MiniMd.getPropertyListOfPropertyMap(pPropertyMapRec); |
458 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndPropertyListOfPropertyMap(ridPropertyMap, &(phEnum->u.m_ulEnd))); |
459 | ulMax = m_LiteWeightStgdb.m_MiniMd.getCountPropertys() + 1; |
460 | if(phEnum->u.m_ulStart == 0) phEnum->u.m_ulStart = 1; |
461 | if(phEnum->u.m_ulEnd > ulMax) phEnum->u.m_ulEnd = ulMax; |
462 | if(phEnum->u.m_ulStart > phEnum->u.m_ulEnd) phEnum->u.m_ulStart = phEnum->u.m_ulEnd; |
463 | } |
464 | break; |
465 | |
466 | case mdtEvent: |
467 | RID ridEventMap; |
468 | EventMapRec *pEventMapRec; |
469 | |
470 | // get the starting/ending rid of events of this typedef |
471 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindEventMapFor(RidFromToken(tkParent), &ridEventMap)); |
472 | if (!InvalidRid(ridEventMap)) |
473 | { |
474 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetEventMapRecord(ridEventMap, &pEventMapRec)); |
475 | phEnum->u.m_ulStart = m_LiteWeightStgdb.m_MiniMd.getEventListOfEventMap(pEventMapRec); |
476 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndEventListOfEventMap(ridEventMap, &(phEnum->u.m_ulEnd))); |
477 | ulMax = m_LiteWeightStgdb.m_MiniMd.getCountEvents() + 1; |
478 | if(phEnum->u.m_ulStart == 0) phEnum->u.m_ulStart = 1; |
479 | if(phEnum->u.m_ulEnd > ulMax) phEnum->u.m_ulEnd = ulMax; |
480 | if(phEnum->u.m_ulStart > phEnum->u.m_ulEnd) phEnum->u.m_ulStart = phEnum->u.m_ulEnd; |
481 | } |
482 | break; |
483 | |
484 | case mdtParamDef: |
485 | _ASSERTE(TypeFromToken(tkParent) == mdtMethodDef); |
486 | |
487 | MethodRec *pMethodRec; |
488 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(RidFromToken(tkParent), &pMethodRec)); |
489 | |
490 | // figure out the start rid and end rid of the parameter list of this methoddef |
491 | phEnum->u.m_ulStart = m_LiteWeightStgdb.m_MiniMd.getParamListOfMethod(pMethodRec); |
492 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndParamListOfMethod(RidFromToken(tkParent), &(phEnum->u.m_ulEnd))); |
493 | break; |
494 | case mdtCustomAttribute: |
495 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getCustomAttributeForToken(tkParent, &phEnum->u.m_ulEnd, &phEnum->u.m_ulStart)); |
496 | break; |
497 | case mdtAssemblyRef: |
498 | _ASSERTE(IsNilToken(tkParent)); |
499 | phEnum->u.m_ulStart = 1; |
500 | phEnum->u.m_ulEnd = m_LiteWeightStgdb.m_MiniMd.getCountAssemblyRefs() + 1; |
501 | break; |
502 | case mdtFile: |
503 | _ASSERTE(IsNilToken(tkParent)); |
504 | phEnum->u.m_ulStart = 1; |
505 | phEnum->u.m_ulEnd = m_LiteWeightStgdb.m_MiniMd.getCountFiles() + 1; |
506 | break; |
507 | case mdtExportedType: |
508 | _ASSERTE(IsNilToken(tkParent)); |
509 | phEnum->u.m_ulStart = 1; |
510 | phEnum->u.m_ulEnd = m_LiteWeightStgdb.m_MiniMd.getCountExportedTypes() + 1; |
511 | break; |
512 | case mdtManifestResource: |
513 | _ASSERTE(IsNilToken(tkParent)); |
514 | phEnum->u.m_ulStart = 1; |
515 | phEnum->u.m_ulEnd = m_LiteWeightStgdb.m_MiniMd.getCountManifestResources() + 1; |
516 | break; |
517 | case mdtModuleRef: |
518 | _ASSERTE(IsNilToken(tkParent)); |
519 | phEnum->u.m_ulStart = 1; |
520 | phEnum->u.m_ulEnd = m_LiteWeightStgdb.m_MiniMd.getCountModuleRefs() + 1; |
521 | break; |
522 | case (TBL_MethodImpl << 24): |
523 | _ASSERTE(! IsNilToken(tkParent)); |
524 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getMethodImplsForClass( |
525 | RidFromToken(tkParent), |
526 | &phEnum->u.m_ulEnd, |
527 | &phEnum->u.m_ulStart)); |
528 | break; |
529 | default: |
530 | _ASSERTE(!"ENUM INIT not implemented for the compressed format!" ); |
531 | IfFailGo(E_NOTIMPL); |
532 | break; |
533 | } |
534 | |
535 | // If the count is negative, the metadata is corrupted somehow. |
536 | if (phEnum->u.m_ulEnd < phEnum->u.m_ulStart) |
537 | IfFailGo(CLDB_E_FILE_CORRUPT); |
538 | |
539 | phEnum->m_ulCount = phEnum->u.m_ulEnd - phEnum->u.m_ulStart; |
540 | phEnum->u.m_ulCur = phEnum->u.m_ulStart; |
541 | |
542 | ErrExit: |
543 | // we are done |
544 | return hr; |
545 | } |
546 | |
547 | |
548 | //***************************************** |
549 | // Enumerator initializer |
550 | //***************************************** |
551 | __checkReturn |
552 | HRESULT MDInternalRO::EnumAllInit( // return S_FALSE if record not found |
553 | DWORD tkKind, // [IN] which table to work on |
554 | HENUMInternal *phEnum) // [OUT] the enumerator to fill |
555 | { |
556 | HRESULT hr = S_OK; |
557 | |
558 | // Vars for query. |
559 | _ASSERTE(phEnum); |
560 | memset(phEnum, 0, sizeof(HENUMInternal)); |
561 | |
562 | // cache the tkKind and the scope |
563 | phEnum->m_tkKind = TypeFromToken(tkKind); |
564 | phEnum->m_EnumType = MDSimpleEnum; |
565 | |
566 | switch (TypeFromToken(tkKind)) |
567 | { |
568 | case mdtTypeRef: |
569 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountTypeRefs(); |
570 | break; |
571 | |
572 | case mdtMemberRef: |
573 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountMemberRefs(); |
574 | break; |
575 | |
576 | case mdtSignature: |
577 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountStandAloneSigs(); |
578 | break; |
579 | |
580 | case mdtMethodDef: |
581 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountMethods(); |
582 | break; |
583 | |
584 | case mdtMethodSpec: |
585 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountMethodSpecs(); |
586 | break; |
587 | |
588 | case mdtFieldDef: |
589 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountFields(); |
590 | break; |
591 | |
592 | case mdtTypeSpec: |
593 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountTypeSpecs(); |
594 | break; |
595 | |
596 | case mdtAssemblyRef: |
597 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountAssemblyRefs(); |
598 | break; |
599 | |
600 | case mdtModuleRef: |
601 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountModuleRefs(); |
602 | break; |
603 | |
604 | case mdtTypeDef: |
605 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountTypeDefs(); |
606 | break; |
607 | |
608 | case mdtFile: |
609 | phEnum->m_ulCount = m_LiteWeightStgdb.m_MiniMd.getCountFiles(); |
610 | break; |
611 | |
612 | default: |
613 | _ASSERTE(!"Bad token kind!" ); |
614 | break; |
615 | } |
616 | phEnum->u.m_ulStart = phEnum->u.m_ulCur = 1; |
617 | phEnum->u.m_ulEnd = phEnum->m_ulCount + 1; |
618 | |
619 | // we are done |
620 | return hr; |
621 | } // MDInternalRO::EnumAllInit |
622 | |
623 | |
624 | //***************************************** |
625 | // get the count |
626 | //***************************************** |
627 | ULONG MDInternalRO::EnumGetCount( |
628 | HENUMInternal *phEnum) // [IN] the enumerator to retrieve information |
629 | { |
630 | _ASSERTE(phEnum); |
631 | return phEnum->m_ulCount; |
632 | } |
633 | |
634 | //***************************************** |
635 | // Get next value contained in the enumerator |
636 | //***************************************** |
637 | bool MDInternalRO::EnumNext( |
638 | HENUMInternal *phEnum, // [IN] the enumerator to retrieve information |
639 | mdToken *ptk) // [OUT] token to scope the search |
640 | { |
641 | _ASSERTE(phEnum && ptk); |
642 | if (phEnum->u.m_ulCur >= phEnum->u.m_ulEnd) |
643 | return false; |
644 | |
645 | if ( phEnum->m_EnumType == MDSimpleEnum ) |
646 | { |
647 | *ptk = phEnum->u.m_ulCur | phEnum->m_tkKind; |
648 | phEnum->u.m_ulCur++; |
649 | } |
650 | else |
651 | { |
652 | TOKENLIST *pdalist = (TOKENLIST *)&(phEnum->m_cursor); |
653 | |
654 | _ASSERTE( phEnum->m_EnumType == MDDynamicArrayEnum ); |
655 | *ptk = *( pdalist->Get(phEnum->u.m_ulCur++) ); |
656 | } |
657 | return true; |
658 | } // MDInternalRO::EnumNext |
659 | |
660 | |
661 | //***************************************** |
662 | // Reset the enumerator to the beginning. |
663 | //***************************************** |
664 | void MDInternalRO::EnumReset( |
665 | HENUMInternal *phEnum) // [IN] the enumerator to be reset |
666 | { |
667 | _ASSERTE(phEnum); |
668 | _ASSERTE( phEnum->m_EnumType == MDSimpleEnum || phEnum->m_EnumType == MDDynamicArrayEnum); |
669 | |
670 | phEnum->u.m_ulCur = phEnum->u.m_ulStart; |
671 | } // MDInternalRO::EnumReset |
672 | |
673 | |
674 | //***************************************** |
675 | // Close the enumerator. Only for read/write mode that we need to close the cursor. |
676 | // Hopefully with readonly mode, it will be a no-op |
677 | //***************************************** |
678 | void MDInternalRO::EnumClose( |
679 | HENUMInternal *phEnum) // [IN] the enumerator to be closed |
680 | { |
681 | _ASSERTE( phEnum->m_EnumType == MDSimpleEnum || |
682 | phEnum->m_EnumType == MDDynamicArrayEnum || |
683 | phEnum->m_EnumType == MDCustomEnum ); |
684 | if (phEnum->m_EnumType == MDDynamicArrayEnum) |
685 | HENUMInternal::ClearEnum(phEnum); |
686 | } // MDInternalRO::EnumClose |
687 | |
688 | |
689 | //--------------------------------------------------------------------------------------- |
690 | // |
691 | // Initialize enumerator of PermissionSets. |
692 | // |
693 | // Return Value: |
694 | // CLDB_E_RECORD_NOTFOUND ... If record not found. |
695 | // S_OK and empty enumeration ... If tkParent is nil token and Action is dclActionNil. |
696 | // |
697 | __checkReturn |
698 | HRESULT |
699 | MDInternalRO::EnumPermissionSetsInit( |
700 | mdToken tkParent, // [IN] Token to scope the search. |
701 | CorDeclSecurity Action, // [IN] Action to scope the search. |
702 | HENUMInternal *phEnum) // [OUT] Enumerator to fill. |
703 | { |
704 | HRESULT hr = S_OK; |
705 | |
706 | _ASSERTE(phEnum != NULL); |
707 | HENUMInternal::ZeroEnum(phEnum); |
708 | |
709 | // cache the tkKind |
710 | phEnum->m_tkKind = mdtPermission; |
711 | |
712 | DeclSecurityRec *pDecl; |
713 | RID ridCur; |
714 | RID ridEnd; |
715 | |
716 | phEnum->m_EnumType = MDSimpleEnum; |
717 | |
718 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getDeclSecurityForToken(tkParent, &ridEnd, &ridCur)); |
719 | if (Action != dclActionNil) |
720 | { |
721 | for (; ridCur < ridEnd; ridCur++) |
722 | { |
723 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetDeclSecurityRecord(ridCur, &pDecl)); |
724 | if (Action == m_LiteWeightStgdb.m_MiniMd.getActionOfDeclSecurity(pDecl)) |
725 | { |
726 | // found a match |
727 | phEnum->u.m_ulStart = phEnum->u.m_ulCur = ridCur; |
728 | phEnum->u.m_ulEnd = ridCur + 1; |
729 | phEnum->m_ulCount = 1; |
730 | goto ErrExit; |
731 | } |
732 | } |
733 | hr = CLDB_E_RECORD_NOTFOUND; |
734 | } |
735 | else |
736 | { |
737 | phEnum->u.m_ulStart = phEnum->u.m_ulCur = ridCur; |
738 | phEnum->u.m_ulEnd = ridEnd; |
739 | phEnum->m_ulCount = ridEnd - ridCur; |
740 | } |
741 | |
742 | ErrExit: |
743 | return hr; |
744 | } // MDInternalRO::EnumPermissionSetInit |
745 | |
746 | |
747 | //***************************************** |
748 | // Enumerator initializer for CustomAttributes |
749 | //***************************************** |
750 | __checkReturn |
751 | HRESULT MDInternalRO::EnumCustomAttributeByNameInit(// return S_FALSE if record not found |
752 | mdToken tkParent, // [IN] token to scope the search |
753 | LPCSTR szName, // [IN] CustomAttribute's name to scope the search |
754 | HENUMInternal *phEnum) // [OUT] the enumerator to fill |
755 | { |
756 | return m_LiteWeightStgdb.m_MiniMd.CommonEnumCustomAttributeByName(tkParent, szName, false, phEnum); |
757 | } // MDInternalRO::EnumCustomAttributeByNameInit |
758 | |
759 | //***************************************** |
760 | // Enumerator for CustomAttributes which doesn't |
761 | // allocate any memory |
762 | //***************************************** |
763 | __checkReturn |
764 | HRESULT MDInternalRO::SafeAndSlowEnumCustomAttributeByNameInit(// return S_FALSE if record not found |
765 | mdToken tkParent, // [IN] token to scope the search |
766 | LPCSTR szName, // [IN] CustomAttribute's name to scope the search |
767 | HENUMInternal *phEnum) // [OUT] The enumerator |
768 | { |
769 | _ASSERTE(phEnum); |
770 | |
771 | HRESULT hr; |
772 | ULONG ridStart, ridEnd; // Loop start and endpoints. |
773 | |
774 | // Get the list of custom values for the parent object. |
775 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getCustomAttributeForToken(tkParent, &ridEnd, &ridStart)); |
776 | // If found none, done. |
777 | if (ridStart == 0) |
778 | goto NoMatch; |
779 | |
780 | phEnum->m_EnumType = MDCustomEnum; |
781 | phEnum->m_tkKind = mdtCustomAttribute; |
782 | phEnum->u.m_ulStart = ridStart; |
783 | phEnum->u.m_ulEnd = ridEnd; |
784 | phEnum->u.m_ulCur = ridStart; |
785 | |
786 | return S_OK; |
787 | |
788 | NoMatch: |
789 | return S_FALSE; |
790 | } // MDInternalRO::SafeAndSlowEnumCustomAttributeByNameInit |
791 | |
792 | __checkReturn |
793 | HRESULT MDInternalRO::SafeAndSlowEnumCustomAttributeByNameNext(// return S_FALSE if record not found |
794 | mdToken tkParent, // [IN] token to scope the search |
795 | LPCSTR szName, // [IN] CustomAttribute's name to scope the search |
796 | HENUMInternal *phEnum, // [IN] The enumerator |
797 | mdCustomAttribute *mdAttribute) // [OUT] The custom attribute that was found |
798 | { |
799 | _ASSERTE(phEnum); |
800 | _ASSERTE(phEnum->m_EnumType == MDCustomEnum); |
801 | _ASSERTE(phEnum->m_tkKind == mdtCustomAttribute); |
802 | |
803 | // Look for one with the given name. |
804 | for (; phEnum->u.m_ulCur < phEnum->u.m_ulEnd; ++phEnum->u.m_ulCur) |
805 | { |
806 | if (S_OK == m_LiteWeightStgdb.m_MiniMd.CompareCustomAttribute( tkParent, szName, phEnum->u.m_ulCur)) |
807 | { |
808 | // If here, found a match. |
809 | *mdAttribute = TokenFromRid(phEnum->u.m_ulCur, mdtCustomAttribute); |
810 | phEnum->u.m_ulCur++; |
811 | return S_OK; |
812 | } |
813 | } |
814 | // No match... |
815 | return S_FALSE; |
816 | } // MDInternalRO::SafeAndSlowEnumCustomAttributeByNameNext |
817 | |
818 | |
819 | //***************************************** |
820 | // Nagivator helper to navigate back to the parent token given a token. |
821 | // For example, given a memberdef token, it will return the containing typedef. |
822 | // |
823 | // the mapping is as following: |
824 | // ---given child type---------parent type |
825 | // mdMethodDef mdTypeDef |
826 | // mdFieldDef mdTypeDef |
827 | // mdInterfaceImpl mdTypeDef |
828 | // mdParam mdMethodDef |
829 | // mdProperty mdTypeDef |
830 | // mdEvent mdTypeDef |
831 | // |
832 | //***************************************** |
833 | __checkReturn |
834 | HRESULT MDInternalRO::GetParentToken( |
835 | mdToken tkChild, // [IN] given child token |
836 | mdToken *ptkParent) // [OUT] returning parent |
837 | { |
838 | HRESULT hr = NOERROR; |
839 | |
840 | _ASSERTE(ptkParent); |
841 | |
842 | switch (TypeFromToken(tkChild)) |
843 | { |
844 | case mdtTypeDef: |
845 | hr = GetNestedClassProps(tkChild, ptkParent); |
846 | // If not found, the *ptkParent has to be left unchanged! (callers depend on that) |
847 | if (hr == CLDB_E_RECORD_NOTFOUND) |
848 | { |
849 | hr = S_OK; |
850 | } |
851 | break; |
852 | |
853 | case mdtMethodDef: |
854 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindParentOfMethod(RidFromToken(tkChild), (RID *)ptkParent)); |
855 | RidToToken(*ptkParent, mdtTypeDef); |
856 | break; |
857 | |
858 | case mdtMethodSpec: |
859 | { |
860 | MethodSpecRec *pRec; |
861 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSpecRecord(RidFromToken(tkChild), &pRec)); |
862 | *ptkParent = m_LiteWeightStgdb.m_MiniMd.getMethodOfMethodSpec(pRec); |
863 | break; |
864 | } |
865 | |
866 | case mdtFieldDef: |
867 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindParentOfField(RidFromToken(tkChild), (RID *)ptkParent)); |
868 | RidToToken(*ptkParent, mdtTypeDef); |
869 | break; |
870 | |
871 | case mdtParamDef: |
872 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindParentOfParam(RidFromToken(tkChild), (RID *)ptkParent)); |
873 | RidToToken(*ptkParent, mdtMethodDef); |
874 | break; |
875 | |
876 | case mdtMemberRef: |
877 | { |
878 | MemberRefRec *pRec; |
879 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMemberRefRecord(RidFromToken(tkChild), &pRec)); |
880 | *ptkParent = m_LiteWeightStgdb.m_MiniMd.getClassOfMemberRef(pRec); |
881 | break; |
882 | } |
883 | |
884 | case mdtCustomAttribute: |
885 | { |
886 | CustomAttributeRec *pRec; |
887 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetCustomAttributeRecord(RidFromToken(tkChild), &pRec)); |
888 | *ptkParent = m_LiteWeightStgdb.m_MiniMd.getParentOfCustomAttribute(pRec); |
889 | break; |
890 | } |
891 | |
892 | case mdtEvent: |
893 | hr = m_LiteWeightStgdb.m_MiniMd.FindParentOfEventHelper(tkChild, ptkParent); |
894 | break; |
895 | |
896 | case mdtProperty: |
897 | hr = m_LiteWeightStgdb.m_MiniMd.FindParentOfPropertyHelper(tkChild, ptkParent); |
898 | break; |
899 | |
900 | default: |
901 | _ASSERTE(!"NYI: for compressed format!" ); |
902 | break; |
903 | } |
904 | return hr; |
905 | } // MDInternalRO::GetParentToken |
906 | |
907 | |
908 | |
909 | //***************************************************************************** |
910 | // Get information about a CustomAttribute. |
911 | //***************************************************************************** |
912 | __checkReturn |
913 | HRESULT |
914 | MDInternalRO::GetCustomAttributeProps( // S_OK or error. |
915 | mdCustomAttribute at, // The attribute. |
916 | mdToken *ptkType) // Put attribute type here. |
917 | { |
918 | HRESULT hr; |
919 | _ASSERTE(TypeFromToken(at) == mdtCustomAttribute); |
920 | |
921 | // Do a linear search on compressed version as we do not want to |
922 | // depends on ICR. |
923 | // |
924 | CustomAttributeRec *pCustomAttributeRec; |
925 | |
926 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetCustomAttributeRecord(RidFromToken(at), &pCustomAttributeRec)); |
927 | *ptkType = m_LiteWeightStgdb.m_MiniMd.getTypeOfCustomAttribute(pCustomAttributeRec); |
928 | return S_OK; |
929 | } // MDInternalRO::GetCustomAttributeProps |
930 | |
931 | //***************************************************************************** |
932 | // return custom value |
933 | //***************************************************************************** |
934 | __checkReturn |
935 | HRESULT |
936 | MDInternalRO::GetCustomAttributeAsBlob( |
937 | mdCustomAttribute cv, // [IN] given custom attribute token |
938 | void const **ppBlob, // [OUT] return the pointer to internal blob |
939 | ULONG *pcbSize) // [OUT] return the size of the blob |
940 | { |
941 | HRESULT hr; |
942 | _ASSERTE(ppBlob && pcbSize && TypeFromToken(cv) == mdtCustomAttribute); |
943 | |
944 | CustomAttributeRec *pCustomAttributeRec; |
945 | |
946 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetCustomAttributeRecord(RidFromToken(cv), &pCustomAttributeRec)); |
947 | |
948 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getValueOfCustomAttribute(pCustomAttributeRec, (const BYTE **)ppBlob, pcbSize)); |
949 | return S_OK; |
950 | } // MDInternalRO::GetCustomAttributeAsBlob |
951 | |
952 | //***************************************************************************** |
953 | // Helper function to lookup and retrieve a CustomAttribute. |
954 | //***************************************************************************** |
955 | __checkReturn |
956 | HRESULT MDInternalRO::GetCustomAttributeByName( // S_OK or error. |
957 | mdToken tkObj, // [IN] Object with Custom Attribute. |
958 | LPCUTF8 szName, // [IN] Name of desired Custom Attribute. |
959 | __deref_out_bcount(*pcbData) const void **ppData, // [OUT] Put pointer to data here. |
960 | __out ULONG *pcbData) // [OUT] Put size of data here. |
961 | { |
962 | return m_LiteWeightStgdb.m_MiniMd.CommonGetCustomAttributeByName(tkObj, szName, ppData, pcbData); |
963 | } // MDInternalRO::GetCustomAttributeByName |
964 | |
965 | |
966 | //***************************************************************************** |
967 | // return the name of a custom attribute |
968 | //***************************************************************************** |
969 | __checkReturn |
970 | HRESULT MDInternalRO::GetNameOfCustomAttribute( // S_OK or error. |
971 | mdCustomAttribute mdAttribute, // [IN] The Custom Attribute |
972 | LPCUTF8 *pszNamespace, // [OUT] Namespace of Custom Attribute. |
973 | LPCUTF8 *pszName) // [OUT] Name of Custom Attribute. |
974 | { |
975 | _ASSERTE(TypeFromToken(mdAttribute) == mdtCustomAttribute); |
976 | |
977 | HRESULT hr = m_LiteWeightStgdb.m_MiniMd.CommonGetNameOfCustomAttribute(RidFromToken(mdAttribute), pszNamespace, pszName); |
978 | return (hr == S_FALSE) ? E_FAIL : hr; |
979 | } // MDInternalRO::GetNameOfCustomAttribute |
980 | |
981 | //***************************************************************************** |
982 | // return scope properties |
983 | //***************************************************************************** |
984 | __checkReturn |
985 | HRESULT |
986 | MDInternalRO::GetScopeProps( |
987 | LPCSTR *pszName, // [OUT] scope name |
988 | GUID *pmvid) // [OUT] version id |
989 | { |
990 | HRESULT hr; |
991 | |
992 | ModuleRec *pModuleRec; |
993 | |
994 | // there is only one module record |
995 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetModuleRecord(1, &pModuleRec)); |
996 | |
997 | if (pmvid != NULL) |
998 | { |
999 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getMvidOfModule(pModuleRec, pmvid)); |
1000 | } |
1001 | if (pszName != NULL) |
1002 | { |
1003 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfModule(pModuleRec, pszName)); |
1004 | } |
1005 | |
1006 | return S_OK; |
1007 | } // MDInternalRO::GetScopeProps |
1008 | |
1009 | |
1010 | //***************************************************************************** |
1011 | // Compare two signatures from the same scope. Varags signatures need to be |
1012 | // preprocessed so they only contain the fixed part. |
1013 | //***************************************************************************** |
1014 | BOOL MDInternalRO::CompareSignatures(PCCOR_SIGNATURE pvFirstSigBlob, // First signature |
1015 | DWORD cbFirstSigBlob, // |
1016 | PCCOR_SIGNATURE pvSecondSigBlob, // Second signature |
1017 | DWORD cbSecondSigBlob, // |
1018 | void * SigArguments) // No additional arguments required |
1019 | { |
1020 | if (cbFirstSigBlob != cbSecondSigBlob || memcmp(pvFirstSigBlob, pvSecondSigBlob, cbSecondSigBlob)) |
1021 | return FALSE; |
1022 | else |
1023 | return TRUE; |
1024 | } |
1025 | |
1026 | //***************************************************************************** |
1027 | // Find a given member in a TypeDef (typically a class). |
1028 | //***************************************************************************** |
1029 | __checkReturn |
1030 | HRESULT MDInternalRO::FindMethodDef( // S_OK or error. |
1031 | mdTypeDef classdef, // The owning class of the member. |
1032 | LPCSTR szName, // Name of the member in utf8. |
1033 | PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature |
1034 | ULONG cbSigBlob, // [IN] count of bytes in the signature blob |
1035 | mdMethodDef *pmethoddef) // Put MemberDef token here. |
1036 | { |
1037 | |
1038 | return FindMethodDefUsingCompare(classdef, |
1039 | szName, |
1040 | pvSigBlob, |
1041 | cbSigBlob, |
1042 | CompareSignatures, |
1043 | NULL, |
1044 | pmethoddef); |
1045 | } |
1046 | |
1047 | //***************************************************************************** |
1048 | // Find a given member in a TypeDef (typically a class). |
1049 | //***************************************************************************** |
1050 | __checkReturn |
1051 | HRESULT MDInternalRO::FindMethodDefUsingCompare( // S_OK or error. |
1052 | mdTypeDef classdef, // The owning class of the member. |
1053 | LPCSTR szName, // Name of the member in utf8. |
1054 | PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of COM+ signature |
1055 | ULONG cbSigBlob, // [IN] count of bytes in the signature blob |
1056 | PSIGCOMPARE SigCompare, // [IN] Signature comparison routine |
1057 | void* pSigArgs, // [IN] Additional arguments passed to signature compare |
1058 | mdMethodDef *pmethoddef) // Put MemberDef token here. |
1059 | { |
1060 | HRESULT hr = NOERROR; |
1061 | PCCOR_SIGNATURE pvSigTemp = pvSigBlob; |
1062 | CQuickBytes qbSig; |
1063 | |
1064 | _ASSERTE(szName && pmethoddef); |
1065 | |
1066 | // initialize the output parameter |
1067 | *pmethoddef = mdMethodDefNil; |
1068 | |
1069 | // check to see if this is a vararg signature |
1070 | if ( isCallConv(CorSigUncompressCallingConv(pvSigTemp), IMAGE_CEE_CS_CALLCONV_VARARG) ) |
1071 | { |
1072 | // Get the fix part of VARARG signature |
1073 | IfFailGo( _GetFixedSigOfVarArg(pvSigBlob, cbSigBlob, &qbSig, &cbSigBlob) ); |
1074 | pvSigBlob = (PCCOR_SIGNATURE) qbSig.Ptr(); |
1075 | } |
1076 | |
1077 | // Do a linear search on compressed version |
1078 | // |
1079 | RID ridMax; |
1080 | MethodRec *pMethodRec; |
1081 | LPCUTF8 szCurMethodName; |
1082 | void const *pvCurMethodSig; |
1083 | ULONG cbSig; |
1084 | TypeDefRec *pRec; |
1085 | RID ridStart; |
1086 | |
1087 | // get the typedef record |
1088 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetTypeDefRecord(RidFromToken(classdef), &pRec)); |
1089 | |
1090 | // get the range of methoddef rids given the classdef |
1091 | ridStart = m_LiteWeightStgdb.m_MiniMd.getMethodListOfTypeDef(pRec); |
1092 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndMethodListOfTypeDef(RidFromToken(classdef), &ridMax)); |
1093 | |
1094 | // loop through each methoddef |
1095 | for (; ridStart < ridMax; ridStart++) |
1096 | { |
1097 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(ridStart, &pMethodRec)); |
1098 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNameOfMethod(pMethodRec, &szCurMethodName)); |
1099 | if (strcmp(szCurMethodName, szName) == 0) |
1100 | { |
1101 | // name match, now check the signature if specified. |
1102 | if (cbSigBlob && SigCompare) |
1103 | { |
1104 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getSignatureOfMethod(pMethodRec, (PCCOR_SIGNATURE *)&pvCurMethodSig, &cbSig)); |
1105 | // Signature comparison is required |
1106 | // Note that if pvSigBlob is vararg, we already preprocess it so that |
1107 | // it only contains the fix part. Therefore, it still should be an exact |
1108 | // match!!!. |
1109 | // |
1110 | if(SigCompare((PCCOR_SIGNATURE) pvCurMethodSig, cbSig, pvSigBlob, cbSigBlob, pSigArgs) == FALSE) |
1111 | continue; |
1112 | } |
1113 | // Ignore PrivateScope methods. |
1114 | if (IsMdPrivateScope(m_LiteWeightStgdb.m_MiniMd.getFlagsOfMethod(pMethodRec))) |
1115 | continue; |
1116 | // found the match |
1117 | *pmethoddef = TokenFromRid(ridStart, mdtMethodDef); |
1118 | goto ErrExit; |
1119 | } |
1120 | } |
1121 | hr = CLDB_E_RECORD_NOTFOUND; |
1122 | |
1123 | ErrExit: |
1124 | return hr; |
1125 | } |
1126 | |
1127 | //***************************************************************************** |
1128 | // Find a given param of a Method. |
1129 | //***************************************************************************** |
1130 | __checkReturn |
1131 | HRESULT MDInternalRO::FindParamOfMethod(// S_OK or error. |
1132 | mdMethodDef md, // [IN] The owning method of the param. |
1133 | ULONG iSeq, // [IN] The sequence # of the param. |
1134 | mdParamDef *pparamdef) // [OUT] Put ParamDef token here. |
1135 | { |
1136 | HRESULT hr; |
1137 | ParamRec *pParamRec; |
1138 | RID ridStart, ridEnd; |
1139 | |
1140 | _ASSERTE(TypeFromToken(md) == mdtMethodDef && pparamdef); |
1141 | |
1142 | // get the methoddef record |
1143 | MethodRec *pMethodRec; |
1144 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(RidFromToken(md), &pMethodRec)); |
1145 | |
1146 | // figure out the start rid and end rid of the parameter list of this methoddef |
1147 | ridStart = m_LiteWeightStgdb.m_MiniMd.getParamListOfMethod(pMethodRec); |
1148 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getEndParamListOfMethod(RidFromToken(md), &ridEnd)); |
1149 | |
1150 | // Ensure that the paramList is valid. If the count is negative, the metadata |
1151 | // is corrupted somehow. Thus, return CLDB_E_FILE_CORRUPT. |
1152 | if (ridEnd < ridStart) |
1153 | return CLDB_E_FILE_CORRUPT; |
1154 | |
1155 | // loop through each param |
1156 | //<TODO>@consider: parameters are sorted by sequence. Maybe a binary search? |
1157 | //</TODO> |
1158 | for (; ridStart < ridEnd; ridStart++) |
1159 | { |
1160 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetParamRecord(ridStart, &pParamRec)); |
1161 | if (iSeq == m_LiteWeightStgdb.m_MiniMd.getSequenceOfParam(pParamRec)) |
1162 | { |
1163 | // parameter has the sequence number matches what we are looking for |
1164 | *pparamdef = TokenFromRid(ridStart, mdtParamDef); |
1165 | return S_OK; |
1166 | } |
1167 | } |
1168 | return CLDB_E_RECORD_NOTFOUND; |
1169 | } |
1170 | |
1171 | |
1172 | |
1173 | //***************************************************************************** |
1174 | // return a pointer which points to meta data's internal string |
1175 | // return the the type name in utf8 |
1176 | //***************************************************************************** |
1177 | __checkReturn |
1178 | HRESULT |
1179 | MDInternalRO::GetNameOfTypeDef( // return hresult |
1180 | mdTypeDef classdef, // given typedef |
1181 | LPCSTR* pszname, // pointer to an internal UTF8 string |
1182 | LPCSTR* psznamespace) // pointer to the namespace. |
1183 | { |
1184 | HRESULT hr; |
1185 | |
1186 | if (pszname != NULL) |
1187 | { |
1188 | *pszname = NULL; |
1189 | } |
1190 | if (psznamespace != NULL) |
1191 | { |
1192 | *psznamespace = NULL; |
1193 | } |
1194 | |
1195 | if (TypeFromToken(classdef) == mdtTypeDef) |
1196 | { |
1197 | TypeDefRec *pTypeDefRec; |
1198 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeDefRecord(RidFromToken(classdef), &pTypeDefRec)); |
1199 | |
1200 | if (pszname != NULL) |
1201 | { |
1202 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfTypeDef(pTypeDefRec, pszname)); |
1203 | } |
1204 | |
1205 | if (psznamespace != NULL) |
1206 | { |
1207 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNamespaceOfTypeDef(pTypeDefRec, psznamespace)); |
1208 | } |
1209 | return S_OK; |
1210 | } |
1211 | |
1212 | _ASSERTE(!"Invalid argument(s) of GetNameOfTypeDef" ); |
1213 | return CLDB_E_INTERNALERROR; |
1214 | } // MDInternalRO::GetNameOfTypeDef |
1215 | |
1216 | |
1217 | __checkReturn |
1218 | HRESULT MDInternalRO::GetIsDualOfTypeDef(// return hresult |
1219 | mdTypeDef classdef, // given classdef |
1220 | ULONG *pDual) // [OUT] return dual flag here. |
1221 | { |
1222 | ULONG iFace=0; // Iface type. |
1223 | HRESULT hr; // A result. |
1224 | |
1225 | hr = GetIfaceTypeOfTypeDef(classdef, &iFace); |
1226 | if (hr == S_OK) |
1227 | *pDual = (iFace == ifDual); |
1228 | else |
1229 | *pDual = 1; |
1230 | |
1231 | return hr; |
1232 | } // MDInternalRO::GetIsDualOfTypeDef |
1233 | |
1234 | __checkReturn |
1235 | HRESULT MDInternalRO::GetIfaceTypeOfTypeDef( |
1236 | mdTypeDef classdef, // [IN] given classdef. |
1237 | ULONG *pIface) // [OUT] 0=dual, 1=vtable, 2=dispinterface |
1238 | { |
1239 | HRESULT hr; // A result. |
1240 | const BYTE *pVal; // The custom value. |
1241 | ULONG cbVal; // Size of the custom value. |
1242 | ULONG ItfType = DEFAULT_COM_INTERFACE_TYPE; // Set the interface type to the default. |
1243 | |
1244 | // If the value is not present, the class is assumed dual. |
1245 | hr = GetCustomAttributeByName(classdef, INTEROP_INTERFACETYPE_TYPE, (const void**)&pVal, &cbVal); |
1246 | if (hr == S_OK) |
1247 | { |
1248 | CustomAttributeParser cap(pVal, cbVal); |
1249 | BYTE u1; |
1250 | if (SUCCEEDED(cap.SkipProlog()) && |
1251 | SUCCEEDED(cap.GetU1(&u1))) |
1252 | { |
1253 | ItfType = u1; |
1254 | } |
1255 | if (ItfType >= ifLast) |
1256 | ItfType = DEFAULT_COM_INTERFACE_TYPE; |
1257 | } |
1258 | |
1259 | // Set the return value. |
1260 | *pIface = ItfType; |
1261 | |
1262 | return hr; |
1263 | } // MDInternalRO::GetIfaceTypeOfTypeDef |
1264 | |
1265 | //***************************************************************************** |
1266 | // Given a methoddef, return a pointer to methoddef's name |
1267 | //***************************************************************************** |
1268 | __checkReturn |
1269 | HRESULT |
1270 | MDInternalRO::GetNameOfMethodDef( |
1271 | mdMethodDef md, |
1272 | LPCSTR *pszMethodName) |
1273 | { |
1274 | HRESULT hr; |
1275 | MethodRec *pMethodRec; |
1276 | *pszMethodName = NULL; |
1277 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(RidFromToken(md), &pMethodRec)); |
1278 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfMethod(pMethodRec, pszMethodName)); |
1279 | return S_OK; |
1280 | } // MDInternalRO::GetNameOfMethodDef |
1281 | |
1282 | //***************************************************************************** |
1283 | // Given a methoddef, return a pointer to methoddef's signature and methoddef's name |
1284 | //***************************************************************************** |
1285 | __checkReturn |
1286 | HRESULT |
1287 | MDInternalRO::GetNameAndSigOfMethodDef( |
1288 | mdMethodDef methoddef, // [IN] given memberdef |
1289 | PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to a blob value of COM+ signature |
1290 | ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob |
1291 | LPCSTR *pszMethodName) |
1292 | { |
1293 | HRESULT hr; |
1294 | // Output parameter should not be NULL |
1295 | _ASSERTE(ppvSigBlob && pcbSigBlob); |
1296 | _ASSERTE(TypeFromToken(methoddef) == mdtMethodDef); |
1297 | |
1298 | MethodRec *pMethodRec; |
1299 | *pszMethodName = NULL; |
1300 | *ppvSigBlob = NULL; |
1301 | *pcbSigBlob = 0; |
1302 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(RidFromToken(methoddef), &pMethodRec)); |
1303 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getSignatureOfMethod(pMethodRec, (PCCOR_SIGNATURE *)ppvSigBlob, pcbSigBlob)); |
1304 | |
1305 | return GetNameOfMethodDef(methoddef, pszMethodName); |
1306 | } // MDInternalRO::GetNameAndSigOfMethodDef |
1307 | |
1308 | //***************************************************************************** |
1309 | // Given a FieldDef, return a pointer to FieldDef's name in UTF8 |
1310 | //***************************************************************************** |
1311 | __checkReturn |
1312 | HRESULT |
1313 | MDInternalRO::GetNameOfFieldDef( // return hresult |
1314 | mdFieldDef fd, // given field |
1315 | LPCSTR *pszFieldName) |
1316 | { |
1317 | HRESULT hr; |
1318 | FieldRec *pFieldRec; |
1319 | *pszFieldName = NULL; |
1320 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetFieldRecord(RidFromToken(fd), &pFieldRec)); |
1321 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfField(pFieldRec, pszFieldName)); |
1322 | return S_OK; |
1323 | } // MDInternalRO::GetNameOfFieldDef |
1324 | |
1325 | |
1326 | //***************************************************************************** |
1327 | // Given a classdef, return the name and namespace of the typeref |
1328 | //***************************************************************************** |
1329 | __checkReturn |
1330 | HRESULT |
1331 | MDInternalRO::GetNameOfTypeRef( // return TypeDef's name |
1332 | mdTypeRef classref, // [IN] given typeref |
1333 | LPCSTR *psznamespace, // [OUT] return typeref name |
1334 | LPCSTR *pszname) // [OUT] return typeref namespace |
1335 | |
1336 | { |
1337 | _ASSERTE(TypeFromToken(classref) == mdtTypeRef); |
1338 | |
1339 | HRESULT hr; |
1340 | TypeRefRec *pTypeRefRec; |
1341 | |
1342 | *psznamespace = NULL; |
1343 | *pszname = NULL; |
1344 | |
1345 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeRefRecord(RidFromToken(classref), &pTypeRefRec)); |
1346 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNamespaceOfTypeRef(pTypeRefRec, psznamespace)); |
1347 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfTypeRef(pTypeRefRec, pszname)); |
1348 | return S_OK; |
1349 | } |
1350 | |
1351 | //***************************************************************************** |
1352 | // return the resolutionscope of typeref |
1353 | //***************************************************************************** |
1354 | __checkReturn |
1355 | HRESULT |
1356 | MDInternalRO::GetResolutionScopeOfTypeRef( |
1357 | mdTypeRef classref, // given classref |
1358 | mdToken *ptkResolutionScope) |
1359 | { |
1360 | _ASSERTE(TypeFromToken(classref) == mdtTypeRef && RidFromToken(classref)); |
1361 | HRESULT hr; |
1362 | |
1363 | TypeRefRec *pTypeRefRec; |
1364 | |
1365 | *ptkResolutionScope = mdTokenNil; |
1366 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeRefRecord(RidFromToken(classref), &pTypeRefRec)); |
1367 | *ptkResolutionScope = m_LiteWeightStgdb.m_MiniMd.getResolutionScopeOfTypeRef(pTypeRefRec); |
1368 | return S_OK; |
1369 | } // MDInternalRO::GetResolutionScopeOfTypeRef |
1370 | |
1371 | //***************************************************************************** |
1372 | // Given a name, find the corresponding TypeRef. |
1373 | //***************************************************************************** |
1374 | __checkReturn |
1375 | HRESULT MDInternalRO::FindTypeRefByName( // S_OK or error. |
1376 | LPCSTR szNamespace, // [IN] Namespace for the TypeRef. |
1377 | LPCSTR szName, // [IN] Name of the TypeRef. |
1378 | mdToken tkResolutionScope, // [IN] Resolution Scope fo the TypeRef. |
1379 | mdTypeRef *ptk) // [OUT] TypeRef token returned. |
1380 | { |
1381 | HRESULT hr = NOERROR; |
1382 | |
1383 | _ASSERTE(ptk); |
1384 | |
1385 | // initialize the output parameter |
1386 | *ptk = mdTypeRefNil; |
1387 | |
1388 | // Treat no namespace as empty string. |
1389 | if (!szNamespace) |
1390 | szNamespace = "" ; |
1391 | |
1392 | // Do a linear search on compressed version as we do not want to |
1393 | // depends on ICR. |
1394 | // |
1395 | ULONG cTypeRefRecs = m_LiteWeightStgdb.m_MiniMd.getCountTypeRefs(); |
1396 | TypeRefRec *pTypeRefRec; |
1397 | LPCUTF8 szNamespaceTmp; |
1398 | LPCUTF8 szNameTmp; |
1399 | mdToken tkRes; |
1400 | |
1401 | for (ULONG i = 1; i <= cTypeRefRecs; i++) |
1402 | { |
1403 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetTypeRefRecord(i, &pTypeRefRec)); |
1404 | tkRes = m_LiteWeightStgdb.m_MiniMd.getResolutionScopeOfTypeRef(pTypeRefRec); |
1405 | |
1406 | if (IsNilToken(tkRes)) |
1407 | { |
1408 | if (!IsNilToken(tkResolutionScope)) |
1409 | continue; |
1410 | } |
1411 | else if (tkRes != tkResolutionScope) |
1412 | continue; |
1413 | |
1414 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNamespaceOfTypeRef(pTypeRefRec, &szNamespaceTmp)); |
1415 | if (strcmp(szNamespace, szNamespaceTmp)) |
1416 | continue; |
1417 | |
1418 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNameOfTypeRef(pTypeRefRec, &szNameTmp)); |
1419 | if (!strcmp(szNameTmp, szName)) |
1420 | { |
1421 | *ptk = TokenFromRid(i, mdtTypeRef); |
1422 | goto ErrExit; |
1423 | } |
1424 | } |
1425 | |
1426 | // cannot find the typedef |
1427 | hr = CLDB_E_RECORD_NOTFOUND; |
1428 | ErrExit: |
1429 | return hr; |
1430 | } |
1431 | |
1432 | //***************************************************************************** |
1433 | // return flags for a given class |
1434 | //***************************************************************************** |
1435 | __checkReturn |
1436 | HRESULT MDInternalRO::GetTypeDefProps( |
1437 | mdTypeDef td, // given classdef |
1438 | DWORD *pdwAttr, // return flags on class |
1439 | mdToken *ptkExtends) // [OUT] Put base class TypeDef/TypeRef here. |
1440 | { |
1441 | HRESULT hr; |
1442 | TypeDefRec *pTypeDefRec; |
1443 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeDefRecord(RidFromToken(td), &pTypeDefRec)); |
1444 | |
1445 | if (ptkExtends) |
1446 | { |
1447 | *ptkExtends = m_LiteWeightStgdb.m_MiniMd.getExtendsOfTypeDef(pTypeDefRec); |
1448 | } |
1449 | if (pdwAttr) |
1450 | { |
1451 | *pdwAttr = m_LiteWeightStgdb.m_MiniMd.getFlagsOfTypeDef(pTypeDefRec); |
1452 | } |
1453 | |
1454 | return S_OK; |
1455 | } |
1456 | |
1457 | |
1458 | //***************************************************************************** |
1459 | // return guid pointer to MetaData internal guid pool given a given class |
1460 | //***************************************************************************** |
1461 | __checkReturn |
1462 | HRESULT MDInternalRO::GetItemGuid( // return hresult |
1463 | mdToken tkObj, // given item |
1464 | CLSID *pGuid) |
1465 | { |
1466 | |
1467 | HRESULT hr; // A result. |
1468 | const BYTE *pBlob = NULL; // Blob with dispid. |
1469 | ULONG cbBlob; // Length of blob. |
1470 | int ix; // Loop control. |
1471 | |
1472 | // Get the GUID, if any. |
1473 | hr = GetCustomAttributeByName(tkObj, INTEROP_GUID_TYPE, (const void**)&pBlob, &cbBlob); |
1474 | if (hr != S_FALSE) |
1475 | { |
1476 | // Should be in format. Total length == 41 |
1477 | // <0x0001><0x24>01234567-0123-0123-0123-001122334455<0x0000> |
1478 | if ((cbBlob != 41) || (GET_UNALIGNED_VAL16(pBlob) != 1)) |
1479 | IfFailGo(E_INVALIDARG); |
1480 | |
1481 | WCHAR wzBlob[40]; // Wide char format of guid. |
1482 | for (ix=1; ix<=36; ++ix) |
1483 | wzBlob[ix] = pBlob[ix+2]; |
1484 | wzBlob[0] = '{'; |
1485 | wzBlob[37] = '}'; |
1486 | wzBlob[38] = 0; |
1487 | hr = IIDFromString(wzBlob, pGuid); |
1488 | } |
1489 | else |
1490 | *pGuid = GUID_NULL; |
1491 | |
1492 | ErrExit: |
1493 | return hr; |
1494 | } // MDInternalRO::GetItemGuid |
1495 | |
1496 | |
1497 | //***************************************************************************** |
1498 | // // get enclosing class of NestedClass |
1499 | //***************************************************************************** |
1500 | __checkReturn |
1501 | HRESULT MDInternalRO::GetNestedClassProps( // S_OK or error |
1502 | mdTypeDef tkNestedClass, // [IN] NestedClass token. |
1503 | mdTypeDef *ptkEnclosingClass) // [OUT] EnclosingClass token. |
1504 | { |
1505 | HRESULT hr; |
1506 | _ASSERTE(TypeFromToken(tkNestedClass) == mdtTypeDef && ptkEnclosingClass); |
1507 | |
1508 | RID rid; |
1509 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindNestedClassFor(RidFromToken(tkNestedClass), &rid)); |
1510 | |
1511 | if (InvalidRid(rid)) |
1512 | { |
1513 | return CLDB_E_RECORD_NOTFOUND; |
1514 | } |
1515 | else |
1516 | { |
1517 | NestedClassRec *pRecord; |
1518 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetNestedClassRecord(rid, &pRecord)); |
1519 | *ptkEnclosingClass = m_LiteWeightStgdb.m_MiniMd.getEnclosingClassOfNestedClass(pRecord); |
1520 | return S_OK; |
1521 | } |
1522 | } |
1523 | |
1524 | //******************************************************************************* |
1525 | // Get count of Nested classes given the enclosing class. |
1526 | //******************************************************************************* |
1527 | __checkReturn |
1528 | HRESULT |
1529 | MDInternalRO::GetCountNestedClasses( // return count of Nested classes. |
1530 | mdTypeDef tkEnclosingClass, // [IN]Enclosing class. |
1531 | ULONG *pcNestedClassesCount) |
1532 | { |
1533 | HRESULT hr; |
1534 | ULONG ulCount; |
1535 | ULONG ulRetCount = 0; |
1536 | NestedClassRec *pRecord; |
1537 | |
1538 | _ASSERTE(TypeFromToken(tkEnclosingClass) == mdtTypeDef && !IsNilToken(tkEnclosingClass)); |
1539 | |
1540 | *pcNestedClassesCount = 0; |
1541 | |
1542 | ulCount = m_LiteWeightStgdb.m_MiniMd.getCountNestedClasss(); |
1543 | |
1544 | for (ULONG i = 1; i <= ulCount; i++) |
1545 | { |
1546 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetNestedClassRecord(i, &pRecord)); |
1547 | if (tkEnclosingClass == m_LiteWeightStgdb.m_MiniMd.getEnclosingClassOfNestedClass(pRecord)) |
1548 | ulRetCount++; |
1549 | } |
1550 | *pcNestedClassesCount = ulRetCount; |
1551 | return S_OK; |
1552 | } // MDInternalRO::GetCountNestedClasses |
1553 | |
1554 | //******************************************************************************* |
1555 | // Return array of Nested classes given the enclosing class. |
1556 | //******************************************************************************* |
1557 | __checkReturn |
1558 | HRESULT |
1559 | MDInternalRO::GetNestedClasses( // Return actual count. |
1560 | mdTypeDef tkEnclosingClass, // [IN] Enclosing class. |
1561 | mdTypeDef *rNestedClasses, // [OUT] Array of nested class tokens. |
1562 | ULONG ulNestedClasses, // [IN] Size of array. |
1563 | ULONG *pcNestedClasses) |
1564 | { |
1565 | HRESULT hr; |
1566 | ULONG ulCount; |
1567 | ULONG ulRetCount = 0; |
1568 | NestedClassRec *pRecord; |
1569 | |
1570 | _ASSERTE(TypeFromToken(tkEnclosingClass) == mdtTypeDef && |
1571 | !IsNilToken(tkEnclosingClass)); |
1572 | |
1573 | *pcNestedClasses = 0; |
1574 | |
1575 | ulCount = m_LiteWeightStgdb.m_MiniMd.getCountNestedClasss(); |
1576 | |
1577 | for (ULONG i = 1; i <= ulCount; i++) |
1578 | { |
1579 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetNestedClassRecord(i, &pRecord)); |
1580 | if (tkEnclosingClass == m_LiteWeightStgdb.m_MiniMd.getEnclosingClassOfNestedClass(pRecord)) |
1581 | { |
1582 | if (ovadd_le(ulRetCount, 1, ulNestedClasses)) // ulRetCount is 0 based. |
1583 | rNestedClasses[ulRetCount] = m_LiteWeightStgdb.m_MiniMd.getNestedClassOfNestedClass(pRecord); |
1584 | ulRetCount++; |
1585 | } |
1586 | } |
1587 | *pcNestedClasses = ulRetCount; |
1588 | return S_OK; |
1589 | } // MDInternalRO::GetNestedClasses |
1590 | |
1591 | //******************************************************************************* |
1592 | // return the ModuleRef properties |
1593 | //******************************************************************************* |
1594 | __checkReturn |
1595 | HRESULT MDInternalRO::GetModuleRefProps( // return hresult |
1596 | mdModuleRef mur, // [IN] moduleref token |
1597 | LPCSTR *pszName) // [OUT] buffer to fill with the moduleref name |
1598 | { |
1599 | _ASSERTE(TypeFromToken(mur) == mdtModuleRef); |
1600 | _ASSERTE(pszName); |
1601 | |
1602 | HRESULT hr; |
1603 | |
1604 | // Is it a valid token? |
1605 | if (!IsValidToken(mur)) |
1606 | { |
1607 | *pszName = NULL; // Not every caller checks returned HRESULT, allow to fail fast in that case |
1608 | return COR_E_BADIMAGEFORMAT; // Invalid Token |
1609 | } |
1610 | |
1611 | ModuleRefRec *pModuleRefRec; |
1612 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetModuleRefRecord(RidFromToken(mur), &pModuleRefRec)); |
1613 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfModuleRef(pModuleRefRec, pszName)); |
1614 | |
1615 | return S_OK; |
1616 | } |
1617 | |
1618 | |
1619 | |
1620 | //***************************************************************************** |
1621 | // Given a scope and a methoddef, return a pointer to methoddef's signature |
1622 | //***************************************************************************** |
1623 | __checkReturn |
1624 | HRESULT |
1625 | MDInternalRO::GetSigOfMethodDef( |
1626 | mdMethodDef methoddef, // given a methoddef |
1627 | ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob |
1628 | PCCOR_SIGNATURE *ppSig) |
1629 | { |
1630 | // Output parameter should not be NULL |
1631 | _ASSERTE(pcbSigBlob); |
1632 | _ASSERTE(TypeFromToken(methoddef) == mdtMethodDef); |
1633 | |
1634 | HRESULT hr; |
1635 | MethodRec *pMethodRec; |
1636 | *ppSig = NULL; |
1637 | *pcbSigBlob = 0; |
1638 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(RidFromToken(methoddef), &pMethodRec)); |
1639 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getSignatureOfMethod(pMethodRec, ppSig, pcbSigBlob)); |
1640 | return S_OK; |
1641 | } // MDInternalRO::GetSigOfMethodDef |
1642 | |
1643 | |
1644 | //***************************************************************************** |
1645 | // Given a scope and a fielddef, return a pointer to fielddef's signature |
1646 | //***************************************************************************** |
1647 | __checkReturn |
1648 | HRESULT |
1649 | MDInternalRO::GetSigOfFieldDef( |
1650 | mdFieldDef fielddef, // given a methoddef |
1651 | ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob |
1652 | PCCOR_SIGNATURE *ppSig) |
1653 | { |
1654 | _ASSERTE(pcbSigBlob); |
1655 | _ASSERTE(TypeFromToken(fielddef) == mdtFieldDef); |
1656 | |
1657 | HRESULT hr; |
1658 | FieldRec *pFieldRec; |
1659 | *ppSig = NULL; |
1660 | *pcbSigBlob = 0; |
1661 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetFieldRecord(RidFromToken(fielddef), &pFieldRec)); |
1662 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getSignatureOfField(pFieldRec, ppSig, pcbSigBlob)); |
1663 | return S_OK; |
1664 | } // MDInternalRO::GetSigOfFieldDef |
1665 | |
1666 | //***************************************************************************** |
1667 | // Get signature for the token (FieldDef, MethodDef, Signature, or TypeSpec). |
1668 | //***************************************************************************** |
1669 | __checkReturn |
1670 | HRESULT |
1671 | MDInternalRO::GetSigFromToken( |
1672 | mdToken tk, |
1673 | ULONG * pcbSig, |
1674 | PCCOR_SIGNATURE * ppSig) |
1675 | { |
1676 | HRESULT hr; |
1677 | |
1678 | *ppSig = NULL; |
1679 | *pcbSig = 0; |
1680 | switch (TypeFromToken(tk)) |
1681 | { |
1682 | case mdtSignature: |
1683 | { |
1684 | StandAloneSigRec * pRec; |
1685 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetStandAloneSigRecord(RidFromToken(tk), &pRec)); |
1686 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getSignatureOfStandAloneSig(pRec, ppSig, pcbSig)); |
1687 | return S_OK; |
1688 | } |
1689 | case mdtTypeSpec: |
1690 | { |
1691 | TypeSpecRec * pRec; |
1692 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeSpecRecord(RidFromToken(tk), &pRec)); |
1693 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getSignatureOfTypeSpec(pRec, ppSig, pcbSig)); |
1694 | return S_OK; |
1695 | } |
1696 | case mdtMethodDef: |
1697 | { |
1698 | IfFailRet(GetSigOfMethodDef(tk, pcbSig, ppSig)); |
1699 | return S_OK; |
1700 | } |
1701 | case mdtFieldDef: |
1702 | { |
1703 | IfFailRet(GetSigOfFieldDef(tk, pcbSig, ppSig)); |
1704 | return S_OK; |
1705 | } |
1706 | } |
1707 | |
1708 | // not a known token type. |
1709 | *pcbSig = 0; |
1710 | return META_E_INVALID_TOKEN_TYPE; |
1711 | } // MDInternalRO::GetSigFromToken |
1712 | |
1713 | |
1714 | //***************************************************************************** |
1715 | // Given methoddef, return the flags |
1716 | //***************************************************************************** |
1717 | __checkReturn |
1718 | HRESULT |
1719 | MDInternalRO::GetMethodDefProps( |
1720 | mdMethodDef md, |
1721 | DWORD *pdwFlags) // return mdPublic, mdAbstract, etc |
1722 | { |
1723 | HRESULT hr; |
1724 | MethodRec *pMethodRec; |
1725 | |
1726 | *pdwFlags = (DWORD)-1; |
1727 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(RidFromToken(md), &pMethodRec)); |
1728 | *pdwFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfMethod(pMethodRec); |
1729 | |
1730 | return S_OK; |
1731 | } // MDInternalRO::GetMethodDefProps |
1732 | |
1733 | //***************************************************************************** |
1734 | // Given a scope and a methoddef/methodimpl, return RVA and impl flags |
1735 | //***************************************************************************** |
1736 | __checkReturn |
1737 | HRESULT MDInternalRO::GetMethodImplProps( |
1738 | mdMethodDef tk, // [IN] MethodDef |
1739 | ULONG *pulCodeRVA, // [OUT] CodeRVA |
1740 | DWORD *pdwImplFlags) // [OUT] Impl. Flags |
1741 | { |
1742 | HRESULT hr; |
1743 | _ASSERTE(TypeFromToken(tk) == mdtMethodDef); |
1744 | |
1745 | MethodRec *pMethodRec; |
1746 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(RidFromToken(tk), &pMethodRec)); |
1747 | |
1748 | if (pulCodeRVA) |
1749 | { |
1750 | *pulCodeRVA = m_LiteWeightStgdb.m_MiniMd.getRVAOfMethod(pMethodRec); |
1751 | } |
1752 | |
1753 | if (pdwImplFlags) |
1754 | { |
1755 | *pdwImplFlags = m_LiteWeightStgdb.m_MiniMd.getImplFlagsOfMethod(pMethodRec); |
1756 | } |
1757 | |
1758 | return S_OK; |
1759 | } // MDInternalRO::GetMethodImplProps |
1760 | |
1761 | |
1762 | //***************************************************************************** |
1763 | // return the field RVA |
1764 | //***************************************************************************** |
1765 | __checkReturn |
1766 | HRESULT MDInternalRO::GetFieldRVA( |
1767 | mdToken fd, // [IN] FieldDef |
1768 | ULONG *pulCodeRVA) // [OUT] CodeRVA |
1769 | { |
1770 | HRESULT hr; |
1771 | _ASSERTE(TypeFromToken(fd) == mdtFieldDef); |
1772 | _ASSERTE(pulCodeRVA); |
1773 | |
1774 | RID iRecord; |
1775 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindFieldRVAFor(RidFromToken(fd), &iRecord)); |
1776 | |
1777 | if (InvalidRid(iRecord)) |
1778 | { |
1779 | if (pulCodeRVA) |
1780 | *pulCodeRVA = 0; |
1781 | return CLDB_E_RECORD_NOTFOUND; |
1782 | } |
1783 | |
1784 | FieldRVARec *pFieldRVARec; |
1785 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetFieldRVARecord(iRecord, &pFieldRVARec)); |
1786 | |
1787 | *pulCodeRVA = m_LiteWeightStgdb.m_MiniMd.getRVAOfFieldRVA(pFieldRVARec); |
1788 | return NOERROR; |
1789 | } |
1790 | |
1791 | //***************************************************************************** |
1792 | // Given a fielddef, return the flags. Such as fdPublic, fdStatic, etc |
1793 | //***************************************************************************** |
1794 | __checkReturn |
1795 | HRESULT |
1796 | MDInternalRO::GetFieldDefProps( |
1797 | mdFieldDef fd, // given memberdef |
1798 | DWORD *pdwFlags) // [OUT] return fdPublic, fdPrive, etc flags |
1799 | { |
1800 | HRESULT hr; |
1801 | _ASSERTE(TypeFromToken(fd) == mdtFieldDef); |
1802 | |
1803 | FieldRec *pFieldRec; |
1804 | |
1805 | *pdwFlags = (DWORD)-1; |
1806 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetFieldRecord(RidFromToken(fd), &pFieldRec)); |
1807 | *pdwFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfField(pFieldRec); |
1808 | |
1809 | return S_OK; |
1810 | } // MDInternalRO::GetFieldDefProps |
1811 | |
1812 | //***************************************************************************** |
1813 | // return default value of a token(could be paramdef, fielddef, or property) |
1814 | //***************************************************************************** |
1815 | __checkReturn |
1816 | HRESULT MDInternalRO::GetDefaultValue( // return hresult |
1817 | mdToken tk, // [IN] given FieldDef, ParamDef, or Property |
1818 | MDDefaultValue *pMDDefaultValue) // [OUT] default value |
1819 | { |
1820 | _ASSERTE(pMDDefaultValue); |
1821 | |
1822 | HRESULT hr; |
1823 | BYTE bType; |
1824 | const VOID *pValue; |
1825 | ULONG cbValue; |
1826 | RID rid; |
1827 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindConstantFor(RidFromToken(tk), TypeFromToken(tk), &rid)); |
1828 | if (InvalidRid(rid)) |
1829 | { |
1830 | pMDDefaultValue->m_bType = ELEMENT_TYPE_VOID; |
1831 | return S_OK; |
1832 | } |
1833 | ConstantRec *pConstantRec; |
1834 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetConstantRecord(rid, &pConstantRec)); |
1835 | |
1836 | // get the type of constant value |
1837 | bType = m_LiteWeightStgdb.m_MiniMd.getTypeOfConstant(pConstantRec); |
1838 | |
1839 | // get the value blob |
1840 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getValueOfConstant(pConstantRec, reinterpret_cast<const BYTE **>(&pValue), &cbValue)); |
1841 | // convert it to our internal default value representation |
1842 | hr = _FillMDDefaultValue(bType, pValue, cbValue, pMDDefaultValue); |
1843 | return hr; |
1844 | } // MDInternalRO::GetDefaultValue |
1845 | |
1846 | //***************************************************************************** |
1847 | // Given a scope and a methoddef/fielddef, return the dispid |
1848 | //***************************************************************************** |
1849 | __checkReturn |
1850 | HRESULT MDInternalRO::GetDispIdOfMemberDef( // return hresult |
1851 | mdToken tk, // given methoddef or fielddef |
1852 | ULONG *pDispid) // Put the dispid here. |
1853 | { |
1854 | #ifdef FEATURE_COMINTEROP |
1855 | HRESULT hr; // A result. |
1856 | const BYTE *pBlob; // Blob with dispid. |
1857 | ULONG cbBlob; // Length of blob. |
1858 | UINT32 dispid; // temporary for dispid. |
1859 | |
1860 | // Get the DISPID, if any. |
1861 | _ASSERTE(pDispid); |
1862 | |
1863 | *pDispid = DISPID_UNKNOWN; |
1864 | hr = GetCustomAttributeByName(tk, INTEROP_DISPID_TYPE, (const void**)&pBlob, &cbBlob); |
1865 | if (hr == S_OK) |
1866 | { |
1867 | CustomAttributeParser cap(pBlob, cbBlob); |
1868 | IfFailGo(cap.SkipProlog()); |
1869 | IfFailGo(cap.GetU4(&dispid)); |
1870 | *pDispid = dispid; |
1871 | } |
1872 | |
1873 | ErrExit: |
1874 | return hr; |
1875 | #else // FEATURE_COMINTEROP |
1876 | _ASSERTE(false); |
1877 | return E_NOTIMPL; |
1878 | #endif // FEATURE_COMINTEROP |
1879 | } // MDInternalRO::GetDispIdOfMemberDef |
1880 | |
1881 | //***************************************************************************** |
1882 | // Given interfaceimpl, return the TypeRef/TypeDef and flags |
1883 | //***************************************************************************** |
1884 | __checkReturn |
1885 | HRESULT |
1886 | MDInternalRO::GetTypeOfInterfaceImpl( // return hresult |
1887 | mdInterfaceImpl iiImpl, // given a interfaceimpl |
1888 | mdToken *ptkType) |
1889 | { |
1890 | HRESULT hr; |
1891 | _ASSERTE(TypeFromToken(iiImpl) == mdtInterfaceImpl); |
1892 | |
1893 | *ptkType = mdTypeDefNil; |
1894 | |
1895 | InterfaceImplRec *pIIRec; |
1896 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetInterfaceImplRecord(RidFromToken(iiImpl), &pIIRec)); |
1897 | *ptkType = m_LiteWeightStgdb.m_MiniMd.getInterfaceOfInterfaceImpl(pIIRec); |
1898 | return S_OK; |
1899 | } // MDInternalRO::GetTypeOfInterfaceImpl |
1900 | |
1901 | //***************************************************************************** |
1902 | // This routine gets the properties for the given MethodSpec token. |
1903 | //***************************************************************************** |
1904 | __checkReturn |
1905 | HRESULT MDInternalRO::GetMethodSpecProps( // S_OK or error. |
1906 | mdMethodSpec mi, // [IN] The method instantiation |
1907 | mdToken *tkParent, // [OUT] MethodDef or MemberRef |
1908 | PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data |
1909 | ULONG *pcbSigBlob) // [OUT] actual size of signature blob |
1910 | { |
1911 | HRESULT hr = NOERROR; |
1912 | MethodSpecRec *pMethodSpecRec; |
1913 | |
1914 | LOG((LOGMD, "MD RegMeta::GetMethodSpecProps(0x%08x, 0x%08x, 0x%08x, 0x%08x)\n" , |
1915 | mi, tkParent, ppvSigBlob, pcbSigBlob)); |
1916 | |
1917 | _ASSERTE(TypeFromToken(mi) == mdtMethodSpec); |
1918 | |
1919 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSpecRecord(RidFromToken(mi), &pMethodSpecRec)); |
1920 | |
1921 | if (tkParent) |
1922 | *tkParent = m_LiteWeightStgdb.m_MiniMd.getMethodOfMethodSpec(pMethodSpecRec); |
1923 | |
1924 | if (ppvSigBlob || pcbSigBlob) |
1925 | { |
1926 | // caller wants signature information |
1927 | PCCOR_SIGNATURE pvSigTmp; |
1928 | ULONG cbSig; |
1929 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getInstantiationOfMethodSpec(pMethodSpecRec, &pvSigTmp, &cbSig)); |
1930 | if ( ppvSigBlob ) |
1931 | *ppvSigBlob = pvSigTmp; |
1932 | if ( pcbSigBlob) |
1933 | *pcbSigBlob = cbSig; |
1934 | } |
1935 | |
1936 | |
1937 | return hr; |
1938 | } // MDInternalRO::GetMethodSpecProps |
1939 | |
1940 | |
1941 | |
1942 | //***************************************************************************** |
1943 | // Given a classname, return the typedef |
1944 | //***************************************************************************** |
1945 | __checkReturn |
1946 | HRESULT |
1947 | MDInternalRO::FindTypeDef( |
1948 | LPCSTR szTypeDefNamespace, // [IN] Namespace for the TypeDef. |
1949 | LPCSTR szTypeDefName, // [IN] Name of the TypeDef. |
1950 | mdToken tkEnclosingClass, // [IN] TypeDef/TypeRef of enclosing class. |
1951 | mdTypeDef * ptkTypeDef) // [OUT] return typedef |
1952 | { |
1953 | HRESULT hr = S_OK; |
1954 | |
1955 | _ASSERTE((szTypeDefName != NULL) && (ptkTypeDef != NULL)); |
1956 | _ASSERTE((TypeFromToken(tkEnclosingClass) == mdtTypeRef) || |
1957 | (TypeFromToken(tkEnclosingClass) == mdtTypeDef) || |
1958 | IsNilToken(tkEnclosingClass)); |
1959 | |
1960 | // initialize the output parameter |
1961 | *ptkTypeDef = mdTypeDefNil; |
1962 | |
1963 | // Treat no namespace as empty string. |
1964 | if (szTypeDefNamespace == NULL) |
1965 | szTypeDefNamespace = "" ; |
1966 | |
1967 | // Do a linear search |
1968 | ULONG cTypeDefRecs = m_LiteWeightStgdb.m_MiniMd.getCountTypeDefs(); |
1969 | TypeDefRec * pTypeDefRec; |
1970 | LPCUTF8 szName; |
1971 | LPCUTF8 szNamespace; |
1972 | DWORD dwFlags; |
1973 | |
1974 | // Get TypeDef of the tkEnclosingClass passed in |
1975 | if (TypeFromToken(tkEnclosingClass) == mdtTypeRef) |
1976 | { |
1977 | TypeRefRec * pTypeRefRec; |
1978 | mdToken tkResolutionScope; |
1979 | |
1980 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeRefRecord(RidFromToken(tkEnclosingClass), &pTypeRefRec)); |
1981 | tkResolutionScope = m_LiteWeightStgdb.m_MiniMd.getResolutionScopeOfTypeRef(pTypeRefRec); |
1982 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNamespaceOfTypeRef(pTypeRefRec, &szNamespace)); |
1983 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfTypeRef(pTypeRefRec, &szName)); |
1984 | |
1985 | // Update tkEnclosingClass to TypeDef |
1986 | IfFailRet(FindTypeDef( |
1987 | szNamespace, |
1988 | szName, |
1989 | (TypeFromToken(tkResolutionScope) == mdtTypeRef) ? tkResolutionScope : mdTokenNil, |
1990 | &tkEnclosingClass)); |
1991 | _ASSERTE(TypeFromToken(tkEnclosingClass) == mdtTypeDef); |
1992 | } |
1993 | |
1994 | // Search for the TypeDef |
1995 | for (ULONG i = 1; i <= cTypeDefRecs; i++) |
1996 | { |
1997 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeDefRecord(i, &pTypeDefRec)); |
1998 | |
1999 | dwFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfTypeDef(pTypeDefRec); |
2000 | |
2001 | if (!IsTdNested(dwFlags) && !IsNilToken(tkEnclosingClass)) |
2002 | { |
2003 | // If the class is not Nested and EnclosingClass passed in is not nil |
2004 | continue; |
2005 | } |
2006 | else if (IsTdNested(dwFlags) && IsNilToken(tkEnclosingClass)) |
2007 | { |
2008 | // If the class is nested and EnclosingClass passed is nil |
2009 | continue; |
2010 | } |
2011 | else if (!IsNilToken(tkEnclosingClass)) |
2012 | { |
2013 | _ASSERTE(TypeFromToken(tkEnclosingClass) == mdtTypeDef); |
2014 | |
2015 | RID iNestedClassRec; |
2016 | NestedClassRec * pNestedClassRec; |
2017 | mdTypeDef tkEnclosingClassTmp; |
2018 | |
2019 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindNestedClassFor(i, &iNestedClassRec)); |
2020 | if (InvalidRid(iNestedClassRec)) |
2021 | continue; |
2022 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetNestedClassRecord(iNestedClassRec, &pNestedClassRec)); |
2023 | tkEnclosingClassTmp = m_LiteWeightStgdb.m_MiniMd.getEnclosingClassOfNestedClass(pNestedClassRec); |
2024 | if (tkEnclosingClass != tkEnclosingClassTmp) |
2025 | continue; |
2026 | } |
2027 | |
2028 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfTypeDef(pTypeDefRec, &szName)); |
2029 | if (strcmp(szTypeDefName, szName) == 0) |
2030 | { |
2031 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNamespaceOfTypeDef(pTypeDefRec, &szNamespace)); |
2032 | if (strcmp(szTypeDefNamespace, szNamespace) == 0) |
2033 | { |
2034 | *ptkTypeDef = TokenFromRid(i, mdtTypeDef); |
2035 | return S_OK; |
2036 | } |
2037 | } |
2038 | } |
2039 | // Cannot find the TypeDef by name |
2040 | return CLDB_E_RECORD_NOTFOUND; |
2041 | } // MDInternalRO::FindTypeDef |
2042 | |
2043 | //***************************************************************************** |
2044 | // Given a memberref, return a pointer to memberref's name and signature |
2045 | //***************************************************************************** |
2046 | // Warning: Even when the return value is ok, *ppvSigBlob could be NULL if |
2047 | // the metadata is corrupted! (e.g. if CPackedLen::GetLength returned -1). |
2048 | // TODO: consider returning a HRESULT to make errors evident to the caller. |
2049 | //***************************************************************************** |
2050 | __checkReturn |
2051 | HRESULT |
2052 | MDInternalRO::GetNameAndSigOfMemberRef( // meberref's name |
2053 | mdMemberRef memberref, // given a memberref |
2054 | PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to a blob value of COM+ signature |
2055 | ULONG *pcbSigBlob, // [OUT] count of bytes in the signature blob |
2056 | LPCSTR *pszMemberRefName) |
2057 | { |
2058 | _ASSERTE(TypeFromToken(memberref) == mdtMemberRef); |
2059 | |
2060 | HRESULT hr; |
2061 | MemberRefRec *pMemberRefRec; |
2062 | *pszMemberRefName = NULL; |
2063 | if (ppvSigBlob != NULL) |
2064 | { |
2065 | _ASSERTE(pcbSigBlob != NULL); |
2066 | *ppvSigBlob = NULL; |
2067 | *pcbSigBlob = 0; |
2068 | } |
2069 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMemberRefRecord(RidFromToken(memberref), &pMemberRefRec)); |
2070 | if (ppvSigBlob != NULL) |
2071 | { |
2072 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getSignatureOfMemberRef(pMemberRefRec, ppvSigBlob, pcbSigBlob)); |
2073 | } |
2074 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfMemberRef(pMemberRefRec, pszMemberRefName)); |
2075 | return S_OK; |
2076 | } // MDInternalRO::GetNameAndSigOfMemberRef |
2077 | |
2078 | //***************************************************************************** |
2079 | // Given a memberref, return parent token. It can be a TypeRef, ModuleRef, or a MethodDef |
2080 | //***************************************************************************** |
2081 | __checkReturn |
2082 | HRESULT |
2083 | MDInternalRO::GetParentOfMemberRef( |
2084 | mdMemberRef memberref, // given a typedef |
2085 | mdToken *ptkParent) // return the parent token |
2086 | { |
2087 | HRESULT hr; |
2088 | _ASSERTE(TypeFromToken(memberref) == mdtMemberRef); |
2089 | |
2090 | MemberRefRec *pMemberRefRec; |
2091 | |
2092 | *ptkParent = mdTokenNil; |
2093 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMemberRefRecord(RidFromToken(memberref), &pMemberRefRec)); |
2094 | *ptkParent = m_LiteWeightStgdb.m_MiniMd.getClassOfMemberRef(pMemberRefRec); |
2095 | |
2096 | return S_OK; |
2097 | } // MDInternalRO::GetParentOfMemberRef |
2098 | |
2099 | //***************************************************************************** |
2100 | // return properties of a paramdef |
2101 | //*****************************************************************************/ |
2102 | __checkReturn |
2103 | HRESULT |
2104 | MDInternalRO::GetParamDefProps ( |
2105 | mdParamDef paramdef, // given a paramdef |
2106 | USHORT *pusSequence, // [OUT] slot number for this parameter |
2107 | DWORD *pdwAttr, // [OUT] flags |
2108 | LPCSTR *pszName) // [OUT] return the name of the parameter |
2109 | { |
2110 | _ASSERTE(TypeFromToken(paramdef) == mdtParamDef); |
2111 | HRESULT hr; |
2112 | ParamRec *pParamRec; |
2113 | |
2114 | *pszName = NULL; |
2115 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetParamRecord(RidFromToken(paramdef), &pParamRec)); |
2116 | if (pdwAttr != NULL) |
2117 | { |
2118 | *pdwAttr = m_LiteWeightStgdb.m_MiniMd.getFlagsOfParam(pParamRec); |
2119 | } |
2120 | if (pusSequence != NULL) |
2121 | { |
2122 | *pusSequence = m_LiteWeightStgdb.m_MiniMd.getSequenceOfParam(pParamRec); |
2123 | } |
2124 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfParam(pParamRec, pszName)); |
2125 | |
2126 | return S_OK; |
2127 | } // MDInternalRO::GetParamDefProps |
2128 | |
2129 | //***************************************************************************** |
2130 | // Get property info for the method. |
2131 | //***************************************************************************** |
2132 | int MDInternalRO::CMethodSemanticsMapSearcher::Compare( |
2133 | const CMethodSemanticsMap *psFirst, |
2134 | const CMethodSemanticsMap *psSecond) |
2135 | { |
2136 | if (psFirst->m_mdMethod < psSecond->m_mdMethod) |
2137 | return -1; |
2138 | if (psFirst->m_mdMethod > psSecond->m_mdMethod) |
2139 | return 1; |
2140 | return 0; |
2141 | } // MDInternalRO::CMethodSemanticsMapSearcher::Compare |
2142 | |
2143 | #ifndef DACCESS_COMPILE |
2144 | int MDInternalRO::CMethodSemanticsMapSorter::Compare( |
2145 | CMethodSemanticsMap *psFirst, |
2146 | CMethodSemanticsMap *psSecond) |
2147 | { |
2148 | if (psFirst->m_mdMethod < psSecond->m_mdMethod) |
2149 | return -1; |
2150 | if (psFirst->m_mdMethod > psSecond->m_mdMethod) |
2151 | return 1; |
2152 | return 0; |
2153 | } // MDInternalRO::CMethodSemanticsMapSorter::Compare |
2154 | |
2155 | __checkReturn |
2156 | HRESULT MDInternalRO::GetPropertyInfoForMethodDef( // Result. |
2157 | mdMethodDef md, // [IN] memberdef |
2158 | mdProperty *ppd, // [OUT] put property token here |
2159 | LPCSTR *pName, // [OUT] put pointer to name here |
2160 | ULONG *pSemantic) // [OUT] put semantic here |
2161 | { |
2162 | HRESULT hr; |
2163 | MethodSemanticsRec *pSemantics; // A MethodSemantics record. |
2164 | MethodSemanticsRec *pFound=0; // A MethodSemantics record that is a property for the desired function. |
2165 | RID ridCur; // loop control. |
2166 | RID ridMax; // Count of entries in table. |
2167 | USHORT usSemantics = 0; // A method's semantics. |
2168 | mdToken tk; // A method def. |
2169 | |
2170 | ridMax = m_LiteWeightStgdb.m_MiniMd.getCountMethodSemantics(); |
2171 | |
2172 | // Lazy initialization of m_pMethodSemanticsMap |
2173 | if ((ridMax > 10) && (m_pMethodSemanticsMap == NULL)) |
2174 | { |
2175 | NewHolder<CMethodSemanticsMap> pMethodSemanticsMap = new (nothrow) CMethodSemanticsMap[ridMax]; |
2176 | if (pMethodSemanticsMap != NULL) |
2177 | { |
2178 | // Fill the table in MethodSemantics order. |
2179 | for (ridCur = 1; ridCur <= ridMax; ridCur++) |
2180 | { |
2181 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSemanticsRecord(ridCur, &pSemantics)); |
2182 | tk = m_LiteWeightStgdb.m_MiniMd.getMethodOfMethodSemantics(pSemantics); |
2183 | pMethodSemanticsMap[ridCur-1].m_mdMethod = tk; |
2184 | pMethodSemanticsMap[ridCur-1].m_ridSemantics = ridCur; |
2185 | } |
2186 | // Sort to MethodDef order. |
2187 | CMethodSemanticsMapSorter sorter(pMethodSemanticsMap, ridMax); |
2188 | sorter.Sort(); |
2189 | |
2190 | if (InterlockedCompareExchangeT<CMethodSemanticsMap *>( |
2191 | &m_pMethodSemanticsMap, pMethodSemanticsMap, NULL) == NULL) |
2192 | { // The exchange did happen, supress of the allocated map |
2193 | pMethodSemanticsMap.SuppressRelease(); |
2194 | } |
2195 | } |
2196 | } |
2197 | |
2198 | // Use m_pMethodSemanticsMap if it has been built. |
2199 | if (m_pMethodSemanticsMap != NULL) |
2200 | { |
2201 | CMethodSemanticsMapSearcher searcher(m_pMethodSemanticsMap, ridMax); |
2202 | CMethodSemanticsMap target; |
2203 | const CMethodSemanticsMap * pMatchedMethod; |
2204 | target.m_mdMethod = md; |
2205 | pMatchedMethod = searcher.Find(&target); |
2206 | |
2207 | // Was there at least one match? |
2208 | if (pMatchedMethod != NULL) |
2209 | { |
2210 | _ASSERTE(pMatchedMethod >= m_pMethodSemanticsMap); |
2211 | _ASSERTE(pMatchedMethod < m_pMethodSemanticsMap+ridMax); |
2212 | _ASSERTE(pMatchedMethod->m_mdMethod == md); |
2213 | |
2214 | ridCur = pMatchedMethod->m_ridSemantics; |
2215 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSemanticsRecord(ridCur, &pSemantics)); |
2216 | usSemantics = m_LiteWeightStgdb.m_MiniMd.getSemanticOfMethodSemantics(pSemantics); |
2217 | |
2218 | // If the semantics record is a getter or setter for the method, that's what we want. |
2219 | if (usSemantics == msGetter || usSemantics == msSetter) |
2220 | pFound = pSemantics; |
2221 | else |
2222 | { // The semantics record was neither getter or setter. Because there can be |
2223 | // multiple semantics records for a given method, look for other semantics |
2224 | // records that match this record. |
2225 | const CMethodSemanticsMap *pScan; |
2226 | const CMethodSemanticsMap *pLo=m_pMethodSemanticsMap; |
2227 | const CMethodSemanticsMap *pHi=pLo+ridMax-1; |
2228 | for (pScan = pMatchedMethod-1; pScan >= pLo; --pScan) |
2229 | { |
2230 | if (pScan->m_mdMethod == md) |
2231 | { |
2232 | ridCur = pScan->m_ridSemantics; |
2233 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSemanticsRecord(ridCur, &pSemantics)); |
2234 | usSemantics = m_LiteWeightStgdb.m_MiniMd.getSemanticOfMethodSemantics(pSemantics); |
2235 | |
2236 | if (usSemantics == msGetter || usSemantics == msSetter) |
2237 | { |
2238 | pFound = pSemantics; |
2239 | break; |
2240 | } |
2241 | } |
2242 | else |
2243 | break; |
2244 | } |
2245 | |
2246 | if (pFound == 0) |
2247 | { // Not found looking down, try looking up. |
2248 | for (pScan = pMatchedMethod+1; pScan <= pHi; ++pScan) |
2249 | { |
2250 | if (pScan->m_mdMethod == md) |
2251 | { |
2252 | ridCur = pScan->m_ridSemantics; |
2253 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSemanticsRecord(ridCur, &pSemantics)); |
2254 | usSemantics = m_LiteWeightStgdb.m_MiniMd.getSemanticOfMethodSemantics(pSemantics); |
2255 | |
2256 | if (usSemantics == msGetter || usSemantics == msSetter) |
2257 | { |
2258 | pFound = pSemantics; |
2259 | break; |
2260 | } |
2261 | } |
2262 | else |
2263 | break; |
2264 | } |
2265 | |
2266 | } |
2267 | } |
2268 | } |
2269 | } |
2270 | else |
2271 | { // Scan entire table. |
2272 | for (ridCur = 1; ridCur <= ridMax; ridCur++) |
2273 | { |
2274 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSemanticsRecord(ridCur, &pSemantics)); |
2275 | if (md == m_LiteWeightStgdb.m_MiniMd.getMethodOfMethodSemantics(pSemantics)) |
2276 | { // The method matched, is this a property? |
2277 | usSemantics = m_LiteWeightStgdb.m_MiniMd.getSemanticOfMethodSemantics(pSemantics); |
2278 | if (usSemantics == msGetter || usSemantics == msSetter) |
2279 | { // found a match. |
2280 | pFound = pSemantics; |
2281 | break; |
2282 | } |
2283 | } |
2284 | } |
2285 | } |
2286 | |
2287 | // Did the search find anything? |
2288 | if (pFound) |
2289 | { // found a match. Fill out the output parameters |
2290 | PropertyRec *pProperty; |
2291 | mdProperty prop; |
2292 | prop = m_LiteWeightStgdb.m_MiniMd.getAssociationOfMethodSemantics(pFound); |
2293 | |
2294 | if (ppd) |
2295 | *ppd = prop; |
2296 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetPropertyRecord(RidFromToken(prop), &pProperty)); |
2297 | |
2298 | if (pName != NULL) |
2299 | { |
2300 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfProperty(pProperty, pName)); |
2301 | } |
2302 | |
2303 | if (pSemantic) |
2304 | *pSemantic = usSemantics; |
2305 | return S_OK; |
2306 | } |
2307 | return S_FALSE; |
2308 | } // MDInternalRO::GetPropertyInfoForMethodDef |
2309 | #endif //!DACCESS_COMPILE |
2310 | |
2311 | //***************************************************************************** |
2312 | // return the pack size of a class |
2313 | //***************************************************************************** |
2314 | __checkReturn |
2315 | HRESULT MDInternalRO::GetClassPackSize( |
2316 | mdTypeDef td, // [IN] give typedef |
2317 | DWORD *pdwPackSize) // [OUT] |
2318 | { |
2319 | HRESULT hr = NOERROR; |
2320 | |
2321 | _ASSERTE(TypeFromToken(td) == mdtTypeDef && pdwPackSize); |
2322 | |
2323 | ClassLayoutRec *pRec; |
2324 | RID ridClassLayout; |
2325 | |
2326 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindClassLayoutFor(RidFromToken(td), &ridClassLayout)); |
2327 | if (InvalidRid(ridClassLayout)) |
2328 | { |
2329 | hr = CLDB_E_RECORD_NOTFOUND; |
2330 | goto ErrExit; |
2331 | } |
2332 | |
2333 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetClassLayoutRecord(RidFromToken(ridClassLayout), &pRec)); |
2334 | *pdwPackSize = m_LiteWeightStgdb.m_MiniMd.getPackingSizeOfClassLayout(pRec); |
2335 | ErrExit: |
2336 | return hr; |
2337 | } // MDInternalRO::GetClassPackSize |
2338 | |
2339 | |
2340 | //***************************************************************************** |
2341 | // return the total size of a value class |
2342 | //***************************************************************************** |
2343 | __checkReturn |
2344 | HRESULT MDInternalRO::GetClassTotalSize( // return error if a class does not have total size info |
2345 | mdTypeDef td, // [IN] give typedef |
2346 | ULONG *pulClassSize) // [OUT] return the total size of the class |
2347 | { |
2348 | _ASSERTE(TypeFromToken(td) == mdtTypeDef && pulClassSize); |
2349 | |
2350 | ClassLayoutRec *pRec; |
2351 | HRESULT hr = NOERROR; |
2352 | RID ridClassLayout; |
2353 | |
2354 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindClassLayoutFor(RidFromToken(td), &ridClassLayout)); |
2355 | if (InvalidRid(ridClassLayout)) |
2356 | { |
2357 | hr = CLDB_E_RECORD_NOTFOUND; |
2358 | goto ErrExit; |
2359 | } |
2360 | |
2361 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetClassLayoutRecord(RidFromToken(ridClassLayout), &pRec)); |
2362 | *pulClassSize = m_LiteWeightStgdb.m_MiniMd.getClassSizeOfClassLayout(pRec); |
2363 | ErrExit: |
2364 | return hr; |
2365 | } // MDInternalRO::GetClassTotalSize |
2366 | |
2367 | |
2368 | //***************************************************************************** |
2369 | // init the layout enumerator of a class |
2370 | //***************************************************************************** |
2371 | __checkReturn |
2372 | HRESULT MDInternalRO::GetClassLayoutInit( |
2373 | mdTypeDef td, // [IN] give typedef |
2374 | MD_CLASS_LAYOUT *pmdLayout) // [OUT] set up the status of query here |
2375 | { |
2376 | HRESULT hr = NOERROR; |
2377 | _ASSERTE(TypeFromToken(td) == mdtTypeDef); |
2378 | |
2379 | // initialize the output parameter |
2380 | _ASSERTE(pmdLayout); |
2381 | memset(pmdLayout, 0, sizeof(MD_CLASS_LAYOUT)); |
2382 | |
2383 | TypeDefRec *pTypeDefRec; |
2384 | |
2385 | // record for this typedef in TypeDef Table |
2386 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeDefRecord(RidFromToken(td), &pTypeDefRec)); |
2387 | |
2388 | // find the starting and end field for this typedef |
2389 | pmdLayout->m_ridFieldCur = m_LiteWeightStgdb.m_MiniMd.getFieldListOfTypeDef(pTypeDefRec); |
2390 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getEndFieldListOfTypeDef(RidFromToken(td), &(pmdLayout->m_ridFieldEnd))); |
2391 | return hr; |
2392 | } // MDInternalRO::GetClassLayoutInit |
2393 | |
2394 | |
2395 | //***************************************************************************** |
2396 | // return the field offset for a given field |
2397 | //***************************************************************************** |
2398 | __checkReturn |
2399 | HRESULT MDInternalRO::GetFieldOffset( |
2400 | mdFieldDef fd, // [IN] fielddef |
2401 | ULONG *pulOffset) // [OUT] FieldOffset |
2402 | { |
2403 | HRESULT hr = S_OK; |
2404 | FieldLayoutRec *pRec; |
2405 | |
2406 | _ASSERTE(pulOffset); |
2407 | |
2408 | RID iLayout; |
2409 | |
2410 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindFieldLayoutFor(RidFromToken(fd), &iLayout)); |
2411 | |
2412 | if (InvalidRid(iLayout)) |
2413 | { |
2414 | hr = S_FALSE; |
2415 | goto ErrExit; |
2416 | } |
2417 | |
2418 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetFieldLayoutRecord(iLayout, &pRec)); |
2419 | *pulOffset = m_LiteWeightStgdb.m_MiniMd.getOffSetOfFieldLayout(pRec); |
2420 | _ASSERTE(*pulOffset != ULONG_MAX); |
2421 | |
2422 | ErrExit: |
2423 | return hr; |
2424 | } |
2425 | |
2426 | |
2427 | //***************************************************************************** |
2428 | // enum the next the field layout |
2429 | //***************************************************************************** |
2430 | __checkReturn |
2431 | HRESULT MDInternalRO::GetClassLayoutNext( |
2432 | MD_CLASS_LAYOUT *pLayout, // [IN|OUT] set up the status of query here |
2433 | mdFieldDef *pfd, // [OUT] field def |
2434 | ULONG *pulOffset) // [OUT] field offset or sequence |
2435 | { |
2436 | HRESULT hr = S_OK; |
2437 | |
2438 | _ASSERTE(pfd && pulOffset && pLayout); |
2439 | |
2440 | RID iLayout2; |
2441 | FieldLayoutRec *pRec; |
2442 | |
2443 | // Make sure no one is messing with pLayout->m_ridFieldLayoutCur, since this doesn't |
2444 | // mean anything if we are using FieldLayout table. |
2445 | while (pLayout->m_ridFieldCur < pLayout->m_ridFieldEnd) |
2446 | { |
2447 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindFieldLayoutFor(pLayout->m_ridFieldCur, &iLayout2)); |
2448 | pLayout->m_ridFieldCur++; |
2449 | if (!InvalidRid(iLayout2)) |
2450 | { |
2451 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetFieldLayoutRecord(iLayout2, &pRec)); |
2452 | *pulOffset = m_LiteWeightStgdb.m_MiniMd.getOffSetOfFieldLayout(pRec); |
2453 | _ASSERTE(*pulOffset != ULONG_MAX); |
2454 | *pfd = TokenFromRid(pLayout->m_ridFieldCur - 1, mdtFieldDef); |
2455 | goto ErrExit; |
2456 | } |
2457 | } |
2458 | |
2459 | *pfd = mdFieldDefNil; |
2460 | hr = S_FALSE; |
2461 | |
2462 | // fall through |
2463 | |
2464 | ErrExit: |
2465 | return hr; |
2466 | } // MDInternalRO::GetClassLayoutNext |
2467 | |
2468 | |
2469 | //***************************************************************************** |
2470 | // return the field's native type signature |
2471 | //***************************************************************************** |
2472 | __checkReturn |
2473 | HRESULT MDInternalRO::GetFieldMarshal( // return error if no native type associate with the token |
2474 | mdToken tk, // [IN] given fielddef or paramdef |
2475 | PCCOR_SIGNATURE *pSigNativeType, // [OUT] the native type signature |
2476 | ULONG *pcbNativeType) // [OUT] the count of bytes of *ppvNativeType |
2477 | { |
2478 | // output parameters have to be supplied |
2479 | _ASSERTE(pcbNativeType); |
2480 | |
2481 | RID rid; |
2482 | FieldMarshalRec *pFieldMarshalRec; |
2483 | HRESULT hr = NOERROR; |
2484 | |
2485 | // find the row containing the marshal definition for tk |
2486 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindFieldMarshalFor(RidFromToken(tk), TypeFromToken(tk), &rid)); |
2487 | if (InvalidRid(rid)) |
2488 | { |
2489 | *pSigNativeType = NULL; |
2490 | *pcbNativeType = 0; |
2491 | hr = CLDB_E_RECORD_NOTFOUND; |
2492 | goto ErrExit; |
2493 | } |
2494 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetFieldMarshalRecord(rid, &pFieldMarshalRec)); |
2495 | |
2496 | // get the native type |
2497 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNativeTypeOfFieldMarshal(pFieldMarshalRec, pSigNativeType, pcbNativeType)); |
2498 | ErrExit: |
2499 | return hr; |
2500 | } // MDInternalRO::GetFieldMarshal |
2501 | |
2502 | |
2503 | |
2504 | //***************************************** |
2505 | // property APIs |
2506 | //***************************************** |
2507 | |
2508 | //***************************************************************************** |
2509 | // Find property by name |
2510 | //***************************************************************************** |
2511 | __checkReturn |
2512 | HRESULT MDInternalRO::FindProperty( |
2513 | mdTypeDef td, // [IN] given a typdef |
2514 | LPCSTR szPropName, // [IN] property name |
2515 | mdProperty *pProp) // [OUT] return property token |
2516 | { |
2517 | HRESULT hr = NOERROR; |
2518 | |
2519 | // output parameters have to be supplied |
2520 | _ASSERTE(TypeFromToken(td) == mdtTypeDef && pProp); |
2521 | |
2522 | PropertyMapRec *pRec; |
2523 | PropertyRec *pProperty; |
2524 | RID ridPropertyMap; |
2525 | RID ridCur; |
2526 | RID ridEnd; |
2527 | LPCUTF8 szName; |
2528 | |
2529 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindPropertyMapFor(RidFromToken(td), &ridPropertyMap)); |
2530 | if (InvalidRid(ridPropertyMap)) |
2531 | { |
2532 | // not found! |
2533 | hr = CLDB_E_RECORD_NOTFOUND; |
2534 | goto ErrExit; |
2535 | } |
2536 | |
2537 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetPropertyMapRecord(ridPropertyMap, &pRec)); |
2538 | |
2539 | // get the starting/ending rid of properties of this typedef |
2540 | ridCur = m_LiteWeightStgdb.m_MiniMd.getPropertyListOfPropertyMap(pRec); |
2541 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndPropertyListOfPropertyMap(ridPropertyMap, &ridEnd)); |
2542 | |
2543 | for (; ridCur < ridEnd; ridCur ++) |
2544 | { |
2545 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetPropertyRecord(ridCur, &pProperty)); |
2546 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNameOfProperty(pProperty, &szName)); |
2547 | if (strcmp(szName, szPropName) ==0) |
2548 | { |
2549 | // Found the match. Set the output parameter and we are done. |
2550 | *pProp = TokenFromRid(ridCur, mdtProperty); |
2551 | goto ErrExit; |
2552 | } |
2553 | } |
2554 | |
2555 | // not found |
2556 | hr = CLDB_E_RECORD_NOTFOUND; |
2557 | ErrExit: |
2558 | return hr; |
2559 | |
2560 | } // MDInternalRO::FindProperty |
2561 | |
2562 | |
2563 | |
2564 | //***************************************************************************** |
2565 | // return the properties of a property |
2566 | //***************************************************************************** |
2567 | __checkReturn |
2568 | HRESULT MDInternalRO::GetPropertyProps( |
2569 | mdProperty prop, // [IN] property token |
2570 | LPCSTR *pszProperty, // [OUT] property name |
2571 | DWORD *pdwPropFlags, // [OUT] property flags. |
2572 | PCCOR_SIGNATURE *ppvSig, // [OUT] property type. pointing to meta data internal blob |
2573 | ULONG *pcbSig) // [OUT] count of bytes in *ppvSig |
2574 | { |
2575 | // output parameters have to be supplied |
2576 | _ASSERTE(TypeFromToken(prop) == mdtProperty); |
2577 | |
2578 | HRESULT hr; |
2579 | |
2580 | PropertyRec *pProperty; |
2581 | ULONG cbSig; |
2582 | |
2583 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetPropertyRecord(RidFromToken(prop), &pProperty)); |
2584 | |
2585 | // get name of the property |
2586 | if (pszProperty != NULL) |
2587 | { |
2588 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfProperty(pProperty, pszProperty)); |
2589 | } |
2590 | |
2591 | // get the flags of property |
2592 | if (pdwPropFlags) |
2593 | *pdwPropFlags = m_LiteWeightStgdb.m_MiniMd.getPropFlagsOfProperty(pProperty); |
2594 | |
2595 | // get the type of the property |
2596 | if (ppvSig != NULL) |
2597 | { |
2598 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getTypeOfProperty(pProperty, ppvSig, &cbSig)); |
2599 | if (pcbSig != NULL) |
2600 | { |
2601 | *pcbSig = cbSig; |
2602 | } |
2603 | } |
2604 | |
2605 | return S_OK; |
2606 | } // MDInternalRO::GetPropertyProps |
2607 | |
2608 | |
2609 | //********************************** |
2610 | // |
2611 | // Event APIs |
2612 | // |
2613 | //********************************** |
2614 | |
2615 | //***************************************************************************** |
2616 | // return an event by given the name |
2617 | //***************************************************************************** |
2618 | __checkReturn |
2619 | HRESULT MDInternalRO::FindEvent( |
2620 | mdTypeDef td, // [IN] given a typdef |
2621 | LPCSTR szEventName, // [IN] event name |
2622 | mdEvent *pEvent) // [OUT] return event token |
2623 | { |
2624 | HRESULT hr = NOERROR; |
2625 | |
2626 | // output parameters have to be supplied |
2627 | _ASSERTE(TypeFromToken(td) == mdtTypeDef && pEvent); |
2628 | |
2629 | EventMapRec *pRec; |
2630 | EventRec *pEventRec; |
2631 | RID ridEventMap; |
2632 | RID ridCur; |
2633 | RID ridEnd; |
2634 | LPCUTF8 szName; |
2635 | |
2636 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.FindEventMapFor(RidFromToken(td), &ridEventMap)); |
2637 | if (InvalidRid(ridEventMap)) |
2638 | { |
2639 | // not found! |
2640 | hr = CLDB_E_RECORD_NOTFOUND; |
2641 | goto ErrExit; |
2642 | } |
2643 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetEventMapRecord(ridEventMap, &pRec)); |
2644 | |
2645 | // get the starting/ending rid of properties of this typedef |
2646 | ridCur = m_LiteWeightStgdb.m_MiniMd.getEventListOfEventMap(pRec); |
2647 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getEndEventListOfEventMap(ridEventMap, &ridEnd)); |
2648 | |
2649 | for (; ridCur < ridEnd; ridCur ++) |
2650 | { |
2651 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetEventRecord(ridCur, &pEventRec)); |
2652 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNameOfEvent(pEventRec, &szName)); |
2653 | if (strcmp(szName, szEventName) ==0) |
2654 | { |
2655 | // Found the match. Set the output parameter and we are done. |
2656 | *pEvent = TokenFromRid(ridCur, mdtEvent); |
2657 | goto ErrExit; |
2658 | } |
2659 | } |
2660 | |
2661 | // not found |
2662 | hr = CLDB_E_RECORD_NOTFOUND; |
2663 | ErrExit: |
2664 | return hr; |
2665 | } // MDInternalRO::FindEvent |
2666 | |
2667 | |
2668 | //***************************************************************************** |
2669 | // return the properties of an event |
2670 | //***************************************************************************** |
2671 | __checkReturn |
2672 | HRESULT MDInternalRO::GetEventProps( // S_OK, S_FALSE, or error. |
2673 | mdEvent ev, // [IN] event token |
2674 | LPCSTR *pszEvent, // [OUT] Event name |
2675 | DWORD *pdwEventFlags, // [OUT] Event flags. |
2676 | mdToken *ptkEventType) // [OUT] EventType class |
2677 | { |
2678 | // output parameters have to be supplied |
2679 | _ASSERTE(TypeFromToken(ev) == mdtEvent); |
2680 | |
2681 | HRESULT hr; |
2682 | EventRec *pEvent; |
2683 | |
2684 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetEventRecord(RidFromToken(ev), &pEvent)); |
2685 | if (pszEvent != NULL) |
2686 | { |
2687 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfEvent(pEvent, pszEvent)); |
2688 | } |
2689 | if (pdwEventFlags) |
2690 | *pdwEventFlags = m_LiteWeightStgdb.m_MiniMd.getEventFlagsOfEvent(pEvent); |
2691 | if (ptkEventType) |
2692 | *ptkEventType = m_LiteWeightStgdb.m_MiniMd.getEventTypeOfEvent(pEvent); |
2693 | |
2694 | return S_OK; |
2695 | } // MDInternalRO::GetEventProps |
2696 | |
2697 | //***************************************************************************** |
2698 | // return the properties of a generic param |
2699 | //***************************************************************************** |
2700 | __checkReturn |
2701 | HRESULT MDInternalRO::GetGenericParamProps( // S_OK or error. |
2702 | mdGenericParam rd, // [IN] The type parameter |
2703 | ULONG* pulSequence, // [OUT] Parameter sequence number |
2704 | DWORD* pdwAttr, // [OUT] Type parameter flags (for future use) |
2705 | mdToken *ptOwner, // [OUT] The owner (TypeDef or MethodDef) |
2706 | DWORD *reserved, // [OUT] The kind (TypeDef/Ref/Spec, for future use) |
2707 | LPCSTR *szName) // [OUT] The name |
2708 | { |
2709 | HRESULT hr = NOERROR; |
2710 | GenericParamRec * pGenericParamRec = NULL; |
2711 | |
2712 | // See if this version of the metadata can do Generics |
2713 | if (!m_LiteWeightStgdb.m_MiniMd.SupportsGenerics()) |
2714 | IfFailGo(CLDB_E_INCOMPATIBLE); |
2715 | |
2716 | _ASSERTE(TypeFromToken(rd) == mdtGenericParam); |
2717 | if (TypeFromToken(rd) != mdtGenericParam) |
2718 | { |
2719 | IfFailGo(CLDB_E_FILE_CORRUPT); |
2720 | } |
2721 | |
2722 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetGenericParamRecord(RidFromToken(rd), &pGenericParamRec)); |
2723 | |
2724 | if (pulSequence) |
2725 | *pulSequence = m_LiteWeightStgdb.m_MiniMd.getNumberOfGenericParam(pGenericParamRec); |
2726 | if (pdwAttr) |
2727 | *pdwAttr = m_LiteWeightStgdb.m_MiniMd.getFlagsOfGenericParam(pGenericParamRec); |
2728 | if (ptOwner) |
2729 | *ptOwner = m_LiteWeightStgdb.m_MiniMd.getOwnerOfGenericParam(pGenericParamRec); |
2730 | if (szName != NULL) |
2731 | { |
2732 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getNameOfGenericParam(pGenericParamRec, szName)); |
2733 | } |
2734 | ErrExit: |
2735 | return hr; |
2736 | } // MDInternalRO::GetGenericParamProps |
2737 | |
2738 | //***************************************************************************** |
2739 | // This routine gets the properties for the given GenericParamConstraint token. |
2740 | //***************************************************************************** |
2741 | __checkReturn |
2742 | HRESULT MDInternalRO::GetGenericParamConstraintProps( // S_OK or error. |
2743 | mdGenericParamConstraint rd, // [IN] The constraint token |
2744 | mdGenericParam *ptGenericParam, // [OUT] GenericParam that is constrained |
2745 | mdToken *ptkConstraintType) // [OUT] TypeDef/Ref/Spec constraint |
2746 | { |
2747 | HRESULT hr = NOERROR; |
2748 | GenericParamConstraintRec *pGPCRec; |
2749 | RID ridRD = RidFromToken(rd); |
2750 | |
2751 | // See if this version of the metadata can do Generics |
2752 | if (!m_LiteWeightStgdb.m_MiniMd.SupportsGenerics()) |
2753 | IfFailGo(CLDB_E_INCOMPATIBLE); |
2754 | |
2755 | if((TypeFromToken(rd) == mdtGenericParamConstraint) && (ridRD != 0)) |
2756 | { |
2757 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetGenericParamConstraintRecord(ridRD, &pGPCRec)); |
2758 | |
2759 | if (ptGenericParam) |
2760 | *ptGenericParam = TokenFromRid(m_LiteWeightStgdb.m_MiniMd.getOwnerOfGenericParamConstraint(pGPCRec),mdtGenericParam); |
2761 | if (ptkConstraintType) |
2762 | *ptkConstraintType = m_LiteWeightStgdb.m_MiniMd.getConstraintOfGenericParamConstraint(pGPCRec); |
2763 | } |
2764 | else |
2765 | hr = META_E_BAD_INPUT_PARAMETER; |
2766 | |
2767 | ErrExit: |
2768 | return hr; |
2769 | } // MDInternalRO::GetGenericParamConstraintProps |
2770 | |
2771 | //***************************************************************************** |
2772 | // Find methoddef of a particular associate with a property or an event |
2773 | //***************************************************************************** |
2774 | __checkReturn |
2775 | HRESULT MDInternalRO::FindAssociate( |
2776 | mdToken evprop, // [IN] given a property or event token |
2777 | DWORD dwSemantics, // [IN] given a associate semantics(setter, getter, testdefault, reset) |
2778 | mdMethodDef *pmd) // [OUT] return method def token |
2779 | { |
2780 | HRESULT hr = NOERROR; |
2781 | |
2782 | // output parameters have to be supplied |
2783 | _ASSERTE(pmd); |
2784 | _ASSERTE(TypeFromToken(evprop) == mdtEvent || TypeFromToken(evprop) == mdtProperty); |
2785 | |
2786 | MethodSemanticsRec *pSemantics; |
2787 | RID ridCur; |
2788 | RID ridEnd; |
2789 | |
2790 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.getAssociatesForToken(evprop, &ridEnd, &ridCur)); |
2791 | for (; ridCur < ridEnd; ridCur++) |
2792 | { |
2793 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetMethodSemanticsRecord(ridCur, &pSemantics)); |
2794 | if (dwSemantics == m_LiteWeightStgdb.m_MiniMd.getSemanticOfMethodSemantics(pSemantics)) |
2795 | { |
2796 | // found a match |
2797 | *pmd = m_LiteWeightStgdb.m_MiniMd.getMethodOfMethodSemantics(pSemantics); |
2798 | goto ErrExit; |
2799 | } |
2800 | } |
2801 | |
2802 | // not found |
2803 | hr = CLDB_E_RECORD_NOTFOUND; |
2804 | ErrExit: |
2805 | return hr; |
2806 | } // MDInternalRO::FindAssociate |
2807 | |
2808 | |
2809 | //***************************************************************************** |
2810 | // get counts of methodsemantics associated with a particular property/event |
2811 | //***************************************************************************** |
2812 | __checkReturn |
2813 | HRESULT MDInternalRO::EnumAssociateInit( |
2814 | mdToken evprop, // [IN] given a property or an event token |
2815 | HENUMInternal *phEnum) // [OUT] cursor to hold the query result |
2816 | { |
2817 | HRESULT hr; |
2818 | _ASSERTE(phEnum); |
2819 | |
2820 | memset(phEnum, 0, sizeof(HENUMInternal)); |
2821 | |
2822 | // There is no token kind!!! |
2823 | phEnum->m_tkKind = ULONG_MAX; |
2824 | |
2825 | // output parameters have to be supplied |
2826 | _ASSERTE(TypeFromToken(evprop) == mdtEvent || TypeFromToken(evprop) == mdtProperty); |
2827 | |
2828 | phEnum->m_EnumType = MDSimpleEnum; |
2829 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getAssociatesForToken(evprop, &phEnum->u.m_ulEnd, &phEnum->u.m_ulStart)); |
2830 | phEnum->u.m_ulCur = phEnum->u.m_ulStart; |
2831 | phEnum->m_ulCount = phEnum->u.m_ulEnd - phEnum->u.m_ulStart; |
2832 | |
2833 | return S_OK; |
2834 | } // MDInternalRO::EnumAssociateInit |
2835 | |
2836 | |
2837 | //***************************************************************************** |
2838 | // get all methodsemantics associated with a particular property/event |
2839 | //***************************************************************************** |
2840 | __checkReturn |
2841 | HRESULT MDInternalRO::GetAllAssociates( |
2842 | HENUMInternal *phEnum, // [OUT] cursor to hold the query result |
2843 | ASSOCIATE_RECORD *pAssociateRec, // [OUT] struct to fill for output |
2844 | ULONG cAssociateRec) // [IN] size of the buffer |
2845 | { |
2846 | _ASSERTE(phEnum && pAssociateRec); |
2847 | |
2848 | HRESULT hr; |
2849 | MethodSemanticsRec *pSemantics; |
2850 | RID ridCur; |
2851 | _ASSERTE(cAssociateRec == phEnum->m_ulCount); |
2852 | |
2853 | // Convert from row pointers to RIDs. |
2854 | for (ridCur = phEnum->u.m_ulStart; ridCur < phEnum->u.m_ulEnd; ++ridCur) |
2855 | { |
2856 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetMethodSemanticsRecord(ridCur, &pSemantics)); |
2857 | |
2858 | pAssociateRec[ridCur-phEnum->u.m_ulStart].m_memberdef = m_LiteWeightStgdb.m_MiniMd.getMethodOfMethodSemantics(pSemantics); |
2859 | pAssociateRec[ridCur-phEnum->u.m_ulStart].m_dwSemantics = m_LiteWeightStgdb.m_MiniMd.getSemanticOfMethodSemantics(pSemantics); |
2860 | } |
2861 | |
2862 | return S_OK; |
2863 | } // MDInternalRO::GetAllAssociates |
2864 | |
2865 | |
2866 | //***************************************************************************** |
2867 | // Get the Action and Permissions blob for a given PermissionSet. |
2868 | //***************************************************************************** |
2869 | __checkReturn |
2870 | HRESULT MDInternalRO::GetPermissionSetProps( |
2871 | mdPermission pm, // [IN] the permission token. |
2872 | DWORD *pdwAction, // [OUT] CorDeclSecurity. |
2873 | void const **ppvPermission, // [OUT] permission blob. |
2874 | ULONG *pcbPermission) // [OUT] count of bytes of pvPermission. |
2875 | { |
2876 | HRESULT hr; |
2877 | _ASSERTE(TypeFromToken(pm) == mdtPermission); |
2878 | _ASSERTE(pdwAction && ppvPermission && pcbPermission); |
2879 | |
2880 | DeclSecurityRec *pPerm; |
2881 | |
2882 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetDeclSecurityRecord(RidFromToken(pm), &pPerm)); |
2883 | *pdwAction = m_LiteWeightStgdb.m_MiniMd.getActionOfDeclSecurity(pPerm); |
2884 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getPermissionSetOfDeclSecurity(pPerm, (const BYTE **)ppvPermission, pcbPermission)); |
2885 | |
2886 | return S_OK; |
2887 | } // MDInternalRO::GetPermissionSetProps |
2888 | |
2889 | //***************************************************************************** |
2890 | // Get the String given the String token. |
2891 | // Return a pointer to the string, or NULL in case of error. |
2892 | //***************************************************************************** |
2893 | __checkReturn |
2894 | HRESULT |
2895 | MDInternalRO::GetUserString( // Offset into the string blob heap. |
2896 | mdString stk, // [IN] the string token. |
2897 | ULONG *pcchStringSize, // [OUT] count of characters in the string. |
2898 | BOOL *pfIs80Plus, // [OUT] specifies where there are extended characters >= 0x80. |
2899 | LPCWSTR *pwszUserString) |
2900 | { |
2901 | HRESULT hr; |
2902 | LPWSTR wszTmp; |
2903 | |
2904 | if (pfIs80Plus != NULL) |
2905 | { |
2906 | *pfIs80Plus = FALSE; |
2907 | } |
2908 | *pwszUserString = NULL; |
2909 | *pcchStringSize = 0; |
2910 | |
2911 | _ASSERTE(pcchStringSize != NULL); |
2912 | MetaData::DataBlob userString; |
2913 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetUserString(RidFromToken(stk), &userString)); |
2914 | |
2915 | wszTmp = reinterpret_cast<LPWSTR>(userString.GetDataPointer()); |
2916 | |
2917 | *pcchStringSize = userString.GetSize() / sizeof(WCHAR); |
2918 | |
2919 | if (userString.IsEmpty()) |
2920 | { |
2921 | *pwszUserString = NULL; |
2922 | return S_OK; |
2923 | } |
2924 | |
2925 | if (pfIs80Plus != NULL) |
2926 | { |
2927 | if (userString.GetSize() % sizeof(WCHAR) == 0) |
2928 | { |
2929 | *pfIs80Plus = TRUE; // no indicator, presume the worst |
2930 | } |
2931 | // Return the user string terminator (contains value fIs80Plus) |
2932 | *pfIs80Plus = *(reinterpret_cast<PBYTE>(wszTmp + *pcchStringSize)); |
2933 | } |
2934 | |
2935 | *pwszUserString = wszTmp; |
2936 | return S_OK; |
2937 | } // MDInternalRO::GetUserString |
2938 | |
2939 | //***************************************************************************** |
2940 | // Return contents of Pinvoke given the forwarded member token. |
2941 | //***************************************************************************** |
2942 | __checkReturn |
2943 | HRESULT MDInternalRO::GetPinvokeMap( |
2944 | mdToken tk, // [IN] FieldDef or MethodDef. |
2945 | DWORD *pdwMappingFlags, // [OUT] Flags used for mapping. |
2946 | LPCSTR *pszImportName, // [OUT] Import name. |
2947 | mdModuleRef *pmrImportDLL) // [OUT] ModuleRef token for the target DLL. |
2948 | { |
2949 | HRESULT hr; |
2950 | ImplMapRec *pRecord; |
2951 | RID iRecord; |
2952 | |
2953 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.FindImplMapFor(RidFromToken(tk), TypeFromToken(tk), &iRecord)); |
2954 | if (InvalidRid(iRecord)) |
2955 | { |
2956 | return CLDB_E_RECORD_NOTFOUND; |
2957 | } |
2958 | else |
2959 | { |
2960 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetImplMapRecord(iRecord, &pRecord)); |
2961 | } |
2962 | |
2963 | if (pdwMappingFlags) |
2964 | *pdwMappingFlags = m_LiteWeightStgdb.m_MiniMd.getMappingFlagsOfImplMap(pRecord); |
2965 | if (pszImportName != NULL) |
2966 | { |
2967 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getImportNameOfImplMap(pRecord, pszImportName)); |
2968 | } |
2969 | if (pmrImportDLL) |
2970 | *pmrImportDLL = m_LiteWeightStgdb.m_MiniMd.getImportScopeOfImplMap(pRecord); |
2971 | |
2972 | return S_OK; |
2973 | } // MDInternalRO::GetPinvokeMap |
2974 | |
2975 | //***************************************************************************** |
2976 | // Get the properties for the given Assembly token. |
2977 | //***************************************************************************** |
2978 | __checkReturn |
2979 | HRESULT MDInternalRO::GetAssemblyProps( |
2980 | mdAssembly mda, // [IN] The Assembly for which to get the properties. |
2981 | const void **ppbPublicKey, // [OUT] Pointer to the public key. |
2982 | ULONG *pcbPublicKey, // [OUT] Count of bytes in the public key. |
2983 | ULONG *pulHashAlgId, // [OUT] Hash Algorithm. |
2984 | LPCSTR *pszName, // [OUT] Buffer to fill with name. |
2985 | AssemblyMetaDataInternal *pMetaData,// [OUT] Assembly MetaData. |
2986 | DWORD *pdwAssemblyFlags) // [OUT] Flags. |
2987 | { |
2988 | HRESULT hr; |
2989 | AssemblyRec *pRecord; |
2990 | |
2991 | _ASSERTE(TypeFromToken(mda) == mdtAssembly && RidFromToken(mda)); |
2992 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetAssemblyRecord(RidFromToken(mda), &pRecord)); |
2993 | |
2994 | if (ppbPublicKey != NULL) |
2995 | { |
2996 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getPublicKeyOfAssembly(pRecord, reinterpret_cast<const BYTE **>(ppbPublicKey), pcbPublicKey)); |
2997 | } |
2998 | if (pulHashAlgId) |
2999 | *pulHashAlgId = m_LiteWeightStgdb.m_MiniMd.getHashAlgIdOfAssembly(pRecord); |
3000 | if (pszName != NULL) |
3001 | { |
3002 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfAssembly(pRecord, pszName)); |
3003 | } |
3004 | if (pMetaData) |
3005 | { |
3006 | pMetaData->usMajorVersion = m_LiteWeightStgdb.m_MiniMd.getMajorVersionOfAssembly(pRecord); |
3007 | pMetaData->usMinorVersion = m_LiteWeightStgdb.m_MiniMd.getMinorVersionOfAssembly(pRecord); |
3008 | pMetaData->usBuildNumber = m_LiteWeightStgdb.m_MiniMd.getBuildNumberOfAssembly(pRecord); |
3009 | pMetaData->usRevisionNumber = m_LiteWeightStgdb.m_MiniMd.getRevisionNumberOfAssembly(pRecord); |
3010 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getLocaleOfAssembly(pRecord, &pMetaData->szLocale)); |
3011 | pMetaData->ulProcessor = 0; |
3012 | pMetaData->ulOS = 0; |
3013 | } |
3014 | if (pdwAssemblyFlags) |
3015 | { |
3016 | *pdwAssemblyFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfAssembly(pRecord); |
3017 | |
3018 | #ifdef FEATURE_WINDOWSPHONE |
3019 | // Turn on the afPublicKey if PublicKey blob is not empty |
3020 | DWORD cbPublicKey; |
3021 | const BYTE *pbPublicKey; |
3022 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getPublicKeyOfAssembly(pRecord, &pbPublicKey, &cbPublicKey)); |
3023 | if (cbPublicKey != 0) |
3024 | *pdwAssemblyFlags |= afPublicKey; |
3025 | #else |
3026 | if (ppbPublicKey) |
3027 | { |
3028 | if (pcbPublicKey && *pcbPublicKey) |
3029 | *pdwAssemblyFlags |= afPublicKey; |
3030 | } |
3031 | else |
3032 | { |
3033 | #ifdef _DEBUG |
3034 | // Assert that afPublicKey is set if PublicKey blob is not empty |
3035 | DWORD cbPublicKey; |
3036 | const BYTE *pPublicKey; |
3037 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getPublicKeyOfAssembly(pRecord, &pPublicKey, &cbPublicKey)); |
3038 | bool hasPublicKey = cbPublicKey != 0; |
3039 | bool hasPublicKeyFlag = ( *pdwAssemblyFlags & afPublicKey ) != 0; |
3040 | if(REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_AssertOnBadImageFormat, 0)) |
3041 | _ASSERTE( hasPublicKey == hasPublicKeyFlag ); |
3042 | #endif |
3043 | } |
3044 | #endif // FEATURE_WINDOWSPHONE |
3045 | } |
3046 | |
3047 | return S_OK; |
3048 | } // MDInternalRO::GetAssemblyProps |
3049 | |
3050 | //***************************************************************************** |
3051 | // Get the properties for the given AssemblyRef token. |
3052 | //***************************************************************************** |
3053 | __checkReturn |
3054 | HRESULT MDInternalRO::GetAssemblyRefProps( |
3055 | mdAssemblyRef mdar, // [IN] The AssemblyRef for which to get the properties. |
3056 | const void **ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token. |
3057 | ULONG *pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or token. |
3058 | LPCSTR *pszName, // [OUT] Buffer to fill with name. |
3059 | AssemblyMetaDataInternal *pMetaData,// [OUT] Assembly MetaData. |
3060 | const void **ppbHashValue, // [OUT] Hash blob. |
3061 | ULONG *pcbHashValue, // [OUT] Count of bytes in the hash blob. |
3062 | DWORD *pdwAssemblyRefFlags) // [OUT] Flags. |
3063 | { |
3064 | HRESULT hr; |
3065 | AssemblyRefRec *pRecord; |
3066 | |
3067 | _ASSERTE(TypeFromToken(mdar) == mdtAssemblyRef && RidFromToken(mdar)); |
3068 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetAssemblyRefRecord(RidFromToken(mdar), &pRecord)); |
3069 | |
3070 | if (ppbPublicKeyOrToken != NULL) |
3071 | { |
3072 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getPublicKeyOrTokenOfAssemblyRef(pRecord, reinterpret_cast<const BYTE **>(ppbPublicKeyOrToken), pcbPublicKeyOrToken)); |
3073 | } |
3074 | if (pszName != NULL) |
3075 | { |
3076 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfAssemblyRef(pRecord, pszName)); |
3077 | } |
3078 | if (pMetaData) |
3079 | { |
3080 | pMetaData->usMajorVersion = m_LiteWeightStgdb.m_MiniMd.getMajorVersionOfAssemblyRef(pRecord); |
3081 | pMetaData->usMinorVersion = m_LiteWeightStgdb.m_MiniMd.getMinorVersionOfAssemblyRef(pRecord); |
3082 | pMetaData->usBuildNumber = m_LiteWeightStgdb.m_MiniMd.getBuildNumberOfAssemblyRef(pRecord); |
3083 | pMetaData->usRevisionNumber = m_LiteWeightStgdb.m_MiniMd.getRevisionNumberOfAssemblyRef(pRecord); |
3084 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getLocaleOfAssemblyRef(pRecord, &pMetaData->szLocale)); |
3085 | pMetaData->ulProcessor = 0; |
3086 | pMetaData->ulOS = 0; |
3087 | } |
3088 | if (ppbHashValue != NULL) |
3089 | { |
3090 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getHashValueOfAssemblyRef(pRecord, reinterpret_cast<const BYTE **>(ppbHashValue), pcbHashValue)); |
3091 | } |
3092 | if (pdwAssemblyRefFlags != NULL) |
3093 | { |
3094 | *pdwAssemblyRefFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfAssemblyRef(pRecord); |
3095 | } |
3096 | |
3097 | return S_OK; |
3098 | } // MDInternalRO::GetAssemblyRefProps |
3099 | |
3100 | //***************************************************************************** |
3101 | // Get the properties for the given File token. |
3102 | //***************************************************************************** |
3103 | __checkReturn |
3104 | HRESULT MDInternalRO::GetFileProps( |
3105 | mdFile mdf, // [IN] The File for which to get the properties. |
3106 | LPCSTR *pszName, // [OUT] Buffer to fill with name. |
3107 | const void **ppbHashValue, // [OUT] Pointer to the Hash Value Blob. |
3108 | ULONG *pcbHashValue, // [OUT] Count of bytes in the Hash Value Blob. |
3109 | DWORD *pdwFileFlags) // [OUT] Flags. |
3110 | { |
3111 | HRESULT hr; |
3112 | FileRec *pRecord; |
3113 | |
3114 | _ASSERTE(TypeFromToken(mdf) == mdtFile && RidFromToken(mdf)); |
3115 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetFileRecord(RidFromToken(mdf), &pRecord)); |
3116 | |
3117 | if (pszName != NULL) |
3118 | { |
3119 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfFile(pRecord, pszName)); |
3120 | } |
3121 | if (ppbHashValue != NULL) |
3122 | { |
3123 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getHashValueOfFile(pRecord, reinterpret_cast<const BYTE **>(ppbHashValue), pcbHashValue)); |
3124 | } |
3125 | if (pdwFileFlags != NULL) |
3126 | { |
3127 | *pdwFileFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfFile(pRecord); |
3128 | } |
3129 | |
3130 | return S_OK; |
3131 | } // MDInternalRO::GetFileProps |
3132 | |
3133 | //***************************************************************************** |
3134 | // Get the properties for the given ExportedType token. |
3135 | //***************************************************************************** |
3136 | __checkReturn |
3137 | HRESULT MDInternalRO::GetExportedTypeProps( |
3138 | mdExportedType mdct, // [IN] The ExportedType for which to get the properties. |
3139 | LPCSTR *pszNamespace, // [OUT] Buffer to fill with namespace. |
3140 | LPCSTR *pszName, // [OUT] Buffer to fill with name. |
3141 | mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ExportedType. |
3142 | mdTypeDef *ptkTypeDef, // [OUT] TypeDef token within the file. |
3143 | DWORD *pdwExportedTypeFlags) // [OUT] Flags. |
3144 | { |
3145 | HRESULT hr; |
3146 | ExportedTypeRec *pRecord; |
3147 | |
3148 | _ASSERTE(TypeFromToken(mdct) == mdtExportedType && RidFromToken(mdct)); |
3149 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetExportedTypeRecord(RidFromToken(mdct), &pRecord)); |
3150 | |
3151 | if (pszNamespace != NULL) |
3152 | { |
3153 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getTypeNamespaceOfExportedType(pRecord, pszNamespace)); |
3154 | } |
3155 | if (pszName != NULL) |
3156 | { |
3157 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getTypeNameOfExportedType(pRecord, pszName)); |
3158 | } |
3159 | if (ptkImplementation) |
3160 | *ptkImplementation = m_LiteWeightStgdb.m_MiniMd.getImplementationOfExportedType(pRecord); |
3161 | if (ptkTypeDef) |
3162 | *ptkTypeDef = m_LiteWeightStgdb.m_MiniMd.getTypeDefIdOfExportedType(pRecord); |
3163 | if (pdwExportedTypeFlags) |
3164 | *pdwExportedTypeFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfExportedType(pRecord); |
3165 | |
3166 | return S_OK; |
3167 | } // MDInternalRO::GetExportedTypeProps |
3168 | |
3169 | //***************************************************************************** |
3170 | // Get the properties for the given Resource token. |
3171 | //***************************************************************************** |
3172 | __checkReturn |
3173 | HRESULT MDInternalRO::GetManifestResourceProps( |
3174 | mdManifestResource mdmr, // [IN] The ManifestResource for which to get the properties. |
3175 | LPCSTR *pszName, // [OUT] Buffer to fill with name. |
3176 | mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides the ExportedType. |
3177 | DWORD *pdwOffset, // [OUT] Offset to the beginning of the resource within the file. |
3178 | DWORD *pdwResourceFlags) // [OUT] Flags. |
3179 | { |
3180 | HRESULT hr; |
3181 | ManifestResourceRec *pRecord; |
3182 | |
3183 | _ASSERTE(TypeFromToken(mdmr) == mdtManifestResource && RidFromToken(mdmr)); |
3184 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetManifestResourceRecord(RidFromToken(mdmr), &pRecord)); |
3185 | |
3186 | if (pszName != NULL) |
3187 | { |
3188 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfManifestResource(pRecord, pszName)); |
3189 | } |
3190 | if (ptkImplementation) |
3191 | *ptkImplementation = m_LiteWeightStgdb.m_MiniMd.getImplementationOfManifestResource(pRecord); |
3192 | if (pdwOffset) |
3193 | *pdwOffset = m_LiteWeightStgdb.m_MiniMd.getOffsetOfManifestResource(pRecord); |
3194 | if (pdwResourceFlags) |
3195 | *pdwResourceFlags = m_LiteWeightStgdb.m_MiniMd.getFlagsOfManifestResource(pRecord); |
3196 | |
3197 | return S_OK; |
3198 | } // MDInternalRO::GetManifestResourceProps |
3199 | |
3200 | //***************************************************************************** |
3201 | // Find the ExportedType given the name. |
3202 | //***************************************************************************** |
3203 | __checkReturn |
3204 | STDMETHODIMP MDInternalRO::FindExportedTypeByName( // S_OK or error |
3205 | LPCSTR szNamespace, // [IN] Namespace of the ExportedType. |
3206 | LPCSTR szName, // [IN] Name of the ExportedType. |
3207 | mdExportedType tkEnclosingType, // [IN] Token for the Enclosing Type. |
3208 | mdExportedType *pmct) // [OUT] Put ExportedType token here. |
3209 | { |
3210 | IMetaModelCommon *pCommon = static_cast<IMetaModelCommon*>(&m_LiteWeightStgdb.m_MiniMd); |
3211 | return pCommon->CommonFindExportedType(szNamespace, szName, tkEnclosingType, pmct); |
3212 | } // MDInternalRO::FindExportedTypeByName |
3213 | |
3214 | //***************************************************************************** |
3215 | // Find the ManifestResource given the name. |
3216 | //***************************************************************************** |
3217 | __checkReturn |
3218 | STDMETHODIMP MDInternalRO::FindManifestResourceByName( // S_OK or error |
3219 | LPCSTR szName, // [IN] Name of the resource. |
3220 | mdManifestResource *pmmr) // [OUT] Put ManifestResource token here. |
3221 | { |
3222 | _ASSERTE(szName && pmmr); |
3223 | |
3224 | HRESULT hr; |
3225 | ManifestResourceRec *pRecord; |
3226 | ULONG cRecords; // Count of records. |
3227 | LPCUTF8 szNameTmp = 0; // Name obtained from the database. |
3228 | ULONG i; |
3229 | |
3230 | cRecords = m_LiteWeightStgdb.m_MiniMd.getCountManifestResources(); |
3231 | |
3232 | // Search for the ExportedType. |
3233 | for (i = 1; i <= cRecords; i++) |
3234 | { |
3235 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetManifestResourceRecord(i, &pRecord)); |
3236 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getNameOfManifestResource(pRecord, &szNameTmp)); |
3237 | if (! strcmp(szName, szNameTmp)) |
3238 | { |
3239 | *pmmr = TokenFromRid(i, mdtManifestResource); |
3240 | return S_OK; |
3241 | } |
3242 | } |
3243 | return CLDB_E_RECORD_NOTFOUND; |
3244 | } // MDInternalRO::FindManifestResourceByName |
3245 | |
3246 | //***************************************************************************** |
3247 | // Get the Assembly token from the given scope. |
3248 | //***************************************************************************** |
3249 | __checkReturn |
3250 | HRESULT MDInternalRO::GetAssemblyFromScope( // S_OK or error |
3251 | mdAssembly *ptkAssembly) // [OUT] Put token here. |
3252 | { |
3253 | _ASSERTE(ptkAssembly); |
3254 | |
3255 | if (m_LiteWeightStgdb.m_MiniMd.getCountAssemblys()) |
3256 | { |
3257 | *ptkAssembly = TokenFromRid(1, mdtAssembly); |
3258 | return S_OK; |
3259 | } |
3260 | else |
3261 | return CLDB_E_RECORD_NOTFOUND; |
3262 | } // MDInternalRO::GetAssemblyFromScope |
3263 | |
3264 | //******************************************************************************* |
3265 | // return properties regarding a TypeSpec |
3266 | //******************************************************************************* |
3267 | __checkReturn |
3268 | HRESULT MDInternalRO::GetTypeSpecFromToken( // S_OK or error. |
3269 | mdTypeSpec typespec, // [IN] Signature token. |
3270 | PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to token. |
3271 | ULONG *pcbSig) // [OUT] return size of signature. |
3272 | { |
3273 | HRESULT hr = NOERROR; |
3274 | |
3275 | _ASSERTE(TypeFromToken(typespec) == mdtTypeSpec); |
3276 | _ASSERTE(ppvSig && pcbSig); |
3277 | |
3278 | if (!IsValidToken(typespec)) |
3279 | { |
3280 | *ppvSig = NULL; |
3281 | *pcbSig = 0; |
3282 | return E_INVALIDARG; |
3283 | } |
3284 | |
3285 | TypeSpecRec *pRec; |
3286 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.GetTypeSpecRecord(RidFromToken(typespec), &pRec)); |
3287 | |
3288 | if (pRec == NULL) |
3289 | { |
3290 | *ppvSig = NULL; |
3291 | *pcbSig = 0; |
3292 | return CLDB_E_FILE_CORRUPT; |
3293 | } |
3294 | |
3295 | IfFailRet(m_LiteWeightStgdb.m_MiniMd.getSignatureOfTypeSpec(pRec, ppvSig, pcbSig)); |
3296 | |
3297 | return hr; |
3298 | } // MDInternalRO::GetTypeSpecFromToken |
3299 | |
3300 | //***************************************************************************** |
3301 | // This function gets the "built for" version of a metadata scope. |
3302 | // NOTE: if the scope has never been saved, it will not have a built-for |
3303 | // version, and an empty string will be returned. |
3304 | //***************************************************************************** |
3305 | __checkReturn |
3306 | HRESULT MDInternalRO::GetVersionString( |
3307 | LPCSTR * pVer) // [OUT] Put version string here. |
3308 | { |
3309 | HRESULT hr = NOERROR; |
3310 | |
3311 | if (m_LiteWeightStgdb.m_pvMd != NULL) |
3312 | { |
3313 | // For convenience, get a pointer to the version string. |
3314 | // @todo: get from alternate locations when there is no STOREAGESIGNATURE. |
3315 | *pVer = reinterpret_cast<const char*>(reinterpret_cast<const STORAGESIGNATURE*>(m_LiteWeightStgdb.m_pvMd)->pVersion); |
3316 | } |
3317 | else |
3318 | { // No string. |
3319 | *pVer = NULL; |
3320 | } |
3321 | |
3322 | return hr; |
3323 | } // MDInternalRO::GetVersionString |
3324 | |
3325 | //***************************************************************************** |
3326 | // convert a text signature to com format |
3327 | //***************************************************************************** |
3328 | __checkReturn |
3329 | HRESULT MDInternalRO::ConvertTextSigToComSig(// Return hresult. |
3330 | BOOL fCreateTrIfNotFound, // create typeref if not found or not |
3331 | LPCSTR pSignature, // class file format signature |
3332 | CQuickBytes *pqbNewSig, // [OUT] place holder for COM+ signature |
3333 | ULONG *pcbCount) // [OUT] the result size of signature |
3334 | { |
3335 | return E_NOTIMPL; |
3336 | } // MDInternalRO::ConvertTextSigToComSig |
3337 | |
3338 | |
3339 | //***************************************************************************** |
3340 | // determine if a token is valid or not |
3341 | //***************************************************************************** |
3342 | BOOL MDInternalRO::IsValidToken( // True or False. |
3343 | mdToken tk) // [IN] Given token. |
3344 | { |
3345 | RID rid = RidFromToken(tk); |
3346 | if (rid == 0) |
3347 | { |
3348 | return FALSE; |
3349 | } |
3350 | switch (TypeFromToken(tk)) |
3351 | { |
3352 | case mdtModule: |
3353 | // can have only one module record |
3354 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountModules()); |
3355 | case mdtTypeRef: |
3356 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountTypeRefs()); |
3357 | case mdtTypeDef: |
3358 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountTypeDefs()); |
3359 | case mdtFieldDef: |
3360 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountFields()); |
3361 | case mdtMethodDef: |
3362 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountMethods()); |
3363 | case mdtParamDef: |
3364 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountParams()); |
3365 | case mdtInterfaceImpl: |
3366 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountInterfaceImpls()); |
3367 | case mdtMemberRef: |
3368 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountMemberRefs()); |
3369 | case mdtCustomAttribute: |
3370 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountCustomAttributes()); |
3371 | case mdtPermission: |
3372 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountDeclSecuritys()); |
3373 | case mdtSignature: |
3374 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountStandAloneSigs()); |
3375 | case mdtEvent: |
3376 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountEvents()); |
3377 | case mdtProperty: |
3378 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountPropertys()); |
3379 | case mdtModuleRef: |
3380 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountModuleRefs()); |
3381 | case mdtTypeSpec: |
3382 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountTypeSpecs()); |
3383 | case mdtAssembly: |
3384 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountAssemblys()); |
3385 | case mdtAssemblyRef: |
3386 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountAssemblyRefs()); |
3387 | case mdtFile: |
3388 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountFiles()); |
3389 | case mdtExportedType: |
3390 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountExportedTypes()); |
3391 | case mdtManifestResource: |
3392 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountManifestResources()); |
3393 | case mdtMethodSpec: |
3394 | return (rid <= m_LiteWeightStgdb.m_MiniMd.getCountMethodSpecs()); |
3395 | case mdtString: |
3396 | // need to check the user string heap |
3397 | return m_LiteWeightStgdb.m_MiniMd.m_UserStringHeap.IsValidIndex(rid); |
3398 | default: |
3399 | /* Don't Assert here, this will break verifier tests. |
3400 | _ASSERTE(!"Unknown token kind!"); |
3401 | */ |
3402 | return FALSE; |
3403 | } |
3404 | } // MDInternalRO::IsValidToken |
3405 | |
3406 | mdModule MDInternalRO::GetModuleFromScope(void) |
3407 | { |
3408 | return TokenFromRid(1, mdtModule); |
3409 | } // MDInternalRO::GetModuleFromScope |
3410 | |
3411 | //***************************************************************************** |
3412 | // Fill a variant given a MDDefaultValue |
3413 | // This routine will create a bstr if the ELEMENT_TYPE of default value is STRING |
3414 | //***************************************************************************** |
3415 | __checkReturn |
3416 | HRESULT _FillVariant( |
3417 | MDDefaultValue *pMDDefaultValue, |
3418 | VARIANT *pvar) |
3419 | { |
3420 | HRESULT hr = NOERROR; |
3421 | |
3422 | _ASSERTE(pMDDefaultValue); |
3423 | |
3424 | switch (pMDDefaultValue->m_bType) |
3425 | { |
3426 | case ELEMENT_TYPE_BOOLEAN: |
3427 | V_VT(pvar) = VT_BOOL; |
3428 | V_BOOL(pvar) = pMDDefaultValue->m_bValue; |
3429 | break; |
3430 | case ELEMENT_TYPE_I1: |
3431 | V_VT(pvar) = VT_I1; |
3432 | V_I1(pvar) = pMDDefaultValue->m_cValue; |
3433 | break; |
3434 | case ELEMENT_TYPE_U1: |
3435 | V_VT(pvar) = VT_UI1; |
3436 | V_UI1(pvar) = pMDDefaultValue->m_byteValue; |
3437 | break; |
3438 | case ELEMENT_TYPE_I2: |
3439 | V_VT(pvar) = VT_I2; |
3440 | V_I2(pvar) = pMDDefaultValue->m_sValue; |
3441 | break; |
3442 | case ELEMENT_TYPE_U2: |
3443 | case ELEMENT_TYPE_CHAR: // char is stored as UI2 internally |
3444 | V_VT(pvar) = VT_UI2; |
3445 | V_UI2(pvar) = pMDDefaultValue->m_usValue; |
3446 | break; |
3447 | case ELEMENT_TYPE_I4: |
3448 | V_VT(pvar) = VT_I4; |
3449 | V_I4(pvar) = pMDDefaultValue->m_lValue; |
3450 | break; |
3451 | case ELEMENT_TYPE_U4: |
3452 | V_VT(pvar) = VT_UI4; |
3453 | V_UI4(pvar) = pMDDefaultValue->m_ulValue; |
3454 | break; |
3455 | case ELEMENT_TYPE_R4: |
3456 | V_VT(pvar) = VT_R4; |
3457 | V_R4(pvar) = pMDDefaultValue->m_fltValue; |
3458 | break; |
3459 | case ELEMENT_TYPE_R8: |
3460 | V_VT(pvar) = VT_R8; |
3461 | V_R8(pvar) = pMDDefaultValue->m_dblValue; |
3462 | break; |
3463 | case ELEMENT_TYPE_STRING: |
3464 | // allocated bstr here |
3465 | V_BSTR(pvar) = ::SysAllocStringLen(pMDDefaultValue->m_wzValue, pMDDefaultValue->m_cbSize / sizeof(WCHAR)); |
3466 | if (V_BSTR(pvar) == NULL) |
3467 | hr = E_OUTOFMEMORY; |
3468 | V_VT(pvar) = VT_BSTR; |
3469 | break; |
3470 | case ELEMENT_TYPE_CLASS: |
3471 | V_VT(pvar) = VT_UNKNOWN; |
3472 | V_UNKNOWN(pvar) = pMDDefaultValue->m_unkValue; |
3473 | break; |
3474 | case ELEMENT_TYPE_I8: |
3475 | V_VT(pvar) = VT_I8; |
3476 | V_CY(pvar).int64 = pMDDefaultValue->m_llValue; |
3477 | break; |
3478 | case ELEMENT_TYPE_U8: |
3479 | V_VT(pvar) = VT_UI8; |
3480 | V_CY(pvar).int64 = pMDDefaultValue->m_ullValue; |
3481 | break; |
3482 | case ELEMENT_TYPE_VOID: |
3483 | V_VT(pvar) = VT_EMPTY; |
3484 | break; |
3485 | default: |
3486 | _ASSERTE(!"bad constant value type!" ); |
3487 | } |
3488 | |
3489 | return hr; |
3490 | } // _FillVariant |
3491 | |
3492 | |
3493 | //***************************************************************************** |
3494 | // Fill a variant given a MDDefaultValue |
3495 | // This routine will create a bstr if the ELEMENT_TYPE of default value is STRING |
3496 | //***************************************************************************** |
3497 | __checkReturn |
3498 | HRESULT _FillMDDefaultValue( |
3499 | BYTE bType, |
3500 | void const *pValue, |
3501 | ULONG cbValue, |
3502 | MDDefaultValue *pMDDefaultValue) |
3503 | { |
3504 | HRESULT hr = NOERROR; |
3505 | |
3506 | pMDDefaultValue->m_bType = bType; |
3507 | pMDDefaultValue->m_cbSize = cbValue; |
3508 | switch (bType) |
3509 | { |
3510 | case ELEMENT_TYPE_BOOLEAN: |
3511 | if (cbValue < 1) |
3512 | { |
3513 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3514 | } |
3515 | pMDDefaultValue->m_bValue = *((BYTE *) pValue); |
3516 | break; |
3517 | case ELEMENT_TYPE_I1: |
3518 | if (cbValue < 1) |
3519 | { |
3520 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3521 | } |
3522 | pMDDefaultValue->m_cValue = *((CHAR *) pValue); |
3523 | break; |
3524 | case ELEMENT_TYPE_U1: |
3525 | if (cbValue < 1) |
3526 | { |
3527 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3528 | } |
3529 | pMDDefaultValue->m_byteValue = *((BYTE *) pValue); |
3530 | break; |
3531 | case ELEMENT_TYPE_I2: |
3532 | if (cbValue < 2) |
3533 | { |
3534 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3535 | } |
3536 | pMDDefaultValue->m_sValue = GET_UNALIGNED_VAL16(pValue); |
3537 | break; |
3538 | case ELEMENT_TYPE_U2: |
3539 | case ELEMENT_TYPE_CHAR: |
3540 | if (cbValue < 2) |
3541 | { |
3542 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3543 | } |
3544 | pMDDefaultValue->m_usValue = GET_UNALIGNED_VAL16(pValue); |
3545 | break; |
3546 | case ELEMENT_TYPE_I4: |
3547 | if (cbValue < 4) |
3548 | { |
3549 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3550 | } |
3551 | pMDDefaultValue->m_lValue = GET_UNALIGNED_VAL32(pValue); |
3552 | break; |
3553 | case ELEMENT_TYPE_U4: |
3554 | if (cbValue < 4) |
3555 | { |
3556 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3557 | } |
3558 | pMDDefaultValue->m_ulValue = GET_UNALIGNED_VAL32(pValue); |
3559 | break; |
3560 | case ELEMENT_TYPE_R4: |
3561 | { |
3562 | if (cbValue < 4) |
3563 | { |
3564 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3565 | } |
3566 | __int32 Value = GET_UNALIGNED_VAL32(pValue); |
3567 | pMDDefaultValue->m_fltValue = (float &)Value; |
3568 | } |
3569 | break; |
3570 | case ELEMENT_TYPE_R8: |
3571 | { |
3572 | if (cbValue < 8) |
3573 | { |
3574 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3575 | } |
3576 | __int64 Value = GET_UNALIGNED_VAL64(pValue); |
3577 | pMDDefaultValue->m_dblValue = (double &) Value; |
3578 | } |
3579 | break; |
3580 | case ELEMENT_TYPE_STRING: |
3581 | if (cbValue == 0) |
3582 | pValue = NULL; |
3583 | |
3584 | #if BIGENDIAN |
3585 | { |
3586 | // We need to allocate and swap the string if we're on a big endian |
3587 | pMDDefaultValue->m_wzValue = new WCHAR[(cbValue + 1) / sizeof (WCHAR)]; |
3588 | _ASSERTE(FALSE); // Nothing ever free's this newly allocated array. Inserting assert so that if we ever actually |
3589 | // use this code path, we'll fix it then. (Don't want to fix something I can't test.) |
3590 | IfNullGo(pMDDefaultValue->m_wzValue); |
3591 | memcpy(const_cast<WCHAR *>(pMDDefaultValue->m_wzValue), pValue, cbValue); |
3592 | _ASSERTE(cbValue % sizeof(WCHAR) == 0); |
3593 | SwapStringLength(const_cast<WCHAR *>(pMDDefaultValue->m_wzValue), cbValue / sizeof(WCHAR)); |
3594 | } |
3595 | #else |
3596 | pMDDefaultValue->m_wzValue = (LPWSTR) pValue; |
3597 | #endif |
3598 | break; |
3599 | case ELEMENT_TYPE_CLASS: |
3600 | // |
3601 | // There is only a 4-byte quantity in the MetaData, and it must always |
3602 | // be zero. So, we load an INT32 and zero-extend it to be pointer-sized. |
3603 | // |
3604 | if (cbValue < 4) |
3605 | { |
3606 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3607 | } |
3608 | pMDDefaultValue->m_unkValue = (IUnknown *)(UINT_PTR)GET_UNALIGNED_VAL32(pValue); |
3609 | if (pMDDefaultValue->m_unkValue != NULL) |
3610 | { |
3611 | _ASSERTE(!"Non-NULL objectref's are not supported as default values!" ); |
3612 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3613 | } |
3614 | break; |
3615 | case ELEMENT_TYPE_I8: |
3616 | if (cbValue < 8) |
3617 | { |
3618 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3619 | } |
3620 | pMDDefaultValue->m_llValue = GET_UNALIGNED_VAL64(pValue); |
3621 | break; |
3622 | case ELEMENT_TYPE_U8: |
3623 | if (cbValue < 8) |
3624 | { |
3625 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3626 | } |
3627 | pMDDefaultValue->m_ullValue = GET_UNALIGNED_VAL64(pValue); |
3628 | break; |
3629 | case ELEMENT_TYPE_VOID: |
3630 | break; |
3631 | default: |
3632 | _ASSERTE(!"BAD TYPE!" ); |
3633 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3634 | break; |
3635 | } |
3636 | ErrExit: |
3637 | return hr; |
3638 | } // _FillMDDefaultValue |
3639 | |
3640 | //***************************************************************************** |
3641 | // Given a scope, return the table size and table ptr for a given index |
3642 | //***************************************************************************** |
3643 | __checkReturn |
3644 | HRESULT MDInternalRO::GetTableInfoWithIndex( // return size |
3645 | ULONG index, // [IN] pass in the index |
3646 | void **pTable, // [OUT] pointer to table at index |
3647 | void **pTableSize) // [OUT] size of table at index |
3648 | { |
3649 | _ASSERTE(!"NYI" ); |
3650 | return E_NOTIMPL; |
3651 | } // MDInternalRO::GetTableInfoWithIndex |
3652 | |
3653 | |
3654 | |
3655 | //***************************************************************************** |
3656 | // Given a delta metadata byte stream, apply the changes to the current metadata |
3657 | // object returning the resulting metadata object in ppv |
3658 | //***************************************************************************** |
3659 | __checkReturn |
3660 | HRESULT MDInternalRO::ApplyEditAndContinue( |
3661 | void *pDeltaMD, // [IN] the delta metadata |
3662 | ULONG cbDeltaMD, // [IN] length of pData |
3663 | IMDInternalImport **ppv) // [OUT] the resulting metadata interface |
3664 | { |
3665 | _ASSERTE(pDeltaMD); |
3666 | _ASSERTE(ppv); |
3667 | |
3668 | HRESULT hr = E_FAIL; |
3669 | |
3670 | IMDInternalImportENC *pDeltaMDImport = NULL; |
3671 | |
3672 | IfFailGo(GetInternalWithRWFormat(pDeltaMD, cbDeltaMD, 0, IID_IMDInternalImportENC, (void**)&pDeltaMDImport)); |
3673 | |
3674 | *ppv = this; |
3675 | IfFailGo(MDApplyEditAndContinue(ppv, pDeltaMDImport)); |
3676 | |
3677 | ErrExit: |
3678 | if (pDeltaMDImport) |
3679 | pDeltaMDImport->Release(); |
3680 | return hr; |
3681 | } |
3682 | |
3683 | HRESULT MDInternalRO::GetRvaOffsetData( |
3684 | DWORD *pFirstMethodRvaOffset, // [OUT] Offset (from start of metadata) to the first RVA field in MethodDef table. |
3685 | DWORD *pMethodDefRecordSize, // [OUT] Size of each record in MethodDef table. |
3686 | DWORD *pMethodDefCount, // [OUT] Number of records in MethodDef table. |
3687 | DWORD *pFirstFieldRvaOffset, // [OUT] Offset (from start of metadata) to the first RVA field in FieldRVA table. |
3688 | DWORD *pFieldRvaRecordSize, // [OUT] Size of each record in FieldRVA table. |
3689 | DWORD *pFieldRvaCount) // [OUT] Number of records in FieldRVA table. |
3690 | { |
3691 | HRESULT hr = S_OK; |
3692 | DWORD methodDefCount = *pMethodDefCount = m_LiteWeightStgdb.m_MiniMd.getCountMethods(); |
3693 | if (methodDefCount == 0) |
3694 | *pFirstMethodRvaOffset = *pMethodDefRecordSize = 0; |
3695 | else |
3696 | { |
3697 | MethodRec *pMethodRec; |
3698 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetMethodRecord(1, &pMethodRec)); |
3699 | |
3700 | // RVA is the first column of the MethodDef table, so the address of MethodRec is also address of RVA column. |
3701 | if ((const BYTE *)m_LiteWeightStgdb.m_pvMd > (const BYTE *)pMethodRec) |
3702 | { |
3703 | Debug_ReportError("Stream header is not within MetaData block." ); |
3704 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3705 | } |
3706 | *pFirstMethodRvaOffset = (DWORD)((const BYTE *)pMethodRec - (const BYTE *)m_LiteWeightStgdb.m_pvMd); |
3707 | *pMethodDefRecordSize = m_LiteWeightStgdb.m_MiniMd._CBREC(Method); |
3708 | } |
3709 | |
3710 | { |
3711 | DWORD fieldRvaCount = *pFieldRvaCount = m_LiteWeightStgdb.m_MiniMd.getCountFieldRVAs(); |
3712 | if (fieldRvaCount == 0) |
3713 | *pFirstFieldRvaOffset = *pFieldRvaRecordSize = 0; |
3714 | else |
3715 | { |
3716 | |
3717 | // orig |
3718 | // FieldRVARec *pFieldRVARec = m_LiteWeightStgdb.m_MiniMd.getFieldRVA(1); |
3719 | FieldRVARec *pFieldRVARec; |
3720 | IfFailGo(m_LiteWeightStgdb.m_MiniMd.GetFieldRVARecord(1, &pFieldRVARec)); |
3721 | |
3722 | //FieldRVARec *pFieldRVARec; |
3723 | //mdToken fakeTok = 1; |
3724 | //RidToToken(&fakeTok, mdtFieldDef); |
3725 | //GetFieldRVA(fakeTok, &pFieldRVARec); |
3726 | // RVA is the first column of the FieldRVA table, so the address of FieldRVARec is also address of RVA column. |
3727 | if ((const BYTE *)m_LiteWeightStgdb.m_pvMd > (const BYTE *)pFieldRVARec) |
3728 | { |
3729 | Debug_ReportError("Stream header is not within MetaData block." ); |
3730 | IfFailGo(CLDB_E_FILE_CORRUPT); |
3731 | } |
3732 | *pFirstFieldRvaOffset = (DWORD)((const BYTE *)pFieldRVARec - (const BYTE *)m_LiteWeightStgdb.m_pvMd); |
3733 | *pFieldRvaRecordSize = m_LiteWeightStgdb.m_MiniMd._CBREC(FieldRVA); |
3734 | } |
3735 | } |
3736 | hr = S_OK; |
3737 | |
3738 | ErrExit: |
3739 | return hr; |
3740 | } |
3741 | |
3742 | #endif //FEATURE_METADATA_INTERNAL_APIS |
3743 | |