1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define WIN32_NO_STATUS
30 //#include "winerror.h"
31 //#include "mmsystem.h"
37 #include <wine/debug.h>
39 WINE_DEFAULT_DEBUG_CHANNEL(msacm
);
41 /***********************************************************************
42 * acmFilterChooseA (MSACM32.@)
44 MMRESULT WINAPI
acmFilterChooseA(PACMFILTERCHOOSEA pafltrc
)
46 FIXME("(%p): stub\n", pafltrc
);
47 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
48 return MMSYSERR_ERROR
;
51 /***********************************************************************
52 * acmFilterChooseW (MSACM32.@)
54 MMRESULT WINAPI
acmFilterChooseW(PACMFILTERCHOOSEW pafltrc
)
56 FIXME("(%p): stub\n", pafltrc
);
57 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
58 return MMSYSERR_ERROR
;
61 /***********************************************************************
62 * acmFilterDetailsA (MSACM32.@)
64 MMRESULT WINAPI
acmFilterDetailsA(HACMDRIVER had
, PACMFILTERDETAILSA pafd
,
67 ACMFILTERDETAILSW afdw
;
70 memset(&afdw
, 0, sizeof(afdw
));
71 afdw
.cbStruct
= sizeof(afdw
);
72 afdw
.dwFilterIndex
= pafd
->dwFilterIndex
;
73 afdw
.dwFilterTag
= pafd
->dwFilterTag
;
74 afdw
.pwfltr
= pafd
->pwfltr
;
75 afdw
.cbwfltr
= pafd
->cbwfltr
;
77 mmr
= acmFilterDetailsW(had
, &afdw
, fdwDetails
);
78 if (mmr
== MMSYSERR_NOERROR
) {
79 pafd
->dwFilterTag
= afdw
.dwFilterTag
;
80 pafd
->fdwSupport
= afdw
.fdwSupport
;
81 WideCharToMultiByte( CP_ACP
, 0, afdw
.szFilter
, -1, pafd
->szFilter
,
82 sizeof(pafd
->szFilter
), NULL
, NULL
);
87 /***********************************************************************
88 * acmFilterDetailsW (MSACM32.@)
90 MMRESULT WINAPI
acmFilterDetailsW(HACMDRIVER had
, PACMFILTERDETAILSW pafd
,
94 ACMFILTERTAGDETAILSA aftd
;
96 TRACE("(%p, %p, %d)\n", had
, pafd
, fdwDetails
);
98 memset(&aftd
, 0, sizeof(aftd
));
99 aftd
.cbStruct
= sizeof(aftd
);
101 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
103 switch (fdwDetails
) {
104 case ACM_FILTERDETAILSF_FILTER
:
105 if (pafd
->dwFilterTag
!= pafd
->pwfltr
->dwFilterTag
) {
106 mmr
= MMSYSERR_INVALPARAM
;
110 PWINE_ACMDRIVERID padid
;
112 mmr
= ACMERR_NOTPOSSIBLE
;
113 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
114 /* should check for codec only */
115 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
116 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
117 mmr
= MSACM_Message(had
, ACMDM_FILTER_DETAILS
,
118 (LPARAM
)pafd
, (LPARAM
)fdwDetails
);
119 acmDriverClose(had
, 0);
120 if (mmr
== MMSYSERR_NOERROR
) break;
124 mmr
= MSACM_Message(had
, ACMDM_FILTER_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
127 case ACM_FILTERDETAILSF_INDEX
:
128 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
129 mmr
= MSACM_Message(had
, ACMDM_FILTER_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
132 WARN("Unknown fdwDetails %08x\n", fdwDetails
);
133 mmr
= MMSYSERR_INVALFLAG
;
137 TRACE("=> %d\n", mmr
);
141 struct MSACM_FilterEnumWtoA_Instance
{
142 PACMFILTERDETAILSA pafda
;
143 DWORD_PTR dwInstance
;
144 ACMFILTERENUMCBA fnCallback
;
147 static BOOL CALLBACK
MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid
,
148 PACMFILTERDETAILSW pafdw
,
149 DWORD_PTR dwInstance
,
152 struct MSACM_FilterEnumWtoA_Instance
* pafei
;
154 pafei
= (struct MSACM_FilterEnumWtoA_Instance
*)dwInstance
;
156 pafei
->pafda
->dwFilterIndex
= pafdw
->dwFilterIndex
;
157 pafei
->pafda
->dwFilterTag
= pafdw
->dwFilterTag
;
158 pafei
->pafda
->fdwSupport
= pafdw
->fdwSupport
;
159 WideCharToMultiByte( CP_ACP
, 0, pafdw
->szFilter
, -1, pafei
->pafda
->szFilter
,
160 sizeof(pafei
->pafda
->szFilter
), NULL
, NULL
);
162 return (pafei
->fnCallback
)(hadid
, pafei
->pafda
,
163 pafei
->dwInstance
, fdwSupport
);
166 /***********************************************************************
167 * acmFilterEnumA (MSACM32.@)
169 MMRESULT WINAPI
acmFilterEnumA(HACMDRIVER had
, PACMFILTERDETAILSA pafda
,
170 ACMFILTERENUMCBA fnCallback
,
171 DWORD_PTR dwInstance
, DWORD fdwEnum
)
173 ACMFILTERDETAILSW afdw
;
174 struct MSACM_FilterEnumWtoA_Instance afei
;
176 memset(&afdw
, 0, sizeof(afdw
));
177 afdw
.cbStruct
= sizeof(afdw
);
178 afdw
.dwFilterIndex
= pafda
->dwFilterIndex
;
179 afdw
.dwFilterTag
= pafda
->dwFilterTag
;
180 afdw
.pwfltr
= pafda
->pwfltr
;
181 afdw
.cbwfltr
= pafda
->cbwfltr
;
184 afei
.dwInstance
= dwInstance
;
185 afei
.fnCallback
= fnCallback
;
187 return acmFilterEnumW(had
, &afdw
, MSACM_FilterEnumCallbackWtoA
,
188 (DWORD_PTR
)&afei
, fdwEnum
);
191 static BOOL
MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid
, HACMDRIVER had
,
192 PACMFILTERDETAILSW pafd
,
193 ACMFILTERENUMCBW fnCallback
,
194 DWORD_PTR dwInstance
, DWORD fdwEnum
)
196 ACMFILTERTAGDETAILSW aftd
;
199 for (i
= 0; i
< padid
->cFilterTags
; i
++) {
200 memset(&aftd
, 0, sizeof(aftd
));
201 aftd
.cbStruct
= sizeof(aftd
);
202 aftd
.dwFilterTagIndex
= i
;
203 if (acmFilterTagDetailsW(had
, &aftd
, ACM_FILTERTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
206 if ((fdwEnum
& ACM_FILTERENUMF_DWFILTERTAG
) &&
207 aftd
.dwFilterTag
!= pafd
->pwfltr
->dwFilterTag
)
210 for (j
= 0; j
< aftd
.cStandardFilters
; j
++) {
211 pafd
->dwFilterIndex
= j
;
212 pafd
->dwFilterTag
= aftd
.dwFilterTag
;
213 if (acmFilterDetailsW(had
, pafd
, ACM_FILTERDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
216 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
223 /***********************************************************************
224 * acmFilterEnumW (MSACM32.@)
226 MMRESULT WINAPI
acmFilterEnumW(HACMDRIVER had
, PACMFILTERDETAILSW pafd
,
227 ACMFILTERENUMCBW fnCallback
,
228 DWORD_PTR dwInstance
, DWORD fdwEnum
)
230 PWINE_ACMDRIVERID padid
;
233 TRACE("(%p, %p, %p, %ld, %d)\n",
234 had
, pafd
, fnCallback
, dwInstance
, fdwEnum
);
236 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
238 if (fdwEnum
& ~(ACM_FILTERENUMF_DWFILTERTAG
))
239 FIXME("Unsupported fdwEnum values\n");
244 if (acmDriverID((HACMOBJ
)had
, &hadid
, 0) != MMSYSERR_NOERROR
)
245 return MMSYSERR_INVALHANDLE
;
246 MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid
), had
, pafd
,
247 fnCallback
, dwInstance
, fdwEnum
);
248 return MMSYSERR_NOERROR
;
250 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
251 /* should check for codec only */
252 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
253 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
255 ret
= MSACM_FilterEnumHelper(padid
, had
, pafd
,
256 fnCallback
, dwInstance
, fdwEnum
);
257 acmDriverClose(had
, 0);
260 return MMSYSERR_NOERROR
;
263 /***********************************************************************
264 * acmFilterTagDetailsA (MSACM32.@)
266 MMRESULT WINAPI
acmFilterTagDetailsA(HACMDRIVER had
, PACMFILTERTAGDETAILSA paftda
,
269 ACMFILTERTAGDETAILSW aftdw
;
272 memset(&aftdw
, 0, sizeof(aftdw
));
273 aftdw
.cbStruct
= sizeof(aftdw
);
274 aftdw
.dwFilterTagIndex
= paftda
->dwFilterTagIndex
;
275 aftdw
.dwFilterTag
= paftda
->dwFilterTag
;
277 mmr
= acmFilterTagDetailsW(had
, &aftdw
, fdwDetails
);
278 if (mmr
== MMSYSERR_NOERROR
) {
279 paftda
->dwFilterTag
= aftdw
.dwFilterTag
;
280 paftda
->dwFilterTagIndex
= aftdw
.dwFilterTagIndex
;
281 paftda
->cbFilterSize
= aftdw
.cbFilterSize
;
282 paftda
->fdwSupport
= aftdw
.fdwSupport
;
283 paftda
->cStandardFilters
= aftdw
.cStandardFilters
;
284 WideCharToMultiByte( CP_ACP
, 0, aftdw
.szFilterTag
, -1, paftda
->szFilterTag
,
285 sizeof(paftda
->szFilterTag
), NULL
, NULL
);
290 /***********************************************************************
291 * acmFilterTagDetailsW (MSACM32.@)
293 MMRESULT WINAPI
acmFilterTagDetailsW(HACMDRIVER had
, PACMFILTERTAGDETAILSW paftd
,
296 PWINE_ACMDRIVERID padid
;
299 TRACE("(%p, %p, %d)\n", had
, paftd
, fdwDetails
);
301 if (fdwDetails
& ~(ACM_FILTERTAGDETAILSF_FILTERTAG
|ACM_FILTERTAGDETAILSF_INDEX
|
302 ACM_FILTERTAGDETAILSF_LARGESTSIZE
))
303 return MMSYSERR_INVALFLAG
;
305 switch (fdwDetails
) {
306 case ACM_FILTERTAGDETAILSF_FILTERTAG
:
308 mmr
= ACMERR_NOTPOSSIBLE
;
309 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
310 /* should check for codec only */
311 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
312 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
313 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
314 acmDriverClose(had
, 0);
315 if (mmr
== MMSYSERR_NOERROR
) break;
319 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
323 case ACM_FILTERTAGDETAILSF_INDEX
:
324 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
325 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
328 case ACM_FILTERTAGDETAILSF_LARGESTSIZE
:
330 ACMFILTERTAGDETAILSW tmp
;
331 DWORD ft
= paftd
->dwFilterTag
;
333 mmr
= ACMERR_NOTPOSSIBLE
;
334 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
335 /* should check for codec only */
336 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
337 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
339 memset(&tmp
, 0, sizeof(tmp
));
340 tmp
.cbStruct
= sizeof(tmp
);
341 tmp
.dwFilterTag
= ft
;
343 if (MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
,
344 (LPARAM
)&tmp
, fdwDetails
) == MMSYSERR_NOERROR
) {
345 if (mmr
== ACMERR_NOTPOSSIBLE
||
346 paftd
->cbFilterSize
< tmp
.cbFilterSize
) {
348 mmr
= MMSYSERR_NOERROR
;
351 acmDriverClose(had
, 0);
355 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
360 WARN("Unsupported fdwDetails=%08x\n", fdwDetails
);
361 mmr
= MMSYSERR_ERROR
;
364 if (mmr
== MMSYSERR_NOERROR
&&
365 paftd
->dwFilterTag
== WAVE_FORMAT_PCM
&& paftd
->szFilterTag
[0] == 0)
366 MultiByteToWideChar( CP_ACP
, 0, "PCM", -1, paftd
->szFilterTag
,
367 sizeof(paftd
->szFilterTag
)/sizeof(WCHAR
) );
372 struct MSACM_FilterTagEnumWtoA_Instance
{
373 PACMFILTERTAGDETAILSA paftda
;
374 DWORD_PTR dwInstance
;
375 ACMFILTERTAGENUMCBA fnCallback
;
378 static BOOL CALLBACK
MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid
,
379 PACMFILTERTAGDETAILSW paftdw
,
380 DWORD_PTR dwInstance
,
383 struct MSACM_FilterTagEnumWtoA_Instance
* paftei
;
385 paftei
= (struct MSACM_FilterTagEnumWtoA_Instance
*)dwInstance
;
387 paftei
->paftda
->dwFilterTagIndex
= paftdw
->dwFilterTagIndex
;
388 paftei
->paftda
->dwFilterTag
= paftdw
->dwFilterTag
;
389 paftei
->paftda
->cbFilterSize
= paftdw
->cbFilterSize
;
390 paftei
->paftda
->fdwSupport
= paftdw
->fdwSupport
;
391 paftei
->paftda
->cStandardFilters
= paftdw
->cStandardFilters
;
392 WideCharToMultiByte( CP_ACP
, 0, paftdw
->szFilterTag
, -1, paftei
->paftda
->szFilterTag
,
393 sizeof(paftei
->paftda
->szFilterTag
), NULL
, NULL
);
395 return (paftei
->fnCallback
)(hadid
, paftei
->paftda
,
396 paftei
->dwInstance
, fdwSupport
);
399 /***********************************************************************
400 * acmFilterTagEnumA (MSACM32.@)
402 MMRESULT WINAPI
acmFilterTagEnumA(HACMDRIVER had
, PACMFILTERTAGDETAILSA paftda
,
403 ACMFILTERTAGENUMCBA fnCallback
,
404 DWORD_PTR dwInstance
, DWORD fdwEnum
)
406 ACMFILTERTAGDETAILSW aftdw
;
407 struct MSACM_FilterTagEnumWtoA_Instance aftei
;
409 memset(&aftdw
, 0, sizeof(aftdw
));
410 aftdw
.cbStruct
= sizeof(aftdw
);
411 aftdw
.dwFilterTagIndex
= paftda
->dwFilterTagIndex
;
412 aftdw
.dwFilterTag
= paftda
->dwFilterTag
;
414 aftei
.paftda
= paftda
;
415 aftei
.dwInstance
= dwInstance
;
416 aftei
.fnCallback
= fnCallback
;
418 return acmFilterTagEnumW(had
, &aftdw
, MSACM_FilterTagEnumCallbackWtoA
,
419 (DWORD_PTR
)&aftei
, fdwEnum
);
422 /***********************************************************************
423 * acmFilterTagEnumW (MSACM32.@)
425 MMRESULT WINAPI
acmFilterTagEnumW(HACMDRIVER had
, PACMFILTERTAGDETAILSW paftd
,
426 ACMFILTERTAGENUMCBW fnCallback
,
427 DWORD_PTR dwInstance
, DWORD fdwEnum
)
429 PWINE_ACMDRIVERID padid
;
432 TRACE("(%p, %p, %p, %ld, %d)\n",
433 had
, paftd
, fnCallback
, dwInstance
, fdwEnum
);
435 if (paftd
->cbStruct
< sizeof(*paftd
)) return MMSYSERR_INVALPARAM
;
437 if (had
) FIXME("had != NULL, not supported\n");
439 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
440 /* should check for codec only */
441 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
442 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == MMSYSERR_NOERROR
) {
444 for (i
= 0; i
< padid
->cFilterTags
; i
++) {
445 paftd
->dwFilterTagIndex
= i
;
446 if (acmFilterTagDetailsW(had
, paftd
, ACM_FILTERTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
447 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
)) {
453 acmDriverClose(had
, 0);
456 return MMSYSERR_NOERROR
;