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 /* Lets allocate a filterfactory */
342 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterFactoryImpl
));
345 /* not enough memory */
346 return STATUS_INSUFFICIENT_RESOURCES
;
349 /* initialize struct */
351 This
->lpVtbl
= &vt_IKsFilterFactoryVtbl
;
353 /* map to com object */
354 Filter
= (IKsFilterFactory
*)&This
->lpVtbl
;
356 /* initialize filter */
357 Status
= Filter
->lpVtbl
->Initialize(Filter
, DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
359 if (!NT_SUCCESS(Status
))
361 /* destroy filterfactory */
362 Filter
->lpVtbl
->Release(Filter
);
375 KsCreateFilterFactory(
376 IN PDEVICE_OBJECT DeviceObject
,
377 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
378 IN PWSTR RefString OPTIONAL
,
379 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
380 IN ULONG CreateItemFlags
,
381 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
382 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
383 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
385 return KspCreateFilterFactory(DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
395 KsFilterFactorySetDeviceClassesState(
396 IN PKSFILTERFACTORY FilterFactory
,
399 IKsFilterFactory
* Factory
= (IKsFilterFactory
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
401 return Factory
->lpVtbl
->SetDeviceClassesState(Factory
, NewState
);
411 KsFilterFactoryGetSymbolicLink(
412 IN PKSFILTERFACTORY FilterFactory
)
414 PSYMBOLIC_LINK_ENTRY LinkEntry
;
415 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
417 if (IsListEmpty(&Factory
->SymbolicLinkList
))
419 /* device has not registered any interfaces */
423 /* get first entry */
424 LinkEntry
= (PSYMBOLIC_LINK_ENTRY
)CONTAINING_RECORD(Factory
->SymbolicLinkList
.Flink
, SYMBOLIC_LINK_ENTRY
, Entry
);
426 /* return first link */
427 return &LinkEntry
->SymbolicLink
;
436 KsFilterFactoryAddCreateItem(
437 IN PKSFILTERFACTORY FilterFactory
,
439 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
440 IN ULONG CreateItemFlags
)
442 KSOBJECT_CREATE_ITEM CreateItem
;
444 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
446 /* initialize create item */
447 CreateItem
.Context
= (PVOID
)&Factory
->FilterFactory
;
448 CreateItem
.Create
= IKsFilterFactory_Create
;
449 CreateItem
.Flags
= CreateItemFlags
;
450 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
451 RtlInitUnicodeString(&CreateItem
.ObjectClass
, RefString
);
453 /* insert create item to device header */
454 return KsAllocateObjectCreateItem((KSDEVICE_HEADER
)Factory
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
463 KsFilterFactoryUpdateCacheData (
464 IN PKSFILTERFACTORY FilterFactory
,
465 IN
const KSFILTER_DESCRIPTOR
* FilterDescriptor OPTIONAL
)
469 return STATUS_NOT_IMPLEMENTED
;