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); }
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 }
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; } }
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; }
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; }
// // 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; } } }
// // 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); }