1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
11 #include "wine/winestring.h"
16 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(msacm
);
20 /***********************************************************************
21 * acmFilterChooseA (MSACM32.13)
23 MMRESULT WINAPI
acmFilterChooseA(PACMFILTERCHOOSEA pafltrc
)
25 FIXME("(%p): stub\n", pafltrc
);
26 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
27 return MMSYSERR_ERROR
;
30 /***********************************************************************
31 * acmFilterChooseW (MSACM32.14)
33 MMRESULT WINAPI
acmFilterChooseW(PACMFILTERCHOOSEW pafltrc
)
35 FIXME("(%p): stub\n", pafltrc
);
36 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
37 return MMSYSERR_ERROR
;
40 /***********************************************************************
41 * acmFilterDetailsA (MSACM32.15)
43 MMRESULT WINAPI
acmFilterDetailsA(HACMDRIVER had
, PACMFILTERDETAILSA pafd
,
46 ACMFILTERDETAILSW afdw
;
49 memset(&afdw
, 0, sizeof(afdw
));
50 afdw
.cbStruct
= sizeof(afdw
);
51 afdw
.dwFilterIndex
= pafd
->dwFilterIndex
;
52 afdw
.dwFilterTag
= pafd
->dwFilterTag
;
53 afdw
.pwfltr
= pafd
->pwfltr
;
54 afdw
.cbwfltr
= pafd
->cbwfltr
;
56 mmr
= acmFilterDetailsW(had
, &afdw
, fdwDetails
);
57 if (mmr
== MMSYSERR_NOERROR
) {
58 pafd
->dwFilterTag
= afdw
.dwFilterTag
;
59 pafd
->fdwSupport
= afdw
.fdwSupport
;
60 lstrcpyWtoA(pafd
->szFilter
, afdw
.szFilter
);
65 /***********************************************************************
66 * acmFilterDetailsW (MSACM32.16)
68 MMRESULT WINAPI
acmFilterDetailsW(HACMDRIVER had
, PACMFILTERDETAILSW pafd
,
72 ACMFILTERTAGDETAILSA aftd
;
74 TRACE("(0x%08x, %p, %ld)\n", had
, pafd
, fdwDetails
);
76 memset(&aftd
, 0, sizeof(aftd
));
77 aftd
.cbStruct
= sizeof(aftd
);
79 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
82 case ACM_FILTERDETAILSF_FILTER
:
83 if (pafd
->dwFilterTag
!= pafd
->pwfltr
->dwFilterTag
) {
84 mmr
= MMSYSERR_INVALPARAM
;
87 if (had
== (HACMDRIVER
)NULL
) {
88 PWINE_ACMDRIVERID padid
;
90 mmr
= ACMERR_NOTPOSSIBLE
;
91 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
92 /* should check for codec only */
93 if (padid
->bEnabled
&&
94 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
95 mmr
= MSACM_Message(had
, ACMDM_FILTER_DETAILS
,
96 (LPARAM
)pafd
, (LPARAM
)fdwDetails
);
97 acmDriverClose(had
, 0);
98 if (mmr
== MMSYSERR_NOERROR
) break;
102 mmr
= MSACM_Message(had
, ACMDM_FILTER_DETAILS
,
103 (LPARAM
)pafd
, (LPARAM
)fdwDetails
);
106 case ACM_FILTERDETAILSF_INDEX
:
107 /* should check pafd->dwFilterIndex < aftd->cStandardFilters */
108 mmr
= MSACM_Message(had
, ACMDM_FILTER_DETAILS
,
109 (LPARAM
)pafd
, (LPARAM
)fdwDetails
);
112 WARN("Unknown fdwDetails %08lx\n", fdwDetails
);
113 mmr
= MMSYSERR_INVALFLAG
;
117 TRACE("=> %d\n", mmr
);
121 struct MSACM_FilterEnumWtoA_Instance
{
122 PACMFILTERDETAILSA pafda
;
124 ACMFILTERENUMCBA fnCallback
;
127 static BOOL CALLBACK
MSACM_FilterEnumCallbackWtoA(HACMDRIVERID hadid
,
128 PACMFILTERDETAILSW pafdw
,
132 struct MSACM_FilterEnumWtoA_Instance
* pafei
;
134 pafei
= (struct MSACM_FilterEnumWtoA_Instance
*)dwInstance
;
136 pafei
->pafda
->dwFilterIndex
= pafdw
->dwFilterIndex
;
137 pafei
->pafda
->dwFilterTag
= pafdw
->dwFilterTag
;
138 pafei
->pafda
->fdwSupport
= pafdw
->fdwSupport
;
139 lstrcpyWtoA(pafei
->pafda
->szFilter
, pafdw
->szFilter
);
141 return (pafei
->fnCallback
)(hadid
, pafei
->pafda
,
142 pafei
->dwInstance
, fdwSupport
);
145 /***********************************************************************
146 * acmFilterEnumA (MSACM32.17)
148 MMRESULT WINAPI
acmFilterEnumA(HACMDRIVER had
, PACMFILTERDETAILSA pafda
,
149 ACMFILTERENUMCBA fnCallback
, DWORD dwInstance
,
152 ACMFILTERDETAILSW afdw
;
153 struct MSACM_FilterEnumWtoA_Instance afei
;
155 memset(&afdw
, 0, sizeof(afdw
));
156 afdw
.cbStruct
= sizeof(afdw
);
157 afdw
.dwFilterIndex
= pafda
->dwFilterIndex
;
158 afdw
.dwFilterTag
= pafda
->dwFilterTag
;
159 afdw
.pwfltr
= pafda
->pwfltr
;
160 afdw
.cbwfltr
= pafda
->cbwfltr
;
163 afei
.dwInstance
= dwInstance
;
164 afei
.fnCallback
= fnCallback
;
166 return acmFilterEnumW(had
, &afdw
, MSACM_FilterEnumCallbackWtoA
,
167 (DWORD
)&afei
, fdwEnum
);
170 static BOOL
MSACM_FilterEnumHelper(PWINE_ACMDRIVERID padid
, HACMDRIVER had
,
171 PACMFILTERDETAILSW pafd
,
172 ACMFILTERENUMCBW fnCallback
, DWORD dwInstance
,
175 ACMDRIVERDETAILSW add
;
176 ACMFILTERTAGDETAILSW aftd
;
179 add
.cbStruct
= sizeof(add
);
181 if (acmDriverDetailsW((HACMDRIVERID
)padid
, &add
, 0) != MMSYSERR_NOERROR
) return FALSE
;
183 for (i
= 0; i
< add
.cFilterTags
; i
++) {
184 memset(&aftd
, 0, sizeof(aftd
));
185 aftd
.cbStruct
= sizeof(aftd
);
186 aftd
.dwFilterTagIndex
= i
;
187 if (acmFilterTagDetailsW(had
, &aftd
, ACM_FILTERTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
190 if ((fdwEnum
& ACM_FILTERENUMF_DWFILTERTAG
) &&
191 aftd
.dwFilterTag
!= pafd
->pwfltr
->dwFilterTag
)
194 for (j
= 0; j
< aftd
.cStandardFilters
; j
++) {
195 pafd
->dwFilterIndex
= j
;
196 pafd
->dwFilterTag
= aftd
.dwFilterTag
;
197 if (acmFilterDetailsW(had
, pafd
, ACM_FILTERDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
200 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, add
.fdwSupport
))
207 /***********************************************************************
208 * acmFilterEnumW (MSACM32.18)
210 MMRESULT WINAPI
acmFilterEnumW(HACMDRIVER had
, PACMFILTERDETAILSW pafd
,
211 ACMFILTERENUMCBW fnCallback
, DWORD dwInstance
,
214 PWINE_ACMDRIVERID padid
;
217 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
218 had
, pafd
, fnCallback
, dwInstance
, fdwEnum
);
220 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
222 if (fdwEnum
& ~(ACM_FILTERENUMF_DWFILTERTAG
))
223 FIXME("Unsupported fdwEnum values\n");
228 if (acmDriverID(had
, &hadid
, 0) != MMSYSERR_NOERROR
)
229 return MMSYSERR_INVALHANDLE
;
230 return MSACM_FilterEnumHelper(MSACM_GetDriverID(hadid
), had
, pafd
,
231 fnCallback
, dwInstance
, fdwEnum
);
233 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
234 /* should check for codec only */
235 if (!padid
->bEnabled
|| acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
237 ret
= MSACM_FilterEnumHelper(padid
, had
, pafd
,
238 fnCallback
, dwInstance
, fdwEnum
);
239 acmDriverClose(had
, 0);
242 return MMSYSERR_NOERROR
;
245 /***********************************************************************
246 * acmFilterTagDetailsA (MSACM32.19)
248 MMRESULT WINAPI
acmFilterTagDetailsA(HACMDRIVER had
, PACMFILTERTAGDETAILSA paftda
,
251 ACMFILTERTAGDETAILSW aftdw
;
254 memset(&aftdw
, 0, sizeof(aftdw
));
255 aftdw
.cbStruct
= sizeof(aftdw
);
256 aftdw
.dwFilterTagIndex
= paftda
->dwFilterTagIndex
;
257 aftdw
.dwFilterTag
= paftda
->dwFilterTag
;
259 mmr
= acmFilterTagDetailsW(had
, &aftdw
, fdwDetails
);
260 if (mmr
== MMSYSERR_NOERROR
) {
261 paftda
->dwFilterTag
= aftdw
.dwFilterTag
;
262 paftda
->dwFilterTagIndex
= aftdw
.dwFilterTagIndex
;
263 paftda
->cbFilterSize
= aftdw
.cbFilterSize
;
264 paftda
->fdwSupport
= aftdw
.fdwSupport
;
265 paftda
->cStandardFilters
= aftdw
.cStandardFilters
;
266 lstrcpyWtoA(paftda
->szFilterTag
, aftdw
.szFilterTag
);
271 /***********************************************************************
272 * acmFilterTagDetailsW (MSACM32.20)
274 MMRESULT WINAPI
acmFilterTagDetailsW(HACMDRIVER had
, PACMFILTERTAGDETAILSW paftd
,
277 PWINE_ACMDRIVERID padid
;
280 TRACE("(0x%08x, %p, %ld)\n", had
, paftd
, fdwDetails
);
282 if (fdwDetails
& ~(ACM_FILTERTAGDETAILSF_FILTERTAG
|ACM_FILTERTAGDETAILSF_INDEX
|
283 ACM_FILTERTAGDETAILSF_LARGESTSIZE
))
284 return MMSYSERR_INVALFLAG
;
286 switch (fdwDetails
) {
287 case ACM_FILTERTAGDETAILSF_FILTERTAG
:
288 if (had
== (HACMDRIVER
)NULL
) {
289 mmr
= ACMERR_NOTPOSSIBLE
;
290 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
291 /* should check for codec only */
292 if (padid
->bEnabled
&& acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
293 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
,
294 (LPARAM
)paftd
, (LPARAM
)fdwDetails
);
295 acmDriverClose(had
, 0);
296 if (mmr
== MMSYSERR_NOERROR
) break;
300 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
,
301 (LPARAM
)paftd
, (LPARAM
)fdwDetails
);
305 case ACM_FILTERTAGDETAILSF_INDEX
:
306 /* FIXME should check paftd->dwFilterTagIndex < add.cFilterTags */
307 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
,
308 (LPARAM
)paftd
, (LPARAM
)fdwDetails
);
311 case ACM_FILTERTAGDETAILSF_LARGESTSIZE
:
312 if (had
== (HACMDRIVER
)NULL
) {
313 ACMFILTERTAGDETAILSW tmp
;
314 DWORD ft
= paftd
->dwFilterTag
;
316 mmr
= ACMERR_NOTPOSSIBLE
;
317 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
318 /* should check for codec only */
319 if (padid
->bEnabled
&&
320 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
322 memset(&tmp
, 0, sizeof(tmp
));
323 tmp
.cbStruct
= sizeof(tmp
);
324 tmp
.dwFilterTag
= ft
;
326 if (MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
,
328 (LPARAM
)fdwDetails
) == MMSYSERR_NOERROR
) {
329 if (mmr
== ACMERR_NOTPOSSIBLE
||
330 paftd
->cbFilterSize
< tmp
.cbFilterSize
) {
332 mmr
= MMSYSERR_NOERROR
;
335 acmDriverClose(had
, 0);
339 mmr
= MSACM_Message(had
, ACMDM_FILTERTAG_DETAILS
,
340 (LPARAM
)paftd
, (LPARAM
)fdwDetails
);
345 WARN("Unsupported fdwDetails=%08lx\n", fdwDetails
);
346 mmr
= MMSYSERR_ERROR
;
349 if (mmr
== MMSYSERR_NOERROR
&&
350 paftd
->dwFilterTag
== WAVE_FORMAT_PCM
&& paftd
->szFilterTag
[0] == 0)
351 lstrcpyAtoW(paftd
->szFilterTag
, "PCM");
356 struct MSACM_FilterTagEnumWtoA_Instance
{
357 PACMFILTERTAGDETAILSA paftda
;
359 ACMFILTERTAGENUMCBA fnCallback
;
362 static BOOL CALLBACK
MSACM_FilterTagEnumCallbackWtoA(HACMDRIVERID hadid
,
363 PACMFILTERTAGDETAILSW paftdw
,
367 struct MSACM_FilterTagEnumWtoA_Instance
* paftei
;
369 paftei
= (struct MSACM_FilterTagEnumWtoA_Instance
*)dwInstance
;
371 paftei
->paftda
->dwFilterTagIndex
= paftdw
->dwFilterTagIndex
;
372 paftei
->paftda
->dwFilterTag
= paftdw
->dwFilterTag
;
373 paftei
->paftda
->cbFilterSize
= paftdw
->cbFilterSize
;
374 paftei
->paftda
->fdwSupport
= paftdw
->fdwSupport
;
375 paftei
->paftda
->cStandardFilters
= paftdw
->cStandardFilters
;
376 lstrcpyWtoA(paftei
->paftda
->szFilterTag
, paftdw
->szFilterTag
);
378 return (paftei
->fnCallback
)(hadid
, paftei
->paftda
,
379 paftei
->dwInstance
, fdwSupport
);
382 /***********************************************************************
383 * acmFilterTagEnumA (MSACM32.21)
385 MMRESULT WINAPI
acmFilterTagEnumA(HACMDRIVER had
, PACMFILTERTAGDETAILSA paftda
,
386 ACMFILTERTAGENUMCBA fnCallback
, DWORD dwInstance
,
389 ACMFILTERTAGDETAILSW aftdw
;
390 struct MSACM_FilterTagEnumWtoA_Instance aftei
;
392 memset(&aftdw
, 0, sizeof(aftdw
));
393 aftdw
.cbStruct
= sizeof(aftdw
);
394 aftdw
.dwFilterTagIndex
= paftda
->dwFilterTagIndex
;
395 aftdw
.dwFilterTag
= paftda
->dwFilterTag
;
397 aftei
.paftda
= paftda
;
398 aftei
.dwInstance
= dwInstance
;
399 aftei
.fnCallback
= fnCallback
;
401 return acmFilterTagEnumW(had
, &aftdw
, MSACM_FilterTagEnumCallbackWtoA
,
402 (DWORD
)&aftei
, fdwEnum
);
405 /***********************************************************************
406 * acmFilterTagEnumW (MSACM32.22)
408 MMRESULT WINAPI
acmFilterTagEnumW(HACMDRIVER had
, PACMFILTERTAGDETAILSW paftd
,
409 ACMFILTERTAGENUMCBW fnCallback
, DWORD dwInstance
,
412 PWINE_ACMDRIVERID padid
;
413 ACMDRIVERDETAILSW add
;
416 TRACE("(0x%08x, %p, %p, %ld, %ld)\n",
417 had
, paftd
, fnCallback
, dwInstance
, fdwEnum
);
419 if (paftd
->cbStruct
< sizeof(*paftd
)) return MMSYSERR_INVALPARAM
;
421 if (had
) FIXME("had != NULL, not supported\n");
423 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
424 /* should check for codec only */
425 if (padid
->bEnabled
&& acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == MMSYSERR_NOERROR
) {
426 add
.cbStruct
= sizeof(add
);
428 if (acmDriverDetailsW((HACMDRIVERID
)padid
, &add
, 0) == MMSYSERR_NOERROR
) {
429 for (i
= 0; i
< add
.cFilterTags
; i
++) {
430 paftd
->dwFilterTagIndex
= i
;
431 if (acmFilterTagDetailsW(had
, paftd
, ACM_FILTERTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
432 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
,
441 acmDriverClose(had
, 0);
443 return MMSYSERR_NOERROR
;