//***************************************************************************** // Get the value of a CustomAttribute, using only TypeName for lookup. //***************************************************************************** STDMETHODIMP RegMeta::GetCustomAttributeByName( // S_OK or error. mdToken tkObj, // [IN] Object with Custom Attribute. LPCWSTR wzName, // [IN] Name of desired Custom Attribute. const void **ppData, // [OUT] Put pointer to data here. ULONG *pcbData) // [OUT] Put size of data here. { HRESULT hr; // A result. BEGIN_ENTRYPOINT_NOTHROW; LPUTF8 szName; // Name in UFT8. int iLen; // A length. CMiniMdRW *pMiniMd = NULL; START_MD_PERF(); LOCKREAD(); pMiniMd = &(m_pStgdb->m_MiniMd); iLen = WszWideCharToMultiByte(CP_UTF8,0, wzName,-1, NULL,0, 0,0); szName = (LPUTF8)_alloca(iLen); VERIFY(WszWideCharToMultiByte(CP_UTF8,0, wzName,-1, szName,iLen, 0,0)); hr = ImportHelper::GetCustomAttributeByName(pMiniMd, tkObj, szName, ppData, pcbData); ErrExit: STOP_MD_PERF(GetCustomAttributeByName); END_ENTRYPOINT_NOTHROW; return hr; } // STDMETHODIMP RegMeta::GetCustomAttributeByName()
// Private helper routine void WS_PERF_OUTPUT_HEAP_ACCOUNTS() { if(g_fWSPerfOn) { int i = 0, dwAlloc = 0, dwCommit = 0; swprintf(wszOutStr, L"Heap\t\tHptr\t\tAlloc\t\tCommit\t\tWaste\n"); WszWideCharToMultiByte (CP_ACP, 0, wszOutStr, -1, szPrintStr, FMT_STR_SIZE-1, 0, 0); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); while (i<MAX_HEAPS) { if(g_HeapAccounts[i][1] == -1) break; swprintf(wszOutStr, L"%d\t\t0x%08x\t%d\t\t%d\t\t%d\n", g_HeapAccounts[i][0], g_HeapAccounts[i][1], g_HeapAccounts[i][2], g_HeapAccounts[i][3], g_HeapAccounts[i][3] - g_HeapAccounts[i][2]); WszWideCharToMultiByte (CP_ACP, 0, wszOutStr, -1, szPrintStr, FMT_STR_SIZE-1, 0, 0); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); dwAlloc += g_HeapAccounts[i][2]; dwCommit += g_HeapAccounts[i][3]; i++; } swprintf(wszOutStr, L"Total\t\t\t\t%d\t\t%d\t\t%d\n", dwAlloc, dwCommit, dwCommit - dwAlloc); WszWideCharToMultiByte (CP_ACP, 0, wszOutStr, -1, szPrintStr, FMT_STR_SIZE-1, 0, 0); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); } }
// Private helper routine void WS_PERF_OUTPUT_MEM_STATS() { if (g_fWSPerfOn) { for (int i=0; i<NUM_HEAP; i++) { swprintf(wszOutStr, L"\n%d;%d\t", i, g_HeapCountCommit[i]); WszWideCharToMultiByte (CP_ACP, 0, wszOutStr, -1, szPrintStr, FMT_STR_SIZE-1, 0, 0); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); } swprintf(wszOutStr, L"\n\nTotal:%d\n", g_HeapCount); WszWideCharToMultiByte (CP_ACP, 0, wszOutStr, -1, szPrintStr, FMT_STR_SIZE-1, 0, 0); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); swprintf(wszOutStr, L"\n\nDetails:\nIndex;HeapType;NumVal;Alloced(bytes)\n"); WszWideCharToMultiByte (CP_ACP, 0, wszOutStr, -1, szPrintStr, FMT_STR_SIZE-1, 0, 0); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); for (i=0; i<NUM_COUNTERS; i++) { swprintf(wszOutStr, L"\n%d;%d;%d;%d\t", i, g_SpecialCounter[i][0], g_SpecialCounter[i][1], g_SpecialCounter[i][1]*g_CounterSize[i]); WszWideCharToMultiByte (CP_ACP, 0, wszOutStr, -1, szPrintStr, FMT_STR_SIZE-1, 0, 0); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); } } }
HRESULT CeeFileGenWriter::emitLibraryName(IMetaDataEmit *emitter) { HRESULT hr; IfFailRet(emitter->SetModuleProps(m_libraryName)); // Set the GUID as a custom attribute, if it is not NULL_GUID. if (m_libraryGuid != GUID_NULL) { static COR_SIGNATURE _SIG[] = INTEROP_GUID_SIG; mdTypeRef tr; mdMemberRef mr; WCHAR wzGuid[40]; BYTE rgCA[50]; IfFailRet(emitter->DefineTypeRefByName(mdTypeRefNil, INTEROP_GUID_TYPE_W, &tr)); IfFailRet(emitter->DefineMemberRef(tr, L".ctor", _SIG, sizeof(_SIG), &mr)); StringFromGUID2(m_libraryGuid, wzGuid, lengthof(wzGuid)); memset(rgCA, 0, sizeof(rgCA)); // Tag is 0x0001 rgCA[0] = 1; // Length of GUID string is 36 characters. rgCA[2] = 0x24; // Convert 36 characters, skipping opening {, into 3rd byte of buffer. WszWideCharToMultiByte(CP_ACP,0, wzGuid+1,36, reinterpret_cast<char*>(&rgCA[3]),36, 0,0); hr = emitter->DefineCustomAttribute(1,mr,rgCA,41,0); } return (hr); } // HRESULT CeeFileGenWriter::emitLibraryName()
HRESULT DumpMessage(HANDLE hFile, LPCWSTR pwzMsg) { HRESULT hr = S_OK; DWORD dwLen = 0; DWORD dwWritten = 0; CHAR szBuf[MAX_DBG_STR_LEN]; dwLen = WszWideCharToMultiByte(CP_UTF8, 0, pwzMsg, -1, szBuf, MAX_DBG_STR_LEN, NULL, false); if (!dwLen) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } // dwLen includes NULL terminator. We don't want to write this out. if (dwLen > 1) { dwLen--; if (!WriteFile(hFile, szBuf, dwLen, &dwWritten, NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } } Exit: return hr; }
void PerfLog::OutToPerfFile(__in_z const wchar_t *wszName, UnitOfMeasure unit, __in_opt const wchar_t *wszDescr) { LIMITED_METHOD_CONTRACT; char szPrintStr[PRINT_STR_LEN]; if (CommaSeparatedFormat()) { if (WszWideCharToMultiByte (CP_ACP, 0, m_wszOutStr_1, -1, szPrintStr, PRINT_STR_LEN-1, 0, 0) ) { if (0 == WriteFile (m_hPerfLogFileHandle, szPrintStr, (DWORD)strlen(szPrintStr), &m_dwWriteByte, NULL)) printf("ERROR: Could not write to perf log.\n"); } else wprintf(W("ERROR: Could not do string conversion.\n")); } else { wchar_t wszOutStr_2[PRINT_STR_LEN]; // workaround. The formats for ExecTime is slightly different from a custom value. if (wcscmp(wszName, W("ExecTime")) == 0) _snwprintf_s(wszOutStr_2, PRINT_STR_LEN, PRINT_STR_LEN - 1, W("ExecUnitDescr=%s\nExecIDirection=%s\n"), wszDescr, wszIDirection[unit]); else { if (wszDescr) _snwprintf_s(wszOutStr_2, PRINT_STR_LEN, PRINT_STR_LEN - 1, W("%s Descr=%s\n%s Unit Descr=None\n%s IDirection=%s\n"), wszName, wszDescr, wszName, wszName, wszIDirection[unit]); else _snwprintf_s(wszOutStr_2, PRINT_STR_LEN, PRINT_STR_LEN - 1, W("%s Descr=None\n%s Unit Descr=None\n%s IDirection=%s\n"), wszName, wszName, wszName, wszIDirection[unit]); } // Write both pieces to the file. if(WszWideCharToMultiByte (CP_ACP, 0, m_wszOutStr_1, -1, szPrintStr, PRINT_STR_LEN-1, 0, 0) ) { if (0 == WriteFile (m_hPerfLogFileHandle, szPrintStr, (DWORD)strlen(szPrintStr), &m_dwWriteByte, NULL)) printf("ERROR: Could not write to perf log.\n"); } else wprintf(W("ERROR: Could not do string conversion.\n")); if(WszWideCharToMultiByte (CP_ACP, 0, wszOutStr_2, -1, szPrintStr, PRINT_STR_LEN-1, 0, 0)) { if (0 == WriteFile (m_hPerfLogFileHandle, szPrintStr, (DWORD)strlen(szPrintStr), &m_dwWriteByte, NULL)) printf("ERROR: Could not write to perf log.\n"); } else wprintf(W("ERROR: Could not do string conversion.\n")); } }
HRESULT CDebugLogElement::Dump(HANDLE hFile) { HRESULT hr = S_OK; DWORD dwLen = 0; DWORD dwWritten = 0; DWORD dwSize = 0; DWORD dwBufSize = 0; LPSTR szBuf = NULL; BOOL bRet; if (!hFile) { hr = E_INVALIDARG; goto Exit; } dwSize = lstrlenW(_pszMsg) + 1; // Allocate for worst-case scenario where the UTF-8 size is 3 bytes // (ie. 1 byte greater than the 2-byte UNICODE char)./ dwBufSize = dwSize * (sizeof(WCHAR) + 1); szBuf = NEW(CHAR[dwBufSize]); if (!szBuf) { hr = E_OUTOFMEMORY; goto Exit; } dwLen = WszWideCharToMultiByte(CP_UTF8, 0, _pszMsg, dwSize, szBuf, dwBufSize, NULL, NULL); if (!dwLen) { hr = E_OUTOFMEMORY; goto Exit; } bRet = WriteFile(hFile, szBuf, dwLen, &dwWritten, NULL); if (!bRet) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } Exit: SAFEDELETEARRAY(szBuf); return hr; }
//***************************************************************************** // Add a stream, and its size, to the list of streams to be saved. //***************************************************************************** HRESULT CLiteWeightStgdbRW::AddStreamToList( ULONG cbSize, LPCWSTR szName) { HRESULT hr = S_OK; STORAGESTREAM *pItem; // New item to allocate & fill. int size; // Add a new item to the end of the list. IfNullGo(pItem = m_pStreamList->Append()); // Fill out the data. pItem->SetOffset(0); pItem->SetSize(cbSize); size = WszWideCharToMultiByte(CP_ACP, 0, szName, -1, pItem->rcName, MAXSTREAMNAME, 0, 0); _ASSERTE(size > 0); ErrExit: return hr; }
void JitConfigValues::MethodSet::initialize(const wchar_t* list, ICorJitHost* host) { assert(m_list == nullptr); assert(m_names == nullptr); enum State { NO_NAME, CLS_NAME, FUNC_NAME, ARG_LIST }; // parsing state machine const char SEP_CHAR = ' '; // current character use to separate each entry wchar_t lastChar = '?'; // dummy int nameStart = -1; // Index of the start of the current class or method name MethodName currentName; // Buffer used while parsing the current entry MethodName** lastName = &m_names; // Last entry inserted into the list bool isQuoted = false; currentName.m_next = nullptr; currentName.m_methodNameStart = -1; currentName.m_methodNameLen = -1; currentName.m_classNameStart = -1; currentName.m_classNameLen = -1; currentName.m_numArgs = -1; // Convert the input list to UTF-8 int utf8ListLen = WszWideCharToMultiByte(CP_UTF8, 0, list, -1, nullptr, 0, nullptr, nullptr); m_list = (char*)host->allocateMemory(utf8ListLen); if (WszWideCharToMultiByte(CP_UTF8, 0, list, -1, const_cast<LPSTR>(m_list), utf8ListLen, nullptr, nullptr) == 0) { // Failed to convert the list. Free the memory and ignore the list. host->freeMemory(reinterpret_cast<void*>(const_cast<char*>(m_list))); m_list = nullptr; return; } State state = NO_NAME; for (int i = 0; lastChar != '\0'; i++) { lastChar = m_list[i]; switch (state) { case NO_NAME: if (m_list[i] != SEP_CHAR) { nameStart = i; state = CLS_NAME; // we have found the start of the next entry } break; case CLS_NAME: if (m_list[nameStart] == '"') { for (; m_list[i] != '\0' && m_list[i] != '"'; i++) { ; } nameStart++; isQuoted = true; } if (m_list[i] == ':') { if (m_list[nameStart] == '*' && !isQuoted) { // The class name is a wildcard; mark it invalid. currentName.m_classNameStart = -1; currentName.m_classNameLen = -1; } else { currentName.m_classNameStart = nameStart; currentName.m_classNameLen = i - nameStart; // Remove the trailing quote, if any if (isQuoted) { currentName.m_classNameLen--; isQuoted = false; } } // Accept class::name syntax as well if (m_list[i + 1] == ':') { i++; } nameStart = i + 1; state = FUNC_NAME; } else if (m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == '(') { // Treat this as a method name without a class name. currentName.m_classNameStart = -1; currentName.m_classNameLen = -1; goto DONE_FUNC_NAME; } break; case FUNC_NAME: if (m_list[nameStart] == '"') { // The first half of the outer contdition handles the case where the // class name is valid. for (; nameStart == i || (m_list[i] != '\0' && m_list[i] != '"'); i++) { ; } nameStart++; isQuoted = true; } if (m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == '(') { DONE_FUNC_NAME: assert(m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == '('); if (m_list[nameStart] == '*' && !isQuoted) { // The method name is a wildcard; mark it invalid. currentName.m_methodNameStart = -1; currentName.m_methodNameLen = -1; } else { currentName.m_methodNameStart = nameStart; currentName.m_methodNameLen = i - nameStart; // Remove the trailing quote, if any if (isQuoted) { currentName.m_classNameLen--; isQuoted = false; } } if (m_list[i] == '\0' || m_list[i] == SEP_CHAR) { currentName.m_numArgs = -1; goto DONE_ARG_LIST; } else { assert(m_list[i] == '('); currentName.m_numArgs = -1; state = ARG_LIST; } } break; case ARG_LIST: if (m_list[i] == '\0' || m_list[i] == ')') { if (currentName.m_numArgs == -1) { currentName.m_numArgs = 0; } DONE_ARG_LIST: assert(m_list[i] == '\0' || m_list[i] == SEP_CHAR || m_list[i] == ')'); // We have parsed an entire method name; create a new entry in the list for it. MethodName* name = (MethodName*)host->allocateMemory(sizeof(MethodName)); *name = currentName; assert(name->m_next == nullptr); *lastName = name; lastName = &name->m_next; state = NO_NAME; // Skip anything after the argument list until we find the next // separator character. Otherwise if we see "func(a,b):foo" we // create entries for "func(a,b)" as well as ":foo". if (m_list[i] == ')') { for (; m_list[i] && m_list[i] != SEP_CHAR; i++) { ; } lastChar = m_list[i]; } } else { if (m_list[i] != SEP_CHAR && currentName.m_numArgs == -1) { currentName.m_numArgs = 1; } if (m_list[i] == ',') { currentName.m_numArgs++; } } break; default: assert(!"Bad state"); break; } } }
LPSTR FillSymbolSearchPathThrows(CQuickBytes &qb) { STATIC_CONTRACT_GC_NOTRIGGER; STATIC_CONTRACT_CANNOT_TAKE_LOCK; SCAN_IGNORE_FAULT; // Faults from Wsz funcs are handled. #ifndef DACCESS_COMPILE // not allowed to do allocation if current thread suspends EE. if (IsSuspendEEThread ()) return NULL; #endif InlineSString<MAX_SYM_PATH> rcBuff ; // Working buffer WCHAR rcVerString[64]; // Extension for install directory. int chTotal = 0; // How full is working buffer. int ch; // If the NT symbol server path vars are there, then use those. chTotal = WszGetEnvironmentVariable(W("_NT_SYMBOL_PATH"), rcBuff); if (chTotal + 1 < MAX_SYM_PATH) rcBuff.Append(W(';')); // Copy the defacto NT symbol path as well. size_t sympathLength = chTotal + NumItems(DEFAULT_SYM_PATH) + 1; // integer overflow occurred if (sympathLength < (size_t)chTotal || sympathLength < NumItems(DEFAULT_SYM_PATH)) { return NULL; } if (sympathLength < MAX_SYM_PATH) { rcBuff.Append(DEFAULT_SYM_PATH); chTotal = rcBuff.GetCount(); } // Next, if there is a URTTARGET, add that since that is where ndpsetup places // your symobls on an install. PathString rcBuffTemp; ch = WszGetEnvironmentVariable(W("URTTARGET"), rcBuffTemp); rcBuff.Append(rcBuffTemp); if (ch != 0 && (chTotal + ch + 1 < MAX_SYM_PATH)) { size_t chNewTotal = chTotal + ch; if (chNewTotal < (size_t)chTotal || chNewTotal < (size_t)ch) { // integer overflow occurred return NULL; } chTotal += ch; rcBuff.Append(W(';')); } #ifndef SELF_NO_HOST // Fetch the path location of the engine dll and add that path as well, just // in case URTARGET didn't cut it either. // For no-host builds of utilcode, we don't necessarily have an engine DLL in the // process, so skip this part. ch = WszGetModuleFileName(GetCLRModuleHack(), rcBuffTemp); size_t pathLocationLength = chTotal + ch + 1; // integer overflow occurred if (pathLocationLength < (size_t)chTotal || pathLocationLength < (size_t)ch) { return NULL; } if (ch != 0 && (pathLocationLength < MAX_SYM_PATH)) { chTotal = chTotal + ch - NumItems(STR_ENGINE_NAME); rcBuff.Append(W(';')); } #endif // Now we have a working buffer with a bunch of interesting stuff. Time // to convert it back to ansi for the imagehlp api's. Allocate the buffer // 2x bigger to handle worst case for MBCS. ch = ::WszWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, 0, 0, 0, 0); LPSTR szRtn = (LPSTR) qb.AllocNoThrow(ch + 1); if (!szRtn) return NULL; WszWideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, rcBuff, -1, szRtn, ch+1, 0, 0); return (szRtn); }
HRESULT Assembler::CreatePEFile(WCHAR *pwzOutputFilename) { HRESULT hr; DWORD mresourceSize = 0; BYTE* mresourceData = NULL; //IUnknown *pUnknown = NULL; // DWORD i; if(bClock) cMDEmitBegin = GetTickCount(); if(m_fReportProgress) printf("Creating %s file\n", m_fOBJ ? "COFF" : "PE"); if (!m_pEmitter) { printf("Error: Cannot create a PE file with no metadata\n"); return E_FAIL; } if(!(m_fDLL || m_fEntryPointPresent)) { printf("Error: No entry point declared for executable\n"); if(!OnErrGo) return E_FAIL; } if (DoGlobalFixups() == FALSE) return E_FAIL; if(bClock) cMDEmit1 = GetTickCount(); if(m_fOBJ) { // emit pseudo-relocs to pass file name and build number to PEWriter // this should be done BEFORE method emission! char* szInFileName = new char[strlen(m_szSourceFileName)+1]; strcpy(szInFileName,m_szSourceFileName); m_pCeeFileGen->AddSectionReloc(m_pILSection,(DWORD)szInFileName,m_pILSection,(CeeSectionRelocType)0x7FFC); time_t tm; time(&tm); struct tm* loct = localtime(&tm); DWORD compid = 0x002E0000 | (loct->tm_mday + (loct->tm_mon+1)*100); m_pCeeFileGen->AddSectionReloc(m_pILSection,compid,m_pILSection,(CeeSectionRelocType)0x7FFB); } // Allocate space for a strong name signature if we're delay or full // signing the assembly. if (m_pManifest->m_sStrongName.m_pbPublicKey) if (FAILED(hr = AllocateStrongNameSignature())) goto exit; if(bClock) cMDEmit2 = GetTickCount(); // Check undefined local TypeRefs if(m_LocalTypeRefDList.COUNT()) { LocalTypeRefDescr* pLTRD=NULL; BOOL bIsUndefClass = FALSE; while((pLTRD = m_LocalTypeRefDList.POP())) { if(NULL == FindClass(pLTRD->m_szFullName)) { report->msg("%s: Reference to undefined class '%s' (token 0x%08X)\n", "Error", pLTRD->m_szFullName,pLTRD->m_tok); bIsUndefClass = TRUE; } delete pLTRD; } if(bIsUndefClass && !OnErrGo) return E_FAIL; } if(bClock) cMDEmit3 = GetTickCount(); // Emit class members and globals: { Class *pSearch; int i; if(m_fReportProgress) printf("\nEmitting members:\n"); for (i=0; (pSearch = m_lstClass.PEEK(i)); i++) { if(m_fReportProgress) { if(i == 0) printf("Global \t"); else printf("Class %d\t",i); } if(!EmitMembers(pSearch)) { if(!OnErrGo) return E_FAIL; } } } if(bClock) cMDEmit4 = GetTickCount(); if(m_MethodImplDList.COUNT()) { if(m_fReportProgress) report->msg("Method Implementations (total): %d\n",m_MethodImplDList.COUNT()); if(!EmitMethodImpls()) { if(!OnErrGo) return E_FAIL; } } if(bClock) cMDEmitEnd = cRef2DefBegin = GetTickCount(); // Now, when all items defined in this file are emitted, let's try to resolve member refs to member defs: if(m_MemberRefDList.COUNT()) { MemberRefDescriptor* pMRD; mdToken tkMemberDef = 0; int i,j; unsigned ulTotal=0, ulDefs=0, ulRefs=0; Class *pSearch; if(m_fReportProgress) printf("Resolving member refs: "); while((pMRD = m_MemberRefDList.POP())) { tkMemberDef = 0; MethodDescriptor* pListMD; mdToken pMRD_tdClass = pMRD->m_tdClass; char* pMRD_szName = pMRD->m_szName; ULONG pMRD_dwCSig = (pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->length() : 0); PCOR_SIGNATURE pMRD_pSig = (PCOR_SIGNATURE)(pMRD->m_pSigBinStr ? pMRD->m_pSigBinStr->ptr() : NULL); ulTotal++; // MemberRef may reference a method or a field if((pMRD_pSig==NULL)||(*pMRD_pSig != IMAGE_CEE_CS_CALLCONV_FIELD)) { for (i=0; (pSearch = m_lstClass.PEEK(i)); i++) { if(pMRD_tdClass != pSearch->m_cl) continue; for(j=0; (pListMD = pSearch->m_MethodDList.PEEK(j)); j++) { if(pListMD->m_dwCSig != pMRD_dwCSig) continue; if(memcmp(pListMD->m_pSig,pMRD_pSig,pMRD_dwCSig)) continue; if(strcmp(pListMD->m_szName,pMRD_szName)) continue; tkMemberDef = pListMD->m_mdMethodTok; break; } } } if(tkMemberDef == 0) { if((pMRD_pSig==NULL)||(*pMRD_pSig == IMAGE_CEE_CS_CALLCONV_FIELD)) { FieldDescriptor* pListFD; for (i=0; (pSearch = m_lstClass.PEEK(i)); i++) { if(pMRD_tdClass != pSearch->m_cl) continue; for(j=0; (pListFD = pSearch->m_FieldDList.PEEK(j)); j++) { if(pListFD->m_pbsSig) { if(pListFD->m_pbsSig->length() != pMRD_dwCSig) continue; if(memcmp(pListFD->m_pbsSig->ptr(),pMRD_pSig,pMRD_dwCSig)) continue; } else if(pMRD_dwCSig) continue; if(strcmp(pListFD->m_szName,pMRD_szName)) continue; tkMemberDef = pListFD->m_fdFieldTok; break; } } } } if(tkMemberDef==0) { // could not resolve ref to def, make new ref and leave it this way if((pSearch = pMRD->m_pClass)) { mdToken tkRef; BinStr* pbs = new BinStr(); pbs->appendInt8(ELEMENT_TYPE_NAME); strcpy((char*)(pbs->getBuff((unsigned int)strlen(pSearch->m_szFQN)+1)),pSearch->m_szFQN); if(!ResolveTypeSpecToRef(pbs,&tkRef)) tkRef = mdTokenNil; delete pbs; if(RidFromToken(tkRef)) { ULONG cTemp = (ULONG)(strlen(pMRD_szName)+1); WCHAR* wzMemberName = new WCHAR[cTemp]; WszMultiByteToWideChar(g_uCodePage,0,pMRD_szName,-1,wzMemberName,cTemp); hr = m_pEmitter->DefineMemberRef(tkRef, wzMemberName, pMRD_pSig, pMRD_dwCSig, &tkMemberDef); ulRefs++; delete [] wzMemberName; } } } else ulDefs++; if(RidFromToken(tkMemberDef)) { SET_UNALIGNED_VAL32((mdToken *)pMRD->m_ulOffset, tkMemberDef); delete pMRD; } else { report->msg("Error: unresolved member ref '%s' of class 0x%08X\n",pMRD->m_szName,pMRD->m_tdClass); hr = E_FAIL; delete pMRD; if(!OnErrGo) goto exit; } } if(m_fReportProgress) printf("%d -> %d defs, %d refs\n",ulTotal,ulDefs,ulRefs); } if(bClock) cRef2DefEnd = GetTickCount(); // emit manifest info (if any) hr = S_OK; if(m_pManifest) { if (FAILED(hr = m_pManifest->EmitManifest())) goto exit; } if(g_wzResourceFile) if (FAILED(hr=m_pCeeFileGen->SetResourceFileName(m_pCeeFile, g_wzResourceFile))) goto exit; if (FAILED(hr=CreateTLSDirectory())) goto exit; if (FAILED(hr=CreateDebugDirectory())) goto exit; if (FAILED(hr=m_pCeeFileGen->SetOutputFileName(m_pCeeFile, pwzOutputFilename))) goto exit; // Reserve a buffer for the meta-data DWORD metaDataSize; if (FAILED(hr=m_pEmitter->GetSaveSize(cssAccurate, &metaDataSize))) goto exit; BYTE* metaData; if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, metaDataSize, sizeof(DWORD), (void**) &metaData))) goto exit; ULONG metaDataOffset; if (FAILED(hr=m_pCeeFileGen->GetSectionDataLen(m_pILSection, &metaDataOffset))) goto exit; metaDataOffset -= metaDataSize; // set managed resource entry, if any if(m_pManifest && m_pManifest->m_dwMResSizeTotal) { mresourceSize = m_pManifest->m_dwMResSizeTotal; if (FAILED(hr=m_pCeeFileGen->GetSectionBlock(m_pILSection, mresourceSize, sizeof(DWORD), (void**) &mresourceData))) goto exit; if (FAILED(hr=m_pCeeFileGen->SetManifestEntry(m_pCeeFile, mresourceSize, 0))) goto exit; } if(m_VTFList.COUNT()) { GlobalLabel *pGlobalLabel; VTFEntry* pVTFEntry; if(m_pVTable) delete m_pVTable; // can't have both; list takes precedence m_pVTable = new BinStr(); hr = S_OK; for(WORD k=0; (pVTFEntry = m_VTFList.POP()); k++) { if((pGlobalLabel = FindGlobalLabel(pVTFEntry->m_szLabel))) { MethodDescriptor* pMD; Class* pClass; m_pVTable->appendInt32(pGlobalLabel->m_GlobalOffset); m_pVTable->appendInt16(pVTFEntry->m_wCount); m_pVTable->appendInt16(pVTFEntry->m_wType); for(int i=0; (pClass = m_lstClass.PEEK(i)); i++) { for(WORD j = 0; (pMD = pClass->m_MethodDList.PEEK(j)); j++) { if(pMD->m_wVTEntry == k+1) { char* ptr; if(SUCCEEDED(hr = m_pCeeFileGen->ComputeSectionPointer(m_pGlobalDataSection,pGlobalLabel->m_GlobalOffset,&ptr))) { DWORD dwDelta = (pMD->m_wVTSlot-1)*((pVTFEntry->m_wType & COR_VTABLE_32BIT) ? (DWORD) sizeof(DWORD) : (DWORD) sizeof(__int64)); ptr += dwDelta; mdMethodDef* mptr = (mdMethodDef*)ptr; *mptr = pMD->m_mdMethodTok; if(pMD->m_dwExportOrdinal != 0xFFFFFFFF) { EATEntry* pEATE = new EATEntry; pEATE->dwOrdinal = pMD->m_dwExportOrdinal; pEATE->szAlias = pMD->m_szExportAlias ? pMD->m_szExportAlias : pMD->m_szName; pEATE->dwStubRVA = EmitExportStub(pGlobalLabel->m_GlobalOffset+dwDelta); m_EATList.PUSH(pEATE); } } else report->msg("Error: Failed to get pointer to label '%s' inVTable fixup\n",pVTFEntry->m_szLabel); } } } } else { report->msg("Error: Unresolved label '%s' in VTable fixup\n",pVTFEntry->m_szLabel); hr = E_FAIL; } delete pVTFEntry; } if(FAILED(hr)) goto exit; } if(m_pVTable) { //DWORD *pdw = (DWORD *)m_pVTable->ptr(); ULONG i, N = m_pVTable->length()/sizeof(DWORD); ULONG ulVTableOffset; m_pCeeFileGen->GetSectionDataLen (m_pILSection, &ulVTableOffset); if (FAILED(hr=m_pCeeFileGen->SetVTableEntry(m_pCeeFile, m_pVTable->length(),(ULONG)(m_pVTable->ptr())))) goto exit; for(i = 0; i < N; i+=2) { m_pCeeFileGen->AddSectionReloc(m_pILSection, ulVTableOffset+(i*sizeof(DWORD)), m_pGlobalDataSection, srRelocAbsolute); } } if(m_EATList.COUNT()) { if(FAILED(CreateExportDirectory())) goto exit; } if (m_fWindowsCE) { if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, IMAGE_SUBSYSTEM_WINDOWS_CE_GUI, 2, 10))) goto exit; if (FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, 0x10000))) goto exit; } else if(m_dwSubsystem) { if (FAILED(hr=m_pCeeFileGen->SetSubsystem(m_pCeeFile, m_dwSubsystem, 4, 0))) goto exit; } if (FAILED(hr=m_pCeeFileGen->ClearComImageFlags(m_pCeeFile, COMIMAGE_FLAGS_ILONLY))) goto exit; if (FAILED(hr=m_pCeeFileGen->SetComImageFlags(m_pCeeFile, m_dwComImageFlags & ~COMIMAGE_FLAGS_STRONGNAMESIGNED))) goto exit; if(m_dwFileAlignment) { if(FAILED(hr=m_pCeeFileGen->SetFileAlignment(m_pCeeFile, m_dwFileAlignment))) goto exit; } if(m_stBaseAddress) { if(FAILED(hr=m_pCeeFileGen->SetImageBase(m_pCeeFile, m_stBaseAddress))) goto exit; } //Compute all the RVAs if (FAILED(hr=m_pCeeFileGen->LinkCeeFile(m_pCeeFile))) goto exit; // Fix up any fields that have RVA associated with them if (m_fHaveFieldsWithRvas) { hr = S_OK; ULONG dataSectionRVA; if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pGlobalDataSection, &dataSectionRVA))) goto exit; ULONG tlsSectionRVA; if (FAILED(hr=m_pCeeFileGen->GetSectionRVA(m_pTLSSection, &tlsSectionRVA))) goto exit; FieldDescriptor* pListFD; Class* pClass; for(int i=0; (pClass = m_lstClass.PEEK(i)); i++) { for(int j=0; (pListFD = pClass->m_FieldDList.PEEK(j)); j++) { if (pListFD->m_rvaLabel != 0) { GlobalLabel *pLabel = FindGlobalLabel(pListFD->m_rvaLabel); if (pLabel == 0) { report->msg("Error:Could not find label '%s' for the field '%s'\n", pListFD->m_rvaLabel, pListFD->m_szName); hr = E_FAIL; continue; } DWORD rva = pLabel->m_GlobalOffset; if (pLabel->m_Section == m_pTLSSection) rva += tlsSectionRVA; else { _ASSERTE(pLabel->m_Section == m_pGlobalDataSection); rva += dataSectionRVA; } if (FAILED(m_pEmitter->SetFieldRVA(pListFD->m_fdFieldTok, rva))) goto exit; } } } if (FAILED(hr)) goto exit; } if(bClock) cFilegenBegin = GetTickCount(); // actually output the meta-data if (FAILED(hr=m_pCeeFileGen->EmitMetaDataAt(m_pCeeFile, m_pEmitter, m_pILSection, metaDataOffset, metaData, metaDataSize))) goto exit; // actually output the resources if(mresourceSize && mresourceData) { size_t i, N = m_pManifest->m_dwMResNum, sizeread, L; BYTE *ptr = (BYTE*)mresourceData; BOOL mrfail = FALSE; FILE* pFile; char sz[2048]; for(i=0; i < N; i++) { memset(sz,0,2048); WszWideCharToMultiByte(CP_ACP,0,m_pManifest->m_wzMResName[i],-1,sz,2047,NULL,NULL); L = m_pManifest->m_dwMResSize[i]; sizeread = 0; memcpy(ptr,&L,sizeof(DWORD)); ptr += sizeof(DWORD); if((pFile = fopen(sz,"rb"))) { sizeread = fread((void *)ptr,1,L,pFile); fclose(pFile); ptr += sizeread; } else { report->msg("Error: failed to open mgd resource file '%ls'\n",m_pManifest->m_wzMResName[i]); mrfail = TRUE; } if(sizeread < L) { report->msg("Error: failed to read expected %d bytes from mgd resource file '%ls'\n",L,m_pManifest->m_wzMResName[i]); mrfail = TRUE; L -= sizeread; memset(ptr,0,L); ptr += L; } } if(mrfail) { hr = E_FAIL; goto exit; } } // Generate the file -- moved to main //if (FAILED(hr=m_pCeeFileGen->GenerateCeeFile(m_pCeeFile))) goto exit; hr = S_OK; exit: return hr; }
//#ifdef EXPORT_DIR_ENABLED HRESULT Assembler::CreateExportDirectory() { HRESULT hr = S_OK; DWORD Nentries = m_EATList.COUNT(); if(Nentries == 0) return S_OK; IMAGE_EXPORT_DIRECTORY exportDirIDD; DWORD exportDirDataSize; BYTE *exportDirData; EATEntry *pEATE; unsigned i, L, ordBase = 0xFFFFFFFF, Ldllname; // get the DLL name from output file name char* pszDllName; Ldllname = (unsigned)wcslen(m_wzOutputFileName)*3+3; char* szOutputFileName = new char[Ldllname]; memset(szOutputFileName,0,wcslen(m_wzOutputFileName)*3+3); WszWideCharToMultiByte(CP_ACP,0,m_wzOutputFileName,-1,szOutputFileName,Ldllname,NULL,NULL); pszDllName = strrchr(szOutputFileName,'\\'); if(pszDllName == NULL) pszDllName = strrchr(szOutputFileName,':'); if(pszDllName == NULL) pszDllName = szOutputFileName; Ldllname = (unsigned)strlen(pszDllName)+1; // Allocate buffer for tables for(i = 0, L=0; i < Nentries; i++) L += 1+(unsigned)strlen(m_EATList.PEEK(i)->szAlias); exportDirDataSize = Nentries*5*sizeof(WORD) + L + Ldllname; exportDirData = new BYTE[exportDirDataSize]; memset(exportDirData,0,exportDirDataSize); // Export address table DWORD* pEAT = (DWORD*)exportDirData; // Name pointer table DWORD* pNPT = pEAT + Nentries; // Ordinal table WORD* pOT = (WORD*)(pNPT + Nentries); // Export name table char* pENT = (char*)(pOT + Nentries); // DLL name char* pDLLName = pENT + L; // sort the names/ordinals char** pAlias = new char*[Nentries]; for(i = 0; i < Nentries; i++) { pEATE = m_EATList.PEEK(i); pOT[i] = (WORD)pEATE->dwOrdinal; if(pOT[i] < ordBase) ordBase = pOT[i]; pAlias[i] = pEATE->szAlias; } bool swapped = true; unsigned j; char* pch; while(swapped) { swapped = false; for(i=1; i < Nentries; i++) { if(strcmp(pAlias[i-1],pAlias[i]) > 0) { swapped = true; pch = pAlias[i-1]; pAlias[i-1] = pAlias[i]; pAlias[i] = pch; j = pOT[i-1]; pOT[i-1] = pOT[i]; pOT[i] = j; } } } // normalize ordinals for(i = 0; i < Nentries; i++) pOT[i] -= ordBase; // fill the export address table for(i = 0; i < Nentries; i++) { pEATE = m_EATList.PEEK(i); pEAT[pEATE->dwOrdinal - ordBase] = pEATE->dwStubRVA; } // fill the export names table unsigned l; for(i = 0, j = 0; i < Nentries; i++) { pNPT[i] = j; // relative offset in the table l = (unsigned)strlen(pAlias[i])+1; memcpy(&pENT[j],pAlias[i],l); j+=l; } _ASSERTE(j==L); // fill the DLL name memcpy(pDLLName,pszDllName,Ldllname); // Data blob is ready pending Name Pointer Table values offsetting memset(&exportDirIDD,0,sizeof(IMAGE_EXPORT_DIRECTORY)); // Grab the timestamp of the PE file. time_t fileTimeStamp; if (FAILED(hr = m_pCeeFileGen->GetFileTimeStamp(m_pCeeFile,&fileTimeStamp))) return hr; // Fill in the directory entry. // Characteristics, MajorVersion and MinorVersion play no role and stay 0 exportDirIDD.TimeDateStamp = VAL32((DWORD)fileTimeStamp); exportDirIDD.Name = VAL32(exportDirDataSize - Ldllname); // to be offset later exportDirIDD.Base = VAL32(ordBase); exportDirIDD.NumberOfFunctions = VAL32(Nentries); exportDirIDD.NumberOfNames = VAL32(Nentries); exportDirIDD.AddressOfFunctions = 0; // to be offset later exportDirIDD.AddressOfNames = VAL32(Nentries*sizeof(DWORD)); // to be offset later exportDirIDD.AddressOfNameOrdinals = VAL32(Nentries*sizeof(DWORD)*2); // to be offset later // Grab memory in the section for our stuff. HCEESECTION sec = m_pGlobalDataSection; BYTE *de; if (FAILED(hr = m_pCeeFileGen->GetSectionBlock(sec, sizeof(IMAGE_EXPORT_DIRECTORY) + exportDirDataSize, 4, (void**) &de))) return hr; // Where did we get that memory? ULONG deOffset, deDataOffset; if (FAILED(hr = m_pCeeFileGen->GetSectionDataLen(sec, &deDataOffset))) return hr; deDataOffset -= exportDirDataSize; deOffset = deDataOffset - sizeof(IMAGE_EXPORT_DIRECTORY); // Add offsets and set up relocs for header entries exportDirIDD.Name = VAL32(VAL32(exportDirIDD.Name) + deDataOffset); if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,Name), sec, srRelocAbsolute))) return hr; exportDirIDD.AddressOfFunctions = VAL32(VAL32(exportDirIDD.AddressOfFunctions) + deDataOffset); if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,AddressOfFunctions), sec, srRelocAbsolute))) return hr; exportDirIDD.AddressOfNames = VAL32(VAL32(exportDirIDD.AddressOfNames) + deDataOffset); if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,AddressOfNames), sec, srRelocAbsolute))) return hr; exportDirIDD.AddressOfNameOrdinals = VAL32(VAL32(exportDirIDD.AddressOfNameOrdinals) + deDataOffset); if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,deOffset + offsetof(IMAGE_EXPORT_DIRECTORY,AddressOfNameOrdinals), sec, srRelocAbsolute))) return hr; // Add offsets and set up relocs for Name Pointer Table j = deDataOffset + Nentries*5*sizeof(WORD); // EA, NP and O Tables come first for(i = 0; i < Nentries; i++) { pNPT[i] += j; if (FAILED(hr = m_pCeeFileGen->AddSectionReloc(sec,exportDirIDD.AddressOfNames+i*sizeof(DWORD), sec, srRelocAbsolute))) return hr; } // Emit the directory entry. if (FAILED(hr = m_pCeeFileGen->SetDirectoryEntry(m_pCeeFile, sec, IMAGE_DIRECTORY_ENTRY_EXPORT, sizeof(IMAGE_EXPORT_DIRECTORY), deOffset))) return hr; // Copy the debug directory into the section. memcpy(de, &exportDirIDD, sizeof(IMAGE_EXPORT_DIRECTORY)); memcpy(de + sizeof(IMAGE_EXPORT_DIRECTORY), exportDirData, exportDirDataSize); delete pAlias; delete exportDirData; return S_OK; }
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; LPWSTR fileName = CLRConfig::GetConfigValue(CLRConfig::INTERNAL_LogFile); if (fileName != 0) { int ret; ret = WszWideCharToMultiByte(CP_ACP, 0, fileName, -1, szLogFileName, sizeof(szLogFileName)-1, NULL, NULL); _ASSERTE(ret != 0); delete fileName; } if (REGUTIL::GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_LogWithPid, FALSE)) { char szPid[20]; sprintf_s(szPid, COUNTOF(szPid), ".%d", GetCurrentProcessId()); strcat_s(szLogFileName, _countof(szLogFileName), szPid); } if ((LogFlags & LOG_ENABLE) && (LogFlags & LOG_ENABLE_FILE_LOGGING) && (LogFileHandle == INVALID_HANDLE_VALUE)) { DWORD fdwCreate = (LogFlags & LOG_ENABLE_APPEND_FILE) ? OPEN_ALWAYS : CREATE_ALWAYS; LogFileHandle = CreateFileA( szLogFileName, 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) { char* ptr = szLogFileName + strlen(szLogFileName) + 1; ptr[-1] = '.'; ptr[0] = '0'; ptr[1] = 0; for(int i = 0; i < 10; i++) { LogFileHandle = CreateFileA( szLogFileName, 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) { DWORD written; char buff[MAX_PATH+60]; strcpy(buff, "Could not open log file, logging to "); strcat_s(buff, _countof(buff), szLogFileName); // ARULM--Changed WriteConsoleA to WriteFile to be CE compat WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buff, (DWORD)strlen(buff), &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" ); } } }
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" ); } } }
HRESULT FusionBind::Init(IAssemblyName *pName) { _ASSERTE(pName); HRESULT hr; // Fill out info from name, if we have it. DWORD cbSize = 0; if (pName->GetProperty(ASM_NAME_NAME, NULL, &cbSize) == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { CQuickBytes qb; LPWSTR pwName = (LPWSTR) qb.Alloc(cbSize); IfFailRet(pName->GetProperty(ASM_NAME_NAME, pwName, &cbSize)); cbSize = WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, NULL, 0, NULL, NULL); m_pAssemblyName = new char[cbSize]; if (!m_pAssemblyName) return E_OUTOFMEMORY; m_ownedFlags |= NAME_OWNED; WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, (LPSTR) m_pAssemblyName, cbSize, NULL, NULL); } m_fParsed = TRUE; // Note: cascade checks so we don't set lower priority version #'s if higher ones are missing cbSize = sizeof(m_context.usMajorVersion); pName->GetProperty(ASM_NAME_MAJOR_VERSION, &m_context.usMajorVersion, &cbSize); if (!cbSize) m_context.usMajorVersion = (USHORT) -1; else { cbSize = sizeof(m_context.usMinorVersion); pName->GetProperty(ASM_NAME_MINOR_VERSION, &m_context.usMinorVersion, &cbSize); } if (!cbSize) m_context.usMinorVersion = (USHORT) -1; else { cbSize = sizeof(m_context.usBuildNumber); pName->GetProperty(ASM_NAME_BUILD_NUMBER, &m_context.usBuildNumber, &cbSize); } if (!cbSize) m_context.usBuildNumber = (USHORT) -1; else { cbSize = sizeof(m_context.usRevisionNumber); pName->GetProperty(ASM_NAME_REVISION_NUMBER, &m_context.usRevisionNumber, &cbSize); } if (!cbSize) m_context.usRevisionNumber = (USHORT) -1; cbSize = 0; if (pName->GetProperty(ASM_NAME_CULTURE, NULL, &cbSize) == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { LPWSTR pwName = (LPWSTR) alloca(cbSize); IfFailRet(pName->GetProperty(ASM_NAME_CULTURE, pwName, &cbSize)); cbSize = WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, NULL, 0, NULL, NULL); m_context.szLocale = new char [cbSize]; if (!m_context.szLocale) return E_OUTOFMEMORY; m_ownedFlags |= LOCALE_OWNED; WszWideCharToMultiByte(CP_UTF8, 0, pwName, -1, (LPSTR) m_context.szLocale, cbSize, NULL, NULL); } m_dwFlags = 0; cbSize = 0; if (pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, NULL, &cbSize) == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { m_pbPublicKeyOrToken = new BYTE[cbSize]; if (m_pbPublicKeyOrToken == NULL) return E_OUTOFMEMORY; m_cbPublicKeyOrToken = cbSize; IfFailRet(pName->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_pbPublicKeyOrToken, &cbSize)); m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED; } else if (pName->GetProperty(ASM_NAME_PUBLIC_KEY, NULL, &cbSize) == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { m_pbPublicKeyOrToken = new BYTE[cbSize]; if (m_pbPublicKeyOrToken == NULL) return E_OUTOFMEMORY; m_cbPublicKeyOrToken = cbSize; IfFailRet(pName->GetProperty(ASM_NAME_PUBLIC_KEY, m_pbPublicKeyOrToken, &cbSize)); m_dwFlags |= afPublicKey; m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED; } else if ((pName->GetProperty(ASM_NAME_NULL_PUBLIC_KEY, NULL, &cbSize) == S_OK) || (pName->GetProperty(ASM_NAME_NULL_PUBLIC_KEY_TOKEN, NULL, &cbSize) == S_OK)) { m_pbPublicKeyOrToken = new BYTE[0]; if (m_pbPublicKeyOrToken == NULL) return E_OUTOFMEMORY; m_cbPublicKeyOrToken = 0; m_ownedFlags |= PUBLIC_KEY_OR_TOKEN_OWNED; } cbSize = 0; if (pName->GetProperty(ASM_NAME_CODEBASE_URL, NULL, &cbSize) == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)) { m_CodeInfo.m_pszCodeBase = new WCHAR [ cbSize/sizeof(WCHAR) ]; if (m_CodeInfo.m_pszCodeBase == NULL) return E_OUTOFMEMORY; IfFailRet(pName->GetProperty(ASM_NAME_CODEBASE_URL, (void*)m_CodeInfo.m_pszCodeBase, &cbSize)); m_CodeInfo.m_dwCodeBase = cbSize/sizeof(WCHAR); m_ownedFlags |= CODE_BASE_OWNED; } return S_OK; }
//***************************************************************************** void Unicode2UTF( LPCWSTR wszSrc, // The string to convert. __out_ecount(cbDst) LPUTF8 szDst, // Buffer for the output UTF8 string. int cbDst) // Size of the buffer for UTF8 string. { int cchSrc = (int)wcslen(wszSrc); int cchRet; cchRet = WszWideCharToMultiByte( CP_UTF8, 0, wszSrc, cchSrc + 1, szDst, cbDst, NULL, NULL); if (cchRet == 0) { _ASSERTE_MSG(FALSE, "Converting unicode string to UTF8 string failed!"); szDst[0] = '\0'; } } // Unicode2UTF HRESULT HENUMInternal::CreateSimpleEnum( DWORD tkKind, // kind of token that we are iterating
DWORD DumpResourceToFile(WCHAR* wzFileName) { BYTE* pbResBase; FILE* pF = NULL; DWORD ret = 0; DWORD dwResDirRVA; DWORD dwResDirSize; if (g_pPELoader->IsPE32()) { IMAGE_OPTIONAL_HEADER32 *pOptHeader = &(g_pPELoader->ntHeaders32()->OptionalHeader); dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size); } else { IMAGE_OPTIONAL_HEADER64 *pOptHeader = &(g_pPELoader->ntHeaders64()->OptionalHeader); dwResDirRVA = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress); dwResDirSize = VAL32(pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size); } if(dwResDirRVA && dwResDirSize) { ULONG L = (ULONG)wcslen(wzFileName)*3+3; char* szFileNameANSI = new char[L]; memset(szFileNameANSI,0,L); WszWideCharToMultiByte(CP_ACP,0,wzFileName,-1,szFileNameANSI,L,NULL,NULL); pF = fopen(szFileNameANSI,"wb"); delete [] szFileNameANSI; if(pF) { if(g_pPELoader->getVAforRVA(dwResDirRVA, (void **) &pbResBase)) { // First, pull out all resource nodes (tree leaves), see ResourceNode struct PIMAGE_RESOURCE_DIRECTORY pirdType = (PIMAGE_RESOURCE_DIRECTORY)pbResBase; PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeType = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbResBase+sizeof(IMAGE_RESOURCE_DIRECTORY)); DWORD dwTypeID; unsigned short i,N = VAL16(pirdType->NumberOfNamedEntries)+VAL16(pirdType->NumberOfIdEntries); for(i=0; i < N; i++, pirdeType++) { dwTypeID = VAL32(IMAGE_RDE_NAME(pirdeType)); if(IMAGE_RDE_OFFSET_FIELD(pirdeType, DataIsDirectory)) { BYTE* pbNameBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeType, OffsetToDirectory)); PIMAGE_RESOURCE_DIRECTORY pirdName = (PIMAGE_RESOURCE_DIRECTORY)pbNameBase; PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeName = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbNameBase+sizeof(IMAGE_RESOURCE_DIRECTORY)); DWORD dwNameID; unsigned short i,N = VAL16(pirdName->NumberOfNamedEntries)+VAL16(pirdName->NumberOfIdEntries); for(i=0; i < N; i++, pirdeName++) { dwNameID = VAL32(IMAGE_RDE_NAME(pirdeName)); if(IMAGE_RDE_OFFSET_FIELD(pirdeName, DataIsDirectory)) { BYTE* pbLangBase = pbResBase + VAL32(IMAGE_RDE_OFFSET_FIELD(pirdeName, OffsetToDirectory)); PIMAGE_RESOURCE_DIRECTORY pirdLang = (PIMAGE_RESOURCE_DIRECTORY)pbLangBase; PIMAGE_RESOURCE_DIRECTORY_ENTRY pirdeLang = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pbLangBase+sizeof(IMAGE_RESOURCE_DIRECTORY)); DWORD dwLangID; unsigned short i,N = VAL32(pirdLang->NumberOfNamedEntries)+VAL16(pirdLang->NumberOfIdEntries); for(i=0; i < N; i++, pirdeLang++) { dwLangID = IMAGE_RDE_NAME(pirdeLang); if(IMAGE_RDE_OFFSET_FIELD(pirdeLang, DataIsDirectory)) { _ASSERTE(!"Resource hierarchy exceeds three levels"); } else { if (g_prResNodePtr == NULL) { g_prResNodePtr = new DynamicArray<ResourceNode*>; } (*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,dwLangID,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeLang))); } } } else { if (g_prResNodePtr == NULL) { g_prResNodePtr = new DynamicArray<ResourceNode*>; } (*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,dwNameID,0,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeName))); } } } else { if (g_prResNodePtr == NULL) { g_prResNodePtr = new DynamicArray<ResourceNode*>; } (*g_prResNodePtr)[ulNumResNodes++] = new ResourceNode(dwTypeID,0,0,pbResBase + VAL32(IMAGE_RDE_OFFSET(pirdeType))); } } // OK, all tree leaves are in ResourceNode structs, and ulNumResNodes ptrs are in g_prResNodePtr // Dump them to pF if(ulNumResNodes) { BYTE* pbData; // Write dummy header ResourceHeader *pRH = new ResourceHeader(); fwrite(pRH,sizeof(ResourceHeader),1,pF); delete pRH; DWORD dwFiller; BYTE bNil[3] = {0,0,0}; // For each resource write header and data for(i=0; i < ulNumResNodes; i++) { if(g_pPELoader->getVAforRVA(VAL32((*g_prResNodePtr)[i]->DataEntry.OffsetToData), (void **) &pbData)) { fwrite(&((*g_prResNodePtr)[i]->ResHdr),sizeof(ResourceHeader),1,pF); fwrite(pbData,VAL32((*g_prResNodePtr)[i]->DataEntry.Size),1,pF); dwFiller = VAL32((*g_prResNodePtr)[i]->DataEntry.Size) & 3; if(dwFiller) { dwFiller = 4 - dwFiller; fwrite(bNil,dwFiller,1,pF); } } delete (*g_prResNodePtr)[i]; } } if (g_prResNodePtr) { delete g_prResNodePtr; g_prResNodePtr = NULL; } ulNumResNodes = 0; ret = 1; }// end if got ptr to resource else ret = 0xFFFFFFFF; if(pF) fclose(pF); }// end if file opened else ret = 0xEFFFFFFF; } // end if there is resource else ret = 0; return ret; }