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