[ros-diffs] [janderwald] 39753: - Fix a bug in the audio_test programm which initialized the deviceinfo before another syscall - Complete also an unhandeled irp - Implement IOCTL_CLOSE_WDMAUD - Account the number of times pin can be instantiated in sysaudio and apply changes to SYSAUDIO_CLIENT structure - There is still a bug which prevents closing the audio adapter at the 2nd time

janderwald at svn.reactos.org janderwald at svn.reactos.org
Wed Feb 25 16:55:21 CET 2009


Author: janderwald
Date: Wed Feb 25 18:55:21 2009
New Revision: 39753

URL: http://svn.reactos.org/svn/reactos?rev=39753&view=rev
Log:
- Fix a bug in the audio_test programm which initialized the deviceinfo before another syscall
- Complete also an unhandeled irp
- Implement IOCTL_CLOSE_WDMAUD
- Account the number of times pin can be instantiated in sysaudio and apply changes to SYSAUDIO_CLIENT structure
- There is still a bug which prevents closing the audio adapter at the 2nd time

Modified:
    trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c
    trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
    trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
    trunk/reactos/drivers/wdm/audio/sysaudio/control.c
    trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
    trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h

Modified: trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/audio_test/audio_test.c [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -39,6 +39,7 @@
      }
 
      printf("WDMAUD: opened\n");
+
      /* clear device info */
      RtlZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
 
@@ -61,19 +62,12 @@
      }
 
      printf("WDMAUD: Num Devices %lu\n", DeviceInfo.DeviceCount);
+
      if (!DeviceInfo.DeviceCount)
      {
         CloseHandle(hWdmAud);
         return 0;
     }
-
-    DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
-    DeviceInfo.u.WaveFormatEx.wFormatTag = 0x1; //WAVE_FORMAT_PCM;
-    DeviceInfo.u.WaveFormatEx.nChannels = 2;
-    DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000;
-    DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
-    DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4;
-    DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
 
     Status = DeviceIoControl(hWdmAud, IOCTL_GETCAPABILITIES, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
 
@@ -84,6 +78,16 @@
            printf("Failed to get iocaps %lx\n", GetLastError());
         }
     }
+    printf("WDMAUD: Capabilites NumChannels %x dwFormats %lx\n", DeviceInfo.u.WaveOutCaps.wChannels, DeviceInfo.u.WaveOutCaps.dwFormats);
+
+    DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
+    DeviceInfo.u.WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
+    DeviceInfo.u.WaveFormatEx.nChannels = 2;
+    DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000;
+    DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
+    DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4;
+    DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
+
 
 
      Status = DeviceIoControl(hWdmAud, IOCTL_OPEN_WDMAUD, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
@@ -97,8 +101,7 @@
          }
      }
 
-
-
+     printf("WDMAUD: opened device\n");
 
     //
     // Allocate a buffer for 1 second
@@ -163,8 +166,8 @@
          }
     }
     printf("WDMAUD:  STOPPED\n");
+    CloseHandle(&Overlapped.hEvent);
     CloseHandle(hWdmAud);
