예제 #1
0
static fx::OMPtr<IScriptRefRuntime> ValidateAndLookUpRef(const std::string& refString, int32_t* refIdx)
{
	// parse the ref string into its components
	int colonIndex = refString.find_first_of(':');
	int colonIndexEnd = refString.find_first_of(':', colonIndex + 1);

	std::string resourceName = refString.substr(0, colonIndex);
	int instanceId = atoi(refString.substr(colonIndex + 1, colonIndexEnd - colonIndex).c_str());
	int refId = atoi(refString.substr(colonIndexEnd + 1).c_str());

	// get the resource manager and find stuff in it
	fx::ResourceManager* manager = Instance<fx::ResourceManager>::Get();

	// if there's a resource by that name...
	fwRefContainer<fx::Resource> resource = manager->GetResource(resourceName);

	if (!resource.GetRef())
	{
		return nullptr;
	}

	// ... and it has a scripting component...
	fwRefContainer<fx::ResourceScriptingComponent> scriptingComponent = resource->GetComponent<fx::ResourceScriptingComponent>();

	if (!scriptingComponent.GetRef())
	{
		return nullptr;
	}

	// ... and there's an instance by this instance ID...
	fx::OMPtr<IScriptRuntime> runtime = scriptingComponent->GetRuntimeById(instanceId);

	if (!runtime.GetRef())
	{
		return nullptr;
	}

	// ... check if it's a RefRuntime and return it.
	fx::OMPtr<IScriptRefRuntime> refRuntime;

	if (FX_FAILED(runtime.As(&refRuntime)))
	{
		return nullptr;
	}

	*refIdx = refId;

	return refRuntime;
}
예제 #2
0
/***********************************************************************
*           FX_CoCreateInstance [COMPOBJ.13]
*           FX_CoCreateInstance [OLE32.@]
*/
firtex::com::FX_HRESULT FX_STDAPICALLTYPE firtex::com::FX_CoCreateInstance(
	firtex::com::FX_REFCLSID rclsid,
	firtex::com::IUnknown* pUnkOuter,
	uint32_t dwClsContext,
	firtex::com::FX_REFIID iid,
	void** ppv)
{
	IClassFactory* lpclf = 0;

	// check parameters
	if (ppv==0) return FX_E_POINTER;

	// Initialize the "out" parameter
	*ppv = 0;

	/*
	* The Standard Global Interface Table (GIT) object is a process-wide singleton.
	* Rather than create a class factory, we can just check for it here
	*/
	if (FX_IsEqualCLSID(rclsid, git::clsid)) 
	{
		return git::QueryInterface( iid, ppv );
	}

	// Get a class factory to construct the object we want.
	FX_HRESULT hr = FX_CoGetClassObject(rclsid, dwClsContext, NULL,
		IClassFactory::iid, (void**)&lpclf);
	if ( FX_FAILED(hr) ) {
		//FIXME("no classfactory created for FX_CLSID %s, hres is 0x%08lx\n",
		//debugstr_guid(rclsid),hres);
		return hr;
	}

	/*
	* Create the object and don't forget to release the factory
	*/
	hr = lpclf->CreateInstance( pUnkOuter, iid, ppv );
	lpclf->Release();
	return hr;
}
예제 #3
0
/***********************************************************************
*           FX_CoGetClassObject [COMPOBJ.7]
*           FX_CoGetClassObject [OLE32.@]
*
* FIXME.  If request allows of several options and there is a failure
*         with one (other than not being registered) do we try the
*         others or return failure?  (E.g. inprocess is registered but
*         the DLL is not found but the server version works)
*/
firtex::com::FX_HRESULT FX_STDAPICALLTYPE firtex::com::FX_CoGetClassObject(
	firtex::com::FX_REFCLSID rclsid, uint32_t dwClsContext, 
	firtex::com::COSERVERINFO *pServerInfo,
	firtex::com::FX_REFIID iid, void** ppv
	)
{
	IUnknown* regClassObject = 0;

	//WINE_StringFromCLSID((LPCLSID)rclsid,xclsid);
	//TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));

	if (pServerInfo) {
		internal::log_printf( internal::WARN, "() non-NULL pServerInfo not supported!\n" );
		//FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
		//FIXME("\t\tpAuthInfo=%p\n",pServerInfo->pAuthInfo);
	}

	/*
	* First, try and see if we can't match the class ID with one of the
	* registered classes.
	*/
	if (FX_S_OK == internal::GetRegisteredClassObject(rclsid, dwClsContext, &regClassObject))
	{
		// Get the required interface from the retrieved pointer.
		FX_HRESULT hr = regClassObject->QueryInterface( iid, ppv );

		/*
		* Since QI got another reference on the pointer, we want to release the
		* one we already have. If QI was unsuccessful, this will release the object. This
		* is good since we are not returning it in the "out" parameter.
		*/
		regClassObject->Release();

		// and we are done
		return hr;
	}

	// first try: in-process 
	if ((FX_CLSCTX_INPROC_SERVER | FX_CLSCTX_INPROC_HANDLER) & dwClsContext) {
		FX_HRESULT hr = internal::GetInprocClassObject( rclsid, &regClassObject);
		if ( FX_FAILED(hr) ) return hr;

		// Get the required interface from the retrieved pointer.
		hr = regClassObject->QueryInterface( iid, ppv );

		/*
		* Since QI got another reference on the pointer, we want to release the
		* one we already have. If QI was unsuccessful, this will release the object. This
		* is good since we are not returning it in the "out" parameter.
		*/
		regClassObject->Release();

		// and we are done
		return hr;
	}

	// Next try out of process 
	internal::log_printf( internal::NONE, "\tChecking out local server\n" );
	if (FX_CLSCTX_LOCAL_SERVER & dwClsContext)
	{
		// return create_marshalled_proxy(rclsid,iid,ppv);
		internal::log_printf( internal::ERROR, "FX_CLSCTX_LOCAL_SERVER not supported." );
		return FX_E_UNEXPECTED;
	}

	/* finally try remote: this requires networked DCOM (a lot of work) */
	internal::log_printf( internal::NONE, "\tChecking out remote server\n" );
	if (FX_CLSCTX_REMOTE_SERVER & dwClsContext)
	{
		internal::log_printf( internal::ERROR, "FX_CLSCTX_REMOTE_SERVER not supported." );
		return FX_E_NOINTERFACE;
	}

	return FX_E_UNEXPECTED;
}