Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpin_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/pin_wavecyclic.cpp 00005 * PURPOSE: WaveCyclic IRP Audio Pin 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "private.hpp" 00010 00011 class CPortPinWaveCyclic : public IPortPinWaveCyclic, 00012 public IServiceSink 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_IPortPinWaveCyclic; 00034 IMP_IServiceSink; 00035 CPortPinWaveCyclic(IUnknown *OuterUnknown){} 00036 virtual ~CPortPinWaveCyclic(){} 00037 00038 protected: 00039 00040 VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount); 00041 VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount); 00042 VOID GeneratePositionEvents(IN ULONGLONG OldOffset, IN ULONGLONG NewOffset); 00043 00044 friend NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00045 friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00046 friend NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00047 friend NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00048 friend NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 00049 friend NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 00050 friend VOID CALLBACK PinSetStateWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); 00051 00052 IPortWaveCyclic * m_Port; 00053 IPortFilterWaveCyclic * m_Filter; 00054 KSPIN_DESCRIPTOR * m_KsPinDescriptor; 00055 PMINIPORTWAVECYCLIC m_Miniport; 00056 PSERVICEGROUP m_ServiceGroup; 00057 PDMACHANNEL m_DmaChannel; 00058 PMINIPORTWAVECYCLICSTREAM m_Stream; 00059 KSSTATE m_State; 00060 PKSDATAFORMAT m_Format; 00061 PKSPIN_CONNECT m_ConnectDetails; 00062 00063 PVOID m_CommonBuffer; 00064 ULONG m_CommonBufferSize; 00065 ULONG m_CommonBufferOffset; 00066 00067 IIrpQueue * m_IrpQueue; 00068 00069 ULONG m_FrameSize; 00070 BOOL m_Capture; 00071 00072 ULONG m_TotalPackets; 00073 ULONG m_StopCount; 00074 KSAUDIO_POSITION m_Position; 00075 KSALLOCATOR_FRAMING m_AllocatorFraming; 00076 PSUBDEVICE_DESCRIPTOR m_Descriptor; 00077 00078 KSPIN_LOCK m_EventListLock; 00079 LIST_ENTRY m_EventList; 00080 00081 KSRESET m_ResetState; 00082 00083 ULONG m_Delay; 00084 00085 LONG m_Ref; 00086 }; 00087 00088 00089 typedef struct 00090 { 00091 ULONG bLoopedStreaming; 00092 ULONGLONG Position; 00093 }LOOPEDSTREAMING_EVENT_CONTEXT, *PLOOPEDSTREAMING_EVENT_CONTEXT; 00094 00095 typedef struct 00096 { 00097 ULONG bLoopedStreaming; 00098 }ENDOFSTREAM_EVENT_CONTEXT, *PENDOFSTREAM_EVENT_CONTEXT; 00099 00100 00101 00102 NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00103 NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00104 NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00105 NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00106 NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 00107 NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 00108 NTSTATUS NTAPI PinWaveCyclicDRMHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 00109 00110 00111 DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming); 00112 DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition); 00113 DEFINE_KSPROPERTY_DRMSET(PinWaveCyclicDRMSet, PinWaveCyclicDRMHandler); 00114 00115 KSEVENT_ITEM PinWaveCyclicConnectionEventSet = 00116 { 00117 KSEVENT_CONNECTION_ENDOFSTREAM, 00118 sizeof(KSEVENTDATA), 00119 sizeof(ENDOFSTREAM_EVENT_CONTEXT), 00120 PinWaveCyclicAddEndOfStreamEvent, 00121 0, 00122 0 00123 }; 00124 00125 KSEVENT_ITEM PinWaveCyclicStreamingEventSet = 00126 { 00127 KSEVENT_LOOPEDSTREAMING_POSITION, 00128 sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA), 00129 sizeof(LOOPEDSTREAMING_EVENT_CONTEXT), 00130 PinWaveCyclicAddLoopedStreamEvent, 00131 0, 00132 0 00133 }; 00134 00135 00136 KSPROPERTY_SET PinWaveCyclicPropertySet[] = 00137 { 00138 { 00139 &KSPROPSETID_Connection, 00140 sizeof(PinWaveCyclicConnectionSet) / sizeof(KSPROPERTY_ITEM), 00141 (const KSPROPERTY_ITEM*)&PinWaveCyclicConnectionSet, 00142 0, 00143 NULL 00144 }, 00145 { 00146 &KSPROPSETID_Audio, 00147 sizeof(PinWaveCyclicAudioSet) / sizeof(KSPROPERTY_ITEM), 00148 (const KSPROPERTY_ITEM*)&PinWaveCyclicAudioSet, 00149 0, 00150 NULL 00151 }, 00152 { 00153 &KSPROPSETID_DrmAudioStream, 00154 sizeof(PinWaveCyclicDRMSet) / sizeof(KSPROPERTY_ITEM), 00155 (const KSPROPERTY_ITEM*)&PinWaveCyclicDRMSet, 00156 0, 00157 NULL 00158 } 00159 }; 00160 00161 KSEVENT_SET PinWaveCyclicEventSet[] = 00162 { 00163 { 00164 &KSEVENTSETID_LoopedStreaming, 00165 sizeof(PinWaveCyclicStreamingEventSet) / sizeof(KSEVENT_ITEM), 00166 (const KSEVENT_ITEM*)&PinWaveCyclicStreamingEventSet 00167 }, 00168 { 00169 &KSEVENTSETID_Connection, 00170 sizeof(PinWaveCyclicConnectionEventSet) / sizeof(KSEVENT_ITEM), 00171 (const KSEVENT_ITEM*)&PinWaveCyclicConnectionEventSet 00172 } 00173 }; 00174 00175 00176 //================================================================================================================================== 00177 00178 NTSTATUS 00179 NTAPI 00180 CPortPinWaveCyclic::QueryInterface( 00181 IN REFIID refiid, 00182 OUT PVOID* Output) 00183 { 00184 DPRINT("IServiceSink_fnQueryInterface entered\n"); 00185 00186 if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || 00187 IsEqualGUIDAligned(refiid, IID_IUnknown)) 00188 { 00189 *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); 00190 PUNKNOWN(*Output)->AddRef(); 00191 return STATUS_SUCCESS; 00192 } 00193 00194 if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) 00195 { 00196 *Output = PVOID(PUNKNOWN(PSERVICESINK(this))); 00197 PUNKNOWN(*Output)->AddRef(); 00198 return STATUS_SUCCESS; 00199 } 00200 00201 return STATUS_UNSUCCESSFUL; 00202 } 00203 00204 NTSTATUS 00205 NTAPI 00206 PinWaveCyclicDRMHandler( 00207 IN PIRP Irp, 00208 IN PKSIDENTIFIER Request, 00209 IN OUT PVOID Data) 00210 { 00211 DPRINT1("PinWaveCyclicDRMHandler\n"); 00212 ASSERT(0); 00213 return STATUS_INVALID_PARAMETER; 00214 } 00215 00216 00217 NTSTATUS 00218 NTAPI 00219 PinWaveCyclicAddEndOfStreamEvent( 00220 IN PIRP Irp, 00221 IN PKSEVENTDATA EventData, 00222 IN PKSEVENT_ENTRY EventEntry) 00223 { 00224 PENDOFSTREAM_EVENT_CONTEXT Entry; 00225 PSUBDEVICE_DESCRIPTOR Descriptor; 00226 CPortPinWaveCyclic *Pin; 00227 00228 // get sub device descriptor 00229 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00230 00231 // sanity check 00232 PC_ASSERT(Descriptor); 00233 PC_ASSERT(Descriptor->PortPin); 00234 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00235 00236 // cast to pin impl 00237 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 00238 00239 // get extra size 00240 Entry = (PENDOFSTREAM_EVENT_CONTEXT)(EventEntry + 1); 00241 00242 // not a looped event 00243 Entry->bLoopedStreaming = FALSE; 00244 00245 // insert item 00246 (void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock); 00247 00248 // done 00249 return STATUS_SUCCESS; 00250 } 00251 00252 NTSTATUS 00253 NTAPI 00254 PinWaveCyclicAddLoopedStreamEvent( 00255 IN PIRP Irp, 00256 IN PKSEVENTDATA EventData, 00257 IN PKSEVENT_ENTRY EventEntry) 00258 { 00259 PLOOPEDSTREAMING_POSITION_EVENT_DATA Data; 00260 PLOOPEDSTREAMING_EVENT_CONTEXT Entry; 00261 PSUBDEVICE_DESCRIPTOR Descriptor; 00262 CPortPinWaveCyclic *Pin; 00263 00264 // get sub device descriptor 00265 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp); 00266 00267 // sanity check 00268 PC_ASSERT(Descriptor); 00269 PC_ASSERT(Descriptor->PortPin); 00270 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00271 00272 // cast to pin impl 00273 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 00274 00275 // cast to looped event 00276 Data = (PLOOPEDSTREAMING_POSITION_EVENT_DATA)EventData; 00277 00278 // get extra size 00279 Entry = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1); 00280 00281 Entry->bLoopedStreaming = TRUE; 00282 Entry->Position = Data->Position; 00283 00284 DPRINT1("Added event\n"); 00285 00286 // insert item 00287 (void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock); 00288 00289 // done 00290 return STATUS_SUCCESS; 00291 } 00292 00293 NTSTATUS 00294 NTAPI 00295 PinWaveCyclicAllocatorFraming( 00296 IN PIRP Irp, 00297 IN PKSIDENTIFIER Request, 00298 IN OUT PVOID Data) 00299 { 00300 CPortPinWaveCyclic *Pin; 00301 PSUBDEVICE_DESCRIPTOR Descriptor; 00302 00303 // get sub device descriptor 00304 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp); 00305 00306 // sanity check 00307 PC_ASSERT(Descriptor); 00308 PC_ASSERT(Descriptor->PortPin); 00309 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00310 00311 // cast to pin impl 00312 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 00313 00314 00315 if (Request->Flags & KSPROPERTY_TYPE_GET) 00316 { 00317 // copy pin framing 00318 RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); 00319 00320 Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); 00321 return STATUS_SUCCESS; 00322 } 00323 00324 // not supported 00325 return STATUS_NOT_SUPPORTED; 00326 } 00327 00328 NTSTATUS 00329 NTAPI 00330 PinWaveCyclicAudioPosition( 00331 IN PIRP Irp, 00332 IN PKSIDENTIFIER Request, 00333 IN OUT PVOID Data) 00334 { 00335 CPortPinWaveCyclic *Pin; 00336 PSUBDEVICE_DESCRIPTOR Descriptor; 00337 PKSAUDIO_POSITION Position; 00338 00339 // get sub device descriptor 00340 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00341 00342 // sanity check 00343 PC_ASSERT(Descriptor); 00344 PC_ASSERT(Descriptor->PortPin); 00345 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00346 00347 // cast to pin impl 00348 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 00349 00350 //sanity check 00351 PC_ASSERT(Pin->m_Stream); 00352 00353 if (Request->Flags & KSPROPERTY_TYPE_GET) 00354 { 00355 // FIXME non multithreading-safe 00356 // copy audio position 00357 00358 Position = (PKSAUDIO_POSITION)Data; 00359 00360 if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_STREAMING) 00361 { 00362 RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); 00363 DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); 00364 } 00365 else if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 00366 { 00367 Position->PlayOffset = Pin->m_Position.PlayOffset; 00368 Position->WriteOffset = (ULONGLONG)Pin->m_IrpQueue->GetCurrentIrpOffset(); 00369 DPRINT("Play %lu Write %lu\n", Position->PlayOffset, Position->WriteOffset); 00370 } 00371 00372 Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); 00373 return STATUS_SUCCESS; 00374 } 00375 00376 // not supported 00377 return STATUS_NOT_SUPPORTED; 00378 } 00379 00380 typedef struct 00381 { 00382 CPortPinWaveCyclic *Pin; 00383 KSSTATE NewState; 00384 PIO_WORKITEM WorkItem; 00385 PIRP Irp; 00386 00387 }SETPIN_CONTEXT, *PSETPIN_CONTEXT; 00388 00389 VOID 00390 CALLBACK 00391 PinSetStateWorkerRoutine( 00392 IN PDEVICE_OBJECT DeviceObject, 00393 IN PVOID Context) 00394 { 00395 PSETPIN_CONTEXT PinWorkContext = (PSETPIN_CONTEXT)Context; 00396 NTSTATUS Status; 00397 00398 // try set stream 00399 Status = PinWorkContext->Pin->m_Stream->SetState(PinWorkContext->NewState); 00400 00401 DPRINT1("Setting state %u %x\n", PinWorkContext->NewState, Status); 00402 if (NT_SUCCESS(Status)) 00403 { 00404 // store new state 00405 PinWorkContext->Pin->m_State = PinWorkContext->NewState; 00406 00407 if (PinWorkContext->Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && PinWorkContext->Pin->m_State == KSSTATE_STOP) 00408 { 00409 /* FIXME complete pending irps with successfull state */ 00410 PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); 00411 } 00412 //HACK 00413 //PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); 00414 } 00415 00416 // store result 00417 PinWorkContext->Irp->IoStatus.Information = sizeof(KSSTATE); 00418 PinWorkContext->Irp->IoStatus.Status = Status; 00419 00420 // complete irp 00421 IoCompleteRequest(PinWorkContext->Irp, IO_NO_INCREMENT); 00422 00423 // free work item 00424 IoFreeWorkItem(PinWorkContext->WorkItem); 00425 00426 // free work context 00427 FreeItem(PinWorkContext, TAG_PORTCLASS); 00428 00429 } 00430 00431 00432 NTSTATUS 00433 NTAPI 00434 PinWaveCyclicState( 00435 IN PIRP Irp, 00436 IN PKSIDENTIFIER Request, 00437 IN OUT PVOID Data) 00438 { 00439 NTSTATUS Status = STATUS_UNSUCCESSFUL; 00440 CPortPinWaveCyclic *Pin; 00441 PSUBDEVICE_DESCRIPTOR Descriptor; 00442 PKSSTATE State = (PKSSTATE)Data; 00443 00444 // get sub device descriptor 00445 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00446 00447 // sanity check 00448 PC_ASSERT(Descriptor); 00449 PC_ASSERT(Descriptor->PortPin); 00450 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00451 00452 // cast to pin impl 00453 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 00454 00455 //sanity check 00456 PC_ASSERT(Pin->m_Stream); 00457 00458 if (Request->Flags & KSPROPERTY_TYPE_SET) 00459 { 00460 // try set stream 00461 Status = Pin->m_Stream->SetState(*State); 00462 00463 DPRINT("Setting state %u %x\n", *State, Status); 00464 if (NT_SUCCESS(Status)) 00465 { 00466 // store new state 00467 Pin->m_State = *State; 00468 00469 if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP) 00470 { 00471 // FIXME 00472 // complete with successful state 00473 Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); 00474 Pin->m_IrpQueue->CancelBuffers(); 00475 Pin->m_Position.PlayOffset = 0; 00476 Pin->m_Position.WriteOffset = 0; 00477 } 00478 else if (Pin->m_State == KSSTATE_STOP) 00479 { 00480 Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); 00481 Pin->m_IrpQueue->CancelBuffers(); 00482 Pin->m_Position.PlayOffset = 0; 00483 Pin->m_Position.WriteOffset = 0; 00484 } 00485 // store result 00486 Irp->IoStatus.Information = sizeof(KSSTATE); 00487 } 00488 return Status; 00489 } 00490 else if (Request->Flags & KSPROPERTY_TYPE_GET) 00491 { 00492 // get current stream state 00493 *State = Pin->m_State; 00494 // store result 00495 Irp->IoStatus.Information = sizeof(KSSTATE); 00496 00497 return STATUS_SUCCESS; 00498 } 00499 00500 // unsupported request 00501 return STATUS_NOT_SUPPORTED; 00502 } 00503 00504 NTSTATUS 00505 NTAPI 00506 PinWaveCyclicDataFormat( 00507 IN PIRP Irp, 00508 IN PKSIDENTIFIER Request, 00509 IN OUT PVOID Data) 00510 { 00511 NTSTATUS Status = STATUS_UNSUCCESSFUL; 00512 CPortPinWaveCyclic *Pin; 00513 PSUBDEVICE_DESCRIPTOR Descriptor; 00514 PIO_STACK_LOCATION IoStack; 00515 00516 // get current irp stack location 00517 IoStack = IoGetCurrentIrpStackLocation(Irp); 00518 00519 // get sub device descriptor 00520 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 00521 00522 // sanity check 00523 PC_ASSERT(Descriptor); 00524 PC_ASSERT(Descriptor->PortPin); 00525 00526 // cast to pin impl 00527 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 00528 00529 //sanity check 00530 PC_ASSERT(Pin->m_Stream); 00531 PC_ASSERT(Pin->m_Format); 00532 00533 if (Request->Flags & KSPROPERTY_TYPE_SET) 00534 { 00535 // try to change data format 00536 PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; 00537 ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize); 00538 00539 if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size) 00540 { 00541 // format is identical 00542 Irp->IoStatus.Information = DataFormat->FormatSize; 00543 return STATUS_SUCCESS; 00544 } 00545 00546 // new change request 00547 PC_ASSERT(Pin->m_State != KSSTATE_RUN); 00548 // FIXME queue a work item when Irql != PASSIVE_LEVEL 00549 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 00550 00551 // allocate new data format 00552 NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 00553 if (!NewDataFormat) 00554 { 00555 // not enough memory 00556 return STATUS_NO_MEMORY; 00557 } 00558 00559 // copy new data format 00560 RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); 00561 00562 // set new format 00563 Status = Pin->m_Stream->SetFormat(NewDataFormat); 00564 if (NT_SUCCESS(Status)) 00565 { 00566 // free old format 00567 FreeItem(Pin->m_Format, TAG_PORTCLASS); 00568 00569 // store new format 00570 Pin->m_Format = NewDataFormat; 00571 Irp->IoStatus.Information = NewDataFormat->FormatSize; 00572 00573 #if 0 00574 PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); 00575 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); 00576 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); 00577 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); 00578 00579 00580 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, 00581 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, 00582 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); 00583 #endif 00584 00585 } 00586 else 00587 { 00588 // failed to set format 00589 FreeItem(NewDataFormat, TAG_PORTCLASS); 00590 } 00591 00592 00593 // done 00594 return Status; 00595 } 00596 else if (Request->Flags & KSPROPERTY_TYPE_GET) 00597 { 00598 // get current data format 00599 PC_ASSERT(Pin->m_Format); 00600 00601 if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) 00602 { 00603 // buffer too small 00604 Irp->IoStatus.Information = Pin->m_Format->FormatSize; 00605 return STATUS_MORE_ENTRIES; 00606 } 00607 // copy data format 00608 RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize); 00609 // store result size 00610 Irp->IoStatus.Information = Pin->m_Format->FormatSize; 00611 00612 // done 00613 return STATUS_SUCCESS; 00614 } 00615 00616 // unsupported request 00617 return STATUS_NOT_SUPPORTED; 00618 } 00619 00620 VOID 00621 CPortPinWaveCyclic::GeneratePositionEvents( 00622 IN ULONGLONG OldOffset, 00623 IN ULONGLONG NewOffset) 00624 { 00625 PLIST_ENTRY Entry; 00626 PKSEVENT_ENTRY EventEntry; 00627 PLOOPEDSTREAMING_EVENT_CONTEXT Context; 00628 00629 // acquire event lock 00630 KeAcquireSpinLockAtDpcLevel(&m_EventListLock); 00631 00632 // point to first entry 00633 Entry = m_EventList.Flink; 00634 00635 while(Entry != &m_EventList) 00636 { 00637 // get event entry 00638 EventEntry = (PKSEVENT_ENTRY)CONTAINING_RECORD(Entry, KSEVENT_ENTRY, ListEntry); 00639 00640 // get event entry context 00641 Context = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1); 00642 00643 if (Context->bLoopedStreaming == TRUE) 00644 { 00645 if (NewOffset > OldOffset) 00646 { 00647 /* buffer progress no overlap */ 00648 if (OldOffset < Context->Position && Context->Position <= NewOffset) 00649 { 00650 /* when someone eventually fixes sprintf... */ 00651 DPRINT("Generating event at OldOffset %I64u\n", OldOffset); 00652 DPRINT("Context->Position %I64u\n", Context->Position); 00653 DPRINT("NewOffset %I64u\n", NewOffset); 00654 /* generate event */ 00655 KsGenerateEvent(EventEntry); 00656 } 00657 } 00658 else 00659 { 00660 /* buffer wrap-arround */ 00661 if (OldOffset < Context->Position || NewOffset > Context->Position) 00662 { 00663 /* when someone eventually fixes sprintf... */ 00664 DPRINT("Generating event at OldOffset %I64u\n", OldOffset); 00665 DPRINT("Context->Position %I64u\n", Context->Position); 00666 DPRINT("NewOffset %I64u\n", NewOffset); 00667 /* generate event */ 00668 KsGenerateEvent(EventEntry); 00669 } 00670 } 00671 } 00672 00673 // move to next entry 00674 Entry = Entry->Flink; 00675 } 00676 00677 // release lock 00678 KeReleaseSpinLockFromDpcLevel(&m_EventListLock); 00679 } 00680 00681 VOID 00682 CPortPinWaveCyclic::UpdateCommonBuffer( 00683 ULONG Position, 00684 ULONG MaxTransferCount) 00685 { 00686 ULONG BufferLength; 00687 ULONG BytesToCopy; 00688 ULONG BufferSize; 00689 ULONG Gap; 00690 PUCHAR Buffer; 00691 NTSTATUS Status; 00692 00693 BufferLength = Position - m_CommonBufferOffset; 00694 BufferLength = min(BufferLength, MaxTransferCount); 00695 00696 while(BufferLength) 00697 { 00698 Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); 00699 if (!NT_SUCCESS(Status)) 00700 { 00701 Gap = Position - m_CommonBufferOffset; 00702 if (Gap > BufferLength) 00703 { 00704 // insert silence samples 00705 DPRINT("Inserting Silence Buffer Offset %lu GapLength %lu\n", m_CommonBufferOffset, BufferLength); 00706 m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); 00707 00708 m_CommonBufferOffset += BufferLength; 00709 } 00710 break; 00711 } 00712 00713 BytesToCopy = min(BufferLength, BufferSize); 00714 00715 if (m_Capture) 00716 { 00717 m_DmaChannel->CopyFrom(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); 00718 } 00719 else 00720 { 00721 m_DmaChannel->CopyTo((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy); 00722 } 00723 00724 m_IrpQueue->UpdateMapping(BytesToCopy); 00725 m_CommonBufferOffset += BytesToCopy; 00726 00727 BufferLength -= BytesToCopy; 00728 m_Position.PlayOffset += BytesToCopy; 00729 00730 if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 00731 { 00732 if (m_Position.WriteOffset) 00733 { 00734 // normalize position 00735 m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; 00736 } 00737 } 00738 } 00739 } 00740 00741 VOID 00742 CPortPinWaveCyclic::UpdateCommonBufferOverlap( 00743 ULONG Position, 00744 ULONG MaxTransferCount) 00745 { 00746 ULONG BufferLength, Length, Gap; 00747 ULONG BytesToCopy; 00748 ULONG BufferSize; 00749 PUCHAR Buffer; 00750 NTSTATUS Status; 00751 00752 00753 BufferLength = Gap = m_CommonBufferSize - m_CommonBufferOffset; 00754 BufferLength = Length = min(BufferLength, MaxTransferCount); 00755 while(BufferLength) 00756 { 00757 Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); 00758 if (!NT_SUCCESS(Status)) 00759 { 00760 Gap = m_CommonBufferSize - m_CommonBufferOffset + Position; 00761 if (Gap > BufferLength) 00762 { 00763 // insert silence samples 00764 DPRINT("Overlap Inserting Silence Buffer Size %lu Offset %lu Gap %lu Position %lu\n", m_CommonBufferSize, m_CommonBufferOffset, Gap, Position); 00765 m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); 00766 00767 m_CommonBufferOffset += BufferLength; 00768 } 00769 break; 00770 } 00771 00772 BytesToCopy = min(BufferLength, BufferSize); 00773 00774 if (m_Capture) 00775 { 00776 m_DmaChannel->CopyFrom(Buffer, 00777 (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, 00778 BytesToCopy); 00779 } 00780 else 00781 { 00782 m_DmaChannel->CopyTo((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, 00783 Buffer, 00784 BytesToCopy); 00785 } 00786 00787 m_IrpQueue->UpdateMapping(BytesToCopy); 00788 m_CommonBufferOffset += BytesToCopy; 00789 m_Position.PlayOffset += BytesToCopy; 00790 00791 BufferLength -=BytesToCopy; 00792 00793 if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 00794 { 00795 if (m_Position.WriteOffset) 00796 { 00797 // normalize position 00798 m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; 00799 } 00800 } 00801 } 00802 00803 if (Gap == Length) 00804 { 00805 m_CommonBufferOffset = 0; 00806 00807 MaxTransferCount -= Length; 00808 00809 if (MaxTransferCount) 00810 { 00811 UpdateCommonBuffer(Position, MaxTransferCount); 00812 } 00813 } 00814 } 00815 00816 VOID 00817 NTAPI 00818 CPortPinWaveCyclic::RequestService() 00819 { 00820 ULONG Position; 00821 ULONGLONG OldOffset, NewOffset; 00822 00823 PC_ASSERT_IRQL(DISPATCH_LEVEL); 00824 00825 if (m_State == KSSTATE_RUN && m_ResetState == KSRESET_END) 00826 { 00827 m_Stream->GetPosition(&Position); 00828 00829 OldOffset = m_Position.PlayOffset; 00830 00831 if (Position < m_CommonBufferOffset) 00832 { 00833 UpdateCommonBufferOverlap(Position, m_FrameSize); 00834 } 00835 else if (Position >= m_CommonBufferOffset) 00836 { 00837 UpdateCommonBuffer(Position, m_FrameSize); 00838 } 00839 00840 NewOffset = m_Position.PlayOffset; 00841 00842 GeneratePositionEvents(OldOffset, NewOffset); 00843 } 00844 } 00845 00846 NTSTATUS 00847 NTAPI 00848 CPortPinWaveCyclic::NewIrpTarget( 00849 OUT struct IIrpTarget **OutTarget, 00850 IN PCWSTR Name, 00851 IN PUNKNOWN Unknown, 00852 IN POOL_TYPE PoolType, 00853 IN PDEVICE_OBJECT DeviceObject, 00854 IN PIRP Irp, 00855 IN KSOBJECT_CREATE *CreateObject) 00856 { 00857 UNIMPLEMENTED 00858 return STATUS_UNSUCCESSFUL; 00859 } 00860 00861 NTSTATUS 00862 NTAPI 00863 CPortPinWaveCyclic::DeviceIoControl( 00864 IN PDEVICE_OBJECT DeviceObject, 00865 IN PIRP Irp) 00866 { 00867 PIO_STACK_LOCATION IoStack; 00868 PKSPROPERTY Property; 00869 UNICODE_STRING GuidString; 00870 NTSTATUS Status = STATUS_NOT_SUPPORTED; 00871 ULONG Data = 0; 00872 KSRESET ResetValue; 00873 00874 /* get current irp stack location */ 00875 IoStack = IoGetCurrentIrpStackLocation(Irp); 00876 00877 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) 00878 { 00879 /* handle property with subdevice descriptor */ 00880 Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor); 00881 00882 if (Status == STATUS_NOT_FOUND) 00883 { 00884 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00885 00886 RtlStringFromGUID(Property->Set, &GuidString); 00887 DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); 00888 RtlFreeUnicodeString(&GuidString); 00889 } 00890 } 00891 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) 00892 { 00893 Status = PcHandleEnableEventWithTable(Irp, m_Descriptor); 00894 } 00895 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT) 00896 { 00897 Status = PcHandleDisableEventWithTable(Irp, m_Descriptor); 00898 } 00899 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) 00900 { 00901 Status = KsAcquireResetValue(Irp, &ResetValue); 00902 DPRINT("Status %x Value %u\n", Status, ResetValue); 00903 /* check for success */ 00904 if (NT_SUCCESS(Status)) 00905 { 00906 //determine state of reset request 00907 if (ResetValue == KSRESET_BEGIN) 00908 { 00909 // start reset procress 00910 // incoming read/write requests will be rejected 00911 m_ResetState = KSRESET_BEGIN; 00912 00913 // cancel existing buffers 00914 m_IrpQueue->CancelBuffers(); 00915 } 00916 else if (ResetValue == KSRESET_END) 00917 { 00918 // end of reset process 00919 m_ResetState = KSRESET_END; 00920 } 00921 } 00922 } 00923 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) 00924 { 00925 /* increment total number of packets */ 00926 InterlockedIncrement((PLONG)&m_TotalPackets); 00927 00928 DPRINT("New Packet Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); 00929 00930 /* is the device not currently reset */ 00931 if (m_ResetState == KSRESET_END) 00932 { 00933 /* add the mapping */ 00934 Status = m_IrpQueue->AddMapping(Irp, &Data); 00935 00936 /* check for success */ 00937 if (NT_SUCCESS(Status)) 00938 { 00939 m_Position.WriteOffset += Data; 00940 Status = STATUS_PENDING; 00941 } 00942 } 00943 else 00944 { 00945 /* reset request is currently in progress */ 00946 Status = STATUS_DEVICE_NOT_READY; 00947 DPRINT1("NotReady\n"); 00948 } 00949 } 00950 else 00951 { 00952 return KsDefaultDeviceIoCompletion(DeviceObject, Irp); 00953 } 00954 00955 if (Status != STATUS_PENDING) 00956 { 00957 Irp->IoStatus.Status = Status; 00958 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00959 } 00960 00961 return Status; 00962 } 00963 00964 NTSTATUS 00965 NTAPI 00966 CPortPinWaveCyclic::Read( 00967 IN PDEVICE_OBJECT DeviceObject, 00968 IN PIRP Irp) 00969 { 00970 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00971 } 00972 00973 NTSTATUS 00974 NTAPI 00975 CPortPinWaveCyclic::Write( 00976 IN PDEVICE_OBJECT DeviceObject, 00977 IN PIRP Irp) 00978 { 00979 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00980 } 00981 00982 NTSTATUS 00983 NTAPI 00984 CPortPinWaveCyclic::Flush( 00985 IN PDEVICE_OBJECT DeviceObject, 00986 IN PIRP Irp) 00987 { 00988 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 00989 } 00990 00991 NTSTATUS 00992 NTAPI 00993 CPortPinWaveCyclic::Close( 00994 IN PDEVICE_OBJECT DeviceObject, 00995 IN PIRP Irp) 00996 { 00997 DPRINT("CPortPinWaveCyclic::Close entered\n"); 00998 00999 PC_ASSERT_IRQL(PASSIVE_LEVEL); 01000 01001 if (m_Format) 01002 { 01003 // free format 01004 FreeItem(m_Format, TAG_PORTCLASS); 01005 01006 // format is freed 01007 m_Format = NULL; 01008 } 01009 01010 if (m_IrpQueue) 01011 { 01012 // cancel remaining irps 01013 m_IrpQueue->CancelBuffers(); 01014 01015 // release irp queue 01016 m_IrpQueue->Release(); 01017 01018 // queue is freed 01019 m_IrpQueue = NULL; 01020 } 01021 01022 if (m_ServiceGroup) 01023 { 01024 // remove member from service group 01025 m_ServiceGroup->RemoveMember(PSERVICESINK(this)); 01026 01027 // do not release service group, it is released by the miniport object 01028 m_ServiceGroup = NULL; 01029 } 01030 01031 if (m_Stream) 01032 { 01033 if (m_State != KSSTATE_STOP) 01034 { 01035 // stop stream 01036 NTSTATUS Status = m_Stream->SetState(KSSTATE_STOP); 01037 if (!NT_SUCCESS(Status)) 01038 { 01039 DPRINT("Warning: failed to stop stream with %x\n", Status); 01040 PC_ASSERT(0); 01041 } 01042 } 01043 // set state to stop 01044 m_State = KSSTATE_STOP; 01045 01046 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); 01047 01048 // release stream 01049 m_Stream->Release(); 01050 01051 // stream is now freed 01052 m_Stream = NULL; 01053 } 01054 01055 01056 if (m_Filter) 01057 { 01058 // disconnect pin from filter 01059 m_Filter->FreePin((PPORTPINWAVECYCLIC)this); 01060 01061 // release filter reference 01062 m_Filter->Release(); 01063 01064 // pin is done with filter 01065 m_Filter = NULL; 01066 } 01067 01068 if (m_Port) 01069 { 01070 // release reference to port driver 01071 m_Port->Release(); 01072 01073 // work is done for port 01074 m_Port = NULL; 01075 } 01076 01077 Irp->IoStatus.Information = 0; 01078 Irp->IoStatus.Status = STATUS_SUCCESS; 01079 IoCompleteRequest(Irp, IO_NO_INCREMENT); 01080 01081 delete this; 01082 01083 return STATUS_SUCCESS; 01084 } 01085 01086 NTSTATUS 01087 NTAPI 01088 CPortPinWaveCyclic::QuerySecurity( 01089 IN PDEVICE_OBJECT DeviceObject, 01090 IN PIRP Irp) 01091 { 01092 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 01093 } 01094 01095 NTSTATUS 01096 NTAPI 01097 CPortPinWaveCyclic::SetSecurity( 01098 IN PDEVICE_OBJECT DeviceObject, 01099 IN PIRP Irp) 01100 { 01101 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 01102 } 01103 01104 BOOLEAN 01105 NTAPI 01106 CPortPinWaveCyclic::FastDeviceIoControl( 01107 IN PFILE_OBJECT FileObject, 01108 IN BOOLEAN Wait, 01109 IN PVOID InputBuffer, 01110 IN ULONG InputBufferLength, 01111 OUT PVOID OutputBuffer, 01112 IN ULONG OutputBufferLength, 01113 IN ULONG IoControlCode, 01114 OUT PIO_STATUS_BLOCK StatusBlock, 01115 IN PDEVICE_OBJECT DeviceObject) 01116 { 01117 return KsDispatchFastIoDeviceControlFailure(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, StatusBlock, DeviceObject); 01118 } 01119 01120 01121 BOOLEAN 01122 NTAPI 01123 CPortPinWaveCyclic::FastRead( 01124 IN PFILE_OBJECT FileObject, 01125 IN PLARGE_INTEGER FileOffset, 01126 IN ULONG Length, 01127 IN BOOLEAN Wait, 01128 IN ULONG LockKey, 01129 IN PVOID Buffer, 01130 OUT PIO_STATUS_BLOCK StatusBlock, 01131 IN PDEVICE_OBJECT DeviceObject) 01132 { 01133 return KsDispatchFastReadFailure(FileObject, FileOffset, Length, Wait, LockKey, Buffer, StatusBlock, DeviceObject); 01134 } 01135 01136 01137 BOOLEAN 01138 NTAPI 01139 CPortPinWaveCyclic::FastWrite( 01140 IN PFILE_OBJECT FileObject, 01141 IN PLARGE_INTEGER FileOffset, 01142 IN ULONG Length, 01143 IN BOOLEAN Wait, 01144 IN ULONG LockKey, 01145 IN PVOID Buffer, 01146 OUT PIO_STATUS_BLOCK StatusBlock, 01147 IN PDEVICE_OBJECT DeviceObject) 01148 { 01149 return KsDispatchFastReadFailure(FileObject, FileOffset, Length, Wait, LockKey, Buffer, StatusBlock, DeviceObject); 01150 } 01151 01152 01153 NTSTATUS 01154 NTAPI 01155 CPortPinWaveCyclic::Init( 01156 IN PPORTWAVECYCLIC Port, 01157 IN PPORTFILTERWAVECYCLIC Filter, 01158 IN KSPIN_CONNECT * ConnectDetails, 01159 IN KSPIN_DESCRIPTOR * KsPinDescriptor) 01160 { 01161 NTSTATUS Status; 01162 PKSDATAFORMAT DataFormat; 01163 //PDEVICE_OBJECT DeviceObject; 01164 BOOLEAN Capture; 01165 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; 01166 //IDrmAudioStream * DrmAudio = NULL; 01167 01168 m_KsPinDescriptor = KsPinDescriptor; 01169 m_ConnectDetails = ConnectDetails; 01170 m_Miniport = GetWaveCyclicMiniport(Port); 01171 01172 //DeviceObject = GetDeviceObject(Port); 01173 01174 DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); 01175 01176 DPRINT("CPortPinWaveCyclic::Init entered Size %u\n", DataFormat->FormatSize); 01177 01178 Status = NewIrpQueue(&m_IrpQueue); 01179 if (!NT_SUCCESS(Status)) 01180 return Status; 01181 01182 if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) 01183 { 01184 Capture = FALSE; 01185 } 01186 else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) 01187 { 01188 Capture = TRUE; 01189 } 01190 else 01191 { 01192 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); 01193 DbgBreakPoint(); 01194 while(TRUE); 01195 } 01196 01197 01198 Status = m_Miniport->NewStream(&m_Stream, 01199 NULL, 01200 NonPagedPool, 01201 ConnectDetails->PinId, 01202 Capture, 01203 DataFormat, 01204 &m_DmaChannel, 01205 &m_ServiceGroup); 01206 #if 0 01207 Status = m_Stream->QueryInterface(IID_IDrmAudioStream, (PVOID*)&DrmAudio); 01208 if (NT_SUCCESS(Status)) 01209 { 01210 DRMRIGHTS DrmRights; 01211 DPRINT("Got IID_IDrmAudioStream interface %p\n", DrmAudio); 01212 01213 DrmRights.CopyProtect = FALSE; 01214 DrmRights.Reserved = 0; 01215 DrmRights.DigitalOutputDisable = FALSE; 01216 01217 Status = DrmAudio->SetContentId(1, &DrmRights); 01218 DPRINT("Status %x\n", Status); 01219 } 01220 #endif 01221 01222 DPRINT1("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture); 01223 01224 if (!NT_SUCCESS(Status)) 01225 return Status; 01226 01227 ISubdevice * Subdevice = NULL; 01228 // get subdevice interface 01229 Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); 01230 01231 if (!NT_SUCCESS(Status)) 01232 return Status; 01233 01234 Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); 01235 if (!NT_SUCCESS(Status)) 01236 { 01237 // failed to get descriptor 01238 Subdevice->Release(); 01239 return Status; 01240 } 01241 01242 /* initialize event management */ 01243 InitializeListHead(&m_EventList); 01244 KeInitializeSpinLock(&m_EventListLock); 01245 01246 Status = PcCreateSubdeviceDescriptor(&m_Descriptor, 01247 SubDeviceDescriptor->InterfaceCount, 01248 SubDeviceDescriptor->Interfaces, 01249 0, /* FIXME KSINTERFACE_STANDARD with KSINTERFACE_STANDARD_STREAMING / KSINTERFACE_STANDARD_LOOPED_STREAMING */ 01250 NULL, 01251 sizeof(PinWaveCyclicPropertySet) / sizeof(KSPROPERTY_SET), 01252 PinWaveCyclicPropertySet, 01253 0, 01254 0, 01255 0, 01256 NULL, 01257 sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET), 01258 PinWaveCyclicEventSet, 01259 SubDeviceDescriptor->DeviceDescriptor); 01260 01261 m_Descriptor->UnknownStream = (PUNKNOWN)m_Stream; 01262 m_Descriptor->UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; 01263 m_Descriptor->PortPin = (PVOID)this; 01264 m_Descriptor->EventList = &m_EventList; 01265 m_Descriptor->EventListLock = &m_EventListLock; 01266 01267 // initialize reset state 01268 m_ResetState = KSRESET_END; 01269 01270 // release subdevice descriptor 01271 Subdevice->Release(); 01272 01273 // add ourselves to service group 01274 Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); 01275 if (!NT_SUCCESS(Status)) 01276 { 01277 DPRINT("Failed to add pin to service group\n"); 01278 return Status; 01279 } 01280 01281 m_Stream->SetState(KSSTATE_STOP); 01282 m_State = KSSTATE_STOP; 01283 m_CommonBufferOffset = 0; 01284 m_CommonBufferSize = m_DmaChannel->AllocatedBufferSize(); 01285 m_CommonBuffer = m_DmaChannel->SystemAddress(); 01286 m_Capture = Capture; 01287 // delay of 10 milisec 01288 m_Delay = Int32x32To64(10, -10000); 01289 01290 // sanity checks 01291 PC_ASSERT(m_CommonBufferSize); 01292 PC_ASSERT(m_CommonBuffer); 01293 01294 Status = m_Stream->SetNotificationFreq(10, &m_FrameSize); 01295 PC_ASSERT(NT_SUCCESS(Status)); 01296 PC_ASSERT(m_FrameSize); 01297 01298 DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u CommonBufferSize %lu, CommonBuffer %p\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize, m_CommonBufferSize, m_DmaChannel->SystemAddress()); 01299 01300 01301 /* set up allocator framing */ 01302 m_AllocatorFraming.RequirementsFlags = KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY; 01303 m_AllocatorFraming.PoolType = NonPagedPool; 01304 m_AllocatorFraming.Frames = 8; 01305 m_AllocatorFraming.FileAlignment = FILE_64_BYTE_ALIGNMENT; 01306 m_AllocatorFraming.Reserved = 0; 01307 m_AllocatorFraming.FrameSize = m_FrameSize; 01308 01309 m_Stream->Silence(m_CommonBuffer, m_CommonBufferSize); 01310 01311 Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, m_FrameSize, 0, FALSE); 01312 if (!NT_SUCCESS(Status)) 01313 { 01314 m_IrpQueue->Release(); 01315 return Status; 01316 } 01317 01318 m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 01319 if (!m_Format) 01320 return STATUS_INSUFFICIENT_RESOURCES; 01321 01322 RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); 01323 01324 Port->AddRef(); 01325 Filter->AddRef(); 01326 01327 m_Port = Port; 01328 m_Filter = Filter; 01329 01330 return STATUS_SUCCESS; 01331 } 01332 01333 01334 ULONG 01335 NTAPI 01336 CPortPinWaveCyclic::GetCompletedPosition() 01337 { 01338 UNIMPLEMENTED; 01339 return 0; 01340 } 01341 01342 01343 ULONG 01344 NTAPI 01345 CPortPinWaveCyclic::GetCycleCount() 01346 { 01347 UNIMPLEMENTED; 01348 return 0; 01349 } 01350 01351 01352 ULONG 01353 NTAPI 01354 CPortPinWaveCyclic::GetDeviceBufferSize() 01355 { 01356 return m_CommonBufferSize; 01357 } 01358 01359 01360 PVOID 01361 NTAPI 01362 CPortPinWaveCyclic::GetIrpStream() 01363 { 01364 return (PVOID)m_IrpQueue; 01365 } 01366 01367 01368 PMINIPORT 01369 NTAPI 01370 CPortPinWaveCyclic::GetMiniport() 01371 { 01372 return (PMINIPORT)m_Miniport; 01373 } 01374 01375 01376 NTSTATUS 01377 NewPortPinWaveCyclic( 01378 OUT IPortPinWaveCyclic ** OutPin) 01379 { 01380 CPortPinWaveCyclic * This; 01381 01382 This = new(NonPagedPool, TAG_PORTCLASS)CPortPinWaveCyclic(NULL); 01383 if (!This) 01384 return STATUS_INSUFFICIENT_RESOURCES; 01385 01386 This->AddRef(); 01387 01388 // store result 01389 *OutPin = (IPortPinWaveCyclic*)This; 01390 01391 return STATUS_SUCCESS; 01392 } 01393 Generated on Sun May 27 2012 04:28:35 for ReactOS by
1.7.6.1
|