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"
/* ===============================================================