- Rewrite registering physical connection handling to support KSPROPERTY_PIN_PHYSICAL...
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 27 Sep 2009 00:50:06 +0000 (00:50 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Sun, 27 Sep 2009 00:50:06 +0000 (00:50 +0000)
svn path=/trunk/; revision=43175

reactos/drivers/wdm/audio/backpln/portcls/adapter.cpp
reactos/drivers/wdm/audio/backpln/portcls/connection.cpp
reactos/drivers/wdm/audio/backpln/portcls/filter_topology.cpp
reactos/drivers/wdm/audio/backpln/portcls/interfaces.hpp
reactos/drivers/wdm/audio/backpln/portcls/irp.cpp
reactos/drivers/wdm/audio/backpln/portcls/port_wavecyclic.cpp
reactos/drivers/wdm/audio/backpln/portcls/private.hpp
reactos/drivers/wdm/audio/backpln/portcls/propertyhandler.cpp
reactos/drivers/wdm/audio/backpln/portcls/undoc.cpp
reactos/drivers/wdm/audio/backpln/portcls/unregister.cpp

index 7a08189..a80899d 100644 (file)
@@ -135,10 +135,6 @@ PcAddAdapterDevice(
     portcls_ext->PhysicalDeviceObject = PhysicalDeviceObject;
     // set up the start device function
     portcls_ext->StartDevice = StartDevice;
-    // prepare the subdevice list
-    InitializeListHead(&portcls_ext->SubDeviceList);
-    // prepare the physical connection list
-    InitializeListHead(&portcls_ext->PhysicalConnectionList);
     // initialize timer lock
     KeInitializeSpinLock(&portcls_ext->TimerListLock);
     // initialize timer list
@@ -214,10 +210,9 @@ PcRegisterSubdevice(
     NTSTATUS Status;
     ISubdevice *SubDevice;
     UNICODE_STRING SymbolicLinkName;
-    SUBDEVICE_DESCRIPTOR * SubDeviceDescriptor;
+    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
     ULONG Index;
     UNICODE_STRING RefName;
-    PSUBDEVICE_ENTRY Entry;
     PSYMBOLICLINK_ENTRY SymEntry;
 
     DPRINT1("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown);
@@ -259,36 +254,19 @@ PcRegisterSubdevice(
         return STATUS_UNSUCCESSFUL;
     }
 
-    // allocate subdevice entry
-    Entry = (PSUBDEVICE_ENTRY)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_ENTRY), TAG_PORTCLASS);
-    if (!Entry)
-    {
-        // Insufficient memory
-        SubDevice->Release();
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
     // add an create item to the device header
     Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PcCreateItemDispatch, (PVOID)SubDevice, Name, NULL);
     if (!NT_SUCCESS(Status))
     {
         // failed to attach
         SubDevice->Release();
-        FreeItem(Entry, TAG_PORTCLASS);
         DPRINT1("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status);
         return Status;
     }
 
     // initialize reference string
     RtlInitUnicodeString(&RefName, Name);
-
-    // initialize subdevice entry
-    Entry->SubDevice = SubDevice;
-    RtlInitUnicodeString(&Entry->Name, Name);
-    InitializeListHead(&Entry->SymbolicLinkList);
-
-    // store subdevice entry
-    InsertTailList(&DeviceExt->SubDeviceList, &Entry->Entry);
+    RtlInitUnicodeString(&SubDeviceDescriptor->RefString, Name);
 
     for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++)
     {
@@ -311,7 +289,7 @@ PcRegisterSubdevice(
                 // initialize symbolic link item
                 RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer);
                 // store item
-                InsertTailList(&Entry->SymbolicLinkList, &SymEntry->Entry);
+                InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
             }
             else
             {
index 45a455b..b10cab4 100644 (file)
@@ -81,107 +81,8 @@ UnRegisterConnection(
     IN PUNICODE_STRING ToString,
     IN ULONG ToPin)
 {
-    PLIST_ENTRY Entry;
-    PPHYSICAL_CONNECTION Connection;
-    PPCLASS_DEVICE_EXTENSION DeviceExt;
-    NTSTATUS Status;
-    ISubdevice * FromSubDevice = NULL;
-    ISubdevice * ToSubDevice = NULL;
-    ULONG bFound;
-
-    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    if (FromUnknown)
-    {
-        // get our private interface
-        Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&FromSubDevice);
-        if (!NT_SUCCESS(Status))
-            return STATUS_INVALID_PARAMETER;
-    }
-
-    if (ToUnknown)
-    {
-        Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&ToSubDevice);
-        if (!NT_SUCCESS(Status))
-            goto cleanup;
-    }
-
-
-    Entry = DeviceExt->PhysicalConnectionList.Flink;
-    bFound = FALSE;
-    // loop physical connection list
-    while(Entry != &DeviceExt->PhysicalConnectionList)
-    {
-        Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry);
-         // compare current entry
-        if (Connection->FromPin == FromPin && Connection->ToPin == ToPin &&
-            Connection->FromSubDevice == FromSubDevice && Connection->ToSubDevice == ToSubDevice)
-        {
-            if (FromString && Connection->FromUnicodeString.Buffer)
-            {
-                if (!RtlCompareUnicodeString(FromString, &Connection->FromUnicodeString, TRUE))
-                {
-                    // UnregisterPhysicalConnectionFromExternal
-                    bFound = TRUE;
-                    break;
-                }
-            }
-            else if (ToString && Connection->ToUnicodeString.Buffer)
-            {
-                if (!RtlCompareUnicodeString(ToString, &Connection->ToUnicodeString, TRUE))
-                {
-                    // UnregisterPhysicalConnectionToExternal
-                    bFound = TRUE;
-                    break;
-                }
-            }
-            else
-            {
-                // UnregisterPhysicalConnection
-                bFound = TRUE;
-                break;
-            }
-        }
-        Entry = Entry->Flink;
-    }
-
-    if (!bFound)
-    {
-         // not found
-         Status = STATUS_NOT_FOUND;
-         goto cleanup;
-    }
-
-    // remove list entry
-    RemoveEntryList(&Connection->Entry);
-
-    // release resources
-    if (Connection->FromSubDevice)
-        Connection->FromSubDevice->Release();
-
-
-    if (Connection->ToSubDevice)
-        Connection->ToSubDevice->Release();
-
-    if (Connection->FromUnicodeString.Buffer)
-        RtlFreeUnicodeString(&Connection->FromUnicodeString);
-
-    if (Connection->ToUnicodeString.Buffer)
-        RtlFreeUnicodeString(&Connection->ToUnicodeString);
-
-    FreeItem(Connection, TAG_PORTCLASS);
-    Status = STATUS_SUCCESS;
-
-cleanup:
-
-    if (FromSubDevice)
-        FromSubDevice->Release();
-
-    if (ToSubDevice)
-        ToSubDevice->Release();
-
-    return Status;
-
+    UNIMPLEMENTED
+    return STATUS_NOT_IMPLEMENTED;
 }
 
 NTSTATUS
