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
;
177 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
179 /* get device extension */
180 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
182 /* initialize filterfactory */
183 This
->SleepCallback
= SleepCallback
;
184 This
->WakeCallback
= WakeCallback
;
185 This
->FilterFactory
.FilterDescriptor
= Descriptor
;
186 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
187 This
->Header
.Type
= KsObjectTypeFilterFactory
;
188 This
->DeviceHeader
= DeviceExtension
->DeviceHeader
;
190 InitializeListHead(&This
->SymbolicLinkList
);
191 InitializeListHead(&This
->FilterInstanceList
);
193 /* does the device use a reference string */
194 if (RefString
|| !Descriptor
->ReferenceGuid
)
196 /* use device reference string */
197 RtlInitUnicodeString(&ReferenceString
, RefString
);
201 /* create reference string from descriptor guid */
202 Status
= RtlStringFromGUID(Descriptor
->ReferenceGuid
, &ReferenceString
);
204 /* check for success */
205 if (!NT_SUCCESS(Status
))
214 /* now register the device interface */
215 Status
= KspRegisterDeviceInterfaces(DeviceExtension
->DeviceHeader
->KsDevice
.PhysicalDeviceObject
,
216 Descriptor
->CategoriesCount
,
217 Descriptor
->Categories
,
219 &This
->SymbolicLinkList
);
220 /* check for success */
221 if (!NT_SUCCESS(Status
))
223 DPRINT1("KspRegisterDeviceInterfaces failed with %x\n", Status
);
227 /* free unicode string */
228 RtlFreeUnicodeString(&ReferenceString
);
234 /* now setup the create item */
235 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
236 CreateItem
.Flags
= CreateItemFlags
;
237 CreateItem
.Create
= IKsFilterFactory_Create
;
238 CreateItem
.Context
= (PVOID
)&This
->FilterFactory
;
239 RtlInitUnicodeString(&CreateItem
.ObjectClass
, ReferenceString
.Buffer
);
241 /* insert create item to device header */
242 Status
= KsAllocateObjectCreateItem((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
246 /* free unicode string */
247 RtlFreeUnicodeString(&ReferenceString
);
252 /* return filterfactory */
253 *FilterFactory
= &This
->FilterFactory
;
255 /*FIXME create object bag */
265 IKsFilterFactory_fnAddFilterInstance(
266 IKsFilterFactory
* iface
,
267 IN IKsFilter
*FilterInstance
)
269 PFILTER_INSTANCE_ENTRY Entry
;
270 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
272 /* allocate filter instance entry */
273 Entry
= AllocateItem(NonPagedPool
, sizeof(FILTER_INSTANCE_ENTRY
));
275 return STATUS_INSUFFICIENT_RESOURCES
;
277 /* initialize filter instance entry */
278 Entry
->FilterInstance
= FilterInstance
;
281 InsertTailList(&This
->FilterInstanceList
, &Entry
->Entry
);
282 return STATUS_SUCCESS
;
287 IKsFilterFactory_fnRemoveFilterInstance(
288 IKsFilterFactory
* iface
,
289 IN IKsFilter
*FilterInstance
)
291 PFILTER_INSTANCE_ENTRY InstanceEntry
;
293 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
295 /* point to first entry */
296 Entry
= This
->FilterInstanceList
.Flink
;
298 while(Entry
!= &This
->FilterInstanceList
)
300 InstanceEntry
= (PFILTER_INSTANCE_ENTRY
)CONTAINING_RECORD(Entry
, FILTER_INSTANCE_ENTRY
, Entry
);
301 if (InstanceEntry
->FilterInstance
== FilterInstance
)
304 RemoveEntryList(&InstanceEntry
->Entry
);
305 FreeItem(InstanceEntry
);
306 return STATUS_SUCCESS
;
310 /* entry not in list! */
311 return STATUS_NOT_FOUND
;
314 static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl
=
316 IKsFilterFactory_fnQueryInterface
,
317 IKsFilterFactory_fnAddRef
,
318 IKsFilterFactory_fnRelease
,
319 IKsFilterFactory_fnGetStruct
,
320 IKsFilterFactory_fnSetDeviceClassesState
,
321 IKsFilterFactory_fnInitialize
,
322 IKsFilterFactory_fnAddFilterInstance
,
323 IKsFilterFactory_fnRemoveFilterInstance
329 KspCreateFilterFactory(
330 IN PDEVICE_OBJECT DeviceObject
,
331 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
332 IN PWSTR RefString OPTIONAL
,
333 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
334 IN ULONG CreateItemFlags
,
335 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
336 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
337 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
339 IKsFilterFactoryImpl
* This
;
340 IKsFilterFactory
* Filter
;
343 /* Lets allocate a filterfactory */
344 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterFactoryImpl
));
347 /* not enough memory */
348 return STATUS_INSUFFICIENT_RESOURCES
;
351 /* initialize struct */
353 This
->lpVtbl
= &vt_IKsFilterFactoryVtbl
;
355 /* map to com object */
356 Filter
= (IKsFilterFactory
*)&This
->lpVtbl
;
358 /* initialize filter */
359 Status
= Filter
->lpVtbl
->Initialize(Filter
, DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
361 if (!NT_SUCCESS(Status
))
363 /* destroy filterfactory */
364 Filter
->lpVtbl
->Release(Filter
);
377 KsCreateFilterFactory(
378 IN PDEVICE_OBJECT DeviceObject
,
379 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
380 IN PWSTR RefString OPTIONAL
,
381 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
382 IN ULONG CreateItemFlags
,
383 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
384 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
385 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
387 return KspCreateFilterFactory(DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
397 KsFilterFactorySetDeviceClassesState(
398 IN PKSFILTERFACTORY FilterFactory
,
401 IKsFilterFactory
* Factory
= (IKsFilterFactory
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
403 return Factory
->lpVtbl
->SetDeviceClassesState(Factory
, NewState
);
413 KsFilterFactoryGetSymbolicLink(
414 IN PKSFILTERFACTORY FilterFactory
)
416 PSYMBOLIC_LINK_ENTRY LinkEntry
;
417 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
419 if (IsListEmpty(&Factory
->SymbolicLinkList
))
421 /* device has not registered any interfaces */
425 /* get first entry */
426 LinkEntry
= (PSYMBOLIC_LINK_ENTRY
)CONTAINING_RECORD(Factory
->SymbolicLinkList
.Flink
, SYMBOLIC_LINK_ENTRY
, Entry
);
428 /* return first link */
429 return &LinkEntry
->SymbolicLink
;
438 KsFilterFactoryAddCreateItem(
439 IN PKSFILTERFACTORY FilterFactory
,
441 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
442 IN ULONG CreateItemFlags
)
444 KSOBJECT_CREATE_ITEM CreateItem
;
446 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
448 /* initialize create item */
449 CreateItem
.Context
= (PVOID
)&Factory
->FilterFactory
;
450 CreateItem
.Create
= IKsFilterFactory_Create
;
451 CreateItem
.Flags
= CreateItemFlags
;
452 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
453 RtlInitUnicodeString(&CreateItem
.ObjectClass
, RefString
);
455 /* insert create item to device header */
456 return KsAllocateObjectCreateItem((KSDEVICE_HEADER
)Factory
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
465 KsFilterFactoryUpdateCacheData (
466 IN PKSFILTERFACTORY FilterFactory
,
467 IN
const KSFILTER_DESCRIPTOR
* FilterDescriptor OPTIONAL
)
471 return STATUS_NOT_IMPLEMENTED
;