1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel Streaming 4 * FILE: drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp 5 * PURPOSE: WaveCyclic IRP Audio Pin 6 * PROGRAMMER: Johannes Anderwald 7 */ 8 9 #include "private.hpp" 10 11 #ifndef YDEBUG 12 #define NDEBUG 13 #endif 14 15 #include <debug.h> 16 17 class CPortPinWaveCyclic : public CUnknownImpl<IPortPinWaveCyclic, IServiceSink> 18 { 19 public: 20 inline 21 PVOID 22 operator new( 23 size_t Size, 24 POOL_TYPE PoolType, 25 ULONG Tag) 26 { 27 return ExAllocatePoolWithTag(PoolType, Size, Tag); 28 } 29 30 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 31 32 IMP_IPortPinWaveCyclic; 33 IMP_IServiceSink; 34 CPortPinWaveCyclic(IUnknown *OuterUnknown) : 35 m_Port(nullptr), 36 m_Filter(nullptr), 37 m_KsPinDescriptor(nullptr), 38 m_Miniport(nullptr), 39 m_ServiceGroup(nullptr), 40 m_DmaChannel(nullptr), 41 m_Stream(nullptr), 42 m_State(KSSTATE_STOP), 43 m_Format(nullptr), 44 m_ConnectDetails(nullptr), 45 m_CommonBuffer(nullptr), 46 m_CommonBufferSize(0), 47 m_CommonBufferOffset(0), 48 m_IrpQueue(nullptr), 49 m_FrameSize(0), 50 m_Capture(FALSE), 51 m_TotalPackets(0), 52 m_StopCount(0), 53 m_Position({0}), 54 m_AllocatorFraming({{0}}), 55 m_Descriptor(nullptr), 56 m_EventListLock(0), 57 m_EventList({nullptr}), 58 m_ResetState(KSRESET_BEGIN), 59 m_Delay(0) 60 { 61 } 62 virtual ~CPortPinWaveCyclic(){} 63 64 protected: 65 66 VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount); 67 VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount); 68 VOID GeneratePositionEvents(IN ULONGLONG OldOffset, IN ULONGLONG NewOffset); 69 70 friend NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 71 friend NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 72 friend NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 73 friend NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 74 friend NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 75 friend NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 76 friend VOID CALLBACK PinSetStateWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); 77 78 IPortWaveCyclic * m_Port; 79 IPortFilterWaveCyclic * m_Filter; 80 KSPIN_DESCRIPTOR * m_KsPinDescriptor; 81 PMINIPORTWAVECYCLIC m_Miniport; 82 PSERVICEGROUP m_ServiceGroup; 83 PDMACHANNEL m_DmaChannel; 84 PMINIPORTWAVECYCLICSTREAM m_Stream; 85 KSSTATE m_State; 86 PKSDATAFORMAT m_Format; 87 PKSPIN_CONNECT m_ConnectDetails; 88 89 PVOID m_CommonBuffer; 90 ULONG m_CommonBufferSize; 91 ULONG m_CommonBufferOffset; 92 93 IIrpQueue * m_IrpQueue; 94 95 ULONG m_FrameSize; 96 BOOL m_Capture; 97 98 ULONG m_TotalPackets; 99 ULONG m_StopCount; 100 KSAUDIO_POSITION m_Position; 101 KSALLOCATOR_FRAMING m_AllocatorFraming; 102 PSUBDEVICE_DESCRIPTOR m_Descriptor; 103 104 KSPIN_LOCK m_EventListLock; 105 LIST_ENTRY m_EventList; 106 107 KSRESET m_ResetState; 108 109 ULONG m_Delay; 110 }; 111 112 113 typedef struct 114 { 115 ULONG bLoopedStreaming; 116 ULONGLONG Position; 117 }LOOPEDSTREAMING_EVENT_CONTEXT, *PLOOPEDSTREAMING_EVENT_CONTEXT; 118 119 typedef struct 120 { 121 ULONG bLoopedStreaming; 122 }ENDOFSTREAM_EVENT_CONTEXT, *PENDOFSTREAM_EVENT_CONTEXT; 123 124 125 126 NTSTATUS NTAPI PinWaveCyclicState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 127 NTSTATUS NTAPI PinWaveCyclicDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 128 NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 129 NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 130 NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 131 NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); 132 NTSTATUS NTAPI PinWaveCyclicDRMHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); 133 134 135 DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming); 136 DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition); 137 DEFINE_KSPROPERTY_DRMSET(PinWaveCyclicDRMSet, PinWaveCyclicDRMHandler); 138 139 KSEVENT_ITEM PinWaveCyclicConnectionEventSet = 140 { 141 KSEVENT_CONNECTION_ENDOFSTREAM, 142 sizeof(KSEVENTDATA), 143 sizeof(ENDOFSTREAM_EVENT_CONTEXT), 144 PinWaveCyclicAddEndOfStreamEvent, 145 0, 146 0 147 }; 148 149 KSEVENT_ITEM PinWaveCyclicStreamingEventSet = 150 { 151 KSEVENT_LOOPEDSTREAMING_POSITION, 152 sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA), 153 sizeof(LOOPEDSTREAMING_EVENT_CONTEXT), 154 PinWaveCyclicAddLoopedStreamEvent, 155 0, 156 0 157 }; 158 159 160 KSPROPERTY_SET PinWaveCyclicPropertySet[] = 161 { 162 { 163 &KSPROPSETID_Connection, 164 sizeof(PinWaveCyclicConnectionSet) / sizeof(KSPROPERTY_ITEM), 165 (const KSPROPERTY_ITEM*)&PinWaveCyclicConnectionSet, 166 0, 167 NULL 168 }, 169 { 170 &KSPROPSETID_Audio, 171 sizeof(PinWaveCyclicAudioSet) / sizeof(KSPROPERTY_ITEM), 172 (const KSPROPERTY_ITEM*)&PinWaveCyclicAudioSet, 173 0, 174 NULL 175 }, 176 { 177 &KSPROPSETID_DrmAudioStream, 178 sizeof(PinWaveCyclicDRMSet) / sizeof(KSPROPERTY_ITEM), 179 (const KSPROPERTY_ITEM*)&PinWaveCyclicDRMSet, 180 0, 181 NULL 182 } 183 }; 184 185 KSEVENT_SET PinWaveCyclicEventSet[] = 186 { 187 { 188 &KSEVENTSETID_LoopedStreaming, 189 sizeof(PinWaveCyclicStreamingEventSet) / sizeof(KSEVENT_ITEM), 190 (const KSEVENT_ITEM*)&PinWaveCyclicStreamingEventSet 191 }, 192 { 193 &KSEVENTSETID_Connection, 194 sizeof(PinWaveCyclicConnectionEventSet) / sizeof(KSEVENT_ITEM), 195 (const KSEVENT_ITEM*)&PinWaveCyclicConnectionEventSet 196 } 197 }; 198 199 200 //================================================================================================================================== 201 202 NTSTATUS 203 NTAPI 204 CPortPinWaveCyclic::QueryInterface( 205 IN REFIID refiid, 206 OUT PVOID* Output) 207 { 208 DPRINT("IServiceSink_fnQueryInterface entered\n"); 209 210 if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || 211 IsEqualGUIDAligned(refiid, IID_IUnknown)) 212 { 213 *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); 214 PUNKNOWN(*Output)->AddRef(); 215 return STATUS_SUCCESS; 216 } 217 218 if (IsEqualGUIDAligned(refiid, IID_IServiceSink)) 219 { 220 *Output = PVOID(PUNKNOWN(PSERVICESINK(this))); 221 PUNKNOWN(*Output)->AddRef(); 222 return STATUS_SUCCESS; 223 } 224 225 return STATUS_UNSUCCESSFUL; 226 } 227 228 NTSTATUS 229 NTAPI 230 PinWaveCyclicDRMHandler( 231 IN PIRP Irp, 232 IN PKSIDENTIFIER Request, 233 IN OUT PVOID Data) 234 { 235 DPRINT1("PinWaveCyclicDRMHandler\n"); 236 ASSERT(0); 237 return STATUS_INVALID_PARAMETER; 238 } 239 240 241 NTSTATUS 242 NTAPI 243 PinWaveCyclicAddEndOfStreamEvent( 244 IN PIRP Irp, 245 IN PKSEVENTDATA EventData, 246 IN PKSEVENT_ENTRY EventEntry) 247 { 248 PENDOFSTREAM_EVENT_CONTEXT Entry; 249 PSUBDEVICE_DESCRIPTOR Descriptor; 250 CPortPinWaveCyclic *Pin; 251 252 // get sub device descriptor 253 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 254 255 // sanity check 256 PC_ASSERT(Descriptor); 257 PC_ASSERT(Descriptor->PortPin); 258 PC_ASSERT_IRQL(DISPATCH_LEVEL); 259 260 // cast to pin impl 261 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 262 263 // get extra size 264 Entry = (PENDOFSTREAM_EVENT_CONTEXT)(EventEntry + 1); 265 266 // not a looped event 267 Entry->bLoopedStreaming = FALSE; 268 269 // insert item 270 (void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock); 271 272 // done 273 return STATUS_SUCCESS; 274 } 275 276 NTSTATUS 277 NTAPI 278 PinWaveCyclicAddLoopedStreamEvent( 279 IN PIRP Irp, 280 IN PKSEVENTDATA EventData, 281 IN PKSEVENT_ENTRY EventEntry) 282 { 283 PLOOPEDSTREAMING_POSITION_EVENT_DATA Data; 284 PLOOPEDSTREAMING_EVENT_CONTEXT Entry; 285 PSUBDEVICE_DESCRIPTOR Descriptor; 286 CPortPinWaveCyclic *Pin; 287 288 // get sub device descriptor 289 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp); 290 291 // sanity check 292 PC_ASSERT(Descriptor); 293 PC_ASSERT(Descriptor->PortPin); 294 PC_ASSERT_IRQL(DISPATCH_LEVEL); 295 296 // cast to pin impl 297 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 298 299 // cast to looped event 300 Data = (PLOOPEDSTREAMING_POSITION_EVENT_DATA)EventData; 301 302 // get extra size 303 Entry = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1); 304 305 Entry->bLoopedStreaming = TRUE; 306 Entry->Position = Data->Position; 307 308 DPRINT1("Added event\n"); 309 310 // insert item 311 (void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock); 312 313 // done 314 return STATUS_SUCCESS; 315 } 316 317 NTSTATUS 318 NTAPI 319 PinWaveCyclicAllocatorFraming( 320 IN PIRP Irp, 321 IN PKSIDENTIFIER Request, 322 IN OUT PVOID Data) 323 { 324 CPortPinWaveCyclic *Pin; 325 PSUBDEVICE_DESCRIPTOR Descriptor; 326 327 // get sub device descriptor 328 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSEVENT_ITEM_IRP_STORAGE(Irp); 329 330 // sanity check 331 PC_ASSERT(Descriptor); 332 PC_ASSERT(Descriptor->PortPin); 333 PC_ASSERT_IRQL(DISPATCH_LEVEL); 334 335 // cast to pin impl 336 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 337 338 339 if (Request->Flags & KSPROPERTY_TYPE_GET) 340 { 341 // copy pin framing 342 RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); 343 344 Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); 345 return STATUS_SUCCESS; 346 } 347 348 // not supported 349 return STATUS_NOT_SUPPORTED; 350 } 351 352 NTSTATUS 353 NTAPI 354 PinWaveCyclicAudioPosition( 355 IN PIRP Irp, 356 IN PKSIDENTIFIER Request, 357 IN OUT PVOID Data) 358 { 359 CPortPinWaveCyclic *Pin; 360 PSUBDEVICE_DESCRIPTOR Descriptor; 361 PKSAUDIO_POSITION Position; 362 363 // get sub device descriptor 364 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 365 366 // sanity check 367 PC_ASSERT(Descriptor); 368 PC_ASSERT(Descriptor->PortPin); 369 PC_ASSERT_IRQL(DISPATCH_LEVEL); 370 371 // cast to pin impl 372 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 373 374 //sanity check 375 PC_ASSERT(Pin->m_Stream); 376 377 if (Request->Flags & KSPROPERTY_TYPE_GET) 378 { 379 // FIXME non multithreading-safe 380 // copy audio position 381 382 Position = (PKSAUDIO_POSITION)Data; 383 384 if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_STREAMING) 385 { 386 RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); 387 DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); 388 } 389 else if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 390 { 391 Position->PlayOffset = Pin->m_Position.PlayOffset; 392 Position->WriteOffset = (ULONGLONG)Pin->m_IrpQueue->GetCurrentIrpOffset(); 393 DPRINT("Play %lu Write %lu\n", Position->PlayOffset, Position->WriteOffset); 394 } 395 396 Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); 397 return STATUS_SUCCESS; 398 } 399 400 // not supported 401 return STATUS_NOT_SUPPORTED; 402 } 403 404 typedef struct 405 { 406 CPortPinWaveCyclic *Pin; 407 KSSTATE NewState; 408 PIO_WORKITEM WorkItem; 409 PIRP Irp; 410 411 }SETPIN_CONTEXT, *PSETPIN_CONTEXT; 412 413 VOID 414 CALLBACK 415 PinSetStateWorkerRoutine( 416 IN PDEVICE_OBJECT DeviceObject, 417 IN PVOID Context) 418 { 419 PSETPIN_CONTEXT PinWorkContext = (PSETPIN_CONTEXT)Context; 420 NTSTATUS Status; 421 422 // try set stream 423 Status = PinWorkContext->Pin->m_Stream->SetState(PinWorkContext->NewState); 424 425 DPRINT1("Setting state %u %x\n", PinWorkContext->NewState, Status); 426 if (NT_SUCCESS(Status)) 427 { 428 // store new state 429 PinWorkContext->Pin->m_State = PinWorkContext->NewState; 430 431 if (PinWorkContext->Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && PinWorkContext->Pin->m_State == KSSTATE_STOP) 432 { 433 /* FIXME complete pending irps with successful state */ 434 PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); 435 } 436 //HACK 437 //PinWorkContext->Pin->m_IrpQueue->CancelBuffers(); 438 } 439 440 // store result 441 PinWorkContext->Irp->IoStatus.Information = sizeof(KSSTATE); 442 PinWorkContext->Irp->IoStatus.Status = Status; 443 444 // complete irp 445 IoCompleteRequest(PinWorkContext->Irp, IO_NO_INCREMENT); 446 447 // free work item 448 IoFreeWorkItem(PinWorkContext->WorkItem); 449 450 // free work context 451 FreeItem(PinWorkContext, TAG_PORTCLASS); 452 453 } 454 455 456 NTSTATUS 457 NTAPI 458 PinWaveCyclicState( 459 IN PIRP Irp, 460 IN PKSIDENTIFIER Request, 461 IN OUT PVOID Data) 462 { 463 NTSTATUS Status = STATUS_UNSUCCESSFUL; 464 CPortPinWaveCyclic *Pin; 465 PSUBDEVICE_DESCRIPTOR Descriptor; 466 PKSSTATE State = (PKSSTATE)Data; 467 468 // get sub device descriptor 469 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 470 471 // sanity check 472 PC_ASSERT(Descriptor); 473 PC_ASSERT(Descriptor->PortPin); 474 PC_ASSERT_IRQL(DISPATCH_LEVEL); 475 476 // cast to pin impl 477 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 478 479 //sanity check 480 PC_ASSERT(Pin->m_Stream); 481 482 if (Request->Flags & KSPROPERTY_TYPE_SET) 483 { 484 // try set stream 485 Status = Pin->m_Stream->SetState(*State); 486 487 DPRINT("Setting state %u %x\n", *State, Status); 488 if (NT_SUCCESS(Status)) 489 { 490 // store new state 491 Pin->m_State = *State; 492 493 if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP) 494 { 495 // FIXME 496 // complete with successful state 497 Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); 498 Pin->m_IrpQueue->CancelBuffers(); 499 Pin->m_Position.PlayOffset = 0; 500 Pin->m_Position.WriteOffset = 0; 501 } 502 else if (Pin->m_State == KSSTATE_STOP) 503 { 504 Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); 505 Pin->m_IrpQueue->CancelBuffers(); 506 Pin->m_Position.PlayOffset = 0; 507 Pin->m_Position.WriteOffset = 0; 508 } 509 // store result 510 Irp->IoStatus.Information = sizeof(KSSTATE); 511 } 512 return Status; 513 } 514 else if (Request->Flags & KSPROPERTY_TYPE_GET) 515 { 516 // get current stream state 517 *State = Pin->m_State; 518 // store result 519 Irp->IoStatus.Information = sizeof(KSSTATE); 520 521 return STATUS_SUCCESS; 522 } 523 524 // unsupported request 525 return STATUS_NOT_SUPPORTED; 526 } 527 528 NTSTATUS 529 NTAPI 530 PinWaveCyclicDataFormat( 531 IN PIRP Irp, 532 IN PKSIDENTIFIER Request, 533 IN OUT PVOID Data) 534 { 535 NTSTATUS Status = STATUS_UNSUCCESSFUL; 536 CPortPinWaveCyclic *Pin; 537 PSUBDEVICE_DESCRIPTOR Descriptor; 538 PIO_STACK_LOCATION IoStack; 539 540 // get current irp stack location 541 IoStack = IoGetCurrentIrpStackLocation(Irp); 542 543 // get sub device descriptor 544 Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); 545 546 // sanity check 547 PC_ASSERT(Descriptor); 548 PC_ASSERT(Descriptor->PortPin); 549 550 // cast to pin impl 551 Pin = (CPortPinWaveCyclic*)Descriptor->PortPin; 552 553 //sanity check 554 PC_ASSERT(Pin->m_Stream); 555 PC_ASSERT(Pin->m_Format); 556 557 if (Request->Flags & KSPROPERTY_TYPE_SET) 558 { 559 // try to change data format 560 PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; 561 ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize); 562 563 if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size) 564 { 565 // format is identical 566 Irp->IoStatus.Information = DataFormat->FormatSize; 567 return STATUS_SUCCESS; 568 } 569 570 // new change request 571 PC_ASSERT(Pin->m_State != KSSTATE_RUN); 572 // FIXME queue a work item when Irql != PASSIVE_LEVEL 573 PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 574 575 // allocate new data format 576 NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 577 if (!NewDataFormat) 578 { 579 // not enough memory 580 return STATUS_NO_MEMORY; 581 } 582 583 // copy new data format 584 RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); 585 586 // set new format 587 Status = Pin->m_Stream->SetFormat(NewDataFormat); 588 if (NT_SUCCESS(Status)) 589 { 590 // free old format 591 FreeItem(Pin->m_Format, TAG_PORTCLASS); 592 593 // store new format 594 Pin->m_Format = NewDataFormat; 595 Irp->IoStatus.Information = NewDataFormat->FormatSize; 596 597 #if 0 598 PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); 599 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); 600 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); 601 PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); 602 603 604 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, 605 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, 606 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); 607 #endif 608 609 } 610 else 611 { 612 // failed to set format 613 FreeItem(NewDataFormat, TAG_PORTCLASS); 614 } 615 616 617 // done 618 return Status; 619 } 620 else if (Request->Flags & KSPROPERTY_TYPE_GET) 621 { 622 // get current data format 623 PC_ASSERT(Pin->m_Format); 624 625 if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) 626 { 627 // buffer too small 628 Irp->IoStatus.Information = Pin->m_Format->FormatSize; 629 return STATUS_MORE_ENTRIES; 630 } 631 // copy data format 632 RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize); 633 // store result size 634 Irp->IoStatus.Information = Pin->m_Format->FormatSize; 635 636 // done 637 return STATUS_SUCCESS; 638 } 639 640 // unsupported request 641 return STATUS_NOT_SUPPORTED; 642 } 643 644 VOID 645 CPortPinWaveCyclic::GeneratePositionEvents( 646 IN ULONGLONG OldOffset, 647 IN ULONGLONG NewOffset) 648 { 649 PLIST_ENTRY Entry; 650 PKSEVENT_ENTRY EventEntry; 651 PLOOPEDSTREAMING_EVENT_CONTEXT Context; 652 653 // acquire event lock 654 KeAcquireSpinLockAtDpcLevel(&m_EventListLock); 655 656 // point to first entry 657 Entry = m_EventList.Flink; 658 659 while(Entry != &m_EventList) 660 { 661 // get event entry 662 EventEntry = (PKSEVENT_ENTRY)CONTAINING_RECORD(Entry, KSEVENT_ENTRY, ListEntry); 663 664 // get event entry context 665 Context = (PLOOPEDSTREAMING_EVENT_CONTEXT)(EventEntry + 1); 666 667 if (Context->bLoopedStreaming != FALSE) 668 { 669 if (NewOffset > OldOffset) 670 { 671 /* buffer progress no overlap */ 672 if (OldOffset < Context->Position && Context->Position <= NewOffset) 673 { 674 /* when someone eventually fixes sprintf... */ 675 DPRINT("Generating event at OldOffset %I64u\n", OldOffset); 676 DPRINT("Context->Position %I64u\n", Context->Position); 677 DPRINT("NewOffset %I64u\n", NewOffset); 678 /* generate event */ 679 KsGenerateEvent(EventEntry); 680 } 681 } 682 else 683 { 684 /* buffer wrap-arround */ 685 if (OldOffset < Context->Position || NewOffset > Context->Position) 686 { 687 /* when someone eventually fixes sprintf... */ 688 DPRINT("Generating event at OldOffset %I64u\n", OldOffset); 689 DPRINT("Context->Position %I64u\n", Context->Position); 690 DPRINT("NewOffset %I64u\n", NewOffset); 691 /* generate event */ 692 KsGenerateEvent(EventEntry); 693 } 694 } 695 } 696 697 // move to next entry 698 Entry = Entry->Flink; 699 } 700 701 // release lock 702 KeReleaseSpinLockFromDpcLevel(&m_EventListLock); 703 } 704 705 VOID 706 CPortPinWaveCyclic::UpdateCommonBuffer( 707 ULONG Position, 708 ULONG MaxTransferCount) 709 { 710 ULONG BufferLength; 711 ULONG BytesToCopy; 712 ULONG BufferSize; 713 ULONG Gap; 714 PUCHAR Buffer; 715 NTSTATUS Status; 716 717 BufferLength = Position - m_CommonBufferOffset; 718 BufferLength = min(BufferLength, MaxTransferCount); 719 720 while(BufferLength) 721 { 722 Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); 723 if (!NT_SUCCESS(Status)) 724 { 725 Gap = Position - m_CommonBufferOffset; 726 if (Gap > BufferLength) 727 { 728 // insert silence samples 729 DPRINT("Inserting Silence Buffer Offset %lu GapLength %lu\n", m_CommonBufferOffset, BufferLength); 730 m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); 731 732 m_CommonBufferOffset += BufferLength; 733 } 734 break; 735 } 736 737 BytesToCopy = min(BufferLength, BufferSize); 738 739 if (m_Capture) 740 { 741 m_DmaChannel->CopyFrom(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy); 742 } 743 else 744 { 745 m_DmaChannel->CopyTo((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy); 746 } 747 748 m_IrpQueue->UpdateMapping(BytesToCopy); 749 m_CommonBufferOffset += BytesToCopy; 750 751 BufferLength -= BytesToCopy; 752 m_Position.PlayOffset += BytesToCopy; 753 754 if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 755 { 756 if (m_Position.WriteOffset) 757 { 758 // normalize position 759 m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; 760 } 761 } 762 } 763 } 764 765 VOID 766 CPortPinWaveCyclic::UpdateCommonBufferOverlap( 767 ULONG Position, 768 ULONG MaxTransferCount) 769 { 770 ULONG BufferLength, Length, Gap; 771 ULONG BytesToCopy; 772 ULONG BufferSize; 773 PUCHAR Buffer; 774 NTSTATUS Status; 775 776 777 BufferLength = Gap = m_CommonBufferSize - m_CommonBufferOffset; 778 BufferLength = Length = min(BufferLength, MaxTransferCount); 779 while(BufferLength) 780 { 781 Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); 782 if (!NT_SUCCESS(Status)) 783 { 784 Gap = m_CommonBufferSize - m_CommonBufferOffset + Position; 785 if (Gap > BufferLength) 786 { 787 // insert silence samples 788 DPRINT("Overlap Inserting Silence Buffer Size %lu Offset %lu Gap %lu Position %lu\n", m_CommonBufferSize, m_CommonBufferOffset, Gap, Position); 789 m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); 790 791 m_CommonBufferOffset += BufferLength; 792 } 793 break; 794 } 795 796 BytesToCopy = min(BufferLength, BufferSize); 797 798 if (m_Capture) 799 { 800 m_DmaChannel->CopyFrom(Buffer, 801 (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, 802 BytesToCopy); 803 } 804 else 805 { 806 m_DmaChannel->CopyTo((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, 807 Buffer, 808 BytesToCopy); 809 } 810 811 m_IrpQueue->UpdateMapping(BytesToCopy); 812 m_CommonBufferOffset += BytesToCopy; 813 m_Position.PlayOffset += BytesToCopy; 814 815 BufferLength -=BytesToCopy; 816 817 if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) 818 { 819 if (m_Position.WriteOffset) 820 { 821 // normalize position 822 m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; 823 } 824 } 825 } 826 827 if (Gap == Length) 828 { 829 m_CommonBufferOffset = 0; 830 831 MaxTransferCount -= Length; 832 833 if (MaxTransferCount) 834 { 835 UpdateCommonBuffer(Position, MaxTransferCount); 836 } 837 } 838 } 839 840 VOID 841 NTAPI 842 CPortPinWaveCyclic::RequestService() 843 { 844 ULONG Position; 845 ULONGLONG OldOffset, NewOffset; 846 847 PC_ASSERT_IRQL(DISPATCH_LEVEL); 848 849 if (m_State == KSSTATE_RUN && m_ResetState == KSRESET_END) 850 { 851 m_Stream->GetPosition(&Position); 852 853 OldOffset = m_Position.PlayOffset; 854 855 if (Position < m_CommonBufferOffset) 856 { 857 UpdateCommonBufferOverlap(Position, m_FrameSize); 858 } 859 else if (Position >= m_CommonBufferOffset) 860 { 861 UpdateCommonBuffer(Position, m_FrameSize); 862 } 863 864 NewOffset = m_Position.PlayOffset; 865 866 GeneratePositionEvents(OldOffset, NewOffset); 867 } 868 } 869 870 NTSTATUS 871 NTAPI 872 CPortPinWaveCyclic::NewIrpTarget( 873 OUT struct IIrpTarget **OutTarget, 874 IN PCWSTR Name, 875 IN PUNKNOWN Unknown, 876 IN POOL_TYPE PoolType, 877 IN PDEVICE_OBJECT DeviceObject, 878 IN PIRP Irp, 879 IN KSOBJECT_CREATE *CreateObject) 880 { 881 UNIMPLEMENTED; 882 return STATUS_UNSUCCESSFUL; 883 } 884 885 NTSTATUS 886 NTAPI 887 CPortPinWaveCyclic::DeviceIoControl( 888 IN PDEVICE_OBJECT DeviceObject, 889 IN PIRP Irp) 890 { 891 PIO_STACK_LOCATION IoStack; 892 PKSPROPERTY Property; 893 UNICODE_STRING GuidString; 894 NTSTATUS Status = STATUS_NOT_SUPPORTED; 895 ULONG Data = 0; 896 KSRESET ResetValue; 897 898 /* get current irp stack location */ 899 IoStack = IoGetCurrentIrpStackLocation(Irp); 900 901 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) 902 { 903 /* handle property with subdevice descriptor */ 904 Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor); 905 906 if (Status == STATUS_NOT_FOUND) 907 { 908 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 909 910 RtlStringFromGUID(Property->Set, &GuidString); 911 DPRINT("Unhandled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); 912 RtlFreeUnicodeString(&GuidString); 913 } 914 } 915 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) 916 { 917 Status = PcHandleEnableEventWithTable(Irp, m_Descriptor); 918 } 919 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT) 920 { 921 Status = PcHandleDisableEventWithTable(Irp, m_Descriptor); 922 } 923 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) 924 { 925 Status = KsAcquireResetValue(Irp, &ResetValue); 926 DPRINT("Status %x Value %u\n", Status, ResetValue); 927 /* check for success */ 928 if (NT_SUCCESS(Status)) 929 { 930 //determine state of reset request 931 if (ResetValue == KSRESET_BEGIN) 932 { 933 // start reset process 934 // incoming read/write requests will be rejected 935 m_ResetState = KSRESET_BEGIN; 936 937 // cancel existing buffers 938 m_IrpQueue->CancelBuffers(); 939 } 940 else if (ResetValue == KSRESET_END) 941 { 942 // end of reset process 943 m_ResetState = KSRESET_END; 944 } 945 } 946 } 947 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) 948 { 949 /* increment total number of packets */ 950 InterlockedIncrement((PLONG)&m_TotalPackets); 951 952 DPRINT("New Packet Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); 953 954 /* is the device not currently reset */ 955 if (m_ResetState == KSRESET_END) 956 { 957 /* add the mapping */ 958 Status = m_IrpQueue->AddMapping(Irp, &Data); 959 960 /* check for success */ 961 if (NT_SUCCESS(Status)) 962 { 963 m_Position.WriteOffset += Data; 964 Status = STATUS_PENDING; 965 } 966 } 967 else 968 { 969 /* reset request is currently in progress */ 970 Status = STATUS_DEVICE_NOT_READY; 971 DPRINT1("NotReady\n"); 972 } 973 } 974 else 975 { 976 return KsDefaultDeviceIoCompletion(DeviceObject, Irp); 977 } 978 979 if (Status != STATUS_PENDING) 980 { 981 Irp->IoStatus.Status = Status; 982 IoCompleteRequest(Irp, IO_NO_INCREMENT); 983 } 984 985 return Status; 986 } 987 988 NTSTATUS 989 NTAPI 990 CPortPinWaveCyclic::Read( 991 IN PDEVICE_OBJECT DeviceObject, 992 IN PIRP Irp) 993 { 994 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 995 } 996 997 NTSTATUS 998 NTAPI 999 CPortPinWaveCyclic::Write( 1000 IN PDEVICE_OBJECT DeviceObject, 1001 IN PIRP Irp) 1002 { 1003 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 1004 } 1005 1006 NTSTATUS 1007 NTAPI 1008 CPortPinWaveCyclic::Flush( 1009 IN PDEVICE_OBJECT DeviceObject, 1010 IN PIRP Irp) 1011 { 1012 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 1013 } 1014 1015 NTSTATUS 1016 NTAPI 1017 CPortPinWaveCyclic::Close( 1018 IN PDEVICE_OBJECT DeviceObject, 1019 IN PIRP Irp) 1020 { 1021 DPRINT("CPortPinWaveCyclic::Close entered\n"); 1022 1023 PC_ASSERT_IRQL(PASSIVE_LEVEL); 1024 1025 if (m_Format) 1026 { 1027 // free format 1028 FreeItem(m_Format, TAG_PORTCLASS); 1029 1030 // format is freed 1031 m_Format = NULL; 1032 } 1033 1034 if (m_IrpQueue) 1035 { 1036 // cancel remaining irps 1037 m_IrpQueue->CancelBuffers(); 1038 1039 // release irp queue 1040 m_IrpQueue->Release(); 1041 1042 // queue is freed 1043 m_IrpQueue = NULL; 1044 } 1045 1046 if (m_ServiceGroup) 1047 { 1048 // remove member from service group 1049 m_ServiceGroup->RemoveMember(PSERVICESINK(this)); 1050 1051 // do not release service group, it is released by the miniport object 1052 m_ServiceGroup = NULL; 1053 } 1054 1055 if (m_Stream) 1056 { 1057 if (m_State != KSSTATE_STOP) 1058 { 1059 // stop stream 1060 NTSTATUS Status = m_Stream->SetState(KSSTATE_STOP); 1061 if (!NT_SUCCESS(Status)) 1062 { 1063 DPRINT("Warning: failed to stop stream with %x\n", Status); 1064 PC_ASSERT(0); 1065 } 1066 } 1067 // set state to stop 1068 m_State = KSSTATE_STOP; 1069 1070 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); 1071 1072 // release stream 1073 m_Stream->Release(); 1074 1075 // stream is now freed 1076 m_Stream = NULL; 1077 } 1078 1079 1080 if (m_Filter) 1081 { 1082 // disconnect pin from filter 1083 m_Filter->FreePin((PPORTPINWAVECYCLIC)this); 1084 1085 // release filter reference 1086 m_Filter->Release(); 1087 1088 // pin is done with filter 1089 m_Filter = NULL; 1090 } 1091 1092 if (m_Port) 1093 { 1094 // release reference to port driver 1095 m_Port->Release(); 1096 1097 // work is done for port 1098 m_Port = NULL; 1099 } 1100 1101 Irp->IoStatus.Information = 0; 1102 Irp->IoStatus.Status = STATUS_SUCCESS; 1103 IoCompleteRequest(Irp, IO_NO_INCREMENT); 1104 1105 delete this; 1106 1107 return STATUS_SUCCESS; 1108 } 1109 1110 NTSTATUS 1111 NTAPI 1112 CPortPinWaveCyclic::QuerySecurity( 1113 IN PDEVICE_OBJECT DeviceObject, 1114 IN PIRP Irp) 1115 { 1116 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 1117 } 1118 1119 NTSTATUS 1120 NTAPI 1121 CPortPinWaveCyclic::SetSecurity( 1122 IN PDEVICE_OBJECT DeviceObject, 1123 IN PIRP Irp) 1124 { 1125 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 1126 } 1127 1128 BOOLEAN 1129 NTAPI 1130 CPortPinWaveCyclic::FastDeviceIoControl( 1131 IN PFILE_OBJECT FileObject, 1132 IN BOOLEAN Wait, 1133 IN PVOID InputBuffer, 1134 IN ULONG InputBufferLength, 1135 OUT PVOID OutputBuffer, 1136 IN ULONG OutputBufferLength, 1137 IN ULONG IoControlCode, 1138 OUT PIO_STATUS_BLOCK StatusBlock, 1139 IN PDEVICE_OBJECT DeviceObject) 1140 { 1141 return KsDispatchFastIoDeviceControlFailure(FileObject, Wait, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, IoControlCode, StatusBlock, DeviceObject); 1142 } 1143 1144 1145 BOOLEAN 1146 NTAPI 1147 CPortPinWaveCyclic::FastRead( 1148 IN PFILE_OBJECT FileObject, 1149 IN PLARGE_INTEGER FileOffset, 1150 IN ULONG Length, 1151 IN BOOLEAN Wait, 1152 IN ULONG LockKey, 1153 IN PVOID Buffer, 1154 OUT PIO_STATUS_BLOCK StatusBlock, 1155 IN PDEVICE_OBJECT DeviceObject) 1156 { 1157 return KsDispatchFastReadFailure(FileObject, FileOffset, Length, Wait, LockKey, Buffer, StatusBlock, DeviceObject); 1158 } 1159 1160 1161 BOOLEAN 1162 NTAPI 1163 CPortPinWaveCyclic::FastWrite( 1164 IN PFILE_OBJECT FileObject, 1165 IN PLARGE_INTEGER FileOffset, 1166 IN ULONG Length, 1167 IN BOOLEAN Wait, 1168 IN ULONG LockKey, 1169 IN PVOID Buffer, 1170 OUT PIO_STATUS_BLOCK StatusBlock, 1171 IN PDEVICE_OBJECT DeviceObject) 1172 { 1173 return KsDispatchFastReadFailure(FileObject, FileOffset, Length, Wait, LockKey, Buffer, StatusBlock, DeviceObject); 1174 } 1175 1176 1177 NTSTATUS 1178 NTAPI 1179 CPortPinWaveCyclic::Init( 1180 IN PPORTWAVECYCLIC Port, 1181 IN PPORTFILTERWAVECYCLIC Filter, 1182 IN KSPIN_CONNECT * ConnectDetails, 1183 IN KSPIN_DESCRIPTOR * KsPinDescriptor) 1184 { 1185 NTSTATUS Status; 1186 PKSDATAFORMAT DataFormat; 1187 //PDEVICE_OBJECT DeviceObject; 1188 BOOLEAN Capture; 1189 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; 1190 //IDrmAudioStream * DrmAudio = NULL; 1191 1192 m_KsPinDescriptor = KsPinDescriptor; 1193 m_ConnectDetails = ConnectDetails; 1194 m_Miniport = GetWaveCyclicMiniport(Port); 1195 1196 //DeviceObject = GetDeviceObject(Port); 1197 1198 DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); 1199 1200 DPRINT("CPortPinWaveCyclic::Init entered Size %u\n", DataFormat->FormatSize); 1201 1202 Status = NewIrpQueue(&m_IrpQueue); 1203 if (!NT_SUCCESS(Status)) 1204 return Status; 1205 1206 if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) 1207 { 1208 Capture = FALSE; 1209 } 1210 else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) 1211 { 1212 Capture = TRUE; 1213 } 1214 else 1215 { 1216 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); 1217 DbgBreakPoint(); 1218 while(TRUE); 1219 } 1220 1221 1222 Status = m_Miniport->NewStream(&m_Stream, 1223 NULL, 1224 NonPagedPool, 1225 ConnectDetails->PinId, 1226 Capture, 1227 DataFormat, 1228 &m_DmaChannel, 1229 &m_ServiceGroup); 1230 #if 0 1231 Status = m_Stream->QueryInterface(IID_IDrmAudioStream, (PVOID*)&DrmAudio); 1232 if (NT_SUCCESS(Status)) 1233 { 1234 DRMRIGHTS DrmRights; 1235 DPRINT("Got IID_IDrmAudioStream interface %p\n", DrmAudio); 1236 1237 DrmRights.CopyProtect = FALSE; 1238 DrmRights.Reserved = 0; 1239 DrmRights.DigitalOutputDisable = FALSE; 1240 1241 Status = DrmAudio->SetContentId(1, &DrmRights); 1242 DPRINT("Status %x\n", Status); 1243 } 1244 #endif 1245 1246 DPRINT1("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture); 1247 1248 if (!NT_SUCCESS(Status)) 1249 return Status; 1250 1251 ISubdevice * Subdevice = NULL; 1252 // get subdevice interface 1253 Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice); 1254 1255 if (!NT_SUCCESS(Status)) 1256 return Status; 1257 1258 Status = Subdevice->GetDescriptor(&SubDeviceDescriptor); 1259 if (!NT_SUCCESS(Status)) 1260 { 1261 // failed to get descriptor 1262 Subdevice->Release(); 1263 return Status; 1264 } 1265 1266 /* initialize event management */ 1267 InitializeListHead(&m_EventList); 1268 KeInitializeSpinLock(&m_EventListLock); 1269 1270 Status = PcCreateSubdeviceDescriptor(&m_Descriptor, 1271 SubDeviceDescriptor->InterfaceCount, 1272 SubDeviceDescriptor->Interfaces, 1273 0, /* FIXME KSINTERFACE_STANDARD with KSINTERFACE_STANDARD_STREAMING / KSINTERFACE_STANDARD_LOOPED_STREAMING */ 1274 NULL, 1275 sizeof(PinWaveCyclicPropertySet) / sizeof(KSPROPERTY_SET), 1276 PinWaveCyclicPropertySet, 1277 0, 1278 0, 1279 0, 1280 NULL, 1281 sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET), 1282 PinWaveCyclicEventSet, 1283 SubDeviceDescriptor->DeviceDescriptor); 1284 1285 m_Descriptor->UnknownStream = (PUNKNOWN)m_Stream; 1286 m_Descriptor->UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; 1287 m_Descriptor->PortPin = (PVOID)this; 1288 m_Descriptor->EventList = &m_EventList; 1289 m_Descriptor->EventListLock = &m_EventListLock; 1290 1291 // initialize reset state 1292 m_ResetState = KSRESET_END; 1293 1294 // release subdevice descriptor 1295 Subdevice->Release(); 1296 1297 // add ourselves to service group 1298 Status = m_ServiceGroup->AddMember(PSERVICESINK(this)); 1299 if (!NT_SUCCESS(Status)) 1300 { 1301 DPRINT("Failed to add pin to service group\n"); 1302 return Status; 1303 } 1304 1305 m_Stream->SetState(KSSTATE_STOP); 1306 m_State = KSSTATE_STOP; 1307 m_CommonBufferOffset = 0; 1308 m_CommonBufferSize = m_DmaChannel->BufferSize(); 1309 m_CommonBuffer = m_DmaChannel->SystemAddress(); 1310 m_Capture = Capture; 1311 // delay of 10 millisec 1312 m_Delay = Int32x32To64(10, -10000); 1313 1314 // sanity checks 1315 PC_ASSERT(m_CommonBufferSize); 1316 PC_ASSERT(m_CommonBuffer); 1317 1318 Status = m_Stream->SetNotificationFreq(10, &m_FrameSize); 1319 PC_ASSERT(NT_SUCCESS(Status)); 1320 PC_ASSERT(m_FrameSize); 1321 1322 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()); 1323 1324 1325 /* set up allocator framing */ 1326 m_AllocatorFraming.RequirementsFlags = KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_PREFERENCES_ONLY; 1327 m_AllocatorFraming.PoolType = NonPagedPool; 1328 m_AllocatorFraming.Frames = 8; 1329 m_AllocatorFraming.FileAlignment = FILE_64_BYTE_ALIGNMENT; 1330 m_AllocatorFraming.Reserved = 0; 1331 m_AllocatorFraming.FrameSize = m_FrameSize; 1332 1333 m_Stream->Silence(m_CommonBuffer, m_CommonBufferSize); 1334 1335 Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, m_FrameSize, 0, FALSE); 1336 if (!NT_SUCCESS(Status)) 1337 { 1338 m_IrpQueue->Release(); 1339 return Status; 1340 } 1341 1342 m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 1343 if (!m_Format) 1344 return STATUS_INSUFFICIENT_RESOURCES; 1345 1346 RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); 1347 1348 Port->AddRef(); 1349 Filter->AddRef(); 1350 1351 m_Port = Port; 1352 m_Filter = Filter; 1353 1354 return STATUS_SUCCESS; 1355 } 1356 1357 1358 ULONG 1359 NTAPI 1360 CPortPinWaveCyclic::GetCompletedPosition() 1361 { 1362 UNIMPLEMENTED; 1363 return 0; 1364 } 1365 1366 1367 ULONG 1368 NTAPI 1369 CPortPinWaveCyclic::GetCycleCount() 1370 { 1371 UNIMPLEMENTED; 1372 return 0; 1373 } 1374 1375 1376 ULONG 1377 NTAPI 1378 CPortPinWaveCyclic::GetDeviceBufferSize() 1379 { 1380 return m_CommonBufferSize; 1381 } 1382 1383 1384 PVOID 1385 NTAPI 1386 CPortPinWaveCyclic::GetIrpStream() 1387 { 1388 return (PVOID)m_IrpQueue; 1389 } 1390 1391 1392 PMINIPORT 1393 NTAPI 1394 CPortPinWaveCyclic::GetMiniport() 1395 { 1396 return (PMINIPORT)m_Miniport; 1397 } 1398 1399 1400 NTSTATUS 1401 NewPortPinWaveCyclic( 1402 OUT IPortPinWaveCyclic ** OutPin) 1403 { 1404 CPortPinWaveCyclic * This; 1405 1406 This = new(NonPagedPool, TAG_PORTCLASS)CPortPinWaveCyclic(NULL); 1407 if (!This) 1408 return STATUS_INSUFFICIENT_RESOURCES; 1409 1410 This->AddRef(); 1411 1412 // store result 1413 *OutPin = (IPortPinWaveCyclic*)This; 1414 1415 return STATUS_SUCCESS; 1416 } 1417 1418