summaryrefslogtreecommitdiff
path: root/src/md/compiler/assemblymd_emit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/md/compiler/assemblymd_emit.cpp')
-rw-r--r--src/md/compiler/assemblymd_emit.cpp811
1 files changed, 811 insertions, 0 deletions
diff --git a/src/md/compiler/assemblymd_emit.cpp b/src/md/compiler/assemblymd_emit.cpp
new file mode 100644
index 0000000000..72fb034221
--- /dev/null
+++ b/src/md/compiler/assemblymd_emit.cpp
@@ -0,0 +1,811 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+//*****************************************************************************
+// AssemblyMD.cpp
+//
+
+//
+// Implementation for the assembly meta data emit code (code:IMetaDataAssemblyEmit).
+//
+//*****************************************************************************
+#include "stdafx.h"
+#include "regmeta.h"
+#include "mdutil.h"
+#include "rwutil.h"
+#include "mdlog.h"
+#include "importhelper.h"
+
+#include <strongname.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4102)
+#endif
+
+#ifdef FEATURE_METADATA_EMIT
+
+//*******************************************************************************
+// 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 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
+
+//*******************************************************************************
+// 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 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 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
+
+//*******************************************************************************
+// Set the specified attributes on the given Assembly token.
+//*******************************************************************************
+STDMETHODIMP RegMeta::SetAssemblyProps( // S_OK or error.
+ mdAssembly ma, // [IN] Assembly token.
+ 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.
+{
+ HRESULT hr = S_OK;
+
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ _ASSERTE(TypeFromToken(ma) == mdtAssembly && RidFromToken(ma));
+
+ LOG((LOGMD, "RegMeta::SetAssemblyProps(%#08x, %#08x, %#08x, %#08x %S, %#08x, %#08x)\n",
+ ma, pbPublicKey, cbPublicKey, ulHashAlgId, MDSTR(szName), pMetaData, dwAssemblyFlags));
+
+ START_MD_PERF();
+ LOCKWRITE();
+
+ IfFailGo(m_pStgdb->m_MiniMd.PreUpdate());
+
+ IfFailGo(_SetAssemblyProps(ma, pbPublicKey, cbPublicKey, ulHashAlgId, szName, pMetaData, dwAssemblyFlags));
+
+ErrExit:
+ STOP_MD_PERF(SetAssemblyProps);
+ END_ENTRYPOINT_NOTHROW;
+
+ return hr;
+} // STDMETHODIMP SetAssemblyProps()
+
+//*******************************************************************************
+// Set the specified attributes on the given AssemblyRef token.
+//*******************************************************************************
+STDMETHODIMP RegMeta::SetAssemblyRefProps( // S_OK or error.
+ mdAssemblyRef ar, // [IN] AssemblyRefToken.
+ 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.
+{
+ HRESULT hr = S_OK;
+
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ _ASSERTE(TypeFromToken(ar) == mdtAssemblyRef && RidFromToken(ar));
+
+ LOG((LOGMD, "RegMeta::SetAssemblyRefProps(0x%08x, 0x%08x, 0x%08x, %S, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n",
+ ar, pbPublicKeyOrToken, cbPublicKeyOrToken, MDSTR(szName), pMetaData, pbHashValue, cbHashValue,
+ dwAssemblyRefFlags));
+
+ START_MD_PERF();
+ LOCKWRITE();
+
+ IfFailGo(m_pStgdb->m_MiniMd.PreUpdate());
+
+ IfFailGo(_SetAssemblyRefProps(
+ ar,
+ pbPublicKeyOrToken,
+ cbPublicKeyOrToken,
+ szName,
+ pMetaData,
+ pbHashValue,
+ cbHashValue,
+ dwAssemblyRefFlags));
+
+ErrExit:
+ STOP_MD_PERF(SetAssemblyRefProps);
+ END_ENTRYPOINT_NOTHROW;
+
+ return hr;
+} // RegMeta::SetAssemblyRefProps
+
+//*******************************************************************************
+// Set the specified attributes on the given File token.
+//*******************************************************************************
+STDMETHODIMP RegMeta::SetFileProps( // S_OK or error.
+ mdFile file, // [IN] File token.
+ const void *pbHashValue, // [IN] Hash Blob.
+ ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob.
+ DWORD dwFileFlags) // [IN] Flags.
+{
+ HRESULT hr = S_OK;
+
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+
+ _ASSERTE(TypeFromToken(file) == mdtFile && RidFromToken(file));
+
+ LOG((LOGMD, "RegMeta::SetFileProps(%#08x, %#08x, %#08x, %#08x)\n",
+ file, pbHashValue, cbHashValue, dwFileFlags));
+ START_MD_PERF();
+ LOCKWRITE();
+
+ IfFailGo(m_pStgdb->m_MiniMd.PreUpdate());
+
+ IfFailGo( _SetFileProps(file, pbHashValue, cbHashValue, dwFileFlags) );
+
+ErrExit:
+
+ STOP_MD_PERF(SetFileProps);
+ END_ENTRYPOINT_NOTHROW;
+
+ return hr;
+} // RegMeta::SetFileProps
+
+//*******************************************************************************
+// Set the specified attributes on the given ExportedType token.
+//*******************************************************************************
+STDMETHODIMP RegMeta::SetExportedTypeProps( // S_OK or error.
+ mdExportedType ct, // [IN] ExportedType token.
+ mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ExportedType.
+ mdTypeDef tkTypeDef, // [IN] TypeDef token within the file.
+ DWORD dwExportedTypeFlags) // [IN] Flags.
+{
+ HRESULT hr = S_OK;
+
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+
+ LOG((LOGMD, "RegMeta::SetExportedTypeProps(%#08x, %#08x, %#08x, %#08x)\n",
+ ct, tkImplementation, tkTypeDef, dwExportedTypeFlags));
+
+ START_MD_PERF();
+ LOCKWRITE();
+
+ IfFailGo( _SetExportedTypeProps( ct, tkImplementation, tkTypeDef, dwExportedTypeFlags) );
+
+ErrExit:
+
+ STOP_MD_PERF(SetExportedTypeProps);
+ END_ENTRYPOINT_NOTHROW;
+
+ return hr;
+} // RegMeta::SetExportedTypeProps
+
+//*******************************************************************************
+// Set the specified attributes on the given ManifestResource token.
+//*******************************************************************************
+STDMETHODIMP RegMeta::SetManifestResourceProps(// S_OK or error.
+ mdManifestResource mr, // [IN] ManifestResource token.
+ 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.
+{
+ HRESULT hr = S_OK;
+
+ BEGIN_ENTRYPOINT_NOTHROW;
+
+ LOG((LOGMD, "RegMeta::SetManifestResourceProps(%#08x, %#08x, %#08x, %#08x)\n",
+ mr, tkImplementation, dwOffset,
+ dwResourceFlags));
+
+ _ASSERTE(TypeFromToken(tkImplementation) == mdtFile ||
+ TypeFromToken(tkImplementation) == mdtAssemblyRef ||
+ tkImplementation == mdTokenNil);
+
+ START_MD_PERF();
+ LOCKWRITE();
+
+ IfFailGo( _SetManifestResourceProps( mr, tkImplementation, dwOffset, dwResourceFlags) );
+
+ErrExit:
+
+ STOP_MD_PERF(SetManifestResourceProps);
+ END_ENTRYPOINT_NOTHROW;
+
+ return hr;
+} // STDMETHODIMP RegMeta::SetManifestResourceProps()
+
+//*******************************************************************************
+// Helper: Set the specified attributes on the given Assembly token.
+//*******************************************************************************
+HRESULT RegMeta::_SetAssemblyProps( // S_OK or error.
+ mdAssembly ma, // [IN] Assembly token.
+ const void *pbPublicKey, // [IN] Originator of the assembly.
+ ULONG cbPublicKey, // [IN] Count of bytes in the Originator blob.
+ ULONG ulHashAlgId, // [IN] Hash Algorithm.
+ LPCWSTR szName, // [IN] Name of the assembly.
+ const ASSEMBLYMETADATA *pMetaData, // [IN] Assembly MetaData.
+ DWORD dwAssemblyFlags) // [IN] Flags.
+{
+ AssemblyRec *pRecord = NULL; // The assembly record.
+ HRESULT hr = S_OK;
+
+ IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRecord(RidFromToken(ma), &pRecord));
+
+ // Set the data.
+ if (pbPublicKey)
+ IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_Assembly, AssemblyRec::COL_PublicKey,
+ pRecord, pbPublicKey, cbPublicKey));
+ if (ulHashAlgId != ULONG_MAX)
+ pRecord->SetHashAlgId(ulHashAlgId);
+ IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_Assembly, AssemblyRec::COL_Name, pRecord, szName));
+ if (pMetaData->usMajorVersion != USHRT_MAX)
+ pRecord->SetMajorVersion(pMetaData->usMajorVersion);
+ if (pMetaData->usMinorVersion != USHRT_MAX)
+ pRecord->SetMinorVersion(pMetaData->usMinorVersion);
+ if (pMetaData->usBuildNumber != USHRT_MAX)
+ pRecord->SetBuildNumber(pMetaData->usBuildNumber);
+ if (pMetaData->usRevisionNumber != USHRT_MAX)
+ pRecord->SetRevisionNumber(pMetaData->usRevisionNumber);
+ if (pMetaData->szLocale)
+ IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_Assembly, AssemblyRec::COL_Locale,
+ pRecord, pMetaData->szLocale));
+
+ dwAssemblyFlags = (dwAssemblyFlags & ~afPublicKey) | (cbPublicKey ? afPublicKey : 0);
+ pRecord->SetFlags(dwAssemblyFlags);
+ IfFailGo(UpdateENCLog(ma));
+
+ErrExit:
+
+
+ return hr;
+} // HRESULT RegMeta::_SetAssemblyProps()
+
+//*******************************************************************************
+// Helper: Set the specified attributes on the given AssemblyRef token.
+//*******************************************************************************
+HRESULT RegMeta::_SetAssemblyRefProps( // S_OK or error.
+ mdAssemblyRef ar, // [IN] AssemblyRefToken.
+ 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.
+{
+ AssemblyRefRec *pRecord;
+ HRESULT hr = S_OK;
+
+ IfFailGo(m_pStgdb->m_MiniMd.GetAssemblyRefRecord(RidFromToken(ar), &pRecord));
+
+ if (pbPublicKeyOrToken)
+ IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_PublicKeyOrToken,
+ pRecord, pbPublicKeyOrToken, cbPublicKeyOrToken));
+ if (szName)
+ IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_AssemblyRef, AssemblyRefRec::COL_Name,
+ pRecord, szName));
+ if (pMetaData)
+ {
+ if (pMetaData->usMajorVersion != USHRT_MAX)
+ pRecord->SetMajorVersion(pMetaData->usMajorVersion);
+ if (pMetaData->usMinorVersion != USHRT_MAX)
+ pRecord->SetMinorVersion(pMetaData->usMinorVersion);
+ if (pMetaData->usBuildNumber != USHRT_MAX)
+ pRecord->SetBuildNumber(pMetaData->usBuildNumber);
+ if (pMetaData->usRevisionNumber != USHRT_MAX)
+ pRecord->SetRevisionNumber(pMetaData->usRevisionNumber);
+ if (pMetaData->szLocale)
+ IfFailGo(m_pStgdb->m_MiniMd.PutStringW(TBL_AssemblyRef,
+ AssemblyRefRec::COL_Locale, pRecord, pMetaData->szLocale));
+
+ }
+ if (pbHashValue)
+ IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_AssemblyRef, AssemblyRefRec::COL_HashValue,
+ pRecord, pbHashValue, cbHashValue));
+ if (dwAssemblyRefFlags != ULONG_MAX)
+ pRecord->SetFlags(PrepareForSaving(dwAssemblyRefFlags));
+
+ IfFailGo(UpdateENCLog(ar));
+
+ErrExit:
+
+
+ return hr;
+} // RegMeta::_SetAssemblyRefProps
+
+//*******************************************************************************
+// Helper: Set the specified attributes on the given File token.
+//*******************************************************************************
+HRESULT RegMeta::_SetFileProps( // S_OK or error.
+ mdFile file, // [IN] File token.
+ const void *pbHashValue, // [IN] Hash Blob.
+ ULONG cbHashValue, // [IN] Count of bytes in the Hash Blob.
+ DWORD dwFileFlags) // [IN] Flags.
+{
+ FileRec *pRecord;
+ HRESULT hr = S_OK;
+
+ IfFailGo(m_pStgdb->m_MiniMd.GetFileRecord(RidFromToken(file), &pRecord));
+
+ if (pbHashValue)
+ IfFailGo(m_pStgdb->m_MiniMd.PutBlob(TBL_File, FileRec::COL_HashValue, pRecord,
+ pbHashValue, cbHashValue));
+ if (dwFileFlags != ULONG_MAX)
+ pRecord->SetFlags(dwFileFlags);
+
+ IfFailGo(UpdateENCLog(file));
+ErrExit:
+ return hr;
+} // RegMeta::_SetFileProps
+
+//*******************************************************************************
+// Helper: Set the specified attributes on the given ExportedType token.
+//*******************************************************************************
+HRESULT RegMeta::_SetExportedTypeProps( // S_OK or error.
+ mdExportedType ct, // [IN] ExportedType token.
+ mdToken tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ExportedType.
+ mdTypeDef tkTypeDef, // [IN] TypeDef token within the file.
+ DWORD dwExportedTypeFlags) // [IN] Flags.
+{
+ ExportedTypeRec *pRecord;
+ HRESULT hr = S_OK;
+
+ IfFailGo(m_pStgdb->m_MiniMd.GetExportedTypeRecord(RidFromToken(ct), &pRecord));
+
+ if(! IsNilToken(tkImplementation))
+ IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_ExportedType, ExportedTypeRec::COL_Implementation,
+ pRecord, tkImplementation));
+ if (! IsNilToken(tkTypeDef))
+ {
+ _ASSERTE(TypeFromToken(tkTypeDef) == mdtTypeDef);
+ pRecord->SetTypeDefId(tkTypeDef);
+ }
+ if (dwExportedTypeFlags != ULONG_MAX)
+ pRecord->SetFlags(dwExportedTypeFlags);
+
+ IfFailGo(UpdateENCLog(ct));
+ErrExit:
+ return hr;
+} // RegMeta::_SetExportedTypeProps
+
+//*******************************************************************************
+// Helper: Set the specified attributes on the given ManifestResource token.
+//*******************************************************************************
+HRESULT RegMeta::_SetManifestResourceProps(// S_OK or error.
+ mdManifestResource mr, // [IN] ManifestResource token.
+ 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.
+{
+ ManifestResourceRec *pRecord = NULL;
+ HRESULT hr = S_OK;
+
+ IfFailGo(m_pStgdb->m_MiniMd.GetManifestResourceRecord(RidFromToken(mr), &pRecord));
+
+ // Set the attributes.
+ if (tkImplementation != mdTokenNil)
+ IfFailGo(m_pStgdb->m_MiniMd.PutToken(TBL_ManifestResource,
+ ManifestResourceRec::COL_Implementation, pRecord, tkImplementation));
+ if (dwOffset != ULONG_MAX)
+ pRecord->SetOffset(dwOffset);
+ if (dwResourceFlags != ULONG_MAX)
+ pRecord->SetFlags(dwResourceFlags);
+
+ IfFailGo(UpdateENCLog(mr));
+
+ErrExit:
+ return hr;
+} // RegMeta::_SetManifestResourceProps
+
+#endif //FEATURE_METADATA_EMIT