Sync with trunk r43000
[reactos.git] / rostests / winetests / msacm32 / msacm.c
1 /*
2 * Unit tests for msacm functions
3 *
4 * Copyright (c) 2004 Robert Reif
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 #include <stdarg.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <math.h>
25
26 #include "wine/test.h"
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winnls.h"
30 #include "mmsystem.h"
31 #define NOBITMAP
32 #include "wine/mmreg.h"
33 #include "wine/msacm.h"
34
35 static BOOL CALLBACK FormatTagEnumProc(HACMDRIVERID hadid,
36 PACMFORMATTAGDETAILS paftd,
37 DWORD dwInstance,
38 DWORD fdwSupport)
39 {
40 if (winetest_interactive)
41 trace(" Format 0x%04x: %s\n", paftd->dwFormatTag, paftd->szFormatTag);
42
43 return TRUE;
44 }
45
46 static BOOL CALLBACK FormatEnumProc(HACMDRIVERID hadid,
47 LPACMFORMATDETAILS pafd,
48 DWORD dwInstance,
49 DWORD fd)
50 {
51 if (winetest_interactive)
52 trace(" 0x%04x, %s\n", pafd->dwFormatTag, pafd->szFormat);
53
54 return TRUE;
55 }
56
57 static BOOL CALLBACK DriverEnumProc(HACMDRIVERID hadid,
58 DWORD dwInstance,
59 DWORD fdwSupport)
60 {
61 MMRESULT rc;
62 ACMDRIVERDETAILSA dd;
63 HACMDRIVER had;
64
65 DWORD dwDriverPriority;
66 DWORD dwDriverSupport;
67
68 if (winetest_interactive) {
69 trace("id: %p\n", hadid);
70 trace(" Supports:\n");
71 if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC)
72 trace(" async conversions\n");
73 if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)
74 trace(" different format conversions\n");
75 if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER)
76 trace(" same format conversions\n");
77 if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER)
78 trace(" filtering\n");
79 }
80
81 /* try an invalid pointer */
82 rc = acmDriverDetails(hadid, 0, 0);
83 ok(rc == MMSYSERR_INVALPARAM,
84 "acmDriverDetails(): rc = %08x, should be %08x\n",
85 rc, MMSYSERR_INVALPARAM);
86
87 /* try an invalid structure size */
88 ZeroMemory(&dd, sizeof(dd));
89 rc = acmDriverDetails(hadid, &dd, 0);
90 ok(rc == MMSYSERR_INVALPARAM,
91 "acmDriverDetails(): rc = %08x, should be %08x\n",
92 rc, MMSYSERR_INVALPARAM);
93
94 /* MSDN says this should fail but it doesn't in practice */
95 dd.cbStruct = 4;
96 rc = acmDriverDetails(hadid, &dd, 0);
97 ok(rc == MMSYSERR_NOERROR,
98 "acmDriverDetails(): rc = %08x, should be %08x\n",
99 rc, MMSYSERR_NOERROR);
100
101 /* try an invalid handle */
102 dd.cbStruct = sizeof(dd);
103 rc = acmDriverDetails((HACMDRIVERID)1, &dd, 0);
104 ok(rc == MMSYSERR_INVALHANDLE,
105 "acmDriverDetails(): rc = %08x, should be %08x\n",
106 rc, MMSYSERR_INVALHANDLE);
107
108 /* try an invalid handle and pointer */
109 rc = acmDriverDetails((HACMDRIVERID)1, 0, 0);
110 ok(rc == MMSYSERR_INVALPARAM,
111 "acmDriverDetails(): rc = %08x, should be %08x\n",
112 rc, MMSYSERR_INVALPARAM);
113
114 /* try invalid details */
115 rc = acmDriverDetails(hadid, &dd, -1);
116 ok(rc == MMSYSERR_INVALFLAG,
117 "acmDriverDetails(): rc = %08x, should be %08x\n",
118 rc, MMSYSERR_INVALFLAG);
119
120 /* try valid parameters */
121 rc = acmDriverDetails(hadid, &dd, 0);
122 ok(rc == MMSYSERR_NOERROR,
123 "acmDriverDetails(): rc = %08x, should be %08x\n",
124 rc, MMSYSERR_NOERROR);
125
126 /* cbStruct should contain size of returned data (at most sizeof(dd))
127 TODO: should it be *exactly* sizeof(dd), as tested here?
128 */
129 if (rc == MMSYSERR_NOERROR) {
130 ok(dd.cbStruct == sizeof(dd),
131 "acmDriverDetails(): cbStruct = %08x, should be %08lx\n",
132 dd.cbStruct, (unsigned long)sizeof(dd));
133 }
134
135 if (rc == MMSYSERR_NOERROR && winetest_interactive) {
136 trace(" Short name: %s\n", dd.szShortName);
137 trace(" Long name: %s\n", dd.szLongName);
138 trace(" Copyright: %s\n", dd.szCopyright);
139 trace(" Licensing: %s\n", dd.szLicensing);
140 trace(" Features: %s\n", dd.szFeatures);
141 trace(" Supports %u formats\n", dd.cFormatTags);
142 trace(" Supports %u filter formats\n", dd.cFilterTags);
143 }
144
145 /* try bad pointer */
146 rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, 0);
147 ok(rc == MMSYSERR_INVALPARAM,
148 "acmMetrics(): rc = %08x, should be %08x\n",
149 rc, MMSYSERR_INVALPARAM);
150
151 /* try bad handle */
152 rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, &dwDriverPriority);
153 ok(rc == MMSYSERR_INVALHANDLE,
154 "acmMetrics(): rc = %08x, should be %08x\n",
155 rc, MMSYSERR_INVALHANDLE);
156
157 /* try bad pointer and handle */
158 rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_PRIORITY, 0);
159 ok(rc == MMSYSERR_INVALHANDLE,
160 "acmMetrics(): rc = %08x, should be %08x\n",
161 rc, MMSYSERR_INVALHANDLE);
162
163 /* try valid parameters */
164 rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_PRIORITY, &dwDriverSupport);
165 ok(rc == MMSYSERR_NOERROR,
166 "acmMetrics(): rc = %08x, should be %08x\n",
167 rc, MMSYSERR_NOERROR);
168
169 /* try bad pointer */
170 rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, 0);
171 ok(rc == MMSYSERR_INVALPARAM,
172 "acmMetrics(): rc = %08x, should be %08x\n",
173 rc, MMSYSERR_INVALPARAM);
174
175 /* try bad handle */
176 rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
177 ok(rc == MMSYSERR_INVALHANDLE,
178 "acmMetrics(): rc = %08x, should be %08x\n",
179 rc, MMSYSERR_INVALHANDLE);
180
181 /* try bad pointer and handle */
182 rc = acmMetrics((HACMOBJ)1, ACM_METRIC_DRIVER_SUPPORT, 0);
183 ok(rc == MMSYSERR_INVALHANDLE,
184 "acmMetrics(): rc = %08x, should be %08x\n",
185 rc, MMSYSERR_INVALHANDLE);
186
187 /* try valid parameters */
188 rc = acmMetrics((HACMOBJ)hadid, ACM_METRIC_DRIVER_SUPPORT, &dwDriverSupport);
189 ok(rc == MMSYSERR_NOERROR,
190 "acmMetrics(): rc = %08x, should be %08x\n",
191 rc, MMSYSERR_NOERROR);
192
193 /* try invalid pointer */
194 rc = acmDriverOpen(0, hadid, 0);
195 ok(rc == MMSYSERR_INVALPARAM,
196 "acmDriverOpen(): rc = %08x, should be %08x\n",
197 rc, MMSYSERR_INVALPARAM);
198
199 /* try invalid handle */
200 rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0);
201 ok(rc == MMSYSERR_INVALHANDLE,
202 "acmDriverOpen(): rc = %08x, should be %08x\n",
203 rc, MMSYSERR_INVALHANDLE);
204
205 /* try invalid open */
206 rc = acmDriverOpen(&had, hadid, -1);
207 ok(rc == MMSYSERR_INVALFLAG,
208 "acmDriverOpen(): rc = %08x, should be %08x\n",
209 rc, MMSYSERR_INVALFLAG);
210
211 /* try valid parameters */
212 rc = acmDriverOpen(&had, hadid, 0);
213 ok(rc == MMSYSERR_NOERROR,
214 "acmDriverOpen(): rc = %08x, should be %08x\n",
215 rc, MMSYSERR_NOERROR);
216
217 if (rc == MMSYSERR_NOERROR) {
218 DWORD dwSize;
219 HACMDRIVERID hid;
220
221 /* try bad pointer */
222 rc = acmDriverID((HACMOBJ)had, 0, 0);
223 ok(rc == MMSYSERR_INVALPARAM,
224 "acmDriverID(): rc = %08x, should be %08x\n",
225 rc, MMSYSERR_INVALPARAM);
226
227 /* try bad handle */
228 rc = acmDriverID((HACMOBJ)1, &hid, 0);
229 ok(rc == MMSYSERR_INVALHANDLE,
230 "acmDriverID(): rc = %08x, should be %08x\n",
231 rc, MMSYSERR_INVALHANDLE);
232
233 /* try bad handle and pointer */
234 rc = acmDriverID((HACMOBJ)1, 0, 0);
235 ok(rc == MMSYSERR_INVALHANDLE,
236 "acmDriverID(): rc = %08x, should be %08x\n",
237 rc, MMSYSERR_INVALHANDLE);
238
239 /* try bad flag */
240 rc = acmDriverID((HACMOBJ)had, &hid, 1);
241 ok(rc == MMSYSERR_INVALFLAG,
242 "acmDriverID(): rc = %08x, should be %08x\n",
243 rc, MMSYSERR_INVALFLAG);
244
245 /* try valid parameters */
246 rc = acmDriverID((HACMOBJ)had, &hid, 0);
247 ok(rc == MMSYSERR_NOERROR,
248 "acmDriverID(): rc = %08x, should be %08x\n",
249 rc, MMSYSERR_NOERROR);
250 ok(hid == hadid,
251 "acmDriverID() returned ID %p doesn't equal %p\n",
252 hid, hadid);
253
254 /* try bad pointer */
255 rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0);
256 ok(rc == MMSYSERR_INVALPARAM,
257 "acmMetrics(): rc = %08x, should be %08x\n",
258 rc, MMSYSERR_INVALPARAM);
259
260 /* try bad handle */
261 rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
262 ok(rc == MMSYSERR_INVALHANDLE,
263 "acmMetrics(): rc = %08x, should be %08x\n",
264 rc, MMSYSERR_INVALHANDLE);
265
266 /* try bad pointer and handle */
267 rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0);
268 ok(rc == MMSYSERR_INVALHANDLE,
269 "acmMetrics(): rc = %08x, should be %08x\n",
270 rc, MMSYSERR_INVALHANDLE);
271
272 /* try valid parameters */
273 rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
274 ok(rc == MMSYSERR_NOERROR,
275 "acmMetrics(): rc = %08x, should be %08x\n",
276 rc, MMSYSERR_NOERROR);
277 if (rc == MMSYSERR_NOERROR) {
278 ACMFORMATDETAILSA fd;
279 WAVEFORMATEX * pwfx;
280 ACMFORMATTAGDETAILSA aftd;
281
282 /* try bad pointer */
283 rc = acmFormatEnum(had, 0, FormatEnumProc, 0, 0);
284 ok(rc == MMSYSERR_INVALPARAM,
285 "acmFormatEnum(): rc = %08x, should be %08x\n",
286 rc, MMSYSERR_INVALPARAM);
287
288 /* try bad structure size */
289 ZeroMemory(&fd, sizeof(fd));
290 rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
291 ok(rc == MMSYSERR_INVALPARAM,
292 "acmFormatEnum(): rc = %08x, should be %08x\n",
293 rc, MMSYSERR_INVALPARAM);
294
295 fd.cbStruct = sizeof(fd) - 1;
296 rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
297 ok(rc == MMSYSERR_INVALPARAM,
298 "acmFormatEnum(): rc = %08x, should be %08x\n",
299 rc, MMSYSERR_INVALPARAM);
300
301 if (dwSize < sizeof(WAVEFORMATEX))
302 dwSize = sizeof(WAVEFORMATEX);
303
304 pwfx = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
305
306 pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
307 pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN;
308
309 fd.cbStruct = sizeof(fd);
310 fd.pwfx = pwfx;
311 fd.cbwfx = dwSize;
312 fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
313
314 /* try valid parameters */
315 rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
316 ok(rc == MMSYSERR_NOERROR,
317 "acmFormatEnum(): rc = %08x, should be %08x\n",
318 rc, MMSYSERR_NOERROR);
319
320 /* try bad pointer */
321 rc = acmFormatTagEnum(had, 0, FormatTagEnumProc, 0, 0);
322 ok(rc == MMSYSERR_INVALPARAM,
323 "acmFormatTagEnum(): rc = %08x, should be %08x\n",
324 rc, MMSYSERR_INVALPARAM);
325
326 /* try bad structure size */
327 ZeroMemory(&aftd, sizeof(aftd));
328 rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
329 ok(rc == MMSYSERR_INVALPARAM,
330 "acmFormatTagEnum(): rc = %08x, should be %08x\n",
331 rc, MMSYSERR_INVALPARAM);
332
333 aftd.cbStruct = sizeof(aftd) - 1;
334 rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
335 ok(rc == MMSYSERR_INVALPARAM,
336 "acmFormatTagEnum(): rc = %08x, should be %08x\n",
337 rc, MMSYSERR_INVALPARAM);
338
339 aftd.cbStruct = sizeof(aftd);
340 aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
341
342 /* try bad flag */
343 rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 1);
344 ok(rc == MMSYSERR_INVALFLAG,
345 "acmFormatTagEnum(): rc = %08x, should be %08x\n",
346 rc, MMSYSERR_INVALFLAG);
347
348 /* try valid parameters */
349 rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
350 ok(rc == MMSYSERR_NOERROR,
351 "acmFormatTagEnum(): rc = %08x, should be %08x\n",
352 rc, MMSYSERR_NOERROR);
353
354 HeapFree(GetProcessHeap(), 0, pwfx);
355
356 /* try invalid handle */
357 rc = acmDriverClose((HACMDRIVER)1, 0);
358 ok(rc == MMSYSERR_INVALHANDLE,
359 "acmDriverClose(): rc = %08x, should be %08x\n",
360 rc, MMSYSERR_INVALHANDLE);
361
362 /* try invalid flag */
363 rc = acmDriverClose(had, 1);
364 ok(rc == MMSYSERR_INVALFLAG,
365 "acmDriverClose(): rc = %08x, should be %08x\n",
366 rc, MMSYSERR_INVALFLAG);
367
368 /* try valid parameters */
369 rc = acmDriverClose(had, 0);
370 ok(rc == MMSYSERR_NOERROR,
371 "acmDriverClose(): rc = %08x, should be %08x\n",
372 rc, MMSYSERR_NOERROR);
373
374 /* try closing again */
375 rc = acmDriverClose(had, 0);
376 ok(rc == MMSYSERR_INVALHANDLE,
377 "acmDriverClose(): rc = %08x, should be %08x\n",
378 rc, MMSYSERR_INVALHANDLE);
379 }
380 }
381
382 return TRUE;
383 }
384
385 static const char * get_metric(UINT uMetric)
386 {
387 switch (uMetric) {
388 case ACM_METRIC_COUNT_CODECS:
389 return "ACM_METRIC_COUNT_CODECS";
390 case ACM_METRIC_COUNT_CONVERTERS:
391 return "ACM_METRIC_COUNT_CONVERTERS";
392 case ACM_METRIC_COUNT_DISABLED:
393 return "ACM_METRIC_COUNT_DISABLED";
394 case ACM_METRIC_COUNT_DRIVERS:
395 return "ACM_METRIC_COUNT_DRIVERS";
396 case ACM_METRIC_COUNT_FILTERS:
397 return "ACM_METRIC_COUNT_FILTERS";
398 case ACM_METRIC_COUNT_HARDWARE:
399 return "ACM_METRIC_COUNT_HARDWARE";
400 case ACM_METRIC_COUNT_LOCAL_CODECS:
401 return "ACM_METRIC_COUNT_LOCAL_CODECS";
402 case ACM_METRIC_COUNT_LOCAL_CONVERTERS:
403 return "ACM_METRIC_COUNT_LOCAL_CONVERTERS";
404 case ACM_METRIC_COUNT_LOCAL_DISABLED:
405 return "ACM_METRIC_COUNT_LOCAL_DISABLED";
406 case ACM_METRIC_COUNT_LOCAL_DRIVERS:
407 return "ACM_METRIC_COUNT_LOCAL_DRIVERS";
408 case ACM_METRIC_COUNT_LOCAL_FILTERS:
409 return "ACM_METRIC_COUNT_LOCAL_FILTERS";
410 case ACM_METRIC_DRIVER_PRIORITY:
411 return "ACM_METRIC_DRIVER_PRIORITY";
412 case ACM_METRIC_DRIVER_SUPPORT:
413 return "ACM_METRIC_DRIVER_SUPPORT";
414 case ACM_METRIC_HARDWARE_WAVE_INPUT:
415 return "ACM_METRIC_HARDWARE_WAVE_INPUT";
416 case ACM_METRIC_HARDWARE_WAVE_OUTPUT:
417 return "ACM_METRIC_HARDWARE_WAVE_OUTPUT";
418 case ACM_METRIC_MAX_SIZE_FILTER:
419 return "ACM_METRIC_MAX_SIZE_FILTER";
420 case ACM_METRIC_MAX_SIZE_FORMAT:
421 return "ACM_METRIC_MAX_SIZE_FORMAT";
422 }
423
424 return "UNKNOWN";
425 }
426
427 static DWORD check_count(UINT uMetric)
428 {
429 DWORD dwMetric;
430 MMRESULT rc;
431
432 /* try invalid result pointer */
433 rc = acmMetrics(NULL, uMetric, 0);
434 ok(rc == MMSYSERR_INVALPARAM,
435 "acmMetrics(NULL, %s, 0): rc = 0x%08x, should be 0x%08x\n",
436 get_metric(uMetric), rc, MMSYSERR_INVALPARAM);
437
438 /* try invalid handle */
439 rc = acmMetrics((HACMOBJ)1, uMetric, &dwMetric);
440 ok(rc == MMSYSERR_INVALHANDLE,
441 "acmMetrics(1, %s, %p): rc = 0x%08x, should be 0x%08x\n",
442 get_metric(uMetric), &dwMetric, rc, MMSYSERR_INVALHANDLE);
443
444 /* try invalid result pointer and handle */
445 rc = acmMetrics((HACMOBJ)1, uMetric, 0);
446 ok(rc == MMSYSERR_INVALHANDLE,
447 "acmMetrics(1, %s, 0): rc = 0x%08x, should be 0x%08x\n",
448 get_metric(uMetric), rc, MMSYSERR_INVALHANDLE);
449
450 /* try valid parameters */
451 rc = acmMetrics(NULL, uMetric, &dwMetric);
452 ok(rc == MMSYSERR_NOERROR, "acmMetrics() failed: rc = 0x%08x\n", rc);
453
454 if (rc == MMSYSERR_NOERROR && winetest_interactive)
455 trace("%s: %u\n", get_metric(uMetric), dwMetric);
456
457 return dwMetric;
458 }
459
460 static void msacm_tests(void)
461 {
462 MMRESULT rc;
463 DWORD dwCount;
464 DWORD dwACMVersion = acmGetVersion();
465
466 if (winetest_interactive) {
467 trace("ACM version = %u.%02u build %u%s\n",
468 HIWORD(dwACMVersion) >> 8,
469 HIWORD(dwACMVersion) & 0xff,
470 LOWORD(dwACMVersion),
471 LOWORD(dwACMVersion) == 0 ? " (Retail)" : "");
472 }
473
474 dwCount = check_count(ACM_METRIC_COUNT_CODECS);
475 dwCount = check_count(ACM_METRIC_COUNT_CONVERTERS);
476 dwCount = check_count(ACM_METRIC_COUNT_DISABLED);
477 dwCount = check_count(ACM_METRIC_COUNT_DRIVERS);
478 dwCount = check_count(ACM_METRIC_COUNT_FILTERS);
479 dwCount = check_count(ACM_METRIC_COUNT_HARDWARE);
480 dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CODECS);
481 dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CONVERTERS);
482 dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DISABLED);
483 dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DRIVERS);
484 dwCount = check_count(ACM_METRIC_COUNT_LOCAL_FILTERS);
485
486 if (winetest_interactive)
487 trace("enabled drivers:\n");
488
489 rc = acmDriverEnum(DriverEnumProc, 0, 0);
490 ok(rc == MMSYSERR_NOERROR,
491 "acmDriverEnum() failed, rc=%08x, should be 0x%08x\n",
492 rc, MMSYSERR_NOERROR);
493 }
494
495 START_TEST(msacm)
496 {
497 msacm_tests();
498 }