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

📄 csurrogate.cpp

📁 com编程
💻 CPP
字号:
////////////////////////////////////////////////////////
//
// CSurrogate.cpp - Copyright 1997, Don Box 
//
// An implementation of ISurrogate that that forwards 
// activation requests to one of N STAs.
//


#include "CCOW.h"
#include "CSurrogate.h"

CSurrogate *CSurrogate::s_pSurrogate = 0;

static HRESULT GUIDFromStringA(char *szGUID, GUID *pguid)
{
    OLECHAR wszGUID[39];
    mbstowcs(wszGUID, szGUID, 39);
    wszGUID[38] = 0;  
    return CLSIDFromString(wszGUID, pguid);
}

CSurrogate *CSurrogate::GetSurrogate(void)
{
    return s_pSurrogate;
}

HRESULT
CSurrogate::ParseCommandLine(LPSTR szCmdParam,
                             CLSID *pclsidInitial,
                             GUID  *pappid)
{
    enum { SURROGATE_SUFFIX = 38 + 1 + 10 };
    LPSTR szSuffix = szCmdParam + lstrlenA(szCmdParam) - SURROGATE_SUFFIX;
    HRESULT hr = GUIDFromStringA(szSuffix, pclsidInitial);
    if (SUCCEEDED(hr))
    {
        char sz[128];
        lstrcpyA(sz, "CLSID\\");
        memcpy(sz + 6, szSuffix, 38);
        sz[44] = 0;

        HKEY hkey = 0;
        LONG err = RegOpenKeyExA(HKEY_CLASSES_ROOT, sz, 0, 
                                 KEY_READ, &hkey);
        if (err == ERROR_SUCCESS)
        {
            DWORD cb = sizeof(sz);
            err = RegQueryValueEx(hkey, "AppID", 0, 0, (BYTE*)sz, &cb);
            if (err == ERROR_SUCCESS)
                hr = GUIDFromStringA(sz, pappid);
            else
                hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, err);

            RegCloseKey(hkey);
        }
        else
            hr = MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, err);
    }
    return hr;
}


CSurrogate::CSurrogate(int nSTAThreads)
:   m_nMaxThreads(nSTAThreads),
    m_iNextThread(0),
    m_dwThreadId(GetCurrentThreadId())
{
    assert(s_pSurrogate == 0); // singleton
    s_pSurrogate = this;
    if (m_nMaxThreads < 1)
        m_nMaxThreads = 1;
    m_prgSTAs = new CSingleThreadedApartment[m_nMaxThreads];
    
}

CSurrogate::~CSurrogate(void)
{
    delete[] m_prgSTAs;
}

CSingleThreadedApartment *
CSurrogate::GetNextApartment(REFCLSID rclsid)
{
    LONG i = InterlockedIncrement(&m_iNextThread);
    return m_prgSTAs + (i % m_nMaxThreads);
}


// IUnknown methods
STDMETHODIMP 
CSurrogate::QueryInterface(REFIID riid, void **ppv)
{
    if (riid == IID_IUnknown || riid == IID_ISurrogate)
        *ppv = (ISurrogate*)this;
    else 
        return (*ppv = 0), E_NOINTERFACE;
    ((IUnknown*)*ppv)->AddRef();
    return S_OK;
}

STDMETHODIMP_(ULONG) 
CSurrogate::AddRef(void)
{
    return 2;
}

STDMETHODIMP_(ULONG) 
CSurrogate::Release(void)
{
    return 1;
}

// ISurrogate methods
STDMETHODIMP 
CSurrogate::LoadDllServer(REFCLSID rclsid)
{
// create a wrapper class object
    CClassObjectWrapper *pcf = new CClassObjectWrapper(rclsid);
    if (!pcf)
        return E_OUTOFMEMORY;
// register the wrapper with COM using REGCLS_SURROGATE
    DWORD dwReg;
    pcf->AddRef();
    HRESULT hr = CoRegisterClassObject(rclsid, (IClassFactory*)pcf,
                                       CLSCTX_LOCAL_SERVER, REGCLS_SURROGATE,
                                       &dwReg);
    pcf->Release();
// keep track of class object to revoke later on
    if (SUCCEEDED(hr))
        m_rgdwReg.push_back(dwReg);
    return hr;
}

STDMETHODIMP 
CSurrogate::FreeSurrogate()
{
// tear down all connections with COM
    for (int i = 0; i < m_rgdwReg.size(); i++)
        CoRevokeClassObject(m_rgdwReg[i]);

// tear down all apartments
    {
    for (int i = 0; i < m_nMaxThreads; i++)
        m_prgSTAs[i].RequestShutdown(30000);
    }
// terminate main thread
    PostThreadMessage(m_dwThreadId, WM_QUIT, 0, 0);
    return S_OK;
}
        

⌨️ 快捷键说明

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