rt_public EIF_POINTER c_query_assembly_emit (EIF_POINTER md_emit) /* Call `QueryInterface(IID_IMetaDataAssemblyEmit, (void **)&imda)' */ { IMetaDataEmit *emit = (IMetaDataEmit *) md_emit; IMetaDataAssemblyEmit *imda; HRESULT hr; hr = emit->QueryInterface(IID_IMetaDataAssemblyEmit, (void **)&imda); CHECK (hr, "Could not get IMetaDataAssemblyEmit"); return imda; }
HRESULT CCeeGen::Cleanup() // virtual { HRESULT hr; for (int i = 0; i < m_numSections; i++) { delete m_sections[i]; } delete m_sections; CeeGenTokenMapper *pMapper = m_pTokenMap; if (pMapper) { if (pMapper->m_pIImport) { IMetaDataEmit *pIIEmit; if (SUCCEEDED( hr = pMapper->m_pIImport->QueryInterface(IID_IMetaDataEmit, (void **) &pIIEmit))) { pIIEmit->SetHandler(NULL); pIIEmit->Release(); } _ASSERTE(SUCCEEDED(hr)); pMapper->m_pIImport->Release(); } pMapper->Release(); m_pTokenMap = NULL; } if (m_pRemapHandler) { m_pRemapHandler->Release(); m_pRemapHandler = NULL; } if (m_peSectionMan) { m_peSectionMan->Cleanup(); delete m_peSectionMan; } return S_OK; }
HRESULT CAsmLink::SetAssemblyProps(mdAssembly AssemblyID, mdToken FileToken, AssemblyOptions Option, VARIANT Value) { ASSERT(m_bInited && !m_bPreClosed && m_pAssem && !m_bManifestEmitted); ASSERT(AssemblyID == TokenFromRid(mdtAssembly, 1) || AssemblyID == AssemblyIsUBM); ASSERT((RidFromToken(FileToken) < m_pAssem->CountFiles() && TypeFromToken(FileToken) == mdtFile) || (FileToken == AssemblyID)); HRESULT hr = S_OK; if (Option >= optLastAssemOption || OptionCAs[Option].flag & 0x40) return E_INVALIDARG; if (AssemblyID == AssemblyIsUBM || (OptionCAs[Option].flag & 0x02)) { CFile *file = NULL; if (FileToken == AssemblyID) file = m_pAssem; else if (FAILED(hr = m_pAssem->GetFile(FileToken, &file))) return hr; ASSERT(file->GetEmitScope()); IMetaDataEmit* pEmit = file->GetEmitScope(); CComPtr<IMetaDataImport> pImport; mdToken tkAttrib = mdTokenNil, tkCtor; DWORD cbValue = 0, cbSig = 4; BYTE pbValue[2048]; PBYTE pBlob = pbValue; COR_SIGNATURE newSig[9]; LPCWSTR wszStr = NULL; ULONG wLen = 0; if (FAILED(hr = pEmit->QueryInterface(IID_IMetaDataImport, (void**)&pImport))) return hr; // Find or Create the TypeRef (This always scopes it to MSCORLIB) if (FAILED(hr = file->GetTypeRef(OptionCAs[Option].name, &tkAttrib))) return hr; // Make the Blob newSig[0] = (IMAGE_CEE_CS_CALLCONV_DEFAULT | IMAGE_CEE_CS_CALLCONV_HASTHIS); newSig[1] = 1; // One parameter newSig[2] = ELEMENT_TYPE_VOID; *(WORD*)pBlob = VAL16(1); // This is aligned pBlob += sizeof(WORD); if (V_VT(&Value) != OptionCAs[Option].vt) return E_INVALIDARG; switch(OptionCAs[Option].vt) { case VT_BOOL: *pBlob++ = (V_BOOL(&Value) == VARIANT_TRUE); newSig[3] = ELEMENT_TYPE_BOOLEAN; break; case VT_UI4: SET_UNALIGNED_VAL32(pBlob, V_UI4(&Value)); pBlob += sizeof(ULONG); newSig[3] = ELEMENT_TYPE_U4; break; case VT_BSTR: if (Option == optAssemOS) { LPWSTR end = NULL; mdToken tkPlatform = mdTokenNil; newSig[1] = 2; // Two parameters newSig[3] = ELEMENT_TYPE_VALUETYPE; // Make the TypeRef if (FAILED(hr = file->GetTypeRef( PLATFORMID_NAME, &tkPlatform))) break; cbSig = 5 + CorSigCompressToken(tkPlatform, newSig + 4); newSig[cbSig - 1] = ELEMENT_TYPE_STRING; SET_UNALIGNED_VAL32(pBlob, wcstoul(V_BSTR(&Value), &end, 0)); // Parse Hex, Octal, and Decimal pBlob += sizeof(ULONG); if (*end == L'.') { wszStr = end++; wLen = SysStringLen(V_BSTR(&Value)) - (UINT)(V_BSTR(&Value) - end); goto ADDSTRING; } else { hr = file->ReportError(ERR_InvalidOSString); return hr; } } else { newSig[3] = ELEMENT_TYPE_STRING; wLen = SysStringLen(V_BSTR(&Value)); wszStr = V_BSTR(&Value); ADDSTRING: if (wLen == 0) { // Too small for unilib *pBlob++ = 0xFF; } else if (wLen & 0x80000000) { // Too big! return ReportOptionError(file, Option, E_INVALIDARG); } else if ((OptionCAs[Option].flag & 0x10) && wLen > MAX_PATH) { // Too big! return ReportOptionError(file, Option, HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW)); // File name too long } else { CHAR pUTF8[2048]; int iLen = wLen; wLen = (UINT)UnicodeToUTF8(wszStr, &iLen, pUTF8, lengthof(pUTF8)); iLen = (int)CorSigCompressData( wLen, pBlob); pBlob += iLen; if (wLen > (UINT)(pbValue + lengthof(pbValue) - pBlob)) { // Too big! return ReportOptionError(file, Option, HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW)); } memcpy(pBlob, pUTF8, wLen); pBlob += wLen; } } break; default: VSFAIL("Unknown Option Type!"); newSig[3] = ELEMENT_TYPE_OBJECT; break; } hr = pImport->FindMemberRef(tkAttrib, L".ctor", newSig, cbSig, &tkCtor); if ((hr == CLDB_E_RECORD_NOTFOUND && FAILED(hr = pEmit->DefineMemberRef(tkAttrib, L".ctor", newSig, 4, &tkCtor))) || FAILED(hr)) return hr; cbValue = (DWORD)(pBlob - pbValue); // Emit the CA // This will also set the option if appropriate hr = EmitAssemblyCustomAttribute( AssemblyID, FileToken, tkCtor, pbValue, cbValue, (OptionCAs[Option].flag & 0x08) ? TRUE : FALSE, (OptionCAs[Option].flag & 0x04) ? TRUE : FALSE); } else { // An assembly level custom attribute hr = m_pAssem->SetOption(Option, &Value); } return hr; }
//************************************************** // GetTypeRef // This function will return the type token given full qual name. If the type // is defined locally, we will return the TypeDef token. Or we will return a TypeRef token // with proper resolution scope calculated. // wszFullName is escaped (TYPE_NAME_RESERVED_CHAR). It should not be byref or contain enclosing type name, // assembly name, and generic argument list. //************************************************** mdTypeRef QCALLTYPE COMModule::GetTypeRef(QCall::ModuleHandle pModule, LPCWSTR wszFullName, QCall::ModuleHandle pRefedModule, LPCWSTR wszRefedModuleFileName, INT32 tkResolutionArg) { QCALL_CONTRACT; mdTypeRef tr = 0; BEGIN_QCALL; RefClassWriter * pRCW = pModule->GetReflectionModule()->GetClassWriter(); _ASSERTE(pRCW); IMetaDataEmit * pEmit = pRCW->GetEmitter(); IMetaDataImport * pImport = pRCW->GetRWImporter(); if (wszFullName == NULL) { COMPlusThrow(kArgumentNullException, W("ArgumentNull_String")); } InlineSString<128> ssNameUnescaped; LPCWSTR wszTemp = wszFullName; WCHAR c; while(0 != (c = *wszTemp++)) { if ( c == W('\\') && IsTypeNameReservedChar(*wszTemp) ) { ssNameUnescaped.Append(*wszTemp++); } else { _ASSERTE( ! IsTypeNameReservedChar(c) ); ssNameUnescaped.Append(c); } } LPCWSTR wszFullNameUnescaped = ssNameUnescaped.GetUnicode(); Assembly * pThisAssembly = pModule->GetClassLoader()->GetAssembly(); Assembly * pRefedAssembly = pRefedModule->GetClassLoader()->GetAssembly(); if (pModule == pRefedModule) { // referenced type is from the same module so we must be able to find a TypeDef. IfFailThrow(pImport->FindTypeDefByName( wszFullNameUnescaped, RidFromToken(tkResolutionArg) ? tkResolutionArg : mdTypeDefNil, &tr)); } else { mdToken tkResolution = mdTokenNil; if (RidFromToken(tkResolutionArg)) { // reference to nested type tkResolution = tkResolutionArg; } else { // reference to top level type if ( pThisAssembly != pRefedAssembly ) { SafeComHolderPreemp<IMetaDataAssemblyEmit> pAssemblyEmit; // Generate AssemblyRef IfFailThrow( pEmit->QueryInterface(IID_IMetaDataAssemblyEmit, (void **) &pAssemblyEmit) ); tkResolution = pThisAssembly->AddAssemblyRef(pRefedAssembly, pAssemblyEmit); // Add the assembly ref token and the manifest module it is referring to this module's rid map. // This is needed regardless of whether the dynamic assembly has run access. Even in Save-only // or Refleciton-only mode, CreateType() of the referencing type may still need the referenced // type to be resolved and loaded, e.g. if the referencing type is a subclass of the referenced type. // // Don't cache if there is assembly associated with the token already. The assembly ref resolution // can be ambiguous because of reflection emit does not require unique assembly names. // We always let the first association win. Ideally, we would disallow this situation by throwing // exception, but that would be a breaking change. if(pModule->LookupAssemblyRef(tkResolution) == NULL) { pModule->ForceStoreAssemblyRef(tkResolution, pRefedAssembly); } } else { _ASSERTE(pModule != pRefedModule); _ASSERTE(wszRefedModuleFileName != NULL); // Generate ModuleRef IfFailThrow(pEmit->DefineModuleRef(wszRefedModuleFileName, &tkResolution)); } } IfFailThrow( pEmit->DefineTypeRefByName(tkResolution, wszFullNameUnescaped, &tr) ); } END_QCALL; return tr; }