-    CloseHandle(&Overlapped.hEvent);
     printf("WDMAUD:  COMPLETE\n");
     return 0;
 }

Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.c [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -225,6 +225,7 @@
     RtlFreeUnicodeString(&GuidString);
     Irp->IoStatus.Information = 0;
     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_NOT_IMPLEMENTED;
 }
 

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/control.c [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -371,13 +371,14 @@
     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
     IN  PWDMAUD_CLIENT ClientInfo)
 {
+    NTSTATUS Status = STATUS_UNSUCCESSFUL;
     KSP_PIN PinProperty;
     KSCOMPONENTID ComponentId;
     KSMULTIPLE_ITEM * MultipleItem;
     ULONG BytesReturned;
     PKSDATARANGE_AUDIO DataRangeAudio;
     PKSDATARANGE DataRange;
-    NTSTATUS Status;
+
     ULONG Index;
     ULONG wChannels = 0;
     ULONG dwFormats = 0;
@@ -419,8 +420,6 @@
     {
         return SetIrpIoStatus(Irp, Status, 0);
     }
-
-
 
     MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
     if (!MultipleItem)
@@ -479,6 +478,31 @@
 
 NTSTATUS
 NTAPI
+WdmAudClose(
+    IN  PDEVICE_OBJECT DeviceObject,
+    IN  PIRP Irp,
+    IN  PWDMAUD_DEVICE_INFO DeviceInfo,
+    IN  PWDMAUD_CLIENT ClientInfo)
+{
+    ULONG Index;
+
+    for(Index = 0; Index < ClientInfo->NumPins; Index++)
+    {
+        if (ClientInfo->hPins[Index] == DeviceInfo->hDevice)
+        {
+            DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
+            ZwClose(DeviceInfo->hDevice);
+            ClientInfo->hPins[Index] = NULL;
+            SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
+            return STATUS_SUCCESS;
+        }
+    }
+    SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
+    return STATUS_INVALID_PARAMETER;
+}
+
+NTSTATUS
+NTAPI
 WdmAudDeviceControl(
     IN  PDEVICE_OBJECT DeviceObject,
     IN  PIRP Irp)
@@ -530,6 +554,7 @@
         case IOCTL_GETCAPABILITIES:
             return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
         case IOCTL_CLOSE_WDMAUD:
+            return WdmAudClose(DeviceObject, Irp, DeviceInfo, ClientInfo);
         case IOCTL_GETDEVID:
         case IOCTL_GETVOLUME:
         case IOCTL_SETVOLUME:

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/entry.c [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -203,7 +203,12 @@
     if (pClient)
     {
         for (Index = 0; Index < pClient->NumPins; Index++)
-           ZwClose(pClient->hPins[Index]);
+        {
+           if (pClient->hPins[Index])
+           {
+               ZwClose(pClient->hPins[Index]);
+           }
+        }
 
         if (pClient->hPins)
         {

Modified: trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/legacy/wdmaud/wdmaud.h [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -8,7 +8,7 @@
 #define YDEBUG
 #include <debug.h>
 #include <ksmedia.h>
-#include <mmsystem.h>	
+#include <mmsystem.h>
 
 #include "interface.h"
 

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/control.c?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -58,8 +58,7 @@
     IN ULONG DeviceNumber,
     PSYSAUDIODEVEXT DeviceExtension)
 {
-    PULONG Index;
-    PHANDLE Handle;
+    PSYSAUDIO_CLIENT_HANDELS Index;
     ULONG Count;
     PSYSAUDIO_CLIENT ClientInfo;
     PKSAUDIO_DEVICE_ENTRY Entry;
@@ -85,23 +84,17 @@
     if (!ClientInfo->NumDevices)
     {
         /* first device to be openend */
-        ClientInfo->Devices = ExAllocatePool(NonPagedPool, sizeof(ULONG));
-        if (!ClientInfo->Devices)
+        ClientInfo->Devs = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS));
+        if (!ClientInfo->Devs)
         {
             /* no memory */
             return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
         }
 
-        ClientInfo->Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE));
-        if (!ClientInfo->Devices)
-        {
-            /* no memory */
-            return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
-        }
-
         ClientInfo->NumDevices = 1;
-        ClientInfo->Devices[0] = DeviceNumber;
-        ClientInfo->Handels[0] = NULL;
+        ClientInfo->Devs[0].DeviceId = DeviceNumber;
+        ClientInfo->Devs[0].ClientHandles = NULL;
+        ClientInfo->Devs[0].ClientHandlesCount = 0;
         /* increase usage count */
         Entry->NumberOfClients++;
         return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
@@ -110,46 +103,37 @@
     /* check if device has already been openend */
     for(Count = 0; Count < ClientInfo->NumDevices; Count++)
     {
-        if (ClientInfo->Devices[Count] == DeviceNumber)
+        if (ClientInfo->Devs[Count].DeviceId == DeviceNumber)
         {
             /* device has already been opened */
             return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
         }
     }
     /* new device to be openend */
-    Index = ExAllocatePool(NonPagedPool, sizeof(ULONG) * (ClientInfo->NumDevices + 1));
+    Index = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS) * (ClientInfo->NumDevices + 1));
     if (!Index)
     {
         /* no memory */
         return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
     }
 
