Exemple #1
0
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
Exemple #3
0
//*****************************************************************************
// 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