mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
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:
parent
928ed84e9f
commit
764ee24fea
24 changed files with 5471 additions and 1637 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
993
reactos/drivers/ksfilter/ks/api.c
Normal file
993
reactos/drivers/ksfilter/ks/api.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
98
reactos/drivers/ksfilter/ks/deviceinterface.c
Normal file
98
reactos/drivers/ksfilter/ks/deviceinterface.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
917
reactos/drivers/ksfilter/ks/filter.c
Normal file
917
reactos/drivers/ksfilter/ks/filter.c
Normal 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;
|
||||||
|
}
|
471
reactos/drivers/ksfilter/ks/filterfactory.c
Normal file
471
reactos/drivers/ksfilter/ks/filterfactory.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
116
reactos/drivers/ksfilter/ks/image.c
Normal file
116
reactos/drivers/ksfilter/ks/image.c
Normal 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
|
@ -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"
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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"
|
||||||
|
|
||||||
/* ===============================================================
|
/* ===============================================================
|
||||||
|
|
Loading…
Reference in a new issue