Example #1
0
HRESULT AssemblySpec::LowLevelLoadManifestFile(PEFile** ppFile,
                                               IAssembly** ppIAssembly,
                                               Assembly **ppDynamicAssembly,
                                               OBJECTREF* pExtraEvidence,
                                               OBJECTREF* pThrowable)
{
    CANNOTTHROWCOMPLUSEXCEPTION();

    HRESULT hr = S_OK;
    IAssemblyName* pFusionAssemblyName = NULL;     // Assembly object to assembly in fusion cache

    if(!(m_pAssemblyName || m_CodeInfo.m_pszCodeBase)) {
        PostFileLoadException("", FALSE, NULL, COR_E_FILENOTFOUND, pThrowable);
        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
    }

    //
    // Check to see if this fits our rather loose idea of a reference to mscorlib.
    // If so, don't use fusion to bind it - do it ourselves.
    //

    if (IsMscorlib())
    {
        _ASSERTE(wcslen(SystemDomain::System()->BaseLibrary()) > 0);
        hr = PEFile::Create(SystemDomain::System()->BaseLibrary(), 
                            NULL, 
                            mdFileNil, 
                            TRUE, 
                            NULL, 
                            NULL, // Code base is the same as the name
                            NULL, // Extra Evidence
                            ppFile);
        _ASSERTE((*ppFile)->IsSystem());
        if (ppDynamicAssembly) *ppDynamicAssembly = NULL;
        return hr;
    }

    CQuickWSTR FusionLog;
    FusionLog.Ptr()[0]=L'\0';

    BEGIN_ENSURE_PREEMPTIVE_GC();

    Assembly *pAssembly = NULL;
    PEFile *pFile = NULL;

    hr = CreateFusionName(&pFusionAssemblyName);
    if (FAILED(hr))
        goto exit;

    hr = pFusionAssemblyName->SetProperty(ASM_NAME_NULL_CUSTOM,NULL,0); //do not look in ZAP
    if (FAILED(hr))
        goto exit;

    hr = GetAssemblyFromFusion(GetAppDomain(),
                               pFusionAssemblyName,
                               &m_CodeInfo,
                               ppIAssembly,
                               &pFile,
                               &FusionLog,
                               pExtraEvidence,
                               pThrowable);
    if(FAILED(hr)) {

            DWORD cb = 0;
            pFusionAssemblyName->GetDisplayName(NULL, &cb, 0);
            if(cb) {
                CQuickBytes qb;
                LPWSTR pwsFullName = (LPWSTR) qb.Alloc(cb*sizeof(WCHAR));

                if (SUCCEEDED(pFusionAssemblyName->GetDisplayName(pwsFullName, &cb, 0))) {
                if ((pAssembly = GetAppDomain()->RaiseAssemblyResolveEvent(pwsFullName, pThrowable)) != NULL) {
                        pFile = pAssembly->GetManifestFile();
                        hr = S_FALSE;
                    }
                }
            }

#ifdef _DEBUG
        if(FAILED(hr)) {
            if (m_pAssemblyName)
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load from full name, %s\n", m_pAssemblyName));
            else if (m_CodeInfo.m_pszCodeBase)
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load from codebase, %s\n",m_CodeInfo.m_pszCodeBase));
            else
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load unknown assembly.\n"));
        }
#endif //_DEBUG

    }

 exit:
    if (SUCCEEDED(hr)) {
        if (ppFile) *ppFile = pFile;
        if (ppDynamicAssembly) *ppDynamicAssembly = pAssembly;
    }

    if(pFusionAssemblyName)
        pFusionAssemblyName->Release();

    END_ENSURE_PREEMPTIVE_GC();

    if (FAILED(hr)) {
        if (m_pAssemblyName)
            PostFileLoadException(m_pAssemblyName, FALSE,FusionLog.Ptr(), hr, pThrowable);
        else {
            MAKE_UTF8PTR_FROMWIDE(szName, m_CodeInfo.m_pszCodeBase);
            PostFileLoadException(szName, TRUE,FusionLog.Ptr(), hr, pThrowable);
        }
    }

    return hr;
}
Example #2
0
HRESULT AssemblySpec::GetAssemblyFromFusion(AppDomain* pAppDomain,
                                            IAssemblyName* pFusionAssemblyName,
                                            CodeBaseInfo* pCodeBase,
                                            IAssembly** ppFusionAssembly,
                                            PEFile** ppFile,
                                            CQuickWSTR* pFusionLog,
                                            OBJECTREF* pExtraEvidence,
                                            OBJECTREF* pThrowable)
{
    _ASSERTE(ppFile);
    HRESULT hr = S_OK;
    IAssembly *pFusionAssembly = NULL;

    COMPLUS_TRY {
        DWORD dwSize = MAX_PATH;
        CQuickWSTR bufferPath;
        WCHAR *pPath = NULL;
        AssemblySink* pSink;
        DWORD eLocation;

        CQuickWSTR bufferCodebase;
        LPWSTR pwsCodeBase = NULL;
        DWORD  dwCodeBase = 0;
        IAssemblyName *pNameDef = NULL;
        
        IApplicationContext *pFusionContext = pAppDomain->GetFusionContext();
        pSink = pAppDomain->GetAssemblySink();
        if(!pSink) {
            hr = E_OUTOFMEMORY;
            COMPLUS_LEAVE;
        }
        
        pSink->pFusionLog=pFusionLog;
        hr = FusionBind::GetAssemblyFromFusion(pFusionContext,
                                               pSink,
                                               pFusionAssemblyName,
                                               pCodeBase,
                                               &pFusionAssembly);
        pSink->pFusionLog=NULL;
        if(SUCCEEDED(hr)) {
            _ASSERTE(pFusionAssembly);

            // Get the path to the module containing the manifest
            dwSize = bufferPath.MaxSize();
            pPath = bufferPath.Ptr();
            hr = pFusionAssembly->GetManifestModulePath(pPath,
                                                        &dwSize);
            if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
                pPath = bufferPath.Alloc(dwSize);
                if (pPath == NULL) {
                    hr = E_OUTOFMEMORY;
                    COMPLUS_LEAVE;
                }
                hr = pFusionAssembly->GetManifestModulePath(pPath,
                                                        &dwSize);
            }

            if(SUCCEEDED(hr)) {
                hr = pFusionAssembly->GetAssemblyNameDef(&pNameDef);
                if (SUCCEEDED(hr)) {
                    dwCodeBase = bufferCodebase.MaxSize();
                    pwsCodeBase = bufferCodebase.Ptr();
                    hr = pNameDef->GetProperty(ASM_NAME_CODEBASE_URL, pwsCodeBase, &dwCodeBase);
                    if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) {
                        pwsCodeBase = bufferCodebase.Alloc(dwCodeBase);
                        if (pwsCodeBase == NULL) {
                            hr = E_OUTOFMEMORY;
                            COMPLUS_LEAVE;
                        }
                        hr = pNameDef->GetProperty(ASM_NAME_CODEBASE_URL, pwsCodeBase, &dwCodeBase);
                    }
                    pNameDef->Release();
                }
            }
        }
        pSink->Release();

        if(hr == S_OK && dwSize) {
            // See if we need to perform a strong name verification.
            hr = pFusionAssembly->GetAssemblyLocation(&eLocation);


            if (SUCCEEDED(hr)) {
                switch ((eLocation & ASMLOC_LOCATION_MASK)) {
                case ASMLOC_GAC:
                case ASMLOC_DOWNLOAD_CACHE:
                case ASMLOC_UNKNOWN:
                    // Assemblies from the GAC or download cache have
                    // already been verified by Fusion. Location Unknown
                    // indicates a load from the dev path, which we'll
                    // assume isn't a interesting case for verification.
                    hr = S_OK;
                    break;
                case ASMLOC_RUN_FROM_SOURCE:
                    // For now, just verify these every time, we need to
                    // cache the fact that at least one verification has
                    // been performed (if strong name policy permits
                    if (SUCCEEDED(hr)&&(eLocation&ASMLOC_CODEBASE_HINT))
                    {
                        hr=CheckFileAccess(pPath,FILE_READ_DATA);
                        if (FAILED(hr))
                            break;
                    }
                    // caching of verification results).
                    if (StrongNameSignatureVerification(pPath,
                                                        SN_INFLAG_INSTALL|SN_INFLAG_ALL_ACCESS|SN_INFLAG_RUNTIME,
                                                        NULL))
                        hr = S_OK;
                    else {
                        hr = StrongNameErrorInfo();
                        if (hr == CORSEC_E_MISSING_STRONGNAME)
                            hr = S_OK;
                        else
                            hr = CORSEC_E_INVALID_STRONGNAME;
                    }
                    break;
                default:
                    _ASSERTE(FALSE);
                }
                if (SUCCEEDED(hr)) {
                    hr = SystemDomain::LoadFile(pPath, 
                                                NULL, 
                                                mdFileNil, 
                                                FALSE, 
                                                pFusionAssembly, 
                                                pwsCodeBase,
                                                pExtraEvidence,
                                                ppFile,
                                                FALSE);
                    if (SUCCEEDED(hr)) {
                        if(ppFusionAssembly) {
                            pFusionAssembly->AddRef();
                            *ppFusionAssembly = pFusionAssembly;
                        }
                        if((eLocation & ASMLOC_LOCATION_MASK) == ASMLOC_GAC)
                            // Assemblies in the GAC have also had any internal module
                            // hashes verified at install time.
                            (*ppFile)->SetHashesVerified();
                    }
                }
            }
            else if (hr == E_NOTIMPL) {
                // process exe
                _ASSERTE(pAppDomain == SystemDomain::System()->DefaultDomain());
                hr = PEFile::Clone(SystemDomain::System()->DefaultDomain()->m_pRootFile, ppFile);
                if(SUCCEEDED(hr) && ppFusionAssembly) {
                    pFusionAssembly->AddRef();
                    *ppFusionAssembly = pFusionAssembly;
                }
            }
        }
    }
    COMPLUS_CATCH {
        BEGIN_ENSURE_COOPERATIVE_GC();
        if (pThrowable) 
        {
            *pThrowable = GETTHROWABLE();
            hr = SecurityHelper::MapToHR(*pThrowable);
        }
        else
            hr = SecurityHelper::MapToHR(GETTHROWABLE());
        END_ENSURE_COOPERATIVE_GC();
    } COMPLUS_END_CATCH
 
    if (pFusionAssembly)
        pFusionAssembly->Release();

    return hr;
}
Example #3
0
VOID InitLogging()
{
    STATIC_CONTRACT_NOTHROW;
    
        // <TODO>FIX bit of a workaround for now, check for the log file in the
        // registry and if there, turn on file logging VPM</TODO>
    
    LogFlags |= REGUTIL::GetConfigFlag_DontUse_(CLRConfig::INTERNAL_LogEnable, LOG_ENABLE);    
    LogFacilityMask = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogFacility, LogFacilityMask) | LF_ALWAYS;
    LogVMLevel = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_LogLevel, LogVMLevel);
    LogFlags |= REGUTIL::GetConfigFlag_DontUse_(CLRConfig::INTERNAL_LogFileAppend, LOG_ENABLE_APPEND_FILE);
    LogFlags |= REGUTIL::GetConfigFlag_DontUse_(CLRConfig::INTERNAL_LogFlushFile,  LOG_ENABLE_FLUSH_FILE);
    LogFlags |= REGUTIL::GetConfigFlag_DontUse_(CLRConfig::INTERNAL_LogToDebugger, LOG_ENABLE_DEBUGGER_LOGGING);
    LogFlags |= REGUTIL::GetConfigFlag_DontUse_(CLRConfig::INTERNAL_LogToFile,     LOG_ENABLE_FILE_LOGGING);
    LogFlags |= REGUTIL::GetConfigFlag_DontUse_(CLRConfig::INTERNAL_LogToConsole,  LOG_ENABLE_CONSOLE_LOGGING);
    
    LogFacilityMask2 = REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogFacility2, LogFacilityMask2) | LF_ALWAYS;

    if (SUCCEEDED(szLogFileName.ReSizeNoThrow(MAX_LONGPATH)))
    {
        wcscpy_s(szLogFileName.Ptr(), szLogFileName.Size(), DEFAULT_LOGFILE_NAME);
    }

    LPWSTR fileName = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_LogFile);
    if (fileName != 0)
    {
        if (SUCCEEDED(szLogFileName.ReSizeNoThrow(wcslen(fileName) + 32)))
        {
            wcscpy_s(szLogFileName.Ptr(), szLogFileName.Size(), fileName);
        }
        delete fileName;
    }

    if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogWithPid, FALSE))
    {
        WCHAR szPid[20];
        swprintf_s(szPid, COUNTOF(szPid), W(".%d"), GetCurrentProcessId());
        wcscat_s(szLogFileName.Ptr(), szLogFileName.Size(), szPid);
    }

    if ((LogFlags & LOG_ENABLE) &&
        (LogFlags & LOG_ENABLE_FILE_LOGGING) &&
        (szLogFileName.Size() > 0) &&
        (LogFileHandle == INVALID_HANDLE_VALUE))
    {
        DWORD fdwCreate = (LogFlags & LOG_ENABLE_APPEND_FILE) ? OPEN_ALWAYS : CREATE_ALWAYS;
        LogFileHandle = WszCreateFile(
            szLogFileName.Ptr(),
            GENERIC_WRITE,
            FILE_SHARE_READ,
            NULL,
            fdwCreate,
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN |  ((LogFlags & LOG_ENABLE_FLUSH_FILE) ? FILE_FLAG_WRITE_THROUGH : 0),
            NULL);

        if(0 == LogFileMutex)
        {
            LogFileMutex = ClrCreateMutex(
                NULL,
                FALSE,
                NULL);
            _ASSERTE(LogFileMutex != 0);
        }

            // Some other logging may be going on, try again with another file name
        if (LogFileHandle == INVALID_HANDLE_VALUE && wcslen(szLogFileName.Ptr()) + 3 <= szLogFileName.Size())
        {
            WCHAR* ptr = szLogFileName.Ptr() + wcslen(szLogFileName.Ptr()) + 1;
            ptr[-1] = W('.');
            ptr[0] = W('0');
            ptr[1] = 0;

            for(int i = 0; i < 10; i++)
            {
                LogFileHandle = WszCreateFile(
                    szLogFileName.Ptr(),
                    GENERIC_WRITE,
                    FILE_SHARE_READ,
                    NULL,
                    fdwCreate,
                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN |  ((LogFlags & LOG_ENABLE_FLUSH_FILE) ? FILE_FLAG_WRITE_THROUGH : 0),
                    NULL);
                if (LogFileHandle != INVALID_HANDLE_VALUE)
                    break;
                *ptr = *ptr + 1;
            }
            if (LogFileHandle == INVALID_HANDLE_VALUE) {
                int ret = WszWideCharToMultiByte(CP_ACP, 0, szLogFileName.Ptr(), -1, NULL, 0, NULL, NULL);
                const char *msg = "Could not open log file, logging to ";
                DWORD msgLen = (DWORD)strlen(msg);
                CQuickSTR buff;
                if (SUCCEEDED(buff.ReSizeNoThrow(ret + msgLen)))
                {
                    strcpy_s(buff.Ptr(), buff.Size(), msg);
                    WszWideCharToMultiByte(CP_ACP, 0, szLogFileName.Ptr(), -1, buff.Ptr() + msgLen, ret, NULL, NULL);
                    msg = buff.Ptr();
                }
                else
                {
                    msg = "Could not open log file";
                }
                DWORD       written;
                WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msg, (DWORD)strlen(msg), &written, 0);
            }
        }
        if (LogFileHandle == INVALID_HANDLE_VALUE)
            UtilMessageBoxNonLocalized(NULL, W("Could not open log file"), W("CLR logging"), MB_OK | MB_ICONINFORMATION, FALSE, TRUE);
        if (LogFileHandle != INVALID_HANDLE_VALUE)
        {
            if (LogFlags & LOG_ENABLE_APPEND_FILE)
                SetFilePointer(LogFileHandle, 0, NULL, FILE_END);
            LogSpew( LF_ALWAYS, FATALERROR, "************************ New Output *****************\n" );
        }
    }
}