Example #1
0
//*****************************************************************************
// Search the cached RegMetas for a given scope.
//*****************************************************************************
HRESULT LOADEDMODULES::FindCachedReadOnlyEntry(
    LPCWSTR    szName,      // Name of the desired file.
    DWORD      dwOpenFlags, // Flags the new file is opened with.
    RegMeta ** ppMeta)      // Put found RegMeta here.
{
    RegMeta * pRegMeta = 0;
    BOOL      bWillBeCopyMemory;    // Will the opened file be copied to memory?
    DWORD     dwLowFileSize;        // Low bytes of this file's size
    DWORD     dwLowFileTime;        // Low butes of this file's last write time
    HRESULT   hr;
    ULONG     ixHash = 0;
    
    IfFailGo(InitializeStatics());
    
    {
        LOCKREAD();

        hr = S_FALSE; // We haven't found a match yet.

        // Avoid confusion.
        *ppMeta = NULL;
    
        bWillBeCopyMemory = IsOfCopyMemory(dwOpenFlags);

        // The cache is locked for read, so the list will not change.
    
        // Figure out the size and timestamp of this file
        WIN32_FILE_ATTRIBUTE_DATA faData;
        if (!WszGetFileAttributesEx(szName, GetFileExInfoStandard, &faData))
            return E_FAIL;
        dwLowFileSize = faData.nFileSizeLow;
        dwLowFileTime = faData.ftLastWriteTime.dwLowDateTime;

        // Check the hash first.
        ixHash = HashFileName(szName);
        if ((pRegMeta = m_HashedModules[ixHash]) != NULL)
        {
            _ASSERTE(pRegMeta->IsReadOnly());

            // Only match if the IsOfCopyMemory() bit is the same in both.  This is because
            //  when ofCopyMemory is set, the file is not locked on disk, and may become stale
            //  in memory.
            //
            // Also, only match if the date and size are the same
            if (pRegMeta->IsCopyMemory() == bWillBeCopyMemory &&
                pRegMeta->GetLowFileTimeOfDBFile() == dwLowFileTime &&
                pRegMeta->GetLowFileSizeOfDBFile() == dwLowFileSize)
            {
                // If the name matches...
                LPCWSTR pszName = pRegMeta->GetNameOfDBFile();
    #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM
                if (wcscmp(szName, pszName) == 0)
    #else
                if (SString::_wcsicmp(szName, pszName) == 0)
    #endif
                {
                    ULONG cRefs;
                
                    // Found it.  Add a reference, and return it.
                    *ppMeta = pRegMeta;
                    cRefs = pRegMeta->AddRef();
                
                    LOG((LF_METADATA, LL_INFO10, "Disp::OpenScope found cached RegMeta in hash: %#8x, crefs: %d\n", pRegMeta, cRefs));
                
                    return S_OK;
                }
            }
        }

        // Not found in hash; loop through each loaded modules
        int count = s_pLoadedModules->Count();
        for (int index = 0; index < count; index++)
        {
            pRegMeta = (*s_pLoadedModules)[index];

            // If the module is read-only, and the CopyMemory bit matches, and the date
            // and size are the same....
            if (pRegMeta->IsReadOnly() && 
                pRegMeta->IsCopyMemory() == bWillBeCopyMemory &&
                pRegMeta->GetLowFileTimeOfDBFile() == dwLowFileTime &&
                pRegMeta->GetLowFileSizeOfDBFile() == dwLowFileSize)
            {
                // If the name matches...
                LPCWSTR pszName = pRegMeta->GetNameOfDBFile();
    #ifdef FEATURE_CASE_SENSITIVE_FILESYSTEM
                if (wcscmp(szName, pszName) == 0)
    #else
                if (SString::_wcsicmp(szName, pszName) == 0)
    #endif
                {
                    ULONG cRefs;

                    // Found it.  Add a reference, and return it.
                    *ppMeta = pRegMeta;
                    cRefs = pRegMeta->AddRef();

                    // Update the hash.
                    m_HashedModules[ixHash] = pRegMeta;

                    LOG((LF_METADATA, LL_INFO10, "Disp::OpenScope found cached RegMeta by search: %#8x, crefs: %d\n", pRegMeta, cRefs));
                
                    return S_OK;
                }
            }
        }
    }

ErrExit:
    // Didn't find it.
    LOG((LF_METADATA, LL_INFO10, "Disp::OpenScope did not find cached RegMeta\n"));

    _ASSERTE(hr != S_OK);
    return hr;
} // LOADEDMODULES::FindCachedReadOnlyEntry