allocators.c

- Implement IKsAllocator interface and use it in new implemented KsCreateAllocator, KsCreateDefaultAllocatorEx, KsValidateAllocatorFramingEx
api.c
- Implement KsSetDevicePnpAndBaseObject, KsQueryDevicePnpObject, KsSetTargetState, KsSetTargetDeviceObject, KsSetPowerDispatch, KsFreeDeviceHeader, KsFreeObjectHeader, KsAllocateObjectCreateItem, KsFreeObjectCreateItem, KsFreeObjectCreateItemsByContext, KsCreateDefaultSecurity
clocks.c
- Implement KsCreateClock, KsCreateDefaultClock,  partly implement KsAllocateDefaultClockEx, KsFreeDefaultClock, KsGetDefaultClockState, KsSetDefaultClockState, KsGetDefaultClockTime, KsSetDefaultClockTime
device.c
- Partly implement IKsDevice interface in order to let AVStream client devices initialize
- Implement KsInitializeDevice
- Implement registering of device interface for AVStream drivers
driver.c
- Implement KsGetDeviceForDeviceObject
- Set device flags for ks
- Store Address for client drivers device extension
filter.c
- Implement IKsFilter & IKsControl interface
- Handle KSPROPERTY requests
filterfactory.c
- Implement IKsFilterFactory interface
- Implement KsCreateFilterFactory, KsFilterFactorySetDeviceClassesState, KsFilterFactoryGetSymbolicLink, KsFilterFactoryAddCreateItem
- Add KsFilterFactoryUpdateCacheData
image.c
- Implement KsLoadResource
irp.c
- Implement KsDispatchQuerySecurity, KsDispatchSetSecurity, KsWriteFile, KsDefaultIoCompletion

svn path=/trunk/; revision=42109
This commit is contained in:
Johannes Anderwald 2009-07-20 23:26:57 +00:00
parent 928ed84e9f
commit 764ee24fea
24 changed files with 5471 additions and 1637 deletions

View file

@ -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" #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 KSDDKAPI NTSTATUS NTAPI
KsCreateAllocator( KsCreateAllocator(
@ -10,8 +367,12 @@ KsCreateAllocator(
IN PKSALLOCATOR_FRAMING AllocatorFraming, IN PKSALLOCATOR_FRAMING AllocatorFraming,
OUT PHANDLE AllocatorHandle) OUT PHANDLE AllocatorHandle)
{ {
UNIMPLEMENTED; return KspCreateObjectType(ConnectionHandle,
return STATUS_UNSUCCESSFUL; L"{642F5D00-4791-11D0-A5D6-28DB04C10000}", //KSNAME_Allocator
(PVOID)AllocatorFraming,
sizeof(KSALLOCATOR_FRAMING),
GENERIC_READ,
AllocatorHandle);
} }
/* /*
@ -36,8 +397,146 @@ KsValidateAllocatorCreateRequest(
return STATUS_UNSUCCESSFUL; 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 KSDDKAPI NTSTATUS NTAPI
KsCreateDefaultAllocatorEx( KsCreateDefaultAllocatorEx(
@ -50,17 +549,91 @@ KsCreateDefaultAllocatorEx(
{ {
NTSTATUS Status; NTSTATUS Status;
PKSALLOCATOR_FRAMING AllocatorFraming; PKSALLOCATOR_FRAMING AllocatorFraming;
PALLOCATOR Allocator;
PKSOBJECT_CREATE_ITEM CreateItem;
PVOID Ctx;
Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming); /* first validate connect request */
if (!NT_SUCCESS(Status)) Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming);
return STATUS_INVALID_PARAMETER; 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 KSDDKAPI NTSTATUS NTAPI
KsValidateAllocatorFramingEx( KsValidateAllocatorFramingEx(
@ -68,6 +641,18 @@ KsValidateAllocatorFramingEx(
IN ULONG BufferSize, IN ULONG BufferSize,
IN const KSALLOCATOR_FRAMING_EX* PinFraming) IN const KSALLOCATOR_FRAMING_EX* PinFraming)
{ {
UNIMPLEMENTED; if (BufferSize < sizeof(KSALLOCATOR_FRAMING_EX))
return STATUS_UNSUCCESSFUL; 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;
} }

View file

@ -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;
}

