ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

allocators.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.