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 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) 309 { 310 return HandleKsProperty(Irp); 311 } 312 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) 313 { 314 /// FIXME 315 /// handle enable event 316 } 317 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT) 318 { 319 /// FIXME 320 /// handle disable event 321 } 322 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) 323 { 324 /// FIXME 325 /// handle reset state 326 } 327 else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM) 328 { 329 return HandleKsStream(Irp); 330 } 331 else 332 { 333 return KsDefaultDeviceIoCompletion(DeviceObject, Irp); 334 } 335 336 UNIMPLEMENTED; 337 338 Irp->IoStatus.Information = 0; 339 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 340 IoCompleteRequest(Irp, IO_NO_INCREMENT); 341 342 return STATUS_UNSUCCESSFUL; 343 } 344 345 NTSTATUS 346 NTAPI 347 CPortPinWaveRT::Read( 348 IN PDEVICE_OBJECT DeviceObject, 349 IN PIRP Irp) 350 { 351 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 352 } 353 354 NTSTATUS 355 NTAPI 356 CPortPinWaveRT::Write( 357 IN PDEVICE_OBJECT DeviceObject, 358 IN PIRP Irp) 359 { 360 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 361 } 362 363 NTSTATUS 364 NTAPI 365 CPortPinWaveRT::Flush( 366 IN PDEVICE_OBJECT DeviceObject, 367 IN PIRP Irp) 368 { 369 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 370 } 371 372 VOID 373 NTAPI 374 CloseStreamRoutine( 375 IN PDEVICE_OBJECT DeviceObject, 376 IN PVOID Context) 377 { 378 PMINIPORTWAVERTSTREAM Stream; 379 NTSTATUS Status; 380 ISubdevice *ISubDevice; 381 PSUBDEVICE_DESCRIPTOR Descriptor; 382 CPortPinWaveRT * This; 383 PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context; 384 385 This = (CPortPinWaveRT*)Ctx->Pin; 386 387 if (This->m_Stream) 388 { 389 if (This->m_State != KSSTATE_STOP) 390 { 391 This->m_Stream->SetState(KSSTATE_STOP); 392 KeStallExecutionProcessor(10); 393 } 394 } 395 396 Status = This->m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice); 397 if (NT_SUCCESS(Status)) 398 { 399 Status = ISubDevice->GetDescriptor(&Descriptor); 400 if (NT_SUCCESS(Status)) 401 { 402 Descriptor->Factory.Instances[This->m_ConnectDetails->PinId].CurrentPinInstanceCount--; 403 } 404 ISubDevice->Release(); 405 } 406 407 if (This->m_Format) 408 { 409 FreeItem(This->m_Format, TAG_PORTCLASS); 410 This->m_Format = NULL; 411 } 412 413 if (This->m_IrpQueue) 414 { 415 This->m_IrpQueue->Release(); 416 } 417 418 // complete the irp 419 Ctx->Irp->IoStatus.Information = 0; 420 Ctx->Irp->IoStatus.Status = STATUS_SUCCESS; 421 IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT); 422 423 // free the work item 424 IoFreeWorkItem(Ctx->WorkItem); 425 426 // free work item ctx 427 FreeItem(Ctx, TAG_PORTCLASS); 428 429 if (This->m_Stream) 430 { 431 Stream = This->m_Stream; 432 This->m_Stream = NULL; 433 DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); 434 Stream->Release(); 435 } 436 } 437 438 NTSTATUS 439 NTAPI 440 CPortPinWaveRT::Close( 441 IN PDEVICE_OBJECT DeviceObject, 442 IN PIRP Irp) 443 { 444 PCLOSESTREAM_CONTEXT Ctx; 445 446 if (m_Stream) 447 { 448 Ctx = (PCLOSESTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS); 449 if (!Ctx) 450 { 451 DPRINT("Failed to allocate stream context\n"); 452 goto cleanup; 453 } 454 455 Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); 456 if (!Ctx->WorkItem) 457 { 458 DPRINT("Failed to allocate work item\n"); 459 goto cleanup; 460 } 461 462 Ctx->Irp = Irp; 463 Ctx->Pin = this; 464 465 IoMarkIrpPending(Irp); 466 Irp->IoStatus.Information = 0; 467 Irp->IoStatus.Status = STATUS_PENDING; 468 469 // defer work item 470 IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx); 471 // Return result 472 return STATUS_PENDING; 473 } 474 475 Irp->IoStatus.Information = 0; 476 Irp->IoStatus.Status = STATUS_SUCCESS; 477 IoCompleteRequest(Irp, IO_NO_INCREMENT); 478 479 return STATUS_SUCCESS; 480 481 cleanup: 482 483 if (Ctx) 484 FreeItem(Ctx, TAG_PORTCLASS); 485 486 Irp->IoStatus.Information = 0; 487 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 488 IoCompleteRequest(Irp, IO_NO_INCREMENT); 489 return STATUS_UNSUCCESSFUL; 490 491 } 492 493 NTSTATUS 494 NTAPI 495 CPortPinWaveRT::QuerySecurity( 496 IN PDEVICE_OBJECT DeviceObject, 497 IN PIRP Irp) 498 { 499 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 500 } 501 502 NTSTATUS 503 NTAPI 504 CPortPinWaveRT::SetSecurity( 505 IN PDEVICE_OBJECT DeviceObject, 506 IN PIRP Irp) 507 { 508 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 509 } 510 511 BOOLEAN 512 NTAPI 513 CPortPinWaveRT::FastDeviceIoControl( 514 IN PFILE_OBJECT FileObject, 515 IN BOOLEAN Wait, 516 IN PVOID InputBuffer, 517 IN ULONG InputBufferLength, 518 OUT PVOID OutputBuffer, 519 IN ULONG OutputBufferLength, 520 IN ULONG IoControlCode, 521 OUT PIO_STATUS_BLOCK StatusBlock, 522 IN PDEVICE_OBJECT DeviceObject) 523 { 524 return FALSE; 525 } 526 527 BOOLEAN 528 NTAPI 529 CPortPinWaveRT::FastRead( 530 IN PFILE_OBJECT FileObject, 531 IN PLARGE_INTEGER FileOffset, 532 IN ULONG Length, 533 IN BOOLEAN Wait, 534 IN ULONG LockKey, 535 IN PVOID Buffer, 536 OUT PIO_STATUS_BLOCK StatusBlock, 537 IN PDEVICE_OBJECT DeviceObject) 538 { 539 return FALSE; 540 } 541 542 BOOLEAN 543 NTAPI 544 CPortPinWaveRT::FastWrite( 545 IN PFILE_OBJECT FileObject, 546 IN PLARGE_INTEGER FileOffset, 547 IN ULONG Length, 548 IN BOOLEAN Wait, 549 IN ULONG LockKey, 550 IN PVOID Buffer, 551 OUT PIO_STATUS_BLOCK StatusBlock, 552 IN PDEVICE_OBJECT DeviceObject) 553 { 554 return FALSE; 555 } 556 557 NTSTATUS 558 NTAPI 559 CPortPinWaveRT::Init( 560 IN PPORTWAVERT Port, 561 IN PPORTFILTERWAVERT Filter, 562 IN KSPIN_CONNECT * ConnectDetails, 563 IN KSPIN_DESCRIPTOR * KsPinDescriptor, 564 IN PDEVICE_OBJECT DeviceObject) 565 { 566 NTSTATUS Status; 567 PKSDATAFORMAT DataFormat; 568 BOOLEAN Capture; 569 KSRTAUDIO_HWLATENCY Latency; 570 571 Port->AddRef(); 572 Filter->AddRef(); 573 574 m_Port = Port; 575 m_Filter = Filter; 576 m_KsPinDescriptor = KsPinDescriptor; 577 m_ConnectDetails = ConnectDetails; 578 m_Miniport = GetWaveRTMiniport(Port); 579 580 DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1); 581 582 DPRINT("CPortPinWaveRT::Init entered\n"); 583 584 m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); 585 if (!m_Format) 586 return STATUS_INSUFFICIENT_RESOURCES; 587 588 RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize); 589 590 Status = NewIrpQueue(&m_IrpQueue); 591 if (!NT_SUCCESS(Status)) 592 { 593 goto cleanup; 594 } 595 596 Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, 0, 0, FALSE); 597 if (!NT_SUCCESS(Status)) 598 { 599 goto cleanup; 600 } 601 602 Status = NewPortWaveRTStream(&m_PortStream); 603 if (!NT_SUCCESS(Status)) 604 { 605 goto cleanup; 606 } 607 608 if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN) 609 { 610 Capture = FALSE; 611 } 612 else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT) 613 { 614 Capture = TRUE; 615 } 616 else 617 { 618 DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow); 619 KeBugCheck(0); 620 while(TRUE); 621 } 622 623 Status = m_Miniport->NewStream(&m_Stream, m_PortStream, ConnectDetails->PinId, Capture, m_Format); 624 DPRINT("CPortPinWaveRT::Init Status %x\n", Status); 625 626 if (!NT_SUCCESS(Status)) 627 goto cleanup; 628 629 m_Stream->GetHWLatency(&Latency); 630 // delay of 10 millisec 631 m_Delay = Int32x32To64(10, -10000); 632 633 Status = m_Stream->AllocateAudioBuffer(16384 * 11, &m_Mdl, &m_CommonBufferSize, &m_CommonBufferOffset, &m_CacheType); 634 if (!NT_SUCCESS(Status)) 635 { 636 DPRINT("AllocateAudioBuffer failed with %x\n", Status); 637 goto cleanup; 638 } 639 640 m_CommonBuffer = MmGetSystemAddressForMdlSafe(m_Mdl, NormalPagePriority); 641 if (!m_CommonBuffer) 642 { 643 DPRINT("Failed to get system address %x\n", Status); 644 IoFreeMdl(m_Mdl); 645 m_Mdl = NULL; 646 goto cleanup; 647 } 648 649 DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); 650 DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); 651 m_State = KSSTATE_PAUSE; 652 return STATUS_SUCCESS; 653 654 cleanup: 655 if (m_IrpQueue) 656 { 657 m_IrpQueue->Release(); 658 m_IrpQueue = NULL; 659 } 660 661 if (m_Format) 662 { 663 FreeItem(m_Format, TAG_PORTCLASS); 664 m_Format = NULL; 665 } 666 667 if (m_Stream) 668 { 669 m_Stream->Release(); 670 m_Stream = NULL; 671 } 672 else 673 { 674 if (m_PortStream) 675 { 676 m_PortStream->Release(); 677 m_PortStream = NULL; 678 } 679 680 } 681 return Status; 682 } 683 684 685 NTSTATUS 686 NewPortPinWaveRT( 687 OUT IPortPinWaveRT ** OutPin) 688 { 689 CPortPinWaveRT * This; 690 691 This = new(NonPagedPool, TAG_PORTCLASS) CPortPinWaveRT(NULL); 692 if (!This) 693 return STATUS_INSUFFICIENT_RESOURCES; 694 695 This->AddRef(); 696 697 // store result 698 *OutPin = (PPORTPINWAVERT)This; 699 700 return STATUS_SUCCESS; 701 } 702