2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/filterfactory.c
5 * PURPOSE: KS IKsFilterFactory interface functions
6 * PROGRAMMER: Johannes Anderwald
14 KSBASIC_HEADER Header
;
15 KSFILTERFACTORY FilterFactory
;
17 IKsFilterFactoryVtbl
*lpVtbl
;
19 PKSIDEVICE_HEADER DeviceHeader
;
20 PFNKSFILTERFACTORYPOWER SleepCallback
;
21 PFNKSFILTERFACTORYPOWER WakeCallback
;
23 LIST_ENTRY SymbolicLinkList
;
24 }IKsFilterFactoryImpl
;
28 IKsFilterFactory_ItemFreeCb(
29 IN PKSOBJECT_CREATE_ITEM CreateItem
)
31 /* callback when create item is freed in the device header */
32 IKsFilterFactory
* iface
= (IKsFilterFactory
*)CONTAINING_RECORD(CreateItem
->Context
, IKsFilterFactoryImpl
, FilterFactory
);
34 iface
->lpVtbl
->Release(iface
);
39 IKsFilterFactory_Create(
40 IN PDEVICE_OBJECT DeviceObject
,
43 PKSOBJECT_CREATE_ITEM CreateItem
;
44 IKsFilterFactoryImpl
* Factory
;
45 IKsFilterFactory
* iface
;
48 /* access the create item */
49 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
52 DPRINT1("IKsFilterFactory_Create no CreateItem\n");
53 return STATUS_UNSUCCESSFUL
;
56 /* get filter factory interface */
57 Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(CreateItem
->Context
, IKsFilterFactoryImpl
, FilterFactory
);
60 iface
= (IKsFilterFactory
*)&Factory
->lpVtbl
;
62 /* create a filter instance */
63 Status
= KspCreateFilter(DeviceObject
, Irp
, iface
);
65 DPRINT("KspCreateFilter Status %x\n", Status
);
67 if (Status
!= STATUS_PENDING
)
69 Irp
->IoStatus
.Information
= 0;
70 Irp
->IoStatus
.Status
= Status
;
71 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
80 IKsFilterFactory_fnQueryInterface(
81 IKsFilterFactory
* iface
,
85 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
87 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
89 *Output
= &This
->lpVtbl
;
90 _InterlockedIncrement(&This
->ref
);
91 return STATUS_SUCCESS
;
93 return STATUS_UNSUCCESSFUL
;
98 IKsFilterFactory_fnAddRef(
99 IKsFilterFactory
* iface
)
101 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
103 return InterlockedIncrement(&This
->ref
);
108 IKsFilterFactory_fnRelease(
109 IKsFilterFactory
* iface
)
111 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
113 InterlockedDecrement(&This
->ref
);
117 if (!IsListEmpty(&This
->SymbolicLinkList
))
119 /* disable device interfaces */
120 KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, FALSE
);
121 /* free device interface strings */
122 KspFreeDeviceInterfaces(&This
->SymbolicLinkList
);
128 /* Return new reference count */
134 IKsFilterFactory_fnGetStruct(
135 IKsFilterFactory
* iface
)
137 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
139 return &This
->FilterFactory
;
144 IKsFilterFactory_fnSetDeviceClassesState(
145 IKsFilterFactory
* iface
,
148 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
150 return KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, Enable
);
154 IKsFilterFactory_AttachFilterFactoryToDeviceHeader(
155 IKsFilterFactoryImpl
* This
,
156 PKSIDEVICE_HEADER DeviceHeader
)
158 PKSBASIC_HEADER BasicHeader
;
159 PKSFILTERFACTORY FilterFactory
;
161 if (DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
== NULL
)
163 /* first attached filter factory */
164 DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
= &This
->FilterFactory
;
168 /* set to first entry */
169 FilterFactory
= DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
;
173 /* get basic header */
174 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
176 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
178 if (BasicHeader
->Next
.FilterFactory
)
180 /* iterate to next filter factory */
181 FilterFactory
= BasicHeader
->Next
.FilterFactory
;
185 /* found last entry */
188 }while(FilterFactory
);
190 /* attach filter factory */
191 BasicHeader
->Next
.FilterFactory
= &This
->FilterFactory
;
196 IKsFilterFactory_fnInitialize(
197 IKsFilterFactory
* iface
,
198 IN PDEVICE_OBJECT DeviceObject
,
199 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
200 IN PWSTR RefString OPTIONAL
,
201 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
202 IN ULONG CreateItemFlags
,
203 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
204 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
205 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
207 UNICODE_STRING ReferenceString
;
209 PDEVICE_EXTENSION DeviceExtension
;
210 KSOBJECT_CREATE_ITEM CreateItem
;
211 BOOL FreeString
= FALSE
;
212 IKsDevice
* KsDevice
;
214 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
216 /* get device extension */
217 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
219 /* initialize filterfactory */
220 This
->SleepCallback
= SleepCallback
;
221 This
->WakeCallback
= WakeCallback
;
222 This
->FilterFactory
.FilterDescriptor
= Descriptor
;
223 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
224 This
->Header
.Type
= KsObjectTypeFilterFactory
;
225 This
->Header
.Parent
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
226 This
->DeviceHeader
= DeviceExtension
->DeviceHeader
;
229 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
230 InitializeListHead(&This
->Header
.EventList
);
231 KeInitializeSpinLock(&This
->Header
.EventListLock
);
234 InitializeListHead(&This
->SymbolicLinkList
);
236 /* initialize filter factory control mutex */
237 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
239 /* does the device use a reference string */
240 if (RefString
|| !Descriptor
->ReferenceGuid
)
242 /* use device reference string */
243 RtlInitUnicodeString(&ReferenceString
, RefString
);
247 /* create reference string from descriptor guid */
248 Status
= RtlStringFromGUID(Descriptor
->ReferenceGuid
, &ReferenceString
);
250 /* check for success */
251 if (!NT_SUCCESS(Status
))
260 DPRINT("IKsFilterFactory_fnInitialize CategoriesCount %u ReferenceString '%S'\n", Descriptor
->CategoriesCount
,ReferenceString
.Buffer
);
262 /* now register the device interface */
263 Status
= KspRegisterDeviceInterfaces(DeviceExtension
->DeviceHeader
->KsDevice
.PhysicalDeviceObject
,
264 Descriptor
->CategoriesCount
,
265 Descriptor
->Categories
,
267 &This
->SymbolicLinkList
);
268 /* check for success */
269 if (!NT_SUCCESS(Status
))
271 DPRINT1("KspRegisterDeviceInterfaces failed with %x\n", Status
);
275 /* free unicode string */
276 RtlFreeUnicodeString(&ReferenceString
);
282 /* now setup the create item */
283 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
284 CreateItem
.Flags
= CreateItemFlags
;
285 CreateItem
.Create
= IKsFilterFactory_Create
;
286 CreateItem
.Context
= (PVOID
)&This
->FilterFactory
;
287 RtlInitUnicodeString(&CreateItem
.ObjectClass
, ReferenceString
.Buffer
);
289 /* insert create item to device header */
290 Status
= KsAllocateObjectCreateItem((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
294 /* free unicode string */
295 RtlFreeUnicodeString(&ReferenceString
);
300 /* return filterfactory */
301 *FilterFactory
= &This
->FilterFactory
;
303 /* create a object bag for the filter factory */
304 This
->FilterFactory
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
305 if (This
->FilterFactory
.Bag
)
307 /* initialize object bag */
308 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
309 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->FilterFactory
.Bag
, NULL
);
313 /* attach filterfactory to device header */
314 IKsFilterFactory_AttachFilterFactoryToDeviceHeader(This
, DeviceExtension
->DeviceHeader
);
320 static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl
=
322 IKsFilterFactory_fnQueryInterface
,
323 IKsFilterFactory_fnAddRef
,
324 IKsFilterFactory_fnRelease
,
325 IKsFilterFactory_fnGetStruct
,
326 IKsFilterFactory_fnSetDeviceClassesState
,
327 IKsFilterFactory_fnInitialize
333 KspCreateFilterFactory(
334 IN PDEVICE_OBJECT DeviceObject
,
335 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
336 IN PWSTR RefString OPTIONAL
,
337 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
338 IN ULONG CreateItemFlags
,
339 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
340 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
341 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
343 IKsFilterFactoryImpl
* This
;
344 IKsFilterFactory
* Filter
;
347 DPRINT("KsCreateFilterFactory\n");
349 /* Lets allocate a filterfactory */
350 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterFactoryImpl
));
353 /* not enough memory */
354 return STATUS_INSUFFICIENT_RESOURCES
;
357 /* initialize struct */
359 This
->lpVtbl
= &vt_IKsFilterFactoryVtbl
;
361 /* map to com object */
362 Filter
= (IKsFilterFactory
*)&This
->lpVtbl
;
364 /* initialize filter */
365 Status
= Filter
->lpVtbl
->Initialize(Filter
, DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
367 if (!NT_SUCCESS(Status
))
369 /* destroy filterfactory */
370 Filter
->lpVtbl
->Release(Filter
);
374 DPRINT("KsCreateFilterFactory %x\n", Status
);
376 ASSERT(Status
== STATUS_SUCCESS
);
387 KsCreateFilterFactory(
388 IN PDEVICE_OBJECT DeviceObject
,
389 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
390 IN PWSTR RefString OPTIONAL
,
391 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
392 IN ULONG CreateItemFlags
,
393 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
394 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
395 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
397 return KspCreateFilterFactory(DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
407 KsFilterFactorySetDeviceClassesState(
408 IN PKSFILTERFACTORY FilterFactory
,
411 IKsFilterFactory
* Factory
;
412 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
414 Factory
= (IKsFilterFactory
*)&This
->lpVtbl
;
415 return Factory
->lpVtbl
->SetDeviceClassesState(Factory
, NewState
);
425 KsFilterFactoryGetSymbolicLink(
426 IN PKSFILTERFACTORY FilterFactory
)
428 PSYMBOLIC_LINK_ENTRY LinkEntry
;
429 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
431 if (IsListEmpty(&Factory
->SymbolicLinkList
))
433 /* device has not registered any interfaces */
437 /* get first entry */
438 LinkEntry
= (PSYMBOLIC_LINK_ENTRY
)CONTAINING_RECORD(Factory
->SymbolicLinkList
.Flink
, SYMBOLIC_LINK_ENTRY
, Entry
);
440 /* return first link */
441 return &LinkEntry
->SymbolicLink
;
450 KsFilterFactoryAddCreateItem(
451 IN PKSFILTERFACTORY FilterFactory
,
453 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
454 IN ULONG CreateItemFlags
)
456 KSOBJECT_CREATE_ITEM CreateItem
;
458 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
460 /* initialize create item */
461 CreateItem
.Context
= (PVOID
)&Factory
->FilterFactory
;
462 CreateItem
.Create
= IKsFilterFactory_Create
;
463 CreateItem
.Flags
= CreateItemFlags
;
464 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
465 RtlInitUnicodeString(&CreateItem
.ObjectClass
, RefString
);
467 /* insert create item to device header */
468 return KsAllocateObjectCreateItem((KSDEVICE_HEADER
)Factory
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
477 KsFilterFactoryUpdateCacheData (
478 IN PKSFILTERFACTORY FilterFactory
,
479 IN
const KSFILTER_DESCRIPTOR
* FilterDescriptor OPTIONAL
)
482 DPRINT("KsFilterFactoryUpdateCacheData %p\n", FilterDescriptor
);
484 return STATUS_SUCCESS
;