/****************************************************************************** * ClassMoniker_BindToObject ******************************************************************************/ static HRESULT WINAPI ClassMoniker_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) { ClassMoniker *This = impl_from_IMoniker(iface); BIND_OPTS2 bindopts; IClassActivator *pActivator; HRESULT hr; TRACE("(%p,%p,%p,%p)\n", pbc, pmkToLeft, riid, ppvResult); bindopts.cbStruct = sizeof(bindopts); IBindCtx_GetBindOptions(pbc, (BIND_OPTS *)&bindopts); if (!pmkToLeft) return CoGetClassObject(&This->clsid, bindopts.dwClassContext, NULL, riid, ppvResult); else { hr = IMoniker_BindToObject(pmkToLeft, pbc, NULL, &IID_IClassActivator, (void **)&pActivator); if (FAILED(hr)) return hr; hr = IClassActivator_GetClassObject(pActivator, &This->clsid, bindopts.dwClassContext, bindopts.locale, riid, ppvResult); IClassActivator_Release(pActivator); return hr; } }
/****************************************************************************** * ItemMoniker_BindToStorage ******************************************************************************/ static HRESULT WINAPI ItemMonikerImpl_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) { ItemMonikerImpl *This = impl_from_IMoniker(iface); HRESULT res; IOleItemContainer *poic=0; TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult); *ppvResult=0; if(pmkToLeft==NULL) return E_INVALIDARG; res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); if (SUCCEEDED(res)){ res=IOleItemContainer_GetObjectStorage(poic,This->itemName,pbc,riid,ppvResult); IOleItemContainer_Release(poic); } return res; }
/* Newer COM libraries supply the functionality of bindObject() via CoGetObject(), but to avoid depending on that being around, we stick with our own implementation. */ HRESULT bindObject( const WCHAR* name, IID* iid, void** unk ) { HRESULT hr; IBindCtx *bc; IMoniker *mk; ULONG count; if (!unk) return E_POINTER; else *unk = NULL; if (!iid) return E_POINTER; bc = NULL; mk = NULL; hr = CreateBindCtx(0, &bc); if (FAILED(hr)) return hr; hr = MkParseDisplayName(bc, name, &count, &mk); if (FAILED(hr)) { IUnknown_Release(bc); return hr; } hr = IMoniker_BindToObject( mk, bc, NULL, iid, unk ); IUnknown_Release(mk); IUnknown_Release(bc); return hr; }
static HRESULT WINAPI IHlink_fnNavigate(IHlink* iface, DWORD grfHLNF, LPBC pbc, IBindStatusCallback *pbsc, IHlinkBrowseContext *phbc) { HlinkImpl *This = impl_from_IHlink(iface); IMoniker *mon = NULL; HRESULT r; FIXME("Semi-Stub:(%p)->(%i %p %p %p)\n", This, grfHLNF, pbc, pbsc, phbc); r = __GetMoniker(This, &mon, HLINKGETREF_ABSOLUTE); TRACE("Moniker %p\n", mon); if (SUCCEEDED(r)) { IBindCtx *bcxt; IUnknown *unk = NULL; IHlinkTarget *target; CreateBindCtx(0, &bcxt); RegisterBindStatusCallback(bcxt, pbsc, NULL, 0); r = IMoniker_BindToObject(mon, bcxt, NULL, &IID_IUnknown, (void**)&unk); if (r == S_OK) { r = IUnknown_QueryInterface(unk, &IID_IHlinkTarget, (void**)&target); IUnknown_Release(unk); } if (r == S_OK) { IHlinkTarget_SetBrowseContext(target, phbc); r = IHlinkTarget_Navigate(target, grfHLNF, This->Location); IHlinkTarget_Release(target); } else { static const WCHAR szOpen[] = {'o','p','e','n',0}; LPWSTR target = NULL; r = IHlink_GetStringReference(iface, HLINKGETREF_DEFAULT, &target, NULL); if (SUCCEEDED(r) && target) { ShellExecuteW(NULL, szOpen, target, NULL, NULL, SW_SHOW); CoTaskMemFree(target); } } RevokeBindStatusCallback(bcxt, pbsc); IBindCtx_Release(bcxt); IMoniker_Release(mon); } if (This->Site) IHlinkSite_OnNavigationComplete(This->Site, This->SiteData, 0, r, NULL); TRACE("Finished Navigation\n"); return r; }
/****************************************************************************** * ClassMoniker_BindToStorage ******************************************************************************/ static HRESULT WINAPI ClassMoniker_BindToStorage(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) { TRACE("(%p, %p, %s, %p)\n", pbc, pmkToLeft, debugstr_guid(riid), ppvResult); return IMoniker_BindToObject(iface, pbc, pmkToLeft, riid, ppvResult); }
static HRESULT bind_to_object(DocHost *This, IMoniker *mon, LPCWSTR url, IBindCtx *bindctx, IBindStatusCallback *callback) { WCHAR schema[30]; DWORD schema_len; HRESULT hres; static const WCHAR httpW[] = {'h','t','t','p',0}; static const WCHAR httpsW[] = {'h','t','t','p','s',0}; static const WCHAR ftpW[]= {'f','t','p',0}; if(mon) { IMoniker_AddRef(mon); }else { hres = create_moniker(url, &mon); if(FAILED(hres)) return hres; } CoTaskMemFree(This->url); hres = IMoniker_GetDisplayName(mon, 0, NULL, &This->url); if(FAILED(hres)) FIXME("GetDisplayName failed: %08x\n", hres); IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM, (IUnknown*)CLIENTSITE(This)); hres = CoInternetParseUrl(This->url, PARSE_SCHEMA, 0, schema, sizeof(schema)/sizeof(schema[0]), &schema_len, 0); if(SUCCEEDED(hres) && (!strcmpW(schema, httpW) || !strcmpW(schema, httpsW) || !strcmpW(schema, ftpW))) { hres = http_load_hack(This, mon, callback, bindctx); }else { IUnknown *unk = NULL; hres = IMoniker_BindToObject(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk); if(SUCCEEDED(hres)) { hres = S_OK; if(unk) IUnknown_Release(unk); }else if(try_application_url(url)) { hres = S_OK; }else { FIXME("BindToObject failed: %08x\n", hres); } } IMoniker_Release(mon); return S_OK; }
/****************************************************************************** * BindMoniker [OLE32.@] * * Binds to a moniker. * * PARAMS * pmk [I] Moniker to bind to. * grfOpt [I] Reserved option flags. Set to 0. * riid [I] ID of the interface to bind to. * pvResult [O] Address that receives the interface of the object that was bound to. * * RETURNS * Success: S_OK. * Failure: Any HRESULT code. */ HRESULT WINAPI BindMoniker(LPMONIKER pmk, DWORD grfOpt, REFIID riid, LPVOID * ppvResult) { HRESULT res; IBindCtx * pbc; TRACE("(%p, %x, %s, %p)\n", pmk, grfOpt, debugstr_guid(riid), ppvResult); res = CreateBindCtx(grfOpt, &pbc); if (SUCCEEDED(res)) { res = IMoniker_BindToObject(pmk, pbc, NULL, riid, ppvResult); IBindCtx_Release(pbc); } return res; }
/****************************************************************************** * ItemMoniker_IsRunning ******************************************************************************/ static HRESULT WINAPI ItemMonikerImpl_IsRunning(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, IMoniker* pmkNewlyRunning) { ItemMonikerImpl *This = impl_from_IMoniker(iface); IRunningObjectTable* rot; HRESULT res; IOleItemContainer *poic=0; TRACE("(%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,pmkNewlyRunning); /* If pmkToLeft is NULL, this method returns TRUE if pmkNewlyRunning is non-NULL and is equal to this */ /* moniker. Otherwise, the method checks the ROT to see whether this moniker is running. */ if (pmkToLeft==NULL) if ((pmkNewlyRunning!=NULL)&&(IMoniker_IsEqual(pmkNewlyRunning,iface)==S_OK)) return S_OK; else { if (pbc==NULL) return E_INVALIDARG; res=IBindCtx_GetRunningObjectTable(pbc,&rot); if (FAILED(res)) return res; res = IRunningObjectTable_IsRunning(rot,iface); IRunningObjectTable_Release(rot); } else{ /* If pmkToLeft is non-NULL, the method calls IMoniker::BindToObject on the pmkToLeft parameter, */ /* requesting an IOleItemContainer interface pointer. The method then calls IOleItemContainer::IsRunning,*/ /* passing the string contained within this moniker. */ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); if (SUCCEEDED(res)){ res=IOleItemContainer_IsRunning(poic,This->itemName); IOleItemContainer_Release(poic); } } return res; }
static void test_SHCreateQueryCancelAutoPlayMoniker(void) { IBindCtx *ctxt; IMoniker *mon; IUnknown *unk; CLSID clsid; HRESULT hr; DWORD sys; if (!pSHCreateQueryCancelAutoPlayMoniker) { win_skip("SHCreateQueryCancelAutoPlayMoniker is not available, skipping tests.\n"); return; } hr = pSHCreateQueryCancelAutoPlayMoniker(NULL); ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); hr = pSHCreateQueryCancelAutoPlayMoniker(&mon); ok(hr == S_OK, "got 0x%08x\n", hr); sys = -1; hr = IMoniker_IsSystemMoniker(mon, &sys); ok(hr == S_OK, "got 0x%08x\n", hr); ok(sys == MKSYS_CLASSMONIKER, "got %d\n", sys); memset(&clsid, 0, sizeof(clsid)); hr = IMoniker_GetClassID(mon, &clsid); ok(hr == S_OK, "got 0x%08x\n", hr); ok(IsEqualGUID(&clsid, &CLSID_ClassMoniker), "got %s\n", wine_dbgstr_guid(&clsid)); /* extract used CLSID that implements this hook */ SET_EXPECT(autoplay_BindToObject); SET_EXPECT(autoplay_GetClassObject); CreateBindCtx(0, &ctxt); hr = IMoniker_BindToObject(mon, ctxt, &test_moniker, &IID_IQueryCancelAutoPlay, (void**)&unk); ok(hr == E_NOTIMPL, "got 0x%08x\n", hr); IBindCtx_Release(ctxt); CHECK_CALLED(autoplay_BindToObject); CHECK_CALLED(autoplay_GetClassObject); IMoniker_Release(mon); }
static HRESULT bind_to_object(DocHost *This, IMoniker *mon, LPCWSTR url, IBindCtx *bindctx, IBindStatusCallback *callback) { IUnknown *unk = NULL; WCHAR *display_name; HRESULT hres; if(mon) { IMoniker_AddRef(mon); }else { hres = create_moniker(url, &mon); if(FAILED(hres)) return hres; } hres = IMoniker_GetDisplayName(mon, 0, NULL, &display_name); if(FAILED(hres)) { FIXME("GetDisplayName failed: %08x\n", hres); return hres; } hres = set_dochost_url(This, display_name); CoTaskMemFree(display_name); if(FAILED(hres)) return hres; IBindCtx_RegisterObjectParam(bindctx, (LPOLESTR)SZ_HTML_CLIENTSITE_OBJECTPARAM, (IUnknown*)&This->IOleClientSite_iface); hres = IMoniker_BindToObject(mon, bindctx, NULL, &IID_IUnknown, (void**)&unk); if(SUCCEEDED(hres)) { hres = S_OK; if(unk) IUnknown_Release(unk); }else if(try_application_url(url)) { hres = S_OK; }else { FIXME("BindToObject failed: %08x\n", hres); } IMoniker_Release(mon); return S_OK; }
/*********************************************************************** * BindAsyncMoniker (URLMON.@) * * Bind a bind status callback to an asynchronous URL Moniker. * * PARAMS * pmk [I] Moniker object to bind status callback to * grfOpt [I] Options, seems not used * pbsc [I] Status callback to bind * iidResult [I] Interface to return * ppvResult [O] Resulting asynchronous moniker object * * RETURNS * Success: S_OK. * Failure: E_INVALIDARG, if any argument is invalid, or * E_OUTOFMEMORY if memory allocation fails. */ HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback *pbsc, REFIID iidResult, LPVOID *ppvResult) { LPBC pbc = NULL; HRESULT hr = E_INVALIDARG; TRACE("(%p %08x %p %s %p)\n", pmk, grfOpt, pbsc, debugstr_guid(iidResult), ppvResult); if (pmk && ppvResult) { *ppvResult = NULL; hr = CreateAsyncBindCtx(0, pbsc, NULL, &pbc); if (hr == NOERROR) { hr = IMoniker_BindToObject(pmk, pbc, NULL, iidResult, ppvResult); IBindCtx_Release(pbc); } } return hr; }
/****************************************************************************** * ItemMoniker_ParseDisplayName ******************************************************************************/ static HRESULT WINAPI ItemMonikerImpl_ParseDisplayName(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, LPOLESTR pszDisplayName, ULONG* pchEaten, IMoniker** ppmkOut) { ItemMonikerImpl *This = impl_from_IMoniker(iface); IOleItemContainer* poic=0; IParseDisplayName* ppdn=0; LPOLESTR displayName; HRESULT res; TRACE("%s\n", debugstr_w(pszDisplayName)); /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */ if (pmkToLeft==NULL) return MK_E_SYNTAX; else{ /* Otherwise, the method calls IMoniker::BindToObject on the pmkToLeft parameter, requesting an */ /* IParseDisplayName interface pointer to the object identified by the moniker, and passes the display */ /* name to IParseDisplayName::ParseDisplayName */ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IOleItemContainer,(void**)&poic); if (SUCCEEDED(res)){ res=IOleItemContainer_GetObject(poic,This->itemName,BINDSPEED_MODERATE,pbc,&IID_IParseDisplayName,(void**)&ppdn); res=IMoniker_GetDisplayName(iface,pbc,NULL,&displayName); res=IParseDisplayName_ParseDisplayName(ppdn,pbc,displayName,pchEaten,ppmkOut); IOleItemContainer_Release(poic); IParseDisplayName_Release(ppdn); } } return res; }
/** * Cycle through available devices using the device enumerator devenum, * retrieve the device with type specified by devtype and return the * pointer to the object found in *pfilter. * If pfilter is NULL, list all device names. */ static int dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, enum dshowSourceFilterType sourcetype, IBaseFilter **pfilter) { struct dshow_ctx *ctx = avctx->priv_data; IBaseFilter *device_filter = NULL; IEnumMoniker *classenum = NULL; IMoniker *m = NULL; const char *device_name = ctx->device_name[devtype]; int skip = (devtype == VideoDevice) ? ctx->video_device_number : ctx->audio_device_number; int r; const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory, &CLSID_AudioInputDeviceCategory }; const char *devtypename = (devtype == VideoDevice) ? "video" : "audio only"; const char *sourcetypename = (sourcetype == VideoSourceDevice) ? "video" : "audio"; r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[sourcetype], (IEnumMoniker **) &classenum, 0); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices (or none found).\n", devtypename); return AVERROR(EIO); } while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) { IPropertyBag *bag = NULL; char *friendly_name = NULL; char *unique_name = NULL; VARIANT var; IBindCtx *bind_ctx = NULL; LPOLESTR olestr = NULL; LPMALLOC co_malloc = NULL; int i; r = CoGetMalloc(1, &co_malloc); if (r != S_OK) goto fail1; r = CreateBindCtx(0, &bind_ctx); if (r != S_OK) goto fail1; /* GetDisplayname works for both video and audio, DevicePath doesn't */ r = IMoniker_GetDisplayName(m, bind_ctx, NULL, &olestr); if (r != S_OK) goto fail1; unique_name = dup_wchar_to_utf8(olestr); /* replace ':' with '_' since we use : to delineate between sources */ for (i = 0; i < strlen(unique_name); i++) { if (unique_name[i] == ':') unique_name[i] = '_'; } r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag); if (r != S_OK) goto fail1; var.vt = VT_BSTR; r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL); if (r != S_OK) goto fail1; friendly_name = dup_wchar_to_utf8(var.bstrVal); if (pfilter) { if (strcmp(device_name, friendly_name) && strcmp(device_name, unique_name)) goto fail1; if (!skip--) { r = IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Unable to BindToObject for %s\n", device_name); goto fail1; } } } else { av_log(avctx, AV_LOG_INFO, " \"%s\"\n", friendly_name); av_log(avctx, AV_LOG_INFO, " Alternative name \"%s\"\n", unique_name); } fail1: if (olestr && co_malloc) IMalloc_Free(co_malloc, olestr); if (bind_ctx) IBindCtx_Release(bind_ctx); av_free(friendly_name); av_free(unique_name); if (bag) IPropertyBag_Release(bag); IMoniker_Release(m); } IEnumMoniker_Release(classenum); if (pfilter) { if (!device_filter) { av_log(avctx, AV_LOG_ERROR, "Could not find %s device with name [%s] among source devices of type %s.\n", devtypename, device_name, sourcetypename); return AVERROR(EIO); } *pfilter = device_filter; } return 0; }
/** * Cycle through available devices using the device enumerator devenum, * retrieve the device with type specified by devtype and return the * pointer to the object found in *pfilter. * If pfilter is NULL, list all device names. */ static int dshow_cycle_devices(AVFormatContext *avctx, ICreateDevEnum *devenum, enum dshowDeviceType devtype, IBaseFilter **pfilter) { struct dshow_ctx *ctx = avctx->priv_data; IBaseFilter *device_filter = NULL; IEnumMoniker *classenum = NULL; IMoniker *m = NULL; const char *device_name = ctx->device_name[devtype]; int skip = (devtype == VideoDevice) ? ctx->video_device_number : ctx->audio_device_number; int r; const GUID *device_guid[2] = { &CLSID_VideoInputDeviceCategory, &CLSID_AudioInputDeviceCategory }; const char *devtypename = (devtype == VideoDevice) ? "video" : "audio"; r = ICreateDevEnum_CreateClassEnumerator(devenum, device_guid[devtype], (IEnumMoniker **) &classenum, 0); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not enumerate %s devices.\n", devtypename); return AVERROR(EIO); } while (!device_filter && IEnumMoniker_Next(classenum, 1, &m, NULL) == S_OK) { IPropertyBag *bag = NULL; char *buf = NULL; VARIANT var; r = IMoniker_BindToStorage(m, 0, 0, &IID_IPropertyBag, (void *) &bag); if (r != S_OK) goto fail1; var.vt = VT_BSTR; r = IPropertyBag_Read(bag, L"FriendlyName", &var, NULL); if (r != S_OK) goto fail1; buf = dup_wchar_to_utf8(var.bstrVal); if (pfilter) { if (strcmp(device_name, buf)) goto fail1; if (!skip--) IMoniker_BindToObject(m, 0, 0, &IID_IBaseFilter, (void *) &device_filter); } else { av_log(avctx, AV_LOG_INFO, " \"%s\"\n", buf); } fail1: if (buf) av_free(buf); if (bag) IPropertyBag_Release(bag); IMoniker_Release(m); } IEnumMoniker_Release(classenum); if (pfilter) { if (!device_filter) { av_log(avctx, AV_LOG_ERROR, "Could not find %s device.\n", devtypename); return AVERROR(EIO); } *pfilter = device_filter; } return 0; }
/****************************************************************************** * FileMoniker_BindToObject */ static HRESULT WINAPI FileMonikerImpl_BindToObject(IMoniker* iface, IBindCtx* pbc, IMoniker* pmkToLeft, REFIID riid, VOID** ppvResult) { FileMonikerImpl *This = impl_from_IMoniker(iface); HRESULT res=E_FAIL; CLSID clsID; IUnknown* pObj=0; IRunningObjectTable *prot=0; IPersistFile *ppf=0; IClassFactory *pcf=0; IClassActivator *pca=0; *ppvResult=0; TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult); if(pmkToLeft==NULL){ res=IBindCtx_GetRunningObjectTable(pbc,&prot); if (SUCCEEDED(res)){ /* if the requested class was loaded before ! we don't need to reload it */ res = IRunningObjectTable_GetObject(prot,iface,&pObj); if (res==S_FALSE){ /* first activation of this class */ res=GetClassFile(This->filePathName,&clsID); if (SUCCEEDED(res)){ res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(res)){ res=IPersistFile_Load(ppf,This->filePathName,STGM_READ); if (SUCCEEDED(res)){ pObj=(IUnknown*)ppf; IUnknown_AddRef(pObj); } } } } } } else{ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassFactory,(void**)&pcf); if (res==E_NOINTERFACE){ res=IMoniker_BindToObject(pmkToLeft,pbc,NULL,&IID_IClassActivator,(void**)&pca); if (res==E_NOINTERFACE) return MK_E_INTERMEDIATEINTERFACENOTSUPPORTED; } if (pcf!=NULL){ IClassFactory_CreateInstance(pcf,NULL,&IID_IPersistFile,(void**)&ppf); res=IPersistFile_Load(ppf,This->filePathName,STGM_READ); if (SUCCEEDED(res)){ pObj=(IUnknown*)ppf; IUnknown_AddRef(pObj); } } if (pca!=NULL){ FIXME("()\n"); /*res=GetClassFile(This->filePathName,&clsID); if (SUCCEEDED(res)){ res=IClassActivator_GetClassObject(pca,&clsID,CLSCTX_ALL,0,&IID_IPersistFile,(void**)&ppf); if (SUCCEEDED(res)){ pObj=(IUnknown*)ppf; IUnknown_AddRef(pObj); } }*/ } } if (pObj!=NULL){ /* get the requested interface from the loaded class */ res= IUnknown_QueryInterface(pObj,riid,ppvResult); IBindCtx_RegisterObjectBound(pbc,*ppvResult); IUnknown_Release(pObj); } if (prot!=NULL) IRunningObjectTable_Release(prot); if (ppf!=NULL) IPersistFile_Release(ppf); if (pca!=NULL) IClassActivator_Release(pca); if (pcf!=NULL) IClassFactory_Release(pcf); return res; }
static GstCaps * gst_dshowaudiosrc_get_caps (GstBaseSrc * basesrc) { HRESULT hres = S_OK; IBindCtx *lpbc = NULL; IMoniker *audiom = NULL; DWORD dwEaten; GstDshowAudioSrc *src = GST_DSHOWAUDIOSRC (basesrc); gunichar2 *unidevice = NULL; if (src->device) { g_free (src->device); src->device = NULL; } src->device = gst_dshow_getdevice_from_devicename (&CLSID_AudioInputDeviceCategory, &src->device_name); if (!src->device) { GST_CAT_ERROR (dshowaudiosrc_debug, "No audio device found."); return NULL; } unidevice = g_utf8_to_utf16 (src->device, strlen (src->device), NULL, NULL, NULL); if (!src->audio_cap_filter) { hres = CreateBindCtx (0, &lpbc); if (SUCCEEDED (hres)) { hres = MkParseDisplayName (lpbc, unidevice, &dwEaten, &audiom); if (SUCCEEDED (hres)) { hres = IMoniker_BindToObject (audiom, lpbc, NULL, &IID_IBaseFilter, &src->audio_cap_filter); IMoniker_Release (audiom); } IBindCtx_Release (lpbc); } } if (src->audio_cap_filter && !src->caps) { /* get the capture pins supported types */ IPin *capture_pin = NULL; IEnumPins *enumpins = NULL; HRESULT hres; hres = IBaseFilter_EnumPins (src->audio_cap_filter, &enumpins); if (SUCCEEDED (hres)) { while (IEnumPins_Next (enumpins, 1, &capture_pin, NULL) == S_OK) { IKsPropertySet *pKs = NULL; hres = IPin_QueryInterface (capture_pin, &IID_IKsPropertySet, (void **) &pKs); if (SUCCEEDED (hres) && pKs) { DWORD cbReturned; GUID pin_category; RPC_STATUS rpcstatus; hres = IKsPropertySet_Get (pKs, &ROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, &pin_category, sizeof (GUID), &cbReturned); /* we only want capture pins */ if (UuidCompare (&pin_category, &PIN_CATEGORY_CAPTURE, &rpcstatus) == 0) { IAMStreamConfig *streamcaps = NULL; if (SUCCEEDED (IPin_QueryInterface (capture_pin, &IID_IAMStreamConfig, (void **) &streamcaps))) { src->caps = gst_dshowaudiosrc_getcaps_from_streamcaps (src, capture_pin, streamcaps); IAMStreamConfig_Release (streamcaps); } } IKsPropertySet_Release (pKs); } IPin_Release (capture_pin); } IEnumPins_Release (enumpins); } } if (unidevice) { g_free (unidevice); } if (src->caps) { return gst_caps_ref (src->caps); } return NULL; }