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_dmus.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_dmus.cpp
00005  * PURPOSE:         DirectMusic Port driver
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 #include "private.hpp"
00010 
00011 class CPortDMus : public IPortDMus,
00012                   public ISubdevice
00013 {
00014 public:
00015     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
00016 
00017     STDMETHODIMP_(ULONG) AddRef()
00018     {
00019         InterlockedIncrement(&m_Ref);
00020         return m_Ref;
00021     }
00022     STDMETHODIMP_(ULONG) Release()
00023     {
00024         InterlockedDecrement(&m_Ref);
00025 
00026         if (!m_Ref)
00027         {
00028             delete this;
00029             return 0;
00030         }
00031         return m_Ref;
00032     }
00033     IMP_IPortDMus;
00034     IMP_ISubdevice;
00035     CPortDMus(IUnknown *OuterUnknown){}
00036     virtual ~CPortDMus(){}
00037 
00038 protected:
00039 
00040     BOOL m_bInitialized;
00041     IMiniportDMus * m_pMiniport;
00042     IMiniportMidi * m_pMiniportMidi;
00043     DEVICE_OBJECT * m_pDeviceObject;
00044     PSERVICEGROUP m_ServiceGroup;
00045     PPINCOUNT m_pPinCount;
00046     PPOWERNOTIFY m_pPowerNotify;
00047     PPORTFILTERDMUS m_Filter;
00048 
00049     PPCFILTER_DESCRIPTOR m_pDescriptor;
00050     PSUBDEVICE_DESCRIPTOR m_SubDeviceDescriptor;
00051 
00052     LONG m_Ref;
00053 
00054     friend VOID GetDMusMiniport(IN IPortDMus * iface, IN PMINIPORTDMUS * Miniport, IN PMINIPORTMIDI * MidiMiniport);
00055 
00056 };
00057 
00058 static GUID InterfaceGuids[3] = 
00059 {
00060     {
00062         0x6994AD04, 0x93EF, 0x11D0, {0xA3, 0xCC, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
00063     },
00064     {
00066         0x65E8773E, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
00067     },
00068     {
00070         0x65E8773D, 0x8F56, 0x11D0, {0xA3, 0xB9, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}
00071     }
00072 };
00073 
00074 DEFINE_KSPROPERTY_TOPOLOGYSET(PortFilterDMusTopologySet, TopologyPropertyHandler);
00075 DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PortFilterDMusPinSet, PinPropertyHandler, PinPropertyHandler, PinPropertyHandler);
00076 
00077 KSPROPERTY_SET PortDMusPropertySet[] =
00078 {
00079     {
00080         &KSPROPSETID_Topology,
00081         sizeof(PortFilterDMusTopologySet) / sizeof(KSPROPERTY_ITEM),
00082         (const KSPROPERTY_ITEM*)&PortFilterDMusTopologySet,
00083         0,
00084         NULL
00085     },
00086     {
00087         &KSPROPSETID_Pin,
00088         sizeof(PortFilterDMusPinSet) / sizeof(KSPROPERTY_ITEM),
00089         (const KSPROPERTY_ITEM*)&PortFilterDMusPinSet,
00090         0,
00091         NULL
00092     }
00093 };
00094 
00095 
00096 //---------------------------------------------------------------
00097 // IUnknown interface functions
00098 //
00099 
00100 NTSTATUS
00101 NTAPI
00102 CPortDMus::QueryInterface(
00103     IN  REFIID refiid,
00104     OUT PVOID* Output)
00105 {
00106     UNICODE_STRING GuidString;
00107 
00108     if (IsEqualGUIDAligned(refiid, IID_IPortDMus) ||
00109         IsEqualGUIDAligned(refiid, IID_IPortMidi) ||
00110         IsEqualGUIDAligned(refiid, IID_IPort) ||
00111         IsEqualGUIDAligned(refiid, IID_IUnknown))
00112     {
00113         *Output = PVOID(PUNKNOWN((IPortDMus*)this));
00114         PUNKNOWN(*Output)->AddRef();
00115         return STATUS_SUCCESS;
00116     }
00117     else if (IsEqualGUIDAligned(refiid, IID_ISubdevice))
00118     {
00119         *Output = PVOID(PSUBDEVICE(this));
00120         PUNKNOWN(*Output)->AddRef();
00121         return STATUS_SUCCESS;
00122     }
00123     else if (IsEqualGUIDAligned(refiid, IID_IDrmPort) ||
00124              IsEqualGUIDAligned(refiid, IID_IDrmPort2))
00125     {
00126         return NewIDrmPort((PDRMPORT2*)Output);
00127     }
00128     else if (IsEqualGUIDAligned(refiid, IID_IPortClsVersion))
00129     {
00130         return NewPortClsVersion((PPORTCLSVERSION*)Output);
00131     }
00132     else if (IsEqualGUIDAligned(refiid, IID_IUnregisterSubdevice))
00133     {
00134         return NewIUnregisterSubdevice((PUNREGISTERSUBDEVICE*)Output);
00135     }
00136     else if (IsEqualGUIDAligned(refiid, IID_IUnregisterPhysicalConnection))
00137     {
00138         return NewIUnregisterPhysicalConnection((PUNREGISTERPHYSICALCONNECTION*)Output);
00139     }
00140 
00141     if (RtlStringFromGUID(refiid, &GuidString) == STATUS_SUCCESS)
00142     {
00143         DPRINT("IPortMidi_fnQueryInterface no interface!!! iface %S\n", GuidString.Buffer);
00144         RtlFreeUnicodeString(&GuidString);
00145     }
00146     return STATUS_UNSUCCESSFUL;
00147 }
00148 
00149 //---------------------------------------------------------------
00150 // IPort interface functions
00151 //
00152 
00153 NTSTATUS
00154 NTAPI
00155 CPortDMus::GetDeviceProperty(
00156     IN DEVICE_REGISTRY_PROPERTY  DeviceRegistryProperty,
00157     IN ULONG  BufferLength,
00158     OUT PVOID  PropertyBuffer,
00159     OUT PULONG  ReturnLength)
00160 {
00161     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
00162 
00163     if (!m_bInitialized)
00164     {
00165         DPRINT("IPortDMus_fnNewRegistryKey called w/o initiazed\n");
00166         return STATUS_UNSUCCESSFUL;
00167     }
00168 
00169     return IoGetDeviceProperty(m_pDeviceObject, DeviceRegistryProperty, BufferLength, PropertyBuffer, ReturnLength);
00170 }
00171 
00172 NTSTATUS
00173 NTAPI
00174 CPortDMus::Init(
00175     IN PDEVICE_OBJECT  DeviceObject,
00176     IN PIRP  Irp,
00177     IN PUNKNOWN  UnknownMiniport,
00178     IN PUNKNOWN  UnknownAdapter  OPTIONAL,
00179     IN PRESOURCELIST  ResourceList)
00180 {
00181     IMiniportDMus * Miniport = NULL;
00182     IMiniportMidi * MidiMiniport = NULL;
00183     NTSTATUS Status;
00184     PSERVICEGROUP ServiceGroup = NULL;
00185     PPINCOUNT PinCount;
00186     PPOWERNOTIFY PowerNotify;
00187 
00188     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
00189 
00190     if (m_bInitialized)
00191     {
00192         DPRINT("IPortDMus_Init called again\n");
00193         return STATUS_SUCCESS;
00194     }
00195 
00196     Status = UnknownMiniport->QueryInterface(IID_IMiniportDMus, (PVOID*)&Miniport);
00197     if (!NT_SUCCESS(Status))
00198     {
00199         // check for legacy interface
00200         Status = UnknownMiniport->QueryInterface(IID_IMiniportMidi, (PVOID*)&MidiMiniport);
00201         if (!NT_SUCCESS(Status))
00202         {
00203             DPRINT("IPortDMus_Init called with invalid IMiniport adapter\n");
00204             return STATUS_INVALID_PARAMETER;
00205         }
00206     }
00207 
00208     // Initialize port object
00209     m_pMiniport = Miniport;
00210     m_pMiniportMidi = MidiMiniport;
00211     m_pDeviceObject = DeviceObject;
00212     m_bInitialized = TRUE;
00213 
00214     if (Miniport)
00215     {
00216         // initialize IMiniportDMus
00217         Status = Miniport->Init(UnknownAdapter, ResourceList, this, &ServiceGroup);
00218         if (!NT_SUCCESS(Status))
00219         {
00220             DPRINT("IMiniportDMus_Init failed with %x\n", Status);
00221             m_bInitialized = FALSE;
00222             return Status;
00223         }
00224 
00225         // get the miniport device descriptor
00226         Status = Miniport->GetDescription(&m_pDescriptor);
00227         if (!NT_SUCCESS(Status))
00228         {
00229             DPRINT("failed to get description\n");
00230             Miniport->Release();
00231             m_bInitialized = FALSE;
00232             return Status;
00233         }
00234 
00235         // increment reference on miniport adapter
00236         Miniport->AddRef();
00237 
00238     }
00239     else
00240     {
00241         // initialize IMiniportMidi
00242         Status = MidiMiniport->Init(UnknownAdapter, ResourceList, (IPortMidi*)this, &ServiceGroup);
00243         if (!NT_SUCCESS(Status))
00244         {
00245             DPRINT("IMiniportMidi_Init failed with %x\n", Status);
00246             m_bInitialized = FALSE;
00247             return Status;
00248         }
00249 
00250         // get the miniport device descriptor
00251         Status = MidiMiniport->GetDescription(&m_pDescriptor);
00252         if (!NT_SUCCESS(Status))
00253         {
00254             DPRINT("failed to get description\n");
00255             MidiMiniport->Release();
00256             m_bInitialized = FALSE;
00257             return Status;
00258         }
00259 
00260         // increment reference on miniport adapter
00261         MidiMiniport->AddRef();
00262     }
00263 
00264     // create the subdevice descriptor
00265     Status = PcCreateSubdeviceDescriptor(&m_SubDeviceDescriptor, 
00266                                          3,
00267                                          InterfaceGuids, 
00268                                          0, 
00269                                          NULL,
00270                                          2, 
00271                                          PortDMusPropertySet,
00272                                          0,
00273                                          0,
00274                                          0,
00275                                          NULL,
00276                                          0,
00277                                          NULL,
00278                                          m_pDescriptor);
00279 
00280     if (!NT_SUCCESS(Status))
00281     {
00282         DPRINT("Failed to create descriptior\n");
00283 
00284         if (Miniport)
00285             Miniport->Release();
00286         else
00287             MidiMiniport->Release();
00288 
00289         m_bInitialized = FALSE;
00290         return Status;
00291     }
00292 
00293     if (m_ServiceGroup == NULL && ServiceGroup)
00294     {
00295         // register service group
00296         m_ServiceGroup = ServiceGroup;
00297     }
00298 
00299     // check if it supports IPinCount interface
00300     Status = UnknownMiniport->QueryInterface(IID_IPinCount, (PVOID*)&PinCount);
00301     if (NT_SUCCESS(Status))
00302     {
00303         // store IPinCount interface
00304         m_pPinCount = PinCount;
00305     }
00306 
00307     // does the Miniport adapter support IPowerNotify interface*/
00308     Status = UnknownMiniport->QueryInterface(IID_IPowerNotify, (PVOID*)&PowerNotify);
00309     if (NT_SUCCESS(Status))
00310     {
00311         // store reference
00312         m_pPowerNotify = PowerNotify;
00313     }
00314 
00315     return STATUS_SUCCESS;
00316 }
00317 
00318 
00319 NTSTATUS
00320 NTAPI
00321 CPortDMus::NewRegistryKey(
00322     OUT PREGISTRYKEY  *OutRegistryKey,
00323     IN PUNKNOWN  OuterUnknown  OPTIONAL,
00324     IN ULONG  RegistryKeyType,
00325     IN ACCESS_MASK  DesiredAccess,
00326     IN POBJECT_ATTRIBUTES  ObjectAttributes  OPTIONAL,
00327     IN ULONG  CreateOptions  OPTIONAL,
00328     OUT PULONG  Disposition  OPTIONAL)
00329 {
00330     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
00331 
00332     if (!m_bInitialized)
00333     {
00334         DPRINT("IPortDMus_fnNewRegistryKey called w/o initialized\n");
00335         return STATUS_UNSUCCESSFUL;
00336     }
00337 
00338     return PcNewRegistryKey(OutRegistryKey,
00339                             OuterUnknown,
00340                             RegistryKeyType,
00341                             DesiredAccess,
00342                             m_pDeviceObject,
00343                             (ISubdevice*)this,
00344                             ObjectAttributes,
00345                             CreateOptions,
00346                             Disposition);
00347 }
00348 
00349 VOID
00350 NTAPI
00351 CPortDMus::Notify(
00352     IN PSERVICEGROUP  ServiceGroup  OPTIONAL)
00353 {
00354     if (ServiceGroup)
00355     {
00356         ServiceGroup->RequestService ();
00357         return;
00358     }
00359 
00360     PC_ASSERT(m_ServiceGroup);
00361 
00362     // notify miniport service group
00363     m_ServiceGroup->RequestService();
00364 
00365     // notify stream miniport service group
00366     if (m_Filter)
00367     {
00368         m_Filter->NotifyPins();
00369     }
00370 }
00371 
00372 VOID
00373 NTAPI
00374 CPortDMus::RegisterServiceGroup(
00375     IN PSERVICEGROUP  ServiceGroup)
00376 {
00377     PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
00378 
00379     m_ServiceGroup = ServiceGroup;
00380 
00381     ServiceGroup->AddMember(PSERVICESINK(this));
00382 }
00383 //---------------------------------------------------------------
00384 // ISubdevice interface
00385 //
00386 
00387 NTSTATUS
00388 NTAPI
00389 CPortDMus::NewIrpTarget(
00390     OUT struct IIrpTarget **OutTarget,
00391     IN PCWSTR Name,
00392     IN PUNKNOWN Unknown,
00393     IN POOL_TYPE PoolType,
00394     IN PDEVICE_OBJECT DeviceObject,
00395     IN PIRP Irp, 
00396     IN KSOBJECT_CREATE *CreateObject)
00397 {
00398     NTSTATUS Status;
00399     PPORTFILTERDMUS Filter;
00400 
00401     DPRINT("ISubDevice_NewIrpTarget this %p\n", this);
00402 
00403     if (m_Filter)
00404     {
00405         *OutTarget = (IIrpTarget*)m_Filter;
00406         return STATUS_SUCCESS;
00407     }
00408 
00409 
00410     Status = NewPortFilterDMus(&Filter);
00411     if (!NT_SUCCESS(Status))
00412     {
00413         return Status;
00414     }
00415 
00416     Status = Filter->Init(PPORTDMUS(this));
00417     if (!NT_SUCCESS(Status))
00418     {
00419         Filter->Release();
00420         return Status;
00421     }
00422 
00423     *OutTarget = (IIrpTarget*)Filter;
00424     return Status;
00425 }
00426 
00427 NTSTATUS
00428 NTAPI
00429 CPortDMus::ReleaseChildren()
00430 {
00431     UNIMPLEMENTED
00432     return STATUS_UNSUCCESSFUL;
00433 }
00434 
00435 NTSTATUS
00436 NTAPI
00437 CPortDMus::GetDescriptor(
00438     IN SUBDEVICE_DESCRIPTOR ** Descriptor)
00439 {
00440     DPRINT("ISubDevice_GetDescriptor this %p\n", this);
00441     *Descriptor = m_SubDeviceDescriptor;
00442     return STATUS_SUCCESS;
00443 }
00444 
00445 NTSTATUS
00446 NTAPI
00447 CPortDMus::DataRangeIntersection(
00448     IN  ULONG PinId,
00449     IN  PKSDATARANGE DataRange,
00450     IN  PKSDATARANGE MatchingDataRange,
00451     IN  ULONG OutputBufferLength,
00452     OUT PVOID ResultantFormat OPTIONAL,
00453     OUT PULONG ResultantFormatLength)
00454 {
00455     DPRINT("ISubDevice_DataRangeIntersection this %p\n", this);
00456 
00457     if (m_pMiniport)
00458     {
00459         return m_pMiniport->DataRangeIntersection (PinId, DataRange, MatchingDataRange, OutputBufferLength, ResultantFormat, ResultantFormatLength);
00460     }
00461 
00462     return STATUS_UNSUCCESSFUL;
00463 }
00464 
00465 NTSTATUS
00466 NTAPI
00467 CPortDMus::PowerChangeNotify(
00468     IN POWER_STATE PowerState)
00469 {
00470     if (m_pPowerNotify)
00471     {
00472         m_pPowerNotify->PowerChangeNotify(PowerState);
00473     }
00474 
00475     return STATUS_SUCCESS;
00476 }
00477 
00478 
00479 NTSTATUS
00480 NTAPI
00481 CPortDMus::PinCount(
00482     IN ULONG  PinId,
00483     IN OUT PULONG  FilterNecessary,
00484     IN OUT PULONG  FilterCurrent,
00485     IN OUT PULONG  FilterPossible,
00486     IN OUT PULONG  GlobalCurrent,
00487     IN OUT PULONG  GlobalPossible)
00488 {
00489     if (m_pPinCount)
00490     {
00491        m_pPinCount->PinCount(PinId, FilterNecessary, FilterCurrent, FilterPossible, GlobalCurrent, GlobalPossible);
00492        return STATUS_SUCCESS;
00493     }
00494 
00495     // FIXME
00496     // scan filter descriptor 
00497     
00498     return STATUS_UNSUCCESSFUL;
00499 }
00500 
00501 
00502 
00503 NTSTATUS
00504 NewPortDMus(
00505     OUT PPORT* OutPort)
00506 {
00507     NTSTATUS Status;
00508     CPortDMus * Port = new(NonPagedPool, TAG_PORTCLASS) CPortDMus(NULL);
00509     if (!Port)
00510         return STATUS_INSUFFICIENT_RESOURCES;
00511 
00512     Status = Port->QueryInterface(IID_IPort, (PVOID*)OutPort);
00513 
00514     if (!NT_SUCCESS(Status))
00515     {
00516         delete Port;
00517     }
00518 
00519     DPRINT("NewPortDMus %p Status %u\n", Port, Status);
00520     return Status;
00521 
00522 }
00523 
00524 
00525 
00526 VOID
00527 GetDMusMiniport(
00528     IN IPortDMus * iface, 
00529     IN PMINIPORTDMUS * Miniport,
00530     IN PMINIPORTMIDI * MidiMiniport)
00531 {
00532     CPortDMus * This = (CPortDMus*)iface;
00533 
00534     *Miniport = This->m_pMiniport;
00535     *MidiMiniport = This->m_pMiniportMidi;
00536 }

Generated on Mon May 28 2012 04:28:25 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.