예제 #1
0
파일: mdutil.cpp 프로젝트: 0-wiz-0/coreclr
//*****************************************************************************
// This is used in conjunction with GetClassFromCORPath.  See it for details
// of the algorithm.
//*****************************************************************************
HRESULT CORPATHService::GetClassFromDir(
    __in __in_z LPWSTR        wzClassname,            // Fully qualified class name.
    __in SString&             directory,             // Directory to try. at most appended with a '\\'
    mdTypeRef   tr,                     // TypeRef to resolve.
    IMetaModelCommon *pCommon,          // Scope in which the TypeRef is defined.
    REFIID        riid, 
    IUnknown    **ppIScope,
    mdTypeDef    *ptd)                    // [OUT] typedef
{
    WCHAR    *temp;                        // Used as a parsing temp.
    int        iTmp;
    bool    bContinue;                    // Flag to check if the for loop should end.
    LPWSTR    wzSaveClassname = NULL;     // Saved offset into the class name string.
    
    // Process the class name appending each segment of the name to the
    // directory until we find a DLL.
    PathString dir;
    if (!directory.EndsWith(DIRECTORY_SEPARATOR_CHAR_W))
    {
        directory.Append(DIRECTORY_SEPARATOR_CHAR_W);
    }

    for(;;)
    {
        bContinue = false;
        dir.Set(directory);

        if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) != NULL)
        {
            *temp = W('\0');  //terminate with null so that it can be appended
            dir.Append(wzClassname);
            *temp = NAMESPACE_SEPARATOR_WCHAR;   //recover the '.'

            wzClassname = temp+1;
            // Check if a directory by this name exists.
            DWORD iAttrs = WszGetFileAttributes(dir);
            if (iAttrs != 0xffffffff && (iAttrs & FILE_ATTRIBUTE_DIRECTORY))
            {
                // Next element in the class spec.
                bContinue = true;
                wzSaveClassname = wzClassname;
            }
        }
        else
        {
            dir.Append(wzClassname);

            // Advance past the class name.
            iTmp = (int)wcslen(wzClassname);
            wzClassname += iTmp;
        }

        // Try to load the image.
        dir.Append(W(".dll"));
       
        // OpenScope given the dll name and make sure that the class is defined in the module.
        if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) )
        {
            return (S_OK);
        }

        // If we didn't find the dll, try some more.
        while (*wzClassname != W('\0'))
        {
            // Find the length of the next class name element.
            if ((temp = wcschr(wzClassname, NAMESPACE_SEPARATOR_WCHAR)) == NULL)
            {
                temp = wzClassname + wcslen(wzClassname);
            }

            // Tack on ".element.dll"
            SString::Iterator iter = dir.End();
            BOOL findperiod = dir.FindBack(iter, NAMESPACE_SEPARATOR_WCHAR);
            _ASSERTE(findperiod);
            iter++;
            dir.Truncate(iter);
            
            WCHAR save = *temp;
            *temp      = W('\0');
            dir.Append(wzClassname);  //element
            *temp = save;
            
            // Try to load the image.
            dir.Append(W(".dll"));
           
            // OpenScope given the dll name and make sure that the class is defined in the module.
            if ( SUCCEEDED( CORPATHService::FindTypeDef(dir, tr, pCommon, riid, ppIScope, ptd) ) )
            {
                return (S_OK);
            }

            // Advance to the next class name element.
            wzClassname = temp;
            if (*wzClassname != '\0')
                ++wzClassname;
        }
        if (bContinue)
        {
            
            wzClassname = wzSaveClassname;
        }
        else
        {
            break;
        }
    }
    return S_FALSE;
} // CORPATHService::GetClassFromDir
예제 #2
0
파일: mdutil.cpp 프로젝트: 0-wiz-0/coreclr
//*****************************************************************************
// This is a routine to try to find a class implementation given its fully
// qualified name by using the CORPATH environment variable.  CORPATH is a list
// of directories (like PATH).  Before checking CORPATH, this checks the current
// directory, then the directory that the exe lives in.  The search is
// performed by parsing off one element at a time from the class name,
// appending it to the directory and looking for a subdirectory or image with
// that name.  If the subdirectory exists, it drills down into that subdirectory
// and tries the next element of the class name.  When it finally bottoms out
// but can't find the image it takes the rest of the fully qualified class name
// and appends them with intervening '.'s trying to find a matching DLL.
// Example:
//
// CORPATH=c:\bin;c:\prog
// classname = namespace.class
//
// checks the following things in order:
// c:\bin\namespace, (if <-exists) c:\bin\namespace\class.dll,
//        c:\bin\namespace.dll, c:\bin\namespace.class.dll
// c:\prog\namespace, (if <-exists) c:\prog\namespace\class.dll,
//        c:\prog\namespace.dll, c:\prog\namespace.class.dll
//*****************************************************************************
HRESULT CORPATHService::GetClassFromCORPath(
    __in __in_z LPWSTR        wzClassname,            // [IN] fully qualified class name
    mdTypeRef   tr,                     // [IN] TypeRef to be resolved.
    IMetaModelCommon *pCommon,          // [IN] Scope in which the TypeRef is defined.
    REFIID        riid,                   // [IN] Interface type to be returned.
    IUnknown    **ppIScope,             // [OUT] Scope in which the TypeRef resolves.
    mdTypeDef    *ptd)                    // [OUT] typedef corresponding the typeref
{
    PathString    rcCorPath;  // The CORPATH environment variable.
    LPWSTR        szCorPath;  // Used to parse CORPATH.
    int            iLen;                   // Length of the directory.
    PathString     rcCorDir;    // Buffer for the directory.
    WCHAR        *temp;                  // Used as a parsing temp.
    WCHAR        *szSemiCol;

    // Get the CORPATH environment variable.
    if (WszGetEnvironmentVariable(W("CORPATH"), rcCorPath))
    {
        NewArrayHolder<WCHAR> szCorPathHolder = rcCorPath.GetCopyOfUnicodeString();
        szCorPath = szCorPathHolder.GetValue();
        // Try each directory in the path.
        for(;*szCorPath != W('\0');)
        {
            // Get the next directory off the path.
            if ((szSemiCol = wcschr(szCorPath, W(';'))))
            {
                temp = szCorPath;
                *szSemiCol = W('\0');
                szCorPath = szSemiCol + 1;
            }
            else 
            {
                temp = szCorPath;
                szCorPath += wcslen(temp);
            }

            rcCorDir.Set(temp);

            // Check if we can find the class in the directory.
            if (CORPATHService::GetClassFromDir(wzClassname, rcCorDir, tr, pCommon, riid, ppIScope, ptd) == S_OK)
                return S_OK;
        }
    }

    //<TODO>These should go before the path search, but it will cause test
    // some headaches right now, so we'll give them a little time to transition.</TODO>

    // Try the current directory first.
    if ((iLen = WszGetCurrentDirectory( rcCorDir)) > 0 &&
        CORPATHService::GetClassFromDir(wzClassname, rcCorDir, tr, pCommon, riid, ppIScope, ptd) == S_OK)
    {
        return S_OK;
    }
    
    // Try the app directory next.
    if ((iLen = WszGetModuleFileName(NULL, rcCorDir)) > 0)
    {
        
        if(SUCCEEDED(CopySystemDirectory(rcCorDir, rcCorDir)) && 
           CORPATHService::GetClassFromDir(
                    wzClassname, 
                    rcCorDir, 
                    tr, 
                    pCommon, 
                    riid, 
                    ppIScope, 
                    ptd) == S_OK)
        {
            return (S_OK);
        }
    }

    // Couldn't find the class.
    return S_FALSE;
} // CORPATHService::GetClassFromCORPath