/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsCreateDefaultClock( IN PIRP Irp, IN PKSDEFAULTCLOCK DefaultClock) { NTSTATUS Status; PKSCLOCK_CREATE ClockCreate; PKSICLOCK Clock; Status = KsValidateClockCreateRequest(Irp, &ClockCreate); if (!NT_SUCCESS(Status)) return Status; /* let's allocate the clock struct */ Clock = AllocateItem(NonPagedPool, sizeof(KSICLOCK)); if (!Clock) { FreeItem(ClockCreate); return STATUS_INSUFFICIENT_RESOURCES; } /* now allocate the object header */ Status = KsAllocateObjectHeader((PVOID*)&Clock->ObjectHeader, 0, NULL, Irp, &DispatchTable); /* did it work */ if (!NT_SUCCESS(Status)) { /* failed */ FreeItem(ClockCreate); FreeItem(Clock); return Status; } /* initialize clock */ /* FIXME IKsClock */ Clock->ObjectHeader->ObjectType = (PVOID)Clock; Clock->ref = 1; Clock->ClockCreate = ClockCreate; Clock->DefaultClock = (PKSIDEFAULTCLOCK)DefaultClock; /* increment reference count */ InterlockedIncrement(&Clock->DefaultClock->ReferenceCount); return Status; }
NTSTATUS NTAPI NewDispatchObject( IN PIRP Irp, IN IIrpTarget * Target, IN ULONG CreateItemCount, IN PKSOBJECT_CREATE_ITEM CreateItem) { NTSTATUS Status; KSOBJECT_HEADER ObjectHeader; PIO_STACK_LOCATION IoStack; PDISPATCH_CONTEXT DispatchContext; // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); DispatchContext = (PDISPATCH_CONTEXT)AllocateItem(NonPagedPool, sizeof(DISPATCH_CONTEXT), TAG_PORTCLASS); if (!DispatchContext) return STATUS_INSUFFICIENT_RESOURCES; // allocate object header Status = KsAllocateObjectHeader(&ObjectHeader, CreateItemCount, CreateItem, Irp, &DispatchTable); if (!NT_SUCCESS(Status)) { // free dispatch context FreeItem(DispatchContext, TAG_PORTCLASS); // done return Status; } // initialize dispatch context DispatchContext->ObjectHeader = ObjectHeader; DispatchContext->Target = Target; DispatchContext->CreateItem = CreateItem; // store dispatch context IoStack->FileObject->FsContext = DispatchContext; DPRINT("KsAllocateObjectHeader result %x Target %p Context %p\n", Status, Target, DispatchContext); return Status; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsCreateDefaultAllocatorEx( IN PIRP Irp, IN PVOID InitializeContext OPTIONAL, IN PFNKSDEFAULTALLOCATE DefaultAllocate OPTIONAL, IN PFNKSDEFAULTFREE DefaultFree OPTIONAL, IN PFNKSINITIALIZEALLOCATOR InitializeAllocator OPTIONAL, IN PFNKSDELETEALLOCATOR DeleteAllocator OPTIONAL) { 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)) { FreeItem(AllocatorFraming); return STATUS_INVALID_PARAMETER; } /* allocate allocator struct */ Allocator = AllocateItem(NonPagedPool, sizeof(ALLOCATOR)); if (!Allocator) { FreeItem(AllocatorFraming); return STATUS_INSUFFICIENT_RESOURCES; } /* allocate object header */ Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&Allocator->Header, 0, NULL, Irp, &DispatchTable); if (!NT_SUCCESS(Status)) { FreeItem(AllocatorFraming); 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)); FreeItem(AllocatorFraming); return Status; }
NTSTATUS NTAPI DispatchCreateSysAudioPin( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IoStack; PKSAUDIO_DEVICE_ENTRY DeviceEntry; PKSPIN_CONNECT Connect; PDISPATCH_CONTEXT DispatchContext; DPRINT("DispatchCreateSysAudioPin entered\n"); /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* sanity checks */ ASSERT(IoStack->FileObject); ASSERT(IoStack->FileObject->RelatedFileObject); ASSERT(IoStack->FileObject->RelatedFileObject->FsContext); /* get current attached virtual device */ DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)IoStack->FileObject->RelatedFileObject->FsContext; /* check for success */ if (!NT_SUCCESS(Status)) { /* failed */ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } /* get connect details */ Status = GetConnectRequest(Irp, &Connect); /* check for success */ if (!NT_SUCCESS(Status)) { /* failed to obtain connect details */ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } /* allocate dispatch context */ DispatchContext = AllocateItem(NonPagedPool, sizeof(DISPATCH_CONTEXT)); if (!DispatchContext) { /* failed */ Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } /* zero dispatch context */ RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT)); /* allocate object header */ Status = KsAllocateObjectHeader(&DispatchContext->ObjectHeader, 0, NULL, Irp, &PinTable); if (!NT_SUCCESS(Status)) { /* failed */ FreeItem(DispatchContext); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } /* now instantiate the pins */ Status = InstantiatePins(DeviceEntry, Connect, DispatchContext, (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension); if (!NT_SUCCESS(Status)) { /* failed */ KsFreeObjectHeader(DispatchContext->ObjectHeader); FreeItem(DispatchContext); } else { /* store dispatch context */ IoStack->FileObject->FsContext = (PVOID)DispatchContext; } /* FIXME create items for clocks / allocators */ Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS InitializeFilterWithKs( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; PSTREAM_DEVICE_EXTENSION DeviceExtension; KSOBJECT_HEADER ObjectHeader; PKSOBJECT_CREATE_ITEM CreateItem; PIO_STACK_LOCATION IoStack; HW_STREAM_REQUEST_BLOCK_EXT RequestBlock; PVOID HwInstanceExtension = NULL; /* Get device extension */ DeviceExtension = (PSTREAM_DEVICE_EXTENSION)DeviceObject->DeviceExtension; if (!DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize) { /* driver supports only one instance */ if (DeviceExtension->InstanceCount) { /* there is already one instance open */ return STATUS_UNSUCCESSFUL; } } else { /* driver supports more than one filter instance */ RtlZeroMemory(&RequestBlock, sizeof(HW_STREAM_REQUEST_BLOCK_EXT)); /* allocate instance extension */ HwInstanceExtension = ExAllocatePool(NonPagedPool, DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize); if (!HwInstanceExtension) { /* Not enough memory */ return STATUS_INSUFFICIENT_RESOURCES; } /* Zero instance extension */ RtlZeroMemory(HwInstanceExtension, DeviceExtension->DriverExtension->Data.FilterInstanceExtensionSize); /* set up request block */ RequestBlock.Block.Command = SRB_OPEN_DEVICE_INSTANCE; RequestBlock.Block.HwDeviceExtension = DeviceExtension->DeviceExtension; RequestBlock.Block.Irp = Irp; RequestBlock.Block.HwInstanceExtension = HwInstanceExtension; KeInitializeEvent(&RequestBlock.Event, SynchronizationEvent, FALSE); /*FIXME SYNCHRONIZATION */ /* Send the request */ DeviceExtension->DriverExtension->Data.HwReceivePacket((PHW_STREAM_REQUEST_BLOCK)&RequestBlock); if (RequestBlock.Block.Status == STATUS_PENDING) { /* Wait for the request */ KeWaitForSingleObject(&RequestBlock.Event, Executive, KernelMode, FALSE, NULL); } /* Check for success */ if (!NT_SUCCESS(RequestBlock.Block.Status)) { /* Resource is not available */ ExFreePool(HwInstanceExtension); return RequestBlock.Block.Status; } } /* Allocate create item */ CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); if (!CreateItem) { /* not enough memory */ return STATUS_INSUFFICIENT_RESOURCES; } /* Zero create item */ RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM)); /* Initialize createitem */ RtlInitUnicodeString(&CreateItem->ObjectClass, KSSTRING_Pin); CreateItem->Create = StreamClassCreatePin; /* Get current irp stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* Create Ks streaming object header */ Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable); if (!NT_SUCCESS(Status)) { /* Failed to create header */ ExFreePool(CreateItem); if (HwInstanceExtension) { /* free instance buffer */ ExFreePool(HwInstanceExtension); } return Status; } /* Store instance buffer in file object context */ IoStack->FileObject->FsContext2 = HwInstanceExtension; /* Increment total instance count */ InterlockedIncrement(&DeviceExtension->InstanceCount); /* Register device stream interfaces */ RegisterDeviceInterfaces(DeviceExtension); /* Return result */ return Status; }