1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
6 * Copyright 1998 Patrik Stridvall
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "wine/port.h"
42 #include "wine/debug.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msacm
);
46 /***********************************************************************
47 * acmDriverAddA (MSACM32.@)
49 MMRESULT WINAPI
acmDriverAddA(PHACMDRIVERID phadid
, HINSTANCE hinstModule
,
50 LPARAM lParam
, DWORD dwPriority
, DWORD fdwAdd
)
52 TRACE("(%p, %p, %08lx, %08lx, %08lx)\n",
53 phadid
, hinstModule
, lParam
, dwPriority
, fdwAdd
);
56 WARN("invalid parameter\n");
57 return MMSYSERR_INVALPARAM
;
60 /* Check if any unknown flags */
62 ~(ACM_DRIVERADDF_FUNCTION
|ACM_DRIVERADDF_NOTIFYHWND
|
63 ACM_DRIVERADDF_GLOBAL
)) {
64 WARN("invalid flag\n");
65 return MMSYSERR_INVALFLAG
;
68 /* Check if any incompatible flags */
69 if ((fdwAdd
& ACM_DRIVERADDF_FUNCTION
) &&
70 (fdwAdd
& ACM_DRIVERADDF_NOTIFYHWND
)) {
71 WARN("invalid flag\n");
72 return MMSYSERR_INVALFLAG
;
75 /* FIXME: in fact, should GetModuleFileName(hinstModule) and do a
76 * LoadDriver on it, to be sure we can call SendDriverMessage on the
79 *phadid
= (HACMDRIVERID
) MSACM_RegisterDriver(NULL
, NULL
, hinstModule
);
81 /* FIXME: lParam, dwPriority and fdwAdd ignored */
83 return MMSYSERR_NOERROR
;
86 /***********************************************************************
87 * acmDriverAddW (MSACM32.@)
91 MMRESULT WINAPI
acmDriverAddW(PHACMDRIVERID phadid
, HINSTANCE hinstModule
,
92 LPARAM lParam
, DWORD dwPriority
, DWORD fdwAdd
)
94 FIXME("(%p, %p, %ld, %ld, %ld): stub\n",
95 phadid
, hinstModule
, lParam
, dwPriority
, fdwAdd
);
97 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
98 return MMSYSERR_ERROR
;
101 /***********************************************************************
102 * acmDriverClose (MSACM32.@)
104 MMRESULT WINAPI
acmDriverClose(HACMDRIVER had
, DWORD fdwClose
)
107 PWINE_ACMDRIVERID padid
;
108 PWINE_ACMDRIVER
* tpad
;
110 TRACE("(%p, %08lx)\n", had
, fdwClose
);
113 WARN("invalid flag\n");
114 return MMSYSERR_INVALFLAG
;
117 pad
= MSACM_GetDriver(had
);
119 WARN("invalid handle\n");
120 return MMSYSERR_INVALHANDLE
;
123 padid
= pad
->obj
.pACMDriverID
;
125 /* remove driver from list */
126 for (tpad
= &(padid
->pACMDriverList
); *tpad
; *tpad
= (*tpad
)->pNextACMDriver
) {
128 *tpad
= (*tpad
)->pNextACMDriver
;
133 /* close driver if it has been opened */
134 if (pad
->hDrvr
&& !padid
->hInstModule
)
135 CloseDriver(pad
->hDrvr
, 0, 0);
137 HeapFree(MSACM_hHeap
, 0, pad
);
139 return MMSYSERR_NOERROR
;
142 /***********************************************************************
143 * acmDriverDetailsA (MSACM32.@)
145 MMRESULT WINAPI
acmDriverDetailsA(HACMDRIVERID hadid
, PACMDRIVERDETAILSA padd
, DWORD fdwDetails
)
148 ACMDRIVERDETAILSW addw
;
150 TRACE("(%p, %p, %08lx)\n", hadid
, padd
, fdwDetails
);
153 WARN("invalid parameter\n");
154 return MMSYSERR_INVALPARAM
;
157 if (padd
->cbStruct
< 4) {
158 WARN("invalid parameter\n");
159 return MMSYSERR_INVALPARAM
;
162 addw
.cbStruct
= sizeof(addw
);
163 mmr
= acmDriverDetailsW(hadid
, &addw
, fdwDetails
);
165 ACMDRIVERDETAILSA padda
;
167 padda
.fccType
= addw
.fccType
;
168 padda
.fccComp
= addw
.fccComp
;
169 padda
.wMid
= addw
.wMid
;
170 padda
.wPid
= addw
.wPid
;
171 padda
.vdwACM
= addw
.vdwACM
;
172 padda
.vdwDriver
= addw
.vdwDriver
;
173 padda
.fdwSupport
= addw
.fdwSupport
;
174 padda
.cFormatTags
= addw
.cFormatTags
;
175 padda
.cFilterTags
= addw
.cFilterTags
;
176 padda
.hicon
= addw
.hicon
;
177 WideCharToMultiByte( CP_ACP
, 0, addw
.szShortName
, -1, padda
.szShortName
,
178 sizeof(padda
.szShortName
), NULL
, NULL
);
179 WideCharToMultiByte( CP_ACP
, 0, addw
.szLongName
, -1, padda
.szLongName
,
180 sizeof(padda
.szLongName
), NULL
, NULL
);
181 WideCharToMultiByte( CP_ACP
, 0, addw
.szCopyright
, -1, padda
.szCopyright
,
182 sizeof(padda
.szCopyright
), NULL
, NULL
);
183 WideCharToMultiByte( CP_ACP
, 0, addw
.szLicensing
, -1, padda
.szLicensing
,
184 sizeof(padda
.szLicensing
), NULL
, NULL
);
185 WideCharToMultiByte( CP_ACP
, 0, addw
.szFeatures
, -1, padda
.szFeatures
,
186 sizeof(padda
.szFeatures
), NULL
, NULL
);
187 memcpy(padd
, &padda
, min(padd
->cbStruct
, sizeof(*padd
)));
192 /***********************************************************************
193 * acmDriverDetailsW (MSACM32.@)
195 MMRESULT WINAPI
acmDriverDetailsW(HACMDRIVERID hadid
, PACMDRIVERDETAILSW padd
, DWORD fdwDetails
)
200 TRACE("(%p, %p, %08lx)\n", hadid
, padd
, fdwDetails
);
203 WARN("invalid parameter\n");
204 return MMSYSERR_INVALPARAM
;
207 if (padd
->cbStruct
< 4) {
208 WARN("invalid parameter\n");
209 return MMSYSERR_INVALPARAM
;
213 WARN("invalid flag\n");
214 return MMSYSERR_INVALFLAG
;
217 mmr
= acmDriverOpen(&acmDrvr
, hadid
, 0);
218 if (mmr
== MMSYSERR_NOERROR
) {
219 ACMDRIVERDETAILSW paddw
;
220 mmr
= (MMRESULT
)MSACM_Message(acmDrvr
, ACMDM_DRIVER_DETAILS
, (LPARAM
)&paddw
, 0);
222 acmDriverClose(acmDrvr
, 0);
223 memcpy(padd
, &paddw
, min(padd
->cbStruct
, sizeof(*padd
)));
229 /***********************************************************************
230 * acmDriverEnum (MSACM32.@)
232 MMRESULT WINAPI
acmDriverEnum(ACMDRIVERENUMCB fnCallback
, DWORD dwInstance
, DWORD fdwEnum
)
234 PWINE_ACMDRIVERID padid
;
237 TRACE("(%p, %08lx, %08lx)\n", fnCallback
, dwInstance
, fdwEnum
);
240 WARN("invalid parameter\n");
241 return MMSYSERR_INVALPARAM
;
244 if (fdwEnum
& ~(ACM_DRIVERENUMF_NOLOCAL
|ACM_DRIVERENUMF_DISABLED
)) {
245 WARN("invalid flag\n");
246 return MMSYSERR_INVALFLAG
;
249 for (padid
= MSACM_pFirstACMDriverID
; padid
; padid
= padid
->pNextACMDriverID
) {
250 fdwSupport
= padid
->fdwSupport
;
252 if (padid
->fdwSupport
& ACMDRIVERDETAILS_SUPPORTF_DISABLED
) {
253 if (fdwEnum
& ACM_DRIVERENUMF_DISABLED
)
254 fdwSupport
|= ACMDRIVERDETAILS_SUPPORTF_DISABLED
;
258 if (!(*fnCallback
)((HACMDRIVERID
)padid
, dwInstance
, fdwSupport
))
262 return MMSYSERR_NOERROR
;
265 /***********************************************************************
266 * acmDriverID (MSACM32.@)
268 MMRESULT WINAPI
acmDriverID(HACMOBJ hao
, PHACMDRIVERID phadid
, DWORD fdwDriverID
)
272 TRACE("(%p, %p, %08lx)\n", hao
, phadid
, fdwDriverID
);
275 WARN("invalid flag\n");
276 return MMSYSERR_INVALFLAG
;
279 pao
= MSACM_GetObj(hao
, WINE_ACMOBJ_DONTCARE
);
281 WARN("invalid handle\n");
282 return MMSYSERR_INVALHANDLE
;
286 WARN("invalid parameter\n");
287 return MMSYSERR_INVALPARAM
;
290 *phadid
= (HACMDRIVERID
) pao
->pACMDriverID
;
292 return MMSYSERR_NOERROR
;
295 /***********************************************************************
296 * acmDriverMessage (MSACM32.@)
299 LRESULT WINAPI
acmDriverMessage(HACMDRIVER had
, UINT uMsg
, LPARAM lParam1
, LPARAM lParam2
)
301 TRACE("(%p, %04x, %08lx, %08lx\n", had
, uMsg
, lParam1
, lParam2
);
303 if ((uMsg
>= ACMDM_USER
&& uMsg
< ACMDM_RESERVED_LOW
) ||
304 uMsg
== ACMDM_DRIVER_ABOUT
||
305 uMsg
== DRV_QUERYCONFIGURE
||
306 uMsg
== DRV_CONFIGURE
)
307 return MSACM_Message(had
, uMsg
, lParam1
, lParam2
);
309 WARN("invalid parameter\n");
310 return MMSYSERR_INVALPARAM
;
313 /***********************************************************************
314 * acmDriverOpen (MSACM32.@)
316 MMRESULT WINAPI
acmDriverOpen(PHACMDRIVER phad
, HACMDRIVERID hadid
, DWORD fdwOpen
)
318 PWINE_ACMDRIVERID padid
;
319 PWINE_ACMDRIVER pad
= NULL
;
322 TRACE("(%p, %p, %08lu)\n", phad
, hadid
, fdwOpen
);
325 WARN("invalid parameter\n");
326 return MMSYSERR_INVALPARAM
;
330 WARN("invalid flag\n");
331 return MMSYSERR_INVALFLAG
;
334 padid
= MSACM_GetDriverID(hadid
);
336 WARN("invalid handle\n");
337 return MMSYSERR_INVALHANDLE
;
340 pad
= HeapAlloc(MSACM_hHeap
, 0, sizeof(WINE_ACMDRIVER
));
343 return MMSYSERR_NOMEM
;
346 pad
->obj
.dwType
= WINE_ACMOBJ_DRIVER
;
347 pad
->obj
.pACMDriverID
= padid
;
349 if (!(pad
->hDrvr
= (HDRVR
)padid
->hInstModule
))
351 ACMDRVOPENDESCW adod
;
354 /* this is not an externally added driver... need to actually load it */
355 if (!padid
->pszDriverAlias
)
357 ret
= MMSYSERR_ERROR
;
361 adod
.cbStruct
= sizeof(adod
);
362 adod
.fccType
= ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
;
363 adod
.fccComp
= ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
;
364 adod
.dwVersion
= acmGetVersion();
365 adod
.dwFlags
= fdwOpen
;
367 len
= strlen("Drivers32") + 1;
368 adod
.pszSectionName
= HeapAlloc(MSACM_hHeap
, 0, len
* sizeof(WCHAR
));
369 MultiByteToWideChar(CP_ACP
, 0, "Drivers32", -1, (LPWSTR
)adod
.pszSectionName
, len
);
370 adod
.pszAliasName
= padid
->pszDriverAlias
;
373 pad
->hDrvr
= OpenDriver(padid
->pszDriverAlias
, NULL
, (DWORD
)&adod
);
375 HeapFree(MSACM_hHeap
, 0, (LPWSTR
)adod
.pszSectionName
);
383 /* insert new pad at beg of list */
384 pad
->pNextACMDriver
= padid
->pACMDriverList
;
385 padid
->pACMDriverList
= pad
;
387 /* FIXME: Create a WINE_ACMDRIVER32 */
388 *phad
= (HACMDRIVER
)pad
;
389 TRACE("'%s' => %08lx\n", debugstr_w(padid
->pszDriverAlias
), (DWORD
)pad
);
391 return MMSYSERR_NOERROR
;
393 WARN("failed: ret = %08x\n", ret
);
394 if (pad
&& !pad
->hDrvr
)
395 HeapFree(MSACM_hHeap
, 0, pad
);
399 /***********************************************************************
400 * acmDriverPriority (MSACM32.@)
402 MMRESULT WINAPI
acmDriverPriority(HACMDRIVERID hadid
, DWORD dwPriority
, DWORD fdwPriority
)
404 PWINE_ACMDRIVERID padid
;
407 LONG lBufferLength
= sizeof(szBuffer
);
410 DWORD dwPriorityCounter
;
412 TRACE("(%p, %08lx, %08lx)\n", hadid
, dwPriority
, fdwPriority
);
414 padid
= MSACM_GetDriverID(hadid
);
416 WARN("invalid handle\n");
417 return MMSYSERR_INVALHANDLE
;
420 /* Check for unknown flags */
422 ~(ACM_DRIVERPRIORITYF_ENABLE
|ACM_DRIVERPRIORITYF_DISABLE
|
423 ACM_DRIVERPRIORITYF_BEGIN
|ACM_DRIVERPRIORITYF_END
)) {
424 WARN("invalid flag\n");
425 return MMSYSERR_INVALFLAG
;
428 /* Check for incompatible flags */
429 if ((fdwPriority
& ACM_DRIVERPRIORITYF_ENABLE
) &&
430 (fdwPriority
& ACM_DRIVERPRIORITYF_DISABLE
)) {
431 WARN("invalid flag\n");
432 return MMSYSERR_INVALFLAG
;
435 /* Check for incompatible flags */
436 if ((fdwPriority
& ACM_DRIVERPRIORITYF_BEGIN
) &&
437 (fdwPriority
& ACM_DRIVERPRIORITYF_END
)) {
438 WARN("invalid flag\n");
439 return MMSYSERR_INVALFLAG
;
442 lError
= RegOpenKeyA(HKEY_CURRENT_USER
,
443 "Software\\Microsoft\\Multimedia\\"
444 "Audio Compression Manager\\Priority v4.00",
447 /* FIXME: Create key */
448 if (lError
!= ERROR_SUCCESS
) {
449 WARN("RegOpenKeyA failed\n");
450 return MMSYSERR_ERROR
;
453 for (dwPriorityCounter
= 1; ; dwPriorityCounter
++) {
454 snprintf(szSubKey
, 17, "Priority%ld", dwPriorityCounter
);
455 lError
= RegQueryValueA(hPriorityKey
, szSubKey
, szBuffer
, &lBufferLength
);
456 if (lError
!= ERROR_SUCCESS
)
459 FIXME("(%p, %ld, %ld): stub (partial)\n",
460 hadid
, dwPriority
, fdwPriority
);
464 RegCloseKey(hPriorityKey
);
466 WARN("RegQueryValueA failed\n");
467 return MMSYSERR_ERROR
;
470 /***********************************************************************
471 * acmDriverRemove (MSACM32.@)
473 MMRESULT WINAPI
acmDriverRemove(HACMDRIVERID hadid
, DWORD fdwRemove
)
475 PWINE_ACMDRIVERID padid
;
477 TRACE("(%p, %08lx)\n", hadid
, fdwRemove
);
479 padid
= MSACM_GetDriverID(hadid
);
481 WARN("invalid handle\n");
482 return MMSYSERR_INVALHANDLE
;
486 WARN("invalid flag\n");
487 return MMSYSERR_INVALFLAG
;
490 MSACM_UnregisterDriver(padid
);
492 return MMSYSERR_NOERROR
;