Пример #1
0
HRESULT CAsmLink::GetAssemblyRefHash(mdToken FileToken, const void** ppvHash, DWORD* pcbHash)
{
    if (TypeFromToken(FileToken) != mdtAssemblyRef) {
        VSFAIL( "You can only get AssemblyRef hashes for assemblies!");
        return E_INVALIDARG;
    }

    HRESULT hr;
    CAssemblyFile *file = NULL;
    if (FAILED(hr = m_pImports->GetFile( FileToken, (CFile**)&file)))
        return hr;

    return file->GetHash(ppvHash, pcbHash);
}
Пример #2
0
BOOL WINAPI DllMain(
    HINSTANCE hInstance,
    DWORD dwReason,
    LPVOID /*lpReserved*/)
{
    if (dwReason == DLL_PROCESS_ATTACH)
    {
#if DEBUG
        // Make it so we don't have to recompile vbhosted every time we need to debug a suite
        if ( 0 != GetEnvironmentVariable(L"DEBUG_VBHOSTED", NULL, 0) )
        {
            VSFAIL("Attach");
        }
#endif

        if ( g_vbCommonHeap == INVALID_HANDLE_VALUE || !g_pvbNorlsManager) 
        {
            return FALSE;
        }

        g_hinstDll = hInstance;
		// Disabled DLL_THREAD_ATTACH/DETACH notifications
        DisableThreadLibraryCalls(hInstance);   // ignore return error
        
        // Pre-bind the LegacyActivationShim. This is required because the default
        // behaviour of the LegacyActivationShim is to use the binding context of
        // the process, and since this is hosted we can't trust that it will bind
        // to v4. Should only be possible to fail if the DLL finds itself installed
        // on a machine that does not have v4 installed (which shouldn't happen).
        if (FAILED(LegacyActivationShim::Util::BindToV4()))
            return FALSE;
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {

        // msvb7.dll is being unloaded -- see if there are any known
        // compiler resource leaks
        DebCheckForResourceLeaks();

        _Module.Term(); //. no return error.

    }

    return TRUE;    // ok
}
Пример #3
0
void
Bindable::RelationalOperatorPool::Add
(
    UserDefinedOperators Operator,
    BCSYM_UserDefinedOperator *Symbol
)
{
    VSASSERT(!IsCollated, "Adding to the pool after it has already been collated!");

    switch (Operator)
    {
        case OperatorIsTrue:       AddMatchingOperator(m_IsTrue, m_IsFalse, Symbol); break;
        case OperatorIsFalse:      AddMatchingOperator(m_IsFalse, m_IsTrue, Symbol); break;
        case OperatorEqual:        AddMatchingOperator(m_Equal, m_NotEqual, Symbol); break;
        case OperatorNotEqual:     AddMatchingOperator(m_NotEqual, m_Equal, Symbol); break;
        case OperatorLess:         AddMatchingOperator(m_Less, m_Greater, Symbol); break;
        case OperatorLessEqual:    AddMatchingOperator(m_LessEqual, m_GreaterEqual, Symbol); break;
        case OperatorGreaterEqual: AddMatchingOperator(m_GreaterEqual, m_LessEqual, Symbol); break;
        case OperatorGreater:      AddMatchingOperator(m_Greater, m_Less, Symbol); break;

#if DEBUG
        case OperatorUNDEF: __fallthrough;
        case OperatorMAXVALID: __fallthrough;
        case OperatorNot2: __fallthrough;
        case OperatorOr2: __fallthrough;
        case OperatorAnd2: __fallthrough;
        case OperatorShiftLeft2: __fallthrough;
        case OperatorShiftRight2: __fallthrough;
        case OperatorMAX:
            VSFAIL("unexpected operator kind");
            __fallthrough;
#endif
        default:
            // do nothing
            break;
    }
}
Пример #4
0
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;
}
Пример #5
0
LOCKKEY CLockBase::AcquireLock (BOOL fWrite)
{
    CLockState  *pState = GetLockState();

    if (pState == NULL)
    {
        VSFAIL ("LOCK STATE FAILURE!");
        return ACQUIRED_NOTHING;
    }

    BOOL        fIsLocked = pState->IsLocked (this);

    // Shortcut
    if (fIsLocked && !fWrite)
        return ACQUIRED_NOTHING;

    // Must acquire lock busy state
GetLockBusy:
    while (InterlockedExchange ((LONG *)&m_iLock, 1) != 0)
        Snooze ();

    if (fWrite)
    {
        if (fIsLocked)
        {
            if (m_fWrite)
            {
                // We're already writing...
                m_iLock = 0;
                return ACQUIRED_NOTHING;
            }

            if (m_iReadThreads == 1)
            {
                // We're reading alone, so we can be upgraded to writer...
                m_fWrite = TRUE;
                m_iLock = 0;
                return ACQUIRED_WRITE;
            }

            ASSERT (m_iReadThreads > 1);

            // Readers exist.  Release lock busy flag, wait until only one reader (us), and try again
            m_iLock = 0;
            while (m_iReadThreads > 1)
                Snooze ();

            goto GetLockBusy;
        }

        if (!m_fWrite && (m_iReadThreads == 0))
        {
            // Lock is available for write.  A write lock is also a read lock.
            m_fWrite = TRUE;
            m_iReadThreads = 1;
            pState->Lock (this);
            m_iLock = 0;
            return ACQUIRED_READWRITE;
        }

        // Lock is unavailable for write -- release lock busy flag and try again
        m_iLock = 0;
        Snooze ();
        goto GetLockBusy;
    }

    if (fIsLocked)
        return ACQUIRED_NOTHING;

    if (m_fWrite)
    {
        // Lock is unavailable for read -- release lock busy flag and try again
        m_iLock = 0;
        Snooze ();
        goto GetLockBusy;
    }

    // Lock is available for read.
    m_iReadThreads++;
    pState->Lock (this);
    m_iLock = 0;
    return ACQUIRED_READ;
}
Пример #6
0
//
// Process Auto Config options:
// #1 search for '/noconfig'
// if not present and csc.cfg exists in EXE dir, inject after env var stuff
//
void ConsoleArgs::ProcessAutoConfig()
{
    bool fFoundNoConfig = false;

    // Scan the argument list for the "/noconfig" options. If present, just kill it and bail.
    for (WStrList * listArgCur = m_listArgs; listArgCur; listArgCur = listArgCur->next)
    {
        // Skip everything except options
        WCHAR * szArg = listArgCur->arg;
        if (szArg == NULL || (szArg[0] != '/' && szArg[0] != '-'))
            continue;

        if (_wcsicmp(szArg + 1, L"noconfig") == 0) {
            listArgCur->arg = NULL;
            VSFree(szArg);
            // We found it, empty it but keep checking in case they specified it twice
            fFoundNoConfig = true;
        }
    }

    if (fFoundNoConfig)
        return;

    // If we got here it means there was no '/noconfig'
    WCHAR szPath[MAX_PATH];
    if (W_IsUnicodeSystem()) {
        if(!GetModuleFileNameW(NULL, szPath, lengthof(szPath)))
            szPath[0] = 0;
    } else {
        CHAR szTemp[MAX_PATH];
        if (!GetModuleFileNameA(NULL, szTemp, lengthof(szTemp)) ||
            !MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP,
                0, szTemp, -1, szPath, lengthof(szPath)))
            szPath[0] = 0;
    }
    if (*szPath && PathRemoveFileSpecW(szPath) &&
        PathAppendW(szPath, L"csc.rsp")) {

        if (W_Access( szPath, 4) == 0) { 
            // We know the file exists and that we have read access
            // so add into the list
            size_t cchLen = wcslen(szPath) + 2; // +2 for @ and terminator
            WCHAR * szPathCopy = (WCHAR*)VSAlloc( sizeof(WCHAR) * cchLen);
            if (!szPathCopy || FAILED(StringCchCopyW(szPathCopy + 1, cchLen, szPath))) {
                VSFAIL("The string changed size, or our pointers got messed up");
                m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
                return;
            }
            szPathCopy[0] = L'@';

            WStrList * listArgNew = new WStrList( szPathCopy, m_listArgs);
            if (!listArgNew) {
                VSFree(szPathCopy);
                m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
                return;
            }

            m_listArgs = listArgNew;
        }
    }
}
Пример #7
0
//
// Parse the text into a list of argument
// return the total count 
// and set 'args' to point to the last list element's 'next'
// This function assumes the text is NULL terminated
//
void ConsoleArgs::TextToArgs(LPCWSTR szText, WStrList ** listReplace)
{
    WStrList **argLast;
    const WCHAR *pCur;
    size_t iSlash;
    int iCount;

    argLast = listReplace;
    pCur = szText;
    iCount = 0;

    // Guaranteed that all tokens are no bigger than the entire file.
    LPWSTR szTemp = (LPWSTR)VSAlloc(sizeof(WCHAR) * (wcslen(szText) + 1));
    if (!szTemp) {
        m_output->ShowErrorId (FTL_NoMemory, ERROR_FATAL);
        return;
    }
    while (*pCur != '\0')
    {
        WCHAR *pPut, *pFirst, *pLast;
        WCHAR chIllegal;

LEADINGWHITE:
        while (IsWhitespace( *pCur) && *pCur != '\0')
            pCur++;

        if (*pCur == '\0')
            break;
        else if (*pCur == L'#')
        {
            while ( *pCur != '\0' && *pCur != '\n')
                pCur++; // Skip to end of line
            goto LEADINGWHITE;
        }

        int cQuotes = 0;
        pPut = pFirst = szTemp;
        chIllegal = 0;
        while ((!IsWhitespace( *pCur) || !!(cQuotes & 1)) && *pCur != '\0')
        {
            switch (*pCur)
            {
                // All this weird slash stuff follows the standard argument processing routines
            case L'\\':
                iSlash = 0;
                // Copy and advance while counting slashes
                while (*pCur == L'\\') {
                    *pPut++ = *pCur++;
                    iSlash++;
                }

                // Slashes not followed by a quote character don't matter now
                if (*pCur != L'\"')
                    break;

                // If there's an odd count of slashes, it's escaping the quote
                // Otherwise the quote is a quote
                if ((iSlash & 1) == 0) {
                    ++cQuotes;
                }
                *pPut++ = *pCur++;
                break;

            case L'\"':
                ++cQuotes;
                *pPut++ = *pCur++;
                break;

            case L'\x01': case L'\x02': case L'\x03': case L'\x04': case L'\x05': case L'\x06': case L'\x07': case L'\x08':
            case L'\x09': case L'\x0A': case L'\x0B': case L'\x0C': case L'\x0D': case L'\x0E': case L'\x0F': case L'\x10':
            case L'\x11': case L'\x12': case L'\x13': case L'\x14': case L'\x15': case L'\x16': case L'\x17': case L'\x18':
            case L'\x19': case L'\x1A': case L'\x1B': case L'\x1C': case L'\x1D': case L'\x1E': case L'\x1F':
            case L'|':
                // Save the first legal character and skip over them
                if (chIllegal == 0)
                    chIllegal = *pCur;
                pCur++;
                break;

            default:
                *pPut++ = *pCur++;  // Copy the char and advance
                break;
            }
        }

        pLast = pPut;
        *pPut++ = '\0';

        // If the string is surrounded by quotes, with no interior quotes, remove them.
        if (cQuotes == 2 && *pFirst == L'\"' && *(pLast - 1) == L'\"') {
            ++pFirst;
            --pLast;
            *pLast = L'\0';
        }

        if (chIllegal != 0) {
            m_output->ShowErrorIdString( ERR_IllegalOptionChar, ERROR_ERROR, chIllegal, pFirst);
        }

        size_t cchLen = pLast - pFirst + 1;
        WCHAR * szArgCopy = (WCHAR*)VSAlloc( sizeof(WCHAR) * cchLen);
        if (!szArgCopy || FAILED(StringCchCopyW(szArgCopy, cchLen, pFirst))) {
            VSFAIL("The string changed size, or our pointers got messed up");
            m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
            break;
        }

        WStrList * listArgNew = new WStrList( szArgCopy, (*argLast));
        if (!listArgNew) {
            m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
            break;
        }

        *argLast = listArgNew;
        argLast = &listArgNew->next;
    }

    VSFree(szTemp);

}