-    Handle = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumDevices + 1));
-    if (!Handle)
-    {
-        /* no memory */
-        ExFreePool(Index);
-        return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
-    }
+    if (ClientInfo->NumDevices)
+    {
+        /* copy device count array */
+        RtlMoveMemory(Index, ClientInfo->Devs, ClientInfo->NumDevices * sizeof(SYSAUDIO_CLIENT_HANDELS));
+    }
+
+    Index[ClientInfo->NumDevices].DeviceId = DeviceNumber;
+    Index[ClientInfo->NumDevices].ClientHandlesCount = 0;
+    Index[ClientInfo->NumDevices].ClientHandles = NULL;
 
     /* increase usage count */
     Entry->NumberOfClients++;
 
-    /* copy device count array */
-    if (ClientInfo->NumDevices)
-    {
-        RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
-        RtlMoveMemory(Handle, ClientInfo->Handels, ClientInfo->NumDevices * sizeof(HANDLE));
-    }
-
-    Index[ClientInfo->NumDevices] = DeviceNumber;
-    Handle[ClientInfo->NumDevices] = NULL;
-    ExFreePool(ClientInfo->Handels);
-    ExFreePool(ClientInfo->Devices);
+    ExFreePool(ClientInfo->Devs);
+
+    ClientInfo->Devs = Index;
     ClientInfo->NumDevices++;
-    ClientInfo->Devices = Index;
-    ClientInfo->Handels = Handle;
-
     return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
 }
 
@@ -160,9 +144,12 @@
     IN PVOID  Context)
 {
     NTSTATUS Status;
-    HANDLE PinHandle;
+    PSYSAUDIO_CLIENT AudioClient;
+    HANDLE RealPinHandle, VirtualPinHandle;
     HANDLE Filter;
+    ULONG NumHandels;
     PFILE_OBJECT FileObject;
+    PSYSAUDIO_PIN_HANDLE ClientPinHandle;
     PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
     Filter = WorkerContext->PinConnect->PinToHandle;
 
@@ -172,7 +159,7 @@
     if (WorkerContext->CreateRealPin)
     {
         /* create the real pin */
-        Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+        Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
         if (!NT_SUCCESS(Status))
         {
             DPRINT1("Failed to create Pin with %x\n", Status);
@@ -182,13 +169,18 @@
         }
 
         /* get pin file object */
-        Status = ObReferenceObjectByHandle(PinHandle,
+        Status = ObReferenceObjectByHandle(RealPinHandle,
                                            GENERIC_READ | GENERIC_WRITE, 
                                            IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
 
-        WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = PinHandle;
+        if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1)
+        {
+            /* store the pin handle there is the pin can only be instantiated once*/
+            WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle;
+        }
+
         WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 1;
-        WorkerContext->DispatchContext->Handle = PinHandle;
+        WorkerContext->DispatchContext->Handle = RealPinHandle;
         WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
         WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
 
@@ -204,7 +196,7 @@
         WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
 
         /* get pin file object */
-        Status = ObReferenceObjectByHandle(PinHandle,
+        Status = ObReferenceObjectByHandle(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle,
                                            GENERIC_READ | GENERIC_WRITE, 
                                            IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
 
@@ -220,7 +212,7 @@
 
     DPRINT1("creating virtual pin\n");
     /* now create the virtual audio pin which is exposed to wdmaud */
-    Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+    Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle);
 
     if (!NT_SUCCESS(Status))
     {
@@ -237,7 +229,7 @@
     }
 
    /* get pin file object */
-    Status = ObReferenceObjectByHandle(PinHandle,
+    Status = ObReferenceObjectByHandle(VirtualPinHandle,
                                       GENERIC_READ | GENERIC_WRITE, 
                                       IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
 
@@ -250,7 +242,7 @@
             WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
         }
 
-        ZwClose(PinHandle);
+        ZwClose(VirtualPinHandle);
         SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
         ExFreePool(WorkerContext);
         return;
@@ -261,19 +253,59 @@
     ASSERT(WorkerContext->DispatchContext->FileObject != NULL);
     ASSERT(WorkerContext->DispatchContext->Handle != NULL);
     ASSERT(WorkerContext->AudioClient);
-    ASSERT(WorkerContext->AudioClient->Handels);
-    ASSERT(WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices -1] == NULL);
+    ASSERT(WorkerContext->AudioClient->NumDevices > 0);
+    ASSERT(WorkerContext->AudioClient->Devs != NULL);
+    ASSERT(WorkerContext->Entry->Pins != NULL);
+    ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId);
+
+
+    AudioClient = WorkerContext->AudioClient;
+    NumHandels = AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount;
+
+    ClientPinHandle = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_PIN_HANDLE) * (NumHandels+1));
+    if (ClientPinHandle)
+    {
+        if (NumHandels)
+        {
+            ASSERT(AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles != NULL);
+            RtlMoveMemory(ClientPinHandle,
+                          AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles,
+                          sizeof(SYSAUDIO_PIN_HANDLE) * NumHandels);
+            ExFreePool(AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles);
+        }
+
+        AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles = ClientPinHandle;
+
+        /// if the pin can be instantiated more than once
+        /// then store the real pin handle in the client context
+        /// otherwise just the pin id of the available pin
+        if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount > 1)
+        {
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = TRUE;
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = RealPinHandle;
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId;
+        }
+        else
+        {
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = FALSE;
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = NULL;
+            AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId;
+        }
+
+        /// increase reference count
+        WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++;
+        AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++;
+    }
+
 
     /* store pin context */
     FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
 
