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
16 KSBASIC_HEADER Header
;
17 KSFILTERFACTORY FilterFactory
;
20 PKSIDEVICE_HEADER DeviceHeader
;
21 PFNKSFILTERFACTORYPOWER SleepCallback
;
22 PFNKSFILTERFACTORYPOWER WakeCallback
;
24 LIST_ENTRY SymbolicLinkList
;
27 }IKsFilterFactoryImpl
;
31 IKsFilterFactory_ItemFreeCb(
32 IN PKSOBJECT_CREATE_ITEM CreateItem
)
34 /* callback when create item is freed in the device header */
35 IKsFilterFactory
* iface
= (IKsFilterFactory
*)CONTAINING_RECORD(CreateItem
->Context
, IKsFilterFactoryImpl
, FilterFactory
);
37 iface
->lpVtbl
->Release(iface
);
42 IKsFilterFactory_Create(
43 IN PDEVICE_OBJECT DeviceObject
,
46 PKSOBJECT_CREATE_ITEM CreateItem
;
47 IKsFilterFactoryImpl
* Factory
;
48 IKsFilterFactory
* iface
;
51 /* access the create item */
52 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
55 DPRINT1("IKsFilterFactory_Create no CreateItem\n");
56 return STATUS_UNSUCCESSFUL
;
59 /* get filter factory interface */
60 Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(CreateItem
->Context
, IKsFilterFactoryImpl
, FilterFactory
);
63 iface
= (IKsFilterFactory
*)&Factory
->Header
.OuterUnknown
;
65 /* create a filter instance */
66 Status
= KspCreateFilter(DeviceObject
, Irp
, iface
);
68 DPRINT("KspCreateFilter Status %x\n", Status
);
70 if (Status
!= STATUS_PENDING
)
72 Irp
->IoStatus
.Information
= 0;
73 Irp
->IoStatus
.Status
= Status
;
74 CompleteRequest(Irp
, IO_NO_INCREMENT
);
83 IKsFilterFactory_fnQueryInterface(
84 IKsFilterFactory
* iface
,
90 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, Header
.OuterUnknown
);
92 if (IsEqualGUIDAligned(refiid
, &IID_IUnknown
))
94 *Output
= &This
->Header
.OuterUnknown
;
95 _InterlockedIncrement(&This
->ref
);
96 return STATUS_SUCCESS
;
99 if (This
->Header
.ClientAggregate
)
101 /* using client aggregate */
102 Status
= This
->Header
.ClientAggregate
->lpVtbl
->QueryInterface(This
->Header
.ClientAggregate
, refiid
, Output
);
104 if (NT_SUCCESS(Status
))
106 /* client aggregate supports interface */
111 DPRINT("IKsFilterFactory_fnQueryInterface no interface\n");
112 return STATUS_NOT_SUPPORTED
;
117 IKsFilterFactory_fnAddRef(
118 IKsFilterFactory
* iface
)
120 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, Header
.OuterUnknown
);
122 return InterlockedIncrement(&This
->ref
);
127 IKsFilterFactory_fnRelease(
128 IKsFilterFactory
* iface
)
130 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, Header
.OuterUnknown
);
132 InterlockedDecrement(&This
->ref
);
136 if (!IsListEmpty(&This
->SymbolicLinkList
))
138 /* disable device interfaces */
139 KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, FALSE
);
140 /* free device interface strings */
141 KspFreeDeviceInterfaces(&This
->SymbolicLinkList
);
147 /* Return new reference count */
153 IKsFilterFactory_fnGetStruct(
154 IKsFilterFactory
* iface
)
156 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, Header
.OuterUnknown
);
158 return &This
->FilterFactory
;
163 IKsFilterFactory_fnSetDeviceClassesState(
164 IKsFilterFactory
* iface
,
167 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, Header
.OuterUnknown
);
169 return KspSetDeviceInterfacesState(&This
->SymbolicLinkList
, Enable
);
173 IKsFilterFactory_AttachFilterFactoryToDeviceHeader(
174 IKsFilterFactoryImpl
* This
,
175 PKSIDEVICE_HEADER DeviceHeader
)
177 PKSBASIC_HEADER BasicHeader
;
178 PKSFILTERFACTORY FilterFactory
;
180 if (DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
== NULL
)
182 /* first attached filter factory */
183 DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
= &This
->FilterFactory
;
187 /* set to first entry */
188 FilterFactory
= DeviceHeader
->BasicHeader
.FirstChild
.FilterFactory
;
192 /* get basic header */
193 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)FilterFactory
- sizeof(KSBASIC_HEADER
));
195 ASSERT(BasicHeader
->Type
== KsObjectTypeFilterFactory
);
197 if (BasicHeader
->Next
.FilterFactory
)
199 /* iterate to next filter factory */
200 FilterFactory
= BasicHeader
->Next
.FilterFactory
;
204 /* found last entry */
207 }while(FilterFactory
);
209 /* attach filter factory */
210 BasicHeader
->Next
.FilterFactory
= &This
->FilterFactory
;
215 IKsFilterFactory_fnInitialize(
216 IKsFilterFactory
* iface
,
217 IN PDEVICE_OBJECT DeviceObject
,
218 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
219 IN PWSTR RefString OPTIONAL
,
220 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
221 IN ULONG CreateItemFlags
,
222 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
223 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
224 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
226 UNICODE_STRING ReferenceString
;
228 PDEVICE_EXTENSION DeviceExtension
;
229 KSOBJECT_CREATE_ITEM CreateItem
;
230 BOOL FreeString
= FALSE
;
231 IKsDevice
* KsDevice
;
233 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(iface
, IKsFilterFactoryImpl
, Header
.OuterUnknown
);
235 /* get device extension */
236 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
238 /* initialize filterfactory */
239 This
->SleepCallback
= SleepCallback
;
240 This
->WakeCallback
= WakeCallback
;
241 This
->FilterFactory
.FilterDescriptor
= Descriptor
;
242 This
->Header
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
243 This
->Header
.Type
= KsObjectTypeFilterFactory
;
244 This
->Header
.Parent
.KsDevice
= &DeviceExtension
->DeviceHeader
->KsDevice
;
245 This
->DeviceHeader
= DeviceExtension
->DeviceHeader
;
247 /* initialize filter factory control mutex */
248 This
->Header
.ControlMutex
= &This
->ControlMutex
;
249 KeInitializeMutex(This
->Header
.ControlMutex
, 0);
252 InitializeListHead(&This
->Header
.EventList
);
253 KeInitializeSpinLock(&This
->Header
.EventListLock
);
255 InitializeListHead(&This
->SymbolicLinkList
);
257 /* does the device use a reference string */
258 if (RefString
|| !Descriptor
->ReferenceGuid
)
260 /* use device reference string */
261 RtlInitUnicodeString(&ReferenceString
, RefString
);
265 /* create reference string from descriptor guid */
266 Status
= RtlStringFromGUID(Descriptor
->ReferenceGuid
, &ReferenceString
);
268 /* check for success */
269 if (!NT_SUCCESS(Status
))
278 DPRINT("IKsFilterFactory_fnInitialize CategoriesCount %u ReferenceString '%S'\n", Descriptor
->CategoriesCount
,ReferenceString
.Buffer
);
280 /* now register the device interface */
281 Status
= KspRegisterDeviceInterfaces(DeviceExtension
->DeviceHeader
->KsDevice
.PhysicalDeviceObject
,
282 Descriptor
->CategoriesCount
,
283 Descriptor
->Categories
,
285 &This
->SymbolicLinkList
);
286 /* check for success */
287 if (!NT_SUCCESS(Status
))
289 DPRINT1("KspRegisterDeviceInterfaces failed with %x\n", Status
);
293 /* free unicode string */
294 RtlFreeUnicodeString(&ReferenceString
);
300 /* now setup the create item */
301 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
302 CreateItem
.Flags
= CreateItemFlags
;
303 CreateItem
.Create
= IKsFilterFactory_Create
;
304 CreateItem
.Context
= (PVOID
)&This
->FilterFactory
;
305 RtlInitUnicodeString(&CreateItem
.ObjectClass
, ReferenceString
.Buffer
);
307 /* insert create item to device header */
308 Status
= KsAllocateObjectCreateItem((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
312 /* free unicode string */
313 RtlFreeUnicodeString(&ReferenceString
);
318 /* return filterfactory */
319 *FilterFactory
= &This
->FilterFactory
;
321 /* create a object bag for the filter factory */
322 This
->FilterFactory
.Bag
= AllocateItem(NonPagedPool
, sizeof(KSIOBJECT_BAG
));
323 if (This
->FilterFactory
.Bag
)
325 /* initialize object bag */
326 KsDevice
= (IKsDevice
*)&DeviceExtension
->DeviceHeader
->BasicHeader
.OuterUnknown
;
327 KsDevice
->lpVtbl
->InitializeObjectBag(KsDevice
, (PKSIOBJECT_BAG
)This
->FilterFactory
.Bag
, NULL
);
331 /* attach filterfactory to device header */
332 IKsFilterFactory_AttachFilterFactoryToDeviceHeader(This
, DeviceExtension
->DeviceHeader
);
338 static IKsFilterFactoryVtbl vt_IKsFilterFactoryVtbl
=
340 IKsFilterFactory_fnQueryInterface
,
341 IKsFilterFactory_fnAddRef
,
342 IKsFilterFactory_fnRelease
,
343 IKsFilterFactory_fnGetStruct
,
344 IKsFilterFactory_fnSetDeviceClassesState
,
345 IKsFilterFactory_fnInitialize
351 KspCreateFilterFactory(
352 IN PDEVICE_OBJECT DeviceObject
,
353 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
354 IN PWSTR RefString OPTIONAL
,
355 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
356 IN ULONG CreateItemFlags
,
357 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
358 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
359 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
361 IKsFilterFactoryImpl
* This
;
362 IKsFilterFactory
* Filter
;
365 DPRINT("KsCreateFilterFactory\n");
367 /* Lets allocate a filterfactory */
368 This
= AllocateItem(NonPagedPool
, sizeof(IKsFilterFactoryImpl
));
371 /* not enough memory */
372 return STATUS_INSUFFICIENT_RESOURCES
;
375 /* initialize struct */
377 This
->Header
.OuterUnknown
= (PUNKNOWN
)&vt_IKsFilterFactoryVtbl
;
379 /* map to com object */
380 Filter
= (IKsFilterFactory
*)&This
->Header
.OuterUnknown
;
382 /* initialize filter */
383 Status
= Filter
->lpVtbl
->Initialize(Filter
, DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
385 if (!NT_SUCCESS(Status
))
387 /* destroy filterfactory */
388 Filter
->lpVtbl
->Release(Filter
);
392 DPRINT("KsCreateFilterFactory %x\n", Status
);
394 ASSERT(Status
== STATUS_SUCCESS
);
405 KsCreateFilterFactory(
406 IN PDEVICE_OBJECT DeviceObject
,
407 IN
const KSFILTER_DESCRIPTOR
*Descriptor
,
408 IN PWSTR RefString OPTIONAL
,
409 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
410 IN ULONG CreateItemFlags
,
411 IN PFNKSFILTERFACTORYPOWER SleepCallback OPTIONAL
,
412 IN PFNKSFILTERFACTORYPOWER WakeCallback OPTIONAL
,
413 OUT PKSFILTERFACTORY
*FilterFactory OPTIONAL
)
415 return KspCreateFilterFactory(DeviceObject
, Descriptor
, RefString
, SecurityDescriptor
, CreateItemFlags
, SleepCallback
, WakeCallback
, FilterFactory
);
425 KsFilterFactorySetDeviceClassesState(
426 IN PKSFILTERFACTORY FilterFactory
,
429 IKsFilterFactory
* Factory
;
430 IKsFilterFactoryImpl
* This
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
432 Factory
= (IKsFilterFactory
*)&This
->Header
.OuterUnknown
;
433 return Factory
->lpVtbl
->SetDeviceClassesState(Factory
, NewState
);
443 KsFilterFactoryGetSymbolicLink(
444 IN PKSFILTERFACTORY FilterFactory
)
446 PSYMBOLIC_LINK_ENTRY LinkEntry
;
447 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
449 if (IsListEmpty(&Factory
->SymbolicLinkList
))
451 /* device has not registered any interfaces */
455 /* get first entry */
456 LinkEntry
= (PSYMBOLIC_LINK_ENTRY
)CONTAINING_RECORD(Factory
->SymbolicLinkList
.Flink
, SYMBOLIC_LINK_ENTRY
, Entry
);
458 /* return first link */
459 return &LinkEntry
->SymbolicLink
;
468 KsFilterFactoryAddCreateItem(
469 IN PKSFILTERFACTORY FilterFactory
,
471 IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL
,
472 IN ULONG CreateItemFlags
)
474 KSOBJECT_CREATE_ITEM CreateItem
;
476 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
478 /* initialize create item */
479 CreateItem
.Context
= (PVOID
)&Factory
->FilterFactory
;
480 CreateItem
.Create
= IKsFilterFactory_Create
;
481 CreateItem
.Flags
= CreateItemFlags
;
482 CreateItem
.SecurityDescriptor
= SecurityDescriptor
;
483 RtlInitUnicodeString(&CreateItem
.ObjectClass
, RefString
);
485 /* insert create item to device header */
486 return KsAllocateObjectCreateItem((KSDEVICE_HEADER
)Factory
->DeviceHeader
, &CreateItem
, TRUE
, IKsFilterFactory_ItemFreeCb
);
491 PKSPCACHE_DESCRIPTOR Descriptor
,
497 for(Index
= 0; Index
< Descriptor
->DataOffset
; Index
++)
499 if (RtlCompareMemory(Descriptor
->DataCache
, Data
, Length
) == Length
)
501 if (Index
+ Length
> Descriptor
->DataOffset
)
503 /* adjust used space */
504 Descriptor
->DataOffset
= Index
+ Length
;
505 /* return absolute offset */
506 return Descriptor
->DataLength
+ Index
;
512 ASSERT(Descriptor
->DataOffset
+ Length
< Descriptor
->DataLength
);
514 /* copy to data blob */
515 RtlMoveMemory((Descriptor
->DataCache
+ Descriptor
->DataOffset
), Data
, Length
);
518 Index
= Descriptor
->DataOffset
;
520 /* adjust used space */
521 Descriptor
->DataOffset
+= Length
;
523 /* return absolute offset */
524 return Descriptor
->DataLength
+ Index
;
533 KsFilterFactoryUpdateCacheData(
534 IN PKSFILTERFACTORY FilterFactory
,
535 IN
const KSFILTER_DESCRIPTOR
* FilterDescriptor OPTIONAL
)
537 KSPCACHE_DESCRIPTOR Descriptor
;
538 PKSPCACHE_FILTER_HEADER FilterHeader
;
539 UNICODE_STRING FilterData
= RTL_CONSTANT_STRING(L
"FilterData");
540 PKSPCACHE_PIN_HEADER PinHeader
;
541 ULONG Index
, SubIndex
;
543 PSYMBOLIC_LINK_ENTRY SymEntry
;
546 NTSTATUS Status
= STATUS_SUCCESS
;
548 IKsFilterFactoryImpl
* Factory
= (IKsFilterFactoryImpl
*)CONTAINING_RECORD(FilterFactory
, IKsFilterFactoryImpl
, FilterFactory
);
550 DPRINT("KsFilterFactoryUpdateCacheData %p\n", FilterDescriptor
);
552 if (!FilterDescriptor
)
553 FilterDescriptor
= Factory
->FilterFactory
.FilterDescriptor
;
555 ASSERT(FilterDescriptor
);
557 /* initialize cache descriptor */
558 RtlZeroMemory(&Descriptor
, sizeof(KSPCACHE_DESCRIPTOR
));
560 /* calculate filter data size */
561 Descriptor
.FilterLength
= sizeof(KSPCACHE_FILTER_HEADER
);
563 /* FIXME support variable size pin descriptors */
564 ASSERT(FilterDescriptor
->PinDescriptorSize
== sizeof(KSPIN_DESCRIPTOR_EX
));
566 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
568 /* add filter descriptor */
569 Descriptor
.FilterLength
+= sizeof(KSPCACHE_PIN_HEADER
);
571 if (FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.Category
)
573 /* add extra ULONG for offset to category */
574 Descriptor
.FilterLength
+= sizeof(ULONG
);
576 /* add size for clsid */
577 Descriptor
.DataLength
+= sizeof(CLSID
);
580 /* add space for formats */
581 Descriptor
.FilterLength
+= FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.DataRangesCount
* sizeof(KSPCACHE_DATARANGE
);
583 /* add space for MajorFormat / MinorFormat */
584 Descriptor
.DataLength
+= FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.DataRangesCount
* sizeof(CLSID
) * 2;
586 /* add space for mediums */
587 Descriptor
.FilterLength
+= FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.MediumsCount
* sizeof(ULONG
);
589 /* add space for the data */
590 Descriptor
.DataLength
+= FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.MediumsCount
* sizeof(KSPCACHE_MEDIUM
);
593 /* now allocate the space */
594 Descriptor
.FilterData
= (PUCHAR
)AllocateItem(NonPagedPool
, Descriptor
.DataLength
+ Descriptor
.FilterLength
);
595 if (!Descriptor
.FilterData
)
598 return STATUS_INSUFFICIENT_RESOURCES
;
601 /* initialize data cache */
602 Descriptor
.DataCache
= (PUCHAR
)((ULONG_PTR
)Descriptor
.FilterData
+ Descriptor
.FilterLength
);
604 /* setup filter header */
605 FilterHeader
= (PKSPCACHE_FILTER_HEADER
)Descriptor
.FilterData
;
607 FilterHeader
->dwVersion
= 2;
608 FilterHeader
->dwMerit
= MERIT_DO_NOT_USE
;
609 FilterHeader
->dwUnused
= 0;
610 FilterHeader
->dwPins
= FilterDescriptor
->PinDescriptorsCount
;
612 Descriptor
.FilterOffset
= sizeof(KSPCACHE_FILTER_HEADER
);
614 /* write pin headers */
615 for(Index
= 0; Index
< FilterDescriptor
->PinDescriptorsCount
; Index
++)
617 /* get offset to pin */
618 PinHeader
= (PKSPCACHE_PIN_HEADER
)((ULONG_PTR
)Descriptor
.FilterData
+ Descriptor
.FilterOffset
);
620 /* write pin header */
621 PinHeader
->Signature
= 0x33697030 + Index
;
622 PinHeader
->Flags
= 0;
623 PinHeader
->Instances
= FilterDescriptor
->PinDescriptors
[Index
].InstancesPossible
;
624 if (PinHeader
->Instances
> 1)
625 PinHeader
->Flags
|= REG_PINFLAG_B_MANY
;
628 PinHeader
->MediaTypes
= FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.DataRangesCount
;
629 PinHeader
->Mediums
= FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.MediumsCount
;
630 PinHeader
->Category
= (FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.Category
? TRUE
: FALSE
);
632 Descriptor
.FilterOffset
+= sizeof(KSPCACHE_PIN_HEADER
);
634 if (PinHeader
->Category
)
636 /* get category offset */
637 PULONG Category
= (PULONG
)(PinHeader
+ 1);
639 /* write category offset */
640 *Category
= KspCacheAddData(&Descriptor
, FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.Category
, sizeof(CLSID
));
643 Descriptor
.FilterOffset
+= sizeof(ULONG
);
647 for(SubIndex
= 0; SubIndex
< FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.DataRangesCount
; SubIndex
++)
649 /* get datarange offset */
650 PKSPCACHE_DATARANGE DataRange
= (PKSPCACHE_DATARANGE
)((ULONG_PTR
)Descriptor
.FilterData
+ Descriptor
.FilterOffset
);
652 /* initialize data range */
653 DataRange
->Signature
= 0x33797430 + SubIndex
;
654 DataRange
->dwUnused
= 0;
655 DataRange
->OffsetMajor
= KspCacheAddData(&Descriptor
, &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.DataRanges
[SubIndex
]->MajorFormat
, sizeof(CLSID
));
656 DataRange
->OffsetMinor
= KspCacheAddData(&Descriptor
, &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.DataRanges
[SubIndex
]->SubFormat
, sizeof(CLSID
));
659 Descriptor
.FilterOffset
+= sizeof(KSPCACHE_DATARANGE
);
663 for(SubIndex
= 0; SubIndex
< FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.MediumsCount
; SubIndex
++)
665 KSPCACHE_MEDIUM Medium
;
668 /* get pin medium offset */
669 MediumOffset
= (PULONG
)((ULONG_PTR
)Descriptor
.FilterData
+ Descriptor
.FilterOffset
);
671 /* copy medium guid */
672 RtlMoveMemory(&Medium
.Medium
, &FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.Mediums
[SubIndex
].Set
, sizeof(GUID
));
673 Medium
.dw1
= FilterDescriptor
->PinDescriptors
[Index
].PinDescriptor
.Mediums
[SubIndex
].Id
; /* FIXME verify */
676 *MediumOffset
= KspCacheAddData(&Descriptor
, &Medium
, sizeof(KSPCACHE_MEDIUM
));
679 Descriptor
.FilterOffset
+= sizeof(ULONG
);
684 ASSERT(Descriptor
.FilterOffset
== Descriptor
.FilterLength
);
685 ASSERT(Descriptor
.DataOffset
<= Descriptor
.DataLength
);
688 /* now go through all entries and update 'FilterData' key */
689 for(Index
= 0; Index
< FilterDescriptor
->CategoriesCount
; Index
++)
691 /* get first entry */
692 Entry
= Factory
->SymbolicLinkList
.Flink
;
694 /* set status to not found */
696 /* loop list until the the current category is found */
697 while(Entry
!= &Factory
->SymbolicLinkList
)
699 /* fetch symbolic link entry */
700 SymEntry
= (PSYMBOLIC_LINK_ENTRY
)CONTAINING_RECORD(Entry
, SYMBOLIC_LINK_ENTRY
, Entry
);
702 if (IsEqualGUIDAligned(&SymEntry
->DeviceInterfaceClass
, &FilterDescriptor
->Categories
[Index
]))
709 /* move to next entry */
710 Entry
= Entry
->Flink
;
715 /* filter category is not present */
716 Status
= STATUS_INVALID_PARAMETER
;
720 /* now open device interface */
721 Status
= IoOpenDeviceInterfaceRegistryKey(&SymEntry
->SymbolicLink
, KEY_WRITE
, &hKey
);
722 if (!NT_SUCCESS(Status
))
724 /* failed to open interface key */
728 /* update filterdata key */
729 Status
= ZwSetValueKey(hKey
, &FilterData
, 0, REG_BINARY
, Descriptor
.FilterData
, Descriptor
.FilterLength
+ Descriptor
.DataOffset
);
731 /* close filterdata key */
734 if (!NT_SUCCESS(Status
))
736 /* failed to set key value */
740 /* free filter data */
741 FreeItem(Descriptor
.FilterData
);