[WDMAUD.DRV]
[reactos.git] / reactos / dll / win32 / wdmaud.drv / legacy.c
index d569d0b..90a00b4 100644 (file)
@@ -171,7 +171,7 @@ WdmAudGetCapabilitiesByLegacy(
     {
         case MIXER_DEVICE_TYPE:
         {
-            LPMIXERCAPS MixerCaps = (LPMIXERCAPS) Capabilities;
+            LPMIXERCAPSW MixerCaps = (LPMIXERCAPSW) Capabilities;
 
             DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0';
             CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname);
@@ -185,13 +185,13 @@ WdmAudGetCapabilitiesByLegacy(
         }
         case WAVE_OUT_DEVICE_TYPE :
         {
-            LPWAVEOUTCAPS WaveOutCaps = (LPWAVEOUTCAPS) Capabilities;
+            LPWAVEOUTCAPSW WaveOutCaps = (LPWAVEOUTCAPSW) Capabilities;
 
             DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
             WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid;
             WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid;
 
-            WaveOutCaps->vDriverVersion = 0x0001;
+            WaveOutCaps->vDriverVersion = DeviceInfo.u.WaveOutCaps.vDriverVersion;
             CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname);
 
             WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats;
@@ -208,7 +208,7 @@ WdmAudGetCapabilitiesByLegacy(
             WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid;
             WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid;
 
-            WaveInCaps->vDriverVersion = 0x0001;
+            WaveInCaps->vDriverVersion = DeviceInfo.u.WaveInCaps.vDriverVersion;
             CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname);
 
             WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats;
@@ -216,13 +216,43 @@ WdmAudGetCapabilitiesByLegacy(
             WaveInCaps->wReserved1 = 0;
             break;
         }
+        case MIDI_IN_DEVICE_TYPE :
+        {
+            LPMIDIINCAPSW MidiInCaps = (LPMIDIINCAPSW)Capabilities;
+
+            DeviceInfo.u.MidiInCaps.szPname[MAXPNAMELEN-1] = L'\0';
+
+            MidiInCaps->vDriverVersion = DeviceInfo.u.MidiInCaps.vDriverVersion;
+            MidiInCaps->wMid = DeviceInfo.u.MidiInCaps.wMid;
+            MidiInCaps->wPid = DeviceInfo.u.MidiInCaps.wPid;
+            MidiInCaps->dwSupport = DeviceInfo.u.MidiInCaps.dwSupport;
+
+            CopyWideString(MidiInCaps->szPname, DeviceInfo.u.MidiInCaps.szPname);
+            break;
+        }
+        case MIDI_OUT_DEVICE_TYPE :
+        {
+            LPMIDIOUTCAPSW MidiOutCaps = (LPMIDIOUTCAPSW)Capabilities;
+
+            DeviceInfo.u.MidiOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
+
+            MidiOutCaps->vDriverVersion = DeviceInfo.u.MidiOutCaps.vDriverVersion;
+            MidiOutCaps->wMid = DeviceInfo.u.MidiOutCaps.wMid;
+            MidiOutCaps->wPid = DeviceInfo.u.MidiOutCaps.wPid;
+            MidiOutCaps->dwSupport = DeviceInfo.u.MidiOutCaps.dwSupport;
+
+            CopyWideString(MidiOutCaps->szPname, DeviceInfo.u.MidiOutCaps.szPname);
+            break;
+        }
     }
 
     return MMSYSERR_NOERROR;
 }
 
 MMRESULT
