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