@@ -255,67 +156,100 @@ RegisterConnection(
     IN PUNICODE_STRING ToString,
     IN ULONG ToPin)
 {
-    PHYSICAL_CONNECTION *NewConnection;
-    PPCLASS_DEVICE_EXTENSION DeviceExt;
+    PSUBDEVICE_DESCRIPTOR FromSubDeviceDescriptor, ToSubDeviceDescriptor;
+    PSYMBOLICLINK_ENTRY SymEntry;
+    ISubdevice * FromSubDevice = NULL, *ToSubDevice = NULL;
     NTSTATUS Status;
-
-    DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
-
-    NewConnection = (PPHYSICAL_CONNECTION)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION), TAG_PORTCLASS);
-    if (!NewConnection)
-    {
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
+    PPHYSICAL_CONNECTION_ENTRY FromEntry = NULL, ToEntry = NULL;
 
     if (FromUnknown)
     {
-        Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->FromSubDevice);
+        Status = FromUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&FromSubDevice);
         if (!NT_SUCCESS(Status))
             goto cleanup;
-    }
-    else
-    {
-        if (!RtlCreateUnicodeString(&NewConnection->FromUnicodeString, (PCWSTR)FromString))
+
+        Status = FromSubDevice->GetDescriptor(&FromSubDeviceDescriptor);
+        if (!NT_SUCCESS(Status))
+            goto cleanup;
+
+        if (IsListEmpty(&FromSubDeviceDescriptor->SymbolicLinkList))
         {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
+            Status = STATUS_UNSUCCESSFUL;
             goto cleanup;
         }
+
+        SymEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(FromSubDeviceDescriptor->SymbolicLinkList.Flink, SYMBOLICLINK_ENTRY, Entry);
+        FromString = &SymEntry->SymbolicLink;
     }
 
