Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS Kernel Streaming * FILE: drivers/ksfilter/ks/device.c * PURPOSE: KS IKsDevice interface functions * PROGRAMMER: Johannes Anderwald */
#include "precomp.h"
#define NDEBUG#include <debug.h>
NTSTATUSNTAPIIKsDevice_fnQueryInterface( IN IKsDevice * iface, REFIID refiid, PVOID* Output){ NTSTATUS Status; PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) { *Output = &This->BasicHeader.OuterUnknown; _InterlockedIncrement(&This->ref); return STATUS_SUCCESS; }
if (This->BasicHeader.ClientAggregate) { /* using client aggregate */ Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
if (NT_SUCCESS(Status)) { /* client aggregate supports interface */ return Status; } }
DPRINT("IKsDevice_fnQueryInterface no interface\n"); return STATUS_NOT_SUPPORTED;}
ULONGNTAPIIKsDevice_fnAddRef( IN IKsDevice * iface){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return InterlockedIncrement(&This->ref);}
ULONGNTAPIIKsDevice_fnRelease( IN IKsDevice * iface){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
InterlockedDecrement(&This->ref);
return This->ref;}
PKSDEVICENTAPIIKsDevice_fnGetStruct( IN IKsDevice * iface){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return &This->KsDevice;}
NTSTATUSNTAPIIKsDevice_fnInitializeObjectBag( IN IKsDevice * iface, IN PKSIOBJECT_BAG Bag, IN PRKMUTEX Mutex){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
if (!Mutex) { /* use device mutex */ Mutex = &This->BagMutex; }
/* initialize object bag */ Bag->BagMutex = Mutex; Bag->DeviceHeader = (PKSIDEVICE_HEADER)This; InitializeListHead(&Bag->ObjectList);
/* insert bag into device list */ InsertTailList(&This->ObjectBags, &Bag->Entry);
return STATUS_SUCCESS;}
NTSTATUSNTAPIIKsDevice_fnAcquireDevice( IN IKsDevice * iface){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL);}
NTSTATUSNTAPIIKsDevice_fnReleaseDevice( IN IKsDevice * iface){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
return KeReleaseMutex(&This->DeviceMutex, FALSE);}
NTSTATUSNTAPIIKsDevice_fnGetAdapterObject( IN IKsDevice * iface, IN PADAPTER_OBJECT * Object, IN PULONG MaxMappingsByteCount, IN PULONG MappingTableStride){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
*Object = This->AdapterObject; *MaxMappingsByteCount = This->MaxMappingsByteCount; *MappingTableStride = This->MappingTableStride;
return STATUS_SUCCESS;
}
NTSTATUSNTAPIIKsDevice_fnAddPowerEntry( IN IKsDevice * iface, IN struct KSPOWER_ENTRY * Entry, IN IKsPowerNotify* Notify){ //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
NTSTATUSNTAPIIKsDevice_fnRemovePowerEntry( IN IKsDevice * iface, IN struct KSPOWER_ENTRY * Entry){ //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
}
NTSTATUSNTAPIIKsDevice_fnPinStateChange( IN IKsDevice * iface, IN KSPIN Pin, IN PIRP Irp, IN KSSTATE OldState, IN KSSTATE NewState){ //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;
}
NTSTATUSNTAPIIKsDevice_fnArbitrateAdapterChannel( IN IKsDevice * iface, IN ULONG NumberOfMapRegisters, IN PDRIVER_CONTROL ExecutionRoutine, IN PVOID Context){ PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); NTSTATUS Status;
DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql());
/* sanity check */ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); ASSERT(This->AdapterObject);
/* allocate adapter channel */ Status = IoAllocateAdapterChannel(This->AdapterObject, This->KsDevice.FunctionalDeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context);
/* done */ return Status;}
NTSTATUSNTAPIIKsDevice_fnCheckIoCapability( IN IKsDevice * iface, IN ULONG Unknown){ //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
UNIMPLEMENTED; return STATUS_NOT_IMPLEMENTED;}
static IKsDeviceVtbl vt_IKsDevice ={ IKsDevice_fnQueryInterface, IKsDevice_fnAddRef, IKsDevice_fnRelease, IKsDevice_fnGetStruct, IKsDevice_fnInitializeObjectBag, IKsDevice_fnAcquireDevice, IKsDevice_fnReleaseDevice, IKsDevice_fnGetAdapterObject, IKsDevice_fnAddPowerEntry, IKsDevice_fnRemovePowerEntry, IKsDevice_fnPinStateChange, IKsDevice_fnArbitrateAdapterChannel, IKsDevice_fnCheckIoCapability};
VOIDNTAPIIKsDevice_PnpPostStart( IN PDEVICE_OBJECT DeviceObject, IN PVOID Context){ NTSTATUS Status; PPNP_POSTSTART_CONTEXT Ctx = (PPNP_POSTSTART_CONTEXT)Context;
/* call driver pnp post routine */ Status = Ctx->DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart(&Ctx->DeviceHeader->KsDevice);
if (!NT_SUCCESS(Status)) { /* set state to disabled */ Ctx->DeviceHeader->TargetState = KSTARGET_STATE_DISABLED; } else { /* set state to enabled */ Ctx->DeviceHeader->TargetState = KSTARGET_STATE_ENABLED; Status = KspSetFilterFactoriesState(Ctx->DeviceHeader, TRUE); }
/* free work item */ IoFreeWorkItem(Ctx->WorkItem);
/* free work context */ FreeItem(Ctx);
DPRINT("IKsDevice_PnpPostStart: PostStart Routine returned %x\n", Status);}
NTSTATUSNTAPIIKsDevice_PnpStartDevice( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PPNP_POSTSTART_CONTEXT Ctx = NULL; NTSTATUS Status; PCM_RESOURCE_LIST TranslatedResourceList; PCM_RESOURCE_LIST UntranslatedResourceList;
/* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get device header */ DeviceHeader = DeviceExtension->DeviceHeader;
DPRINT("IKsDevice_PnpStartDevice DeviceHeader %p\n", DeviceHeader);
/* first forward irp to lower device object */ if (!IoForwardIrpSynchronously(DeviceHeader->KsDevice.NextDeviceObject, Irp)) { Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; } Status = Irp->IoStatus.Status;
/* check for success */ if (!NT_SUCCESS(Status)) { DPRINT1("NextDevice object failed to start with %x\n", Status); CompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated; UntranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
ASSERT(DeviceHeader->KsDevice.Descriptor);
/* do we have a device descriptor */ if (DeviceHeader->KsDevice.Descriptor) { /* does the device want pnp notifications */ if (DeviceHeader->KsDevice.Descriptor->Dispatch) { /* does the driver care about IRP_MN_START_DEVICE */ if (DeviceHeader->KsDevice.Descriptor->Dispatch->Start) { /* call driver start device routine */ Status = DeviceHeader->KsDevice.Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp, TranslatedResourceList, UntranslatedResourceList);
DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader->KsDevice.Descriptor->Dispatch->Start, DeviceHeader->KsDevice.Context); ASSERT(Status != STATUS_PENDING);
if (!NT_SUCCESS(Status)) { DPRINT1("Driver: failed to start %x\n", Status); Irp->IoStatus.Status = Status; CompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
/* set state to run */ DeviceHeader->KsDevice.Started = TRUE;
}
/* does the driver need post start routine */ if (DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart) { /* allocate pnp post workitem context */ Ctx = (PPNP_POSTSTART_CONTEXT)AllocateItem(NonPagedPool, sizeof(PNP_POSTSTART_CONTEXT)); if (!Ctx) { /* no memory */ Status = STATUS_INSUFFICIENT_RESOURCES; } else { /* allocate a work item */ Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
if (!Ctx->WorkItem) { /* no memory */ FreeItem(Ctx); Ctx = NULL; Status = STATUS_INSUFFICIENT_RESOURCES; } else { /* store device header for post-start pnp processing */ Ctx->DeviceHeader = DeviceHeader; } } } else { /* set state to enabled, IRP_MJ_CREATE request may now succeed */ DeviceHeader->TargetState = KSTARGET_STATE_ENABLED; Status = KspSetFilterFactoriesState(DeviceHeader, TRUE); } } else { /* set state to run */ DeviceHeader->KsDevice.Started = TRUE; } }
/* store result */ Irp->IoStatus.Status = Status; /* complete request */ CompleteRequest(Irp, IO_NO_INCREMENT);
if (Ctx) { /* queue a work item for driver post start routine */ IoQueueWorkItem(Ctx->WorkItem, IKsDevice_PnpPostStart, DelayedWorkQueue, (PVOID)Ctx); }
/* return result */ DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx); return Status;}
NTSTATUSNTAPIIKsDevice_Pnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PKSDEVICE_DISPATCH Dispatch = NULL; NTSTATUS Status;
/* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get device header */ DeviceHeader = DeviceExtension->DeviceHeader;
/* do we have a device descriptor */ if (DeviceHeader->KsDevice.Descriptor && DeviceHeader->KsDevice.Descriptor->Dispatch) { /* does the device want pnp notifications */ Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->KsDevice.Descriptor->Dispatch; }
switch (IoStack->MinorFunction) { case IRP_MN_START_DEVICE: { return IKsDevice_PnpStartDevice(DeviceObject, Irp); }
case IRP_MN_QUERY_STOP_DEVICE: { Status = STATUS_SUCCESS; /* check for pnp notification support */ if (Dispatch) { /* check for query stop support */ if (Dispatch->QueryStop) { /* call driver's query stop */ Status = Dispatch->QueryStop(&DeviceHeader->KsDevice, Irp); ASSERT(Status != STATUS_PENDING); } }
if (!NT_SUCCESS(Status)) { DPRINT1("Driver: query stop failed %x\n", Status); Irp->IoStatus.Status = Status; CompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
/* pass the irp down the driver stack */ IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); }
case IRP_MN_REMOVE_DEVICE: { /* Clean up */ if (Dispatch) { /* check for remove support */ if (Dispatch->Remove) { /* call driver's stop routine */ Dispatch->Remove(&DeviceHeader->KsDevice, Irp); } }
/* pass the irp down the driver stack */ IoSkipCurrentIrpStackLocation(Irp); Status = IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); /* FIXME delete device resources */ return Status; } case IRP_MN_QUERY_INTERFACE: { Status = STATUS_UNSUCCESSFUL; /* check for pnp notification support */ if (Dispatch) { /* check for query interface support */ if (Dispatch->QueryInterface) { /* call driver's query interface */ Status = Dispatch->QueryInterface(&DeviceHeader->KsDevice, Irp); ASSERT(Status != STATUS_PENDING); } }
if (NT_SUCCESS(Status)) { /* driver supports a private interface */ DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n"); Irp->IoStatus.Status = Status; CompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
/* pass the irp down the driver stack */ IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); } case IRP_MN_QUERY_DEVICE_RELATIONS: { /* pass the irp down the driver stack */ IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); } case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: { /* pass the irp down the driver stack */ //Status = KspForwardIrpSynchronous(DeviceObject, Irp); Status = Irp->IoStatus.Status; DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
//Irp->IoStatus.Status = Status; CompleteRequest(Irp, IO_NO_INCREMENT); return Status; } case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: { /* pass the irp down the driver stack */ IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); } default: DPRINT1("unhandled function %u\n", IoStack->MinorFunction); /* pass the irp down the driver stack */ IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); }}
NTSTATUSNTAPIIKsDevice_Power( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ UNIMPLEMENTED;
/* TODO */
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; CompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;}
NTSTATUSNTAPIIKsDevice_Create( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PCREATE_ITEM_ENTRY CreateItemEntry; PIO_STACK_LOCATION IoStack; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_HEADER ObjectHeader; NTSTATUS Status;
DPRINT("IKsDevice_Create\n"); /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; /* get device header */ DeviceHeader = DeviceExtension->DeviceHeader;
if (IoStack->FileObject->FileName.Buffer == NULL) { // ReactOS PnPMgr still sucks ASSERT(IoStack->FileObject->FileName.Length == 0); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); DPRINT1("ReactOS PnP hack\n"); return STATUS_SUCCESS; }
/* acquire list lock */ IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
/* sanity check */ ASSERT(IoStack->FileObject);
/* check if the request is relative */ if (IoStack->FileObject->RelatedFileObject != NULL) { /* request is to instantiate a pin / node / clock / allocator */ ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2;
/* sanity check */ ASSERT(ObjectHeader);
/* find a matching a create item */ Status = FindMatchingCreateItem(&ObjectHeader->ItemList, &IoStack->FileObject->FileName, &CreateItemEntry); } else { /* request to create a filter */ Status = FindMatchingCreateItem(&DeviceHeader->ItemList, &IoStack->FileObject->FileName, &CreateItemEntry); }
if (NT_SUCCESS(Status)) { /* set object create item */ KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
/* call create function */ Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
if (NT_SUCCESS(Status)) { /* increment create item reference count */ InterlockedIncrement(&CreateItemEntry->ReferenceCount); } }
/* release list lock */ IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
/* done */ return Status;
}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsInitializeDevice( IN PDEVICE_OBJECT FunctionalDeviceObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PDEVICE_OBJECT NextDeviceObject, IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL){ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER Header; ULONG Index; PKSIOBJECT_BAG Bag; NTSTATUS Status = STATUS_SUCCESS;
DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor);
/* get device extension */ DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
/* first allocate device header */ Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 0, NULL);
/* point to allocated header */ Header = DeviceExtension->DeviceHeader;
DPRINT1("DeviceHeader %p\n", DeviceExtension->DeviceHeader);
if (Descriptor && Descriptor->Dispatch) { DPRINT("Descriptor Add %p\n", Descriptor->Dispatch->Add); DPRINT("Descriptor Start %p\n", Descriptor->Dispatch->Start); DPRINT("Descriptor PostStart %p\n", Descriptor->Dispatch->PostStart); DPRINT("Descriptor QueryStop %p\n", Descriptor->Dispatch->QueryStop); DPRINT("Descriptor CancelStop %p\n", Descriptor->Dispatch->CancelStop); DPRINT("Descriptor Stop %p\n", Descriptor->Dispatch->Stop); DPRINT("Descriptor QueryRemove %p\n", Descriptor->Dispatch->QueryRemove); DPRINT("Descriptor CancelRemove %p\n", Descriptor->Dispatch->CancelRemove); DPRINT("Descriptor Remove %p\n", Descriptor->Dispatch->Remove); DPRINT("Descriptor QueryCapabilities %p\n", Descriptor->Dispatch->QueryCapabilities); DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor->Dispatch->SurpriseRemoval); DPRINT("Descriptor QueryPower %p\n", Descriptor->Dispatch->QueryPower); DPRINT("Descriptor SetPower %p\n", Descriptor->Dispatch->SetPower); DPRINT("Descriptor QueryInterface %p\n", Descriptor->Dispatch->QueryInterface); }
/* check for success */ if (!NT_SUCCESS(Status)) { DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status); return Status; }
/* initialize IKsDevice interface */ Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice; Header->ref = 1;
/* allocate object bag */ Header->KsDevice.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); if (!Header->KsDevice.Bag) { /* no memory */ KsFreeDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader); return STATUS_INSUFFICIENT_RESOURCES; }
/* initialize object bag */ KeInitializeMutex(&Header->BagMutex, 0); KeInitializeMutex(&Header->DeviceMutex, 0);
Bag = (PKSIOBJECT_BAG)Header->KsDevice.Bag; Bag->BagMutex = &Header->BagMutex; InitializeListHead(&Header->ObjectBags); InitializeListHead(&Bag->ObjectList); Bag->DeviceHeader = (PVOID)Header;
/* insert bag into device list */ InsertTailList(&Header->ObjectBags, &Bag->Entry);
/* initialize device header */ Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject; Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject; Header->KsDevice.NextDeviceObject = NextDeviceObject; Header->KsDevice.Descriptor = Descriptor; Header->KsDevice.SystemPowerState = PowerSystemWorking; Header->KsDevice.DevicePowerState = PowerDeviceD0; Header->KsDevice.Started = FALSE; Header->KsDevice.Context = NULL; KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject);
if (Descriptor) { /* create a filter factory for each filter descriptor */ DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor->FilterDescriptorsCount); for(Index = 0; Index < Descriptor->FilterDescriptorsCount; Index++) { Status = KspCreateFilterFactory(FunctionalDeviceObject, Descriptor->FilterDescriptors[Index], NULL, NULL, 0, NULL, NULL, NULL);
DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index, Status); /* check for success */ if (!NT_SUCCESS(Status)) { DPRINT1("KspCreateFilterFactory failed with %x\n", Status); /* FIXME memory leak */ return Status; } }
/* does the driver care about the add device */ if (Descriptor->Dispatch && Descriptor->Dispatch->Add) { Status = Descriptor->Dispatch->Add(&Header->KsDevice); DPRINT("Driver: AddHandler Status %x\n", Status); }
Header->KsDevice.Descriptor = Descriptor; }
return Status;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsReferenceSoftwareBusObject( IN KSDEVICE_HEADER Header){ IKsDevice * Device; PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* get device interface */ Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device) { /* reference device interface */ Device->lpVtbl->AddRef(Device); }
return STATUS_SUCCESS;}
/* @implemented*/KSDDKAPINTSTATUSNTAPIKsReferenceBusObject( IN KSDEVICE_HEADER Header){ IKsDevice * Device; PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* get device interface */ Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device) { /* reference device interface */ Device->lpVtbl->AddRef(Device); }
return STATUS_SUCCESS;
}
/* @implemented*/KSDDKAPIVOIDNTAPIKsDereferenceBusObject( IN KSDEVICE_HEADER Header){ IKsDevice * Device; PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
/* get device interface */ Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device) { /* release device interface */ Device->lpVtbl->Release(Device); }}
/* @implemented*/KSDDKAPIVOIDNTAPIKsDereferenceSoftwareBusObject( IN KSDEVICE_HEADER Header){ IKsDevice * Device; PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
/* get device interface */ Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
if (Device) { /* release device interface */ Device->lpVtbl->Release(Device); }}