Esempio n. 1
0
/* From quartz, 2008/04/07 */
static HRESULT GetFilterInfo(IMoniker *pMoniker, GUID *pclsid, VARIANT *pvar)
{
    static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
    static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
    IPropertyBag *pPropBagCat = NULL;
    HRESULT hr;

    VariantInit(pvar);
    V_VT(pvar) = VT_BSTR;

    hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag,
                                (LPVOID *) &pPropBagCat);

    if (SUCCEEDED(hr))
        hr = IPropertyBag_Read(pPropBagCat, wszClsidName, pvar, NULL);

    if (SUCCEEDED(hr))
    {
        hr = CLSIDFromString(V_UNION(pvar, bstrVal), pclsid);
        VariantClear(pvar);
        V_VT(pvar) = VT_BSTR;
    }

    if (SUCCEEDED(hr))
        hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, pvar, NULL);

    if (SUCCEEDED(hr))
        TRACE("Moniker = %s - %s\n", debugstr_guid(pclsid),
              debugstr_w(V_UNION(pvar, bstrVal)));

    if (pPropBagCat)
        IPropertyBag_Release(pPropBagCat);

    return hr;
}
Esempio n. 2
0
static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
    LPPROPERTYBAG iface,
    LPCOLESTR pszPropName,
    VARIANT* pVar)
{
    RegPropBagImpl *This = impl_from_IPropertyBag(iface);
    LPVOID lpData = NULL;
    DWORD cbData = 0;
    DWORD dwType = 0;
    HRESULT res = S_OK;

    TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);

    switch (V_VT(pVar))
    {
    case VT_BSTR:
    case VT_LPWSTR:
        TRACE("writing %s\n", debugstr_w(V_UNION(pVar, bstrVal)));
        lpData = V_UNION(pVar, bstrVal);
        dwType = REG_SZ;
        cbData = (lstrlenW(V_UNION(pVar, bstrVal)) + 1) * sizeof(WCHAR);
        break;
    case VT_I4:
    case VT_UI4:
        TRACE("writing %u\n", V_UNION(pVar, ulVal));
        lpData = &V_UNION(pVar, ulVal);
        dwType = REG_DWORD;
        cbData = sizeof(DWORD);
        break;
    case VT_ARRAY | VT_UI1:
    {
        LONG lUbound = 0;
        LONG lLbound = 0;
        dwType = REG_BINARY;
        res = SafeArrayGetLBound(V_UNION(pVar, parray), 1, &lLbound);
        res = SafeArrayGetUBound(V_UNION(pVar, parray), 1, &lUbound);
        cbData = (lUbound - lLbound + 1) /* * sizeof(BYTE)*/;
        TRACE("cbData: %d\n", cbData);
        res = SafeArrayAccessData(V_UNION(pVar, parray), &lpData);
        break;
    }
    default:
        FIXME("Variant type %d not handled\n", V_VT(pVar));
        return E_FAIL;
    }

    if (RegSetValueExW(This->hkey,
                       pszPropName, 0,
                       dwType, lpData, cbData) != ERROR_SUCCESS)
        res = E_FAIL;

    if (V_VT(pVar) & VT_ARRAY)
        res = SafeArrayUnaccessData(V_UNION(pVar, parray));

    return res;
}
Esempio n. 3
0
static void test_propertybag_write(IPropertyBag2 *property)
{
    HRESULT hr;
    PROPBAG2 options[2] = {{0}};
    VARIANT values[2];

    VariantInit(&values[0]);
    VariantInit(&values[1]);

    /* 1. One unknown property */
    options[0].pstrName = (LPOLESTR)wszTestInvalidProperty;
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == E_FAIL, "Write for an unknown property did not fail with expected code, hr=%x\n", hr);

    /* 2. One property without correct type */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    V_VT(&values[0]) = VT_UI1;
    V_UNION(&values[0], bVal) = 1;
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == S_OK, "Write for one property failed, hr=%x\n", hr);

    /* 3. One property with mismatching type */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    V_VT(&values[0]) = VT_I1;
    V_UNION(&values[0], bVal) = 2;
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE,
       "Write with mismatching type did not fail with expected code hr=%x\n", hr);

    /* 4. Reset one property to empty */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    VariantClear(&values[0]);
    hr = IPropertyBag2_Write(property, 1, options, values);
    ok(hr == WINCODEC_ERR_PROPERTYUNEXPECTEDTYPE,
       "Write to reset to empty value does not fail with expected code, hr=%x\n", hr);

    /* 5. Set two properties */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    V_VT(&values[0]) = VT_UI1;
    V_UNION(&values[0], bVal) = 12;
    options[1].pstrName = (LPOLESTR)wszTestProperty2;
    V_VT(&values[1]) = VT_R4;
    V_UNION(&values[1], fltVal) = (float)3.14;
    hr = IPropertyBag2_Write(property, 2, options, values);
    ok(hr == S_OK, "Write for two properties failed, hr=%x\n", hr);
}
Esempio n. 4
0
/* Helper function, checks if filter with given name was enumerated. */
static BOOL enum_find_filter(const WCHAR *wszFilterName, IEnumMoniker *pEnum)
{
    IMoniker *pMoniker = NULL;
    BOOL found = FALSE;
    ULONG nb;
    HRESULT hr;
    static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};

    while(!found && IEnumMoniker_Next(pEnum, 1, &pMoniker, &nb) == S_OK)
    {
        IPropertyBag * pPropBagCat = NULL;
        VARIANT var;

        VariantInit(&var);

        hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID*)&pPropBagCat);
        ok(SUCCEEDED(hr), "IMoniker_BindToStorage failed with %x\n", hr);
        if (FAILED(hr) || !pPropBagCat)
        {
            VariantClear(&var);
            IMoniker_Release(pMoniker);
            continue;
        }

        hr = IPropertyBag_Read(pPropBagCat, wszFriendlyName, &var, NULL);
        ok(SUCCEEDED(hr), "IPropertyBag_Read failed with %x\n", hr);

        if (SUCCEEDED(hr))
        {
            CHAR val1[512], val2[512];

            WideCharToMultiByte(CP_ACP, 0, V_UNION(&var, bstrVal), -1, val1, sizeof(val1), 0, 0);
            WideCharToMultiByte(CP_ACP, 0, wszFilterName, -1, val2, sizeof(val2), 0, 0);
            if (!lstrcmpA(val1, val2)) found = TRUE;
        }

        IPropertyBag_Release(pPropBagCat);
        IMoniker_Release(pMoniker);
        VariantClear(&var);
    }

    return found;
}
Esempio n. 5
0
/**********************************************************************
 * DEVENUM_CreateSpecialCategories (INTERNAL)
 *
 * Creates the keys in the registry for the dynamic categories
 */
