5a41183655ab9e2363da9fe40eaac41a1161d381
[reactos.git] / modules / rostests / winetests / devenum / devenum.c
1 /*
2 * Some unit tests for devenum
3 *
4 * Copyright (C) 2012 Christian Costa
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21 #define COBJMACROS
22
23 #include <stdio.h>
24
25 #include "wine/test.h"
26 #include "initguid.h"
27 #include "ole2.h"
28 #include "strmif.h"
29 #include "uuids.h"
30
31 static const WCHAR friendly_name[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
32 static const WCHAR fcc_handlerW[] = {'F','c','c','H','a','n','d','l','e','r',0};
33 static const WCHAR mrleW[] = {'m','r','l','e',0};
34
35 struct category
36 {
37 const char * name;
38 const GUID * clsid;
39 };
40
41 static struct category am_categories[] =
42 {
43 { "Legacy AM Filter category", &CLSID_LegacyAmFilterCategory },
44 { "Audio renderer category", &CLSID_AudioRendererCategory },
45 { "Midi renderer category", &CLSID_MidiRendererCategory },
46 { "Audio input device category", &CLSID_AudioInputDeviceCategory },
47 { "Video input device category", &CLSID_VideoInputDeviceCategory },
48 { "Audio compressor category", &CLSID_AudioCompressorCategory },
49 { "Video compressor category", &CLSID_VideoCompressorCategory }
50 };
51
52 static void test_devenum(IBindCtx *bind_ctx)
53 {
54 HRESULT res;
55 ICreateDevEnum* create_devenum;
56 IEnumMoniker* enum_moniker = NULL;
57 BOOL have_mrle = FALSE;
58 int i;
59
60 res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
61 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
62 if (res != S_OK) {
63 skip("Cannot create SystemDeviceEnum object (%x)\n", res);
64 return;
65 }
66
67 for (i = 0; i < (sizeof(am_categories) / sizeof(struct category)); i++)
68 {
69 if (winetest_debug > 1)
70 trace("%s:\n", am_categories[i].name);
71
72 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, am_categories[i].clsid, &enum_moniker, 0);
73 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
74 if (res == S_OK)
75 {
76 IMoniker* moniker;
77 while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK)
78 {
79 IPropertyBag* prop_bag = NULL;
80 VARIANT var;
81 HRESULT hr;
82 CLSID clsid = {0};
83
84 hr = IMoniker_GetClassID(moniker, NULL);
85 ok(hr == E_INVALIDARG, "IMoniker_GetClassID should failed %x\n", hr);
86
87 hr = IMoniker_GetClassID(moniker, &clsid);
88 ok(hr == S_OK, "IMoniker_GetClassID failed with error %x\n", hr);
89 ok(IsEqualGUID(&clsid, &CLSID_CDeviceMoniker),
90 "Expected CLSID_CDeviceMoniker got %s\n", wine_dbgstr_guid(&clsid));
91
92 VariantInit(&var);
93 hr = IMoniker_BindToStorage(moniker, bind_ctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
94 ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr);
95
96 if (SUCCEEDED(hr))
97 {
98 hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
99 ok((hr == S_OK) || broken(hr == 0x80070002), "IPropertyBag_Read failed with error %x\n", hr);
100
101 if (SUCCEEDED(hr))
102 {
103 if (winetest_debug > 1)
104 trace(" %s\n", wine_dbgstr_w(V_BSTR(&var)));
105 VariantClear(&var);
106 }
107 else
108 {
109 trace(" ???\n");
110 }
111
112 if (IsEqualGUID(&CLSID_VideoCompressorCategory, am_categories[i].clsid)) {
113 /* Test well known compressor to ensure that we really enumerate codecs */
114 hr = IPropertyBag_Read(prop_bag, fcc_handlerW, &var, NULL);
115 if (SUCCEEDED(hr)) {
116 ok(V_VT(&var) == VT_BSTR, "V_VT(var) = %d\n", V_VT(&var));
117 if(!lstrcmpW(V_BSTR(&var), mrleW))
118 have_mrle = TRUE;
119 VariantClear(&var);
120 }
121 }
122 }
123
124 if (prop_bag)
125 IPropertyBag_Release(prop_bag);
126 IMoniker_Release(moniker);
127 }
128 IEnumMoniker_Release(enum_moniker);
129 }
130 }
131
132 ICreateDevEnum_Release(create_devenum);
133
134 /* 64-bit windows are missing mrle codec */
135 if(sizeof(void*) == 4)
136 ok(have_mrle, "mrle codec not found\n");
137 }
138 static void test_moniker_isequal(void)
139 {
140 HRESULT res;
141 ICreateDevEnum *create_devenum = NULL;
142 IEnumMoniker *enum_moniker0 = NULL, *enum_moniker1 = NULL;
143 IMoniker *moniker0 = NULL, *moniker1 = NULL;
144
145 res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
146 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
147 if (FAILED(res))
148 {
149 skip("Cannot create SystemDeviceEnum object (%x)\n", res);
150 return;
151 }
152
153 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
154 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
155 if (SUCCEEDED(res))
156 {
157 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
158 IEnumMoniker_Next(enum_moniker0, 1, &moniker1, NULL) == S_OK)
159 {
160 res = IMoniker_IsEqual(moniker0, moniker1);
161 ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
162
163 res = IMoniker_IsEqual(moniker1, moniker0);
164 ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
165
166 IMoniker_Release(moniker0);
167 IMoniker_Release(moniker1);
168 }
169 else
170 skip("Cannot get moniker for testing.\n");
171 }
172 IEnumMoniker_Release(enum_moniker0);
173
174 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
175 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
176 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_AudioRendererCategory, &enum_moniker1, 0);
177 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
178 if (SUCCEEDED(res))
179 {
180 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
181 IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
182 {
183 res = IMoniker_IsEqual(moniker0, moniker1);
184 ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
185
186 res = IMoniker_IsEqual(moniker1, moniker0);
187 ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
188
189 IMoniker_Release(moniker0);
190 IMoniker_Release(moniker1);
191 }
192 else
193 skip("Cannot get moniker for testing.\n");
194 }
195 IEnumMoniker_Release(enum_moniker0);
196 IEnumMoniker_Release(enum_moniker1);
197
198 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
199 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
200 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker1, 0);
201 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
202 if (SUCCEEDED(res))
203 {
204 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
205 IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
206 {
207 res = IMoniker_IsEqual(moniker0, moniker1);
208 ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
209
210 res = IMoniker_IsEqual(moniker1, moniker0);
211 ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
212
213 IMoniker_Release(moniker0);
214 IMoniker_Release(moniker1);
215 }
216 else
217 skip("Cannot get moniker for testing.\n");
218 }
219 IEnumMoniker_Release(enum_moniker0);
220 IEnumMoniker_Release(enum_moniker1);
221
222 ICreateDevEnum_Release(create_devenum);
223
224 return;
225 }
226
227 /* CLSID_CDeviceMoniker */
228
229 START_TEST(devenum)
230 {
231 IBindCtx *bind_ctx = NULL;
232 HRESULT hr;
233
234 CoInitialize(NULL);
235
236 test_devenum(NULL);
237
238 /* IBindCtx is allowed in IMoniker_BindToStorage (IMediaCatMoniker_BindToStorage) */
239 hr = CreateBindCtx(0, &bind_ctx);
240 ok(hr == S_OK, "Cannot create BindCtx: (res = 0x%x)\n", hr);
241 if (bind_ctx) {
242 test_devenum(bind_ctx);
243 IBindCtx_Release(bind_ctx);
244 }
245
246 test_moniker_isequal();
247
248 CoUninitialize();
249 }