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 LIST_ENTRY FilterInstanceList
;
25 }IKsFilterFactoryImpl
;
30 IKsFilter
*FilterInstance
;
31 }FILTER_INSTANCE_ENTRY
, *PFILTER_INSTANCE_ENTRY
;
37 IKsFilterFactory_ItemFreeCb(
38 IN PKSOBJECT_CREATE_ITEM CreateItem
)
40 /* callback when create item is freed in the device header */
41 IKsFilterFactory
* iface
= (IKsFilterFactory
*)CONTAINING_RECORD(CreateItem
->Context
, IKsFilterFactoryImpl
, FilterFactory
);
43 iface
->lpVtbl
->Release(iface
);
48 IKsFilterFactory_Create(
49 IN PDEVICE_OBJECT DeviceObject
,
52 PKSOBJECT_CREATE_ITEM CreateItem
;
53 IKsFilterFactory
* iface
;
56 /* access the create item */
57 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
60 DPRINT1("IKsFilterFactory_Create no CreateItem\n");
61 return STATUS_UNSUCCESSFUL
;
64 /* get filter factory interface */
65 iface
= (IKsFilterFactory
*)CONTAINING_RECORD(CreateItem
->Context
, IKsFilterFactoryImpl
, FilterFactory
);
67 /* create a filter instance */
68 Status
= KspCreateFilter(DeviceObject
, Irp
, iface
);
70 DPRINT("KspCreateFilter Status %x\n", Status
);
72 if (Status
!= STATUS_PENDING
)
74 Irp
->IoStatus
.Information
= 0;
75 Irp
->IoStatus
.Status
= Status
;
76 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
85 IKsFilterFactory_fnQueryInterface(
86 IKsFilterFactory
* iface
,
90 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
92 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
94 *Output
= &This
->lpVtbl
;
95 _InterlockedIncrement(&This
->ref
);
96 return STATUS_SUCCESS
;
98 return STATUS_UNSUCCESSFUL
;
103 IKsFilterFactory_fnAddRef(
104 IKsFilterFactory
* iface
)
106 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
108 return InterlockedIncrement(&This
->ref
);
113 IKsFilterFactory_fnRelease(
114 IKsFilterFactory
* iface
)
116 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
118 InterlockedDecrement(&This
->ref
);
122 if (!IsListEmpty(&This
->SymbolicLinkList
))
124 /* disable device interfaces */
125 KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, FALSE
);
126 /* free device interface strings */
127 KspFreeDeviceInterfaces(&This
->SymbolicLinkList
);
133 /* Return new reference count */
139 IKsFilterFactory_fnGetStruct(
140 IKsFilterFactory
* iface
)
142 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
144 return &This
->FilterFactory
;
149 IKsFilterFactory_fnSetDeviceClassesState(
150 IKsFilterFactory
* iface
,
153 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
155 return KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, Enable
);
160 IKsFilterFactory_fnInitialize(
161 IKsFilterFactory
* iface
,
162 IN PDEVICE_OBJECT DeviceObject
,
163 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
164 IN PWSTR RefString OPTIONAL
,
165 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
166 IN ULONG CreateItemFlags
,
167 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
168 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
169 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
171 UNICODE_STRING ReferenceString
;
173 PDEVICE_EXTENSION DeviceExtension
;
174 KSOBJECT_CREATE_ITEM CreateItem
;
175 BOOL FreeString
= FALSE
;
176 IKsDevice
* KsDevice
;
178 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
180 /* get device extension */
181 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
183 /* initialize filterfactory */
184 This
->SleepCallback
= SleepCallback
;
185 This
->WakeCallback
= WakeCallback
;
186 This
->FilterFactory
.FilterDescriptor
= Descriptor
;
187 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
188 This
->Header
.Type
= KsObjectTypeFilterFactory
;
189 This
->Header
.Parent
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
190 This
->DeviceHeader
= DeviceExtension
->DeviceHeader
;
193 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
194 InitializeListHead(&This
->Header
.EventList
);
195 KeInitializeSpinLock(&This
->Header
.EventListLock
);
198 InitializeListHead(&This
->SymbolicLinkList
);
199 InitializeListHead(&This
->FilterInstanceList
);
201 /* initialize filter factory control mutex */
202 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
204 /* does the device use a reference string */
205 if (RefString
|| !Descriptor
->ReferenceGuid
)
207 /* use device reference string */
208 RtlInitUnicodeString(&ReferenceString
, RefString
);
212 /* create reference string from descriptor guid */
213 Status
= RtlStringFromGUID(Descriptor
->ReferenceGuid
, &ReferenceString
);
215 /* check for success */
216 if (!NT_SUCCESS(Status
))
225 /* now register the device interface */
226 Status
= KspRegisterDeviceInterfaces(DeviceExtension
->DeviceHeader
->KsDevice
.PhysicalDeviceObject
,
227 Descriptor
->CategoriesCount
,
228 Descriptor
->Categories
,
230 &This
->SymbolicLinkList
);
231 /* check for success */
232 if (!NT_SUCCESS(Status
))
234 DPRINT1("KspRegisterDeviceInterfaces failed with %x\n", Status
);
238 /* free unicode string */
239 RtlFreeUnicodeString(&ReferenceString
);
245 /* now setup the create item */
246 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
247 CreateItem
.Flags
= CreateItemFlags
;
248 CreateItem
.Create
= IKsFilterFactory_Create
;
249 CreateItem
.Context
= (PVOID
)&This
->FilterFactory
;
250 RtlInitUnicodeString(&CreateItem
.ObjectClass
, ReferenceString
.Buffer
);
252 /* insert create item to device header */
253 Status
= KsAllocateObjectCreateItem((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
257 /* free unicode string */
258 RtlFreeUnicodeString(&ReferenceString
);
263 /* return filterfactory */
264 *FilterFactory
= &This
->FilterFactory
;
266 /* create a object bag for the filter factory */
267 This
->FilterFactory
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
268 if (This
->FilterFactory
.Bag
)
270 /* initialize object bag */
271 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
272 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->FilterFactory
.Bag
, NULL
);
283 IKsFilterFactory_fnAddFilterInstance(
284 IKsFilterFactory
* iface
,
285 IN IKsFilter
*FilterInstance
)
287 PFILTER_INSTANCE_ENTRY Entry
;
288 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
290 /* allocate filter instance entry */
291 Entry
= AllocateItem(NonPagedPool
, sizeof(FILTER_INSTANCE_ENTRY
));
293 return STATUS_INSUFFICIENT_RESOURCES
;
295 /* initialize filter instance entry */
296 Entry
->FilterInstance
= FilterInstance
;
299 InsertTailList(&This
->FilterInstanceList
, &Entry
->Entry
);
300 return STATUS_SUCCESS
;
305 IKsFilterFactory_fnRemoveFilterInstance(
306 IKsFilterFactory
* iface
,
307 IN IKsFilter
*FilterInstance
)
309 PFILTER_INSTANCE_ENTRY InstanceEntry
;
311 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
313 /* point to first entry */
314 Entry
= This
->FilterInstanceList
.Flink
;
316 while(Entry
!= &This
->FilterInstanceList
)
318 InstanceEntry
= (PFILTER_INSTANCE_ENTRY
)CONTAINING_RECORD(Entry
, FILTER_INSTANCE_ENTRY
, Entry
);
319 if (InstanceEntry
->FilterInstance
== FilterInstance
)
322 RemoveEntryList(&InstanceEntry
->Entry
);
323 FreeItem(InstanceEntry
);
324 return STATUS_SUCCESS
;
328 /* entry not in list! */
329 return STATUS_NOT_FOUND
;
332 static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl
=
334 IKsFilterFactory_fnQueryInterface
,
335 IKsFilterFactory_fnAddRef
,
336 IKsFilterFactory_fnRelease
,
337 IKsFilterFactory_fnGetStruct
,
338 IKsFilterFactory_fnSetDeviceClassesState
,
339 IKsFilterFactory_fnInitialize
,
340 IKsFilterFactory_fnAddFilterInstance
,
341 IKsFilterFactory_fnRemoveFilterInstance
347 KspCreateFilterFactory(
348 IN PDEVICE_OBJECT DeviceObject
,
349 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
350 IN PWSTR RefString OPTIONAL
,
351 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
352 IN ULONG CreateItemFlags
,
353 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
354 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
355 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
357 IKsFilterFactoryImpl
* This
;
358 IKsFilterFactory
* Filter
;
361 /* Lets allocate a filterfactory */
362 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterFactoryImpl
));
365 /* not enough memory */
366 return STATUS_INSUFFICIENT_RESOURCES
;
369 /* initialize struct */
371 This
->lpVtbl
= &vt_IKsFilterFactoryVtbl
;
373 /* map to com object */
374 Filter
= (IKsFilterFactory
*)&This
->lpVtbl
;
376 /* initialize filter */
377 Status
= Filter
->lpVtbl
->Initialize(Filter
, DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
379 if (!NT_SUCCESS(Status
))
381 /* destroy filterfactory */
382 Filter
->lpVtbl
->Release(Filter
);
395 KsCreateFilterFactory(
396 IN PDEVICE_OBJECT DeviceObject
,
397 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
398 IN PWSTR RefString OPTIONAL
,
399 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
400 IN ULONG CreateItemFlags
,
401 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
402 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
403 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
405 return KspCreateFilterFactory(DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
415 KsFilterFactorySetDeviceClassesState(
416 IN PKSFILTERFACTORY FilterFactory
,
419 IKsFilterFactory
* Factory
= (IKsFilterFactory
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
421 return Factory
->lpVtbl
->SetDeviceClassesState(Factory
, NewState
);
431 KsFilterFactoryGetSymbolicLink(
432 IN PKSFILTERFACTORY FilterFactory
)
434 PSYMBOLIC_LINK_ENTRY LinkEntry
;
435 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
437 if (IsListEmpty(&Factory
->SymbolicLinkList
))
439 /* device has not registered any interfaces */
443 /* get first entry */
444 LinkEntry
= (PSYMBOLIC_LINK_ENTRY
)CONTAINING_RECORD(Factory
->SymbolicLinkList
.Flink
, SYMBOLIC_LINK_ENTRY
, Entry
);
446 /* return first link */
447 return &LinkEntry
->SymbolicLink
;
456 KsFilterFactoryAddCreateItem(
457 IN PKSFILTERFACTORY FilterFactory
,
459 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
460 IN ULONG CreateItemFlags
)
462 KSOBJECT_CREATE_ITEM CreateItem
;
464 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
466 /* initialize create item */
467 CreateItem
.Context
= (PVOID
)&Factory
->FilterFactory
;
468 CreateItem
.Create
= IKsFilterFactory_Create
;
469 CreateItem
.Flags
= CreateItemFlags
;
470 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
471 RtlInitUnicodeString(&CreateItem
.ObjectClass
, RefString
);
473 /* insert create item to device header */
474 return KsAllocateObjectCreateItem((KSDEVICE_HEADER
)Factory
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
483 KsFilterFactoryUpdateCacheData (
484 IN PKSFILTERFACTORY FilterFactory
,
485 IN
const KSFILTER_DESCRIPTOR
* FilterDescriptor OPTIONAL
)
489 return STATUS_NOT_IMPLEMENTED
;