1*c2c66affSColin Finck /*
2*c2c66affSColin Finck * COPYRIGHT: See COPYING in the top level directory
3*c2c66affSColin Finck * PROJECT: ReactOS Kernel Streaming
4*c2c66affSColin Finck * FILE: drivers/wdm/audio/backpln/portcls/api.cpp
5*c2c66affSColin Finck * PURPOSE: Port api functions
6*c2c66affSColin Finck * PROGRAMMER: Johannes Anderwald
7*c2c66affSColin Finck */
8*c2c66affSColin Finck
9*c2c66affSColin Finck #include "private.hpp"
10*c2c66affSColin Finck
11*c2c66affSColin Finck #define NDEBUG
12*c2c66affSColin Finck #include <debug.h>
13*c2c66affSColin Finck
14*c2c66affSColin Finck NTSTATUS
15*c2c66affSColin Finck NTAPI
KsoDispatchCreateWithGenericFactory(LONG Unknown,PIRP Irp)16*c2c66affSColin Finck KsoDispatchCreateWithGenericFactory(
17*c2c66affSColin Finck LONG Unknown,
18*c2c66affSColin Finck PIRP Irp)
19*c2c66affSColin Finck {
20*c2c66affSColin Finck UNIMPLEMENTED;
21*c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED;
22*c2c66affSColin Finck }
23*c2c66affSColin Finck
24*c2c66affSColin Finck IIrpTarget *
25*c2c66affSColin Finck NTAPI
KsoGetIrpTargetFromFileObject(PFILE_OBJECT FileObject)26*c2c66affSColin Finck KsoGetIrpTargetFromFileObject(
27*c2c66affSColin Finck PFILE_OBJECT FileObject)
28*c2c66affSColin Finck {
29*c2c66affSColin Finck PC_ASSERT(FileObject);
30*c2c66affSColin Finck
31*c2c66affSColin Finck // IrpTarget is stored in FsContext
32*c2c66affSColin Finck return (IIrpTarget*)FileObject->FsContext;
33*c2c66affSColin Finck }
34*c2c66affSColin Finck
35*c2c66affSColin Finck IIrpTarget *
36*c2c66affSColin Finck NTAPI
KsoGetIrpTargetFromIrp(PIRP Irp)37*c2c66affSColin Finck KsoGetIrpTargetFromIrp(
38*c2c66affSColin Finck PIRP Irp)
39*c2c66affSColin Finck {
40*c2c66affSColin Finck PIO_STACK_LOCATION IoStack;
41*c2c66affSColin Finck
42*c2c66affSColin Finck // get current irp stack location
43*c2c66affSColin Finck IoStack = IoGetCurrentIrpStackLocation(Irp);
44*c2c66affSColin Finck
45*c2c66affSColin Finck // IIrpTarget is stored in Context member
46*c2c66affSColin Finck return (IIrpTarget*)IoStack->FileObject->FsContext;
47*c2c66affSColin Finck }
48*c2c66affSColin Finck
49*c2c66affSColin Finck NTSTATUS
50*c2c66affSColin Finck NTAPI
PcHandleEnableEventWithTable(IN PIRP Irp,IN PSUBDEVICE_DESCRIPTOR Descriptor)51*c2c66affSColin Finck PcHandleEnableEventWithTable(
52*c2c66affSColin Finck IN PIRP Irp,
53*c2c66affSColin Finck IN PSUBDEVICE_DESCRIPTOR Descriptor)
54*c2c66affSColin Finck {
55*c2c66affSColin Finck // store descriptor
56*c2c66affSColin Finck KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
57*c2c66affSColin Finck
58*c2c66affSColin Finck // FIXME seh probing
59*c2c66affSColin Finck return KsEnableEvent(Irp, Descriptor->EventSetCount, Descriptor->EventSet, NULL, KSEVENTS_NONE, NULL);
60*c2c66affSColin Finck }
61*c2c66affSColin Finck
62*c2c66affSColin Finck NTSTATUS
63*c2c66affSColin Finck NTAPI
PcHandleDisableEventWithTable(IN PIRP Irp,IN PSUBDEVICE_DESCRIPTOR Descriptor)64*c2c66affSColin Finck PcHandleDisableEventWithTable(
65*c2c66affSColin Finck IN PIRP Irp,
66*c2c66affSColin Finck IN PSUBDEVICE_DESCRIPTOR Descriptor)
67*c2c66affSColin Finck {
68*c2c66affSColin Finck // store descriptor
69*c2c66affSColin Finck KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor;
70*c2c66affSColin Finck
71*c2c66affSColin Finck // FIXME seh probing
72*c2c66affSColin Finck
73*c2c66affSColin Finck return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock);
74*c2c66affSColin Finck }
75*c2c66affSColin Finck
76*c2c66affSColin Finck NTSTATUS
77*c2c66affSColin Finck NTAPI
PcHandlePropertyWithTable(IN PIRP Irp,IN ULONG PropertySetCount,IN PKSPROPERTY_SET PropertySet,IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)78*c2c66affSColin Finck PcHandlePropertyWithTable(
79*c2c66affSColin Finck IN PIRP Irp,
80*c2c66affSColin Finck IN ULONG PropertySetCount,
81*c2c66affSColin Finck IN PKSPROPERTY_SET PropertySet,
82*c2c66affSColin Finck IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
83*c2c66affSColin Finck {
84*c2c66affSColin Finck PIO_STACK_LOCATION IoStack;
85*c2c66affSColin Finck
86*c2c66affSColin Finck // get current irp stack location
87*c2c66affSColin Finck IoStack = IoGetCurrentIrpStackLocation(Irp);
88*c2c66affSColin Finck
89*c2c66affSColin Finck if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
90*c2c66affSColin Finck {
91*c2c66affSColin Finck // certainly an invalid request
92*c2c66affSColin Finck return STATUS_INVALID_PARAMETER;
93*c2c66affSColin Finck }
94*c2c66affSColin Finck
95*c2c66affSColin Finck // store device descriptor
96*c2c66affSColin Finck KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor;
97*c2c66affSColin Finck
98*c2c66affSColin Finck // then try KsPropertyHandler
99*c2c66affSColin Finck return KsPropertyHandler(Irp, PropertySetCount, PropertySet);
100*c2c66affSColin Finck }
101*c2c66affSColin Finck
102*c2c66affSColin Finck VOID
103*c2c66affSColin Finck NTAPI
PcAcquireFormatResources(LONG Unknown,LONG Unknown2,LONG Unknown3,LONG Unknown4)104*c2c66affSColin Finck PcAcquireFormatResources(
105*c2c66affSColin Finck LONG Unknown,
106*c2c66affSColin Finck LONG Unknown2,
107*c2c66affSColin Finck LONG Unknown3,
108*c2c66affSColin Finck LONG Unknown4)
109*c2c66affSColin Finck {
110*c2c66affSColin Finck UNIMPLEMENTED;
111*c2c66affSColin Finck }
112*c2c66affSColin Finck
113*c2c66affSColin Finck NTSTATUS
PcAddToEventTable(PVOID Ptr,LONG Unknown2,ULONG Length,LONG Unknown3,LONG Unknown4,LONG Unknown5,LONG Unknown6,LONG Unknown7)114*c2c66affSColin Finck PcAddToEventTable(
115*c2c66affSColin Finck PVOID Ptr,
116*c2c66affSColin Finck LONG Unknown2,
117*c2c66affSColin Finck ULONG Length,
118*c2c66affSColin Finck LONG Unknown3,
119*c2c66affSColin Finck LONG Unknown4,
120*c2c66affSColin Finck LONG Unknown5,
121*c2c66affSColin Finck LONG Unknown6,
122*c2c66affSColin Finck LONG Unknown7)
123*c2c66affSColin Finck {
124*c2c66affSColin Finck UNIMPLEMENTED;
125*c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED;
126*c2c66affSColin Finck }
127*c2c66affSColin Finck
128*c2c66affSColin Finck NTSTATUS
129*c2c66affSColin Finck NTAPI
PropertyItemDispatch(IN PIRP Irp,IN PKSIDENTIFIER Request,IN OUT PVOID Data)130*c2c66affSColin Finck PropertyItemDispatch(
131*c2c66affSColin Finck IN PIRP Irp,
132*c2c66affSColin Finck IN PKSIDENTIFIER Request,
133*c2c66affSColin Finck IN OUT PVOID Data)
134*c2c66affSColin Finck {
135*c2c66affSColin Finck PPCPROPERTY_REQUEST PropertyRequest;
136*c2c66affSColin Finck PSUBDEVICE_DESCRIPTOR Descriptor;
137*c2c66affSColin Finck PKSPROPERTY Property;
138*c2c66affSColin Finck PPCNODE_DESCRIPTOR NodeDescriptor;
139*c2c66affSColin Finck PKSNODEPROPERTY NodeProperty;
140*c2c66affSColin Finck PKSPROPERTY_SET PropertySet;
141*c2c66affSColin Finck PPCPROPERTY_ITEM PropertyItem;
142*c2c66affSColin Finck PPCAUTOMATION_TABLE NodeAutomation;
143*c2c66affSColin Finck PIO_STACK_LOCATION IoStack;
144*c2c66affSColin Finck ULONG InstanceSize, ValueSize, Index;
145*c2c66affSColin Finck PVOID Instance;
146*c2c66affSColin Finck NTSTATUS Status;
147*c2c66affSColin Finck
148*c2c66affSColin Finck // allocate a property request
149*c2c66affSColin Finck PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS);
150*c2c66affSColin Finck if (!PropertyRequest)
151*c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
152*c2c66affSColin Finck
153*c2c66affSColin Finck // grab device descriptor
154*c2c66affSColin Finck Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
155*c2c66affSColin Finck
156*c2c66affSColin Finck // get current irp stack
157*c2c66affSColin Finck IoStack = IoGetCurrentIrpStackLocation(Irp);
158*c2c66affSColin Finck
159*c2c66affSColin Finck // get input property request
160*c2c66affSColin Finck Property = (PKSPROPERTY)Request;
161*c2c66affSColin Finck
162*c2c66affSColin Finck // get property set
163*c2c66affSColin Finck PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp);
164*c2c66affSColin Finck
165*c2c66affSColin Finck // sanity check
166*c2c66affSColin Finck PC_ASSERT(Descriptor);
167*c2c66affSColin Finck PC_ASSERT(Descriptor->UnknownMiniport);
168*c2c66affSColin Finck
169*c2c66affSColin Finck // get instance / value size
170*c2c66affSColin Finck InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength;
171*c2c66affSColin Finck Instance = Request;
172*c2c66affSColin Finck ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
173*c2c66affSColin Finck
174*c2c66affSColin Finck // initialize property request
175*c2c66affSColin Finck PropertyRequest->MajorTarget = Descriptor->UnknownMiniport;
176*c2c66affSColin Finck PropertyRequest->MinorTarget = Descriptor->UnknownStream;
177*c2c66affSColin Finck PropertyRequest->Irp = Irp;
178*c2c66affSColin Finck PropertyRequest->Verb = Property->Flags;
179*c2c66affSColin Finck
180*c2c66affSColin Finck // check if this is filter / pin property request
181*c2c66affSColin Finck if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY))
182*c2c66affSColin Finck {
183*c2c66affSColin Finck // adjust input buffer size
184*c2c66affSColin Finck InstanceSize -= sizeof(KSPROPERTY);
185*c2c66affSColin Finck Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSPROPERTY));
186*c2c66affSColin Finck
187*c2c66affSColin Finck // filter / pin property request dont use node field
188*c2c66affSColin Finck PropertyRequest->Node = MAXULONG;
189*c2c66affSColin Finck }
190*c2c66affSColin Finck else if (InstanceSize >= sizeof(KSNODEPROPERTY))
191*c2c66affSColin Finck {
192*c2c66affSColin Finck // request is for a node
193*c2c66affSColin Finck InstanceSize -= sizeof(KSNODEPROPERTY);
194*c2c66affSColin Finck Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSNODEPROPERTY));
195*c2c66affSColin Finck
196*c2c66affSColin Finck // cast node property request
197*c2c66affSColin Finck NodeProperty = (PKSNODEPROPERTY)Request;
198*c2c66affSColin Finck
199*c2c66affSColin Finck // store node id
200*c2c66affSColin Finck PropertyRequest->Node = NodeProperty->NodeId;
201*c2c66affSColin Finck }
202*c2c66affSColin Finck else
203*c2c66affSColin Finck {
204*c2c66affSColin Finck // invalid buffer size
205*c2c66affSColin Finck FreeItem(PropertyRequest, TAG_PORTCLASS);
206*c2c66affSColin Finck return STATUS_INVALID_BUFFER_SIZE;
207*c2c66affSColin Finck }
208*c2c66affSColin Finck
209*c2c66affSColin Finck // store instance size
210*c2c66affSColin Finck PropertyRequest->InstanceSize = InstanceSize;
211*c2c66affSColin Finck PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL);
212*c2c66affSColin Finck
213*c2c66affSColin Finck // store value size
214*c2c66affSColin Finck PropertyRequest->ValueSize = ValueSize;
215*c2c66affSColin Finck PropertyRequest->Value = Data;
216*c2c66affSColin Finck
217*c2c66affSColin Finck // now scan the property set for the attached property set item stored in Relations member
218*c2c66affSColin Finck if (PropertySet)
219*c2c66affSColin Finck {
220*c2c66affSColin Finck // sanity check
221*c2c66affSColin Finck PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set));
222*c2c66affSColin Finck
223*c2c66affSColin Finck for(Index = 0; Index < PropertySet->PropertiesCount; Index++)
224*c2c66affSColin Finck {
225*c2c66affSColin Finck // check if they got the same property id
226*c2c66affSColin Finck if (PropertySet->PropertyItem[Index].PropertyId == Property->Id)
227*c2c66affSColin Finck {
228*c2c66affSColin Finck // found item
229*c2c66affSColin Finck PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations;
230*c2c66affSColin Finck
231*c2c66affSColin Finck // done
232*c2c66affSColin Finck break;
233*c2c66affSColin Finck }
234*c2c66affSColin Finck }
235*c2c66affSColin Finck }
236*c2c66affSColin Finck
237*c2c66affSColin Finck // check if there has been a property set item attached
238*c2c66affSColin Finck if (!PropertyRequest->PropertyItem)
239*c2c66affSColin Finck {
240*c2c66affSColin Finck // is topology node id valid
241*c2c66affSColin Finck if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount)
242*c2c66affSColin Finck {
243*c2c66affSColin Finck // get node descriptor
244*c2c66affSColin Finck NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize);
245*c2c66affSColin Finck
246*c2c66affSColin Finck // get node automation table
247*c2c66affSColin Finck NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable;
248*c2c66affSColin Finck
249*c2c66affSColin Finck // has it got a automation table
250*c2c66affSColin Finck if (NodeAutomation)
251*c2c66affSColin Finck {
252*c2c66affSColin Finck // now scan the properties and check if it supports this request
253*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties;
254*c2c66affSColin Finck for(Index = 0; Index < NodeAutomation->PropertyCount; Index++)
255*c2c66affSColin Finck {
256*c2c66affSColin Finck // are they same property
257*c2c66affSColin Finck if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set))
258*c2c66affSColin Finck {
259*c2c66affSColin Finck if (PropertyItem->Id == Property->Id)
260*c2c66affSColin Finck {
261*c2c66affSColin Finck // found match
262*c2c66affSColin Finck PropertyRequest->PropertyItem = PropertyItem;
263*c2c66affSColin Finck DPRINT("Using property item %p\n", PropertyItem);
264*c2c66affSColin Finck // done
265*c2c66affSColin Finck break;
266*c2c66affSColin Finck }
267*c2c66affSColin Finck }
268*c2c66affSColin Finck
269*c2c66affSColin Finck // move to next property item
270*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeAutomation->PropertyItemSize);
271*c2c66affSColin Finck }
272*c2c66affSColin Finck }
273*c2c66affSColin Finck }
274*c2c66affSColin Finck }
275*c2c66affSColin Finck
276*c2c66affSColin Finck if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler)
277*c2c66affSColin Finck {
278*c2c66affSColin Finck // now call the handler
279*c2c66affSColin Finck UNICODE_STRING GuidBuffer;
280*c2c66affSColin Finck RtlStringFromGUID(Property->Set, &GuidBuffer);
281*c2c66affSColin Finck DPRINT("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p PropertyItemFlags %lx PropertyItemId %lu\n",
282*c2c66affSColin Finck PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize,
283*c2c66affSColin Finck PropertyRequest->PropertyItem->Handler, PropertyRequest, PropertyRequest->PropertyItem->Flags, PropertyRequest->PropertyItem->Id);
284*c2c66affSColin Finck RtlFreeUnicodeString(&GuidBuffer);
285*c2c66affSColin Finck Status = PropertyRequest->PropertyItem->Handler(PropertyRequest);
286*c2c66affSColin Finck DPRINT("Status %lx ValueSize %lu Information %lu\n", Status, PropertyRequest->ValueSize, Irp->IoStatus.Information);
287*c2c66affSColin Finck Irp->IoStatus.Information = PropertyRequest->ValueSize;
288*c2c66affSColin Finck
289*c2c66affSColin Finck if (Status != STATUS_PENDING)
290*c2c66affSColin Finck {
291*c2c66affSColin Finck // free property request
292*c2c66affSColin Finck FreeItem(PropertyRequest, TAG_PORTCLASS);
293*c2c66affSColin Finck }
294*c2c66affSColin Finck }
295*c2c66affSColin Finck else
296*c2c66affSColin Finck {
297*c2c66affSColin Finck FreeItem(PropertyRequest, TAG_PORTCLASS);
298*c2c66affSColin Finck Status = STATUS_NOT_FOUND;
299*c2c66affSColin Finck }
300*c2c66affSColin Finck
301*c2c66affSColin Finck /* done */
302*c2c66affSColin Finck return Status;
303*c2c66affSColin Finck }
304*c2c66affSColin Finck
305*c2c66affSColin Finck NTSTATUS
PcAddToPropertyTable(IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor,IN PPCPROPERTY_ITEM PropertyItem,IN ULONG bNode)306*c2c66affSColin Finck PcAddToPropertyTable(
307*c2c66affSColin Finck IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor,
308*c2c66affSColin Finck IN PPCPROPERTY_ITEM PropertyItem,
309*c2c66affSColin Finck IN ULONG bNode)
310*c2c66affSColin Finck {
311*c2c66affSColin Finck ULONG bFound = FALSE;
312*c2c66affSColin Finck ULONG Index, PropertySetIndex, PropertySetItemIndex;
313*c2c66affSColin Finck PKSPROPERTY_SET NewPropertySet;
314*c2c66affSColin Finck PKSPROPERTY_ITEM FilterPropertyItem, NewFilterPropertyItem;
315*c2c66affSColin Finck LPGUID Guid;
316*c2c66affSColin Finck //UNICODE_STRING GuidBuffer;
317*c2c66affSColin Finck
318*c2c66affSColin Finck ASSERT(PropertyItem->Set);
319*c2c66affSColin Finck // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer);
320*c2c66affSColin Finck // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags);
321*c2c66affSColin Finck
322*c2c66affSColin Finck //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount);
323*c2c66affSColin Finck // first step check if the property set is present already
324*c2c66affSColin Finck for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySetCount; Index++)
325*c2c66affSColin Finck {
326*c2c66affSColin Finck
327*c2c66affSColin Finck //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer);
328*c2c66affSColin Finck //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount);
329*c2c66affSColin Finck if (IsEqualGUIDAligned(*SubDeviceDescriptor->FilterPropertySet[Index].Set, *PropertyItem->Set))
330*c2c66affSColin Finck {
331*c2c66affSColin Finck // property set is already present
332*c2c66affSColin Finck bFound = TRUE;
333*c2c66affSColin Finck PropertySetIndex = Index;
334*c2c66affSColin Finck
335*c2c66affSColin Finck // break out
336*c2c66affSColin Finck break;
337*c2c66affSColin Finck }
338*c2c66affSColin Finck }
339*c2c66affSColin Finck
340*c2c66affSColin Finck // is the property set present
341*c2c66affSColin Finck if (!bFound)
342*c2c66affSColin Finck {
343*c2c66affSColin Finck // need to allocate a property set
344*c2c66affSColin Finck NewPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySetCount + 1) * sizeof(KSPROPERTY_SET), TAG_PORTCLASS);
345*c2c66affSColin Finck if (!NewPropertySet)
346*c2c66affSColin Finck {
347*c2c66affSColin Finck // out of memory
348*c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
349*c2c66affSColin Finck }
350*c2c66affSColin Finck
351*c2c66affSColin Finck // need to allocate property set guid
352*c2c66affSColin Finck Guid = (LPGUID)AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS);
353*c2c66affSColin Finck if (!Guid)
354*c2c66affSColin Finck {
355*c2c66affSColin Finck // out of memory
356*c2c66affSColin Finck FreeItem(NewPropertySet, TAG_PORTCLASS);
357*c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
358*c2c66affSColin Finck }
359*c2c66affSColin Finck
360*c2c66affSColin Finck // are any existing property sets
361*c2c66affSColin Finck if (SubDeviceDescriptor->FilterPropertySetCount)
362*c2c66affSColin Finck {
363*c2c66affSColin Finck // copy property sets
364*c2c66affSColin Finck RtlMoveMemory(NewPropertySet, SubDeviceDescriptor->FilterPropertySet, SubDeviceDescriptor->FilterPropertySetCount * sizeof(KSPROPERTY_SET));
365*c2c66affSColin Finck
366*c2c66affSColin Finck // release memory
367*c2c66affSColin Finck FreeItem(SubDeviceDescriptor->FilterPropertySet, TAG_PORTCLASS);
368*c2c66affSColin Finck }
369*c2c66affSColin Finck
370*c2c66affSColin Finck // store new property set descriptors
371*c2c66affSColin Finck SubDeviceDescriptor->FilterPropertySet = NewPropertySet;
372*c2c66affSColin Finck
373*c2c66affSColin Finck // store index
374*c2c66affSColin Finck PropertySetIndex = SubDeviceDescriptor->FilterPropertySetCount;
375*c2c66affSColin Finck
376*c2c66affSColin Finck // increment property set count
377*c2c66affSColin Finck SubDeviceDescriptor->FilterPropertySetCount++;
378*c2c66affSColin Finck
379*c2c66affSColin Finck // copy property guid
380*c2c66affSColin Finck RtlMoveMemory(Guid, PropertyItem->Set, sizeof(GUID));
381*c2c66affSColin Finck
382*c2c66affSColin Finck // initialize property set
383*c2c66affSColin Finck SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].Set = Guid;
384*c2c66affSColin Finck SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount = 0;
385*c2c66affSColin Finck }
386*c2c66affSColin Finck
387*c2c66affSColin Finck // as the property set has been identified, now search for duplicate property set item entries
388*c2c66affSColin Finck FilterPropertyItem = (PKSPROPERTY_ITEM)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem;
389*c2c66affSColin Finck bFound = FALSE;
390*c2c66affSColin Finck
391*c2c66affSColin Finck for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; Index++)
392*c2c66affSColin Finck {
393*c2c66affSColin Finck // now search for an equal property set item
394*c2c66affSColin Finck if (FilterPropertyItem->PropertyId == PropertyItem->Id)
395*c2c66affSColin Finck {
396*c2c66affSColin Finck // found existing property set item
397*c2c66affSColin Finck bFound = TRUE;
398*c2c66affSColin Finck PropertySetItemIndex = Index;
399*c2c66affSColin Finck break;
400*c2c66affSColin Finck }
401*c2c66affSColin Finck
402*c2c66affSColin Finck // move to next entry
403*c2c66affSColin Finck FilterPropertyItem++;
404*c2c66affSColin Finck }
405*c2c66affSColin Finck
406*c2c66affSColin Finck if (!bFound)
407*c2c66affSColin Finck {
408*c2c66affSColin Finck // need to allocate memory for new property set item
409*c2c66affSColin Finck NewFilterPropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount + 1) * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS);
410*c2c66affSColin Finck if (!NewFilterPropertyItem)
411*c2c66affSColin Finck {
412*c2c66affSColin Finck // out of memory
413*c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
414*c2c66affSColin Finck }
415*c2c66affSColin Finck
416*c2c66affSColin Finck // are any existing property set items
417*c2c66affSColin Finck if (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount)
418*c2c66affSColin Finck {
419*c2c66affSColin Finck // copy property item sets
420*c2c66affSColin Finck RtlMoveMemory(NewFilterPropertyItem,
421*c2c66affSColin Finck (PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem,
422*c2c66affSColin Finck SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount * sizeof(KSPROPERTY_ITEM));
423*c2c66affSColin Finck
424*c2c66affSColin Finck // release old descriptors
425*c2c66affSColin Finck FreeItem((PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, TAG_PORTCLASS);
426*c2c66affSColin Finck }
427*c2c66affSColin Finck
428*c2c66affSColin Finck // store new descriptor
429*c2c66affSColin Finck SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem = NewFilterPropertyItem;
430*c2c66affSColin Finck
431*c2c66affSColin Finck // store index
432*c2c66affSColin Finck PropertySetItemIndex = SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount;
433*c2c66affSColin Finck
434*c2c66affSColin Finck // increment property item set count
435*c2c66affSColin Finck SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount++;
436*c2c66affSColin Finck
437*c2c66affSColin Finck // now initialize property item
438*c2c66affSColin Finck FilterPropertyItem = (PKSPROPERTY_ITEM)&SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex];
439*c2c66affSColin Finck FilterPropertyItem->PropertyId = PropertyItem->Id;
440*c2c66affSColin Finck FilterPropertyItem->MinProperty = sizeof(KSPROPERTY);
441*c2c66affSColin Finck FilterPropertyItem->MinData = 0;
442*c2c66affSColin Finck
443*c2c66affSColin Finck // are any set operations supported
444*c2c66affSColin Finck if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_SET)
445*c2c66affSColin Finck {
446*c2c66affSColin Finck // setup handler
447*c2c66affSColin Finck FilterPropertyItem->SetPropertyHandler = PropertyItemDispatch;
448*c2c66affSColin Finck }
449*c2c66affSColin Finck
450*c2c66affSColin Finck // are set operation supported
451*c2c66affSColin Finck if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET)
452*c2c66affSColin Finck {
453*c2c66affSColin Finck // setup handler
454*c2c66affSColin Finck FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch;
455*c2c66affSColin Finck }
456*c2c66affSColin Finck
457*c2c66affSColin Finck // are get operations supported
458*c2c66affSColin Finck if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET)
459*c2c66affSColin Finck {
460*c2c66affSColin Finck // setup handler
461*c2c66affSColin Finck FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch;
462*c2c66affSColin Finck }
463*c2c66affSColin Finck
464*c2c66affSColin Finck // are basic support operations supported
465*c2c66affSColin Finck if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_BASICSUPPORT)
466*c2c66affSColin Finck {
467*c2c66affSColin Finck // setup handler
468*c2c66affSColin Finck FilterPropertyItem->SupportHandler = PropertyItemDispatch;
469*c2c66affSColin Finck }
470*c2c66affSColin Finck
471*c2c66affSColin Finck if (!bNode)
472*c2c66affSColin Finck {
473*c2c66affSColin Finck // store property item in relations
474*c2c66affSColin Finck // only store property item of filter properties / pin properties
475*c2c66affSColin Finck // because filter & pin properties do not require a specific context
476*c2c66affSColin Finck // on the other hand node properties are specifically bound to a node
477*c2c66affSColin Finck
478*c2c66affSColin Finck FilterPropertyItem->Relations = (const KSPROPERTY*)PropertyItem;
479*c2c66affSColin Finck }
480*c2c66affSColin Finck }
481*c2c66affSColin Finck else
482*c2c66affSColin Finck {
483*c2c66affSColin Finck // property set item handler already present
484*c2c66affSColin Finck
485*c2c66affSColin Finck if (bNode)
486*c2c66affSColin Finck {
487*c2c66affSColin Finck // filter & pin properties should not be exposed on a node
488*c2c66affSColin Finck ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations == NULL);
489*c2c66affSColin Finck }
490*c2c66affSColin Finck else
491*c2c66affSColin Finck {
492*c2c66affSColin Finck // node properties should not be exposed on a filter & pin
493*c2c66affSColin Finck ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations != NULL);
494*c2c66affSColin Finck }
495*c2c66affSColin Finck }
496*c2c66affSColin Finck
497*c2c66affSColin Finck // done
498*c2c66affSColin Finck return STATUS_SUCCESS;
499*c2c66affSColin Finck }
500*c2c66affSColin Finck
501*c2c66affSColin Finck NTSTATUS
PcCaptureFormat(LONG Unknown,LONG Unknown2,LONG Unknown3,LONG Unknown4)502*c2c66affSColin Finck PcCaptureFormat(
503*c2c66affSColin Finck LONG Unknown,
504*c2c66affSColin Finck LONG Unknown2,
505*c2c66affSColin Finck LONG Unknown3,
506*c2c66affSColin Finck LONG Unknown4)
507*c2c66affSColin Finck {
508*c2c66affSColin Finck UNIMPLEMENTED;
509*c2c66affSColin Finck return STATUS_NOT_IMPLEMENTED;
510*c2c66affSColin Finck }
511*c2c66affSColin Finck
512*c2c66affSColin Finck VOID
DumpAutomationTable(IN PPCAUTOMATION_TABLE AutomationTable,IN LPCWSTR DebugPrefix,IN LPCWSTR DebugIndentation)513*c2c66affSColin Finck DumpAutomationTable(
514*c2c66affSColin Finck IN PPCAUTOMATION_TABLE AutomationTable,
515*c2c66affSColin Finck IN LPCWSTR DebugPrefix,
516*c2c66affSColin Finck IN LPCWSTR DebugIndentation)
517*c2c66affSColin Finck {
518*c2c66affSColin Finck PPCPROPERTY_ITEM PropertyItem;
519*c2c66affSColin Finck PPCEVENT_ITEM EventItem;
520*c2c66affSColin Finck PPCMETHOD_ITEM MethodItem;
521*c2c66affSColin Finck ULONG Index;
522*c2c66affSColin Finck UNICODE_STRING GuidString;
523*c2c66affSColin Finck
524*c2c66affSColin Finck if (!AutomationTable)
525*c2c66affSColin Finck {
526*c2c66affSColin Finck // no table
527*c2c66affSColin Finck return;
528*c2c66affSColin Finck }
529*c2c66affSColin Finck
530*c2c66affSColin Finck DPRINT("=====================================================================\n");
531*c2c66affSColin Finck DPRINT("%S%S AutomationTable %p\n", DebugIndentation, DebugPrefix, AutomationTable);
532*c2c66affSColin Finck DPRINT("%S%S PropertyCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->PropertyCount);
533*c2c66affSColin Finck DPRINT("%S%S EventCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->EventCount);
534*c2c66affSColin Finck DPRINT("%S%S MethodCount %lu\n", DebugIndentation, DebugPrefix, AutomationTable->MethodCount);
535*c2c66affSColin Finck
536*c2c66affSColin Finck // print properties
537*c2c66affSColin Finck if (AutomationTable->PropertyCount)
538*c2c66affSColin Finck {
539*c2c66affSColin Finck if (AutomationTable->PropertyItemSize >= sizeof(PCPROPERTY_ITEM))
540*c2c66affSColin Finck {
541*c2c66affSColin Finck // get property item
542*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)AutomationTable->Properties;
543*c2c66affSColin Finck
544*c2c66affSColin Finck // sanity check
545*c2c66affSColin Finck ASSERT(PropertyItem);
546*c2c66affSColin Finck
547*c2c66affSColin Finck // display all properties associated
548*c2c66affSColin Finck for(Index = 0; Index < AutomationTable->PropertyCount; Index++)
549*c2c66affSColin Finck {
550*c2c66affSColin Finck // convert to printable string
551*c2c66affSColin Finck RtlStringFromGUID(*PropertyItem->Set, &GuidString);
552*c2c66affSColin Finck DPRINT("%SPropertyItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, PropertyItem, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags);
553*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
554*c2c66affSColin Finck // move to next item
555*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + AutomationTable->PropertyItemSize);
556*c2c66affSColin Finck }
557*c2c66affSColin Finck
558*c2c66affSColin Finck }
559*c2c66affSColin Finck else
560*c2c66affSColin Finck {
561*c2c66affSColin Finck DPRINT1("DRIVER BUG: property item must be at least %lu but got %lu\n", sizeof(PCPROPERTY_ITEM), AutomationTable->PropertyItemSize);
562*c2c66affSColin Finck }
563*c2c66affSColin Finck }
564*c2c66affSColin Finck
565*c2c66affSColin Finck // print events
566*c2c66affSColin Finck if (AutomationTable->EventCount)
567*c2c66affSColin Finck {
568*c2c66affSColin Finck if (AutomationTable->EventItemSize >= sizeof(PCEVENT_ITEM))
569*c2c66affSColin Finck {
570*c2c66affSColin Finck // get first event item
571*c2c66affSColin Finck EventItem = (PPCEVENT_ITEM)AutomationTable->Events;
572*c2c66affSColin Finck
573*c2c66affSColin Finck // sanity check
574*c2c66affSColin Finck ASSERT(EventItem);
575*c2c66affSColin Finck
576*c2c66affSColin Finck for(Index = 0; Index < AutomationTable->EventCount; Index++)
577*c2c66affSColin Finck {
578*c2c66affSColin Finck // convert to printable string
579*c2c66affSColin Finck RtlStringFromGUID(*EventItem->Set, &GuidString);
580*c2c66affSColin Finck DPRINT("%SEventItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, EventItem, GuidString.Buffer, EventItem->Id, EventItem->Flags);
581*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
582*c2c66affSColin Finck
583*c2c66affSColin Finck // move to next item
584*c2c66affSColin Finck EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + AutomationTable->EventItemSize);
585*c2c66affSColin Finck }
586*c2c66affSColin Finck }
587*c2c66affSColin Finck else
588*c2c66affSColin Finck {
589*c2c66affSColin Finck DPRINT1("DRIVER BUG: event item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->EventItemSize);
590*c2c66affSColin Finck }
591*c2c66affSColin Finck }
592*c2c66affSColin Finck
593*c2c66affSColin Finck // print methods
594*c2c66affSColin Finck if (AutomationTable->MethodCount)
595*c2c66affSColin Finck {
596*c2c66affSColin Finck if (AutomationTable->MethodItemSize >= sizeof(PCMETHOD_ITEM))
597*c2c66affSColin Finck {
598*c2c66affSColin Finck // get first event item
599*c2c66affSColin Finck MethodItem = (PPCMETHOD_ITEM)AutomationTable->Methods;
600*c2c66affSColin Finck
601*c2c66affSColin Finck // sanity check
602*c2c66affSColin Finck ASSERT(MethodItem);
603*c2c66affSColin Finck
604*c2c66affSColin Finck for(Index = 0; Index < AutomationTable->MethodCount; Index++)
605*c2c66affSColin Finck {
606*c2c66affSColin Finck // convert to printable string
607*c2c66affSColin Finck RtlStringFromGUID(*MethodItem->Set, &GuidString);
608*c2c66affSColin Finck DPRINT("%SMethodItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIndentation, Index, MethodItem, GuidString.Buffer, MethodItem->Id, MethodItem->Flags);
609*c2c66affSColin Finck RtlFreeUnicodeString(&GuidString);
610*c2c66affSColin Finck
611*c2c66affSColin Finck // move to next item
612*c2c66affSColin Finck MethodItem = (PPCMETHOD_ITEM)((ULONG_PTR)MethodItem + AutomationTable->MethodItemSize);
613*c2c66affSColin Finck }
614*c2c66affSColin Finck
615*c2c66affSColin Finck }
616*c2c66affSColin Finck else
617*c2c66affSColin Finck {
618*c2c66affSColin Finck DPRINT1("DRIVER BUG: method item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->MethodItemSize);
619*c2c66affSColin Finck }
620*c2c66affSColin Finck }
621*c2c66affSColin Finck DPRINT("=====================================================================\n");
622*c2c66affSColin Finck }
623*c2c66affSColin Finck
624*c2c66affSColin Finck VOID
DumpFilterDescriptor(IN PPCFILTER_DESCRIPTOR FilterDescription)625*c2c66affSColin Finck DumpFilterDescriptor(
626*c2c66affSColin Finck IN PPCFILTER_DESCRIPTOR FilterDescription)
627*c2c66affSColin Finck {
628*c2c66affSColin Finck ULONG Index;
629*c2c66affSColin Finck WCHAR Buffer[30];
630*c2c66affSColin Finck PPCPIN_DESCRIPTOR PinDescriptor;
631*c2c66affSColin Finck PPCNODE_DESCRIPTOR NodeDescriptor;
632*c2c66affSColin Finck
633*c2c66affSColin Finck DPRINT("======================\n");
634*c2c66affSColin Finck DPRINT("Descriptor Automation Table %p\n",FilterDescription->AutomationTable);
635*c2c66affSColin Finck DPRINT("PinCount %lu PinSize %lu StandardSize %lu\n", FilterDescription->PinCount, FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR));
636*c2c66affSColin Finck DPRINT("NodeCount %lu NodeSize %lu StandardSize %lu\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR));
637*c2c66affSColin Finck
638*c2c66affSColin Finck // dump filter description table
639*c2c66affSColin Finck DumpAutomationTable((PPCAUTOMATION_TABLE)FilterDescription->AutomationTable, L"Filter", L"");
640*c2c66affSColin Finck
641*c2c66affSColin Finck if (FilterDescription->PinCount)
642*c2c66affSColin Finck {
643*c2c66affSColin Finck if (FilterDescription->PinSize >= sizeof(PCPIN_DESCRIPTOR))
644*c2c66affSColin Finck {
645*c2c66affSColin Finck // get first pin
646*c2c66affSColin Finck PinDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
647*c2c66affSColin Finck
648*c2c66affSColin Finck // sanity check
649*c2c66affSColin Finck ASSERT(PinDescriptor);
650*c2c66affSColin Finck
651*c2c66affSColin Finck for(Index = 0; Index < FilterDescription->PinCount; Index++)
652*c2c66affSColin Finck {
653*c2c66affSColin Finck // print prefix
654*c2c66affSColin Finck swprintf(Buffer, L"PinIndex %lu", Index);
655*c2c66affSColin Finck
656*c2c66affSColin Finck // dump automation table
657*c2c66affSColin Finck DumpAutomationTable((PPCAUTOMATION_TABLE)PinDescriptor->AutomationTable, Buffer, L" ");
658*c2c66affSColin Finck
659*c2c66affSColin Finck // move to next pin descriptor
660*c2c66affSColin Finck PinDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)PinDescriptor + FilterDescription->PinSize);
661*c2c66affSColin Finck }
662*c2c66affSColin Finck }
663*c2c66affSColin Finck else
664*c2c66affSColin Finck {
665*c2c66affSColin Finck DPRINT1("DRIVER BUG: pin size smaller than minimum size\n");
666*c2c66affSColin Finck }
667*c2c66affSColin Finck }
668*c2c66affSColin Finck
669*c2c66affSColin Finck if (FilterDescription->Nodes)
670*c2c66affSColin Finck {
671*c2c66affSColin Finck if (FilterDescription->NodeSize >= sizeof(PCNODE_DESCRIPTOR))
672*c2c66affSColin Finck {
673*c2c66affSColin Finck // get first descriptor
674*c2c66affSColin Finck NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
675*c2c66affSColin Finck
676*c2c66affSColin Finck // sanity check
677*c2c66affSColin Finck ASSERT(NodeDescriptor);
678*c2c66affSColin Finck
679*c2c66affSColin Finck for(Index = 0; Index < FilterDescription->NodeCount; Index++)
680*c2c66affSColin Finck {
681*c2c66affSColin Finck // print prefix
682*c2c66affSColin Finck swprintf(Buffer, L"NodeIndex %lu", Index);
683*c2c66affSColin Finck
684*c2c66affSColin Finck // dump automation table
685*c2c66affSColin Finck DumpAutomationTable((PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable, Buffer, L" ");
686*c2c66affSColin Finck
687*c2c66affSColin Finck // move to next node descriptor
688*c2c66affSColin Finck NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
689*c2c66affSColin Finck }
690*c2c66affSColin Finck }
691*c2c66affSColin Finck else
692*c2c66affSColin Finck {
693*c2c66affSColin Finck DPRINT1("DRIVER BUG: node size smaller than standard descriptor size\n");
694*c2c66affSColin Finck }
695*c2c66affSColin Finck }
696*c2c66affSColin Finck
697*c2c66affSColin Finck DPRINT("ConnectionCount: %lu\n", FilterDescription->ConnectionCount);
698*c2c66affSColin Finck
699*c2c66affSColin Finck if (FilterDescription->ConnectionCount)
700*c2c66affSColin Finck {
701*c2c66affSColin Finck DPRINT("------ Start of Nodes Connections ----------------\n");
702*c2c66affSColin Finck for(Index = 0; Index < FilterDescription->ConnectionCount; Index++)
703*c2c66affSColin Finck {
704*c2c66affSColin Finck DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index,
705*c2c66affSColin Finck FilterDescription->Connections[Index].FromNodePin,
706*c2c66affSColin Finck FilterDescription->Connections[Index].FromNode,
707*c2c66affSColin Finck FilterDescription->Connections[Index].ToNodePin,
708*c2c66affSColin Finck FilterDescription->Connections[Index].ToNode);
709*c2c66affSColin Finck }
710*c2c66affSColin Finck DPRINT("------ End of Nodes Connections----------------\n");
711*c2c66affSColin Finck }
712*c2c66affSColin Finck DPRINT1("======================\n");
713*c2c66affSColin Finck }
714*c2c66affSColin Finck
715*c2c66affSColin Finck NTSTATUS
716*c2c66affSColin Finck NTAPI
PcCreateSubdeviceDescriptor(OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,IN ULONG InterfaceCount,IN GUID * InterfaceGuids,IN ULONG IdentifierCount,IN KSIDENTIFIER * Identifier,IN ULONG FilterPropertiesCount,IN KSPROPERTY_SET * FilterProperties,IN ULONG Unknown1,IN ULONG Unknown2,IN ULONG PinPropertiesCount,IN KSPROPERTY_SET * PinProperties,IN ULONG EventSetCount,IN KSEVENT_SET * EventSet,IN PPCFILTER_DESCRIPTOR FilterDescription)717*c2c66affSColin Finck PcCreateSubdeviceDescriptor(
718*c2c66affSColin Finck OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor,
719*c2c66affSColin Finck IN ULONG InterfaceCount,
720*c2c66affSColin Finck IN GUID * InterfaceGuids,
721*c2c66affSColin Finck IN ULONG IdentifierCount,
722*c2c66affSColin Finck IN KSIDENTIFIER *Identifier,
723*c2c66affSColin Finck IN ULONG FilterPropertiesCount,
724*c2c66affSColin Finck IN KSPROPERTY_SET * FilterProperties,
725*c2c66affSColin Finck IN ULONG Unknown1,
726*c2c66affSColin Finck IN ULONG Unknown2,
727*c2c66affSColin Finck IN ULONG PinPropertiesCount,
728*c2c66affSColin Finck IN KSPROPERTY_SET * PinProperties,
729*c2c66affSColin Finck IN ULONG EventSetCount,
730*c2c66affSColin Finck IN KSEVENT_SET * EventSet,
731*c2c66affSColin Finck IN PPCFILTER_DESCRIPTOR FilterDescription)
732*c2c66affSColin Finck {
733*c2c66affSColin Finck SUBDEVICE_DESCRIPTOR * Descriptor;
734*c2c66affSColin Finck ULONG Index, SubIndex;
735*c2c66affSColin Finck NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
736*c2c66affSColin Finck PPCPIN_DESCRIPTOR SrcDescriptor;
737*c2c66affSColin Finck PPCNODE_DESCRIPTOR NodeDescriptor;
738*c2c66affSColin Finck PPCPROPERTY_ITEM PropertyItem;
739*c2c66affSColin Finck
740*c2c66affSColin Finck // allocate subdevice descriptor
741*c2c66affSColin Finck Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS);
742*c2c66affSColin Finck if (!Descriptor)
743*c2c66affSColin Finck return STATUS_INSUFFICIENT_RESOURCES;
744*c2c66affSColin Finck
745*c2c66affSColin Finck // initialize physical / symbolic link connection list
746*c2c66affSColin Finck InitializeListHead(&Descriptor->SymbolicLinkList);
747*c2c66affSColin Finck InitializeListHead(&Descriptor->PhysicalConnectionList);
748*c2c66affSColin Finck
749*c2c66affSColin Finck //FIXME add driver category guids
750*c2c66affSColin Finck Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS);
751*c2c66affSColin Finck if (!Descriptor->Interfaces)
752*c2c66affSColin Finck goto cleanup;
753*c2c66affSColin Finck
754*c2c66affSColin Finck // copy interface guids
755*c2c66affSColin Finck RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
756*c2c66affSColin Finck Descriptor->InterfaceCount = InterfaceCount;
757*c2c66affSColin Finck
758*c2c66affSColin Finck //DumpFilterDescriptor(FilterDescription);
759*c2c66affSColin Finck
760*c2c66affSColin Finck // are any property sets supported by the portcls
761*c2c66affSColin Finck if (FilterPropertiesCount)
762*c2c66affSColin Finck {
763*c2c66affSColin Finck // first allocate filter properties set
764*c2c66affSColin Finck Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS);
765*c2c66affSColin Finck if (! Descriptor->FilterPropertySet)
766*c2c66affSColin Finck goto cleanup;
767*c2c66affSColin Finck
768*c2c66affSColin Finck // now copy all filter property sets
769*c2c66affSColin Finck Descriptor->FilterPropertySetCount = FilterPropertiesCount;
770*c2c66affSColin Finck for(Index = 0; Index < FilterPropertiesCount; Index++)
771*c2c66affSColin Finck {
772*c2c66affSColin Finck // copy property set
773*c2c66affSColin Finck RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET));
774*c2c66affSColin Finck
775*c2c66affSColin Finck if (Descriptor->FilterPropertySet[Index].PropertiesCount)
776*c2c66affSColin Finck {
777*c2c66affSColin Finck // copy property items to make sure they are dynamically allocated
778*c2c66affSColin Finck Descriptor->FilterPropertySet[Index].PropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS);
779*c2c66affSColin Finck if (!Descriptor->FilterPropertySet[Index].PropertyItem)
780*c2c66affSColin Finck {
781*c2c66affSColin Finck // no memory
782*c2c66affSColin Finck goto cleanup;
783*c2c66affSColin Finck }
784*c2c66affSColin Finck
785*c2c66affSColin Finck // copy filter property items
786*c2c66affSColin Finck RtlMoveMemory((PVOID)Descriptor->FilterPropertySet[Index].PropertyItem, FilterProperties[Index].PropertyItem, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM));
787*c2c66affSColin Finck }
788*c2c66affSColin Finck }
789*c2c66affSColin Finck }
790*c2c66affSColin Finck
791*c2c66affSColin Finck // now check if the filter descriptor supports filter properties
792*c2c66affSColin Finck if (FilterDescription->AutomationTable)
793*c2c66affSColin Finck {
794*c2c66affSColin Finck // get first entry
795*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties;
796*c2c66affSColin Finck
797*c2c66affSColin Finck // copy driver filter property sets
798*c2c66affSColin Finck for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++)
799*c2c66affSColin Finck {
800*c2c66affSColin Finck // add the property item
801*c2c66affSColin Finck Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE);
802*c2c66affSColin Finck
803*c2c66affSColin Finck // check for success
804*c2c66affSColin Finck if (Status != STATUS_SUCCESS)
805*c2c66affSColin Finck {
806*c2c66affSColin Finck // goto cleanup
807*c2c66affSColin Finck goto cleanup;
808*c2c66affSColin Finck }
809*c2c66affSColin Finck
810*c2c66affSColin Finck // move to next entry
811*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize);
812*c2c66affSColin Finck }
813*c2c66affSColin Finck }
814*c2c66affSColin Finck
815*c2c66affSColin Finck // check if the filter has pins
816*c2c66affSColin Finck if (FilterDescription->PinCount)
817*c2c66affSColin Finck {
818*c2c66affSColin Finck // allocate pin factory descriptors
819*c2c66affSColin Finck Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS);
820*c2c66affSColin Finck if (!Descriptor->Factory.KsPinDescriptor)
821*c2c66affSColin Finck goto cleanup;
822*c2c66affSColin Finck
823*c2c66affSColin Finck // allocate pin instance info
824*c2c66affSColin Finck Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS);
825*c2c66affSColin Finck if (!Descriptor->Factory.Instances)
826*c2c66affSColin Finck goto cleanup;
827*c2c66affSColin Finck
828*c2c66affSColin Finck // initialize pin factory descriptor
829*c2c66affSColin Finck Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
830*c2c66affSColin Finck Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
831*c2c66affSColin Finck
832*c2c66affSColin Finck // grab first entry
833*c2c66affSColin Finck SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
834*c2c66affSColin Finck
835*c2c66affSColin Finck // copy pin factories
836*c2c66affSColin Finck for(Index = 0; Index < FilterDescription->PinCount; Index++)
837*c2c66affSColin Finck {
838*c2c66affSColin Finck // copy pin descriptor
839*c2c66affSColin Finck RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR));
840*c2c66affSColin Finck
841*c2c66affSColin Finck // initialize pin factory instance data
842*c2c66affSColin Finck Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0;
843*c2c66affSColin Finck Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount;
844*c2c66affSColin Finck Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount;
845*c2c66affSColin Finck Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount;
846*c2c66affSColin Finck
847*c2c66affSColin Finck // check if the descriptor has an automation table
848*c2c66affSColin Finck if (SrcDescriptor->AutomationTable)
849*c2c66affSColin Finck {
850*c2c66affSColin Finck // it has, grab first entry
851*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)SrcDescriptor->AutomationTable->Properties;
852*c2c66affSColin Finck
853*c2c66affSColin Finck // now add all supported property items
854*c2c66affSColin Finck for(SubIndex = 0; SubIndex < SrcDescriptor->AutomationTable->PropertyCount; SubIndex++)
855*c2c66affSColin Finck {
856*c2c66affSColin Finck // add the property item to the table
857*c2c66affSColin Finck Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE);
858*c2c66affSColin Finck
859*c2c66affSColin Finck // check for success
860*c2c66affSColin Finck if (Status != STATUS_SUCCESS)
861*c2c66affSColin Finck {
862*c2c66affSColin Finck // goto cleanup
863*c2c66affSColin Finck goto cleanup;
864*c2c66affSColin Finck }
865*c2c66affSColin Finck
866*c2c66affSColin Finck // move to next entry
867*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + SrcDescriptor->AutomationTable->PropertyItemSize);
868*c2c66affSColin Finck }
869*c2c66affSColin Finck }
870*c2c66affSColin Finck
871*c2c66affSColin Finck // move to next entry
872*c2c66affSColin Finck SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize);
873*c2c66affSColin Finck }
874*c2c66affSColin Finck }
875*c2c66affSColin Finck
876*c2c66affSColin Finck // allocate topology descriptor
877*c2c66affSColin Finck Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS);
878*c2c66affSColin Finck if (!Descriptor->Topology)
879*c2c66affSColin Finck goto cleanup;
880*c2c66affSColin Finck
881*c2c66affSColin Finck // are there any connections
882*c2c66affSColin Finck if (FilterDescription->ConnectionCount)
883*c2c66affSColin Finck {
884*c2c66affSColin Finck // allocate connection descriptor
885*c2c66affSColin Finck Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS);
886*c2c66affSColin Finck if (!Descriptor->Topology->TopologyConnections)
887*c2c66affSColin Finck goto cleanup;
888*c2c66affSColin Finck
889*c2c66affSColin Finck // copy connection descriptor
890*c2c66affSColin Finck RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR));
891*c2c66affSColin Finck
892*c2c66affSColin Finck // store connection count
893*c2c66affSColin Finck Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount;
894*c2c66affSColin Finck }
895*c2c66affSColin Finck
896*c2c66affSColin Finck // does the filter have nodes
897*c2c66affSColin Finck if (FilterDescription->NodeCount)
898*c2c66affSColin Finck {
899*c2c66affSColin Finck // allocate topology node types array
900*c2c66affSColin Finck Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
901*c2c66affSColin Finck if (!Descriptor->Topology->TopologyNodes)
902*c2c66affSColin Finck goto cleanup;
903*c2c66affSColin Finck
904*c2c66affSColin Finck // allocate topology node names array
905*c2c66affSColin Finck Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS);
906*c2c66affSColin Finck if (!Descriptor->Topology->TopologyNodesNames)
907*c2c66affSColin Finck goto cleanup;
908*c2c66affSColin Finck
909*c2c66affSColin Finck // grab first entry
910*c2c66affSColin Finck NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes;
911*c2c66affSColin Finck
912*c2c66affSColin Finck // iterate all nodes and copy node types / names and node properties
913*c2c66affSColin Finck for(Index = 0; Index < FilterDescription->NodeCount; Index++)
914*c2c66affSColin Finck {
915*c2c66affSColin Finck // does it have a type
916*c2c66affSColin Finck if (NodeDescriptor->Type)
917*c2c66affSColin Finck {
918*c2c66affSColin Finck // copy node type
919*c2c66affSColin Finck RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID));
920*c2c66affSColin Finck }
921*c2c66affSColin Finck
922*c2c66affSColin Finck // does it have a node name
923*c2c66affSColin Finck if (NodeDescriptor->Name)
924*c2c66affSColin Finck {
925*c2c66affSColin Finck // copy node name
926*c2c66affSColin Finck RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID));
927*c2c66affSColin Finck }
928*c2c66affSColin Finck
929*c2c66affSColin Finck // check if has an automation table
930*c2c66affSColin Finck if (NodeDescriptor->AutomationTable)
931*c2c66affSColin Finck {
932*c2c66affSColin Finck // grab first entry
933*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties;
934*c2c66affSColin Finck
935*c2c66affSColin Finck // copy all node properties into the global property set
936*c2c66affSColin Finck for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++)
937*c2c66affSColin Finck {
938*c2c66affSColin Finck // add to property set
939*c2c66affSColin Finck Status = PcAddToPropertyTable(Descriptor, PropertyItem, TRUE);
940*c2c66affSColin Finck
941*c2c66affSColin Finck // check for success
942*c2c66affSColin Finck if (Status != STATUS_SUCCESS)
943*c2c66affSColin Finck {
944*c2c66affSColin Finck // failed
945*c2c66affSColin Finck goto cleanup;
946*c2c66affSColin Finck }
947*c2c66affSColin Finck
948*c2c66affSColin Finck // move to next property item
949*c2c66affSColin Finck PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize);
950*c2c66affSColin Finck }
951*c2c66affSColin Finck }
952*c2c66affSColin Finck
953*c2c66affSColin Finck // move to next descriptor
954*c2c66affSColin Finck NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize);
955*c2c66affSColin Finck }
956*c2c66affSColin Finck
957*c2c66affSColin Finck // now store the topology node count
958*c2c66affSColin Finck Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount;
959*c2c66affSColin Finck }
960*c2c66affSColin Finck
961*c2c66affSColin Finck // store descriptor
962*c2c66affSColin Finck Descriptor->DeviceDescriptor = FilterDescription;
963*c2c66affSColin Finck
964*c2c66affSColin Finck // store result
965*c2c66affSColin Finck *OutSubdeviceDescriptor = Descriptor;
966*c2c66affSColin Finck // done
967*c2c66affSColin Finck return STATUS_SUCCESS;
968*c2c66affSColin Finck
969*c2c66affSColin Finck cleanup:
970*c2c66affSColin Finck if (Descriptor)
971*c2c66affSColin Finck {
972*c2c66affSColin Finck if (Descriptor->Interfaces)
973*c2c66affSColin Finck FreeItem(Descriptor->Interfaces, TAG_PORTCLASS);
974*c2c66affSColin Finck
975*c2c66affSColin Finck if (Descriptor->Factory.KsPinDescriptor)
976*c2c66affSColin Finck FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS);
977*c2c66affSColin Finck
978*c2c66affSColin Finck FreeItem(Descriptor, TAG_PORTCLASS);
979*c2c66affSColin Finck }
980*c2c66affSColin Finck return Status;
981*c2c66affSColin Finck }
982*c2c66affSColin Finck
983*c2c66affSColin Finck NTSTATUS
984*c2c66affSColin Finck NTAPI
PcValidateConnectRequest(IN PIRP Irp,IN KSPIN_FACTORY * Factory,OUT PKSPIN_CONNECT * Connect)985*c2c66affSColin Finck PcValidateConnectRequest(
986*c2c66affSColin Finck IN PIRP Irp,
987*c2c66affSColin Finck IN KSPIN_FACTORY * Factory,
988*c2c66affSColin Finck OUT PKSPIN_CONNECT * Connect)
989*c2c66affSColin Finck {
990*c2c66affSColin Finck return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect);
991*c2c66affSColin Finck }
992