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

Generated on Fri May 25 2012 04:26:52 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.