+
     if (ToUnknown)
     {
-        Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&NewConnection->ToSubDevice);
+        Status = ToUnknown->QueryInterface(IID_ISubdevice, (PVOID*)&ToSubDevice);
         if (!NT_SUCCESS(Status))
             goto cleanup;
-    }
-    else
-    {
-        if (!RtlCreateUnicodeString(&NewConnection->ToUnicodeString, (PCWSTR)ToString))
+
+        Status = ToSubDevice->GetDescriptor(&ToSubDeviceDescriptor);
+        if (!NT_SUCCESS(Status))
+            goto cleanup;
+
+        if (IsListEmpty(&ToSubDeviceDescriptor->SymbolicLinkList))
         {
-            Status = STATUS_INSUFFICIENT_RESOURCES;
+            Status = STATUS_UNSUCCESSFUL;
             goto cleanup;
         }
+
+
+        SymEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(ToSubDeviceDescriptor->SymbolicLinkList.Flink, SYMBOLICLINK_ENTRY, Entry);
+        ToString = &SymEntry->SymbolicLink;
+
+    }
+
+    FromEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + ToString->MaximumLength, TAG_PORTCLASS);
+    if (!FromEntry)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto cleanup;
+    }
+
+    ToEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + FromString->MaximumLength, TAG_PORTCLASS);
+    if (!ToEntry)
+    {
+        Status = STATUS_INSUFFICIENT_RESOURCES;
+        goto cleanup;
     }
 
-    InsertTailList(&DeviceExt->PhysicalConnectionList, &NewConnection->Entry);
+    FromEntry->FromPin = FromPin;
+    FromEntry->Connection.Pin = ToPin;
+    FromEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + ToString->MaximumLength;
+    RtlMoveMemory(&FromEntry->Connection.SymbolicLinkName, ToString->Buffer, ToString->MaximumLength);
+    FromEntry->Connection.SymbolicLinkName[ToString->Length / sizeof(WCHAR)] = L'\0';
+
+    ToEntry->FromPin = ToPin;
+    ToEntry->Connection.Pin = FromPin;
+    ToEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + FromString->MaximumLength;
+    RtlMoveMemory(&ToEntry->Connection.SymbolicLinkName, FromString->Buffer, FromString->MaximumLength);
+    ToEntry->Connection.SymbolicLinkName[FromString->Length /  sizeof(WCHAR)] = L'\0';
+
+
+    InsertTailList(&FromSubDeviceDescriptor->PhysicalConnectionList, &FromEntry->Entry);
+    InsertTailList(&ToSubDeviceDescriptor->PhysicalConnectionList, &ToEntry->Entry);
+
     return STATUS_SUCCESS;
 
 cleanup:
 
-    if (NewConnection->FromSubDevice)
-        NewConnection->FromSubDevice->Release();
-
-    if (NewConnection->ToSubDevice)
-        NewConnection->ToSubDevice->Release();
+    if (FromSubDevice)
+        FromSubDevice->Release();
 
-    if (NewConnection->FromUnicodeString.Buffer)
-        RtlFreeUnicodeString(&NewConnection->FromUnicodeString);
+    if (ToSubDevice)
+        ToSubDevice->Release();
 
