HRESULT CLiteWeightStgdbRW::FindImageMetaData(PVOID pImage, DWORD dwFileLength, BOOL bMappedImage, PVOID *ppMetaData, ULONG *pcbMetaData) { #ifndef DACCESS_COMPILE PEDecoder pe; // We need to use different PEDecoder initialization based on the type of data we give it. // We use the one with a 'bool' as the second argument when dealing with a mapped file, // and we use the one that takes a COUNT_T as the second argument when dealing with a // flat file. if (bMappedImage) { if (FAILED(pe.Init(pImage, false)) || !pe.CheckNTHeaders()) { return COR_E_BADIMAGEFORMAT; } } else { pe.Init(pImage, (COUNT_T)dwFileLength); } // Minimally validate image if (!pe.CheckCorHeader()) return COR_E_BADIMAGEFORMAT; COUNT_T size = 0; *ppMetaData = (void *)pe.GetMetadata(&size); // Couldn't find any IL metadata in this image if (*ppMetaData == NULL) return CLDB_E_NO_DATA; if (pcbMetaData != NULL) *pcbMetaData = size; return S_OK; #else DacNotImpl(); return E_NOTIMPL; #endif } // CLiteWeightStgdbRW::FindImageMetaData
//***************************************************************************** // Pull the PEKind and Machine out of PE headers -- if we have PE headers. //***************************************************************************** __checkReturn HRESULT CLiteWeightStgdbRW::GetPEKind( // S_OK or error. MAPPINGTYPE mtMapping, // The type of mapping the image has DWORD *pdwPEKind, // [OUT] The kind of PE (0 - not a PE) DWORD *pdwMachine) // [OUT] Machine as defined in NT header { HRESULT hr = NOERROR; DWORD dwPEKind=0; // Working copy of pe kind. DWORD dwMachine=0; // Working copy of machine. #ifndef DACCESS_COMPILE // Do we already have cached information? if (m_dwPEKind != (DWORD)(-1)) { dwPEKind = m_dwPEKind; dwMachine = m_dwMachine; } else if (m_pImage) { PEDecoder pe; // We need to use different PEDecoder initialization based on the type of data we give it. // We use the one with a 'bool' as the second argument when dealing with a mapped file, // and we use the one that takes a COUNT_T as the second argument when dealing with a // flat file. if (mtMapping == MTYPE_IMAGE) { if (FAILED(pe.Init(m_pImage, false)) || !pe.CheckNTHeaders()) { IfFailRet(COR_E_BADIMAGEFORMAT); } } else { pe.Init(m_pImage, (COUNT_T)(m_dwImageSize)); } if (pe.HasContents() && pe.HasNTHeaders()) { pe.GetPEKindAndMachine(&dwPEKind, &dwMachine); // Cache entries. m_dwPEKind = dwPEKind; m_dwMachine = dwMachine; } else // if (pe.HasContents()... { hr = COR_E_BADIMAGEFORMAT; } } else { hr = S_FALSE; } #endif if (pdwPEKind) *pdwPEKind = dwPEKind; if (pdwMachine) *pdwMachine = dwMachine; return hr; } // CLiteWeightStgdbRW::GetPEKind
//***************************************************************************** // 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