static HRESULT DEVENUM_CreateSpecialCategories(void)
{
    HRESULT res;
    WCHAR szDSoundNameFormat[MAX_PATH + 1];
    WCHAR szDSoundName[MAX_PATH + 1];
    DWORD iDefaultDevice = -1;
    UINT numDevs;
    IFilterMapper2 * pMapper = NULL;
    REGFILTER2 rf2;
    REGFILTERPINS2 rfp2;
    WCHAR path[MAX_PATH];
    HKEY basekey;

    if (DEVENUM_populate_handle)
        return S_OK;
    DEVENUM_populate_handle = CreateEventW(NULL, TRUE, FALSE, DEVENUM_populate_handle_nameW);
    if (GetLastError() == ERROR_ALREADY_EXISTS)
    {
        /* Webcams can take some time to scan if the driver is badly written and it enables them,
         * so have a 10 s timeout here
         */
        if (WaitForSingleObject(DEVENUM_populate_handle, 10000) == WAIT_TIMEOUT)
            WARN("Waiting for object timed out\n");
        TRACE("No need to rescan\n");
        return S_OK;
    }
    TRACE("Scanning for devices\n");

    /* Since devices can change between session, for example because you just plugged in a webcam
     * or switched from pulseaudio to alsa, delete all old devices first
     */
    if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_AudioRendererCategory, &basekey, path, MAX_PATH)))
        RegDeleteTreeW(basekey, path);
    if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_AudioInputDeviceCategory, &basekey, path, MAX_PATH)))
        RegDeleteTreeW(basekey, path);
    if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_VideoInputDeviceCategory, &basekey, path, MAX_PATH)))
        RegDeleteTreeW(basekey, path);
    if (SUCCEEDED(DEVENUM_GetCategoryKey(&CLSID_MidiRendererCategory, &basekey, path, MAX_PATH)))
        RegDeleteTreeW(basekey, path);

    rf2.dwVersion = 2;
    rf2.dwMerit = MERIT_PREFERRED;
    rf2.u.s1.cPins2 = 1;
    rf2.u.s1.rgPins2 = &rfp2;
    rfp2.cInstances = 1;
    rfp2.nMediums = 0;
    rfp2.lpMedium = NULL;
    rfp2.clsPinCategory = &IID_NULL;

    if (!LoadStringW(DEVENUM_hInstance, IDS_DEVENUM_DS, szDSoundNameFormat, sizeof(szDSoundNameFormat)/sizeof(szDSoundNameFormat[0])-1))
    {
        ERR("Couldn't get string resource (GetLastError() is %d)\n", GetLastError());
        return HRESULT_FROM_WIN32(GetLastError());
    }

    res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
                           &IID_IFilterMapper2, (void **) &pMapper);
    /*
     * Fill in info for devices
     */
    if (SUCCEEDED(res))
    {
        UINT i;
        WAVEOUTCAPSW wocaps;
	WAVEINCAPSW wicaps;
        MIDIOUTCAPSW mocaps;
        REGPINTYPES * pTypes;

	numDevs = waveOutGetNumDevs();

        res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioRendererCategory);
        if (FAILED(res)) /* can't register any devices in this category */
            numDevs = 0;

	rfp2.dwFlags = REG_PINFLAG_B_RENDERER;
	for (i = 0; i < numDevs; i++)
	{
	    if (waveOutGetDevCapsW(i, &wocaps, sizeof(WAVEOUTCAPSW))
	        == MMSYSERR_NOERROR)
	    {
                IMoniker * pMoniker = NULL;

                rfp2.nMediaTypes = 1;
                pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
                if (!pTypes)
                {
                    IFilterMapper2_Release(pMapper);
                    return E_OUTOFMEMORY;
                }
                /* FIXME: Native devenum seems to register a lot more types for
                 * DSound than we do. Not sure what purpose they serve */
                pTypes[0].clsMajorType = &MEDIATYPE_Audio;
                pTypes[0].clsMinorType = &MEDIASUBTYPE_PCM;

                rfp2.lpMediaType = pTypes;

                res = IFilterMapper2_RegisterFilter(pMapper,
		                              &CLSID_AudioRender,
					      wocaps.szPname,
					      &pMoniker,
					      &CLSID_AudioRendererCategory,
					      wocaps.szPname,
					      &rf2);

                /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */

                if (pMoniker)
                {
                    IMoniker_Release(pMoniker);
                    pMoniker = NULL;
                }

		wsprintfW(szDSoundName, szDSoundNameFormat, wocaps.szPname);
	        res = IFilterMapper2_RegisterFilter(pMapper,
		                              &CLSID_DSoundRender,
					      szDSoundName,
					      &pMoniker,
					      &CLSID_AudioRendererCategory,
					      szDSoundName,
					      &rf2);

                /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */

		if (pMoniker)
		    IMoniker_Release(pMoniker);

		if (i == iDefaultDevice)
		{
		    FIXME("Default device\n");
		}

                CoTaskMemFree(pTypes);
	    }
	}

        numDevs = waveInGetNumDevs();

        res = DEVENUM_CreateAMCategoryKey(&CLSID_AudioInputDeviceCategory);
        if (FAILED(res)) /* can't register any devices in this category */
            numDevs = 0;

	rfp2.dwFlags = REG_PINFLAG_B_OUTPUT;
        for (i = 0; i < numDevs; i++)
        {
            if (waveInGetDevCapsW(i, &wicaps, sizeof(WAVEINCAPSW))
                == MMSYSERR_NOERROR)
            {
                IMoniker * pMoniker = NULL;

                rfp2.nMediaTypes = 1;
                pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
                if (!pTypes)
                {
                    IFilterMapper2_Release(pMapper);
                    return E_OUTOFMEMORY;
                }

                /* FIXME: Not sure if these are correct */
                pTypes[0].clsMajorType = &MEDIATYPE_Audio;
                pTypes[0].clsMinorType = &MEDIASUBTYPE_PCM;

                rfp2.lpMediaType = pTypes;

	        res = IFilterMapper2_RegisterFilter(pMapper,
		                              &CLSID_AudioRecord,
					      wicaps.szPname,
					      &pMoniker,
					      &CLSID_AudioInputDeviceCategory,
					      wicaps.szPname,
					      &rf2);

                /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */

		if (pMoniker)
		    IMoniker_Release(pMoniker);

                CoTaskMemFree(pTypes);
	    }
	}

	numDevs = midiOutGetNumDevs();

        res = DEVENUM_CreateAMCategoryKey(&CLSID_MidiRendererCategory);
        if (FAILED(res)) /* can't register any devices in this category */
            numDevs = 0;

	rfp2.dwFlags = REG_PINFLAG_B_RENDERER;
	for (i = 0; i < numDevs; i++)
	{
	    if (midiOutGetDevCapsW(i, &mocaps, sizeof(MIDIOUTCAPSW))
	        == MMSYSERR_NOERROR)
	    {
                IMoniker * pMoniker = NULL;

                rfp2.nMediaTypes = 1;
                pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
                if (!pTypes)
                {
                    IFilterMapper2_Release(pMapper);
                    return E_OUTOFMEMORY;
                }

                /* FIXME: Not sure if these are correct */
                pTypes[0].clsMajorType = &MEDIATYPE_Midi;
                pTypes[0].clsMinorType = &MEDIASUBTYPE_None;

                rfp2.lpMediaType = pTypes;

                res = IFilterMapper2_RegisterFilter(pMapper,
		                              &CLSID_AVIMIDIRender,
					      mocaps.szPname,
					      &pMoniker,
					      &CLSID_MidiRendererCategory,
					      mocaps.szPname,
					      &rf2);

                /* FIXME: do additional stuff with IMoniker here, depending on what RegisterFilter does */
		/* Native version sets MidiOutId */

		if (pMoniker)
		    IMoniker_Release(pMoniker);

		if (i == iDefaultDevice)
		{
		    FIXME("Default device\n");
		}

                CoTaskMemFree(pTypes);
	    }
	}
        res = DEVENUM_CreateAMCategoryKey(&CLSID_VideoInputDeviceCategory);
        if (SUCCEEDED(res))
            for (i = 0; i < 10; i++)
            {
                WCHAR szDeviceName[32], szDeviceVersion[32], szDevicePath[10];

                if (capGetDriverDescriptionW ((WORD) i,
                                              szDeviceName, sizeof(szDeviceName)/sizeof(WCHAR),
                                              szDeviceVersion, sizeof(szDeviceVersion)/sizeof(WCHAR)))
                {
                    IMoniker * pMoniker = NULL;
                    IPropertyBag * pPropBag = NULL;
                    WCHAR dprintf[] = { 'v','i','d','e','o','%','d',0 };
                    snprintfW(szDevicePath, sizeof(szDevicePath)/sizeof(WCHAR), dprintf, i);
                    /* The above code prevents 1 device with a different ID overwriting another */

                    rfp2.nMediaTypes = 1;
                    pTypes = CoTaskMemAlloc(rfp2.nMediaTypes * sizeof(REGPINTYPES));
                    if (!pTypes) {
                        IFilterMapper2_Release(pMapper);
                        return E_OUTOFMEMORY;
                    }

                    pTypes[0].clsMajorType = &MEDIATYPE_Video;
                    pTypes[0].clsMinorType = &MEDIASUBTYPE_None;

                    rfp2.lpMediaType = pTypes;

                    res = IFilterMapper2_RegisterFilter(pMapper,
                                                        &CLSID_VfwCapture,
                                                        szDeviceName,
                                                        &pMoniker,
                                                        &CLSID_VideoInputDeviceCategory,
                                                        szDevicePath,
                                                        &rf2);

                    if (pMoniker) {
                       OLECHAR wszVfwIndex[] = { 'V','F','W','I','n','d','e','x',0 };
                       VARIANT var;
                       V_VT(&var) = VT_I4;
                       V_UNION(&var, ulVal) = i;
                       res = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (LPVOID)&pPropBag);
                       if (SUCCEEDED(res))
                          res = IPropertyBag_Write(pPropBag, wszVfwIndex, &var);
                       IMoniker_Release(pMoniker);
                    }

                    if (i == iDefaultDevice) FIXME("Default device\n");
                    CoTaskMemFree(pTypes);
                }
            }
    }

    if (pMapper)
        IFilterMapper2_Release(pMapper);
    SetEvent(DEVENUM_populate_handle);
    return res;
}
Esempio n. 6
0
static HRESULT GetSplitter(MediaDetImpl *This)
{
    IFileSourceFilter *file;
    LPOLESTR name;
    AM_MEDIA_TYPE mt;
    GUID type[2];
    IFilterMapper2 *map;
    IEnumMoniker *filters;
    IMoniker *mon;
    VARIANT var;
    GUID clsid;
    IBaseFilter *splitter;
    IEnumPins *pins;
    IPin *source_pin, *splitter_pin;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
                          &IID_IFilterMapper2, (void **) &map);
    if (FAILED(hr))
        return hr;

    hr = IBaseFilter_QueryInterface(This->source, &IID_IFileSourceFilter,
                                    (void **) &file);
    if (FAILED(hr))
    {
        IFilterMapper2_Release(map);
        return hr;
    }

    hr = IFileSourceFilter_GetCurFile(file, &name, &mt);
    IFileSourceFilter_Release(file);
    CoTaskMemFree(name);
    if (FAILED(hr))
    {
        IFilterMapper2_Release(map);
        return hr;
    }
    type[0] = mt.majortype;
    type[1] = mt.subtype;
    CoTaskMemFree(mt.pbFormat);

    hr = IFilterMapper2_EnumMatchingFilters(map, &filters, 0, TRUE,
                                            MERIT_UNLIKELY, FALSE, 1, type,
                                            NULL, NULL, FALSE, TRUE,
                                            0, NULL, NULL, NULL);
    IFilterMapper2_Release(map);
    if (FAILED(hr))
        return hr;

    hr = E_NOINTERFACE;
    while (IEnumMoniker_Next(filters, 1, &mon, NULL) == S_OK)
    {
        hr = GetFilterInfo(mon, &clsid, &var);
        IMoniker_Release(mon);
        if (FAILED(hr))
            continue;

        hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER,
                              &IID_IBaseFilter, (void **) &splitter);
        if (FAILED(hr))
        {
            VariantClear(&var);
            continue;
        }

        hr = IGraphBuilder_AddFilter(This->graph, splitter,
                                     V_UNION(&var, bstrVal));
        VariantClear(&var);
        This->splitter = splitter;
        if (FAILED(hr))
            goto retry;

        hr = IBaseFilter_EnumPins(This->source, &pins);
        if (FAILED(hr))
            goto retry;
        IEnumPins_Next(pins, 1, &source_pin, NULL);
        IEnumPins_Release(pins);

        hr = IBaseFilter_EnumPins(splitter, &pins);
        if (FAILED(hr))
        {
            IPin_Release(source_pin);
            goto retry;
        }
        IEnumPins_Next(pins, 1, &splitter_pin, NULL);
        IEnumPins_Release(pins);

        hr = IPin_Connect(source_pin, splitter_pin, NULL);
        IPin_Release(source_pin);
        IPin_Release(splitter_pin);
        if (SUCCEEDED(hr))
            break;

