msacm32/tests: Win64 printf format warning fixes.
[wine] / dlls / msacm32 / tests / 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 "mmreg.h"
33 #include "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     ACMDRIVERDETAILS 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             ACMFORMATDETAILS fd;
279             WAVEFORMATEX * pwfx;
280             ACMFORMATTAGDETAILS 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 = (WAVEFORMATEX *) malloc(dwSize);
305
306             ZeroMemory(pwfx, dwSize);
307             pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
308             pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN;
309
310             fd.cbStruct = sizeof(fd);
311             fd.pwfx = pwfx;
312             fd.cbwfx = dwSize;
313             fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
314
315             /* try valid parameters */
316             rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
317             ok(rc == MMSYSERR_NOERROR,
318                "acmFormatEnum(): rc = %08x, should be %08x\n",
319                rc, MMSYSERR_NOERROR);
320
321             /* try bad pointer */
322             rc = acmFormatTagEnum(had, 0, FormatTagEnumProc, 0, 0);
323             ok(rc == MMSYSERR_INVALPARAM,
324                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
325                 rc, MMSYSERR_INVALPARAM);
326
327             /* try bad structure size */
328             ZeroMemory(&aftd, sizeof(aftd));
329             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
330             ok(rc == MMSYSERR_INVALPARAM,
331                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
332                rc, MMSYSERR_INVALPARAM);
333
334             aftd.cbStruct = sizeof(aftd) - 1;
335             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
336             ok(rc == MMSYSERR_INVALPARAM,
337                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
338                rc, MMSYSERR_INVALPARAM);
339
340             aftd.cbStruct = sizeof(aftd);
341             aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
342
343             /* try bad flag */
344             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 1);
345             ok(rc == MMSYSERR_INVALFLAG,
346                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
347                rc, MMSYSERR_INVALFLAG);
348
349             /* try valid parameters */
350             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
351             ok(rc == MMSYSERR_NOERROR,
352                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
353                rc, MMSYSERR_NOERROR);
354
355             free(pwfx);
356
357             /* try invalid handle */
358             rc = acmDriverClose((HACMDRIVER)1, 0);
359             ok(rc == MMSYSERR_INVALHANDLE,
360                "acmDriverClose(): rc = %08x, should be %08x\n",
361                rc, MMSYSERR_INVALHANDLE);
362
363             /* try invalid flag */
364             rc = acmDriverClose(had, 1);
365             ok(rc == MMSYSERR_INVALFLAG,
366                "acmDriverClose(): rc = %08x, should be %08x\n",
367                rc, MMSYSERR_INVALFLAG);
368
369             /* try valid parameters */
370             rc = acmDriverClose(had, 0);
371             ok(rc == MMSYSERR_NOERROR,
372                "acmDriverClose(): rc = %08x, should be %08x\n",
373                rc, MMSYSERR_NOERROR);
374
375             /* try closing again */
376             rc = acmDriverClose(had, 0);
377             ok(rc == MMSYSERR_INVALHANDLE,
378                "acmDriverClose(): rc = %08x, should be %08x\n",
379                rc, MMSYSERR_INVALHANDLE);
380         }
381     }
382
383     return TRUE;
384 }
385
386 static const char * get_metric(UINT uMetric)
387 {
388     switch (uMetric) {
389     case ACM_METRIC_COUNT_CODECS:
390         return "ACM_METRIC_COUNT_CODECS";
391     case ACM_METRIC_COUNT_CONVERTERS:
392         return "ACM_METRIC_COUNT_CONVERTERS";
393     case ACM_METRIC_COUNT_DISABLED:
394         return "ACM_METRIC_COUNT_DISABLED";
395     case ACM_METRIC_COUNT_DRIVERS:
396         return "ACM_METRIC_COUNT_DRIVERS";
397     case ACM_METRIC_COUNT_FILTERS:
398         return "ACM_METRIC_COUNT_FILTERS";
399     case ACM_METRIC_COUNT_HARDWARE:
400         return "ACM_METRIC_COUNT_HARDWARE";
401     case ACM_METRIC_COUNT_LOCAL_CODECS:
402         return "ACM_METRIC_COUNT_LOCAL_CODECS";
403     case ACM_METRIC_COUNT_LOCAL_CONVERTERS:
404         return "ACM_METRIC_COUNT_LOCAL_CONVERTERS";
405     case ACM_METRIC_COUNT_LOCAL_DISABLED:
406         return "ACM_METRIC_COUNT_LOCAL_DISABLED";
407     case ACM_METRIC_COUNT_LOCAL_DRIVERS:
408         return "ACM_METRIC_COUNT_LOCAL_DRIVERS";
409     case ACM_METRIC_COUNT_LOCAL_FILTERS:
410         return "ACM_METRIC_COUNT_LOCAL_FILTERS";
411     case ACM_METRIC_DRIVER_PRIORITY:
412         return "ACM_METRIC_DRIVER_PRIORITY";
413     case ACM_METRIC_DRIVER_SUPPORT:
414         return "ACM_METRIC_DRIVER_SUPPORT";
415     case ACM_METRIC_HARDWARE_WAVE_INPUT:
416         return "ACM_METRIC_HARDWARE_WAVE_INPUT";
417     case ACM_METRIC_HARDWARE_WAVE_OUTPUT:
418         return "ACM_METRIC_HARDWARE_WAVE_OUTPUT";
419     case ACM_METRIC_MAX_SIZE_FILTER:
420         return "ACM_METRIC_MAX_SIZE_FILTER";
421     case ACM_METRIC_MAX_SIZE_FORMAT:
422         return "ACM_METRIC_MAX_SIZE_FORMAT";
423     }
424
425     return "UNKNOWN";
426 }
427
428 static DWORD check_count(UINT uMetric)
429 {
430     DWORD dwMetric;
431     MMRESULT rc;
432
433     /* try invalid result pointer */
434     rc = acmMetrics(NULL, uMetric, 0);
435     ok(rc == MMSYSERR_INVALPARAM,
436        "acmMetrics(NULL, %s, 0): rc = 0x%08x, should be 0x%08x\n",
437        get_metric(uMetric), rc, MMSYSERR_INVALPARAM);
438
439     /* try invalid handle */
440     rc = acmMetrics((HACMOBJ)1, uMetric, &dwMetric);
441     ok(rc == MMSYSERR_INVALHANDLE,
442        "acmMetrics(1, %s, %p): rc = 0x%08x, should be 0x%08x\n",
443        get_metric(uMetric), &dwMetric, rc, MMSYSERR_INVALHANDLE);
444
445     /* try invalid result pointer and handle */
446     rc = acmMetrics((HACMOBJ)1, uMetric, 0);
447     ok(rc == MMSYSERR_INVALHANDLE,
448        "acmMetrics(1, %s, 0): rc = 0x%08x, should be 0x%08x\n",
449        get_metric(uMetric), rc, MMSYSERR_INVALHANDLE);
450
451     /* try valid parameters */
452     rc = acmMetrics(NULL, uMetric, &dwMetric);
453     ok(rc == MMSYSERR_NOERROR, "acmMetrics() failed: rc = 0x%08x\n", rc);
454
455     if (rc == MMSYSERR_NOERROR && winetest_interactive)
456         trace("%s: %u\n", get_metric(uMetric), dwMetric);
457
458     return dwMetric;
459 }
460
461 static void msacm_tests(void)
462 {
463     MMRESULT rc;
464     DWORD dwCount;
465     DWORD dwACMVersion = acmGetVersion();
466
467     if (winetest_interactive) {
468         trace("ACM version = %u.%02u build %u%s\n",
469             HIWORD(dwACMVersion) >> 8,
470             HIWORD(dwACMVersion) & 0xff,
471             LOWORD(dwACMVersion),
472             LOWORD(dwACMVersion)  ==  0 ? " (Retail)" : "");
473     }
474
475     dwCount = check_count(ACM_METRIC_COUNT_CODECS);
476     dwCount = check_count(ACM_METRIC_COUNT_CONVERTERS);
477     dwCount = check_count(ACM_METRIC_COUNT_DISABLED);
478     dwCount = check_count(ACM_METRIC_COUNT_DRIVERS);
479     dwCount = check_count(ACM_METRIC_COUNT_FILTERS);
480     dwCount = check_count(ACM_METRIC_COUNT_HARDWARE);
481     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CODECS);
482     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CONVERTERS);
483     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DISABLED);
484     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DRIVERS);
485     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_FILTERS);
486
487     if (winetest_interactive)
488         trace("enabled drivers:\n");
489
490     rc = acmDriverEnum(DriverEnumProc, 0, 0);
491     ok(rc == MMSYSERR_NOERROR,
492       "acmDriverEnum() failed, rc=%08x, should be 0x%08x\n",
493       rc, MMSYSERR_NOERROR);
494 }
495
496 START_TEST(msacm)
497 {
498     msacm_tests();
499 }