-WdmAudOpenSoundDeviceByLegacy()
+WdmAudOpenSoundDeviceByLegacy(
+    IN PSOUND_DEVICE SoundDevice,
+    OUT PVOID *Handle)
 {
     /* Only open this if it's not already open */
     if ( KernelHandle == INVALID_HANDLE_VALUE )
@@ -282,6 +312,25 @@ WdmAudCloseSoundDeviceByLegacy(
          /* First stop the stream */
          if (DeviceType != MIXER_DEVICE_TYPE)
          {
+             DeviceInfo.u.State = KSSTATE_PAUSE;
+             SyncOverlappedDeviceIoControl(KernelHandle,
+                                           IOCTL_SETDEVICE_STATE,
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           (LPVOID) &DeviceInfo,
+                                            sizeof(WDMAUD_DEVICE_INFO),
+                                            NULL);
+
+             DeviceInfo.u.State = KSSTATE_ACQUIRE;
+             SyncOverlappedDeviceIoControl(KernelHandle,
+                                           IOCTL_SETDEVICE_STATE,
+                                           (LPVOID) &DeviceInfo,
+                                           sizeof(WDMAUD_DEVICE_INFO),
+                                           (LPVOID) &DeviceInfo,
+                                            sizeof(WDMAUD_DEVICE_INFO),
+                                            NULL);
+
+
              DeviceInfo.u.State = KSSTATE_STOP;
              SyncOverlappedDeviceIoControl(KernelHandle,
                                            IOCTL_SETDEVICE_STATE,
@@ -429,7 +478,7 @@ WdmAudSetWaveDeviceFormatByLegacy(
     DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
     DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
     DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
-    DeviceInfo.u.WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
+    DeviceInfo.u.WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels);
 #endif
 
     Result = SyncOverlappedDeviceIoControl(KernelHandle,
@@ -445,14 +494,19 @@ WdmAudSetWaveDeviceFormatByLegacy(
         return TranslateInternalMmResult(Result);
     }
 
-    /* Store format */
-    Instance->WaveFormatEx.cbSize = WaveFormat->cbSize;
-    Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
-    Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
-    Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
-    Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
-    Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
-    Instance->WaveFormatEx.wBitsPerSample = WaveFormat->wBitsPerSample;
+    if (WaveFormatSize >= sizeof(WAVEFORMAT))
+    {
+        /* Store format */
+        Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag;
+        Instance->WaveFormatEx.nChannels = WaveFormat->nChannels;
+        Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec;
+        Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign;
+        Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec;
+    }
+
+    /* store details */
+    Instance->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
+    Instance->WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels);
 
     /* Store sound device handle instance handle */
     Instance->Handle = (PVOID)DeviceInfo.hDevice;
@@ -481,22 +535,41 @@ WdmAudSetWaveDeviceFormatByLegacy(
         Instance->BufferCount = 100;
     }
 
-    if (DeviceType == WAVE_OUT_DEVICE_TYPE)
-    {
-        /* Now start the stream */
-        DeviceInfo.u.State = KSSTATE_RUN;
-        SyncOverlappedDeviceIoControl(KernelHandle,
-                                      IOCTL_SETDEVICE_STATE,
-                                      (LPVOID) &DeviceInfo,
-                                      sizeof(WDMAUD_DEVICE_INFO),
-                                      (LPVOID) &DeviceInfo,
-                                      sizeof(WDMAUD_DEVICE_INFO),
-                                      NULL);
-    }
+    /* Now acquire resources */
+    DeviceInfo.u.State = KSSTATE_ACQUIRE;
+    SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL);
+
+    /* pause the pin */
+    DeviceInfo.u.State = KSSTATE_PAUSE;
+    SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL);
+
+    /* start the pin */
+    DeviceInfo.u.State = KSSTATE_RUN;
+    SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL);
+
 
     return MMSYSERR_NOERROR;
 }
 
