⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fileregistry.cpp

📁 vxworks操作系统的源代码 供研究学习
💻 CPP
字号:
/* unixRegistry.cpp - VxCOM Unix disk-based registry class *//* Copyright (c) 2001 Wind River Systems, Inc. *//*modification history--------------------01b,03jan02,nel  Remove T2OLE reference.01a,02oct01,dsellars  created*/#if defined (VXDCOM_PLATFORM_SOLARIS) || defined (VXDCOM_PLATFORM_LINUX)#include <dirent.h>#include <string>#include <fstream>#include <sys/param.h>#include <dlfcn.h>#include "comLib.h"#include "comObjLib.h"#include "private/comStl.h"#include "private/comMisc.h"////////////////////////////////////////////////////////////////////////////// The 'FileRegistry' class implements a 'plug-in' VxCOM registry for// Unix-based systems, where the coclasses are located in shared// libraries on disk. Each shared library must export a function// called DllGetClassObject() which must match the PFN_GETCLASSOBJECT// signature.//// A text-file (with extension .registry) is used to record the CLSIDs// and map them to shared libraries, which can be anywhere on the// system. The registration file must be in a directory which is// mentioned in the environment variable VXCOM_REGISTRY_PATH (which is// a list of directories, separated by colons, in the usual Unix way).//// Each line in the registry file must be of the form:-////  {CLSID}=/path/to/shared/library.so//// i.e. the string-form of the CLSID as defined by COM, followed by// the path to the shared-library itself.//class FileRegistry :    public CComObjectRoot,    public IRegistry    {  public:    virtual ~FileRegistry ();    FileRegistry ();    // IRegistry implementation...    HRESULT RegisterClass (REFCLSID, void*)        {        // Not required for this kind of registry...        return E_NOTIMPL;        }        HRESULT IsClassRegistered        (        REFCLSID                clsid        );    HRESULT CreateInstance        (        REFCLSID                clsid,        IUnknown *              pUnkOuter,        DWORD                   dwClsContext,        const char *            hint,        ULONG                   cMQIs,        MULTI_QI *              pMQIs        );    HRESULT GetClassObject        (        REFCLSID                clsid,        REFIID                  iid,        DWORD                   dwClsContext,        const char *            hint,        IUnknown **             ppClsObj        );    HRESULT GetClassID        (        DWORD                   dwIndex,        LPCLSID                 pclsid        );            // Load a .registry file...    int loadRegistryFile (const string& fileName);    BEGIN_COM_MAP(FileRegistry)        COM_INTERFACE_ENTRY(IRegistry)    END_COM_MAP()  private:    // Not implemented    FileRegistry (const FileRegistry& other);    FileRegistry& operator= (const FileRegistry& rhs);    // universal private instance-creation function    HRESULT instanceCreate        (        bool                    classMode,        REFCLSID                clsid,        IUnknown *              pUnkOuter,        DWORD                   dwClsContext,        const char *            hint,        ULONG                   cMQIs,        MULTI_QI *              pMQIs        );    // registry entry    struct entry        {        CLSID   clsid;        string  library;        entry (REFCLSID cid, const string& lib)          : clsid (cid), library (lib)            {}        entry ()            {}        };        typedef STL_MAP(CLSID, entry)       RegMap_t;    RegMap_t    m_regmap;    };typedef CComObject<FileRegistry> FileRegistryClass;////////////////////////////////////////////////////////////////////////////// theRegistryInstance - returns the single instance of FileRegistryClass//static HRESULT theRegistryInstance (FileRegistryClass **ppReg)    {    static FileRegistryClass* s_instance = 0;    if (! s_instance)        {        // Create one, add a ref to keep it around forever...        s_instance = new FileRegistryClass ();        if (! s_instance)            return E_FAIL;                s_instance->AddRef ();        }    *ppReg = s_instance;    return S_OK;    }////////////////////////////////////////////////////////////////////////////// comFileRegistryInit - initialise the Unix registry component//// This function reads all the registry files it can find, and adds// entries to the one-and-only instance of FileRegistryClass. It then// puts that registry into the VxCOM registry-list, so that classes// are accessible to CoCreateInstance() via this mechanism.//extern "C" int comFileRegistryInit ()     {    IRegistry* pReg;    FileRegistryClass* pur = 0;    // Find the one-and-only instance (adds a ref)...    HRESULT hr = theRegistryInstance (&pur);    if (FAILED (hr))        return hr;    // Get its IRegistry interface...    hr = pur->QueryInterface (IID_IRegistry, (void**) &pReg);    if (FAILED (hr))        return hr;    // Add it to the VxCOM registry...    hr = comRegistryAdd ("Unix Registry",                         CLSCTX_INPROC_SERVER,                         pReg);    // Done with the IRegistry interface...    pReg->Release ();    // Get path list...    const char* regPath = getenv ("VXCOM_REGISTRY_PATH");    if (! regPath)        return ERROR;    // Split into dirs...    string path (regPath);    size_t prev = 0;    size_t ix = 0;    while (ix != string::npos)        {        ix = path.find_first_of (':', prev);        string dirName = path.substr (prev, ix);        if (ix != string::npos)            prev = ix + 1;        if (dirName.length () == 0)            continue;        // Now look in this dir for *.registry files...        cout << "Searching directory " << dirName << endl;        DIR* dir = opendir (dirName.c_str ());        if (! dir)            {            perror (dirName.c_str ());            continue;            }        struct dirent* pDirent;        // Load them one by one...        while ((pDirent = readdir (dir)) != 0)            {            const string DOT_REGISTRY = ".registry";                        string f = pDirent->d_name;            if ((f.length () >= DOT_REGISTRY.length ()) &&                (f.rfind (DOT_REGISTRY) == (f.length() - DOT_REGISTRY.length ())))                {                // Found a file...                pur->loadRegistryFile (dirName + "/" + f);                }            }        // Tidy up...        closedir (dir);        }    // Clean up...    pur->Release ();    return S_OK;    }//////////////////////////////////////////////////////////////////////////FileRegistry::FileRegistry ()    {    }//////////////////////////////////////////////////////////////////////////FileRegistry::~FileRegistry ()    {    }////////////////////////////////////////////////////////////////////////////// FileRegistry::loadRegistryFile - load a .registry file//int FileRegistry::loadRegistryFile (const string& fileName)    {    cout << "Loading registry file " << fileName << endl;    ifstream str (fileName.c_str ());    if (! str)        return -1;    char buf [MAXPATHLEN + 40];    // big enough for GUID + path    while (str.getline (buf, sizeof (buf)))        {        string line = buf;        size_t eq = line.find_first_of ('=');        if (eq == string::npos)            continue;                string clsid = line.substr (0, eq);        string shlib = line.substr (eq+1, string::npos);                CLSID classid;        OLECHAR * pwsz = new OLECHAR [(strlen (clsid.c_str ()) + 1)];	comAsciiToWide (pwsz, clsid.c_str (), (strlen (clsid.c_str ()) + 1));        HRESULT hr = CLSIDFromString (pwsz, &classid);	delete []pwsz;        if (FAILED (hr))            return hr;        cout << "Registering CLSID " << clsid << endl             << "  for shared-lib " << shlib << endl;        m_regmap [classid] = entry (classid, shlib);        }        return 0;    }////////////////////////////////////////////////////////////////////////////// FileRegistry::IsClassRegistered - is class registered here?//HRESULT FileRegistry::IsClassRegistered    (    REFCLSID                clsid    )    {    RegMap_t::const_iterator i = m_regmap.find (clsid);    if (i == m_regmap.end ())        {        for (i = m_regmap.begin (); i != m_regmap.end (); ++i)            cout << (*i).first << endl;        return REGDB_E_CLASSNOTREG;        }    return S_OK;    }////////////////////////////////////////////////////////////////////////////// FileRegistry::CreateInstance - create an instance of the given class//HRESULT FileRegistry::CreateInstance    (    REFCLSID                clsid,    IUnknown *              pUnkOuter,    DWORD                   dwClsContext,    const char *            hint,    ULONG                   cMQIs,    MULTI_QI *              pMQIs    )    {    IClassFactory* pCF = 0;    // Get the class-factory...    HRESULT hr = GetClassObject (clsid,                                 IID_IClassFactory,                                 dwClsContext,                                 hint,                                 (IUnknown**) &pCF);        // Now get the instance...    IUnknown *punk = 0;    hr = pCF->CreateInstance (pUnkOuter, IID_IUnknown, (void**) &punk);    if (FAILED (hr))        return hr;    // Finished with the factory...    pCF->Release ();        // Ask for all the interfaces...    for (ULONG i = 0; i < cMQIs; ++i)        {        pMQIs[i].hr = punk->QueryInterface (*(pMQIs[i].pIID),                                            (void**) &pMQIs[i].pItf);        }        // Release our original ref...    punk->Release ();    return hr;    }////////////////////////////////////////////////////////////////////////////// FileRegistry::GetClassObject - get the class-factory object//HRESULT FileRegistry::GetClassObject    (    REFCLSID                clsid,    REFIID                  iid,    DWORD                   dwClsContext,    const char *            hint,    IUnknown **             ppClsObj    )    {    // Find the reg-entry...    RegMap_t::const_iterator i = m_regmap.find (clsid);    if (i == m_regmap.end ())        return REGDB_E_CLASSNOTREG;    string fileName = (*i).second.library;    // Open the shared-lib...    void* handle = dlopen (fileName.c_str (), RTLD_NOW | RTLD_GLOBAL);    if (! handle)        {        cout << dlerror () << endl;        return E_UNEXPECTED;        }        // Find the symbol...    PFN_GETCLASSOBJECT gco =        (PFN_GETCLASSOBJECT) dlsym (handle, "DllGetClassObject");    if (! gco)        {        dlclose (handle);        cout << dlerror () << endl;        return E_UNEXPECTED;        }    // Call the function to get the class-factory...    return gco (clsid, iid, (void**) ppClsObj);    }////////////////////////////////////////////////////////////////////////////// FileRegistry::GetClassID - enumerate class IDs//HRESULT FileRegistry::GetClassID    (    DWORD                   dwIndex,    LPCLSID                 pclsid    )    {    RegMap_t::const_iterator iter = m_regmap.begin ();    for (DWORD i = 0; i < dwIndex; ++i)        {        ++iter;        if (iter == m_regmap.end ())            return E_FAIL;        }    *pclsid = (*iter).first;            return S_OK;    }#endif  /* defined SOLARIS || LINUX */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -