[KS]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 10 Jul 2009 15:14:56 +0000 (15:14 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Fri, 10 Jul 2009 15:14:56 +0000 (15:14 +0000)
- The pin creation parameters are now placed right after the reference string. Handle this case in KsValidateConnectRequest
- Only store the passed create items, no need  to copy the passed create items. This is required for enabling dynamic audio devices
- Fix copying of the object class in KsAllocateObjectHeader
- Check for KSCREATE_ITEM_IRP_STORAGE flag in KsCreate
[PORTCLS]
- Reduce initial audio buffer to about 1/3 second which greatly improves performance
[SYSAUDIO]
- Remove concept of audio subdevices
- Remove imported KsCreatePin
- Replace OpenDevice loop hack

svn path=/trunk/; revision=41842

13 files changed:
reactos/drivers/ksfilter/ks/connectivity.c
reactos/drivers/ksfilter/ks/irp.c
reactos/drivers/ksfilter/ks/kstypes.h
reactos/drivers/ksfilter/ks/misc.c
reactos/drivers/ksfilter/ks/topology.c
reactos/drivers/wdm/audio/backpln/portcls/irpstream.c
reactos/drivers/wdm/audio/backpln/portcls/port_topology.c
reactos/drivers/wdm/audio/filters/kmixer/filter.c
reactos/drivers/wdm/audio/sysaudio/control.c
reactos/drivers/wdm/audio/sysaudio/deviface.c
reactos/drivers/wdm/audio/sysaudio/dispatcher.c
reactos/drivers/wdm/audio/sysaudio/main.c
reactos/drivers/wdm/audio/sysaudio/sysaudio.h

index d2744ff..73921ee 100644 (file)
@@ -45,15 +45,23 @@ KsValidateConnectRequest(
     PKSPIN_CONNECT ConnectDetails;
     LPWSTR PinName = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}\\";
     PKSDATAFORMAT DataFormat;
+    LPWSTR Offset;
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     if (!IoStack->FileObject->FileName.Buffer)
         return STATUS_INVALID_PARAMETER;
 
-    if (wcsncmp(IoStack->FileObject->FileName.Buffer, PinName, wcslen(PinName)))
+    if (IoStack->FileObject->FileName.Length < wcslen(PinName) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT))
         return STATUS_INVALID_PARAMETER;
 
-    ConnectDetails = (PKSPIN_CONNECT)(IoStack->FileObject->FileName.Buffer + wcslen(PinName));
+    Offset = wcsstr(IoStack->FileObject->FileName.Buffer, PinName);
+    if (!Offset)
+    {
+        /* request is not targeted for a pin */
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    ConnectDetails = (PKSPIN_CONNECT)(Offset + wcslen(PinName));
 
     if (ConnectDetails->PinToHandle != NULL)
     {
@@ -61,11 +69,6 @@ KsValidateConnectRequest(
         return STATUS_NOT_IMPLEMENTED;
     }
 
-    if (IoStack->FileObject->FileName.Length < wcslen(PinName) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT))
-        return STATUS_INVALID_PARAMETER;
-
-    ConnectDetails = (PKSPIN_CONNECT)(IoStack->FileObject->FileName.Buffer + wcslen(PinName));
-
     if (ConnectDetails->PinId >= DescriptorsCount)
         return STATUS_INVALID_PARAMETER;
 
index 5c34c72..336f8e7 100644 (file)
@@ -104,14 +104,15 @@ KsAddObjectCreateItemToDeviceHeader(
     /* now scan the list and check for a free item */
     for(Index = 0; Index < Header->MaxItems; Index++)
     {
-        if (!Header->ItemList[Index].bCreated)
-        {
-            if (FreeIndex == (ULONG)-1)
-                FreeIndex = Index;
+        ASSERT(Header->ItemList[Index].CreateItem);
 
-            continue;
+        if (Header->ItemList[Index].CreateItem->Create == NULL)
+        {
+            FreeIndex = Index;
+            break;
         }
-        else if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem.ObjectClass.Buffer))
+
+        if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem->ObjectClass.Buffer))
         {
             /* the same object class already exists */
             return STATUS_OBJECT_NAME_COLLISION;
@@ -120,26 +121,17 @@ KsAddObjectCreateItemToDeviceHeader(
     /* found a free index */
     if (FreeIndex == (ULONG)-1)
     {
-        /* allocate a new device entry */
-        PDEVICE_ITEM Item = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * (Header->MaxItems + 1), TAG_DEVICE_HEADER);
-        if (!Item)
-            return STATUS_INSUFFICIENT_RESOURCES;
-
-        RtlMoveMemory(Item, Header->ItemList, Header->MaxItems * sizeof(DEVICE_ITEM));
-        ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER);
-        
-        Header->ItemList = Item;
-        FreeIndex = Header->MaxItems;
-        Header->MaxItems++;
+        /* no empty space found */
+        return STATUS_ALLOTTED_SPACE_EXCEEDED;
     }
 
-    /* store the new item */
-    Header->ItemList[FreeIndex].bCreated = TRUE;
-    Header->ItemList[FreeIndex].CreateItem.Create = Create;
-    Header->ItemList[FreeIndex].CreateItem.Context = Context;
-    RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem.ObjectClass, ObjectClass);
-    Header->ItemList[FreeIndex].CreateItem.SecurityDescriptor = SecurityDescriptor;
-    Header->ItemList[FreeIndex].CreateItem.Flags = 0;
+    /* initialize create item */
+    Header->ItemList[FreeIndex].CreateItem->Create = Create;
+    Header->ItemList[FreeIndex].CreateItem->Context = Context;
+    RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem->ObjectClass, ObjectClass);
+    Header->ItemList[FreeIndex].CreateItem->SecurityDescriptor = SecurityDescriptor;
+
+
     return STATUS_SUCCESS;
 }
 
