Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenport_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
1.7.6.1
|