Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenallocators.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/ksfilter/ks/allocators.c 00005 * PURPOSE: KS Allocator functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 00010 #include "priv.h" 00011 00012 typedef enum 00013 { 00014 ALLOCATOR_NPAGED_LOOKASIDE, 00015 ALLOCATOR_PAGED_LOOKASIDE, 00016 ALLOCATOR_CUSTOM 00017 }ALLOCATOR_TYPE; 00018 00019 typedef enum 00020 { 00021 ALLOCATOR_DEVICE_CONTROL, 00022 ALLOCATOR_DEVICE_CLOSE, 00023 ALLOCATOR_ALLOCATE, 00024 ALLOCATOR_FREE 00025 00026 }ALLOC_REQUEST; 00027 00028 typedef PVOID (*PFNKSPAGEDPOOLALLOCATE)(IN PPAGED_LOOKASIDE_LIST Lookaside); 00029 typedef PVOID (*PFNKSNPAGEDPOOLALLOCATE)(IN PNPAGED_LOOKASIDE_LIST Lookaside); 00030 00031 typedef VOID (*PFNKSPAGEDPOOLFREE)(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry); 00032 typedef VOID (*PFNKSNPAGEDPOOLFREE)(IN PNPAGED_LOOKASIDE_LIST Lookaside, IN PVOID Entry); 00033 00034 typedef VOID (NTAPI *PFNKSNPAGEDPOOLDELETE)(IN PNPAGED_LOOKASIDE_LIST Lookaside); 00035 typedef VOID (NTAPI *PFNKSPAGEDPOOLDELETE)(IN PPAGED_LOOKASIDE_LIST Lookaside); 00036 00037 typedef struct 00038 { 00039 IKsAllocatorVtbl *lpVtbl; 00040 LONG ref; 00041 PKSIOBJECT_HEADER Header; 00042 ALLOCATOR_TYPE Type; 00043 00044 KSSTREAMALLOCATOR_STATUS Status; 00045 00046 union 00047 { 00048 NPAGED_LOOKASIDE_LIST NPagedList; 00049 PAGED_LOOKASIDE_LIST PagedList; 00050 PVOID CustomList; 00051 }u; 00052 00053 union 00054 { 00055 PFNKSDEFAULTALLOCATE DefaultAllocate; 00056 PFNKSPAGEDPOOLALLOCATE PagedPool; 00057 PFNKSNPAGEDPOOLALLOCATE NPagedPool; 00058 }Allocate; 00059 00060 union 00061 { 00062 PFNKSDEFAULTFREE DefaultFree; 00063 PFNKSPAGEDPOOLFREE PagedPool; 00064 PFNKSNPAGEDPOOLFREE NPagedPool; 00065 }Free; 00066 00067 union 00068 { 00069 PFNKSDELETEALLOCATOR DefaultDelete; 00070 PFNKSNPAGEDPOOLDELETE NPagedPool; 00071 PFNKSPAGEDPOOLDELETE PagedPool; 00072 }Delete; 00073 00074 }ALLOCATOR, *PALLOCATOR; 00075 00076 /* use KSNAME_Allocator for IID_IKsAllocator */ 00077 const GUID IID_IKsAllocator = {0x642F5D00L, 0x4791, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00078 const GUID KSPROPSETID_StreamAllocator = {0x0cf6e4342, 0xec87, 0x11cf, {0xa1, 0x30, 0x00, 0x20, 0xaf, 0xd1, 0x56, 0xe4}}; 00079 00080 00081 NTSTATUS 00082 NTAPI 00083 IKsAllocator_Allocate( 00084 IN PFILE_OBJECT FileObject, 00085 PVOID *Frame); 00086 00087 VOID 00088 NTAPI 00089 IKsAllocator_FreeFrame( 00090 IN PFILE_OBJECT FileObject, 00091 PVOID Frame); 00092 00093 00094 NTSTATUS 00095 NTAPI 00096 IKsAllocator_fnQueryInterface( 00097 IKsAllocator * iface, 00098 IN REFIID refiid, 00099 OUT PVOID* Output) 00100 { 00101 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); 00102 00103 if (IsEqualGUIDAligned(refiid, &IID_IUnknown) || 00104 IsEqualGUIDAligned(refiid, &IID_IKsAllocator)) 00105 { 00106 *Output = &This->lpVtbl; 00107 _InterlockedIncrement(&This->ref); 00108 return STATUS_SUCCESS; 00109 } 00110 return STATUS_UNSUCCESSFUL; 00111 } 00112 00113 ULONG 00114 NTAPI 00115 IKsAllocator_fnAddRef( 00116 IKsAllocator * iface) 00117 { 00118 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); 00119 00120 return InterlockedIncrement(&This->ref); 00121 } 00122 00123 ULONG 00124 NTAPI 00125 IKsAllocator_fnRelease( 00126 IKsAllocator * iface) 00127 { 00128 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); 00129 00130 InterlockedDecrement(&This->ref); 00131 00132 if (This->ref == 0) 00133 { 00134 FreeItem(This); 00135 return 0; 00136 } 00137 /* Return new reference count */ 00138 return This->ref; 00139 } 00140 00141 NTSTATUS 00142 NTAPI 00143 IKsAllocator_fnDeviceIoControl( 00144 IKsAllocator *iface, 00145 IN PDEVICE_OBJECT DeviceObject, 00146 IN PIRP Irp) 00147 { 00148 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); 00149 PIO_STACK_LOCATION IoStack; 00150 PKSSTREAMALLOCATOR_FUNCTIONTABLE FunctionTable; 00151 PKSSTREAMALLOCATOR_STATUS State; 00152 PKSPROPERTY Property; 00153 00154 /* FIXME locks */ 00155 00156 /* get current irp stack */ 00157 IoStack = IoGetCurrentIrpStackLocation(Irp); 00158 00159 if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) 00160 { 00161 /* only KSPROPERTY requests are supported */ 00162 UNIMPLEMENTED 00163 00164 /* complete and forget irps */ 00165 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 00166 CompleteRequest(Irp, IO_NO_INCREMENT); 00167 00168 return STATUS_NOT_IMPLEMENTED; 00169 } 00170 00171 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) 00172 { 00173 /* invalid request */ 00174 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 00175 CompleteRequest(Irp, IO_NO_INCREMENT); 00176 00177 return STATUS_INVALID_DEVICE_REQUEST; 00178 } 00179 00180 /* check the request */ 00181 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00182 00183 if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_StreamAllocator)) 00184 { 00185 if (Property->Id == KSPROPERTY_STREAMALLOCATOR_FUNCTIONTABLE) 00186 { 00187 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE)) 00188 { 00189 /* buffer too small */ 00190 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 00191 Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); 00192 /* complete and forget irp */ 00193 CompleteRequest(Irp, IO_NO_INCREMENT); 00194 return STATUS_BUFFER_TOO_SMALL; 00195 } 00196 if (!(Property->Flags & KSPROPERTY_TYPE_GET)) 00197 { 00198 /* only support retrieving the property */ 00199 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00200 /* complete and forget irp */ 00201 CompleteRequest(Irp, IO_NO_INCREMENT); 00202 return STATUS_UNSUCCESSFUL; 00203 } 00204 00205 /* get output buffer */ 00206 FunctionTable = (PKSSTREAMALLOCATOR_FUNCTIONTABLE)Irp->UserBuffer; 00207 00208 FunctionTable->AllocateFrame = IKsAllocator_Allocate; 00209 FunctionTable->FreeFrame = IKsAllocator_FreeFrame; 00210 00211 /* save result */ 00212 Irp->IoStatus.Status = STATUS_SUCCESS; 00213 Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_FUNCTIONTABLE); 00214 /* complete request */ 00215 CompleteRequest(Irp, IO_NO_INCREMENT); 00216 return STATUS_SUCCESS; 00217 } 00218 else if (Property->Id == KSPROPERTY_STREAMALLOCATOR_STATUS) 00219 { 00220 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS)) 00221 { 00222 /* buffer too small */ 00223 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 00224 Irp->IoStatus.Information = sizeof(KSPROPERTY_STREAMALLOCATOR_STATUS); 00225 /* complete and forget irp */ 00226 CompleteRequest(Irp, IO_NO_INCREMENT); 00227 return STATUS_BUFFER_TOO_SMALL; 00228 } 00229 if (!(Property->Flags & KSPROPERTY_TYPE_GET)) 00230 { 00231 /* only support retrieving the property */ 00232 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00233 /* complete and forget irp */ 00234 CompleteRequest(Irp, IO_NO_INCREMENT); 00235 return STATUS_UNSUCCESSFUL; 00236 } 00237 00238 /* get output buffer */ 00239 State = (PKSSTREAMALLOCATOR_STATUS)Irp->UserBuffer; 00240 00241 /* copy allocator status */ 00242 RtlMoveMemory(State, &This->Status, sizeof(KSSTREAMALLOCATOR_STATUS)); 00243 00244 /* save result */ 00245 Irp->IoStatus.Status = STATUS_SUCCESS; 00246 Irp->IoStatus.Information = sizeof(KSSTREAMALLOCATOR_STATUS); 00247 00248 /* complete request */ 00249 CompleteRequest(Irp, IO_NO_INCREMENT); 00250 return STATUS_SUCCESS; 00251 } 00252 } 00253 00254 /* unhandled request */ 00255 Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; 00256 CompleteRequest(Irp, IO_NO_INCREMENT); 00257 00258 return STATUS_NOT_SUPPORTED; 00259 } 00260 00261 NTSTATUS 00262 NTAPI 00263 IKsAllocator_fnClose( 00264 IKsAllocator *iface) 00265 { 00266 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); 00267 00268 /* FIXME locks */ 00269 00270 /* now close allocator */ 00271 if (This->Type == ALLOCATOR_CUSTOM) 00272 { 00273 This->Delete.DefaultDelete(This->u.CustomList); 00274 } 00275 else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE) 00276 { 00277 This->Delete.NPagedPool(&This->u.NPagedList); 00278 } 00279 else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE) 00280 { 00281 This->Delete.PagedPool(&This->u.PagedList); 00282 } 00283 00284 /* free object header */ 00285 KsFreeObjectHeader(&This->Header); 00286 00287 return STATUS_SUCCESS; 00288 } 00289 00290 NTSTATUS 00291 NTAPI 00292 IKsAllocator_fnAllocateFrame( 00293 IKsAllocator *iface, 00294 IN PVOID * OutFrame) 00295 { 00296 PVOID Frame = NULL; 00297 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); 00298 00299 /* FIXME locks */ 00300 00301 /* now allocate frame */ 00302 if (This->Type == ALLOCATOR_CUSTOM) 00303 { 00304 Frame = This->Allocate.DefaultAllocate(This->u.CustomList); 00305 } 00306 else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE) 00307 { 00308 Frame = This->Allocate.NPagedPool(&This->u.NPagedList); 00309 } 00310 else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE) 00311 { 00312 Frame = This->Allocate.PagedPool(&This->u.PagedList); 00313 } 00314 00315 if (Frame) 00316 { 00317 *OutFrame = Frame; 00318 InterlockedIncrement((PLONG)&This->Status.AllocatedFrames); 00319 return STATUS_SUCCESS; 00320 } 00321 00322 return STATUS_UNSUCCESSFUL; 00323 } 00324 00325 VOID 00326 NTAPI 00327 IKsAllocator_fnFreeFrame( 00328 IKsAllocator *iface, 00329 IN PVOID Frame) 00330 { 00331 PALLOCATOR This = (PALLOCATOR)CONTAINING_RECORD(iface, ALLOCATOR, lpVtbl); 00332 00333 /* now allocate frame */ 00334 if (This->Type == ALLOCATOR_CUSTOM) 00335 { 00336 This->Free.DefaultFree(This->u.CustomList, Frame); 00337 } 00338 else if (This->Type == ALLOCATOR_NPAGED_LOOKASIDE) 00339 { 00340 This->Free.NPagedPool(&This->u.NPagedList, Frame); 00341 } 00342 else if (This->Type == ALLOCATOR_PAGED_LOOKASIDE) 00343 { 00344 This->Free.PagedPool(&This->u.PagedList, Frame); 00345 } 00346 } 00347 00348 00349 static IKsAllocatorVtbl vt_IKsAllocator = 00350 { 00351 IKsAllocator_fnQueryInterface, 00352 IKsAllocator_fnAddRef, 00353 IKsAllocator_fnRelease, 00354 IKsAllocator_fnDeviceIoControl, 00355 IKsAllocator_fnClose, 00356 IKsAllocator_fnAllocateFrame, 00357 IKsAllocator_fnFreeFrame 00358 }; 00359 00360 00361 /* 00362 @implemented 00363 */ 00364 KSDDKAPI NTSTATUS NTAPI 00365 KsCreateAllocator( 00366 IN HANDLE ConnectionHandle, 00367 IN PKSALLOCATOR_FRAMING AllocatorFraming, 00368 OUT PHANDLE AllocatorHandle) 00369 { 00370 return KspCreateObjectType(ConnectionHandle, 00371 KSSTRING_Allocator, 00372 (PVOID)AllocatorFraming, 00373 sizeof(KSALLOCATOR_FRAMING), 00374 GENERIC_READ, 00375 AllocatorHandle); 00376 } 00377 00378 /* 00379 @implemented 00380 */ 00381 KSDDKAPI NTSTATUS NTAPI 00382 KsCreateDefaultAllocator( 00383 IN PIRP Irp) 00384 { 00385 return KsCreateDefaultAllocatorEx(Irp, NULL, NULL, NULL, NULL, NULL); 00386 } 00387 00388 /* 00389 @implemented 00390 */ 00391 KSDDKAPI 00392 NTSTATUS 00393 NTAPI 00394 KsValidateAllocatorCreateRequest( 00395 IN PIRP Irp, 00396 OUT PKSALLOCATOR_FRAMING* OutAllocatorFraming) 00397 { 00398 PKSALLOCATOR_FRAMING AllocatorFraming; 00399 ULONG Size; 00400 NTSTATUS Status; 00401 ULONG SupportedFlags; 00402 00403 /* set minimum request size */ 00404 Size = sizeof(KSALLOCATOR_FRAMING); 00405 00406 Status = KspCopyCreateRequest(Irp, 00407 KSSTRING_Allocator, 00408 &Size, 00409 (PVOID*)&AllocatorFraming); 00410 00411 if (!NT_SUCCESS(Status)) 00412 return Status; 00413 00414 /* allowed supported flags */ 00415 SupportedFlags = (KSALLOCATOR_OPTIONF_COMPATIBLE | KSALLOCATOR_OPTIONF_SYSTEM_MEMORY | 00416 KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER | KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY | 00417 KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE); 00418 00419 00420 if (!AllocatorFraming->FrameSize || (AllocatorFraming->OptionsFlags & (~SupportedFlags))) 00421 { 00422 FreeItem(AllocatorFraming); 00423 return STATUS_INVALID_PARAMETER; 00424 } 00425 00426 /* store result */ 00427 *OutAllocatorFraming = AllocatorFraming; 00428 00429 return Status; 00430 } 00431 00432 NTSTATUS 00433 IKsAllocator_DispatchRequest( 00434 IN PDEVICE_OBJECT DeviceObject, 00435 IN PFILE_OBJECT FileObject, 00436 IN PIRP Irp, 00437 IN PVOID Frame, 00438 IN ALLOC_REQUEST Request) 00439 { 00440 PKSIOBJECT_HEADER Header; 00441 NTSTATUS Status; 00442 IKsAllocator * Allocator; 00443 00444 /* sanity check */ 00445 ASSERT(FileObject); 00446 00447 /* get object header */ 00448 Header = (PKSIOBJECT_HEADER)FileObject->FsContext2; 00449 00450 /* get real allocator */ 00451 Status = Header->Unknown->lpVtbl->QueryInterface(Header->Unknown, &IID_IKsAllocator, (PVOID*)&Allocator); 00452 00453 if (!NT_SUCCESS(Status)) 00454 { 00455 /* misbehaving object */ 00456 return STATUS_UNSUCCESSFUL; 00457 } 00458 00459 if (Request == ALLOCATOR_DEVICE_CONTROL) 00460 { 00461 /* dispatch request allocator */ 00462 Status = Allocator->lpVtbl->DispatchDeviceIoControl(Allocator, DeviceObject, Irp); 00463 } 00464 else if (Request == ALLOCATOR_DEVICE_CLOSE) 00465 { 00466 /* delete allocator */ 00467 Status = Allocator->lpVtbl->Close(Allocator); 00468 } 00469 else if (Request == ALLOCATOR_ALLOCATE) 00470 { 00471 /* allocate frame */ 00472 Status = Allocator->lpVtbl->AllocateFrame(Allocator, (PVOID*)Frame); 00473 00474 }else if (Request == ALLOCATOR_FREE) 00475 { 00476 /* allocate frame */ 00477 Allocator->lpVtbl->FreeFrame(Allocator, Frame); 00478 Status = STATUS_SUCCESS; 00479 } 00480 00481 /* release interface */ 00482 Allocator->lpVtbl->Release(Allocator); 00483 00484 return Status; 00485 } 00486 00487 NTSTATUS 00488 NTAPI 00489 IKsAllocator_DispatchDeviceIoControl( 00490 IN PDEVICE_OBJECT DeviceObject, 00491 IN PIRP Irp) 00492 { 00493 PIO_STACK_LOCATION IoStack; 00494 NTSTATUS Status; 00495 00496 /* get current irp stack */ 00497 IoStack = IoGetCurrentIrpStackLocation(Irp); 00498 00499 /* dispatch request */ 00500 Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CONTROL); 00501 00502 /* complete request */ 00503 Irp->IoStatus.Status = Status; 00504 CompleteRequest(Irp, IO_NO_INCREMENT); 00505 00506 return Status; 00507 } 00508 00509 NTSTATUS 00510 NTAPI 00511 IKsAllocator_DispatchClose( 00512 IN PDEVICE_OBJECT DeviceObject, 00513 IN PIRP Irp) 00514 { 00515 PIO_STACK_LOCATION IoStack; 00516 NTSTATUS Status; 00517 00518 /* get current irp stack */ 00519 IoStack = IoGetCurrentIrpStackLocation(Irp); 00520 00521 /* dispatch request */ 00522 Status = IKsAllocator_DispatchRequest(DeviceObject, IoStack->FileObject, Irp, NULL, ALLOCATOR_DEVICE_CLOSE); 00523 00524 /* complete request */ 00525 Irp->IoStatus.Status = Status; 00526 CompleteRequest(Irp, IO_NO_INCREMENT); 00527 00528 return Status; 00529 } 00530 00531 NTSTATUS 00532 NTAPI 00533 IKsAllocator_Allocate( 00534 IN PFILE_OBJECT FileObject, 00535 PVOID *Frame) 00536 { 00537 NTSTATUS Status; 00538 00539 /* dispatch request */ 00540 Status = IKsAllocator_DispatchRequest(NULL, FileObject, NULL, (PVOID)Frame, ALLOCATOR_ALLOCATE); 00541 00542 return Status; 00543 } 00544 00545 VOID 00546 NTAPI 00547 IKsAllocator_FreeFrame( 00548 IN PFILE_OBJECT FileObject, 00549 PVOID Frame) 00550 { 00551 /* dispatch request */ 00552 IKsAllocator_DispatchRequest(NULL, FileObject, NULL, Frame, ALLOCATOR_FREE); 00553 } 00554 00555 00556 static KSDISPATCH_TABLE DispatchTable = 00557 { 00558 IKsAllocator_DispatchDeviceIoControl, 00559 KsDispatchInvalidDeviceRequest, 00560 KsDispatchInvalidDeviceRequest, 00561 KsDispatchInvalidDeviceRequest, 00562 IKsAllocator_DispatchClose, 00563 KsDispatchQuerySecurity, 00564 KsDispatchSetSecurity, 00565 KsDispatchFastIoDeviceControlFailure, 00566 KsDispatchFastReadFailure, 00567 KsDispatchFastReadFailure, 00568 }; 00569 00570 /* 00571 @implemented 00572 */ 00573 KSDDKAPI NTSTATUS NTAPI 00574 KsCreateDefaultAllocatorEx( 00575 IN PIRP Irp, 00576 IN PVOID InitializeContext OPTIONAL, 00577 IN PFNKSDEFAULTALLOCATE DefaultAllocate OPTIONAL, 00578 IN PFNKSDEFAULTFREE DefaultFree OPTIONAL, 00579 IN PFNKSINITIALIZEALLOCATOR InitializeAllocator OPTIONAL, 00580 IN PFNKSDELETEALLOCATOR DeleteAllocator OPTIONAL) 00581 { 00582 NTSTATUS Status; 00583 PKSALLOCATOR_FRAMING AllocatorFraming; 00584 PALLOCATOR Allocator; 00585 PVOID Ctx; 00586 00587 /* first validate connect request */ 00588 Status = KsValidateAllocatorCreateRequest(Irp, &AllocatorFraming); 00589 if (!NT_SUCCESS(Status)) 00590 return STATUS_INVALID_PARAMETER; 00591 00592 /* check the valid file alignment */ 00593 if (AllocatorFraming->FileAlignment > (PAGE_SIZE-1)) 00594 return STATUS_INVALID_PARAMETER; 00595 00596 /* allocate allocator struct */ 00597 Allocator = AllocateItem(NonPagedPool, sizeof(ALLOCATOR)); 00598 if (!Allocator) 00599 return STATUS_INSUFFICIENT_RESOURCES; 00600 00601 /* allocate object header */ 00602 00603 Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&Allocator->Header, 0, NULL, Irp, &DispatchTable); 00604 if (!NT_SUCCESS(Status)) 00605 { 00606 FreeItem(Allocator); 00607 return Status; 00608 } 00609 00610 /* set allocator type in object header */ 00611 Allocator->lpVtbl = &vt_IKsAllocator; 00612 Allocator->Header->Unknown = (PUNKNOWN)&Allocator->lpVtbl; 00613 Allocator->ref = 1; 00614 00615 if (DefaultAllocate) 00616 { 00617 /* use external allocator */ 00618 Allocator->Type = ALLOCATOR_CUSTOM; 00619 Allocator->Allocate.DefaultAllocate = DefaultAllocate; 00620 Allocator->Free.DefaultFree = DefaultFree; 00621 Allocator->Delete.DefaultDelete = DeleteAllocator; 00622 Ctx = InitializeAllocator(InitializeContext, AllocatorFraming, &Allocator->u.CustomList); 00623 /* check for success */ 00624 if (!Ctx) 00625 { 00626 KsFreeObjectHeader(Allocator->Header); 00627 FreeItem(Allocator); 00628 return Status; 00629 } 00630 } 00631 else if (AllocatorFraming->PoolType == NonPagedPool) 00632 { 00633 /* use non-paged pool allocator */ 00634 Allocator->Type = ALLOCATOR_NPAGED_LOOKASIDE; 00635 Allocator->Allocate.NPagedPool = ExAllocateFromNPagedLookasideList; 00636 Allocator->Free.NPagedPool = ExFreeToNPagedLookasideList; 00637 Allocator->Delete.NPagedPool = ExDeleteNPagedLookasideList; 00638 ExInitializeNPagedLookasideList(&Allocator->u.NPagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0); 00639 } 00640 else if (AllocatorFraming->PoolType == PagedPool) 00641 { 00642 /* use paged pool allocator */ 00643 Allocator->Allocate.PagedPool = ExAllocateFromPagedLookasideList; 00644 Allocator->Free.PagedPool = ExFreeToPagedLookasideList; 00645 Allocator->Delete.PagedPool = ExDeletePagedLookasideList; 00646 Allocator->Type = ALLOCATOR_PAGED_LOOKASIDE; 00647 ExInitializePagedLookasideList(&Allocator->u.PagedList, NULL, NULL, 0, AllocatorFraming->FrameSize, 0, 0); 00648 00649 } 00650 00651 /* backup allocator framing */ 00652 RtlMoveMemory(&Allocator->Status.Framing, AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); 00653 00654 return Status; 00655 } 00656 00657 /* 00658 @implemented 00659 */ 00660 KSDDKAPI NTSTATUS NTAPI 00661 KsValidateAllocatorFramingEx( 00662 IN PKSALLOCATOR_FRAMING_EX Framing, 00663 IN ULONG BufferSize, 00664 IN const KSALLOCATOR_FRAMING_EX* PinFraming) 00665 { 00666 if (BufferSize < sizeof(KSALLOCATOR_FRAMING_EX)) 00667 return STATUS_INVALID_DEVICE_REQUEST; 00668 00669 /* verify framing */ 00670 if ((Framing->FramingItem[0].Flags & KSALLOCATOR_FLAG_PARTIAL_READ_SUPPORT) && 00671 Framing->OutputCompression.RatioNumerator != MAXULONG && 00672 Framing->OutputCompression.RatioDenominator != 0 && 00673 Framing->OutputCompression.RatioDenominator < Framing->OutputCompression.RatioNumerator) 00674 { 00675 /* framing request is ok */ 00676 return STATUS_SUCCESS; 00677 } 00678 00679 return STATUS_INVALID_DEVICE_REQUEST; 00680 } Generated on Fri May 25 2012 04:26:03 for ReactOS by
1.7.6.1
|