Exemple #1
0
static void test_default_handler_run(void)
{
    const CLSID test_server_clsid = {0x0f77e570,0x80c3,0x11e2,{0x9e,0x96,0x08,0x00,0x20,0x0c,0x9a,0x66}};

    IUnknown *unk;
    IRunnableObject *ro;
    DWORD class_reg;
    HRESULT hres;

    if(!GetProcAddress(GetModuleHandle("ole32"), "CoRegisterSurrogateEx")) {
        win_skip("skipping OleCreateDefaultHandler tests\n");
        return;
    }

    hres = CoRegisterClassObject(&test_server_clsid, (IUnknown*)&ClassFactory,
            CLSCTX_INPROC_SERVER, 0, &class_reg);
    ok(hres == S_OK, "CoRegisterClassObject failed: %x\n", hres);

    hres = OleCreateDefaultHandler(&test_server_clsid, NULL, &IID_IUnknown, (void**)&unk);
    ok(hres == S_OK, "OleCreateDefaultHandler failed: %x\n", hres);

    hres = IUnknown_QueryInterface(unk, &IID_IRunnableObject, (void**)&ro);
    ok(hres == S_OK, "QueryInterface(IRunnableObject) failed: %x\n", hres);
    IUnknown_Release(unk);

    hres = IRunnableObject_Run(ro, NULL);
    ok(hres == REGDB_E_CLASSNOTREG, "Run returned: %x, expected REGDB_E_CLASSNOTREG\n", hres);
    IRunnableObject_Release(ro);

    SET_EXPECT(CF_QueryInterface_IMarshal);
    CoRevokeClassObject(class_reg);
    todo_wine CHECK_CALLED(CF_QueryInterface_IMarshal);

    hres = CoRegisterClassObject(&test_server_clsid, (IUnknown*)&ClassFactory,
            CLSCTX_LOCAL_SERVER, 0, &class_reg);
    ok(hres == S_OK, "CoRegisterClassObject failed: %x\n", hres);

    hres = OleCreateDefaultHandler(&test_server_clsid, NULL, &IID_IUnknown, (void**)&unk);
    ok(hres == S_OK, "OleCreateDefaultHandler failed: %x\n", hres);

    hres = IUnknown_QueryInterface(unk, &IID_IRunnableObject, (void**)&ro);
    ok(hres == S_OK, "QueryInterface(IRunnableObject) failed: %x\n", hres);
    IUnknown_Release(unk);

    SET_EXPECT(CF_QueryInterface_ClassFactory);
    SET_EXPECT(CF_CreateInstance);
    hres = IRunnableObject_Run(ro, NULL);
    todo_wine ok(hres == S_OK, "Run failed: %x\n", hres);
    CHECK_CALLED(CF_QueryInterface_ClassFactory);
    CHECK_CALLED(CF_CreateInstance);
    IRunnableObject_Release(ro);

    SET_EXPECT(CF_QueryInterface_IMarshal);
    CoRevokeClassObject(class_reg);
    todo_wine CHECK_CALLED(CF_QueryInterface_IMarshal);
}
Exemple #2
0
/* Main thread of the service */
static BOOL
StartCount(void)
{
    HRESULT hr;
    DWORD dwReg;

    TRACE("\n");

    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
    if (!SUCCEEDED(hr))
        return FALSE;

    hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE,
                              RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE,
                              NULL);
    if (!SUCCEEDED(hr))
        return FALSE;

    hr = CoRegisterClassObject(&CLSID_BackgroundCopyManager,
                               (IUnknown *) &BITS_ClassFactory,
                               CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE,
                               &dwReg);
    if (!SUCCEEDED(hr))
        return FALSE;

    return TRUE;
}
Exemple #3
0
//==============================================
int g_Init_EyeTrack( ){

//  int iRet;
  HRESULT hr;


  x_pIFactory = new CFactory();
  if( x_pIFactory == NULL) return 2;

	hr = CoRegisterClassObject( CLSID_CP_ET_Class,     //Class identifier (CLSID) to be registered
                              x_pIFactory,     //Pointer to the class object
                              CLSCTX_LOCAL_SERVER,  //Context for running executable code
                              REGCLS_MULTIPLEUSE,  // multiple clients for the same server, we do not start a new server for each client
                              &x_dwRegister ); //Save registered object info, for future release by CoRevokeClassObject()
  if( hr != S_OK)  return 3;


  g_pEyeTrack = new CEyeTrack;
  if( g_pEyeTrack == NULL )  return 4;

//  iRet = g_pEyeTrack->Initialize( );
//  if( iRet )  return 5;

  return 0;
}
Exemple #4
0
//==============================================
int g_InitActX_Control( HWND hWnd) {
    IUnknown * pUnk;
    IUnknown * pUnkCont;
    HRESULT hRet;


    x_pIFactory = new CFactory();
    if( x_pIFactory == NULL) return 2;

    hRet = CoRegisterClassObject( CLSID_CP_TimeSyncClass,     //Class identifier (CLSID) to be registered
                                  x_pIFactory,     //Pointer to the class object
                                  CLSCTX_LOCAL_SERVER,  //Context for running executable code
                                  REGCLS_MULTIPLEUSE,  // multiple clients for the same server, we do not start a new server for each client
                                  &x_dwRegister ); //Save registered object info, for future release by CoRevokeClassObject()
    if( hRet != S_OK)  return 3;


    // Initialize ATL control containment code.
    AtlAxWinInit();
    // Create ActiveX control using the window handle
    // and get the IUnknown interface of this control
    hRet = AtlAxCreateControlEx( OLESTR("RPco.X"), hWnd, NULL,
                                 &pUnkCont, &pUnk, IID_NULL, NULL );

    // Obtain smart pointer to TDevAccX using IUnknown of the control
    g_pRPcoX = pUnk;
    pUnk->Release();

    return 0;
}
Exemple #5
0
/*
    Start the COM server (if necessary).
*/
bool qax_startServer(QAxFactory::ServerType type)
{
    if (qAxIsServer)
        return true;
    
    const QStringList keys = qAxFactory()->featureList();
    if (!keys.count())
        return false;
    
    if (!qAxFactory()->isService())
        StartMonitor();
    
    classRegistration = new DWORD[keys.count()];
    int object = 0;
    for (QStringList::ConstIterator key = keys.begin(); key != keys.end(); ++key, ++object) {
        IUnknown* p = 0;
        CLSID clsid = qAxFactory()->classID(*key);
        
        // Create a QClassFactory (implemented in qaxserverbase.cpp)
        HRESULT hRes = GetClassObject(clsid, IID_IClassFactory, (void**)&p);
        if (SUCCEEDED(hRes))
            hRes = CoRegisterClassObject(clsid, p, CLSCTX_LOCAL_SERVER,
                type == QAxFactory::MultipleInstances ? REGCLS_MULTIPLEUSE : REGCLS_SINGLEUSE,
                classRegistration+object);
        if (p)
            p->Release();
    }

    qAxIsServer = true;
    return true;
}
Exemple #6
0
//
// Method:		CMainModule::regClass
//
// Description:	This function tries to workaround the registry requirement. Here I've a custom implementation
//              of CoCreateInstance via LoadLibrary, class object, and Create.
//
// TODO:		Unfortunately, this function works for the Creation once Trident has the guid, but DOES NOT
//				WORK for finding the GUID when the JavaScript is using the ProgID. Eventually I'll have to 
//				figure out why the regfree assembly doesn't work yet.
HRESULT CMainModule::regClass()
{
	HRESULT hr = S_OK;
	HMODULE hmodule = NULL;
	DllGetClassObjectFunction fn = NULL;
	CComPtr<IClassFactory> ifFactory;

	if( SUCCEEDED(hr) ) {
		hmodule = LoadLibrary( L"SiaCore.dll" );
		if( !hmodule ) {
			hr = HRESULT_FROM_WIN32(GetLastError());
		}
	}

	if( SUCCEEDED(hr) ) {
		fn = (DllGetClassObjectFunction)GetProcAddress( hmodule, "DllGetClassObject" );
		if( !fn ) {
			hr = HRESULT_FROM_WIN32(GetLastError());
		}
	}

	if( SUCCEEDED(hr) ) {
		hr = fn( __uuidof(ScsInstallationAdvisor), IID_IClassFactory, (void**)&ifFactory );
	}


	if( SUCCEEDED(hr) ) {
		hr = CoRegisterClassObject( __uuidof(ScsInstallationAdvisor), ifFactory, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &m_dwRegister );
	}

	return hr;
}
BOOL installIA2Support() {
	LPFNGETCLASSOBJECT IA2Dll_DllGetClassObject;
	int i;
	int res;
	if(isIA2Installed) return TRUE;
	if((IA2DllHandle=CoLoadLibrary(IA2DllPath,FALSE))==NULL) {
		LOG_ERROR(L"CoLoadLibrary failed");
		return FALSE;
	}
	IA2Dll_DllGetClassObject=(LPFNGETCLASSOBJECT)GetProcAddress(static_cast<HMODULE>(IA2DllHandle),"DllGetClassObject");
	assert(IA2Dll_DllGetClassObject); //IAccessible2 proxy dll must have this function
	IUnknown* ia2ClassObjPunk=NULL;
	if((res=IA2Dll_DllGetClassObject(IAccessible2ProxyIID,IID_IUnknown,(LPVOID*)&ia2ClassObjPunk))!=S_OK) {
		LOG_ERROR(L"Error calling DllGetClassObject, code "<<res);
		CoFreeLibrary(IA2DllHandle);
		IA2DllHandle=0;
		return FALSE;
	}
	if((res=CoRegisterClassObject(IAccessible2ProxyIID,ia2ClassObjPunk,CLSCTX_INPROC_SERVER,REGCLS_MULTIPLEUSE,(LPDWORD)&IA2RegCooky))!=S_OK) {
		LOG_DEBUGWARNING(L"Error registering class object, code "<<res);
		ia2ClassObjPunk->Release();
		CoFreeLibrary(IA2DllHandle);
		IA2DllHandle=0;
		return FALSE;
	}
	ia2ClassObjPunk->Release();
	for(i=0;i<ARRAYSIZE(ia2Iids);++i) {
		CoGetPSClsid(ia2Iids[i],&(_ia2PSClsidBackups[i]));
		CoRegisterPSClsid(ia2Iids[i],IAccessible2ProxyIID);
	}
	isIA2Installed=TRUE;
	return TRUE;
}
Exemple #8
0
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow) {

    CoInitialize(NULL);
	
#if 0
    // register the type lib
	ITypeLib* pTLib = NULL;
	LoadTypeLibEx(L"AnyEXETypeInfo.tlb", REGKIND_REGISTER, &pTLib);
	pTLib->Release();
#endif

	if(strstr(lpCmdLine, "/Embedding") || strstr(lpCmdLine, "-Embedding")) {
        ComponentClassFactory cf;
		DWORD regID = 0;
		CoRegisterClassObject(CLSID_Component, (IClassFactory*)&cf, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &regID);
		MSG ms;
		while(GetMessage(&ms, 0, 0, 0)) {
			TranslateMessage(&ms);
			DispatchMessage(&ms);
		}
		CoRevokeClassObject(regID);
    }
	CoUninitialize();   
	return 0;
}
Exemple #9
0
HRESULT com_register()
{
  // Initialize my IClassFactory with the pointer to its vtable
  MyIClassFactoryObj.lpVtbl = (IClassFactoryVtbl *)&IClassFactory_Vtbl;

  return CoRegisterClassObject(&CLSID_IMzObj, (IUnknown*)&MyIClassFactoryObj,
                               CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE, &reg_cookie);
}
Exemple #10
0
HRESULT _ATL_OBJMAP_ENTRY::RegisterClassObject(DWORD dwClsContext, DWORD dwFlags)
{
	CComPtr<IUnknown> p;
	HRESULT hRes = pFunc(NULL, IID_IUnknown, (LPVOID*) &p);
	if (SUCCEEDED(hRes))
		hRes = CoRegisterClassObject(*pclsid, p, dwClsContext, dwFlags, &dwRegister);
	return hRes;
}
Exemple #11
0
int main(int argc,const char* agrv[])
{
	if(argc < 2) {
		printf("Usage: talk_server /AUTOMTION | /REGSERVER | /UNREGSERVER\n");
		return -1;
	}
	const char* szCmdParam = agrv[1];
	
	HRESULT hr = CoInitializeEx(0, COINIT_MULTITHREADED);
	if (SUCCEEDED(hr))
	{
		if(0 == u_strcasecmp(agrv[1],"/REGSERVER") || 0 == u_strcasecmp(agrv[1],"-REGSERVER"))
		{
			printf("/REGSERVER\n");
		}
		else if(0 == u_strcasecmp(agrv[1],"/UNREGSERVER") || 0 == u_strcasecmp(agrv[1],"-UNREGSERVER"))
		{
			printf("/UNREGSERVER\n");

		}else if(0 == u_strcasecmp(agrv[1],"/AUTOMATION") || 0 == u_strcasecmp(agrv[1],"-AUTOMATION") 
			|| 0 == u_strcasecmp(agrv[1],"/EMBEDDING") || 0 == u_strcasecmp(agrv[1],"-EMBEDDING") )
		{
			IUnknown *pUnk = NULL;
			DWORD dwReg = 0;
			static tgmtl::class_factory<CTalkManager> cf;
			hr = cf.QueryInterface(IID_IUnknown,(void **)&pUnk);
			if (SUCCEEDED(hr))
			{
				hr = CoRegisterClassObject(CLSID_TalkToStranger,pUnk,CLSCTX_LOCAL_SERVER,REGCLS_MULTIPLEUSE| REGCLS_SUSPENDED,&dwReg);
				if (SUCCEEDED(hr))
					hr = CoResumeClassObjects();

				if(SUCCEEDED(hr)){
					printf("=============================================\n");
					printf("Server is Ready!\n");

					ModuleAddRef();//this line ensure the server running forever

					ModuleServerListen();
				}

				CoRevokeClassObject(dwReg);
			}
			//pUnk->Release();
		}
		else
		{
#ifdef WIN32
			MessageBoxA(NULL,"UNKNOWN PARAMS","Test",MB_OK);
#endif
		}
		
		CoUninitialize();
	}
	return hr;
}
Exemple #12
0
static BOOL register_activex(void)
{
    DWORD regid;
    HRESULT hres;

    if(!init_registry(TRUE)) {
        init_registry(FALSE);
        return FALSE;
    }

    hres = CoRegisterClassObject(&CLSID_TestObj, (IUnknown *)&activex_cf,
                                 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
    ok(hres == S_OK, "Could not register script engine: %08x\n", hres);

    hres = CoRegisterClassObject(&CLSID_TestObjInst, (IUnknown *)&testObj,
                                 CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &regid);
    ok(hres == S_OK, "Could not register script engine: %08x\n", hres);

    return TRUE;
}
Exemple #13
0
// initexeserver - embedding
BOOL initexeserver()
{
    HRESULT     hr;
	setguids();

	pFactory=new CJServerFactory();
    if (NULL==pFactory) return 0;
    pFactory->AddRef();	// we hold on to this till we quit

    // REGCLS_MULTIPLEUSE allows multiple users (or reconnections) to same task
	   hr=CoRegisterClassObject(jclsid, pFactory, CLSCTX_LOCAL_SERVER,
    	 REGCLS_SINGLEUSE, &dwRegCO);
	//	sometimes REGCLS_SINGLEUSE, sometimes REGCLS_MULTIPLEUSE
    if (FAILED(hr)) return FALSE;
	coregflag = 1;
    return TRUE;
}
Exemple #14
0
HRESULT STDAPICALLTYPE 
ClassTableRegisterClassObjects(COCLASS_ENTRY *pTable, 
                               DWORD dwClsCtx,
                               DWORD dwRegCls,
                               BOOL bResumeClassObjects )
{
    HRESULT hr = E_FAIL;
#ifdef _WIN32_DCOM
    dwRegCls |= REGCLS_SUSPENDED;
#else
    assert(bResumeClassObjects);
#endif
    if (pTable)
    {
        hr = S_OK;
        COCLASS_ENTRY *pHead = pTable;
        for (; SUCCEEDED(hr) && pTable->pclsid != &GUID_NULL; pTable++)
        {
            if (pTable->pfnGetClassObject)
            {
                IUnknown *pUnk = 0;
                hr = pTable->pfnGetClassObject(IID_IUnknown, (void**)&pUnk);
                if (SUCCEEDED(hr))
                {
                    hr = CoRegisterClassObject(*pTable->pclsid,
                                               pUnk,
                                               dwClsCtx,
                                               dwRegCls,
                                               &pTable->dwReg);
                    pUnk->Release();
                }
            }
        }
        
        if (SUCCEEDED(hr) && bResumeClassObjects)
            hr = CoResumeClassObjects();

        if (FAILED(hr)) // unwind if failed
            for (pTable--; pTable >= pHead; pTable--)
                if (pTable->pfnGetClassObject)
                    CoRevokeClassObject(pTable->dwReg);
        
    }
    return hr;
}
Exemple #15
0
// 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;
}
Exemple #16
0
//
//  Function: AptThreadProc
//
//  Summary:  The common apartment model thread procedure for this server.
//
//  Args:     LPARAM lparam
//              Standard Window Proc parameter.
//
//  Modifies: .
//
//  Returns:  DWORD
//              Thread procedure return (usually msg.wParam).
// ************************************************************************************************
DWORD WINAPI AptThreadProcIngresObject(LPARAM lparam)
{
	HRESULT hError;
	MSG msg;
	DWORD dwCFRegId;
	APT_INIT_DATA* paid = (APT_INIT_DATA*) lparam;

	// Initialize COM for this apartment thread. Default of apartment
	// model is assumed.
	hError = CoInitializeEx(NULL, COINIT_MULTITHREADED);

	//
	// Now register the class factory with COM.
	hError = CoRegisterClassObject(
		paid->rclsid,
		paid->pcf,
		CLSCTX_LOCAL_SERVER,
		REGCLS_MULTIPLEUSE,
		&dwCFRegId);

	if (SUCCEEDED(hError))
	{
		//
		// Provide a message pump for this thread.
		while (GetMessage(&msg, 0, 0, 0))
			DispatchMessage(&msg);

		//
		// Unregister the class factory with COM when the thread dies.
		CoRevokeClassObject(dwCFRegId);
	}
	else
	{
	}

	//
	// Uninitialize COM in the context of this apartment thread.
	CoUninitialize();

	return msg.wParam;
}
Exemple #17
0
static void test_CoRegisterPSClsid(void)
{
    HRESULT hr;
    DWORD dwRegistrationKey;
    IStream *stream;
    CLSID clsid;

    hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
    ok(hr == CO_E_NOTINITIALIZED, "CoRegisterPSClsid should have returened CO_E_NOTINITIALIZED instead of 0x%08lx\n", hr);

    pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    hr = CoRegisterClassObject(&CLSID_WineTestPSFactoryBuffer, (IUnknown *)&PSFactoryBuffer,
        CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &dwRegistrationKey);
    ok_ole_success(hr, "CoRegisterClassObject");

    hr = CoRegisterPSClsid(&IID_IWineTest, &CLSID_WineTestPSFactoryBuffer);
    ok_ole_success(hr, "CoRegisterPSClsid");

    hr = CreateStreamOnHGlobal(NULL, TRUE, &stream);
    ok_ole_success(hr, "CreateStreamOnHGlobal");

    hr = CoMarshalInterface(stream, &IID_IWineTest, (IUnknown *)&Test_Unknown, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
    ok(hr == E_NOTIMPL, "CoMarshalInterface should have returned E_NOTIMPL instead of 0x%08lx\n", hr);
    IStream_Release(stream);

    hr = CoRevokeClassObject(dwRegistrationKey);
    ok_ole_success(hr, "CoRevokeClassObject");

    CoUninitialize();

    pCoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    hr = CoGetPSClsid(&IID_IWineTest, &clsid);
    ok(hr == REGDB_E_IIDNOTREG, "CoGetPSClsid should have returned REGDB_E_IIDNOTREG instead of 0x%08lx\n", hr);

    CoUninitialize();
}
Exemple #18
0
HRESULT WINAPI AtlModuleRegisterClassObjects(_ATL_MODULEW *pM, DWORD dwClsContext,
                                             DWORD dwFlags)
{
    _ATL_OBJMAP_ENTRYW_V1 *obj;
    int i=0;

    TRACE("(%p %i %i)\n",pM, dwClsContext, dwFlags);

    if (pM == NULL)
        return E_INVALIDARG;

    while ((obj = get_objmap_entry( pM, i++ )))
    {
        IUnknown* pUnknown;
        HRESULT rc;

        TRACE("Registering object %i\n",i);
        if (obj->pfnGetClassObject)
        {
            rc = obj->pfnGetClassObject(obj->pfnCreateInstance, &IID_IUnknown,
                                   (LPVOID*)&pUnknown);
            if (SUCCEEDED (rc) )
            {
                rc = CoRegisterClassObject(obj->pclsid, pUnknown, dwClsContext,
                                           dwFlags, &obj->dwRegister);

                if (FAILED (rc) )
                    WARN("Failed to register object %i: 0x%08x\n", i, rc);

                if (pUnknown)
                    IUnknown_Release(pUnknown);
            }
        }
    }

   return S_OK;
}
Exemple #19
0
// This is called when the user first loads the add-in, and on start-up
//  of each subsequent Developer Studio session
STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime,
		long dwCookie, VARIANT_BOOL* OnConnection)
{
  HRESULT result = S_OK;

  try
  {
    CComPtr< IUnknown> pIUnk;

	  AFX_MANAGE_STATE(AfxGetStaticModuleState());

    cex_ = _Module.GetClassObject( GetObjectCLSID(), IID_IUnknown, reinterpret_cast<void**>(&pIUnk));

    cex_ = CoRegisterClassObject( 
      GetObjectCLSID(),
      pIUnk,
      CLSCTX_LOCAL_SERVER,
      REGCLS_MULTIPLEUSE,
      &classRegistrationId_
      );

    pIApp_ = pApp;

    m_dwCookie = dwCookie;
    *OnConnection = VARIANT_TRUE;
  }
  catch( const std::bad_cast&)
  {
    *OnConnection = VARIANT_FALSE;
  }
  catch( const _com_error&)
  {
    *OnConnection = VARIANT_FALSE;
  }

  return result;
}
Exemple #20
0
HRESULT register_class_object(BOOL do_reg)
{
    HRESULT hres;

    static DWORD cookie;

    if(do_reg) {
        hres = CoRegisterClassObject(&CLSID_InternetExplorer,
                (IUnknown*)&InternetExplorerFactory, CLSCTX_SERVER,
                REGCLS_MULTIPLEUSE|REGCLS_SUSPENDED, &cookie);
        if (FAILED(hres)) {
            ERR("failed to register object %08x\n", hres);
            return hres;
        }

        hres = CoResumeClassObjects();
        if(SUCCEEDED(hres))
            return hres;

        ERR("failed to resume object %08x\n", hres);
    }

    return CoRevokeClassObject(cookie);
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	bool bExit = false;

	CoInitialize(NULL);

	// To know which thread has to receive the right message when closing
	CFactory::s_dwThreadID = ::GetCurrentThreadId();
		

	// Read the command line.
	// This commandline routine is straight from the Inside COM book

	char szTokens[] = "-/" ;

	char* szToken = strtok(lpCmdLine, szTokens) ; 
	while (szToken != NULL)
	{
		if (_stricmp(szToken, "UnregServer") == 0)
		{
			UnregisterServer(	CLSID_SDWSourceContainer,
									g_szVerIndProgID,
									g_szProgID) ;

			// We are done, so exit.
			bExit = TRUE ;
		}
		else if (_stricmp(szToken, "RegServer") == 0)
		{
			// thanks to the _OUTPROC_SERVER_ define in the settings
			// the Registerserver() function is creating a LocalServer32 key
			// instead of InprocServer32
			RegisterServer(	hInstance,
									CLSID_SDWSourceContainer, 
									g_szFriendlyName,
									g_szVerIndProgID,
									g_szProgID ) ;

			// We are done, so exit.
			bExit = TRUE ;
		}
		szToken = strtok(NULL, szTokens) ;
	}

	// Create the factory
	CFactory * pIFact = new CFactory();

	// A cookie to store the reg info
	DWORD dwRegCookie;

	// register the Factory, so COM knows how to create an SDWSourceContainer
	CoRegisterClassObject(	CLSID_SDWSourceContainer,
									static_cast<IUnknown*> (pIFact),
									CLSCTX_LOCAL_SERVER,
									REGCLS_SINGLEUSE,
									&dwRegCookie	);


	// start an messagepump
	if ( !bExit )
	{
		MSG msg ;
		// GetMessage only gives back a 0 if WM_QUIT is send
		while (::GetMessage(&msg, 0, 0, 0))
		{
			::DispatchMessage(&msg) ;
		}
	}
	// release the factory
	pIFact->Release();

	// Unregister the ClassFactory
	CoRevokeClassObject(dwRegCookie);


	CoUninitialize();
	return 0;
}