Example #1
0
//*******************************************************************************
// 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
Example #2
0
//*******************************************************************************
// 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
Example #3
0
//*******************************************************************************
// 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
Example #4
0
//*******************************************************************************
// 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
Example #5
0
//*******************************************************************************
// 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
Example #6
0
//*******************************************************************************
// 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