diff --git a/reactos/drivers/ksfilter/directory.rbuild b/reactos/drivers/ksfilter/directory.rbuild
index db069940a31..f74ff5d9226 100644
--- a/reactos/drivers/ksfilter/directory.rbuild
+++ b/reactos/drivers/ksfilter/directory.rbuild
@@ -4,8 +4,8 @@
-
+
diff --git a/reactos/drivers/ksfilter/ks/allocators.c b/reactos/drivers/ksfilter/ks/allocators.c
index 5a4970f1b58..b3fbbbe20d5 100644
--- a/reactos/drivers/ksfilter/ks/allocators.c
+++ b/reactos/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/reactos/drivers/ksfilter/ks/api.c b/reactos/drivers/ksfilter/ks/api.c
index 64c341c20b3..3a037bfa168 100644
--- a/reactos/drivers/ksfilter/ks/api.c
+++ b/reactos/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;
}
@@ -1723,136 +1723,8 @@ KsCompletePendingRequest(
}
-/*
- @implemented
-*/
-KSDDKAPI
NTSTATUS
NTAPI
-KsCreateBusEnumObject(
- IN PWCHAR BusIdentifier,
- IN PDEVICE_OBJECT BusDeviceObject,
- IN PDEVICE_OBJECT PhysicalDeviceObject,
- IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL,
- IN REFGUID InterfaceGuid OPTIONAL,
- IN PWCHAR ServiceRelativePath OPTIONAL)
-{
- ULONG Length;
- NTSTATUS Status = STATUS_SUCCESS;
- UNICODE_STRING ServiceKeyPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
- PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
- PDEVICE_EXTENSION DeviceExtension;
-
- /* calculate sizeof bus enum device extension */
- Length = wcslen(BusIdentifier) * sizeof(WCHAR);
- Length += sizeof(BUS_ENUM_DEVICE_EXTENSION);
-
- BusDeviceExtension = AllocateItem(NonPagedPool, Length);
- if (!BusDeviceExtension)
- {
- /* not enough memory */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- /* zero device extension */
- RtlZeroMemory(BusDeviceExtension, sizeof(BUS_ENUM_DEVICE_EXTENSION));
-
- /* initialize bus device extension */
- wcscpy(BusDeviceExtension->BusIdentifier, BusIdentifier);
-
- /* allocate service path string */
- Length = ServiceKeyPath.MaximumLength;
- Length += BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName.MaximumLength;
-
- if (ServiceRelativePath)
- {
- /* relative path for devices */
- Length += wcslen(ServiceRelativePath) + 2 * sizeof(WCHAR);
- }
-
- BusDeviceExtension->ServicePath.Length = 0;
- BusDeviceExtension->ServicePath.MaximumLength = Length;
- BusDeviceExtension->ServicePath.Buffer = AllocateItem(NonPagedPool, Length);
-
- if (!BusDeviceExtension->ServicePath.Buffer)
- {
- /* not enough memory */
- FreeItem(BusDeviceExtension);
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &ServiceKeyPath);
- RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName);
-
- if (ServiceRelativePath)
- {
- RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, L"\\");
- RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, ServiceRelativePath);
- }
-
- if (InterfaceGuid)
- {
- /* register an device interface */
- Status = IoRegisterDeviceInterface(PhysicalDeviceObject, InterfaceGuid, NULL, &BusDeviceExtension->SymbolicLinkName);
-
- /* check for success */
- if (!NT_SUCCESS(Status))
- {
- FreeItem(BusDeviceExtension->ServicePath.Buffer);
- FreeItem(BusDeviceExtension);
- return Status;
- }
-
- /* now enable device interface */
- Status = IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, TRUE);
-
- if (!NT_SUCCESS(Status))
- {
- FreeItem(BusDeviceExtension->ServicePath.Buffer);
- FreeItem(BusDeviceExtension);
- return Status;
- }
-
- /* set state enabled */
- BusDeviceExtension->Enabled = TRUE;
- }
-
- /* store device objects */
- BusDeviceExtension->BusDeviceObject = BusDeviceObject;
- BusDeviceExtension->PnpDeviceObject = PnpDeviceObject;
- BusDeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
-
- if (!PnpDeviceObject)
- {
- BusDeviceExtension->PnpDeviceObject = IoAttachDeviceToDeviceStack(BusDeviceObject, PhysicalDeviceObject);
-
- if (!BusDeviceExtension->PnpDeviceObject)
- {
- /* failed to attach device */
- if (BusDeviceExtension->Enabled)
- {
- IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, FALSE);
- RtlFreeUnicodeString(&BusDeviceExtension->SymbolicLinkName);
- }
-
- /* free device extension */
- FreeItem(BusDeviceExtension->ServicePath.Buffer);
- FreeItem(BusDeviceExtension);
-
- return STATUS_DEVICE_REMOVED;
- }
- }
-
- /* attach device extension */
- DeviceExtension = (PDEVICE_EXTENSION)BusDeviceObject->DeviceExtension;
- DeviceExtension->DeviceHeader = (PKSIDEVICE_HEADER)BusDeviceExtension;
-
- /* FIXME scan bus and invalidate device relations */
- return Status;
-}
-
- NTSTATUS
-NTAPI
KspSetGetBusDataCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
@@ -1979,47 +1851,6 @@ KsDeviceRegisterAdapterObject(
}
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsGetBusEnumIdentifier(
- IN PIRP Irp)
-{
- UNIMPLEMENTED
-
- return STATUS_UNSUCCESSFUL;
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsGetBusEnumParentFDOFromChildPDO(
- IN PDEVICE_OBJECT DeviceObject,
- OUT PDEVICE_OBJECT *FunctionalDeviceObject)
-{
- UNIMPLEMENTED
- return STATUS_UNSUCCESSFUL;
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsGetBusEnumPnpDeviceObject(
- IN PDEVICE_OBJECT DeviceObject,
- IN PDEVICE_OBJECT *PnpDeviceObject)
-{
- UNIMPLEMENTED
- return STATUS_UNSUCCESSFUL;
-}
/*
@implemented
@@ -2061,33 +1892,6 @@ KsGetNextSibling(
return (PVOID)BasicHeader->Next.Pin;
}
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsInstallBusEnumInterface(
- PIRP Irp)
-{
- UNIMPLEMENTED
- return STATUS_UNSUCCESSFUL;
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsIsBusEnumChildDevice(
- IN PDEVICE_OBJECT DeviceObject,
- OUT PBOOLEAN ChildDevice)
-{
- UNIMPLEMENTED
- return STATUS_UNSUCCESSFUL;
-}
-
ULONG
KspCountMethodSets(
IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
@@ -2598,104 +2402,6 @@ cleanup:
return STATUS_INSUFFICIENT_RESOURCES;
}
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsServiceBusEnumCreateRequest(
- IN PDEVICE_OBJECT DeviceObject,
- IN OUT PIRP Irp)
-{
- UNIMPLEMENTED
- return STATUS_UNSUCCESSFUL;
-}
-
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsServiceBusEnumPnpRequest(
- IN PDEVICE_OBJECT DeviceObject,
- IN OUT PIRP Irp)
-{
- UNIMPLEMENTED
- return STATUS_UNSUCCESSFUL;
-}
-
-VOID
-NTAPI
-KspRemoveBusInterface(
- PVOID Ctx)
-{
- PKSREMOVE_BUS_INTERFACE_CTX Context =(PKSREMOVE_BUS_INTERFACE_CTX)Ctx;
-
- /* TODO
- * get SWENUM_INSTALL_INTERFACE struct
- * open device key and delete the keys
- */
-
- UNIMPLEMENTED
-
- /* set status */
- Context->Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-
-
- /* signal completion */
- KeSetEvent(&Context->Event, IO_NO_INCREMENT, FALSE);
-}
-
-/*
- @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsRemoveBusEnumInterface(
- IN PIRP Irp)
-{
- KPROCESSOR_MODE Mode;
- LUID luid;
- KSREMOVE_BUS_INTERFACE_CTX Ctx;
- WORK_QUEUE_ITEM WorkItem;
-
- /* get previous mode */
- Mode = ExGetPreviousMode();
-
- /* convert to luid */
- luid = RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
-
- /* perform access check */
- if (!SeSinglePrivilegeCheck(luid, Mode))
- {
- /* insufficient privileges */
- return STATUS_PRIVILEGE_NOT_HELD;
- }
- /* initialize event */
- KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);
-
- /* store irp in ctx */
- Ctx.Irp = Irp;
-
- /* initialize work item */
- ExInitializeWorkItem(&WorkItem, KspRemoveBusInterface, (PVOID)&Ctx);
-
- /* now queue the work item */
- ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
-
- /* wait for completion */
- KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);
-
- /* return result */
- return Ctx.Irp->IoStatus.Status;
-
-}
-
-
/*
@unimplemented
*/
diff --git a/reactos/drivers/ksfilter/ks/clocks.c b/reactos/drivers/ksfilter/ks/clocks.c
index 05064be740a..2e3f03f0b55 100644
--- a/reactos/drivers/ksfilter/ks/clocks.c
+++ b/reactos/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/reactos/drivers/ksfilter/ks/device.c b/reactos/drivers/ksfilter/ks/device.c
index 432548c6d91..49d5787820e 100644
--- a/reactos/drivers/ksfilter/ks/device.c
+++ b/reactos/drivers/ksfilter/ks/device.c
@@ -282,8 +282,6 @@ IKsDevice_PnpStartDevice(
NTSTATUS Status;
PCM_RESOURCE_LIST TranslatedResourceList;
PCM_RESOURCE_LIST UntranslatedResourceList;
- PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor, UnPartialDescriptor;
- ULONG Index;
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -302,42 +300,14 @@ 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;
}
TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
UntranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
- DPRINT("ResourceDescriptorCount %lu\n", TranslatedResourceList->List[0].PartialResourceList.Count);
- for (Index = 0; Index < TranslatedResourceList->List[0].PartialResourceList.Count; Index ++ )
- {
- PartialDescriptor = &TranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[Index];
- UnPartialDescriptor = &UntranslatedResourceList->List[0].PartialResourceList.PartialDescriptors[Index];
- DPRINT("Descriptor Type %u\n", PartialDescriptor->Type);
-
- if (PartialDescriptor->Type == CmResourceTypeInterrupt)
- {
- DPRINT("CmResourceTypeInterrupt Index %u TRANS Interrupt Number Affinity %x Level %u Vector %u Flags %x Share %x\n", Index, PartialDescriptor->u.Interrupt.Affinity, PartialDescriptor->u.Interrupt.Level, PartialDescriptor->u.Interrupt.Vector, PartialDescriptor->Flags, PartialDescriptor->ShareDisposition);
- DPRINT("CmResourceTypeInterrupt Index %u UNTRANS Interrupt Number Affinity %x Level %u Vector %u Flags %x Share %x\\n", Index, UnPartialDescriptor->u.Interrupt.Affinity, UnPartialDescriptor->u.Interrupt.Level, UnPartialDescriptor->u.Interrupt.Vector, UnPartialDescriptor->Flags, UnPartialDescriptor->ShareDisposition);
-
- }
- else if (PartialDescriptor->Type == CmResourceTypePort)
- {
- DPRINT("CmResourceTypePort Index %u TRANS Port Length %u Start %u %u Flags %x Share %x\n", Index, PartialDescriptor->u.Port.Length, PartialDescriptor->u.Port.Start.HighPart, PartialDescriptor->u.Port.Start.LowPart, PartialDescriptor->Flags, PartialDescriptor->ShareDisposition);
- DPRINT("CmResourceTypePort Index %u UNTRANS Port Length %u Start %u %u Flags %x Share %x\n", Index, UnPartialDescriptor->u.Port.Length, UnPartialDescriptor->u.Port.Start.HighPart, UnPartialDescriptor->u.Port.Start.LowPart, UnPartialDescriptor->Flags, UnPartialDescriptor->ShareDisposition);
- }
- else if (PartialDescriptor->Type == CmResourceTypeMemory)
- {
- DPRINT("CmResourceTypeMemory Index %u TRANS Start %x Length %u Flags %x Share %x\n", Index, PartialDescriptor->u.Memory.Start.LowPart, PartialDescriptor->u.Memory.Length, PartialDescriptor->Flags, PartialDescriptor->ShareDisposition);
- DPRINT("CmResourceTypeMemory Index %u TRANS Start %x Length %u Flags %x Share %x\n", Index, UnPartialDescriptor->u.Memory.Start.LowPart, UnPartialDescriptor->u.Memory.Length, UnPartialDescriptor->Flags, UnPartialDescriptor->ShareDisposition);
- }
- }
-
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 +331,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 +376,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 +395,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 +452,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 +462,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 +488,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 +511,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 +520,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 +531,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 +542,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 +553,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 +562,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 +579,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 +644,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 +671,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 +682,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 +864,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/reactos/drivers/ksfilter/ks/filter.c b/reactos/drivers/ksfilter/ks/filter.c
index 5f4a74b9b64..1e6ebbf661e 100644
--- a/reactos/drivers/ksfilter/ks/filter.c
+++ b/reactos/drivers/ksfilter/ks/filter.c
@@ -16,6 +16,7 @@ typedef struct
IKsControlVtbl *lpVtblKsControl;
IKsFilterFactory * FilterFactory;
+ IKsProcessingObjectVtbl * lpVtblKsProcessingObject;
LONG ref;
PKSIOBJECT_HEADER ObjectHeader;
@@ -25,6 +26,9 @@ typedef struct
KMUTEX ControlMutex;
KMUTEX ProcessingMutex;
+ PKSWORKER Worker;
+ WORK_QUEUE_ITEM WorkItem;
+ KSGATE Gate;
PFNKSFILTERPOWER Sleep;
PFNKSFILTERPOWER Wake;
@@ -70,6 +74,196 @@ KSPROPERTY_SET FilterPropertySet[] =
}
};
+NTSTATUS
+NTAPI
+IKsProcessingObject_fnQueryInterface(
+ IKsProcessingObject * iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
+ {
+ *Output = &This->Header.OuterUnknown;
+ _InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+ULONG
+NTAPI
+IKsProcessingObject_fnAddRef(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ return InterlockedIncrement(&This->ref);
+}
+
+ULONG
+NTAPI
+IKsProcessingObject_fnRelease(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ InterlockedDecrement(&This->ref);
+
+ /* Return new reference count */
+ return This->ref;
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnProcessingObjectWork(
+ IKsProcessingObject * iface)
+{
+ NTSTATUS Status;
+ LARGE_INTEGER TimeOut;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ DPRINT1("processing object\n");
+ /* first check if running at passive level */
+ if (KeGetCurrentIrql() == PASSIVE_LEVEL)
+ {
+ /* acquire processing mutex */
+ KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, NULL);
+ }
+ else
+ {
+ /* dispatch level processing */
+ if (KeReadStateMutex(&This->ControlMutex) == 0)
+ {
+ /* some thread was faster */
+ DPRINT1("processing object too slow\n");
+ return;
+ }
+
+ /* acquire processing mutex */
+ TimeOut.QuadPart = 0LL;
+ Status = KeWaitForSingleObject(&This->ControlMutex, Executive, KernelMode, FALSE, &TimeOut);
+
+ if (Status == STATUS_TIMEOUT)
+ {
+ /* some thread was faster */
+ DPRINT1("processing object too slow\n");
+ return;
+ }
+ }
+
+ do
+ {
+
+ /* check if the and-gate has been enabled again */
+ if (&This->Gate.Count != 0)
+ {
+ /* gate is open */
+ DPRINT1("processing object gate open\n");
+ break;
+ }
+
+ DPRINT1("IKsProcessingObject_fnProcessingObjectWork not implemented\n");
+ ASSERT(0);
+
+ }while(TRUE);
+
+ /* release process mutex */
+ KeReleaseMutex(&This->ProcessingMutex, FALSE);
+}
+
+PKSGATE
+NTAPI
+IKsProcessingObject_fnGetAndGate(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ /* return and gate */
+ return &This->Gate;
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnProcess(
+ IKsProcessingObject * iface,
+ IN BOOLEAN Asynchronous)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ /* should the action be asynchronous */
+ if (Asynchronous)
+ {
+ /* queue work item */
+ KsQueueWorkItem(This->Worker, &This->WorkItem);
+DPRINT1("queueing\n");
+ /* done */
+ return;
+ }
+
+ /* does the filter require explicit deferred processing */
+ if ((This->Filter.Descriptor->Flags & (KSFILTER_FLAG_DISPATCH_LEVEL_PROCESSING | KSFILTER_FLAG_CRITICAL_PROCESSING | KSFILTER_FLAG_HYPERCRITICAL_PROCESSING)) &&
+ KeGetCurrentIrql() > PASSIVE_LEVEL)
+ {
+ /* queue work item */
+ KsQueueWorkItem(This->Worker, &This->WorkItem);
+DPRINT1("queueing\n");
+ /* done */
+ return;
+ }
+DPRINT1("invoke\n");
+ /* call worker routine directly */
+ iface->lpVtbl->ProcessingObjectWork(iface);
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnReset(
+ IKsProcessingObject * iface)
+{
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsProcessingObject);
+
+ /* acquire processing mutex */
+ KeWaitForSingleObject(&This->ProcessingMutex, Executive, KernelMode, FALSE, NULL);
+
+ /* check if the filter supports dispatch routines */
+ if (This->Filter.Descriptor->Dispatch)
+ {
+ /* has the filter a reset routine */
+ if (This->Filter.Descriptor->Dispatch->Reset)
+ {
+ /* reset filter */
+ This->Filter.Descriptor->Dispatch->Reset(&This->Filter);
+ }
+ }
+
+ /* release process mutex */
+ KeReleaseMutex(&This->ProcessingMutex, FALSE);
+}
+
+VOID
+NTAPI
+IKsProcessingObject_fnTriggerNotification(
+ IKsProcessingObject * iface)
+{
+
+}
+
+static IKsProcessingObjectVtbl vt_IKsProcessingObject =
+{
+ IKsProcessingObject_fnQueryInterface,
+ IKsProcessingObject_fnAddRef,
+ IKsProcessingObject_fnRelease,
+ IKsProcessingObject_fnProcessingObjectWork,
+ IKsProcessingObject_fnGetAndGate,
+ IKsProcessingObject_fnProcess,
+ IKsProcessingObject_fnReset,
+ IKsProcessingObject_fnTriggerNotification
+};
+
+
+//---------------------------------------------------------------------------------------------------------
NTSTATUS
NTAPI
IKsControl_fnQueryInterface(
@@ -485,7 +679,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 +716,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 +729,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 +1075,7 @@ IKsFilter_DispatchDeviceIoControl(
if (Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
}
/* done */
@@ -1227,7 +1421,7 @@ IKsFilter_DispatchCreatePin(
{
/* complete request */
Irp->IoStatus.Status = Status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
}
/* done */
@@ -1243,7 +1437,7 @@ IKsFilter_DispatchCreateNode(
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
@@ -1356,6 +1550,20 @@ IKsFilter_RemoveFilterFromFilterFactory(
}while(TRUE);
}
+VOID
+NTAPI
+IKsFilter_FilterCentricWorker(
+ IN PVOID Ctx)
+{
+ IKsProcessingObject * Object = (IKsProcessingObject*)Ctx;
+
+ /* sanity check */
+ ASSERT(Object);
+
+ /* perform work */
+ Object->lpVtbl->ProcessingObjectWork(Object);
+}
+
NTSTATUS
NTAPI
KspCreateFilter(
@@ -1377,17 +1585,27 @@ KspCreateFilter(
/* get the filter factory */
Factory = iface->lpVtbl->GetStruct(iface);
- if (!Factory || !Factory->FilterDescriptor || !Factory->FilterDescriptor->Dispatch || !Factory->FilterDescriptor->Dispatch->Create)
+ if (!Factory || !Factory->FilterDescriptor)
{
/* Sorry it just will not work */
return STATUS_UNSUCCESSFUL;
}
+ if (Factory->FilterDescriptor->Flags & KSFILTER_FLAG_DENY_USERMODE_ACCESS)
+ {
+ if (Irp->RequestorMode == UserMode)
+ {
+ /* filter not accessible from user mode */
+ DPRINT1("Access denied\n");
+ return STATUS_UNSUCCESSFUL;
+ }
+ }
+
/* allocate filter instance */
This = AllocateItem(NonPagedPool, sizeof(IKsFilterImpl));
if (!This)
{
- DPRINT("KspCreateFilter OutOfMemory\n");
+ DPRINT1("KspCreateFilter OutOfMemory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
@@ -1397,7 +1615,7 @@ KspCreateFilter(
{
/* no memory */
FreeItem(This);
- DPRINT("KspCreateFilter OutOfMemory\n");
+ DPRINT1("KspCreateFilter OutOfMemory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
KsDevice = (IKsDevice*)&DeviceExtension->DeviceHeader->BasicHeader.OuterUnknown;
@@ -1424,12 +1642,10 @@ KspCreateFilter(
/* no memory */
FreeItem(This->Filter.Bag);
FreeItem(This);
- DPRINT("KspCreateFilter OutOfMemory\n");
+ DPRINT1("KspCreateFilter OutOfMemory\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
- DPRINT("KspCreateFilter Flags %lx\n", Factory->FilterDescriptor->Flags);
-
/* initialize pin create item */
CreateItem[0].Create = IKsFilter_DispatchCreatePin;
CreateItem[0].Context = (PVOID)This;
@@ -1446,11 +1662,13 @@ KspCreateFilter(
This->ref = 1;
This->Header.OuterUnknown = (PUNKNOWN)&vt_IKsFilter;
This->lpVtblKsControl = &vt_IKsControl;
+ This->lpVtblKsProcessingObject = &vt_IKsProcessingObject;
This->Factory = Factory;
This->FilterFactory = iface;
This->FileObject = IoStack->FileObject;
KeInitializeMutex(&This->ProcessingMutex, 0);
+
/* initialize basic header */
This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
This->Header.Parent.KsFilterFactory = iface->lpVtbl->GetStruct(iface);
@@ -1460,17 +1678,39 @@ KspCreateFilter(
InitializeListHead(&This->Header.EventList);
KeInitializeSpinLock(&This->Header.EventListLock);
+ /* initialize and gate */
+ KsGateInitializeAnd(&This->Gate, NULL);
+
+ /* FIXME initialize and gate based on pin flags */
+
+ /* initialize work item */
+ ExInitializeWorkItem(&This->WorkItem, IKsFilter_FilterCentricWorker, (PVOID)This->lpVtblKsProcessingObject);
+
+ /* allocate counted work item */
+ Status = KsRegisterCountedWorker(HyperCriticalWorkQueue, &This->WorkItem, &This->Worker);
+ if (!NT_SUCCESS(Status))
+ {
+ /* what can go wrong, goes wrong */
+ DPRINT1("KsRegisterCountedWorker failed with %lx\n", Status);
+ FreeItem(This);
+ FreeItem(CreateItem);
+ return Status;
+ }
+
/* allocate the stream descriptors */
Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor);
if (!NT_SUCCESS(Status))
{
/* what can go wrong, goes wrong */
+ DPRINT1("IKsFilter_CreateDescriptors failed with %lx\n", Status);
+ KsUnregisterWorker(This->Worker);
FreeItem(This);
FreeItem(CreateItem);
- DPRINT("IKsFilter_CreateDescriptors failed with %lx\n", Status);
return Status;
}
+
+
/* does the filter have a filter dispatch */
if (Factory->FilterDescriptor->Dispatch)
{
@@ -1489,6 +1729,7 @@ KspCreateFilter(
DPRINT1("Driver: Status %x\n", Status);
/* free filter instance */
+ KsUnregisterWorker(This->Worker);
FreeItem(This);
FreeItem(CreateItem);
return Status;
@@ -1515,7 +1756,7 @@ KspCreateFilter(
IKsFilter_AttachFilterToFilterFactory(This, This->Header.Parent.KsFilterFactory);
/* completed initialization */
- DPRINT("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
+ DPRINT1("KspCreateFilter done %lx KsDevice %p\n", Status, This->Header.KsDevice);
return Status;
}
@@ -1599,7 +1840,7 @@ KsFilterAddTopologyConnections (
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI
VOID
@@ -1608,7 +1849,20 @@ KsFilterAttemptProcessing(
IN PKSFILTER Filter,
IN BOOLEAN Asynchronous)
{
- UNIMPLEMENTED
+ PKSGATE Gate;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+ /* get gate */
+ Gate = This->lpVtblKsProcessingObject->GetAndGate((IKsProcessingObject*)This->lpVtblKsProcessingObject);
+
+ if (!KsGateCaptureThreshold(Gate))
+ {
+ /* filter control gate is closed */
+ return;
+ }
+DPRINT1("processing\n");
+ /* try initiate processing */
+ This->lpVtblKsProcessingObject->Process((IKsProcessingObject*)This->lpVtblKsProcessingObject, Asynchronous);
}
/*
@@ -1710,8 +1964,10 @@ NTAPI
KsFilterGetAndGate(
IN PKSFILTER Filter)
{
- UNIMPLEMENTED
- return NULL;
+ IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, Filter);
+
+ /* return and-gate */
+ return &This->Gate;
}
/*
diff --git a/reactos/drivers/ksfilter/ks/filterfactory.c b/reactos/drivers/ksfilter/ks/filterfactory.c
index e60bfc41e81..51c9a65d273 100644
--- a/reactos/drivers/ksfilter/ks/filterfactory.c
+++ b/reactos/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/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c
index fb36d6df78a..2fa100af098 100644
--- a/reactos/drivers/ksfilter/ks/irp.c
+++ b/reactos/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/reactos/drivers/ksfilter/ks/ks.rbuild b/reactos/drivers/ksfilter/ks/ks.rbuild
index 57ded213d3b..ffa517843bf 100644
--- a/reactos/drivers/ksfilter/ks/ks.rbuild
+++ b/reactos/drivers/ksfilter/ks/ks.rbuild
@@ -32,4 +32,5 @@
unknown.c
worker.c
kcom.c
+ swenum.c
diff --git a/reactos/drivers/ksfilter/ks/ksfunc.h b/reactos/drivers/ksfilter/ks/ksfunc.h
index 6a4d85df867..1c51a8c1c80 100644
--- a/reactos/drivers/ksfilter/ks/ksfunc.h
+++ b/reactos/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/reactos/drivers/ksfilter/ks/ksiface.h b/reactos/drivers/ksfilter/ks/ksiface.h
index ad95fc9a922..f5e388887ba 100644
--- a/reactos/drivers/ksfilter/ks/ksiface.h
+++ b/reactos/drivers/ksfilter/ks/ksiface.h
@@ -307,3 +307,34 @@ DECLARE_INTERFACE_(IKsDevice, IUnknown)
STDMETHOD_(NTSTATUS, CheckIoCapability)(THIS_
IN ULONG Unknown)PURE;
};
+
+#undef INTERFACE
+
+
+/*****************************************************************************
+ * IKsProcessingObject
+ *****************************************************************************
+ */
+
+#undef INTERFACE
+#define INTERFACE IKsProcessingObject
+
+DECLARE_INTERFACE_(IKsProcessingObject, IUnknown)
+{
+ DEFINE_ABSTRACT_UNKNOWN()
+
+ STDMETHOD_(VOID, ProcessingObjectWork)(THIS) PURE;
+
+ STDMETHOD_(PKSGATE, GetAndGate)(THIS) PURE;
+
+ STDMETHOD_(VOID, Process)(THIS_
+ IN BOOLEAN Asynchronous)PURE;
+
+ STDMETHOD_(VOID, Reset)(THIS) PURE;
+
+ STDMETHOD_(VOID, TriggerNotification)(THIS) PURE;
+
+};
+
+#undef INTERFACE
+
diff --git a/reactos/drivers/ksfilter/ks/kstypes.h b/reactos/drivers/ksfilter/ks/kstypes.h
index 0e64312e095..0be5956264c 100644
--- a/reactos/drivers/ksfilter/ks/kstypes.h
+++ b/reactos/drivers/ksfilter/ks/kstypes.h
@@ -134,12 +134,6 @@ typedef struct
PIO_WORKITEM WorkItem;
}PNP_POSTSTART_CONTEXT, *PPNP_POSTSTART_CONTEXT;
-typedef struct
-{
- PIRP Irp;
- KEVENT Event;
-}KSREMOVE_BUS_INTERFACE_CTX, *PKSREMOVE_BUS_INTERFACE_CTX;
-
typedef struct
{
PLIST_ENTRY List;
@@ -150,20 +144,97 @@ typedef struct
typedef BOOLEAN (NTAPI *PKSEVENT_SYNCHRONIZED_ROUTINE)(PKSEVENT_CTX Context);
+struct __BUS_ENUM_DEVICE_EXTENSION__;
+struct __BUS_DEVICE_ENTRY__;
+
typedef struct
{
- BOOLEAN Enabled;
+ LIST_ENTRY Entry;
+ ULONG IsBus;
+ union
+ {
+ PDEVICE_OBJECT DeviceObject;
+ ULONG DeviceReferenceCount;
+ };
+ union
+ {
+ struct __BUS_DEVICE_ENTRY__* DeviceEntry;
+ ULONG Dummy1;
+ };
+ struct __BUS_ENUM_DEVICE_EXTENSION__ *BusDeviceExtension;
+ ULONG DeviceObjectReferenceCount;
+}COMMON_DEVICE_EXTENSION, *PCOMMON_DEVICE_EXTENSION;
- PDEVICE_OBJECT PnpDeviceObject;
+typedef struct
+{
+ PCOMMON_DEVICE_EXTENSION Ext;
+}DEV_EXTENSION, *PDEV_EXTENSION;
+
+typedef struct
+{
+ LIST_ENTRY Entry;
+ GUID InterfaceGuid;
+ UNICODE_STRING SymbolicLink;
+}BUS_INSTANCE_ENTRY, *PBUS_INSTANCE_ENTRY;
+
+
+
+typedef enum
+{
+ NotStarted = 0, // Not started yet
+ Started, // Device has received the START_DEVICE IRP
+ StopPending, // Device has received the QUERY_STOP IRP
+ Stopped, // Device has received the STOP_DEVICE IRP
+ RemovePending, // Device has received the QUERY_REMOVE IRP
+ SurpriseRemovePending, // Device has received the SURPRISE_REMOVE IRP
+ Deleted
+}DEVICE_STATE;
+
+
+typedef struct __BUS_DEVICE_ENTRY__
+{
+ LIST_ENTRY Entry;
+ LIST_ENTRY DeviceInterfaceList;
+ LIST_ENTRY IrpPendingList;
+ PDEVICE_OBJECT PDO;
+ DEVICE_STATE DeviceState;
+ GUID DeviceGuid;
+ LPWSTR PDODeviceName;
+ LPWSTR DeviceName;
+ LPWSTR BusId;
+ LARGE_INTEGER TimeCreated;
+ LARGE_INTEGER TimeExpired;
+ LPWSTR Instance;
+}BUS_DEVICE_ENTRY, *PBUS_DEVICE_ENTRY;
+
+typedef struct __BUS_ENUM_DEVICE_EXTENSION__
+{
+ COMMON_DEVICE_EXTENSION Common;
+ KSPIN_LOCK Lock;
+ KEVENT Event;
+ UNICODE_STRING DeviceInterfaceLink;
PDEVICE_OBJECT PhysicalDeviceObject;
+ PDEVICE_OBJECT PnpDeviceObject;
PDEVICE_OBJECT BusDeviceObject;
-
+ ULONG PdoCreated;
+ KTIMER Timer;
+ KDPC Dpc;
+ WORK_QUEUE_ITEM WorkItem;
+ ULONG DeviceAttached;
UNICODE_STRING ServicePath;
- UNICODE_STRING SymbolicLinkName;
WCHAR BusIdentifier[1];
}BUS_ENUM_DEVICE_EXTENSION, *PBUS_ENUM_DEVICE_EXTENSION;
+typedef struct
+{
+ PIRP Irp;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+ KEVENT Event;
+ NTSTATUS Status;
+ WORK_QUEUE_ITEM WorkItem;
+}BUS_INSTALL_ENUM_CONTEXT, *PBUS_INSTALL_ENUM_CONTEXT;
+
typedef struct
{
PUCHAR FilterData;
diff --git a/reactos/drivers/ksfilter/ks/misc.c b/reactos/drivers/ksfilter/ks/misc.c
index 057103d3414..9ba4b2611b5 100644
--- a/reactos/drivers/ksfilter/ks/misc.c
+++ b/reactos/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/reactos/drivers/ksfilter/ks/pin.c b/reactos/drivers/ksfilter/ks/pin.c
index a6caeb30de0..883f098b43d 100644
--- a/reactos/drivers/ksfilter/ks/pin.c
+++ b/reactos/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/reactos/drivers/ksfilter/ks/priv.h b/reactos/drivers/ksfilter/ks/priv.h
index 75b514158cc..8eb1959c288 100644
--- a/reactos/drivers/ksfilter/ks/priv.h
+++ b/reactos/drivers/ksfilter/ks/priv.h
@@ -19,6 +19,8 @@
#include "ksmedia.h"
#include "bdamedia.h"
+#include
+
#define TAG_DEVICE_HEADER 'KSDH'
#define REG_PINFLAG_B_MANY 0x4 /* strmif.h */
diff --git a/reactos/drivers/ksfilter/ks/swenum.c b/reactos/drivers/ksfilter/ks/swenum.c
new file mode 100644
index 00000000000..08d5286bd58
--- /dev/null
+++ b/reactos/drivers/ksfilter/ks/swenum.c
@@ -0,0 +1,2174 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/ksfilter/ks/swenum.c
+ * PURPOSE: KS Software BUS functions
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+
+#include "priv.h"
+
+LONG KsDeviceCount = 0;
+
+typedef NTSTATUS (NTAPI *PKSP_BUS_ENUM_CALLBACK)(
+ IN PHANDLE hKey,
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PBUS_DEVICE_ENTRY DummyEntry,
+ IN LPWSTR RootName,
+ IN LPWSTR DirectoryName);
+
+NTSTATUS
+KspCreatePDO(
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PBUS_DEVICE_ENTRY DeviceEntry,
+ OUT PDEVICE_OBJECT * OutDeviceObject)
+{
+ PDEVICE_OBJECT DeviceObject;
+ WCHAR Buffer[50];
+ ULONG CurDeviceId;
+ UNICODE_STRING DeviceName;
+ NTSTATUS Status;
+ PCOMMON_DEVICE_EXTENSION DeviceExtension;
+
+ /* increment device count */
+ CurDeviceId = InterlockedIncrement(&KsDeviceCount);
+
+ /* generate new device id */
+ swprintf(Buffer, L"\\Device\\KSENUM%08x", CurDeviceId);
+
+ /* initialize new device name */
+ RtlInitUnicodeString(&DeviceName, Buffer);
+
+ /* create new device object */
+ Status = IoCreateDevice(BusDeviceExtension->BusDeviceObject->DriverObject, sizeof(PVOID), &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to create pdo */
+ return Status;
+ }
+
+ /* now allocate device extension */
+ DeviceExtension = (PCOMMON_DEVICE_EXTENSION)AllocateItem(NonPagedPool, sizeof(COMMON_DEVICE_EXTENSION));
+ if (!DeviceExtension)
+ {
+ /* no memory */
+ IoDeleteDevice(DeviceObject);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* store device extension */
+ *((PVOID*)DeviceObject->DeviceExtension) = DeviceExtension;
+
+ /* initialize device extension */
+ DeviceExtension->IsBus = FALSE;
+ DeviceExtension->DeviceObject = DeviceObject;
+ DeviceExtension->DeviceEntry = DeviceEntry;
+ DeviceExtension->BusDeviceExtension = BusDeviceExtension;
+
+ /* TODO: update last creation time in bus device extension */
+
+ /* setup flags */
+ DeviceObject->Flags |= DO_POWER_PAGABLE;
+ DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
+ /* TODO: fire time when expired */
+
+ *OutDeviceObject = DeviceObject;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+KspRegisterDeviceAssociation(
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PBUS_DEVICE_ENTRY DeviceEntry,
+ IN OUT PBUS_INSTANCE_ENTRY BusInstanceEntry)
+{
+ NTSTATUS Status;
+ UNICODE_STRING ReferenceString;
+
+ /* initialize reference string */
+ RtlInitUnicodeString(&ReferenceString, DeviceEntry->DeviceName);
+
+ /* register device interface */
+ Status = IoRegisterDeviceInterface(BusDeviceExtension->PhysicalDeviceObject, &BusInstanceEntry->InterfaceGuid, &ReferenceString, &BusInstanceEntry->SymbolicLink);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ return Status;
+ }
+
+ /* now enable the interface */
+ Status = IoSetDeviceInterfaceState(&BusInstanceEntry->SymbolicLink, TRUE);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed, free memory */
+ FreeItem(BusInstanceEntry->SymbolicLink.Buffer);
+ return Status;
+ }
+
+ DPRINT1("Registered DeviceInterface %wZ\n", &BusInstanceEntry->SymbolicLink);
+
+
+ /* done */
+ return Status;
+}
+
+VOID
+KspRemoveDeviceAssociations(
+ IN PBUS_DEVICE_ENTRY DeviceEntry)
+{
+ PLIST_ENTRY Entry;
+ PBUS_INSTANCE_ENTRY CurEntry;
+
+ /* remove all entries */
+ Entry = DeviceEntry->DeviceInterfaceList.Flink;
+
+ while(Entry != &DeviceEntry->DeviceInterfaceList)
+ {
+ /* get offset */
+ CurEntry = (PBUS_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BUS_INSTANCE_ENTRY, Entry);
+
+ /* sanity check */
+ ASSERT(CurEntry->SymbolicLink.Buffer);
+
+ /* de-register interface */
+ IoSetDeviceInterfaceState(&CurEntry->SymbolicLink, FALSE);
+
+ /* free symbolic link buffer */
+ FreeItem(CurEntry->SymbolicLink.Buffer);
+
+ /* remove entry from list */
+ RemoveEntryList(Entry);
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+
+ /* free entry */
+ FreeItem(CurEntry);
+ }
+}
+
+NTSTATUS
+KspEnumerateBusRegistryKeys(
+ IN HANDLE hKey,
+ IN LPWSTR ReferenceString,
+ IN PKSP_BUS_ENUM_CALLBACK Callback,
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PBUS_DEVICE_ENTRY DeviceEntry)
+{
+ UNICODE_STRING String;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hNewKey;
+ NTSTATUS Status;
+ ULONG ResultLength, Index, KeyInfoLength;
+ KEY_FULL_INFORMATION KeyInformation;
+ PKEY_BASIC_INFORMATION KeyInfo;
+
+ /* initialize key name */
+ RtlInitUnicodeString(&String, ReferenceString);
+
+ /* initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &String, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hKey, NULL);
+
+ /* open new key */
+ Status = ZwOpenKey(&hNewKey, GENERIC_READ, &ObjectAttributes);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to open key */
+
+ return Status;
+ }
+
+ /* query key stats */
+ Status = ZwQueryKey(hNewKey, KeyFullInformation, &KeyInformation, sizeof(KeyInformation), &ResultLength);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* close key */
+ ZwClose(hNewKey);
+
+ /* done */
+ return Status;
+ }
+
+ /* calculate key info length */
+ KeyInfoLength = KeyInformation.MaxNameLen + sizeof(KEY_BASIC_INFORMATION) + 1 * sizeof(WCHAR);
+
+ /* allocate buffer */
+ KeyInfo = (PKEY_BASIC_INFORMATION)AllocateItem(NonPagedPool, KeyInfoLength);
+ if (!KeyInfo)
+ {
+
+ /* no memory */
+ ZwClose(hNewKey);
+
+ /* done */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* enumerate all keys */
+ for(Index = 0; Index < KeyInformation.SubKeys; Index++)
+ {
+
+ /* query sub key */
+ Status = ZwEnumerateKey(hNewKey, Index, KeyBasicInformation, (PVOID)KeyInfo, KeyInfoLength, &ResultLength);
+
+ /* check for success */
+ if (NT_SUCCESS(Status))
+ {
+ /* perform callback */
+ Status = Callback(hNewKey, BusDeviceExtension, DeviceEntry, ReferenceString, KeyInfo->Name);
+
+ /* should enumeration stop */
+ if (!NT_SUCCESS(Status))
+ break;
+ }
+ }
+
+ /* free info buffer */
+ FreeItem(KeyInfo);
+
+ /* close key */
+ ZwClose(hNewKey);
+
+ /* done */
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+KspCreateDeviceAssociation(
+ IN PHANDLE hKey,
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PBUS_DEVICE_ENTRY DeviceEntry,
+ IN LPWSTR ReferenceString,
+ IN LPWSTR InterfaceString)
+{
+ GUID DeviceGuid;
+ NTSTATUS Status;
+ PLIST_ENTRY Entry;
+ PBUS_INSTANCE_ENTRY CurEntry;
+ UNICODE_STRING DeviceName;
+
+ /* initialize interface string */
+ RtlInitUnicodeString(&DeviceName, InterfaceString);
+
+ /* first convert device name to guid */
+ RtlGUIDFromString(&DeviceName, &DeviceGuid);
+
+ /* check if the device is already present */
+ Entry = DeviceEntry->DeviceInterfaceList.Flink;
+
+ while(Entry != &DeviceEntry->DeviceInterfaceList)
+ {
+ /* get offset */
+ CurEntry = (PBUS_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, BUS_INSTANCE_ENTRY, Entry);
+
+ if (IsEqualGUIDAligned(&CurEntry->InterfaceGuid, &DeviceGuid))
+ {
+ /* entry already exists */
+ return STATUS_SUCCESS;
+ }
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+ }
+
+ /* time to allocate new entry */
+ CurEntry = (PBUS_INSTANCE_ENTRY)AllocateItem(NonPagedPool, sizeof(BUS_INSTANCE_ENTRY));
+
+ if (!CurEntry)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* store guid */
+ RtlMoveMemory(&CurEntry->InterfaceGuid, &DeviceGuid, sizeof(GUID));
+
+ /* now register the association */
+ Status = KspRegisterDeviceAssociation(BusDeviceExtension, DeviceEntry, CurEntry);
+
+ /* check for success */
+ if (NT_SUCCESS(Status))
+ {
+ /* store entry */
+ InsertTailList(&DeviceEntry->DeviceInterfaceList, &CurEntry->Entry);
+ }
+ else
+ {
+ /* failed to associated device */
+ FreeItem(CurEntry);
+ }
+
+ /* done */
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+KspCreateDeviceReference(
+ IN PHANDLE hKey,
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PBUS_DEVICE_ENTRY DummyEntry,
+ IN LPWSTR DeviceCategory,
+ IN LPWSTR ReferenceString)
+{
+ LPWSTR DeviceName;
+ ULONG Length;
+ PLIST_ENTRY Entry;
+ PBUS_DEVICE_ENTRY DeviceEntry = NULL; /* GCC warning */
+ BOOLEAN ItemExists = FALSE;
+ UNICODE_STRING String;
+ NTSTATUS Status;
+ KIRQL OldLevel;
+
+ /* first construct device name & reference guid */
+ Length = wcslen(DeviceCategory) + wcslen(ReferenceString);
+
+ /* append '&' and null byte */
+ Length += 2;
+
+ /* allocate device name */
+ DeviceName = AllocateItem(NonPagedPool, Length * sizeof(WCHAR));
+
+ if (!DeviceName)
+ {
+ /* not enough memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* construct device name */
+ swprintf(DeviceName, L"%s&%s", DeviceCategory, ReferenceString);
+
+ /* scan list and check if it is already present */
+ Entry = BusDeviceExtension->Common.Entry.Flink;
+
+ while(Entry != &BusDeviceExtension->Common.Entry)
+ {
+ /* get real offset */
+ DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
+
+ /* check if name matches */
+ if (!wcsicmp(DeviceEntry->DeviceName, DeviceName))
+ {
+ /* item already exists */
+ ItemExists = TRUE;
+ break;
+ }
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+ }
+
+ if (!ItemExists)
+ {
+ /* allocate new device entry */
+ DeviceEntry = AllocateItem(NonPagedPool, sizeof(BUS_DEVICE_ENTRY));
+ if (!DeviceEntry)
+ {
+ /* no memory */
+ FreeItem(DeviceName);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* initialize device entry */
+ InitializeListHead(&DeviceEntry->DeviceInterfaceList);
+ InitializeListHead(&DeviceEntry->IrpPendingList);
+
+ /* copy device guid */
+ RtlInitUnicodeString(&String, ReferenceString);
+ RtlGUIDFromString(&String, &DeviceEntry->DeviceGuid);
+
+ /* copy device names */
+ DeviceEntry->DeviceName = DeviceName;
+ DeviceEntry->Instance = (DeviceName + wcslen(DeviceCategory) + 1);
+
+ /* copy name */
+ DeviceEntry->BusId = AllocateItem(NonPagedPool, (wcslen(DeviceCategory) + 1) * sizeof(WCHAR));
+ if (!DeviceEntry->BusId)
+ {
+ /* no memory */
+ FreeItem(DeviceName);
+ FreeItem(DeviceEntry);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ wcscpy(DeviceEntry->BusId, DeviceCategory);
+ }
+
+ /* now enumerate the devices */
+ Status = KspEnumerateBusRegistryKeys(hKey, ReferenceString, KspCreateDeviceAssociation, BusDeviceExtension, DeviceEntry);
+
+ /* check if list is empty */
+ if (IsListEmpty(&DeviceEntry->DeviceInterfaceList))
+ {
+ /* invalid device settings */
+ FreeItem(DeviceEntry->BusId);
+ FreeItem(DeviceEntry->DeviceName);
+ FreeItem(DeviceEntry);
+
+ ASSERT(ItemExists == FALSE);
+
+ return STATUS_INVALID_DEVICE_STATE;
+ }
+
+ /* check if enumeration failed */
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed */
+ KspRemoveDeviceAssociations(DeviceEntry);
+ FreeItem(DeviceEntry->BusId);
+ FreeItem(DeviceEntry->DeviceName);
+ FreeItem(DeviceEntry);
+
+ ASSERT(ItemExists == FALSE);
+
+ /* done */
+ return Status;
+ }
+
+ 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;
+}
+
+NTSTATUS
+NTAPI
+KspCreateDeviceReferenceTrampoline(
+ IN PHANDLE hKey,
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PBUS_DEVICE_ENTRY DummyEntry,
+ IN LPWSTR DeviceCategory,
+ IN LPWSTR ReferenceString)
+{
+ return KspEnumerateBusRegistryKeys(hKey, ReferenceString, KspCreateDeviceReference, BusDeviceExtension, DummyEntry);
+}
+
+
+NTSTATUS
+KspOpenBusRegistryKey(
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ OUT PHANDLE hKey)
+{
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
+ /* initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &BusDeviceExtension->ServicePath, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ return ZwCreateKey(hKey, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
+}
+
+NTSTATUS
+KspScanBus(
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension)
+{
+ HANDLE hKey;
+ NTSTATUS Status;
+
+ /* first open key */
+ Status = KspOpenBusRegistryKey(BusDeviceExtension, &hKey);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* no success */
+
+ return Status;
+ }
+
+ /* TODO clear reference marks */
+
+ /* construct device entries */
+ Status = KspEnumerateBusRegistryKeys(hKey, NULL, KspCreateDeviceReferenceTrampoline, BusDeviceExtension, NULL);
+
+ /* TODO: delete unreferenced devices */
+
+ /* close handle */
+ ZwClose(hKey);
+
+ /* done */
+ return Status;
+}
+
+
+NTSTATUS
+NTAPI
+KspBusQueryReferenceString(
+ IN PVOID Context,
+ IN OUT PWCHAR *String)
+{
+ LPWSTR Name;
+ ULONG Length;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)Context;
+
+ /* sanity checks */
+ ASSERT(BusDeviceExtension);
+ ASSERT(BusDeviceExtension->BusIdentifier);
+
+ /* calculate length */
+ Length = wcslen(BusDeviceExtension->BusIdentifier) + 1;
+
+ /* allocate buffer */
+ Name = AllocateItem(PagedPool, Length * sizeof(WCHAR));
+
+ if (!Name)
+ {
+ /* failed to allocate buffer */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* copy buffer */
+ wcscpy(Name, BusDeviceExtension->BusIdentifier);
+
+ /* store result */
+ *String = Name;
+
+ /* done */
+ return STATUS_SUCCESS;
+}
+
+VOID
+NTAPI
+KspBusDeviceReference(
+ IN PVOID Context)
+{
+ PCOMMON_DEVICE_EXTENSION ChildDeviceExtension = (PCOMMON_DEVICE_EXTENSION)Context;
+
+ /* reference count */
+ InterlockedIncrement((PLONG)&ChildDeviceExtension->DeviceReferenceCount);
+}
+
+VOID
+NTAPI
+KspBusDeviceDereference(
+ IN PVOID Context)
+{
+ PCOMMON_DEVICE_EXTENSION ChildDeviceExtension = (PCOMMON_DEVICE_EXTENSION)Context;
+
+ /* reference count */
+ InterlockedDecrement((PLONG)&ChildDeviceExtension->DeviceReferenceCount);
+}
+
+VOID
+NTAPI
+KspBusReferenceDeviceObject(
+ IN PVOID Context)
+{
+ PCOMMON_DEVICE_EXTENSION ChildDeviceExtension = (PCOMMON_DEVICE_EXTENSION)Context;
+
+ /* reference count */
+ InterlockedIncrement((PLONG)&ChildDeviceExtension->DeviceObjectReferenceCount);
+}
+
+VOID
+NTAPI
+KspBusDereferenceDeviceObject(
+ IN PVOID Context)
+{
+ PCOMMON_DEVICE_EXTENSION ChildDeviceExtension = (PCOMMON_DEVICE_EXTENSION)Context;
+
+ /* reference count */
+ InterlockedDecrement((PLONG)&ChildDeviceExtension->DeviceObjectReferenceCount);
+}
+
+NTSTATUS
+KspQueryBusDeviceInterface(
+ IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
+ IN PIRP Irp)
+{
+ PBUS_INTERFACE_SWENUM Interface;
+ PIO_STACK_LOCATION IoStack;
+
+ /* get current irp stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* sanity checks */
+ ASSERT(IoStack->Parameters.QueryInterface.Size == sizeof(BUS_INTERFACE_SWENUM));
+ ASSERT(IoStack->Parameters.QueryInterface.Interface);
+
+ /* fill in interface */
+ Interface = (PBUS_INTERFACE_SWENUM)IoStack->Parameters.QueryInterface.Interface;
+ Interface->Interface.Size = sizeof(BUS_INTERFACE_SWENUM);
+ Interface->Interface.Version = BUS_INTERFACE_SWENUM_VERSION;
+ Interface->Interface.Context = ChildDeviceExtension;
+ Interface->Interface.InterfaceReference = KspBusDeviceReference;
+ Interface->Interface.InterfaceDereference = KspBusDeviceDereference;
+ Interface->ReferenceDeviceObject = KspBusReferenceDeviceObject;
+ Interface->DereferenceDeviceObject = KspBusDereferenceDeviceObject;
+ Interface->QueryReferenceString = KspBusQueryReferenceString;
+
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+KspEnableBusDeviceInterface(
+ PBUS_DEVICE_ENTRY DeviceEntry,
+ BOOLEAN bEnable)
+{
+ PLIST_ENTRY Entry;
+ PBUS_INSTANCE_ENTRY InstanceEntry;
+ NTSTATUS Status = STATUS_SUCCESS;
+
+ /* enable now all interfaces */
+ Entry = DeviceEntry->DeviceInterfaceList.Flink;
+
+ while(Entry != &DeviceEntry->DeviceInterfaceList)
+ {
+ /* 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);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to set interface */
+ break;
+ }
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+ }
+
+ /* done */
+ return Status;
+}
+
+NTSTATUS
+KspDoReparseForIrp(
+ PIRP Irp,
+ PBUS_DEVICE_ENTRY DeviceEntry)
+{
+ ULONG Length;
+ LPWSTR Buffer;
+ PIO_STACK_LOCATION IoStack;
+
+ /* get stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* sanity checks */
+ ASSERT(DeviceEntry->PDODeviceName);
+ ASSERT(DeviceEntry->Instance);
+ ASSERT(IoStack->FileObject);
+ ASSERT(IoStack->FileObject->FileName.Buffer);
+
+ /* calculate length */
+ Length = wcslen(DeviceEntry->PDODeviceName);
+ Length += wcslen(DeviceEntry->Instance);
+
+ /* zero byte and '\\' */
+ Length += 2;
+
+ /* allocate buffer */
+ Buffer = AllocateItem(NonPagedPool, Length * sizeof(WCHAR));
+ if (!Buffer)
+ {
+ /* no resources */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* construct buffer */
+ swprintf(Buffer, L"%s\\%s", DeviceEntry->PDODeviceName, DeviceEntry->Instance);
+
+ ExFreePool(IoStack->FileObject->FileName.Buffer);
+
+ /* store new file name */
+ RtlInitUnicodeString(&IoStack->FileObject->FileName, Buffer);
+
+ /* done */
+ return STATUS_REPARSE;
+}
+
+VOID
+KspCompletePendingIrps(
+ IN PBUS_DEVICE_ENTRY DeviceEntry,
+ IN OUT NTSTATUS ResultCode)
+{
+ PLIST_ENTRY Entry;
+ PIRP Irp;
+ NTSTATUS Status;
+
+ /* go through list */
+ while(!IsListEmpty(&DeviceEntry->IrpPendingList))
+ {
+ /* get first entry */
+ Entry = RemoveHeadList(&DeviceEntry->IrpPendingList);
+
+ /* get irp */
+ Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
+
+ if (ResultCode == STATUS_REPARSE)
+ {
+ /* construct reparse information */
+ Status = KspDoReparseForIrp(Irp, DeviceEntry);
+ }
+ else
+ {
+ /* use default code */
+ Status = ResultCode;
+ }
+
+ /* store result code */
+ Irp->IoStatus.Status = Status;
+
+ DPRINT1("Completing IRP %p Status %x\n", Irp, Status);
+
+ /* complete the request */
+ CompleteRequest(Irp, IO_NO_INCREMENT);
+ }
+
+}
+
+
+
+NTSTATUS
+KspStartBusDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
+ IN PIRP Irp)
+{
+ WCHAR PDOName[256];
+ NTSTATUS Status;
+ ULONG ResultLength;
+ LPWSTR Name;
+ PBUS_DEVICE_ENTRY DeviceEntry;
+
+ /* FIXME handle pending remove */
+
+ /* get full device name */
+ Status = IoGetDeviceProperty(DeviceObject, DevicePropertyPhysicalDeviceObjectName, sizeof(PDOName), (PVOID)PDOName, &ResultLength);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to get device name */
+ return Status;
+ }
+
+ /* allocate device name buffer */
+ Name = AllocateItem(NonPagedPool, (ResultLength + 1) * sizeof(WCHAR));
+ if (!Name)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* copy name */
+ wcscpy(Name, PDOName);
+
+ /* TODO: time stamp creation time */
+
+ /* get device entry */
+ DeviceEntry = (PBUS_DEVICE_ENTRY)ChildDeviceExtension->DeviceEntry;
+
+ /* sanity check */
+ ASSERT(DeviceEntry);
+
+ /* store device name */
+ DeviceEntry->PDODeviceName = Name;
+
+ /* mark device as started */
+ DeviceEntry->DeviceState = Started;
+
+ /* reference start time */
+ KeQuerySystemTime(&DeviceEntry->TimeCreated);
+
+ 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;
+}
+
+NTSTATUS
+KspQueryBusDeviceCapabilities(
+ IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
+ IN PIRP Irp)
+{
+ PDEVICE_CAPABILITIES Capabilities;
+ PIO_STACK_LOCATION IoStack;
+
+ /* get stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* get capabilities */
+ Capabilities = IoStack->Parameters.DeviceCapabilities.Capabilities;
+
+ RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
+
+ /* setup capabilities */
+ Capabilities->UniqueID = TRUE;
+ Capabilities->SilentInstall = TRUE;
+ Capabilities->SurpriseRemovalOK = TRUE;
+ Capabilities->Address = 0;
+ Capabilities->UINumber = 0;
+ Capabilities->SystemWake = PowerSystemWorking; /* FIXME common device extension */
+ Capabilities->DeviceWake = PowerDeviceD0;
+
+ /* done */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+KspQueryBusInformation(
+ IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
+ IN PIRP Irp)
+{
+ PPNP_BUS_INFORMATION BusInformation;
+
+ /* allocate bus information */
+ BusInformation = (PPNP_BUS_INFORMATION)AllocateItem(PagedPool, sizeof(PNP_BUS_INFORMATION));
+
+ if (!BusInformation)
+ {
+ /* no memory */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* return info */
+ BusInformation->BusNumber = 0;
+ BusInformation->LegacyBusType = InterfaceTypeUndefined;
+ RtlMoveMemory(&BusInformation->BusTypeGuid, &KSMEDIUMSETID_Standard, sizeof(GUID));
+
+ /* store result */
+ Irp->IoStatus.Information = (ULONG_PTR)BusInformation;
+
+ /* done */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+KspQueryBusDevicePnpState(
+ IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
+ IN PIRP Irp)
+{
+ /* set device flags */
+ Irp->IoStatus.Information = PNP_DEVICE_DONT_DISPLAY_IN_UI | PNP_DEVICE_NOT_DISABLEABLE;
+
+ /* done */
+ return STATUS_SUCCESS;
+}
+
+NTSTATUS
+KspQueryId(
+ IN PCOMMON_DEVICE_EXTENSION ChildDeviceExtension,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ PBUS_DEVICE_ENTRY DeviceEntry;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+ LPWSTR Name;
+ ULONG Length;
+
+ /* get current irp stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ if (IoStack->Parameters.QueryId.IdType == BusQueryInstanceID)
+ {
+ /* get device entry */
+ DeviceEntry = (PBUS_DEVICE_ENTRY) ChildDeviceExtension->DeviceEntry;
+
+ /* sanity check */
+ ASSERT(DeviceEntry);
+ ASSERT(DeviceEntry->Instance);
+
+ /* calculate length */
+ Length = wcslen(DeviceEntry->Instance) + 1;
+
+ /* allocate buffer */
+ Name = AllocateItem(PagedPool, Length * sizeof(WCHAR));
+
+ if (!Name)
+ {
+ /* failed to allocate buffer */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* copy buffer */
+ wcscpy(Name, DeviceEntry->Instance);
+
+ /* store result */
+ Irp->IoStatus.Information = (ULONG_PTR)Name;
+
+ /* done */
+ return STATUS_SUCCESS;
+ }
+ else if (IoStack->Parameters.QueryId.IdType == BusQueryDeviceID ||
+ IoStack->Parameters.QueryId.IdType == BusQueryHardwareIDs)
+ {
+ /* get device entry */
+ DeviceEntry = (PBUS_DEVICE_ENTRY) ChildDeviceExtension->DeviceEntry;
+
+ /* get bus device extension */
+ BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION) ChildDeviceExtension->BusDeviceExtension;
+
+ /* sanity check */
+ ASSERT(DeviceEntry);
+ ASSERT(DeviceEntry->BusId);
+ ASSERT(BusDeviceExtension);
+ ASSERT(BusDeviceExtension->BusIdentifier);
+
+ /* calculate length */
+ Length = wcslen(BusDeviceExtension->BusIdentifier);
+ Length += wcslen(DeviceEntry->BusId);
+
+ /* extra length for '\\' and zero byte */
+ Length += 2;
+
+ /* allocate buffer */
+ Name = ExAllocatePool(PagedPool, Length * sizeof(WCHAR));
+ if (!Name)
+ {
+ /* failed to allocate buffer */
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* construct id */
+ swprintf(Name, L"%s\\%s", BusDeviceExtension->BusIdentifier, DeviceEntry->BusId);
+
+ /* store result */
+ Irp->IoStatus.Information = (ULONG_PTR)Name;
+
+ /* done */
+ return STATUS_SUCCESS;
+ }
+ else
+ {
+ /* other ids are not supported */
+ //DPRINT1("Not Supported ID Type %x\n", IoStack->Parameters.QueryId.IdType);
+ return Irp->IoStatus.Status;
+ }
+}
+
+NTSTATUS
+KspInstallInterface(
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PSWENUM_INSTALL_INTERFACE InstallInterface)
+{
+ ULONG Length, Index;
+ UNICODE_STRING DeviceString, InterfaceString, ReferenceString;
+ HANDLE hKey, hDeviceKey, hInterfaceKey, hReferenceKey;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+
+ /* sanity check */
+ ASSERT(InstallInterface);
+
+ /* calculate length */
+ Length = wcslen(InstallInterface->ReferenceString);
+
+ /* check for invalid characters */
+ for(Index = 0; Index < Length; Index++)
+ {
+ if (InstallInterface->ReferenceString[Index] <= L' ' ||
+ InstallInterface->ReferenceString[Index] > L'~' ||
+ InstallInterface->ReferenceString[Index] == L',' ||
+ InstallInterface->ReferenceString[Index] == L'\\' ||
+ InstallInterface->ReferenceString[Index] == L'/')
+ {
+ /* invalid character */
+ return STATUS_INVALID_PARAMETER;
+ }
+ }
+
+ /* open bus key */
+ Status = KspOpenBusRegistryKey(BusDeviceExtension, &hKey);
+ if (NT_SUCCESS(Status))
+ {
+ /* convert device guid to string */
+ Status = RtlStringFromGUID(&InstallInterface->DeviceId, &DeviceString);
+ if (NT_SUCCESS(Status))
+ {
+ /* initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &DeviceString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hKey, NULL);
+
+ /* construct device key */
+ Status = ZwCreateKey(&hDeviceKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* initialize reference string */
+ RtlInitUnicodeString(&ReferenceString, InstallInterface->ReferenceString);
+
+ /* initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &ReferenceString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hDeviceKey, NULL);
+
+ /* construct device key */
+ Status = ZwCreateKey(&hReferenceKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* convert interface guid to string */
+ Status = RtlStringFromGUID(&InstallInterface->InterfaceId, &InterfaceString);
+ if (NT_SUCCESS(Status))
+ {
+ /* initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &InterfaceString, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, hReferenceKey, NULL);
+
+ /* construct device key */
+ Status = ZwCreateKey(&hInterfaceKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL);
+ if (NT_SUCCESS(Status))
+ {
+ /* close key */
+ ZwClose(hInterfaceKey);
+ }
+ /* free interface string */
+ RtlFreeUnicodeString(&InterfaceString);
+ }
+ /* close reference key */
+ ZwClose(hReferenceKey);
+ }
+ /* close device key */
+ ZwClose(hDeviceKey);
+ }
+ /* free device string */
+ RtlFreeUnicodeString(&DeviceString);
+ }
+ /* close bus key */
+ ZwClose(hKey);
+ }
+
+ /* done */
+ return Status;
+ }
+
+VOID
+NTAPI
+KspInstallBusEnumInterface(
+ IN PVOID Ctx)
+{
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
+ PLIST_ENTRY Entry;
+ PBUS_DEVICE_ENTRY DeviceEntry;
+ PSWENUM_INSTALL_INTERFACE InstallInterface;
+ KIRQL OldLevel;
+ PBUS_INSTALL_ENUM_CONTEXT Context = (PBUS_INSTALL_ENUM_CONTEXT)Ctx;
+
+ /* get current irp stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Context->Irp);
+
+ /* get install request */
+ InstallInterface = (PSWENUM_INSTALL_INTERFACE)Context->Irp->AssociatedIrp.SystemBuffer;
+
+ /* sanity check */
+ ASSERT(InstallInterface);
+ ASSERT(Context->BusDeviceExtension);
+
+ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SWENUM_INSTALL_INTERFACE))
+ {
+ /* buffer too small */
+ Context->Status = STATUS_INVALID_PARAMETER;
+
+ /* signal completion */
+ KeSetEvent(&Context->Event, 0, FALSE);
+
+ /* done */
+ return;
+ }
+
+ /* FIXME locks */
+
+ /* now install the interface */
+ Status = KspInstallInterface(Context->BusDeviceExtension, InstallInterface);
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to install interface */
+ Context->Status = Status;
+
+ /* signal completion */
+ KeSetEvent(&Context->Event, 0, FALSE);
+
+ /* done */
+ return;
+ }
+
+ /* acquire device entry lock */
+ KeAcquireSpinLock(&Context->BusDeviceExtension->Lock, &OldLevel);
+
+ /* now iterate all device entries */
+ Entry = Context->BusDeviceExtension->Common.Entry.Flink;
+ while(Entry != &Context->BusDeviceExtension->Common.Entry)
+ {
+ /* get device entry */
+ DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
+
+ if (IsEqualGUIDAligned(&DeviceEntry->DeviceGuid, &InstallInterface->DeviceId) &&
+ !wcsicmp(DeviceEntry->Instance, InstallInterface->ReferenceString))
+ {
+ if (!DeviceEntry->PDO)
+ {
+ /* create pdo */
+ Status = KspCreatePDO(Context->BusDeviceExtension, DeviceEntry, &DeviceEntry->PDO);
+
+ /* done */
+ break;
+ }
+ }
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+ }
+
+ /* release device entry lock */
+ KeReleaseSpinLock(&Context->BusDeviceExtension->Lock, OldLevel);
+
+ /* signal that bus driver relations has changed */
+ IoInvalidateDeviceRelations(Context->BusDeviceExtension->PhysicalDeviceObject, BusRelations);
+
+ /* update status */
+ Context->Status = Status;
+
+ /* signal completion */
+ KeSetEvent(&Context->Event, 0, FALSE);
+}
+
+
+VOID
+NTAPI
+KspBusWorkerRoutine(
+ IN PVOID Parameter)
+{
+ 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
+NTAPI
+KspBusDpcRoutine(
+ IN PKDPC Dpc,
+ IN PVOID DeferredContext OPTIONAL,
+ IN PVOID SystemArgument1 OPTIONAL,
+ IN PVOID SystemArgument2 OPTIONAL)
+{
+ /* get device extension */
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeferredContext;
+
+ /* queue the item */
+ ExQueueWorkItem(&BusDeviceExtension->WorkItem, DelayedWorkQueue);
+}
+
+VOID
+NTAPI
+KspRemoveBusInterface(
+ PVOID Ctx)
+{
+ PBUS_INSTALL_ENUM_CONTEXT Context =(PBUS_INSTALL_ENUM_CONTEXT)Ctx;
+
+ /* TODO
+ * get SWENUM_INSTALL_INTERFACE struct
+ * open device key and delete the keys
+ */
+
+ UNIMPLEMENTED
+
+ /* set status */
+ Context->Status = STATUS_NOT_IMPLEMENTED;
+
+
+ /* signal completion */
+ KeSetEvent(&Context->Event, IO_NO_INCREMENT, FALSE);
+}
+
+NTSTATUS
+KspQueryBusRelations(
+ IN PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension,
+ IN PIRP Irp)
+{
+ PDEVICE_RELATIONS DeviceRelations;
+ PLIST_ENTRY Entry;
+ PBUS_DEVICE_ENTRY DeviceEntry;
+ ULONG Count = 0, Length;
+ KIRQL OldLevel;
+
+ /* acquire lock */
+ KeAcquireSpinLock(&BusDeviceExtension->Lock, &OldLevel);
+
+ /* first scan 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);
+
+ /* is there a pdo yet */
+ if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
+ {
+ /* increment count */
+ Count++;
+ }
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+ }
+
+ /* calculate length */
+ Length = sizeof(DEVICE_RELATIONS) + (Count > 1 ? sizeof(PDEVICE_OBJECT) * (Count-1) : 0);
+
+ /* allocate device relations */
+ DeviceRelations = (PDEVICE_RELATIONS)AllocateItem(NonPagedPool, Length);
+
+ if (!DeviceRelations)
+ {
+ /* not enough memory */
+ KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* rescan 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);
+
+ /* is there a pdo yet */
+ if (DeviceEntry->PDO && (DeviceEntry->DeviceState == NotStarted || DeviceEntry->DeviceState == Started))
+ {
+ /* store pdo */
+ DeviceRelations->Objects[DeviceRelations->Count] = DeviceEntry->PDO;
+
+ /* reference device object */
+ ObReferenceObject(DeviceEntry->PDO);
+
+ /* increment pdo count */
+ DeviceRelations->Count++;
+ }
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+ }
+
+ /* release lock */
+ KeReleaseSpinLock(&BusDeviceExtension->Lock, OldLevel);
+
+ /* FIXME handle existing device relations */
+ ASSERT(Irp->IoStatus.Information == 0);
+
+ /* store device relations */
+ Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
+
+ /* done */
+ return STATUS_SUCCESS;
+}
+
+//------------------------------------------------------------------------------------
+
+/*
+ @implemented
+*/
+
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsGetBusEnumIdentifier(
+ IN PIRP Irp)
+{
+ PDEV_EXTENSION DeviceExtension;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+ PIO_STACK_LOCATION IoStack;
+ ULONG Length;
+ NTSTATUS Status;
+ LPWSTR Buffer;
+
+ DPRINT1("KsGetBusEnumIdentifier\n");
+
+ /* get stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* sanity checks */
+ ASSERT(IoStack->DeviceObject);
+ ASSERT(IoStack->DeviceObject->DeviceExtension);
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)IoStack->DeviceObject->DeviceExtension;
+
+ /* get bus device extension */
+ BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
+
+ /* sanity checks */
+ ASSERT(BusDeviceExtension);
+ ASSERT(BusDeviceExtension->Common.IsBus);
+
+ if (!BusDeviceExtension)
+ {
+ /* invalid parameter */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* get length */
+ Length = (wcslen(BusDeviceExtension->BusIdentifier)+1) * sizeof(WCHAR);
+
+ /* is there an output buffer provided */
+ if (IoStack->Parameters.DeviceIoControl.InputBufferLength)
+ {
+ if (Length > IoStack->Parameters.DeviceIoControl.InputBufferLength)
+ {
+ /* buffer is too small */
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* now allocate buffer */
+ Buffer = AllocateItem(NonPagedPool, Length);
+ if (!Buffer)
+ {
+ /* no memory */
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ /* copy bus identifier */
+ wcscpy(Buffer, BusDeviceExtension->BusIdentifier);
+
+ /* store buffer */
+ Irp->AssociatedIrp.SystemBuffer = Buffer;
+
+ /* set flag that buffer gets copied back */
+ Irp->Flags |= IRP_BUFFERED_IO | IRP_DEALLOCATE_BUFFER | IRP_INPUT_OPERATION;
+
+ /* done */
+ Status = STATUS_SUCCESS;
+ }
+ }
+ else
+ {
+ /* no buffer provided */
+ Status = STATUS_BUFFER_OVERFLOW;
+ }
+
+ /* done */
+ Irp->IoStatus.Status = Status;
+ return Status;
+}
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsGetBusEnumParentFDOFromChildPDO(
+ IN PDEVICE_OBJECT DeviceObject,
+ OUT PDEVICE_OBJECT *FunctionalDeviceObject)
+{
+ PDEV_EXTENSION DeviceExtension;
+
+ DPRINT1("KsGetBusEnumParentFDOFromChildPDO\n");
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* check if this is child pdo */
+ if (DeviceExtension->Ext->IsBus == FALSE)
+ {
+ /* return bus device object */
+ *FunctionalDeviceObject = DeviceExtension->Ext->BusDeviceExtension->BusDeviceObject;
+
+ /* done */
+ return STATUS_SUCCESS;
+ }
+
+ /* invalid parameter */
+ return STATUS_INVALID_PARAMETER;
+}
+
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsCreateBusEnumObject(
+ IN PWCHAR BusIdentifier,
+ IN PDEVICE_OBJECT BusDeviceObject,
+ IN PDEVICE_OBJECT PhysicalDeviceObject,
+ IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL,
+ IN REFGUID InterfaceGuid OPTIONAL,
+ IN PWCHAR ServiceRelativePath OPTIONAL)
+{
+ ULONG Length;
+ NTSTATUS Status = STATUS_SUCCESS;
+ UNICODE_STRING ServiceKeyPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+ PDEV_EXTENSION DeviceExtension;
+
+ DPRINT1("KsCreateBusEnumObject %S BusDeviceObject %p\n", ServiceRelativePath, BusDeviceObject);
+
+ /* calculate sizeof bus enum device extension */
+ Length = wcslen(BusIdentifier) * sizeof(WCHAR);
+ Length += sizeof(BUS_ENUM_DEVICE_EXTENSION);
+
+ BusDeviceExtension = AllocateItem(NonPagedPool, Length);
+ if (!BusDeviceExtension)
+ {
+ /* not enough memory */
+
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)BusDeviceObject->DeviceExtension;
+
+ DPRINT1("DeviceExtension %p BusDeviceExtension %p\n", DeviceExtension, DeviceExtension->Ext);
+
+ /* store bus device extension */
+ DeviceExtension->Ext = (PCOMMON_DEVICE_EXTENSION)BusDeviceExtension;
+
+ DPRINT1("DeviceExtension %p BusDeviceExtension %p\n", DeviceExtension, DeviceExtension->Ext);
+
+
+ /* zero device extension */
+ RtlZeroMemory(BusDeviceExtension, sizeof(BUS_ENUM_DEVICE_EXTENSION));
+
+ /* initialize bus device extension */
+ wcscpy(BusDeviceExtension->BusIdentifier, BusIdentifier);
+
+ /* allocate service path string */
+ Length = ServiceKeyPath.MaximumLength;
+ Length += BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName.MaximumLength;
+
+ if (ServiceRelativePath)
+ {
+ /* relative path for devices */
+ Length += (wcslen(ServiceRelativePath) + 2) * sizeof(WCHAR);
+ }
+
+ BusDeviceExtension->ServicePath.Length = 0;
+ BusDeviceExtension->ServicePath.MaximumLength = Length;
+ BusDeviceExtension->ServicePath.Buffer = AllocateItem(NonPagedPool, Length);
+
+ if (!BusDeviceExtension->ServicePath.Buffer)
+ {
+ /* not enough memory */
+ FreeItem(BusDeviceExtension);
+
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &ServiceKeyPath);
+ RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName);
+
+ if (ServiceRelativePath)
+ {
+ RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, L"\\");
+ RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, ServiceRelativePath);
+ }
+
+ if (InterfaceGuid)
+ {
+ /* register an device interface */
+ Status = IoRegisterDeviceInterface(PhysicalDeviceObject, InterfaceGuid, NULL, &BusDeviceExtension->DeviceInterfaceLink);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+
+ FreeItem(BusDeviceExtension->ServicePath.Buffer);
+ FreeItem(BusDeviceExtension);
+ return Status;
+ }
+
+ /* now enable device interface */
+ Status = IoSetDeviceInterfaceState(&BusDeviceExtension->DeviceInterfaceLink, TRUE);
+
+ if (!NT_SUCCESS(Status))
+ {
+ FreeItem(BusDeviceExtension->ServicePath.Buffer);
+ FreeItem(BusDeviceExtension);
+ return Status;
+ }
+ }
+
+ /* initialize common device extension */
+ BusDeviceExtension->Common.BusDeviceExtension = NULL;
+ BusDeviceExtension->Common.DeviceObjectReferenceCount = 1;
+ BusDeviceExtension->Common.DeviceReferenceCount = 1;
+ BusDeviceExtension->Common.IsBus = TRUE;
+ InitializeListHead(&BusDeviceExtension->Common.Entry);
+
+ /* store device objects */
+ BusDeviceExtension->BusDeviceObject = BusDeviceObject;
+ BusDeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
+
+ /* initialize lock */
+ KeInitializeSpinLock(&BusDeviceExtension->Lock);
+
+ /* initialize timer */
+ KeInitializeTimer(&BusDeviceExtension->Timer);
+
+ /* initialize dpc */
+ KeInitializeDpc(&BusDeviceExtension->Dpc, KspBusDpcRoutine, (PVOID)BusDeviceExtension);
+
+ /* initialize event */
+ KeInitializeEvent(&BusDeviceExtension->Event, SynchronizationEvent, FALSE);
+
+ /* initialize work item */
+ ExInitializeWorkItem(&BusDeviceExtension->WorkItem, KspBusWorkerRoutine, (PVOID)BusDeviceExtension);
+
+ if (!PnpDeviceObject)
+ {
+ /* attach device */
+ BusDeviceExtension->PnpDeviceObject = IoAttachDeviceToDeviceStack(BusDeviceObject, PhysicalDeviceObject);
+
+ if (!BusDeviceExtension->PnpDeviceObject)
+ {
+ /* failed to attach device */
+ if (BusDeviceExtension->DeviceInterfaceLink.Buffer)
+ {
+ IoSetDeviceInterfaceState(&BusDeviceExtension->DeviceInterfaceLink, FALSE);
+ RtlFreeUnicodeString(&BusDeviceExtension->DeviceInterfaceLink);
+ }
+
+ /* free device extension */
+ FreeItem(BusDeviceExtension->ServicePath.Buffer);
+ FreeItem(BusDeviceExtension);
+
+ return STATUS_DEVICE_REMOVED;
+ }
+
+ /* mark device as attached */
+ BusDeviceExtension->DeviceAttached = TRUE;
+ }
+ else
+ {
+ /* directly attach */
+ BusDeviceExtension->PnpDeviceObject = PnpDeviceObject;
+ }
+
+ /* now scan the bus */
+ Status = KspScanBus(BusDeviceExtension);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to scan bus */
+ if (BusDeviceExtension->DeviceInterfaceLink.Buffer)
+ {
+ IoSetDeviceInterfaceState(&BusDeviceExtension->DeviceInterfaceLink, FALSE);
+ RtlFreeUnicodeString(&BusDeviceExtension->DeviceInterfaceLink);
+ }
+
+ if (BusDeviceExtension->DeviceAttached)
+ {
+ /* detach device */
+ IoDetachDevice(BusDeviceExtension->PnpDeviceObject);
+ }
+
+ /* free device extension */
+ FreeItem(BusDeviceExtension->ServicePath.Buffer);
+ FreeItem(BusDeviceExtension);
+ }
+
+ DPRINT("KsCreateBusEnumObject Status %x\n", Status);
+ /* done */
+ return Status;
+}
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsGetBusEnumPnpDeviceObject(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PDEVICE_OBJECT *PnpDeviceObject)
+{
+ PDEV_EXTENSION DeviceExtension;
+ PCOMMON_DEVICE_EXTENSION CommonDeviceExtension;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+
+ DPRINT("KsGetBusEnumPnpDeviceObject\n");
+
+ if (!DeviceObject->DeviceExtension)
+ {
+ /* invalid parameter */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* get common device extension */
+ CommonDeviceExtension = DeviceExtension->Ext;
+
+ if (!CommonDeviceExtension)
+ {
+ /* invalid parameter */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (!CommonDeviceExtension->IsBus)
+ {
+ /* getting pnp device object is only supported for software bus device object */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* sanity checks */
+ ASSERT(CommonDeviceExtension);
+ ASSERT(CommonDeviceExtension->IsBus);
+
+ /* cast to bus device extension */
+ BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)CommonDeviceExtension;
+
+ /* store result */
+ *PnpDeviceObject = BusDeviceExtension->PnpDeviceObject;
+
+ /* done */
+ return STATUS_SUCCESS;
+}
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsInstallBusEnumInterface(
+ PIRP Irp)
+{
+ BUS_INSTALL_ENUM_CONTEXT Context;
+ KPROCESSOR_MODE Mode;
+ LUID luid;
+ PIO_STACK_LOCATION IoStack;
+ PDEV_EXTENSION DeviceExtension;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+
+ DPRINT1("KsInstallBusEnumInterface\n");
+
+ /* get current irp stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* get previous mode */
+ Mode = ExGetPreviousMode();
+
+ /* convert to luid */
+ luid = RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
+
+ /* perform access check */
+ if (!SeSinglePrivilegeCheck(luid, Mode))
+ {
+ /* insufficient privileges */
+ return STATUS_PRIVILEGE_NOT_HELD;
+ }
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)IoStack->DeviceObject->DeviceExtension;
+
+ /* get bus device extension */
+ BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
+
+
+ /* initialize context */
+ Context.Irp = Irp;
+ KeInitializeEvent(&Context.Event, NotificationEvent, FALSE);
+ Context.BusDeviceExtension = BusDeviceExtension;
+ ExInitializeWorkItem(&Context.WorkItem, KspInstallBusEnumInterface, (PVOID)&Context);
+
+ /* queue the work item */
+ ExQueueWorkItem(&Context.WorkItem, DelayedWorkQueue);
+ /* wait for completion */
+ KeWaitForSingleObject(&Context.Event, Executive, KernelMode, FALSE, NULL);
+
+ /* store result */
+ Irp->IoStatus.Status = Context.Status;
+
+ /* done */
+ return Context.Status;
+}
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsIsBusEnumChildDevice(
+ IN PDEVICE_OBJECT DeviceObject,
+ OUT PBOOLEAN ChildDevice)
+{
+ PDEV_EXTENSION DeviceExtension;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+
+ DPRINT("KsIsBusEnumChildDevice %p\n", DeviceObject);
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* get bus device extension */
+ BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
+
+ if (!BusDeviceExtension)
+ {
+ /* not a bus device */
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* store result */
+ *ChildDevice = (BusDeviceExtension->Common.IsBus == FALSE);
+
+ return STATUS_SUCCESS;
+}
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsServiceBusEnumCreateRequest(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN OUT PIRP Irp)
+{
+ PLIST_ENTRY Entry;
+ PBUS_DEVICE_ENTRY DeviceEntry = NULL; /* fix gcc */
+ PIO_STACK_LOCATION IoStack;
+ BOOLEAN ItemExists = FALSE;
+ PDEV_EXTENSION DeviceExtension;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+ //PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
+ NTSTATUS Status;
+ LARGE_INTEGER Time;
+
+ /* FIXME: locks */
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* get bus device extension */
+ BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
+
+ /* get current irp stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* sanity checks */
+ 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;
+
+ while(Entry != &BusDeviceExtension->Common.Entry)
+ {
+ /* get real offset */
+ DeviceEntry = (PBUS_DEVICE_ENTRY)CONTAINING_RECORD(Entry, BUS_DEVICE_ENTRY, Entry);
+
+ /* check if name matches */
+ if (!wcsicmp(DeviceEntry->DeviceName, IoStack->FileObject->FileName.Buffer + 1))
+ {
+ /* item already exists */
+ ItemExists = TRUE;
+ break;
+ }
+
+ /* move to next entry */
+ Entry = Entry->Flink;
+ }
+
+ if (!ItemExists)
+ {
+ /* interface not registered */
+ DPRINT1("Interface %wZ not registered\n", &IoStack->FileObject->FileName);
+ return STATUS_OBJECT_NAME_NOT_FOUND;
+ }
+
+ /* is there a pdo yet */
+ if (DeviceEntry->PDO)
+ {
+ if (DeviceEntry->DeviceState == Started)
+ {
+ /* issue reparse */
+ 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 */
+ IoMarkIrpPending(Irp);
+
+ /* insert into irp pending list */
+ InsertTailList(&DeviceEntry->IrpPendingList, &Irp->Tail.Overlay.ListEntry);
+
+ 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;
+
+ }
+ else
+ {
+ /* time to create PDO */
+ Status = KspCreatePDO(BusDeviceExtension, DeviceEntry, &DeviceEntry->PDO);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to create PDO */
+ 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);
+
+ /* insert into irp pending list */
+ InsertTailList(&DeviceEntry->IrpPendingList, &Irp->Tail.Overlay.ListEntry);
+
+ /* get current time */
+ KeQuerySystemTime(&DeviceEntry->TimeCreated);
+
+ /* invalidate device relations */
+ IoInvalidateDeviceRelations(BusDeviceExtension->PhysicalDeviceObject, BusRelations);
+
+ /* done for now */
+ return STATUS_PENDING;
+ }
+}
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsServiceBusEnumPnpRequest(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN OUT PIRP Irp)
+{
+ PDEV_EXTENSION DeviceExtension;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+ PCOMMON_DEVICE_EXTENSION ChildDeviceExtension;
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
+ LARGE_INTEGER Time;
+ PDEVICE_RELATIONS DeviceRelation;
+ PBUS_DEVICE_ENTRY DeviceEntry;
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)DeviceObject->DeviceExtension;
+
+ /* get bus device extension */
+ BusDeviceExtension = (PBUS_ENUM_DEVICE_EXTENSION)DeviceExtension->Ext;
+
+ /* get current irp stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ if (BusDeviceExtension->Common.IsBus)
+ {
+ if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
+ {
+ /* no op for bus driver */
+ Status = STATUS_SUCCESS;
+ }
+ else if (IoStack->MinorFunction == IRP_MN_QUERY_DEVICE_RELATIONS)
+ {
+ /* handle bus device relations */
+ ASSERT(IoStack->Parameters.QueryDeviceRelations.Type == BusRelations);
+
+ Status = KspQueryBusRelations(BusDeviceExtension, Irp);
+ }
+ else
+ {
+ /* get default status */
+ Status = Irp->IoStatus.Status;
+ }
+ }
+ else
+ {
+ /* get child device extension */
+ ChildDeviceExtension = DeviceExtension->Ext;
+
+ /* get bus device extension */
+ BusDeviceExtension = ChildDeviceExtension->BusDeviceExtension;
+
+ if (IoStack->MinorFunction == IRP_MN_QUERY_ID)
+ {
+ /* query id */
+ 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 */
+ Status = KspQueryBusInformation(ChildDeviceExtension, Irp);
+ }
+ else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES)
+ {
+ /* no op */
+ Status = STATUS_SUCCESS;
+ }
+ else if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
+ {
+ /* no op */
+ Status = STATUS_SUCCESS;
+ }
+ else if (IoStack->MinorFunction == IRP_MN_START_DEVICE)
+ {
+ /* start bus */
+ 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 */
+ Status = KspQueryBusDeviceCapabilities(ChildDeviceExtension, Irp);
+ }
+ else if (IoStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
+ {
+ /* query pnp state */
+ Status = KspQueryBusDevicePnpState(ChildDeviceExtension, Irp);
+ }
+ else if (IoStack->MinorFunction == IRP_MN_QUERY_INTERFACE)
+ {
+ /* query interface */
+ 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);
+
+ /* 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;
+}
+
+/*
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
+KsRemoveBusEnumInterface(
+ IN PIRP Irp)
+{
+ KPROCESSOR_MODE Mode;
+ LUID luid;
+ BUS_INSTALL_ENUM_CONTEXT Ctx;
+ PDEV_EXTENSION DeviceExtension;
+ PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
+ PIO_STACK_LOCATION IoStack;
+
+ DPRINT1("KsRemoveBusEnumInterface\n");
+
+ /* get io stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* get device extension */
+ DeviceExtension = (PDEV_EXTENSION)IoStack->DeviceObject->DeviceExtension;
+
+ /* get bus device extension */
+ BusDeviceExtension = DeviceExtension->Ext->BusDeviceExtension;
+
+ /* get previous mode */
+ Mode = ExGetPreviousMode();
+
+ /* convert to luid */
+ luid = RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
+
+ /* perform access check */
+ if (!SeSinglePrivilegeCheck(luid, Mode))
+ {
+ /* insufficient privileges */
+ return STATUS_PRIVILEGE_NOT_HELD;
+ }
+
+ /* initialize context */
+ KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);
+ Ctx.Irp = Irp;
+ Ctx.BusDeviceExtension = BusDeviceExtension;
+ ExInitializeWorkItem(&Ctx.WorkItem, KspRemoveBusInterface, (PVOID)&Ctx);
+
+ /* now queue the work item */
+ ExQueueWorkItem(&Ctx.WorkItem, DelayedWorkQueue);
+
+ /* wait for completion */
+ KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);
+
+ /* return result */
+ return Ctx.Status;
+}
diff --git a/reactos/drivers/ksfilter/swenum/swenum.c b/reactos/drivers/ksfilter/swenum/swenum.c
index 459e60b377f..c2aeaad5ea3 100644
--- a/reactos/drivers/ksfilter/swenum/swenum.c
+++ b/reactos/drivers/ksfilter/swenum/swenum.c
@@ -18,8 +18,56 @@ SwDispatchPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
+ NTSTATUS Status, PnpStatus;
+ BOOLEAN ChildDevice;
+ PIO_STACK_LOCATION IoStack;
+ PDEVICE_OBJECT PnpDeviceObject = NULL;
- UNIMPLEMENTED;
+ /* get current stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* check if the device object is a child device */
+ Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
+
+ /* get bus enum pnp object */
+ PnpStatus = KsGetBusEnumPnpDeviceObject(DeviceObject, &PnpDeviceObject);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status) || !NT_SUCCESS(PnpStatus))
+ {
+ /* start next power irp */
+ PoStartNextPowerIrp(Irp);
+
+ /* just complete the irp */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ /* complete the irp */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ /* done */
+ return STATUS_SUCCESS;
+ }
+
+ if (IoStack->MinorFunction == IRP_MN_SET_POWER || IoStack->MinorFunction == IRP_MN_QUERY_POWER)
+ {
+ /* fake success */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ }
+
+ if (!ChildDevice)
+ {
+ /* forward to pnp device object */
+ PoStartNextPowerIrp(Irp);
+
+ /* skip current location */
+ IoSkipCurrentIrpStackLocation(Irp);
+
+ /* done */
+ return PoCallDriver(PnpDeviceObject, Irp);
+ }
+
+ /* start next power irp */
+ PoStartNextPowerIrp(Irp);
/* just complete the irp */
Irp->IoStatus.Status = STATUS_SUCCESS;
@@ -29,7 +77,6 @@ SwDispatchPower(
/* done */
return STATUS_SUCCESS;
-
}
NTSTATUS
@@ -43,6 +90,9 @@ SwDispatchPnp(
PIO_STACK_LOCATION IoStack;
PDEVICE_OBJECT PnpDeviceObject = NULL;
+ /* get current stack location */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
/* check if the device object is a child device */
Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
@@ -55,10 +105,30 @@ SwDispatchPnp(
return Status;
}
+ DPRINT("SwDispatchPnp ChildDevice %u Request %x\n", ChildDevice, IoStack->MinorFunction);
+
/* let ks handle it */
Status = KsServiceBusEnumPnpRequest(DeviceObject, Irp);
- if (!NT_SUCCESS(Status))
+ /* check if the request was for a pdo */
+ if (!ChildDevice)
+ {
+ if (Status != STATUS_NOT_SUPPORTED)
+ {
+ /* store result */
+ Irp->IoStatus.Status = Status;
+ }
+
+ /* complete request */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ /* done */
+ return Status;
+ }
+
+ DPRINT("SwDispatchPnp KsServiceBusEnumPnpRequest Status %x\n", Status);
+
+ if (NT_SUCCESS(Status))
{
/* invalid request or not supported */
Irp->IoStatus.Status = Status;
@@ -69,6 +139,8 @@ SwDispatchPnp(
/* get bus enum pnp object */
Status = KsGetBusEnumPnpDeviceObject(DeviceObject, &PnpDeviceObject);
+ DPRINT("SwDispatchPnp KsGetBusEnumPnpDeviceObject Status %x\n", Status);
+
/* check for success */
if (!NT_SUCCESS(Status))
{
@@ -89,11 +161,49 @@ SwDispatchPnp(
/* delete the device */
IoDeleteDevice(DeviceObject);
}
+ else
+ {
+ if (IoStack->MinorFunction == IRP_MN_QUERY_RESOURCES || IoStack->MinorFunction == IRP_MN_QUERY_RESOURCE_REQUIREMENTS)
+ {
+ /* no resources required */
+ Irp->IoStatus.Information = 0;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
- /* skip current location */
- IoSkipCurrentIrpStackLocation(Irp);
- /* call the pnp device object */
- return IoCallDriver(PnpDeviceObject, Irp);
+ /* skip current location */
+ IoSkipCurrentIrpStackLocation(Irp);
+
+ /* call the pnp device object */
+ return IoCallDriver(PnpDeviceObject, Irp);
+ }
+
+ if (IoStack->MajorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE)
+ {
+ /* device cannot be disabled */
+ Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+
+ /* skip current location */
+ IoSkipCurrentIrpStackLocation(Irp);
+
+ /* call the pnp device object */
+ return IoCallDriver(PnpDeviceObject, Irp);
+ }
+
+ if (Status == STATUS_NOT_SUPPORTED)
+ {
+ /* skip current location */
+ IoSkipCurrentIrpStackLocation(Irp);
+
+ /* call the pnp device object */
+ return IoCallDriver(PnpDeviceObject, Irp);
+ }
+ }
+
+ /* complete the request */
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
}
NTSTATUS
@@ -149,7 +259,7 @@ SwDispatchDeviceControl(
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
- NTSTATUS Status = STATUS_SUCCESS;
+ NTSTATUS Status;
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
@@ -158,16 +268,25 @@ SwDispatchDeviceControl(
{
/* install interface */
Status = KsInstallBusEnumInterface(Irp);
+ DPRINT("SwDispatchDeviceControl IOCTL_SWENUM_INSTALL_INTERFACE %x\n", Status);
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_REMOVE_INTERFACE)
{
/* remove interface */
Status = KsRemoveBusEnumInterface(Irp);
+ DPRINT("SwDispatchDeviceControl IOCTL_SWENUM_REMOVE_INTERFACE %x\n", Status);
+
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SWENUM_GET_BUS_ID)
{
/* get bus id */
- return KsGetBusEnumIdentifier(Irp);
+ Status = KsGetBusEnumIdentifier(Irp);
+ DPRINT("SwDispatchDeviceControl IOCTL_SWENUM_GET_BUS_ID %x\n", Status);
+ }
+ else
+ {
+ DPRINT("SwDispatchDeviceControl Unknown IOCTL %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
+ Status = STATUS_INVALID_PARAMETER;
}
/* store result */
@@ -193,6 +312,8 @@ SwDispatchCreate(
/* check if the device object is a child device */
Status = KsIsBusEnumChildDevice(DeviceObject, &ChildDevice);
+ DPRINT("SwDispatchCreate %x\n", Status);
+
/* check for success */
if (NT_SUCCESS(Status))
{
@@ -205,6 +326,7 @@ SwDispatchCreate(
}
/* perform the create request */
Status = KsServiceBusEnumCreateRequest(DeviceObject, Irp);
+ DPRINT("SwDispatchCreate %x\n", Status);
}
/* check the irp is pending */
@@ -245,6 +367,7 @@ SwAddDevice(
NTSTATUS Status;
PDEVICE_OBJECT FunctionalDeviceObject;
+ DPRINT("SWENUM AddDevice\n");
/* create the device */
Status = IoCreateDevice(DriverObject, sizeof(KSDEVICE_HEADER), NULL, FILE_DEVICE_BUS_EXTENDER, 0, FALSE, &FunctionalDeviceObject);
@@ -303,7 +426,7 @@ DriverEntry(
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SwDispatchDeviceControl;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = SwDispatchSystemControl;
-
+ DPRINT("SWENUM loaded\n");
return STATUS_SUCCESS;
}
diff --git a/reactos/drivers/ksfilter/swenum/swenum.rbuild b/reactos/drivers/ksfilter/swenum/swenum.rbuild
index 0978c11a1b2..462a0f6824d 100644
--- a/reactos/drivers/ksfilter/swenum/swenum.rbuild
+++ b/reactos/drivers/ksfilter/swenum/swenum.rbuild
@@ -1,6 +1,7 @@
+
ntoskrnl
ks
swenum.c