Revert shell32 version to Win2K SP4 level.
[wine] / dlls / msacm / 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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%04lx: %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%04lx, %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     if (winetest_interactive) {
66         trace("id: %p\n", hadid);
67         trace("  Supports:\n");
68         if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_ASYNC)
69             trace("    async conversions\n");
70         if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)
71             trace("    different format conversions\n");
72         if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CONVERTER)
73             trace("    same format conversions\n");
74         if (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_FILTER)
75             trace("    filtering\n");
76     }
77
78     /* try an invalid pointer */
79     rc = acmDriverDetails(hadid, 0, 0);
80     ok(rc == MMSYSERR_INVALPARAM,
81        "acmDriverDetails(): rc = %08x, should be %08x\n",
82        rc, MMSYSERR_INVALPARAM);
83
84     /* try an invalid structure size */
85     ZeroMemory(&dd, sizeof(dd));
86     rc = acmDriverDetails(hadid, &dd, 0);
87     ok(rc == MMSYSERR_INVALPARAM,
88        "acmDriverDetails(): rc = %08x, should be %08x\n",
89        rc, MMSYSERR_INVALPARAM);
90
91     /* MSDN says this should fail but it doesn't in practice */
92     dd.cbStruct = 4;
93     rc = acmDriverDetails(hadid, &dd, 0);
94     ok(rc == MMSYSERR_NOERROR,
95        "acmDriverDetails(): rc = %08x, should be %08x\n",
96        rc, MMSYSERR_NOERROR);
97
98     /* try an invalid handle */
99     dd.cbStruct = sizeof(dd);
100     rc = acmDriverDetails((HACMDRIVERID)1, &dd, 0);
101     ok(rc == MMSYSERR_INVALHANDLE,
102        "acmDriverDetails(): rc = %08x, should be %08x\n",
103        rc, MMSYSERR_INVALHANDLE);
104
105     /* try an invalid handle and pointer */
106     rc = acmDriverDetails((HACMDRIVERID)1, 0, 0);
107     ok(rc == MMSYSERR_INVALPARAM,
108        "acmDriverDetails(): rc = %08x, should be %08x\n",
109        rc, MMSYSERR_INVALPARAM);
110
111     /* try invalid details */
112     rc = acmDriverDetails(hadid, &dd, -1);
113     ok(rc == MMSYSERR_INVALFLAG,
114        "acmDriverDetails(): rc = %08x, should be %08x\n",
115        rc, MMSYSERR_INVALFLAG);
116
117     /* try valid parameters */
118     rc = acmDriverDetails(hadid, &dd, 0);
119     ok(rc == MMSYSERR_NOERROR,
120        "acmDriverDetails(): rc = %08x, should be %08x\n",
121        rc, MMSYSERR_NOERROR);
122
123     if (rc == MMSYSERR_NOERROR && winetest_interactive) {
124         trace("  Short name: %s\n", dd.szShortName);
125         trace("  Long name: %s\n", dd.szLongName);
126         trace("  Copyright: %s\n", dd.szCopyright);
127         trace("  Licensing: %s\n", dd.szLicensing);
128         trace("  Features: %s\n", dd.szFeatures);
129         trace("  Supports %lu formats\n", dd.cFormatTags);
130         trace("  Supports %lu filter formats\n", dd.cFilterTags);
131     }
132
133     /* try invalid pointer */
134     rc = acmDriverOpen(0, hadid, 0);
135     ok(rc == MMSYSERR_INVALPARAM,
136        "acmDriverOpen(): rc = %08x, should be %08x\n",
137        rc, MMSYSERR_INVALPARAM);
138
139     /* try invalid handle */
140     rc = acmDriverOpen(&had, (HACMDRIVERID)1, 0);
141     ok(rc == MMSYSERR_INVALHANDLE,
142        "acmDriverOpen(): rc = %08x, should be %08x\n",
143        rc, MMSYSERR_INVALHANDLE);
144
145     /* try invalid open */
146     rc = acmDriverOpen(&had, hadid, -1);
147     ok(rc == MMSYSERR_INVALFLAG,
148        "acmDriverOpen(): rc = %08x, should be %08x\n",
149        rc, MMSYSERR_INVALFLAG);
150
151     /* try valid parameters */
152     rc = acmDriverOpen(&had, hadid, 0);
153     ok(rc == MMSYSERR_NOERROR,
154        "acmDriverOpen(): rc = %08x, should be %08x\n",
155        rc, MMSYSERR_NOERROR);
156
157     if (rc == MMSYSERR_NOERROR) {
158         DWORD dwSize;
159         HACMDRIVERID hid;
160
161         /* try bad pointer */
162         rc = acmDriverID((HACMOBJ)had, 0, 0);
163         ok(rc == MMSYSERR_INVALPARAM,
164            "acmDriverID(): rc = %08x, should be %08x\n",
165            rc, MMSYSERR_INVALPARAM);
166
167         /* try bad handle */
168         rc = acmDriverID((HACMOBJ)1, &hid, 0);
169         ok(rc == MMSYSERR_INVALHANDLE,
170            "acmMetrics(): rc = %08x, should be %08x\n",
171            rc, MMSYSERR_INVALHANDLE);
172
173         /* try bad handle and pointer */
174         rc = acmDriverID((HACMOBJ)1, 0, 0);
175         ok(rc == MMSYSERR_INVALHANDLE,
176            "acmMetrics(): rc = %08x, should be %08x\n",
177            rc, MMSYSERR_INVALHANDLE);
178
179         /* try bad flag */
180         rc = acmDriverID((HACMOBJ)had, &hid, 1);
181         ok(rc == MMSYSERR_INVALFLAG,
182            "acmDriverID(): rc = %08x, should be %08x\n",
183            rc, MMSYSERR_INVALFLAG);
184
185         /* try valid parameters */
186         rc = acmDriverID((HACMOBJ)had, &hid, 0);
187         ok(rc == MMSYSERR_NOERROR,
188            "acmDriverID(): rc = %08x, should be %08x\n",
189            rc, MMSYSERR_NOERROR);
190         ok(hid == hadid,
191            "acmDriverID() returned ID %08lx doesn't equal %08lx\n",
192            (DWORD)hid, (DWORD)hadid);
193
194         /* try bad pointer */
195         rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, 0);
196         ok(rc == MMSYSERR_INVALPARAM,
197            "acmMetrics(): rc = %08x, should be %08x\n",
198            rc, MMSYSERR_INVALPARAM);
199
200         /* try bad handle */
201         rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
202         ok(rc == MMSYSERR_INVALHANDLE,
203            "acmMetrics(): rc = %08x, should be %08x\n",
204            rc, MMSYSERR_INVALHANDLE);
205
206         /* try bad pointer and handle */
207         rc = acmMetrics((HACMOBJ)1, ACM_METRIC_MAX_SIZE_FORMAT, 0);
208         ok(rc == MMSYSERR_INVALHANDLE,
209            "acmMetrics(): rc = %08x, should be %08x\n",
210            rc, MMSYSERR_INVALHANDLE);
211
212         /* try valid parameters */
213         rc = acmMetrics((HACMOBJ)had, ACM_METRIC_MAX_SIZE_FORMAT, &dwSize);
214         ok(rc == MMSYSERR_NOERROR,
215            "acmMetrics(): rc = %08x, should be %08x\n",
216            rc, MMSYSERR_NOERROR);
217         if (rc == MMSYSERR_NOERROR) {
218             ACMFORMATDETAILS fd;
219             WAVEFORMATEX * pwfx;
220             ACMFORMATTAGDETAILS aftd;
221
222             /* try bad pointer */
223             rc = acmFormatEnum(had, 0, FormatEnumProc, 0, 0);
224             ok(rc == MMSYSERR_INVALPARAM,
225                "acmFormatEnum(): rc = %08x, should be %08x\n",
226                 rc, MMSYSERR_INVALPARAM);
227
228             /* try bad structure size */
229             ZeroMemory(&fd, sizeof(fd));
230             rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
231             ok(rc == MMSYSERR_INVALPARAM,
232                "acmFormatEnum(): rc = %08x, should be %08x\n",
233                rc, MMSYSERR_INVALPARAM);
234
235             fd.cbStruct = sizeof(fd) - 1;
236             rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
237             ok(rc == MMSYSERR_INVALPARAM,
238                "acmFormatEnum(): rc = %08x, should be %08x\n",
239                rc, MMSYSERR_INVALPARAM);
240
241             if (dwSize < sizeof(WAVEFORMATEX))
242                 dwSize = sizeof(WAVEFORMATEX);
243
244             pwfx = (WAVEFORMATEX *) malloc(dwSize);
245
246             ZeroMemory(pwfx, dwSize);
247             pwfx->cbSize = LOWORD(dwSize) - sizeof(WAVEFORMATEX);
248             pwfx->wFormatTag = WAVE_FORMAT_UNKNOWN;
249
250             fd.cbStruct = sizeof(fd);
251             fd.pwfx = pwfx;
252             fd.cbwfx = dwSize;
253             fd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
254
255             /* try valid parameters */
256             rc = acmFormatEnum(had, &fd, FormatEnumProc, 0, 0);
257             ok(rc == MMSYSERR_NOERROR,
258                "acmFormatEnum(): rc = %08x, should be %08x\n",
259                rc, MMSYSERR_NOERROR);
260
261             /* try bad pointer */
262             rc = acmFormatTagEnum(had, 0, FormatTagEnumProc, 0, 0);
263             ok(rc == MMSYSERR_INVALPARAM,
264                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
265                 rc, MMSYSERR_INVALPARAM);
266
267             /* try bad structure size */
268             ZeroMemory(&aftd, sizeof(fd));
269             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
270             ok(rc == MMSYSERR_INVALPARAM,
271                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
272                rc, MMSYSERR_INVALPARAM);
273
274             aftd.cbStruct = sizeof(aftd) - 1;
275             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
276             ok(rc == MMSYSERR_INVALPARAM,
277                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
278                rc, MMSYSERR_INVALPARAM);
279
280             aftd.cbStruct = sizeof(aftd);
281             aftd.dwFormatTag = WAVE_FORMAT_UNKNOWN;
282
283             /* try bad flag */
284             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 1);
285             ok(rc == MMSYSERR_INVALFLAG,
286                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
287                rc, MMSYSERR_INVALFLAG);
288
289             /* try valid parameters */
290             rc = acmFormatTagEnum(had, &aftd, FormatTagEnumProc, 0, 0);
291             ok(rc == MMSYSERR_NOERROR,
292                "acmFormatTagEnum(): rc = %08x, should be %08x\n",
293                rc, MMSYSERR_NOERROR);
294
295             free(pwfx);
296
297             /* try invalid handle */
298             rc = acmDriverClose((HACMDRIVER)1, 0);
299             ok(rc == MMSYSERR_INVALHANDLE,
300                "acmDriverClose(): rc = %08x, should be %08x\n",
301                rc, MMSYSERR_INVALHANDLE);
302
303             /* try invalid flag */
304             rc = acmDriverClose(had, 1);
305             ok(rc == MMSYSERR_INVALFLAG,
306                "acmDriverClose(): rc = %08x, should be %08x\n",
307                rc, MMSYSERR_INVALFLAG);
308
309             /* try valid parameters */
310             rc = acmDriverClose(had, 0);
311             ok(rc == MMSYSERR_NOERROR,
312                "acmDriverClose(): rc = %08x, should be %08x\n",
313                rc, MMSYSERR_NOERROR);
314
315             /* try closing again */
316             rc = acmDriverClose(had, 0);
317             ok(rc == MMSYSERR_INVALHANDLE,
318                "acmDriverClose(): rc = %08x, should be %08x\n",
319                rc, MMSYSERR_INVALHANDLE);
320         }
321     }
322
323     return TRUE;
324 }
325
326 static const char * get_metric(UINT uMetric)
327 {
328     switch (uMetric) {
329     case ACM_METRIC_COUNT_CODECS:
330         return "ACM_METRIC_COUNT_CODECS";
331     case ACM_METRIC_COUNT_CONVERTERS:
332         return "ACM_METRIC_COUNT_CONVERTERS";
333     case ACM_METRIC_COUNT_DISABLED:
334         return "ACM_METRIC_COUNT_DISABLED";
335     case ACM_METRIC_COUNT_DRIVERS:
336         return "ACM_METRIC_COUNT_DRIVERS";
337     case ACM_METRIC_COUNT_FILTERS:
338         return "ACM_METRIC_COUNT_FILTERS";
339     case ACM_METRIC_COUNT_HARDWARE:
340         return "ACM_METRIC_COUNT_HARDWARE";
341     case ACM_METRIC_COUNT_LOCAL_CODECS:
342         return "ACM_METRIC_COUNT_LOCAL_CODECS";
343     case ACM_METRIC_COUNT_LOCAL_CONVERTERS:
344         return "ACM_METRIC_COUNT_LOCAL_CONVERTERS";
345     case ACM_METRIC_COUNT_LOCAL_DISABLED:
346         return "ACM_METRIC_COUNT_LOCAL_DISABLED";
347     case ACM_METRIC_COUNT_LOCAL_DRIVERS:
348         return "ACM_METRIC_COUNT_LOCAL_DRIVERS";
349     case ACM_METRIC_COUNT_LOCAL_FILTERS:
350         return "ACM_METRIC_COUNT_LOCAL_FILTERS";
351     case ACM_METRIC_DRIVER_PRIORITY:
352         return "ACM_METRIC_DRIVER_PRIORITY";
353     case ACM_METRIC_DRIVER_SUPPORT:
354         return "ACM_METRIC_DRIVER_SUPPORT";
355     case ACM_METRIC_HARDWARE_WAVE_INPUT:
356         return "ACM_METRIC_HARDWARE_WAVE_INPUT";
357     case ACM_METRIC_HARDWARE_WAVE_OUTPUT:
358         return "ACM_METRIC_HARDWARE_WAVE_OUTPUT";
359     case ACM_METRIC_MAX_SIZE_FILTER:
360         return "ACM_METRIC_MAX_SIZE_FILTER";
361     case ACM_METRIC_MAX_SIZE_FORMAT:
362         return "ACM_METRIC_MAX_SIZE_FORMAT";
363     }
364
365     return "UNKNOWN";
366 }
367
368 static DWORD check_count(UINT uMetric)
369 {
370     DWORD dwMetric;
371     MMRESULT rc;
372
373     /* try invalid result pointer */
374     rc = acmMetrics(NULL, uMetric, 0);
375     ok(rc == MMSYSERR_INVALPARAM,
376        "acmMetrics(NULL, %s, 0): rc = 0x%08x, should be 0x%08x\n",
377        get_metric(uMetric), rc, MMSYSERR_INVALPARAM);
378
379     /* try invalid handle */
380     rc = acmMetrics((HACMOBJ)1, uMetric, &dwMetric);
381     ok(rc == MMSYSERR_INVALHANDLE,
382        "acmMetrics(1, %s, %p): rc = 0x%08x, should be 0x%08x\n",
383        get_metric(uMetric), &dwMetric, rc, MMSYSERR_INVALHANDLE);
384
385     /* try invalid result pointer and handle */
386     rc = acmMetrics((HACMOBJ)1, uMetric, 0);
387     ok(rc == MMSYSERR_INVALHANDLE,
388        "acmMetrics(1, %s, 0): rc = 0x%08x, should be 0x%08x\n",
389        get_metric(uMetric), rc, MMSYSERR_INVALHANDLE);
390
391     /* try valid parameters */
392     rc = acmMetrics(NULL, uMetric, &dwMetric);
393     ok(rc == MMSYSERR_NOERROR, "acmMetrics() failed: rc = 0x%08x\n", rc);
394
395     if (rc == MMSYSERR_NOERROR && winetest_interactive)
396         trace("%s: %lu\n", get_metric(uMetric), dwMetric);
397
398     return dwMetric;
399 }
400
401 static void msacm_tests()
402 {
403     MMRESULT rc;
404     DWORD dwCount;
405     DWORD dwACMVersion = acmGetVersion();
406
407     if (winetest_interactive) {
408         trace("ACM version = %u.%02u build %u%s\n",
409             HIWORD(dwACMVersion) >> 8,
410             HIWORD(dwACMVersion) & 0xff,
411             LOWORD(dwACMVersion),
412             LOWORD(dwACMVersion)  ==  0 ? " (Retail)" : "");
413     }
414
415     dwCount = check_count(ACM_METRIC_COUNT_CODECS);
416     dwCount = check_count(ACM_METRIC_COUNT_CONVERTERS);
417     dwCount = check_count(ACM_METRIC_COUNT_DISABLED);
418     dwCount = check_count(ACM_METRIC_COUNT_DRIVERS);
419     dwCount = check_count(ACM_METRIC_COUNT_FILTERS);
420     dwCount = check_count(ACM_METRIC_COUNT_HARDWARE);
421     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CODECS);
422     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_CONVERTERS);
423     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DISABLED);
424     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_DRIVERS);
425     dwCount = check_count(ACM_METRIC_COUNT_LOCAL_FILTERS);
426
427     if (winetest_interactive)
428         trace("enabled drivers:\n");
429
430     rc = acmDriverEnum(DriverEnumProc, 0, 0);
431     ok(rc == MMSYSERR_NOERROR,
432       "acmDriverEnum() failed, rc=%08x, should be 0x%08x\n",
433       rc, MMSYSERR_NOERROR);
434 }
435
436 START_TEST(msacm)
437 {
438     msacm_tests();
439 }