[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
This commit is contained in:
Johannes Anderwald 2010-12-21 13:06:47 +00:00
parent 8baebdbded
commit ea8f6ef311
12 changed files with 350 additions and 141 deletions

View file

@ -163,7 +163,7 @@ IKsAllocator_fnDeviceIoControl(
/* complete and forget irps */ /* complete and forget irps */
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
@ -172,7 +172,7 @@ IKsAllocator_fnDeviceIoControl(
{ {
/* invalid request */ /* invalid request */
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
} }
@ -190,7 +190,7 @@ IKsAllocator_fnDeviceIoControl(
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
/* complete and forget irp */ /* complete and forget irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
if (!(Property->Flags & KSPROPERTY_TYPE_GET)) if (!(Property->Flags & KSPROPERTY_TYPE_GET))
@ -198,7 +198,7 @@ IKsAllocator_fnDeviceIoControl(
/* only support retrieving the property */ /* only support retrieving the property */
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
/* complete and forget irp */ /* complete and forget irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -212,7 +212,7 @@ IKsAllocator_fnDeviceIoControl(
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
/* complete request */ /* complete request */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS) else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS)
@ -223,7 +223,7 @@ IKsAllocator_fnDeviceIoControl(
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS); Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS);
/* complete and forget irp */ /* complete and forget irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_BUFFER_TOO_SMALL; return STATUS_BUFFER_TOO_SMALL;
} }
if (!(Property->Flags & KSPROPERTY_TYPE_GET)) if (!(Property->Flags & KSPROPERTY_TYPE_GET))
@ -231,7 +231,7 @@ IKsAllocator_fnDeviceIoControl(
/* only support retrieving the property */ /* only support retrieving the property */
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
/* complete and forget irp */ /* complete and forget irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -246,14 +246,14 @@ IKsAllocator_fnDeviceIoControl(
Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS); Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS);
/* complete request */ /* complete request */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
} }
/* unhandled request */ /* unhandled request */
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_SUPPORTED; return STATUS_NOT_SUPPORTED;
} }
@ -501,7 +501,7 @@ IKsAllocator_DispatchDeviceIoControl(
/* complete request */ /* complete request */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -523,7 +523,7 @@ IKsAllocator_DispatchClose(
/* complete request */ /* complete request */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }

View file

@ -1332,7 +1332,7 @@ KopDispatchClose(
/* complete request */ /* complete request */
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1416,7 +1416,7 @@ KopDispatchCreate(
IoStack->FileObject->FsContext2 = (PVOID)Header; IoStack->FileObject->FsContext2 = (PVOID)Header;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
@ -1429,7 +1429,7 @@ cleanup:
FreeItem(Header); FreeItem(Header);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -1703,7 +1703,7 @@ KsCompletePendingRequest(
if (IoStack->MajorFunction != IRP_MJ_CLOSE) if (IoStack->MajorFunction != IRP_MJ_CLOSE)
{ {
/* can be completed immediately */ /* can be completed immediately */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return; return;
} }
@ -1711,7 +1711,7 @@ KsCompletePendingRequest(
if (!NT_SUCCESS(Irp->IoStatus.Status)) if (!NT_SUCCESS(Irp->IoStatus.Status))
{ {
/* closing failed, complete irp */ /* closing failed, complete irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return; return;
} }

View file

@ -339,7 +339,7 @@ IKsClock_DispatchDeviceIoControl(
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -353,7 +353,7 @@ IKsClock_DispatchClose(
UNIMPLEMENTED UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }

View file

@ -302,7 +302,7 @@ IKsDevice_PnpStartDevice(
{ {
DPRINT1("NextDevice object failed to start with %x\n", Status); DPRINT1("NextDevice object failed to start with %x\n", Status);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -335,9 +335,6 @@ IKsDevice_PnpStartDevice(
} }
ASSERT(DeviceHeader->KsDevice.Descriptor); ASSERT(DeviceHeader->KsDevice.Descriptor);
ASSERT(DeviceHeader->KsDevice.Descriptor->Dispatch);
ASSERT(DeviceHeader->KsDevice.Descriptor->Dispatch->Start);
/* do we have a device descriptor */ /* do we have a device descriptor */
if (DeviceHeader->KsDevice.Descriptor) if (DeviceHeader->KsDevice.Descriptor)
@ -361,7 +358,7 @@ IKsDevice_PnpStartDevice(
{ {
DPRINT1("Driver: failed to start %x\n", Status); DPRINT1("Driver: failed to start %x\n", Status);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -406,12 +403,17 @@ IKsDevice_PnpStartDevice(
Status = KspSetFilterFactoriesState(DeviceHeader, TRUE); Status = KspSetFilterFactoriesState(DeviceHeader, TRUE);
} }
} }
else
{
/* set state to run */
DeviceHeader->KsDevice.Started = TRUE;
}
} }
/* store result */ /* store result */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
/* complete request */ /* complete request */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
if (Ctx) if (Ctx)
{ {
@ -420,7 +422,7 @@ IKsDevice_PnpStartDevice(
} }
/* return result */ /* return result */
DPRINT1("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx); DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx);
return Status; return Status;
} }
@ -477,7 +479,7 @@ IKsDevice_Pnp(
{ {
DPRINT1("Driver: query stop failed %x\n", Status); DPRINT1("Driver: query stop failed %x\n", Status);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -487,7 +489,7 @@ IKsDevice_Pnp(
DPRINT("Next Device: Status %x\n", Status); DPRINT("Next Device: Status %x\n", Status);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -513,7 +515,7 @@ IKsDevice_Pnp(
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
case IRP_MN_QUERY_INTERFACE: case IRP_MN_QUERY_INTERFACE:
@ -536,7 +538,7 @@ IKsDevice_Pnp(
/* driver supports a private interface */ /* driver supports a private interface */
DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n"); DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -545,7 +547,7 @@ IKsDevice_Pnp(
DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status); DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
case IRP_MN_QUERY_DEVICE_RELATIONS: case IRP_MN_QUERY_DEVICE_RELATIONS:
@ -556,7 +558,7 @@ IKsDevice_Pnp(
DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status); DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status);
//Irp->IoStatus.Status = Status; //Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
@ -567,7 +569,7 @@ IKsDevice_Pnp(
DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status); DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
//Irp->IoStatus.Status = Status; //Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
@ -578,7 +580,7 @@ IKsDevice_Pnp(
DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status); DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
default: default:
@ -587,7 +589,7 @@ IKsDevice_Pnp(
Status = KspForwardIrpSynchronous(DeviceObject, Irp); Status = KspForwardIrpSynchronous(DeviceObject, Irp);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
} }
@ -604,7 +606,7 @@ IKsDevice_Power(
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -669,17 +671,10 @@ IKsDevice_Create(
} }
} }
/* acquire list lock */ /* release list lock */
IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
if (Status != STATUS_PENDING) /* done */
{
Irp->IoStatus.Information = 0;
/* set return status */
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
return Status; return Status;
@ -703,7 +698,7 @@ KsInitializeDevice(
PKSIOBJECT_BAG Bag; PKSIOBJECT_BAG Bag;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
DPRINT("KsInitializeDevice Descriptor %p\n", Descriptor); DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor);
/* get device extension */ /* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension; DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
@ -714,7 +709,7 @@ KsInitializeDevice(
/* point to allocated header */ /* point to allocated header */
Header = DeviceExtension->DeviceHeader; Header = DeviceExtension->DeviceHeader;
DPRINT("DeviceHeader %p\n", DeviceExtension->DeviceHeader); DPRINT1("DeviceHeader %p\n", DeviceExtension->DeviceHeader);
if (Descriptor && Descriptor->Dispatch) if (Descriptor && Descriptor->Dispatch)
{ {
@ -896,7 +891,7 @@ KsDereferenceSoftwareBusObject(
IKsDevice * Device; IKsDevice * Device;
PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
DPRINT1("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header); DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
/* get device interface */ /* get device interface */
Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;

View file

@ -485,7 +485,7 @@ IKsFilter_GetFilterFromIrp(
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
/* complete and forget irp */ /* complete and forget irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
return Status; return Status;
@ -522,7 +522,7 @@ IKsFilter_DispatchClose(
/* save the result */ /* save the result */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
/* complete irp */ /* complete irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
/* remove our instance from the filter factory */ /* remove our instance from the filter factory */
IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory); IKsFilter_RemoveFilterFromFilterFactory(This, This->Factory);
@ -535,7 +535,7 @@ IKsFilter_DispatchClose(
/* complete and forget */ /* complete and forget */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
/* complete irp */ /* complete irp */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
} }
/* done */ /* done */
@ -881,7 +881,7 @@ IKsFilter_DispatchDeviceIoControl(
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
{ {
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
} }
/* done */ /* done */
@ -1227,7 +1227,7 @@ IKsFilter_DispatchCreatePin(
{ {
/* complete request */ /* complete request */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
} }
/* done */ /* done */
@ -1243,7 +1243,7 @@ IKsFilter_DispatchCreateNode(
{ {
UNIMPLEMENTED UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -1608,7 +1608,7 @@ KsFilterAttemptProcessing(
IN PKSFILTER Filter, IN PKSFILTER Filter,
IN BOOLEAN Asynchronous) IN BOOLEAN Asynchronous)
{ {
UNIMPLEMENTED //UNIMPLEMENTED
} }
/* /*

View file

@ -69,7 +69,7 @@ IKsFilterFactory_Create(
{ {
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
} }
return Status; return Status;

View file

@ -34,7 +34,7 @@ KsDispatchQuerySecurity(
{ {
/* no create item */ /* no create item */
Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT; Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_SECURITY_ON_OBJECT; return STATUS_NO_SECURITY_ON_OBJECT;
} }
@ -50,7 +50,7 @@ KsDispatchQuerySecurity(
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length; Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -80,7 +80,7 @@ KsDispatchSetSecurity(
{ {
/* no create item */ /* no create item */
Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT; Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NO_SECURITY_ON_OBJECT; return STATUS_NO_SECURITY_ON_OBJECT;
} }
@ -109,7 +109,7 @@ KsDispatchSetSecurity(
/* store result */ /* store result */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -1154,7 +1154,7 @@ KsDispatchInvalidDeviceRequest(
IN PIRP Irp) IN PIRP Irp)
{ {
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST; return STATUS_INVALID_DEVICE_REQUEST;
} }
@ -1198,7 +1198,7 @@ KsDefaultDeviceIoCompletion(
/* complete request */ /* complete request */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
@ -1643,14 +1643,15 @@ KsAddIrpToCancelableQueue(
/* get current irp stack */ /* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp); 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 // HACK for ms portcls
if (IoStack->MajorFunction == IRP_MJ_CREATE) if (IoStack->MajorFunction == IRP_MJ_CREATE)
{ {
// complete the request // complete the request
DPRINT1("MS HACK\n");
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return; return;
} }
@ -1736,7 +1737,7 @@ KsCancelRoutine(
{ {
/* let's complete it */ /* let's complete it */
Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
} }
} }
@ -1795,14 +1796,12 @@ FindMatchingCreateItem(
continue; continue;
} }
ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer);
DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer, DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
CreateItemEntry->CreateItem->ObjectClass.Length, CreateItemEntry->CreateItem->ObjectClass.Length,
&RefString, &RefString,
BufferSize); RefString.Length);
if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize) if (CreateItemEntry->CreateItem->ObjectClass.Length > RefString.Length)
{ {
/* create item doesnt match in length */ /* create item doesnt match in length */
Entry = Entry->Flink; Entry = Entry->Flink;
@ -1853,7 +1852,7 @@ KspCreate(
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
/* set return status */ /* set return status */
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -1893,7 +1892,7 @@ KspCreate(
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
/* set return status */ /* set return status */
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -1929,7 +1928,7 @@ KspDispatchIrp(
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
/* complete and forget */ /* complete and forget */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
@ -2036,6 +2035,7 @@ KsDispatchIrp(
/* get device extension */ /* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get device header */ /* get device header */
DeviceHeader = DeviceExtension->DeviceHeader; DeviceHeader = DeviceExtension->DeviceHeader;

View file

@ -6,6 +6,13 @@
#define TAG_KSDEVICE 'DESK' #define TAG_KSDEVICE 'DESK'
#define TAG_KSOBJECT_TAG 'HOSK' #define TAG_KSOBJECT_TAG 'HOSK'
VOID
CompleteRequest(
PIRP Irp,
CCHAR PriorityBoost);
NTSTATUS NTSTATUS
NTAPI NTAPI
KspCreateObjectType( KspCreateObjectType(

View file

@ -145,7 +145,7 @@ typedef struct
typedef BOOLEAN (NTAPI *PKSEVENT_SYNCHRONIZED_ROUTINE)(PKSEVENT_CTX Context); typedef BOOLEAN (NTAPI *PKSEVENT_SYNCHRONIZED_ROUTINE)(PKSEVENT_CTX Context);
struct __BUS_ENUM_DEVICE_EXTENSION__; struct __BUS_ENUM_DEVICE_EXTENSION__;
struct BUS_DEVICE_ENTRY; struct __BUS_DEVICE_ENTRY__;
typedef struct typedef struct
{ {
@ -158,7 +158,7 @@ typedef struct
}; };
union union
{ {
PVOID DeviceEntry; struct __BUS_DEVICE_ENTRY__* DeviceEntry;
ULONG Dummy1; ULONG Dummy1;
}; };
struct __BUS_ENUM_DEVICE_EXTENSION__ *BusDeviceExtension; struct __BUS_ENUM_DEVICE_EXTENSION__ *BusDeviceExtension;
@ -191,7 +191,7 @@ typedef enum
}DEVICE_STATE; }DEVICE_STATE;
typedef struct typedef struct __BUS_DEVICE_ENTRY__
{ {
LIST_ENTRY Entry; LIST_ENTRY Entry;
LIST_ENTRY DeviceInterfaceList; LIST_ENTRY DeviceInterfaceList;

View file

@ -9,6 +9,19 @@
#include "priv.h" #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 PVOID
AllocateItem( AllocateItem(
IN POOL_TYPE PoolType, IN POOL_TYPE PoolType,

View file

@ -1875,7 +1875,7 @@ IKsPin_DispatchKsStream(
DPRINT1("KsProbeStreamIrp failed with %x\n", Status); DPRINT1("KsProbeStreamIrp failed with %x\n", Status);
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -1888,7 +1888,7 @@ IKsPin_DispatchKsStream(
{ {
DPRINT("NoHeader Canceling Irp %p\n", Irp); DPRINT("NoHeader Canceling Irp %p\n", Irp);
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -1911,7 +1911,7 @@ IKsPin_DispatchKsStream(
{ {
DPRINT("NoHeader->Data Canceling Irp %p\n", Irp); DPRINT("NoHeader->Data Canceling Irp %p\n", Irp);
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -1960,7 +1960,7 @@ IKsPin_DispatchKsStream(
/* invalid device request */ /* invalid device request */
DPRINT("Filter Centric Processing No Process Routine\n"); DPRINT("Filter Centric Processing No Process Routine\n");
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
@ -2095,7 +2095,7 @@ IKsPin_DispatchDeviceIoControl(
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
{ {
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
} }
/* done */ /* done */
@ -2135,7 +2135,7 @@ IKsPin_Close(
{ {
/* abort closing */ /* abort closing */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -2145,7 +2145,7 @@ IKsPin_Close(
if (Status != STATUS_PENDING) if (Status != STATUS_PENDING)
{ {
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
} }
@ -2162,7 +2162,7 @@ IKsPin_DispatchCreateAllocator(
UNIMPLEMENTED; UNIMPLEMENTED;
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }
@ -2244,7 +2244,7 @@ IKsPin_DispatchCreateClock(
/* done */ /* done */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return Status; return Status;
} }
@ -2257,7 +2257,7 @@ IKsPin_DispatchCreateNode(
UNIMPLEMENTED; UNIMPLEMENTED;
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
} }

View file

@ -35,7 +35,7 @@ KspCreatePDO(
CurDeviceId = InterlockedIncrement(&KsDeviceCount); CurDeviceId = InterlockedIncrement(&KsDeviceCount);
/* generate new device id */ /* generate new device id */
swprintf(Buffer, L"\\Device\\KSENUM%08x\n", CurDeviceId); swprintf(Buffer, L"\\Device\\KSENUM%08x", CurDeviceId);
/* initialize new device name */ /* initialize new device name */
RtlInitUnicodeString(&DeviceName, Buffer); RtlInitUnicodeString(&DeviceName, Buffer);
@ -71,8 +71,8 @@ KspCreatePDO(
/* TODO: update last creation time in bus device extension */ /* TODO: update last creation time in bus device extension */
/* setup flags */ /* 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 */ /* TODO: fire time when expired */
*OutDeviceObject = DeviceObject; *OutDeviceObject = DeviceObject;
@ -330,6 +330,7 @@ KspCreateDeviceReference(
BOOLEAN ItemExists = FALSE; BOOLEAN ItemExists = FALSE;
UNICODE_STRING String; UNICODE_STRING String;
NTSTATUS Status; NTSTATUS Status;
KIRQL OldLevel;
/* first construct device name & reference guid */ /* first construct device name & reference guid */
Length = wcslen(DeviceCategory) + wcslen(ReferenceString); Length = wcslen(DeviceCategory) + wcslen(ReferenceString);
@ -347,9 +348,7 @@ KspCreateDeviceReference(
} }
/* construct device name */ /* construct device name */
wcscpy(DeviceName, DeviceCategory); swprintf(DeviceName, L"%s&%s", DeviceCategory, ReferenceString);
wcscat(DeviceName, L"&");
wcscat(DeviceName, ReferenceString);
/* scan list and check if it is already present */ /* scan list and check if it is already present */
Entry = BusDeviceExtension->Common.Entry.Flink; Entry = BusDeviceExtension->Common.Entry.Flink;
@ -437,8 +436,17 @@ KspCreateDeviceReference(
return Status; return Status;
} }
/* successfully initialized entry */ if (!ItemExists)
InsertTailList(&BusDeviceExtension->Common.Entry, &DeviceEntry->Entry); {
/* acquire lock */
KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
/* successfully initialized entry */
InsertTailList(&BusDeviceExtension->Common.Entry, &DeviceEntry->Entry);
/* release lock */
KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
}
/* done */ /* done */
return Status; return Status;
@ -585,8 +593,8 @@ KspBusDereferenceDeviceObject(
NTSTATUS NTSTATUS
KspQueryBusDeviceInterface( KspQueryBusDeviceInterface(
IN PIRP Irp, IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension) IN PIRP Irp)
{ {
PBUS_INTERFACE_SWENUM Interface; PBUS_INTERFACE_SWENUM Interface;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
@ -628,6 +636,7 @@ KspEnableBusDeviceInterface(
{ {
/* get bus instance entry */ /* get bus instance entry */
InstanceEntry = (PBUS_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BUS_INSTANCE_ENTRY, 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 */ /* set interface state */
Status = IoSetDeviceInterfaceState(&InstanceEntry->SymbolicLink, bEnable); Status = IoSetDeviceInterfaceState(&InstanceEntry->SymbolicLink, bEnable);
@ -672,7 +681,7 @@ KspDoReparseForIrp(
Length += 2; Length += 2;
/* allocate buffer */ /* allocate buffer */
Buffer = AllocateItem(PagedPool, Length * sizeof(WCHAR)); Buffer = AllocateItem(NonPagedPool, Length * sizeof(WCHAR));
if (!Buffer) if (!Buffer)
{ {
/* no resources */ /* no resources */
@ -680,11 +689,8 @@ KspDoReparseForIrp(
} }
/* construct buffer */ /* construct buffer */
wcscpy(Buffer, DeviceEntry->PDODeviceName); swprintf(Buffer, L"%s\\%s", DeviceEntry->PDODeviceName, DeviceEntry->Instance);
wcscat(Buffer, L"\\");
wcscat(Buffer, DeviceEntry->Instance);
/* free old file name */
ExFreePool(IoStack->FileObject->FileName.Buffer); ExFreePool(IoStack->FileObject->FileName.Buffer);
/* store new file name */ /* store new file name */
@ -704,7 +710,6 @@ KspCompletePendingIrps(
NTSTATUS Status; NTSTATUS Status;
/* go through list */ /* go through list */
while(!IsListEmpty(&DeviceEntry->IrpPendingList)) while(!IsListEmpty(&DeviceEntry->IrpPendingList))
{ {
/* get first entry */ /* get first entry */
@ -727,11 +732,12 @@ KspCompletePendingIrps(
/* store result code */ /* store result code */
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
DPRINT1("Completing IRP %p\n", Irp); DPRINT1("Completing IRP %p Status %x\n", Irp, Status);
/* complete the request */ /* complete the request */
IoCompleteRequest(Irp, IO_NO_INCREMENT); CompleteRequest(Irp, IO_NO_INCREMENT);
} }
} }
@ -760,7 +766,7 @@ KspStartBusDevice(
} }
/* allocate device name buffer */ /* allocate device name buffer */
Name = AllocateItem(PagedPool, ResultLength); Name = AllocateItem(NonPagedPool, (ResultLength + 1) * sizeof(WCHAR));
if (!Name) if (!Name)
{ {
/* no memory */ /* no memory */
@ -784,10 +790,13 @@ KspStartBusDevice(
/* mark device as started */ /* mark device as started */
DeviceEntry->DeviceState = Started; DeviceEntry->DeviceState = Started;
DPRINT1("KspStartBusDevice Name %S Started\n", Name); /* reference start time */
KeQuerySystemTime(&DeviceEntry->TimeCreated);
/* now complete pending i/o */ DPRINT1("KspStartBusDevice Name %S DeviceName %S Instance %S Started\n", Name, DeviceEntry->DeviceName, DeviceEntry->Instance);
KspCompletePendingIrps(DeviceEntry, STATUS_REPARSE);
/* enable device classes */
//KspEnableBusDeviceInterface(DeviceEntry, TRUE);
/* done */ /* done */
return STATUS_SUCCESS; return STATUS_SUCCESS;
@ -807,6 +816,8 @@ KspQueryBusDeviceCapabilities(
/* get capabilities */ /* get capabilities */
Capabilities = IoStack->Parameters.DeviceCapabilities.Capabilities; Capabilities = IoStack->Parameters.DeviceCapabilities.Capabilities;
RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
/* setup capabilities */ /* setup capabilities */
Capabilities->UniqueID = TRUE; Capabilities->UniqueID = TRUE;
Capabilities->SilentInstall = TRUE; Capabilities->SilentInstall = TRUE;
@ -935,9 +946,7 @@ KspQueryId(
} }
/* construct id */ /* construct id */
wcscpy(Name, BusDeviceExtension->BusIdentifier); swprintf(Name, L"%s\\%s", BusDeviceExtension->BusIdentifier, DeviceEntry->BusId);
wcscat(Name, L"\\");
wcscat(Name, DeviceEntry->BusId);
/* store result */ /* store result */
Irp->IoStatus.Information = (ULONG_PTR)Name; Irp->IoStatus.Information = (ULONG_PTR)Name;
@ -948,8 +957,8 @@ KspQueryId(
else else
{ {
/* other ids are not supported */ /* other ids are not supported */
DPRINT1("Not Supported ID Type %x\n", IoStack->Parameters.QueryId.IdType); //DPRINT1("Not Supported ID Type %x\n", IoStack->Parameters.QueryId.IdType);
return STATUS_NOT_SUPPORTED; return Irp->IoStatus.Status;
} }
} }
@ -1123,8 +1132,83 @@ NTAPI
KspBusWorkerRoutine( KspBusWorkerRoutine(
IN PVOID Parameter) IN PVOID Parameter)
{ {
/* TODO: implement sweeping */ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
UNIMPLEMENTED 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 VOID
@ -1173,9 +1257,10 @@ KspQueryBusRelations(
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PBUS_DEVICE_ENTRY DeviceEntry; PBUS_DEVICE_ENTRY DeviceEntry;
ULONG Count = 0, Length; ULONG Count = 0, Length;
KIRQL OldLevel;
/* acquire lock */
/* FIXME locks */ KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
/* first scan all device entries */ /* first scan all device entries */
Entry = BusDeviceExtension->Common.Entry.Flink; Entry = BusDeviceExtension->Common.Entry.Flink;
@ -1186,7 +1271,7 @@ KspQueryBusRelations(
DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry); DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
/* is there a pdo yet */ /* is there a pdo yet */
if (DeviceEntry->PDO) if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
{ {
/* increment count */ /* increment count */
Count++; Count++;
@ -1205,6 +1290,7 @@ KspQueryBusRelations(
if (!DeviceRelations) if (!DeviceRelations)
{ {
/* not enough memory */ /* not enough memory */
KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
@ -1217,7 +1303,7 @@ KspQueryBusRelations(
DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry); DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
/* is there a pdo yet */ /* is there a pdo yet */
if (DeviceEntry->PDO) if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
{ {
/* store pdo */ /* store pdo */
DeviceRelations->Objects[DeviceRelations->Count] = DeviceEntry->PDO; DeviceRelations->Objects[DeviceRelations->Count] = DeviceEntry->PDO;
@ -1233,6 +1319,9 @@ KspQueryBusRelations(
Entry = Entry->Flink; Entry = Entry->Flink;
} }
/* release lock */
KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
/* FIXME handle existing device relations */ /* FIXME handle existing device relations */
ASSERT(Irp->IoStatus.Information == 0); ASSERT(Irp->IoStatus.Information == 0);
@ -1328,6 +1417,7 @@ KsGetBusEnumIdentifier(
} }
/* done */ /* done */
Irp->IoStatus.Status = Status;
return Status; return Status;
} }
@ -1550,7 +1640,7 @@ KsCreateBusEnumObject(
FreeItem(BusDeviceExtension); FreeItem(BusDeviceExtension);
} }
DPRINT1("KsCreateBusEnumObject cp %x\n", Status); DPRINT("KsCreateBusEnumObject Status %x\n", Status);
/* done */ /* done */
return Status; return Status;
} }
@ -1569,7 +1659,7 @@ KsGetBusEnumPnpDeviceObject(
PCOMMON_DEVICE_EXTENSION CommonDeviceExtension; PCOMMON_DEVICE_EXTENSION CommonDeviceExtension;
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension; PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
DPRINT1("KsGetBusEnumPnpDeviceObject\n"); DPRINT("KsGetBusEnumPnpDeviceObject\n");
if (!DeviceObject->DeviceExtension) if (!DeviceObject->DeviceExtension)
{ {
@ -1712,13 +1802,12 @@ KsServiceBusEnumCreateRequest(
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PBUS_DEVICE_ENTRY DeviceEntry = NULL; /* fix gcc */ PBUS_DEVICE_ENTRY DeviceEntry = NULL; /* fix gcc */
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
BOOLEAN ItemExists; BOOLEAN ItemExists = FALSE;
PDEV_EXTENSION DeviceExtension; PDEV_EXTENSION DeviceExtension;
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension; PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
//PCOMMON_DEVICE_EXTENSION ChildDeviceExtension; //PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
NTSTATUS Status; NTSTATUS Status;
LARGE_INTEGER Time;
DPRINT1("KsServiceBusEnumCreateRequest\n");
/* FIXME: locks */ /* FIXME: locks */
@ -1735,6 +1824,8 @@ KsServiceBusEnumCreateRequest(
ASSERT(IoStack->FileObject); ASSERT(IoStack->FileObject);
ASSERT(IoStack->FileObject->FileName.Buffer); 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 */ /* scan list and check if it is already present */
Entry = BusDeviceExtension->Common.Entry.Flink; Entry = BusDeviceExtension->Common.Entry.Flink;
@ -1768,7 +1859,11 @@ KsServiceBusEnumCreateRequest(
if (DeviceEntry->DeviceState == Started) if (DeviceEntry->DeviceState == Started)
{ {
/* issue reparse */ /* 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 */ /* delay processing until pnp is finished with enumeration */
@ -1777,9 +1872,14 @@ KsServiceBusEnumCreateRequest(
/* insert into irp pending list */ /* insert into irp pending list */
InsertTailList(&DeviceEntry->IrpPendingList, &Irp->Tail.Overlay.ListEntry); InsertTailList(&DeviceEntry->IrpPendingList, &Irp->Tail.Overlay.ListEntry);
/* HACK */ Time.QuadPart = Int32x32To64(1500, -10000);
IoInvalidateDeviceRelations(BusDeviceExtension->PhysicalDeviceObject, BusRelations); 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 */ /* done for now */
return STATUS_PENDING; return STATUS_PENDING;
@ -1796,6 +1896,7 @@ KsServiceBusEnumCreateRequest(
DPRINT1("KsServiceBusEnumCreateRequest failed to create PDO with %x\n", Status); DPRINT1("KsServiceBusEnumCreateRequest failed to create PDO with %x\n", Status);
return Status; return Status;
} }
DPRINT1("PENDING CREATE Irp %p %wZ\n", Irp, &IoStack->FileObject->FileName);
/* delay processing until pnp is finished with enumeration */ /* delay processing until pnp is finished with enumeration */
IoMarkIrpPending(Irp); IoMarkIrpPending(Irp);
@ -1826,9 +1927,12 @@ KsServiceBusEnumPnpRequest(
{ {
PDEV_EXTENSION DeviceExtension; PDEV_EXTENSION DeviceExtension;
PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension; PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
PIO_STACK_LOCATION IoStack; PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
DPRINT1("KsServiceBusEnumPnpRequest %p\n", DeviceObject); LARGE_INTEGER Time;
PDEVICE_RELATIONS DeviceRelation;
PBUS_DEVICE_ENTRY DeviceEntry;
/* get device extension */ /* get device extension */
DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension; DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
@ -1844,64 +1948,154 @@ KsServiceBusEnumPnpRequest(
if (IoStack->MinorFunction == IRP_MN_START_DEVICE) if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
{ {
/* no op for bus driver */ /* no op for bus driver */
return STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS) else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)
{ {
/* handle bus device relations */ /* handle bus device relations */
ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == BusRelations); 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 else
{ {
/* get child device extension */
ChildDeviceExtension = DeviceExtension->Ext;
/* get bus device extension */
BusDeviceExtension = ChildDeviceExtension->BusDeviceExtension;
if (IoStack->MinorFunction == IRP_MN_QUERY_ID) if (IoStack->MinorFunction == IRP_MN_QUERY_ID)
{ {
/* 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) else if (IoStack->MinorFunction == IRP_MN_QUERY_BUS_INFORMATION)
{ {
/* query bus information */ /* query bus information */
return KspQueryBusInformation(&BusDeviceExtension->Common, Irp); Status = KspQueryBusInformation(ChildDeviceExtension, Irp);
} }
else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES) else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES)
{ {
/* no op */ /* no op */
return STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS) else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
{ {
/* no op */ /* no op */
return STATUS_SUCCESS; Status = STATUS_SUCCESS;
} }
else if (IoStack->MinorFunction == IRP_MN_START_DEVICE) else if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
{ {
/* start bus */ /* 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) else if (IoStack->MinorFunction == IRP_MN_QUERY_CAPABILITIES)
{ {
/* query capabilities */ /* query capabilities */
return KspQueryBusDeviceCapabilities(&BusDeviceExtension->Common, Irp); Status = KspQueryBusDeviceCapabilities(ChildDeviceExtension, Irp);
} }
else if (IoStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE) else if (IoStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
{ {
/* query pnp state */ /* query pnp state */
return KspQueryBusDevicePnpState(&BusDeviceExtension->Common, Irp); Status = KspQueryBusDevicePnpState(ChildDeviceExtension, Irp);
} }
else if (IoStack->MinorFunction == IRP_MN_QUERY_INTERFACE) else if (IoStack->MinorFunction == IRP_MN_QUERY_INTERFACE)
{ {
/* 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); /* allocate device relation */
return STATUS_NOT_SUPPORTED; 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;
} }
/* /*