retry:
        IBaseFilter_Release(splitter);
        This->splitter = NULL;
    }

    IEnumMoniker_Release(filters);
    if (FAILED(hr))
        return hr;

    return S_OK;
}
Esempio n. 7
0
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBindCtx *pbc,
        IMoniker *pmkToLeft, REFIID riidResult, void **ppvResult)
{
    MediaCatMoniker *This = impl_from_IMoniker(iface);
    IUnknown * pObj = NULL;
    IPropertyBag * pProp = NULL;
    CLSID clsID;
    VARIANT var;
    HRESULT res = E_FAIL;

    TRACE("(%p)->(%p, %p, %s, %p)\n", This, pbc, pmkToLeft, debugstr_guid(riidResult), ppvResult);

    VariantInit(&var);
    *ppvResult = NULL;

    if(pmkToLeft==NULL)
    {
        /* first activation of this class */
        LPVOID pvptr;
        res=IMoniker_BindToStorage(iface, NULL, NULL, &IID_IPropertyBag, &pvptr);
        pProp = pvptr;
        if (SUCCEEDED(res))
        {
            V_VT(&var) = VT_LPWSTR;
            res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL);
        }
        if (SUCCEEDED(res))
        {
            res = CLSIDFromString(V_UNION(&var,bstrVal), &clsID);
            CoTaskMemFree(V_UNION(&var, bstrVal));
        }
        if (SUCCEEDED(res))
        {
            res=CoCreateInstance(&clsID,NULL,CLSCTX_ALL,&IID_IUnknown,&pvptr);
            pObj = pvptr;
        }
    }

    if (pObj!=NULL)
    {
        /* get the requested interface from the loaded class */
        res = S_OK;
        if (pProp) {
            HRESULT res2;
            LPVOID ppv = NULL;
            res2 = IUnknown_QueryInterface(pObj, &IID_IPersistPropertyBag, &ppv);
            if (SUCCEEDED(res2)) {
                res = IPersistPropertyBag_Load((IPersistPropertyBag *) ppv, pProp, NULL);
                IPersistPropertyBag_Release((IPersistPropertyBag *) ppv);
            }
        }
        if (SUCCEEDED(res))
            res= IUnknown_QueryInterface(pObj,riidResult,ppvResult);
        IUnknown_Release(pObj);
    }

    if (pProp)
    {
        IPropertyBag_Release(pProp);
    }

    TRACE("<- 0x%x\n", res);

    return res;
}
Esempio n. 8
0
static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
    LPPROPERTYBAG iface,
    LPCOLESTR pszPropName,
    VARIANT* pVar,
    IErrorLog* pErrorLog)
{
    LPVOID pData = NULL;
    DWORD received;
    DWORD type = 0;
    RegPropBagImpl *This = impl_from_IPropertyBag(iface);
    HRESULT res = S_OK;
    LONG reswin32;

    TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);

    if (!pszPropName || !pVar)
        return E_POINTER;

    reswin32 = RegQueryValueExW(This->hkey, pszPropName, NULL, NULL, NULL, &received);
    res = HRESULT_FROM_WIN32(reswin32);

    if (SUCCEEDED(res))
    {
        pData = HeapAlloc(GetProcessHeap(), 0, received);

        /* work around a GCC bug that occurs here unless we use the reswin32 variable as well */
        reswin32 = RegQueryValueExW(This->hkey, pszPropName, NULL, &type, pData, &received);
        res = HRESULT_FROM_WIN32(reswin32);
    }

    if (SUCCEEDED(res))
    {
        res = E_INVALIDARG; /* assume we cannot coerce into right type */

        TRACE("Read %d bytes (%s)\n", received, type == REG_SZ ? debugstr_w(pData) : "binary data");

        switch (type)
        {
        case REG_SZ:
            switch (V_VT(pVar))
            {
            case VT_LPWSTR:
                V_UNION(pVar, bstrVal) = CoTaskMemAlloc(received);
                memcpy(V_UNION(pVar, bstrVal), pData, received);
                res = S_OK;
                break;
            case VT_EMPTY:
                V_VT(pVar) = VT_BSTR;
            /* fall through */
            case VT_BSTR:
                V_UNION(pVar, bstrVal) = SysAllocStringLen(pData, received/sizeof(WCHAR) - 1);
                res = S_OK;
                break;
            }
            break;
        case REG_DWORD:
            TRACE("REG_DWORD: %x\n", *(DWORD *)pData);
            switch (V_VT(pVar))
            {
            case VT_EMPTY:
                V_VT(pVar) = VT_I4;
            /* fall through */
            case VT_I4:
            case VT_UI4:
                V_UNION(pVar, ulVal) = *(DWORD *)pData;
                res = S_OK;
                break;
            }
            break;
        case REG_BINARY:
        {
            SAFEARRAYBOUND bound;
            void * pArrayElements;
            bound.lLbound = 0;
            bound.cElements = received;
            TRACE("REG_BINARY: len = %d\n", received);
            switch (V_VT(pVar))
            {
            case VT_EMPTY:
                V_VT(pVar) = VT_ARRAY | VT_UI1;
            /* fall through */
            case VT_ARRAY | VT_UI1:
                if (!(V_UNION(pVar, parray) = SafeArrayCreate(VT_UI1, 1, &bound)))
                    res = E_OUTOFMEMORY;
                else
                    res = S_OK;
                break;
            }

            if (res == E_INVALIDARG)
                break;

            res = SafeArrayAccessData(V_UNION(pVar, parray), &pArrayElements);
            if (FAILED(res))
                break;

            CopyMemory(pArrayElements, pData, received);
            res = SafeArrayUnaccessData(V_UNION(pVar, parray));
            break;
        }
        }
        if (res == E_INVALIDARG)
            FIXME("Variant type %x not supported for regtype %x\n", V_VT(pVar), type);
    }

    HeapFree(GetProcessHeap(), 0, pData);

    TRACE("<- %x\n", res);
    return res;
}
Esempio n. 9
0
static void test_propertybag_read(IPropertyBag2 *property)
{
    HRESULT hr;
    PROPBAG2 options[3] = {{0}};
    VARIANT values[3];
    HRESULT itm_hr[3] = {S_OK, S_OK, S_OK};

    /* 1. One unknown property */
    options[0].pstrName = (LPOLESTR)wszTestInvalidProperty;
    hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr);
    ok(hr == E_FAIL,
       "Read for an unknown property did not fail with expected code, hr=%x\n", hr);

    /* 2. One known property */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    itm_hr[0] = E_FAIL;
    hr = IPropertyBag2_Read(property, 1, options, NULL, values, itm_hr);
    ok(hr == S_OK, "Read failed, hr=%x\n", hr);
    if (SUCCEEDED(hr))
    {
        ok(itm_hr[0] == S_OK,
           "Read failed, itm_hr[0]=%x\n", itm_hr[0]);
        ok(V_VT(&values[0]) == VT_UI1,
           "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0]));
        ok(V_UNION(&values[0], bVal) == 12,
           "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal));

        VariantClear(&values[0]);
    }

    /* 3. Two known properties */
    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    options[1].pstrName = (LPOLESTR)wszTestProperty2;
    itm_hr[0] = E_FAIL;
    itm_hr[1] = E_FAIL;
    hr = IPropertyBag2_Read(property, 2, options, NULL, values, itm_hr);
    ok(hr == S_OK, "Read failed, hr=%x\n", hr);
    if (SUCCEEDED(hr))
    {
        ok(itm_hr[0] == S_OK, "Read failed, itm_hr[0]=%x\n", itm_hr[0]);
        ok(V_VT(&values[0]) == VT_UI1, "Read failed, V_VT(&values[0])=%x\n", V_VT(&values[0]));
        ok(V_UNION(&values[0], bVal) == 12, "Read failed, &values[0]=%i\n", V_UNION(&values[0], bVal));

        ok(itm_hr[1] == S_OK, "Read failed, itm_hr[1]=%x\n", itm_hr[1]);
        ok(V_VT(&values[1]) == VT_R4, "Read failed, V_VT(&values[1])=%x\n", V_VT(&values[1]));
        ok(V_UNION(&values[1], fltVal) == (float)3.14, "Read failed, &values[1]=%f\n", V_UNION(&values[1], fltVal));

        VariantClear(&values[0]);
        VariantClear(&values[1]);
    }


    /* 4. One unknown property between two valid */

    /* Exotic initializations so we can detect what is unchanged */
    itm_hr[0] = -1; itm_hr[1] = -1; itm_hr[2] = -1;
    V_VT(&values[0]) = VT_NULL;
    V_VT(&values[1]) = VT_NULL;
    V_VT(&values[2]) = VT_NULL;
    V_UNION(&values[0], bVal) = 254;
    V_UNION(&values[1], bVal) = 254;
    V_UNION(&values[2], bVal) = 254;

    options[0].pstrName = (LPOLESTR)wszTestProperty1;
    options[1].pstrName = (LPOLESTR)wszTestInvalidProperty;
    options[2].pstrName = (LPOLESTR)wszTestProperty2;

    hr = IPropertyBag2_Read(property, 3, options, NULL, values, itm_hr);
    ok(hr == E_FAIL, "Read failed, hr=%x\n", hr);
    if (hr == E_FAIL)
    {
        ok(itm_hr[0] == S_OK, "Read error code has unexpected value, itm_hr[0]=%x\n", itm_hr[0]);
        ok(itm_hr[1] == -1,   "Read error code has unexpected value, itm_hr[1]=%x\n", itm_hr[1]);
        ok(itm_hr[2] == -1,   "Read error code has unexpected value, itm_hr[2]=%x\n", itm_hr[2]);

        ok(V_VT(&values[0]) == VT_UI1,  "Read variant has unexpected type, V_VT(&values[0])=%x\n", V_VT(&values[0]));
        ok(V_VT(&values[1]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[1])=%x\n", V_VT(&values[1]));
        ok(V_VT(&values[2]) == VT_NULL, "Read variant has unexpected type, V_VT(&values[2])=%x\n", V_VT(&values[2]));

        ok(V_UNION(&values[0], bVal) == 12,  "Read variant has unexpected value, V_UNION(&values[0])=%i\n", V_UNION(&values[0], bVal));
        ok(V_UNION(&values[1], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[1])=%i\n", V_UNION(&values[1], bVal));
        ok(V_UNION(&values[2], bVal) == 254, "Read variant has unexpected value, V_UNION(&values[2])=%i\n", V_UNION(&values[2], bVal));
    }
}
Esempio n. 10
0
static void test_specific_encoder_properties(IPropertyBag2 *options, const property_opt_test_data* data, PROPBAG2* all_props, int all_prop_cnt)
{
    HRESULT hr;
    int i = 0;
    VARIANT pvarValue;
    HRESULT phrError = S_OK;

    while (data[i].name)
    {
        int idx = find_property_index(data[i].name, all_props, all_prop_cnt);
        PROPBAG2 pb = {0};
        pb.pstrName = (LPOLESTR)data[i].name;

        hr = IPropertyBag2_Read(options, 1, &pb, NULL, &pvarValue, &phrError);

        ok(idx >= 0, "Property %s not in output of GetPropertyInfo\n",
           wine_dbgstr_w(data[i].name));
        if (idx >= 0)
        {
            ok(all_props[idx].vt == data[i].var_type, "Property %s has unexpected vt type, vt=%i\n",
               wine_dbgstr_w(data[i].name), all_props[idx].vt);
            ok(all_props[idx].dwType == PROPBAG2_TYPE_DATA, "Property %s has unexpected dw type, vt=%i\n",
               wine_dbgstr_w(data[i].name), all_props[idx].dwType);
            ok(all_props[idx].cfType == 0, "Property %s has unexpected cf type, vt=%i\n",
               wine_dbgstr_w(data[i].name), all_props[idx].cfType);
        }

        ok(SUCCEEDED(hr), "Reading property %s from bag failed, hr=%x\n",
           wine_dbgstr_w(data[i].name), hr);

        if (SUCCEEDED(hr))
        {
            /* On XP the initial type is always VT_EMPTY */
            ok(V_VT(&pvarValue) == data[i].initial_var_type || V_VT(&pvarValue) == VT_EMPTY,
               "Property %s has unexpected initial type, V_VT=%i\n",
               wine_dbgstr_w(data[i].name), V_VT(&pvarValue));

            if(V_VT(&pvarValue) == data[i].initial_var_type)
            {
                switch (data[i].initial_var_type)
                {
                    case VT_BOOL:
                    case VT_UI1:
                        ok(V_UNION(&pvarValue, bVal) == data[i].i_init_val, "Property %s has an unexpected initial value, pvarValue=%i\n",
                           wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, bVal));
                        break;
                    case VT_R4:
                        ok(V_UNION(&pvarValue, fltVal) == data[i].f_init_val, "Property %s has an unexpected initial value, pvarValue=%f\n",
                           wine_dbgstr_w(data[i].name), V_UNION(&pvarValue, fltVal));
                        break;
                    default:
                        break;
                }
            }

            VariantClear(&pvarValue);
        }

        i++;
    }
}
Esempio n. 11
0
static HRESULT DXDiag_InitDXDiagDirectShowFiltersContainer(IDxDiagContainer* pSubCont) {
    HRESULT hr = S_OK;
    static const WCHAR szName[] = {'s','z','N','a','m','e',0};
    static const WCHAR szCatName[] = {'s','z','C','a','t','N','a','m','e',0};
    static const WCHAR szClsidCat[] = {'s','z','C','l','s','i','d','C','a','t',0};
    static const WCHAR szClsidFilter[] = {'s','z','C','l','s','i','d','F','i','l','t','e','r',0};
    static const WCHAR dwInputs[] = {'d','w','I','n','p','u','t','s',0};
    static const WCHAR dwOutputs[] = {'d','w','O','u','t','p','u','t','s',0};
    static const WCHAR dwMerit[] = {'d','w','M','e','r','i','t',0};
    /*
    static const WCHAR szFileName[] = {'s','z','F','i','l','e','N','a','m','e',0};
    static const WCHAR szFileVersion[] = {'s','z','F','i','l','e','V','e','r','s','i','o','n',0};
    */
    VARIANT v;

    static const WCHAR wszClsidName[] = {'C','L','S','I','D',0};
    static const WCHAR wszFriendlyName[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
    static const WCHAR wszFilterDataName[] = {'F','i','l','t','e','r','D','a','t','a',0};
    /*static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};*/

    ICreateDevEnum* pCreateDevEnum = NULL;
    IEnumMoniker* pEmCat = NULL;
    IMoniker* pMCat = NULL;
    /** */
    hr = CoCreateInstance(&CLSID_SystemDeviceEnum,
                          NULL,
                          CLSCTX_INPROC_SERVER,
                          &IID_ICreateDevEnum,
                          (void**) &pCreateDevEnum);
    if (FAILED(hr)) return hr;

    hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &CLSID_ActiveMovieCategories, &pEmCat, 0);
    if (FAILED(hr)) goto out_show_filters;

    VariantInit(&v);

    while (S_OK == IEnumMoniker_Next(pEmCat, 1, &pMCat, NULL)) {
        IPropertyBag* pPropBag = NULL;
        CLSID clsidCat;
        hr = IMoniker_BindToStorage(pMCat, NULL, NULL, &IID_IPropertyBag, (void**) &pPropBag);
        if (SUCCEEDED(hr)) {
            WCHAR* wszCatName = NULL;
            WCHAR* wszCatClsid = NULL;

            hr = IPropertyBag_Read(pPropBag, wszFriendlyName, &v, 0);
            wszCatName = SysAllocString(V_BSTR(&v));
            VariantClear(&v);

            hr = IPropertyBag_Read(pPropBag, wszClsidName, &v, 0);
            wszCatClsid = SysAllocString(V_BSTR(&v));
            hr = CLSIDFromString(V_UNION(&v, bstrVal), &clsidCat);
            VariantClear(&v);

            /*
            hr = IPropertyBag_Read(pPropBag, wszMeritName, &v, 0);
            hr = IDxDiagContainerImpl_AddProp(pSubCont, dwMerit, &v);
            VariantClear(&v);
            */

            if (SUCCEEDED(hr)) {
                IEnumMoniker* pEnum = NULL;
                IMoniker* pMoniker = NULL;
                hr = ICreateDevEnum_CreateClassEnumerator(pCreateDevEnum, &clsidCat, &pEnum, 0);
                FIXME("\tClassEnumerator for clsid(%s) pEnum(%p)\n", debugstr_guid(&clsidCat), pEnum);
                if (FAILED(hr) || pEnum == NULL) {
                    goto class_enum_failed;
                }
                while (NULL != pEnum && S_OK == IEnumMoniker_Next(pEnum, 1, &pMoniker, NULL)) {
                    IPropertyBag* pPropFilterBag = NULL;
                    FIXME("\tIEnumMoniker_Next(%p, 1, %p)\n", pEnum, pMoniker);
                    hr = IMoniker_BindToStorage(pMoniker, NULL, NULL, &IID_IPropertyBag, (void**) &pPropFilterBag);
                    if (SUCCEEDED(hr)) {
                        LPBYTE pData = NULL;
                        LPBYTE pCurrent = NULL;
                        struct REG_RF* prrf = NULL;
                        VARIANT v_data;
                        DWORD it;
                        DWORD dwNOutputs = 0;
                        DWORD dwNInputs = 0;

                        V_VT(&v) = VT_BSTR;
                        V_BSTR(&v) = SysAllocString(wszCatName);
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szCatName, &v);
                        VariantClear(&v);

                        V_VT(&v) = VT_BSTR;
                        V_BSTR(&v) = SysAllocString(wszCatClsid);
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szClsidCat, &v);
                        VariantClear(&v);

                        hr = IPropertyBag_Read(pPropFilterBag, wszFriendlyName, &v, 0);
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szName, &v);
                        FIXME("\tName:%s\n", debugstr_w(V_BSTR(&v)));
                        VariantClear(&v);

                        hr = IPropertyBag_Read(pPropFilterBag, wszClsidName, &v, 0);
                        FIXME("\tClsid:%s\n", debugstr_w(V_BSTR(&v)));
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szClsidFilter, &v);
                        VariantClear(&v);

                        hr = IPropertyBag_Read(pPropFilterBag, wszFilterDataName, &v, NULL);
                        hr = SafeArrayAccessData(V_UNION(&v, parray), (LPVOID*) &pData);
                        prrf = (struct REG_RF*) pData;
                        pCurrent = pData;

                        VariantInit(&v_data);
                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = prrf->dwVersion;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, szName, &v_data);
                        VariantClear(&v_data);
                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = prrf->dwMerit;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, dwMerit, &v_data);
                        VariantClear(&v_data);

                        pCurrent += sizeof(struct REG_RF);
                        for (it = 0; it < prrf->dwPins; ++it) {
                            struct REG_RFP* prrfp = (struct REG_RFP*) pCurrent;
                            UINT j;

                            if (prrfp->dwFlags & REG_PINFLAG_B_OUTPUT) ++dwNOutputs;
                            else ++dwNInputs;

                            pCurrent += sizeof(struct REG_RFP);
                            if (prrfp->bCategory) {
                                pCurrent += sizeof(DWORD);
                            }
                            for (j = 0; j < prrfp->dwMediaTypes; ++j) {
                                struct REG_TYPE* prt = (struct REG_TYPE *)pCurrent;
                                pCurrent += sizeof(*prt);
                            }
                            for (j = 0; j < prrfp->dwMediums; ++j) {
                                DWORD dwOffset = *(DWORD*) pCurrent;
                                pCurrent += sizeof(dwOffset);
                            }
                        }

                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = dwNInputs;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, dwInputs, &v_data);
                        VariantClear(&v_data);
                        V_VT(&v_data) = VT_UI4;
                        V_UI4(&v_data) = dwNOutputs;
                        hr = IDxDiagContainerImpl_AddProp(pSubCont, dwOutputs, &v_data);
                        VariantClear(&v_data);

                        SafeArrayUnaccessData(V_UNION(&v, parray));
                        VariantClear(&v);
                    }
                    IPropertyBag_Release(pPropFilterBag);
                    pPropFilterBag = NULL;
                }
                IEnumMoniker_Release(pEnum);
                pEnum = NULL;
            }
