3040a041837e5ce4ac42d2e377c5ed40b26ca197
[reactos.git] / reactos / drivers / ksfilter / ks / allocators.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/allocators.c
5 * PURPOSE: KS Allocator functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9
10 #include "priv.h"
11
12 typedef enum
13 {
14 ALLOCATOR_NPAGED_LOOKASIDE,
15 ALLOCATOR_PAGED_LOOKASIDE,
16 ALLOCATOR_CUSTOM
17 }ALLOCATOR_TYPE;
18
19 typedef enum
20 {
21 ALLOCATOR_DEVICE_CONTROL,
22 ALLOCATOR_DEVICE_CLOSE,
23 ALLOCATOR_ALLOCATE,
24 ALLOCATOR_FREE
25
26 }ALLOC_REQUEST;
27
28 typedef PVOID (*PFNKSPAGEDPOOLALLOCATE)(IN PPAGED_LOOKASIDE_LIST Lookaside);
29 typedef PVOID (*PFNKSNPAGEDPOOLALLOCATE)(IN PNPAGED_LOOKASIDE_LIST Lookaside);
30
31 typedef VOID (*PFNKSPAGEDPOOLFREE)(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry);
32 typedef VOID (*PFNKSNPAGEDPOOLFREE)(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry);
33
34 typedef VOID (NTAPI *PFNKSNPAGEDPOOLDELETE)(IN PNPAGED_LOOKASIDE_LIST Lookaside);
35 typedef VOID (NTAPI *PFNKSPAGEDPOOLDELETE)(IN PPAGED_LOOKASIDE_LIST Lookaside);
36
37 typedef struct
38 {
39 IKsAllocatorVtbl *lpVtbl;
40 LONG ref;
41 PKSIOBJECT_HEADER Header;
42 ALLOCATOR_TYPE Type;
43
44 KSSTREAMALLOCATOR_STATUS Status;
45
46 union
47 {
48 NPAGED_LOOKASIDE_LIST NPagedList;
49 PAGED_LOOKASIDE_LIST PagedList;
50 PVOID CustomList;
51 }u;
52
53 union
54 {
55 PFNKSDEFAULTALLOCATE DefaultAllocate;
56 PFNKSPAGEDPOOLALLOCATE PagedPool;
57 PFNKSNPAGEDPOOLALLOCATE NPagedPool;
58 }Allocate;
59
60 union
61 {
62 PFNKSDEFAULTFREE DefaultFree;
63 PFNKSPAGEDPOOLFREE PagedPool;
64 PFNKSNPAGEDPOOLFREE NPagedPool;
65 }Free;
66
67 union
68 {
69 PFNKSDELETEALLOCATOR DefaultDelete;
70 PFNKSNPAGEDPOOLDELETE NPagedPool;
71 PFNKSPAGEDPOOLDELETE PagedPool;
72 }Delete;
73
74 }ALLOCATOR, *PALLOCATOR;
75
76 /* use KSNAME_Allocator for IID_IKsAllocator */
77 const GUID IID_IKsAllocator = {0x642F5D00L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
78 const GUID KSPROPSETID_StreamAllocator = {0x0cf6e4342, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}};
79
80
81 NTSTATUS
82 NTAPI
83 IKsAllocator_Allocate(
84 IN PFILE_OBJECT FileObject,
85 PVOID *Frame);
86
87 VOID
88 NTAPI
89 IKsAllocator_FreeFrame(
90 IN PFILE_OBJECT FileObject,
91 PVOID Frame);
92
93
94 NTSTATUS
95 NTAPI
96 IKsAllocator_fnQueryInterface(
97 IKsAllocator * iface,
98 IN REFIID refiid,
99 OUT PVOID* Output)
100 {
101 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
102
103 if (IsEqualGUIDAligned(refiid, &IID_IUnknown) ||
104 IsEqualGUIDAligned(refiid, &IID_IKsAllocator))
105 {
106 *Output = &This->lpVtbl;
107 _InterlockedIncrement(&This->ref);
108 return STATUS_SUCCESS;
109 }
110 return STATUS_UNSUCCESSFUL;
111 }
112
113 ULONG
114 NTAPI
115 IKsAllocator_fnAddRef(
116 IKsAllocator * iface)
117 {
118 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
119
120 return InterlockedIncrement(&This->ref);
121 }
122
123 ULONG
124 NTAPI
125 IKsAllocator_fnRelease(
126 IKsAllocator * iface)
127 {
128 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
129
130 InterlockedDecrement(&This->ref);
131
132 if (This->ref == 0)
133 {
134 FreeItem(This);
135 return 0;
136 }
137 /* Return new reference count */
138 return This->ref;
139 }
140
141 NTSTATUS
142 NTAPI
143 IKsAllocator_fnDeviceIoControl(
144 IKsAllocator *iface,
145 IN PDEVICE_OBJECT DeviceObject,
146 IN PIRP Irp)
147 {
148 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
149 PIO_STACK_LOCATION IoStack;
150 PKSSTREAMALLOCATOR_FUNCTIONTABLE FunctionTable;
151 PKSSTREAMALLOCATOR_STATUS State;
152 PKSPROPERTY Property;
153
154 /* FIXME locks */
155
156 /* get current irp stack */
157 IoStack = IoGetCurrentIrpStackLocation(Irp);
158
159 if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
160 {
161 /* only KSPROPERTY requests are supported */
162 UNIMPLEMENTED
163
164 /* complete and forget irps */
165 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
166 IoCompleteRequest(Irp, IO_NO_INCREMENT);
167
168 return STATUS_NOT_IMPLEMENTED;
169 }
170
171 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
172 {
173 /* invalid request */
174 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
175 IoCompleteRequest(Irp, IO_NO_INCREMENT);
176
177 return STATUS_INVALID_DEVICE_REQUEST;
178 }
179
180 /* check the request */
181 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
182
183 if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_StreamAllocator))
184 {
185 if (Property->Id == KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE)
186 {
187 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE))
188 {
189 /* buffer too small */
190 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
191 Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
192 /* complete and forget irp */
193 IoCompleteRequest(Irp, IO_NO_INCREMENT);
194 return STATUS_BUFFER_TOO_SMALL;
195 }
196 if (!(Property->Flags & KSPROPERTY_TYPE_GET))
197 {
198 /* only support retrieving the property */
199 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
200 /* complete and forget irp */
201 IoCompleteRequest(Irp, IO_NO_INCREMENT);
202 return STATUS_UNSUCCESSFUL;
203 }
204
205 /* get output buffer */
206 FunctionTable = (PKSSTREAMALLOCATOR_FUNCTIONTABLE)Irp->UserBuffer;
207
208 FunctionTable->AllocateFrame = IKsAllocator_Allocate;
209 FunctionTable->FreeFrame = IKsAllocator_FreeFrame;
210
211 /* save result */
212 Irp->IoStatus.Status = STATUS_SUCCESS;
213 Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE);
214 /* complete request */
215 IoCompleteRequest(Irp, IO_NO_INCREMENT);
216 return STATUS_SUCCESS;
217 }
218 else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS)
219 {
220 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS))
221 {
222 /* buffer too small */
223 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
224 Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS);
225 /* complete and forget irp */
226 IoCompleteRequest(Irp, IO_NO_INCREMENT);
227 return STATUS_BUFFER_TOO_SMALL;
228 }
229 if (!(Property->Flags & KSPROPERTY_TYPE_GET))
230 {
231 /* only support retrieving the property */
232 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
233 /* complete and forget irp */
234 IoCompleteRequest(Irp, IO_NO_INCREMENT);
235 return STATUS_UNSUCCESSFUL;
236 }
237
238 /* get output buffer */
239 State = (PKSSTREAMALLOCATOR_STATUS)Irp->UserBuffer;
240
241 /* copy allocator status */
242 RtlMoveMemory(State, &This->Status, sizeof(KSSTREAMALLOCATOR_STATUS));
243
244 /* save result */
245 Irp->IoStatus.Status = STATUS_SUCCESS;
246 Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS);
247
248 /* complete request */
249 IoCompleteRequest(Irp, IO_NO_INCREMENT);
250 return STATUS_SUCCESS;
251 }
252 }
253
254 /* unhandeled request */
255 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
256 IoCompleteRequest(Irp, IO_NO_INCREMENT);
257
258 return STATUS_NOT_SUPPORTED;
259 }
260
261 NTSTATUS
262 NTAPI
263 IKsAllocator_fnClose(
264 IKsAllocator *iface)
265 {
266 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
267
268 /* FIXME locks */
269
270 /* now close allocator */
271 if (This->Type == ALLOCATOR_CUSTOM)
272 {
273 This->Delete.DefaultDelete(This->u.CustomList);
274 }
275 else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE)
276 {
277 This->Delete.NPagedPool(&This->u.NPagedList);
278 }
279 else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE)
280 {
281 This->Delete.PagedPool(&This->u.PagedList);
282 }
283
284 /* free object header */
285 KsFreeObjectHeader(&This->Header);
286
287 return STATUS_SUCCESS;
288 }
289
290 NTSTATUS
291 NTAPI
292 IKsAllocator_fnAllocateFrame(
293 IKsAllocator *iface,
294 IN PVOID * OutFrame)
295 {
296 PVOID Frame = NULL;
297 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
298
299 /* FIXME locks */
300
301 /* now allocate frame */
302 if (This->Type == ALLOCATOR_CUSTOM)
303 {
304 Frame = This->Allocate.DefaultAllocate(This->u.CustomList);
305 }
306 else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE)
307 {
308 Frame = This->Allocate.NPagedPool(&This->u.NPagedList);
309 }
310 else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE)
311 {
312 Frame = This->Allocate.PagedPool(&This->u.PagedList);
313 }
314
315 if (Frame)
316 {
317 *OutFrame = Frame;
318 InterlockedIncrement((PLONG)&This->Status.AllocatedFrames);
319 return STATUS_SUCCESS;
320 }
321
322 return STATUS_UNSUCCESSFUL;
323 }
324
325 VOID
326 NTAPI
327 IKsAllocator_fnFreeFrame(
328 IKsAllocator *iface,
329 IN PVOID Frame)
330 {
331 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl);
332
333 /* now allocate frame */
334 if (This->Type == ALLOCATOR_CUSTOM)
335 {
336 This->Free.DefaultFree(This->u.CustomList, Frame);
337 }
338 else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE)
339 {
340 This->Free.NPagedPool(&This->u.NPagedList, Frame);
341 }
342 else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE)
343 {
344 This->Free.PagedPool(&This->u.PagedList, Frame);
345 }
346 }
347
348
349 static IKsAllocatorVtbl vt_IKsAllocator =
350 {
351 IKsAllocator_fnQueryInterface,
352 IKsAllocator_fnAddRef,
353 IKsAllocator_fnRelease,
354 IKsAllocator_fnDeviceIoControl,
355 IKsAllocator_fnClose,
356 IKsAllocator_fnAllocateFrame,
357 IKsAllocator_fnFreeFrame
358 };
359
360
361 /*
362 @implemented
363 */
364 KSDDKAPI NTSTATUS NTAPI
365 KsCreateAllocator(
366 IN HANDLE ConnectionHandle,
367 IN PKSALLOCATOR_FRAMING AllocatorFraming,
368 OUT PHANDLE AllocatorHandle)
369 {
370 return KspCreateObjectType(ConnectionHandle,
371 KSSTRING_Allocator,
372 (PVOID)AllocatorFraming,
373 sizeof(KSALLOCATOR_FRAMING),
374 GENERIC_READ,
375 AllocatorHandle);
376 }
377
378 /*
379 @implemented
380 */
381 KSDDKAPI NTSTATUS NTAPI
382 KsCreateDefaultAllocator(
383 IN PIRP Irp)
384 {
385 return KsCreateDefaultAllocatorEx(Irp, NULL, NULL, NULL, NULL, NULL);
386 }
387
388 /*
389 @implemented
390 */
391 KSDDKAPI
392 NTSTATUS
393 NTAPI
394 KsValidateAllocatorCreateRequest(
395 IN PIRP Irp,
396 OUT PKSALLOCATOR_FRAMING* OutAllocatorFraming)
397 {
398 PKSALLOCATOR_FRAMING AllocatorFraming;
399 ULONG Size;
400 NTSTATUS Status;
401 ULONG SupportedFlags;
402
403 /* set minimum request size */
404 Size = sizeof(KSALLOCATOR_FRAMING);
405
406 Status = KspCopyCreateRequest(Irp,
407 KSSTRING_Allocator,
408 &Size,
409 (PVOID*)&AllocatorFraming);
410
411 if (!NT_SUCCESS(Status))
412 return Status;
413
414 /* allowed supported flags */
415 SupportedFlags = (KSALLOCATOR_OPTIONF_COMPATIBLE | KSALLOCATOR_OPTIONF_SYSTEM_MEMORY |
416 KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER | KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY |
417 KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE);
418
419
420 if (!AllocatorFraming->FrameSize || (AllocatorFraming->OptionsFlags & (~SupportedFlags)))
421 {
422 FreeItem(AllocatorFraming);
423 return STATUS_INVALID_PARAMETER;
424 }
425
426 /* store result */
427 *OutAllocatorFraming = AllocatorFraming;
428
429 return Status;
430 }
431
432 NTSTATUS
433 IKsAllocator_DispatchRequest(
434 IN PDEVICE_OBJECT DeviceObject,
435 IN PFILE_OBJECT FileObject,
436 IN PIRP Irp,
437 IN PVOID Frame,
438 IN ALLOC_REQUEST Request)
439 {
440 PKSIOBJECT_HEADER Header;
441 NTSTATUS Status;
442 IKsAllocator * Allocator;
443
444 /* sanity check */
445 ASSERT(FileObject);
446
447 /* get object header */
448 Header = (PKSIOBJECT_HEADER)FileObject->FsContext2;
449
450 /* get real allocator */
451 Status = Header->Unknown->lpVtbl->QueryInterface(Header->Unknown, &IID_IKsAllocator, (PVOID*)&Allocator);
452
453 if (!NT_SUCCESS(Status))
454 {
455 /* misbehaving object */
456 return STATUS_UNSUCCESSFUL;
457 }
458
459 if (Request == ALLOCATOR_DEVICE_CONTROL)
460 {
461 /* dispatch request allocator */
462 Status = Allocator->lpVtbl->DispatchDeviceIoControl(Allocator, DeviceObject, Irp);
463 }
464 else if (Request == ALLOCATOR_DEVICE_CLOSE)
465 {
466 /* delete allocator */
467 Status = Allocator->lpVtbl->Close(Allocator);
468 }
469 else if (Request == ALLOCATOR_ALLOCATE)
470 {
471 /* allocate frame */
472 Status = Allocator->lpVtbl->AllocateFrame(Allocator, (PVOID*)Frame);
473
474 }else if (Request == ALLOCATOR_FREE)
475 {
476 /* allocate frame */
477 Allocator->lpVtbl->FreeFrame(Allocator, Frame);
478 Status = STATUS_SUCCESS;
479 }
480
481 /* release interface */
482 Allocator->lpVtbl->Release(Allocator);
483
484 return Status;
485 }
486
487 NTSTATUS
488 NTAPI
489 IKsAllocator_DispatchDeviceIoControl(
490 IN PDEVICE_OBJECT DeviceObject,
491 IN PIRP Irp)
492 {
493 PIO_STACK_LOCATION IoStack;
494 NTSTATUS Status;
495
496 /* get current irp stack */
497 IoStack = IoGetCurrentIrpStackLocation(Irp);
498
499 /* dispatch request */
500 Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CONTROL);
501
502 /* complete request */
503 Irp->IoStatus.Status = Status;
504 IoCompleteRequest(Irp, IO_NO_INCREMENT);
505
506 return Status;
507 }
508
509 NTSTATUS
510 NTAPI
511 IKsAllocator_DispatchClose(
512 IN PDEVICE_OBJECT DeviceObject,
513 IN PIRP Irp)
514 {
515 PIO_STACK_LOCATION IoStack;
516 NTSTATUS Status;
517
518 /* get current irp stack */
519 IoStack = IoGetCurrentIrpStackLocation(Irp);
520
521 /* dispatch request */
522 Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CLOSE);
523
524 /* complete request */
525 Irp->IoStatus.Status = Status;
526 IoCompleteRequest(Irp, IO_NO_INCREMENT);
527
528 return Status;
529 }
530
531 NTSTATUS
532 NTAPI
533 IKsAllocator_Allocate(
534 IN PFILE_OBJECT FileObject,
535 PVOID *Frame)
536 {
537 NTSTATUS Status;
538
539 /* dispatch request */
540 Status = IKsAllocator_DispatchRequest(NULL, FileObject, NULL, (PVOID)Frame, ALLOCATOR_ALLOCATE);
541
542 return Status;
543 }
544
545 VOID
546 NTAPI
547 IKsAllocator_FreeFrame(
548 IN PFILE_OBJECT FileObject,
549 PVOID Frame)
550 {
551 /* dispatch request */
552 IKsAllocator_DispatchRequest(NULL, FileObject, NULL, Frame, ALLOCATOR_FREE);
553 }
554
555
556 static KSDISPATCH_TABLE DispatchTable =
557 {
558 IKsAllocator_DispatchDeviceIoControl,
559 KsDispatchInvalidDeviceRequest,
560 KsDispatchInvalidDeviceRequest,
561 KsDispatchInvalidDeviceRequest,
562 IKsAllocator_DispatchClose,
563 KsDispatchQuerySecurity,
564 KsDispatchSetSecurity,
565 KsDispatchFastIoDeviceControlFailure,
566 KsDispatchFastReadFailure,
567 KsDispatchFastReadFailure,
568 };
569
570 /*
571 @implemented
572 */
573 KSDDKAPI NTSTATUS NTAPI
574 KsCreateDefaultAllocatorEx(
575 IN PIRP Irp,
576 IN PVOID InitializeContext OPTIONAL,
577 IN PFNKSDEFAULTALLOCATE DefaultAllocate OPTIONAL,
578 IN PFNKSDEFAULTFREE DefaultFree OPTIONAL,
579 IN PFNKSINITIALIZEALLOCATOR InitializeAllocator OPTIONAL,
580 IN PFNKSDELETEALLOCATOR DeleteAllocator OPTIONAL)
581 {
582 NTSTATUS Status;
583 PKSALLOCATOR_FRAMING AllocatorFraming;
584 PALLOCATOR Allocator;
585 PVOID Ctx;
586
587 /* first validate connect request */
588 Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming);
589 if (!NT_SUCCESS(Status))
590 return STATUS_INVALID_PARAMETER;
591
592 /* check the valid file alignment */
593 if (AllocatorFraming->FileAlignment > (PAGE_SIZE-1))
594 return STATUS_INVALID_PARAMETER;
595
596 /* allocate allocator struct */
597 Allocator = AllocateItem(NonPagedPool, sizeof(ALLOCATOR));
598 if (!Allocator)
599 return STATUS_INSUFFICIENT_RESOURCES;
600
601 /* allocate object header */
602
603 Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&Allocator->Header, 0, NULL, Irp, &DispatchTable);
604 if (!NT_SUCCESS(Status))
605 {
606 FreeItem(Allocator);
607 return Status;
608 }
609
610 /* set allocator type in object header */
611 Allocator->lpVtbl = &vt_IKsAllocator;
612 Allocator->Header->Unknown = (PUNKNOWN)&Allocator->lpVtbl;
613 Allocator->ref = 1;
614
615 if (DefaultAllocate)
616 {
617 /* use external allocator */
618 Allocator->Type = ALLOCATOR_CUSTOM;
619 Allocator->Allocate.DefaultAllocate = DefaultAllocate;
620 Allocator->Free.DefaultFree = DefaultFree;
621 Allocator->Delete.DefaultDelete = DeleteAllocator;
622 Ctx = InitializeAllocator(InitializeContext, AllocatorFraming, &Allocator->u.CustomList);
623 /* check for success */
624 if (!Ctx)
625 {
626 KsFreeObjectHeader(Allocator->Header);
627 FreeItem(Allocator);
628 return Status;
629 }
630 }
631 else if (AllocatorFraming->PoolType == NonPagedPool)
632 {
633 /* use non-paged pool allocator */
634 Allocator->Type = ALLOCATOR_NPAGED_LOOKASIDE;
635 Allocator->Allocate.NPagedPool = ExAllocateFromNPagedLookasideList;
636 Allocator->Free.NPagedPool = ExFreeToNPagedLookasideList;
637 Allocator->Delete.NPagedPool = ExDeleteNPagedLookasideList;
638 ExInitializeNPagedLookasideList(&Allocator->u.NPagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0);
639 }
640 else if (AllocatorFraming->PoolType == PagedPool)
641 {
642 /* use paged pool allocator */
643 Allocator->Allocate.PagedPool = ExAllocateFromPagedLookasideList;
644 Allocator->Free.PagedPool = ExFreeToPagedLookasideList;
645 Allocator->Delete.PagedPool = ExDeletePagedLookasideList;
646 Allocator->Type = ALLOCATOR_PAGED_LOOKASIDE;
647 ExInitializePagedLookasideList(&Allocator->u.PagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0);
648
649 }
650
651 /* backup allocator framing */
652 RtlMoveMemory(&Allocator->Status.Framing, AllocatorFraming, sizeof(KSALLOCATOR_FRAMING));
653
654 return Status;
655 }
656
657 /*
658 @implemented
659 */
660 KSDDKAPI NTSTATUS NTAPI
661 KsValidateAllocatorFramingEx(
662 IN PKSALLOCATOR_FRAMING_EX Framing,
663 IN ULONG BufferSize,
664 IN const KSALLOCATOR_FRAMING_EX* PinFraming)
665 {
666 if (BufferSize < sizeof(KSALLOCATOR_FRAMING_EX))
667 return STATUS_INVALID_DEVICE_REQUEST;
668
669 /* verify framing */
670 if ((Framing->FramingItem[0].Flags & KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT) &&
671 Framing->OutputCompression.RatioNumerator != MAXULONG &&
672 Framing->OutputCompression.RatioDenominator != 0 &&
673 Framing->OutputCompression.RatioDenominator < Framing->OutputCompression.RatioNumerator)
674 {
675 /* framing request is ok */
676 return STATUS_SUCCESS;
677 }
678
679 return STATUS_INVALID_DEVICE_REQUEST;
680 }