// This function returns the address to the MapView of file and file size. void GetMapViewOfFile(wchar_t *szFile, PBYTE *ppbMap, DWORD *pdwFileSize) { HANDLE hMapFile; DWORD dwHighSize; HANDLE hFile = WszCreateFile(szFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hFile == INVALID_HANDLE_VALUE) MDInfo::Error("CreateFileA failed!"); *pdwFileSize = GetFileSize(hFile, &dwHighSize); if ((*pdwFileSize == 0xFFFFFFFF) && (GetLastError() != NO_ERROR)) MDInfo::Error("GetFileSize failed!"); _ASSERTE(dwHighSize == 0); hMapFile = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL); CloseHandle(hFile); if (!hMapFile) MDInfo::Error("CreateFileMappingA failed!"); *ppbMap = (PBYTE) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); CloseHandle(hMapFile); if (!*ppbMap) MDInfo::Error("MapViewOfFile failed!"); } // void GetMapViewOfFile()
BOOL PELoader::open(const WCHAR* moduleName) { HMODULE newhMod = NULL; DWORD dwFileSizeLow; _ASSERTE(moduleName); if (!moduleName) return FALSE; m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (m_hFile == INVALID_HANDLE_VALUE) return FALSE; dwFileSizeLow = GetFileSize( m_hFile, NULL); if (dwFileSizeLow == INVALID_FILE_SIZE) return FALSE; m_FileSize = dwFileSizeLow; m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (m_hMapFile == NULL) return FALSE; newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0); if (newhMod == NULL) return FALSE; return open(newhMod); }
// public interface routine void InitWSPerf() { wchar_t lpszValue[2]; DWORD cchValue = 2; #ifdef _WS_PERF_OUTPUT g_fWSPerfOn = WszGetEnvironmentVariable (L"WS_PERF_OUTPUT", lpszValue, cchValue); if (g_fWSPerfOn) { g_hWSPerfLogFile = WszCreateFile (L"WSPerf.log", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (g_hWSPerfLogFile == INVALID_HANDLE_VALUE) g_fWSPerfOn = 0; #ifdef WS_PERF_DETAIL g_hWSPerfDetailLogFile = WszCreateFile (L"WSPerfDetail.log", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); if (g_hWSPerfDetailLogFile == INVALID_HANDLE_VALUE) g_fWSPerfOn = 0; #endif g_HeapAccounts[0][1] = -1; //null list sprintf(szPrintStr, "HPtr\t\tPage Range\t\tReserved Size\n"); WriteFile (g_hWSPerfLogFile, szPrintStr, strlen(szPrintStr), &dwWriteByte, NULL); } #endif }
HRESULT CAssemblyStream::Init (LPCOLESTR pszPath, DWORD dwFormat) { HRESULT hr = S_OK; DWORD cwPath; BOOL bRet; _ASSERTE(pszPath); _dwFormat = dwFormat; cwPath = lstrlenW(pszPath) + 1; _ASSERTE(cwPath < MAX_PATH); memcpy(_szPath, pszPath, sizeof(TCHAR) * cwPath); _hf = WszCreateFile(pszPath, GENERIC_WRITE, 0 /* no sharing */, NULL, CREATE_NEW, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (_hf == INVALID_HANDLE_VALUE) { hr = HRESULT_FROM_WIN32(GetLastError()); ReleaseParent(hr); goto Exit; } if (!g_hProv) { HCRYPTPROV hProv; bRet = CryptAcquireContextA(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT); if (!bRet) { hr = HRESULT_FROM_WIN32(GetLastError()); ReleaseParent(hr); goto Exit; } if (InterlockedCompareExchangePointer((void **)&g_hProv, (void *)hProv, 0)) { // Lost the race. Release our provider. CryptReleaseContext(hProv, 0); } } bRet = CryptCreateHash(g_hProv, CALG_SHA1, 0, 0, &_hHash); if (!bRet) { hr = HRESULT_FROM_WIN32(GetLastError()); ReleaseParent(hr); goto Exit; } Exit: return hr; }
HRESULT CFileStream::OpenForRead(LPCWSTR wzFilePath) { HRESULT hr = S_OK; DWORD dwShareMode = FILE_SHARE_READ; dwShareMode |= FILE_SHARE_DELETE; _ASSERTE(_hFile == INVALID_HANDLE_VALUE && wzFilePath); if (_hFile != INVALID_HANDLE_VALUE || !wzFilePath) { hr = E_INVALIDARG; goto Exit; } _hFile = WszCreateFile(wzFilePath, GENERIC_READ, dwShareMode, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (_hFile == INVALID_HANDLE_VALUE) { hr = HRESULT_FROM_WIN32(GetLastError()); goto Exit; } Exit: return hr; }
HRESULT GetHash(LPCTSTR szFileName, ALG_ID iHashAlg, PBYTE pbHash, DWORD *pdwHash) { #define MAX_ARRAY_SIZE 16384 #define HASH_BUFFER_SIZE (MAX_ARRAY_SIZE-4) HRESULT hr = E_FAIL; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; DWORD dwBufferLen; BYTE *pbBuffer = NULL; HANDLE hSourceFile = INVALID_HANDLE_VALUE; pbBuffer = NEW(BYTE[MAX_ARRAY_SIZE]); if (!pbBuffer) { hr = E_OUTOFMEMORY; goto exit; } if(!WszCryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } if(!CryptCreateHash(hProv, iHashAlg, 0, 0, &hHash)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } // Open source file. hSourceFile = WszCreateFile (szFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); if (hSourceFile == INVALID_HANDLE_VALUE) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } while (TRUE) { if (!ReadFile (hSourceFile, pbBuffer, HASH_BUFFER_SIZE, &dwBufferLen, NULL)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } if (!dwBufferLen) { break; } // Add data to hash object. if(!CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } } if(!CryptGetHashParam(hHash, HP_HASHVAL, pbHash, pdwHash, 0)) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } hr = S_OK; exit: SAFEDELETEARRAY(pbBuffer); if (hHash) CryptDestroyHash(hHash); if (hProv) CryptReleaseContext(hProv,0); if (hSourceFile != INVALID_HANDLE_VALUE) CloseHandle(hSourceFile); return hr; }
void AsmMan::EndAssembly() { if(m_pCurAsmRef) { if(m_pCurAsmRef->isRef) { // list the assembly ref if(GetAsmRefByName(m_pCurAsmRef->szAlias)) { //report->warn("Multiple declarations of Assembly Ref '%s', ignored except the 1st one\n",m_pCurAsmRef->szName); delete m_pCurAsmRef; m_pCurAsmRef = NULL; return; } if(m_pCurAsmRef->isAutodetect) { IAssemblyName* pIAsmName; HRESULT hr; // Convert name to Unicode WszMultiByteToWideChar(g_uCodePage,0,m_pCurAsmRef->szName,-1,wzUniBuf,dwUniBuf); hr = CreateAssemblyNameObject(&pIAsmName,wzUniBuf,CANOF_PARSE_DISPLAY_NAME,NULL); if(SUCCEEDED(hr)) { // set enumeration criteria: what is known about AsmRef (besides name) if(m_pCurAsmRef->usVerMajor != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_MAJOR_VERSION,&(m_pCurAsmRef->usVerMajor),2); if(m_pCurAsmRef->usVerMinor != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_MINOR_VERSION,&(m_pCurAsmRef->usVerMinor),2); if(m_pCurAsmRef->usBuild != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_BUILD_NUMBER,&(m_pCurAsmRef->usBuild),2); if(m_pCurAsmRef->usRevision != (USHORT)0xFFFF) pIAsmName->SetProperty(ASM_NAME_REVISION_NUMBER,&(m_pCurAsmRef->usRevision),2); if(m_pCurAsmRef->pPublicKeyToken) pIAsmName->SetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, m_pCurAsmRef->pPublicKeyToken->ptr(), m_pCurAsmRef->pPublicKeyToken->length()); if(m_pCurAsmRef->pLocale) pIAsmName->SetProperty(ASM_NAME_CULTURE, m_pCurAsmRef->pLocale->ptr(), m_pCurAsmRef->pLocale->length()); // enumerate assemblies IAssemblyEnum* pIAsmEnum = NULL; hr = CreateAssemblyEnum(&pIAsmEnum, NULL, pIAsmName, ASM_CACHE_GAC, NULL); if(SUCCEEDED(hr)) { IAssemblyName* pIAsmNameFound; IAssemblyName* pIAsmNameLatestVer = NULL; ULONGLONG ullVer=0, ullVerLatest=0; DWORD dwVerHi, dwVerLo; // find the latest and greatest, if any for(;;) { pIAsmNameFound = NULL; hr = pIAsmEnum->GetNextAssembly(NULL,&pIAsmNameFound,0); if(SUCCEEDED(hr) && pIAsmNameFound) { pIAsmNameFound->GetVersion(&dwVerHi,&dwVerLo); ullVer = (ULONGLONG)dwVerHi; ullVer <<= sizeof(DWORD); ullVer |= dwVerLo; if(ullVer > ullVerLatest) { if(pIAsmNameLatestVer) pIAsmNameLatestVer->Release(); ullVerLatest = ullVer; pIAsmNameLatestVer = pIAsmNameFound; } else pIAsmNameFound->Release(); } else break; } // if found, fill the gaps if(pIAsmNameLatestVer) { DWORD cbSize=0; USHORT usDummy=0; if(m_pCurAsmRef->pPublicKeyToken == NULL) { cbSize = 1024; pIAsmNameLatestVer->GetProperty(ASM_NAME_PUBLIC_KEY_TOKEN, wzUniBuf, &cbSize); if(cbSize) { if((m_pCurAsmRef->pPublicKeyToken = new BinStr())) memcpy(m_pCurAsmRef->pPublicKeyToken->getBuff(cbSize), wzUniBuf, cbSize); } } if(m_pCurAsmRef->usVerMajor == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_MAJOR_VERSION, &usDummy, &cbSize); m_pCurAsmRef->usVerMajor = usDummy; } if(m_pCurAsmRef->usVerMinor == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_MINOR_VERSION, &usDummy, &cbSize); m_pCurAsmRef->usVerMinor = usDummy; } if(m_pCurAsmRef->usBuild == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_BUILD_NUMBER, &usDummy, &cbSize); m_pCurAsmRef->usBuild = usDummy; } if(m_pCurAsmRef->usRevision == (USHORT)0xFFFF) { cbSize = (DWORD)sizeof(WORD); pIAsmNameLatestVer->GetProperty(ASM_NAME_REVISION_NUMBER, &usDummy, &cbSize); m_pCurAsmRef->usRevision = usDummy; } if(m_pCurAsmRef->pLocale == NULL) { cbSize = 1024; pIAsmNameLatestVer->GetProperty(ASM_NAME_CULTURE, wzUniBuf, &cbSize); if(cbSize > (DWORD)sizeof(WCHAR)) { if((m_pCurAsmRef->pLocale = new BinStr())) memcpy(m_pCurAsmRef->pLocale->getBuff(cbSize), wzUniBuf, cbSize); } } pIAsmNameLatestVer->Release(); } else report->warn("Failed to autodetect assembly '%s'\n",m_pCurAsmRef->szName); // if no assembly found, leave it as is, it might be not a GAC assembly pIAsmEnum->Release(); } else report->error("Failed to enum assemblies %S, hr=0x%08X\n",wzUniBuf,hr); pIAsmName->Release(); } else report->error("Failed to create assembly name object for %S, hr=0x%08X\n",wzUniBuf,hr); } // end if isAutodetect m_AsmRefLst.PUSH(m_pCurAsmRef); m_pCurAsmRef->tkTok = TokenFromRid(m_AsmRefLst.COUNT(),mdtAssemblyRef); } else { HRESULT hr = S_OK; m_pCurAsmRef->tkTok = TokenFromRid(1,mdtAssembly); // Determine the strong name public key. This may have been set // via a directive in the source or from the command line (which // overrides the directive). From the command line we may have // been provided with a file or the name of a CAPI key // container. Either may contain a public key or a full key // pair. if (((Assembler*)m_pAssembler)->m_wzKeySourceName) { { // Read public key or key pair from file. HANDLE hFile = WszCreateFile(((Assembler*)m_pAssembler)->m_wzKeySourceName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFile == INVALID_HANDLE_VALUE) { hr = GetLastError(); report->error("Failed to open key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr); m_pCurAsmRef = NULL; return; } // Determine file size and allocate an appropriate buffer. m_sStrongName.m_cbPublicKey = SafeGetFileSize(hFile, NULL); if (m_sStrongName.m_cbPublicKey == 0xffffffff) { report->error("File size too large\n"); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } m_sStrongName.m_pbPublicKey = new BYTE[m_sStrongName.m_cbPublicKey]; if (m_sStrongName.m_pbPublicKey == NULL) { report->error("Failed to allocate key buffer\n"); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } m_sStrongName.m_dwPublicKeyAllocated = 2; // Read the file into the buffer. DWORD dwBytesRead; if (!ReadFile(hFile, m_sStrongName.m_pbPublicKey, m_sStrongName.m_cbPublicKey, &dwBytesRead, NULL)) { hr = GetLastError(); report->error("Failed to read key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } CloseHandle(hFile); // Guess whether we're full or delay signing based on // whether the blob passed to us looks like a public // key. (I.e. we may just have copied a full key pair // into the public key buffer). if (m_sStrongName.m_cbPublicKey >= sizeof(PublicKeyBlob) && (offsetof(PublicKeyBlob, PublicKey) + ((PublicKeyBlob*)m_sStrongName.m_pbPublicKey)->cbPublicKey) == m_sStrongName.m_cbPublicKey) m_sStrongName.m_fFullSign = FALSE; else m_sStrongName.m_fFullSign = TRUE; // If we really have a key pair, we'll move it into a // key container so the signing code gets the key pair // from a consistent place. if (m_sStrongName.m_fFullSign) { m_sStrongName.m_pbPrivateKey = m_sStrongName.m_pbPublicKey; m_sStrongName.m_cbPrivateKey = m_sStrongName.m_cbPublicKey; m_sStrongName.m_pbPublicKey = NULL; m_sStrongName.m_cbPublicKey = NULL; m_sStrongName.m_dwPublicKeyAllocated = 0; // Retrieve the public key portion as a byte blob. if (!StrongNameGetPublicKey(NULL, m_sStrongName.m_pbPrivateKey, m_sStrongName.m_cbPrivateKey, &m_sStrongName.m_pbPublicKey, &m_sStrongName.m_cbPublicKey)) { hr = StrongNameErrorInfo(); report->error("Failed to extract public key: 0x%08X\n",hr); m_pCurAsmRef = NULL; return; } m_sStrongName.m_dwPublicKeyAllocated = 2; } } } else if (m_pAssembly->pPublicKey) { m_sStrongName.m_pbPublicKey = m_pAssembly->pPublicKey->ptr(); m_sStrongName.m_cbPublicKey = m_pAssembly->pPublicKey->length(); m_sStrongName.m_wzKeyContainer = NULL; m_sStrongName.m_fFullSign = FALSE; m_sStrongName.m_dwPublicKeyAllocated = 0; } else { m_sStrongName.m_pbPublicKey = NULL; m_sStrongName.m_cbPublicKey = 0; m_sStrongName.m_wzKeyContainer = NULL; m_sStrongName.m_fFullSign = FALSE; m_sStrongName.m_dwPublicKeyAllocated = 0; } } m_pCurAsmRef = NULL; } ((Assembler*)m_pAssembler)->m_pCustomDescrList = ((Assembler*)m_pAssembler)->m_CustomDescrListStack.POP(); }
HRESULT GetHash(__in LPWSTR moduleName, ALG_ID iHashAlg, BYTE** pbCurrentValue, // should be NULL DWORD *cbCurrentValue) { HRESULT hr = E_FAIL; HCRYPTPROV hProv = 0; HCRYPTHASH hHash = 0; DWORD dwCount = sizeof(DWORD); PBYTE pbBuffer = NULL; DWORD dwBufferLen; HANDLE hFile = INVALID_HANDLE_VALUE; HANDLE hMapFile = NULL; hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (hFile == INVALID_HANDLE_VALUE) return E_FAIL; dwBufferLen = SafeGetFileSize(hFile,NULL); if (dwBufferLen == 0xffffffff) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } hMapFile = WszCreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hMapFile == NULL) goto exit; pbBuffer = (PBYTE) MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); if (pbBuffer == NULL) goto exit; // No need to late bind this stuff, all these crypto API entry points happen // to live in ADVAPI32. if ((!WszCryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) || (!CryptCreateHash(hProv, iHashAlg, 0, 0, &hHash)) || (!CryptHashData(hHash, pbBuffer, dwBufferLen, 0)) || (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *) cbCurrentValue, &dwCount, 0))) { hr = HRESULT_FROM_WIN32(GetLastError()); goto exit; } *pbCurrentValue = new BYTE[*cbCurrentValue]; if (!(*pbCurrentValue)) { hr = E_OUTOFMEMORY; goto exit; } if(!CryptGetHashParam(hHash, HP_HASHVAL, *pbCurrentValue, cbCurrentValue, 0)) { hr = HRESULT_FROM_WIN32(GetLastError()); delete[] *pbCurrentValue; *pbCurrentValue = 0; goto exit; } hr = S_OK; exit: if (pbBuffer) UnmapViewOfFile(pbBuffer); if (hMapFile) CloseHandle(hMapFile); CloseHandle(hFile); if (hHash) CryptDestroyHash(hHash); if (hProv) CryptReleaseContext(hProv, 0); return hr; }
HRESULT AsmMan::EmitManifest() { //AsmManAssembly* pAsmRef; AsmManComType* pComType; AsmManRes* pManRes; HRESULT hr = S_OK; wzUniBuf[0] = 0; if(m_pAsmEmitter==NULL) hr=m_pEmitter->QueryInterface(IID_IMetaDataAssemblyEmit, (void**) &m_pAsmEmitter); if(SUCCEEDED(hr)) { EmitFiles(); EmitAssembly(); if((((Assembler*)m_pAssembler)->m_dwIncludeDebugInfo != 0) && (m_pAssembly == NULL) && !(((Assembler*)m_pAssembler)->m_fENCMode)) { mdToken tkOwner, tkMscorlib; tkMscorlib = ((Assembler*)m_pAssembler)->GetAsmRef("mscorlib"); tkOwner = ((Assembler*)m_pAssembler)->ResolveClassRef(tkMscorlib, "System.Runtime.CompilerServices.AssemblyAttributesGoHere", NULL); EmitDebuggableAttribute(tkOwner); } // Emit all com types unsigned i; for(i = 0; (pComType = m_ComTypeLst.PEEK(i)); i++) { if(!pComType->m_fNew) continue; pComType->m_fNew = FALSE; WszMultiByteToWideChar(g_uCodePage,0,pComType->szName,-1,wzUniBuf,dwUniBuf); mdToken tkImplementation = mdTokenNil; if(pComType->tkImpl) tkImplementation = pComType->tkImpl; else if(pComType->szFileName) { tkImplementation = GetFileTokByName(pComType->szFileName); if(tkImplementation==mdFileNil) { report->error("Undefined File '%s' in ExportedType '%s'\n",pComType->szFileName,pComType->szName); if(!((Assembler*)m_pAssembler)->OnErrGo) continue; } } else if(pComType->szAsmRefName) { tkImplementation = GetAsmRefTokByName(pComType->szAsmRefName); if(RidFromToken(tkImplementation)==0) { report->error("Undefined AssemblyRef '%s' in ExportedType '%s'\n",pComType->szAsmRefName,pComType->szName); if(!((Assembler*)m_pAssembler)->OnErrGo) continue; } } else if(pComType->szComTypeName) { tkImplementation = GetComTypeTokByName(pComType->szComTypeName); if(tkImplementation==mdExportedTypeNil) { report->error("Undefined ExportedType '%s' in ExportedType '%s'\n",pComType->szComTypeName,pComType->szName); if(!((Assembler*)m_pAssembler)->OnErrGo) continue; } } else { report->warn("Undefined implementation in ExportedType '%s' -- ExportType not emitted\n",pComType->szName); if(!((Assembler*)m_pAssembler)->OnErrGo) continue; } hr = m_pAsmEmitter->DefineExportedType( // S_OK or error. (LPCWSTR)wzUniBuf, // [IN] Name of the Com Type. tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the ComType. (mdTypeDef)pComType->tkClass, // [IN] TypeDef token within the file. pComType->dwAttr, // [IN] Flags. (mdExportedType*)&(pComType->tkTok)); // [OUT] Returned ComType token. if(FAILED(hr)) report->error("Failed to define ExportedType '%s': 0x%08X\n",pComType->szName,hr); else { ((Assembler*)m_pAssembler)->EmitCustomAttributes(pComType->tkTok, &(pComType->m_CustomDescrList)); } } // Emit all manifest resources m_dwMResSizeTotal = 0; m_dwMResNum = 0; for(i = 0; (pManRes = m_ManResLst.PEEK(i)); i++) { BOOL fOK = TRUE; mdToken tkImplementation = mdFileNil; if(!pManRes->m_fNew) continue; pManRes->m_fNew = FALSE; WszMultiByteToWideChar(g_uCodePage,0,pManRes->szAlias,-1,wzUniBuf,dwUniBuf); if(pManRes->szAsmRefName) { tkImplementation = GetAsmRefTokByName(pManRes->szAsmRefName); if(RidFromToken(tkImplementation)==0) { report->error("Undefined AssemblyRef '%s' in MResource '%s'\n",pManRes->szAsmRefName,pManRes->szName); fOK = FALSE; } } else if(pManRes->szFileName) { tkImplementation = GetFileTokByName(pManRes->szFileName); if(RidFromToken(tkImplementation)==0) { report->error("Undefined File '%s' in MResource '%s'\n",pManRes->szFileName,pManRes->szName); fOK = FALSE; } } else // embedded mgd.resource, go after the file { HANDLE hFile = INVALID_HANDLE_VALUE; int j; WCHAR wzFileName[2048]; WCHAR* pwz; pManRes->ulOffset = m_dwMResSizeTotal; for(j=0; (hFile == INVALID_HANDLE_VALUE)&&(pwzInputFiles[j] != NULL); j++) { wcscpy_s(wzFileName,2048,pwzInputFiles[j]); pwz = wcsrchr(wzFileName,'\\'); if(pwz == NULL) pwz = wcsrchr(wzFileName,':'); if(pwz == NULL) pwz = &wzFileName[0]; else pwz++; wcscpy_s(pwz,2048-(pwz-wzFileName),wzUniBuf); hFile = WszCreateFile(wzFileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); } if (hFile == INVALID_HANDLE_VALUE) { report->error("Failed to open managed resource file '%s'\n",pManRes->szAlias); fOK = FALSE; } else { m_dwMResSize[m_dwMResNum] = SafeGetFileSize(hFile,NULL); if(m_dwMResSize[m_dwMResNum] == 0xFFFFFFFF) { report->error("Failed to get size of managed resource file '%s'\n",pManRes->szAlias); fOK = FALSE; } else { m_dwMResSizeTotal += m_dwMResSize[m_dwMResNum]+sizeof(DWORD); m_wzMResName[m_dwMResNum] = new WCHAR[wcslen(wzFileName)+1]; wcscpy_s(m_wzMResName[m_dwMResNum],wcslen(wzFileName)+1,wzFileName); m_fMResNew[m_dwMResNum] = TRUE; m_dwMResNum++; } CloseHandle(hFile); } } if(fOK || ((Assembler*)m_pAssembler)->OnErrGo) { WszMultiByteToWideChar(g_uCodePage,0,pManRes->szName,-1,wzUniBuf,dwUniBuf); hr = m_pAsmEmitter->DefineManifestResource( // S_OK or error. (LPCWSTR)wzUniBuf, // [IN] Name of the resource. tkImplementation, // [IN] mdFile or mdAssemblyRef that provides the resource. pManRes->ulOffset, // [IN] Offset to the beginning of the resource within the file. pManRes->dwAttr, // [IN] Flags. (mdManifestResource*)&(pManRes->tkTok)); // [OUT] Returned ManifestResource token. if(FAILED(hr)) report->error("Failed to define manifest resource '%s': 0x%08X\n",pManRes->szName,hr); } } m_pAsmEmitter->Release(); m_pAsmEmitter = NULL; } else report->error("Failed to obtain IMetaDataAssemblyEmit interface: 0x%08X\n",hr); return hr; }
//***************************************************************************** // Open the base file on top of: (a) file, (b) memory buffer, or (c) stream. // If create flag is specified, then this will create a new file with the // name supplied. No data is read from an opened file. You must call // MapFileToMem before doing direct pointer access to the contents. //***************************************************************************** HRESULT StgIO::Open( // Return code. LPCWSTR szName, // Name of the storage. int fFlags, // How to open the file. const void *pbBuff, // Optional buffer for memory. ULONG cbBuff, // Size of buffer. IStream *pIStream, // Stream for input. LPSECURITY_ATTRIBUTES pAttributes) // Security token. { HRESULT hr; // If we were given the storage memory to begin with, then use it. if (pbBuff && cbBuff) { _ASSERTE((fFlags & DBPROP_TMODEF_WRITE) == 0); // Save the memory address and size only. No handles. m_pData = (void *) pbBuff; m_cbData = cbBuff; // All access to data will be by memory provided. if ((fFlags & DBPROP_TMODEF_SHAREDMEM) == DBPROP_TMODEF_SHAREDMEM) { // We're taking ownership of this memory m_pBaseData = m_pData; m_iType = STGIO_SHAREDMEM; } else { m_iType = STGIO_MEM; } goto ErrExit; } // Check for data backed by a stream pointer. else if (pIStream) { // If this is for the non-create case, get the size of existing data. if ((fFlags & DBPROP_TMODEF_CREATE) == 0) { LARGE_INTEGER iMove = { { 0, 0 } }; ULARGE_INTEGER iSize; // Need the size of the data so we can map it into memory. if (FAILED(hr = pIStream->Seek(iMove, STREAM_SEEK_END, &iSize))) return (hr); m_cbData = iSize.u.LowPart; } // Else there is nothing. else m_cbData = 0; // Save an addref'd copy of the stream. m_pIStream = pIStream; m_pIStream->AddRef(); // All access to data will be by memory provided. m_iType = STGIO_STREAM; goto ErrExit; } // If not on memory, we need a file to do a create/open. if (!szName || !*szName) { return (PostError(E_INVALIDARG)); } // Check for create of a new file. else if (fFlags & DBPROP_TMODEF_CREATE) { //<REVISIT_TODO>@future: This could chose to open the file in write through // mode, which would provide better Duribility (from ACID props), // but would be much slower.</REVISIT_TODO> // Create the new file, overwriting only if caller allows it. if ((m_hFile = WszCreateFile(szName, GENERIC_READ | GENERIC_WRITE, 0, 0, (fFlags & DBPROP_TMODEF_FAILIFTHERE) ? CREATE_NEW : CREATE_ALWAYS, 0, 0)) == INVALID_HANDLE_VALUE) { return (MapFileError(GetLastError())); } // Data will come from the file. m_iType = STGIO_HFILE; } // For open in read mode, need to open the file on disk. If opening a shared // memory view, it has to be opened already, so no file open. else if ((fFlags & DBPROP_TMODEF_WRITE) == 0) { // We have not opened the file nor loaded it as module _ASSERTE(m_hFile == INVALID_HANDLE_VALUE); _ASSERTE(m_hModule == NULL); // Open the file for read. Sharing is determined by caller, it can // allow other readers or be exclusive. DWORD dwFileSharingFlags = FILE_SHARE_DELETE; if (!(fFlags & DBPROP_TMODEF_EXCLUSIVE)) { dwFileSharingFlags |= FILE_SHARE_READ; #if !defined(DACCESS_COMPILE) && !defined(FEATURE_PAL) // PEDecoder is not defined in DAC // We prefer to use LoadLibrary if we can because it will share already loaded images (used for execution) // which saves virtual memory. We only do this if our caller has indicated that this PE file is trusted // and thus it is OK to do LoadLibrary (note that we still only load it as a resource, which mitigates // most of the security risk anyway). if ((fFlags & DBPROP_TMODEF_TRYLOADLIBRARY) != 0) { m_hModule = WszLoadLibraryEx(szName, NULL, LOAD_LIBRARY_AS_IMAGE_RESOURCE); if (m_hModule != NULL) { m_iType = STGIO_HMODULE; m_mtMappedType = MTYPE_IMAGE; // LoadLibraryEx returns 2 lowest bits indicating how the module was loaded m_pBaseData = m_pData = (void *)(((INT_PTR)m_hModule) & ~(INT_PTR)0x3); PEDecoder peDecoder; if (SUCCEEDED(peDecoder.Init( m_pBaseData, false)) && // relocated peDecoder.CheckNTHeaders()) { m_cbData = peDecoder.GetNTHeaders32()->OptionalHeader.SizeOfImage; } else { // PEDecoder failed on loaded library, let's backout all our changes to this object // and fall back to file mapping m_iType = STGIO_NODATA; m_mtMappedType = MTYPE_NOMAPPING; m_pBaseData = m_pData = NULL; FreeLibrary(m_hModule); m_hModule = NULL; } } } #endif //!DACCESS_COMPILE && !FEATURE_PAL } if (m_hModule == NULL) { // We didn't get the loaded module (we either didn't want to or it failed) HandleHolder hFile(WszCreateFile(szName, GENERIC_READ, dwFileSharingFlags, 0, OPEN_EXISTING, 0, 0)); if (hFile == INVALID_HANDLE_VALUE) return (MapFileError(GetLastError())); // Get size of file. m_cbData = ::SetFilePointer(hFile, 0, 0, FILE_END); // Can't read anything from an empty file. if (m_cbData == 0) return (PostError(CLDB_E_NO_DATA)); // Data will come from the file. m_hFile = hFile.Extract(); m_iType = STGIO_HFILE; } } ErrExit: // If we will ever write, then we need the buffer cache. if (fFlags & DBPROP_TMODEF_WRITE) { // Allocate a cache buffer for writing. if ((m_rgBuff = (BYTE *) AllocateMemory(m_iCacheSize)) == NULL) { Close(); return PostError(OutOfMemory()); } m_cbBuff = 0; } // Save flags for later. m_fFlags = fFlags; if ((szName != NULL) && (*szName != 0)) { WCHAR rcExt[_MAX_PATH]; SplitPath(szName, NULL, 0, NULL, 0, NULL, 0, rcExt, _MAX_PATH); if (SString::_wcsicmp(rcExt, W(".obj")) == 0) { m_FileType = FILETYPE_NTOBJ; } else if (SString::_wcsicmp(rcExt, W(".tlb")) == 0) { m_FileType = FILETYPE_TLB; } } // For auto map case, map the view of the file as part of open. if (m_bAutoMap && (m_iType == STGIO_HFILE || m_iType == STGIO_STREAM) && !(fFlags & DBPROP_TMODEF_CREATE)) { void * ptr; ULONG cb; if (FAILED(hr = MapFileToMem(ptr, &cb, pAttributes))) { Close(); return hr; } } return S_OK; } // StgIO::Open
//----------------------------------------------------------------------------- // Initliaze perf logging. Must be called before calling PERFLOG (x)... void PerfLog::PerfLogInitialize() { LIMITED_METHOD_CONTRACT; // Make sure we are called only once. if (m_perfLogInit) { return; } // First check for special cases: #if defined(ENABLE_JIT_PERF) // Checks the JIT_PERF_OUTPUT env var and sets g_fJitPerfOn. InitJitPerf(); #endif #ifdef WS_PERF // Private working set perf stats InitWSPerf(); #endif // WS_PERF // Put other special cases here. // <TODO>@TODO agk: clean this logic a bit</TODO> // Special cases considered. Now turn on loggin if any of above want logging // or if PERF_OUTPUT says so. InlineSString<4> lpszValue; // Read the env var PERF_OUTPUT and if set continue. m_fLogPerfData = WszGetEnvironmentVariable (W("PERF_OUTPUT"), lpszValue); #if defined(ENABLE_JIT_PERF) if (!m_fLogPerfData) { // Make sure that JIT perf was not requested. if (!g_fJitPerfOn) return; // JIT perf stats are needed so set the flags also. m_fLogPerfData = 1; } #endif // See if we want to output to the database PathString _lpszValue; DWORD _cchValue = 10; // 11 - 1 _cchValue = WszGetEnvironmentVariable (W("PerfOutput"), _lpszValue); if (_cchValue && (wcscmp (_lpszValue, W("DBase")) == 0)) m_perfAutomationFormat = true; if (_cchValue && (wcscmp (_lpszValue, W("CSV")) == 0)) m_commaSeparatedFormat = true; if (PerfAutomationFormat() || CommaSeparatedFormat()) { // Hardcoded file name for spitting the perf auotmation formatted perf data. Open // the file here for writing and close in PerfLogDone(). m_hPerfLogFileHandle = WszCreateFile ( #ifdef PLATFORM_UNIX W("/tmp/PerfData.dat"), #else W("C:\\PerfData.dat"), #endif GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0); // check return value if(m_hPerfLogFileHandle == INVALID_HANDLE_VALUE) { m_fLogPerfData = 0; goto ErrExit; } // Make sure we append to the file. <TODO>@TODO agk: Is this necessary?</TODO> if(SetFilePointer (m_hPerfLogFileHandle, 0, NULL, FILE_END) == INVALID_SET_FILE_POINTER ) { CloseHandle (m_hPerfLogFileHandle); m_fLogPerfData = 0; goto ErrExit; } } m_perfLogInit = true; ErrExit: return; }
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" ); } } }
void AsmMan::EndAssembly() { if(m_pCurAsmRef) { if(m_pCurAsmRef->isRef) { // list the assembly ref if(GetAsmRefByName(m_pCurAsmRef->szAlias)) { //report->warn("Multiple declarations of Assembly Ref '%s', ignored except the 1st one\n",m_pCurAsmRef->szName); delete m_pCurAsmRef; m_pCurAsmRef = NULL; return; } m_AsmRefLst.PUSH(m_pCurAsmRef); m_pCurAsmRef->tkTok = TokenFromRid(m_AsmRefLst.COUNT(),mdtAssemblyRef); } else { HRESULT hr = S_OK; m_pCurAsmRef->tkTok = TokenFromRid(1,mdtAssembly); // Determine the strong name public key. This may have been set // via a directive in the source or from the command line (which // overrides the directive). From the command line we may have // been provided with a file or the name of a CAPI key // container. Either may contain a public key or a full key // pair. if (((Assembler*)m_pAssembler)->m_wzKeySourceName) { // Key file versus container is determined by the first // character of the source ('@' for container). if (*(((Assembler*)m_pAssembler)->m_wzKeySourceName) == L'@') { report->error("Error: ilasm on CoreCLR does not support getting public key from container.\n"); m_pCurAsmRef = NULL; return; } else { // Read public key or key pair from file. HANDLE hFile = WszCreateFile(((Assembler*)m_pAssembler)->m_wzKeySourceName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); if(hFile == INVALID_HANDLE_VALUE) { hr = GetLastError(); report->error("Failed to open key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr); m_pCurAsmRef = NULL; return; } // Determine file size and allocate an appropriate buffer. m_sStrongName.m_cbPublicKey = SafeGetFileSize(hFile, NULL); if (m_sStrongName.m_cbPublicKey == 0xffffffff) { report->error("File size too large\n"); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } m_sStrongName.m_pbPublicKey = new BYTE[m_sStrongName.m_cbPublicKey]; if (m_sStrongName.m_pbPublicKey == NULL) { report->error("Failed to allocate key buffer\n"); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::AllocatedByNew; // Read the file into the buffer. DWORD dwBytesRead; if (!ReadFile(hFile, m_sStrongName.m_pbPublicKey, m_sStrongName.m_cbPublicKey, &dwBytesRead, NULL)) { hr = GetLastError(); report->error("Failed to read key file '%S': 0x%08X\n",((Assembler*)m_pAssembler)->m_wzKeySourceName,hr); m_pCurAsmRef = NULL; CloseHandle(hFile); return; } CloseHandle(hFile); // Guess whether we're full or delay signing based on // whether the blob passed to us looks like a public // key. (I.e. we may just have copied a full key pair // into the public key buffer). if (m_sStrongName.m_cbPublicKey >= sizeof(PublicKeyBlob) && (offsetof(PublicKeyBlob, PublicKey) + ((PublicKeyBlob*)m_sStrongName.m_pbPublicKey)->cbPublicKey) == m_sStrongName.m_cbPublicKey) m_sStrongName.m_fFullSign = FALSE; else m_sStrongName.m_fFullSign = TRUE; // If we really have a key pair, we'll move it into a // key container so the signing code gets the key pair // from a consistent place. if (m_sStrongName.m_fFullSign) { report->error("Error: ilasm on CoreCLR does not support full sign.\n"); m_pCurAsmRef = NULL; return; } } } else { if (m_pAssembly->pPublicKey) { m_sStrongName.m_pbPublicKey = m_pAssembly->pPublicKey->ptr(); m_sStrongName.m_cbPublicKey = m_pAssembly->pPublicKey->length(); } else { m_sStrongName.m_pbPublicKey = NULL; m_sStrongName.m_cbPublicKey = 0; } m_sStrongName.m_wzKeyContainer = NULL; m_sStrongName.m_fFullSign = FALSE; m_sStrongName.m_dwPublicKeyAllocated = AsmManStrongName::NotAllocated; } } m_pCurAsmRef = NULL; } ((Assembler*)m_pAssembler)->m_pCustomDescrList = ((Assembler*)m_pAssembler)->m_CustomDescrListStack.POP(); }