+VOID
+CALLBACK
+LegacyCompletionRoutine(
+    IN  DWORD dwErrorCode,
+    IN  DWORD dwNumberOfBytesTransferred,
+    IN  LPOVERLAPPED lpOverlapped)
+{
+    PSOUND_OVERLAPPED Overlap;
+    PWDMAUD_DEVICE_INFO DeviceInfo;
+
+    Overlap = (PSOUND_OVERLAPPED)lpOverlapped;
+    DeviceInfo = (PWDMAUD_DEVICE_INFO)Overlap->CompletionContext;
+
+    /* Call mmebuddy overlap routine */
+    Overlap->OriginalCompletionRoutine(dwErrorCode, DeviceInfo->Header.DataUsed, lpOverlapped);
+
+    HeapFree(GetProcessHeap(), 0, DeviceInfo);
+}
+
 MMRESULT
 WdmAudCommitWaveBufferByLegacy(
     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
@@ -507,7 +580,7 @@ WdmAudCommitWaveBufferByLegacy(
 {
     HANDLE Handle;
     MMRESULT Result;
-    WDMAUD_DEVICE_INFO DeviceInfo;
+    PWDMAUD_DEVICE_INFO DeviceInfo;
     PSOUND_DEVICE SoundDevice;
     MMDEVICE_TYPE DeviceType;
     BOOL Ret;
@@ -530,42 +603,56 @@ WdmAudCommitWaveBufferByLegacy(
     Result = GetSoundDeviceType(SoundDevice, &DeviceType);
     SND_ASSERT( Result == MMSYSERR_NOERROR );
 
-    ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
+    DeviceInfo = (PWDMAUD_DEVICE_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WDMAUD_DEVICE_INFO));
+    if (!DeviceInfo)
+    {
+        // no memory
+        return MMSYSERR_NOMEM;
+    }
 
-    DeviceInfo.Header.FrameExtent = Length;
+    DeviceInfo->Header.FrameExtent = Length;
     if (DeviceType == WAVE_OUT_DEVICE_TYPE)
     {
-        DeviceInfo.Header.DataUsed = Length;
+        DeviceInfo->Header.DataUsed = Length;
     }
-    DeviceInfo.Header.Data = OffsetPtr;
-    DeviceInfo.Header.Size = sizeof(WDMAUD_DEVICE_INFO);
-    DeviceInfo.Header.PresentationTime.Numerator = 1;
-    DeviceInfo.Header.PresentationTime.Denominator = 1;
-    DeviceInfo.hDevice = Handle;
-    DeviceInfo.DeviceType = DeviceType;
+    DeviceInfo->Header.Data = OffsetPtr;
+    DeviceInfo->Header.Size = sizeof(WDMAUD_DEVICE_INFO);
+    DeviceInfo->Header.PresentationTime.Numerator = 1;
+    DeviceInfo->Header.PresentationTime.Denominator = 1;
+    DeviceInfo->hDevice = Handle;
+    DeviceInfo->DeviceType = DeviceType;
 
 
+    // create completion event
+    Overlap->Standard.hEvent = Handle = CreateEventW(NULL, FALSE, FALSE, NULL);
+    if (Overlap->Standard.hEvent == NULL)
+    {
+        // no memory
+        return MMSYSERR_NOMEM;
+    }
 
-    Overlap->Standard.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+    Overlap->OriginalCompletionRoutine = CompletionRoutine;
+    Overlap->CompletionContext = (PVOID)DeviceInfo;
 
     if (DeviceType == WAVE_OUT_DEVICE_TYPE)
     {
-        Ret = WriteFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
+        Ret = WriteFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine);
         if (Ret)
             WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
     }
     else if (DeviceType == WAVE_IN_DEVICE_TYPE)
     {
-        Ret = ReadFileEx(KernelHandle, &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, CompletionRoutine);
-        //if (Ret)
-        //    WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
+        Ret = ReadFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine);
+        if (Ret)
+            WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE);
     }
 
+    // close event handle
+    CloseHandle(Handle);
+
     return MMSYSERR_NOERROR;
 }
 
-
-
 MMRESULT
 WdmAudSetWaveStateByLegacy(
     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
@@ -753,6 +840,7 @@ WdmAudResetStreamByLegacy(
 MMRESULT
 WdmAudQueryMixerInfoByLegacy(
     IN  struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
+    IN DWORD DeviceId,
     IN UINT uMsg,
     IN LPVOID Parameter,
     IN DWORD Flags)
@@ -772,6 +860,7 @@ WdmAudQueryMixerInfoByLegacy(
 
     ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
     DeviceInfo.hDevice = Handle;
+    DeviceInfo.DeviceIndex = DeviceId;
     DeviceInfo.DeviceType = MIXER_DEVICE_TYPE;
     DeviceInfo.Flags = Flags;