@@ -187,12 +179,8 @@ KsAllocateDeviceHeader(
 
         for(Index = 0; Index < ItemsCount; Index++)
         {
-            /* copy provided create items */
-            RtlMoveMemory(&Header->ItemList[Index].CreateItem, &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM));
-            if (ItemsList[Index].Create!= NULL)
-            {
-                Header->ItemList[Index].bCreated = TRUE;
-            }
+            /* store provided create items */
+            Header->ItemList[Index].CreateItem = &ItemsList[Index];
         }
         Header->MaxItems = ItemsCount;
     }
@@ -294,7 +282,6 @@ KsAllocateObjectHeader(
     PDEVICE_EXTENSION DeviceExtension;
     PKSIDEVICE_HEADER DeviceHeader;
     PKSIOBJECT_HEADER ObjectHeader;
-    WCHAR ObjectClass[50];
 
     if (!Header)
         return STATUS_INVALID_PARAMETER_1;
@@ -312,18 +299,10 @@ KsAllocateObjectHeader(
     /* get device header */
     DeviceHeader = DeviceExtension->DeviceHeader;
 
-    ObjectClass[0] = L'\0';
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
     /* check for an file object */
-    if (IoStack->FileObject != NULL)
-    {
-        /* validate the file name */
-        if (IoStack->FileObject->FileName.Length >= 38)
-        {
-            RtlMoveMemory(ObjectClass, IoStack->FileObject->FileName.Buffer, 38 * sizeof(WCHAR));
-            ObjectClass[38] = L'\0';
-            DPRINT("ObjectClass %S\n", ObjectClass);
-        }
-    }
+
     /* allocate the object header */
     ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER);
     if (!ObjectHeader)
@@ -333,13 +312,17 @@ KsAllocateObjectHeader(
     RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
 
     /* do we have a name */
-    if (ObjectClass[0])
+    if (IoStack->FileObject->FileName.Buffer)
     {
-        ObjectHeader->ObjectClass = ExAllocatePoolWithTag(NonPagedPool, 40 * sizeof(WCHAR), TAG_DEVICE_HEADER);
-        if (ObjectHeader->ObjectClass)
+        /* copy object class */
+        ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength;
+        ObjectHeader->ObjectClass.Buffer = ExAllocatePoolWithTag(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength, TAG_DEVICE_HEADER);
+        if (!ObjectHeader->ObjectClass.Buffer)
         {
-            wcscpy(ObjectHeader->ObjectClass, ObjectClass);
+            ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER);
+            return STATUS_INSUFFICIENT_RESOURCES;
         }
+        RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName);
     }
 
     /* copy dispatch table */
@@ -362,7 +345,6 @@ KsAllocateObjectHeader(
     {
         /* the object header is for a audio filter */
         ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
-        DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader;
         IoStack->FileObject->FsContext = ObjectHeader;
     }
 
@@ -370,7 +352,7 @@ KsAllocateObjectHeader(
     *Header = ObjectHeader;
 
 
-    DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectClass, IoStack->FileObject, ObjectHeader);
+    DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader);
 
     return STATUS_SUCCESS;
 
@@ -725,8 +707,9 @@ KsCreate(
     PDEVICE_EXTENSION DeviceExtension;
     PKSIDEVICE_HEADER DeviceHeader;
     ULONG Index;
-    NTSTATUS Status = STATUS_SUCCESS;
+    NTSTATUS Status;
     KIRQL OldLevel;
+    ULONG Length;
 
     DPRINT("KS / CREATE\n");
     /* get current stack location */
@@ -738,56 +721,85 @@ KsCreate(
 
     /* acquire list lock */
     KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel);
-    /* loop all device items */
-    for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
+
+    /* sanity check */
+    ASSERT(IoStack->FileObject);
+
+    if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->MaxItems == 1)
     {
-        if (DeviceHeader->ItemList[Index].bCreated && DeviceHeader->ItemList[Index].ObjectHeader == NULL)
+        /* hack for bug 4566 */
+        if (!DeviceHeader->ItemList[0].CreateItem || !DeviceHeader->ItemList[0].CreateItem->Create)
         {
-            DeviceHeader->DeviceIndex = Index;
-             /* set object create item */
-            KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem;
-            Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp);
-
-            /* FIXME IoRegisterDeviceInterface does not support reference strings */
-            /* FIXME Check the irp target with the create item's object class */
-            if (NT_SUCCESS(Status))
-            {
-                /* release lock */
-                KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
-                return Status;
-            }
+            /* no valid create item */
+            Irp->IoStatus.Information = 0;
+            Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            /* release lock */
+            KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
+            /* return status */
+            return STATUS_UNSUCCESSFUL;
         }
-        else if (DeviceHeader->ItemList[Index].bCreated && IoStack->FileObject->FileName.Buffer != NULL)
-        {
-            ULONG Length;
 
-            ASSERT(DeviceHeader->ItemList[Index].ObjectHeader);
-            ASSERT(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem);
-            ASSERT(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer);
+        /* set object create item */
+        KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[0].CreateItem;
 
-            Length = wcslen(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer);
+        /* call create function */
+        Status = DeviceHeader->ItemList[0].CreateItem->Create(DeviceObject, Irp);
+        /* release lock */
+        KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
+        /* return result */
+        return Status;
+    }
 
-            /* filter for that type has already exists */
-            if (!_wcsnicmp(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer,
-                          IoStack->FileObject->FileName.Buffer,
-                          Length))
-            {
-                if (IoStack->FileObject->FileName.Buffer[0] != L'{')
-                {
-                    RtlMoveMemory(IoStack->FileObject->FileName.Buffer, &IoStack->FileObject->FileName.Buffer[Length+1],
-                                   IoStack->FileObject->FileName.Length - (Length + 1) * sizeof(WCHAR));
 
-                    IoStack->FileObject->FileName.Length -= (Length + 1)* sizeof(WCHAR);
-                }
+    /* hack for bug 4566 */
+    if (IoStack->FileObject->FileName.Buffer == NULL)
+    {
+        DPRINT("Using reference string hack\n");
+        /* release lock */
+        KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
+        Irp->IoStatus.Information = 0;
+        /* set return status */
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
+
+    /* loop all device items */
+    for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
+    {
+        /* is there a create item */
+        if (DeviceHeader->ItemList[Index].CreateItem == NULL)
+            continue;
 
+        /* check if the create item is initialized */
+        if (!DeviceHeader->ItemList[Index].CreateItem->Create)
+            continue;
 
-                KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem;
-                Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp);
-                KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
-                return Status;
-            }
-        }
+        ASSERT(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer);
+        DPRINT("CreateItem %p Request %S\n", DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer,
+                                              IoStack->FileObject->FileName.Buffer);
 