View file

@ -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" #include "priv.h"

View file

@ -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" #include "priv.h"
typedef struct 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 KSDDKAPI NTSTATUS NTAPI
KsCreateClock( KsCreateClock(
@ -14,36 +45,136 @@ KsCreateClock(
IN PKSCLOCK_CREATE ClockCreate, IN PKSCLOCK_CREATE ClockCreate,
OUT PHANDLE ClockHandle) OUT PHANDLE ClockHandle)
{ {
UNIMPLEMENTED; return KspCreateObjectType(ConnectionHandle,
return STATUS_UNSUCCESSFUL; L"{53172480-4791-11D0-A5D6-28DB04C10000}", /* KSName_Clock */
ClockCreate,
sizeof(KSCLOCK_CREATE),
GENERIC_READ,
ClockHandle);
} }
/* /*
@unimplemented @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( KsCreateDefaultClock(
IN PIRP Irp, IN PIRP Irp,
IN PKSDEFAULTCLOCK DefaultClock) IN PKSDEFAULTCLOCK DefaultClock)
{ {
NTSTATUS Status; NTSTATUS Status;
PKSCLOCK_CREATE ClockCreate; PKSCLOCK_CREATE ClockCreate;
PKSICLOCK Clock;
PKSOBJECT_CREATE_ITEM CreateItem;
Status = KsValidateClockCreateRequest(Irp, &ClockCreate); Status = KsValidateClockCreateRequest(Irp, &ClockCreate);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
return 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 @implemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
NTSTATUS
NTAPI
KsAllocateDefaultClock( KsAllocateDefaultClock(
OUT PKSDEFAULTCLOCK* DefaultClock) OUT PKSDEFAULTCLOCK* DefaultClock)
{ {
@ -53,7 +184,9 @@ KsAllocateDefaultClock(
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
NTSTATUS
NTAPI
KsAllocateDefaultClockEx( KsAllocateDefaultClockEx(
OUT PKSDEFAULTCLOCK* DefaultClock, OUT PKSDEFAULTCLOCK* DefaultClock,
IN PVOID Context OPTIONAL, IN PVOID Context OPTIONAL,
@ -63,72 +196,113 @@ KsAllocateDefaultClockEx(
IN const KSRESOLUTION* Resolution OPTIONAL, IN const KSRESOLUTION* Resolution OPTIONAL,
IN ULONG Flags) IN ULONG Flags)
{ {
UNIMPLEMENTED; PKSIDEFAULTCLOCK Clock;
return STATUS_UNSUCCESSFUL;
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( KsFreeDefaultClock(
IN PKSDEFAULTCLOCK DefaultClock) 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 KSDDKAPI
KsValidateClockCreateRequest( KSSTATE
IN PIRP Irp, NTAPI
OUT PKSCLOCK_CREATE* ClockCreate)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/*
@unimplemented
*/
KSDDKAPI KSSTATE NTAPI
KsGetDefaultClockState( KsGetDefaultClockState(
IN PKSDEFAULTCLOCK DefaultClock) IN PKSDEFAULTCLOCK DefaultClock)
{ {
UNIMPLEMENTED; PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock;
return STATUS_UNSUCCESSFUL; return Clock->State;
} }
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI VOID NTAPI KSDDKAPI
VOID
NTAPI
KsSetDefaultClockState( KsSetDefaultClockState(
IN PKSDEFAULTCLOCK DefaultClock, IN PKSDEFAULTCLOCK DefaultClock,
IN KSSTATE State) 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( KsGetDefaultClockTime(
IN PKSDEFAULTCLOCK DefaultClock) IN PKSDEFAULTCLOCK DefaultClock)
{ {
UNIMPLEMENTED; LONGLONG Time = 0LL;
return 0; PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock;
Time = ExInterlockedCompareExchange64(&Clock->Time, &Time, &Time, &Clock->TimeLock);
return Time;
} }
/* /*
@unimplemented @implemented
*/ */
KSDDKAPI VOID NTAPI KSDDKAPI
VOID
NTAPI
KsSetDefaultClockTime( KsSetDefaultClockTime(
IN PKSDEFAULTCLOCK DefaultClock, IN PKSDEFAULTCLOCK DefaultClock,
IN LONGLONG Time) IN LONGLONG Time)
{ {
UNIMPLEMENTED; PKSIDEFAULTCLOCK Clock = (PKSIDEFAULTCLOCK)DefaultClock;
/* set the time safely */
ExInterlockedCompareExchange64(&Clock->Time, &Time, &Clock->Time, &Clock->TimeLock);
} }

View file

@ -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" #include "priv.h"
/* /*
@ -437,9 +446,13 @@ KsPinDataIntersection(
return STATUS_NO_MATCH; return STATUS_NO_MATCH;
} }
/* Does this belong here? */ /*
@unimplemented
*/
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
NTSTATUS
NTAPI
KsHandleSizedListQuery( KsHandleSizedListQuery(
IN PIRP Irp, IN PIRP Irp,
IN ULONG DataItemsCount, IN ULONG DataItemsCount,

View file

@ -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" #include "priv.h"
typedef struct
{
IKsDeviceVtbl *lpVtbl;
LONG ref;
KSDEVICE KsDevice;
}IKsDeviceImpl;
NTSTATUS NTSTATUS
NTAPI NTAPI
IKsDevice_fnQueryInterface( IKsDevice_fnQueryInterface(
IN IKsDevice * iface, IN IKsDevice * iface,
REFIID InterfaceId, REFIID refiid,
PVOID* Interface) PVOID* Output)
{ {
IKsDeviceImpl * This = (IKsDeviceImpl*)iface; PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
DPRINT1("IKsDevice_fnQueryInterface %p\n", This); if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
return STATUS_NOT_IMPLEMENTED; {
*Output = &This->lpVtblIKsDevice;
_InterlockedIncrement(&This->ref);
return STATUS_SUCCESS;
}
return STATUS_NOT_SUPPORTED;
} }
ULONG ULONG
@ -28,7 +33,7 @@ NTAPI
IKsDevice_fnAddRef( IKsDevice_fnAddRef(
IN IKsDevice * iface) IN IKsDevice * iface)
{ {
IKsDeviceImpl * This = (IKsDeviceImpl*)iface; PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
return InterlockedIncrement(&This->ref); return InterlockedIncrement(&This->ref);
} }
@ -38,27 +43,21 @@ NTAPI
IKsDevice_fnRelease( IKsDevice_fnRelease(
IN IKsDevice * iface) IN IKsDevice * iface)
{ {
IKsDeviceImpl * This = (IKsDeviceImpl*)iface; PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
InterlockedDecrement(&This->ref); InterlockedDecrement(&This->ref);
if (This->ref == 0)
{
ExFreePoolWithTag(This, TAG_KSDEVICE);
return 0;
}
return This->ref; return This->ref;
} }
KSDEVICE * PKSDEVICE
NTAPI NTAPI
IKsDevice_fnGetStruct( IKsDevice_fnGetStruct(
IN IKsDevice * iface) IN IKsDevice * iface)
{ {
IKsDeviceImpl * This = (IKsDeviceImpl*)iface; PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, lpVtblIKsDevice);
return &This->KsDevice; return &This->KsDevice;
} }
@ -70,9 +69,9 @@ IKsDevice_fnInitializeObjectBag(
IN struct KSIOBJECTBAG *Bag, IN struct KSIOBJECTBAG *Bag,
IN KMUTANT * Mutant) 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; return STATUS_NOT_IMPLEMENTED;
} }
@ -81,10 +80,9 @@ NTAPI
IKsDevice_fnAcquireDevice( IKsDevice_fnAcquireDevice(
IN IKsDevice * iface) 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 KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL);
return STATUS_NOT_IMPLEMENTED;
} }
NTSTATUS NTSTATUS
@ -92,10 +90,9 @@ NTAPI
IKsDevice_fnReleaseDevice( IKsDevice_fnReleaseDevice(
IN IKsDevice * iface) 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 KeReleaseMutex(&This->DeviceMutex, FALSE);
return STATUS_NOT_IMPLEMENTED;
} }
NTSTATUS NTSTATUS
@ -106,9 +103,9 @@ IKsDevice_fnGetAdapterObject(
IN PULONG Unknown1, IN PULONG Unknown1,
IN PULONG Unknown2) 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; return STATUS_NOT_IMPLEMENTED;
} }
@ -120,9 +117,9 @@ IKsDevice_fnAddPowerEntry(
IN struct KSPOWER_ENTRY * Entry, IN struct KSPOWER_ENTRY * Entry,
IN IKsPowerNotify* Notify) 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; return STATUS_NOT_IMPLEMENTED;
} }
@ -132,9 +129,9 @@ IKsDevice_fnRemovePowerEntry(
IN IKsDevice * iface, IN IKsDevice * iface,
IN struct KSPOWER_ENTRY * Entry) 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; return STATUS_NOT_IMPLEMENTED;
} }
@ -148,9 +145,9 @@ IKsDevice_fnPinStateChange(
IN KSSTATE OldState, IN KSSTATE OldState,
IN KSSTATE NewState) 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; return STATUS_NOT_IMPLEMENTED;
} }
@ -163,9 +160,9 @@ IKsDevice_fnArbitrateAdapterChannel(
IN IO_ALLOCATION_ACTION Action, IN IO_ALLOCATION_ACTION Action,
IN PVOID Context) 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; return STATUS_NOT_IMPLEMENTED;
} }
@ -176,9 +173,9 @@ IKsDevice_fnCheckIoCapability(
IN IKsDevice * iface, IN IKsDevice * iface,
IN ULONG Unknown) 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; 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 NTSTATUS
NTAPI 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); /* get current stack location */
if (!This) IoStack = IoGetCurrentIrpStackLocation(Irp);
return STATUS_INSUFFICIENT_RESOURCES; /* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get device header */
DeviceHeader = DeviceExtension->DeviceHeader;
This->ref = 1; /* first forward irp to lower device object */
This->lpVtbl = &vt_IKsDevice; 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; 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;
}

