Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpin_wavepci.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/pin_wavepci.cpp 00005 * PURPOSE: WavePci IRP Audio Pin 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "private.hpp" 00010 00011 class CPortPinWavePci : public IPortPinWavePci, 00012 public IServiceSink, 00013 public IPortWavePciStream 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_IPortPinWavePci; 00035 IMP_IServiceSink; 00036 IMP_IPortWavePciStream; 00037 CPortPinWavePci(IUnknown *OuterUnknown) {} 00038 virtual ~CPortPinWavePci(){} 00039 protected: 00040 00041 friend NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00042 friend NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00043 friend NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00044 friend NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00045 00046 IPortWavePci * m_Port; 00047 IPortFilterWavePci * m_Filter; 00048 KSPIN_DESCRIPTOR * m_KsPinDescriptor; 00049 PMINIPORTWAVEPCI m_Miniport; 00050 PSERVICEGROUP m_ServiceGroup; 00051 PDMACHANNEL m_DmaChannel; 00052 PMINIPORTWAVEPCISTREAM m_Stream; 00053 KSSTATE m_State; 00054 PKSDATAFORMAT m_Format; 00055 KSPIN_CONNECT * m_ConnectDetails; 00056 00057 BOOL m_Capture; 00058 PDEVICE_OBJECT m_DeviceObject; 00059 IIrpQueue * m_IrpQueue; 00060 00061 ULONG m_TotalPackets; 00062 KSAUDIO_POSITION m_Position; 00063 ULONG m_StopCount; 00064 00065 BOOL m_bUsePrefetch; 00066 ULONG m_PrefetchOffset; 00067 SUBDEVICE_DESCRIPTOR m_Descriptor; 00068 00069 KSALLOCATOR_FRAMING m_AllocatorFraming; 00070 00071 LONG m_Ref; 00072 00073 NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); 00074 NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); 00075 }; 00076 00077 typedef struct 00078 { 00079 CPortPinWavePci *Pin; 00080 PIO_WORKITEM WorkItem; 00081 KSSTATE State; 00082 }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; 00083 00084 NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00085 NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00086 NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00087 NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00088 00089 DEFINE_KSPROPERTY_CONNECTIONSET(PinWavePciConnectionSet, PinWavePciState, PinWavePciDataFormat, PinWavePciAllocatorFraming); 00090 DEFINE_KSPROPERTY_AUDIOSET(PinWavePciAudioSet, PinWavePciAudioPosition); 00091 00092 KSPROPERTY_SET PinWavePciPropertySet[] = 00093 { 00094 { 00095 &KSPROPSETID_Connection, 00096 sizeof(PinWavePciConnectionSet) / sizeof(KSPROPERTY_ITEM), 00097 (const KSPROPERTY_ITEM*)&PinWavePciConnectionSet, 00098 0, 00099 NULL 00100 }, 00101 { 00102 &KSPROPSETID_Audio, 00103 sizeof(PinWavePciAudioSet) / sizeof(KSPROPERTY_ITEM), 00104 (const KSPROPERTY_ITEM*)&PinWavePciAudioSet, 00105 0, 00106 NULL 00107 } 00108 }; 00109 00110 00111 NTSTATUS 00112 NTAPI 00113 PinWavePciAllocatorFraming( 00114 IN PIRP Irp, 00115 IN PKSIDENTIFIER Request, 00116 IN OUT PVOID Data) 00117 { 00118 CPortPinWavePci *Pin; 00119 PSUBDEVICE_DESCRIPTOR Descriptor; 00120 00121 // get sub device descriptor 00122 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00123 00124 // sanity check 00125 PC_ASSERT(Descriptor); 00126 PC_ASSERT(Descriptor->PortPin); 00127 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00128 00129 // cast to pin impl 00130 Pin = (CPortPinWavePci*)Descriptor->PortPin; 00131 00132 00133 if (Request->Flags & KSPROPERTY_TYPE_GET) 00134 { 00135 // copy pin framing 00136 RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); 00137 00138 Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); 00139 return STATUS_SUCCESS; 00140 } 00141 00142 // not supported 00143 return STATUS_NOT_SUPPORTED; 00144 } 00145 00146 NTSTATUS 00147 NTAPI 00148 PinWavePciAudioPosition( 00149 IN PIRP Irp, 00150 IN PKSIDENTIFIER Request, 00151 IN OUT PVOID Data) 00152 { 00153 CPortPinWavePci *Pin; 00154 PSUBDEVICE_DESCRIPTOR Descriptor; 00155 00156 // get sub device descriptor 00157 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00158 00159 // sanity check 00160 PC_ASSERT(Descriptor); 00161 PC_ASSERT(Descriptor->PortPin); 00162 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00163 00164 // cast to pin impl 00165 Pin = (CPortPinWavePci*)Descriptor->PortPin; 00166 00167 //sanity check 00168 PC_ASSERT(Pin->m_Stream); 00169 00170 if (Request->Flags & KSPROPERTY_TYPE_GET) 00171 { 00172 // FIXME non multithreading-safe 00173 // copy audio position 00174 RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); 00175 00176 DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); 00177 Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); 00178 return STATUS_SUCCESS; 00179 } 00180 00181 // not supported 00182 return STATUS_NOT_SUPPORTED; 00183 } 00184 00185 00186 NTSTATUS 00187 NTAPI 00188 PinWavePciState( 00189 IN PIRP Irp, 00190 IN PKSIDENTIFIER Request, 00191 IN OUT PVOID Data) 00192 { 00193 NTSTATUS Status = STATUS_UNSUCCESSFUL; 00194 CPortPinWavePci *Pin; 00195 PSUBDEVICE_DESCRIPTOR Descriptor; 00196 PVOID FirstTag, LastTag; 00197 ULONG MappingsRevoked; 00198 PKSSTATE State = (PKSSTATE)Data; 00199 00200 // get sub device descriptor 00201 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00202 00203 // sanity check 00204 PC_ASSERT(Descriptor); 00205 PC_ASSERT(Descriptor->PortPin); 00206 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00207 00208 // cast to pin impl 00209 Pin = (CPortPinWavePci*)Descriptor->PortPin; 00210 00211 //sanity check 00212 PC_ASSERT(Pin->m_Stream); 00213 00214 if (Request->Flags & KSPROPERTY_TYPE_SET) 00215 { 00216 // try set stream 00217 Status = Pin->m_Stream->SetState(*State); 00218 00219 DPRINT("Setting state %u %x\n", *State, Status); 00220 if (NT_SUCCESS(Status)) 00221 { 00222 // store new state 00223 Pin->m_State = *State; 00224 if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP) 00225 { 00226 // FIXME 00227 // complete with successful state 00228 Pin->m_IrpQueue->CancelBuffers(); 00229 while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag)) 00230 { 00231 Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked); 00232 DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked); 00233 KeStallExecutionProcessor(10); 00234 } 00235 Pin->m_Position.PlayOffset = 0; 00236 Pin->m_Position.WriteOffset = 0; 00237 } 00238 else if (Pin->m_State == KSSTATE_STOP) 00239 { 00240 Pin->m_IrpQueue->CancelBuffers(); 00241 while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag)) 00242 { 00243 Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked); 00244 DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked); 00245 KeStallExecutionProcessor(10); 00246 } 00247 Pin->m_Position.PlayOffset = 0; 00248 Pin->m_Position.WriteOffset = 0; 00249 } 00250 // store result 00251 Irp->IoStatus.Information = sizeof(KSSTATE); 00252 00253 } 00254 // store result 00255 Irp->IoStatus.Information = sizeof(KSSTATE); 00256 return Status; 00257 } 00258 else if (Request->Flags & KSPROPERTY_TYPE_GET) 00259 { 00260 // get current stream state 00261 *State = Pin->m_State; 00262 // store result 00263 Irp->IoStatus.Information = sizeof(KSSTATE); 00264 00265 return STATUS_SUCCESS; 00266 } 00267 00268 // unsupported request 00269 return STATUS_NOT_SUPPORTED; 00270 } 00271 00272 NTSTATUS 00273 NTAPI 00274 PinWavePciDataFormat( 00275 IN PIRP Irp, 00276 IN PKSIDENTIFIER Request, 00277 IN OUT PVOID Data) 00278 { 00279 NTSTATUS Status = STATUS_UNSUCCESSFUL; 00280 CPortPinWavePci *Pin; 00281 PSUBDEVICE_DESCRIPTOR Descriptor; 00282 PIO_STACK_LOCATION IoStack; 00283 00284 // get current irp stack location 00285 IoStack = IoGetCurrentIrpStackLocation(Irp); 00286 00287 // get sub device descriptor 00288 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00289 00290 // sanity check 00291 PC_ASSERT(Descriptor); 00292 PC_ASSERT(Descriptor->PortPin); 00293 00294 // cast to pin impl 00295 Pin = (CPortPinWavePci*)Descriptor->PortPin; 00296 00297 //sanity check 00298 PC_ASSERT(Pin->m_Stream); 00299 PC_ASSERT(Pin->m_Format); 00300 00301 if (Request->Flags & KSPROPERTY_TYPE_SET) 00302 { 00303 // try to change data format 00304 PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; 00305 ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize); 00306 00307 if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size) 00308 { 00309 // format is identical 00310 Irp->IoStatus.Information = DataFormat->FormatSize; 00311 return STATUS_SUCCESS; 00312 } 00313 00314 // new change request 00315 PC_ASSERT(Pin->m_State == KSSTATE_STOP); 00316 // FIXME queue a work item when Irql != PASSIVE_LEVEL 00317 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 00318 00319 // allocate new data format 00320 NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 00321 if (!NewDataFormat) 00322 { 00323 // not enough memory 00324 return STATUS_NO_MEMORY; 00325 } 00326 00327 // copy new data format 00328 RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); 00329 00330 // set new format 00331 Status = Pin->m_Stream->SetFormat(NewDataFormat); 00332 if (NT_SUCCESS(Status)) 00333 { 00334 // free old format 00335 FreeItem(Pin->m_Format, TAG_PORTCLASS); 00336 00337 // store new format 00338 Pin->m_Format = NewDataFormat; 00339 Irp->IoStatus.Information = NewDataFormat->FormatSize; 00340 00341 #if 0 00342 PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); 00343 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); 00344 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); 00345 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); 00346 00347 00348 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, 00349 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, 00350 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); 00351 #endif 00352 00353 } 00354 else 00355 { 00356 // failed to set format 00357 FreeItem(NewDataFormat, TAG_PORTCLASS); 00358 } 00359 00360 00361 // done 00362 return Status; 00363 } 00364 else if (Request->Flags & KSPROPERTY_TYPE_GET) 00365 { 00366 // get current data format 00367 PC_ASSERT(Pin->m_Format); 00368 00369 if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) 00370 { 00371 // buffer too small 00372 Irp->IoStatus.Information = Pin->m_Format->FormatSize; 00373 return STATUS_MORE_ENTRIES; 00374 } 00375 // copy data format 00376 RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize); 00377 // store result size 00378 Irp->IoStatus.Information = Pin->m_Format->FormatSize; 00379 00380 // done 00381 return STATUS_SUCCESS; 00382 } 00383 00384 // unsupported request 00385 return STATUS_NOT_SUPPORTED; 00386 } 00387 00388 00389 //================================================================================================================================== 00390 NTSTATUS 00391 NTAPI 00392 CPortPinWavePci::QueryInterface( 00393 IN REFIID refiid, 00394 OUT PVOID* Output) 00395 { 00396 //DPRINT("CPortPinWavePci::QueryInterface entered\n"); 00397 00398 if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || 00399 IsEqualGUIDAligned(refiid, IID_IUnknown)) 00400 { 00401 *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); 00402 PUNKNOWN(*Output)->AddRef(); 00403 return STATUS_SUCCESS; 00404 } 00405 00406 if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) 00407 { 00408 *Output = PVOID(PSERVICESINK(this)); 00409 PUNKNOWN(*Output)->AddRef(); 00410 return STATUS_SUCCESS; 00411 } 00412 00413 00414 if (IsEqualGUIDAligned(refiid, IID_IPortWavePciStream)) 00415 { 00416 *Output = PVOID(PPORTWAVEPCISTREAM(this)); 00417 PUNKNOWN(*Output)->AddRef(); 00418 return STATUS_SUCCESS; 00419 } 00420 00421 return STATUS_UNSUCCESSFUL; 00422 } 00423 00424 NTSTATUS 00425 NTAPI 00426 CPortPinWavePci::GetMapping( 00427 IN PVOID Tag, 00428 OUT PPHYSICAL_ADDRESS PhysicalAddress, 00429 OUT PVOID *VirtualAddress, 00430 OUT PULONG ByteCount, 00431 OUT PULONG Flags) 00432 { 00433 00434 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00435 return m_IrpQueue->GetMappingWithTag(Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags); 00436 } 00437 00438 NTSTATUS 00439 NTAPI 00440 CPortPinWavePci::ReleaseMapping( 00441 IN PVOID Tag) 00442 { 00443 00444 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00445 return m_IrpQueue->ReleaseMappingWithTag(Tag); 00446 } 00447 00448 NTSTATUS 00449 NTAPI 00450 CPortPinWavePci::TerminatePacket() 00451 { 00452 UNIMPLEMENTED 00453 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00454 return STATUS_SUCCESS; 00455 } 00456 00457 00458 VOID 00459 NTAPI 00460 CPortPinWavePci::RequestService() 00461 { 00462 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00463 00464 if (m_State == KSSTATE_RUN) 00465 { 00466 m_Stream->Service(); 00467 //TODO 00468 //generate events 00469 } 00470 } 00471 00472 //================================================================================================================================== 00473 00474 NTSTATUS 00475 NTAPI 00476 CPortPinWavePci::NewIrpTarget( 00477 OUT struct IIrpTarget **OutTarget, 00478 IN PCWSTR Name, 00479 IN PUNKNOWN Unknown, 00480 IN POOL_TYPE PoolType, 00481 IN PDEVICE_OBJECT DeviceObject, 00482 IN PIRP Irp, 00483 IN KSOBJECT_CREATE *CreateObject) 00484 { 00485 UNIMPLEMENTED 00486 00487 Irp->IoStatus.Information = 0; 00488 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00489 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00490 00491 return STATUS_UNSUCCESSFUL; 00492 } 00493 00494 NTSTATUS 00495 NTAPI 00496 CPortPinWavePci::HandleKsProperty( 00497 IN PIRP Irp) 00498 { 00499 //PKSPROPERTY Property; 00500 NTSTATUS Status; 00501 //UNICODE_STRING GuidString; 00502 PIO_STACK_LOCATION IoStack; 00503 00504 IoStack = IoGetCurrentIrpStackLocation(Irp); 00505 00506 //DPRINT("IPortPinWave_HandleKsProperty entered\n"); 00507 00508 IoStack = IoGetCurrentIrpStackLocation(Irp); 00509 00510 if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) 00511 { 00512 //DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength); 00513 00514 Irp->IoStatus.Status = STATUS_SUCCESS; 00515 00516 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00517 return STATUS_SUCCESS; 00518 } 00519 00520 Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); 00521 00522 if (Status == STATUS_NOT_FOUND) 00523 { 00524 //Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00525 #if 0 00526 RtlStringFromGUID(Property->Set, &GuidString); 00527 //DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); 00528 RtlFreeUnicodeString(&GuidString); 00529 #endif 00530 } 00531 00532 if (Status != STATUS_PENDING) 00533 { 00534 Irp->IoStatus.Status = Status; 00535 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00536 } 00537 00538 return Status; 00539 } 00540 00541 NTSTATUS 00542 NTAPI 00543 CPortPinWavePci::HandleKsStream( 00544 IN PIRP Irp) 00545 { 00546 NTSTATUS Status; 00547 ULONG Data = 0; 00548 BOOLEAN bFailed; 00549 InterlockedIncrement((PLONG)&m_TotalPackets); 00550 00551 DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); 00552 00553 bFailed = m_IrpQueue->HasLastMappingFailed(); 00554 00555 Status = m_IrpQueue->AddMapping(Irp, &Data); 00556 00557 if (NT_SUCCESS(Status)) 00558 { 00559 if (m_Capture) 00560 m_Position.WriteOffset += Data; 00561 else 00562 m_Position.WriteOffset += Data; 00563 00564 if (bFailed) 00565 { 00566 // notify stream of new mapping 00567 m_Stream->MappingAvailable(); 00568 } 00569 00570 return STATUS_PENDING; 00571 } 00572 00573 return Status; 00574 } 00575 00576 00577 NTSTATUS 00578 NTAPI 00579 CPortPinWavePci::DeviceIoControl( 00580 IN PDEVICE_OBJECT DeviceObject, 00581 IN PIRP Irp) 00582 { 00583 PIO_STACK_LOCATION IoStack; 00584 00585 IoStack = IoGetCurrentIrpStackLocation(Irp); 00586 00587 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) 00588 { 00589 return HandleKsProperty(Irp); 00590 } 00591 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) 00592 { 00593 return HandleKsStream(Irp); 00594 } 00595 00596 UNIMPLEMENTED 00597 00598 Irp->IoStatus.Information = 0; 00599 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 00600 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00601 00602 return STATUS_UNSUCCESSFUL; 00603 } 00604 00605 NTSTATUS 00606 NTAPI 00607 CPortPinWavePci::Read( 00608 IN PDEVICE_OBJECT DeviceObject, 00609 IN PIRP Irp) 00610 { 00611 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00612 } 00613 00614 NTSTATUS 00615 NTAPI 00616 CPortPinWavePci::Write( 00617 IN PDEVICE_OBJECT DeviceObject, 00618 IN PIRP Irp) 00619 { 00620 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00621 } 00622 00623 NTSTATUS 00624 NTAPI 00625 CPortPinWavePci::Flush( 00626 IN PDEVICE_OBJECT DeviceObject, 00627 IN PIRP Irp) 00628 { 00629 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00630 } 00631 00632 NTSTATUS 00633 NTAPI 00634 CPortPinWavePci::Close( 00635 IN PDEVICE_OBJECT DeviceObject, 00636 IN PIRP Irp) 00637 { 00638 NTSTATUS Status; 00639 00640 if (m_Format) 00641 { 00642 // free format 00643 FreeItem(m_Format, TAG_PORTCLASS); 00644 00645 // format is freed 00646 m_Format = NULL; 00647 } 00648 00649 if (m_IrpQueue) 00650 { 00651 // cancel remaining irps 00652 m_IrpQueue->CancelBuffers(); 00653 00654 // release irp queue 00655 m_IrpQueue->Release(); 00656 00657 // queue is freed 00658 m_IrpQueue = NULL; 00659 } 00660 00661 00662 if (m_ServiceGroup) 00663 { 00664 // remove member from service group 00665 m_ServiceGroup->RemoveMember(PSERVICESINK(this)); 00666 00667 // do not release service group, it is released by the miniport object 00668 m_ServiceGroup = NULL; 00669 } 00670 00671 if (m_Stream) 00672 { 00673 if (m_State != KSSTATE_STOP) 00674 { 00675 // stop stream 00676 Status = m_Stream->SetState(KSSTATE_STOP); 00677 if (!NT_SUCCESS(Status)) 00678 { 00679 DPRINT("Warning: failed to stop stream with %x\n", Status); 00680 PC_ASSERT(0); 00681 } 00682 } 00683 // set state to stop 00684 m_State = KSSTATE_STOP; 00685 00686 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); 00687 00688 // release stream 00689 m_Stream->Release(); 00690 00691 // stream is now freed 00692 m_Stream = NULL; 00693 } 00694 00695 if (m_Filter) 00696 { 00697 // disconnect pin from filter 00698 m_Filter->FreePin((PPORTPINWAVEPCI)this); 00699 00700 // release filter reference 00701 m_Filter->Release(); 00702 00703 // pin is done with filter 00704 m_Filter = NULL; 00705 } 00706 00707 if (m_Port) 00708 { 00709 // release reference to port driver 00710 m_Port->Release(); 00711 00712 // work is done for port 00713 m_Port = NULL; 00714 } 00715 00716 // successfully complete irp 00717 Irp->IoStatus.Status = STATUS_SUCCESS; 00718 Irp->IoStatus.Information = 0; 00719 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00720 00721 return STATUS_SUCCESS; 00722 } 00723 00724 NTSTATUS 00725 NTAPI 00726 CPortPinWavePci::QuerySecurity( 00727 IN PDEVICE_OBJECT DeviceObject, 00728 IN PIRP Irp) 00729 { 00730 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00731 } 00732 00733 NTSTATUS 00734 NTAPI 00735 CPortPinWavePci::SetSecurity( 00736 IN PDEVICE_OBJECT DeviceObject, 00737 IN PIRP Irp) 00738 { 00739 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00740 } 00741 00742 BOOLEAN 00743 NTAPI 00744 CPortPinWavePci::FastDeviceIoControl( 00745 IN PFILE_OBJECT FileObject, 00746 IN BOOLEAN Wait, 00747 IN PVOID InputBuffer, 00748 IN ULONG InputBufferLength, 00749 OUT PVOID OutputBuffer, 00750 IN ULONG OutputBufferLength, 00751 IN ULONG IoControlCode, 00752 OUT PIO_STATUS_BLOCK StatusBlock, 00753 IN PDEVICE_OBJECT DeviceObject) 00754 { 00755 return FALSE; 00756 } 00757 00758 BOOLEAN 00759 NTAPI 00760 CPortPinWavePci::FastRead( 00761 IN PFILE_OBJECT FileObject, 00762 IN PLARGE_INTEGER FileOffset, 00763 IN ULONG Length, 00764 IN BOOLEAN Wait, 00765 IN ULONG LockKey, 00766 IN PVOID Buffer, 00767 OUT PIO_STATUS_BLOCK StatusBlock, 00768 IN PDEVICE_OBJECT DeviceObject) 00769 { 00770 return FALSE; 00771 } 00772 00773 BOOLEAN 00774 NTAPI 00775 CPortPinWavePci::FastWrite( 00776 IN PFILE_OBJECT FileObject, 00777 IN PLARGE_INTEGER FileOffset, 00778 IN ULONG Length, 00779 IN BOOLEAN Wait, 00780 IN ULONG LockKey, 00781 IN PVOID Buffer, 00782 OUT PIO_STATUS_BLOCK StatusBlock, 00783 IN PDEVICE_OBJECT DeviceObject) 00784 { 00785 return FALSE; 00786 } 00787 00788 00789 NTSTATUS 00790 NTAPI 00791 CPortPinWavePci::Init( 00792 IN PPORTWAVEPCI Port, 00793 IN PPORTFILTERWAVEPCI Filter, 00794 IN KSPIN_CONNECT * ConnectDetails, 00795 IN KSPIN_DESCRIPTOR * KsPinDescriptor, 00796 IN PDEVICE_OBJECT DeviceObject) 00797 { 00798 NTSTATUS Status; 00799 PKSDATAFORMAT DataFormat; 00800 BOOLEAN Capture; 00801 ISubdevice * Subdevice = NULL; 00802 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; 00803 00804 // check if it is a source / sink pin 00805 if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) 00806 { 00807 // sink pin 00808 Capture = FALSE; 00809 } 00810 else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) 00811 { 00812 // source pin 00813 Capture = TRUE; 00814 } 00815 else 00816 { 00817 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); 00818 DbgBreakPoint(); 00819 while(TRUE); 00820 } 00821 00822 // add port / filter reference 00823 Port->AddRef(); 00824 Filter->AddRef(); 00825 00826 // initialize pin 00827 m_Port = Port; 00828 m_Filter = Filter; 00829 m_KsPinDescriptor = KsPinDescriptor; 00830 m_ConnectDetails = ConnectDetails; 00831 m_Miniport = GetWavePciMiniport(Port); 00832 m_DeviceObject = DeviceObject; 00833 m_State = KSSTATE_STOP; 00834 m_Capture = Capture; 00835 00836 DPRINT("IPortPinWavePci_fnInit entered\n"); 00837 00838 // get dataformat 00839 DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); 00840 00841 // allocate data format 00842 m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 00843 if (!m_Format) 00844 { 00845 // release references 00846 m_Port->Release(); 00847 m_Filter->Release(); 00848 00849 // no dangling pointers 00850 Port = NULL; 00851 Filter = NULL; 00852 00853 // failed to allocate data format 00854 return STATUS_INSUFFICIENT_RESOURCES; 00855 } 00856 00857 // copy data format 00858 RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); 00859 00860 // allocate new stream 00861 Status = m_Miniport->NewStream(&m_Stream, 00862 NULL, 00863 NonPagedPool, 00864 PPORTWAVEPCISTREAM(this), 00865 ConnectDetails->PinId, 00866 Capture, 00867 m_Format, 00868 &m_DmaChannel, 00869 &m_ServiceGroup); 00870 00871 DPRINT("IPortPinWavePci_fnInit Status %x\n", Status); 00872 00873 if (!NT_SUCCESS(Status)) 00874 { 00875 // free references 00876 Port->Release(); 00877 Filter->Release(); 00878 00879 // free data format 00880 FreeItem(m_Format, TAG_PORTCLASS); 00881 00882 // no dangling pointers 00883 m_Port = NULL; 00884 m_Filter = NULL; 00885 m_Format = NULL; 00886 00887 // failed to allocate stream 00888 return Status; 00889 } 00890 00891 // get allocator requirements for pin 00892 Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming); 00893 if (NT_SUCCESS(Status)) 00894 { 00895 DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n", 00896 m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); 00897 } 00898 00899 // allocate new irp queue 00900 Status = NewIrpQueue(&m_IrpQueue); 00901 if (!NT_SUCCESS(Status)) 00902 { 00903 // free references 00904 Port->Release(); 00905 Filter->Release(); 00906 m_Stream->Release(); 00907 00908 // free data format 00909 FreeItem(m_Format, TAG_PORTCLASS); 00910 00911 // no dangling pointers 00912 m_Port = NULL; 00913 m_Filter = NULL; 00914 m_Format = NULL; 00915 m_Stream = NULL; 00916 00917 // failed to allocate irp queue 00918 return Status; 00919 } 00920 00921 // initialize irp queue 00922 Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, TRUE); 00923 if (!NT_SUCCESS(Status)) 00924 { 00925 // this should never happen 00926 ASSERT(0); 00927 } 00928 00929 // get subdevice interface 00930 Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); 00931 00932 if (!NT_SUCCESS(Status)) 00933 { 00934 // this function should never fail 00935 ASSERT(0); 00936 } 00937 00938 // get subdevice descriptor 00939 Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); 00940 if (!NT_SUCCESS(Status)) 00941 { 00942 // this function should never fail 00943 ASSERT(0); 00944 } 00945 00946 // release subdevice 00947 Subdevice->Release(); 00948 00949 /* set up subdevice descriptor */ 00950 RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); 00951 m_Descriptor.FilterPropertySet = PinWavePciPropertySet; 00952 m_Descriptor.FilterPropertySetCount = sizeof(PinWavePciPropertySet) / sizeof(KSPROPERTY_SET); 00953 m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream; 00954 m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; 00955 m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; 00956 m_Descriptor.PortPin = (PVOID)this; 00957 00958 if (m_ServiceGroup) 00959 { 00960 Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); 00961 if (!NT_SUCCESS(Status)) 00962 { 00963 // free references 00964 m_Stream->Release(); 00965 Port->Release(); 00966 Filter->Release(); 00967 00968 // free data format 00969 FreeItem(m_Format, TAG_PORTCLASS); 00970 00971 // no dangling pointers 00972 m_Stream = NULL; 00973 m_Port = NULL; 00974 m_Filter = NULL; 00975 m_Format = NULL; 00976 00977 // failed to add to service group 00978 return Status; 00979 } 00980 } 00981 00982 00983 return STATUS_SUCCESS; 00984 } 00985 00986 PVOID 00987 NTAPI 00988 CPortPinWavePci::GetIrpStream() 00989 { 00990 return (PVOID)m_IrpQueue; 00991 } 00992 00993 00994 PMINIPORT 00995 NTAPI 00996 CPortPinWavePci::GetMiniport() 00997 { 00998 return (PMINIPORT)m_Miniport; 00999 } 01000 01001 01002 NTSTATUS 01003 NewPortPinWavePci( 01004 OUT IPortPinWavePci ** OutPin) 01005 { 01006 CPortPinWavePci * This; 01007 01008 This = new(NonPagedPool, TAG_PORTCLASS) CPortPinWavePci(NULL); 01009 if (!This) 01010 return STATUS_INSUFFICIENT_RESOURCES; 01011 01012 This->AddRef(); 01013 01014 // store result 01015 *OutPin = (IPortPinWavePci*)This; 01016 01017 return STATUS_SUCCESS; 01018 } 01019 Generated on Sat May 26 2012 04:27:10 for ReactOS by
1.7.6.1
|