4 * Copyright 1998 Patrik Stridvall
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/unicode.h"
31 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msacm
);
40 struct MSACM_FillFormatData
{
42 #define WINE_ACMFF_TAG 0
43 #define WINE_ACMFF_FORMAT 1
44 #define WINE_ACMFF_WFX 2
46 WCHAR szFormatTag
[ACMFORMATTAGDETAILS_FORMATTAG_CHARS
];
47 PACMFORMATCHOOSEW afc
;
51 static BOOL CALLBACK
MSACM_FillFormatTagsCB(HACMDRIVERID hadid
,
52 PACMFORMATTAGDETAILSW paftd
,
56 struct MSACM_FillFormatData
* affd
= (struct MSACM_FillFormatData
*)dwInstance
;
60 if (paftd
->cStandardFormats
> 0)
62 if (SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
63 CB_FINDSTRINGEXACT
, -1,
64 (LPARAM
)paftd
->szFormatTag
) == CB_ERR
)
66 int index
= SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
67 CB_ADDSTRING
, 0, (LPARAM
)paftd
->szFormatTag
);
68 if (((affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
69 (paftd
->dwFormatTag
== affd
->afc
->pwfx
->wFormatTag
)) ||
70 (!(affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
71 (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
)))
72 SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
73 CB_SETCURSEL
, index
, 0);
77 case WINE_ACMFF_FORMAT
:
78 if (strcmpW(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
81 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
82 ACMFORMATDETAILSW afd
= {0};
85 WCHAR buffer
[ACMFORMATDETAILS_FORMAT_CHARS
+16];
87 afd
.cbStruct
= sizeof(afd
);
88 afd
.dwFormatTag
= paftd
->dwFormatTag
;
89 afd
.pwfx
= HeapAlloc(MSACM_hHeap
, 0, paftd
->cbFormatSize
);
90 if (!afd
.pwfx
) return FALSE
;
91 afd
.pwfx
->wFormatTag
= paftd
->dwFormatTag
;
92 if (paftd
->dwFormatTag
!= WAVE_FORMAT_PCM
)
93 afd
.pwfx
->cbSize
= paftd
->cbFormatSize
- sizeof(WAVEFORMATEX
);
94 afd
.cbwfx
= paftd
->cbFormatSize
;
96 for (i
= 0; i
< paftd
->cStandardFormats
; i
++) {
97 static const WCHAR fmtW
[] = {'%','d',' ','K','o','/','s','\0'};
100 afd
.dwFormatIndex
= i
;
102 mmr
= acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
103 if (mmr
== MMSYSERR_NOERROR
) {
104 lstrcpynW(buffer
, afd
.szFormat
, ACMFORMATTAGDETAILS_FORMATTAG_CHARS
+ 1);
105 len
= strlenW(buffer
);
106 for (j
= len
; j
< ACMFORMATTAGDETAILS_FORMATTAG_CHARS
; j
++)
108 wsprintfW(buffer
+ ACMFORMATTAGDETAILS_FORMATTAG_CHARS
,
109 fmtW
, (afd
.pwfx
->nAvgBytesPerSec
+ 512) / 1024);
110 index
= SendDlgItemMessageW(affd
->hWnd
,
111 IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
112 CB_ADDSTRING
, 0, (LPARAM
)buffer
);
113 if ((affd
->afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
) &&
114 affd
->afc
->cbwfx
>= paftd
->cbFormatSize
&&
115 !memcmp(afd
.pwfx
, affd
->afc
->pwfx
, paftd
->cbFormatSize
))
116 SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
117 CB_SETCURSEL
, index
, 0);
120 acmDriverClose(had
, 0);
121 HeapFree(MSACM_hHeap
, 0, afd
.pwfx
);
126 if (strcmpW(affd
->szFormatTag
, paftd
->szFormatTag
) == 0) {
129 if (acmDriverOpen(&had
, hadid
, 0) == MMSYSERR_NOERROR
) {
130 ACMFORMATDETAILSW afd
= {0};
132 afd
.cbStruct
= sizeof(afd
);
133 afd
.dwFormatTag
= paftd
->dwFormatTag
;
134 afd
.pwfx
= affd
->afc
->pwfx
;
135 afd
.cbwfx
= affd
->afc
->cbwfx
;
137 afd
.dwFormatIndex
= SendDlgItemMessageW(affd
->hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
,
139 affd
->ret
= acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_INDEX
);
140 acmDriverClose(had
, 0);
146 FIXME("Unknown mode (%d)\n", affd
->mode
);
152 static BOOL
MSACM_FillFormatTags(HWND hWnd
, PACMFORMATCHOOSEW afc
)
154 ACMFORMATTAGDETAILSW aftd
;
155 struct MSACM_FillFormatData affd
;
157 memset(&aftd
, 0, sizeof(aftd
));
158 aftd
.cbStruct
= sizeof(aftd
);
161 affd
.mode
= WINE_ACMFF_TAG
;
164 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
165 if (SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
166 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
, CB_SETCURSEL
, 0, 0);
170 static BOOL
MSACM_FillFormat(HWND hWnd
, PACMFORMATCHOOSEW afc
)
172 ACMFORMATTAGDETAILSW aftd
;
173 struct MSACM_FillFormatData affd
;
175 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_RESETCONTENT
, 0, 0);
177 memset(&aftd
, 0, sizeof(aftd
));
178 aftd
.cbStruct
= sizeof(aftd
);
181 affd
.mode
= WINE_ACMFF_FORMAT
;
183 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
185 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
187 (LPARAM
)affd
.szFormatTag
);
189 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
190 if (SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_GETCURSEL
, 0, 0) == CB_ERR
)
191 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMAT
, CB_SETCURSEL
, 0, 0);
195 static MMRESULT
MSACM_GetWFX(HWND hWnd
, PACMFORMATCHOOSEW afc
)
197 ACMFORMATTAGDETAILSW aftd
;
198 struct MSACM_FillFormatData affd
;
200 memset(&aftd
, 0, sizeof(aftd
));
201 aftd
.cbStruct
= sizeof(aftd
);
204 affd
.mode
= WINE_ACMFF_WFX
;
206 affd
.ret
= MMSYSERR_NOERROR
;
207 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
209 SendDlgItemMessageW(hWnd
, IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
,
211 (LPARAM
)affd
.szFormatTag
);
213 acmFormatTagEnumW(NULL
, &aftd
, MSACM_FillFormatTagsCB
, (DWORD_PTR
)&affd
, 0);
217 static const WCHAR fmt_prop
[] = {'a','c','m','p','r','o','p','\0'};
219 static INT_PTR CALLBACK
FormatChooseDlgProc(HWND hWnd
, UINT msg
,
220 WPARAM wParam
, LPARAM lParam
)
222 PACMFORMATCHOOSEW afc
= (PACMFORMATCHOOSEW
)GetPropW(hWnd
, fmt_prop
);
224 TRACE("hwnd=%p msg=%i 0x%08lx 0x%08lx\n", hWnd
, msg
, wParam
, lParam
);
228 afc
= (PACMFORMATCHOOSEW
)lParam
;
229 SetPropW(hWnd
, fmt_prop
, (HANDLE
)afc
);
230 MSACM_FillFormatTags(hWnd
, afc
);
231 MSACM_FillFormat(hWnd
, afc
);
232 if ((afc
->fdwStyle
& ~(ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
|
233 ACMFORMATCHOOSE_STYLEF_SHOWHELP
|
234 ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT
|
235 ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE
|
236 ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE
)) != 0)
237 FIXME("Unsupported style %08x\n", afc
->fdwStyle
);
238 if (!(afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
))
239 ShowWindow(GetDlgItem(hWnd
, IDD_ACMFORMATCHOOSE_BTN_HELP
), SW_HIDE
);
243 switch (LOWORD(wParam
)) {
245 EndDialog(hWnd
, MSACM_GetWFX(hWnd
, afc
));
248 EndDialog(hWnd
, ACMERR_CANCELED
);
250 case IDD_ACMFORMATCHOOSE_CMB_FORMATTAG
:
251 switch (HIWORD(wParam
)) {
253 MSACM_FillFormat(hWnd
, afc
);
256 TRACE("Dropped dlgNotif (fmtTag): 0x%08x 0x%08lx\n",
257 HIWORD(wParam
), lParam
);
261 case IDD_ACMFORMATCHOOSE_BTN_HELP
:
262 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_SHOWHELP
)
263 SendMessageW(afc
->hwndOwner
,
264 RegisterWindowMessageW(ACMHELPMSGSTRINGW
), 0L, 0L);
268 TRACE("Dropped dlgCmd: ctl=%d ntf=0x%04x 0x%08lx\n",
269 LOWORD(wParam
), HIWORD(wParam
), lParam
);
274 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
275 SendMessageW(afc
->hwndOwner
,
276 RegisterWindowMessageW(ACMHELPMSGCONTEXTMENUW
),
279 #if defined(WM_CONTEXTHELP)
281 if (afc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_CONTEXTHELP
)
282 SendMessageW(afc
->hwndOwner
,
283 RegisterWindowMessageW(ACMHELPMSGCONTEXTHELPW
),
288 TRACE("Dropped dlgMsg: hwnd=%p msg=%i 0x%08lx 0x%08lx\n",
289 hWnd
, msg
, wParam
, lParam
);
295 /***********************************************************************
296 * acmFormatChooseA (MSACM32.@)
298 MMRESULT WINAPI
acmFormatChooseA(PACMFORMATCHOOSEA pafmtc
)
300 ACMFORMATCHOOSEW afcw
;
307 if (pafmtc
->cbStruct
< sizeof(ACMFORMATCHOOSEA
))
308 return MMSYSERR_INVALPARAM
;
310 afcw
.cbStruct
= sizeof(afcw
);
311 afcw
.fdwStyle
= pafmtc
->fdwStyle
;
312 afcw
.hwndOwner
= pafmtc
->hwndOwner
;
313 afcw
.pwfx
= pafmtc
->pwfx
;
314 afcw
.cbwfx
= pafmtc
->cbwfx
;
315 if (pafmtc
->pszTitle
)
317 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTitle
, -1, NULL
, 0);
318 if (!(title
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
320 ret
= MMSYSERR_NOMEM
;
323 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTitle
, -1, title
, sz
);
325 afcw
.pszTitle
= title
;
328 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszName
, -1, NULL
, 0);
329 if (!(name
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
331 ret
= MMSYSERR_NOMEM
;
334 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszName
, -1, name
, sz
);
337 afcw
.cchName
= pafmtc
->cchName
;
338 afcw
.fdwEnum
= pafmtc
->fdwEnum
;
339 afcw
.pwfxEnum
= pafmtc
->pwfxEnum
;
340 afcw
.hInstance
= pafmtc
->hInstance
;
341 if (pafmtc
->pszTemplateName
)
343 sz
= MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTemplateName
, -1, NULL
, 0);
344 if (!(templ
= HeapAlloc(GetProcessHeap(), 0, sz
* sizeof(WCHAR
))))
346 ret
= MMSYSERR_NOMEM
;
349 MultiByteToWideChar(CP_ACP
, 0, pafmtc
->pszTemplateName
, -1, templ
, sz
);
351 afcw
.pszTemplateName
= templ
;
352 /* FIXME: hook procs not supported yet */
355 FIXME("Unsupported hook procs\n");
356 ret
= MMSYSERR_NOTSUPPORTED
;
359 ret
= acmFormatChooseW(&afcw
);
360 if (ret
== MMSYSERR_NOERROR
)
362 WideCharToMultiByte(CP_ACP
, 0, afcw
.szFormatTag
, -1, pafmtc
->szFormatTag
, sizeof(pafmtc
->szFormatTag
),
364 WideCharToMultiByte(CP_ACP
, 0, afcw
.szFormat
, -1, pafmtc
->szFormat
, sizeof(pafmtc
->szFormat
),
367 WideCharToMultiByte(CP_ACP
, 0, afcw
.pszName
, -1, pafmtc
->pszName
, pafmtc
->cchName
, NULL
, NULL
);
370 HeapFree(GetProcessHeap(), 0, title
);
371 HeapFree(GetProcessHeap(), 0, name
);
372 HeapFree(GetProcessHeap(), 0, templ
);
376 /***********************************************************************
377 * acmFormatChooseW (MSACM32.@)
379 MMRESULT WINAPI
acmFormatChooseW(PACMFORMATCHOOSEW pafmtc
)
381 if (pafmtc
->cbStruct
< sizeof(ACMFORMATCHOOSEW
))
382 return MMSYSERR_INVALPARAM
;
385 return MMSYSERR_INVALPARAM
;
387 if (pafmtc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATEHANDLE
)
388 return DialogBoxIndirectParamW(MSACM_hInstance32
, (LPCDLGTEMPLATEW
)pafmtc
->hInstance
,
389 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
391 if (pafmtc
->fdwStyle
& ACMFORMATCHOOSE_STYLEF_ENABLETEMPLATE
)
392 return DialogBoxParamW(pafmtc
->hInstance
, pafmtc
->pszTemplateName
,
393 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
395 return DialogBoxParamW(MSACM_hInstance32
, MAKEINTRESOURCEW(DLG_ACMFORMATCHOOSE_ID
),
396 pafmtc
->hwndOwner
, FormatChooseDlgProc
, (LPARAM
)pafmtc
);
399 /***********************************************************************
400 * acmFormatDetailsA (MSACM32.@)
402 MMRESULT WINAPI
acmFormatDetailsA(HACMDRIVER had
, PACMFORMATDETAILSA pafd
,
405 ACMFORMATDETAILSW afdw
;
409 return MMSYSERR_INVALPARAM
;
411 memset(&afdw
, 0, sizeof(afdw
));
412 afdw
.cbStruct
= sizeof(afdw
);
413 afdw
.dwFormatIndex
= pafd
->dwFormatIndex
;
414 afdw
.dwFormatTag
= pafd
->dwFormatTag
;
415 afdw
.fdwSupport
= pafd
->fdwSupport
;
416 afdw
.pwfx
= pafd
->pwfx
;
417 afdw
.cbwfx
= pafd
->cbwfx
;
419 mmr
= acmFormatDetailsW(had
, &afdw
, fdwDetails
);
420 if (mmr
== MMSYSERR_NOERROR
) {
421 pafd
->dwFormatTag
= afdw
.dwFormatTag
;
422 pafd
->fdwSupport
= afdw
.fdwSupport
;
423 WideCharToMultiByte( CP_ACP
, 0, afdw
.szFormat
, -1,
424 pafd
->szFormat
, sizeof(pafd
->szFormat
), NULL
, NULL
);
429 /***********************************************************************
430 * acmFormatDetailsW (MSACM32.@)
432 MMRESULT WINAPI
acmFormatDetailsW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
, DWORD fdwDetails
)
435 static const WCHAR fmt1
[] = {'%','d',' ','H','z',0};
436 static const WCHAR fmt2
[] = {';',' ','%','d',' ','b','i','t','s',0};
437 ACMFORMATTAGDETAILSW aftd
= {0};
439 TRACE("(%p, %p, %d)\n", had
, pafd
, fdwDetails
);
442 return MMSYSERR_INVALPARAM
;
444 if (pafd
->cbStruct
< sizeof(*pafd
)) return MMSYSERR_INVALPARAM
;
447 return MMSYSERR_INVALPARAM
;
449 if (pafd
->cbwfx
< sizeof(PCMWAVEFORMAT
))
450 return MMSYSERR_INVALPARAM
;
452 if (pafd
->fdwSupport
)
453 return MMSYSERR_INVALPARAM
;
455 if (pafd
->dwFormatTag
== WAVE_FORMAT_UNKNOWN
)
456 return MMSYSERR_INVALPARAM
;
458 switch (fdwDetails
) {
459 case ACM_FORMATDETAILSF_FORMAT
:
460 if (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
) {
461 mmr
= MMSYSERR_INVALPARAM
;
465 PWINE_ACMDRIVERID padid
;
467 mmr
= ACMERR_NOTPOSSIBLE
;
468 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
469 /* should check for codec only */
470 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
471 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
472 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
473 acmDriverClose(had
, 0);
474 if (mmr
== MMSYSERR_NOERROR
) break;
478 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
481 case ACM_FORMATDETAILSF_INDEX
:
482 aftd
.cbStruct
= sizeof(aftd
);
483 aftd
.dwFormatTag
= pafd
->dwFormatTag
;
484 mmr
= acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_FORMATTAG
);
485 if (mmr
!= MMSYSERR_NOERROR
)
487 if (pafd
->dwFormatIndex
>= aftd
.cStandardFormats
)
489 mmr
= MMSYSERR_INVALPARAM
;
492 mmr
= MSACM_Message(had
, ACMDM_FORMAT_DETAILS
, (LPARAM
)pafd
, fdwDetails
);
495 WARN("Unknown fdwDetails %08x\n", fdwDetails
);
496 mmr
= MMSYSERR_INVALFLAG
;
500 if (mmr
== MMSYSERR_NOERROR
&& pafd
->szFormat
[0] == 0) {
501 wsprintfW(pafd
->szFormat
, fmt1
, pafd
->pwfx
->nSamplesPerSec
);
502 if (pafd
->pwfx
->wBitsPerSample
) {
503 wsprintfW(pafd
->szFormat
+ lstrlenW(pafd
->szFormat
), fmt2
,
504 pafd
->pwfx
->wBitsPerSample
);
506 MultiByteToWideChar(CP_ACP
, 0, (pafd
->pwfx
->nChannels
== 1) ? "; Mono" : "; Stereo", -1,
507 pafd
->szFormat
+ strlenW(pafd
->szFormat
),
508 ARRAY_SIZE(pafd
->szFormat
) - strlenW(pafd
->szFormat
));
511 TRACE("=> %d\n", mmr
);
515 struct MSACM_FormatEnumWtoA_Instance
{
516 PACMFORMATDETAILSA pafda
;
517 DWORD_PTR dwInstance
;
518 ACMFORMATENUMCBA fnCallback
;
521 static BOOL CALLBACK
MSACM_FormatEnumCallbackWtoA(HACMDRIVERID hadid
,
522 PACMFORMATDETAILSW pafdw
,
523 DWORD_PTR dwInstance
,
526 struct MSACM_FormatEnumWtoA_Instance
* pafei
;
528 pafei
= (struct MSACM_FormatEnumWtoA_Instance
*)dwInstance
;
530 pafei
->pafda
->dwFormatIndex
= pafdw
->dwFormatIndex
;
531 pafei
->pafda
->dwFormatTag
= pafdw
->dwFormatTag
;
532 pafei
->pafda
->fdwSupport
= pafdw
->fdwSupport
;
533 WideCharToMultiByte( CP_ACP
, 0, pafdw
->szFormat
, -1,
534 pafei
->pafda
->szFormat
, sizeof(pafei
->pafda
->szFormat
), NULL
, NULL
);
536 return (pafei
->fnCallback
)(hadid
, pafei
->pafda
,
537 pafei
->dwInstance
, fdwSupport
);
540 /***********************************************************************
541 * acmFormatEnumA (MSACM32.@)
543 MMRESULT WINAPI
acmFormatEnumA(HACMDRIVER had
, PACMFORMATDETAILSA pafda
,
544 ACMFORMATENUMCBA fnCallback
,
545 DWORD_PTR dwInstance
, DWORD fdwEnum
)
547 ACMFORMATDETAILSW afdw
;
548 struct MSACM_FormatEnumWtoA_Instance afei
;
551 return MMSYSERR_INVALPARAM
;
554 return MMSYSERR_INVALPARAM
;
556 if (pafda
->cbStruct
< sizeof(*pafda
))
557 return MMSYSERR_INVALPARAM
;
559 memset(&afdw
, 0, sizeof(afdw
));
560 afdw
.cbStruct
= sizeof(afdw
);
561 afdw
.dwFormatIndex
= pafda
->dwFormatIndex
;
562 afdw
.dwFormatTag
= pafda
->dwFormatTag
;
563 afdw
.fdwSupport
= pafda
->fdwSupport
;
564 afdw
.pwfx
= pafda
->pwfx
;
565 afdw
.cbwfx
= pafda
->cbwfx
;
568 afei
.dwInstance
= dwInstance
;
569 afei
.fnCallback
= fnCallback
;
571 return acmFormatEnumW(had
, &afdw
, MSACM_FormatEnumCallbackWtoA
,
572 (DWORD_PTR
)&afei
, fdwEnum
);
575 /***********************************************************************
576 * acmFormatEnumW (MSACM32.@)
578 static BOOL
MSACM_FormatEnumHelper(PWINE_ACMDRIVERID padid
, HACMDRIVER had
,
579 PACMFORMATDETAILSW pafd
, PWAVEFORMATEX pwfxRef
,
580 ACMFORMATENUMCBW fnCallback
,
581 DWORD_PTR dwInstance
, DWORD fdwEnum
)
583 ACMFORMATTAGDETAILSW aftd
;
586 if (fdwEnum
& ACM_FORMATENUMF_SUGGEST
) {
588 ACMDRVFORMATSUGGEST adfs
;
589 pafd
->dwFormatIndex
= 0;
590 memset(&aftd
, 0, sizeof(aftd
));
591 aftd
.cbStruct
= sizeof(aftd
);
592 memset(&adfs
, 0, sizeof(adfs
));
593 adfs
.cbStruct
= sizeof(adfs
);
595 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
596 aftd
.dwFormatTag
= i
;
597 pafd
->dwFormatTag
= aftd
.dwFormatTag
;
598 pafd
->pwfx
->wFormatTag
= pafd
->dwFormatTag
;
600 if (acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
603 adfs
.cbwfxSrc
= aftd
.cbFormatSize
;
604 adfs
.cbwfxDst
= aftd
.cbFormatSize
;
605 adfs
.pwfxSrc
= pwfxRef
;
606 adfs
.pwfxDst
= pafd
->pwfx
;
607 pafd
->fdwSupport
= padid
->fdwSupport
;
609 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) &&
610 aftd
.dwFormatTag
!= pwfxRef
->wFormatTag
)
613 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
614 !(pafd
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_HARDWARE
))
617 hdrvr
= OpenDriver(padid
->pszFileName
,0,0);
618 SendDriverMessage(hdrvr
,ACMDM_FORMAT_SUGGEST
,(LPARAM
)&adfs
,(fdwEnum
& 0x000000FFL
));
620 if (acmFormatDetailsW(had
, pafd
, ACM_FORMATDETAILSF_FORMAT
) != MMSYSERR_NOERROR
)
623 pafd
->cbwfx
= sizeof(*(pafd
->pwfx
));
625 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
629 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
630 memset(&aftd
, 0, sizeof(aftd
));
631 aftd
.cbStruct
= sizeof(aftd
);
632 aftd
.dwFormatTagIndex
= i
;
633 if (acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
636 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) && aftd
.dwFormatTag
!= pwfxRef
->wFormatTag
)
639 for (j
= 0; j
< aftd
.cStandardFormats
; j
++) {
640 pafd
->dwFormatIndex
= j
;
641 pafd
->dwFormatTag
= aftd
.dwFormatTag
;
642 pafd
->fdwSupport
= 0;
643 if (acmFormatDetailsW(had
, pafd
, ACM_FORMATDETAILSF_INDEX
) != MMSYSERR_NOERROR
)
646 if ((fdwEnum
& ACM_FORMATENUMF_NCHANNELS
) &&
647 pafd
->pwfx
->nChannels
!= pwfxRef
->nChannels
)
649 if ((fdwEnum
& ACM_FORMATENUMF_NSAMPLESPERSEC
) &&
650 pafd
->pwfx
->nSamplesPerSec
!= pwfxRef
->nSamplesPerSec
)
652 if ((fdwEnum
& ACM_FORMATENUMF_WBITSPERSAMPLE
) &&
653 pafd
->pwfx
->wBitsPerSample
!= pwfxRef
->wBitsPerSample
)
655 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
656 !(pafd
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_HARDWARE
))
659 /* more checks to be done on fdwEnum */
661 if (!(fnCallback
)((HACMDRIVERID
)padid
, pafd
, dwInstance
, padid
->fdwSupport
))
664 /* the "formats" used by the filters are also reported */
670 /**********************************************************************/
672 MMRESULT WINAPI
acmFormatEnumW(HACMDRIVER had
, PACMFORMATDETAILSW pafd
,
673 ACMFORMATENUMCBW fnCallback
,
674 DWORD_PTR dwInstance
, DWORD fdwEnum
)
676 PWINE_ACMDRIVERID padid
;
682 TRACE("(%p, %p, %p, %ld, %d)\n",
683 had
, pafd
, fnCallback
, dwInstance
, fdwEnum
);
686 return MMSYSERR_INVALPARAM
;
689 return MMSYSERR_INVALPARAM
;
691 if (pafd
->cbStruct
< sizeof(*pafd
))
692 return MMSYSERR_INVALPARAM
;
694 if (pafd
->fdwSupport
)
695 return MMSYSERR_INVALPARAM
;
698 return MMSYSERR_INVALPARAM
;
700 if (fdwEnum
& (ACM_FORMATENUMF_WFORMATTAG
|ACM_FORMATENUMF_NCHANNELS
|
701 ACM_FORMATENUMF_NSAMPLESPERSEC
|ACM_FORMATENUMF_WBITSPERSAMPLE
|
702 ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_SUGGEST
))
703 wfxRef
= *pafd
->pwfx
;
705 if ((fdwEnum
& ACM_FORMATENUMF_HARDWARE
) &&
706 !(fdwEnum
& (ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
)))
707 return MMSYSERR_INVALPARAM
;
709 if ((fdwEnum
& ACM_FORMATENUMF_WFORMATTAG
) &&
710 (pafd
->dwFormatTag
!= pafd
->pwfx
->wFormatTag
))
711 return MMSYSERR_INVALPARAM
;
713 if (fdwEnum
& (ACM_FORMATENUMF_CONVERT
|ACM_FORMATENUMF_INPUT
|ACM_FORMATENUMF_OUTPUT
))
714 FIXME("Unsupported fdwEnum values %08x\n", fdwEnum
);
716 mmr
= acmMetrics((HACMOBJ
)had
, ACM_METRIC_MAX_SIZE_FORMAT
, &cbwfxMax
);
717 if (mmr
!= MMSYSERR_NOERROR
)
719 if (pafd
->cbwfx
< cbwfxMax
)
720 return MMSYSERR_INVALPARAM
;
725 if (acmDriverID((HACMOBJ
)had
, &hadid
, 0) != MMSYSERR_NOERROR
)
726 return MMSYSERR_INVALHANDLE
;
727 MSACM_FormatEnumHelper(MSACM_GetDriverID(hadid
), had
, pafd
, &wfxRef
,
728 fnCallback
, dwInstance
, fdwEnum
);
729 return MMSYSERR_NOERROR
;
731 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
732 /* should check for codec only */
733 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
734 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
736 ret
= MSACM_FormatEnumHelper(padid
, had
, pafd
, &wfxRef
,
737 fnCallback
, dwInstance
, fdwEnum
);
738 acmDriverClose(had
, 0);
741 return MMSYSERR_NOERROR
;
744 /***********************************************************************
745 * acmFormatSuggest (MSACM32.@)
747 MMRESULT WINAPI
acmFormatSuggest(HACMDRIVER had
, PWAVEFORMATEX pwfxSrc
,
748 PWAVEFORMATEX pwfxDst
, DWORD cbwfxDst
, DWORD fdwSuggest
)
750 ACMFORMATTAGDETAILSW aftd
= {0};
751 ACMDRVFORMATSUGGEST adfg
;
754 TRACE("(%p, %p, %p, %d, %d)\n",
755 had
, pwfxSrc
, pwfxDst
, cbwfxDst
, fdwSuggest
);
757 if (!pwfxSrc
|| !pwfxDst
)
758 return MMSYSERR_INVALPARAM
;
760 if (fdwSuggest
& ~(ACM_FORMATSUGGESTF_NCHANNELS
|ACM_FORMATSUGGESTF_NSAMPLESPERSEC
|
761 ACM_FORMATSUGGESTF_WBITSPERSAMPLE
|ACM_FORMATSUGGESTF_WFORMATTAG
))
762 return MMSYSERR_INVALFLAG
;
764 /* if we were given PCM, try to convert to PCM */
765 if (pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&& !had
&&
766 !(fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
))
768 ACMFORMATDETAILSW afd
= {0};
769 afd
.cbStruct
= sizeof(afd
);
770 afd
.dwFormatTag
= WAVE_FORMAT_PCM
;
772 afd
.cbwfx
= sizeof(PCMWAVEFORMAT
);
773 if (!acmFormatDetailsW(had
, &afd
, ACM_FORMATDETAILSF_FORMAT
))
775 memcpy(pwfxDst
, pwfxSrc
, sizeof(PCMWAVEFORMAT
));
776 return MMSYSERR_NOERROR
;
780 aftd
.cbStruct
= sizeof(aftd
);
781 if (fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
)
782 aftd
.dwFormatTag
= pwfxDst
->wFormatTag
;
783 mmr
= acmFormatTagDetailsW(had
, &aftd
, ACM_FORMATTAGDETAILSF_LARGESTSIZE
);
784 if ((fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
) && mmr
== ACMERR_NOTPOSSIBLE
)
785 return ACMERR_NOTPOSSIBLE
;
787 if (cbwfxDst
< aftd
.cbFormatSize
)
788 return MMSYSERR_INVALPARAM
;
790 adfg
.cbStruct
= sizeof(adfg
);
791 adfg
.fdwSuggest
= fdwSuggest
;
792 adfg
.pwfxSrc
= pwfxSrc
;
793 adfg
.cbwfxSrc
= (pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
) ?
794 sizeof(WAVEFORMATEX
) : (sizeof(WAVEFORMATEX
) + pwfxSrc
->cbSize
);
795 adfg
.pwfxDst
= pwfxDst
;
796 adfg
.cbwfxDst
= cbwfxDst
;
799 PWINE_ACMDRIVERID padid
;
801 /* MS doc says: ACM finds the best suggestion.
802 * Well, first found will be the "best"
804 mmr
= ACMERR_NOTPOSSIBLE
;
805 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
806 /* should check for codec only */
807 if ((padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) ||
808 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) != MMSYSERR_NOERROR
)
811 if (MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L) == MMSYSERR_NOERROR
) {
812 mmr
= MMSYSERR_NOERROR
;
815 acmDriverClose(had
, 0);
818 mmr
= MSACM_Message(had
, ACMDM_FORMAT_SUGGEST
, (LPARAM
)&adfg
, 0L);
823 /***********************************************************************
824 * acmFormatTagDetailsA (MSACM32.@)
826 MMRESULT WINAPI
acmFormatTagDetailsA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
829 ACMFORMATTAGDETAILSW aftdw
;
832 memset(&aftdw
, 0, sizeof(aftdw
));
833 aftdw
.cbStruct
= sizeof(aftdw
);
834 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
835 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
837 mmr
= acmFormatTagDetailsW(had
, &aftdw
, fdwDetails
);
838 if (mmr
== MMSYSERR_NOERROR
) {
839 paftda
->dwFormatTag
= aftdw
.dwFormatTag
;
840 paftda
->dwFormatTagIndex
= aftdw
.dwFormatTagIndex
;
841 paftda
->cbFormatSize
= aftdw
.cbFormatSize
;
842 paftda
->fdwSupport
= aftdw
.fdwSupport
;
843 paftda
->cStandardFormats
= aftdw
.cStandardFormats
;
844 WideCharToMultiByte( CP_ACP
, 0, aftdw
.szFormatTag
, -1, paftda
->szFormatTag
,
845 sizeof(paftda
->szFormatTag
), NULL
, NULL
);
850 /***********************************************************************
851 * acmFormatTagDetailsW (MSACM32.@)
853 MMRESULT WINAPI
acmFormatTagDetailsW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
856 PWINE_ACMDRIVERID padid
;
857 MMRESULT mmr
= ACMERR_NOTPOSSIBLE
;
859 TRACE("(%p, %p, %d)\n", had
, paftd
, fdwDetails
);
861 if (fdwDetails
& ~(ACM_FORMATTAGDETAILSF_FORMATTAG
|ACM_FORMATTAGDETAILSF_INDEX
|
862 ACM_FORMATTAGDETAILSF_LARGESTSIZE
))
863 return MMSYSERR_INVALFLAG
;
865 switch (fdwDetails
) {
866 case ACM_FORMATTAGDETAILSF_FORMATTAG
:
868 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
869 /* should check for codec only */
870 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
871 MSACM_FindFormatTagInCache(padid
, paftd
->dwFormatTag
, NULL
) &&
872 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
873 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
874 acmDriverClose(had
, 0);
875 if (mmr
== MMSYSERR_NOERROR
) break;
879 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
881 if (pad
&& MSACM_FindFormatTagInCache(pad
->obj
.pACMDriverID
, paftd
->dwFormatTag
, NULL
))
882 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
886 case ACM_FORMATTAGDETAILSF_INDEX
:
888 PWINE_ACMDRIVER pad
= MSACM_GetDriver(had
);
890 if (pad
&& paftd
->dwFormatTagIndex
< pad
->obj
.pACMDriverID
->cFormatTags
)
891 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
895 case ACM_FORMATTAGDETAILSF_LARGESTSIZE
:
897 ACMFORMATTAGDETAILSW tmp
;
898 DWORD ft
= paftd
->dwFormatTag
;
900 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
901 /* should check for codec only */
902 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
903 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == 0) {
905 memset(&tmp
, 0, sizeof(tmp
));
906 tmp
.cbStruct
= sizeof(tmp
);
907 tmp
.dwFormatTag
= ft
;
909 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
910 (LPARAM
)&tmp
, fdwDetails
) == MMSYSERR_NOERROR
) {
911 if (mmr
== ACMERR_NOTPOSSIBLE
||
912 paftd
->cbFormatSize
< tmp
.cbFormatSize
) {
914 mmr
= MMSYSERR_NOERROR
;
917 acmDriverClose(had
, 0);
921 mmr
= MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
, (LPARAM
)paftd
, fdwDetails
);
926 WARN("Unsupported fdwDetails=%08x\n", fdwDetails
);
927 mmr
= MMSYSERR_ERROR
;
930 if (mmr
== MMSYSERR_NOERROR
&&
931 paftd
->dwFormatTag
== WAVE_FORMAT_PCM
&& paftd
->szFormatTag
[0] == 0)
932 MultiByteToWideChar(CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
933 ARRAY_SIZE(paftd
->szFormatTag
));
938 struct MSACM_FormatTagEnumWtoA_Instance
{
939 PACMFORMATTAGDETAILSA paftda
;
940 DWORD_PTR dwInstance
;
941 ACMFORMATTAGENUMCBA fnCallback
;
944 static BOOL CALLBACK
MSACM_FormatTagEnumCallbackWtoA(HACMDRIVERID hadid
,
945 PACMFORMATTAGDETAILSW paftdw
,
946 DWORD_PTR dwInstance
,
949 struct MSACM_FormatTagEnumWtoA_Instance
* paftei
;
951 paftei
= (struct MSACM_FormatTagEnumWtoA_Instance
*)dwInstance
;
953 paftei
->paftda
->dwFormatTagIndex
= paftdw
->dwFormatTagIndex
;
954 paftei
->paftda
->dwFormatTag
= paftdw
->dwFormatTag
;
955 paftei
->paftda
->cbFormatSize
= paftdw
->cbFormatSize
;
956 paftei
->paftda
->fdwSupport
= paftdw
->fdwSupport
;
957 paftei
->paftda
->cStandardFormats
= paftdw
->cStandardFormats
;
958 WideCharToMultiByte( CP_ACP
, 0, paftdw
->szFormatTag
, -1, paftei
->paftda
->szFormatTag
,
959 sizeof(paftei
->paftda
->szFormatTag
), NULL
, NULL
);
961 return (paftei
->fnCallback
)(hadid
, paftei
->paftda
,
962 paftei
->dwInstance
, fdwSupport
);
965 /***********************************************************************
966 * acmFormatTagEnumA (MSACM32.@)
968 MMRESULT WINAPI
acmFormatTagEnumA(HACMDRIVER had
, PACMFORMATTAGDETAILSA paftda
,
969 ACMFORMATTAGENUMCBA fnCallback
,
970 DWORD_PTR dwInstance
, DWORD fdwEnum
)
972 ACMFORMATTAGDETAILSW aftdw
;
973 struct MSACM_FormatTagEnumWtoA_Instance aftei
;
976 return MMSYSERR_INVALPARAM
;
978 if (paftda
->cbStruct
< sizeof(*paftda
))
979 return MMSYSERR_INVALPARAM
;
982 return MMSYSERR_INVALFLAG
;
984 memset(&aftdw
, 0, sizeof(aftdw
));
985 aftdw
.cbStruct
= sizeof(aftdw
);
986 aftdw
.dwFormatTagIndex
= paftda
->dwFormatTagIndex
;
987 aftdw
.dwFormatTag
= paftda
->dwFormatTag
;
989 aftei
.paftda
= paftda
;
990 aftei
.dwInstance
= dwInstance
;
991 aftei
.fnCallback
= fnCallback
;
993 return acmFormatTagEnumW(had
, &aftdw
, MSACM_FormatTagEnumCallbackWtoA
,
994 (DWORD_PTR
)&aftei
, fdwEnum
);
997 /***********************************************************************
998 * acmFormatTagEnumW (MSACM32.@)
1000 MMRESULT WINAPI
acmFormatTagEnumW(HACMDRIVER had
, PACMFORMATTAGDETAILSW paftd
,
1001 ACMFORMATTAGENUMCBW fnCallback
,
1002 DWORD_PTR dwInstance
, DWORD fdwEnum
)
1004 PWINE_ACMDRIVERID padid
;
1006 BOOL bPcmDone
= FALSE
;
1008 TRACE("(%p, %p, %p, %ld, %d)\n",
1009 had
, paftd
, fnCallback
, dwInstance
, fdwEnum
);
1012 return MMSYSERR_INVALPARAM
;
1014 if (paftd
->cbStruct
< sizeof(*paftd
))
1015 return MMSYSERR_INVALPARAM
;
1018 return MMSYSERR_INVALFLAG
;
1020 /* (WS) MSDN info page says that if had != 0, then we should find
1021 * the specific driver to get its tags from. Therefore I'm removing
1022 * the FIXME call and adding a search block below. It also seems
1023 * that the lack of this functionality was the responsible for
1024 * codecs to be multiply and incorrectly listed.
1027 /* if (had) FIXME("had != NULL, not supported\n"); */
1030 if (acmDriverID((HACMOBJ
)had
, (HACMDRIVERID
*)&padid
, 0) != MMSYSERR_NOERROR
)
1031 return MMSYSERR_INVALHANDLE
;
1033 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
1034 paftd
->dwFormatTagIndex
= i
;
1035 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
1036 (LPARAM
)paftd
, ACM_FORMATTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
1037 if (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
) {
1038 if (paftd
->szFormatTag
[0] == 0)
1039 MultiByteToWideChar(CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
1040 ARRAY_SIZE(paftd
->szFormatTag
));
1041 /* (WS) I'm preserving this PCM hack since it seems to be
1042 * correct. Please notice this block was borrowed from
1045 if (bPcmDone
) continue;
1048 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
))
1049 return MMSYSERR_NOERROR
;
1053 /* if had==0 then search for the first suitable driver */
1055 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
1056 /* should check for codec only */
1057 if (!(padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) &&
1058 acmDriverOpen(&had
, (HACMDRIVERID
)padid
, 0) == MMSYSERR_NOERROR
) {
1059 for (i
= 0; i
< padid
->cFormatTags
; i
++) {
1060 paftd
->dwFormatTagIndex
= i
;
1061 if (MSACM_Message(had
, ACMDM_FORMATTAG_DETAILS
,
1062 (LPARAM
)paftd
, ACM_FORMATTAGDETAILSF_INDEX
) == MMSYSERR_NOERROR
) {
1063 if (paftd
->dwFormatTag
== WAVE_FORMAT_PCM
) {
1064 if (paftd
->szFormatTag
[0] == 0)
1065 MultiByteToWideChar(CP_ACP
, 0, "PCM", -1, paftd
->szFormatTag
,
1066 ARRAY_SIZE(paftd
->szFormatTag
));
1067 /* FIXME (EPP): I'm not sure this is the correct
1068 * algorithm (should make more sense to apply the same
1069 * for all already loaded formats, but this will do
1072 if (bPcmDone
) continue;
1075 if (!(fnCallback
)((HACMDRIVERID
)padid
, paftd
, dwInstance
, padid
->fdwSupport
)) {
1076 acmDriverClose(had
, 0);
1077 return MMSYSERR_NOERROR
;
1081 acmDriverClose(had
, 0);
1085 return MMSYSERR_NOERROR
;