1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel Streaming 4 * FILE: drivers/wdm/audio/backpln/portcls/pin_wavert.cpp 5 * PURPOSE: WaveRT 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 CPortPinWaveRT : public IPortPinWaveRT 18 { 19 public: 20 STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface); 21 22 STDMETHODIMP_(ULONG) AddRef() 23 { 24 InterlockedIncrement(&m_Ref); 25 return m_Ref; 26 } 27 STDMETHODIMP_(ULONG) Release() 28 { 29 InterlockedDecrement(&m_Ref); 30 31 if (!m_Ref) 32 { 33 delete this; 34 return 0; 35 } 36 return m_Ref; 37 } 38 IMP_IPortPinWaveRT; 39 CPortPinWaveRT(IUnknown *OuterUnknown){} 40 virtual ~CPortPinWaveRT(){} 41 42 protected: 43 44 IPortWaveRT * m_Port; 45 IPortFilterWaveRT * m_Filter; 46 KSPIN_DESCRIPTOR * m_KsPinDescriptor; 47 PMINIPORTWAVERT m_Miniport; 48 PMINIPORTWAVERTSTREAM m_Stream; 49 PPORTWAVERTSTREAM m_PortStream; 50 KSSTATE m_State; 51 PKSDATAFORMAT m_Format; 52 KSPIN_CONNECT * m_ConnectDetails; 53 54 PVOID m_CommonBuffer; 55 ULONG m_CommonBufferSize; 56 ULONG m_CommonBufferOffset; 57 58 IIrpQueue * m_IrpQueue; 59 60 BOOL m_Capture; 61 62 ULONG m_TotalPackets; 63 ULONG m_PreCompleted; 64 ULONG m_PostCompleted; 65 66 ULONGLONG m_Delay; 67 68 MEMORY_CACHING_TYPE m_CacheType; 69 PMDL m_Mdl; 70 71 LONG m_Ref; 72 73 NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp); 74 NTSTATUS NTAPI HandleKsStream(IN PIRP Irp); 75 VOID NTAPI SetStreamState(IN KSSTATE State); 76 friend VOID NTAPI SetStreamWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); 77 friend VOID NTAPI CloseStreamRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context); 78 79 }; 80 81 82 typedef struct 83 { 84 CPortPinWaveRT *Pin; 85 PIO_WORKITEM WorkItem; 86 KSSTATE State; 87 }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT; 88 89 90 //================================================================================================================================== 91 NTSTATUS 92 NTAPI 93 CPortPinWaveRT::QueryInterface( 94 IN REFIID refiid, 95 OUT PVOID* Output) 96 { 97 DPRINT("IServiceSink_fnQueryInterface entered\n"); 98 99 if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || 100 IsEqualGUIDAligned(refiid, IID_IUnknown)) 101 { 102 *Output = PVOID(PUNKNOWN((IIrpTarget*)this)); 103 PUNKNOWN(*Output)->AddRef(); 104 return STATUS_SUCCESS; 105 } 106 return STATUS_UNSUCCESSFUL; 107 } 108 109 //================================================================================================================================== 110 111 NTSTATUS 112 NTAPI 113 CPortPinWaveRT::NewIrpTarget( 114 OUT struct IIrpTarget **OutTarget, 115 IN PCWSTR Name, 116 IN PUNKNOWN Unknown, 117 IN POOL_TYPE PoolType, 118 IN PDEVICE_OBJECT DeviceObject, 119 IN PIRP Irp, 120 IN KSOBJECT_CREATE *CreateObject) 121 { 122 UNIMPLEMENTED; 123 return STATUS_UNSUCCESSFUL; 124 } 125 126 NTSTATUS 127 NTAPI 128 CPortPinWaveRT::HandleKsProperty( 129 IN PIRP Irp) 130 { 131 PKSPROPERTY Property; 132 NTSTATUS Status; 133 UNICODE_STRING GuidString; 134 PIO_STACK_LOCATION IoStack; 135 136 IoStack = IoGetCurrentIrpStackLocation(Irp); 137 138 DPRINT("IPortPinWave_HandleKsProperty entered\n"); 139 140 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) 141 { 142 Irp->IoStatus.Information = 0; 143 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 144 IoCompleteRequest(Irp, IO_NO_INCREMENT); 145 return STATUS_INVALID_PARAMETER; 146 } 147 148 Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 149 150 if (IsEqualGUIDAligned(Property->Set, KSPROPSETID_Connection)) 151 { 152 if (Property->Id == KSPROPERTY_CONNECTION_STATE) 153 { 154 PKSSTATE State = (PKSSTATE)Irp->UserBuffer; 155 156 if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE)) 157 { 158 Irp->IoStatus.Information = sizeof(KSSTATE); 159 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 160 IoCompleteRequest(Irp, IO_NO_INCREMENT); 161 return STATUS_BUFFER_TOO_SMALL; 162 } 163 164 if (Property->Flags & KSPROPERTY_TYPE_SET) 165 { 166 Status = STATUS_UNSUCCESSFUL; 167 Irp->IoStatus.Information = 0; 168 169 if (m_Stream) 170 { 171 Status = m_Stream->SetState(*State); 172 173 DPRINT("Setting state %u %x\n", *State, Status); 174 if (NT_SUCCESS(Status)) 175 { 176 m_State = *State; 177 } 178 } 179 Irp->IoStatus.Status = Status; 180 IoCompleteRequest(Irp, IO_NO_INCREMENT); 181 return Status; 182 } 183 else if (Property->Flags & KSPROPERTY_TYPE_GET) 184 { 185 *State = m_State; 186 Irp->IoStatus.Information = sizeof(KSSTATE); 187 Irp->IoStatus.Status = STATUS_SUCCESS; 188 IoCompleteRequest(Irp, IO_NO_INCREMENT); 189 return STATUS_SUCCESS; 190 } 191 } 192 else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT) 193 { 194 PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; 195 if (Property->Flags & KSPROPERTY_TYPE_SET) 196 { 197 PKSDATAFORMAT NewDataFormat; 198 if (!RtlCompareMemory(DataFormat, m_Format, DataFormat->FormatSize)) 199 { 200 Irp->IoStatus.Information = DataFormat->FormatSize; 201 Irp->IoStatus.Status = STATUS_SUCCESS; 202 IoCompleteRequest(Irp, IO_NO_INCREMENT); 203 return STATUS_SUCCESS; 204 } 205 206 NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 207 if (!NewDataFormat) 208 { 209 Irp->IoStatus.Information = 0; 210 Irp->IoStatus.Status = STATUS_NO_MEMORY; 211 IoCompleteRequest(Irp, IO_NO_INCREMENT); 212 return STATUS_NO_MEMORY; 213 } 214 RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); 215 216 if (m_Stream) 217 { 218 #if 0 219 ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); 220 ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); 221 ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO)); 222 ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)); 223 ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); 224 225 ASSERT(m_State == KSSTATE_STOP); 226 #endif 227 DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, 228 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, 229 ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); 230 231 Status = m_Stream->SetFormat(NewDataFormat); 232 if (NT_SUCCESS(Status)) 233 { 234 if (m_Format) 235 FreeItem(m_Format, TAG_PORTCLASS); 236 237 m_Format = NewDataFormat; 238 Irp->IoStatus.Information = DataFormat->FormatSize; 239 Irp->IoStatus.Status = STATUS_SUCCESS; 240 IoCompleteRequest(Irp, IO_NO_INCREMENT); 241 return STATUS_SUCCESS; 242 } 243 } 244 DPRINT("Failed to set format\n"); 245 Irp->IoStatus.Information = 0; 246 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 247 IoCompleteRequest(Irp, IO_NO_INCREMENT); 248 return STATUS_UNSUCCESSFUL; 249 } 250 else if (Property->Flags & KSPROPERTY_TYPE_GET) 251 { 252 if (!m_Format) 253 { 254 DPRINT("No format\n"); 255 Irp->IoStatus.Information = 0; 256 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 257 IoCompleteRequest(Irp, IO_NO_INCREMENT); 258 return STATUS_UNSUCCESSFUL; 259 } 260 if (m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) 261 { 262 Irp->IoStatus.Information = m_Format->FormatSize; 263 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL; 264 IoCompleteRequest(Irp, IO_NO_INCREMENT); 265 return STATUS_BUFFER_TOO_SMALL; 266 } 267 268 RtlMoveMemory(DataFormat, m_Format, m_Format->FormatSize); 269 Irp->IoStatus.Information = DataFormat->FormatSize; 270 Irp->IoStatus.Status = STATUS_SUCCESS; 271 IoCompleteRequest(Irp, IO_NO_INCREMENT); 272 return STATUS_SUCCESS; 273 } 274 } 275 276 } 277 RtlStringFromGUID(Property->Set, &GuidString); 278 DPRINT("Unhandled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags); 279 RtlFreeUnicodeString(&GuidString); 280 281 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 282 Irp->IoStatus.Information = 0; 283 IoCompleteRequest(Irp, IO_NO_INCREMENT); 284 return STATUS_NOT_IMPLEMENTED; 285 } 286 287 NTSTATUS 288 NTAPI 289 CPortPinWaveRT::HandleKsStream( 290 IN PIRP Irp) 291 { 292 DPRINT("IPortPinWaveRT_HandleKsStream entered State %u Stream %p is UNIMPLEMENTED\n", m_State, m_Stream); 293 294 return STATUS_PENDING; 295 } 296 297 NTSTATUS 298 NTAPI 299 CPortPinWaveRT::DeviceIoControl( 300 IN PDEVICE_OBJECT DeviceObject, 301 IN PIRP Irp) 302 { 303 PIO_STACK_LOCATION IoStack; 304 305 IoStack = IoGetCurrentIrpStackLocation(Irp); 306 307 308 switch (IoStack->Parameters.DeviceIoControl.IoControlCode) 309 { 310 case IOCTL_KS_PROPERTY: 311 return HandleKsProperty(Irp); 312 313 case IOCTL_KS_ENABLE_EVENT: 314 /* FIXME UNIMPLEMENTED */ 315 UNIMPLEMENTED_ONCE; 316 break; 317 318 case IOCTL_KS_DISABLE_EVENT: 319 /* FIXME UNIMPLEMENTED */ 320 UNIMPLEMENTED_ONCE; 321 break; 322 323 case IOCTL_KS_HANDSHAKE: 324 /* FIXME UNIMPLEMENTED */ 325 UNIMPLEMENTED_ONCE; 326 break; 327 328 case IOCTL_KS_METHOD: 329 /* FIXME UNIMPLEMENTED */ 330 UNIMPLEMENTED_ONCE; 331 return KsDefaultDeviceIoCompletion(DeviceObject, Irp); 332 333 case IOCTL_KS_RESET_STATE: 334 /* FIXME UNIMPLEMENTED */ 335 UNIMPLEMENTED_ONCE; 336 break; 337 338 case IOCTL_KS_WRITE_STREAM: 339 case IOCTL_KS_READ_STREAM: 340 return HandleKsStream(Irp); 341 342 default: 343 return KsDefaultDeviceIoCompletion(DeviceObject, Irp); 344 } 345 346 Irp->IoStatus.Information = 0; 347 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 348 IoCompleteRequest(Irp, IO_NO_INCREMENT); 349 350 return STATUS_UNSUCCESSFUL; 351 } 352 353 NTSTATUS 354 NTAPI 355 CPortPinWaveRT::Read( 356 IN PDEVICE_OBJECT DeviceObject, 357 IN PIRP Irp) 358 { 359 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 360 } 361 362 NTSTATUS 363 NTAPI 364 CPortPinWaveRT::Write( 365 IN PDEVICE_OBJECT DeviceObject, 366 IN PIRP Irp) 367 { 368 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 369 } 370 371 NTSTATUS 372 NTAPI 373 CPortPinWaveRT::Flush( 374 IN PDEVICE_OBJECT DeviceObject, 375 IN PIRP Irp) 376 { 377 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 378 } 379 380 VOID 381 NTAPI 382 CloseStreamRoutine( 383 IN PDEVICE_OBJECT DeviceObject, 384 IN PVOID Context) 385 { 386 PMINIPORTWAVERTSTREAM Stream; 387 NTSTATUS Status; 388 ISubdevice *ISubDevice; 389 PSUBDEVICE_DESCRIPTOR Descriptor; 390 CPortPinWaveRT * This; 391 PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; 392 393 This = (CPortPinWaveRT*)Ctx->Pin; 394 395 if (This->m_Stream) 396 { 397 if (This->m_State != KSSTATE_STOP) 398 { 399 This->m_Stream->SetState(KSSTATE_STOP); 400 KeStallExecutionProcessor(10); 401 } 402 } 403 404 Status = This->m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); 405 if (NT_SUCCESS(Status)) 406 { 407 Status = ISubDevice->GetDescriptor(&Descriptor); 408 if (NT_SUCCESS(Status)) 409 { 410 Descriptor->Factory.Instances[This->m_ConnectDetails->PinId].CurrentPinInstanceCount--; 411 } 412 ISubDevice->Release(); 413 } 414 415 if (This->m_Format) 416 { 417 FreeItem(This->m_Format, TAG_PORTCLASS); 418 This->m_Format = NULL; 419 } 420 421 if (This->m_IrpQueue) 422 { 423 This->m_IrpQueue->Release(); 424 } 425 426 // complete the irp 427 Ctx->Irp->IoStatus.Information = 0; 428 Ctx->Irp->IoStatus.Status = STATUS_SUCCESS; 429 IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT); 430 431 // free the work item 432 IoFreeWorkItem(Ctx->WorkItem); 433 434 // free work item ctx 435 FreeItem(Ctx, TAG_PORTCLASS); 436 437 if (This->m_Stream) 438 { 439 Stream = This->m_Stream; 440 This->m_Stream = NULL; 441 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); 442 Stream->Release(); 443 } 444 } 445 446 NTSTATUS 447 NTAPI 448 CPortPinWaveRT::Close( 449 IN PDEVICE_OBJECT DeviceObject, 450 IN PIRP Irp) 451 { 452 PCLOSESTREAM_CONTEXT Ctx; 453 454 if (m_Stream) 455 { 456 Ctx = (PCLOSESTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS); 457 if (!Ctx) 458 { 459 DPRINT("Failed to allocate stream context\n"); 460 goto cleanup; 461 } 462 463 Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); 464 if (!Ctx->WorkItem) 465 { 466 DPRINT("Failed to allocate work item\n"); 467 goto cleanup; 468 } 469 470 Ctx->Irp = Irp; 471 Ctx->Pin = this; 472 473 IoMarkIrpPending(Irp); 474 Irp->IoStatus.Information = 0; 475 Irp->IoStatus.Status = STATUS_PENDING; 476 477 // defer work item 478 IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx); 479 // Return result 480 return STATUS_PENDING; 481 } 482 483 Irp->IoStatus.Information = 0; 484 Irp->IoStatus.Status = STATUS_SUCCESS; 485 IoCompleteRequest(Irp, IO_NO_INCREMENT); 486 487 return STATUS_SUCCESS; 488 489 cleanup: 490 491 if (Ctx) 492 FreeItem(Ctx, TAG_PORTCLASS); 493 494 Irp->IoStatus.Information = 0; 495 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 496 IoCompleteRequest(Irp, IO_NO_INCREMENT); 497 return STATUS_UNSUCCESSFUL; 498 499 } 500 501 NTSTATUS 502 NTAPI 503 CPortPinWaveRT::QuerySecurity( 504 IN PDEVICE_OBJECT DeviceObject, 505 IN PIRP Irp) 506 { 507 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 508 } 509 510 NTSTATUS 511 NTAPI 512 CPortPinWaveRT::SetSecurity( 513 IN PDEVICE_OBJECT DeviceObject, 514 IN PIRP Irp) 515 { 516 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 517 } 518 519 BOOLEAN 520 NTAPI 521 CPortPinWaveRT::FastDeviceIoControl( 522 IN PFILE_OBJECT FileObject, 523 IN BOOLEAN Wait, 524 IN PVOID InputBuffer, 525 IN ULONG InputBufferLength, 526 OUT PVOID OutputBuffer, 527 IN ULONG OutputBufferLength, 528 IN ULONG IoControlCode, 529 OUT PIO_STATUS_BLOCK StatusBlock, 530 IN PDEVICE_OBJECT DeviceObject) 531 { 532 return FALSE; 533 } 534 535 BOOLEAN 536 NTAPI 537 CPortPinWaveRT::FastRead( 538 IN PFILE_OBJECT FileObject, 539 IN PLARGE_INTEGER FileOffset, 540 IN ULONG Length, 541 IN BOOLEAN Wait, 542 IN ULONG LockKey, 543 IN PVOID Buffer, 544 OUT PIO_STATUS_BLOCK StatusBlock, 545 IN PDEVICE_OBJECT DeviceObject) 546 { 547 return FALSE; 548 } 549 550 BOOLEAN 551 NTAPI 552 CPortPinWaveRT::FastWrite( 553 IN PFILE_OBJECT FileObject, 554 IN PLARGE_INTEGER FileOffset, 555 IN ULONG Length, 556 IN BOOLEAN Wait, 557 IN ULONG LockKey, 558 IN PVOID Buffer, 559 OUT PIO_STATUS_BLOCK StatusBlock, 560 IN PDEVICE_OBJECT DeviceObject) 561 { 562 return FALSE; 563 } 564 565 NTSTATUS 566 NTAPI 567 CPortPinWaveRT::Init( 568 IN PPORTWAVERT Port, 569 IN PPORTFILTERWAVERT Filter, 570 IN KSPIN_CONNECT * ConnectDetails, 571 IN KSPIN_DESCRIPTOR * KsPinDescriptor, 572 IN PDEVICE_OBJECT DeviceObject) 573 { 574 NTSTATUS Status; 575 PKSDATAFORMAT DataFormat; 576 BOOLEAN Capture; 577 KSRTAUDIO_HWLATENCY Latency; 578 579 Port->AddRef(); 580 Filter->AddRef(); 581 582 m_Port = Port; 583 m_Filter = Filter; 584 m_KsPinDescriptor = KsPinDescriptor; 585 m_ConnectDetails = ConnectDetails; 586 m_Miniport = GetWaveRTMiniport(Port); 587 588 DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); 589 590 DPRINT("CPortPinWaveRT::Init entered\n"); 591 592 m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 593 if (!m_Format) 594 return STATUS_INSUFFICIENT_RESOURCES; 595 596 RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); 597 598 Status = NewIrpQueue(&m_IrpQueue); 599 if (!NT_SUCCESS(Status)) 600 { 601 goto cleanup; 602 } 603 604 Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, 0, 0, FALSE); 605 if (!NT_SUCCESS(Status)) 606 { 607 goto cleanup; 608 } 609 610 Status = NewPortWaveRTStream(&m_PortStream); 611 if (!NT_SUCCESS(Status)) 612 { 613 goto cleanup; 614 } 615 616 if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) 617 { 618 Capture = FALSE; 619 } 620 else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) 621 { 622 Capture = TRUE; 623 } 624 else 625 { 626 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); 627 KeBugCheck(0); 628 while(TRUE); 629 } 630 631 Status = m_Miniport->NewStream(&m_Stream, m_PortStream, ConnectDetails->PinId, Capture, m_Format); 632 DPRINT("CPortPinWaveRT::Init Status %x\n", Status); 633 634 if (!NT_SUCCESS(Status)) 635 goto cleanup; 636 637 m_Stream->GetHWLatency(&Latency); 638 // delay of 10 millisec 639 m_Delay = Int32x32To64(10, -10000); 640 641 Status = m_Stream->AllocateAudioBuffer(16384 * 11, &m_Mdl, &m_CommonBufferSize, &m_CommonBufferOffset, &m_CacheType); 642 if (!NT_SUCCESS(Status)) 643 { 644 DPRINT("AllocateAudioBuffer failed with %x\n", Status); 645 goto cleanup; 646 } 647 648 m_CommonBuffer = MmGetSystemAddressForMdlSafe(m_Mdl, NormalPagePriority); 649 if (!m_CommonBuffer) 650 { 651 DPRINT("Failed to get system address %x\n", Status); 652 IoFreeMdl(m_Mdl); 653 m_Mdl = NULL; 654 goto cleanup; 655 } 656 657 DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); 658 DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); 659 m_State = KSSTATE_PAUSE; 660 return STATUS_SUCCESS; 661 662 cleanup: 663 if (m_IrpQueue) 664 { 665 m_IrpQueue->Release(); 666 m_IrpQueue = NULL; 667 } 668 669 if (m_Format) 670 { 671 FreeItem(m_Format, TAG_PORTCLASS); 672 m_Format = NULL; 673 } 674 675 if (m_Stream) 676 { 677 m_Stream->Release(); 678 m_Stream = NULL; 679 } 680 else 681 { 682 if (m_PortStream) 683 { 684 m_PortStream->Release(); 685 m_PortStream = NULL; 686 } 687 688 } 689 return Status; 690 } 691 692 693 NTSTATUS 694 NewPortPinWaveRT( 695 OUT IPortPinWaveRT ** OutPin) 696 { 697 CPortPinWaveRT * This; 698 699 This = new(NonPagedPool, TAG_PORTCLASS) CPortPinWaveRT(NULL); 700 if (!This) 701 return STATUS_INSUFFICIENT_RESOURCES; 702 703 This->AddRef(); 704 705 // store result 706 *OutPin = (PPORTPINWAVERT)This; 707 708 return STATUS_SUCCESS; 709 } 710