diff --git a/reactos/drivers/ksfilter/ks/allocators.c b/reactos/drivers/ksfilter/ks/allocators.c index 21637ae87cf..c2ffb210ac8 100644 --- a/reactos/drivers/ksfilter/ks/allocators.c +++ b/reactos/drivers/ksfilter/ks/allocators.c @@ -1,8 +1,365 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/allocators.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" +typedef enum +{ + ALLOCATOR_NPAGED_LOOKASIDE, + ALLOCATOR_PAGED_LOOKASIDE, + ALLOCATOR_CUSTOM +}ALLOCATOR_TYPE; + +typedef enum +{ + ALLOCATOR_DEVICE_CONTROL, + ALLOCATOR_DEVICE_CLOSE, + ALLOCATOR_ALLOCATE, + ALLOCATOR_FREE + +}ALLOC_REQUEST; + +typedef PVOID (*PFNKSPAGEDPOOLALLOCATE)(IN PPAGED_LOOKASIDE_LIST Lookaside); +typedef PVOID (*PFNKSNPAGEDPOOLALLOCATE)(IN PNPAGED_LOOKASIDE_LIST Lookaside); + +typedef VOID (*PFNKSPAGEDPOOLFREE)(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry); +typedef VOID (*PFNKSNPAGEDPOOLFREE)(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry); + +typedef VOID (NTAPI *PFNKSNPAGEDPOOLDELETE)(IN PNPAGED_LOOKASIDE_LIST Lookaside); +typedef VOID (NTAPI *PFNKSPAGEDPOOLDELETE)(IN PPAGED_LOOKASIDE_LIST Lookaside); + +typedef struct +{ + IKsAllocatorVtbl *lpVtbl; + LONG ref; + PKSIOBJECT_HEADER Header; + ALLOCATOR_TYPE Type; + + KSSTREAMALLOCATOR_STATUS Status; + + union + { + NPAGED_LOOKASIDE_LIST NPagedList; + PAGED_LOOKASIDE_LIST PagedList; + PVOID CustomList; + }u; + + union + { + PFNKSDEFAULTALLOCATE DefaultAllocate; + PFNKSPAGEDPOOLALLOCATE PagedPool; + PFNKSNPAGEDPOOLALLOCATE NPagedPool; + }Allocate; + + union + { + PFNKSDEFAULTFREE DefaultFree; + PFNKSPAGEDPOOLFREE PagedPool; + PFNKSNPAGEDPOOLFREE NPagedPool; + }Free; + + union + { + PFNKSDELETEALLOCATOR DefaultDelete; + PFNKSNPAGEDPOOLDELETE NPagedPool; + PFNKSPAGEDPOOLDELETE PagedPool; + }Delete; + +}ALLOCATOR, *PALLOCATOR; + +/* use KSNAME_Allocator for IID_IKsAllocator */ +const GUID IID_IKsAllocator = {0x642F5D00L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_StreamAllocator = {0x0cf6e4342, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}}; + + +NTSTATUS +NTAPI +IKsAllocator_Allocate( + IN PFILE_OBJECT FileObject, + PVOID *Frame); + +VOID +NTAPI +IKsAllocator_FreeFrame( + IN PFILE_OBJECT FileObject, + PVOID Frame); + + +NTSTATUS +NTAPI +IKsAllocator_fnQueryInterface( + IKsAllocator * iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); + + if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || + IsEqualGUIDAligned(refiid, &IID_IKsAllocator)) + { + *Output = &This->lpVtbl; + _InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +IKsAllocator_fnAddRef( + IKsAllocator * iface) +{ + PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); + + return InterlockedIncrement(&This->ref); +} + +ULONG +NTAPI +IKsAllocator_fnRelease( + IKsAllocator * iface) +{ + PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + FreeItem(This); + return 0; + } + /* Return new reference count */ + return This->ref; +} + +NTSTATUS +NTAPI +IKsAllocator_fnDeviceIoControl( + IKsAllocator *iface, + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); + PIO_STACK_LOCATION IoStack; + PKSSTREAMALLOCATOR_FUNCTIONTABLE FunctionTable; + PKSSTREAMALLOCATOR_STATUS State; + PKSPROPERTY Property; + + /* FIXME locks */ + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) + { + /* only KSPROPERTY requests are supported */ + UNIMPLEMENTED + + /* complete and forget irps */ + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_NOT_IMPLEMENTED; + } + + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) + { + /* invalid request */ + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_INVALID_DEVICE_REQUEST; + } + + /* check the request */ + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_StreamAllocator)) + { + if (Property->Id == KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE) + { + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE)) + { + /* buffer too small */ + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); + /* complete and forget irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + if (!(Property->Flags & KSPROPERTY_TYPE_GET)) + { + /* only support retrieving the property */ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + /* complete and forget irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + /* get output buffer */ + FunctionTable = (PKSSTREAMALLOCATOR_FUNCTIONTABLE)Irp->UserBuffer; + + FunctionTable->AllocateFrame = IKsAllocator_Allocate; + FunctionTable->FreeFrame = IKsAllocator_FreeFrame; + + /* save result */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); + /* complete request */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS) + { + if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS)) + { + /* buffer too small */ + Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; + Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS); + /* complete and forget irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_BUFFER_TOO_SMALL; + } + if (!(Property->Flags & KSPROPERTY_TYPE_GET)) + { + /* only support retrieving the property */ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + /* complete and forget irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; + } + + /* get output buffer */ + State = (PKSSTREAMALLOCATOR_STATUS)Irp->UserBuffer; + + /* copy allocator status */ + RtlMoveMemory(State, &This->Status, sizeof(KSSTREAMALLOCATOR_STATUS)); + + /* save result */ + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS); + + /* complete request */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + } + + /* unhandeled request */ + Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_NOT_SUPPORTED; +} + +NTSTATUS +NTAPI +IKsAllocator_fnClose( + IKsAllocator *iface) +{ + PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); + + /* FIXME locks */ + + /* now close allocator */ + if (This->Type == ALLOCATOR_CUSTOM) + { + This->Delete.DefaultDelete(This->u.CustomList); + } + else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE) + { + This->Delete.NPagedPool(&This->u.NPagedList); + } + else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE) + { + This->Delete.PagedPool(&This->u.PagedList); + } + + /* free object header */ + KsFreeObjectHeader(&This->Header); + + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IKsAllocator_fnAllocateFrame( + IKsAllocator *iface, + IN PVOID * OutFrame) +{ + PVOID Frame = NULL; + PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); + + /* FIXME locks */ + + /* now allocate frame */ + if (This->Type == ALLOCATOR_CUSTOM) + { + Frame = This->Allocate.DefaultAllocate(This->u.CustomList); + } + else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE) + { + Frame = This->Allocate.NPagedPool(&This->u.NPagedList); + } + else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE) + { + Frame = This->Allocate.PagedPool(&This->u.PagedList); + } + + if (Frame) + { + *OutFrame = Frame; + InterlockedIncrement((PLONG)This->Status.AllocatedFrames); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +VOID +NTAPI +IKsAllocator_fnFreeFrame( + IKsAllocator *iface, + IN PVOID Frame) +{ + PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); + + /* now allocate frame */ + if (This->Type == ALLOCATOR_CUSTOM) + { + This->Free.DefaultFree(This->u.CustomList, Frame); + } + else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE) + { + This->Free.NPagedPool(&This->u.NPagedList, Frame); + } + else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE) + { + This->Free.PagedPool(&This->u.PagedList, Frame); + } +} + + +static IKsAllocatorVtbl vt_IKsAllocator = +{ + IKsAllocator_fnQueryInterface, + IKsAllocator_fnAddRef, + IKsAllocator_fnRelease, + IKsAllocator_fnDeviceIoControl, + IKsAllocator_fnClose, + IKsAllocator_fnAllocateFrame, + IKsAllocator_fnFreeFrame +}; + /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS NTAPI KsCreateAllocator( @@ -10,8 +367,12 @@ KsCreateAllocator( IN PKSALLOCATOR_FRAMING AllocatorFraming, OUT PHANDLE AllocatorHandle) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + return KspCreateObjectType(ConnectionHandle, + L"{642F5D00-4791-11D0-A5D6-28DB04C10000}", //KSNAME_Allocator + (PVOID)AllocatorFraming, + sizeof(KSALLOCATOR_FRAMING), + GENERIC_READ, + AllocatorHandle); } /* @@ -36,8 +397,146 @@ KsValidateAllocatorCreateRequest( return STATUS_UNSUCCESSFUL; } +NTSTATUS +IKsAllocator_DispatchRequest( + IN PDEVICE_OBJECT DeviceObject, + IN PFILE_OBJECT FileObject, + IN PIRP Irp, + IN PVOID Frame, + IN ALLOC_REQUEST Request) +{ + PKSIOBJECT_HEADER Header; + NTSTATUS Status; + IKsAllocator * Allocator; + + /* sanity check */ + ASSERT(FileObject); + + /* get object header */ + Header = (PKSIOBJECT_HEADER)FileObject->FsContext; + + /* get real allocator */ + Status = Header->Unknown->lpVtbl->QueryInterface(Header->Unknown, &IID_IKsAllocator, (PVOID*)&Allocator); + + if (!NT_SUCCESS(Status)) + { + /* misbehaving object */ + return STATUS_UNSUCCESSFUL; + } + + if (Request == ALLOCATOR_DEVICE_CONTROL) + { + /* dispatch request allocator */ + Status = Allocator->lpVtbl->DispatchDeviceIoControl(Allocator, DeviceObject, Irp); + } + else if (Request == ALLOCATOR_DEVICE_CLOSE) + { + /* delete allocator */ + Status = Allocator->lpVtbl->Close(Allocator); + } + else if (Request == ALLOCATOR_ALLOCATE) + { + /* allocate frame */ + Status = Allocator->lpVtbl->AllocateFrame(Allocator, (PVOID*)Frame); + + }else if (Request == ALLOCATOR_FREE) + { + /* allocate frame */ + Allocator->lpVtbl->FreeFrame(Allocator, Frame); + Status = STATUS_SUCCESS; + } + + /* release interface */ + Allocator->lpVtbl->Release(Allocator); + + return Status; +} + +NTSTATUS +NTAPI +IKsAllocator_DispatchDeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* dispatch request */ + Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CONTROL); + + /* complete request */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +NTSTATUS +NTAPI +IKsAllocator_DispatchClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* dispatch request */ + Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CLOSE); + + /* complete request */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return Status; +} + +NTSTATUS +NTAPI +IKsAllocator_Allocate( + IN PFILE_OBJECT FileObject, + PVOID *Frame) +{ + NTSTATUS Status; + + /* dispatch request */ + Status = IKsAllocator_DispatchRequest(NULL, FileObject, NULL, (PVOID)Frame, ALLOCATOR_ALLOCATE); + + return Status; +} + +VOID +NTAPI +IKsAllocator_FreeFrame( + IN PFILE_OBJECT FileObject, + PVOID Frame) +{ + /* dispatch request */ + IKsAllocator_DispatchRequest(NULL, FileObject, NULL, Frame, ALLOCATOR_FREE); +} + + +static KSDISPATCH_TABLE DispatchTable = +{ + IKsAllocator_DispatchDeviceIoControl, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + IKsAllocator_DispatchClose, + KsDispatchQuerySecurity, + KsDispatchSetSecurity, + KsDispatchFastIoDeviceControlFailure, + KsDispatchFastReadFailure, + KsDispatchFastReadFailure, +}; + /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS NTAPI KsCreateDefaultAllocatorEx( @@ -50,17 +549,91 @@ KsCreateDefaultAllocatorEx( { NTSTATUS Status; PKSALLOCATOR_FRAMING AllocatorFraming; + PALLOCATOR Allocator; + PKSOBJECT_CREATE_ITEM CreateItem; + PVOID Ctx; - Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming); - if (!NT_SUCCESS(Status)) - return STATUS_INVALID_PARAMETER; + /* first validate connect request */ + Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming); + if (!NT_SUCCESS(Status)) + return STATUS_INVALID_PARAMETER; + /* check the valid file alignment */ + if (AllocatorFraming->FileAlignment > (PAGE_SIZE-1)) + return STATUS_INVALID_PARAMETER; - return STATUS_UNSUCCESSFUL; + /* allocate allocator struct */ + Allocator = AllocateItem(NonPagedPool, sizeof(ALLOCATOR)); + if (!Allocator) + return STATUS_INSUFFICIENT_RESOURCES; + + /* allocate object header */ + Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&Allocator->Header, 0, NULL, Irp, &DispatchTable); + if (!NT_SUCCESS(Status)) + { + FreeItem(Allocator); + return Status; + } + + /* set allocator type in object header */ + Allocator->lpVtbl = &vt_IKsAllocator; + Allocator->Header->Unknown = (PUNKNOWN)&Allocator->lpVtbl; + Allocator->ref = 1; + + if (DefaultAllocate) + { + /* use external allocator */ + Allocator->Type = ALLOCATOR_CUSTOM; + Allocator->Allocate.DefaultAllocate = DefaultAllocate; + Allocator->Free.DefaultFree = DefaultFree; + Allocator->Delete.DefaultDelete = DeleteAllocator; + Ctx = InitializeAllocator(InitializeContext, AllocatorFraming, &Allocator->u.CustomList); + /* check for success */ + if (!Ctx) + { + KsFreeObjectHeader(Allocator->Header); + FreeItem(Allocator); + return Status; + } + } + else if (AllocatorFraming->PoolType == NonPagedPool) + { + /* use non-paged pool allocator */ + Allocator->Type = ALLOCATOR_NPAGED_LOOKASIDE; + Allocator->Allocate.NPagedPool = ExAllocateFromNPagedLookasideList; + Allocator->Free.NPagedPool = ExFreeToNPagedLookasideList; + Allocator->Delete.NPagedPool = ExDeleteNPagedLookasideList; + ExInitializeNPagedLookasideList(&Allocator->u.NPagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0); + } + else if (AllocatorFraming->PoolType == PagedPool) + { + /* use paged pool allocator */ + Allocator->Allocate.PagedPool = ExAllocateFromPagedLookasideList; + Allocator->Free.PagedPool = ExFreeToPagedLookasideList; + Allocator->Delete.PagedPool = ExDeletePagedLookasideList; + Allocator->Type = ALLOCATOR_PAGED_LOOKASIDE; + ExInitializePagedLookasideList(&Allocator->u.PagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0); + + } + + /* backup allocator framing */ + RtlMoveMemory(&Allocator->Status.Framing, AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); + + /* get create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + + if (CreateItem) + { + /* store create item */ + Allocator->Header->CreateItem = CreateItem; + Allocator->Header->ItemCount = 1; + } + + return Status; } /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS NTAPI KsValidateAllocatorFramingEx( @@ -68,6 +641,18 @@ KsValidateAllocatorFramingEx( IN ULONG BufferSize, IN const KSALLOCATOR_FRAMING_EX* PinFraming) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + if (BufferSize < sizeof(KSALLOCATOR_FRAMING_EX)) + return STATUS_INVALID_DEVICE_REQUEST; + + /* verify framing */ + if ((Framing->FramingItem[0].Flags & KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT) && + Framing->OutputCompression.RatioNumerator != (ULONG)-1 && + Framing->OutputCompression.RatioDenominator != 0 && + Framing->OutputCompression.RatioDenominator < Framing->OutputCompression.RatioNumerator) + { + /* framing request is ok */ + return STATUS_SUCCESS; + } + + return STATUS_INVALID_DEVICE_REQUEST; } diff --git a/reactos/drivers/ksfilter/ks/api.c b/reactos/drivers/ksfilter/ks/api.c new file mode 100644 index 00000000000..9bdb16a374e --- /dev/null +++ b/reactos/drivers/ksfilter/ks/api.c @@ -0,0 +1,993 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/api.c + * PURPOSE: KS API functions + * PROGRAMMER: Johannes Anderwald + */ + + +#include "priv.h" + + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsAcquireResetValue( + IN PIRP Irp, + OUT KSRESET* ResetValue) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsAcquireDeviceSecurityLock( + IN KSDEVICE_HEADER DevHeader, + IN BOOLEAN Exclusive) +{ + NTSTATUS Status; + PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader; + + KeEnterCriticalRegion(); + + if (Exclusive) + { + Status = ExAcquireResourceExclusiveLite(&Header->SecurityLock, TRUE); + } + else + { + Status = ExAcquireResourceSharedLite(&Header->SecurityLock, TRUE); + } +} + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsReleaseDeviceSecurityLock( + IN KSDEVICE_HEADER DevHeader) +{ + PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader; + + ExReleaseResourceLite(&Header->SecurityLock); + KeLeaveCriticalRegion(); +} + +/* + @unimplemented +*/ + +KSDDKAPI +NTSTATUS +NTAPI +KsDefaultDispatchPnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status = STATUS_SUCCESS; + + IoStack = IoGetCurrentIrpStackLocation(Irp); + + //FIXME + //REWRITE + + DPRINT1("KsDefaultDispatchPnp entered with func %x\n", IoStack->MinorFunction); + + switch(IoStack->MinorFunction) + { + 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); + } + + return Status; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsDefaultDispatchPower( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; + + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +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; +} + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsSetDevicePnpAndBaseObject( + IN KSDEVICE_HEADER Header, + IN PDEVICE_OBJECT PnpDeviceObject, + IN PDEVICE_OBJECT BaseDevice) +{ + PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; + + DeviceHeader->PhysicalDeviceObject = PnpDeviceObject; + DeviceHeader->NextDeviceObject = BaseDevice; +} + +/* + @implemented +*/ +KSDDKAPI +PDEVICE_OBJECT +NTAPI +KsQueryDevicePnpObject( + IN KSDEVICE_HEADER Header) +{ + PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; + + /* return next device header */ + return DeviceHeader->NextDeviceObject; + +} + +/* + @unimplemented +*/ +KSDDKAPI +ACCESS_MASK +NTAPI +KsQueryObjectAccessMask( + IN KSOBJECT_HEADER Header) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +/* + @unimplemented +*/ +KSDDKAPI +VOID +NTAPI +KsRecalculateStackDepth( + IN KSDEVICE_HEADER Header, + IN BOOLEAN ReuseStackLocation) +{ + UNIMPLEMENTED; +} + + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsSetTargetState( + IN KSOBJECT_HEADER Header, + IN KSTARGET_STATE TargetState) +{ + PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; + + /* set target state */ + DeviceHeader->TargetState = TargetState; +} + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsSetTargetDeviceObject( + IN KSOBJECT_HEADER Header, + IN PDEVICE_OBJECT TargetDevice OPTIONAL) +{ + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header; + + if(ObjectHeader->TargetDevice) + { + /* there is already a target device set */ + if (!TargetDevice) + { + /* caller wants to remove the target device */ + DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->TargetDevice->DeviceExtension; + + /* get device header */ + DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; + + /* acquire lock */ + KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE); + + /* remove entry */ + RemoveEntryList(&ObjectHeader->TargetDeviceListEntry); + + /* remove device pointer */ + ObjectHeader->TargetDevice = NULL; + + /* release lock */ + KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); + } + } + else + { + /* no target device yet set */ + if (TargetDevice) + { + /* caller wants to add the target device */ + DeviceExtension = (PDEVICE_EXTENSION)TargetDevice->DeviceExtension; + + /* get device header */ + DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; + + /* acquire lock */ + KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE); + + /* insert list entry */ + InsertTailList(&DeviceHeader->TargetDeviceList, &ObjectHeader->TargetDeviceListEntry); + + /* store target device */ + ObjectHeader->TargetDevice = TargetDevice; + + /* release lock */ + KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); + } + } + +} + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsSetPowerDispatch( + IN KSOBJECT_HEADER Header, + IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL, + IN PVOID PowerContext OPTIONAL) +{ + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header; + + /* caller wants to add the target device */ + DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->ParentDeviceObject->DeviceExtension; + + /* get device header */ + DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; + + /* acquire lock */ + KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE); + + if (PowerDispatch) + { + /* add power dispatch entry */ + InsertTailList(&DeviceHeader->PowerDispatchList, &ObjectHeader->PowerDispatchEntry); + + /* store function and context */ + ObjectHeader->PowerDispatch = PowerDispatch; + ObjectHeader->PowerContext = PowerContext; + } + else + { + /* remove power dispatch entry */ + RemoveEntryList(&ObjectHeader->PowerDispatchEntry); + + /* store function and context */ + ObjectHeader->PowerDispatch = NULL; + ObjectHeader->PowerContext = NULL; + + } + + /* release lock */ + KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); +} + + +/* + @unimplemented +*/ +KSDDKAPI +PKSOBJECT_CREATE_ITEM +NTAPI +KsQueryObjectCreateItem( + IN KSOBJECT_HEADER Header) +{ + UNIMPLEMENTED; + return NULL; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsAllocateDeviceHeader( + OUT KSDEVICE_HEADER* OutHeader, + IN ULONG ItemsCount, + IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL) +{ + ULONG Index = 0; + PKSIDEVICE_HEADER Header; + + if (!OutHeader) + return STATUS_INVALID_PARAMETER; + + /* allocate a device header */ + Header = ExAllocatePoolWithTag(PagedPool, sizeof(KSIDEVICE_HEADER), TAG_DEVICE_HEADER); + + /* check for success */ + if (!Header) + return STATUS_INSUFFICIENT_RESOURCES; + + /* clear all memory */ + RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER)); + + /* initialize spin lock */ + KeInitializeSpinLock(&Header->ItemListLock); //FIXME + + /* initialize device mutex */ + KeInitializeMutex(&Header->DeviceMutex, 0); + + /* initialize target device list */ + InitializeListHead(&Header->TargetDeviceList); + /* initialize power dispatch list */ + InitializeListHead(&Header->PowerDispatchList); + + /* are there any create items provided */ + if (ItemsCount && ItemsList) + { + /* allocate space for device item list */ + Header->ItemList = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * ItemsCount, TAG_DEVICE_HEADER); + if (!Header->ItemList) + { + ExFreePoolWithTag(Header, TAG_DEVICE_HEADER); + return STATUS_INSUFFICIENT_RESOURCES; + } + RtlZeroMemory(Header->ItemList, sizeof(DEVICE_ITEM) * ItemsCount); + + for(Index = 0; Index < ItemsCount; Index++) + { + /* store provided create items */ + Header->ItemList[Index].CreateItem = &ItemsList[Index]; + } + Header->MaxItems = ItemsCount; + } + + /* store result */ + *OutHeader = Header; + + return STATUS_SUCCESS; +} + +/* + @unimplemented +*/ +KSDDKAPI +VOID +NTAPI +KsFreeDeviceHeader( + IN KSDEVICE_HEADER DevHeader) +{ + PKSIDEVICE_HEADER Header; + + Header = (PKSIDEVICE_HEADER)DevHeader; + + if (!DevHeader) + return; + + ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER); + ExFreePoolWithTag(Header, TAG_DEVICE_HEADER); +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsAllocateObjectHeader( + OUT KSOBJECT_HEADER *Header, + IN ULONG ItemsCount, + IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL, + IN PIRP Irp, + IN KSDISPATCH_TABLE* Table) +{ + PIO_STACK_LOCATION IoStack; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + PKSIOBJECT_HEADER ObjectHeader; + + if (!Header) + return STATUS_INVALID_PARAMETER_1; + + if (!Irp) + return STATUS_INVALID_PARAMETER_4; + + if (!Table) + return STATUS_INVALID_PARAMETER_5; + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + + /* sanity check */ + ASSERT(IoStack->FileObject); + /* check for an file object */ + + /* allocate the object header */ + ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER); + if (!ObjectHeader) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize object header */ + RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER)); + + /* do we have a name */ + if (IoStack->FileObject->FileName.Buffer) + { + /* copy object class */ + ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength; + ObjectHeader->ObjectClass.Buffer = ExAllocatePoolWithTag(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength, TAG_DEVICE_HEADER); + if (!ObjectHeader->ObjectClass.Buffer) + { + ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER); + return STATUS_INSUFFICIENT_RESOURCES; + } + RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName); + } + + /* copy dispatch table */ + RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE)); + /* store create items */ + if (ItemsCount && ItemsList) + { + ObjectHeader->ItemCount = ItemsCount; + ObjectHeader->CreateItem = ItemsList; + } + + /* store the object in the file object */ + ASSERT(IoStack->FileObject->FsContext == NULL); + IoStack->FileObject->FsContext = ObjectHeader; + + /* the object header is for a audio filter */ + ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems); + + /* store parent device */ + ObjectHeader->ParentDeviceObject = IoGetRelatedDeviceObject(IoStack->FileObject); + + /* store result */ + *Header = ObjectHeader; + + + + DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader); + + return STATUS_SUCCESS; + +} + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsFreeObjectHeader( + IN PVOID Header) +{ + PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER) Header; + + if (ObjectHeader->ObjectClass.Buffer) + { + /* release object class buffer */ + ExFreePoolWithTag(ObjectHeader->ObjectClass.Buffer, TAG_DEVICE_HEADER); + } + + if (ObjectHeader->Unknown) + { + /* release associated object */ + ObjectHeader->Unknown->lpVtbl->Release(ObjectHeader->Unknown); + } + + /* FIXME free create items */ + + /* free object header */ + ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER); + +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsAddObjectCreateItemToDeviceHeader( + IN KSDEVICE_HEADER DevHeader, + IN PDRIVER_DISPATCH Create, + IN PVOID Context, + IN PWCHAR ObjectClass, + IN PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + PKSIDEVICE_HEADER Header; + ULONG FreeIndex, Index; + + Header = (PKSIDEVICE_HEADER)DevHeader; + + DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n"); + + /* check if a device header has been provided */ + if (!DevHeader) + return STATUS_INVALID_PARAMETER_1; + + /* check if a create item has been provided */ + if (!Create) + return STATUS_INVALID_PARAMETER_2; + + /* check if a object class has been provided */ + if (!ObjectClass) + return STATUS_INVALID_PARAMETER_4; + + FreeIndex = (ULONG)-1; + /* now scan the list and check for a free item */ + for(Index = 0; Index < Header->MaxItems; Index++) + { + ASSERT(Header->ItemList[Index].CreateItem); + + if (Header->ItemList[Index].CreateItem->Create == NULL) + { + FreeIndex = Index; + break; + } + + if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem->ObjectClass.Buffer)) + { + /* the same object class already exists */ + return STATUS_OBJECT_NAME_COLLISION; + } + } + /* found a free index */ + if (FreeIndex == (ULONG)-1) + { + /* no empty space found */ + return STATUS_ALLOTTED_SPACE_EXCEEDED; + } + + /* initialize create item */ + Header->ItemList[FreeIndex].CreateItem->Create = Create; + Header->ItemList[FreeIndex].CreateItem->Context = Context; + RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem->ObjectClass, ObjectClass); + Header->ItemList[FreeIndex].CreateItem->SecurityDescriptor = SecurityDescriptor; + + + return STATUS_SUCCESS; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsAddObjectCreateItemToObjectHeader( + IN KSOBJECT_HEADER Header, + IN PDRIVER_DISPATCH Create, + IN PVOID Context, + IN PWCHAR ObjectClass, + IN PSECURITY_DESCRIPTOR SecurityDescriptor) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsAllocateObjectCreateItem( + IN KSDEVICE_HEADER DevHeader, + IN PKSOBJECT_CREATE_ITEM CreateItem, + IN BOOLEAN AllocateEntry, + IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL) +{ + PKSIDEVICE_HEADER Header; + PKSOBJECT_CREATE_ITEM Item; + PDEVICE_ITEM ItemList; + KIRQL OldLevel; + + Header = (PKSIDEVICE_HEADER)DevHeader; + + if (!DevHeader) + return STATUS_INVALID_PARAMETER_1; + + if (!CreateItem) + return STATUS_INVALID_PARAMETER_2; + + /* acquire list lock */ + KeAcquireSpinLock(&Header->ItemListLock, &OldLevel); + + ItemList = ExAllocatePool(NonPagedPool, sizeof(DEVICE_ITEM) * (Header->MaxItems + 1)); + if (!ItemList) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + if (AllocateEntry) + { + if (!ItemFreeCallback) + { + /* caller must be notified */ + ExFreePool(ItemList); + /* release lock */ + KeReleaseSpinLock(&Header->ItemListLock, OldLevel); + + return STATUS_INVALID_PARAMETER_4; + } + /* allocate create item */ + Item = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); + if (!Item) + { + /* no memory */ + ExFreePool(ItemList); + /* release lock */ + KeReleaseSpinLock(&Header->ItemListLock, OldLevel); + + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize descriptor */ + Item->Context = CreateItem->Context; + Item->Create = CreateItem->Create; + Item->Flags = CreateItem->Flags; + Item->SecurityDescriptor = CreateItem->SecurityDescriptor; + Item->ObjectClass.Length = 0; + Item->ObjectClass.MaximumLength = CreateItem->ObjectClass.MaximumLength; + + /* copy object class */ + Item->ObjectClass.Buffer = ExAllocatePool(NonPagedPool, Item->ObjectClass.MaximumLength); + if (!Item->ObjectClass.Buffer) + { + /* release resources */ + ExFreePool(Item); + ExFreePool(ItemList); + + /* release lock */ + KeReleaseSpinLock(&Header->ItemListLock, OldLevel); + + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlCopyUnicodeString(&Item->ObjectClass, &CreateItem->ObjectClass); + } + else + { + if (ItemFreeCallback) + { + /* callback is only accepted when the create item is copied */ + ExFreePool(ItemList); + /* release lock */ + KeReleaseSpinLock(&Header->ItemListLock, OldLevel); + + return STATUS_INVALID_PARAMETER_4; + } + + Item = CreateItem; + } + + + if (Header->MaxItems) + { + /* copy old create items */ + RtlMoveMemory(ItemList, Header->ItemList, sizeof(DEVICE_ITEM) * Header->MaxItems); + } + + /* initialize item entry */ + ItemList[Header->MaxItems].CreateItem = Item; + ItemList[Header->MaxItems].ItemFreeCallback = ItemFreeCallback; + + + /* free old item list */ + ExFreePool(Header->ItemList); + + Header->ItemList = ItemList; + Header->MaxItems++; + + /* release lock */ + KeReleaseSpinLock(&Header->ItemListLock, OldLevel); + + return STATUS_SUCCESS; + +} + +NTSTATUS +KspObjectFreeCreateItems( + IN KSDEVICE_HEADER Header, + IN PKSOBJECT_CREATE_ITEM CreateItem) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsFreeObjectCreateItem( + IN KSDEVICE_HEADER Header, + IN PUNICODE_STRING CreateItem) +{ + KSOBJECT_CREATE_ITEM Item; + + RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM)); + RtlInitUnicodeString(&Item.ObjectClass, CreateItem->Buffer); + + return KspObjectFreeCreateItems(Header, &Item); +} + + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsFreeObjectCreateItemsByContext( + IN KSDEVICE_HEADER Header, + IN PVOID Context) +{ + KSOBJECT_CREATE_ITEM Item; + + RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM)); + + Item.Context = Context; + + return KspObjectFreeCreateItems(Header, &Item); +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsCreateDefaultSecurity( + IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL, + OUT PSECURITY_DESCRIPTOR* DefaultSecurity) +{ + PGENERIC_MAPPING Mapping; + SECURITY_SUBJECT_CONTEXT SubjectContext; + NTSTATUS Status; + + /* start capturing security context of calling thread */ + SeCaptureSubjectContext(&SubjectContext); + /* get generic mapping */ + Mapping = IoGetFileObjectGenericMapping(); + /* build new descriptor */ + Status = SeAssignSecurity(ParentSecurity, NULL, DefaultSecurity, FALSE, &SubjectContext, Mapping, NonPagedPool); + /* release security descriptor */ + SeReleaseSubjectContext(&SubjectContext); + /* done */ + return Status; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsForwardIrp( + IN PIRP Irp, + IN PFILE_OBJECT FileObject, + IN BOOLEAN ReuseStackLocation) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsForwardAndCatchIrp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PFILE_OBJECT FileObject, + IN KSSTACK_USE StackUse) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + + +NTSTATUS +NTAPI +KspSynchronousIoControlDeviceCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)Context; + + IoStatusBlock->Information = Irp->IoStatus.Information; + IoStatusBlock->Status = Irp->IoStatus.Status; + + return STATUS_SUCCESS; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsSynchronousIoControlDevice( + IN PFILE_OBJECT FileObject, + IN KPROCESSOR_MODE RequestorMode, + IN ULONG IoControl, + IN PVOID InBuffer, + IN ULONG InSize, + OUT PVOID OutBuffer, + IN ULONG OutSize, + OUT PULONG BytesReturned) +{ + PKSIOBJECT_HEADER ObjectHeader; + PDEVICE_OBJECT DeviceObject; + KEVENT Event; + PIRP Irp; + IO_STATUS_BLOCK IoStatusBlock; + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + /* check for valid file object */ + if (!FileObject) + return STATUS_INVALID_PARAMETER; + + /* get device object to send the request to */ + DeviceObject = IoGetRelatedDeviceObject(FileObject); + if (!DeviceObject) + return STATUS_UNSUCCESSFUL; + + + /* get object header */ + ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext; + + /* check if there is fast device io function */ + if (ObjectHeader && ObjectHeader->DispatchTable.FastDeviceIoControl) + { + IoStatusBlock.Status = STATUS_UNSUCCESSFUL; + IoStatusBlock.Information = 0; + + /* it is send the request */ + Status = ObjectHeader->DispatchTable.FastDeviceIoControl(FileObject, TRUE, InBuffer, InSize, OutBuffer, OutSize, IoControl, &IoStatusBlock, DeviceObject); + /* check if the request was handled */ + DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information); + if (Status) + { + /* store bytes returned */ + *BytesReturned = IoStatusBlock.Information; + /* return status */ + return IoStatusBlock.Status; + } + } + + /* initialize the event */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + /* create the irp */ + Irp = IoBuildDeviceIoControlRequest(IoControl, DeviceObject, InBuffer, InSize, OutBuffer, OutSize, FALSE, &Event, &IoStatusBlock); + + /* HACK */ + IoStack = IoGetNextIrpStackLocation(Irp); + IoStack->FileObject = FileObject; + + IoSetCompletionRoutine(Irp, KspSynchronousIoControlDeviceCompletion, (PVOID)&IoStatusBlock, TRUE, TRUE, TRUE); + + Status = IoCallDriver(DeviceObject, Irp); + if (Status == STATUS_PENDING) + { + KeWaitForSingleObject(&Event, Executive, RequestorMode, FALSE, NULL); + Status = IoStatusBlock.Status; + } + + *BytesReturned = IoStatusBlock.Information; + return Status; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsUnserializeObjectPropertiesFromRegistry( + IN PFILE_OBJECT FileObject, + IN HANDLE ParentKey OPTIONAL, + IN PUNICODE_STRING RegistryPath OPTIONAL) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsCacheMedium( + IN PUNICODE_STRING SymbolicLink, + IN PKSPIN_MEDIUM Medium, + IN ULONG PinDirection) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + diff --git a/reactos/drivers/ksfilter/ks/bag.c b/reactos/drivers/ksfilter/ks/bag.c index c6f288dc764..bde0b33d6b5 100644 --- a/reactos/drivers/ksfilter/ks/bag.c +++ b/reactos/drivers/ksfilter/ks/bag.c @@ -1,3 +1,12 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/bag.c + * PURPOSE: KS Object Bag functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" diff --git a/reactos/drivers/ksfilter/ks/clocks.c b/reactos/drivers/ksfilter/ks/clocks.c index bc34145568b..b117b739f61 100644 --- a/reactos/drivers/ksfilter/ks/clocks.c +++ b/reactos/drivers/ksfilter/ks/clocks.c @@ -1,12 +1,43 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/clocks.c + * PURPOSE: KS Clocks functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" typedef struct { + LONGLONG Time; + KSPIN_LOCK TimeLock; + KSSTATE State; + KTIMER Timer; + LONG ReferenceCount; + + PVOID Context; + PFNKSSETTIMER SetTimer; + PFNKSCANCELTIMER CancelTimer; + PFNKSCORRELATEDTIME CorrelatedTime; + KSRESOLUTION* Resolution; + ULONG Flags; + +}KSIDEFAULTCLOCK, *PKSIDEFAULTCLOCK; + +typedef struct +{ + IKsClock *lpVtbl; + LONG ref; + PKSCLOCK_CREATE ClockCreate; + PKSIDEFAULTCLOCK DefaultClock; + PKSIOBJECT_HEADER ObjectHeader; +}KSICLOCK, *PKSICLOCK; -}KS_DEFAULT_CLOCK; /* - @unimplemented + @implemented */ KSDDKAPI NTSTATUS NTAPI KsCreateClock( @@ -14,36 +45,136 @@ KsCreateClock( IN PKSCLOCK_CREATE ClockCreate, OUT PHANDLE ClockHandle) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + return KspCreateObjectType(ConnectionHandle, + L"{53172480-4791-11D0-A5D6-28DB04C10000}", /* KSName_Clock */ + ClockCreate, + sizeof(KSCLOCK_CREATE), + GENERIC_READ, + ClockHandle); } /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI +KsValidateClockCreateRequest( + IN PIRP Irp, + OUT PKSCLOCK_CREATE* ClockCreate) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +IKsClock_DispatchDeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsClock_DispatchClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_NOT_IMPLEMENTED; +} + + + +static KSDISPATCH_TABLE DispatchTable = +{ + IKsClock_DispatchDeviceIoControl, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + IKsClock_DispatchClose, + KsDispatchQuerySecurity, + KsDispatchSetSecurity, + KsDispatchFastIoDeviceControlFailure, + KsDispatchFastReadFailure, + KsDispatchFastReadFailure, +}; + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI KsCreateDefaultClock( IN PIRP Irp, IN PKSDEFAULTCLOCK DefaultClock) { NTSTATUS Status; PKSCLOCK_CREATE ClockCreate; + PKSICLOCK Clock; + PKSOBJECT_CREATE_ITEM CreateItem; Status = KsValidateClockCreateRequest(Irp, &ClockCreate); if (!NT_SUCCESS(Status)) return Status; -// ExAllocatePoolWithTag(NonPagedPool, sizeof(KS_DEFAULT_CLOCK), 0); + /* let's allocate the clock struct */ + Clock = AllocateItem(NonPagedPool, sizeof(KSICLOCK)); + if (!Clock) + return STATUS_INSUFFICIENT_RESOURCES; + /* now allocate the object header */ + Status = KsAllocateObjectHeader((PVOID*)&Clock->ObjectHeader, 0, NULL, Irp, &DispatchTable); + /* did it work */ + if (!NT_SUCCESS(Status)) + { + /* failed */ + FreeItem(Clock); + return Status; + } - return STATUS_UNSUCCESSFUL; + /* initialize clock */ + /* FIXME IKsClock */ + Clock->ObjectHeader->Unknown = (PUNKNOWN)&Clock->lpVtbl; + Clock->ref = 1; + Clock->ClockCreate = ClockCreate; + Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock; + + /* increment reference count */ + InterlockedIncrement(&Clock->DefaultClock->ReferenceCount); + + /* get create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + + if (CreateItem) + { + /* store create item */ + Clock->ObjectHeader->CreateItem = CreateItem; + Clock->ObjectHeader->ItemCount = 1; + } + + return Status; } /* @implemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsAllocateDefaultClock( OUT PKSDEFAULTCLOCK* DefaultClock) { @@ -53,7 +184,9 @@ KsAllocateDefaultClock( /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsAllocateDefaultClockEx( OUT PKSDEFAULTCLOCK* DefaultClock, IN PVOID Context OPTIONAL, @@ -63,72 +196,113 @@ KsAllocateDefaultClockEx( IN const KSRESOLUTION* Resolution OPTIONAL, IN ULONG Flags) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PKSIDEFAULTCLOCK Clock; + + if (!DefaultClock) + return STATUS_INVALID_PARAMETER_1; + + /* allocate default clock */ + Clock = AllocateItem(NonPagedPool, sizeof(KSIDEFAULTCLOCK)); + if (!Clock) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize default clock */ + KeInitializeSpinLock(&Clock->TimeLock); + KeInitializeTimer(&Clock->Timer); + Clock->ReferenceCount = 1; + Clock->Context = Context; + Clock->SetTimer = SetTimer; + Clock->CancelTimer = CancelTimer; + Clock->CorrelatedTime = CorrelatedTime; + Clock->Resolution = (PKSRESOLUTION)Resolution; + Clock->Flags = Flags; + + *DefaultClock = (PKSDEFAULTCLOCK)Clock; + return STATUS_SUCCESS; } /* - @unimplemented + @implemented */ -KSDDKAPI VOID NTAPI +KSDDKAPI +VOID +NTAPI KsFreeDefaultClock( IN PKSDEFAULTCLOCK DefaultClock) { - UNIMPLEMENTED; + PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock; + + InterlockedDecrement(&Clock->ReferenceCount); + + if (Clock->ReferenceCount == 0) + { + /* free default clock */ + FreeItem(Clock); + } } /* - @unimplemented + @implemented */ -KSDDKAPI NTSTATUS NTAPI -KsValidateClockCreateRequest( - IN PIRP Irp, - OUT PKSCLOCK_CREATE* ClockCreate) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI KSSTATE NTAPI +KSDDKAPI +KSSTATE +NTAPI KsGetDefaultClockState( IN PKSDEFAULTCLOCK DefaultClock) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock; + return Clock->State; } /* @unimplemented */ -KSDDKAPI VOID NTAPI +KSDDKAPI +VOID +NTAPI KsSetDefaultClockState( IN PKSDEFAULTCLOCK DefaultClock, IN KSSTATE State) { - UNIMPLEMENTED; + PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock; + + if (State != Clock->State) + { + /* FIXME set time etc */ + Clock->State = State; + } + } /* - @unimplemented + @implemented */ -KSDDKAPI LONGLONG NTAPI +KSDDKAPI +LONGLONG +NTAPI KsGetDefaultClockTime( IN PKSDEFAULTCLOCK DefaultClock) { - UNIMPLEMENTED; - return 0; + LONGLONG Time = 0LL; + PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock; + + Time = ExInterlockedCompareExchange64(&Clock->Time, &Time, &Time, &Clock->TimeLock); + + return Time; } /* - @unimplemented + @implemented */ -KSDDKAPI VOID NTAPI +KSDDKAPI +VOID +NTAPI KsSetDefaultClockTime( IN PKSDEFAULTCLOCK DefaultClock, IN LONGLONG Time) { - UNIMPLEMENTED; + PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock; + + /* set the time safely */ + ExInterlockedCompareExchange64(&Clock->Time, &Time, &Clock->Time, &Clock->TimeLock); } diff --git a/reactos/drivers/ksfilter/ks/connectivity.c b/reactos/drivers/ksfilter/ks/connectivity.c index 73921ee2163..13e26b53906 100644 --- a/reactos/drivers/ksfilter/ks/connectivity.c +++ b/reactos/drivers/ksfilter/ks/connectivity.c @@ -1,3 +1,12 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/connectivity.c + * PURPOSE: KS Pin functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" /* @@ -437,9 +446,13 @@ KsPinDataIntersection( return STATUS_NO_MATCH; } -/* Does this belong here? */ +/* + @unimplemented +*/ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsHandleSizedListQuery( IN PIRP Irp, IN ULONG DataItemsCount, diff --git a/reactos/drivers/ksfilter/ks/device.c b/reactos/drivers/ksfilter/ks/device.c index 36ce5570b0c..00c5d852022 100644 --- a/reactos/drivers/ksfilter/ks/device.c +++ b/reactos/drivers/ksfilter/ks/device.c @@ -1,26 +1,31 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/device.c + * PURPOSE: KS IKsDevice interface functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" -typedef struct -{ - IKsDeviceVtbl *lpVtbl; - - LONG ref; - KSDEVICE KsDevice; - -}IKsDeviceImpl; - - NTSTATUS NTAPI IKsDevice_fnQueryInterface( IN IKsDevice * iface, - REFIID InterfaceId, - PVOID* Interface) + REFIID refiid, + PVOID* Output) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnQueryInterface %p\n", This); - return STATUS_NOT_IMPLEMENTED; + if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtblIKsDevice; + _InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + + return STATUS_NOT_SUPPORTED; } ULONG @@ -28,7 +33,7 @@ NTAPI IKsDevice_fnAddRef( IN IKsDevice * iface) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); return InterlockedIncrement(&This->ref); } @@ -38,27 +43,21 @@ NTAPI IKsDevice_fnRelease( IN IKsDevice * iface) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); InterlockedDecrement(&This->ref); - if (This->ref == 0) - { - ExFreePoolWithTag(This, TAG_KSDEVICE); - return 0; - } - return This->ref; } -KSDEVICE * +PKSDEVICE NTAPI IKsDevice_fnGetStruct( IN IKsDevice * iface) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); return &This->KsDevice; } @@ -70,9 +69,9 @@ IKsDevice_fnInitializeObjectBag( IN struct KSIOBJECTBAG *Bag, IN KMUTANT * Mutant) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnInitializeObjectBag %p\n", This); + UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -81,10 +80,9 @@ NTAPI IKsDevice_fnAcquireDevice( IN IKsDevice * iface) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnAcquireDevice %p\n", This); - return STATUS_NOT_IMPLEMENTED; + return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL); } NTSTATUS @@ -92,10 +90,9 @@ NTAPI IKsDevice_fnReleaseDevice( IN IKsDevice * iface) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnReleaseDevice %p\n", This); - return STATUS_NOT_IMPLEMENTED; + return KeReleaseMutex(&This->DeviceMutex, FALSE); } NTSTATUS @@ -106,9 +103,9 @@ IKsDevice_fnGetAdapterObject( IN PULONG Unknown1, IN PULONG Unknown2) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnGetAdapterObject %p\n", This); + UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -120,9 +117,9 @@ IKsDevice_fnAddPowerEntry( IN struct KSPOWER_ENTRY * Entry, IN IKsPowerNotify* Notify) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnAddPowerEntry %p\n", This); + UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -132,9 +129,9 @@ IKsDevice_fnRemovePowerEntry( IN IKsDevice * iface, IN struct KSPOWER_ENTRY * Entry) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnRemovePowerEntry %p\n", This); + UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -148,9 +145,9 @@ IKsDevice_fnPinStateChange( IN KSSTATE OldState, IN KSSTATE NewState) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnPinStateChange %p\n", This); + UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -163,9 +160,9 @@ IKsDevice_fnArbitrateAdapterChannel( IN IO_ALLOCATION_ACTION Action, IN PVOID Context) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnArbitrateAdapterChannel %p\n", This); + UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -176,9 +173,9 @@ IKsDevice_fnCheckIoCapability( IN IKsDevice * iface, IN ULONG Unknown) { - IKsDeviceImpl * This = (IKsDeviceImpl*)iface; + //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice); - DPRINT1("IKsDevice_fnCheckIoCapability %p\n", This); + UNIMPLEMENTED return STATUS_NOT_IMPLEMENTED; } @@ -200,21 +197,487 @@ static IKsDeviceVtbl vt_IKsDevice = }; +VOID +NTAPI +IKsDevice_PnpPostStart( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + NTSTATUS Status; + PPNP_POSTSTART_CONTEXT Ctx = (PPNP_POSTSTART_CONTEXT)Context; + + /* call driver pnp post routine */ + Status = Ctx->DeviceHeader->Descriptor->Dispatch->PostStart(&Ctx->DeviceHeader->KsDevice); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Driver: PostStart Routine returned %x\n", Status); + + /* set state to disabled */ + Ctx->DeviceHeader->TargetState = KSTARGET_STATE_DISABLED; + } + else + { + /* set state to enabled */ + Ctx->DeviceHeader->TargetState = KSTARGET_STATE_ENABLED; + } + + /* free work item */ + IoFreeWorkItem(Ctx->WorkItem); + + /* free work context */ + FreeItem(Ctx); +} NTSTATUS NTAPI -NewIKsDevice(IKsDevice** OutDevice) +IKsDevice_PnpStartDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { - IKsDeviceImpl * This; + PIO_STACK_LOCATION IoStack; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + PPNP_POSTSTART_CONTEXT Ctx = NULL; + NTSTATUS Status; - This = ExAllocatePoolWithTag(NonPagedPool, sizeof(IKsDeviceImpl), TAG_KSDEVICE); - if (!This) - return STATUS_INSUFFICIENT_RESOURCES; + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; - This->ref = 1; - This->lpVtbl = &vt_IKsDevice; + /* first forward irp to lower device object */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("NextDevice object failed to start with %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + /* do we have a device descriptor */ + if (DeviceHeader->Descriptor) + { + /* does the device want pnp notifications */ + if (DeviceHeader->Descriptor->Dispatch) + { + /* does the driver care about IRP_MN_START_DEVICE */ + if (DeviceHeader->Descriptor->Dispatch->Start) + { + /* call driver start device routine */ + Status = DeviceHeader->Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp, + IoStack->Parameters.StartDevice.AllocatedResourcesTranslated, + IoStack->Parameters.StartDevice.AllocatedResources); + + ASSERT(Status != STATUS_PENDING); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Driver: failed to start %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + /* set state to run */ + DeviceHeader->KsDevice.Started = TRUE; + + } + + /* does the driver need post start routine */ + if (DeviceHeader->Descriptor->Dispatch->PostStart) + { + /* allocate pnp post workitem context */ + Ctx = (PPNP_POSTSTART_CONTEXT)AllocateItem(NonPagedPool, sizeof(PNP_POSTSTART_CONTEXT)); + if (!Ctx) + { + /* no memory */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + /* allocate a work item */ + Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); + + if (!Ctx->WorkItem) + { + /* no memory */ + FreeItem(Ctx); + Ctx = NULL; + Status = STATUS_INSUFFICIENT_RESOURCES; + } + else + { + /* store device header for post-start pnp processing */ + Ctx->DeviceHeader = DeviceHeader; + } + } + } + else + { + /* set state to enabled, IRP_MJ_CREATE request may now succeed */ + DeviceHeader->TargetState = KSTARGET_STATE_ENABLED; + } + } + } + + /* store result */ + Irp->IoStatus.Status = Status; + /* complete request */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + if (Ctx) + { + /* queue a work item for driver post start routine */ + IoQueueWorkItem(Ctx->WorkItem, IKsDevice_PnpPostStart, DelayedWorkQueue, (PVOID)Ctx); + } + + /* return result */ + return Status; +} + +NTSTATUS +NTAPI +IKsDevice_Pnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + PKSDEVICE_DISPATCH Dispatch = NULL; + NTSTATUS Status; + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + + /* do we have a device descriptor */ + if (DeviceHeader->Descriptor) + { + /* does the device want pnp notifications */ + Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->Descriptor->Dispatch; + } + + switch (IoStack->MinorFunction) + { + case IRP_MN_START_DEVICE: + { + return IKsDevice_PnpStartDevice(DeviceObject, Irp); + } + + case IRP_MN_QUERY_STOP_DEVICE: + { + Status = STATUS_SUCCESS; + /* check for pnp notification support */ + if (Dispatch) + { + /* check for query stop support */ + if (Dispatch->QueryStop) + { + /* call driver's query stop */ + Status = Dispatch->QueryStop(&DeviceHeader->KsDevice, Irp); + ASSERT(Status != STATUS_PENDING); + } + } + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Driver: query stop failed %x\n", Status); + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + DPRINT("Next Device: Status %x\n", Status); + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + case IRP_MN_REMOVE_DEVICE: + { + /* Clean up */ + if (Dispatch) + { + /* check for remove support */ + if (Dispatch->Remove) + { + /* call driver's stop routine */ + Dispatch->Remove(&DeviceHeader->KsDevice, Irp); + } + } + + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + DPRINT("Next Device: Status %x\n", Status); + + /* FIXME delete device resources */ + + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + case IRP_MN_QUERY_INTERFACE: + { + Status = STATUS_SUCCESS; + /* check for pnp notification support */ + if (Dispatch) + { + /* check for query interface support */ + if (Dispatch->QueryInterface) + { + /* call driver's query interface */ + Status = Dispatch->QueryInterface(&DeviceHeader->KsDevice, Irp); + ASSERT(Status != STATUS_PENDING); + } + } + + if (NT_SUCCESS(Status)) + { + /* driver supports a private interface */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + DPRINT("Next Device: Status %x\n", Status); + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + case IRP_MN_QUERY_DEVICE_RELATIONS: + { + DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n"); + + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + DPRINT("Next Device: Status %x\n", Status); + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: + { + DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + DPRINT("Next Device: Status %x\n", Status); + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: + { + DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n"); + /* pass the irp down the driver stack */ + Status = KspForwardIrpSynchronous(DeviceObject, Irp); + + DPRINT("Next Device: Status %x\n", Status); + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + default: + DPRINT1("unhandled function %u\n", IoStack->MinorFunction); + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_SUPPORTED; + } +} + +NTSTATUS +NTAPI +IKsDevice_Power( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED + + /* TODO */ + + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); - *OutDevice = (IKsDevice*)This; return STATUS_SUCCESS; } +NTSTATUS +NTAPI +IKsDevice_Create( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + ULONG Index; + NTSTATUS Status; + ULONG Length; + + DPRINT("KS / CREATE\n"); + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + + /* acquire list lock */ + IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice); + + /* sanity check */ + ASSERT(IoStack->FileObject); + + /* loop all device items */ + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + /* is there a create item */ + if (DeviceHeader->ItemList[Index].CreateItem == NULL) + continue; + + /* check if the create item is initialized */ + if (!DeviceHeader->ItemList[Index].CreateItem->Create) + continue; + + ASSERT(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + DPRINT("CreateItem %p Request %S\n", DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, + IoStack->FileObject->FileName.Buffer); + + /* get object class length */ + Length = wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + /* now check if the object class is the same */ + if (!_wcsnicmp(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, &IoStack->FileObject->FileName.Buffer[1], Length) || + (DeviceHeader->ItemList[Index].CreateItem->Flags & KSCREATE_ITEM_WILDCARD)) + { + /* setup create parameters */ + DeviceHeader->DeviceIndex = Index; + /* set object create item */ + KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[Index].CreateItem; + + /* call create function */ + Status = DeviceHeader->ItemList[Index].CreateItem->Create(DeviceObject, Irp); + + /* release lock */ + IKsDevice_fnRelease((IKsDevice*)&DeviceHeader->lpVtblIKsDevice); + + /* did we succeed */ + if (NT_SUCCESS(Status)) + { + /* increment create item reference count */ + InterlockedIncrement((PLONG)&DeviceHeader->ItemList[Index].ReferenceCount); + } + + /* return result */ + return Status; + } + } + + /* release lock */ + IKsDevice_fnRelease((IKsDevice*)&DeviceHeader->lpVtblIKsDevice); + + Irp->IoStatus.Information = 0; + /* set return status */ + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_UNSUCCESSFUL; +} + + + + + + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsInitializeDevice( + IN PDEVICE_OBJECT FunctionalDeviceObject, + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN PDEVICE_OBJECT NextDeviceObject, + IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL) +{ + PKSIDEVICE_HEADER Header; + ULONG Index; + NTSTATUS Status = STATUS_SUCCESS; + + /* first allocate device header */ + Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&Header, 0, NULL); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to allocate device header with %x\n", Status); + return Status; + } + + /* initialize device header */ + Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject; + Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject; + Header->KsDevice.NextDeviceObject = NextDeviceObject; + Header->KsDevice.Descriptor = Descriptor; + KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject); + /* initialize IKsDevice interface */ + Header->lpVtblIKsDevice = &vt_IKsDevice; + Header->ref = 1; + + /* FIXME Power state */ + + if (Descriptor) + { + /* create a filter factory for each filter descriptor */ + for(Index = 0; Index < Descriptor->FilterDescriptorsCount; Index++) + { + Status = KspCreateFilterFactory(FunctionalDeviceObject, Descriptor->FilterDescriptors[Index], NULL, NULL, 0, NULL, NULL, NULL); + /* check for success */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("KspCreateFilterFactory failed with %x\n", Status); + /* FIXME memory leak */ + return Status; + } + } + + /* does the driver pnp notification */ + if (Descriptor->Dispatch) + { + /* does the driver care about the add device */ + Status = Descriptor->Dispatch->Add(&Header->KsDevice); + + DPRINT("Driver: AddHandler Status %x\n", Status); + } + } + + + return Status; +} + + + diff --git a/reactos/drivers/ksfilter/ks/deviceinterface.c b/reactos/drivers/ksfilter/ks/deviceinterface.c new file mode 100644 index 00000000000..05546c32080 --- /dev/null +++ b/reactos/drivers/ksfilter/ks/deviceinterface.c @@ -0,0 +1,98 @@ +#include "priv.h" + +NTSTATUS +KspSetDeviceInterfacesState( + IN PLIST_ENTRY ListHead, + IN BOOL Enable) +{ + NTSTATUS Status = STATUS_SUCCESS; + PLIST_ENTRY Entry; + PSYMBOLIC_LINK_ENTRY SymEntry; + + + Entry = ListHead->Flink; + while(Entry != ListHead) + { + /* fetch symbolic link entry */ + SymEntry = (PSYMBOLIC_LINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLIC_LINK_ENTRY, Entry); + /* set device interface state */ + Status = IoSetDeviceInterfaceState(&SymEntry->SymbolicLink, Enable); + /* check for success */ + if (!NT_SUCCESS(Status)) + return Status; + /* get next entry */ + Entry = Entry->Flink; + } + /* return result */ + return Status; +} + +NTSTATUS +KspFreeDeviceInterfaces( + IN PLIST_ENTRY ListHead) +{ + PLIST_ENTRY Entry; + PSYMBOLIC_LINK_ENTRY SymEntry; + + while(!IsListEmpty(ListHead)) + { + /* remove first entry */ + Entry = RemoveHeadList(ListHead); + + /* fetch symbolic link entry */ + SymEntry = (PSYMBOLIC_LINK_ENTRY)CONTAINING_RECORD(Entry, SYMBOLIC_LINK_ENTRY, Entry); + + /* free device interface string */ + RtlFreeUnicodeString(&SymEntry->SymbolicLink); + /* free entry item */ + FreeItem(Entry); + } + + return STATUS_SUCCESS; +} + +NTSTATUS +KspRegisterDeviceInterfaces( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN ULONG CategoriesCount, + IN GUID const*Categories, + IN PUNICODE_STRING ReferenceString, + OUT PLIST_ENTRY SymbolicLinkList) +{ + ULONG Index; + NTSTATUS Status = STATUS_SUCCESS; + PSYMBOLIC_LINK_ENTRY SymEntry; + + for(Index = 0; Index < CategoriesCount; Index++) + { + /* allocate a symbolic link entry */ + SymEntry = AllocateItem(NonPagedPool, sizeof(SYMBOLIC_LINK_ENTRY)); + /* check for success */ + if (!SymEntry) + return STATUS_INSUFFICIENT_RESOURCES; + + /* now register device interface */ + Status = IoRegisterDeviceInterface(PhysicalDeviceObject, + &Categories[Index], + ReferenceString, /* see damn bug 4566 */ + &SymEntry->SymbolicLink); + + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to register device interface %x\n", Status); + + /* free entry */ + FreeItem(SymEntry); + + /* return result */ + return Status; + } + /* insert symbolic link entry */ + InsertTailList(SymbolicLinkList, &SymEntry->Entry); + } + + /* return result */ + return Status; +} + + diff --git a/reactos/drivers/ksfilter/ks/driver.c b/reactos/drivers/ksfilter/ks/driver.c index facd00ea95e..afd43ccbe4a 100644 --- a/reactos/drivers/ksfilter/ks/driver.c +++ b/reactos/drivers/ksfilter/ks/driver.c @@ -1,3 +1,11 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/driver.c + * PURPOSE: KS Driver functions + * PROGRAMMER: Johannes Anderwald + */ + #include "priv.h" #include "ksfunc.h" @@ -15,7 +23,7 @@ DriverEntry( } /* - @unimplemented + @implemented */ KSDDKAPI PKSDEVICE @@ -23,23 +31,12 @@ NTAPI KsGetDeviceForDeviceObject( IN PDEVICE_OBJECT FunctionalDeviceObject) { + PDEVICE_EXTENSION DeviceExtension; - return NULL; -} + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension; -/* - @unimplemented -*/ -KSDDKAPI -NTSTATUS -NTAPI -KsInitializeDevice( - IN PDEVICE_OBJECT FunctionalDeviceObject, - IN PDEVICE_OBJECT PhysicalDeviceObject, - IN PDEVICE_OBJECT NextDeviceObject, - IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL) -{ - return STATUS_UNSUCCESSFUL; + return &DeviceExtension->DeviceHeader->KsDevice; } /* @@ -58,9 +55,8 @@ KsCreateDevice( NTSTATUS Status = STATUS_DEVICE_REMOVED; PDEVICE_OBJECT FunctionalDeviceObject= NULL; PDEVICE_OBJECT OldHighestDeviceObject; - if (!ExtensionSize) - ExtensionSize = sizeof(PVOID); + ExtensionSize = sizeof(KSDEVICE_HEADER); Status = IoCreateDevice(DriverObject, ExtensionSize, NULL, FILE_DEVICE_KS, FILE_DEVICE_SECURE_OPEN, FALSE, &FunctionalDeviceObject); if (!NT_SUCCESS(Status)) @@ -71,7 +67,12 @@ KsCreateDevice( { Status = KsInitializeDevice(FunctionalDeviceObject, PhysicalDeviceObject, OldHighestDeviceObject, Descriptor); } + else + { + Status = STATUS_DEVICE_REMOVED; + } + /* check if all succeeded */ if (!NT_SUCCESS(Status)) { if (OldHighestDeviceObject) @@ -81,9 +82,20 @@ KsCreateDevice( return Status; } + /* set device flags */ + FunctionalDeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; + FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING; + if (Device) { + /* get PKSDEVICE struct */ *Device = KsGetDeviceForDeviceObject(FunctionalDeviceObject); + + if (ExtensionSize > sizeof(KSDEVICE_HEADER)) + { + /* caller needs a device extension */ + (*Device)->Context = (PVOID)((ULONG_PTR)FunctionalDeviceObject->DeviceExtension + sizeof(KSDEVICE_HEADER)); + } } return Status; @@ -135,9 +147,13 @@ KsInitializeDriver( } } /* Setting our IRP handlers */ - //DriverObject->MajorFunction[IRP_MJ_CREATE] = KspDispatch; - //DriverObject->MajorFunction[IRP_MJ_PNP] = KspDispatch; - //DriverObject->MajorFunction[IRP_MJ_POWER] = KspDispatch; + DriverObject->MajorFunction[IRP_MJ_CREATE] = IKsDevice_Create; + DriverObject->MajorFunction[IRP_MJ_PNP] = IKsDevice_Pnp; + DriverObject->MajorFunction[IRP_MJ_POWER] = IKsDevice_Power; + DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp; + + /* The driver unload routine */ + DriverObject->DriverUnload = KsNullDriverUnload; /* The driver-supplied AddDevice */ DriverObject->DriverExtension->AddDevice = KsAddDevice; diff --git a/reactos/drivers/ksfilter/ks/events.c b/reactos/drivers/ksfilter/ks/event.c similarity index 71% rename from reactos/drivers/ksfilter/ks/events.c rename to reactos/drivers/ksfilter/ks/event.c index 1558b216c68..a803f18c6ac 100644 --- a/reactos/drivers/ksfilter/ks/events.c +++ b/reactos/drivers/ksfilter/ks/event.c @@ -1,55 +1,20 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/event.c + * PURPOSE: KS Event functions + * PROGRAMMER: Johannes Anderwald + */ + #include "priv.h" -/* =============================================================== - Event Functions -*/ /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsGenerateEvent( - IN PKSEVENT_ENTRY EntryEvent) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsEnableEventWithAllocator( - IN PIRP Irp, - IN ULONG EventSetsCount, - IN PKSEVENT_SET EventSet, - IN OUT PLIST_ENTRY EventsList OPTIONAL, - IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, - IN PVOID EventsLock OPTIONAL, - IN PFNKSALLOCATOR Allocator OPTIONAL, - IN ULONG EventItemSize OPTIONAL) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsGenerateDataEvent( - IN PKSEVENT_ENTRY EventEntry, - IN ULONG DataSize, - IN PVOID Data) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsEnableEvent( IN PIRP Irp, IN ULONG EventSetsCount, @@ -65,17 +30,30 @@ KsEnableEvent( /* @unimplemented */ -KSDDKAPI VOID NTAPI -KsDiscardEvent( - IN PKSEVENT_ENTRY EventEntry) +KSDDKAPI +NTSTATUS +NTAPI +KsEnableEventWithAllocator( + IN PIRP Irp, + IN ULONG EventSetsCount, + IN PKSEVENT_SET EventSet, + IN OUT PLIST_ENTRY EventsList OPTIONAL, + IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL, + IN PVOID EventsLock OPTIONAL, + IN PFNKSALLOCATOR Allocator OPTIONAL, + IN ULONG EventItemSize OPTIONAL) { UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; } + /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsDisableEvent( IN PIRP Irp, IN OUT PLIST_ENTRY EventsList, @@ -89,7 +67,22 @@ KsDisableEvent( /* @unimplemented */ -KSDDKAPI VOID NTAPI +KSDDKAPI +VOID +NTAPI +KsDiscardEvent( + IN PKSEVENT_ENTRY EventEntry) +{ + UNIMPLEMENTED; +} + + +/* + @unimplemented +*/ +KSDDKAPI +VOID +NTAPI KsFreeEventList( IN PFILE_OBJECT FileObject, IN OUT PLIST_ENTRY EventsList, @@ -98,3 +91,46 @@ KsFreeEventList( { UNIMPLEMENTED; } + + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsGenerateEvent( + IN PKSEVENT_ENTRY EntryEvent) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsGenerateDataEvent( + IN PKSEVENT_ENTRY EventEntry, + IN ULONG DataSize, + IN PVOID Data) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +KSDDKAPI +VOID +NTAPI +KsGenerateEventList( + IN GUID* Set OPTIONAL, + IN ULONG EventId, + IN PLIST_ENTRY EventsList, + IN KSEVENTS_LOCKTYPE EventsFlags, + IN PVOID EventsLock) +{ + UNIMPLEMENTED +} + diff --git a/reactos/drivers/ksfilter/ks/filter.c b/reactos/drivers/ksfilter/ks/filter.c new file mode 100644 index 00000000000..6b3002b7a7e --- /dev/null +++ b/reactos/drivers/ksfilter/ks/filter.c @@ -0,0 +1,917 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/filter.c + * PURPOSE: KS IKsFilter interface functions + * PROGRAMMER: Johannes Anderwald + */ + + +#include "priv.h" + +typedef struct +{ + IKsFilterVtbl *lpVtbl; + IKsControlVtbl *lpVtblKsControl; + IKsFilterFactory * FilterFactory; + LONG ref; + + PKSIOBJECT_HEADER ObjectHeader; + KSFILTER Filter; + KSTOPOLOGY Topology; + KSPIN_DESCRIPTOR * PinDescriptors; + ULONG PinDescriptorCount; + PKSFILTERFACTORY Factory; + PFILE_OBJECT FileObject; + + + ULONG *PinInstanceCount; +}IKsFilterImpl; + +const GUID IID_IKsControl = {0x28F54685L, 0x06FD, 0x11D2, {0xB2, 0x7A, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}}; +const GUID IID_IKsFilter = {0x3ef6ee44L, 0x0D41, 0x11d2, {0xbe, 0xDA, 0x00, 0xc0, 0x4f, 0x8e, 0xF4, 0x57}}; +const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; + + +DEFINE_KSPROPERTY_TOPOLOGYSET(IKsFilterTopologySet, KspTopologyPropertyHandler); +DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(IKsFilterPinSet, KspPinPropertyHandler, KspPinPropertyHandler, KspPinPropertyHandler); + +KSPROPERTY_SET FilterPropertySet[] = +{ + { + &KSPROPSETID_Topology, + sizeof(IKsFilterTopologySet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&IKsFilterTopologySet, + 0, + NULL + }, + { + &KSPROPSETID_Pin, + sizeof(IKsFilterPinSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&IKsFilterPinSet, + 0, + NULL + } +}; + +NTSTATUS +NTAPI +IKsControl_fnQueryInterface( + IKsControl * iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); + + if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + _InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +IKsControl_fnAddRef( + IKsControl * iface) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); + + return InterlockedIncrement(&This->ref); +} + +ULONG +NTAPI +IKsControl_fnRelease( + IKsControl * iface) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); + + InterlockedDecrement(&This->ref); + + /* Return new reference count */ + return This->ref; +} + +NTSTATUS +NTAPI +IKsControl_fnKsProperty( + IKsControl * iface, + IN PKSPROPERTY Property, + IN ULONG PropertyLength, + IN OUT PVOID PropertyData, + IN ULONG DataLength, + OUT ULONG* BytesReturned) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); + + return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_PROPERTY, Property, PropertyLength, PropertyData, DataLength, BytesReturned); +} + + +NTSTATUS +NTAPI +IKsControl_fnKsMethod( + IKsControl * iface, + IN PKSMETHOD Method, + IN ULONG MethodLength, + IN OUT PVOID MethodData, + IN ULONG DataLength, + OUT ULONG* BytesReturned) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); + + return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_METHOD, Method, MethodLength, MethodData, DataLength, BytesReturned); +} + + +NTSTATUS +NTAPI +IKsControl_fnKsEvent( + IKsControl * iface, + IN PKSEVENT Event OPTIONAL, + IN ULONG EventLength, + IN OUT PVOID EventData, + IN ULONG DataLength, + OUT ULONG* BytesReturned) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtblKsControl); + + if (Event) + { + return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_ENABLE_EVENT, Event, EventLength, EventData, DataLength, BytesReturned); + } + else + { + return KsSynchronousIoControlDevice(This->FileObject, KernelMode, IOCTL_KS_DISABLE_EVENT, EventData, DataLength, NULL, 0, BytesReturned); + } + +} + +static IKsControlVtbl vt_IKsControl = +{ + IKsControl_fnQueryInterface, + IKsControl_fnAddRef, + IKsControl_fnRelease, + IKsControl_fnKsProperty, + IKsControl_fnKsMethod, + IKsControl_fnKsEvent +}; + + +NTSTATUS +NTAPI +IKsFilter_fnQueryInterface( + IKsFilter * iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + + if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || + IsEqualGUIDAligned(refiid, &IID_IKsFilter)) + { + *Output = &This->lpVtbl; + _InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + else if (IsEqualGUIDAligned(refiid, &IID_IKsControl)) + { + *Output = &This->lpVtblKsControl; + _InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +IKsFilter_fnAddRef( + IKsFilter * iface) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + + return InterlockedIncrement(&This->ref); +} + +ULONG +NTAPI +IKsFilter_fnRelease( + IKsFilter * iface) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + FreeItem(This); + return 0; + } + /* Return new reference count */ + return This->ref; + +} + +PKSFILTER +NTAPI +IKsFilter_fnGetStruct( + IKsFilter * iface) +{ + IKsFilterImpl * This = (IKsFilterImpl*)CONTAINING_RECORD(iface, IKsFilterImpl, lpVtbl); + + return &This->Filter; +} + +BOOL +NTAPI +IKsFilter_fnDoAllNecessaryPinsExist( + IKsFilter * iface) +{ + UNIMPLEMENTED + return FALSE; +} + +NTSTATUS +NTAPI +IKsFilter_fnCreateNode( + IKsFilter * iface, + IN PIRP Irp, + IN IKsPin * Pin, + IN PLIST_ENTRY ListEntry) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsFilter_fnBindProcessPinsToPipeSection( + IKsFilter * iface, + IN struct KSPROCESSPIPESECTION *Section, + IN PVOID Create, + IN PKSPIN KsPin, + OUT IKsPin **Pin, + OUT PKSGATE *OutGate) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsFilter_fnUnbindProcessPinsFromPipeSection( + IKsFilter * iface, + IN struct KSPROCESSPIPESECTION *Section) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsFilter_fnAddProcessPin( + IKsFilter * iface, + IN PKSPROCESSPIN ProcessPin) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS +NTAPI +IKsFilter_fnRemoveProcessPin( + IKsFilter * iface, + IN PKSPROCESSPIN ProcessPin) +{ + UNIMPLEMENTED + return STATUS_NOT_IMPLEMENTED; +} + +BOOL +NTAPI +IKsFilter_fnReprepareProcessPipeSection( + IKsFilter * iface, + IN struct KSPROCESSPIPESECTION *PipeSection, + IN PULONG Data) +{ + UNIMPLEMENTED + return FALSE; +} + +VOID +NTAPI +IKsFilter_fnDeliverResetState( + IKsFilter * iface, + IN struct KSPROCESSPIPESECTION *PipeSection, + IN KSRESET ResetState) +{ + UNIMPLEMENTED +} + +BOOL +NTAPI +IKsFilter_fnIsFrameHolding( + IKsFilter * iface) +{ + UNIMPLEMENTED + return FALSE; +} + +VOID +NTAPI +IKsFilter_fnRegisterForCopyCallbacks( + IKsFilter * iface, + IKsQueue *Queue, + BOOL Register) +{ + UNIMPLEMENTED +} + +PKSPROCESSPIN_INDEXENTRY +NTAPI +IKsFilter_fnGetProcessDispatch( + IKsFilter * iface) +{ + UNIMPLEMENTED + return NULL; +} + +static IKsFilterVtbl vt_IKsFilter = +{ + IKsFilter_fnQueryInterface, + IKsFilter_fnAddRef, + IKsFilter_fnRelease, + IKsFilter_fnGetStruct, + IKsFilter_fnDoAllNecessaryPinsExist, + IKsFilter_fnCreateNode, + IKsFilter_fnBindProcessPinsToPipeSection, + IKsFilter_fnUnbindProcessPinsFromPipeSection, + IKsFilter_fnAddProcessPin, + IKsFilter_fnRemoveProcessPin, + IKsFilter_fnReprepareProcessPipeSection, + IKsFilter_fnDeliverResetState, + IKsFilter_fnIsFrameHolding, + IKsFilter_fnRegisterForCopyCallbacks, + IKsFilter_fnGetProcessDispatch +}; + +NTSTATUS +IKsFilter_GetFilterFromIrp( + IN PIRP Irp, + OUT IKsFilter **Filter) +{ + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + NTSTATUS Status; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* santiy check */ + ASSERT(IoStack->FileObject != NULL); + + ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext; + + /* sanity is important */ + ASSERT(ObjectHeader != NULL); + ASSERT(ObjectHeader->Type == KsObjectTypeFilter); + ASSERT(ObjectHeader->Unknown != NULL); + + /* get our private interface */ + Status = ObjectHeader->Unknown->lpVtbl->QueryInterface(ObjectHeader->Unknown, &IID_IKsFilter, (PVOID*)Filter); + + if (!NT_SUCCESS(Status)) + { + /* something is wrong here */ + DPRINT1("KS: Misbehaving filter %p\n", ObjectHeader->Unknown); + Irp->IoStatus.Status = Status; + + /* complete and forget irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; + } + return Status; +} + + +NTSTATUS +NTAPI +IKsFilter_DispatchClose( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + IKsFilter * Filter; + IKsFilterImpl * This; + NTSTATUS Status; + + /* obtain filter from object header */ + Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); + if (!NT_SUCCESS(Status)) + return Status; + + /* get our real implementation */ + This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl); + + /* does the driver support notifications */ + if (This->Factory->FilterDescriptor && This->Factory->FilterDescriptor->Dispatch && This->Factory->FilterDescriptor->Dispatch->Close) + { + /* call driver's filter close function */ + Status = This->Factory->FilterDescriptor->Dispatch->Close(&This->Filter, Irp); + } + + if (Status != STATUS_PENDING) + { + /* save the result */ + Irp->IoStatus.Status = Status; + /* complete irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + /* remove our instance from the filter factory */ + This->FilterFactory->lpVtbl->RemoveFilterInstance(This->FilterFactory, Filter); + + /* now release the acquired interface */ + Filter->lpVtbl->Release(Filter); + + /* free object header */ + KsFreeObjectHeader(This->ObjectHeader); + } + + /* done */ + return Status; +} + +NTSTATUS +KspHandlePropertyInstances( + IN PIO_STATUS_BLOCK IoStatus, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data, + IN IKsFilterImpl * This, + IN BOOL Global) +{ + KSPIN_CINSTANCES * Instances; + KSP_PIN * Pin = (KSP_PIN*)Request; + + if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount) + { + /* no filter / pin descriptor */ + IoStatus->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; + } + + /* ignore custom structs for now */ + ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId); + + Instances = (KSPIN_CINSTANCES*)Data; + /* max instance count */ + Instances->PossibleCount = This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].InstancesPossible; + /* current instance count */ + Instances->CurrentCount = This->PinInstanceCount[Pin->PinId]; + + IoStatus->Information = sizeof(KSPIN_CINSTANCES); + IoStatus->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; +} + +NTSTATUS +KspHandleNecessaryPropertyInstances( + IN PIO_STATUS_BLOCK IoStatus, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data, + IN IKsFilterImpl * This) +{ + PULONG Result; + KSP_PIN * Pin = (KSP_PIN*)Request; + + if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount) + { + /* no filter / pin descriptor */ + IoStatus->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; + } + + /* ignore custom structs for now */ + ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId); + + Result = (PULONG)Data; + *Result = This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].InstancesNecessary; + + IoStatus->Information = sizeof(ULONG); + IoStatus->Status = STATUS_SUCCESS; + return STATUS_SUCCESS; +} + +NTSTATUS +KspHandleDataIntersection( + IN PIRP Irp, + IN PIO_STATUS_BLOCK IoStatus, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data, + IN ULONG DataLength, + IN IKsFilterImpl * This) +{ + PKSMULTIPLE_ITEM MultipleItem; + PKSDATARANGE DataRange; + NTSTATUS Status = STATUS_NO_MATCH; + ULONG Index, Length; + KSP_PIN * Pin = (KSP_PIN*)Request; + + /* Access parameters */ + MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); + DataRange = (PKSDATARANGE)(MultipleItem + 1); + + if (!This->Factory->FilterDescriptor || !This->Factory->FilterDescriptor->PinDescriptorsCount) + { + /* no filter / pin descriptor */ + IoStatus->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; + } + + /* ignore custom structs for now */ + ASSERT(This->Factory->FilterDescriptor->PinDescriptorSize == sizeof(KSPIN_DESCRIPTOR_EX)); + ASSERT(This->Factory->FilterDescriptor->PinDescriptorsCount > Pin->PinId); + + if (This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].IntersectHandler == NULL || + This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges == NULL || + This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRangesCount == 0) + { + /* no driver supported intersect handler / no provided data ranges */ + IoStatus->Status = STATUS_NOT_IMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; + } + + for(Index = 0; Index < MultipleItem->Count; Index++) + { + /* Call miniport's properitary handler */ + Status = This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].IntersectHandler(NULL, /* context */ + Irp, + Pin, + DataRange, + (PKSDATAFORMAT)This->Factory->FilterDescriptor->PinDescriptors[Pin->PinId].PinDescriptor.DataRanges, + DataLength, + Data, + &Length); + + if (Status == STATUS_SUCCESS) + { + IoStatus->Information = Length; + break; + } + DataRange = UlongToPtr(PtrToUlong(DataRange) + DataRange->FormatSize); + } + + IoStatus->Status = Status; + return Status; +} + +NTSTATUS +NTAPI +KspPinPropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + PIO_STACK_LOCATION IoStack; + IKsFilterImpl * This; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + /* get filter implementation */ + This = (IKsFilterImpl*)KSPROPERTY_ITEM_IRP_STORAGE(Irp); + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + switch(Request->Id) + { + case KSPROPERTY_PIN_CTYPES: + case KSPROPERTY_PIN_DATAFLOW: + case KSPROPERTY_PIN_DATARANGES: + case KSPROPERTY_PIN_INTERFACES: + case KSPROPERTY_PIN_MEDIUMS: + case KSPROPERTY_PIN_COMMUNICATION: + case KSPROPERTY_PIN_CATEGORY: + case KSPROPERTY_PIN_NAME: + case KSPROPERTY_PIN_PROPOSEDATAFORMAT: + Status = KsPinPropertyHandler(Irp, Request, Data, This->PinDescriptorCount, This->PinDescriptors); + break; + case KSPROPERTY_PIN_GLOBALCINSTANCES: + Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, TRUE); + break; + case KSPROPERTY_PIN_CINSTANCES: + Status = KspHandlePropertyInstances(&Irp->IoStatus, Request, Data, This, FALSE); + break; + case KSPROPERTY_PIN_NECESSARYINSTANCES: + Status = KspHandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, This); + break; + + case KSPROPERTY_PIN_DATAINTERSECTION: + Status = KspHandleDataIntersection(Irp, &Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, This); + break; + case KSPROPERTY_PIN_PHYSICALCONNECTION: + case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: + UNIMPLEMENTED + Status = STATUS_NOT_IMPLEMENTED; + break; + default: + UNIMPLEMENTED + Status = STATUS_UNSUCCESSFUL; + } + + return Status; +} + +NTSTATUS +FindPropertyHandler( + IN PIO_STATUS_BLOCK IoStatus, + IN KSPROPERTY_SET * FilterPropertySet, + IN ULONG FilterPropertySetCount, + IN PKSPROPERTY Property, + IN ULONG InputBufferLength, + IN ULONG OutputBufferLength, + OUT PFNKSHANDLER *PropertyHandler) +{ + ULONG Index, ItemIndex; + + for(Index = 0; Index < FilterPropertySetCount; Index++) + { + if (IsEqualGUIDAligned(&Property->Set, FilterPropertySet[Index].Set)) + { + for(ItemIndex = 0; ItemIndex < FilterPropertySet[Index].PropertiesCount; ItemIndex++) + { + if (FilterPropertySet[Index].PropertyItem[ItemIndex].PropertyId == Property->Id) + { + if (Property->Flags & KSPROPERTY_TYPE_SET) + *PropertyHandler = FilterPropertySet[Index].PropertyItem[ItemIndex].SetPropertyHandler; + + if (Property->Flags & KSPROPERTY_TYPE_GET) + *PropertyHandler = FilterPropertySet[Index].PropertyItem[ItemIndex].GetPropertyHandler; + + if (FilterPropertySet[Index].PropertyItem[ItemIndex].MinProperty > InputBufferLength) + { + /* too small input buffer */ + IoStatus->Information = FilterPropertySet[Index].PropertyItem[ItemIndex].MinProperty; + IoStatus->Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + + if (FilterPropertySet[Index].PropertyItem[ItemIndex].MinData > OutputBufferLength) + { + /* too small output buffer */ + IoStatus->Information = FilterPropertySet[Index].PropertyItem[ItemIndex].MinData; + IoStatus->Status = STATUS_BUFFER_TOO_SMALL; + return STATUS_BUFFER_TOO_SMALL; + } + return STATUS_SUCCESS; + } + } + } + } + return STATUS_UNSUCCESSFUL; +} + + + +NTSTATUS +NTAPI +IKsFilter_DispatchDeviceIoControl( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PFNKSHANDLER PropertyHandler = NULL; + IKsFilter * Filter; + IKsFilterImpl * This; + NTSTATUS Status; + + /* obtain filter from object header */ + Status = IKsFilter_GetFilterFromIrp(Irp, &Filter); + if (!NT_SUCCESS(Status)) + return Status; + + /* get our real implementation */ + This = (IKsFilterImpl*)CONTAINING_RECORD(Filter, IKsFilterImpl, lpVtbl); + + /* current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) + { + UNIMPLEMENTED; + + /* release filter interface */ + Filter->lpVtbl->Release(Filter); + + /* complete and forget irp */ + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; + } + + /* find a supported property handler */ + Status = FindPropertyHandler(&Irp->IoStatus, FilterPropertySet, 2, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &PropertyHandler); + if (NT_SUCCESS(Status)) + { + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PVOID)This; + DPRINT("Calling property handler %p\n", PropertyHandler); + Status = PropertyHandler(Irp, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, Irp->UserBuffer); + } + else + { + /* call driver's property handler */ + UNIMPLEMENTED + Status = STATUS_NOT_IMPLEMENTED; + } + + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + /* done */ + return Status; +} + +static KSDISPATCH_TABLE DispatchTable = +{ + IKsFilter_DispatchDeviceIoControl, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + KsDispatchInvalidDeviceRequest, + IKsFilter_DispatchClose, + KsDispatchQuerySecurity, + KsDispatchSetSecurity, + KsDispatchFastIoDeviceControlFailure, + KsDispatchFastReadFailure, + KsDispatchFastReadFailure, +}; + + +NTSTATUS +IKsFilter_CreateDescriptors( + IKsFilterImpl * This, + KSFILTER_DESCRIPTOR* FilterDescriptor) +{ + ULONG Index = 0; + + /* initialize pin descriptors */ + if (FilterDescriptor->PinDescriptorsCount) + { + /* allocate pin instance count array */ + This->PinInstanceCount = AllocateItem(NonPagedPool, sizeof(ULONG) * FilterDescriptor->PinDescriptorsCount); + if(!This->PinDescriptors) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + + /* allocate pin descriptor array */ + This->PinDescriptors = AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescriptor->PinDescriptorsCount); + if(!This->PinDescriptors) + { + FreeItem(This->PinInstanceCount); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* set pin count */ + This->PinDescriptorCount = FilterDescriptor->PinDescriptorsCount; + /* now copy those pin descriptors over */ + for(Index = 0; Index < FilterDescriptor->PinDescriptorsCount; Index++) + { + /* copy one pin per time */ + RtlMoveMemory(&This->PinDescriptors[Index], &FilterDescriptor->PinDescriptors[Index].PinDescriptor, sizeof(KSPIN_DESCRIPTOR)); + } + } + + /* initialize topology descriptor */ + This->Topology.CategoriesCount = FilterDescriptor->CategoriesCount; + This->Topology.Categories = FilterDescriptor->Categories; + This->Topology.TopologyNodesCount = FilterDescriptor->NodeDescriptorsCount; + This->Topology.TopologyConnectionsCount = FilterDescriptor->ConnectionsCount; + This->Topology.TopologyConnections = FilterDescriptor->Connections; + + if (This->Topology.TopologyNodesCount > 0) + { + This->Topology.TopologyNodes = AllocateItem(NonPagedPool, sizeof(GUID) * This->Topology.TopologyNodesCount); + /* allocate topology node types array */ + if (!This->Topology.TopologyNodes) + return STATUS_INSUFFICIENT_RESOURCES; + + This->Topology.TopologyNodesNames = AllocateItem(NonPagedPool, sizeof(GUID) * This->Topology.TopologyNodesCount); + /* allocate topology names array */ + if (!This->Topology.TopologyNodesNames) + { + FreeItem((PVOID)This->Topology.TopologyNodes); + return STATUS_INSUFFICIENT_RESOURCES; + } + + for(Index = 0; Index < This->Topology.TopologyNodesCount; Index++) + { + /* copy topology type */ + RtlMoveMemory((PVOID)&This->Topology.TopologyNodes[Index], FilterDescriptor->NodeDescriptors[Index].Type, sizeof(GUID)); + /* copy topology name */ + RtlMoveMemory((PVOID)&This->Topology.TopologyNodesNames[Index], FilterDescriptor->NodeDescriptors[Index].Name, sizeof(GUID)); + } + } + + /* done! */ + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +KspCreateFilter( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN IKsFilterFactory *iface) +{ + IKsFilterImpl * This; + PKSFILTERFACTORY Factory; + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + + /* get the filter factory */ + Factory = iface->lpVtbl->GetStruct(iface); + + if (!Factory || !Factory->FilterDescriptor || !Factory->FilterDescriptor->Dispatch || !Factory->FilterDescriptor->Dispatch->Create) + { + /* Sorry it just will not work */ + return STATUS_UNSUCCESSFUL; + } + + /* allocate filter instance */ + This = AllocateItem(NonPagedPool, sizeof(IKsFilterFactory)); + if (!This) + return STATUS_INSUFFICIENT_RESOURCES; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* initialize filter instance */ + This->ref = 1; + This->lpVtbl = &vt_IKsFilter; + This->lpVtblKsControl = &vt_IKsControl; + This->Filter.Descriptor = Factory->FilterDescriptor; + This->Factory = Factory; + This->FilterFactory = iface; + This->FileObject = IoStack->FileObject; + + /* allocate the stream descriptors */ + Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor); + if (!NT_SUCCESS(Status)) + { + /* what can go wrong, goes wrong */ + FreeItem(This); + return Status; + } + + /* now add the filter instance to the filter factory */ + Status = iface->lpVtbl->AddFilterInstance(iface, (IKsFilter*)&This->lpVtbl); + + if (!NT_SUCCESS(Status)) + { + /* failed to add filter */ + FreeItem(This); + + return Status; + } + + /* now let driver initialize the filter instance */ + Status = Factory->FilterDescriptor->Dispatch->Create(&This->Filter, Irp); + + if (!NT_SUCCESS(Status) && Status != STATUS_PENDING) + { + /* driver failed to initialize */ + DPRINT1("Driver: Status %x\n", Status); + + /* remove filter instance from filter factory */ + iface->lpVtbl->RemoveFilterInstance(iface, (IKsFilter*)&This->lpVtbl); + + /* free filter instance */ + FreeItem(This); + + return Status; + } + + /* now allocate the object header */ + Status = KsAllocateObjectHeader((PVOID*)&This->ObjectHeader, 0, NULL, Irp, &DispatchTable); + if (!NT_SUCCESS(Status)) + { + /* failed to allocate object header */ + DPRINT1("Failed to allocate object header %x\n", Status); + + return Status; + } + + /* initialize object header */ + This->ObjectHeader->Type = KsObjectTypeFilter; + This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl; + + + /* completed initialization */ + return Status; +} diff --git a/reactos/drivers/ksfilter/ks/filterfactory.c b/reactos/drivers/ksfilter/ks/filterfactory.c new file mode 100644 index 00000000000..99a148f2f40 --- /dev/null +++ b/reactos/drivers/ksfilter/ks/filterfactory.c @@ -0,0 +1,471 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/filterfactory.c + * PURPOSE: KS IKsFilterFactory interface functions + * PROGRAMMER: Johannes Anderwald + */ + + +#include "priv.h" + +typedef struct +{ + IKsFilterFactoryVtbl *lpVtbl; + KSFILTERFACTORY FilterFactory; + PKSIDEVICE_HEADER DeviceHeader; + + LONG ref; + + PFNKSFILTERFACTORYPOWER SleepCallback; + PFNKSFILTERFACTORYPOWER WakeCallback; + + LIST_ENTRY SymbolicLinkList; + LIST_ENTRY FilterInstanceList; + + +}IKsFilterFactoryImpl; + +typedef struct +{ + LIST_ENTRY Entry; + IKsFilter *FilterInstance; +}FILTER_INSTANCE_ENTRY, *PFILTER_INSTANCE_ENTRY; + + + +VOID +NTAPI +IKsFilterFactory_ItemFreeCb( + IN PKSOBJECT_CREATE_ITEM CreateItem) +{ + /* callback when create item is freed in the device header */ + IKsFilterFactory * iface = (IKsFilterFactory*)CONTAINING_RECORD(CreateItem->Context, IKsFilterFactoryImpl, FilterFactory); + + iface->lpVtbl->Release(iface); +} + +NTSTATUS +NTAPI +IKsFilterFactory_Create( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PKSOBJECT_CREATE_ITEM CreateItem; + IKsFilterFactory * iface; + NTSTATUS Status; + + /* access the create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + if (!CreateItem) + { + DPRINT1("IKsFilterFactory_Create no CreateItem\n"); + return STATUS_UNSUCCESSFUL; + } + + /* get filter factory interface */ + iface = (IKsFilterFactory*)CONTAINING_RECORD(CreateItem->Context, IKsFilterFactoryImpl, FilterFactory); + + /* create a filter instance */ + Status = KspCreateFilter(DeviceObject, Irp, iface); + + DPRINT("KspCreateFilter Status %x\n", Status); + + if (Status != STATUS_PENDING) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + } + + return Status; +} + + +NTSTATUS +NTAPI +IKsFilterFactory_fnQueryInterface( + IKsFilterFactory * iface, + IN REFIID refiid, + OUT PVOID* Output) +{ + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) + { + *Output = &This->lpVtbl; + _InterlockedIncrement(&This->ref); + return STATUS_SUCCESS; + } + return STATUS_UNSUCCESSFUL; +} + +ULONG +NTAPI +IKsFilterFactory_fnAddRef( + IKsFilterFactory * iface) +{ + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + return InterlockedIncrement(&This->ref); +} + +ULONG +NTAPI +IKsFilterFactory_fnRelease( + IKsFilterFactory * iface) +{ + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + InterlockedDecrement(&This->ref); + + if (This->ref == 0) + { + if (!IsListEmpty(&This->SymbolicLinkList)) + { + /* disable device interfaces */ + KspSetDeviceInterfacesState(&This->SymbolicLinkList, FALSE); + /* free device interface strings */ + KspFreeDeviceInterfaces(&This->SymbolicLinkList); + } + + FreeItem(This); + return 0; + } + /* Return new reference count */ + return This->ref; +} + +KSFILTERFACTORY* +NTAPI +IKsFilterFactory_fnGetStruct( + IKsFilterFactory * iface) +{ + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + return &This->FilterFactory; +} + +NTSTATUS +NTAPI +IKsFilterFactory_fnSetDeviceClassesState( + IKsFilterFactory * iface, + IN BOOLEAN Enable) +{ + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + return KspSetDeviceInterfacesState(&This->SymbolicLinkList, Enable); +} + +NTSTATUS +NTAPI +IKsFilterFactory_fnInitialize( + IKsFilterFactory * iface, + IN PDEVICE_OBJECT DeviceObject, + IN const KSFILTER_DESCRIPTOR *Descriptor, + IN PWSTR RefString OPTIONAL, + IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN ULONG CreateItemFlags, + IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, + IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, + OUT PKSFILTERFACTORY *FilterFactory OPTIONAL) +{ + UNICODE_STRING ReferenceString; + NTSTATUS Status; + PDEVICE_EXTENSION DeviceExtension; + KSOBJECT_CREATE_ITEM CreateItem; + BOOL FreeString = FALSE; + + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + /* initialize filterfactory */ + This->SleepCallback = SleepCallback; + This->WakeCallback = WakeCallback; + This->FilterFactory.FilterDescriptor = Descriptor; + InitializeListHead(&This->SymbolicLinkList); + InitializeListHead(&This->FilterInstanceList); + + /* does the device use a reference string */ + if (RefString || !Descriptor->ReferenceGuid) + { + /* use device reference string */ + RtlInitUnicodeString(&ReferenceString, RefString); + } + else + { + /* create reference string from descriptor guid */ + Status = RtlStringFromGUID(Descriptor->ReferenceGuid, &ReferenceString); + + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* omg, we failed */ + return Status; + } + + FreeString = TRUE; + } + + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + + /* now register the device interface */ + Status = KspRegisterDeviceInterfaces(DeviceExtension->DeviceHeader->KsDevice.PhysicalDeviceObject, + Descriptor->CategoriesCount, + Descriptor->Categories, + &ReferenceString, + &This->SymbolicLinkList); + /* check for success */ + if (!NT_SUCCESS(Status)) + { + DPRINT1("KspRegisterDeviceInterfaces failed with %x\n", Status); + + if (FreeString) + { + /* free unicode string */ + RtlFreeUnicodeString(&ReferenceString); + } + + return Status; + } + + /* now setup the create item */ + CreateItem.SecurityDescriptor = SecurityDescriptor; + CreateItem.Flags = CreateItemFlags; + CreateItem.Create = IKsFilterFactory_Create; + CreateItem.Context = (PVOID)&This->FilterFactory; + RtlInitUnicodeString(&CreateItem.ObjectClass, ReferenceString.Buffer); + + /* insert create item to device header */ + Status = KsAllocateObjectCreateItem((KSDEVICE_HEADER)DeviceExtension->DeviceHeader, &CreateItem, TRUE, IKsFilterFactory_ItemFreeCb); + + if (FreeString) + { + /* free unicode string */ + RtlFreeUnicodeString(&ReferenceString); + } + + if (FilterFactory) + { + /* return filterfactory */ + *FilterFactory = &This->FilterFactory; + + /*FIXME create object bag */ + } + + + /* return result */ + return Status; +} + +NTSTATUS +NTAPI +IKsFilterFactory_fnAddFilterInstance( + IKsFilterFactory * iface, + IN IKsFilter *FilterInstance) +{ + PFILTER_INSTANCE_ENTRY Entry; + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + /* allocate filter instance entry */ + Entry = AllocateItem(NonPagedPool, sizeof(FILTER_INSTANCE_ENTRY)); + if (!Entry) + return STATUS_INSUFFICIENT_RESOURCES; + + /* initialize filter instance entry */ + Entry->FilterInstance = FilterInstance; + + /* insert entry */ + InsertTailList(&This->FilterInstanceList, &Entry->Entry); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +IKsFilterFactory_fnRemoveFilterInstance( + IKsFilterFactory * iface, + IN IKsFilter *FilterInstance) +{ + PFILTER_INSTANCE_ENTRY InstanceEntry; + PLIST_ENTRY Entry; + IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl); + + /* point to first entry */ + Entry = This->FilterInstanceList.Flink; + + while(Entry != &This->FilterInstanceList) + { + InstanceEntry = (PFILTER_INSTANCE_ENTRY)CONTAINING_RECORD(Entry, FILTER_INSTANCE_ENTRY, Entry); + if (InstanceEntry->FilterInstance == FilterInstance) + { + /* found entry */ + RemoveEntryList(&InstanceEntry->Entry); + FreeItem(InstanceEntry); + return STATUS_SUCCESS; + } + } + + /* entry not in list! */ + return STATUS_NOT_FOUND; +} + +static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl = +{ + IKsFilterFactory_fnQueryInterface, + IKsFilterFactory_fnAddRef, + IKsFilterFactory_fnRelease, + IKsFilterFactory_fnGetStruct, + IKsFilterFactory_fnSetDeviceClassesState, + IKsFilterFactory_fnInitialize, + IKsFilterFactory_fnAddFilterInstance, + IKsFilterFactory_fnRemoveFilterInstance +}; + + +NTSTATUS +NTAPI +KspCreateFilterFactory( + IN PDEVICE_OBJECT DeviceObject, + IN const KSFILTER_DESCRIPTOR *Descriptor, + IN PWSTR RefString OPTIONAL, + IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN ULONG CreateItemFlags, + IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, + IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, + OUT PKSFILTERFACTORY *FilterFactory OPTIONAL) +{ + IKsFilterFactoryImpl * This; + IKsFilterFactory * Filter; + NTSTATUS Status; + + /* Lets allocate a filterfactory */ + This = AllocateItem(NonPagedPool, sizeof(IKsFilterFactoryImpl)); + if (!This) + { + /* not enough memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize struct */ + This->ref = 1; + This->lpVtbl = &vt_IKsFilterFactoryVtbl; + + /* map to com object */ + Filter = (IKsFilterFactory*)&This->lpVtbl; + + /* initialize filter */ + Status = Filter->lpVtbl->Initialize(Filter, DeviceObject, Descriptor, RefString, SecurityDescriptor, CreateItemFlags, SleepCallback, WakeCallback, FilterFactory); + /* did we succeed */ + if (!NT_SUCCESS(Status)) + { + /* destroy filterfactory */ + Filter->lpVtbl->Release(Filter); + } + + /* return result */ + return Status; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsCreateFilterFactory( + IN PDEVICE_OBJECT DeviceObject, + IN const KSFILTER_DESCRIPTOR *Descriptor, + IN PWSTR RefString OPTIONAL, + IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN ULONG CreateItemFlags, + IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, + IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, + OUT PKSFILTERFACTORY *FilterFactory OPTIONAL) +{ + return KspCreateFilterFactory(DeviceObject, Descriptor, RefString, SecurityDescriptor, CreateItemFlags, SleepCallback, WakeCallback, FilterFactory); + +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsFilterFactorySetDeviceClassesState( + IN PKSFILTERFACTORY FilterFactory, + IN BOOLEAN NewState) +{ + IKsFilterFactory * Factory = (IKsFilterFactory*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory); + + return Factory->lpVtbl->SetDeviceClassesState(Factory, NewState); +} + + +/* + @implemented +*/ +KSDDKAPI +PUNICODE_STRING +NTAPI +KsFilterFactoryGetSymbolicLink( + IN PKSFILTERFACTORY FilterFactory) +{ + PSYMBOLIC_LINK_ENTRY LinkEntry; + IKsFilterFactoryImpl * Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory); + + if (IsListEmpty(&Factory->SymbolicLinkList)) + { + /* device has not registered any interfaces */ + return NULL; + } + + /* get first entry */ + LinkEntry = (PSYMBOLIC_LINK_ENTRY)CONTAINING_RECORD(Factory->SymbolicLinkList.Flink, SYMBOLIC_LINK_ENTRY, Entry); + + /* return first link */ + return &LinkEntry->SymbolicLink; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsFilterFactoryAddCreateItem( + IN PKSFILTERFACTORY FilterFactory, + IN PWSTR RefString, + IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN ULONG CreateItemFlags) +{ + KSOBJECT_CREATE_ITEM CreateItem; + + IKsFilterFactoryImpl * Factory = (IKsFilterFactoryImpl*)CONTAINING_RECORD(FilterFactory, IKsFilterFactoryImpl, FilterFactory); + + /* initialize create item */ + CreateItem.Context = (PVOID)&Factory->FilterFactory; + CreateItem.Create = IKsFilterFactory_Create; + CreateItem.Flags = CreateItemFlags; + CreateItem.SecurityDescriptor = SecurityDescriptor; + RtlInitUnicodeString(&CreateItem.ObjectClass, RefString); + + /* insert create item to device header */ + return KsAllocateObjectCreateItem((KSDEVICE_HEADER)Factory->DeviceHeader, &CreateItem, TRUE, IKsFilterFactory_ItemFreeCb); +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsFilterFactoryUpdateCacheData ( + IN PKSFILTERFACTORY FilterFactory, + IN const KSFILTER_DESCRIPTOR* FilterDescriptor OPTIONAL) +{ + UNIMPLEMENTED + + return STATUS_NOT_IMPLEMENTED; +} + diff --git a/reactos/drivers/ksfilter/ks/image.c b/reactos/drivers/ksfilter/ks/image.c new file mode 100644 index 00000000000..db004c404eb --- /dev/null +++ b/reactos/drivers/ksfilter/ks/image.c @@ -0,0 +1,116 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/allocators.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + */ + +#include "priv.h" + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsLoadResource( + IN PVOID ImageBase, + IN POOL_TYPE PoolType, + IN ULONG_PTR ResourceName, + IN ULONG ResourceType, + OUT PVOID* Resource, + OUT PULONG ResourceSize) +{ + NTSTATUS Status; + LDR_RESOURCE_INFO ResourceInfo; + PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; + PVOID Data; + ULONG Size; + PVOID Result = NULL; + + /* set up resource info */ + ResourceInfo.Type = ResourceType; + ResourceInfo.Name = ResourceName; + ResourceInfo.Language = 0; + + _SEH2_TRY + { + /* find the resource */ + Status = LdrFindResource_U(ImageBase, &ResourceInfo, RESOURCE_DATA_LEVEL, &ResourceDataEntry); + if (NT_SUCCESS(Status)) + { + /* try accessing it */ + Status = LdrAccessResource(ImageBase, ResourceDataEntry, &Data, &Size); + if (NT_SUCCESS(Status)) + { + /* allocate resource buffer */ + Result = ExAllocatePool(PoolType, Size); + if (Result) + { + /* copy resource */ + RtlMoveMemory(Result, Data, Size); + /* store result */ + *Resource = Result; + *ResourceSize = Size; + } + else + { + /* not enough memory */ + Status = STATUS_INSUFFICIENT_RESOURCES; + } + } + } + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + /* Exception, get the error code */ + Status = _SEH2_GetExceptionCode(); + } + _SEH2_END; + + if (!NT_SUCCESS(Status)) + { + /* failed */ + if (Result) + { + /* free resource buffer in case of a failure */ + ExFreePool(Result); + } + } + /* done */ + return Status; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsGetImageNameAndResourceId( + IN HANDLE RegKey, + OUT PUNICODE_STRING ImageName, + OUT PULONG_PTR ResourceId, + OUT PULONG ValueType) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsMapModuleName( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN PUNICODE_STRING ModuleName, + OUT PUNICODE_STRING ImageName, + OUT PULONG_PTR ResourceId, + OUT PULONG ValueType) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 336f8e783dc..8feb2269723 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -1,138 +1,37 @@ /* - ReactOS Kernel Streaming - IRP Helpers -*/ + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/factory.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + */ + #include "priv.h" /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsAcquireResetValue( - IN PIRP Irp, - OUT KSRESET* ResetValue) +KSDDKAPI +NTSTATUS +NTAPI +KsReferenceBusObject( + IN KSDEVICE_HEADER Header) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; } /* - @implemented + @unimplemented */ KSDDKAPI VOID NTAPI -KsAddIrpToCancelableQueue( - IN OUT PLIST_ENTRY QueueHead, - IN PKSPIN_LOCK SpinLock, - IN PIRP Irp, - IN KSLIST_ENTRY_LOCATION ListLocation, - IN PDRIVER_CANCEL DriverCancel OPTIONAL) -{ - PQUEUE_ENTRY Entry; - - if (!QueueHead || !SpinLock || !Irp) - return; - - Entry = ExAllocatePool(NonPagedPool, sizeof(QUEUE_ENTRY)); - if (!Entry) - return; - - ///FIXME - // setup cancel routine - // - - Entry->Irp = Irp; - - if (ListLocation == KsListEntryTail) - ExInterlockedInsertTailList(QueueHead, &Entry->Entry, SpinLock); - else - ExInterlockedInsertHeadList(QueueHead, &Entry->Entry, SpinLock); - -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsAddObjectCreateItemToObjectHeader( - IN KSOBJECT_HEADER Header, - IN PDRIVER_DISPATCH Create, - IN PVOID Context, - IN PWCHAR ObjectClass, - IN PSECURITY_DESCRIPTOR SecurityDescriptor) +KsDereferenceBusObject( + IN KSDEVICE_HEADER Header) { UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - - -/* - @implemented -*/ -KSDDKAPI -NTSTATUS -NTAPI -KsAddObjectCreateItemToDeviceHeader( - IN KSDEVICE_HEADER DevHeader, - IN PDRIVER_DISPATCH Create, - IN PVOID Context, - IN PWCHAR ObjectClass, - IN PSECURITY_DESCRIPTOR SecurityDescriptor) -{ - PKSIDEVICE_HEADER Header; - ULONG FreeIndex, Index; - - Header = (PKSIDEVICE_HEADER)DevHeader; - - DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n"); - - /* check if a device header has been provided */ - if (!DevHeader) - return STATUS_INVALID_PARAMETER_1; - - /* check if a create item has been provided */ - if (!Create) - return STATUS_INVALID_PARAMETER_2; - - /* check if a object class has been provided */ - if (!ObjectClass) - return STATUS_INVALID_PARAMETER_4; - - FreeIndex = (ULONG)-1; - /* now scan the list and check for a free item */ - for(Index = 0; Index < Header->MaxItems; Index++) - { - ASSERT(Header->ItemList[Index].CreateItem); - - if (Header->ItemList[Index].CreateItem->Create == NULL) - { - FreeIndex = Index; - break; - } - - if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem->ObjectClass.Buffer)) - { - /* the same object class already exists */ - return STATUS_OBJECT_NAME_COLLISION; - } - } - /* found a free index */ - if (FreeIndex == (ULONG)-1) - { - /* no empty space found */ - return STATUS_ALLOTTED_SPACE_EXCEEDED; - } - - /* initialize create item */ - Header->ItemList[FreeIndex].CreateItem->Create = Create; - Header->ItemList[FreeIndex].CreateItem->Context = Context; - RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem->ObjectClass, ObjectClass); - Header->ItemList[FreeIndex].CreateItem->SecurityDescriptor = SecurityDescriptor; - - - return STATUS_SUCCESS; } /* @@ -141,336 +40,111 @@ KsAddObjectCreateItemToDeviceHeader( KSDDKAPI NTSTATUS NTAPI -KsAllocateDeviceHeader( - OUT KSDEVICE_HEADER* OutHeader, - IN ULONG ItemsCount, - IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL) -{ - ULONG Index = 0; - PKSIDEVICE_HEADER Header; - - if (!OutHeader) - return STATUS_INVALID_PARAMETER; - - /* allocate a device header */ - Header = ExAllocatePoolWithTag(PagedPool, sizeof(KSIDEVICE_HEADER), TAG_DEVICE_HEADER); - - /* check for success */ - if (!Header) - return STATUS_INSUFFICIENT_RESOURCES; - - /* clear all memory */ - RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER)); - - /* initialize spin lock */ - KeInitializeSpinLock(&Header->ItemListLock); - - /* are there any create items provided */ - if (ItemsCount && ItemsList) - { - /* allocate space for device item list */ - Header->ItemList = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * ItemsCount, TAG_DEVICE_HEADER); - if (!Header->ItemList) - { - ExFreePoolWithTag(Header, TAG_DEVICE_HEADER); - return STATUS_INSUFFICIENT_RESOURCES; - } - RtlZeroMemory(Header->ItemList, sizeof(DEVICE_ITEM) * ItemsCount); - - for(Index = 0; Index < ItemsCount; Index++) - { - /* store provided create items */ - Header->ItemList[Index].CreateItem = &ItemsList[Index]; - } - Header->MaxItems = ItemsCount; - } - - /* store result */ - *OutHeader = Header; - - return STATUS_SUCCESS; -} - -/* - @unimplemented - - http://www.osronline.com/DDKx/stream/ksfunc_3sc3.htm -*/ -KSDDKAPI -NTSTATUS -NTAPI -KsAllocateObjectCreateItem( - IN KSDEVICE_HEADER DevHeader, - IN PKSOBJECT_CREATE_ITEM CreateItem, - IN BOOLEAN AllocateEntry, - IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL) -{ - PKSIDEVICE_HEADER Header; - - Header = (PKSIDEVICE_HEADER)DevHeader; - - if (!DevHeader) - return STATUS_INVALID_PARAMETER_1; - - if (!CreateItem) - return STATUS_INVALID_PARAMETER_2; - - //FIXME - //handle ItemFreeCallback - // - if (AllocateEntry && ItemFreeCallback) - DPRINT1("Ignoring ItemFreeCallback\n"); - - return KsAddObjectCreateItemToDeviceHeader(DevHeader, CreateItem->Create, CreateItem->Context, CreateItem->ObjectClass.Buffer, CreateItem->SecurityDescriptor); -} - - -/* - @implemented -*/ -KSDDKAPI -VOID -NTAPI -KsFreeDeviceHeader( - IN KSDEVICE_HEADER DevHeader) -{ - PKSIDEVICE_HEADER Header; - - Header = (PKSIDEVICE_HEADER)DevHeader; - - if (!DevHeader) - return; - - ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER); - ExFreePoolWithTag(Header, TAG_DEVICE_HEADER); -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsAllocateExtraData( - IN PIRP Irp, - IN ULONG ExtraSize, - OUT PVOID* ExtraBuffer) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented - - Initialize the required file context header. - Allocates KSOBJECT_HEADER structure. - Irp is an IRP_MJ_CREATE structure. - Driver must allocate KSDISPATCH_TABLE and initialize it first. - - http://www.osronline.com/DDKx/stream/ksfunc_0u2b.htm -*/ -KSDDKAPI -NTSTATUS -NTAPI -KsAllocateObjectHeader( - OUT KSOBJECT_HEADER *Header, - IN ULONG ItemsCount, - IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL, - IN PIRP Irp, - IN KSDISPATCH_TABLE* Table) +KsDispatchQuerySecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) { + PKSOBJECT_CREATE_ITEM CreateItem; PIO_STACK_LOCATION IoStack; - PDEVICE_EXTENSION DeviceExtension; - PKSIDEVICE_HEADER DeviceHeader; - PKSIOBJECT_HEADER ObjectHeader; + NTSTATUS Status; + ULONG Length; - if (!Header) - return STATUS_INVALID_PARAMETER_1; - - if (!Irp) - return STATUS_INVALID_PARAMETER_4; - - if (!Table) - return STATUS_INVALID_PARAMETER_5; - - /* get current stack location */ + /* get current irp stack */ IoStack = IoGetCurrentIrpStackLocation(Irp); - /* get device extension */ - DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; - /* get device header */ - DeviceHeader = DeviceExtension->DeviceHeader; - /* sanity check */ - ASSERT(IoStack->FileObject); - /* check for an file object */ + /* get create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); - /* allocate the object header */ - ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER); - if (!ObjectHeader) - return STATUS_INSUFFICIENT_RESOURCES; - - /* initialize object header */ - RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER)); - - /* do we have a name */ - if (IoStack->FileObject->FileName.Buffer) + if (!CreateItem || !CreateItem->SecurityDescriptor) { - /* copy object class */ - ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength; - ObjectHeader->ObjectClass.Buffer = ExAllocatePoolWithTag(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength, TAG_DEVICE_HEADER); - if (!ObjectHeader->ObjectClass.Buffer) - { - ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER); - return STATUS_INSUFFICIENT_RESOURCES; - } - RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName); + /* no create item */ + Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NO_SECURITY_ON_OBJECT; } - /* copy dispatch table */ - RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE)); - /* store create items */ - if (ItemsCount && ItemsList) + + /* get input length */ + Length = IoStack->Parameters.QuerySecurity.Length; + + /* clone the security descriptor */ + Status = SeQuerySecurityDescriptorInfo(&IoStack->Parameters.QuerySecurity.SecurityInformation, (PSECURITY_DESCRIPTOR)Irp->UserBuffer, &Length, &CreateItem->SecurityDescriptor); + + DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status); + /* store result */ + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = Length; + + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsDispatchSetSecurity( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PKSOBJECT_CREATE_ITEM CreateItem; + PIO_STACK_LOCATION IoStack; + PGENERIC_MAPPING Mapping; + PSECURITY_DESCRIPTOR Descriptor; + NTSTATUS Status; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* get create item */ + CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); + + if (!CreateItem || !CreateItem->SecurityDescriptor) { - ObjectHeader->ItemCount = ItemsCount; - ObjectHeader->CreateItem = ItemsList; + /* no create item */ + Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NO_SECURITY_ON_OBJECT; } - /* was the request for a pin/clock/node */ - if (IoStack->FileObject->FileName.Buffer) + /* backup old descriptor */ + Descriptor = CreateItem->SecurityDescriptor; + + /* get generic mapping */ + Mapping = IoGetFileObjectGenericMapping(); + + /* change security descriptor */ + Status = SeSetSecurityDescriptorInfo(NULL, /*FIXME */ + &IoStack->Parameters.SetSecurity.SecurityInformation, + IoStack->Parameters.SetSecurity.SecurityDescriptor, + &CreateItem->SecurityDescriptor, + NonPagedPool, + Mapping); + + if (NT_SUCCESS(Status)) { - /* store the object in the file object */ - ASSERT(IoStack->FileObject->FsContext == NULL); - IoStack->FileObject->FsContext = ObjectHeader; - } - else - { - /* the object header is for a audio filter */ - ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems); - IoStack->FileObject->FsContext = ObjectHeader; + /* free old descriptor */ + ExFreePool(Descriptor); + + /* mark create item as changed */ + CreateItem->Flags |= KSCREATE_ITEM_SECURITYCHANGED; } /* store result */ - *Header = ObjectHeader; - - - DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader); - - return STATUS_SUCCESS; - -} - -/* - @unimplemented -*/ -KSDDKAPI -VOID -NTAPI -KsFreeObjectHeader( - IN PVOID Header) -{ - - -} - -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsCancelIo( - IN OUT PLIST_ENTRY QueueHead, - IN PKSPIN_LOCK SpinLock) -{ - UNIMPLEMENTED; -} - -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsCancelRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - UNIMPLEMENTED; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsDefaultDeviceIoCompletion( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI BOOLEAN NTAPI -KsDispatchFastIoDeviceControlFailure( - IN PFILE_OBJECT FileObject, - IN BOOLEAN Wait, - IN PVOID InputBuffer OPTIONAL, - IN ULONG InputBufferLength, - OUT PVOID OutputBuffer OPTIONAL, - IN ULONG OutputBufferLength, - IN ULONG IoControlCode, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) /* always return false */ -{ - return FALSE; -} - -/* - @unimplemented -*/ -KSDDKAPI BOOLEAN NTAPI -KsDispatchFastReadFailure( - IN PFILE_OBJECT FileObject, - IN PLARGE_INTEGER FileOffset, - IN ULONG Length, - IN BOOLEAN Wait, - IN ULONG LockKey, - OUT PVOID Buffer, - OUT PIO_STATUS_BLOCK IoStatus, - IN PDEVICE_OBJECT DeviceObject) /* always return false */ -{ - return FALSE; -} - -/* - Used in dispatch table entries that aren't handled and need to return - STATUS_INVALID_DEVICE_REQUEST. -*/ -KSDDKAPI NTSTATUS NTAPI -KsDispatchInvalidDeviceRequest( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INVALID_DEVICE_REQUEST; + return Status; } /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsDispatchSpecificMethod( - IN PIRP Irp, - IN PFNKSHANDLER Handler) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsDispatchSpecificProperty( IN PIRP Irp, IN PFNKSHANDLER Handler) @@ -482,113 +156,24 @@ KsDispatchSpecificProperty( /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsForwardAndCatchIrp( - IN PDEVICE_OBJECT DeviceObject, +KSDDKAPI +NTSTATUS +NTAPI +KsDispatchSpecificMethod( IN PIRP Irp, - IN PFILE_OBJECT FileObject, - IN KSSTACK_USE StackUse) + IN PFNKSHANDLER Handler) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; } -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsForwardIrp( - IN PIRP Irp, - IN PFILE_OBJECT FileObject, - IN BOOLEAN ReuseStackLocation) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsGetChildCreateParameter( - IN PIRP Irp, - OUT PVOID* CreateParameter) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsMoveIrpsOnCancelableQueue( - IN OUT PLIST_ENTRY SourceList, - IN PKSPIN_LOCK SourceLock, - IN OUT PLIST_ENTRY DestinationList, - IN PKSPIN_LOCK DestinationLock OPTIONAL, - IN KSLIST_ENTRY_LOCATION ListLocation, - IN PFNKSIRPLISTCALLBACK ListCallback, - IN PVOID Context) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsProbeStreamIrp( - IN PIRP Irp, - IN ULONG ProbeFlags, - IN ULONG HeaderSize) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsQueryInformationFile( - IN PFILE_OBJECT FileObject, - OUT PVOID FileInformation, - IN ULONG Length, - IN FILE_INFORMATION_CLASS FileInformationClass) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI ACCESS_MASK NTAPI -KsQueryObjectAccessMask( - IN KSOBJECT_HEADER Header) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI PKSOBJECT_CREATE_ITEM NTAPI -KsQueryObjectCreateItem( - IN KSOBJECT_HEADER Header) -{ - UNIMPLEMENTED; -/* return STATUS_UNSUCCESSFUL; */ - return NULL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsReadFile( IN PFILE_OBJECT FileObject, IN PKEVENT Event OPTIONAL, @@ -606,85 +191,126 @@ KsReadFile( /* @unimplemented */ -KSDDKAPI VOID NTAPI -KsReleaseIrpOnCancelableQueue( - IN PIRP Irp, - IN PDRIVER_CANCEL DriverCancel OPTIONAL) -{ - UNIMPLEMENTED; -} - -/* - @implemented -*/ KSDDKAPI -PIRP +NTSTATUS NTAPI -KsRemoveIrpFromCancelableQueue( - IN OUT PLIST_ENTRY QueueHead, - IN PKSPIN_LOCK SpinLock, - IN KSLIST_ENTRY_LOCATION ListLocation, - IN KSIRP_REMOVAL_OPERATION RemovalOperation) +KsWriteFile( + IN PFILE_OBJECT FileObject, + IN PKEVENT Event OPTIONAL, + IN PVOID PortContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + IN PVOID Buffer, + IN ULONG Length, + IN ULONG Key OPTIONAL, + IN KPROCESSOR_MODE RequestorMode) { - PQUEUE_ENTRY Entry = NULL; + PDEVICE_OBJECT DeviceObject; PIRP Irp; - KIRQL OldIrql; + NTSTATUS Status; + BOOLEAN Result; + KEVENT LocalEvent; - if (!QueueHead || !SpinLock) - return NULL; - - if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead) - return NULL; - - if (RemovalOperation != KsAcquireOnly && RemovalOperation != KsAcquireAndRemove) - return NULL; - - KeAcquireSpinLock(SpinLock, &OldIrql); - - if (!IsListEmpty(QueueHead)) + if (Event) { - if (RemovalOperation == KsAcquireOnly) + /* make sure event is reset */ + KeClearEvent(Event); + } + + if (RequestorMode == UserMode) + { + /* probe the user buffer */ + _SEH2_TRY { - if (ListLocation == KsListEntryHead) - Entry = (PQUEUE_ENTRY)QueueHead->Flink; - else - Entry = (PQUEUE_ENTRY)QueueHead->Blink; + ProbeForRead(Buffer, Length, sizeof(UCHAR)); + Status = STATUS_SUCCESS; } - else if (RemovalOperation == KsAcquireAndRemove) + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - if (ListLocation == KsListEntryTail) - Entry = (PQUEUE_ENTRY)RemoveTailList(QueueHead); - else - Entry = (PQUEUE_ENTRY)RemoveHeadList(QueueHead); + /* 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 write is only available for kernel mode clients */ + if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode && + DeviceObject->DriverObject->FastIoDispatch->FastIoWrite) + { + /* call fast io write */ + Result = DeviceObject->DriverObject->FastIoDispatch->FastIoWrite(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject); + + if (Result && NT_SUCCESS(IoStatusBlock->Status)) + { + /* request was handeled and succeeded */ + return STATUS_SUCCESS; } } - KeReleaseSpinLock(SpinLock, OldIrql); - if (!Entry) - return NULL; + /* do the slow way */ - Irp = Entry->Irp; + if (!Event) + { + /* initialize temp event */ + KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE); + Event = &LocalEvent; + } - if (RemovalOperation == KsAcquireAndRemove) - ExFreePool(Entry); + /* build the irp packet */ + Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject, Buffer, Length, &FileObject->CurrentByteOffset, Event, IoStatusBlock); + if (!Irp) + { + /* not enough resources */ + return STATUS_INSUFFICIENT_RESOURCES; + } - return Irp; + /* 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; } /* @unimplemented */ -KSDDKAPI VOID NTAPI -KsRemoveSpecificIrpFromCancelableQueue( - IN PIRP Irp) +KSDDKAPI +NTSTATUS +NTAPI +KsQueryInformationFile( + IN PFILE_OBJECT FileObject, + OUT PVOID FileInformation, + IN ULONG Length, + IN FILE_INFORMATION_CLASS FileInformationClass) { UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; } /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsSetInformationFile( IN PFILE_OBJECT FileObject, IN PVOID FileInformation, @@ -695,491 +321,6 @@ KsSetInformationFile( return STATUS_UNSUCCESSFUL; } - - -NTAPI -NTSTATUS -KsCreate( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PDEVICE_EXTENSION DeviceExtension; - PKSIDEVICE_HEADER DeviceHeader; - ULONG Index; - NTSTATUS Status; - KIRQL OldLevel; - ULONG Length; - - DPRINT("KS / CREATE\n"); - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - /* get device extension */ - DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; - /* get device header */ - DeviceHeader = DeviceExtension->DeviceHeader; - - /* acquire list lock */ - KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel); - - /* sanity check */ - ASSERT(IoStack->FileObject); - - if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->MaxItems == 1) - { - /* hack for bug 4566 */ - if (!DeviceHeader->ItemList[0].CreateItem || !DeviceHeader->ItemList[0].CreateItem->Create) - { - /* no valid create item */ - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - /* release lock */ - KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - /* return status */ - return STATUS_UNSUCCESSFUL; - } - - /* set object create item */ - KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[0].CreateItem; - - /* call create function */ - Status = DeviceHeader->ItemList[0].CreateItem->Create(DeviceObject, Irp); - /* release lock */ - KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - /* return result */ - return Status; - } - - - /* hack for bug 4566 */ - if (IoStack->FileObject->FileName.Buffer == NULL) - { - DPRINT("Using reference string hack\n"); - /* release lock */ - KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - Irp->IoStatus.Information = 0; - /* set return status */ - Irp->IoStatus.Status = STATUS_SUCCESS; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - - /* loop all device items */ - for(Index = 0; Index < DeviceHeader->MaxItems; Index++) - { - /* is there a create item */ - if (DeviceHeader->ItemList[Index].CreateItem == NULL) - continue; - - /* check if the create item is initialized */ - if (!DeviceHeader->ItemList[Index].CreateItem->Create) - continue; - - ASSERT(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); - DPRINT("CreateItem %p Request %S\n", DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, - IoStack->FileObject->FileName.Buffer); - - /* get object class length */ - Length = wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); - /* now check if the object class is the same */ - if (!_wcsnicmp(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, &IoStack->FileObject->FileName.Buffer[1], Length) || - (DeviceHeader->ItemList[Index].CreateItem->Flags & KSCREATE_ITEM_WILDCARD)) - { - /* setup create parameters */ - DeviceHeader->DeviceIndex = Index; - /* set object create item */ - KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[Index].CreateItem; - - /* call create function */ - Status = DeviceHeader->ItemList[Index].CreateItem->Create(DeviceObject, Irp); - - /* release lock */ - KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - - /* return result */ - return Status; - } - } - - /* release lock */ - KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - - Irp->IoStatus.Information = 0; - /* set return status */ - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -} - -static NTAPI -NTSTATUS -KsClose( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - PDEVICE_EXTENSION DeviceExtension; - PKSIDEVICE_HEADER DeviceHeader; - - /* 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) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - return ObjectHeader->DispatchTable.Close(DeviceObject, Irp); - } - 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; - } -} - -static NTAPI -NTSTATUS -KsDeviceControl( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - PKSIDEVICE_HEADER DeviceHeader; - PDEVICE_EXTENSION DeviceExtension; - ULONG Length, Index; - LPWSTR Buffer; - - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - /* 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; - - for(Index = 0; Index < DeviceHeader->MaxItems; Index++) - { - if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) - continue; - - Length += wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + 1; - } - - /* add extra zero */ - Length += 1; - - /* allocate the buffer */ - Buffer = ExAllocatePool(NonPagedPool, Length * sizeof(WCHAR)); - if (!Buffer) - { - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - - *((LPWSTR*)Irp->UserBuffer) = Buffer; - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(LPWSTR); - - for(Index = 0; Index < DeviceHeader->MaxItems; Index++) - { - if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) - continue; - - wcscpy(Buffer, DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); - Buffer += wcslen(Buffer) + 1; - } - *Buffer = L'\0'; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } - - DPRINT("KS / DeviceControl\n"); - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - - return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp); - } - else - { - DPRINT1("Expected Object Header\n"); - KeBugCheckEx(0, 0, 0, 0, 0); - return STATUS_SUCCESS; - } -} - -static NTAPI -NTSTATUS -KsRead( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - PKSIOBJECT_HEADER ObjectHeader; - - /* get current stack location */ - IoStack = IoGetCurrentIrpStackLocation(Irp); - - DPRINT("KS / Read\n"); - if (IoStack->FileObject && IoStack->FileObject->FsContext) - { - ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; - - KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - return ObjectHeader->DispatchTable.Read(DeviceObject, Irp); - } - else - { - DPRINT1("Expected Object Header\n"); - KeBugCheckEx(0, 0, 0, 0, 0); - return STATUS_SUCCESS; - } -} - -static NTAPI -NTSTATUS -KsWrite( - 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; - } -} - -static NTAPI -NTSTATUS -KsFlushBuffers( - 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; - } -} - -static NTAPI -NTSTATUS -KsQuerySecurity( - 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; - } -} - -static NTAPI -NTSTATUS -KsSetSecurity( - 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; - } -} - -/* - @implemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsSetMajorFunctionHandler( - IN PDRIVER_OBJECT DriverObject, - IN ULONG MajorFunction) -{ - /* - Sets a DriverObject's major function handler to point to an internal - function we implement. - - TODO: Deal with KSDISPATCH_FASTIO - */ - - switch ( MajorFunction ) - { - case IRP_MJ_CREATE: - DriverObject->MajorFunction[MajorFunction] = KsCreate; - break; - case IRP_MJ_CLOSE: - DriverObject->MajorFunction[MajorFunction] = KsClose; - break; - case IRP_MJ_DEVICE_CONTROL: - DriverObject->MajorFunction[MajorFunction] = KsDeviceControl; - break; - case IRP_MJ_READ: - DriverObject->MajorFunction[MajorFunction] = KsRead; - break; - case IRP_MJ_WRITE: - DriverObject->MajorFunction[MajorFunction] = KsWrite; - break; - case IRP_MJ_FLUSH_BUFFERS : - DriverObject->MajorFunction[MajorFunction] = KsFlushBuffers; - break; - case IRP_MJ_QUERY_SECURITY: - DriverObject->MajorFunction[MajorFunction] = KsQuerySecurity; - break; - case IRP_MJ_SET_SECURITY: - DriverObject->MajorFunction[MajorFunction] = KsSetSecurity; - break; - - default: - return STATUS_INVALID_PARAMETER; /* is this right? */ - }; - - return STATUS_SUCCESS; -} - -/* - @implemented -*/ -KSDDKAPI -NTSTATUS -NTAPI -KsDispatchIrp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) -{ - PIO_STACK_LOCATION IoStack; - - /* Calls a dispatch routine corresponding to the function code of the IRP */ - /* - First we need to get the dispatch table. An opaque header is pointed to by - FsContext. The first element points to this table. This table is the key - to dispatching the IRP correctly. - */ - - IoStack = IoGetCurrentIrpStackLocation(Irp); - DPRINT("KsDispatchIrp %x\n", IoStack->MajorFunction); - - switch (IoStack->MajorFunction) - { - case IRP_MJ_CREATE: - return KsCreate(DeviceObject, Irp); - case IRP_MJ_CLOSE: - return KsClose(DeviceObject, Irp); - break; - case IRP_MJ_DEVICE_CONTROL: - return KsDeviceControl(DeviceObject, Irp); - break; - case IRP_MJ_READ: - return KsRead(DeviceObject, Irp); - break; - case IRP_MJ_WRITE: - return KsWrite(DeviceObject, Irp); - break; - case IRP_MJ_FLUSH_BUFFERS: - return KsFlushBuffers(DeviceObject, Irp); - break; - case IRP_MJ_QUERY_SECURITY: - return KsQuerySecurity(DeviceObject, Irp); - break; - case IRP_MJ_SET_SECURITY: - return KsSetSecurity(DeviceObject, Irp); - break; - default: - return STATUS_INVALID_PARAMETER; /* is this right? */ - }; -} - - /* @implemented */ @@ -1273,19 +414,17 @@ KsStreamIo( return Status; } + /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsWriteFile( - IN PFILE_OBJECT FileObject, - IN PKEVENT Event OPTIONAL, - IN PVOID PortContext OPTIONAL, - OUT PIO_STATUS_BLOCK IoStatusBlock, - IN PVOID Buffer, - IN ULONG Length, - IN ULONG Key OPTIONAL, - IN KPROCESSOR_MODE RequestorMode) +KSDDKAPI +NTSTATUS +NTAPI +KsProbeStreamIrp( + IN PIRP Irp, + IN ULONG ProbeFlags, + IN ULONG HeaderSize) { UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; @@ -1294,15 +433,775 @@ KsWriteFile( /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsDefaultForwardIrp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) +KSDDKAPI +NTSTATUS +NTAPI +KsAllocateExtraData( + IN PIRP Irp, + IN ULONG ExtraSize, + OUT PVOID* ExtraBuffer) { UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsNullDriverUnload( + IN PDRIVER_OBJECT DriverObject) +{ +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsDispatchInvalidDeviceRequest( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + return STATUS_INVALID_DEVICE_REQUEST; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsDefaultDeviceIoCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + NTSTATUS Status; + + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY && + IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_METHOD && + IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) + { + if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) + { + /* fake success */ + Status = STATUS_SUCCESS; + } + else + { + /* request unsupported */ + Status = STATUS_INVALID_DEVICE_REQUEST; + } + } + else + { + /* property / method / event not found */ + Status = STATUS_PROPSET_NOT_FOUND; + } + + /* complete request */ + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + + + return Status; +} + +/* + @implemented +*/ +KSDDKAPI +BOOLEAN +NTAPI +KsDispatchFastIoDeviceControlFailure( + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + +/* + @implemented +*/ +KSDDKAPI +BOOLEAN +NTAPI +KsDispatchFastReadFailure( + IN PFILE_OBJECT FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject) +{ + return FALSE; +} + + +/* + @unimplemented +*/ +KSDDKAPI +VOID +NTAPI +KsCancelIo( + IN OUT PLIST_ENTRY QueueHead, + IN PKSPIN_LOCK SpinLock) +{ + UNIMPLEMENTED; +} + +/* + @unimplemented +*/ +KSDDKAPI +VOID +NTAPI +KsReleaseIrpOnCancelableQueue( + IN PIRP Irp, + IN PDRIVER_CANCEL DriverCancel OPTIONAL) +{ + UNIMPLEMENTED; +} + +/* + @implemented +*/ +KSDDKAPI +PIRP +NTAPI +KsRemoveIrpFromCancelableQueue( + IN OUT PLIST_ENTRY QueueHead, + IN PKSPIN_LOCK SpinLock, + IN KSLIST_ENTRY_LOCATION ListLocation, + IN KSIRP_REMOVAL_OPERATION RemovalOperation) +{ + PQUEUE_ENTRY Entry = NULL; + PIRP Irp; + KIRQL OldIrql; + + if (!QueueHead || !SpinLock) + return NULL; + + if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead) + return NULL; + + if (RemovalOperation != KsAcquireOnly && RemovalOperation != KsAcquireAndRemove) + return NULL; + + KeAcquireSpinLock(SpinLock, &OldIrql); + + if (!IsListEmpty(QueueHead)) + { + if (RemovalOperation == KsAcquireOnly) + { + if (ListLocation == KsListEntryHead) + Entry = (PQUEUE_ENTRY)QueueHead->Flink; + else + Entry = (PQUEUE_ENTRY)QueueHead->Blink; + } + else if (RemovalOperation == KsAcquireAndRemove) + { + if (ListLocation == KsListEntryTail) + Entry = (PQUEUE_ENTRY)RemoveTailList(QueueHead); + else + Entry = (PQUEUE_ENTRY)RemoveHeadList(QueueHead); + } + } + KeReleaseSpinLock(SpinLock, OldIrql); + + if (!Entry) + return NULL; + + Irp = Entry->Irp; + + if (RemovalOperation == KsAcquireAndRemove) + ExFreePool(Entry); + + return Irp; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsMoveIrpsOnCancelableQueue( + IN OUT PLIST_ENTRY SourceList, + IN PKSPIN_LOCK SourceLock, + IN OUT PLIST_ENTRY DestinationList, + IN PKSPIN_LOCK DestinationLock OPTIONAL, + IN KSLIST_ENTRY_LOCATION ListLocation, + IN PFNKSIRPLISTCALLBACK ListCallback, + IN PVOID Context) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +/* + @unimplemented +*/ +KSDDKAPI +VOID +NTAPI +KsRemoveSpecificIrpFromCancelableQueue( + IN PIRP Irp) +{ + UNIMPLEMENTED; +} + + +/* + @implemented +*/ +KSDDKAPI +VOID +NTAPI +KsAddIrpToCancelableQueue( + IN OUT PLIST_ENTRY QueueHead, + IN PKSPIN_LOCK SpinLock, + IN PIRP Irp, + IN KSLIST_ENTRY_LOCATION ListLocation, + IN PDRIVER_CANCEL DriverCancel OPTIONAL) +{ + UNIMPLEMENTED; +} + +/* + @unimplemented +*/ +KSDDKAPI +VOID +NTAPI +KsCancelRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + UNIMPLEMENTED; +} + +/* + @unimplemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsGetChildCreateParameter( + IN PIRP Irp, + OUT PVOID* CreateParameter) +{ + UNIMPLEMENTED; + return STATUS_UNSUCCESSFUL; +} + +NTAPI +NTSTATUS +KspCreate( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; + ULONG Index; + NTSTATUS Status; + KIRQL OldLevel; + ULONG Length; + + DPRINT("KS / CREATE\n"); + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + + /* acquire list lock */ + KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel); + + /* sanity check */ + ASSERT(IoStack->FileObject); + + if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->MaxItems == 1) + { + /* hack for bug 4566 */ + if (!DeviceHeader->ItemList[0].CreateItem || !DeviceHeader->ItemList[0].CreateItem->Create) + { + /* no valid create item */ + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + /* return status */ + return STATUS_UNSUCCESSFUL; + } + + /* set object create item */ + KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[0].CreateItem; + + /* call create function */ + Status = DeviceHeader->ItemList[0].CreateItem->Create(DeviceObject, Irp); + + if (NT_SUCCESS(Status)) + { + /* increment create item reference count */ + InterlockedIncrement((PLONG)&DeviceHeader->ItemList[0].ReferenceCount); + } + + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + /* return result */ + return Status; + } + + + /* hack for bug 4566 */ + if (IoStack->FileObject->FileName.Buffer == NULL) + { + DPRINT("Using reference string hack\n"); + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + Irp->IoStatus.Information = 0; + /* set return status */ + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + + /* loop all device items */ + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + /* is there a create item */ + if (DeviceHeader->ItemList[Index].CreateItem == NULL) + continue; + + /* check if the create item is initialized */ + if (!DeviceHeader->ItemList[Index].CreateItem->Create) + continue; + + ASSERT(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + DPRINT("CreateItem %p Request %S\n", DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, + IoStack->FileObject->FileName.Buffer); + + /* get object class length */ + Length = wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + /* now check if the object class is the same */ + if (!_wcsnicmp(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, &IoStack->FileObject->FileName.Buffer[1], Length) || + (DeviceHeader->ItemList[Index].CreateItem->Flags & KSCREATE_ITEM_WILDCARD)) + { + /* setup create parameters */ + DeviceHeader->DeviceIndex = Index; + /* set object create item */ + KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[Index].CreateItem; + + /* call create function */ + Status = DeviceHeader->ItemList[Index].CreateItem->Create(DeviceObject, Irp); + + if (NT_SUCCESS(Status)) + { + /* increment create item reference count */ + InterlockedIncrement((PLONG)&DeviceHeader->ItemList[Index].ReferenceCount); + } + + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + + /* return result */ + return Status; + } + } + + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + Irp->IoStatus.Information = 0; + /* set return status */ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(Irp, IO_NO_INCREMENT); 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( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + PKSIDEVICE_HEADER DeviceHeader; + PDEVICE_EXTENSION DeviceExtension; + ULONG Length, Index; + LPWSTR Buffer; + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* 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; + + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + continue; + + Length += wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + 1; + } + + /* add extra zero */ + Length += 1; + + /* allocate the buffer */ + Buffer = ExAllocatePool(NonPagedPool, Length * sizeof(WCHAR)); + if (!Buffer) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + *((LPWSTR*)Irp->UserBuffer) = Buffer; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(LPWSTR); + + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + continue; + + wcscpy(Buffer, DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + Buffer += wcslen(Buffer) + 1; + } + *Buffer = L'\0'; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + + DPRINT("KS / DeviceControl\n"); + if (IoStack->FileObject && IoStack->FileObject->FsContext) + { + ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; + + KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; + + return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp); + } + else + { + DPRINT1("Expected Object Header\n"); + KeBugCheckEx(0, 0, 0, 0, 0); + return STATUS_SUCCESS; + } +} + +NTAPI +NTSTATUS +KspRead( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + PKSIOBJECT_HEADER ObjectHeader; + + /* get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + DPRINT("KS / Read\n"); + if (IoStack->FileObject && IoStack->FileObject->FsContext) + { + ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; + + KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; + return ObjectHeader->DispatchTable.Read(DeviceObject, Irp); + } + else + { + DPRINT1("Expected Object Header\n"); + KeBugCheckEx(0, 0, 0, 0, 0); + return STATUS_SUCCESS; + } +} + +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; + } +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsSetMajorFunctionHandler( + IN PDRIVER_OBJECT DriverObject, + IN ULONG MajorFunction) +{ + switch ( MajorFunction ) + { + 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_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; + break; + + default: + return STATUS_INVALID_PARAMETER; + }; + + return STATUS_SUCCESS; +} + +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +KsDispatchIrp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + PIO_STACK_LOCATION IoStack; + /* get current irp stack */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + //FIXME REWRITE + + switch (IoStack->MajorFunction) + { + case IRP_MJ_CREATE: + return KspCreate(DeviceObject, Irp); + case IRP_MJ_CLOSE: + return KspClose(DeviceObject, Irp); + break; + case IRP_MJ_DEVICE_CONTROL: + 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? */ + }; +} diff --git a/reactos/drivers/ksfilter/ks/kcom.c b/reactos/drivers/ksfilter/ks/kcom.c index 3b2a7b63d5a..8921caf1268 100644 --- a/reactos/drivers/ksfilter/ks/kcom.c +++ b/reactos/drivers/ksfilter/ks/kcom.c @@ -1,6 +1,11 @@ -/* =============================================================== - Kernel-mode COM -*/ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/allocators.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + Andrew Greenwood + */ #include "priv.h" diff --git a/reactos/drivers/ksfilter/ks/ks.rbuild b/reactos/drivers/ksfilter/ks/ks.rbuild index 8862684d5df..1e8998d7ca3 100644 --- a/reactos/drivers/ksfilter/ks/ks.rbuild +++ b/reactos/drivers/ksfilter/ks/ks.rbuild @@ -7,20 +7,26 @@ ntoskrnl hal + pseh ks.rc + api.c allocators.c bag.c device.c + deviceinterface.c driver.c clocks.c connectivity.c - events.c + event.c + filter.c + filterfactory.c + image.c irp.c methods.c misc.c - properties.c + property.c topology.c worker.c kcom.c diff --git a/reactos/drivers/ksfilter/ks/ksfunc.h b/reactos/drivers/ksfilter/ks/ksfunc.h index a3769122e80..3b87f6df060 100644 --- a/reactos/drivers/ksfilter/ks/ksfunc.h +++ b/reactos/drivers/ksfilter/ks/ksfunc.h @@ -3,10 +3,6 @@ #include "ksiface.h" -NTSTATUS -NTAPI -NewIKsDevice(IKsDevice** OutDevice); - #define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24)) #define TAG_KSDEVICE TAG('K', 'S', 'E', 'D') #define TAG_KSOBJECT_TAG TAG('K', 'S', 'O', 'H') @@ -21,6 +17,86 @@ KspCreateObjectType( IN ACCESS_MASK DesiredAccess, OUT PHANDLE NodeHandle); +NTSTATUS +NTAPI +KspCreateFilterFactory( + IN PDEVICE_OBJECT DeviceObject, + IN const KSFILTER_DESCRIPTOR *Descriptor, + IN PWSTR RefString OPTIONAL, + IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN ULONG CreateItemFlags, + IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, + IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, + OUT PKSFILTERFACTORY *FilterFactory OPTIONAL); +NTSTATUS +NTAPI +IKsDevice_Create( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +NTAPI +IKsDevice_Pnp( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +NTAPI +IKsDevice_Power( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +NTAPI +KspCreateFilter( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN IKsFilterFactory *iface); + +NTSTATUS +KspSetDeviceInterfacesState( + IN PLIST_ENTRY ListHead, + IN BOOL Enable); + +NTSTATUS +KspFreeDeviceInterfaces( + IN PLIST_ENTRY ListHead); + +NTSTATUS +KspRegisterDeviceInterfaces( + IN PDEVICE_OBJECT PhysicalDeviceObject, + IN ULONG CategoriesCount, + IN GUID const*Categories, + IN PUNICODE_STRING ReferenceString, + OUT PLIST_ENTRY SymbolicLinkList); + +NTSTATUS +KspForwardIrpSynchronous( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +PVOID +AllocateItem( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes); + +VOID +FreeItem( + IN PVOID Item); + +NTSTATUS +NTAPI +KspTopologyPropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data); + +NTSTATUS +NTAPI +KspPinPropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data); #endif diff --git a/reactos/drivers/ksfilter/ks/ksiface.h b/reactos/drivers/ksfilter/ks/ksiface.h index 896652b554e..f323e1a84c8 100644 --- a/reactos/drivers/ksfilter/ks/ksiface.h +++ b/reactos/drivers/ksfilter/ks/ksiface.h @@ -14,6 +14,129 @@ STDMETHOD_(ULONG,Release)(THIS) PURE; #endif +/***************************************************************************** + * IKsAllocator + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IKsAllocator + +DECLARE_INTERFACE_(IKsAllocator, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + + STDMETHOD_(NTSTATUS, DispatchDeviceIoControl)(THIS_ + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) PURE; + + STDMETHOD_(NTSTATUS, Close)(THIS) PURE; + + STDMETHOD_(NTSTATUS, AllocateFrame)(THIS_ + IN PVOID * OutFrame) PURE; + + STDMETHOD_(VOID, FreeFrame)(THIS_ + IN PVOID OutFrame) PURE; +}; + + +/***************************************************************************** + * IKsPin + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IKsClock + +DECLARE_INTERFACE_(IKsClock, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() +}; + +/***************************************************************************** + * IKsPin + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IKsPin + +DECLARE_INTERFACE_(IKsPin, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() +}; + +/***************************************************************************** + * IKsQueue + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IKsQueue + +DECLARE_INTERFACE_(IKsQueue, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + +}; + +/***************************************************************************** + * IKsFilterFactory + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IKsFilter + +struct KSPROCESSPIPESECTION; + + +DECLARE_INTERFACE_(IKsFilter, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + + STDMETHOD_(PKSFILTER, GetStruct)(THIS) PURE; + + STDMETHOD_(BOOL, DoAllNecessaryPinsExist)(THIS) PURE; + + STDMETHOD_(NTSTATUS, CreateNode)(THIS_ + IN PIRP Irp, + IN IKsPin * Pin, + IN PLIST_ENTRY ListEntry) PURE; + + STDMETHOD_(NTSTATUS, BindProcessPinsToPipeSection)(THIS_ + IN struct KSPROCESSPIPESECTION *Section, + IN PVOID Create, + IN PKSPIN KsPin, + OUT IKsPin **Pin, + OUT PKSGATE *OutGate) PURE; + + STDMETHOD_(NTSTATUS, UnbindProcessPinsFromPipeSection)(THIS_ + IN struct KSPROCESSPIPESECTION *Section) PURE; + + STDMETHOD_(NTSTATUS, AddProcessPin)(THIS_ + IN PKSPROCESSPIN ProcessPin) PURE; + + STDMETHOD_(NTSTATUS, RemoveProcessPin)(THIS_ + IN PKSPROCESSPIN ProcessPin) PURE; + + STDMETHOD_(BOOL, ReprepareProcessPipeSection)(THIS_ + IN struct KSPROCESSPIPESECTION *PipeSection, + IN PULONG Data) PURE; + + STDMETHOD_(VOID, DeliverResetState)(THIS_ + IN struct KSPROCESSPIPESECTION *PipeSection, + IN KSRESET ResetState) PURE; + + STDMETHOD_(BOOL, IsFrameHolding)(THIS); + + STDMETHOD_(VOID, RegisterForCopyCallbacks)(THIS_ + IKsQueue * Queue, + IN BOOL Enable) PURE; + + STDMETHOD_(PKSPROCESSPIN_INDEXENTRY, GetProcessDispatch)(THIS); +}; + /***************************************************************************** * IKsFilterFactory ***************************************************************************** @@ -26,10 +149,26 @@ DECLARE_INTERFACE_(IKsFilterFactory, IUnknown) { DEFINE_ABSTRACT_UNKNOWN() - STDMETHOD_(KSFILTERFACTORY*,GetStruct)(THIS) PURE; + STDMETHOD_(KSFILTERFACTORY*, GetStruct)(THIS) PURE; - STDMETHOD_(NTSTATUS,SetDeviceClassesState)(THIS_ + STDMETHOD_(NTSTATUS, SetDeviceClassesState)(THIS_ IN BOOLEAN Enable)PURE; + + STDMETHOD_(NTSTATUS, Initialize)(THIS_ + IN PDEVICE_OBJECT DeviceObject, + IN const KSFILTER_DESCRIPTOR *Descriptor, + IN PWSTR RefString OPTIONAL, + IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, + IN ULONG CreateItemFlags, + IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL, + IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL, + OUT PKSFILTERFACTORY *FilterFactory OPTIONAL)PURE; + + STDMETHOD_(NTSTATUS, AddFilterInstance)(THIS_ + IN IKsFilter *Filter)PURE; + + STDMETHOD_(NTSTATUS, RemoveFilterInstance)(THIS_ + IN IKsFilter *Filter)PURE; }; diff --git a/reactos/drivers/ksfilter/ks/kstypes.h b/reactos/drivers/ksfilter/ks/kstypes.h index 89f2cf70a97..ab34c5b60cf 100644 --- a/reactos/drivers/ksfilter/ks/kstypes.h +++ b/reactos/drivers/ksfilter/ks/kstypes.h @@ -1,33 +1,60 @@ #ifndef KSTYPES_H__ #define KSTYPES_H__ -struct KSIDEVICE_HEADER; - typedef struct { KSDISPATCH_TABLE DispatchTable; + KSOBJECTTYPE Type; ULONG ItemCount; PKSOBJECT_CREATE_ITEM CreateItem; UNICODE_STRING ObjectClass; + PUNKNOWN Unknown; + + PDEVICE_OBJECT TargetDevice; + LIST_ENTRY TargetDeviceListEntry; + + PDEVICE_OBJECT ParentDeviceObject; + + PFNKSCONTEXT_DISPATCH PowerDispatch; + PVOID PowerContext; + LIST_ENTRY PowerDispatchEntry; + }KSIOBJECT_HEADER, *PKSIOBJECT_HEADER; typedef struct { PKSOBJECT_CREATE_ITEM CreateItem; + PFNKSITEMFREECALLBACK ItemFreeCallback; + LONG ReferenceCount; }DEVICE_ITEM, *PDEVICE_ITEM; + typedef struct { + IKsDeviceVtbl *lpVtblIKsDevice; + LONG ref; + ERESOURCE SecurityLock; + USHORT MaxItems; DEVICE_ITEM *ItemList; ULONG DeviceIndex; KSPIN_LOCK ItemListLock; + PDEVICE_OBJECT PhysicalDeviceObject; PDEVICE_OBJECT NextDeviceObject; - ERESOURCE SecurityLock; + + KSTARGET_STATE TargetState; + LIST_ENTRY TargetDeviceList; + + KSDEVICE KsDevice; + KMUTEX DeviceMutex; + KSDEVICE_DESCRIPTOR* Descriptor; + + LIST_ENTRY PowerDispatchList; + }KSIDEVICE_HEADER, *PKSIDEVICE_HEADER; @@ -43,5 +70,17 @@ typedef struct PIRP Irp; }QUEUE_ENTRY, *PQUEUE_ENTRY; +typedef struct +{ + LIST_ENTRY Entry; + UNICODE_STRING SymbolicLink; +}SYMBOLIC_LINK_ENTRY, *PSYMBOLIC_LINK_ENTRY; + +typedef struct +{ + PKSIDEVICE_HEADER DeviceHeader; + PIO_WORKITEM WorkItem; +}PNP_POSTSTART_CONTEXT, *PPNP_POSTSTART_CONTEXT; + #endif diff --git a/reactos/drivers/ksfilter/ks/methods.c b/reactos/drivers/ksfilter/ks/methods.c index 9084df3773d..512371a6a29 100644 --- a/reactos/drivers/ksfilter/ks/methods.c +++ b/reactos/drivers/ksfilter/ks/methods.c @@ -1,13 +1,19 @@ -#include "priv.h" +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/methods.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + */ -/* =============================================================== - Method Functions -*/ +#include "priv.h" /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsMethodHandler( IN PIRP Irp, IN ULONG MethodSetsCount, @@ -20,7 +26,9 @@ KsMethodHandler( /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsMethodHandlerWithAllocator( IN PIRP Irp, IN ULONG MethodSetsCount, @@ -35,7 +43,9 @@ KsMethodHandlerWithAllocator( /* @unimplemented */ -KSDDKAPI BOOLEAN NTAPI +KSDDKAPI +BOOLEAN +NTAPI KsFastMethodHandler( IN PFILE_OBJECT FileObject, IN PKSMETHOD UNALIGNED Method, diff --git a/reactos/drivers/ksfilter/ks/misc.c b/reactos/drivers/ksfilter/ks/misc.c index a20d2dd181f..07700105bde 100644 --- a/reactos/drivers/ksfilter/ks/misc.c +++ b/reactos/drivers/ksfilter/ks/misc.c @@ -1,175 +1,84 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/misc.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" -/* =============================================================== - Misc. Helper Functions -*/ - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsCacheMedium( - IN PUNICODE_STRING SymbolicLink, - IN PKSPIN_MEDIUM Medium, - IN ULONG PinDirection) +PVOID +AllocateItem( + IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes) { - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + PVOID Item = ExAllocatePool(PoolType, NumberOfBytes); + if (!Item) + return Item; + + RtlZeroMemory(Item, NumberOfBytes); + return Item; } -/* - @unimplemented -*/ - -KSDDKAPI NTSTATUS NTAPI -KsDefaultDispatchPnp( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp) +VOID +FreeItem( + IN PVOID Item) { - PIO_STACK_LOCATION IoStack; - NTSTATUS Status = STATUS_SUCCESS; - IoStack = IoGetCurrentIrpStackLocation(Irp); + ExFreePool(Item); +} - DPRINT1("KsDefaultDispatchPnp entered with func %x\n", IoStack->MinorFunction); - - switch(IoStack->MinorFunction) +NTSTATUS +NTAPI +KspForwardIrpSynchronousCompletion( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + if (Irp->PendingReturned == TRUE) { - 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); + KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE); } - - return Status; + return STATUS_MORE_PROCESSING_REQUIRED; } -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsSetDevicePnpAndBaseObject( - IN KSDEVICE_HEADER Header, - IN PDEVICE_OBJECT PnpDeviceObject, - IN PDEVICE_OBJECT BaseDevice) -{ - UNIMPLEMENTED; -} -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsDefaultDispatchPower( +NTSTATUS +KspForwardIrpSynchronous( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { - UNIMPLEMENTED; + KEVENT Event; + NTSTATUS Status; + PDEVICE_EXTENSION DeviceExtension; + PKSIDEVICE_HEADER DeviceHeader; - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -} + ASSERT_IRQL_EQUAL(PASSIVE_LEVEL); -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsSetPowerDispatch( - IN KSOBJECT_HEADER Header, - IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL, - IN PVOID PowerContext OPTIONAL) -{ - UNIMPLEMENTED; -} + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsReferenceBusObject( - IN KSDEVICE_HEADER Header) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} + /* initialize the notification event */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsDereferenceBusObject( - IN KSDEVICE_HEADER Header) -{ - UNIMPLEMENTED; -} + IoCopyCurrentIrpStackLocationToNext(Irp); -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsFreeObjectCreateItem( - IN KSDEVICE_HEADER Header, - IN PUNICODE_STRING CreateItem) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} + IoSetCompletionRoutine(Irp, KspForwardIrpSynchronousCompletion, (PVOID)&Event, TRUE, TRUE, TRUE); -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsFreeObjectCreateItemsByContext( - IN KSDEVICE_HEADER Header, - IN PVOID Context) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI -KsLoadResource( - IN PVOID ImageBase, - IN POOL_TYPE PoolType, - IN ULONG_PTR ResourceName, - IN ULONG ResourceType, - OUT PVOID* Resource, - OUT PULONG ResourceSize) -{ - UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; -} - -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsNullDriverUnload( - IN PDRIVER_OBJECT DriverObject) -{ - UNIMPLEMENTED; + /* now call the driver */ + Status = IoCallDriver(DeviceHeader->NextDeviceObject, Irp); + /* did the request complete yet */ + if (Status == STATUS_PENDING) + { + /* not yet, lets wait a bit */ + KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); + Status = Irp->IoStatus.Status; + } + return Status; } /* @@ -189,189 +98,3 @@ KsPinDataIntersectionEx( UNIMPLEMENTED; return STATUS_UNSUCCESSFUL; } - -/* - @unimplemented -*/ -KSDDKAPI PDEVICE_OBJECT NTAPI -KsQueryDevicePnpObject( - IN KSDEVICE_HEADER Header) -{ - UNIMPLEMENTED; - return NULL; -} - -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsRecalculateStackDepth( - IN KSDEVICE_HEADER Header, - IN BOOLEAN ReuseStackLocation) -{ - UNIMPLEMENTED; -} - -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsSetTargetDeviceObject( - IN KSOBJECT_HEADER Header, - IN PDEVICE_OBJECT TargetDevice OPTIONAL) -{ - UNIMPLEMENTED; -} - -/* - @unimplemented -*/ -KSDDKAPI VOID NTAPI -KsSetTargetState( - IN KSOBJECT_HEADER Header, - IN KSTARGET_STATE TargetState) -{ - UNIMPLEMENTED; -} - -NTSTATUS -NTAPI -CompletionRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)Context; - - IoStatusBlock->Information = Irp->IoStatus.Information; - IoStatusBlock->Status = Irp->IoStatus.Status; - - return STATUS_SUCCESS; -} - -/* - @implemented -*/ -KSDDKAPI -NTSTATUS -NTAPI -KsSynchronousIoControlDevice( - IN PFILE_OBJECT FileObject, - IN KPROCESSOR_MODE RequestorMode, - IN ULONG IoControl, - IN PVOID InBuffer, - IN ULONG InSize, - OUT PVOID OutBuffer, - IN ULONG OutSize, - OUT PULONG BytesReturned) -{ - PKSIOBJECT_HEADER ObjectHeader; - PDEVICE_OBJECT DeviceObject; - KEVENT Event; - PIRP Irp; - IO_STATUS_BLOCK IoStatusBlock; - PIO_STACK_LOCATION IoStack; - NTSTATUS Status; - - /* check for valid file object */ - if (!FileObject) - return STATUS_INVALID_PARAMETER; - - /* get device object to send the request to */ - DeviceObject = IoGetRelatedDeviceObject(FileObject); - if (!DeviceObject) - return STATUS_UNSUCCESSFUL; - - - /* get object header */ - ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext; -#if 0 - if (!ObjectHeader) - { - DPRINT("Expected object header\n"); - return STATUS_UNSUCCESSFUL; - } -#endif - /* check if there is fast device io function */ - if (ObjectHeader && ObjectHeader->DispatchTable.FastDeviceIoControl) - { - IoStatusBlock.Status = STATUS_UNSUCCESSFUL; - IoStatusBlock.Information = 0; - - /* it is send the request */ - Status = ObjectHeader->DispatchTable.FastDeviceIoControl(FileObject, TRUE, InBuffer, InSize, OutBuffer, OutSize, IoControl, &IoStatusBlock, DeviceObject); - /* check if the request was handled */ - DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information); - if (Status) - { - /* store bytes returned */ - *BytesReturned = IoStatusBlock.Information; - /* return status */ - return IoStatusBlock.Status; - } - } - - /* initialize the event */ - KeInitializeEvent(&Event, NotificationEvent, FALSE); - - /* create the irp */ - Irp = IoBuildDeviceIoControlRequest(IoControl, DeviceObject, InBuffer, InSize, OutBuffer, OutSize, FALSE, &Event, &IoStatusBlock); - - /* HACK */ - IoStack = IoGetNextIrpStackLocation(Irp); - IoStack->FileObject = FileObject; - - IoSetCompletionRoutine(Irp, CompletionRoutine, (PVOID)&IoStatusBlock, TRUE, TRUE, TRUE); - - Status = IoCallDriver(DeviceObject, Irp); - if (Status == STATUS_PENDING) - { - KeWaitForSingleObject(&Event, Executive, RequestorMode, FALSE, NULL); - Status = IoStatusBlock.Status; - } - - *BytesReturned = IoStatusBlock.Information; - return Status; -} - - -/* - @implemented -*/ -KSDDKAPI -VOID -NTAPI -KsAcquireDeviceSecurityLock( - IN KSDEVICE_HEADER DevHeader, - IN BOOLEAN Exclusive) -{ - NTSTATUS Status; - PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader; - - KeEnterCriticalRegion(); - - if (Exclusive) - { - Status = ExAcquireResourceExclusiveLite(&Header->SecurityLock, TRUE); - } - else - { - Status = ExAcquireResourceSharedLite(&Header->SecurityLock, TRUE); - } -} - -/* - @implemented -*/ -KSDDKAPI -VOID -NTAPI -KsReleaseDeviceSecurityLock( - IN KSDEVICE_HEADER DevHeader) -{ - PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader; - - ExReleaseResourceLite(&Header->SecurityLock); - KeLeaveCriticalRegion(); -} - diff --git a/reactos/drivers/ksfilter/ks/priv.h b/reactos/drivers/ksfilter/ks/priv.h index 44f04149b6d..3ee1033e3eb 100644 --- a/reactos/drivers/ksfilter/ks/priv.h +++ b/reactos/drivers/ksfilter/ks/priv.h @@ -1,6 +1,8 @@ #ifndef PRIV_H__ #define PRIV_H__ +#define _KSDDK_ + #include #include #define NDEBUG @@ -8,6 +10,8 @@ #include #include #include +#include +#include #include "ksfunc.h" #include "kstypes.h" @@ -18,4 +22,22 @@ #define IOCTL_KS_OBJECT_CLASS CTL_CODE(FILE_DEVICE_KS, 0x7, METHOD_NEITHER, FILE_ANY_ACCESS) + +#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ + PropGeneral, PropInstances, PropIntersection)\ +DEFINE_KSPROPERTY_TABLE(PinSet) {\ + DEFINE_KSPROPERTY_ITEM_PIN_CINSTANCES(PropInstances),\ + DEFINE_KSPROPERTY_ITEM_PIN_CTYPES(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_DATAFLOW(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_DATARANGES(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_DATAINTERSECTION(PropIntersection),\ + DEFINE_KSPROPERTY_ITEM_PIN_INTERFACES(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_MEDIUMS(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_COMMUNICATION(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_CATEGORY(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_NAME(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_CONSTRAINEDDATARANGES(PropGeneral),\ + DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\ +} + #endif diff --git a/reactos/drivers/ksfilter/ks/properties.c b/reactos/drivers/ksfilter/ks/property.c similarity index 67% rename from reactos/drivers/ksfilter/ks/properties.c rename to reactos/drivers/ksfilter/ks/property.c index 44ee640f536..f53329de679 100644 --- a/reactos/drivers/ksfilter/ks/properties.c +++ b/reactos/drivers/ksfilter/ks/property.c @@ -1,31 +1,19 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/event.c + * PURPOSE: KS property handling functions + * PROGRAMMER: Johannes Anderwald + */ + #include "priv.h" -/* =============================================================== - Property Functions -*/ - /* @unimplemented */ -KSDDKAPI BOOLEAN NTAPI -KsFastPropertyHandler( - IN PFILE_OBJECT FileObject, - IN PKSPROPERTY UNALIGNED Property, - IN ULONG PropertyLength, - IN OUT PVOID UNALIGNED Data, - IN ULONG DataLength, - OUT PIO_STATUS_BLOCK IoStatus, - IN ULONG PropertySetsCount, - IN const KSPROPERTY_SET* PropertySet) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - @unimplemented -*/ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsPropertyHandler( IN PIRP Irp, IN ULONG PropertySetsCount, @@ -35,10 +23,13 @@ KsPropertyHandler( return STATUS_UNSUCCESSFUL; } + /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI +KSDDKAPI +NTSTATUS +NTAPI KsPropertyHandlerWithAllocator( IN PIRP Irp, IN ULONG PropertySetsCount, @@ -53,12 +44,19 @@ KsPropertyHandlerWithAllocator( /* @unimplemented */ -KSDDKAPI NTSTATUS NTAPI -KsUnserializeObjectPropertiesFromRegistry( +KSDDKAPI +BOOLEAN +NTAPI +KsFastPropertyHandler( IN PFILE_OBJECT FileObject, - IN HANDLE ParentKey OPTIONAL, - IN PUNICODE_STRING RegistryPath OPTIONAL) + IN PKSPROPERTY UNALIGNED Property, + IN ULONG PropertyLength, + IN OUT PVOID UNALIGNED Data, + IN ULONG DataLength, + OUT PIO_STATUS_BLOCK IoStatus, + IN ULONG PropertySetsCount, + IN const KSPROPERTY_SET* PropertySet) { UNIMPLEMENTED; - return STATUS_UNSUCCESSFUL; + return FALSE; } diff --git a/reactos/drivers/ksfilter/ks/topology.c b/reactos/drivers/ksfilter/ks/topology.c index 07d7d855855..42cf66ff8f7 100644 --- a/reactos/drivers/ksfilter/ks/topology.c +++ b/reactos/drivers/ksfilter/ks/topology.c @@ -1,8 +1,14 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/topoology.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" -/* =============================================================== - Topology Functions -*/ NTSTATUS NTAPI @@ -291,3 +297,14 @@ KsTopologyPropertyHandler( return Status; } + +NTSTATUS +NTAPI +KspTopologyPropertyHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + + return STATUS_NOT_IMPLEMENTED; +} diff --git a/reactos/drivers/ksfilter/ks/worker.c b/reactos/drivers/ksfilter/ks/worker.c index 426859963ad..c36d4a5ba27 100644 --- a/reactos/drivers/ksfilter/ks/worker.c +++ b/reactos/drivers/ksfilter/ks/worker.c @@ -1,3 +1,12 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS Kernel Streaming + * FILE: drivers/ksfilter/ks/worker.c + * PURPOSE: KS Allocator functions + * PROGRAMMER: Johannes Anderwald + */ + + #include "priv.h" /* ===============================================================