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