1c2c66affSColin Finck /*
2c2c66affSColin Finck  * Some unit tests for devenum
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright (C) 2012 Christian Costa
5c2c66affSColin Finck  *
6c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
7c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
8c2c66affSColin Finck  * License as published by the Free Software Foundation; either
9c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
10c2c66affSColin Finck  *
11c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
12c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14c2c66affSColin Finck  * Lesser General Public License for more details.
15c2c66affSColin Finck  *
16c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
17c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
18c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19c2c66affSColin Finck  */
20c2c66affSColin Finck 
21c2c66affSColin Finck #define COBJMACROS
22c2c66affSColin Finck 
23d9b4957fSAmine Khaldi #include <stdio.h>
24c2c66affSColin Finck 
25d9b4957fSAmine Khaldi #include "wine/test.h"
26d9b4957fSAmine Khaldi #include "initguid.h"
27d9b4957fSAmine Khaldi #include "ole2.h"
28d9b4957fSAmine Khaldi #include "strmif.h"
29d9b4957fSAmine Khaldi #include "uuids.h"
306e5b60fcSAmine Khaldi #include "vfwmsgs.h"
316e5b60fcSAmine Khaldi #include "mmsystem.h"
326e5b60fcSAmine Khaldi #include "dsound.h"
336e5b60fcSAmine Khaldi #include "mmddk.h"
346e5b60fcSAmine Khaldi #include "vfw.h"
35*8cc0d363SAmine Khaldi #include "dmoreg.h"
36*8cc0d363SAmine Khaldi #include "setupapi.h"
376e5b60fcSAmine Khaldi 
386e5b60fcSAmine Khaldi DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
39c2c66affSColin Finck 
40c2c66affSColin Finck static const WCHAR friendly_name[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
416e5b60fcSAmine Khaldi static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
426e5b60fcSAmine Khaldi static const WCHAR clsidW[] = {'C','L','S','I','D',0};
436e5b60fcSAmine Khaldi static const WCHAR waveW[] = {'w','a','v','e',':',0};
44*8cc0d363SAmine Khaldi static const WCHAR dmoW[] = {'d','m','o',':',0};
456e5b60fcSAmine Khaldi static const WCHAR swW[] = {'s','w',':',0};
466e5b60fcSAmine Khaldi static const WCHAR cmW[] = {'c','m',':',0};
476e5b60fcSAmine Khaldi static const WCHAR backslashW[] = {'\\',0};
48c2c66affSColin Finck 
strchrW(const WCHAR * str,WCHAR ch)496e5b60fcSAmine Khaldi static inline WCHAR *strchrW( const WCHAR *str, WCHAR ch )
50c2c66affSColin Finck {
516e5b60fcSAmine Khaldi     do { if (*str == ch) return (WCHAR *)str; } while (*str++);
526e5b60fcSAmine Khaldi     return NULL;
536e5b60fcSAmine Khaldi }
54c2c66affSColin Finck 
strncmpW(const WCHAR * str1,const WCHAR * str2,int n)556e5b60fcSAmine Khaldi static inline int strncmpW( const WCHAR *str1, const WCHAR *str2, int n )
56c2c66affSColin Finck {
576e5b60fcSAmine Khaldi     if (n <= 0) return 0;
586e5b60fcSAmine Khaldi     while ((--n > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
596e5b60fcSAmine Khaldi     return *str1 - *str2;
606e5b60fcSAmine Khaldi }
61c2c66affSColin Finck 
test_devenum(IBindCtx * bind_ctx)62c2c66affSColin Finck static void test_devenum(IBindCtx *bind_ctx)
63c2c66affSColin Finck {
646e5b60fcSAmine Khaldi     IEnumMoniker *enum_cat, *enum_moniker;
65c2c66affSColin Finck     ICreateDevEnum* create_devenum;
666e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
67c2c66affSColin Finck     IMoniker *moniker;
686e5b60fcSAmine Khaldi     GUID cat_guid, clsid;
69*8cc0d363SAmine Khaldi     WCHAR *displayname;
70c2c66affSColin Finck     VARIANT var;
71c2c66affSColin Finck     HRESULT hr;
72*8cc0d363SAmine Khaldi     int count;
73c2c66affSColin Finck 
746e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
756e5b60fcSAmine Khaldi                            &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
766e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create devenum: %#x\n", hr);
776e5b60fcSAmine Khaldi 
786e5b60fcSAmine Khaldi     hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_ActiveMovieCategories, &enum_cat, 0);
796e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to enum categories: %#x\n", hr);
806e5b60fcSAmine Khaldi 
816e5b60fcSAmine Khaldi     while (IEnumMoniker_Next(enum_cat, 1, &moniker, NULL) == S_OK)
826e5b60fcSAmine Khaldi     {
836e5b60fcSAmine Khaldi         hr = IMoniker_BindToStorage(moniker, bind_ctx, NULL, &IID_IPropertyBag, (void **)&prop_bag);
846e5b60fcSAmine Khaldi         ok(hr == S_OK, "IMoniker_BindToStorage failed: %#x\n", hr);
856e5b60fcSAmine Khaldi 
866e5b60fcSAmine Khaldi         VariantInit(&var);
876e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
886e5b60fcSAmine Khaldi         ok(hr == S_OK, "Failed to read CLSID: %#x\n", hr);
896e5b60fcSAmine Khaldi 
906e5b60fcSAmine Khaldi         hr = CLSIDFromString(V_BSTR(&var), &cat_guid);
916e5b60fcSAmine Khaldi         ok(hr == S_OK, "got %#x\n", hr);
926e5b60fcSAmine Khaldi 
93*8cc0d363SAmine Khaldi         VariantClear(&var);
94*8cc0d363SAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
95*8cc0d363SAmine Khaldi         ok(hr == S_OK, "Failed to read FriendlyName: %#x\n", hr);
96*8cc0d363SAmine Khaldi 
97*8cc0d363SAmine Khaldi         if (winetest_debug > 1)
98*8cc0d363SAmine Khaldi             trace("%s %s:\n", wine_dbgstr_guid(&cat_guid), wine_dbgstr_w(V_BSTR(&var)));
99*8cc0d363SAmine Khaldi 
100*8cc0d363SAmine Khaldi         VariantClear(&var);
1016e5b60fcSAmine Khaldi         IPropertyBag_Release(prop_bag);
1026e5b60fcSAmine Khaldi         IMoniker_Release(moniker);
1036e5b60fcSAmine Khaldi 
1046e5b60fcSAmine Khaldi         hr = ICreateDevEnum_CreateClassEnumerator(create_devenum, &cat_guid, &enum_moniker, 0);
1056e5b60fcSAmine Khaldi         ok(SUCCEEDED(hr), "Failed to enum devices: %#x\n", hr);
1066e5b60fcSAmine Khaldi 
1076e5b60fcSAmine Khaldi         if (hr == S_OK)
1086e5b60fcSAmine Khaldi         {
109*8cc0d363SAmine Khaldi             count = 0;
110*8cc0d363SAmine Khaldi 
1116e5b60fcSAmine Khaldi             while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK)
1126e5b60fcSAmine Khaldi             {
113*8cc0d363SAmine Khaldi                 hr = IMoniker_GetDisplayName(moniker, NULL, NULL, &displayname);
114*8cc0d363SAmine Khaldi                 ok(hr == S_OK, "got %#x\n", hr);
115*8cc0d363SAmine Khaldi 
116c2c66affSColin Finck                 hr = IMoniker_GetClassID(moniker, NULL);
117c2c66affSColin Finck                 ok(hr == E_INVALIDARG, "IMoniker_GetClassID should failed %x\n", hr);
118c2c66affSColin Finck 
119c2c66affSColin Finck                 hr = IMoniker_GetClassID(moniker, &clsid);
120c2c66affSColin Finck                 ok(hr == S_OK, "IMoniker_GetClassID failed with error %x\n", hr);
121c2c66affSColin Finck                 ok(IsEqualGUID(&clsid, &CLSID_CDeviceMoniker),
122c2c66affSColin Finck                    "Expected CLSID_CDeviceMoniker got %s\n", wine_dbgstr_guid(&clsid));
123c2c66affSColin Finck 
124c2c66affSColin Finck                 VariantInit(&var);
125c2c66affSColin Finck                 hr = IMoniker_BindToStorage(moniker, bind_ctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
126c2c66affSColin Finck                 ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr);
127c2c66affSColin Finck 
128c2c66affSColin Finck                 hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
129*8cc0d363SAmine Khaldi                 ok((hr == S_OK) | (hr == ERROR_KEY_DOES_NOT_EXIST),
130*8cc0d363SAmine Khaldi 					"IPropertyBag_Read failed: %#x\n", hr);
131c2c66affSColin Finck 
132c2c66affSColin Finck                 if (winetest_debug > 1)
133*8cc0d363SAmine Khaldi                     trace("  %s %s\n", wine_dbgstr_w(displayname), wine_dbgstr_w(V_BSTR(&var)));
134c2c66affSColin Finck 
1356e5b60fcSAmine Khaldi                 hr = IMoniker_BindToObject(moniker, bind_ctx, NULL, &IID_IUnknown, NULL);
1366e5b60fcSAmine Khaldi                 ok(hr == E_POINTER, "got %#x\n", hr);
1376e5b60fcSAmine Khaldi 
138*8cc0d363SAmine Khaldi                 VariantClear(&var);
139*8cc0d363SAmine Khaldi                 CoTaskMemFree(displayname);
140c2c66affSColin Finck                 IPropertyBag_Release(prop_bag);
141c2c66affSColin Finck                 IMoniker_Release(moniker);
142*8cc0d363SAmine Khaldi                 count++;
143c2c66affSColin Finck             }
144c2c66affSColin Finck             IEnumMoniker_Release(enum_moniker);
145*8cc0d363SAmine Khaldi 
146*8cc0d363SAmine Khaldi             ok(count > 0, "CreateClassEnumerator() returned S_OK but no devices were enumerated.\n");
147c2c66affSColin Finck         }
148c2c66affSColin Finck     }
149c2c66affSColin Finck 
150*8cc0d363SAmine Khaldi     IEnumMoniker_Release(enum_cat);
151c2c66affSColin Finck     ICreateDevEnum_Release(create_devenum);
152c2c66affSColin Finck }
153*8cc0d363SAmine Khaldi 
test_moniker_isequal(void)154c2c66affSColin Finck static void test_moniker_isequal(void)
155c2c66affSColin Finck {
156c2c66affSColin Finck     HRESULT res;
157c2c66affSColin Finck     ICreateDevEnum *create_devenum = NULL;
158c2c66affSColin Finck     IEnumMoniker *enum_moniker0 = NULL, *enum_moniker1 = NULL;
159c2c66affSColin Finck     IMoniker *moniker0 = NULL, *moniker1 = NULL;
160c2c66affSColin Finck 
161c2c66affSColin Finck     res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
162c2c66affSColin Finck                            &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
163c2c66affSColin Finck     if (FAILED(res))
164c2c66affSColin Finck     {
165c2c66affSColin Finck          skip("Cannot create SystemDeviceEnum object (%x)\n", res);
166c2c66affSColin Finck          return;
167c2c66affSColin Finck     }
168c2c66affSColin Finck 
169c2c66affSColin Finck     res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
170c2c66affSColin Finck     ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
171c2c66affSColin Finck     if (SUCCEEDED(res))
172c2c66affSColin Finck     {
173c2c66affSColin Finck         if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
174c2c66affSColin Finck             IEnumMoniker_Next(enum_moniker0, 1, &moniker1, NULL) == S_OK)
175c2c66affSColin Finck         {
176c2c66affSColin Finck             res = IMoniker_IsEqual(moniker0, moniker1);
177c2c66affSColin Finck             ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
178c2c66affSColin Finck 
179c2c66affSColin Finck             res = IMoniker_IsEqual(moniker1, moniker0);
180c2c66affSColin Finck             ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
181c2c66affSColin Finck 
182c2c66affSColin Finck             IMoniker_Release(moniker0);
183c2c66affSColin Finck             IMoniker_Release(moniker1);
184c2c66affSColin Finck         }
185c2c66affSColin Finck         else
186c2c66affSColin Finck             skip("Cannot get moniker for testing.\n");
187c2c66affSColin Finck     }
188c2c66affSColin Finck     IEnumMoniker_Release(enum_moniker0);
189c2c66affSColin Finck 
190c2c66affSColin Finck     res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
191c2c66affSColin Finck     ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
192c2c66affSColin Finck     res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_AudioRendererCategory, &enum_moniker1, 0);
193c2c66affSColin Finck     ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
194c2c66affSColin Finck     if (SUCCEEDED(res))
195c2c66affSColin Finck     {
196c2c66affSColin Finck         if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
197c2c66affSColin Finck             IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
198c2c66affSColin Finck         {
199c2c66affSColin Finck             res = IMoniker_IsEqual(moniker0, moniker1);
200c2c66affSColin Finck             ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
201c2c66affSColin Finck 
202c2c66affSColin Finck             res = IMoniker_IsEqual(moniker1, moniker0);
203c2c66affSColin Finck             ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
204c2c66affSColin Finck 
205c2c66affSColin Finck             IMoniker_Release(moniker0);
206c2c66affSColin Finck             IMoniker_Release(moniker1);
207c2c66affSColin Finck         }
208c2c66affSColin Finck         else
209c2c66affSColin Finck             skip("Cannot get moniker for testing.\n");
210c2c66affSColin Finck     }
211c2c66affSColin Finck     IEnumMoniker_Release(enum_moniker0);
212c2c66affSColin Finck     IEnumMoniker_Release(enum_moniker1);
213c2c66affSColin Finck 
214c2c66affSColin Finck     res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
215c2c66affSColin Finck     ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
216c2c66affSColin Finck     res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker1, 0);
217c2c66affSColin Finck     ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
218c2c66affSColin Finck     if (SUCCEEDED(res))
219c2c66affSColin Finck     {
220c2c66affSColin Finck         if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
221c2c66affSColin Finck             IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
222c2c66affSColin Finck         {
223c2c66affSColin Finck             res = IMoniker_IsEqual(moniker0, moniker1);
224c2c66affSColin Finck             ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
225c2c66affSColin Finck 
226c2c66affSColin Finck             res = IMoniker_IsEqual(moniker1, moniker0);
227c2c66affSColin Finck             ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
228c2c66affSColin Finck 
229c2c66affSColin Finck             IMoniker_Release(moniker0);
230c2c66affSColin Finck             IMoniker_Release(moniker1);
231c2c66affSColin Finck         }
232c2c66affSColin Finck         else
233c2c66affSColin Finck             skip("Cannot get moniker for testing.\n");
234c2c66affSColin Finck     }
235c2c66affSColin Finck     IEnumMoniker_Release(enum_moniker0);
236c2c66affSColin Finck     IEnumMoniker_Release(enum_moniker1);
237c2c66affSColin Finck 
238c2c66affSColin Finck     ICreateDevEnum_Release(create_devenum);
239c2c66affSColin Finck 
240c2c66affSColin Finck     return;
241c2c66affSColin Finck }
242c2c66affSColin Finck 
find_moniker(const GUID * class,IMoniker * needle)2436e5b60fcSAmine Khaldi static BOOL find_moniker(const GUID *class, IMoniker *needle)
2446e5b60fcSAmine Khaldi {
2456e5b60fcSAmine Khaldi     ICreateDevEnum *devenum;
2466e5b60fcSAmine Khaldi     IEnumMoniker *enum_mon;
2476e5b60fcSAmine Khaldi     IMoniker *mon;
2486e5b60fcSAmine Khaldi     BOOL found = FALSE;
2496e5b60fcSAmine Khaldi 
2506e5b60fcSAmine Khaldi     CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC, &IID_ICreateDevEnum, (void **)&devenum);
2516e5b60fcSAmine Khaldi     ICreateDevEnum_CreateClassEnumerator(devenum, class, &enum_mon, 0);
2526e5b60fcSAmine Khaldi     while (!found && IEnumMoniker_Next(enum_mon, 1, &mon, NULL) == S_OK)
2536e5b60fcSAmine Khaldi     {
2546e5b60fcSAmine Khaldi         if (IMoniker_IsEqual(mon, needle) == S_OK)
2556e5b60fcSAmine Khaldi             found = TRUE;
2566e5b60fcSAmine Khaldi 
2576e5b60fcSAmine Khaldi         IMoniker_Release(mon);
2586e5b60fcSAmine Khaldi     }
2596e5b60fcSAmine Khaldi 
2606e5b60fcSAmine Khaldi     IEnumMoniker_Release(enum_mon);
2616e5b60fcSAmine Khaldi     ICreateDevEnum_Release(devenum);
2626e5b60fcSAmine Khaldi     return found;
2636e5b60fcSAmine Khaldi }
2646e5b60fcSAmine Khaldi 
2656e5b60fcSAmine Khaldi DEFINE_GUID(CLSID_TestFilter,  0xdeadbeef,0xcf51,0x43e6,0xb6,0xc5,0x29,0x9e,0xa8,0xb6,0xb5,0x91);
2666e5b60fcSAmine Khaldi 
test_register_filter(void)2676e5b60fcSAmine Khaldi static void test_register_filter(void)
2686e5b60fcSAmine Khaldi {
2696e5b60fcSAmine Khaldi     static const WCHAR name[] = {'d','e','v','e','n','u','m',' ','t','e','s','t',0};
2706e5b60fcSAmine Khaldi     IFilterMapper2 *mapper2;
2716e5b60fcSAmine Khaldi     IMoniker *mon = NULL;
2726e5b60fcSAmine Khaldi     REGFILTER2 rgf2 = {0};
2736e5b60fcSAmine Khaldi     HRESULT hr;
2746e5b60fcSAmine Khaldi 
2756e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper2, (void **)&mapper2);
2766e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create FilterMapper2: %#x\n", hr);
2776e5b60fcSAmine Khaldi 
2786e5b60fcSAmine Khaldi     rgf2.dwVersion = 2;
2796e5b60fcSAmine Khaldi     rgf2.dwMerit = MERIT_UNLIKELY;
2806e5b60fcSAmine Khaldi     S2(U(rgf2)).cPins2 = 0;
2816e5b60fcSAmine Khaldi 
2826e5b60fcSAmine Khaldi     hr = IFilterMapper2_RegisterFilter(mapper2, &CLSID_TestFilter, name, &mon, NULL, NULL, &rgf2);
2836e5b60fcSAmine Khaldi     if (hr == E_ACCESSDENIED)
2846e5b60fcSAmine Khaldi     {
2856e5b60fcSAmine Khaldi         skip("Not enough permissions to register filters\n");
2866e5b60fcSAmine Khaldi         IFilterMapper2_Release(mapper2);
2876e5b60fcSAmine Khaldi         return;
2886e5b60fcSAmine Khaldi     }
2896e5b60fcSAmine Khaldi     ok(hr == S_OK, "RegisterFilter failed: %#x\n", hr);
2906e5b60fcSAmine Khaldi 
2916e5b60fcSAmine Khaldi     ok(find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should be registered\n");
2926e5b60fcSAmine Khaldi 
2936e5b60fcSAmine Khaldi     hr = IFilterMapper2_UnregisterFilter(mapper2, NULL, NULL, &CLSID_TestFilter);
2946e5b60fcSAmine Khaldi     ok(hr == S_OK, "UnregisterFilter failed: %#x\n", hr);
2956e5b60fcSAmine Khaldi 
2966e5b60fcSAmine Khaldi     ok(!find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should not be registered\n");
2976e5b60fcSAmine Khaldi     IMoniker_Release(mon);
2986e5b60fcSAmine Khaldi 
2996e5b60fcSAmine Khaldi     mon = NULL;
3006e5b60fcSAmine Khaldi     hr = IFilterMapper2_RegisterFilter(mapper2, &CLSID_TestFilter, name, &mon, &CLSID_AudioRendererCategory, NULL, &rgf2);
3016e5b60fcSAmine Khaldi     ok(hr == S_OK, "RegisterFilter failed: %#x\n", hr);
3026e5b60fcSAmine Khaldi 
3036e5b60fcSAmine Khaldi     ok(find_moniker(&CLSID_AudioRendererCategory, mon), "filter should be registered\n");
3046e5b60fcSAmine Khaldi 
3056e5b60fcSAmine Khaldi     hr = IFilterMapper2_UnregisterFilter(mapper2, &CLSID_AudioRendererCategory, NULL, &CLSID_TestFilter);
3066e5b60fcSAmine Khaldi     ok(hr == S_OK, "UnregisterFilter failed: %#x\n", hr);
3076e5b60fcSAmine Khaldi 
3086e5b60fcSAmine Khaldi     ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n");
3096e5b60fcSAmine Khaldi     IMoniker_Release(mon);
3106e5b60fcSAmine Khaldi 
3116e5b60fcSAmine Khaldi     IFilterMapper2_Release(mapper2);
3126e5b60fcSAmine Khaldi }
3136e5b60fcSAmine Khaldi 
check_display_name_(int line,IParseDisplayName * parser,WCHAR * buffer)3146e5b60fcSAmine Khaldi static IMoniker *check_display_name_(int line, IParseDisplayName *parser, WCHAR *buffer)
3156e5b60fcSAmine Khaldi {
3166e5b60fcSAmine Khaldi     IMoniker *mon;
3176e5b60fcSAmine Khaldi     ULONG eaten;
3186e5b60fcSAmine Khaldi     HRESULT hr;
3196e5b60fcSAmine Khaldi     WCHAR *str;
3206e5b60fcSAmine Khaldi 
3216e5b60fcSAmine Khaldi     hr = IParseDisplayName_ParseDisplayName(parser, NULL, buffer, &eaten, &mon);
3226e5b60fcSAmine Khaldi     ok_(__FILE__, line)(hr == S_OK, "ParseDisplayName failed: %#x\n", hr);
3236e5b60fcSAmine Khaldi 
3246e5b60fcSAmine Khaldi     hr = IMoniker_GetDisplayName(mon, NULL, NULL, &str);
3256e5b60fcSAmine Khaldi     ok_(__FILE__, line)(hr == S_OK, "GetDisplayName failed: %#x\n", hr);
3266e5b60fcSAmine Khaldi     ok_(__FILE__, line)(!lstrcmpW(str, buffer), "got %s\n", wine_dbgstr_w(str));
3276e5b60fcSAmine Khaldi 
3286e5b60fcSAmine Khaldi     CoTaskMemFree(str);
3296e5b60fcSAmine Khaldi 
3306e5b60fcSAmine Khaldi     return mon;
3316e5b60fcSAmine Khaldi }
3326e5b60fcSAmine Khaldi #define check_display_name(parser, buffer) check_display_name_(__LINE__, parser, buffer)
3336e5b60fcSAmine Khaldi 
test_directshow_filter(void)3346e5b60fcSAmine Khaldi static void test_directshow_filter(void)
3356e5b60fcSAmine Khaldi {
3366e5b60fcSAmine Khaldi     static const WCHAR instanceW[] = {'\\','I','n','s','t','a','n','c','e',0};
3376e5b60fcSAmine Khaldi     static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
3386e5b60fcSAmine Khaldi     static WCHAR testW[] = {'\\','t','e','s','t',0};
3396e5b60fcSAmine Khaldi     IParseDisplayName *parser;
3406e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
3416e5b60fcSAmine Khaldi     IMoniker *mon;
3426e5b60fcSAmine Khaldi     WCHAR buffer[200];
3436e5b60fcSAmine Khaldi     LRESULT res;
3446e5b60fcSAmine Khaldi     VARIANT var;
3456e5b60fcSAmine Khaldi     HRESULT hr;
3466e5b60fcSAmine Khaldi 
3476e5b60fcSAmine Khaldi     /* Test ParseDisplayName and GetDisplayName */
3486e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
3496e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
3506e5b60fcSAmine Khaldi 
3516e5b60fcSAmine Khaldi     lstrcpyW(buffer, deviceW);
3526e5b60fcSAmine Khaldi     lstrcatW(buffer, swW);
3536e5b60fcSAmine Khaldi     StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
3546e5b60fcSAmine Khaldi     lstrcatW(buffer, testW);
3556e5b60fcSAmine Khaldi     mon = check_display_name(parser, buffer);
3566e5b60fcSAmine Khaldi 
3576e5b60fcSAmine Khaldi     /* Test writing and reading from the property bag */
3586e5b60fcSAmine Khaldi     ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "filter should not be registered\n");
3596e5b60fcSAmine Khaldi 
3606e5b60fcSAmine Khaldi     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
3616e5b60fcSAmine Khaldi     ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
3626e5b60fcSAmine Khaldi 
3636e5b60fcSAmine Khaldi     VariantInit(&var);
3646e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
3656e5b60fcSAmine Khaldi     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
3666e5b60fcSAmine Khaldi 
3676e5b60fcSAmine Khaldi     /* writing causes the key to be created */
3686e5b60fcSAmine Khaldi     V_VT(&var) = VT_BSTR;
3696e5b60fcSAmine Khaldi     V_BSTR(&var) = SysAllocString(testW);
3706e5b60fcSAmine Khaldi     hr = IPropertyBag_Write(prop_bag, friendly_name, &var);
3716e5b60fcSAmine Khaldi     if (hr != E_ACCESSDENIED)
3726e5b60fcSAmine Khaldi     {
3736e5b60fcSAmine Khaldi         ok(hr == S_OK, "Write failed: %#x\n", hr);
3746e5b60fcSAmine Khaldi 
3756e5b60fcSAmine Khaldi         ok(find_moniker(&CLSID_AudioRendererCategory, mon), "filter should be registered\n");
3766e5b60fcSAmine Khaldi 
3776e5b60fcSAmine Khaldi         VariantClear(&var);
3786e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
3796e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
3806e5b60fcSAmine Khaldi         ok(!lstrcmpW(V_BSTR(&var), testW), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
3816e5b60fcSAmine Khaldi 
3826e5b60fcSAmine Khaldi         IMoniker_Release(mon);
3836e5b60fcSAmine Khaldi 
3846e5b60fcSAmine Khaldi         /* devenum doesn't give us a way to unregister�we have to do that manually */
3856e5b60fcSAmine Khaldi         lstrcpyW(buffer, clsidW);
3866e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
3876e5b60fcSAmine Khaldi         lstrcatW(buffer, instanceW);
3886e5b60fcSAmine Khaldi         lstrcatW(buffer, testW);
3896e5b60fcSAmine Khaldi         res = RegDeleteKeyW(HKEY_CLASSES_ROOT, buffer);
3906e5b60fcSAmine Khaldi         ok(!res, "RegDeleteKey failed: %lu\n", res);
3916e5b60fcSAmine Khaldi     }
3926e5b60fcSAmine Khaldi 
3936e5b60fcSAmine Khaldi     VariantClear(&var);
3946e5b60fcSAmine Khaldi     IPropertyBag_Release(prop_bag);
3956e5b60fcSAmine Khaldi 
3966e5b60fcSAmine Khaldi     /* name can be anything */
3976e5b60fcSAmine Khaldi 
3986e5b60fcSAmine Khaldi     lstrcpyW(buffer, deviceW);
3996e5b60fcSAmine Khaldi     lstrcatW(buffer, swW);
4006e5b60fcSAmine Khaldi     lstrcatW(buffer, testW+1);
4016e5b60fcSAmine Khaldi     mon = check_display_name(parser, buffer);
4026e5b60fcSAmine Khaldi 
4036e5b60fcSAmine Khaldi     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
4046e5b60fcSAmine Khaldi     ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
4056e5b60fcSAmine Khaldi 
4066e5b60fcSAmine Khaldi     VariantClear(&var);
4076e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
4086e5b60fcSAmine Khaldi     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
4096e5b60fcSAmine Khaldi 
4106e5b60fcSAmine Khaldi     V_VT(&var) = VT_BSTR;
4116e5b60fcSAmine Khaldi     V_BSTR(&var) = SysAllocString(testW);
4126e5b60fcSAmine Khaldi     hr = IPropertyBag_Write(prop_bag, friendly_name, &var);
4136e5b60fcSAmine Khaldi     if (hr != E_ACCESSDENIED)
4146e5b60fcSAmine Khaldi     {
4156e5b60fcSAmine Khaldi         ok(hr == S_OK, "Write failed: %#x\n", hr);
4166e5b60fcSAmine Khaldi 
4176e5b60fcSAmine Khaldi         VariantClear(&var);
4186e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
4196e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
4206e5b60fcSAmine Khaldi         ok(!lstrcmpW(V_BSTR(&var), testW), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
4216e5b60fcSAmine Khaldi 
4226e5b60fcSAmine Khaldi         IMoniker_Release(mon);
4236e5b60fcSAmine Khaldi 
4246e5b60fcSAmine Khaldi         /* vista+ stores it inside the Instance key */
4256e5b60fcSAmine Khaldi         RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\test\\Instance");
4266e5b60fcSAmine Khaldi 
4276e5b60fcSAmine Khaldi         res = RegDeleteKeyA(HKEY_CLASSES_ROOT, "CLSID\\test");
4286e5b60fcSAmine Khaldi         ok(!res, "RegDeleteKey failed: %lu\n", res);
4296e5b60fcSAmine Khaldi     }
4306e5b60fcSAmine Khaldi 
4316e5b60fcSAmine Khaldi     VariantClear(&var);
4326e5b60fcSAmine Khaldi     IPropertyBag_Release(prop_bag);
4336e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
4346e5b60fcSAmine Khaldi }
4356e5b60fcSAmine Khaldi 
test_codec(void)4366e5b60fcSAmine Khaldi static void test_codec(void)
4376e5b60fcSAmine Khaldi {
4386e5b60fcSAmine Khaldi     static WCHAR testW[] = {'\\','t','e','s','t',0};
4396e5b60fcSAmine Khaldi     IParseDisplayName *parser;
4406e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
4416e5b60fcSAmine Khaldi     IMoniker *mon;
4426e5b60fcSAmine Khaldi     WCHAR buffer[200];
4436e5b60fcSAmine Khaldi     VARIANT var;
4446e5b60fcSAmine Khaldi     HRESULT hr;
4456e5b60fcSAmine Khaldi 
4466e5b60fcSAmine Khaldi     /* Test ParseDisplayName and GetDisplayName */
4476e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
4486e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
4496e5b60fcSAmine Khaldi 
4506e5b60fcSAmine Khaldi     lstrcpyW(buffer, deviceW);
4516e5b60fcSAmine Khaldi     lstrcatW(buffer, cmW);
4526e5b60fcSAmine Khaldi     StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
4536e5b60fcSAmine Khaldi     lstrcatW(buffer, testW);
4546e5b60fcSAmine Khaldi     mon = check_display_name(parser, buffer);
4556e5b60fcSAmine Khaldi 
4566e5b60fcSAmine Khaldi     /* Test writing and reading from the property bag */
4576e5b60fcSAmine Khaldi     ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n");
4586e5b60fcSAmine Khaldi 
4596e5b60fcSAmine Khaldi     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
4606e5b60fcSAmine Khaldi     ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
4616e5b60fcSAmine Khaldi 
4626e5b60fcSAmine Khaldi     VariantInit(&var);
4636e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
4646e5b60fcSAmine Khaldi     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
4656e5b60fcSAmine Khaldi 
4666e5b60fcSAmine Khaldi     V_VT(&var) = VT_BSTR;
4676e5b60fcSAmine Khaldi     V_BSTR(&var) = SysAllocString(testW);
4686e5b60fcSAmine Khaldi     hr = IPropertyBag_Write(prop_bag, friendly_name, &var);
4696e5b60fcSAmine Khaldi     ok(hr == S_OK, "Write failed: %#x\n", hr);
4706e5b60fcSAmine Khaldi 
4716e5b60fcSAmine Khaldi     VariantClear(&var);
4726e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
4736e5b60fcSAmine Khaldi     ok(hr == S_OK, "Read failed: %#x\n", hr);
4746e5b60fcSAmine Khaldi     ok(!lstrcmpW(V_BSTR(&var), testW), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
4756e5b60fcSAmine Khaldi 
4766e5b60fcSAmine Khaldi     /* unlike DirectShow filters, these are automatically generated, so
4776e5b60fcSAmine Khaldi      * enumerating them will destroy the key */
4786e5b60fcSAmine Khaldi     ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "codec should not be registered\n");
4796e5b60fcSAmine Khaldi 
480*8cc0d363SAmine Khaldi     VariantClear(&var);
4816e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
4826e5b60fcSAmine Khaldi     ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got %#x\n", hr);
4836e5b60fcSAmine Khaldi 
4846e5b60fcSAmine Khaldi     IPropertyBag_Release(prop_bag);
4856e5b60fcSAmine Khaldi     IMoniker_Release(mon);
4866e5b60fcSAmine Khaldi 
4876e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
4886e5b60fcSAmine Khaldi }
4896e5b60fcSAmine Khaldi 
test_dmo(void)490*8cc0d363SAmine Khaldi static void test_dmo(void)
491*8cc0d363SAmine Khaldi {
492*8cc0d363SAmine Khaldi     static const WCHAR name[] = {'d','e','v','e','n','u','m',' ','t','e','s','t',0};
493*8cc0d363SAmine Khaldi     IParseDisplayName *parser;
494*8cc0d363SAmine Khaldi     IPropertyBag *prop_bag;
495*8cc0d363SAmine Khaldi     WCHAR buffer[200];
496*8cc0d363SAmine Khaldi     IMoniker *mon;
497*8cc0d363SAmine Khaldi     VARIANT var;
498*8cc0d363SAmine Khaldi     HRESULT hr;
499*8cc0d363SAmine Khaldi 
500*8cc0d363SAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
501*8cc0d363SAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
502*8cc0d363SAmine Khaldi 
503*8cc0d363SAmine Khaldi     lstrcpyW(buffer, deviceW);
504*8cc0d363SAmine Khaldi     lstrcatW(buffer, dmoW);
505*8cc0d363SAmine Khaldi     StringFromGUID2(&CLSID_TestFilter, buffer + lstrlenW(buffer), CHARS_IN_GUID);
506*8cc0d363SAmine Khaldi     StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
507*8cc0d363SAmine Khaldi     mon = check_display_name(parser, buffer);
508*8cc0d363SAmine Khaldi 
509*8cc0d363SAmine Khaldi     ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should not be registered\n");
510*8cc0d363SAmine Khaldi 
511*8cc0d363SAmine Khaldi     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
512*8cc0d363SAmine Khaldi     ok(hr == S_OK, "got %#x\n", hr);
513*8cc0d363SAmine Khaldi 
514*8cc0d363SAmine Khaldi     VariantInit(&var);
515*8cc0d363SAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
516*8cc0d363SAmine Khaldi     ok(hr == E_FAIL, "got %#x\n", hr);
517*8cc0d363SAmine Khaldi 
518*8cc0d363SAmine Khaldi     V_VT(&var) = VT_BSTR;
519*8cc0d363SAmine Khaldi     V_BSTR(&var) = SysAllocString(name);
520*8cc0d363SAmine Khaldi     hr = IPropertyBag_Write(prop_bag, friendly_name, &var);
521*8cc0d363SAmine Khaldi     ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
522*8cc0d363SAmine Khaldi 
523*8cc0d363SAmine Khaldi     hr = DMORegister(name, &CLSID_TestFilter, &CLSID_AudioRendererCategory, 0, 0, NULL, 0, NULL);
524*8cc0d363SAmine Khaldi     if (hr != E_FAIL)
525*8cc0d363SAmine Khaldi     {
526*8cc0d363SAmine Khaldi         ok(hr == S_OK, "got %#x\n", hr);
527*8cc0d363SAmine Khaldi 
528*8cc0d363SAmine Khaldi         ok(find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should be registered\n");
529*8cc0d363SAmine Khaldi 
530*8cc0d363SAmine Khaldi         VariantClear(&var);
531*8cc0d363SAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
532*8cc0d363SAmine Khaldi         ok(hr == S_OK, "got %#x\n", hr);
533*8cc0d363SAmine Khaldi         ok(!lstrcmpW(V_BSTR(&var), name), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
534*8cc0d363SAmine Khaldi 
535*8cc0d363SAmine Khaldi         VariantClear(&var);
536*8cc0d363SAmine Khaldi         V_VT(&var) = VT_BSTR;
537*8cc0d363SAmine Khaldi         V_BSTR(&var) = SysAllocString(name);
538*8cc0d363SAmine Khaldi         hr = IPropertyBag_Write(prop_bag, friendly_name, &var);
539*8cc0d363SAmine Khaldi         ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
540*8cc0d363SAmine Khaldi 
541*8cc0d363SAmine Khaldi         VariantClear(&var);
542*8cc0d363SAmine Khaldi         hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
543*8cc0d363SAmine Khaldi         ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr);
544*8cc0d363SAmine Khaldi 
545*8cc0d363SAmine Khaldi         hr = DMOUnregister(&CLSID_TestFilter, &CLSID_AudioRendererCategory);
546*8cc0d363SAmine Khaldi         ok(hr == S_OK, "got %#x\n", hr);
547*8cc0d363SAmine Khaldi     }
548*8cc0d363SAmine Khaldi     IPropertyBag_Release(prop_bag);
549*8cc0d363SAmine Khaldi     IMoniker_Release(mon);
550*8cc0d363SAmine Khaldi     IParseDisplayName_Release(parser);
551*8cc0d363SAmine Khaldi }
552*8cc0d363SAmine Khaldi 
test_legacy_filter(void)5536e5b60fcSAmine Khaldi static void test_legacy_filter(void)
5546e5b60fcSAmine Khaldi {
5556e5b60fcSAmine Khaldi     static const WCHAR nameW[] = {'t','e','s','t',0};
5566e5b60fcSAmine Khaldi     IParseDisplayName *parser;
5576e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
5586e5b60fcSAmine Khaldi     IFilterMapper *mapper;
5596e5b60fcSAmine Khaldi     IMoniker *mon;
5606e5b60fcSAmine Khaldi     WCHAR buffer[200];
5616e5b60fcSAmine Khaldi     VARIANT var;
5626e5b60fcSAmine Khaldi     HRESULT hr;
5636e5b60fcSAmine Khaldi 
5646e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
5656e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
5666e5b60fcSAmine Khaldi 
5676e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC, &IID_IFilterMapper, (void **)&mapper);
5686e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create FilterMapper: %#x\n", hr);
5696e5b60fcSAmine Khaldi 
5706e5b60fcSAmine Khaldi     hr = IFilterMapper_RegisterFilter(mapper, CLSID_TestFilter, nameW, 0xdeadbeef);
5716e5b60fcSAmine Khaldi     if (hr == VFW_E_BAD_KEY)
5726e5b60fcSAmine Khaldi     {
5736e5b60fcSAmine Khaldi         win_skip("not enough permissions to register filters\n");
5746e5b60fcSAmine Khaldi         goto end;
5756e5b60fcSAmine Khaldi     }
5766e5b60fcSAmine Khaldi     ok(hr == S_OK, "RegisterFilter failed: %#x\n", hr);
5776e5b60fcSAmine Khaldi 
5786e5b60fcSAmine Khaldi     lstrcpyW(buffer, deviceW);
5796e5b60fcSAmine Khaldi     lstrcatW(buffer, cmW);
5806e5b60fcSAmine Khaldi     StringFromGUID2(&CLSID_LegacyAmFilterCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
5816e5b60fcSAmine Khaldi     lstrcatW(buffer, backslashW);
5826e5b60fcSAmine Khaldi     StringFromGUID2(&CLSID_TestFilter, buffer + lstrlenW(buffer), CHARS_IN_GUID);
5836e5b60fcSAmine Khaldi 
5846e5b60fcSAmine Khaldi     mon = check_display_name(parser, buffer);
5856e5b60fcSAmine Khaldi     ok(find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should be registered\n");
5866e5b60fcSAmine Khaldi 
5876e5b60fcSAmine Khaldi     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
5886e5b60fcSAmine Khaldi     ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
5896e5b60fcSAmine Khaldi 
5906e5b60fcSAmine Khaldi     VariantInit(&var);
5916e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
5926e5b60fcSAmine Khaldi     ok(hr == S_OK, "Read failed: %#x\n", hr);
5936e5b60fcSAmine Khaldi 
5946e5b60fcSAmine Khaldi     StringFromGUID2(&CLSID_TestFilter, buffer, CHARS_IN_GUID);
5956e5b60fcSAmine Khaldi     ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
5966e5b60fcSAmine Khaldi         wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
5976e5b60fcSAmine Khaldi 
5986e5b60fcSAmine Khaldi     VariantClear(&var);
5996e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
6006e5b60fcSAmine Khaldi     ok(hr == S_OK, "Read failed: %#x\n", hr);
6016e5b60fcSAmine Khaldi     ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
6026e5b60fcSAmine Khaldi         wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
6036e5b60fcSAmine Khaldi 
604*8cc0d363SAmine Khaldi     VariantClear(&var);
6056e5b60fcSAmine Khaldi     IPropertyBag_Release(prop_bag);
6066e5b60fcSAmine Khaldi 
6076e5b60fcSAmine Khaldi     hr = IFilterMapper_UnregisterFilter(mapper, CLSID_TestFilter);
6086e5b60fcSAmine Khaldi     ok(hr == S_OK, "UnregisterFilter failed: %#x\n", hr);
6096e5b60fcSAmine Khaldi 
6106e5b60fcSAmine Khaldi     ok(!find_moniker(&CLSID_LegacyAmFilterCategory, mon), "filter should not be registered\n");
6116e5b60fcSAmine Khaldi     IMoniker_Release(mon);
6126e5b60fcSAmine Khaldi 
6136e5b60fcSAmine Khaldi end:
6146e5b60fcSAmine Khaldi     IFilterMapper_Release(mapper);
6156e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
6166e5b60fcSAmine Khaldi }
6176e5b60fcSAmine Khaldi 
test_dsound(GUID * guid,const WCHAR * desc,const WCHAR * module,void * context)6186e5b60fcSAmine Khaldi static BOOL CALLBACK test_dsound(GUID *guid, const WCHAR *desc, const WCHAR *module, void *context)
6196e5b60fcSAmine Khaldi {
6206e5b60fcSAmine Khaldi     static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','D','i','r','e','c','t','S','o','u','n','d',' ','D','e','v','i','c','e',0};
6216e5b60fcSAmine Khaldi     static const WCHAR directsoundW[] = {'D','i','r','e','c','t','S','o','u','n','d',':',' ',0};
6226e5b60fcSAmine Khaldi     static const WCHAR dsguidW[] = {'D','S','G','u','i','d',0};
6236e5b60fcSAmine Khaldi     IParseDisplayName *parser;
6246e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
6256e5b60fcSAmine Khaldi     IMoniker *mon;
6266e5b60fcSAmine Khaldi     WCHAR buffer[200];
6276e5b60fcSAmine Khaldi     WCHAR name[200];
6286e5b60fcSAmine Khaldi     VARIANT var;
6296e5b60fcSAmine Khaldi     HRESULT hr;
6306e5b60fcSAmine Khaldi 
6316e5b60fcSAmine Khaldi     if (guid)
6326e5b60fcSAmine Khaldi     {
6336e5b60fcSAmine Khaldi         lstrcpyW(name, directsoundW);
6346e5b60fcSAmine Khaldi         lstrcatW(name, desc);
6356e5b60fcSAmine Khaldi     }
6366e5b60fcSAmine Khaldi     else
6376e5b60fcSAmine Khaldi     {
6386e5b60fcSAmine Khaldi         lstrcpyW(name, defaultW);
6396e5b60fcSAmine Khaldi         guid = (GUID *)&GUID_NULL;
6406e5b60fcSAmine Khaldi     }
6416e5b60fcSAmine Khaldi 
6426e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
6436e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
6446e5b60fcSAmine Khaldi 
6456e5b60fcSAmine Khaldi     lstrcpyW(buffer, deviceW);
6466e5b60fcSAmine Khaldi     lstrcatW(buffer, cmW);
6476e5b60fcSAmine Khaldi     StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
6486e5b60fcSAmine Khaldi     lstrcatW(buffer, backslashW);
6496e5b60fcSAmine Khaldi     lstrcatW(buffer, name);
6506e5b60fcSAmine Khaldi 
6516e5b60fcSAmine Khaldi     mon = check_display_name(parser, buffer);
6526e5b60fcSAmine Khaldi 
6536e5b60fcSAmine Khaldi     hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
6546e5b60fcSAmine Khaldi     ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
6556e5b60fcSAmine Khaldi 
6566e5b60fcSAmine Khaldi     VariantInit(&var);
6576e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
6586e5b60fcSAmine Khaldi     if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
6596e5b60fcSAmine Khaldi     {
6606e5b60fcSAmine Khaldi         /* Win8+ uses the GUID instead of the device name */
6616e5b60fcSAmine Khaldi         IPropertyBag_Release(prop_bag);
6626e5b60fcSAmine Khaldi         IMoniker_Release(mon);
6636e5b60fcSAmine Khaldi 
6646e5b60fcSAmine Khaldi         lstrcpyW(buffer, deviceW);
6656e5b60fcSAmine Khaldi         lstrcatW(buffer, cmW);
6666e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
6676e5b60fcSAmine Khaldi         lstrcatW(buffer, backslashW);
6686e5b60fcSAmine Khaldi         lstrcatW(buffer, directsoundW);
6696e5b60fcSAmine Khaldi         StringFromGUID2(guid, buffer + lstrlenW(buffer) - 1, CHARS_IN_GUID);
6706e5b60fcSAmine Khaldi 
6716e5b60fcSAmine Khaldi         mon = check_display_name(parser, buffer);
6726e5b60fcSAmine Khaldi 
6736e5b60fcSAmine Khaldi         hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
6746e5b60fcSAmine Khaldi         ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
6756e5b60fcSAmine Khaldi 
6766e5b60fcSAmine Khaldi         VariantInit(&var);
6776e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
6786e5b60fcSAmine Khaldi     }
6796e5b60fcSAmine Khaldi     ok(hr == S_OK, "Read failed: %#x\n", hr);
6806e5b60fcSAmine Khaldi 
6816e5b60fcSAmine Khaldi     ok(!lstrcmpW(name, V_BSTR(&var)), "expected %s, got %s\n",
6826e5b60fcSAmine Khaldi         wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
6836e5b60fcSAmine Khaldi 
6846e5b60fcSAmine Khaldi     VariantClear(&var);
6856e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
6866e5b60fcSAmine Khaldi     ok(hr == S_OK, "Read failed: %#x\n", hr);
6876e5b60fcSAmine Khaldi 
6886e5b60fcSAmine Khaldi     StringFromGUID2(&CLSID_DSoundRender, buffer, CHARS_IN_GUID);
6896e5b60fcSAmine Khaldi     ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
6906e5b60fcSAmine Khaldi         wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
6916e5b60fcSAmine Khaldi 
6926e5b60fcSAmine Khaldi     VariantClear(&var);
6936e5b60fcSAmine Khaldi     hr = IPropertyBag_Read(prop_bag, dsguidW, &var, NULL);
6946e5b60fcSAmine Khaldi     ok(hr == S_OK, "Read failed: %#x\n", hr);
6956e5b60fcSAmine Khaldi 
6966e5b60fcSAmine Khaldi     StringFromGUID2(guid, buffer, CHARS_IN_GUID);
6976e5b60fcSAmine Khaldi     ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
6986e5b60fcSAmine Khaldi         wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
6996e5b60fcSAmine Khaldi 
700*8cc0d363SAmine Khaldi     VariantClear(&var);
7016e5b60fcSAmine Khaldi     IPropertyBag_Release(prop_bag);
7026e5b60fcSAmine Khaldi     IMoniker_Release(mon);
7036e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
7046e5b60fcSAmine Khaldi     return TRUE;
7056e5b60fcSAmine Khaldi }
7066e5b60fcSAmine Khaldi 
test_waveout(void)7076e5b60fcSAmine Khaldi static void test_waveout(void)
7086e5b60fcSAmine Khaldi {
7096e5b60fcSAmine Khaldi     static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','W','a','v','e','O','u','t',' ','D','e','v','i','c','e',0};
7106e5b60fcSAmine Khaldi     static const WCHAR waveoutidW[] = {'W','a','v','e','O','u','t','I','d',0};
7116e5b60fcSAmine Khaldi     IParseDisplayName *parser;
7126e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
7136e5b60fcSAmine Khaldi     IMoniker *mon;
7146e5b60fcSAmine Khaldi     WCHAR endpoint[200];
7156e5b60fcSAmine Khaldi     WAVEOUTCAPSW caps;
7166e5b60fcSAmine Khaldi     WCHAR buffer[200];
7176e5b60fcSAmine Khaldi     const WCHAR *name;
7186e5b60fcSAmine Khaldi     MMRESULT mmr;
7196e5b60fcSAmine Khaldi     int count, i;
7206e5b60fcSAmine Khaldi     VARIANT var;
7216e5b60fcSAmine Khaldi     HRESULT hr;
7226e5b60fcSAmine Khaldi 
7236e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
7246e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
7256e5b60fcSAmine Khaldi 
7266e5b60fcSAmine Khaldi     count = waveOutGetNumDevs();
7276e5b60fcSAmine Khaldi 
7286e5b60fcSAmine Khaldi     for (i = -1; i < count; i++)
7296e5b60fcSAmine Khaldi     {
7306e5b60fcSAmine Khaldi         waveOutGetDevCapsW(i, &caps, sizeof(caps));
7316e5b60fcSAmine Khaldi 
7326e5b60fcSAmine Khaldi         if (i == -1)    /* WAVE_MAPPER */
7336e5b60fcSAmine Khaldi             name = defaultW;
7346e5b60fcSAmine Khaldi         else
7356e5b60fcSAmine Khaldi             name = caps.szPname;
7366e5b60fcSAmine Khaldi 
7376e5b60fcSAmine Khaldi         lstrcpyW(buffer, deviceW);
7386e5b60fcSAmine Khaldi         lstrcatW(buffer, cmW);
7396e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
7406e5b60fcSAmine Khaldi         lstrcatW(buffer, backslashW);
7416e5b60fcSAmine Khaldi         lstrcatW(buffer, name);
7426e5b60fcSAmine Khaldi 
7436e5b60fcSAmine Khaldi         mon = check_display_name(parser, buffer);
7446e5b60fcSAmine Khaldi 
7456e5b60fcSAmine Khaldi         hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
7466e5b60fcSAmine Khaldi         ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
7476e5b60fcSAmine Khaldi 
7486e5b60fcSAmine Khaldi         VariantInit(&var);
7496e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
7506e5b60fcSAmine Khaldi         if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
7516e5b60fcSAmine Khaldi         {
7526e5b60fcSAmine Khaldi             IPropertyBag_Release(prop_bag);
7536e5b60fcSAmine Khaldi             IMoniker_Release(mon);
7546e5b60fcSAmine Khaldi 
7556e5b60fcSAmine Khaldi             /* Win8+ uses the endpoint GUID instead of the device name */
7566e5b60fcSAmine Khaldi             mmr = waveOutMessage((HWAVEOUT)(DWORD_PTR) i, DRV_QUERYFUNCTIONINSTANCEID,
7576e5b60fcSAmine Khaldi                                  (DWORD_PTR) endpoint, sizeof(endpoint));
7586e5b60fcSAmine Khaldi             ok(!mmr, "waveOutMessage failed: %u\n", mmr);
7596e5b60fcSAmine Khaldi 
7606e5b60fcSAmine Khaldi             lstrcpyW(buffer, deviceW);
7616e5b60fcSAmine Khaldi             lstrcatW(buffer, cmW);
7626e5b60fcSAmine Khaldi             StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
7636e5b60fcSAmine Khaldi             lstrcatW(buffer, backslashW);
7646e5b60fcSAmine Khaldi             lstrcatW(buffer, waveW);
7656e5b60fcSAmine Khaldi             lstrcatW(buffer, strchrW(endpoint, '}') + 2);
7666e5b60fcSAmine Khaldi 
7676e5b60fcSAmine Khaldi             mon = check_display_name(parser, buffer);
7686e5b60fcSAmine Khaldi 
7696e5b60fcSAmine Khaldi             hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
7706e5b60fcSAmine Khaldi             ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
7716e5b60fcSAmine Khaldi 
7726e5b60fcSAmine Khaldi             hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
7736e5b60fcSAmine Khaldi         }
7746e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
7756e5b60fcSAmine Khaldi 
7766e5b60fcSAmine Khaldi         ok(!strncmpW(name, V_BSTR(&var), lstrlenW(name)), "expected %s, got %s\n",
7776e5b60fcSAmine Khaldi             wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
7786e5b60fcSAmine Khaldi 
7796e5b60fcSAmine Khaldi         VariantClear(&var);
7806e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
7816e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
7826e5b60fcSAmine Khaldi 
7836e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AudioRender, buffer, CHARS_IN_GUID);
7846e5b60fcSAmine Khaldi         ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
7856e5b60fcSAmine Khaldi             wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
7866e5b60fcSAmine Khaldi 
7876e5b60fcSAmine Khaldi         VariantClear(&var);
7886e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, waveoutidW, &var, NULL);
7896e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
7906e5b60fcSAmine Khaldi 
7916e5b60fcSAmine Khaldi         ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var));
7926e5b60fcSAmine Khaldi 
7936e5b60fcSAmine Khaldi         IPropertyBag_Release(prop_bag);
7946e5b60fcSAmine Khaldi         IMoniker_Release(mon);
7956e5b60fcSAmine Khaldi     }
7966e5b60fcSAmine Khaldi 
7976e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
7986e5b60fcSAmine Khaldi }
7996e5b60fcSAmine Khaldi 
test_wavein(void)8006e5b60fcSAmine Khaldi static void test_wavein(void)
8016e5b60fcSAmine Khaldi {
8026e5b60fcSAmine Khaldi     static const WCHAR waveinidW[] = {'W','a','v','e','I','n','I','d',0};
8036e5b60fcSAmine Khaldi     IParseDisplayName *parser;
8046e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
8056e5b60fcSAmine Khaldi     IMoniker *mon;
8066e5b60fcSAmine Khaldi     WCHAR endpoint[200];
8076e5b60fcSAmine Khaldi     WCHAR buffer[200];
8086e5b60fcSAmine Khaldi     WAVEINCAPSW caps;
8096e5b60fcSAmine Khaldi     MMRESULT mmr;
8106e5b60fcSAmine Khaldi     int count, i;
8116e5b60fcSAmine Khaldi     VARIANT var;
8126e5b60fcSAmine Khaldi     HRESULT hr;
8136e5b60fcSAmine Khaldi 
8146e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
8156e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
8166e5b60fcSAmine Khaldi 
8176e5b60fcSAmine Khaldi     count = waveInGetNumDevs();
8186e5b60fcSAmine Khaldi 
8196e5b60fcSAmine Khaldi     for (i = 0; i < count; i++)
8206e5b60fcSAmine Khaldi     {
8216e5b60fcSAmine Khaldi         waveInGetDevCapsW(i, &caps, sizeof(caps));
8226e5b60fcSAmine Khaldi 
8236e5b60fcSAmine Khaldi         lstrcpyW(buffer, deviceW);
8246e5b60fcSAmine Khaldi         lstrcatW(buffer, cmW);
8256e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
8266e5b60fcSAmine Khaldi         lstrcatW(buffer, backslashW);
8276e5b60fcSAmine Khaldi         lstrcatW(buffer, caps.szPname);
8286e5b60fcSAmine Khaldi 
8296e5b60fcSAmine Khaldi         mon = check_display_name(parser, buffer);
8306e5b60fcSAmine Khaldi 
8316e5b60fcSAmine Khaldi         hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
8326e5b60fcSAmine Khaldi         ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
8336e5b60fcSAmine Khaldi 
8346e5b60fcSAmine Khaldi         VariantInit(&var);
8356e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
8366e5b60fcSAmine Khaldi         if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
8376e5b60fcSAmine Khaldi         {
8386e5b60fcSAmine Khaldi             IPropertyBag_Release(prop_bag);
8396e5b60fcSAmine Khaldi             IMoniker_Release(mon);
8406e5b60fcSAmine Khaldi 
8416e5b60fcSAmine Khaldi             /* Win8+ uses the endpoint GUID instead of the device name */
8426e5b60fcSAmine Khaldi             mmr = waveInMessage((HWAVEIN)(DWORD_PTR) i, DRV_QUERYFUNCTIONINSTANCEID,
8436e5b60fcSAmine Khaldi                                 (DWORD_PTR) endpoint, sizeof(endpoint));
8446e5b60fcSAmine Khaldi             ok(!mmr, "waveInMessage failed: %u\n", mmr);
8456e5b60fcSAmine Khaldi 
8466e5b60fcSAmine Khaldi             lstrcpyW(buffer, deviceW);
8476e5b60fcSAmine Khaldi             lstrcatW(buffer, cmW);
8486e5b60fcSAmine Khaldi             StringFromGUID2(&CLSID_AudioInputDeviceCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
8496e5b60fcSAmine Khaldi             lstrcatW(buffer, backslashW);
8506e5b60fcSAmine Khaldi             lstrcatW(buffer, waveW);
8516e5b60fcSAmine Khaldi             lstrcatW(buffer, strchrW(endpoint, '}') + 2);
8526e5b60fcSAmine Khaldi 
8536e5b60fcSAmine Khaldi             mon = check_display_name(parser, buffer);
8546e5b60fcSAmine Khaldi 
8556e5b60fcSAmine Khaldi             hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
8566e5b60fcSAmine Khaldi             ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
8576e5b60fcSAmine Khaldi 
8586e5b60fcSAmine Khaldi             hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
8596e5b60fcSAmine Khaldi         }
8606e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
8616e5b60fcSAmine Khaldi 
8626e5b60fcSAmine Khaldi         ok(!strncmpW(caps.szPname, V_BSTR(&var), lstrlenW(caps.szPname)), "expected %s, got %s\n",
8636e5b60fcSAmine Khaldi             wine_dbgstr_w(caps.szPname), wine_dbgstr_w(V_BSTR(&var)));
8646e5b60fcSAmine Khaldi 
8656e5b60fcSAmine Khaldi         VariantClear(&var);
8666e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
8676e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
8686e5b60fcSAmine Khaldi 
8696e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AudioRecord, buffer, CHARS_IN_GUID);
8706e5b60fcSAmine Khaldi         ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
8716e5b60fcSAmine Khaldi             wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
8726e5b60fcSAmine Khaldi 
8736e5b60fcSAmine Khaldi         VariantClear(&var);
8746e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, waveinidW, &var, NULL);
8756e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
8766e5b60fcSAmine Khaldi 
8776e5b60fcSAmine Khaldi         ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var));
8786e5b60fcSAmine Khaldi 
8796e5b60fcSAmine Khaldi         IPropertyBag_Release(prop_bag);
8806e5b60fcSAmine Khaldi         IMoniker_Release(mon);
8816e5b60fcSAmine Khaldi     }
8826e5b60fcSAmine Khaldi 
8836e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
8846e5b60fcSAmine Khaldi }
8856e5b60fcSAmine Khaldi 
test_midiout(void)8866e5b60fcSAmine Khaldi static void test_midiout(void)
8876e5b60fcSAmine Khaldi {
8886e5b60fcSAmine Khaldi     static const WCHAR defaultW[] = {'D','e','f','a','u','l','t',' ','M','i','d','i','O','u','t',' ','D','e','v','i','c','e',0};
8896e5b60fcSAmine Khaldi     static const WCHAR midioutidW[] = {'M','i','d','i','O','u','t','I','d',0};
8906e5b60fcSAmine Khaldi     IParseDisplayName *parser;
8916e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
8926e5b60fcSAmine Khaldi     IMoniker *mon;
8936e5b60fcSAmine Khaldi     MIDIOUTCAPSW caps;
8946e5b60fcSAmine Khaldi     WCHAR buffer[200];
8956e5b60fcSAmine Khaldi     const WCHAR *name;
8966e5b60fcSAmine Khaldi     int count, i;
8976e5b60fcSAmine Khaldi     VARIANT var;
8986e5b60fcSAmine Khaldi     HRESULT hr;
8996e5b60fcSAmine Khaldi 
9006e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
9016e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
9026e5b60fcSAmine Khaldi 
9036e5b60fcSAmine Khaldi     count = midiOutGetNumDevs();
9046e5b60fcSAmine Khaldi 
9056e5b60fcSAmine Khaldi     for (i = -1; i < count; i++)
9066e5b60fcSAmine Khaldi     {
9076e5b60fcSAmine Khaldi         midiOutGetDevCapsW(i, &caps, sizeof(caps));
9086e5b60fcSAmine Khaldi 
9096e5b60fcSAmine Khaldi         if (i == -1)    /* MIDI_MAPPER */
9106e5b60fcSAmine Khaldi             name = defaultW;
9116e5b60fcSAmine Khaldi         else
9126e5b60fcSAmine Khaldi             name = caps.szPname;
9136e5b60fcSAmine Khaldi 
9146e5b60fcSAmine Khaldi         lstrcpyW(buffer, deviceW);
9156e5b60fcSAmine Khaldi         lstrcatW(buffer, cmW);
9166e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_MidiRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
9176e5b60fcSAmine Khaldi         lstrcatW(buffer, backslashW);
9186e5b60fcSAmine Khaldi         lstrcatW(buffer, name);
9196e5b60fcSAmine Khaldi 
9206e5b60fcSAmine Khaldi         mon = check_display_name(parser, buffer);
9216e5b60fcSAmine Khaldi 
9226e5b60fcSAmine Khaldi         hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
9236e5b60fcSAmine Khaldi         ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
9246e5b60fcSAmine Khaldi 
9256e5b60fcSAmine Khaldi         VariantInit(&var);
9266e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
9276e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
9286e5b60fcSAmine Khaldi 
9296e5b60fcSAmine Khaldi         ok(!lstrcmpW(name, V_BSTR(&var)), "expected %s, got %s\n",
9306e5b60fcSAmine Khaldi             wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
9316e5b60fcSAmine Khaldi 
9326e5b60fcSAmine Khaldi         VariantClear(&var);
9336e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
9346e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
9356e5b60fcSAmine Khaldi 
9366e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AVIMIDIRender, buffer, CHARS_IN_GUID);
9376e5b60fcSAmine Khaldi         ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
9386e5b60fcSAmine Khaldi             wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
9396e5b60fcSAmine Khaldi 
9406e5b60fcSAmine Khaldi         VariantClear(&var);
9416e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, midioutidW, &var, NULL);
9426e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
9436e5b60fcSAmine Khaldi 
9446e5b60fcSAmine Khaldi         ok(V_I4(&var) == i, "expected %d, got %d\n", i, V_I4(&var));
9456e5b60fcSAmine Khaldi 
9466e5b60fcSAmine Khaldi         IPropertyBag_Release(prop_bag);
9476e5b60fcSAmine Khaldi         IMoniker_Release(mon);
9486e5b60fcSAmine Khaldi     }
9496e5b60fcSAmine Khaldi 
9506e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
9516e5b60fcSAmine Khaldi }
9526e5b60fcSAmine Khaldi 
test_vfw(void)9536e5b60fcSAmine Khaldi static void test_vfw(void)
9546e5b60fcSAmine Khaldi {
9556e5b60fcSAmine Khaldi     static const WCHAR fcchandlerW[] = {'F','c','c','H','a','n','d','l','e','r',0};
9566e5b60fcSAmine Khaldi     IParseDisplayName *parser;
9576e5b60fcSAmine Khaldi     IPropertyBag *prop_bag;
9586e5b60fcSAmine Khaldi     IMoniker *mon;
9596e5b60fcSAmine Khaldi     WCHAR buffer[200];
9606e5b60fcSAmine Khaldi     ICINFO info;
9616e5b60fcSAmine Khaldi     VARIANT var;
9626e5b60fcSAmine Khaldi     HRESULT hr;
9636e5b60fcSAmine Khaldi     int i = 0;
9646e5b60fcSAmine Khaldi     HIC hic;
9656e5b60fcSAmine Khaldi 
9666e5b60fcSAmine Khaldi     if (broken(sizeof(void *) == 8))
9676e5b60fcSAmine Khaldi     {
9686e5b60fcSAmine Khaldi         win_skip("VFW codecs are not enumerated on 64-bit Windows\n");
9696e5b60fcSAmine Khaldi         return;
9706e5b60fcSAmine Khaldi     }
9716e5b60fcSAmine Khaldi 
9726e5b60fcSAmine Khaldi     hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
9736e5b60fcSAmine Khaldi     ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
9746e5b60fcSAmine Khaldi 
9756e5b60fcSAmine Khaldi     while (ICInfo(ICTYPE_VIDEO, i++, &info))
9766e5b60fcSAmine Khaldi     {
9776e5b60fcSAmine Khaldi         WCHAR name[5] = {LOBYTE(LOWORD(info.fccHandler)), HIBYTE(LOWORD(info.fccHandler)),
9786e5b60fcSAmine Khaldi                          LOBYTE(HIWORD(info.fccHandler)), HIBYTE(HIWORD(info.fccHandler))};
9796e5b60fcSAmine Khaldi 
9806e5b60fcSAmine Khaldi         hic = ICOpen(ICTYPE_VIDEO, info.fccHandler, ICMODE_QUERY);
9816e5b60fcSAmine Khaldi         ICGetInfo(hic, &info, sizeof(info));
9826e5b60fcSAmine Khaldi         ICClose(hic);
9836e5b60fcSAmine Khaldi 
9846e5b60fcSAmine Khaldi         lstrcpyW(buffer, deviceW);
9856e5b60fcSAmine Khaldi         lstrcatW(buffer, cmW);
9866e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_VideoCompressorCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
9876e5b60fcSAmine Khaldi         lstrcatW(buffer, backslashW);
9886e5b60fcSAmine Khaldi         lstrcatW(buffer, name);
9896e5b60fcSAmine Khaldi 
9906e5b60fcSAmine Khaldi         mon = check_display_name(parser, buffer);
9916e5b60fcSAmine Khaldi 
9926e5b60fcSAmine Khaldi         hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
9936e5b60fcSAmine Khaldi         ok(hr == S_OK, "BindToStorage failed: %#x\n", hr);
9946e5b60fcSAmine Khaldi 
9956e5b60fcSAmine Khaldi         VariantInit(&var);
9966e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
9976e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
9986e5b60fcSAmine Khaldi 
9996e5b60fcSAmine Khaldi         ok(!lstrcmpW(info.szDescription, V_BSTR(&var)), "expected %s, got %s\n",
10006e5b60fcSAmine Khaldi             wine_dbgstr_w(info.szDescription), wine_dbgstr_w(V_BSTR(&var)));
10016e5b60fcSAmine Khaldi 
10026e5b60fcSAmine Khaldi         VariantClear(&var);
10036e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
10046e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
10056e5b60fcSAmine Khaldi 
10066e5b60fcSAmine Khaldi         StringFromGUID2(&CLSID_AVICo, buffer, CHARS_IN_GUID);
10076e5b60fcSAmine Khaldi         ok(!lstrcmpW(buffer, V_BSTR(&var)), "expected %s, got %s\n",
10086e5b60fcSAmine Khaldi             wine_dbgstr_w(buffer), wine_dbgstr_w(V_BSTR(&var)));
10096e5b60fcSAmine Khaldi 
10106e5b60fcSAmine Khaldi         VariantClear(&var);
10116e5b60fcSAmine Khaldi         hr = IPropertyBag_Read(prop_bag, fcchandlerW, &var, NULL);
10126e5b60fcSAmine Khaldi         ok(hr == S_OK, "Read failed: %#x\n", hr);
10136e5b60fcSAmine Khaldi         ok(!lstrcmpW(name, V_BSTR(&var)), "expected %s, got %s\n",
10146e5b60fcSAmine Khaldi             wine_dbgstr_w(name), wine_dbgstr_w(V_BSTR(&var)));
10156e5b60fcSAmine Khaldi 
1016*8cc0d363SAmine Khaldi         VariantClear(&var);
10176e5b60fcSAmine Khaldi         IPropertyBag_Release(prop_bag);
10186e5b60fcSAmine Khaldi         IMoniker_Release(mon);
10196e5b60fcSAmine Khaldi     }
10206e5b60fcSAmine Khaldi 
10216e5b60fcSAmine Khaldi     IParseDisplayName_Release(parser);
10226e5b60fcSAmine Khaldi }
1023c2c66affSColin Finck 
START_TEST(devenum)1024c2c66affSColin Finck START_TEST(devenum)
1025c2c66affSColin Finck {
1026c2c66affSColin Finck     IBindCtx *bind_ctx = NULL;
1027c2c66affSColin Finck     HRESULT hr;
1028c2c66affSColin Finck 
1029c2c66affSColin Finck     CoInitialize(NULL);
1030c2c66affSColin Finck 
1031c2c66affSColin Finck     test_devenum(NULL);
1032c2c66affSColin Finck 
1033c2c66affSColin Finck     /* IBindCtx is allowed in IMoniker_BindToStorage (IMediaCatMoniker_BindToStorage) */
1034c2c66affSColin Finck     hr = CreateBindCtx(0, &bind_ctx);
1035c2c66affSColin Finck     ok(hr == S_OK, "Cannot create BindCtx: (res = 0x%x)\n", hr);
1036c2c66affSColin Finck     if (bind_ctx) {
1037c2c66affSColin Finck         test_devenum(bind_ctx);
1038c2c66affSColin Finck         IBindCtx_Release(bind_ctx);
1039c2c66affSColin Finck     }
1040c2c66affSColin Finck 
1041c2c66affSColin Finck     test_moniker_isequal();
10426e5b60fcSAmine Khaldi     test_register_filter();
10436e5b60fcSAmine Khaldi     test_directshow_filter();
10446e5b60fcSAmine Khaldi     test_codec();
1045*8cc0d363SAmine Khaldi     test_dmo();
10466e5b60fcSAmine Khaldi 
10476e5b60fcSAmine Khaldi     test_legacy_filter();
10486e5b60fcSAmine Khaldi     hr = DirectSoundEnumerateW(test_dsound, NULL);
10496e5b60fcSAmine Khaldi     ok(hr == S_OK, "got %#x\n", hr);
10506e5b60fcSAmine Khaldi     test_waveout();
10516e5b60fcSAmine Khaldi     test_wavein();
10526e5b60fcSAmine Khaldi     test_midiout();
10536e5b60fcSAmine Khaldi     test_vfw();
1054c2c66affSColin Finck 
1055c2c66affSColin Finck     CoUninitialize();
1056c2c66affSColin Finck }
1057