ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

undoc.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.