+        /* get object class length */
+        Length = wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer);
+        /* now check if the object class is the same */
+        if (!_wcsnicmp(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, &IoStack->FileObject->FileName.Buffer[1], Length) ||
+            (DeviceHeader->ItemList[Index].CreateItem->Flags & KSCREATE_ITEM_WILDCARD))
+        {
+            /* setup create parameters */
+            DeviceHeader->DeviceIndex = Index;
+             /* set object create item */
+            KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[Index].CreateItem;
+
+            /* call create function */
+            Status = DeviceHeader->ItemList[Index].CreateItem->Create(DeviceObject, Irp);
+
+            /* release lock */
+            KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
+
+            /* return result */
+            return Status;
+        }
     }
 
     /* release lock */
@@ -810,7 +822,6 @@ KsClose(
     PKSIOBJECT_HEADER ObjectHeader;
     PDEVICE_EXTENSION DeviceExtension;
     PKSIDEVICE_HEADER DeviceHeader;
-    ULONG Index;
 
     /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -827,20 +838,20 @@ KsClose(
         ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
 
         KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
-
-        for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
-        {
-            if (DeviceHeader->ItemList[Index].ObjectHeader == ObjectHeader)
-            {
-                DeviceHeader->ItemList[Index].ObjectHeader = NULL;
-            }
-        }
         return ObjectHeader->DispatchTable.Close(DeviceObject, Irp);
     }
     else
     {
+#if 0
         DPRINT1("Expected Object Header FileObject %p FsContext %p\n", IoStack->FileObject, IoStack->FileObject->FsContext);
         KeBugCheckEx(0, 0, 0, 0, 0);
+#else
+        DPRINT("Using reference string hack\n");
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = 0;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+#endif
         return STATUS_SUCCESS;
     }
 }
