-/* ===============================================================
- Allocator Functions
-*/
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/ksfilter/ks/allocators.c
+ * PURPOSE: KS Allocator functions
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+
+#include "priv.h"
+
+typedef enum
+{
+ ALLOCATOR_NPAGED_LOOKASIDE,
+ ALLOCATOR_PAGED_LOOKASIDE,
+ ALLOCATOR_CUSTOM
+}ALLOCATOR_TYPE;
+
+typedef enum
+{
+ ALLOCATOR_DEVICE_CONTROL,
+ ALLOCATOR_DEVICE_CLOSE,
+ ALLOCATOR_ALLOCATE,
+ ALLOCATOR_FREE
+
+}ALLOC_REQUEST;
+
+typedef PVOID (*PFNKSPAGEDPOOLALLOCATE)(IN PPAGED_LOOKASIDE_LIST Lookaside);
+typedef PVOID (*PFNKSNPAGEDPOOLALLOCATE)(IN PNPAGED_LOOKASIDE_LIST Lookaside);
+
+typedef VOID (*PFNKSPAGEDPOOLFREE)(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry);
+typedef VOID (*PFNKSNPAGEDPOOLFREE)(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry);
+
+typedef VOID (NTAPI *PFNKSNPAGEDPOOLDELETE)(IN PNPAGED_LOOKASIDE_LIST Lookaside);
+typedef VOID (NTAPI *PFNKSPAGEDPOOLDELETE)(IN PPAGED_LOOKASIDE_LIST Lookaside);
+
+typedef struct
+{
+ IKsAllocatorVtbl *lpVtbl;
+ LONG ref;
+ PKSIOBJECT_HEADER Header;
+ ALLOCATOR_TYPE Type;
+
+ KSSTREAMALLOCATOR_STATUS Status;
+
+ union
+ {
+ NPAGED_LOOKASIDE_LIST NPagedList;
+ PAGED_LOOKASIDE_LIST PagedList;
+ PVOID CustomList;
+ }u;
+
+ union
+ {
+ PFNKSDEFAULTALLOCATE DefaultAllocate;
+ PFNKSPAGEDPOOLALLOCATE PagedPool;
+ PFNKSNPAGEDPOOLALLOCATE NPagedPool;
+ }Allocate;
+
+ union
+ {
+ PFNKSDEFAULTFREE DefaultFree;
+ PFNKSPAGEDPOOLFREE PagedPool;
+ PFNKSNPAGEDPOOLFREE NPagedPool;
+ }Free;
+
+ union
+ {
+ PFNKSDELETEALLOCATOR DefaultDelete;
+ PFNKSNPAGEDPOOLDELETE NPagedPool;
+ PFNKSPAGEDPOOLDELETE PagedPool;
+ }Delete;
+
+}ALLOCATOR, *PALLOCATOR;
+
+/* use KSNAME_Allocator for IID_IKsAllocator */
+const GUID IID_IKsAllocator = {0x642F5D00L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSPROPSETID_StreamAllocator = {0x0cf6e4342, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
+
+
+NTSTATUS
+NTAPI
+IKsAllocator_Allocate(
+ IN PFILE_OBJECT FileObject,
+ PVOID *Frame);
+
+VOID
+NTAPI
+IKsAllocator_FreeFrame(
+ IN PFILE_OBJECT FileObject,
+ PVOID Frame);
+
+
+NTSTATUS
+NTAPI
+IKsAllocator_fnQueryInterface(
+ IKsAllocator * iface,
+ IN REFIID refiid,
+ OUT PVOID* Output)
+{
+ PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
+
+ if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
+ IsEqualGUIDAligned(refiid, &IID_IKsAllocator))
+ {
+ *Output = &This->lpVtbl;
+ _InterlockedIncrement(&This->ref);
+ return STATUS_SUCCESS;
+ }
+ return STATUS_UNSUCCESSFUL;
+}
+
+ULONG
+NTAPI
+IKsAllocator_fnAddRef(
+ IKsAllocator * iface)
+{
+ PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
+
+ return InterlockedIncrement(&This->ref);
+}
+
+ULONG
+NTAPI
+IKsAllocator_fnRelease(
+ IKsAllocator * iface)
+{
+ PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
+
+ InterlockedDecrement(&This->ref);
+
+ if (This->ref == 0)
+ {
+ FreeItem(This);
+ return 0;
+ }
+ /* Return new reference count */
+ return This->ref;
+}
+
+NTSTATUS
+NTAPI
+IKsAllocator_fnDeviceIoControl(
+ IKsAllocator *iface,
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
+ PIO_STACK_LOCATION IoStack;
+ PKSSTREAMALLOCATOR_FUNCTIONTABLE FunctionTable;
+ PKSSTREAMALLOCATOR_STATUS State;
+ PKSPROPERTY Property;
+
+ /* FIXME locks */
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
+ {
+ /* only KSPROPERTY requests are supported */
+ UNIMPLEMENTED
+
+ /* complete and forget irps */
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
+ {
+ /* invalid request */
+ Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return STATUS_INVALID_DEVICE_REQUEST;
+ }
+
+ /* check the request */
+ Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
+
+ if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_StreamAllocator))
+ {
+ if (Property->Id == KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE)
+ {
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE))
+ {
+ /* buffer too small */
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
+ /* complete and forget irp */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+ if (!(Property->Flags & KSPROPERTY_TYPE_GET))
+ {
+ /* only support retrieving the property */
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ /* complete and forget irp */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* get output buffer */
+ FunctionTable = (PKSSTREAMALLOCATOR_FUNCTIONTABLE)Irp->UserBuffer;
+
+ FunctionTable->AllocateFrame = IKsAllocator_Allocate;
+ FunctionTable->FreeFrame = IKsAllocator_FreeFrame;
+
+ /* save result */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
+ /* complete request */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+ else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS)
+ {
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS))
+ {
+ /* buffer too small */
+ Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS);
+ /* complete and forget irp */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_BUFFER_TOO_SMALL;
+ }
+ if (!(Property->Flags & KSPROPERTY_TYPE_GET))
+ {
+ /* only support retrieving the property */
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ /* complete and forget irp */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* get output buffer */
+ State = (PKSSTREAMALLOCATOR_STATUS)Irp->UserBuffer;
+
+ /* copy allocator status */
+ RtlMoveMemory(State, &This->Status, sizeof(KSSTREAMALLOCATOR_STATUS));
+
+ /* save result */
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS);
+
+ /* complete request */
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ return STATUS_SUCCESS;
+ }
+ }
+
+ /* unhandled 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
+};
-#include <ntddk.h>
-#include <debug.h>
-#include <ks.h>
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI NTSTATUS NTAPI
KsCreateAllocator(
IN PKSALLOCATOR_FRAMING AllocatorFraming,
OUT PHANDLE AllocatorHandle)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ return KspCreateObjectType(ConnectionHandle,
+ KSSTRING_Allocator,
+ (PVOID)AllocatorFraming,
+ sizeof(KSALLOCATOR_FRAMING),
+ GENERIC_READ,
+ AllocatorHandle);
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI NTSTATUS NTAPI
KsCreateDefaultAllocator(
IN PIRP Irp)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ return KsCreateDefaultAllocatorEx(Irp, NULL, NULL, NULL, NULL, NULL);
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
+KSDDKAPI
+NTSTATUS
+NTAPI
KsValidateAllocatorCreateRequest(
IN PIRP Irp,
- OUT PKSALLOCATOR_FRAMING* AllocatorFraming)
+ OUT PKSALLOCATOR_FRAMING* OutAllocatorFraming)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ PKSALLOCATOR_FRAMING AllocatorFraming;
+ ULONG Size;
+ NTSTATUS Status;
+ ULONG SupportedFlags;
+
+ /* set minimum request size */
+ Size = sizeof(KSALLOCATOR_FRAMING);
+
+ Status = KspCopyCreateRequest(Irp,
+ KSSTRING_Allocator,
+ &Size,
+ (PVOID*)&AllocatorFraming);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* allowed supported flags */
+ SupportedFlags = (KSALLOCATOR_OPTIONF_COMPATIBLE | KSALLOCATOR_OPTIONF_SYSTEM_MEMORY |
+ KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER | KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY |
+ KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE);
+
+
+ if (!AllocatorFraming->FrameSize || (AllocatorFraming->OptionsFlags & (~SupportedFlags)))
+ {
+ FreeItem(AllocatorFraming);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* store result */
+ *OutAllocatorFraming = AllocatorFraming;
+
+ return Status;
+}
+
+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->FsContext2;
+
+ /* get real allocator */
+ Status = Header->Unknown->lpVtbl->QueryInterface(Header->Unknown, &IID_IKsAllocator, (PVOID*)&Allocator);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* misbehaving object */
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ if (Request == ALLOCATOR_DEVICE_CONTROL)
+ {
+ /* dispatch request allocator */
+ Status = Allocator->lpVtbl->DispatchDeviceIoControl(Allocator, DeviceObject, Irp);
+ }
+ else if (Request == ALLOCATOR_DEVICE_CLOSE)
+ {
+ /* delete allocator */
+ Status = Allocator->lpVtbl->Close(Allocator);
+ }
+ else if (Request == ALLOCATOR_ALLOCATE)
+ {
+ /* allocate frame */
+ Status = Allocator->lpVtbl->AllocateFrame(Allocator, (PVOID*)Frame);
+
+ }else if (Request == ALLOCATOR_FREE)
+ {
+ /* allocate frame */
+ Allocator->lpVtbl->FreeFrame(Allocator, Frame);
+ Status = STATUS_SUCCESS;
+ }
+
+ /* release interface */
+ Allocator->lpVtbl->Release(Allocator);
+
+ return Status;
}
+NTSTATUS
+NTAPI
+IKsAllocator_DispatchDeviceIoControl(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* dispatch request */
+ Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CONTROL);
+
+ /* complete request */
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+IKsAllocator_DispatchClose(
+ IN PDEVICE_OBJECT DeviceObject,
+ IN PIRP Irp)
+{
+ PIO_STACK_LOCATION IoStack;
+ NTSTATUS Status;
+
+ /* get current irp stack */
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ /* dispatch request */
+ Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CLOSE);
+
+ /* complete request */
+ Irp->IoStatus.Status = Status;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+
+ return Status;
+}
+
+NTSTATUS
+NTAPI
+IKsAllocator_Allocate(
+ IN PFILE_OBJECT FileObject,
+ PVOID *Frame)
+{
+ NTSTATUS Status;
+
+ /* dispatch request */
+ Status = IKsAllocator_DispatchRequest(NULL, FileObject, NULL, (PVOID)Frame, ALLOCATOR_ALLOCATE);
+
+ return Status;
+}
+
+VOID
+NTAPI
+IKsAllocator_FreeFrame(
+ IN PFILE_OBJECT FileObject,
+ PVOID Frame)
+{
+ /* dispatch request */
+ IKsAllocator_DispatchRequest(NULL, FileObject, NULL, Frame, ALLOCATOR_FREE);
+}
+
+
+static KSDISPATCH_TABLE DispatchTable =
+{
+ IKsAllocator_DispatchDeviceIoControl,
+ KsDispatchInvalidDeviceRequest,
+ KsDispatchInvalidDeviceRequest,
+ KsDispatchInvalidDeviceRequest,
+ IKsAllocator_DispatchClose,
+ KsDispatchQuerySecurity,
+ KsDispatchSetSecurity,
+ KsDispatchFastIoDeviceControlFailure,
+ KsDispatchFastReadFailure,
+ KsDispatchFastReadFailure,
+};
+
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI NTSTATUS NTAPI
KsCreateDefaultAllocatorEx(
IN PFNKSINITIALIZEALLOCATOR InitializeAllocator OPTIONAL,
IN PFNKSDELETEALLOCATOR DeleteAllocator OPTIONAL)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ NTSTATUS Status;
+ PKSALLOCATOR_FRAMING AllocatorFraming;
+ PALLOCATOR Allocator;
+ PVOID Ctx;
+
+ /* first validate connect request */
+ Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming);
+ if (!NT_SUCCESS(Status))
+ return STATUS_INVALID_PARAMETER;
+
+ /* check the valid file alignment */
+ if (AllocatorFraming->FileAlignment > (PAGE_SIZE-1))
+ return STATUS_INVALID_PARAMETER;
+
+ /* 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));
+
+ return Status;
}
/*
- @unimplemented
+ @implemented
*/
KSDDKAPI NTSTATUS NTAPI
KsValidateAllocatorFramingEx(
IN ULONG BufferSize,
IN const KSALLOCATOR_FRAMING_EX* PinFraming)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ if (BufferSize < sizeof(KSALLOCATOR_FRAMING_EX))
+ return STATUS_INVALID_DEVICE_REQUEST;
+
+ /* verify framing */
+ if ((Framing->FramingItem[0].Flags & KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT) &&
+ Framing->OutputCompression.RatioNumerator != MAXULONG &&
+ Framing->OutputCompression.RatioDenominator != 0 &&
+ Framing->OutputCompression.RatioDenominator < Framing->OutputCompression.RatioNumerator)
+ {
+ /* framing request is ok */
+ return STATUS_SUCCESS;
+ }
+
+ return STATUS_INVALID_DEVICE_REQUEST;
}