From 4725a4fd9cb76e05ab5bb225e1f30bd94743e8d9 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Tue, 21 Jul 2009 13:32:28 +0000 Subject: [PATCH] - Rewrite KsDefaultDispatchPnp to make it actually work - Implement KsDefaultDispatchPower, KsDefaultForwardIrp - Return the correct device object in KsQueryDevicePnpObject - Implement KsReadFile, KsSetInformationFile and partly KsQueryInformationFile - Remove KspClose, KspRead, KspWrite, KspFlushBuffers, KspQuerySecurity, KspSetSecurity and all these IOCTL in KspDispatchIrp - Rewrite KsDispatchIrp to handle IRP_MJ_CREATE & IRP_MJ_POWER, IRP_MJ_PNP for AV Stream minidrivers and forward IRP_MJ_SYSTEM_CONTROL requests to the registered pnp base object - Unsupported IOCTLs are now completed with KsDispatchInvalidDeviceRequest (previously leaked) svn path=/trunk/; revision=42117 --- reactos/drivers/ksfilter/ks/api.c | 151 +++++-- reactos/drivers/ksfilter/ks/device.c | 5 - reactos/drivers/ksfilter/ks/irp.c | 578 ++++++++++++++++---------- reactos/drivers/ksfilter/ks/kstypes.h | 4 +- reactos/drivers/ksfilter/ks/misc.c | 2 +- 5 files changed, 463 insertions(+), 277 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/api.c b/reactos/drivers/ksfilter/ks/api.c index 9bdb16a374e..37a4df011ad 100644 --- a/reactos/drivers/ksfilter/ks/api.c +++ b/reactos/drivers/ksfilter/ks/api.c @@ -65,9 +65,8 @@ KsReleaseDeviceSecurityLock( } /* - @unimplemented + @implemented */ - KSDDKAPI NTSTATUS NTAPI @@ -75,46 +74,54 @@ KsDefaultDispatchPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; PIO_STACK_LOCATION IoStack; - NTSTATUS Status = STATUS_SUCCESS; + PDEVICE_OBJECT PnpDeviceObject; + NTSTATUS Status; + ULONG MinorFunction; + /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); - //FIXME - //REWRITE + /* caller wants to add the target device */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; - DPRINT1("KsDefaultDispatchPnp entered with func %x\n", IoStack->MinorFunction); + /* get device header */ + DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; - switch(IoStack->MinorFunction) + /* backup PnpBaseObject */ + PnpDeviceObject = DeviceHeader->PnpDeviceObject; + + + /* backup minor function code */ + MinorFunction = IoStack->MinorFunction; + + if(MinorFunction == IRP_MN_REMOVE_DEVICE) { - case IRP_MN_QUERY_DEVICE_RELATIONS: - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - case IRP_MN_REMOVE_DEVICE: - // FIXME - // destroy device header, detach device and delete device - case IRP_MN_START_DEVICE: - case IRP_MN_QUERY_REMOVE_DEVICE: - case IRP_MN_CANCEL_STOP_DEVICE: - case IRP_MN_SURPRISE_REMOVAL: - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - default: - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - //Status = IoCallDriver(NULL /* PnpBaseObject */, Irp); + /* remove the device */ + KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader); } + /* skip current irp stack */ + IoSkipCurrentIrpStackLocation(Irp); + + /* call attached pnp device object */ + Status = IoCallDriver(PnpDeviceObject, Irp); + + if (MinorFunction == IRP_MN_REMOVE_DEVICE) + { + /* time is over */ + IoDetachDevice(PnpDeviceObject); + /* delete device */ + IoDeleteDevice(DeviceObject); + } + /* done */ return Status; } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -123,16 +130,59 @@ KsDefaultDispatchPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + PKSIOBJECT_HEADER ObjectHeader; + PIO_STACK_LOCATION IoStack; + PLIST_ENTRY ListEntry; + NTSTATUS Status; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* caller wants to add the target device */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* get device header */ + DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; + + /* FIXME locks */ + + /* loop our power dispatch list and call registered notification functions */ + ListEntry = DeviceHeader->PowerDispatchList.Flink; + /* let's go */ + while(ListEntry != &DeviceHeader->PowerDispatchList) + { + /* get object header */ + ObjectHeader = (PKSIOBJECT_HEADER)CONTAINING_RECORD(ListEntry, KSIOBJECT_HEADER, PowerDispatchEntry); + + /* does it have still a cb */ + if (ObjectHeader->PowerDispatch) + { + /* call the power cb */ + Status = ObjectHeader->PowerDispatch(ObjectHeader->PowerContext, Irp); + ASSERT(NT_SUCCESS(Status)); + } + + /* iterate to next entry */ + ListEntry = ListEntry->Flink; + } + + /* start next power irp */ + PoStartNextPowerIrp(Irp); + + /* skip current irp stack location */ + IoSkipCurrentIrpStackLocation(Irp); + + /* let's roll */ + Status = PoCallDriver(DeviceHeader->PnpDeviceObject, Irp); + + /* done */ + return Status; } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -141,11 +191,24 @@ KsDefaultForwardIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* caller wants to add the target device */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* get device header */ + DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; + + /* forward the request to the PDO */ + Status = IoCallDriver(DeviceHeader->PnpDeviceObject, Irp); + + return Status; } /* @@ -161,8 +224,8 @@ KsSetDevicePnpAndBaseObject( { PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; - DeviceHeader->PhysicalDeviceObject = PnpDeviceObject; - DeviceHeader->NextDeviceObject = BaseDevice; + DeviceHeader->PnpDeviceObject = PnpDeviceObject; + DeviceHeader->BaseDevice = BaseDevice; } /* @@ -176,8 +239,8 @@ KsQueryDevicePnpObject( { PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; - /* return next device header */ - return DeviceHeader->NextDeviceObject; + /* return PnpDeviceObject */ + return DeviceHeader->PnpDeviceObject; } diff --git a/reactos/drivers/ksfilter/ks/device.c b/reactos/drivers/ksfilter/ks/device.c index 00c5d852022..650115f4075 100644 --- a/reactos/drivers/ksfilter/ks/device.c +++ b/reactos/drivers/ksfilter/ks/device.c @@ -607,11 +607,6 @@ IKsDevice_Create( return STATUS_UNSUCCESSFUL; } - - - - - /* @unimplemented */ diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 8feb2269723..03b799cd452 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -169,7 +169,7 @@ KsDispatchSpecificMethod( /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -184,8 +184,88 @@ KsReadFile( IN ULONG Key OPTIONAL, IN KPROCESSOR_MODE RequestorMode) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PDEVICE_OBJECT DeviceObject; + PIRP Irp; + NTSTATUS Status; + BOOLEAN Result; + KEVENT LocalEvent; + + if (Event) + { + /* make sure event is reset */ + KeClearEvent(Event); + } + + if (RequestorMode == UserMode) + { + /* probe the user buffer */ + _SEH2_TRY + { + ProbeForWrite(Buffer, Length, sizeof(UCHAR)); + Status = STATUS_SUCCESS; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Exception, get the error code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Invalid user buffer provided\n"); + return Status; + } + } + + /* get corresponding device object */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + + /* fast-io read is only available for kernel mode clients */ + if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode && + DeviceObject->DriverObject->FastIoDispatch->FastIoRead) + { + /* call fast io write */ + Result = DeviceObject->DriverObject->FastIoDispatch->FastIoRead(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject); + + if (Result && NT_SUCCESS(IoStatusBlock->Status)) + { + /* request was handeled and succeeded */ + return STATUS_SUCCESS; + } + } + + /* do the slow way */ + if (!Event) + { + /* initialize temp event */ + KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE); + Event = &LocalEvent; + } + + /* build the irp packet */ + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, Buffer, Length, &FileObject->CurrentByteOffset, Event, IoStatusBlock); + if (!Irp) + { + /* not enough resources */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* send the packet */ + Status = IoCallDriver(DeviceObject, Irp); + + if (Status == STATUS_PENDING) + { + /* operation is pending, is sync file object */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + { + /* it is so wait */ + KeWaitForSingleObject(Event, Executive, RequestorMode, FALSE, NULL); + Status = IoStatusBlock->Status; + } + } + /* return result */ + return Status; } /* @@ -256,7 +336,6 @@ KsWriteFile( } /* do the slow way */ - if (!Event) { /* initialize temp event */ @@ -301,12 +380,45 @@ KsQueryInformationFile( IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass) { - UNIMPLEMENTED; + PDEVICE_OBJECT DeviceObject; + PFAST_IO_DISPATCH FastIoDispatch; + IO_STATUS_BLOCK IoStatus; + + /* get related file object */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + + /* get fast i/o table */ + FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; + + /* is there a fast table */ + if (FastIoDispatch) + { + /* check the class */ + if (FileInformationClass == FileBasicInformation) + { + /* use FastIoQueryBasicInfo routine */ + if (FastIoDispatch->FastIoQueryBasicInfo) + { + return FastIoDispatch->FastIoQueryBasicInfo(FileObject, TRUE, (PFILE_BASIC_INFORMATION)FileInformation, &IoStatus, DeviceObject); + } + } + else if (FileInformationClass == FileStandardInformation) + { + /* use FastIoQueryBasicInfo routine */ + if (FastIoDispatch->FastIoQueryBasicInfo) + { + return FastIoDispatch->FastIoQueryStandardInfo(FileObject, TRUE, (PFILE_STANDARD_INFORMATION)FileInformation, &IoStatus, DeviceObject); + } + } + } + + /* Implement Me */ + return STATUS_UNSUCCESSFUL; } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS @@ -317,8 +429,84 @@ KsSetInformationFile( IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PIO_STACK_LOCATION IoStack; + PDEVICE_OBJECT DeviceObject; + PIRP Irp; + PVOID Buffer; + KEVENT Event; + LARGE_INTEGER Offset; + IO_STATUS_BLOCK IoStatus; + NTSTATUS Status; + + /* get related device object */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + + /* copy file information */ + Buffer = AllocateItem(NonPagedPool, Length); + if (!Buffer) + return STATUS_INSUFFICIENT_RESOURCES; + + _SEH2_TRY + { + ProbeForRead(Buffer, Length, sizeof(UCHAR)); + RtlMoveMemory(Buffer, FileInformation, Length); + Status = STATUS_SUCCESS; + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Exception, get the error code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + if (!NT_SUCCESS(Status)) + { + /* invalid user buffer */ + FreeItem(Buffer); + return Status; + } + + /* initialize the event */ + KeInitializeEvent(&Event, SynchronizationEvent, FALSE); + + /* zero offset */ + Offset.QuadPart = 0LL; + + /* build the irp */ + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION, DeviceObject, NULL, 0, &Offset, &Event, &IoStatus); + + if (!Irp) + { + /* failed to allocate irp */ + FreeItem(Buffer); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* get next stack location */ + IoStack = IoGetNextIrpStackLocation(Irp); + + /* set irp parameters */ + IoStack->Parameters.SetFile.FileInformationClass = FileInformationClass; + IoStack->Parameters.SetFile.Length = Length; + IoStack->Parameters.SetFile.FileObject = FileObject; + Irp->AssociatedIrp.SystemBuffer = Buffer; + Irp->UserBuffer = FileInformation; + + /* dispatch the irp */ + Status = IoCallDriver(DeviceObject, Irp); + + if (Status == STATUS_PENDING) + { + /* wait untill the operation has completed */ + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + /* is a sync file object */ + if (FileObject->Flags & FO_SYNCHRONOUS_IO) + Status = FileObject->FinalStatus; + else + Status = IoStatus.Status; + } + /* done */ + return Status; } /* @@ -843,57 +1031,6 @@ KspCreate( return STATUS_UNSUCCESSFUL; } -NTAPI -NTSTATUS -KspClose( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - PDEVICE_EXTENSION DeviceExtension; - PKSIDEVICE_HEADER DeviceHeader; - NTSTATUS Status; - - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - /* get device extension */ - DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; - /* get device header */ - DeviceHeader = DeviceExtension->DeviceHeader; - - - DPRINT("KS / CLOSE\n"); - - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - /* get object header */ - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - /* store create item */ - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - /* call object close method */ - Status = ObjectHeader->DispatchTable.Close(DeviceObject, Irp); - /* FIXME decrease reference count on original create item */ - - /* return result */ - return Status; - } - else - { -#if 0 - DPRINT1("Expected Object Header FileObject %p FsContext %p\n", IoStack->FileObject, IoStack->FileObject->FsContext); - KeBugCheckEx(0, 0, 0, 0, 0); -#else - DPRINT("Using reference string hack\n"); - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -#endif - return STATUS_SUCCESS; - } -} - NTAPI NTSTATUS KspDeviceControl( @@ -910,14 +1047,14 @@ KspDeviceControl( /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + /* hack for bug 4566 */ if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS) { - /* get device extension */ - DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; - /* get device header */ - DeviceHeader = DeviceExtension->DeviceHeader; - /* retrieve all available reference strings registered */ Length = 0; @@ -978,142 +1115,87 @@ KspDeviceControl( NTAPI NTSTATUS -KspRead( +KspDispatchIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IoStack; + PDEVICE_EXTENSION DeviceExtension; PKSIOBJECT_HEADER ObjectHeader; + PKSIDEVICE_HEADER DeviceHeader; + PDRIVER_DISPATCH Dispatch; + NTSTATUS Status; /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); - DPRINT("KS / Read\n"); - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - return ObjectHeader->DispatchTable.Read(DeviceObject, Irp); + /* get object header */ + ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; + + if (!ObjectHeader) + { + /* hack for bug 4566 */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + /* complete and forget */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + + /* sanity check */ + ASSERT(ObjectHeader); + /* store create item */ + KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; + + /* retrieve matching dispatch function */ + switch(IoStack->MajorFunction) + { + case IRP_MJ_CLOSE: + Dispatch = ObjectHeader->DispatchTable.Close; + break; + case IRP_MJ_DEVICE_CONTROL: + Dispatch = ObjectHeader->DispatchTable.DeviceIoControl; + break; + case IRP_MJ_READ: + Dispatch = ObjectHeader->DispatchTable.Read; + break; + case IRP_MJ_WRITE: + Dispatch = ObjectHeader->DispatchTable.Write; + break; + case IRP_MJ_FLUSH_BUFFERS : + Dispatch = ObjectHeader->DispatchTable.Flush; + break; + case IRP_MJ_QUERY_SECURITY: + Dispatch = ObjectHeader->DispatchTable.QuerySecurity; + break; + case IRP_MJ_SET_SECURITY: + Dispatch = ObjectHeader->DispatchTable.SetSecurity; + break; + case IRP_MJ_PNP: + Dispatch = KsDefaultDispatchPnp; + default: + Dispatch = NULL; + } + + /* is the request supported */ + if (Dispatch) + { + /* now call the dispatch function */ + Status = Dispatch(DeviceObject, Irp); } else { - DPRINT1("Expected Object Header\n"); - KeBugCheckEx(0, 0, 0, 0, 0); - return STATUS_SUCCESS; + /* not supported request */ + Status = KsDispatchInvalidDeviceRequest(DeviceObject, Irp); } -} -NTAPI -NTSTATUS -KspWrite( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("KS / Write\n"); - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - return ObjectHeader->DispatchTable.Write(DeviceObject, Irp); - } - else - { - DPRINT1("Expected Object Header %p\n", IoStack->FileObject); - KeBugCheckEx(0, 0, 0, 0, 0); - return STATUS_SUCCESS; - } -} - -NTAPI -NTSTATUS -KspFlushBuffers( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("KS / FlushBuffers\n"); - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - return ObjectHeader->DispatchTable.Flush(DeviceObject, Irp); - } - else - { - DPRINT1("Expected Object Header\n"); - KeBugCheckEx(0, 0, 0, 0, 0); - return STATUS_SUCCESS; - } -} - -NTAPI -NTSTATUS -KspQuerySecurity( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("KS / QuerySecurity\n"); - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - return ObjectHeader->DispatchTable.QuerySecurity(DeviceObject, Irp); - } - else - { - DPRINT1("Expected Object Header\n"); - KeBugCheckEx(0, 0, 0, 0, 0); - return STATUS_SUCCESS; - } -} - -NTAPI -NTSTATUS -KspSetSecurity( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("KS / SetSecurity\n"); - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - return ObjectHeader->DispatchTable.SetSecurity(DeviceObject, Irp); - } - else - { - DPRINT1("Expected Object Header\n"); - KeBugCheckEx(0, 0, 0, 0, 0); - return STATUS_SUCCESS; - } + /* done */ + return Status; } /* @@ -1131,28 +1213,18 @@ KsSetMajorFunctionHandler( case IRP_MJ_CREATE: DriverObject->MajorFunction[MajorFunction] = KspCreate; break; - case IRP_MJ_CLOSE: - DriverObject->MajorFunction[MajorFunction] = KspClose; break; case IRP_MJ_DEVICE_CONTROL: DriverObject->MajorFunction[MajorFunction] = KspDeviceControl; break; + case IRP_MJ_CLOSE: case IRP_MJ_READ: - DriverObject->MajorFunction[MajorFunction] = KspRead; - break; case IRP_MJ_WRITE: - DriverObject->MajorFunction[MajorFunction] = KspWrite; - break; case IRP_MJ_FLUSH_BUFFERS : - DriverObject->MajorFunction[MajorFunction] = KspFlushBuffers; - break; case IRP_MJ_QUERY_SECURITY: - DriverObject->MajorFunction[MajorFunction] = KspQuerySecurity; - break; case IRP_MJ_SET_SECURITY: - DriverObject->MajorFunction[MajorFunction] = KspSetSecurity; + DriverObject->MajorFunction[MajorFunction] = KspDispatchIrp; break; - default: return STATUS_INVALID_PARAMETER; }; @@ -1171,37 +1243,93 @@ KsDispatchIrp( IN PIRP Irp) { PIO_STACK_LOCATION IoStack; + PKSIDEVICE_HEADER DeviceHeader; + PDEVICE_EXTENSION DeviceExtension; + + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + + /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); - //FIXME REWRITE - - switch (IoStack->MajorFunction) + if (IoStack->MajorFunction <= IRP_MJ_DEVICE_CONTROL) { - case IRP_MJ_CREATE: - return KspCreate(DeviceObject, Irp); - case IRP_MJ_CLOSE: - return KspClose(DeviceObject, Irp); - break; - case IRP_MJ_DEVICE_CONTROL: + if (IoStack->MajorFunction == IRP_MJ_CREATE) + { + /* check internal type */ + if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + { + /* AVStream client */ + return IKsDevice_Create(DeviceObject, Irp); + } + else + { + /* external client (portcls) */ + return KspCreate(DeviceObject, Irp); + } + } + + if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) + { + /* handle device requests */ return KspDeviceControl(DeviceObject, Irp); - break; - case IRP_MJ_READ: - return KspRead(DeviceObject, Irp); - break; - case IRP_MJ_WRITE: - return KspWrite(DeviceObject, Irp); - break; - case IRP_MJ_FLUSH_BUFFERS: - return KspFlushBuffers(DeviceObject, Irp); - break; - case IRP_MJ_QUERY_SECURITY: - return KspQuerySecurity(DeviceObject, Irp); - break; - case IRP_MJ_SET_SECURITY: - return KspSetSecurity(DeviceObject, Irp); - break; - default: - return STATUS_INVALID_PARAMETER; /* is this right? */ - }; + } + + switch (IoStack->MajorFunction) + { + case IRP_MJ_CLOSE: + case IRP_MJ_READ: + case IRP_MJ_WRITE: + case IRP_MJ_FLUSH_BUFFERS: + case IRP_MJ_QUERY_SECURITY: + case IRP_MJ_SET_SECURITY: + case IRP_MJ_PNP: + return KspDispatchIrp(DeviceObject, Irp); + default: + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); + } + } + + /* dispatch power */ + if (IoStack->MajorFunction == IRP_MJ_POWER) + { + /* check internal type */ + if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + { + /* AVStream client */ + return IKsDevice_Power(DeviceObject, Irp); + } + else + { + /* external client (portcls) */ + return KsDefaultDispatchPower(DeviceObject, Irp); + } + } + else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */ + { + /* check internal type */ + if (DeviceHeader->lpVtblIKsDevice) /* FIXME improve check */ + { + /* AVStream client */ + return IKsDevice_Pnp(DeviceObject, Irp); + } + else + { + /* external client (portcls) */ + return KsDefaultDispatchPnp(DeviceObject, Irp); + } + } + else if (IoStack->MajorFunction == IRP_MJ_SYSTEM_CONTROL) + { + /* forward irp */ + return KsDefaultForwardIrp(DeviceObject, Irp); + } + else + { + /* not supported */ + return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); + } } diff --git a/reactos/drivers/ksfilter/ks/kstypes.h b/reactos/drivers/ksfilter/ks/kstypes.h index ab34c5b60cf..b9fa5a38d43 100644 --- a/reactos/drivers/ksfilter/ks/kstypes.h +++ b/reactos/drivers/ksfilter/ks/kstypes.h @@ -43,8 +43,8 @@ typedef struct ULONG DeviceIndex; KSPIN_LOCK ItemListLock; - PDEVICE_OBJECT PhysicalDeviceObject; - PDEVICE_OBJECT NextDeviceObject; + PDEVICE_OBJECT PnpDeviceObject; + PDEVICE_OBJECT BaseDevice; KSTARGET_STATE TargetState; LIST_ENTRY TargetDeviceList; diff --git a/reactos/drivers/ksfilter/ks/misc.c b/reactos/drivers/ksfilter/ks/misc.c index 07700105bde..f0a5acaed14 100644 --- a/reactos/drivers/ksfilter/ks/misc.c +++ b/reactos/drivers/ksfilter/ks/misc.c @@ -70,7 +70,7 @@ KspForwardIrpSynchronous( IoSetCompletionRoutine(Irp, KspForwardIrpSynchronousCompletion, (PVOID)&Event, TRUE, TRUE, TRUE); /* now call the driver */ - Status = IoCallDriver(DeviceHeader->NextDeviceObject, Irp); + Status = IoCallDriver(DeviceHeader->BaseDevice, Irp); /* did the request complete yet */ if (Status == STATUS_PENDING) {