class_enum_failed:
            SysFreeString(wszCatName);
            SysFreeString(wszCatClsid);
            IPropertyBag_Release(pPropBag);
            pPropBag = NULL;
        }
        IEnumMoniker_Release(pMCat);
        pMCat = NULL;
    }

out_show_filters:
    if (NULL != pEmCat) {
        IEnumMoniker_Release(pEmCat);
        pEmCat = NULL;
    }
    if (NULL != pCreateDevEnum) {
        ICreateDevEnum_Release(pCreateDevEnum);
        pCreateDevEnum = NULL;
    }
    return hr;
}
Esempio n. 12
0
static void test_devenum(IBindCtx *bind_ctx)
{
    HRESULT res;
    ICreateDevEnum* create_devenum;
    IEnumMoniker* enum_moniker = NULL;
    int i;

    res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
                           &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
    if (res != S_OK) {
        skip("Cannot create SystemDeviceEnum object (%x)\n", res);
        return;
    }

    for (i = 0; i < (sizeof(am_categories) / sizeof(struct category)); i++)
    {
        if (winetest_debug > 1)
            trace("%s:\n", am_categories[i].name);

        res = ICreateDevEnum_CreateClassEnumerator(create_devenum, am_categories[i].clsid, &enum_moniker, 0);
        ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
        if (res == S_OK)
        {
            IMoniker* moniker;
            while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK)
            {
                IPropertyBag* prop_bag = NULL;
                VARIANT var;
                HRESULT hr;

                VariantInit(&var);
                hr = IMoniker_BindToStorage(moniker, bind_ctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
                ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr);

                if (SUCCEEDED(hr))
                {
                    hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
                    ok((hr == S_OK) || broken(hr == 0x80070002), "IPropertyBag_Read failed with error %x\n", hr);

                    if (SUCCEEDED(hr))
                    {
                        if (winetest_debug > 1)
                            trace("  %s\n", wine_dbgstr_w(V_UNION(&var, bstrVal)));
                        VariantClear(&var);
                    }
                    else
                    {
                        trace("  ???\n");
                    }
                }

                if (prop_bag)
                    IPropertyBag_Release(prop_bag);
                IMoniker_Release(moniker);
            }
            IEnumMoniker_Release(enum_moniker);
        }
    }

    ICreateDevEnum_Release(create_devenum);
}