View file

@ -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;
}

View file

@ -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 "priv.h"
#include "ksfunc.h" #include "ksfunc.h"
@ -15,7 +23,7 @@ DriverEntry(
} }
/* /*
@unimplemented @implemented
*/ */
KSDDKAPI KSDDKAPI
PKSDEVICE PKSDEVICE
@ -23,23 +31,12 @@ NTAPI
KsGetDeviceForDeviceObject( KsGetDeviceForDeviceObject(
IN PDEVICE_OBJECT FunctionalDeviceObject) IN PDEVICE_OBJECT FunctionalDeviceObject)
{ {
PDEVICE_EXTENSION DeviceExtension;
return NULL; /* get device extension */
} DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
/* return &DeviceExtension->DeviceHeader->KsDevice;
@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;
} }
/* /*
@ -58,9 +55,8 @@ KsCreateDevice(
NTSTATUS Status = STATUS_DEVICE_REMOVED; NTSTATUS Status = STATUS_DEVICE_REMOVED;
PDEVICE_OBJECT FunctionalDeviceObject= NULL; PDEVICE_OBJECT FunctionalDeviceObject= NULL;
PDEVICE_OBJECT OldHighestDeviceObject; PDEVICE_OBJECT OldHighestDeviceObject;
if (!ExtensionSize) if (!ExtensionSize)
ExtensionSize = sizeof(PVOID); ExtensionSize = sizeof(KSDEVICE_HEADER);
Status = IoCreateDevice(DriverObject, ExtensionSize, NULL, FILE_DEVICE_KS, FILE_DEVICE_SECURE_OPEN, FALSE, &FunctionalDeviceObject); Status = IoCreateDevice(DriverObject, ExtensionSize, NULL, FILE_DEVICE_KS, FILE_DEVICE_SECURE_OPEN, FALSE, &FunctionalDeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
@ -71,7 +67,12 @@ KsCreateDevice(
{ {
Status = KsInitializeDevice(FunctionalDeviceObject, PhysicalDeviceObject, OldHighestDeviceObject, Descriptor); Status = KsInitializeDevice(FunctionalDeviceObject, PhysicalDeviceObject, OldHighestDeviceObject, Descriptor);
} }
else
{
Status = STATUS_DEVICE_REMOVED;
}
/* check if all succeeded */
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
if (OldHighestDeviceObject) if (OldHighestDeviceObject)
@ -81,9 +82,20 @@ KsCreateDevice(
return Status; return Status;
} }
/* set device flags */
FunctionalDeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
if (Device) if (Device)
{ {
/* get PKSDEVICE struct */
*Device = KsGetDeviceForDeviceObject(FunctionalDeviceObject); *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; return Status;
@ -135,9 +147,13 @@ KsInitializeDriver(
} }
} }
/* Setting our IRP handlers */ /* Setting our IRP handlers */
//DriverObject->MajorFunction[IRP_MJ_CREATE] = KspDispatch; DriverObject->MajorFunction[IRP_MJ_CREATE] = IKsDevice_Create;
//DriverObject->MajorFunction[IRP_MJ_PNP] = KspDispatch; DriverObject->MajorFunction[IRP_MJ_PNP] = IKsDevice_Pnp;
//DriverObject->MajorFunction[IRP_MJ_POWER] = KspDispatch; 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 */ /* The driver-supplied AddDevice */
DriverObject->DriverExtension->AddDevice = KsAddDevice; DriverObject->DriverExtension->AddDevice = KsAddDevice;

