//******************************************************************************* // helper to add a declarative security blob to a class or method // // Implements internal API code:IMetaDataEmitHelper::AddDeclarativeSecurityHelper. //******************************************************************************* STDMETHODIMP RegMeta::AddDeclarativeSecurityHelper( mdToken tk, // [IN] Parent token (typedef/methoddef) DWORD dwAction, // [IN] Security action (CorDeclSecurity) void const *pValue, // [IN] Permission set blob DWORD cbValue, // [IN] Byte count of permission set blob mdPermission*pmdPermission) // [OUT] Output permission token { HRESULT hr = S_OK; DeclSecurityRec *pDeclSec = NULL; RID iDeclSec; short sAction = static_cast<short>(dwAction); mdPermission tkPerm; LOG((LOGMD, "MD RegMeta::AddDeclarativeSecurityHelper(0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", tk, dwAction, pValue, cbValue, pmdPermission)); LOCKWRITE(); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); _ASSERTE(TypeFromToken(tk) == mdtTypeDef || TypeFromToken(tk) == mdtMethodDef || TypeFromToken(tk) == mdtAssembly); // Check for valid Action. if (sAction == 0 || sAction > dclMaximumValue) IfFailGo(E_INVALIDARG); if (CheckDups(MDDupPermission)) { hr = ImportHelper::FindPermission(&(m_pStgdb->m_MiniMd), tk, sAction, &tkPerm); if (SUCCEEDED(hr)) { // Set output parameter. if (pmdPermission) *pmdPermission = tkPerm; if (IsENCOn()) IfFailGo(m_pStgdb->m_MiniMd.GetDeclSecurityRecord(RidFromToken(tkPerm), &pDeclSec)); else { hr = META_S_DUPLICATE; goto ErrExit; } } else if (hr != CLDB_E_RECORD_NOTFOUND) IfFailGo(hr); } // Create a new record. if (!pDeclSec) { IfFailGo(m_pStgdb->m_MiniMd.AddDeclSecurityRecord(&pDeclSec, &iDeclSec)); tkPerm = TokenFromRid(iDeclSec, mdtPermission); // Set output parameter. if (pmdPermission) *pmdPermission = tkPerm; // Save parent and action information. IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_DeclSecurity, DeclSecurityRec::COL_Parent, pDeclSec, tk)); pDeclSec->SetAction(sAction); // Turn on the internal security flag on the parent. if (TypeFromToken(tk) == mdtTypeDef) IfFailGo(_TurnInternalFlagsOn(tk, tdHasSecurity)); else if (TypeFromToken(tk) == mdtMethodDef) IfFailGo(_TurnInternalFlagsOn(tk, mdHasSecurity)); IfFailGo(UpdateENCLog(tk)); } // Write the blob into the record. IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_DeclSecurity, DeclSecurityRec::COL_PermissionSet, pDeclSec, pValue, cbValue)); IfFailGo(UpdateENCLog(tkPerm)); ErrExit: return hr; } // RegMeta::AddDeclarativeSecurityHelper
//******************************************************************************* // Define a Resource and set the attributes. //******************************************************************************* STDMETHODIMP RegMeta::DefineManifestResource( // S_OK or error. LPCWSTR szName, // [IN] Name of the ManifestResource. mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource. DWORD dwOffset, // [IN] Offset to the beginning of the resource within the file. DWORD dwResourceFlags, // [IN] Flags. mdManifestResource *pmmr) // [OUT] Returned ManifestResource token. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; ManifestResourceRec *pRecord = NULL; ULONG iRecord; LOG((LOGMD, "RegMeta::DefineManifestResource(%S, %#08x, %#08x, %#08x, %#08x)\n", MDSTR(szName), tkImplementation, dwOffset, dwResourceFlags, pmmr)); START_MD_PERF(); LOCKWRITE(); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); _ASSERTE(szName && dwResourceFlags != ULONG_MAX && pmmr); _ASSERTE(TypeFromToken(tkImplementation) == mdtFile || TypeFromToken(tkImplementation) == mdtAssemblyRef || tkImplementation == mdTokenNil); if (CheckDups(MDDupManifestResource)) { LPUTF8 szUTF8Name; UTF8STR(szName, szUTF8Name); hr = ImportHelper::FindManifestResource(&m_pStgdb->m_MiniMd, szUTF8Name, pmmr); if (SUCCEEDED(hr)) { if (IsENCOn()) { IfFailGo(m_pStgdb->m_MiniMd.GetManifestResourceRecord(RidFromToken(*pmmr), &pRecord)); } else { hr = META_S_DUPLICATE; goto ErrExit; } } else if (hr != CLDB_E_RECORD_NOTFOUND) { IfFailGo(hr); } } // Create a new record if needed. if (pRecord == NULL) { // Create a new record. IfFailGo(m_pStgdb->m_MiniMd.AddManifestResourceRecord(&pRecord, &iRecord)); // Set the output parameter. *pmmr = TokenFromRid(iRecord, mdtManifestResource); // Set the name. IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_ManifestResource, ManifestResourceRec::COL_Name, pRecord, szName)); } // Set the rest of the attributes. IfFailGo(_SetManifestResourceProps(*pmmr, tkImplementation, dwOffset, dwResourceFlags)); ErrExit: STOP_MD_PERF(DefineManifestResource); END_ENTRYPOINT_NOTHROW; return hr; } // RegMeta::DefineManifestResource
//******************************************************************************* // Define an Assembly and set the attributes. //******************************************************************************* STDMETHODIMP RegMeta::DefineAssembly( // S_OK or error. const void *pbPublicKey, // [IN] Public key of the assembly. ULONG cbPublicKey, // [IN] Count of bytes in the public key. ULONG ulHashAlgId, // [IN] Hash Algorithm. LPCWSTR szName, // [IN] Name of the assembly. const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. DWORD dwAssemblyFlags, // [IN] Flags. mdAssembly *pma) // [OUT] Returned Assembly token. { HRESULT hr = S_OK; AssemblyRec *pRecord = NULL; // The assembly record. ULONG iRecord; // RID of the assembly record. if (szName == NULL || pMetaData == NULL || pma == NULL) return E_INVALIDARG; BEGIN_ENTRYPOINT_NOTHROW; LOG((LOGMD, "RegMeta::DefineAssembly(0x%08x, 0x%08x, 0x%08x, %S, 0x%08x, 0x%08x, 0x%08x)\n", pbPublicKey, cbPublicKey, ulHashAlgId, MDSTR(szName), pMetaData, dwAssemblyFlags, pma)); START_MD_PERF(); LOCKWRITE(); _ASSERTE(szName && pMetaData && pma); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); // Assembly defs always contain a full public key (assuming they're strong // named) rather than the tokenized version. Force the flag on to indicate // this, and this way blindly copying public key & flags from a def to a ref // will work (though the ref will be bulkier than strictly necessary). if (cbPublicKey != 0) dwAssemblyFlags |= afPublicKey; if (CheckDups(MDDupAssembly)) { // Should be no more than one -- just check count of records. if (m_pStgdb->m_MiniMd.getCountAssemblys() > 0) { // S/b only one, so we know the rid. iRecord = 1; // If ENC, let them update the existing record. if (IsENCOn()) IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRecord(iRecord, &pRecord)); else { // Not ENC, so it is a duplicate. *pma = TokenFromRid(iRecord, mdtAssembly); hr = META_S_DUPLICATE; goto ErrExit; } } } else { // Not ENC, not duplicate checking, so shouldn't already have one. _ASSERTE(m_pStgdb->m_MiniMd.getCountAssemblys() == 0); } // Create a new record, if needed. if (pRecord == NULL) { IfFailGo(m_pStgdb->m_MiniMd.AddAssemblyRecord(&pRecord, &iRecord)); } // Set the output parameter. *pma = TokenFromRid(iRecord, mdtAssembly); IfFailGo(_SetAssemblyProps(*pma, pbPublicKey, cbPublicKey, ulHashAlgId, szName, pMetaData, dwAssemblyFlags)); ErrExit: STOP_MD_PERF(DefineAssembly); END_ENTRYPOINT_NOTHROW; return hr; } // RegMeta::DefineAssembly
//******************************************************************************* // Define a ExportedType and set the attributes. //******************************************************************************* STDMETHODIMP RegMeta::DefineExportedType( // S_OK or error. LPCWSTR szName, // [IN] Name of the Com Type. mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ExportedType. mdTypeDef tkTypeDef, // [IN] TypeDef token within the file. DWORD dwExportedTypeFlags, // [IN] Flags. mdExportedType *pmct) // [OUT] Returned ExportedType token. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; ExportedTypeRec *pRecord = NULL; ULONG iRecord; LPSTR szNameUTF8; LPCSTR szTypeNameUTF8; LPCSTR szTypeNamespaceUTF8; LOG((LOGMD, "RegMeta::DefineExportedType(%S, %#08x, %08x, %#08x, %#08x)\n", MDSTR(szName), tkImplementation, tkTypeDef, dwExportedTypeFlags, pmct)); START_MD_PERF(); LOCKWRITE(); // Validate name for prefix. if (szName == NULL) IfFailGo(E_INVALIDARG); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); //SLASHES2DOTS_NAMESPACE_BUFFER_UNICODE(szName, szName); UTF8STR(szName, szNameUTF8); // Split the name into name/namespace pair. ns::SplitInline(szNameUTF8, szTypeNamespaceUTF8, szTypeNameUTF8); _ASSERTE(szName && dwExportedTypeFlags != ULONG_MAX && pmct); _ASSERTE(TypeFromToken(tkImplementation) == mdtFile || TypeFromToken(tkImplementation) == mdtAssemblyRef || TypeFromToken(tkImplementation) == mdtExportedType || tkImplementation == mdTokenNil); if (CheckDups(MDDupExportedType)) { hr = ImportHelper::FindExportedType(&m_pStgdb->m_MiniMd, szTypeNamespaceUTF8, szTypeNameUTF8, tkImplementation, pmct); if (SUCCEEDED(hr)) { if (IsENCOn()) { IfFailGo(m_pStgdb->m_MiniMd.GetExportedTypeRecord(RidFromToken(*pmct), &pRecord)); } else { hr = META_S_DUPLICATE; goto ErrExit; } } else if (hr != CLDB_E_RECORD_NOTFOUND) { IfFailGo(hr); } } // Create a new record if needed. if (pRecord == NULL) { // Create a new record. IfFailGo(m_pStgdb->m_MiniMd.AddExportedTypeRecord(&pRecord, &iRecord)); // Set the output parameter. *pmct = TokenFromRid(iRecord, mdtExportedType); // Set the TypeName and TypeNamespace. IfFailGo(m_pStgdb->m_MiniMd.PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeName, pRecord, szTypeNameUTF8)); if (szTypeNamespaceUTF8) { IfFailGo(m_pStgdb->m_MiniMd.PutString(TBL_ExportedType, ExportedTypeRec::COL_TypeNamespace, pRecord, szTypeNamespaceUTF8)); } } // Set rest of the attributes. IfFailGo(_SetExportedTypeProps(*pmct, tkImplementation, tkTypeDef, dwExportedTypeFlags)); ErrExit: STOP_MD_PERF(DefineExportedType); END_ENTRYPOINT_NOTHROW; return hr; } // RegMeta::DefineExportedType
//******************************************************************************* // Define a File and set the attributes. //******************************************************************************* STDMETHODIMP RegMeta::DefineFile( // S_OK or error. LPCWSTR szName, // [IN] Name of the file. const void *pbHashValue, // [IN] Hash Blob. ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. DWORD dwFileFlags, // [IN] Flags. mdFile *pmf) // [OUT] Returned File token. { HRESULT hr = S_OK; BEGIN_ENTRYPOINT_NOTHROW; FileRec *pRecord = NULL; ULONG iRecord; LOG((LOGMD, "RegMeta::DefineFile(%S, %#08x, %#08x, %#08x, %#08x)\n", MDSTR(szName), pbHashValue, cbHashValue, dwFileFlags, pmf)); START_MD_PERF(); LOCKWRITE(); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); _ASSERTE(szName && pmf); if (CheckDups(MDDupFile)) { LPUTF8 szUTF8Name; UTF8STR(szName, szUTF8Name); hr = ImportHelper::FindFile(&m_pStgdb->m_MiniMd, szUTF8Name, pmf); if (SUCCEEDED(hr)) { if (IsENCOn()) { IfFailGo(m_pStgdb->m_MiniMd.GetFileRecord(RidFromToken(*pmf), &pRecord)); } else { hr = META_S_DUPLICATE; goto ErrExit; } } else if (hr != CLDB_E_RECORD_NOTFOUND) { IfFailGo(hr); } } // Create a new record if needed. if (pRecord == NULL) { // Create a new record. IfFailGo(m_pStgdb->m_MiniMd.AddFileRecord(&pRecord, &iRecord)); // Set the output parameter. *pmf = TokenFromRid(iRecord, mdtFile); // Set the name. IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_File, FileRec::COL_Name, pRecord, szName)); } // Set rest of the attributes. IfFailGo(_SetFileProps(*pmf, pbHashValue, cbHashValue, dwFileFlags)); ErrExit: STOP_MD_PERF(DefineFile); END_ENTRYPOINT_NOTHROW; return hr; } // RegMeta::DefineFile
//******************************************************************************* // Define an AssemblyRef and set the attributes. //******************************************************************************* STDMETHODIMP RegMeta::DefineAssemblyRef( // S_OK or error. const void *pbPublicKeyOrToken, // [IN] Public key or token of the assembly. ULONG cbPublicKeyOrToken, // [IN] Count of bytes in the public key or token. LPCWSTR szName, // [IN] Name of the assembly being referenced. const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData. const void *pbHashValue, // [IN] Hash Blob. ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob. DWORD dwAssemblyRefFlags, // [IN] Flags. mdAssemblyRef *pmar) // [OUT] Returned AssemblyRef token. { HRESULT hr = S_OK; AssemblyRefRec *pRecord = NULL; ULONG iRecord; if (szName == NULL || pmar == NULL || pMetaData == NULL) return E_INVALIDARG; BEGIN_ENTRYPOINT_NOTHROW; LOG((LOGMD, "RegMeta::DefineAssemblyRef(0x%08x, 0x%08x, %S, 0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", pbPublicKeyOrToken, cbPublicKeyOrToken, MDSTR(szName), pMetaData, pbHashValue, cbHashValue, dwAssemblyRefFlags, pmar)); START_MD_PERF(); LOCKWRITE(); IfFailGo(m_pStgdb->m_MiniMd.PreUpdate()); _ASSERTE(szName && pmar); if (CheckDups(MDDupAssemblyRef)) { LPUTF8 szUTF8Name, szUTF8Locale; UTF8STR(szName, szUTF8Name); UTF8STR(pMetaData->szLocale, szUTF8Locale); hr = ImportHelper::FindAssemblyRef(&m_pStgdb->m_MiniMd, szUTF8Name, szUTF8Locale, pbPublicKeyOrToken, cbPublicKeyOrToken, pMetaData->usMajorVersion, pMetaData->usMinorVersion, pMetaData->usBuildNumber, pMetaData->usRevisionNumber, dwAssemblyRefFlags, pmar); if (SUCCEEDED(hr)) { if (IsENCOn()) { IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRefRecord(RidFromToken(*pmar), &pRecord)); } else { hr = META_S_DUPLICATE; goto ErrExit; } } else if (hr != CLDB_E_RECORD_NOTFOUND) { IfFailGo(hr); } } // Create a new record if needed. if (pRecord == NULL) { // Create a new record. IfFailGo(m_pStgdb->m_MiniMd.AddAssemblyRefRecord(&pRecord, &iRecord)); // Set the output parameter. *pmar = TokenFromRid(iRecord, mdtAssemblyRef); } // Set rest of the attributes. SetCallerDefine(); IfFailGo(_SetAssemblyRefProps(*pmar, pbPublicKeyOrToken, cbPublicKeyOrToken, szName, pMetaData, pbHashValue, cbHashValue, dwAssemblyRefFlags)); ErrExit: SetCallerExternal(); STOP_MD_PERF(DefineAssemblyRef); END_ENTRYPOINT_NOTHROW; return hr; } // RegMeta::DefineAssemblyRef