/*
+ * PROJECT: ReactOS Sound System
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: dll/win32/wdmaud.drv/wdmaud.c
*
- * PROJECT: ReactOS WDM Audio driver mapper
- * FILE: dll/win32/wdmaud.drv/wdmaud.c
- * PURPOSE: wdmaud.drv
- * PROGRAMMER: Dmitry Chapyshev (dmitry@reactos.org)
+ * PURPOSE: WDM Audio Driver (User-mode part)
+ * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
+ *
+ * NOTES: Looking for wodMessage & co? You won't find them here. Try
+ * the MME Buddy library, which is where these routines are
+ * actually implemented.
*
- * UPDATE HISTORY:
- * 25/05/2008 Created
*/
-#include <stdarg.h>
+#include "wdmaud.h"
-#include <windows.h>
-#include <mmsystem.h>
-#include <mmddk.h>
-#include <mmreg.h>
-#include <debug.h>
+HANDLE KernelHandle = INVALID_HANDLE_VALUE;
-DWORD APIENTRY
-mxdMessage(UINT uDevice,
- UINT uMsg,
- DWORD dwUser,
- DWORD dwParam1,
- DWORD dwParam2)
+MMRESULT
+QueryWdmWaveDeviceFormatSupport(
+ IN PSOUND_DEVICE Device,
+ IN PWAVEFORMATEX WaveFormat,
+ IN DWORD WaveFormatSize)
{
- DPRINT1("mxdMessage(%04X, %04X, %08X, %08X, %08X);\n", uDevice, uMsg, dwUser, dwParam1, dwParam2);
-
- switch (uMsg)
- {
- case MXDM_INIT:
- break;
-
- case MXDM_GETNUMDEVS:
- break;
-
- case MXDM_GETDEVCAPS:
- break;
-
- case MXDM_OPEN:
- break;
-
- case MXDM_CLOSE:
- break;
-
- case MXDM_GETLINEINFO:
- break;
-
- case MXDM_GETLINECONTROLS:
- break;
-
- case MXDM_GETCONTROLDETAILS:
- break;
-
- case MXDM_SETCONTROLDETAILS:
- break;
- }
-
- return MMSYSERR_NOTSUPPORTED;
+ /* Whatever... */
+ return MMSYSERR_NOERROR;
}
-DWORD APIENTRY
-auxMessage(UINT uDevice,
- UINT uMsg,
- DWORD dwUser,
- DWORD dwParam1,
- DWORD dwParam2)
-{
- DPRINT1("auxMessage(%04X, %04X, %08X, %08X, %08X);\n", uDevice, uMsg, dwUser, dwParam1, dwParam2);
-
- switch (uMsg)
- {
- case AUXDM_GETDEVCAPS:
-
- break;
-
- case AUXDM_GETNUMDEVS:
-
- break;
- case AUXDM_GETVOLUME:
-
- break;
+MMRESULT
+PopulateWdmDeviceList(
+ MMDEVICE_TYPE DeviceType)
+{
+ MMRESULT Result;
+ DWORD DeviceCount = 0;
+ PSOUND_DEVICE SoundDevice = NULL;
+ MMFUNCTION_TABLE FuncTable;
+ DWORD i;
- case AUXDM_SETVOLUME:
+ VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) );
- break;
+#ifdef USE_MMIXER_LIB
+ Result = WdmAudGetNumDevsByMMixer(DeviceType, &DeviceCount);
+#else
+ Result = WdmAudGetNumWdmDevsByLegacy(DeviceType, &DeviceCount);
+#endif
- default:
- return MMSYSERR_NOTSUPPORTED;
+ if ( ! MMSUCCESS(Result) )
+ {
+ SND_ERR(L"Error %d while obtaining number of devices\n", Result);
+ return TranslateInternalMmResult(Result);
}
- return MMSYSERR_NOTSUPPORTED;
-}
+ SND_TRACE(L"%d devices of type %d found\n", DeviceCount, DeviceType);
-DWORD APIENTRY
-wodMessage(UINT uDevice,
- UINT uMsg,
- DWORD dwUser,
- DWORD dwParam1,
- DWORD dwParam2)
-{
- DPRINT1("wodMessage(%04X, %04X, %08X, %08X, %08X);\n", uDevice, uMsg, dwUser, dwParam1, dwParam2);
- switch (uMsg)
+ for ( i = 0; i < DeviceCount; ++ i )
{
- case WODM_GETNUMDEVS:
- break;
-
- case WODM_GETDEVCAPS:
- break;
-
- case WODM_OPEN:
- break;
-
- case WODM_CLOSE:
- break;
-
- case WODM_WRITE:
- break;
-
- case WODM_PAUSE:
- break;
-
- case WODM_RESTART:
- break;
-
- case WODM_RESET:
- break;
-
- case WODM_BREAKLOOP:
- break;
-
- case WODM_GETPOS:
- break;
-
- case WODM_SETPITCH:
- break;
-
- case WODM_SETVOLUME:
- break;
-
- case WODM_SETPLAYBACKRATE:
- break;
-
- case WODM_GETPITCH:
- break;
-
- case WODM_GETVOLUME:
- break;
-
- case WODM_GETPLAYBACKRATE:
- break;
-
- default:
- return MMSYSERR_NOTSUPPORTED;
+ Result = ListSoundDevice(DeviceType, UlongToPtr(i), &SoundDevice);
+
+ if ( ! MMSUCCESS(Result) )
+ {
+ SND_ERR(L"Failed to list sound device - error %d\n", Result);
+ return TranslateInternalMmResult(Result);
+ }
+
+ /* Set up our function table */
+ ZeroMemory(&FuncTable, sizeof(MMFUNCTION_TABLE));
+#ifdef USE_MMIXER_LIB
+ FuncTable.GetCapabilities = WdmAudGetCapabilitiesByMMixer;
+ FuncTable.Open = WdmAudOpenSoundDeviceByMMixer;
+ FuncTable.Close = WdmAudCloseSoundDeviceByMMixer;
+ FuncTable.GetDeviceInterfaceString = WdmAudGetDeviceInterfaceStringByMMixer;
+#else
+ FuncTable.GetCapabilities = WdmAudGetCapabilitiesByLegacy;
+ FuncTable.Open = WdmAudOpenSoundDeviceByLegacy;
+ FuncTable.Close = WdmAudCloseSoundDeviceByLegacy;
+ FuncTable.GetDeviceInterfaceString = WdmAudGetDeviceInterfaceStringByLegacy;
+#endif
+
+ FuncTable.QueryWaveFormatSupport = QueryWdmWaveDeviceFormatSupport;
+ if (DeviceType == MIXER_DEVICE_TYPE)
+ {
+#ifdef USE_MMIXER_LIB
+ FuncTable.SetWaveFormat = WdmAudSetMixerDeviceFormatByMMixer;
+ FuncTable.QueryMixerInfo = WdmAudQueryMixerInfoByMMixer;
+#else
+ FuncTable.SetWaveFormat = WdmAudSetMixerDeviceFormatByLegacy;
+ FuncTable.QueryMixerInfo = WdmAudQueryMixerInfoByLegacy;
+#endif
+ }
+
+ if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE)
+ {
+#ifdef USE_MMIXER_LIB
+ FuncTable.SetWaveFormat = WdmAudSetWdmWaveDeviceFormatByMMixer;
+ FuncTable.SetState = WdmAudSetWdmWaveStateByMMixer;
+ FuncTable.ResetStream = WdmAudResetStreamByMMixer;
+ FuncTable.GetPos = WdmAudGetWdmPositionByMMixer;
+#else
+ FuncTable.SetWaveFormat = WdmAudSetWaveDeviceFormatByLegacy;
+ FuncTable.SetState = WdmAudSetWaveStateByLegacy;
+ FuncTable.ResetStream = WdmAudResetStreamByLegacy;
+ FuncTable.GetPos = WdmAudGetWavePositionByLegacy;
+#endif
+
+#ifdef USE_MMIXER_LIB
+ FuncTable.CommitWaveBuffer = WdmAudCommitWaveBufferByMMixer;
+#elif defined (USERMODE_MIXER)
+ FuncTable.CommitWaveBuffer = WriteFileEx_Remixer;
+#else
+ FuncTable.CommitWaveBuffer = WriteFileEx_Committer2;
+#endif
+ }
+
+ SetSoundDeviceFunctionTable(SoundDevice, &FuncTable);
}
- return MMSYSERR_NOTSUPPORTED;
+ return MMSYSERR_NOERROR;
}
-DWORD APIENTRY
-widMessage(UINT uDevice,
- UINT uMsg,
- DWORD dwUser,
- DWORD dwParam1,
- DWORD dwParam2)
+LONG
+APIENTRY
+DriverProc(
+ DWORD DriverId,
+ HANDLE DriverHandle,
+ UINT Message,
+ LONG Parameter1,
+ LONG Parameter2)
{
- DPRINT1("widMessage(%04X, %04X, %08X, %08X, %08X);\n", uDevice, uMsg, dwUser, dwParam1, dwParam2);
+ MMRESULT Result;
- switch (uMsg)
+ switch ( Message )
{
- case WIDM_GETNUMDEVS:
- break;
-
- case WIDM_GETDEVCAPS:
- break;
-
- case WIDM_OPEN:
- break;
-
- case WIDM_CLOSE:
- break;
-
- case WIDM_ADDBUFFER:
- break;
-
- case WIDM_STOP:
- break;
-
- case WIDM_START:
- break;
-
- case WIDM_RESET:
- break;
-
- case WIDM_GETPOS:
- break;
-
- default:
- return MMSYSERR_NOTSUPPORTED;
+ case DRV_LOAD :
+ {
+ SND_TRACE(L"DRV_LOAD\n");
+
+ Result = InitEntrypointMutexes();
+
+ if ( ! MMSUCCESS(Result) )
+ return 0L;
+
+#ifdef USE_MMIXER_LIB
+ if (!WdmAudInitUserModeMixer())
+ {
+ SND_ERR(L"Failed to initialize mmixer lib\n");
+ return 0;
+ }
+#else
+ if (WdmAudOpenSoundDeviceByLegacy() != MMSYSERR_NOERROR)
+ {
+ SND_ERR(L"Failed to open \\\\.\\wdmaud\n");
+ CleanupEntrypointMutexes();
+
+ //UnlistAllSoundDevices();
+
+ return 0L;
+ }
+#endif
+
+ /* Populate the device lists */
+ SND_TRACE(L"Populating device lists\n");
+ PopulateWdmDeviceList(WAVE_OUT_DEVICE_TYPE);
+ PopulateWdmDeviceList(WAVE_IN_DEVICE_TYPE);
+ PopulateWdmDeviceList(MIDI_OUT_DEVICE_TYPE);
+ PopulateWdmDeviceList(MIDI_IN_DEVICE_TYPE);
+ PopulateWdmDeviceList(AUX_DEVICE_TYPE);
+ PopulateWdmDeviceList(MIXER_DEVICE_TYPE);
+
+ SND_TRACE(L"Initialisation complete\n");
+
+ return 1L;
+ }
+
+ case DRV_FREE :
+ {
+ SND_TRACE(L"DRV_FREE\n");
+
+#ifdef USE_MMIXER_LIB
+ WdmAudCleanupMMixer();
+#else
+ WdmAudCleanupLegacy();
+#endif
+
+ /* TODO: Clean up the path names! */
+ UnlistAllSoundDevices();
+
+ CleanupEntrypointMutexes();
+
+ SND_TRACE(L"Unfreed memory blocks: %d\n",
+ GetMemoryAllocationCount());
+
+ return 1L;
+ }
+
+ case DRV_ENABLE :
+ case DRV_DISABLE :
+ {
+ SND_TRACE(L"DRV_ENABLE / DRV_DISABLE\n");
+ return 1L;
+ }
+
+ case DRV_OPEN :
+ case DRV_CLOSE :
+ {
+ SND_TRACE(L"DRV_OPEN / DRV_CLOSE\n");
+ return 1L;
+ }
+
+ case DRV_QUERYCONFIGURE :
+ {
+ SND_TRACE(L"DRV_QUERYCONFIGURE\n");
+ return 0L;
+ }
+ case DRV_CONFIGURE :
+ return DRVCNF_OK;
+
+ default :
+ SND_TRACE(L"Unhandled message %d\n", Message);
+ return DefDriverProc(DriverId,
+ DriverHandle,
+ Message,
+ Parameter1,
+ Parameter2);
}
-
- return MMSYSERR_NOTSUPPORTED;
}
-DWORD APIENTRY
-modMessage(UINT uDevice,
- UINT uMsg,
- DWORD dwUser,
- DWORD dwParam1,
- DWORD dwParam2)
-{
- DPRINT1("modMessage(%04X, %04X, %08X, %08X, %08X);\n", uDevice, uMsg, dwUser, dwParam1, dwParam2);
-
- return MMSYSERR_NOTSUPPORTED;
-}
-LRESULT APIENTRY
-DriverProc(DWORD dwDriverID,
- HDRVR hDriver,
- UINT uiMessage,
- LPARAM lParam1,
- LPARAM lParam2)
+BOOL WINAPI DllMain(
+ HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
{
- return DefDriverProc(dwDriverID, hDriver, uiMessage, lParam1, lParam2);
-}
-
-BOOL WINAPI
-DllMain(IN HINSTANCE hinstDLL,
- IN DWORD dwReason,
- IN LPVOID lpvReserved)
-{
- switch (dwReason)
+ switch ( fdwReason )
{
- case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hinstDLL);
+ case DLL_PROCESS_ATTACH :
+ SND_TRACE(L"WDMAUD.DRV - Process attached\n");
+ break;
+ case DLL_PROCESS_DETACH :
+ SND_TRACE(L"WDMAUD.DRV - Process detached\n");
+ break;
+ case DLL_THREAD_ATTACH :
+ SND_TRACE(L"WDMAUD.DRV - Thread attached\n");
+ break;
+ case DLL_THREAD_DETACH :
+ SND_TRACE(L"WDMAUD.DRV - Thread detached\n");
break;
}
return TRUE;
}
-