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"
43 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(msacm);
47 /***********************************************************************
48 * acmDriverAddA (MSACM32.@)
50 MMRESULT WINAPI acmDriverAddA(PHACMDRIVERID phadid, HINSTANCE hinstModule,
51 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
54 WCHAR * driverW = NULL;
55 LPARAM lParamW = lParam;
57 TRACE("(%p, %p, %08lx, %08lx, %08lx)\n",
58 phadid, hinstModule, lParam, dwPriority, fdwAdd);
61 WARN("invalid parameter\n");
62 return MMSYSERR_INVALPARAM;
65 /* Check if any unknown flags */
67 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
68 ACM_DRIVERADDF_GLOBAL)) {
69 WARN("invalid flag\n");
70 return MMSYSERR_INVALFLAG;
73 /* Check if any incompatible flags */
74 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
75 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) {
76 WARN("invalid flag\n");
77 return MMSYSERR_INVALFLAG;
80 /* A->W translation of name */
81 if ((fdwAdd & ACM_DRIVERADDF_TYPEMASK) == ACM_DRIVERADDF_NAME) {
84 if (lParam == 0) return MMSYSERR_INVALPARAM;
85 len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)lParam, -1, NULL, 0);
86 driverW = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
87 if (!driverW) return MMSYSERR_NOMEM;
88 MultiByteToWideChar(CP_ACP, 0, (LPSTR)lParam, -1, driverW, len);
89 lParamW = (LPARAM)driverW;
92 resultW = acmDriverAddW(phadid, hinstModule, lParamW, dwPriority, fdwAdd);
93 HeapFree(MSACM_hHeap, 0, driverW);
97 /***********************************************************************
98 * acmDriverAddW (MSACM32.@)
101 MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule,
102 LPARAM lParam, DWORD dwPriority, DWORD fdwAdd)
104 TRACE("(%p, %p, %08lx, %08lx, %08lx)\n",
105 phadid, hinstModule, lParam, dwPriority, fdwAdd);
108 WARN("invalid parameter\n");
109 return MMSYSERR_INVALPARAM;
112 /* Check if any unknown flags */
114 ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND|
115 ACM_DRIVERADDF_GLOBAL)) {
116 WARN("invalid flag\n");
117 return MMSYSERR_INVALFLAG;
120 /* Check if any incompatible flags */
121 if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) &&
122 (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) {
123 WARN("invalid flag\n");
124 return MMSYSERR_INVALFLAG;
127 switch (fdwAdd & ACM_DRIVERADDF_TYPEMASK) {
128 case ACM_DRIVERADDF_NAME:
131 lParam name of value in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32
132 dwPriority (unused, set to 0)
134 *phadid = (HACMDRIVERID) MSACM_RegisterDriverFromRegistry((LPCWSTR)lParam);
136 ERR("Unable to register driver via ACM_DRIVERADDF_NAME\n");
137 return MMSYSERR_INVALPARAM;
140 case ACM_DRIVERADDF_FUNCTION:
142 hInstModule Handle of module which contains driver entry proc
143 lParam Driver function address
144 dwPriority (unused, set to 0)
146 fdwAdd &= ~ACM_DRIVERADDF_TYPEMASK;
149 FIXME("(%p, %p, %ld, %ld, %ld): ACM_DRIVERADDF_FUNCTION: stub\n", phadid, hinstModule, lParam, dwPriority, fdwAdd);
150 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
151 return MMSYSERR_ERROR;
152 case ACM_DRIVERADDF_NOTIFYHWND:
155 lParam Handle of notification window
156 dwPriority Window message to send for notification broadcasts
158 *phadid = (HACMDRIVERID) MSACM_RegisterNotificationWindow((HWND)lParam, dwPriority);
160 ERR("Unable to register driver via ACM_DRIVERADDF_NOTIFYHWND\n");
161 return MMSYSERR_INVALPARAM;
165 ERR("invalid flag value 0x%08lx for fdwAdd\n", fdwAdd & ACM_DRIVERADDF_TYPEMASK);
166 return MMSYSERR_INVALFLAG;
169 MSACM_BroadcastNotification();
170 return MMSYSERR_NOERROR;
173 /***********************************************************************
174 * acmDriverClose (MSACM32.@)
176 MMRESULT WINAPI acmDriverClose(HACMDRIVER had, DWORD fdwClose)
179 PWINE_ACMDRIVERID padid;
180 PWINE_ACMDRIVER* tpad;
182 TRACE("(%p, %08lx)\n", had, fdwClose);
185 WARN("invalid flag\n");
186 return MMSYSERR_INVALFLAG;
189 pad = MSACM_GetDriver(had);
191 WARN("invalid handle\n");
192 return MMSYSERR_INVALHANDLE;
195 padid = pad->obj.pACMDriverID;
197 /* remove driver from list */
198 for (tpad = &(padid->pACMDriverList); *tpad; tpad = &((*tpad)->pNextACMDriver)) {
200 *tpad = (*tpad)->pNextACMDriver;
205 /* close driver if it has been opened */
206 if (pad->hDrvr && !padid->hInstModule)
207 CloseDriver(pad->hDrvr, 0, 0);
209 HeapFree(MSACM_hHeap, 0, pad);
211 return MMSYSERR_NOERROR;
214 /***********************************************************************
215 * acmDriverDetailsA (MSACM32.@)
217 MMRESULT WINAPI acmDriverDetailsA(HACMDRIVERID hadid, PACMDRIVERDETAILSA padd, DWORD fdwDetails)
220 ACMDRIVERDETAILSW addw;
222 TRACE("(%p, %p, %08lx)\n", hadid, padd, fdwDetails);
225 WARN("invalid parameter\n");
226 return MMSYSERR_INVALPARAM;
229 if (padd->cbStruct < 4) {
230 WARN("invalid parameter\n");
231 return MMSYSERR_INVALPARAM;
234 addw.cbStruct = sizeof(addw);
235 mmr = acmDriverDetailsW(hadid, &addw, fdwDetails);
237 ACMDRIVERDETAILSA padda;
239 padda.fccType = addw.fccType;
240 padda.fccComp = addw.fccComp;
241 padda.wMid = addw.wMid;
242 padda.wPid = addw.wPid;
243 padda.vdwACM = addw.vdwACM;
244 padda.vdwDriver = addw.vdwDriver;
245 padda.fdwSupport = addw.fdwSupport;
246 padda.cFormatTags = addw.cFormatTags;
247 padda.cFilterTags = addw.cFilterTags;
248 padda.hicon = addw.hicon;
249 WideCharToMultiByte( CP_ACP, 0, addw.szShortName, -1, padda.szShortName,
250 sizeof(padda.szShortName), NULL, NULL );
251 WideCharToMultiByte( CP_ACP, 0, addw.szLongName, -1, padda.szLongName,
252 sizeof(padda.szLongName), NULL, NULL );
253 WideCharToMultiByte( CP_ACP, 0, addw.szCopyright, -1, padda.szCopyright,
254 sizeof(padda.szCopyright), NULL, NULL );
255 WideCharToMultiByte( CP_ACP, 0, addw.szLicensing, -1, padda.szLicensing,
256 sizeof(padda.szLicensing), NULL, NULL );
257 WideCharToMultiByte( CP_ACP, 0, addw.szFeatures, -1, padda.szFeatures,
258 sizeof(padda.szFeatures), NULL, NULL );
259 padda.cbStruct = min(padd->cbStruct, sizeof(*padd));
260 memcpy(padd, &padda, padda.cbStruct);
265 /***********************************************************************
266 * acmDriverDetailsW (MSACM32.@)
268 MMRESULT WINAPI acmDriverDetailsW(HACMDRIVERID hadid, PACMDRIVERDETAILSW padd, DWORD fdwDetails)
273 TRACE("(%p, %p, %08lx)\n", hadid, padd, fdwDetails);
276 WARN("invalid parameter\n");
277 return MMSYSERR_INVALPARAM;
280 if (padd->cbStruct < 4) {
281 WARN("invalid parameter\n");
282 return MMSYSERR_INVALPARAM;
286 WARN("invalid flag\n");
287 return MMSYSERR_INVALFLAG;
290 mmr = acmDriverOpen(&acmDrvr, hadid, 0);
291 if (mmr == MMSYSERR_NOERROR) {
292 ACMDRIVERDETAILSW paddw;
293 paddw.cbStruct = sizeof(paddw);
294 mmr = (MMRESULT)MSACM_Message(acmDrvr, ACMDM_DRIVER_DETAILS, (LPARAM)&paddw, 0);
296 acmDriverClose(acmDrvr, 0);
297 paddw.cbStruct = min(padd->cbStruct, sizeof(*padd));
298 memcpy(padd, &paddw, paddw.cbStruct);
304 /***********************************************************************
305 * acmDriverEnum (MSACM32.@)
307 MMRESULT WINAPI acmDriverEnum(ACMDRIVERENUMCB fnCallback, DWORD dwInstance, DWORD fdwEnum)
309 PWINE_ACMDRIVERID padid;
312 TRACE("(%p, %08lx, %08lx)\n", fnCallback, dwInstance, fdwEnum);
315 WARN("invalid parameter\n");
316 return MMSYSERR_INVALPARAM;
319 if (fdwEnum & ~(ACM_DRIVERENUMF_NOLOCAL|ACM_DRIVERENUMF_DISABLED)) {
320 WARN("invalid flag\n");
321 return MMSYSERR_INVALFLAG;
324 for (padid = MSACM_pFirstACMDriverID; padid; padid = padid->pNextACMDriverID) {
325 fdwSupport = padid->fdwSupport;
327 if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
328 if (fdwEnum & ACM_DRIVERENUMF_DISABLED)
329 fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
333 if (!(*fnCallback)((HACMDRIVERID)padid, dwInstance, fdwSupport))
337 return MMSYSERR_NOERROR;
340 /***********************************************************************
341 * acmDriverID (MSACM32.@)
343 MMRESULT WINAPI acmDriverID(HACMOBJ hao, PHACMDRIVERID phadid, DWORD fdwDriverID)
347 TRACE("(%p, %p, %08lx)\n", hao, phadid, fdwDriverID);
350 WARN("invalid flag\n");
351 return MMSYSERR_INVALFLAG;
354 pao = MSACM_GetObj(hao, WINE_ACMOBJ_DONTCARE);
356 WARN("invalid handle\n");
357 return MMSYSERR_INVALHANDLE;
361 WARN("invalid parameter\n");
362 return MMSYSERR_INVALPARAM;
365 *phadid = (HACMDRIVERID) pao->pACMDriverID;
367 return MMSYSERR_NOERROR;
370 /***********************************************************************
371 * acmDriverMessage (MSACM32.@)
373 * Note: MSDN documentation (July 2001) is incomplete. This function
374 * accepts sending messages to an HACMDRIVERID in addition to the
375 * documented HACMDRIVER. In fact, for DRV_QUERYCONFIGURE and DRV_CONFIGURE,
376 * this might actually be the required mode of operation.
378 * Note: For DRV_CONFIGURE, msacm supplies its own DRVCONFIGINFO structure
379 * when the application fails to supply one. Some native drivers depend on
380 * this and refuse to display unless a valid DRVCONFIGINFO structure is
381 * built and supplied.
383 LRESULT WINAPI acmDriverMessage(HACMDRIVER had, UINT uMsg, LPARAM lParam1, LPARAM lParam2)
385 TRACE("(%p, %04x, %08lx, %08lx\n", had, uMsg, lParam1, lParam2);
387 if ((uMsg >= ACMDM_USER && uMsg < ACMDM_RESERVED_LOW) ||
388 uMsg == ACMDM_DRIVER_ABOUT ||
389 uMsg == DRV_QUERYCONFIGURE ||
390 uMsg == DRV_CONFIGURE)
392 PWINE_ACMDRIVERID padid;
394 LPDRVCONFIGINFO pConfigInfo = NULL;
396 /* Check whether handle is an HACMDRIVERID */
397 padid = MSACM_GetDriverID((HACMDRIVERID)had);
399 /* If the message is DRV_CONFIGURE, and the application provides no
400 DRVCONFIGINFO structure, msacm must supply its own.
402 if (uMsg == DRV_CONFIGURE && lParam2 == 0) {
405 /* Get the alias from the HACMDRIVERID */
407 pAlias = padid->pszDriverAlias;
408 if (pAlias == NULL) {
409 WARN("DRV_CONFIGURE: no alias for this driver, cannot self-supply alias\n");
412 FIXME("DRV_CONFIGURE: reverse lookup HACMDRIVER -> HACMDRIVERID not implemented\n");
416 if (pAlias != NULL) {
417 unsigned int iStructSize = 16;
418 /* This verification is required because DRVCONFIGINFO is 12 bytes
419 long, yet native msacm reports a 16-byte structure to codecs.
421 if (iStructSize < sizeof(DRVCONFIGINFO)) iStructSize = sizeof(DRVCONFIGINFO);
422 pConfigInfo = HeapAlloc(MSACM_hHeap, 0, iStructSize);
424 ERR("OOM while supplying DRVCONFIGINFO for DRV_CONFIGURE, using NULL\n");
426 static const WCHAR drivers32[] = {'D','r','i','v','e','r','s','3','2','\0'};
427 pConfigInfo->dwDCISize = iStructSize;
429 pConfigInfo->lpszDCISectionName = HeapAlloc(MSACM_hHeap, 0, (strlenW(drivers32) + 1) * sizeof(WCHAR));
430 if (pConfigInfo->lpszDCISectionName) strcpyW((WCHAR *)pConfigInfo->lpszDCISectionName, drivers32);
431 pConfigInfo->lpszDCIAliasName = HeapAlloc(MSACM_hHeap, 0, (strlenW(pAlias) + 1) * sizeof(WCHAR));
432 if (pConfigInfo->lpszDCIAliasName) strcpyW((WCHAR *)pConfigInfo->lpszDCIAliasName, pAlias);
434 if (pConfigInfo->lpszDCISectionName == NULL || pConfigInfo->lpszDCIAliasName == NULL) {
435 HeapFree(MSACM_hHeap, 0, (void *)pConfigInfo->lpszDCIAliasName);
436 HeapFree(MSACM_hHeap, 0, (void *)pConfigInfo->lpszDCISectionName);
437 HeapFree(MSACM_hHeap, 0, pConfigInfo);
439 ERR("OOM while supplying DRVCONFIGINFO for DRV_CONFIGURE, using NULL\n");
444 lParam2 = (LPARAM)pConfigInfo;
448 /* Handle is really an HACMDRIVERID, must have an open session to get an HACMDRIVER */
449 if (padid->pACMDriverList != NULL) {
450 lResult = MSACM_Message((HACMDRIVER)padid->pACMDriverList, uMsg, lParam1, lParam2);
452 MMRESULT mmr = acmDriverOpen(&had, (HACMDRIVERID)padid, 0);
453 if (mmr != MMSYSERR_NOERROR) {
454 lResult = MMSYSERR_INVALPARAM;
456 lResult = acmDriverMessage(had, uMsg, lParam1, lParam2);
457 acmDriverClose(had, 0);
461 lResult = MSACM_Message(had, uMsg, lParam1, lParam2);
464 HeapFree(MSACM_hHeap, 0, (void *)pConfigInfo->lpszDCIAliasName);
465 HeapFree(MSACM_hHeap, 0, (void *)pConfigInfo->lpszDCISectionName);
466 HeapFree(MSACM_hHeap, 0, pConfigInfo);
470 WARN("invalid parameter\n");
471 return MMSYSERR_INVALPARAM;
474 /***********************************************************************
475 * acmDriverOpen (MSACM32.@)
477 MMRESULT WINAPI acmDriverOpen(PHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen)
479 PWINE_ACMDRIVERID padid;
480 PWINE_ACMDRIVER pad = NULL;
483 TRACE("(%p, %p, %08lu)\n", phad, hadid, fdwOpen);
486 WARN("invalid parameter\n");
487 return MMSYSERR_INVALPARAM;
491 WARN("invalid flag\n");
492 return MMSYSERR_INVALFLAG;
495 padid = MSACM_GetDriverID(hadid);
497 WARN("invalid handle\n");
498 return MMSYSERR_INVALHANDLE;
501 pad = HeapAlloc(MSACM_hHeap, 0, sizeof(WINE_ACMDRIVER));
504 return MMSYSERR_NOMEM;
507 pad->obj.dwType = WINE_ACMOBJ_DRIVER;
508 pad->obj.pACMDriverID = padid;
510 if (!(pad->hDrvr = (HDRVR)padid->hInstModule))
512 ACMDRVOPENDESCW adod;
515 /* this is not an externally added driver... need to actually load it */
516 if (!padid->pszDriverAlias)
518 ret = MMSYSERR_ERROR;
522 adod.cbStruct = sizeof(adod);
523 adod.fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
524 adod.fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
525 adod.dwVersion = acmGetVersion();
526 adod.dwFlags = fdwOpen;
528 len = strlen("Drivers32") + 1;
529 adod.pszSectionName = HeapAlloc(MSACM_hHeap, 0, len * sizeof(WCHAR));
530 MultiByteToWideChar(CP_ACP, 0, "Drivers32", -1, (LPWSTR)adod.pszSectionName, len);
531 adod.pszAliasName = padid->pszDriverAlias;
534 pad->hDrvr = OpenDriver(padid->pszDriverAlias, NULL, (DWORD)&adod);
536 HeapFree(MSACM_hHeap, 0, (LPWSTR)adod.pszSectionName);
544 /* insert new pad at beg of list */
545 pad->pNextACMDriver = padid->pACMDriverList;
546 padid->pACMDriverList = pad;
548 /* FIXME: Create a WINE_ACMDRIVER32 */
549 *phad = (HACMDRIVER)pad;
550 TRACE("'%s' => %p\n", debugstr_w(padid->pszDriverAlias), pad);
552 return MMSYSERR_NOERROR;
554 WARN("failed: ret = %08x\n", ret);
555 if (pad && !pad->hDrvr)
556 HeapFree(MSACM_hHeap, 0, pad);
560 /***********************************************************************
561 * acmDriverPriority (MSACM32.@)
563 MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority)
566 TRACE("(%p, %08lx, %08lx)\n", hadid, dwPriority, fdwPriority);
568 /* Check for unknown flags */
570 ~(ACM_DRIVERPRIORITYF_ENABLE|ACM_DRIVERPRIORITYF_DISABLE|
571 ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END)) {
572 WARN("invalid flag\n");
573 return MMSYSERR_INVALFLAG;
576 /* Check for incompatible flags */
577 if ((fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) &&
578 (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE)) {
579 WARN("invalid flag\n");
580 return MMSYSERR_INVALFLAG;
583 /* Check for incompatible flags */
584 if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) &&
585 (fdwPriority & ACM_DRIVERPRIORITYF_END)) {
586 WARN("invalid flag\n");
587 return MMSYSERR_INVALFLAG;
590 /* According to MSDN, ACM_DRIVERPRIORITYF_BEGIN and ACM_DRIVERPRIORITYF_END
591 may only appear by themselves, and in addition, hadid and dwPriority must
593 if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) ||
594 (fdwPriority & ACM_DRIVERPRIORITYF_END)) {
595 if (fdwPriority & ~(ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END)) {
596 WARN("ACM_DRIVERPRIORITYF_[BEGIN|END] cannot be used with any other flags\n");
597 return MMSYSERR_INVALPARAM;
600 WARN("priority invalid with ACM_DRIVERPRIORITYF_[BEGIN|END]\n");
601 return MMSYSERR_INVALPARAM;
604 WARN("non-null hadid invalid with ACM_DRIVERPRIORITYF_[BEGIN|END]\n");
605 return MMSYSERR_INVALPARAM;
607 /* FIXME: MSDN wording suggests that deferred notification should be
608 implemented as a system-wide lock held by a calling task, and that
609 re-enabling notifications should broadcast them across all processes.
610 This implementation uses a simple DWORD counter. One consequence of the
611 current implementation is that applications will never see
612 MMSYSERR_ALLOCATED as a return error.
614 if (fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) {
615 MSACM_DisableNotifications();
616 } else if (fdwPriority & ACM_DRIVERPRIORITYF_END) {
617 MSACM_EnableNotifications();
619 return MMSYSERR_NOERROR;
621 PWINE_ACMDRIVERID padid;
622 PWINE_ACMNOTIFYWND panwnd;
623 BOOL bPerformBroadcast = FALSE;
625 /* Fetch driver ID */
626 padid = MSACM_GetDriverID(hadid);
627 panwnd = MSACM_GetNotifyWnd(hadid);
628 if (!padid && !panwnd) {
629 WARN("invalid handle\n");
630 return MMSYSERR_INVALHANDLE;
634 /* Check whether driver ID is appropriate for requested op */
636 if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL) {
637 return MMSYSERR_NOTSUPPORTED;
639 if (dwPriority != 1 && dwPriority != -1) {
640 FIXME("unexpected priority %ld, using sign only\n", dwPriority);
641 if (dwPriority < 0) dwPriority = -1;
642 if (dwPriority > 0) dwPriority = 1;
645 if (dwPriority == 1 && (padid->pPrevACMDriverID == NULL ||
646 (padid->pPrevACMDriverID->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL))) {
647 /* do nothing - driver is first of list, or first after last
649 } else if (dwPriority == -1 && padid->pNextACMDriverID == NULL) {
650 /* do nothing - driver is last of list */
652 MSACM_RePositionDriver(padid, dwPriority);
653 bPerformBroadcast = TRUE;
657 /* Check whether driver ID should be enabled or disabled */
658 if (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE) {
659 if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
660 padid->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
661 bPerformBroadcast = TRUE;
663 } else if (fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) {
664 if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
665 padid->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED;
666 bPerformBroadcast = TRUE;
673 return MMSYSERR_NOTSUPPORTED;
676 /* Check whether notify window should be enabled or disabled */
677 if (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE) {
678 if (!(panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) {
679 panwnd->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED;
680 bPerformBroadcast = TRUE;
682 } else if (fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) {
683 if (panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) {
684 panwnd->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED;
685 bPerformBroadcast = TRUE;
690 /* Perform broadcast of changes */
691 if (bPerformBroadcast) {
692 MSACM_WriteCurrentPriorities();
693 MSACM_BroadcastNotification();
695 return MMSYSERR_NOERROR;
699 /***********************************************************************
700 * acmDriverRemove (MSACM32.@)
702 MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove)
704 PWINE_ACMDRIVERID padid;
705 PWINE_ACMNOTIFYWND panwnd;
707 TRACE("(%p, %08lx)\n", hadid, fdwRemove);
709 padid = MSACM_GetDriverID(hadid);
710 panwnd = MSACM_GetNotifyWnd(hadid);
711 if (!padid && !panwnd) {
712 WARN("invalid handle\n");
713 return MMSYSERR_INVALHANDLE;
717 WARN("invalid flag\n");
718 return MMSYSERR_INVALFLAG;
721 if (padid) MSACM_UnregisterDriver(padid);
722 if (panwnd) MSACM_UnRegisterNotificationWindow(panwnd);
723 MSACM_BroadcastNotification();
725 return MMSYSERR_NOERROR;