View file

@ -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" #include "priv.h"
/* ===============================================================
Event Functions
*/
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
KsGenerateEvent( NTSTATUS
IN PKSEVENT_ENTRY EntryEvent) NTAPI
{
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
KsEnableEvent( KsEnableEvent(
IN PIRP Irp, IN PIRP Irp,
IN ULONG EventSetsCount, IN ULONG EventSetsCount,
@ -65,17 +30,30 @@ KsEnableEvent(
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI VOID NTAPI KSDDKAPI
KsDiscardEvent( NTSTATUS
IN PKSEVENT_ENTRY EventEntry) 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; UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
} }
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
NTSTATUS
NTAPI
KsDisableEvent( KsDisableEvent(
IN PIRP Irp, IN PIRP Irp,
IN OUT PLIST_ENTRY EventsList, IN OUT PLIST_ENTRY EventsList,
@ -89,7 +67,22 @@ KsDisableEvent(
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI VOID NTAPI KSDDKAPI
VOID
NTAPI
KsDiscardEvent(
IN PKSEVENT_ENTRY EventEntry)
{
UNIMPLEMENTED;
}
/*
@unimplemented
*/
KSDDKAPI
VOID
NTAPI
KsFreeEventList( KsFreeEventList(
IN PFILE_OBJECT FileObject, IN PFILE_OBJECT FileObject,
IN OUT PLIST_ENTRY EventsList, IN OUT PLIST_ENTRY EventsList,
@ -98,3 +91,46 @@ KsFreeEventList(
{ {
UNIMPLEMENTED; 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
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

File diff suppressed because it is too large Load diff

View file

@ -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" #include "priv.h"

View file

@ -7,20 +7,26 @@
<importlibrary definition="ks.spec" /> <importlibrary definition="ks.spec" />
<library>ntoskrnl</library> <library>ntoskrnl</library>
<library>hal</library> <library>hal</library>
<library>pseh</library>
<define name="BUILDING_KS" /> <define name="BUILDING_KS" />
<define name="_COMDDK_" /> <define name="_COMDDK_" />
<file>ks.rc</file> <file>ks.rc</file>
<file>api.c</file>
<file>allocators.c</file> <file>allocators.c</file>
<file>bag.c</file> <file>bag.c</file>
<file>device.c</file> <file>device.c</file>
<file>deviceinterface.c</file>
<file>driver.c</file> <file>driver.c</file>
<file>clocks.c</file> <file>clocks.c</file>
<file>connectivity.c</file> <file>connectivity.c</file>
<file>events.c</file> <file>event.c</file>
<file>filter.c</file>
<file>filterfactory.c</file>
<file>image.c</file>
<file>irp.c</file> <file>irp.c</file>
<file>methods.c</file> <file>methods.c</file>
<file>misc.c</file> <file>misc.c</file>
<file>properties.c</file> <file>property.c</file>
<file>topology.c</file> <file>topology.c</file>
<file>worker.c</file> <file>worker.c</file>
<file>kcom.c</file> <file>kcom.c</file>

View file

@ -3,10 +3,6 @@
#include "ksiface.h" #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(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
#define TAG_KSDEVICE TAG('K', 'S', 'E', 'D') #define TAG_KSDEVICE TAG('K', 'S', 'E', 'D')
#define TAG_KSOBJECT_TAG TAG('K', 'S', 'O', 'H') #define TAG_KSOBJECT_TAG TAG('K', 'S', 'O', 'H')
@ -21,6 +17,86 @@ KspCreateObjectType(
IN ACCESS_MASK DesiredAccess, IN ACCESS_MASK DesiredAccess,
OUT PHANDLE NodeHandle); 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 #endif

View file

@ -14,6 +14,129 @@
STDMETHOD_(ULONG,Release)(THIS) PURE; STDMETHOD_(ULONG,Release)(THIS) PURE;
#endif #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 * IKsFilterFactory
***************************************************************************** *****************************************************************************
@ -26,10 +149,26 @@ DECLARE_INTERFACE_(IKsFilterFactory, IUnknown)
{ {
DEFINE_ABSTRACT_UNKNOWN() 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; 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;
}; };

View file

@ -1,33 +1,60 @@
#ifndef KSTYPES_H__ #ifndef KSTYPES_H__
#define KSTYPES_H__ #define KSTYPES_H__
struct KSIDEVICE_HEADER;
typedef struct typedef struct
{ {
KSDISPATCH_TABLE DispatchTable; KSDISPATCH_TABLE DispatchTable;
KSOBJECTTYPE Type;
ULONG ItemCount; ULONG ItemCount;
PKSOBJECT_CREATE_ITEM CreateItem; PKSOBJECT_CREATE_ITEM CreateItem;
UNICODE_STRING ObjectClass; 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; }KSIOBJECT_HEADER, *PKSIOBJECT_HEADER;
typedef struct typedef struct
{ {
PKSOBJECT_CREATE_ITEM CreateItem; PKSOBJECT_CREATE_ITEM CreateItem;
PFNKSITEMFREECALLBACK ItemFreeCallback;
LONG ReferenceCount;
}DEVICE_ITEM, *PDEVICE_ITEM; }DEVICE_ITEM, *PDEVICE_ITEM;
typedef struct typedef struct
{ {
IKsDeviceVtbl *lpVtblIKsDevice;
LONG ref;
ERESOURCE SecurityLock;
USHORT MaxItems; USHORT MaxItems;
DEVICE_ITEM *ItemList; DEVICE_ITEM *ItemList;
ULONG DeviceIndex; ULONG DeviceIndex;
KSPIN_LOCK ItemListLock; KSPIN_LOCK ItemListLock;
PDEVICE_OBJECT PhysicalDeviceObject;
PDEVICE_OBJECT NextDeviceObject; 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; }KSIDEVICE_HEADER, *PKSIDEVICE_HEADER;
@ -43,5 +70,17 @@ typedef struct
PIRP Irp; PIRP Irp;
}QUEUE_ENTRY, *PQUEUE_ENTRY; }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 #endif

View file

@ -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
*/
/* =============================================================== #include "priv.h"
Method Functions
*/
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
NTSTATUS
NTAPI
KsMethodHandler( KsMethodHandler(
IN PIRP Irp, IN PIRP Irp,
IN ULONG MethodSetsCount, IN ULONG MethodSetsCount,
@ -20,7 +26,9 @@ KsMethodHandler(
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
NTSTATUS
NTAPI
KsMethodHandlerWithAllocator( KsMethodHandlerWithAllocator(
IN PIRP Irp, IN PIRP Irp,
IN ULONG MethodSetsCount, IN ULONG MethodSetsCount,
@ -35,7 +43,9 @@ KsMethodHandlerWithAllocator(
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI BOOLEAN NTAPI KSDDKAPI
BOOLEAN
NTAPI
KsFastMethodHandler( KsFastMethodHandler(
IN PFILE_OBJECT FileObject, IN PFILE_OBJECT FileObject,
IN PKSMETHOD UNALIGNED Method, IN PKSMETHOD UNALIGNED Method,

View file

@ -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" #include "priv.h"
/* =============================================================== PVOID
Misc. Helper Functions AllocateItem(
*/ IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes)
/*
@unimplemented
*/
KSDDKAPI NTSTATUS NTAPI
KsCacheMedium(
IN PUNICODE_STRING SymbolicLink,
IN PKSPIN_MEDIUM Medium,
IN ULONG PinDirection)
{ {
UNIMPLEMENTED; PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
return STATUS_UNSUCCESSFUL; if (!Item)
return Item;
RtlZeroMemory(Item, NumberOfBytes);
return Item;
} }
/* VOID
@unimplemented FreeItem(
*/ IN PVOID Item)
KSDDKAPI NTSTATUS NTAPI
KsDefaultDispatchPnp(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{ {
PIO_STACK_LOCATION IoStack;
NTSTATUS Status = STATUS_SUCCESS;
IoStack = IoGetCurrentIrpStackLocation(Irp); ExFreePool(Item);
}
DPRINT1("KsDefaultDispatchPnp entered with func %x\n", IoStack->MinorFunction); NTSTATUS
NTAPI
switch(IoStack->MinorFunction) KspForwardIrpSynchronousCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context)
{
if (Irp->PendingReturned == TRUE)
{ {
case IRP_MN_QUERY_DEVICE_RELATIONS: KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
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_MORE_PROCESSING_REQUIRED;
return Status;
} }
/*
@unimplemented
*/
KSDDKAPI VOID NTAPI
KsSetDevicePnpAndBaseObject(
IN KSDEVICE_HEADER Header,
IN PDEVICE_OBJECT PnpDeviceObject,
IN PDEVICE_OBJECT BaseDevice)
{
UNIMPLEMENTED;
}
/* NTSTATUS
@unimplemented KspForwardIrpSynchronous(
*/
KSDDKAPI NTSTATUS NTAPI
KsDefaultDispatchPower(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
UNIMPLEMENTED; KEVENT Event;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExtension;
PKSIDEVICE_HEADER DeviceHeader;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
/* /* get device extension */
@unimplemented DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
*/ /* get device header */
KSDDKAPI VOID NTAPI DeviceHeader = DeviceExtension->DeviceHeader;
KsSetPowerDispatch(
IN KSOBJECT_HEADER Header,
IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL,
IN PVOID PowerContext OPTIONAL)
{
UNIMPLEMENTED;
}
/* /* initialize the notification event */
@unimplemented KeInitializeEvent(&Event, NotificationEvent, FALSE);
*/
KSDDKAPI NTSTATUS NTAPI
KsReferenceBusObject(
IN KSDEVICE_HEADER Header)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/* IoCopyCurrentIrpStackLocationToNext(Irp);
@unimplemented
*/
KSDDKAPI VOID NTAPI
KsDereferenceBusObject(
IN KSDEVICE_HEADER Header)
{
UNIMPLEMENTED;
}
/* IoSetCompletionRoutine(Irp, KspForwardIrpSynchronousCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
@unimplemented
*/
KSDDKAPI NTSTATUS NTAPI
KsFreeObjectCreateItem(
IN KSDEVICE_HEADER Header,
IN PUNICODE_STRING CreateItem)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
}
/* /* now call the driver */
@unimplemented Status = IoCallDriver(DeviceHeader->NextDeviceObject, Irp);
*/ /* did the request complete yet */
KSDDKAPI NTSTATUS NTAPI if (Status == STATUS_PENDING)
KsFreeObjectCreateItemsByContext( {
IN KSDEVICE_HEADER Header, /* not yet, lets wait a bit */
IN PVOID Context) KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
{ Status = Irp->IoStatus.Status;
UNIMPLEMENTED; }
return STATUS_UNSUCCESSFUL; return Status;
}
/*
@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;
} }
/* /*
@ -189,189 +98,3 @@ KsPinDataIntersectionEx(
UNIMPLEMENTED; UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL; 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();
}

View file

@ -1,6 +1,8 @@
#ifndef PRIV_H__ #ifndef PRIV_H__
#define PRIV_H__ #define PRIV_H__
#define _KSDDK_
#include <ntifs.h> #include <ntifs.h>
#include <ntddk.h> #include <ntddk.h>
#define NDEBUG #define NDEBUG
@ -8,6 +10,8 @@
#include <portcls.h> #include <portcls.h>
#include <ks.h> #include <ks.h>
#include <kcom.h> #include <kcom.h>
#include <pseh/pseh2.h>
#include <ntndk.h>
#include "ksfunc.h" #include "ksfunc.h"
#include "kstypes.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 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 #endif

View file

@ -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" #include "priv.h"
/* ===============================================================
Property Functions
*/
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI BOOLEAN NTAPI KSDDKAPI
KsFastPropertyHandler( NTSTATUS
IN PFILE_OBJECT FileObject, NTAPI
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
KsPropertyHandler( KsPropertyHandler(
IN PIRP Irp, IN PIRP Irp,
IN ULONG PropertySetsCount, IN ULONG PropertySetsCount,
@ -35,10 +23,13 @@ KsPropertyHandler(
return STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL;
} }
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
NTSTATUS
NTAPI
KsPropertyHandlerWithAllocator( KsPropertyHandlerWithAllocator(
IN PIRP Irp, IN PIRP Irp,
IN ULONG PropertySetsCount, IN ULONG PropertySetsCount,
@ -53,12 +44,19 @@ KsPropertyHandlerWithAllocator(
/* /*
@unimplemented @unimplemented
*/ */
KSDDKAPI NTSTATUS NTAPI KSDDKAPI
KsUnserializeObjectPropertiesFromRegistry( BOOLEAN
NTAPI
KsFastPropertyHandler(
IN PFILE_OBJECT FileObject, IN PFILE_OBJECT FileObject,
IN HANDLE ParentKey OPTIONAL, IN PKSPROPERTY UNALIGNED Property,
IN PUNICODE_STRING RegistryPath OPTIONAL) 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; UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL; return FALSE;
} }

View file

@ -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" #include "priv.h"
/* ===============================================================
Topology Functions
*/
NTSTATUS NTSTATUS
NTAPI NTAPI
@ -291,3 +297,14 @@ KsTopologyPropertyHandler(
return Status; return Status;
} }
NTSTATUS
NTAPI
KspTopologyPropertyHandler(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
return STATUS_NOT_IMPLEMENTED;
}

View file

@ -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" #include "priv.h"
/* =============================================================== /* ===============================================================