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