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 IKsFilterFactory
* iface
;
47 /* access the create item */
48 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
51 DPRINT1("IKsFilterFactory_Create no CreateItem\n");
52 return STATUS_UNSUCCESSFUL
;
55 /* get filter factory interface */
56 iface
= (IKsFilterFactory
*)CONTAINING_RECORD(CreateItem
->Context
, IKsFilterFactoryImpl
, FilterFactory
);
58 /* create a filter instance */
59 Status
= KspCreateFilter(DeviceObject
, Irp
, iface
);
61 DPRINT("KspCreateFilter Status %x\n", Status
);
63 if (Status
!= STATUS_PENDING
)
65 Irp
->IoStatus
.Information
= 0;
66 Irp
->IoStatus
.Status
= Status
;
67 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
76 IKsFilterFactory_fnQueryInterface(
77 IKsFilterFactory
* iface
,
81 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
83 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
85 *Output
= &This
->lpVtbl
;
86 _InterlockedIncrement(&This
->ref
);
87 return STATUS_SUCCESS
;
89 return STATUS_UNSUCCESSFUL
;
94 IKsFilterFactory_fnAddRef(
95 IKsFilterFactory
* iface
)
97 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
99 return InterlockedIncrement(&This
->ref
);
104 IKsFilterFactory_fnRelease(
105 IKsFilterFactory
* iface
)
107 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
109 InterlockedDecrement(&This
->ref
);
113 if (!IsListEmpty(&This
->SymbolicLinkList
))
115 /* disable device interfaces */
116 KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, FALSE
);
117 /* free device interface strings */
118 KspFreeDeviceInterfaces(&This
->SymbolicLinkList
);
124 /* Return new reference count */
130 IKsFilterFactory_fnGetStruct(
131 IKsFilterFactory
* iface
)
133 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
135 return &This
->FilterFactory
;
140 IKsFilterFactory_fnSetDeviceClassesState(
141 IKsFilterFactory
* iface
,
144 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
146 return KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, Enable
);
150 IKsFilterFactory_AttachFilterFactoryToDeviceHeader(
151 IKsFilterFactoryImpl
* This
,
152 PKSIDEVICE_HEADER DeviceHeader
)
154 PKSBASIC_HEADER BasicHeader
;
155 PKSFILTERFACTORY FilterFactory
;
157 if (DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
== NULL
)
159 /* first attached filter factory */
160 DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
= &This
->FilterFactory
;
164 /* set to first entry */
165 FilterFactory
= DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
;
169 /* get basic header */
170 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
172 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
174 if (BasicHeader
->Next
.FilterFactory
)
176 /* iterate to next filter factory */
177 FilterFactory
= BasicHeader
->Next
.FilterFactory
;
181 /* found last entry */
184 }while(FilterFactory
);
186 /* attach filter factory */
187 BasicHeader
->Next
.FilterFactory
= &This
->FilterFactory
;
192 IKsFilterFactory_fnInitialize(
193 IKsFilterFactory
* iface
,
194 IN PDEVICE_OBJECT DeviceObject
,
195 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
196 IN PWSTR RefString OPTIONAL
,
197 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
198 IN ULONG CreateItemFlags
,
199 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
200 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
201 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
203 UNICODE_STRING ReferenceString
;
205 PDEVICE_EXTENSION DeviceExtension
;
206 KSOBJECT_CREATE_ITEM CreateItem
;
207 BOOL FreeString
= FALSE
;
208 IKsDevice
* KsDevice
;
210 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, lpVtbl
);
212 /* get device extension */
213 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
215 /* initialize filterfactory */
216 This
->SleepCallback
= SleepCallback
;
217 This
->WakeCallback
= WakeCallback
;
218 This
->FilterFactory
.FilterDescriptor
= Descriptor
;
219 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
220 This
->Header
.Type
= KsObjectTypeFilterFactory
;
221 This
->Header
.Parent
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
222 This
->DeviceHeader
= DeviceExtension
->DeviceHeader
;
225 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
226 InitializeListHead(&This
->Header
.EventList
);
227 KeInitializeSpinLock(&This
->Header
.EventListLock
);
230 InitializeListHead(&This
->SymbolicLinkList
);
232 /* initialize filter factory control mutex */
233 KeInitializeMutex(&This
->Header
.ControlMutex
, 0);
235 /* does the device use a reference string */
236 if (RefString
|| !Descriptor
->ReferenceGuid
)
238 /* use device reference string */
239 RtlInitUnicodeString(&ReferenceString
, RefString
);
243 /* create reference string from descriptor guid */
244 Status
= RtlStringFromGUID(Descriptor
->ReferenceGuid
, &ReferenceString
);
246 /* check for success */
247 if (!NT_SUCCESS(Status
))
256 /* now register the device interface */
257 Status
= KspRegisterDeviceInterfaces(DeviceExtension
->DeviceHeader
->KsDevice
.PhysicalDeviceObject
,
258 Descriptor
->CategoriesCount
,
259 Descriptor
->Categories
,
261 &This
->SymbolicLinkList
);
262 /* check for success */
263 if (!NT_SUCCESS(Status
))
265 DPRINT1("KspRegisterDeviceInterfaces failed with %x\n", Status
);
269 /* free unicode string */
270 RtlFreeUnicodeString(&ReferenceString
);
276 /* now setup the create item */
277 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
278 CreateItem
.Flags
= CreateItemFlags
;
279 CreateItem
.Create
= IKsFilterFactory_Create
;
280 CreateItem
.Context
= (PVOID
)&This
->FilterFactory
;
281 RtlInitUnicodeString(&CreateItem
.ObjectClass
, ReferenceString
.Buffer
);
283 /* insert create item to device header */
284 Status
= KsAllocateObjectCreateItem((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
288 /* free unicode string */
289 RtlFreeUnicodeString(&ReferenceString
);
294 /* return filterfactory */
295 *FilterFactory
= &This
->FilterFactory
;
297 /* create a object bag for the filter factory */
298 This
->FilterFactory
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
299 if (This
->FilterFactory
.Bag
)
301 /* initialize object bag */
302 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->lpVtblIKsDevice
;
303 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->FilterFactory
.Bag
, NULL
);
307 /* attach filterfactory to device header */
308 IKsFilterFactory_AttachFilterFactoryToDeviceHeader(This
, DeviceExtension
->DeviceHeader
);
314 static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl
=
316 IKsFilterFactory_fnQueryInterface
,
317 IKsFilterFactory_fnAddRef
,
318 IKsFilterFactory_fnRelease
,
319 IKsFilterFactory_fnGetStruct
,
320 IKsFilterFactory_fnSetDeviceClassesState
,
321 IKsFilterFactory_fnInitialize
327 KspCreateFilterFactory(
328 IN PDEVICE_OBJECT DeviceObject
,
329 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
330 IN PWSTR RefString OPTIONAL
,
331 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
332 IN ULONG CreateItemFlags
,
333 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
334 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
335 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
337 IKsFilterFactoryImpl
* This
;
338 IKsFilterFactory
* Filter
;
341 DPRINT("KsCreateFilterFactory\n");
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
)
470 DPRINT("KsFilterFactoryUpdateCacheData %p\n", FilterDescriptor
);
472 return STATUS_SUCCESS
;