[AUDIO-BRINGUP]
authorJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 21 Dec 2010 13:06:47 +0000 (13:06 +0000)
committerJohannes Anderwald <johannes.anderwald@reactos.org>
Tue, 21 Dec 2010 13:06:47 +0000 (13:06 +0000)
- Move irp completion to CompleteRequest function for debugging of multiple irp completion bugs
- Remove bugs asserts in IKsDevice_PnpStartDevice
- Set device to started when the device does not need pnp notification
- Don't complete the irp in IKsDevice_Create, the driver has already done this
- Comment out UNIMPLEMENTED macro in KsFilterAttemptProcessing
- Fix check in FindMatchingCreateItem
- Don't set DO_DIRECT_IO flags on PDO devices
- Set DO_DEVICE_INITIALIZING flag on PDO device
- Construct device name with swprintf
- Add check if the device entry has already been constructed
- Zero device capabilities
- Implement bus watchdog routine. The routine checks if pdo has successfully been started, otherwise the pdo is marked invalid and the deleted and then constructed again. If the pdo has been started, all pending irp requests are completed with STATUS_REPARSE. (This is probably not supported by Ros kernel yet)
- Acquire device entry list lock when working with device entries
- Always store status code in irp for all Ks bus api routines
- Handle IRP_MN_REMOVE_DEVICE
- Start watchdog timer when IRP_MN_START_DEVICE is received
- Ros KS nos successfully initializes and all audio devices appear in VBOX+WinXP+SP3. Playback not yet working (Needs KsAttemptFilterProcessing for splitter and friends)
- TODO: enhance time out to make audio system initialize faster

svn path=/branches/audio-bringup/; revision=50079

12 files changed:
drivers/ksfilter/ks/allocators.c
drivers/ksfilter/ks/api.c
drivers/ksfilter/ks/clocks.c
drivers/ksfilter/ks/device.c
drivers/ksfilter/ks/filter.c
drivers/ksfilter/ks/filterfactory.c
drivers/ksfilter/ks/irp.c
drivers/ksfilter/ks/ksfunc.h
drivers/ksfilter/ks/kstypes.h
drivers/ksfilter/ks/misc.c
drivers/ksfilter/ks/pin.c
drivers/ksfilter/ks/swenum.c

index 5a4970f..b3fbbbe 100644 (file)
@@ -163,7 +163,7 @@ IKsAllocator_fnDeviceIoControl(
 
         /* complete and forget irps */
         Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
 
         return STATUS_NOT_IMPLEMENTED;
    }
@@ -172,7 +172,7 @@ IKsAllocator_fnDeviceIoControl(
     {
         /* invalid request */
         Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
 
         return STATUS_INVALID_DEVICE_REQUEST;
     }
@@ -190,7 +190,7 @@ IKsAllocator_fnDeviceIoControl(
                 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                 Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
                 /* complete and forget irp */
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return STATUS_BUFFER_TOO_SMALL;
             }
             if (!(Property->Flags & KSPROPERTY_TYPE_GET))
@@ -198,7 +198,7 @@ IKsAllocator_fnDeviceIoControl(
                 /* only support retrieving the property */
                 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                 /* complete and forget irp */
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return STATUS_UNSUCCESSFUL;
             }
 
@@ -212,7 +212,7 @@ IKsAllocator_fnDeviceIoControl(
             Irp->IoStatus.Status = STATUS_SUCCESS;
             Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
             /* complete request */
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return STATUS_SUCCESS;
         }
         else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS)
@@ -223,7 +223,7 @@ IKsAllocator_fnDeviceIoControl(
                 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
                 Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS);
                 /* complete and forget irp */
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return STATUS_BUFFER_TOO_SMALL;
             }
             if (!(Property->Flags & KSPROPERTY_TYPE_GET))
@@ -231,7 +231,7 @@ IKsAllocator_fnDeviceIoControl(
                 /* only support retrieving the property */
                 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
                 /* complete and forget irp */
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return STATUS_UNSUCCESSFUL;
             }
 
@@ -246,14 +246,14 @@ IKsAllocator_fnDeviceIoControl(
             Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS);
 
             /* complete request */
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return STATUS_SUCCESS;
         }
     }
 
     /* unhandled request */
     Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_NOT_SUPPORTED;
 }
@@ -501,7 +501,7 @@ IKsAllocator_DispatchDeviceIoControl(
 
     /* complete request */
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return Status;
 }
@@ -523,7 +523,7 @@ IKsAllocator_DispatchClose(
 
     /* complete request */
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return Status;
 }
index bf0e18b..3a037bf 100644 (file)
@@ -1332,7 +1332,7 @@ KopDispatchClose(
 
     /* complete request */
     Irp->IoStatus.Status = STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_SUCCESS;
 }
