//***************************************************************************** // Remove a RegMeta pointer from the loaded module list //***************************************************************************** HRESULT LOADEDMODULES::ResolveTypeRefWithLoadedModules( mdTypeRef tr, // [IN] TypeRef to be resolved. IMetaModelCommon *pCommon, // [IN] scope in which the typeref is defined. REFIID riid, // [IN] iid for the return interface IUnknown **ppIScope, // [OUT] return interface mdTypeDef *ptd) // [OUT] typedef corresponding the typeref { HRESULT hr = NOERROR; RegMeta *pRegMeta; CQuickArray<mdTypeRef> cqaNesters; CQuickArray<LPCUTF8> cqaNesterNamespaces; CQuickArray<LPCUTF8> cqaNesterNames; int count; int index; if (g_LoadedModules == NULL) { // No loaded module! _ASSERTE(!"Bad state!"); return E_FAIL; } LOCKREAD(); // Get the Nesting hierarchy. IfFailGo(ImportHelper::GetNesterHierarchy(pCommon, tr, cqaNesters, cqaNesterNamespaces, cqaNesterNames)); count = g_LoadedModules->Count(); for (index = 0; index < count; index++) { pRegMeta = (*g_LoadedModules)[index]; hr = ImportHelper::FindNestedTypeDef( pRegMeta->GetMiniMd(), cqaNesterNamespaces, cqaNesterNames, mdTokenNil, ptd); if (SUCCEEDED(hr)) { // found a loaded module containing the TypeDef. hr = pRegMeta->QueryInterface(riid, (void **)ppIScope); break; } else if (hr != CLDB_E_RECORD_NOTFOUND) IfFailGo(hr); } if (FAILED(hr)) { // cannot find the match! hr = E_FAIL; } ErrExit: return hr; } // LOADEDMODULES::ResolveTypeRefWithLoadedModules
//************************************************************* // // Open the file with anme wzModule and check to see if there is a type // with namespace/class of wzNamespace/wzType. If so, return the RegMeta // corresponding to the file and the mdTypeDef of the typedef // //************************************************************* HRESULT CORPATHService::FindTypeDef( __in __in_z LPWSTR wzModule, // name of the module that we are going to open mdTypeRef tr, // TypeRef to resolve. IMetaModelCommon * pCommon, // Scope in which the TypeRef is defined. REFIID riid, IUnknown ** ppIScope, mdTypeDef * ptd) // [OUT] the type that we resolve to { HRESULT hr = NOERROR; NewHolder<Disp> pDisp; ReleaseHolder<IMetaDataImport2> pImport = NULL; CQuickArray<mdTypeRef> cqaNesters; CQuickArray<LPCUTF8> cqaNesterNamespaces; CQuickArray<LPCUTF8> cqaNesterNames; RegMeta * pRegMeta; _ASSERTE((ppIScope != NULL) && (ptd != NULL)); *ppIScope = NULL; pDisp = new (nothrow) Disp; IfNullGo(pDisp); IfFailGo(pDisp->OpenScope(wzModule, 0, IID_IMetaDataImport2, (IUnknown **)&pImport)); pRegMeta = static_cast<RegMeta *>(pImport.GetValue()); // Get the Nesting hierarchy. IfFailGo(ImportHelper::GetNesterHierarchy(pCommon, tr, cqaNesters, cqaNesterNamespaces, cqaNesterNames)); hr = ImportHelper::FindNestedTypeDef( pRegMeta->GetMiniMd(), cqaNesterNamespaces, cqaNesterNames, mdTokenNil, ptd); if (SUCCEEDED(hr)) { *ppIScope = pImport.Extract(); } ErrExit: return hr; } // CORPATHService::FindTypeDef
//***************************************************************************** // Remove a RegMeta pointer from the loaded module list //***************************************************************************** // static HRESULT LOADEDMODULES::ResolveTypeRefWithLoadedModules( mdTypeRef tkTypeRef, // [IN] TypeRef to be resolved. RegMeta * pTypeRefRegMeta, // [IN] Scope in which the TypeRef is defined. IMetaModelCommon * pTypeRefScope, // [IN] Scope in which the TypeRef is defined. REFIID riid, // [IN] iid for the return interface. IUnknown ** ppIScope, // [OUT] Return interface. mdTypeDef * ptd) // [OUT] TypeDef corresponding the TypeRef. { HRESULT hr = NOERROR; RegMeta * pRegMeta; CQuickArray<mdTypeRef> cqaNesters; CQuickArray<LPCUTF8> cqaNesterNamespaces; CQuickArray<LPCUTF8> cqaNesterNames; IfFailGo(InitializeStatics()); { LOCKREAD(); // Get the Nesting hierarchy. IfFailGo(ImportHelper::GetNesterHierarchy( pTypeRefScope, tkTypeRef, cqaNesters, cqaNesterNamespaces, cqaNesterNames)); int count = s_pLoadedModules->Count(); for (int index = 0; index < count; index++) { pRegMeta = (*s_pLoadedModules)[index]; { // Do not lock the TypeRef RegMeta (again), as it is already locked for read by the caller. // The code:UTSemReadWrite will block ReadLock even for thread holding already the read lock if // some other thread is waiting for WriteLock on the same lock. That would cause dead-lock if we // try to lock for read again here. CMDSemReadWrite cSemRegMeta((pRegMeta == pTypeRefRegMeta) ? NULL : pRegMeta->GetReaderWriterLock()); IfFailGo(cSemRegMeta.LockRead()); hr = ImportHelper::FindNestedTypeDef( pRegMeta->GetMiniMd(), cqaNesterNamespaces, cqaNesterNames, mdTokenNil, ptd); } if (hr == CLDB_E_RECORD_NOTFOUND) { // Process next MetaData module continue; } IfFailGo(hr); // Found a loaded module containing the TypeDef. IfFailGo(pRegMeta->QueryInterface(riid, (void **)ppIScope)); break; } } if (FAILED(hr)) { // cannot find the match! hr = E_FAIL; } ErrExit: return hr; } // LOADEDMODULES::ResolveTypeRefWithLoadedModules