-    if (NewConnection->ToUnicodeString.Buffer)
-        RtlFreeUnicodeString(&NewConnection->ToUnicodeString);
+    if (FromEntry)
+        FreeItem(FromEntry, TAG_PORTCLASS);
 
-     FreeItem(NewConnection, TAG_PORTCLASS);
+    if (ToEntry)
+        FreeItem(ToEntry, TAG_PORTCLASS);
 
     return Status;
 }
index 4be94fa..b63b704 100644 (file)
@@ -91,6 +91,17 @@ CPortFilterTopology::DeviceIoControl(
     PIO_STACK_LOCATION IoStack;
 
     IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
+    {
+        DPRINT1("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
+        
+        Irp->IoStatus.Status = STATUS_SUCCESS;
+
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_SUCCESS;
+    }
+
     PC_ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
 
     return PcPropertyHandler(Irp, m_Descriptor);
index 1fa54f2..b7d9f84 100644 (file)
@@ -168,6 +168,19 @@ DECLARE_INTERFACE_(IIrpTarget, IUnknown)
 
 struct IIrpTargetFactory;
 
+typedef struct
+{
+    LIST_ENTRY Entry;
+    UNICODE_STRING SymbolicLink;
+}SYMBOLICLINK_ENTRY, *PSYMBOLICLINK_ENTRY;
+
+typedef struct
+{
+    LIST_ENTRY Entry;
+    ULONG FromPin;
+    KSPIN_PHYSICALCONNECTION Connection;
+}PHYSICAL_CONNECTION_ENTRY, *PPHYSICAL_CONNECTION_ENTRY;
+
 typedef struct
 {
     ULONG MaxGlobalInstanceCount;
@@ -202,6 +215,9 @@ typedef struct
 
     PPCFILTER_DESCRIPTOR DeviceDescriptor;
     KSTOPOLOGY*  Topology;
+    LIST_ENTRY SymbolicLinkList;
+    LIST_ENTRY PhysicalConnectionList;
+    UNICODE_STRING RefString;
 }SUBDEVICE_DESCRIPTOR, *PSUBDEVICE_DESCRIPTOR;
 
 #undef INTERFACE
index ff9b9ca..b83f0e1 100644 (file)
@@ -174,33 +174,11 @@ PortClsShutdown(
     IN  PIRP Irp)
 {
     PPCLASS_DEVICE_EXTENSION DeviceExtension;
-    PLIST_ENTRY Entry;
-    PPHYSICAL_CONNECTION Connection;
     DPRINT("PortClsShutdown called\n");
 
     // get device extension
     DeviceExtension = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 
-    while(!IsListEmpty(&DeviceExtension->PhysicalConnectionList))
-    {
-        // get connection entry
-        Entry = RemoveHeadList(&DeviceExtension->PhysicalConnectionList);
-        Connection = (PPHYSICAL_CONNECTION)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION, Entry);
-
-        if (Connection->FromSubDevice)
-        {
-            // release subdevice
-            Connection->FromSubDevice->Release();
-        }
-
-        if (Connection->ToSubDevice)
-        {
-            // release subdevice
-            Connection->ToSubDevice->Release();
-        }
-        FreeItem(Connection, TAG_PORTCLASS);
-    }
-
     if (DeviceExtension->AdapterPowerManagement)
     {
         // release adapter power management
index af7c602..d9136c9 100644 (file)
@@ -25,7 +25,6 @@ public:
     STDMETHODIMP_(ULONG) Release()
     {
         InterlockedDecrement(&m_Ref);
-        DPRINT1("Release %u\n", m_Ref);
         if (!m_Ref)
         {
             //delete this;
index ca5e1a9..0dc1d0e 100644 (file)
@@ -346,32 +346,6 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
     DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\
 }
 
-typedef struct
-{
-    LIST_ENTRY Entry;
-    UNICODE_STRING SymbolicLink;
-}SYMBOLICLINK_ENTRY, *PSYMBOLICLINK_ENTRY;
-
-
-typedef struct
-{
-    LIST_ENTRY Entry;
-    ISubdevice *SubDevice;
-    UNICODE_STRING Name;
-    LIST_ENTRY SymbolicLinkList;
-}SUBDEVICE_ENTRY, *PSUBDEVICE_ENTRY;
-
-typedef struct
-{
-    LIST_ENTRY Entry;
-    ISubdevice * FromSubDevice;
-    UNICODE_STRING FromUnicodeString;
-    ULONG FromPin;
-    ISubdevice * ToSubDevice;
-    UNICODE_STRING ToUnicodeString;
-    ULONG ToPin;
-}PHYSICAL_CONNECTION, *PPHYSICAL_CONNECTION;
-
 typedef struct
 {
     KSDEVICE_HEADER KsDeviceHeader;
@@ -384,8 +358,6 @@ typedef struct
     KSOBJECT_CREATE_ITEM * CreateItems;
 
     IResourceList* resources;
-    LIST_ENTRY SubDeviceList;
-    LIST_ENTRY PhysicalConnectionList;
 
     LIST_ENTRY TimerList;
     KSPIN_LOCK TimerListLock;
index 98df574..40f01ec 100644 (file)
@@ -114,6 +114,71 @@ HandleDataIntersection(
     return Status;
 }
 
+NTSTATUS
+HandlePhysicalConnection(
+    IN PIO_STATUS_BLOCK IoStatus,
+    IN PKSIDENTIFIER Request,
+    IN ULONG RequestLength,
+    IN OUT PVOID  Data,
+    IN ULONG DataLength,
+    IN PSUBDEVICE_DESCRIPTOR Descriptor)
+{
+    PKSP_PIN Pin;
+    PLIST_ENTRY Entry;
+    PKSPIN_PHYSICALCONNECTION Connection;
+    PPHYSICAL_CONNECTION_ENTRY ConEntry;
+
+    // get pin
+    Pin = (PKSP_PIN)Request;
+
+    if (RequestLength < sizeof(KSP_PIN))
+    {
+        // input buffer must be at least sizeof KSP_PIN
+        DPRINT1("input length too small\n");
+        return STATUS_INVALID_PARAMETER;
+    }
+
+    if (IsListEmpty(&Descriptor->PhysicalConnectionList))
+    {
+        DPRINT1("no connection\n");
+        return STATUS_NOT_FOUND;
+    }
+
+    // get first item
+    Entry = Descriptor->PhysicalConnectionList.Flink;
+
+    do
+    {
+        ConEntry = (PPHYSICAL_CONNECTION_ENTRY)CONTAINING_RECORD(Entry, PHYSICAL_CONNECTION_ENTRY, Entry);
+
+        if (ConEntry->FromPin == Pin->PinId)
+        {
+            Connection = (PKSPIN_PHYSICALCONNECTION)Data;
+            DPRINT("FoundEntry %S Size %u\n", ConEntry->Connection.SymbolicLinkName, ConEntry->Connection.Size);
+            IoStatus->Information = ConEntry->Connection.Size;
+
+            if (!DataLength)
+            {
+                IoStatus->Information = ConEntry->Connection.Size;
+                return STATUS_MORE_ENTRIES;
+            }
+
+            if (DataLength < ConEntry->Connection.Size)
+            {
+                return STATUS_BUFFER_TOO_SMALL;
+            }
+
+            RtlMoveMemory(Data, &ConEntry->Connection, ConEntry->Connection.Size);
+            return STATUS_SUCCESS;
+       }
+
+        // move to next item
+        Entry = Entry->Flink;
+    }while(Entry != &Descriptor->PhysicalConnectionList);
+
+    IoStatus->Information = 0;
+    return STATUS_NOT_FOUND;
+}
 
 NTSTATUS
 NTAPI
@@ -188,6 +253,8 @@ PinPropertyHandler(
             Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice);
             break;
         case KSPROPERTY_PIN_PHYSICALCONNECTION:
+            Status = HandlePhysicalConnection(&Irp->IoStatus, Request, IoStack->Parameters.DeviceIoControl.InputBufferLength, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor);
+            break;
         case KSPROPERTY_PIN_CONSTRAINEDDATARANGES:
             UNIMPLEMENTED
             Status = STATUS_NOT_IMPLEMENTED;
index c858095..bdf32ec 100644 (file)
@@ -165,6 +165,10 @@ PcCreateSubdeviceDescriptor(
     if (!Descriptor)
         return STATUS_INSUFFICIENT_RESOURCES;
 
+    // initialize physical / symbolic link connection list 
+    InitializeListHead(&Descriptor->SymbolicLinkList);
+    InitializeListHead(&Descriptor->PhysicalConnectionList);
+
     Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
     if (!Descriptor->Interfaces)
         goto cleanup;
index bbebbf5..c6a615b 100644 (file)
@@ -66,10 +66,9 @@ CUnregisterSubdevice::UnregisterSubdevice(
 {
     PPCLASS_DEVICE_EXTENSION DeviceExtension;
     PLIST_ENTRY Entry;
-    PSUBDEVICE_ENTRY SubDeviceEntry;
     PSYMBOLICLINK_ENTRY SymLinkEntry;
+    PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
     ISubdevice *SubDevice;
-    ULONG Found;
     ULONG Index;
     NTSTATUS Status;
 
@@ -93,32 +92,18 @@ CUnregisterSubdevice::UnregisterSubdevice(
         return STATUS_INVALID_PARAMETER;
     }
 
-    Entry = DeviceExtension->SubDeviceList.Flink;
-    Found = FALSE;
-    // loop subdevice entry list and search for the subdevice
-    while(Entry != &DeviceExtension->SubDeviceList)
+    Status = SubDevice->GetDescriptor(&SubDeviceDescriptor);
+    if (!NT_SUCCESS(Status))
     {
-        SubDeviceEntry = (PSUBDEVICE_ENTRY)CONTAINING_RECORD(Entry, SUBDEVICE_ENTRY, Entry);
-        if (SubDeviceEntry->SubDevice == SubDevice)
-        {
-            Found = TRUE;
-            break;
-        }
-        Entry = Entry->Flink;
+        DPRINT1("Failed to retrieve subdevice descriptor %x\n", Status);
+        // the provided port driver doesnt support ISubdevice
+        return STATUS_INVALID_PARAMETER;
     }
-    // release the subdevice
-    SubDevice->Release();
-
-    if (!Found)
-        return STATUS_NOT_FOUND;
-
-    // remove subdevice entry
-    RemoveEntryList(&SubDeviceEntry->Entry);
 
     // loop our create items and disable the create handler
     for(Index = 0; Index < DeviceExtension->MaxSubDevices; Index++)
     {
-        if (!RtlCompareUnicodeString(&SubDeviceEntry->Name, &DeviceExtension->CreateItems[Index].ObjectClass, TRUE))
+        if (!RtlCompareUnicodeString(&SubDeviceDescriptor->RefString, &DeviceExtension->CreateItems[Index].ObjectClass, TRUE))
         {
             DeviceExtension->CreateItems[Index].Create = NULL;
             RtlInitUnicodeString(&DeviceExtension->CreateItems[Index].ObjectClass, NULL);
@@ -127,10 +112,10 @@ CUnregisterSubdevice::UnregisterSubdevice(
     }
 
     // now unregister device interfaces
-    while(!IsListEmpty(&SubDeviceEntry->SymbolicLinkList))
+    while(!IsListEmpty(&SubDeviceDescriptor->SymbolicLinkList))
     {
         // remove entry
-        Entry = RemoveHeadList(&SubDeviceEntry->SymbolicLinkList);
+        Entry = RemoveHeadList(&SubDeviceDescriptor->SymbolicLinkList);
         // get symlink entry
         SymLinkEntry = (PSYMBOLICLINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLICLINK_ENTRY, Entry);
 
@@ -142,9 +127,6 @@ CUnregisterSubdevice::UnregisterSubdevice(
         FreeItem(SymLinkEntry, TAG_PORTCLASS);
     }
 
-    // free subdevice entry
-    ExFreePool(SubDeviceEntry);
-
     return STATUS_SUCCESS;
 }