@@ -853,10 +864,63 @@ KsDeviceControl(
 {
     PIO_STACK_LOCATION IoStack;
     PKSIOBJECT_HEADER ObjectHeader;
+    PKSIDEVICE_HEADER DeviceHeader;
+    PDEVICE_EXTENSION DeviceExtension;
+    ULONG Length, Index;
+    LPWSTR Buffer;
 
     /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
+    /* hack for bug 4566 */
+    if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS)
+    {
+        /* get device extension */
+        DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
+        /* get device header */
+        DeviceHeader = DeviceExtension->DeviceHeader;
+
+        /* retrieve all available reference strings registered */
+        Length = 0;
+
+        for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
+        {
+            if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer)
+                continue;
+
+            Length += wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + 1;
+        }
+
+        /* add extra zero */
+        Length += 1;
+
+        /* allocate the buffer */
+        Buffer = ExAllocatePool(NonPagedPool, Length * sizeof(WCHAR));
+        if (!Buffer)
+        {
+            Irp->IoStatus.Information = 0;
+            Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        *((LPWSTR*)Irp->UserBuffer) = Buffer;
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+        Irp->IoStatus.Information = sizeof(LPWSTR);
+
+        for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
+        {
+            if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer)
+                continue;
+
+            wcscpy(Buffer, DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer);
+            Buffer += wcslen(Buffer) + 1;
+        }
+        *Buffer = L'\0';
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
+
     DPRINT("KS / DeviceControl\n");
     if (IoStack->FileObject && IoStack->FileObject->FsContext)
     {
@@ -864,14 +928,6 @@ KsDeviceControl(
 
         KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
 
-        if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS)
-        {
-            *((LPWSTR*)Irp->UserBuffer) = ObjectHeader->CreateItem->ObjectClass.Buffer;
-            Irp->IoStatus.Status = STATUS_SUCCESS;
-            Irp->IoStatus.Information = sizeof(LPWSTR);
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
-            return STATUS_SUCCESS;
-        }
         return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
     }
     else
index 68a563c..89f2cf7 100644 (file)
@@ -6,17 +6,15 @@ struct KSIDEVICE_HEADER;
 typedef struct
 {
     KSDISPATCH_TABLE DispatchTable;
-    LPWSTR ObjectClass;
     ULONG ItemCount;
     PKSOBJECT_CREATE_ITEM CreateItem;
 
+    UNICODE_STRING ObjectClass;
 }KSIOBJECT_HEADER, *PKSIOBJECT_HEADER;
 
 typedef struct
 {
-    BOOL bCreated;
-    PKSIOBJECT_HEADER ObjectHeader;
-    KSOBJECT_CREATE_ITEM CreateItem;
+    PKSOBJECT_CREATE_ITEM CreateItem;
 }DEVICE_ITEM, *PDEVICE_ITEM;
 
 
index c402266..a20d2dd 100644 (file)
@@ -282,16 +282,18 @@ KsSynchronousIoControlDevice(
     if (!DeviceObject)
         return STATUS_UNSUCCESSFUL;
 
+
     /* get object header */
     ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext;
+#if 0
     if (!ObjectHeader)
     {
         DPRINT("Expected object header\n");
         return STATUS_UNSUCCESSFUL;
     }
-
+#endif
     /* check if there is fast device io function */
-    if (ObjectHeader->DispatchTable.FastDeviceIoControl)
+    if (ObjectHeader && ObjectHeader->DispatchTable.FastDeviceIoControl)
     {
         IoStatusBlock.Status = STATUS_UNSUCCESSFUL;
         IoStatusBlock.Information = 0;
index a887eab..07d7d85 100644 (file)
@@ -17,26 +17,56 @@ KspCreateObjectType(
     NTSTATUS Status;
     IO_STATUS_BLOCK IoStatusBlock;
     OBJECT_ATTRIBUTES ObjectAttributes;
+    PFILE_OBJECT FileObject;
     UNICODE_STRING Name;
+    PKSIOBJECT_HEADER ObjectHeader;
 
-    Name.Length = Name.MaximumLength = (wcslen(ObjectType) + 1) * sizeof(WCHAR) + CreateParametersSize;
+    /* acquire parent file object */
+    Status = ObReferenceObjectByHandle(ParentHandle,
+                                       GENERIC_READ | GENERIC_WRITE, 
+                                       IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT("Failed to reference parent %x\n", Status);
+        return Status;
+    }
+
+    /* get parent object header */
+    ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext;
+    /* sanity check */
+    ASSERT(ObjectHeader);
+
+    /* calculate request length */
+    Name.Length = 0;
+    Name.MaximumLength = wcslen(ObjectType) * sizeof(WCHAR) + CreateParametersSize + ObjectHeader->ObjectClass.MaximumLength + 2 * sizeof(WCHAR);
     Name.MaximumLength += sizeof(WCHAR);
+    /* acquire request buffer */
     Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength);
-
+    /* check for success */
     if (!Name.Buffer)
     {
+        /* insufficient resources */
+        ObDereferenceObject(FileObject);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
-    wcscpy(Name.Buffer, ObjectType);
-    Name.Buffer[wcslen(ObjectType)] = '\\';
-
-    RtlMoveMemory(Name.Buffer + wcslen(ObjectType) +1, CreateParameters, CreateParametersSize);
-
+    /* build a request which looks like \Parent\{ObjectGuid}\CreateParameters 
+     * For pins the parent is the reference string used in registration
+     * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams
+     */
+    
+    RtlAppendUnicodeStringToString(&Name, &ObjectHeader->ObjectClass);
+    RtlAppendUnicodeToString(&Name, L"\\");
+    RtlAppendUnicodeToString(&Name, ObjectType);
+    RtlAppendUnicodeToString(&Name, L"\\");
+    /* append create parameters */
+    RtlMoveMemory(Name.Buffer + (Name.Length / sizeof(WCHAR)), CreateParameters, CreateParametersSize);
+    Name.Length += CreateParametersSize;
     Name.Buffer[Name.Length / 2] = L'\0';
-    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL);
-
 
+    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL);
+    /* create the instance */
     Status = IoCreateFile(NodeHandle,
                           DesiredAccess,
                           &ObjectAttributes,
@@ -52,7 +82,10 @@ KspCreateObjectType(
                           NULL,
                           IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
 
+    /* free request buffer */
     ExFreePool(Name.Buffer);
+    /* release parent handle */
+    ObDereferenceObject(FileObject);
     return Status;
 }
 
index 1fecad8..dd5de4d 100644 (file)
@@ -314,7 +314,7 @@ IIrpQueue_fnMinimumDataAvailable(
     if (This->StartStream)
         return TRUE;
 
-    if (This->DataFormat->WaveFormatEx.nAvgBytesPerSec < This->NumDataAvailable)
+    if (This->DataFormat->WaveFormatEx.nAvgBytesPerSec/3 < This->NumDataAvailable)
     {
         This->StartStream = TRUE;
         Result = TRUE;
index 4b8b7e3..fcacc43 100644 (file)
@@ -542,6 +542,8 @@ PcCreateItemDispatch(
     IIrpTarget *Filter;
     PKSOBJECT_CREATE_ITEM CreateItem;
     PPIN_WORKER_CONTEXT Context;
+    LPWSTR Buffer;
+    static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
 
     DPRINT1("PcCreateItemDispatch called DeviceObject %p\n", DeviceObject);
 
@@ -604,60 +606,55 @@ PcCreateItemDispatch(
         return Status;
     }
 
-    /* is just the filter requested */
-    if (IoStack->FileObject->FileName.Buffer == NULL)
+    /* get the buffer */
+    Buffer = IoStack->FileObject->FileName.Buffer;
+
+    /* check if the request contains a pin request */
+    if (!wcsstr(Buffer, KS_NAME_PIN))
     {
-        /* create the dispatch object */
+        /* creator just wants the filter object */
         Status = NewDispatchObject(Irp, Filter, CreateItem->ObjectClass.Buffer);
 
         DPRINT1("Filter %p\n", Filter);
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
     }
     else
     {
-        LPWSTR Buffer = IoStack->FileObject->FileName.Buffer;
-
-        static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
-
-        /* is the request for a new pin */
-        if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
+        /* try to create new pin */
+        Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
+        if (!Context)
         {
-            /* try to create new pin */
-            Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS);
-            if (!Context)
-            {
-                DPRINT("Failed to allocate worker context\n");
-                Irp->IoStatus.Information = 0;
-                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-            /* allocate work item */
-            Context->WorkItem = IoAllocateWorkItem(DeviceObject);
-            if (!Context->WorkItem)
-            {
-                DPRINT("Failed to allocate workitem\n");
-                FreeItem(Context, TAG_PORTCLASS);
-                Irp->IoStatus.Information = 0;
-                Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
-                return STATUS_INSUFFICIENT_RESOURCES;
-            }
-
-            Context->Filter = Filter;
-            Context->Irp = Irp;
-
-            DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql());
+            DPRINT("Failed to allocate worker context\n");
             Irp->IoStatus.Information = 0;
-            Irp->IoStatus.Status = STATUS_PENDING;
-            IoMarkIrpPending(Irp);
-            IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
-            return STATUS_PENDING;
+            Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_INSUFFICIENT_RESOURCES;
         }
+        /* allocate work item */
+        Context->WorkItem = IoAllocateWorkItem(DeviceObject);
+        if (!Context->WorkItem)
+        {
+            DPRINT("Failed to allocate workitem\n");
+            FreeItem(Context, TAG_PORTCLASS);
+            Irp->IoStatus.Information = 0;
+            Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        Context->Filter = Filter;
+        Context->Irp = Irp;
+
+        DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql());
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = STATUS_PENDING;
+        IoMarkIrpPending(Irp);
+        IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
+        return STATUS_PENDING;
     }
-    Irp->IoStatus.Information = 0;
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return Status;
 }
 
 
index 6840037..a71e8fc 100644 (file)
@@ -201,7 +201,7 @@ DispatchCreateKMix(
     if (Buffer)
     {
         /* is the request for a new pin */
-        if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
+        if (!wcsstr(KS_NAME_PIN, Buffer))
         {
             Status = CreatePin(Irp);
 
index 8fca496..1b582d6 100644 (file)
@@ -20,97 +20,13 @@ const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX  = {0x05589f81L, 0xc356, 0x11ce,
 
 NTSTATUS
 ComputeCompatibleFormat(
-    IN PKSAUDIO_SUBDEVICE_ENTRY Entry,
+    IN PKSAUDIO_DEVICE_ENTRY Entry,
     IN ULONG PinId,
     IN PSYSAUDIODEVEXT DeviceExtension,
     IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
     OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat);
 
 
-NTSTATUS
-NTAPI
-KspCreateObjectType(
-    IN HANDLE ParentHandle,
-    IN LPWSTR ObjectType,
-    PVOID CreateParameters,
-    UINT CreateParametersSize,
-    IN  ACCESS_MASK DesiredAccess,
-    OUT PHANDLE NodeHandle)
-{
-    NTSTATUS Status;
-    IO_STATUS_BLOCK IoStatusBlock;
-    OBJECT_ATTRIBUTES ObjectAttributes;
-    UNICODE_STRING Name;
-
-    Name.Length = Name.MaximumLength = (wcslen(ObjectType) + 1) * sizeof(WCHAR) + CreateParametersSize;
-    Name.MaximumLength += sizeof(WCHAR);
-    Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength);
-
-    if (!Name.Buffer)
-    {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    wcscpy(Name.Buffer, ObjectType);
-    Name.Buffer[wcslen(ObjectType)] = '\\';
-
-    RtlMoveMemory(Name.Buffer + wcslen(ObjectType) +1, CreateParameters, CreateParametersSize);
-
-    Name.Buffer[Name.Length / 2] = L'\0';
-    InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL);
-
-
-    Status = IoCreateFile(NodeHandle,
-                          DesiredAccess,
-                          &ObjectAttributes,
-                          &IoStatusBlock,
-                          NULL,
-                          0,
-                          0,
-                          FILE_OPEN,
-                          FILE_SYNCHRONOUS_IO_NONALERT,
-                          NULL,
-                          0,
-                          CreateFileTypeNone,
-                          NULL,
-                          IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
-
-    ExFreePool(Name.Buffer);
-
-    return Status;
-}
-
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsoCreatePin(
-    IN  HANDLE FilterHandle,
-    IN  PKSPIN_CONNECT Connect,
-    IN  ACCESS_MASK DesiredAccess,
-    OUT PHANDLE ConnectionHandle,
-    IN LPWSTR ObjectClass)
-{
-    WCHAR szBuffer[100];
-    UINT ConnectSize = sizeof(KSPIN_CONNECT);
-
-    PKSDATAFORMAT_WAVEFORMATEX Format = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1);
-    if (Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) ||
-        Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX))
-    {
-        ConnectSize += Format->DataFormat.FormatSize;
-    }
-
-    swprintf(szBuffer, L"%s\\{146F1A80-4791-11D0-A5D6-28DB04C10000}", ObjectClass);
-
-    return KspCreateObjectType(FilterHandle,
-                               szBuffer,
-                               (PVOID)Connect,
-                               ConnectSize,
-                               DesiredAccess,
-                               ConnectionHandle);
-}
-
-
 NTSTATUS
 SetIrpIoStatus(
     IN PIRP Irp,
@@ -131,38 +47,20 @@ SetIrpIoStatus(
 
 }
 
-PKSAUDIO_SUBDEVICE_ENTRY
+PKSAUDIO_DEVICE_ENTRY
 GetListEntry(
     IN PLIST_ENTRY Head,
     IN ULONG Index)
 {
-    PKSAUDIO_DEVICE_ENTRY DeviceEntry;
-    PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
-    PLIST_ENTRY SubEntry, Entry = Head->Flink;
-
-    while(Entry != Head)
-    {
-        DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
-        if (Index < DeviceEntry->NumSubDevices)
-        {
-            SubEntry = DeviceEntry->SubDeviceList.Flink;
-            while(SubEntry != &DeviceEntry->SubDeviceList && Index--)
-                SubEntry = SubEntry->Flink;
-
-            SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry);
-            return SubDeviceEntry;
-        }
-        else
-        {
-            Index -= DeviceEntry->NumSubDevices;
-        }
+    PLIST_ENTRY Entry = Head->Flink;
 
+    while(Index-- && Entry != Head)
         Entry = Entry->Flink;
 
-    }
-    DPRINT1("Not Found index %u\n", Index);
+    if (Entry == Head)
+        return NULL;
 
-    return NULL;
+    return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry);
 }
 
 NTSTATUS
@@ -171,7 +69,7 @@ SysAudioOpenVirtualDevice(
     IN ULONG DeviceNumber,
     PSYSAUDIODEVEXT DeviceExtension)
 {
-    PKSAUDIO_SUBDEVICE_ENTRY Entry;
+    PKSAUDIO_DEVICE_ENTRY Entry;
     PKSOBJECT_CREATE_ITEM CreateItem;
 
     /* access the create item */
@@ -243,7 +141,7 @@ CreateMixerPinAndSetFormat(
     HANDLE PinHandle;
     PFILE_OBJECT FileObject;
 
-    Status = KsoCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle, L"KMixer");
+    Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);//, L"KMixer");
 
     if (!NT_SUCCESS(Status))
     {
@@ -305,7 +203,7 @@ CreatePinWorkerRoutine(
 
 
     /* Let's try to create the audio irp pin */
-    Status = KsoCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass);
+    Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
 
     if (!NT_SUCCESS(Status))
     {
@@ -345,7 +243,7 @@ CreatePinWorkerRoutine(
         }
 
         /* Retry with Mixer format */
-        Status = KsoCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass);
+        Status = KsCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); //, WorkerContext->Entry->ObjectClass);
         if (!NT_SUCCESS(Status))
         {
            /* This should not fail */
@@ -390,7 +288,7 @@ CreatePinWorkerRoutine(
 
     DPRINT1("creating virtual pin\n");
     /* now create the virtual audio pin which is exposed to wdmaud */
-    Status = KsoCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle, L"SysAudio");
+    Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle); //, L"SysAudio");
 
     if (!NT_SUCCESS(Status))
     {
@@ -454,7 +352,7 @@ HandleSysAudioFilterPinProperties(
 {
     PIO_STACK_LOCATION IoStack;
     NTSTATUS Status;
-    PKSAUDIO_SUBDEVICE_ENTRY Entry;
+    PKSAUDIO_DEVICE_ENTRY Entry;
     ULONG BytesReturned;
     PKSP_PIN Pin;
 
@@ -541,7 +439,7 @@ HandleSysAudioFilterPinProperties(
 
 NTSTATUS
 ComputeCompatibleFormat(
-    IN PKSAUDIO_SUBDEVICE_ENTRY Entry,
+    IN PKSAUDIO_DEVICE_ENTRY Entry,
     IN ULONG PinId,
     IN PSYSAUDIODEVEXT DeviceExtension,
     IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
@@ -676,7 +574,7 @@ ComputeCompatibleFormat(
 
 NTSTATUS
 GetPinInstanceCount(
-    PKSAUDIO_SUBDEVICE_ENTRY Entry,
+    PKSAUDIO_DEVICE_ENTRY Entry,
     PKSPIN_CINSTANCES PinInstances,
     PKSPIN_CONNECT PinConnect)
 {
@@ -701,7 +599,7 @@ HandleSysAudioFilterPinCreation(
     PDEVICE_OBJECT DeviceObject)
 {
     ULONG Length;
-    PKSAUDIO_SUBDEVICE_ENTRY Entry;
+    PKSAUDIO_DEVICE_ENTRY Entry;
     KSPIN_CONNECT * PinConnect;
     PIO_STACK_LOCATION IoStack;
     PSYSAUDIO_INSTANCE_INFO InstanceInfo;
@@ -848,7 +746,7 @@ SysAudioHandleProperty(
     PULONG Index;
     PKSPROPERTY Property;
     PSYSAUDIODEVEXT DeviceExtension;
-    PKSAUDIO_SUBDEVICE_ENTRY Entry;
+    PKSAUDIO_DEVICE_ENTRY Entry;
     PSYSAUDIO_INSTANCE_INFO InstanceInfo;
     ULONG BytesReturned;
     PKSOBJECT_CREATE_ITEM CreateItem;
index d76cb5f..d9a8567 100644 (file)
@@ -18,7 +18,7 @@ const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL    = {0xBF963D80L, 0xC559, 0x11D0, {
 
 VOID
 QueryFilterRoutine(
-    IN PKSAUDIO_SUBDEVICE_ENTRY DeviceEntry)
+    IN PKSAUDIO_DEVICE_ENTRY DeviceEntry)
 {
     KSPROPERTY PropertyRequest;
     KSP_PIN PinRequest;
@@ -32,15 +32,6 @@ QueryFilterRoutine(
 
     DPRINT("Querying filter...\n");
 
-    Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_OBJECT_CLASS, NULL, 0, &DeviceEntry->ObjectClass, sizeof(LPWSTR), &BytesReturned);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Failed to query object class Status %x\n", Status);
-        return;
-    }
-
-    DPRINT("ObjectClass %S\n", DeviceEntry->ObjectClass);
-
     PropertyRequest.Set = KSPROPSETID_Pin;
     PropertyRequest.Flags = KSPROPERTY_TYPE_GET;
     PropertyRequest.Id = KSPROPERTY_PIN_CTYPES;
@@ -114,9 +105,6 @@ QueryFilterRoutine(
     DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, NumWaveOutPin);
 }
 
-
-
-
 VOID
 NTAPI
 FilterPinWorkerRoutine(
@@ -124,21 +112,11 @@ FilterPinWorkerRoutine(
     IN PVOID Context)
 {
     PKSAUDIO_DEVICE_ENTRY DeviceEntry;
-    PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
-    PLIST_ENTRY ListEntry;
-
     PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context;
 
     DeviceEntry = Ctx->DeviceEntry;
 
-    ListEntry = DeviceEntry->SubDeviceList.Flink;
-    while(ListEntry != &DeviceEntry->SubDeviceList)
-    {
-        SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(ListEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry);
-        QueryFilterRoutine(SubDeviceEntry);
-        ListEntry = ListEntry->Flink;
-    }
-
+    QueryFilterRoutine(DeviceEntry);
 
     /* free work item */
     IoFreeWorkItem(Ctx->WorkItem);
@@ -177,7 +155,7 @@ OpenDevice(
 
     if (!NT_SUCCESS(Status))
     {
-        DPRINT("ZwCreateFile failed with %x\n", Status);
+        DPRINT("ZwCreateFile failed with %x %S\n", Status, DeviceName->Buffer);
         return Status;
     }
 
@@ -194,6 +172,114 @@ OpenDevice(
     return Status;
 }
 
+NTSTATUS
+InsertAudioDevice(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PUNICODE_STRING DeviceName,
+    IN LPWSTR ReferenceString)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PFILTER_WORKER_CONTEXT Ctx = NULL;
+    PIO_WORKITEM WorkItem = NULL;
+    PSYSAUDIODEVEXT DeviceExtension;
+    PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
+
+    /* a new device has arrived */
+    DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
+    if (!DeviceEntry)
+    {
+        /* no memory */
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* initialize audio device entry */
+    RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY));
+
+    /* allocate filter ctx */
+    Ctx = ExAllocatePool(NonPagedPool, sizeof(FILTER_WORKER_CONTEXT));
+    if (!Ctx)
+    {
+        /* no memory */
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto cleanup;
+    }
+
+    /* allocate work item */
+    WorkItem = IoAllocateWorkItem(DeviceObject);
+    if (!WorkItem)
+    {
+        /* no memory */
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto cleanup;
+    }
+
+    /* set device name */
+    DeviceEntry->DeviceName.Length = 0;
+    DeviceEntry->DeviceName.MaximumLength = DeviceName->MaximumLength + 10 * sizeof(WCHAR);
+
+    /* hack for bug 4566 */
+    if (ReferenceString)
+    {
+        DeviceEntry->DeviceName.MaximumLength += (wcslen(ReferenceString) + 2) * sizeof(WCHAR);
+    }
+
+    DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
+
+    if (!DeviceEntry->DeviceName.Buffer)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto cleanup;
+    }
+
+    RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\");
+    RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, DeviceName);
+
+    if (ReferenceString)
+    {
+        RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\");
+        RtlAppendUnicodeToString(&DeviceEntry->DeviceName, ReferenceString);
+    }
+
+    Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject);
+
+     if (!NT_SUCCESS(Status))
+     {
+         goto cleanup;
+     }
+
+    Ctx->DeviceEntry = DeviceEntry;
+    Ctx->WorkItem = WorkItem;
+
+    /* fetch device extension */
+    DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
+    /* insert new audio device */
+    ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock);
+    InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices);
+
+    DPRINT("Successfully opened audio device %u Device %S\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer);
+    IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx);
+    return Status;
+
+cleanup:
+    if (Ctx)
+        ExFreePool(Ctx);
+
+    if (WorkItem)
+        IoFreeWorkItem(WorkItem);
+
+    if (DeviceEntry)
+    {
+        if (DeviceEntry->DeviceName.Buffer)
+            ExFreePool(DeviceEntry->DeviceName.Buffer);
+
+        ExFreePool(DeviceEntry);
+    }
+
+    return Status;
+
+}
+
+
 NTSTATUS
 NTAPI
 DeviceInterfaceChangeCallback(
@@ -203,10 +289,13 @@ DeviceInterfaceChangeCallback(
     DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event;
     NTSTATUS Status = STATUS_SUCCESS;
     PSYSAUDIODEVEXT DeviceExtension;
-    PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL;
-    PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
-    PIO_WORKITEM WorkItem = NULL;
-    PFILTER_WORKER_CONTEXT Ctx = NULL;
+    UNICODE_STRING DeviceName;
+    HANDLE Handle;
+    PFILE_OBJECT FileObject;
+    LPWSTR ReferenceString;
+    ULONG BytesReturned;
+
+
     PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
 
     DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
@@ -216,96 +305,54 @@ DeviceInterfaceChangeCallback(
     if (IsEqualGUIDAligned(&Event->Event,
                            &GUID_DEVICE_INTERFACE_ARRIVAL))
     {
+        /*<HACK>
+         * 1) Open the filter w/o reference string
+         * 2) Retrieve reference strings with our private IOCTL_KS_OBJECT_CLASS
+         * 3) Append these reference strings to symbolic link we got
+         * * see bug 4566
+         */
 
-        /* a new device has arrived */
-        DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
-        if (!DeviceEntry)
-        {
-            /* no memory */
-            return STATUS_INSUFFICIENT_RESOURCES;
-        }
+        DeviceName.Length = 0;
+        DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR);
 
-        /* initialize audio device entry */
-        RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY));
-
-        /* allocate filter ctx */
-        Ctx = ExAllocatePool(NonPagedPool, sizeof(FILTER_WORKER_CONTEXT));
-        if (!Ctx)
-        {
-            /* no memory */
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto cleanup;
-        }
+        DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName.MaximumLength);
 
-        /* allocate work item */
-        WorkItem = IoAllocateWorkItem(DeviceObject);
-        if (!WorkItem)
+        if (!DeviceName.Buffer)
         {
-            /* no memory */
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto cleanup;
+            return STATUS_INSUFFICIENT_RESOURCES;
         }
 
-        /* set device name */
-        DeviceEntry->DeviceName.Length = 0;
-        DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR);
-        DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
+       RtlAppendUnicodeToString(&DeviceName, L"\\??\\");
+       RtlAppendUnicodeStringToString(&DeviceName, Event->SymbolicLinkName);
 
-        if (!DeviceEntry->DeviceName.Buffer)
-        {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
-            goto cleanup;
-        }
 
-        if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\")))
+        Status = OpenDevice(&DeviceName, &Handle, &FileObject);
+        if (!NT_SUCCESS(Status))
         {
-            DPRINT1("RtlAppendUnicodeToString failed with %x\n", Status);
-            goto cleanup;
+            ExFreePool(DeviceName.Buffer);
+            return Status;
         }
 
-        if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName)))
+        Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_OBJECT_CLASS, NULL, 0, &ReferenceString, sizeof(LPWSTR), &BytesReturned);
+        if (!NT_SUCCESS(Status))
         {
-            DPRINT1("RtlAppendUnicodeStringToString failed with %x\n", Status);
-            goto cleanup;
-        }
+            DPRINT1("failed Status %x\n", Status);
 
-        /* FIXME Ros does not support device interface strings */
-        /* Workarround: repeatly call IoCreateFile untill ks wont find a create item which has no object header attached */
+            ExFreePool(DeviceName.Buffer);
+            ObDereferenceObject(FileObject);
+            ZwClose(Handle);
+            return Status;
+       }
 
-        InitializeListHead(&DeviceEntry->SubDeviceList);
-        do
+        while(*ReferenceString)
         {
-            SubDeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_SUBDEVICE_ENTRY));
-            if (SubDeviceEntry)
-            {
-                RtlZeroMemory(SubDeviceEntry,  sizeof(KSAUDIO_SUBDEVICE_ENTRY));
-                Status = OpenDevice(&DeviceEntry->DeviceName, &SubDeviceEntry->Handle, &SubDeviceEntry->FileObject);
-                if (NT_SUCCESS(Status))
-                {
-                    InsertTailList(&DeviceEntry->SubDeviceList, &SubDeviceEntry->Entry);
-                    DeviceEntry->NumSubDevices++;
-                    /* increment audio device count */
-                    InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices);
-                }
-                else
-                {
-                    ExFreePool(SubDeviceEntry);
-                    break;
-                }
-            }
-        }while(NT_SUCCESS(Status) && SubDeviceEntry != NULL);
-
-        DPRINT("Successfully opened audio device %u Device %S NumberOfSubDevices %u\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer, DeviceEntry->NumSubDevices);
-
-        Ctx->DeviceEntry = DeviceEntry;
-        Ctx->WorkItem = WorkItem;
-
-        /* fetch device extension */
-        DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
-        /* insert new audio device */
-        ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock);
-
-        IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx);
+            Status = InsertAudioDevice(DeviceObject, Event->SymbolicLinkName, ReferenceString);
+            ReferenceString += wcslen(ReferenceString) + 1;
+        }
+        //ExFreePool(ReferenceString);
+        ObDereferenceObject(FileObject);
+        ZwClose(Handle);
+        ExFreePool(DeviceName.Buffer);
         return Status;
     }
     else
