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

port_topology.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/port_topology.cpp
00005  * PURPOSE:         Topology Port driver
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 #include "private.hpp"
00010 
00011 class CPortTopology : public IPortTopology,
00012                       public ISubdevice,
00013                       public IPortEvents
00014 {
00015 public:
00016     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
00017 
00018     STDMETHODIMP_(ULONG) AddRef()
00019     {
00020         InterlockedIncrement(&m_Ref);
00021         return m_Ref;
00022     }
00023     STDMETHODIMP_(ULONG) Release()
00024     {
00025         InterlockedDecrement(&m_Ref);
00026 
00027         if (!m_Ref)
00028         {
00029             delete this;
00030             return 0;
00031         }
00032         return m_Ref;
00033     }
00034     IMP_IPortTopology;
00035     IMP_ISubdevice;
00036     IMP_IPortEvents;
00037     CPortTopology(IUnknown *OuterUnknown){}
00038     virtual ~CPortTopology(){}
00039 
00040 protected:
00041     BOOL m_bInitialized;
00042 
00043     PMINIPORTTOPOLOGY m_pMiniport;
00044     PDEVICE_OBJECT m_pDeviceObject;
00045     PPINCOUNT m_pPinCount;
00046     PPOWERNOTIFY m_pPowerNotify;
00047 
00048     PPCFILTER_DESCRIPTOR m_pDescriptor;
00049     PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor;
00050     IPortFilterTopology * m_Filter;
00051 
00052     LONG m_Ref;
00053 
00054     friend PMINIPORTTOPOLOGY GetTopologyMiniport(PPORTTOPOLOGY Port);
00055 
00056 };
00057 
00058 static GUID InterfaceGuids[2] = 
00059 {
00060     {
00062         0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
00063     },
00064     {
00066         0xDDA54A40, 0x1E4C, 0x11D1, {0xA0, 0x50, 0x40, 0x57, 0x05, 0xC1, 0x00, 0x00}
00067     }
00068 };
00069 
00070 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterTopologyTopologySet, TopologyPropertyHandler);
00071 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterTopologyPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler);
00072 
00073 KSPROPERTY_SET TopologyPropertySet[] =
00074 {
00075     {
00076         &KSPROPSETID_Topology,
00077         sizeof(PortFilterTopologyTopologySet) / sizeof(KSPROPERTY_ITEM),
00078         (const KSPROPERTY_ITEM*)&PortFilterTopologyTopologySet,
00079         0,
00080         NULL
00081     },
00082     {
00083         &KSPROPSETID_Pin,
00084         sizeof(PortFilterTopologyPinSet) / sizeof(KSPROPERTY_ITEM),
00085         (const KSPROPERTY_ITEM*)&PortFilterTopologyPinSet,
00086         0,
00087         NULL
00088     }
00089 };
00090 
00091 //---------------------------------------------------------------
00092 // IPortEvents
00093 //
00094 
00095 
00096 void
00097 NTAPI
00098 CPortTopology::AddEventToEventList(
00099     IN PKSEVENT_ENTRY EventEntry)
00100 {
00101     UNIMPLEMENTED
00102 }
00103 
00104 void
00105 NTAPI
00106 CPortTopology::GenerateEventList(
00107     IN  GUID* Set OPTIONAL,
00108     IN  ULONG EventId,
00109     IN  BOOL PinEvent,
00110     IN  ULONG PinId,
00111     IN  BOOL NodeEvent,
00112     IN  ULONG NodeId)
00113 {
00114     UNIMPLEMENTED
00115 }
00116 
00117 
00118 //---------------------------------------------------------------
00119 // IUnknown interface functions
00120 //
00121 
00122 NTSTATUS
00123 NTAPI
00124 CPortTopology::QueryInterface(
00125     IN  REFIID refiid,
00126     OUT PVOID* Output)
00127 {
00128     UNICODE_STRING GuidString;
00129 
00130     DPRINT("IPortTopology_fnQueryInterface\n");
00131 
00132     if (IsEqualGUIDAligned(refiid, IID_IPortTopology) ||
00133         IsEqualGUIDAligned(refiid, IID_IPort) ||
00134         IsEqualGUIDAligned(refiid, IID_IUnknown))
00135     {
00136         *Output = PVOID(PUNKNOWN((IPortTopology*)this));
00137         PUNKNOWN(*Output)->AddRef();
00138         return STATUS_SUCCESS;
00139     }
00140     else if (IsEqualGUIDAligned(refiid, IID_IPortEvents))
00141     {
00142         *Output = PVOID(PPORTEVENTS(this));
00143         PUNKNOWN(*Output)->AddRef();
00144         return STATUS_SUCCESS;
00145     }
00146     else if (IsEqualGUIDAligned(refiid, IID_ISubdevice))
00147     {
00148         *Output = PVOID(PSUBDEVICE(this));
00149         PUNKNOWN(*Output)->AddRef();
00150         return STATUS_SUCCESS;
00151     }
00152     else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion))
00153     {
00154         return NewPortClsVersion((PPORTCLSVERSION*)Output);
00155     }
00156     else if (IsEqualGUIDAligned(refiid, IID_IDrmPort) ||
00157              IsEqualGUIDAligned(refiid, IID_IDrmPort2))
00158     {
00159         return NewIDrmPort((PDRMPORT2*)Output);
00160     }
00161     else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice))
00162     {
00163         return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
00164     }
00165     else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection))
00166     {
00167         return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output);
00168     }
00169 
00170     if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
00171     {
00172         DPRINT1("IPortTopology_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
00173         RtlFreeUnicodeString(&GuidString);
00174     }
00175     return STATUS_UNSUCCESSFUL;
00176 }
00177 
00178 //---------------------------------------------------------------
00179 // IPort interface functions
00180 //
00181 
00182 NTSTATUS
00183 NTAPI
00184 CPortTopology::GetDeviceProperty(
00185     IN DEVICE_REGISTRY_PROPERTY  DeviceRegistryProperty,
00186     IN ULONG  BufferLength,
00187     OUT PVOID  PropertyBuffer,
00188     OUT PULONG  ReturnLength)
00189 {
00190     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
00191 
00192     if (!m_bInitialized)
00193     {
00194         DPRINT("IPortTopology_fnNewRegistryKey called w/o initiazed\n");
00195         return STATUS_UNSUCCESSFUL;
00196     }
00197 
00198     return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
00199 }
00200 
00201 NTSTATUS
00202 NTAPI
00203 CPortTopology::Init(
00204     IN PDEVICE_OBJECT  DeviceObject,
00205     IN PIRP  Irp,
00206     IN PUNKNOWN  UnknownMiniport,
00207     IN PUNKNOWN  UnknownAdapter  OPTIONAL,
00208     IN PRESOURCELIST  ResourceList)
00209 {
00210     IMiniportTopology * Miniport;
00211     NTSTATUS Status;
00212 
00213     DPRINT("IPortTopology_fnInit entered This %p DeviceObject %p Irp %p UnknownMiniport %p UnknownAdapter %p ResourceList %p\n",
00214             this, DeviceObject, Irp, UnknownMiniport, UnknownAdapter, ResourceList);
00215 
00216     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
00217 
00218     if (m_bInitialized)
00219     {
00220         DPRINT("IPortTopology_Init called again\n");
00221         return STATUS_SUCCESS;
00222     }
00223 
00224     Status = UnknownMiniport->QueryInterface(IID_IMiniportTopology, (PVOID*)&Miniport);
00225     if (!NT_SUCCESS(Status))
00226     {
00227         DPRINT("IPortTopology_Init called with invalid IMiniport adapter\n");
00228         return STATUS_INVALID_PARAMETER;
00229     }
00230 
00231     // Initialize port object
00232     m_pMiniport = Miniport;
00233     m_pDeviceObject = DeviceObject;
00234     m_bInitialized = TRUE;
00235 
00236     // now initialize the miniport driver
00237     Status = Miniport->Init(UnknownAdapter, ResourceList, this);
00238     if (!NT_SUCCESS(Status))
00239     {
00240         DPRINT("IPortTopology_Init failed with %x\n", Status);
00241         m_bInitialized = FALSE;
00242         Miniport->Release();
00243         return Status;
00244     }
00245 
00246     // get the miniport device descriptor
00247     Status = Miniport->GetDescription(&m_pDescriptor);
00248     if (!NT_SUCCESS(Status))
00249     {
00250         DPRINT("failed to get description\n");
00251         Miniport->Release();
00252         m_bInitialized = FALSE;
00253         return Status;
00254     }
00255 
00256     // create the subdevice descriptor
00257     Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor,
00258                                          2,
00259                                          InterfaceGuids,
00260                                          0, 
00261                                          NULL,
00262                                          2, 
00263                                          TopologyPropertySet,
00264                                          0,
00265                                          0,
00266                                          0,
00267                                          NULL,
00268                                          0,
00269                                          NULL,
00270                                          m_pDescriptor);
00271 
00272 
00273     DPRINT("IPortTopology_fnInit success\n");
00274     if (NT_SUCCESS(Status))
00275     {
00276         // store for node property requests
00277         m_SubDeviceDescriptor->UnknownMiniport = UnknownMiniport;
00278     }
00279 
00280     return STATUS_SUCCESS;
00281 }
00282 
00283 
00284 NTSTATUS
00285 NTAPI
00286 CPortTopology::NewRegistryKey(
00287     OUT PREGISTRYKEY  *OutRegistryKey,
00288     IN PUNKNOWN  OuterUnknown  OPTIONAL,
00289     IN ULONG  RegistryKeyType,
00290     IN ACCESS_MASK  DesiredAccess,
00291     IN POBJECT_ATTRIBUTES  ObjectAttributes  OPTIONAL,
00292     IN ULONG  CreateOptions  OPTIONAL,
00293     OUT PULONG  Disposition  OPTIONAL)
00294 {
00295     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
00296 
00297     if (!m_bInitialized)
00298     {
00299         DPRINT("IPortTopology_fnNewRegistryKey called w/o initialized\n");
00300         return STATUS_UNSUCCESSFUL;
00301     }
00302     return PcNewRegistryKey(OutRegistryKey, 
00303                             OuterUnknown,
00304                             RegistryKeyType,
00305                             DesiredAccess,
00306                             m_pDeviceObject,
00307                             (ISubdevice*)this,
00308                             ObjectAttributes,
00309                             CreateOptions,
00310                             Disposition);
00311 }
00312 
00313 //---------------------------------------------------------------
00314 // ISubdevice interface
00315 //
00316 
00317 NTSTATUS
00318 NTAPI
00319 CPortTopology::NewIrpTarget(
00320     OUT struct IIrpTarget **OutTarget,
00321     IN PCWSTR Name,
00322     IN PUNKNOWN Unknown,
00323     IN POOL_TYPE PoolType,
00324     IN PDEVICE_OBJECT DeviceObject,
00325     IN PIRP Irp, 
00326     IN KSOBJECT_CREATE *CreateObject)
00327 {
00328     NTSTATUS Status;
00329     IPortFilterTopology * Filter;
00330 
00331     // is there already an instance of the filter
00332     if (m_Filter)
00333     {
00334         // it is, let's return the result
00335         *OutTarget = (IIrpTarget*)m_Filter;
00336 
00337         // increment reference
00338         m_Filter->AddRef();
00339         return STATUS_SUCCESS;
00340     }
00341 
00342     // create new instance of filter
00343     Status = NewPortFilterTopology(&Filter);
00344     if (!NT_SUCCESS(Status))
00345     {
00346         // not enough memory
00347         return Status;
00348     }
00349 
00350     // initialize the filter
00351     Status = Filter->Init((IPortTopology*)this);
00352     if (!NT_SUCCESS(Status))
00353     {
00354         // destroy filter
00355         Filter->Release();
00356         // return status
00357         return Status;
00358     }
00359 
00360     // store result
00361     *OutTarget = (IIrpTarget*)Filter;
00362     // store for later re-use
00363     m_Filter = Filter;
00364     // return status
00365     return Status;
00366 }
00367 
00368 NTSTATUS
00369 NTAPI
00370 CPortTopology::ReleaseChildren()
00371 {
00372     DPRINT("ISubDevice_fnReleaseChildren\n");
00373 
00374     // release the filter
00375     m_Filter->Release();
00376 
00377     // release the miniport
00378     DPRINT("Refs %u\n", m_pMiniport->Release());
00379 
00380     return STATUS_SUCCESS;
00381 }
00382 
00383 NTSTATUS
00384 NTAPI
00385 CPortTopology::GetDescriptor(
00386     IN SUBDEVICE_DESCRIPTOR ** Descriptor)
00387 {
00388     DPRINT("ISubDevice_GetDescriptor this %p Descp %p\n", this, m_SubDeviceDescriptor);
00389     *Descriptor = m_SubDeviceDescriptor;
00390     return STATUS_SUCCESS;
00391 }
00392 
00393 NTSTATUS
00394 NTAPI
00395 CPortTopology::DataRangeIntersection(
00396     IN  ULONG PinId,
00397     IN  PKSDATARANGE DataRange,
00398     IN  PKSDATARANGE MatchingDataRange,
00399     IN  ULONG OutputBufferLength,
00400     OUT PVOID ResultantFormat OPTIONAL,
00401     OUT PULONG ResultantFormatLength)
00402 {
00403     DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
00404 
00405     if (m_pMiniport)
00406     {
00407         return m_pMiniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength);
00408     }
00409 
00410     return STATUS_UNSUCCESSFUL;
00411 }
00412 
00413 NTSTATUS
00414 NTAPI
00415 CPortTopology::PowerChangeNotify(
00416     IN POWER_STATE PowerState)
00417 {
00418     if (m_pPowerNotify)
00419     {
00420         m_pPowerNotify->PowerChangeNotify(PowerState);
00421     }
00422 
00423     return STATUS_SUCCESS;
00424 }
00425 
00426 NTSTATUS
00427 NTAPI
00428 CPortTopology::PinCount(
00429     IN ULONG  PinId,
00430     IN OUT PULONG  FilterNecessary,
00431     IN OUT PULONG  FilterCurrent,
00432     IN OUT PULONG  FilterPossible,
00433     IN OUT PULONG  GlobalCurrent,
00434     IN OUT PULONG  GlobalPossible)
00435 {
00436     if (m_pPinCount)
00437     {
00438        m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible);
00439        return STATUS_SUCCESS;
00440     }
00441 
00442     // FIXME
00443      // scan filter descriptor 
00444     
00445     return STATUS_UNSUCCESSFUL;
00446 }
00447 
00448 
00449 NTSTATUS
00450 NTAPI
00451 PcCreatePinDispatch(
00452     IN  PDEVICE_OBJECT DeviceObject,
00453     IN  PIRP Irp)
00454 {
00455     NTSTATUS Status;
00456     IIrpTarget *Filter;
00457     IIrpTarget *Pin;
00458     PKSOBJECT_CREATE_ITEM CreateItem;
00459 
00460     // access the create item
00461     CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
00462     // sanity check
00463     PC_ASSERT(CreateItem);
00464 
00465     DPRINT("PcCreatePinDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer);
00466 
00467     Filter = (IIrpTarget*)CreateItem->Context;
00468 
00469     // sanity checks
00470     PC_ASSERT(Filter != NULL);
00471     PC_ASSERT_IRQL(PASSIVE_LEVEL);
00472 
00473 
00474 #if KS_IMPLEMENTED
00475     Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
00476     if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
00477     {
00478         DPRINT("PcCreatePinDispatch failed to reference device header\n");
00479 
00480         FreeItem(Entry, TAG_PORTCLASS);
00481         goto cleanup;
00482     }
00483 #endif
00484 
00485     Status = Filter->NewIrpTarget(&Pin,
00486                                   KSSTRING_Pin,
00487                                   NULL,
00488                                   NonPagedPool,
00489                                   DeviceObject,
00490                                   Irp,
00491                                   NULL);
00492 
00493     DPRINT("PcCreatePinDispatch Status %x\n", Status);
00494 
00495     if (NT_SUCCESS(Status))
00496     {
00497         // create the dispatch object
00498         // FIXME need create item for clock
00499         Status = NewDispatchObject(Irp, Pin, 0, NULL);
00500         DPRINT("Pin %p\n", Pin);
00501     }
00502 
00503     DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp);
00504     // save status in irp
00505     Irp->IoStatus.Status = Status;
00506     Irp->IoStatus.Information = 0;
00507     // complete the request
00508     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00509     return Status;
00510 }
00511 
00512 NTSTATUS
00513 NTAPI
00514 PcCreateItemDispatch(
00515     IN  PDEVICE_OBJECT DeviceObject,
00516     IN  PIRP Irp)
00517 {
00518     NTSTATUS Status;
00519     ISubdevice * SubDevice;
00520     IIrpTarget *Filter;
00521     PKSOBJECT_CREATE_ITEM CreateItem, PinCreateItem;
00522 
00523     // access the create item
00524     CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
00525 
00526     DPRINT("PcCreateItemDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer);
00527 
00528     // get the subdevice
00529     SubDevice = (ISubdevice*)CreateItem->Context;
00530 
00531     // sanity checks
00532     PC_ASSERT(SubDevice != NULL);
00533 
00534 
00535 #if KS_IMPLEMENTED
00536     Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
00537     if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
00538     {
00539         DPRINT("PcCreateItemDispatch failed to reference device header\n");
00540 
00541         FreeItem(Entry, TAG_PORTCLASS);
00542         goto cleanup;
00543     }
00544 #endif
00545 
00546     // get filter object 
00547     Status = SubDevice->NewIrpTarget(&Filter,
00548                                      NULL,
00549                                      NULL,
00550                                      NonPagedPool,
00551                                      DeviceObject,
00552                                      Irp,
00553                                      NULL);
00554     if (!NT_SUCCESS(Status))
00555     {
00556         DPRINT("Failed to get filter object\n");
00557         Irp->IoStatus.Status = Status;
00558         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00559         return Status;
00560     }
00561 
00562     // allocate pin create item
00563     PinCreateItem = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);
00564     if (!PinCreateItem)
00565     {
00566         // not enough memory
00567         Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
00568         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00569         return STATUS_INSUFFICIENT_RESOURCES;
00570     }
00571 
00572     // initialize pin create item
00573     PinCreateItem->Context = (PVOID)Filter;
00574     PinCreateItem->Create = PcCreatePinDispatch;
00575     RtlInitUnicodeString(&PinCreateItem->ObjectClass, KSSTRING_Pin);
00576     // FIXME copy security descriptor
00577 
00578     // now allocate a dispatch object
00579     Status = NewDispatchObject(Irp, Filter, 1, PinCreateItem);
00580 
00581     // complete request
00582     Irp->IoStatus.Status = Status;
00583     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00584 
00585     return STATUS_SUCCESS;
00586 }
00587 
00588 
00589 NTSTATUS
00590 NewPortTopology(
00591     OUT PPORT* OutPort)
00592 {
00593     CPortTopology * This;
00594     NTSTATUS Status;
00595 
00596     This= new(NonPagedPool, TAG_PORTCLASS) CPortTopology(NULL);
00597     if (!This)
00598         return STATUS_INSUFFICIENT_RESOURCES;
00599 
00600     Status = This->QueryInterface(IID_IPort, (PVOID*)OutPort);
00601 
00602     if (!NT_SUCCESS(Status))
00603     {
00604         delete This;
00605     }
00606 
00607     DPRINT("NewPortTopology %p Status %x\n", *OutPort, Status);
00608     return Status;
00609 }
00610 
00611 
00612 PMINIPORTTOPOLOGY
00613 GetTopologyMiniport(
00614     PPORTTOPOLOGY Port)
00615 {
00616     CPortTopology * This = (CPortTopology*)Port;
00617     return This->m_pMiniport;
00618 }

Generated on Sun May 27 2012 04:28:35 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.