From ea8f6ef3112cf57afd547b722b62d91f8c557c2a Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 21 Dec 2010 13:06:47 +0000 Subject: [PATCH] [AUDIO-BRINGUP] - 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 --- drivers/ksfilter/ks/allocators.c | 22 +- drivers/ksfilter/ks/api.c | 10 +- drivers/ksfilter/ks/clocks.c | 4 +- drivers/ksfilter/ks/device.c | 53 +++-- drivers/ksfilter/ks/filter.c | 14 +- drivers/ksfilter/ks/filterfactory.c | 2 +- drivers/ksfilter/ks/irp.c | 32 +-- drivers/ksfilter/ks/ksfunc.h | 7 + drivers/ksfilter/ks/kstypes.h | 6 +- drivers/ksfilter/ks/misc.c | 13 ++ drivers/ksfilter/ks/pin.c | 20 +- drivers/ksfilter/ks/swenum.c | 308 +++++++++++++++++++++++----- 12 files changed, 350 insertions(+), 141 deletions(-) diff --git a/drivers/ksfilter/ks/allocators.c b/drivers/ksfilter/ks/allocators.c index 5a4970f1b58..b3fbbbe20d5 100644 --- a/drivers/ksfilter/ks/allocators.c +++ b/drivers/ksfilter/ks/allocators.c @@ -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; } diff --git a/drivers/ksfilter/ks/api.c b/drivers/ksfilter/ks/api.c index bf0e18b4f23..3a037bfa168 100644 --- a/drivers/ksfilter/ks/api.c +++ b/drivers/ksfilter/ks/api.c @@ -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; } diff --git a/drivers/ksfilter/ks/clocks.c b/drivers/ksfilter/ks/clocks.c index 05064be740a..2e3f03f0b55 100644 --- a/drivers/ksfilter/ks/clocks.c +++ b/drivers/ksfilter/ks/clocks.c @@ -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; } diff --git a/drivers/ksfilter/ks/device.c b/drivers/ksfilter/ks/device.c index 432548c6d91..3cd4ec3a06a 100644 --- a/drivers/ksfilter/ks/device.c +++ b/drivers/ksfilter/ks/device.c @@ -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; diff --git a/drivers/ksfilter/ks/filter.c b/drivers/ksfilter/ks/filter.c index 5f4a74b9b64..7f0f820c367 100644 --- a/drivers/ksfilter/ks/filter.c +++ b/drivers/ksfilter/ks/filter.c @@ -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 } /* diff --git a/drivers/ksfilter/ks/filterfactory.c b/drivers/ksfilter/ks/filterfactory.c index e60bfc41e81..51c9a65d273 100644 --- a/drivers/ksfilter/ks/filterfactory.c +++ b/drivers/ksfilter/ks/filterfactory.c @@ -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; diff --git a/drivers/ksfilter/ks/irp.c b/drivers/ksfilter/ks/irp.c index fb36d6df78a..2b94a6d0faf 100644 --- a/drivers/ksfilter/ks/irp.c +++ b/drivers/ksfilter/ks/irp.c @@ -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; diff --git a/drivers/ksfilter/ks/ksfunc.h b/drivers/ksfilter/ks/ksfunc.h index 6a4d85df867..1c51a8c1c80 100644 --- a/drivers/ksfilter/ks/ksfunc.h +++ b/drivers/ksfilter/ks/ksfunc.h @@ -6,6 +6,13 @@ #define TAG_KSDEVICE 'DESK' #define TAG_KSOBJECT_TAG 'HOSK' +VOID +CompleteRequest( + PIRP Irp, + CCHAR PriorityBoost); + + + NTSTATUS NTAPI KspCreateObjectType( diff --git a/drivers/ksfilter/ks/kstypes.h b/drivers/ksfilter/ks/kstypes.h index da144526565..0be5956264c 100644 --- a/drivers/ksfilter/ks/kstypes.h +++ b/drivers/ksfilter/ks/kstypes.h @@ -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; diff --git a/drivers/ksfilter/ks/misc.c b/drivers/ksfilter/ks/misc.c index 057103d3414..9ba4b2611b5 100644 --- a/drivers/ksfilter/ks/misc.c +++ b/drivers/ksfilter/ks/misc.c @@ -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, diff --git a/drivers/ksfilter/ks/pin.c b/drivers/ksfilter/ks/pin.c index a6caeb30de0..883f098b43d 100644 --- a/drivers/ksfilter/ks/pin.c +++ b/drivers/ksfilter/ks/pin.c @@ -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; } diff --git a/drivers/ksfilter/ks/swenum.c b/drivers/ksfilter/ks/swenum.c index b79c0cd77c3..d764ed9a88d 100644 --- a/drivers/ksfilter/ks/swenum.c +++ b/drivers/ksfilter/ks/swenum.c @@ -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); - DPRINT1("KsServiceBusEnumPnpRequest BusObject MinorFunction %x\n", IoStack->MinorFunction); - return STATUS_NOT_SUPPORTED; + /* allocate device relation */ + DeviceRelation = AllocateItem(PagedPool, sizeof(DEVICE_RELATIONS)); + if (DeviceRelation) + { + DeviceRelation->Count = 1; + DeviceRelation->Objects[0] = DeviceObject; + + /* reference self */ + ObReferenceObject(DeviceObject); + + /* 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; } /*