@@ -315,22 +362,7 @@ DeviceInterfaceChangeCallback(
         return STATUS_SUCCESS;
     }
 
-cleanup:
-    if (Ctx)
-        ExFreePool(Ctx);
-
-    if (WorkItem)
-        IoFreeWorkItem(WorkItem);
 
-    if (DeviceEntry)
-    {
-        if (DeviceEntry->DeviceName.Buffer)
-            ExFreePool(DeviceEntry->DeviceName.Buffer);
-
-        ExFreePool(DeviceEntry);
-    }
-
-    return Status;
 }
 
 NTSTATUS
index 218772b..078bf41 100644 (file)
@@ -201,7 +201,7 @@ DispatchCreateSysAudio(
     if (Buffer)
     {
         /* is the request for a new pin */
-        if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
+        if (wcsstr(Buffer, KS_NAME_PIN))
         {
             Status = CreateDispatcher(Irp);
             DPRINT("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject);
@@ -259,6 +259,7 @@ SysAudioAllocateDeviceHeader(
     RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
     CreateItem->Create = DispatchCreateSysAudio;
     RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
+    CreateItem->Flags = KSCREATE_ITEM_WILDCARD;
 
     Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
                                     1,
@@ -271,7 +272,6 @@ SysAudioOpenKMixer(
     IN SYSAUDIODEVEXT *DeviceExtension)
 {
     NTSTATUS Status;
-    
     UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer");
     UNICODE_STRING DevicePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\kmixer");
 
index 628e8d1..6cdf252 100644 (file)
@@ -34,9 +34,8 @@ SysAudio_Shutdown(
     IN  PIRP Irp)
 {
     PKSAUDIO_DEVICE_ENTRY DeviceEntry;
-    PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry;
     PSYSAUDIODEVEXT DeviceExtension;
-    PLIST_ENTRY Entry, SubEntry;
+    PLIST_ENTRY Entry;
 
     DPRINT1("SysAudio_Shutdown called\n");
 
@@ -50,16 +49,6 @@ SysAudio_Shutdown(
         DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName);
         RtlFreeUnicodeString(&DeviceEntry->DeviceName);
 
-        while(!IsListEmpty(&DeviceEntry->SubDeviceList))
-        {
-            SubEntry = RemoveHeadList(&DeviceEntry->SubDeviceList);
-            SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry);
-
-            ZwClose(SubDeviceEntry->Handle);
-            ObDereferenceObject(SubDeviceEntry->FileObject);
-            ExFreePool(SubDeviceEntry->Pins);
-            ExFreePool(SubDeviceEntry);
-        }
         ExFreePool(DeviceEntry);
     }
 
index 9673f21..8defc5b 100644 (file)
@@ -22,7 +22,8 @@ typedef struct
 
 typedef struct
 {
-    LIST_ENTRY Entry;                       // linked list entry to KSAUDIO_DEVICE_ENTRY
+    LIST_ENTRY Entry;                                  // device entry for KsAudioDeviceList
+    UNICODE_STRING DeviceName;                         // symbolic link of audio device
 
     HANDLE Handle;                          // handle to audio sub device
     PFILE_OBJECT FileObject;                // file objecto to audio sub device
@@ -30,18 +31,6 @@ typedef struct
     ULONG NumberOfPins;                     // number of pins of audio device
     PIN_INFO * Pins;                        // array of PIN_INFO
 
-    LPWSTR ObjectClass;                     // object class of sub device
-
-}KSAUDIO_SUBDEVICE_ENTRY, *PKSAUDIO_SUBDEVICE_ENTRY;
-
-typedef struct
-{
-    LIST_ENTRY Entry;                                  // device entry for KsAudioDeviceList
-    UNICODE_STRING DeviceName;                         // symbolic link of audio device
-
-    ULONG NumSubDevices;                               // number of subdevices
-    LIST_ENTRY SubDeviceList;                          // audio sub device list
-
 }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
 
 typedef struct
@@ -71,7 +60,7 @@ typedef struct
 {
     HANDLE Handle;                                       // audio irp pin handle
     ULONG PinId;                                         // pin id of device
-    PKSAUDIO_SUBDEVICE_ENTRY AudioEntry;                 // pointer to audio device entry
+    PKSAUDIO_DEVICE_ENTRY AudioEntry;                 // pointer to audio device entry
 
     HANDLE hMixerPin;                                    // handle to mixer pin
 }DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
@@ -86,7 +75,7 @@ typedef struct
     PIRP Irp;
     BOOL CreateRealPin;
     BOOL CreateMixerPin;
-    PKSAUDIO_SUBDEVICE_ENTRY Entry;
+    PKSAUDIO_DEVICE_ENTRY Entry;
     KSPIN_CONNECT * PinConnect;
     PDISPATCH_CONTEXT DispatchContext;
     PSYSAUDIODEVEXT DeviceExtension;
@@ -129,7 +118,7 @@ OpenDevice(
     IN PHANDLE HandleOut,
     IN PFILE_OBJECT * FileObjectOut);
 
-PKSAUDIO_SUBDEVICE_ENTRY
+PKSAUDIO_DEVICE_ENTRY
 GetListEntry(
     IN PLIST_ENTRY Head,
     IN ULONG Index);