예제 #1
0
//*****************************************************************************
// Open a metadata section for read
//*****************************************************************************
__checkReturn 
HRESULT CLiteWeightStgdbRW::OpenForRead(
    LPCWSTR     szDatabase,             // Name of database.
    void        *pbData,                // Data to open on top of, 0 default.
    ULONG       cbData,                 // How big is the data.
    DWORD       dwFlags)                // Flags for the open.
{
    LPCWSTR     pNoFile=W("");            // Constant for empty file name.
    StgIO       *pStgIO = NULL;         // For file i/o.
    HRESULT     hr;

    m_pImage = NULL;
    m_dwImageSize = 0;
    m_eFileType = FILETYPE_UNKNOWN;
    // szDatabase, and pbData are mutually exclusive.  Only one may be
    // non-NULL.  Having both NULL means empty stream creation.
    //
    _ASSERTE(!(szDatabase && (pbData)));
    _ASSERTE(!(pbData && (szDatabase)));

    // Open on memory needs there to be something to work with.
    if (pbData && cbData == 0)
        IfFailGo(CLDB_E_NO_DATA);

    // Make sure we have a path to work with.
    if (!szDatabase)
        szDatabase = pNoFile;
    
    // Sanity check the name lentgh.
    if (!IsValidFileNameLength(szDatabase))
    {
        IfFailGo(E_INVALIDARG);
    }
    
    // If we have storage to work with, init it and get type.
    if (*szDatabase || pbData)
    {
        // Allocate a storage instance to use for i/o.
        if ((pStgIO = new (nothrow) StgIO) == 0)
            IfFailGo( E_OUTOFMEMORY );

        DBPROPMODE dmOpenFlags = DBPROP_TMODEF_READ;

        // If we're taking ownership of this memory.....
        if (IsOfTakeOwnership(dwFlags))
        {
#ifdef FEATURE_METADATA_STANDALONE_WINRT_RO
            // Shared memory uses ole32.dll - we cannot depend on it in the standalone WinRT Read-Only DLL
            IfFailGo(E_INVALIDARG);
#else
            dmOpenFlags = (DBPROPMODE)(dmOpenFlags | DBPROP_TMODEF_SHAREDMEM);
#endif //!FEATURE_METADATA_STANDALONE_WINRT_RO
        }
#ifdef FEATURE_METADATA_LOAD_TRUSTED_IMAGES
        if (IsOfTrustedImage(dwFlags))
            dmOpenFlags = (DBPROPMODE)(dmOpenFlags | DBPROP_TMODEF_TRYLOADLIBRARY);
#endif

        // Open the storage so we can read the signature if there is already data.
        IfFailGo( pStgIO->Open(szDatabase, 
                               dmOpenFlags, 
                               pbData, 
                               cbData, 
                               0, // IStream*
                               NULL) );

        // Determine the type of file we are working with.
        IfFailGo( _GetFileTypeForPath(pStgIO, &m_eFileType) );
    }

    // Check for default type.
    if (m_eFileType == FILETYPE_CLB)
    {
        // If user wanted us to make a local copy of the data, do that now.
        if (IsOfCopyMemory(dwFlags))
            IfFailGo(pStgIO->LoadFileToMemory());

        // Try the native .clb file.
        IfFailGo( InitFileForRead(pStgIO, IsOfRead(dwFlags)) );
    }
    // PE/COFF executable/object format.  This requires us to find the .clb 
    // inside the binary before doing the Init.
    else if (m_eFileType == FILETYPE_NTPE || m_eFileType == FILETYPE_NTOBJ)
    {
        //<TODO>@FUTURE: Ideally the FindImageMetaData function
        //@FUTURE:  would take the pStgIO and map only the part of the file where
        //@FUTURE:  our data lives, leaving the rest alone.  This would be smaller
        //@FUTURE:  working set for us.</TODO>
        void        *ptr;
        ULONG       cbSize;

        // Map the entire binary for the FindImageMetaData function.
        IfFailGo( pStgIO->MapFileToMem(ptr, &cbSize) );

        // Find the .clb inside of the content.
        if (m_eFileType == FILETYPE_NTPE)
        {
            m_pImage = ptr;
            m_dwImageSize = cbSize;
            hr = FindImageMetaData(ptr, 
                                   cbSize, 
                                   pStgIO->GetMemoryMappedType() == MTYPE_IMAGE, 
                                   &ptr, 
                                   &cbSize);
        }
        else
        {
            _ASSERTE(pStgIO->GetMemoryMappedType() != MTYPE_IMAGE);
            hr = FindObjMetaData(ptr, cbSize, &ptr, &cbSize);
        }
        // Was the metadata found inside the PE file?
        if (FAILED(hr))
        {
            if (hr == E_OUTOFMEMORY)
                IfFailGo(E_OUTOFMEMORY);
        
            // No clb in the PE, assume it is a type library.
            m_eFileType = FILETYPE_TLB;

            // Let the caller deal with a TypeLib.
            IfFailGo(hr);
        }
        else
        {
            // Metadata was found inside the file.
            // Now reset the base of the stg object so that all memory accesses
            // are relative to the .clb content.
            //
            IfFailGo( pStgIO->SetBaseRange(ptr, cbSize) );

            // If user wanted us to make a local copy of the data, do that now.
            if (IsOfCopyMemory(dwFlags))
            {
                // Cache the PEKind, Machine.
                GetPEKind(pStgIO->GetMemoryMappedType(), NULL, NULL);
                // Copy the file into memory; releases the file.
                IfFailGo(pStgIO->LoadFileToMemory());
                // No longer have the image.
                m_pImage = NULL;
                m_dwImageSize = 0;
            }

            // Defer to the normal lookup.
            IfFailGo( InitFileForRead(pStgIO, IsOfRead(dwFlags)) );
        }
    }
    else if (m_eFileType == FILETYPE_TLB)
    {
        // Let the caller deal with a TypeLib.
        IfFailGo(CLDB_E_NO_DATA);
    }
    // This spells trouble, we need to handle all types we might find.
    else
    {
        _ASSERTE(!"Unknown file type.");
        IfFailGo( E_FAIL );
    }

    // Save off everything.
    IfFailGo(SetFileName(szDatabase));

    // If this was a file...
    if (pbData == NULL)
    {
        WIN32_FILE_ATTRIBUTE_DATA faData;
        if (!WszGetFileAttributesEx(szDatabase, GetFileExInfoStandard, &faData))
            IfFailGo(E_FAIL);
        m_dwDatabaseLFS = faData.nFileSizeLow;
        m_dwDatabaseLFT = faData.ftLastWriteTime.dwLowDateTime;
    }
    
ErrExit:
    if (SUCCEEDED(hr))
    {
        m_pStgIO = pStgIO;
    }
    else
    {
        if (pStgIO != NULL)
            pStgIO->Release();
    }
    return hr;
}
예제 #2
0
파일: mdobj.cpp 프로젝트: ArildF/masters
void DisplayArchive(wchar_t* szFile, ULONG DumpFilter, wchar_t* szObjName, strPassBackFn pDisplayString)
{
    PBYTE       pbMapAddress;
    PBYTE       pbStartAddress;
    PBYTE       pbLongNameAddress;
    PIMAGE_ARCHIVE_MEMBER_HEADER pMemHdr;
    DWORD       dwFileSize;
    PVOID       pvMetaData;
    char        *szName;
    wchar_t     wzName[1024];
    char        szBuf[17];
    long        cbMetaData;
    int         i;
    HRESULT     hr;
	char		szString[1024];

    GetMapViewOfFile(szFile, &pbMapAddress, &dwFileSize);
    pbStartAddress = pbMapAddress;

    // Verify and skip archive signature.
    if (dwFileSize < IMAGE_ARCHIVE_START_SIZE ||
        strncmp((char *)pbMapAddress, IMAGE_ARCHIVE_START, IMAGE_ARCHIVE_START_SIZE))
    {
        MDInfo::Error("Bad file format - archive signature mis-match!");
    }
    pbMapAddress += IMAGE_ARCHIVE_START_SIZE;

    // Skip linker member 1, linker member 2.
    for (i = 0; i < 2; i++)
        pbMapAddress = SkipMember(pbMapAddress);

    // Save address of the long name member and skip it if there exists one.
    pMemHdr = (PIMAGE_ARCHIVE_MEMBER_HEADER)pbMapAddress;
    if (pMemHdr->Name[0] == '/' && pMemHdr->Name[1] == '/')
    {
        pbLongNameAddress = pbMapAddress + IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR;
        pbMapAddress = SkipMember(pbMapAddress);
    }
    else
        pbLongNameAddress = 0;

    pDisplayString ("\n");
    // Get the MetaData for each object file and display it.
    while (DWORD(pbMapAddress - pbStartAddress) < dwFileSize)
    {
        szName = GetNameOfObj(pbLongNameAddress, (PIMAGE_ARCHIVE_MEMBER_HEADER)pbMapAddress, szBuf);
        if (Wsz_mbstowcs(wzName, szName, 1024) == -1)
            MDInfo::Error("Conversion from Multi-Byte to Wide-Char failed.");

        // Display metadata only for object files.
        // If szObjName is specified, display metadata only for that one object file.
        if (!_stricmp(&szName[strlen(szName) - OBJ_EXT_LEN], OBJ_EXT) && 
            (!szObjName || !_wcsicmp(szObjName, wzName)))
        {
            // Try to find the MetaData section in the current object file.
            hr = FindObjMetaData(pbMapAddress+IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR, &pvMetaData, &cbMetaData);
            if (SUCCEEDED(hr))
            {
                sprintf (szString,"MetaData for object file %s:\n", szName);
				pDisplayString(szString);
                MDInfo archiveInfo(g_pDisp,
                                (PBYTE)pvMetaData,
                                cbMetaData,
                                pDisplayString,
                                DumpFilter);
                archiveInfo.DisplayMD();
            }
            else
			{
                sprintf(szString,"MetaData not found for object file %s!\n\n", szName);
				pDisplayString(szString);
			}
        }

        // Skip past the object file.
        pbMapAddress = SkipMember(pbMapAddress);
    }

    UnmapViewOfFile(pbStartAddress);
} // void DisplayArchive()
예제 #3
0
//*****************************************************************************
// Open a metadata section for read
//*****************************************************************************
HRESULT CLiteWeightStgdbRW::OpenForRead(
    LPCWSTR     szDatabase,             // Name of database.
    void        *pbData,                // Data to open on top of, 0 default.
    ULONG       cbData,                 // How big is the data.
    IStream     *pIStream,              // Optional stream to use.
    LPCWSTR     szSharedMem,            // Shared memory name for read.
    int         bReadOnly)              // If true, read-only.
{
    LPCWSTR     pNoFile=L"";            // Constant for empty file name.
    StgIO       *pStgIO = NULL;         // For file i/o.
    HRESULT     hr;

    m_pImage = NULL;
    m_dwImageSize = 0;
    m_eFileType = FILETYPE_UNKNOWN;
    // szDatabase, pbData, and pIStream are mutually exclusive.  Only one may be
    // non-NULL.  Having all 3 NULL means empty stream creation.
    //
    _ASSERTE(!(szDatabase && (pbData || pIStream)));
    _ASSERTE(!(pbData && (szDatabase || pIStream)));
    _ASSERTE(!(pIStream && (szDatabase || pbData)));

    // Open on memory needs there to be something to work with.
    if (pbData && cbData == 0)
        IfFailGo(CLDB_E_NO_DATA);

    // Make sure we have a path to work with.
    if (!szDatabase)
        szDatabase = pNoFile;

    // Sanity check the name.
    if (lstrlenW(szDatabase) >= _MAX_PATH)
        IfFailGo( E_INVALIDARG );

    // If we have storage to work with, init it and get type.
    if (*szDatabase || pbData || pIStream || szSharedMem)
    {
        // Allocate a storage instance to use for i/o.
        if ((pStgIO = new StgIO) == 0)
            IfFailGo( E_OUTOFMEMORY );

        // Open the storage so we can read the signature if there is already data.
        IfFailGo( pStgIO->Open(szDatabase,
                               STGIO_READ,
                               pbData,
                               cbData,
                               pIStream,
                               szSharedMem,
                               NULL) );

        // Determine the type of file we are working with.
        IfFailGo( _GetFileTypeForPath(pStgIO, &m_eFileType) );
    }

    // Check for default type.
    if (m_eFileType == FILETYPE_CLB)
    {
        // Try the native .clb file.
        IfFailGo( InitFileForRead(pStgIO, bReadOnly) );
    }
    // PE/COFF executable/object format.  This requires us to find the .clb
    // inside the binary before doing the Init.
    else if (m_eFileType == FILETYPE_NTPE || m_eFileType == FILETYPE_NTOBJ)
    {
        void        *ptr;
        ULONG       cbSize;

        // Map the entire binary for the FindImageMetaData function.
        IfFailGo( pStgIO->MapFileToMem(ptr, &cbSize) );

        // Find the .clb inside of the content.
        if (m_eFileType == FILETYPE_NTPE)
        {
            m_pImage = ptr;
            m_dwImageSize = cbSize;
            hr = FindImageMetaData(ptr, &ptr, &cbSize, cbSize);
        }
        else
            hr = FindObjMetaData(ptr, &ptr, &cbSize, cbSize);

        // Was the metadata found inside the PE file?
        if (FAILED(hr))
        {
            // No clb in the PE, assume it is a type library.
            m_eFileType = FILETYPE_TLB;

            // Let the caller deal with a TypeLib.
            IfFailGo(CLDB_E_NO_DATA);
        }
        else
        {
            // Metadata was found inside the file.
            // Now reset the base of the stg object so that all memory accesses
            // are relative to the .clb content.
            //
            IfFailGo( pStgIO->SetBaseRange(ptr, cbSize) );

            // Defer to the normal lookup.
            IfFailGo( InitFileForRead(pStgIO, bReadOnly) );
        }
    }
    else if (m_eFileType == FILETYPE_TLB)
    {
        // Let the caller deal with a TypeLib.
        IfFailGo(CLDB_E_NO_DATA);
    }
    // This spells trouble, we need to handle all types we might find.
    else
    {
        _ASSERTE(!"Unknown file type.");
        IfFailGo( E_FAIL );
    }

    // Save off everything.
    wcscpy(m_rcDatabase, szDatabase);

ErrExit:

    if (SUCCEEDED(hr))
    {
        m_pStgIO = pStgIO;
    }
    else
    {
        if (pStgIO)
            pStgIO->Release();
    }
    return (hr);
}