Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenundoc.cpp
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/wdm/audio/backpln/portcls/api.cpp 00005 * PURPOSE: Port api functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "private.hpp" 00010 00011 NTSTATUS 00012 NTAPI 00013 KsoDispatchCreateWithGenericFactory( 00014 LONG Unknown, 00015 PIRP Irp) 00016 { 00017 UNIMPLEMENTED; 00018 return STATUS_NOT_IMPLEMENTED; 00019 } 00020 00021 IIrpTarget * 00022 NTAPI 00023 KsoGetIrpTargetFromFileObject( 00024 PFILE_OBJECT FileObject) 00025 { 00026 PC_ASSERT(FileObject); 00027 00028 // IrpTarget is stored in FsContext 00029 return (IIrpTarget*)FileObject->FsContext; 00030 } 00031 00032 IIrpTarget * 00033 NTAPI 00034 KsoGetIrpTargetFromIrp( 00035 PIRP Irp) 00036 { 00037 PIO_STACK_LOCATION IoStack; 00038 00039 // get current irp stack location 00040 IoStack = IoGetCurrentIrpStackLocation(Irp); 00041 00042 // IIrpTarget is stored in Context member 00043 return (IIrpTarget*)IoStack->FileObject->FsContext; 00044 } 00045 00046 NTSTATUS 00047 NTAPI 00048 PcHandleEnableEventWithTable( 00049 IN PIRP Irp, 00050 IN PSUBDEVICE_DESCRIPTOR Descriptor) 00051 { 00052 // store descriptor 00053 KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor; 00054 00055 // FIXME seh probing 00056 return KsEnableEvent(Irp, Descriptor->EventSetCount, Descriptor->EventSet, NULL, KSEVENTS_NONE, NULL); 00057 } 00058 00059 NTSTATUS 00060 NTAPI 00061 PcHandleDisableEventWithTable( 00062 IN PIRP Irp, 00063 IN PSUBDEVICE_DESCRIPTOR Descriptor) 00064 { 00065 // store descriptor 00066 KSEVENT_ITEM_IRP_STORAGE(Irp) = (PKSEVENT_ITEM)Descriptor; 00067 00068 // FIXME seh probing 00069 00070 return KsDisableEvent(Irp, Descriptor->EventList, KSEVENTS_SPINLOCK, (PVOID)Descriptor->EventListLock); 00071 } 00072 00073 NTSTATUS 00074 NTAPI 00075 PcHandlePropertyWithTable( 00076 IN PIRP Irp, 00077 IN ULONG PropertySetCount, 00078 IN PKSPROPERTY_SET PropertySet, 00079 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) 00080 { 00081 PIO_STACK_LOCATION IoStack; 00082 00083 // get current irp stack location 00084 IoStack = IoGetCurrentIrpStackLocation(Irp); 00085 00086 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) 00087 { 00088 // certainly an invalid request 00089 return STATUS_INVALID_PARAMETER; 00090 } 00091 00092 // store device descriptor 00093 KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; 00094 00095 00096 // then try KsPropertyHandler 00097 return KsPropertyHandler(Irp, PropertySetCount, PropertySet); 00098 } 00099 00100 VOID 00101 NTAPI 00102 PcAcquireFormatResources( 00103 LONG Unknown, 00104 LONG Unknown2, 00105 LONG Unknown3, 00106 LONG Unknown4) 00107 { 00108 UNIMPLEMENTED; 00109 } 00110 00111 NTSTATUS 00112 PcAddToEventTable( 00113 PVOID Ptr, 00114 LONG Unknown2, 00115 ULONG Length, 00116 LONG Unknown3, 00117 LONG Unknown4, 00118 LONG Unknown5, 00119 LONG Unknown6, 00120 LONG Unknown7) 00121 { 00122 UNIMPLEMENTED; 00123 return STATUS_NOT_IMPLEMENTED; 00124 } 00125 00126 NTSTATUS 00127 NTAPI 00128 PropertyItemDispatch( 00129 IN PIRP Irp, 00130 IN PKSIDENTIFIER Request, 00131 IN OUT PVOID Data) 00132 { 00133 PPCPROPERTY_REQUEST PropertyRequest; 00134 PSUBDEVICE_DESCRIPTOR Descriptor; 00135 PKSPROPERTY Property; 00136 PPCNODE_DESCRIPTOR NodeDescriptor; 00137 PKSNODEPROPERTY NodeProperty; 00138 PKSPROPERTY_SET PropertySet; 00139 PPCPROPERTY_ITEM PropertyItem; 00140 PPCAUTOMATION_TABLE NodeAutomation; 00141 PIO_STACK_LOCATION IoStack; 00142 ULONG InstanceSize, ValueSize, Index; 00143 PVOID Instance; 00144 NTSTATUS Status; 00145 00146 // allocate a property request 00147 PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); 00148 if (!PropertyRequest) 00149 return STATUS_INSUFFICIENT_RESOURCES; 00150 00151 // grab device descriptor 00152 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00153 00154 // get current irp stack 00155 IoStack = IoGetCurrentIrpStackLocation(Irp); 00156 00157 // get input property request 00158 Property = (PKSPROPERTY)Request; 00159 00160 // get property set 00161 PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp); 00162 00163 // sanity check 00164 PC_ASSERT(Descriptor); 00165 PC_ASSERT(Descriptor->UnknownMiniport); 00166 00167 // get instance / value size 00168 InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength; 00169 Instance = Request; 00170 ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; 00171 00172 // initialize property request 00173 PropertyRequest->MajorTarget = Descriptor->UnknownMiniport; 00174 PropertyRequest->MinorTarget = Descriptor->UnknownStream; 00175 PropertyRequest->Irp = Irp; 00176 PropertyRequest->Verb = Property->Flags; 00177 00178 00179 // check if this is filter / pin property request 00180 if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY)) 00181 { 00182 // adjust input buffer size 00183 InstanceSize -= sizeof(KSPROPERTY); 00184 Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSPROPERTY)); 00185 00186 // filter / pin property request dont use node field 00187 PropertyRequest->Node = MAXULONG; 00188 } 00189 else if (InstanceSize >= sizeof(KSNODEPROPERTY)) 00190 { 00191 // request is for a node 00192 InstanceSize -= sizeof(KSNODEPROPERTY); 00193 Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSNODEPROPERTY)); 00194 00195 // cast node property request 00196 NodeProperty = (PKSNODEPROPERTY)Request; 00197 00198 // store node id 00199 PropertyRequest->Node = NodeProperty->NodeId; 00200 } 00201 else 00202 { 00203 // invalid buffer size 00204 return STATUS_INVALID_BUFFER_SIZE; 00205 } 00206 00207 // store instance size 00208 PropertyRequest->InstanceSize = InstanceSize; 00209 PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL); 00210 00211 // store value size 00212 PropertyRequest->ValueSize = ValueSize; 00213 PropertyRequest->Value = Data; 00214 00215 // now scan the property set for the attached property set item stored in Relations member 00216 if (PropertySet) 00217 { 00218 // sanity check 00219 PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set)); 00220 00221 for(Index = 0; Index < PropertySet->PropertiesCount; Index++) 00222 { 00223 // check if they got the same property id 00224 if (PropertySet->PropertyItem[Index].PropertyId == Property->Id) 00225 { 00226 // found item 00227 PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations; 00228 00229 // done 00230 break; 00231 } 00232 } 00233 } 00234 00235 // check if there has been a property set item attached 00236 if (!PropertyRequest->PropertyItem) 00237 { 00238 // is topology node id valid 00239 if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount) 00240 { 00241 // get node descriptor 00242 NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize); 00243 00244 // get node automation table 00245 NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable; 00246 00247 // has it got a automation table 00248 if (NodeAutomation) 00249 { 00250 // now scan the properties and check if it supports this request 00251 PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties; 00252 for(Index = 0; Index < NodeAutomation->PropertyCount; Index++) 00253 { 00254 // are they same property 00255 if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set)) 00256 { 00257 if (PropertyItem->Id == Property->Id) 00258 { 00259 // found match 00260 PropertyRequest->PropertyItem = PropertyItem; 00261 DPRINT1("Using property item %p\n", PropertyItem); 00262 // done 00263 break; 00264 } 00265 } 00266 00267 // move to next property item 00268 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeAutomation->PropertyItemSize); 00269 } 00270 } 00271 } 00272 } 00273 00274 if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler) 00275 { 00276 // now call the handler 00277 UNICODE_STRING GuidBuffer; 00278 RtlStringFromGUID(Property->Set, &GuidBuffer); 00279 DPRINT1("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", 00280 PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize, 00281 PropertyRequest->PropertyItem->Handler, PropertyRequest, PropertyRequest->PropertyItem->Flags, PropertyRequest->PropertyItem->Id); 00282 RtlFreeUnicodeString(&GuidBuffer); 00283 Status = PropertyRequest->PropertyItem->Handler(PropertyRequest); 00284 DPRINT1("Status %lx ValueSize %lu Information %lu\n", Status, PropertyRequest->ValueSize, Irp->IoStatus.Information); 00285 Irp->IoStatus.Information = PropertyRequest->ValueSize; 00286 00287 if (Status != STATUS_PENDING) 00288 { 00289 // free property request 00290 FreeItem(PropertyRequest, TAG_PORTCLASS); 00291 } 00292 } 00293 else 00294 { 00295 FreeItem(PropertyRequest, TAG_PORTCLASS); 00296 Status = STATUS_NOT_FOUND; 00297 } 00298 00299 /* done */ 00300 return Status; 00301 } 00302 00303 NTSTATUS 00304 PcAddToPropertyTable( 00305 IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, 00306 IN PPCPROPERTY_ITEM PropertyItem, 00307 IN ULONG bNode) 00308 { 00309 ULONG bFound = FALSE; 00310 ULONG Index, PropertySetIndex, PropertySetItemIndex; 00311 PKSPROPERTY_SET NewPropertySet; 00312 PKSPROPERTY_ITEM FilterPropertyItem, NewFilterPropertyItem; 00313 LPGUID Guid; 00314 //UNICODE_STRING GuidBuffer; 00315 00316 ASSERT(PropertyItem->Set); 00317 // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer); 00318 // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags); 00319 00320 00321 00322 //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount); 00323 // first step check if the property set is present already 00324 for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySetCount; Index++) 00325 { 00326 00327 //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer); 00328 //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount); 00329 if (IsEqualGUIDAligned(*SubDeviceDescriptor->FilterPropertySet[Index].Set, *PropertyItem->Set)) 00330 { 00331 // property set is already present 00332 bFound = TRUE; 00333 PropertySetIndex = Index; 00334 00335 // break out 00336 break; 00337 } 00338 } 00339 00340 // is the property set present 00341 if (!bFound) 00342 { 00343 // need to allocate a property set 00344 NewPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySetCount + 1) * sizeof(KSPROPERTY_SET), TAG_PORTCLASS); 00345 if (!NewPropertySet) 00346 { 00347 // out of memory 00348 return STATUS_INSUFFICIENT_RESOURCES; 00349 } 00350 00351 // need to allocate property set guid 00352 Guid = (LPGUID)AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS); 00353 if (!Guid) 00354 { 00355 // out of memory 00356 FreeItem(NewPropertySet, TAG_PORTCLASS); 00357 return STATUS_INSUFFICIENT_RESOURCES; 00358 } 00359 00360 // are any existing property sets 00361 if (SubDeviceDescriptor->FilterPropertySetCount) 00362 { 00363 // copy property sets 00364 RtlMoveMemory(NewPropertySet, SubDeviceDescriptor->FilterPropertySet, SubDeviceDescriptor->FilterPropertySetCount * sizeof(KSPROPERTY_SET)); 00365 00366 // release memory 00367 FreeItem(SubDeviceDescriptor->FilterPropertySet, TAG_PORTCLASS); 00368 } 00369 00370 // store new property set descriptors 00371 SubDeviceDescriptor->FilterPropertySet = NewPropertySet; 00372 00373 // store index 00374 PropertySetIndex = SubDeviceDescriptor->FilterPropertySetCount; 00375 00376 // increment property set count 00377 SubDeviceDescriptor->FilterPropertySetCount++; 00378 00379 // copy property guid 00380 RtlMoveMemory(Guid, PropertyItem->Set, sizeof(GUID)); 00381 00382 // initialize property set 00383 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].Set = Guid; 00384 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount = 0; 00385 } 00386 00387 // as the property set has been indentified, now search for duplicate property set item entries 00388 FilterPropertyItem = (PKSPROPERTY_ITEM)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem; 00389 bFound = FALSE; 00390 00391 for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; Index++) 00392 { 00393 // now search for an equal property set item 00394 if (FilterPropertyItem->PropertyId == PropertyItem->Id) 00395 { 00396 // found existing property set item 00397 bFound = TRUE; 00398 PropertySetItemIndex = Index; 00399 break; 00400 } 00401 00402 // move to next entry 00403 FilterPropertyItem++; 00404 } 00405 00406 if (!bFound) 00407 { 00408 // need to allocate memory for new property set item 00409 NewFilterPropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount + 1) * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); 00410 if (!NewFilterPropertyItem) 00411 { 00412 // out of memory 00413 return STATUS_INSUFFICIENT_RESOURCES; 00414 } 00415 00416 // are any existing property set items 00417 if (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount) 00418 { 00419 // copy property item sets 00420 RtlMoveMemory(NewFilterPropertyItem, 00421 (PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, 00422 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount * sizeof(KSPROPERTY_ITEM)); 00423 00424 // release old descriptors 00425 FreeItem((PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, TAG_PORTCLASS); 00426 } 00427 00428 // store new descriptor 00429 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem = NewFilterPropertyItem; 00430 00431 // store index 00432 PropertySetItemIndex = SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; 00433 00434 // increment property item set count 00435 SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount++; 00436 00437 // now initialize property item 00438 FilterPropertyItem = (PKSPROPERTY_ITEM)&SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex]; 00439 FilterPropertyItem->PropertyId = PropertyItem->Id; 00440 FilterPropertyItem->MinProperty = sizeof(KSPROPERTY); 00441 FilterPropertyItem->MinData = 0; 00442 00443 // are any set operations supported 00444 if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_SET) 00445 { 00446 // setup handler 00447 FilterPropertyItem->SetPropertyHandler = PropertyItemDispatch; 00448 } 00449 00450 // are set operation supported 00451 if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) 00452 { 00453 // setup handler 00454 FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; 00455 } 00456 00457 // are get operations supported 00458 if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) 00459 { 00460 // setup handler 00461 FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; 00462 } 00463 00464 // are basic support operations supported 00465 if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_BASICSUPPORT) 00466 { 00467 // setup handler 00468 FilterPropertyItem->SupportHandler = PropertyItemDispatch; 00469 } 00470 00471 if (!bNode) 00472 { 00473 // store property item in relations 00474 // only store property item of filter properties / pin properties 00475 // because filter & pin properties do not require a specific context 00476 // on the other hand node properties are specifically bound to a node 00477 00478 FilterPropertyItem->Relations = (const KSPROPERTY*)PropertyItem; 00479 } 00480 } 00481 else 00482 { 00483 // property set item handler already present 00484 00485 if (bNode) 00486 { 00487 // filter & pin properties should not be exposed on a node 00488 ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations == NULL); 00489 } 00490 else 00491 { 00492 // node properties should not be exposed on a filter & pin 00493 ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations != NULL); 00494 } 00495 } 00496 00497 // done 00498 return STATUS_SUCCESS; 00499 } 00500 00501 NTSTATUS 00502 PcCaptureFormat( 00503 LONG Unknown, 00504 LONG Unknown2, 00505 LONG Unknown3, 00506 LONG Unknown4) 00507 { 00508 UNIMPLEMENTED; 00509 return STATUS_NOT_IMPLEMENTED; 00510 } 00511 00512 00513 00514 00515 VOID 00516 DumpAutomationTable( 00517 IN PPCAUTOMATION_TABLE AutomationTable, 00518 IN LPCWSTR DebugPrefix, 00519 IN LPCWSTR DebugIdentation) 00520 { 00521 PPCPROPERTY_ITEM PropertyItem; 00522 PPCEVENT_ITEM EventItem; 00523 PPCMETHOD_ITEM MethodItem; 00524 ULONG Index; 00525 UNICODE_STRING GuidString; 00526 00527 if (!AutomationTable) 00528 { 00529 // no table 00530 return; 00531 } 00532 00533 DPRINT("=====================================================================\n"); 00534 DPRINT("%S%S AutomationTable %p\n", DebugIdentation, DebugPrefix, AutomationTable); 00535 DPRINT("%S%S PropertyCount %lu\n", DebugIdentation, DebugPrefix, AutomationTable->PropertyCount); 00536 DPRINT("%S%S EventCount %lu\n", DebugIdentation, DebugPrefix, AutomationTable->EventCount); 00537 DPRINT("%S%S MethodCount %lu\n", DebugIdentation, DebugPrefix, AutomationTable->MethodCount); 00538 00539 // print properties 00540 if (AutomationTable->PropertyCount) 00541 { 00542 if (AutomationTable->PropertyItemSize >= sizeof(PCPROPERTY_ITEM)) 00543 { 00544 // get property item 00545 PropertyItem = (PPCPROPERTY_ITEM)AutomationTable->Properties; 00546 00547 // sanity check 00548 ASSERT(PropertyItem); 00549 00550 // display all properties associated 00551 for(Index = 0; Index < AutomationTable->PropertyCount; Index++) 00552 { 00553 // convert to printable string 00554 RtlStringFromGUID(*PropertyItem->Set, &GuidString); 00555 DPRINT("%SPropertyItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIdentation, Index, PropertyItem, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags); 00556 RtlFreeUnicodeString(&GuidString); 00557 // move to next item 00558 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + AutomationTable->PropertyItemSize); 00559 } 00560 00561 } 00562 else 00563 { 00564 DPRINT1("DRIVER BUG: property item must be at least %lu but got %lu\n", sizeof(PCPROPERTY_ITEM), AutomationTable->PropertyItemSize); 00565 } 00566 } 00567 00568 // print events 00569 if (AutomationTable->EventCount) 00570 { 00571 if (AutomationTable->EventItemSize >= sizeof(PCEVENT_ITEM)) 00572 { 00573 // get first event item 00574 EventItem = (PPCEVENT_ITEM)AutomationTable->Events; 00575 00576 // sanity check 00577 ASSERT(EventItem); 00578 00579 for(Index = 0; Index < AutomationTable->EventCount; Index++) 00580 { 00581 // convert to printable string 00582 RtlStringFromGUID(*EventItem->Set, &GuidString); 00583 DPRINT("%SEventItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIdentation, Index, EventItem, GuidString.Buffer, EventItem->Id, EventItem->Flags); 00584 RtlFreeUnicodeString(&GuidString); 00585 00586 // move to next item 00587 EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + AutomationTable->EventItemSize); 00588 } 00589 } 00590 else 00591 { 00592 DPRINT1("DRIVER BUG: event item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->EventItemSize); 00593 } 00594 } 00595 00596 // print methods 00597 if (AutomationTable->MethodCount) 00598 { 00599 if (AutomationTable->MethodItemSize >= sizeof(PCMETHOD_ITEM)) 00600 { 00601 // get first event item 00602 MethodItem = (PPCMETHOD_ITEM)AutomationTable->Methods; 00603 00604 // sanity check 00605 ASSERT(MethodItem); 00606 00607 for(Index = 0; Index < AutomationTable->MethodCount; Index++) 00608 { 00609 // convert to printable string 00610 RtlStringFromGUID(*MethodItem->Set, &GuidString); 00611 DPRINT("%SMethodItemIndex %lu %p GUID %S Id %u Flags %x\n", DebugIdentation, Index, MethodItem, GuidString.Buffer, MethodItem->Id, MethodItem->Flags); 00612 RtlFreeUnicodeString(&GuidString); 00613 00614 // move to next item 00615 MethodItem = (PPCMETHOD_ITEM)((ULONG_PTR)MethodItem + AutomationTable->MethodItemSize); 00616 } 00617 00618 } 00619 else 00620 { 00621 DPRINT1("DRIVER BUG: method item must be at least %lu but got %lu\n", sizeof(PCEVENT_ITEM), AutomationTable->MethodItemSize); 00622 } 00623 } 00624 DPRINT("=====================================================================\n"); 00625 } 00626 00627 00628 VOID 00629 DumpFilterDescriptor( 00630 IN PPCFILTER_DESCRIPTOR FilterDescription) 00631 { 00632 ULONG Index; 00633 WCHAR Buffer[30]; 00634 PPCPIN_DESCRIPTOR PinDescriptor; 00635 PPCNODE_DESCRIPTOR NodeDescriptor; 00636 00637 DPRINT("======================\n"); 00638 DPRINT("Descriptor Automation Table %p\n",FilterDescription->AutomationTable); 00639 DPRINT("PinCount %lu PinSize %lu StandardSize %lu\n", FilterDescription->PinCount, FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR)); 00640 DPRINT("NodeCount %lu NodeSize %lu StandardSize %lu\n", FilterDescription->NodeCount, FilterDescription->NodeSize, sizeof(PCNODE_DESCRIPTOR)); 00641 00642 // dump filter description table 00643 DumpAutomationTable((PPCAUTOMATION_TABLE)FilterDescription->AutomationTable, L"Filter", L""); 00644 00645 00646 if (FilterDescription->PinCount) 00647 { 00648 if (FilterDescription->PinSize >= sizeof(PCPIN_DESCRIPTOR)) 00649 { 00650 // get first pin 00651 PinDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins; 00652 00653 // sanity check 00654 ASSERT(PinDescriptor); 00655 00656 for(Index = 0; Index < FilterDescription->PinCount; Index++) 00657 { 00658 // print prefix 00659 swprintf(Buffer, L"PinIndex %lu", Index); 00660 00661 // dump automation table 00662 DumpAutomationTable((PPCAUTOMATION_TABLE)PinDescriptor->AutomationTable, Buffer, L" "); 00663 00664 // move to next pin descriptor 00665 PinDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)PinDescriptor + FilterDescription->PinSize); 00666 } 00667 } 00668 else 00669 { 00670 DPRINT1("DRIVER BUG: pin size smaller than minimum size\n"); 00671 } 00672 } 00673 00674 00675 if (FilterDescription->Nodes) 00676 { 00677 if (FilterDescription->NodeSize >= sizeof(PCNODE_DESCRIPTOR)) 00678 { 00679 // get first descriptor 00680 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes; 00681 00682 // sanity check 00683 ASSERT(NodeDescriptor); 00684 00685 for(Index = 0; Index < FilterDescription->NodeCount; Index++) 00686 { 00687 // print prefix 00688 swprintf(Buffer, L"NodeIndex %lu", Index); 00689 00690 // dump automation table 00691 DumpAutomationTable((PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable, Buffer, L" "); 00692 00693 // move to next node descriptor 00694 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize); 00695 } 00696 } 00697 else 00698 { 00699 DPRINT1("DRIVER BUG: node size smaller than standard descriptor size\n"); 00700 } 00701 } 00702 00703 DPRINT("ConnectionCount: %lu\n", FilterDescription->ConnectionCount); 00704 00705 if (FilterDescription->ConnectionCount) 00706 { 00707 DPRINT("------ Start of Nodes Connections ----------------\n"); 00708 for(Index = 0; Index < FilterDescription->ConnectionCount; Index++) 00709 { 00710 DPRINT1("Index %ld FromPin %ld FromNode %ld -> ToPin %ld ToNode %ld\n", Index, 00711 FilterDescription->Connections[Index].FromNodePin, 00712 FilterDescription->Connections[Index].FromNode, 00713 FilterDescription->Connections[Index].ToNodePin, 00714 FilterDescription->Connections[Index].ToNode); 00715 } 00716 DPRINT("------ End of Nodes Connections----------------\n"); 00717 } 00718 DPRINT1("======================\n"); 00719 } 00720 00721 NTSTATUS 00722 NTAPI 00723 PcCreateSubdeviceDescriptor( 00724 OUT SUBDEVICE_DESCRIPTOR ** OutSubdeviceDescriptor, 00725 IN ULONG InterfaceCount, 00726 IN GUID * InterfaceGuids, 00727 IN ULONG IdentifierCount, 00728 IN KSIDENTIFIER *Identifier, 00729 IN ULONG FilterPropertiesCount, 00730 IN KSPROPERTY_SET * FilterProperties, 00731 IN ULONG Unknown1, 00732 IN ULONG Unknown2, 00733 IN ULONG PinPropertiesCount, 00734 IN KSPROPERTY_SET * PinProperties, 00735 IN ULONG EventSetCount, 00736 IN KSEVENT_SET * EventSet, 00737 IN PPCFILTER_DESCRIPTOR FilterDescription) 00738 { 00739 SUBDEVICE_DESCRIPTOR * Descriptor; 00740 ULONG Index, SubIndex; 00741 NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; 00742 PPCPIN_DESCRIPTOR SrcDescriptor; 00743 PPCNODE_DESCRIPTOR NodeDescriptor; 00744 PPCPROPERTY_ITEM PropertyItem; 00745 00746 // allocate subdevice descriptor 00747 Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS); 00748 if (!Descriptor) 00749 return STATUS_INSUFFICIENT_RESOURCES; 00750 00751 // initialize physical / symbolic link connection list 00752 InitializeListHead(&Descriptor->SymbolicLinkList); 00753 InitializeListHead(&Descriptor->PhysicalConnectionList); 00754 00755 //FIXME add driver category guids 00756 Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS); 00757 if (!Descriptor->Interfaces) 00758 goto cleanup; 00759 00760 // copy interface guids 00761 RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount); 00762 Descriptor->InterfaceCount = InterfaceCount; 00763 00764 //DumpFilterDescriptor(FilterDescription); 00765 00766 // are any property sets supported by the portcls 00767 if (FilterPropertiesCount) 00768 { 00769 // first allocate filter properties set 00770 Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS); 00771 if (! Descriptor->FilterPropertySet) 00772 goto cleanup; 00773 00774 // now copy all filter property sets 00775 Descriptor->FilterPropertySetCount = FilterPropertiesCount; 00776 for(Index = 0; Index < FilterPropertiesCount; Index++) 00777 { 00778 // copy property set 00779 RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET)); 00780 00781 if (Descriptor->FilterPropertySet[Index].PropertiesCount) 00782 { 00783 // copy property items to make sure they are dynamically allocated 00784 Descriptor->FilterPropertySet[Index].PropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); 00785 if (!Descriptor->FilterPropertySet[Index].PropertyItem) 00786 { 00787 // no memory 00788 goto cleanup; 00789 } 00790 00791 // copy filter property items 00792 RtlMoveMemory((PVOID)Descriptor->FilterPropertySet[Index].PropertyItem, FilterProperties[Index].PropertyItem, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM)); 00793 } 00794 } 00795 } 00796 00797 // now check if the filter descriptor supports filter properties 00798 if (FilterDescription->AutomationTable) 00799 { 00800 // get first entry 00801 PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties; 00802 00803 // copy driver filter property sets 00804 for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++) 00805 { 00806 // add the property item 00807 Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); 00808 00809 // check for success 00810 if (Status != STATUS_SUCCESS) 00811 { 00812 // goto cleanup 00813 goto cleanup; 00814 } 00815 00816 // move to next entry 00817 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize); 00818 } 00819 } 00820 00821 // check if the filter has pins 00822 if (FilterDescription->PinCount) 00823 { 00824 // allocate pin factory descriptors 00825 Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS); 00826 if (!Descriptor->Factory.KsPinDescriptor) 00827 goto cleanup; 00828 00829 // allocate pin instance info 00830 Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS); 00831 if (!Descriptor->Factory.Instances) 00832 goto cleanup; 00833 00834 // initialize pin factory descriptor 00835 Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount; 00836 Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR); 00837 00838 // grab first entry 00839 SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins; 00840 00841 // copy pin factories 00842 for(Index = 0; Index < FilterDescription->PinCount; Index++) 00843 { 00844 // copy pin descriptor 00845 RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR)); 00846 00847 // initialize pin factory instance data 00848 Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0; 00849 Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount; 00850 Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount; 00851 Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount; 00852 00853 // check if the descriptor has an automation table 00854 if (SrcDescriptor->AutomationTable) 00855 { 00856 // it has, grab first entry 00857 PropertyItem = (PPCPROPERTY_ITEM)SrcDescriptor->AutomationTable->Properties; 00858 00859 // now add all supported property items 00860 for(SubIndex = 0; SubIndex < SrcDescriptor->AutomationTable->PropertyCount; SubIndex++) 00861 { 00862 // add the property item to the table 00863 Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); 00864 00865 // check for success 00866 if (Status != STATUS_SUCCESS) 00867 { 00868 // goto cleanup 00869 goto cleanup; 00870 } 00871 00872 // move to next entry 00873 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + SrcDescriptor->AutomationTable->PropertyItemSize); 00874 } 00875 } 00876 00877 // move to next entry 00878 SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize); 00879 } 00880 } 00881 00882 // allocate topology descriptor 00883 Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); 00884 if (!Descriptor->Topology) 00885 goto cleanup; 00886 00887 // are there any connections 00888 if (FilterDescription->ConnectionCount) 00889 { 00890 // allocate connection descriptor 00891 Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS); 00892 if (!Descriptor->Topology->TopologyConnections) 00893 goto cleanup; 00894 00895 // copy connection descriptor 00896 RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR)); 00897 00898 // store connection count 00899 Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount; 00900 } 00901 00902 // does the filter have nodes 00903 if (FilterDescription->NodeCount) 00904 { 00905 // allocate topology node types array 00906 Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); 00907 if (!Descriptor->Topology->TopologyNodes) 00908 goto cleanup; 00909 00910 // allocate topology node names array 00911 Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); 00912 if (!Descriptor->Topology->TopologyNodesNames) 00913 goto cleanup; 00914 00915 // grab first entry 00916 NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes; 00917 00918 // iterate all nodes and copy node types / names and node properties 00919 for(Index = 0; Index < FilterDescription->NodeCount; Index++) 00920 { 00921 // does it have a type 00922 if (NodeDescriptor->Type) 00923 { 00924 // copy node type 00925 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID)); 00926 } 00927 00928 // does it have a node name 00929 if (NodeDescriptor->Name) 00930 { 00931 // copy node name 00932 RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID)); 00933 } 00934 00935 // check if has an automation table 00936 if (NodeDescriptor->AutomationTable) 00937 { 00938 // grab first entry 00939 PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties; 00940 00941 // copy all node properties into the global property set 00942 for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++) 00943 { 00944 // add to property set 00945 Status = PcAddToPropertyTable(Descriptor, PropertyItem, TRUE); 00946 00947 // check for success 00948 if (Status != STATUS_SUCCESS) 00949 { 00950 // failed 00951 goto cleanup; 00952 } 00953 00954 // move to next property item 00955 PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize); 00956 } 00957 } 00958 00959 // move to next descriptor 00960 NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize); 00961 } 00962 00963 // now store the topology node count 00964 Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; 00965 } 00966 00967 // store descriptor 00968 Descriptor->DeviceDescriptor = FilterDescription; 00969 00970 // store result 00971 *OutSubdeviceDescriptor = Descriptor; 00972 // done 00973 return STATUS_SUCCESS; 00974 00975 cleanup: 00976 if (Descriptor) 00977 { 00978 if (Descriptor->Interfaces) 00979 FreeItem(Descriptor->Interfaces, TAG_PORTCLASS); 00980 00981 if (Descriptor->Factory.KsPinDescriptor) 00982 FreeItem(Descriptor->Factory.KsPinDescriptor, TAG_PORTCLASS); 00983 00984 FreeItem(Descriptor, TAG_PORTCLASS); 00985 } 00986 return Status; 00987 } 00988 00989 NTSTATUS 00990 NTAPI 00991 PcValidateConnectRequest( 00992 IN PIRP Irp, 00993 IN KSPIN_FACTORY * Factory, 00994 OUT PKSPIN_CONNECT * Connect) 00995 { 00996 return KsValidateConnectRequest(Irp, Factory->PinDescriptorCount, Factory->KsPinDescriptor, Connect); 00997 } 00998 Generated on Sat May 26 2012 04:27:12 for ReactOS by
1.7.6.1
|