[DEVENUM_WINETEST]
[reactos.git] / 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 WIN32_NO_STATUS
22 #define _INC_WINDOWS
23 #define COM_NO_WINDOWS_H
24
25 #define COBJMACROS
26
27 //#include <stdio.h>
28
29 #include <wine/test.h>
30 #include <wingdi.h>
31 #include <initguid.h>
32 #include <ole2.h>
33 #include <strmif.h>
34 #include <uuids.h>
35
36 static const WCHAR friendly_name[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
37 static const WCHAR fcc_handlerW[] = {'F','c','c','H','a','n','d','l','e','r',0};
38 static const WCHAR mrleW[] = {'m','r','l','e',0};
39
40 struct category
41 {
42 const char * name;
43 const GUID * clsid;
44 };
45
46 static struct category am_categories[] =
47 {
48 { "Legacy AM Filter category", &CLSID_LegacyAmFilterCategory },
49 { "Audio renderer category", &CLSID_AudioRendererCategory },
50 { "Midi renderer category", &CLSID_MidiRendererCategory },
51 { "Audio input device category", &CLSID_AudioInputDeviceCategory },
52 { "Video input device category", &CLSID_VideoInputDeviceCategory },
53 { "Audio compressor category", &CLSID_AudioCompressorCategory },
54 { "Video compressor category", &CLSID_VideoCompressorCategory }
55 };
56
57 static void test_devenum(IBindCtx *bind_ctx)
58 {
59 HRESULT res;
60 ICreateDevEnum* create_devenum;
61 IEnumMoniker* enum_moniker = NULL;
62 BOOL have_mrle = FALSE;
63 int i;
64
65 res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
66 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
67 if (res != S_OK) {
68 skip("Cannot create SystemDeviceEnum object (%x)\n", res);
69 return;
70 }
71
72 for (i = 0; i < (sizeof(am_categories) / sizeof(struct category)); i++)
73 {
74 if (winetest_debug > 1)
75 trace("%s:\n", am_categories[i].name);
76
77 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, am_categories[i].clsid, &enum_moniker, 0);
78 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
79 if (res == S_OK)
80 {
81 IMoniker* moniker;
82 while (IEnumMoniker_Next(enum_moniker, 1, &moniker, NULL) == S_OK)
83 {
84 IPropertyBag* prop_bag = NULL;
85 VARIANT var;
86 HRESULT hr;
87 CLSID clsid = {0};
88
89 hr = IMoniker_GetClassID(moniker, NULL);
90 ok(hr == E_INVALIDARG, "IMoniker_GetClassID should failed %x\n", hr);
91
92 hr = IMoniker_GetClassID(moniker, &clsid);
93 ok(hr == S_OK, "IMoniker_GetClassID failed with error %x\n", hr);
94 ok(IsEqualGUID(&clsid, &CLSID_CDeviceMoniker),
95 "Expected CLSID_CDeviceMoniker got %s\n", wine_dbgstr_guid(&clsid));
96
97 VariantInit(&var);
98 hr = IMoniker_BindToStorage(moniker, bind_ctx, NULL, &IID_IPropertyBag, (LPVOID*)&prop_bag);
99 ok(hr == S_OK, "IMoniker_BindToStorage failed with error %x\n", hr);
100
101 if (SUCCEEDED(hr))
102 {
103 hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
104 ok((hr == S_OK) || broken(hr == 0x80070002), "IPropertyBag_Read failed with error %x\n", hr);
105
106 if (SUCCEEDED(hr))
107 {
108 if (winetest_debug > 1)
109 trace(" %s\n", wine_dbgstr_w(V_BSTR(&var)));
110 VariantClear(&var);
111 }
112 else
113 {
114 trace(" ???\n");
115 }
116
117 if (IsEqualGUID(&CLSID_VideoCompressorCategory, am_categories[i].clsid)) {
118 /* Test well known compressor to ensure that we really enumerate codecs */
119 hr = IPropertyBag_Read(prop_bag, fcc_handlerW, &var, NULL);
120 if (SUCCEEDED(hr)) {
121 ok(V_VT(&var) == VT_BSTR, "V_VT(var) = %d\n", V_VT(&var));
122 if(!lstrcmpW(V_BSTR(&var), mrleW))
123 have_mrle = TRUE;
124 VariantClear(&var);
125 }
126 }
127 }
128
129 if (prop_bag)
130 IPropertyBag_Release(prop_bag);
131 IMoniker_Release(moniker);
132 }
133 IEnumMoniker_Release(enum_moniker);
134 }
135 }
136
137 ICreateDevEnum_Release(create_devenum);
138
139 /* 64-bit windows are missing mrle codec */
140 if(sizeof(void*) == 4)
141 ok(have_mrle, "mrle codec not found\n");
142 }
143 static void test_moniker_isequal(void)
144 {
145 HRESULT res;
146 ICreateDevEnum *create_devenum = NULL;
147 IEnumMoniker *enum_moniker0 = NULL, *enum_moniker1 = NULL;
148 IMoniker *moniker0 = NULL, *moniker1 = NULL;
149
150 res = CoCreateInstance(&CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC,
151 &IID_ICreateDevEnum, (LPVOID*)&create_devenum);
152 if (FAILED(res))
153 {
154 skip("Cannot create SystemDeviceEnum object (%x)\n", res);
155 return;
156 }
157
158 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
159 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
160 if (SUCCEEDED(res))
161 {
162 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
163 IEnumMoniker_Next(enum_moniker0, 1, &moniker1, NULL) == S_OK)
164 {
165 res = IMoniker_IsEqual(moniker0, moniker1);
166 ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
167
168 res = IMoniker_IsEqual(moniker1, moniker0);
169 ok(res == S_FALSE, "IMoniker_IsEqual should fail (res = %x)\n", res);
170
171 IMoniker_Release(moniker0);
172 IMoniker_Release(moniker1);
173 }
174 else
175 skip("Cannot get moniker for testing.\n");
176 }
177 IEnumMoniker_Release(enum_moniker0);
178
179 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
180 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
181 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_AudioRendererCategory, &enum_moniker1, 0);
182 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
183 if (SUCCEEDED(res))
184 {
185 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
186 IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
187 {
188 res = IMoniker_IsEqual(moniker0, moniker1);
189 ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
190
191 res = IMoniker_IsEqual(moniker1, moniker0);
192 ok(res == S_FALSE, "IMoniker_IsEqual should failed (res = %x)\n", res);
193
194 IMoniker_Release(moniker0);
195 IMoniker_Release(moniker1);
196 }
197 else
198 skip("Cannot get moniker for testing.\n");
199 }
200 IEnumMoniker_Release(enum_moniker0);
201 IEnumMoniker_Release(enum_moniker1);
202
203 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker0, 0);
204 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
205 res = ICreateDevEnum_CreateClassEnumerator(create_devenum, &CLSID_LegacyAmFilterCategory, &enum_moniker1, 0);
206 ok(SUCCEEDED(res), "Cannot create enum moniker (res = %x)\n", res);
207 if (SUCCEEDED(res))
208 {
209 if (IEnumMoniker_Next(enum_moniker0, 1, &moniker0, NULL) == S_OK &&
210 IEnumMoniker_Next(enum_moniker1, 1, &moniker1, NULL) == S_OK)
211 {
212 res = IMoniker_IsEqual(moniker0, moniker1);
213 ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
214
215 res = IMoniker_IsEqual(moniker1, moniker0);
216 ok(res == S_OK, "IMoniker_IsEqual failed (res = %x)\n", res);
217
218 IMoniker_Release(moniker0);
219 IMoniker_Release(moniker1);
220 }
221 else
222 skip("Cannot get moniker for testing.\n");
223 }
224 IEnumMoniker_Release(enum_moniker0);
225 IEnumMoniker_Release(enum_moniker1);
226
227 ICreateDevEnum_Release(create_devenum);
228
229 return;
230 }
231
232 /* CLSID_CDeviceMoniker */
233
234 START_TEST(devenum)
235 {
236 IBindCtx *bind_ctx = NULL;
237 HRESULT hr;
238
239 CoInitialize(NULL);
240
241 test_devenum(NULL);
242
243 /* IBindCtx is allowed in IMoniker_BindToStorage (IMediaCatMoniker_BindToStorage) */
244 hr = CreateBindCtx(0, &bind_ctx);
245 ok(hr == S_OK, "Cannot create BindCtx: (res = 0x%x)\n", hr);
246 if (bind_ctx) {
247 test_devenum(bind_ctx);
248 IBindCtx_Release(bind_ctx);
249 }
250
251 test_moniker_isequal();
252
253 CoUninitialize();
254 }