@@ -1416,7 +1416,7 @@ KopDispatchCreate(
     IoStack->FileObject->FsContext2 = (PVOID)Header;
 
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return Status;
 
@@ -1429,7 +1429,7 @@ cleanup:
         FreeItem(Header);
 
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
 
@@ -1703,7 +1703,7 @@ KsCompletePendingRequest(
     if (IoStack->MajorFunction != IRP_MJ_CLOSE)
     {
         /* can be completed immediately */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return;
     }
 
@@ -1711,7 +1711,7 @@ KsCompletePendingRequest(
     if (!NT_SUCCESS(Irp->IoStatus.Status))
     {
         /* closing failed, complete irp */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return;
     }
 
index 05064be..2e3f03f 100644 (file)
@@ -339,7 +339,7 @@ IKsClock_DispatchDeviceIoControl(
 
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_SUCCESS;
 }
@@ -353,7 +353,7 @@ IKsClock_DispatchClose(
     UNIMPLEMENTED
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_SUCCESS;
 }
index 432548c..3cd4ec3 100644 (file)
@@ -302,7 +302,7 @@ IKsDevice_PnpStartDevice(
     {
         DPRINT1("NextDevice object failed to start with %x\n", Status);
         Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return Status;
     }
 
@@ -335,9 +335,6 @@ IKsDevice_PnpStartDevice(
     }
 
     ASSERT(DeviceHeader->KsDevice.Descriptor);
-    ASSERT(DeviceHeader->KsDevice.Descriptor->Dispatch);
-    ASSERT(DeviceHeader->KsDevice.Descriptor->Dispatch->Start);
-
 
     /* do we have a device descriptor */
     if (DeviceHeader->KsDevice.Descriptor)
@@ -361,7 +358,7 @@ IKsDevice_PnpStartDevice(
                 {
                     DPRINT1("Driver: failed to start %x\n", Status);
                     Irp->IoStatus.Status = Status;
-                    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                    CompleteRequest(Irp, IO_NO_INCREMENT);
                     return Status;
                 }
 
@@ -406,12 +403,17 @@ IKsDevice_PnpStartDevice(
                 Status = KspSetFilterFactoriesState(DeviceHeader, TRUE);
             }
         }
+        else
+        {
+            /* set state to run */
+            DeviceHeader->KsDevice.Started = TRUE;
+        }
     }
 
     /* store result */
     Irp->IoStatus.Status = Status;
     /* complete request */
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     if (Ctx)
     {
@@ -420,7 +422,7 @@ IKsDevice_PnpStartDevice(
     }
 
     /* return result */
-    DPRINT1("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx);
+    DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx);
     return Status;
 }
 
@@ -477,7 +479,7 @@ IKsDevice_Pnp(
             {
                 DPRINT1("Driver: query stop failed %x\n", Status);
                 Irp->IoStatus.Status = Status;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return Status;
             }
 
@@ -487,7 +489,7 @@ IKsDevice_Pnp(
             DPRINT("Next Device: Status %x\n", Status);
 
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
 
@@ -513,7 +515,7 @@ IKsDevice_Pnp(
 
 
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
         case IRP_MN_QUERY_INTERFACE:
@@ -536,7 +538,7 @@ IKsDevice_Pnp(
                 /* driver supports a private interface */
                 DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
                 Irp->IoStatus.Status = Status;
-                IoCompleteRequest(Irp, IO_NO_INCREMENT);
+                CompleteRequest(Irp, IO_NO_INCREMENT);
                 return Status;
             }
 
@@ -545,7 +547,7 @@ IKsDevice_Pnp(
 
             DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status);
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
         case IRP_MN_QUERY_DEVICE_RELATIONS:
@@ -556,7 +558,7 @@ IKsDevice_Pnp(
             DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status);
 
             //Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
         case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
@@ -567,7 +569,7 @@ IKsDevice_Pnp(
             DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
 
             //Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
@@ -578,7 +580,7 @@ IKsDevice_Pnp(
             DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
 
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
        }
        default:
@@ -587,7 +589,7 @@ IKsDevice_Pnp(
           Status = KspForwardIrpSynchronous(DeviceObject, Irp);
 
           Irp->IoStatus.Status = Status;
-          IoCompleteRequest(Irp, IO_NO_INCREMENT);
+          CompleteRequest(Irp, IO_NO_INCREMENT);
           return Status;
     }
 }
@@ -604,7 +606,7 @@ IKsDevice_Power(
 
     Irp->IoStatus.Status = STATUS_SUCCESS;
     Irp->IoStatus.Information = 0;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_SUCCESS;
 }
@@ -669,17 +671,10 @@ IKsDevice_Create(
         }
     }
 
-    /* acquire list lock */
+    /* release list lock */
     IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
 
-    if (Status != STATUS_PENDING)
-    {
-        Irp->IoStatus.Information = 0;
-        /* set return status */
-        Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    }
-
+    /* done */
     return Status;
 
 
@@ -703,7 +698,7 @@ KsInitializeDevice(
     PKSIOBJECT_BAG Bag;
     NTSTATUS Status = STATUS_SUCCESS;
 
-    DPRINT("KsInitializeDevice Descriptor %p\n", Descriptor);
+    DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor);
 
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
@@ -714,7 +709,7 @@ KsInitializeDevice(
     /* point to allocated header */
     Header = DeviceExtension->DeviceHeader;
 
-    DPRINT("DeviceHeader %p\n", DeviceExtension->DeviceHeader);
+    DPRINT1("DeviceHeader %p\n", DeviceExtension->DeviceHeader);
 
     if (Descriptor && Descriptor->Dispatch)
     {
@@ -896,7 +891,7 @@ KsDereferenceSoftwareBusObject(
      IKsDevice * Device;
      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
 
-     DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
+     DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
 
      /* get device interface */
      Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
index 5f4a74b..7f0f820 100644 (file)
@@ -485,7 +485,7 @@ IKsFilter_GetFilterFromIrp(
         Irp->IoStatus.Status = Status;
 
         /* complete and forget irp */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return Status;
     }
     return Status;
@@ -522,7 +522,7 @@ IKsFilter_DispatchClose(
         /* save the result */
         Irp->IoStatus.Status = Status;
         /* complete irp */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
 
         /* remove our instance from the filter factory */
         IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory);
@@ -535,7 +535,7 @@ IKsFilter_DispatchClose(
         /* complete and forget */
         Irp->IoStatus.Status = Status;
         /* complete irp */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
     /* done */
@@ -881,7 +881,7 @@ IKsFilter_DispatchDeviceIoControl(
     if (Status != STATUS_PENDING)
     {
         Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
     /* done */
@@ -1227,7 +1227,7 @@ IKsFilter_DispatchCreatePin(
     {
         /* complete request */
         Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
     /* done */
@@ -1243,7 +1243,7 @@ IKsFilter_DispatchCreateNode(
 {
     UNIMPLEMENTED
     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -1608,7 +1608,7 @@ KsFilterAttemptProcessing(
     IN PKSFILTER Filter,
     IN BOOLEAN Asynchronous)
 {
-    UNIMPLEMENTED
+    //UNIMPLEMENTED
 }
 
 /*
index e60bfc4..51c9a65 100644 (file)
@@ -69,7 +69,7 @@ IKsFilterFactory_Create(
     {
         Irp->IoStatus.Information = 0;
         Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
     return Status;
index fb36d6d..2b94a6d 100644 (file)
@@ -34,7 +34,7 @@ KsDispatchQuerySecurity(
     {
         /* no create item */
         Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_NO_SECURITY_ON_OBJECT;
     }
 
@@ -50,7 +50,7 @@ KsDispatchQuerySecurity(
     Irp->IoStatus.Status = Status;
     Irp->IoStatus.Information = Length;
 
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
 
@@ -80,7 +80,7 @@ KsDispatchSetSecurity(
     {
         /* no create item */
         Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_NO_SECURITY_ON_OBJECT;
     }
 
@@ -109,7 +109,7 @@ KsDispatchSetSecurity(
 
     /* store result */
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return Status;
 }
@@ -1154,7 +1154,7 @@ KsDispatchInvalidDeviceRequest(
     IN  PIRP Irp)
 {
     Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_INVALID_DEVICE_REQUEST;
 }
@@ -1198,7 +1198,7 @@ KsDefaultDeviceIoCompletion(
 
     /* complete request */
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
 
     return Status;
@@ -1643,14 +1643,15 @@ KsAddIrpToCancelableQueue(
     /* get current irp stack */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
+    DPRINT1("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
 
     // HACK for ms portcls
     if (IoStack->MajorFunction == IRP_MJ_CREATE)
     {
         // complete the request
+DPRINT1("MS HACK\n");
         Irp->IoStatus.Status = STATUS_SUCCESS;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
 
         return;
     }
@@ -1736,7 +1737,7 @@ KsCancelRoutine(
     {
         /* let's complete it */
         Irp->IoStatus.Status = STATUS_CANCELLED;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
     }
 }
 
@@ -1795,14 +1796,12 @@ FindMatchingCreateItem(
             continue;
         }
 
-        ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer);
-
         DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
                                                            CreateItemEntry->CreateItem->ObjectClass.Length,
                                                            &RefString,
-                                                           BufferSize);
+                                                           RefString.Length);
 
-        if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize)
+        if (CreateItemEntry->CreateItem->ObjectClass.Length > RefString.Length)
         {
             /* create item doesnt match in length */
             Entry = Entry->Flink;
@@ -1853,7 +1852,7 @@ KspCreate(
         Irp->IoStatus.Information = 0;
         /* set return status */
         Irp->IoStatus.Status = STATUS_SUCCESS;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_SUCCESS;
     }
 
@@ -1893,7 +1892,7 @@ KspCreate(
     Irp->IoStatus.Information = 0;
     /* set return status */
     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -1929,7 +1928,7 @@ KspDispatchIrp(
         Irp->IoStatus.Status = STATUS_SUCCESS;
         Irp->IoStatus.Information = 0;
         /* complete and forget */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return STATUS_SUCCESS;
     }
 
@@ -2036,6 +2035,7 @@ KsDispatchIrp(
 
     /* get device extension */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
+
     /* get device header */
     DeviceHeader = DeviceExtension->DeviceHeader;
 
index 6a4d85d..1c51a8c 100644 (file)
@@ -6,6 +6,13 @@
 #define TAG_KSDEVICE 'DESK'
 #define TAG_KSOBJECT_TAG 'HOSK'
 
+VOID
+CompleteRequest(
+    PIRP Irp,
+    CCHAR PriorityBoost);
+
+
+
 NTSTATUS
 NTAPI
 KspCreateObjectType(
index da14452..0be5956 100644 (file)
@@ -145,7 +145,7 @@ typedef struct
 typedef BOOLEAN (NTAPI *PKSEVENT_SYNCHRONIZED_ROUTINE)(PKSEVENT_CTX Context);
 
 struct __BUS_ENUM_DEVICE_EXTENSION__;
-struct BUS_DEVICE_ENTRY;
+struct __BUS_DEVICE_ENTRY__;
 
 typedef struct
 {
@@ -158,7 +158,7 @@ typedef struct
     };
     union
     {
-        PVOID DeviceEntry;
+        struct __BUS_DEVICE_ENTRY__* DeviceEntry;
         ULONG Dummy1;
     };
     struct __BUS_ENUM_DEVICE_EXTENSION__ *BusDeviceExtension;
@@ -191,7 +191,7 @@ typedef enum
 }DEVICE_STATE;
 
 
-typedef struct
+typedef struct __BUS_DEVICE_ENTRY__
 {
     LIST_ENTRY Entry;
     LIST_ENTRY DeviceInterfaceList;
index 057103d..9ba4b26 100644 (file)
@@ -9,6 +9,19 @@
 
 #include "priv.h"
 
+VOID
+CompleteRequest(
+    PIRP Irp,
+    CCHAR PriorityBoost)
+{
+    DPRINT("Completing IRP %p Status %x\n", Irp, Irp->IoStatus.Status);
+
+    ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
+
+
+    IoCompleteRequest(Irp, PriorityBoost);
+}
+
 PVOID
 AllocateItem(
     IN POOL_TYPE PoolType,
index a6caeb3..883f098 100644 (file)
@@ -1875,7 +1875,7 @@ IKsPin_DispatchKsStream(
         DPRINT1("KsProbeStreamIrp failed with %x\n", Status);
 
         Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return Status;
     }
 
@@ -1888,7 +1888,7 @@ IKsPin_DispatchKsStream(
     {
         DPRINT("NoHeader Canceling Irp %p\n", Irp);
         Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return Status;
     }
 
@@ -1911,7 +1911,7 @@ IKsPin_DispatchKsStream(
         {
             DPRINT("NoHeader->Data Canceling Irp %p\n", Irp);
             Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
 
@@ -1960,7 +1960,7 @@ IKsPin_DispatchKsStream(
             /* invalid device request */
             DPRINT("Filter Centric Processing No Process Routine\n");
             Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return STATUS_UNSUCCESSFUL;
         }
 
@@ -2095,7 +2095,7 @@ IKsPin_DispatchDeviceIoControl(
     if (Status != STATUS_PENDING)
     {
         Irp->IoStatus.Status = Status;
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
     }
 
     /* done */
@@ -2135,7 +2135,7 @@ IKsPin_Close(
         {
             /* abort closing */
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
 
@@ -2145,7 +2145,7 @@ IKsPin_Close(
         if (Status != STATUS_PENDING)
         {
             Irp->IoStatus.Status = Status;
-            IoCompleteRequest(Irp, IO_NO_INCREMENT);
+            CompleteRequest(Irp, IO_NO_INCREMENT);
             return Status;
         }
     }
@@ -2162,7 +2162,7 @@ IKsPin_DispatchCreateAllocator(
     UNIMPLEMENTED;
 
     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_NOT_IMPLEMENTED;
 }
 
@@ -2244,7 +2244,7 @@ IKsPin_DispatchCreateClock(
 
     /* done */
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
 
@@ -2257,7 +2257,7 @@ IKsPin_DispatchCreateNode(
     UNIMPLEMENTED;
 
     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_NOT_IMPLEMENTED;
 }
 
index b79c0cd..d764ed9 100644 (file)
@@ -35,7 +35,7 @@ KspCreatePDO(
     CurDeviceId = InterlockedIncrement(&KsDeviceCount);
 
     /* generate new device id */
-    swprintf(Buffer, L"\\Device\\KSENUM%08x\n", CurDeviceId);
+    swprintf(Buffer, L"\\Device\\KSENUM%08x", CurDeviceId);
 
     /* initialize new device name */
     RtlInitUnicodeString(&DeviceName, Buffer);
@@ -71,8 +71,8 @@ KspCreatePDO(
     /* TODO: update last creation time in bus device extension */
 
     /* setup flags */
-    DeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
-
+    DeviceObject->Flags |= DO_POWER_PAGABLE;
+    DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
     /* TODO: fire time when expired */
 
     *OutDeviceObject = DeviceObject;
@@ -330,6 +330,7 @@ KspCreateDeviceReference(
     BOOLEAN ItemExists = FALSE;
     UNICODE_STRING String;
     NTSTATUS Status;
+    KIRQL OldLevel;
 
     /* first construct device name & reference guid */
     Length = wcslen(DeviceCategory) + wcslen(ReferenceString);
@@ -347,9 +348,7 @@ KspCreateDeviceReference(
     }
 
     /* construct device name */
-    wcscpy(DeviceName, DeviceCategory);
-    wcscat(DeviceName, L"&");
-    wcscat(DeviceName, ReferenceString);
+    swprintf(DeviceName, L"%s&%s", DeviceCategory, ReferenceString);
 
     /* scan list and check if it is already present */
     Entry = BusDeviceExtension->Common.Entry.Flink;
@@ -437,8 +436,17 @@ KspCreateDeviceReference(
         return Status;
     }
 
-    /* successfully initialized entry */
-    InsertTailList(&BusDeviceExtension->Common.Entry, &DeviceEntry->Entry);
+    if (!ItemExists)
+    {
+        /* acquire lock */
+        KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
+
+        /* successfully initialized entry */
+        InsertTailList(&BusDeviceExtension->Common.Entry, &DeviceEntry->Entry);
+
+        /* release lock */
+        KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
+    }
 
     /* done */
     return Status;
@@ -585,8 +593,8 @@ KspBusDereferenceDeviceObject(
 
 NTSTATUS
 KspQueryBusDeviceInterface(
-    IN PIRP Irp,
-    IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension)
+    IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
+    IN PIRP Irp)
 {
     PBUS_INTERFACE_SWENUM Interface;
     PIO_STACK_LOCATION IoStack;
@@ -628,6 +636,7 @@ KspEnableBusDeviceInterface(
     {
         /* get bus instance entry */
         InstanceEntry = (PBUS_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BUS_INSTANCE_ENTRY, Entry);
+        DPRINT1("Enabling %u %wZ Irql %u\n", bEnable, &InstanceEntry->SymbolicLink, KeGetCurrentIrql());
 
         /* set interface state */
         Status = IoSetDeviceInterfaceState(&InstanceEntry->SymbolicLink, bEnable);
@@ -672,7 +681,7 @@ KspDoReparseForIrp(
     Length += 2; 
 
     /* allocate buffer */
-    Buffer = AllocateItem(PagedPool, Length * sizeof(WCHAR));
+    Buffer = AllocateItem(NonPagedPool, Length * sizeof(WCHAR));
     if (!Buffer)
     {
         /* no resources */
@@ -680,11 +689,8 @@ KspDoReparseForIrp(
     }
 
     /* construct buffer */
-    wcscpy(Buffer, DeviceEntry->PDODeviceName);
-    wcscat(Buffer, L"\\");
-    wcscat(Buffer, DeviceEntry->Instance);
+    swprintf(Buffer, L"%s\\%s", DeviceEntry->PDODeviceName, DeviceEntry->Instance);
 
-    /* free old file name */
     ExFreePool(IoStack->FileObject->FileName.Buffer);
 
     /* store new file name */
@@ -704,7 +710,6 @@ KspCompletePendingIrps(
     NTSTATUS Status;
 
     /* go through list */
-
     while(!IsListEmpty(&DeviceEntry->IrpPendingList))
     {
         /* get first entry */
@@ -727,11 +732,12 @@ KspCompletePendingIrps(
         /* store result code */
         Irp->IoStatus.Status = Status;
 
-        DPRINT1("Completing IRP %p\n", Irp);
+        DPRINT1("Completing IRP %p Status %x\n", Irp, Status);
 
         /* complete the request */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
     }
+
 }
 
 
@@ -760,7 +766,7 @@ KspStartBusDevice(
     }
 
     /* allocate device name buffer */
-    Name = AllocateItem(PagedPool, ResultLength);
+    Name = AllocateItem(NonPagedPool, (ResultLength + 1) * sizeof(WCHAR));
     if (!Name)
     {
         /* no memory */
@@ -784,10 +790,13 @@ KspStartBusDevice(
     /* mark device as started */
     DeviceEntry->DeviceState = Started;
 
-    DPRINT1("KspStartBusDevice Name %S Started\n", Name);
+    /* reference start time */
+    KeQuerySystemTime(&DeviceEntry->TimeCreated);
 
-    /* now complete pending i/o */
-    KspCompletePendingIrps(DeviceEntry, STATUS_REPARSE);
+    DPRINT1("KspStartBusDevice Name %S DeviceName %S Instance %S Started\n", Name, DeviceEntry->DeviceName, DeviceEntry->Instance);
+
+    /* enable device classes */
+    //KspEnableBusDeviceInterface(DeviceEntry, TRUE);
 
     /* done */
     return STATUS_SUCCESS;
@@ -807,6 +816,8 @@ KspQueryBusDeviceCapabilities(
     /* get capabilities */
     Capabilities = IoStack->Parameters.DeviceCapabilities.Capabilities;
 
+    RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
+
     /* setup capabilities */
     Capabilities->UniqueID = TRUE;
     Capabilities->SilentInstall = TRUE;
@@ -935,9 +946,7 @@ KspQueryId(
         }
 
         /* construct id */
-        wcscpy(Name, BusDeviceExtension->BusIdentifier);
-        wcscat(Name, L"\\");
-        wcscat(Name, DeviceEntry->BusId);
+        swprintf(Name, L"%s\\%s", BusDeviceExtension->BusIdentifier, DeviceEntry->BusId);
 
         /* store result */
         Irp->IoStatus.Information = (ULONG_PTR)Name;
@@ -948,8 +957,8 @@ KspQueryId(
     else
     {
         /* other ids are not supported */
-        DPRINT1("Not Supported ID Type %x\n", IoStack->Parameters.QueryId.IdType);
-        return STATUS_NOT_SUPPORTED;
+        //DPRINT1("Not Supported ID Type %x\n", IoStack->Parameters.QueryId.IdType);
+        return Irp->IoStatus.Status;
     }
 }
 
@@ -1123,8 +1132,83 @@ NTAPI
 KspBusWorkerRoutine(
   IN PVOID Parameter)
 {
-    /* TODO: implement sweeping */
-    UNIMPLEMENTED
+    PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+    PBUS_DEVICE_ENTRY DeviceEntry;
+    PLIST_ENTRY Entry;
+    LARGE_INTEGER Time, Diff;
+    BOOLEAN DoInvalidate = FALSE;
+    KIRQL OldLevel;
+
+    /* acquire lock */
+    KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
+
+    /* get device extension */
+    BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)Parameter;
+
+    /* get current time */
+    KeQuerySystemTime(&Time);
+
+    /* enumerate all device entries */
+    Entry = BusDeviceExtension->Common.Entry.Flink;
+    while(Entry != &BusDeviceExtension->Common.Entry)
+    {
+        /* get offset to device entry */
+        DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
+
+        /* sanity check */
+        ASSERT(DeviceEntry);
+
+        //DPRINT1("DeviceEntry %p PDO %p State %x\n", DeviceEntry, DeviceEntry->PDO, DeviceEntry->DeviceState);
+
+        if (DeviceEntry->PDO)
+        {
+            if (DeviceEntry->DeviceState == NotStarted)
+            {
+                Diff.QuadPart = Time.QuadPart - DeviceEntry->TimeCreated.QuadPart;
+
+                if (Diff.QuadPart > Int32x32To64(15000, 10000))
+                {
+                     DPRINT1("DeviceID %S  Instance %S TimeCreated %I64u Now %I64u Diff %I64u hung\n", DeviceEntry->DeviceName, DeviceEntry->Instance, DeviceEntry->TimeCreated.QuadPart, Time.QuadPart, Diff.QuadPart);
+
+                     /* release spin lock */
+                     KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
+
+                     /* deactivate interfaces */
+                     //KspEnableBusDeviceInterface(DeviceEntry, FALSE);
+
+                     /* re-acquire lock */
+                     KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
+
+                     /* pending remove device object */
+                     DeviceEntry->DeviceState = StopPending;
+
+                     /* perform invalidation */
+                     DoInvalidate = TRUE;
+                }
+            }
+            else if (DeviceEntry->DeviceState == Started)
+            {
+                /* found pending irps */
+                KspCompletePendingIrps(DeviceEntry, STATUS_REPARSE);
+            }
+        }
+
+
+        /* move to next */
+        Entry = Entry->Flink;
+    }
+
+   /* release lock */
+    KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
+
+    if (DoInvalidate)
+    {
+        /* invalidate device relations */
+        IoInvalidateDeviceRelations(BusDeviceExtension->PhysicalDeviceObject, BusRelations);
+    }
+
+    Time.QuadPart = Int32x32To64(5000, -10000);
+    KeSetTimer(&BusDeviceExtension->Timer, Time, &BusDeviceExtension->Dpc);
 }
 
 VOID
@@ -1173,9 +1257,10 @@ KspQueryBusRelations(
     PLIST_ENTRY Entry;
     PBUS_DEVICE_ENTRY DeviceEntry;
     ULONG Count = 0, Length;
+    KIRQL OldLevel;
 
-
-    /* FIXME locks */
+    /* acquire lock */
+    KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
 
     /* first scan all device entries */
     Entry = BusDeviceExtension->Common.Entry.Flink;
@@ -1186,7 +1271,7 @@ KspQueryBusRelations(
         DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
 
         /* is there a pdo yet */
-        if (DeviceEntry->PDO)
+        if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
         {
             /* increment count */
             Count++;
@@ -1205,6 +1290,7 @@ KspQueryBusRelations(
     if (!DeviceRelations)
     {
         /* not enough memory */
+        KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
         return STATUS_INSUFFICIENT_RESOURCES;
     }
 
@@ -1217,7 +1303,7 @@ KspQueryBusRelations(
         DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
 
         /* is there a pdo yet */
-        if (DeviceEntry->PDO)
+        if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
         {
             /* store pdo */
             DeviceRelations->Objects[DeviceRelations->Count] = DeviceEntry->PDO;
@@ -1233,6 +1319,9 @@ KspQueryBusRelations(
         Entry = Entry->Flink;
     }
 
+    /* release lock */
+    KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
+
     /* FIXME handle existing device relations */
     ASSERT(Irp->IoStatus.Information == 0);
 
@@ -1328,6 +1417,7 @@ KsGetBusEnumIdentifier(
     }
 
     /* done */
+    Irp->IoStatus.Status = Status;
     return Status;
 }
 
@@ -1550,7 +1640,7 @@ KsCreateBusEnumObject(
         FreeItem(BusDeviceExtension);
     }
 
-    DPRINT1("KsCreateBusEnumObject cp %x\n", Status);
+    DPRINT("KsCreateBusEnumObject Status %x\n", Status);
     /* done */
     return Status;
 }
@@ -1569,7 +1659,7 @@ KsGetBusEnumPnpDeviceObject(
     PCOMMON_DEVICE_EXTENSION CommonDeviceExtension;
     PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
 
-    DPRINT1("KsGetBusEnumPnpDeviceObject\n");
+    DPRINT("KsGetBusEnumPnpDeviceObject\n");
 
     if (!DeviceObject->DeviceExtension)
     {
@@ -1712,13 +1802,12 @@ KsServiceBusEnumCreateRequest(
     PLIST_ENTRY Entry;
     PBUS_DEVICE_ENTRY DeviceEntry = NULL; /* fix gcc */
     PIO_STACK_LOCATION IoStack;
-    BOOLEAN ItemExists;
+    BOOLEAN ItemExists = FALSE;
     PDEV_EXTENSION DeviceExtension;
     PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
     //PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
     NTSTATUS Status;
-
-    DPRINT1("KsServiceBusEnumCreateRequest\n");
+    LARGE_INTEGER Time;
 
     /* FIXME: locks */
 
@@ -1735,6 +1824,8 @@ KsServiceBusEnumCreateRequest(
     ASSERT(IoStack->FileObject);
     ASSERT(IoStack->FileObject->FileName.Buffer);
 
+    DPRINT1("KsServiceBusEnumCreateRequest IRP %p Name %wZ\n", Irp, &IoStack->FileObject->FileName);
+
     /* scan list and check if it is already present */
     Entry = BusDeviceExtension->Common.Entry.Flink;
 
@@ -1768,7 +1859,11 @@ KsServiceBusEnumCreateRequest(
         if (DeviceEntry->DeviceState == Started)
         {
             /* issue reparse */
-            return KspDoReparseForIrp(Irp, DeviceEntry);
+            Status =  KspDoReparseForIrp(Irp, DeviceEntry);
+            DPRINT("REPARSE Irp %p '%wZ'\n", Irp, &IoStack->FileObject->FileName);
+
+            Irp->IoStatus.Status = Status;
+            return Status;
         }
 
         /* delay processing until pnp is finished with enumeration */
@@ -1777,9 +1872,14 @@ KsServiceBusEnumCreateRequest(
         /* insert into irp pending list */
         InsertTailList(&DeviceEntry->IrpPendingList, &Irp->Tail.Overlay.ListEntry);
 
-        /* HACK */
-        IoInvalidateDeviceRelations(BusDeviceExtension->PhysicalDeviceObject, BusRelations);
+        Time.QuadPart = Int32x32To64(1500, -10000);
+        DbgPrint("PENDING Irp %p %wZ\n", Irp, &IoStack->FileObject->FileName);
 
+        /* query current time */
+        KeQuerySystemTime(&DeviceEntry->TimeCreated);
+
+        /* set timer */
+        KeSetTimer(&BusDeviceExtension->Timer, Time, &BusDeviceExtension->Dpc);
 
         /* done for now */
         return STATUS_PENDING;
@@ -1796,6 +1896,7 @@ KsServiceBusEnumCreateRequest(
             DPRINT1("KsServiceBusEnumCreateRequest failed to create PDO with %x\n", Status);
             return Status;
         }
+        DPRINT1("PENDING CREATE Irp %p %wZ\n", Irp, &IoStack->FileObject->FileName);
 
         /* delay processing until pnp is finished with enumeration */
         IoMarkIrpPending(Irp);
@@ -1826,9 +1927,12 @@ KsServiceBusEnumPnpRequest(
 {
     PDEV_EXTENSION DeviceExtension;
     PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+    PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
     PIO_STACK_LOCATION IoStack;
-
-    DPRINT1("KsServiceBusEnumPnpRequest %p\n", DeviceObject);
+    NTSTATUS Status;
+    LARGE_INTEGER Time;
+    PDEVICE_RELATIONS DeviceRelation;
+    PBUS_DEVICE_ENTRY DeviceEntry;
 
     /* get device extension */
     DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
@@ -1844,64 +1948,154 @@ KsServiceBusEnumPnpRequest(
         if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
         {
             /* no op for bus driver */
-            return STATUS_SUCCESS;
+            Status = STATUS_SUCCESS;
         }
         else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)
         {
             /* handle bus device relations */
             ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == BusRelations);
 
-            return KspQueryBusRelations(BusDeviceExtension, Irp);
+            Status = KspQueryBusRelations(BusDeviceExtension, Irp);
+        }
+        else
+        {
+            /* get default status */
+            Status = Irp->IoStatus.Status;
         }
-        DPRINT1("KsServiceBusEnumPnpRequest BusObject MinorFunction %x\n", IoStack->MinorFunction);
-        return STATUS_NOT_SUPPORTED;
     }
     else
     {
+        /* get child device extension */
+        ChildDeviceExtension = DeviceExtension->Ext;
+
+        /* get bus device extension */
+        BusDeviceExtension = ChildDeviceExtension->BusDeviceExtension;
+
         if (IoStack->MinorFunction == IRP_MN_QUERY_ID)
         {
             /* query id */
-            return KspQueryId(&BusDeviceExtension->Common, Irp);
+            Status = KspQueryId(ChildDeviceExtension, Irp);
+        }
+        else if (IoStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
+        {
+            ASSERT(ChildDeviceExtension->DeviceEntry->DeviceState != Started || ChildDeviceExtension->DeviceEntry->DeviceState == NotStarted);
+            ASSERT(ChildDeviceExtension->DeviceEntry->PDO == DeviceObject);
+
+            /* backup device entry */
+            DeviceEntry = ChildDeviceExtension->DeviceEntry;
+
+            /* free device extension */
+            FreeItem(ChildDeviceExtension);
+
+            /* clear PDO reference */
+            DeviceEntry->PDO = NULL;
+
+            /* delete the device */
+            IoDeleteDevice(DeviceObject);
+
+            if (DeviceEntry->PDODeviceName)
+            {
+                /* delete pdo device name */
+                FreeItem(DeviceEntry->PDODeviceName);
+
+                /* set to null */
+                DeviceEntry->PDODeviceName = NULL;
+            }
+
+            /* set state no notstarted */
+            DeviceEntry->DeviceState = NotStarted;
+
+        /* time to create PDO */
+        KspCreatePDO(BusDeviceExtension, DeviceEntry, &DeviceEntry->PDO);
+
+        /* invalidate device relations */
+        IoInvalidateDeviceRelations(BusDeviceExtension->PhysicalDeviceObject, BusRelations);
+
+            /* done */
+            Status = STATUS_SUCCESS;
         }
         else if (IoStack->MinorFunction == IRP_MN_QUERY_BUS_INFORMATION)
         {
             /* query bus information */
-            return KspQueryBusInformation(&BusDeviceExtension->Common, Irp);
+            Status = KspQueryBusInformation(ChildDeviceExtension, Irp);
         }
         else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES)
         {
             /* no op */
-            return STATUS_SUCCESS;
+            Status = STATUS_SUCCESS;
         }
         else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
         {
             /* no op */
-            return STATUS_SUCCESS;
+            Status = STATUS_SUCCESS;
         }
         else if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
         {
             /* start bus */
-            return KspStartBusDevice(DeviceObject, &BusDeviceExtension->Common, Irp);
+            Status = KspStartBusDevice(DeviceObject, ChildDeviceExtension, Irp);
+
+            /* set time out */
+            Time.QuadPart = Int32x32To64(1500, -10000);
+
+            /* sanity check */
+            ASSERT(BusDeviceExtension);
+
+            /* set timer */
+            KeSetTimer(&BusDeviceExtension->Timer, Time, &BusDeviceExtension->Dpc);
         }
         else if (IoStack->MinorFunction == IRP_MN_QUERY_CAPABILITIES)
         {
             /* query capabilities */
-            return KspQueryBusDeviceCapabilities(&BusDeviceExtension->Common, Irp);
+            Status = KspQueryBusDeviceCapabilities(ChildDeviceExtension, Irp);
         }
         else if (IoStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
         {
             /* query pnp state */
-            return KspQueryBusDevicePnpState(&BusDeviceExtension->Common, Irp);
+            Status = KspQueryBusDevicePnpState(ChildDeviceExtension, Irp);
         }
         else if (IoStack->MinorFunction == IRP_MN_QUERY_INTERFACE)
         {
             /* query interface */
-            return KspQueryBusDeviceInterface(Irp, &BusDeviceExtension->Common);
+            Status = KspQueryBusDeviceInterface(ChildDeviceExtension, Irp);
         }
+        else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS && IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation)
+        {
+            /* handle target device relations */
+            ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == TargetDeviceRelation);
+            ASSERT(Irp->IoStatus.Information == 0);
+
+            /* allocate device relation */
+            DeviceRelation = AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS));
+            if (DeviceRelation)
+            {
+                DeviceRelation->Count = 1;
+                DeviceRelation->Objects[0] = DeviceObject;
+
+                /* reference self */
+                ObReferenceObject(DeviceObject);
 
-        DPRINT1("KsServiceBusEnumPnpRequest BusObject MinorFunction %x\n", IoStack->MinorFunction);
-        return STATUS_NOT_SUPPORTED;
+                /* store result */
+                Irp->IoStatus.Information = (ULONG_PTR)DeviceRelation;
+
+                /* done */
+                Status = STATUS_SUCCESS;
+            }
+            else
+            {
+                /* no memory */
+                Status = STATUS_INSUFFICIENT_RESOURCES;
+            }
+        }
+        else
+        {
+            /* get default status */
+            Status = Irp->IoStatus.Status;
+        }
     }
+
+    DPRINT("KsServiceBusEnumPnpRequest %p Bus %u Function %x Status %x\n", DeviceObject, BusDeviceExtension->Common.IsBus, IoStack->MinorFunction, Status);
+    Irp->IoStatus.Status = Status;
+    return Status;
 }
 
 /*