/*********************************************************************** * acmDriverRemove (MSACM32.@) */ MMRESULT WINAPI acmDriverRemove(HACMDRIVERID hadid, DWORD fdwRemove) { PWINE_ACMDRIVERID padid; PWINE_ACMNOTIFYWND panwnd; TRACE("(%p, %08x)\n", hadid, fdwRemove); padid = MSACM_GetDriverID(hadid); panwnd = MSACM_GetNotifyWnd(hadid); if (!padid && !panwnd) { WARN("invalid handle\n"); return MMSYSERR_INVALHANDLE; } if (fdwRemove) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } if (padid) MSACM_UnregisterDriver(padid); if (panwnd) MSACM_UnRegisterNotificationWindow(panwnd); MSACM_BroadcastNotification(); return MMSYSERR_NOERROR; }
/*********************************************************************** * MSACM_EnableNotifications() */ void MSACM_EnableNotifications(void) { if (MSACM_suspendBroadcastCount > 0) { MSACM_suspendBroadcastCount--; if (MSACM_suspendBroadcastCount == 0 && MSACM_pendingBroadcast) { MSACM_pendingBroadcast = FALSE; MSACM_BroadcastNotification(); } } }
/*********************************************************************** * acmDriverAddW (MSACM32.@) * */ MMRESULT WINAPI acmDriverAddW(PHACMDRIVERID phadid, HINSTANCE hinstModule, LPARAM lParam, DWORD dwPriority, DWORD fdwAdd) { PWINE_ACMLOCALDRIVER pLocalDrv = NULL; TRACE("(%p, %p, %08lx, %08x, %08x)\n", phadid, hinstModule, lParam, dwPriority, fdwAdd); if (!phadid) { WARN("invalid parameter\n"); return MMSYSERR_INVALPARAM; } /* Check if any unknown flags */ if (fdwAdd & ~(ACM_DRIVERADDF_FUNCTION|ACM_DRIVERADDF_NOTIFYHWND| ACM_DRIVERADDF_GLOBAL)) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } /* Check if any incompatible flags */ if ((fdwAdd & ACM_DRIVERADDF_FUNCTION) && (fdwAdd & ACM_DRIVERADDF_NOTIFYHWND)) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } switch (fdwAdd & ACM_DRIVERADDF_TYPEMASK) { case ACM_DRIVERADDF_NAME: /* hInstModule (unused) lParam name of value in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Drivers32 dwPriority (unused, set to 0) */ *phadid = (HACMDRIVERID) MSACM_RegisterDriverFromRegistry((LPCWSTR)lParam); if (!*phadid) { ERR("Unable to register driver via ACM_DRIVERADDF_NAME\n"); return MMSYSERR_INVALPARAM; } break; case ACM_DRIVERADDF_FUNCTION: /* hInstModule Handle of module which contains driver entry proc lParam Driver function address dwPriority (unused, set to 0) */ fdwAdd &= ~ACM_DRIVERADDF_TYPEMASK; /* FIXME: fdwAdd ignored */ /* Application-supplied acmDriverProc's are placed at the top of the priority unless fdwAdd indicates ACM_DRIVERADDF_GLOBAL */ pLocalDrv = MSACM_RegisterLocalDriver(hinstModule, (DRIVERPROC)lParam); *phadid = pLocalDrv ? (HACMDRIVERID) MSACM_RegisterDriver(NULL, NULL, pLocalDrv) : NULL; if (!*phadid) { ERR("Unable to register driver via ACM_DRIVERADDF_FUNCTION\n"); return MMSYSERR_INVALPARAM; } break; case ACM_DRIVERADDF_NOTIFYHWND: /* hInstModule (unused) lParam Handle of notification window dwPriority Window message to send for notification broadcasts */ *phadid = (HACMDRIVERID) MSACM_RegisterNotificationWindow((HWND)lParam, dwPriority); if (!*phadid) { ERR("Unable to register driver via ACM_DRIVERADDF_NOTIFYHWND\n"); return MMSYSERR_INVALPARAM; } break; default: ERR("invalid flag value 0x%08x for fdwAdd\n", fdwAdd & ACM_DRIVERADDF_TYPEMASK); return MMSYSERR_INVALFLAG; } MSACM_BroadcastNotification(); return MMSYSERR_NOERROR; }
/*********************************************************************** * acmDriverPriority (MSACM32.@) */ MMRESULT WINAPI acmDriverPriority(HACMDRIVERID hadid, DWORD dwPriority, DWORD fdwPriority) { TRACE("(%p, %08x, %08x)\n", hadid, dwPriority, fdwPriority); /* Check for unknown flags */ if (fdwPriority & ~(ACM_DRIVERPRIORITYF_ENABLE|ACM_DRIVERPRIORITYF_DISABLE| ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END)) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } /* Check for incompatible flags */ if ((fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) && (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE)) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } /* Check for incompatible flags */ if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) && (fdwPriority & ACM_DRIVERPRIORITYF_END)) { WARN("invalid flag\n"); return MMSYSERR_INVALFLAG; } /* According to MSDN, ACM_DRIVERPRIORITYF_BEGIN and ACM_DRIVERPRIORITYF_END may only appear by themselves, and in addition, hadid and dwPriority must both be zero */ if ((fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) || (fdwPriority & ACM_DRIVERPRIORITYF_END)) { if (fdwPriority & ~(ACM_DRIVERPRIORITYF_BEGIN|ACM_DRIVERPRIORITYF_END)) { WARN("ACM_DRIVERPRIORITYF_[BEGIN|END] cannot be used with any other flags\n"); return MMSYSERR_INVALPARAM; } if (dwPriority) { WARN("priority invalid with ACM_DRIVERPRIORITYF_[BEGIN|END]\n"); return MMSYSERR_INVALPARAM; } if (hadid) { WARN("non-null hadid invalid with ACM_DRIVERPRIORITYF_[BEGIN|END]\n"); return MMSYSERR_INVALPARAM; } /* FIXME: MSDN wording suggests that deferred notification should be implemented as a system-wide lock held by a calling task, and that re-enabling notifications should broadcast them across all processes. This implementation uses a simple DWORD counter. One consequence of the current implementation is that applications will never see MMSYSERR_ALLOCATED as a return error. */ if (fdwPriority & ACM_DRIVERPRIORITYF_BEGIN) { MSACM_DisableNotifications(); } else if (fdwPriority & ACM_DRIVERPRIORITYF_END) { MSACM_EnableNotifications(); } return MMSYSERR_NOERROR; } else { PWINE_ACMDRIVERID padid; PWINE_ACMNOTIFYWND panwnd; BOOL bPerformBroadcast = FALSE; /* Fetch driver ID */ padid = MSACM_GetDriverID(hadid); panwnd = MSACM_GetNotifyWnd(hadid); if (!padid && !panwnd) { WARN("invalid handle\n"); return MMSYSERR_INVALHANDLE; } if (padid) { /* Check whether driver ID is appropriate for requested op */ if (dwPriority) { if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL) { return MMSYSERR_NOTSUPPORTED; } if (dwPriority != 1 && dwPriority != (DWORD)-1) { FIXME("unexpected priority %d, using sign only\n", dwPriority); if ((signed)dwPriority < 0) dwPriority = (DWORD)-1; if (dwPriority > 0) dwPriority = 1; } if (dwPriority == 1 && (padid->pPrevACMDriverID == NULL || (padid->pPrevACMDriverID->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_LOCAL))) { /* do nothing - driver is first of list, or first after last local driver */ } else if (dwPriority == (DWORD)-1 && padid->pNextACMDriverID == NULL) { /* do nothing - driver is last of list */ } else { MSACM_RePositionDriver(padid, dwPriority); bPerformBroadcast = TRUE; } } /* Check whether driver ID should be enabled or disabled */ if (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE) { if (!(padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) { padid->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; bPerformBroadcast = TRUE; } } else if (fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) { if (padid->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) { padid->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED; bPerformBroadcast = TRUE; } } } if (panwnd) { if (dwPriority) { return MMSYSERR_NOTSUPPORTED; } /* Check whether notify window should be enabled or disabled */ if (fdwPriority & ACM_DRIVERPRIORITYF_DISABLE) { if (!(panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED)) { panwnd->fdwSupport |= ACMDRIVERDETAILS_SUPPORTF_DISABLED; bPerformBroadcast = TRUE; } } else if (fdwPriority & ACM_DRIVERPRIORITYF_ENABLE) { if (panwnd->fdwSupport & ACMDRIVERDETAILS_SUPPORTF_DISABLED) { panwnd->fdwSupport &= ~ACMDRIVERDETAILS_SUPPORTF_DISABLED; bPerformBroadcast = TRUE; } } } /* Perform broadcast of changes */ if (bPerformBroadcast) { MSACM_WriteCurrentPriorities(); MSACM_BroadcastNotification(); } return MMSYSERR_NOERROR; } }