-    /* store pin handle in client specific struct */
-    WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices-1] = PinHandle;
-
-    DPRINT1("Successfully created Pin %p\n", WorkerContext->Irp);
-    *((PHANDLE)WorkerContext->Irp->UserBuffer) = PinHandle;
+    DPRINT1("Successfully created virtual pin %p\n", VirtualPinHandle);
+    *((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
 
     SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
+    ExFreePool(WorkerContext);
 }
 
 
@@ -425,7 +457,7 @@
                     return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
                 }
                 /* store last opened device number */
-                *Index = ClientInfo->Devices[ClientInfo->NumDevices-1];
+                *Index = ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId;
                 /* found no device with that device index open */
                 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
             }
@@ -458,7 +490,7 @@
                 }
                 for(Count = 0; Count < ClientInfo->NumDevices; Count++)
                 {
-                    if (ClientInfo->Devices[Count] == InstanceInfo->DeviceNumber)
+                    if (ClientInfo->Devs[Count].DeviceId == InstanceInfo->DeviceNumber)
                     {
                         /* specified device is open */
                         return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
@@ -493,8 +525,8 @@
             ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
             ASSERT(ClientInfo);
             ASSERT(ClientInfo->NumDevices >= 1);
-            ASSERT(ClientInfo->Devices != NULL);
-            ASSERT(ClientInfo->Devices[ClientInfo->NumDevices-1] == InstanceInfo->DeviceNumber);
+            ASSERT(ClientInfo->Devs != NULL);
+            ASSERT(ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId == InstanceInfo->DeviceNumber);
 
             /* get sysaudio entry */
             Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber);
@@ -541,14 +573,14 @@
             PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
             PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
 
-            //RtlZeroMemory(&PinInstances, sizeof(KSPIN_CINSTANCES));
             Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
             if (!NT_SUCCESS(Status))
             {
                 DPRINT("Property Request KSPROPERTY_PIN_GLOBALCINSTANCES failed with %x\n", Status);
                 return SetIrpIoStatus(Irp, Status, 0);
             }
-            DPRINT1("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount);
+            DPRINT("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount);
+            Entry->Pins[PinConnect->PinId].MaxPinInstanceCount = PinInstances.PossibleCount;
 
             WorkItem = IoAllocateWorkItem(DeviceObject);
             if (!WorkItem)
@@ -588,10 +620,10 @@
                 DbgBreakPoint();
                 ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
 
-                if (Entry->Pins[PinConnect->PinId].References != 0)
+                if (Entry->Pins[PinConnect->PinId].References > 1)
                 {
                     /* FIXME need ksmixer */
-                    DPRINT1("Device %u Pin %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId);
+                    DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References);
                     IoFreeWorkItem(WorkItem);
                     ExFreePool(WorkerContext);
                     ExFreePool(DispatchContext);

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -91,30 +91,48 @@
     PIRP Irp)
 {
     PSYSAUDIO_CLIENT Client;
+    PKSAUDIO_DEVICE_ENTRY Entry;
     PIO_STACK_LOCATION IoStatus;
-    ULONG Index;
-
-
-    DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
+    ULONG Index, SubIndex;
+    PSYSAUDIODEVEXT DeviceExtension;
 
     IoStatus = IoGetCurrentIrpStackLocation(Irp);
 
     Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2;
+    DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
+
 
     DPRINT1("Client %p NumDevices %u\n", Client, Client->NumDevices);
     for(Index = 0; Index < Client->NumDevices; Index++)
     {
-        if (Client->Handels[Index])
+        if (Client->Devs[Index].ClientHandlesCount)
         {
-           ZwClose(Client->Handels[Index]);
+            Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Client->Devs[Index].DeviceId);
+            ASSERT(Entry != NULL);
+
+            for(SubIndex = 0; SubIndex < Client->Devs[Index].ClientHandlesCount; SubIndex++)
+            {
+                ASSERT(Entry->NumberOfPins > Client->Devs[Index].ClientHandles[SubIndex].PinId);
+                if (Client->Devs[Index].ClientHandles[SubIndex].bHandle)
+                {
+                    DPRINT1("Closing handle %p\n", Client->Devs[Index].ClientHandles[SubIndex].hPin);
+
+                    ZwClose(Client->Devs[Index].ClientHandles[SubIndex].hPin);
+                    Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--;
+                }
+                else
+                {
+                    /* this is pin which can only be instantiated once
+                     * so we just need to release the reference count on that pin */
+                    Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--;
+                }
+            }
+            ExFreePool(Client->Devs[Index].ClientHandles);
         }
     }
 
-    if (Client->Handels)
-        ExFreePool(Client->Handels);
-
-    if (Client->Devices)
-        ExFreePool(Client->Devices);
+    if (Client->Devs)
+        ExFreePool(Client->Devs);
 
     ExFreePool(Client);
 
@@ -250,7 +268,8 @@
         if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
         {
             Status = CreateDispatcher(Irp);
-            DPRINT1("Virtual pin Status %x\n", Status);
+            DPRINT1("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject);
+DbgBreakPoint();
             Irp->IoStatus.Information = 0;
             Irp->IoStatus.Status = Status;
             IoCompleteRequest(Irp, IO_NO_INCREMENT);

Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h?rev=39753&r1=39752&r2=39753&view=diff
==============================================================================
--- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Wed Feb 25 18:55:21 2009
@@ -3,14 +3,30 @@
 
 typedef struct
 {
+    BOOL bHandle;
+    ULONG PinId;
+    HANDLE hPin;
+}SYSAUDIO_PIN_HANDLE, *PSYSAUDIO_PIN_HANDLE;
+
+
+typedef struct
+{
+    ULONG DeviceId;
+    ULONG ClientHandlesCount;
+    PSYSAUDIO_PIN_HANDLE ClientHandles;
+
+}SYSAUDIO_CLIENT_HANDELS, *PSYSAUDIO_CLIENT_HANDELS;
+
+typedef struct
+{
     ULONG NumDevices;
-    PULONG Devices;
-    PHANDLE Handels;
+    PSYSAUDIO_CLIENT_HANDELS Devs;
 
 }SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
 
 typedef struct
 {
+    ULONG MaxPinInstanceCount;
     HANDLE PinHandle;
     ULONG References;
 }PIN_INFO;



More information about the Ros-diffs mailing list