ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pin_wavert.cpp
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * PROJECT:         ReactOS Kernel Streaming
00004  * FILE:            drivers/wdm/audio/backpln/portcls/pin_wavert.cpp
00005  * PURPOSE:         WaveRT IRP Audio Pin
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 #include "private.hpp"
00010 
00011 class CPortPinWaveRT : public IPortPinWaveRT
00012 {
00013 public:
00014     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
00015 
00016     STDMETHODIMP_(ULONG) AddRef()
00017     {
00018         InterlockedIncrement(&m_Ref);
00019         return m_Ref;
00020     }
00021     STDMETHODIMP_(ULONG) Release()
00022     {
00023         InterlockedDecrement(&m_Ref);
00024 
00025         if (!m_Ref)
00026         {
00027             delete this;
00028             return 0;
00029         }
00030         return m_Ref;
00031     }
00032     IMP_IPortPinWaveRT;
00033     CPortPinWaveRT(IUnknown *OuterUnknown){}
00034     virtual ~CPortPinWaveRT(){}
00035 
00036 protected:
00037 
00038     IPortWaveRT * m_Port;
00039     IPortFilterWaveRT * m_Filter;
00040     KSPIN_DESCRIPTOR * m_KsPinDescriptor;
00041     PMINIPORTWAVERT m_Miniport;
00042     PMINIPORTWAVERTSTREAM m_Stream;
00043     PPORTWAVERTSTREAM m_PortStream;
00044     KSSTATE m_State;
00045     PKSDATAFORMAT m_Format;
00046     KSPIN_CONNECT * m_ConnectDetails;
00047 
00048     PVOID m_CommonBuffer;
00049     ULONG m_CommonBufferSize;
00050     ULONG m_CommonBufferOffset;
00051 
00052     IIrpQueue * m_IrpQueue;
00053 
00054     BOOL m_Capture;
00055 
00056     ULONG m_TotalPackets;
00057     ULONG m_PreCompleted;
00058     ULONG m_PostCompleted;
00059 
00060     ULONGLONG m_Delay;
00061 
00062     MEMORY_CACHING_TYPE m_CacheType;
00063     PMDL m_Mdl;
00064 
00065     LONG m_Ref;
00066 
00067     NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
00068     NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
00069     VOID NTAPI SetStreamState(IN KSSTATE State);
00070     friend VOID NTAPI SetStreamWorkerRoutine(IN PDEVICE_OBJECT  DeviceObject, IN PVOID  Context);
00071     friend VOID NTAPI CloseStreamRoutine(IN PDEVICE_OBJECT  DeviceObject, IN PVOID Context);
00072 
00073 };
00074 
00075 
00076 typedef struct
00077 {
00078     CPortPinWaveRT *Pin;
00079     PIO_WORKITEM WorkItem;
00080     KSSTATE State;
00081 }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
00082 
00083 
00084 //==================================================================================================================================
00085 NTSTATUS
00086 NTAPI
00087 CPortPinWaveRT::QueryInterface(
00088     IN  REFIID refiid,
00089     OUT PVOID* Output)
00090 {
00091     DPRINT("IServiceSink_fnQueryInterface entered\n");
00092 
00093     if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || 
00094         IsEqualGUIDAligned(refiid, IID_IUnknown))
00095     {
00096         *Output = PVOID(PUNKNOWN((IIrpTarget*)this));
00097         PUNKNOWN(*Output)->AddRef();
00098         return STATUS_SUCCESS;
00099     }
00100     return STATUS_UNSUCCESSFUL;
00101 }
00102 
00103 //==================================================================================================================================
00104 
00105 NTSTATUS
00106 NTAPI
00107 CPortPinWaveRT::NewIrpTarget(
00108     OUT struct IIrpTarget **OutTarget,
00109     IN PCWSTR Name,
00110     IN PUNKNOWN Unknown,
00111     IN POOL_TYPE PoolType,
00112     IN PDEVICE_OBJECT DeviceObject,
00113     IN PIRP Irp,
00114     IN KSOBJECT_CREATE *CreateObject)
00115 {
00116     UNIMPLEMENTED
00117     return STATUS_UNSUCCESSFUL;
00118 }
00119 
00120 NTSTATUS
00121 NTAPI
00122 CPortPinWaveRT::HandleKsProperty(
00123     IN PIRP Irp)
00124 {
00125     PKSPROPERTY Property;
00126     NTSTATUS Status;
00127     UNICODE_STRING GuidString;
00128     PIO_STACK_LOCATION IoStack;
00129 
00130     IoStack = IoGetCurrentIrpStackLocation(Irp);
00131 
00132     DPRINT("IPortPinWave_HandleKsProperty entered\n");
00133 
00134     if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
00135     {
00136         Irp->IoStatus.Information = 0;
00137         Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
00138         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00139         return STATUS_INVALID_PARAMETER;
00140     }
00141 
00142     Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
00143 
00144     if (IsEqualGUIDAligned(Property->Set, KSPROPSETID_Connection))
00145     {
00146         if (Property->Id == KSPROPERTY_CONNECTION_STATE)
00147         {
00148             PKSSTATE State = (PKSSTATE)Irp->UserBuffer;
00149 
00150             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE))
00151             {
00152                 Irp->IoStatus.Information = sizeof(KSSTATE);
00153                 Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
00154                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
00155                 return STATUS_BUFFER_TOO_SMALL;
00156             }
00157 
00158             if (Property->Flags & KSPROPERTY_TYPE_SET)
00159             {
00160                 Status = STATUS_UNSUCCESSFUL;
00161                 Irp->IoStatus.Information = 0;
00162 
00163                 if (m_Stream)
00164                 {
00165                     Status = m_Stream->SetState(*State);
00166 
00167                     DPRINT("Setting state %u %x\n", *State, Status);
00168                     if (NT_SUCCESS(Status))
00169                     {
00170                         m_State = *State;
00171                     }
00172                 }
00173                 Irp->IoStatus.Status = Status;
00174                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
00175                 return Status;
00176             }
00177             else if (Property->Flags & KSPROPERTY_TYPE_GET)
00178             {
00179                 *State = m_State;
00180                 Irp->IoStatus.Information = sizeof(KSSTATE);
00181                 Irp->IoStatus.Status = STATUS_SUCCESS;
00182                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
00183                 return STATUS_SUCCESS;
00184             }
00185         }
00186         else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT)
00187         {
00188             PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
00189             if (Property->Flags & KSPROPERTY_TYPE_SET)
00190             {
00191                 PKSDATAFORMAT NewDataFormat;
00192                 if (!RtlCompareMemory(DataFormat, m_Format, DataFormat->FormatSize))
00193                 {
00194                     Irp->IoStatus.Information = DataFormat->FormatSize;
00195                     Irp->IoStatus.Status = STATUS_SUCCESS;
00196                     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00197                     return STATUS_SUCCESS;
00198                 }
00199 
00200                 NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
00201                 if (!NewDataFormat)
00202                 {
00203                     Irp->IoStatus.Information = 0;
00204                     Irp->IoStatus.Status = STATUS_NO_MEMORY;
00205                     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00206                     return STATUS_NO_MEMORY;
00207                 }
00208                 RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
00209 
00210                 if (m_Stream)
00211                 {
00212 #if 0
00213                     ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
00214                     ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX));
00215                     ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO));
00216                     ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM));
00217                     ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX));
00218 
00219                     ASSERT(m_State == KSSTATE_STOP);
00220 #endif
00221                     DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels,
00222                                                                                  ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample,
00223                                                                                  ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec);
00224 
00225                     Status = m_Stream->SetFormat(NewDataFormat);
00226                     if (NT_SUCCESS(Status))
00227                     {
00228                         if (m_Format)
00229                             FreeItem(m_Format, TAG_PORTCLASS);
00230 
00231                         m_Format = NewDataFormat;
00232                         Irp->IoStatus.Information = DataFormat->FormatSize;
00233                         Irp->IoStatus.Status = STATUS_SUCCESS;
00234                         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00235                         return STATUS_SUCCESS;
00236                     }
00237                 }
00238                 DPRINT("Failed to set format\n");
00239                 Irp->IoStatus.Information = 0;
00240                 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
00241                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
00242                 return STATUS_UNSUCCESSFUL;
00243             }
00244             else if (Property->Flags & KSPROPERTY_TYPE_GET)
00245             {
00246                 if (!m_Format)
00247                 {
00248                     DPRINT("No format\n");
00249                     Irp->IoStatus.Information = 0;
00250                     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
00251                     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00252                     return STATUS_UNSUCCESSFUL;
00253                 }
00254                 if (m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
00255                 {
00256                     Irp->IoStatus.Information = m_Format->FormatSize;
00257                     Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
00258                     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00259                     return STATUS_BUFFER_TOO_SMALL;
00260                 }
00261 
00262                 RtlMoveMemory(DataFormat, m_Format, m_Format->FormatSize);
00263                 Irp->IoStatus.Information = DataFormat->FormatSize;
00264                 Irp->IoStatus.Status = STATUS_SUCCESS;
00265                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
00266                 return STATUS_SUCCESS;
00267             }
00268         }
00269 
00270     }
00271     RtlStringFromGUID(Property->Set, &GuidString);
00272     DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
00273     RtlFreeUnicodeString(&GuidString);
00274 
00275     Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
00276     Irp->IoStatus.Information = 0;
00277     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00278     return STATUS_NOT_IMPLEMENTED;
00279 }
00280 
00281 NTSTATUS
00282 NTAPI
00283 CPortPinWaveRT::HandleKsStream(
00284     IN PIRP Irp)
00285 {
00286     DPRINT("IPortPinWaveRT_HandleKsStream entered State %u Stream %p is UNIMPLEMENTED\n", m_State, m_Stream);
00287 
00288     return STATUS_PENDING;
00289 }
00290 
00291 NTSTATUS
00292 NTAPI
00293 CPortPinWaveRT::DeviceIoControl(
00294     IN PDEVICE_OBJECT DeviceObject,
00295     IN PIRP Irp)
00296 {
00297     PIO_STACK_LOCATION IoStack;
00298 
00299     IoStack = IoGetCurrentIrpStackLocation(Irp);
00300 
00301 
00302     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
00303     {
00304        return HandleKsProperty(Irp);
00305     }
00306     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
00307     {
00310     }
00311     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT)
00312     {
00315     }
00316     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE)
00317     {
00320     }
00321     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
00322     {
00323        return HandleKsStream(Irp);
00324     }
00325     else
00326     {
00327         return KsDefaultDeviceIoCompletion(DeviceObject, Irp);
00328     }
00329 
00330     UNIMPLEMENTED
00331 
00332     Irp->IoStatus.Information = 0;
00333     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
00334     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00335 
00336     return STATUS_UNSUCCESSFUL;
00337 }
00338 
00339 NTSTATUS
00340 NTAPI
00341 CPortPinWaveRT::Read(
00342     IN PDEVICE_OBJECT DeviceObject,
00343     IN PIRP Irp)
00344 {
00345     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00346 }
00347 
00348 NTSTATUS
00349 NTAPI
00350 CPortPinWaveRT::Write(
00351     IN PDEVICE_OBJECT DeviceObject,
00352     IN PIRP Irp)
00353 {
00354     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00355 }
00356 
00357 NTSTATUS
00358 NTAPI
00359 CPortPinWaveRT::Flush(
00360     IN PDEVICE_OBJECT DeviceObject,
00361     IN PIRP Irp)
00362 {
00363     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00364 }
00365 
00366 VOID
00367 NTAPI
00368 CloseStreamRoutine(
00369     IN PDEVICE_OBJECT  DeviceObject,
00370     IN PVOID Context)
00371 {
00372     PMINIPORTWAVERTSTREAM Stream;
00373     NTSTATUS Status;
00374     ISubdevice *ISubDevice;
00375     PSUBDEVICE_DESCRIPTOR Descriptor;
00376     CPortPinWaveRT * This;
00377     PCLOSESTREAM_CONTEXT Ctx = (PCLOSESTREAM_CONTEXT)Context;
00378 
00379     This = (CPortPinWaveRT*)Ctx->Pin;
00380 
00381     if (This->m_Stream)
00382     {
00383         if (This->m_State != KSSTATE_STOP)
00384         {
00385             This->m_Stream->SetState(KSSTATE_STOP);
00386             KeStallExecutionProcessor(10);
00387         }
00388     }
00389 
00390     Status = This->m_Port->QueryInterface(IID_ISubdevice, (PVOID*)&ISubDevice);
00391     if (NT_SUCCESS(Status))
00392     {
00393         Status = ISubDevice->GetDescriptor(&Descriptor);
00394         if (NT_SUCCESS(Status))
00395         {
00396             Descriptor->Factory.Instances[This->m_ConnectDetails->PinId].CurrentPinInstanceCount--;
00397         }
00398         ISubDevice->Release();
00399     }
00400 
00401     if (This->m_Format)
00402     {
00403         FreeItem(This->m_Format, TAG_PORTCLASS);
00404         This->m_Format = NULL;
00405     }
00406 
00407     if (This->m_IrpQueue)
00408     {
00409         This->m_IrpQueue->Release();
00410     }
00411 
00412     // complete the irp
00413     Ctx->Irp->IoStatus.Information = 0;
00414     Ctx->Irp->IoStatus.Status = STATUS_SUCCESS;
00415     IoCompleteRequest(Ctx->Irp, IO_NO_INCREMENT);
00416 
00417     // free the work item
00418     IoFreeWorkItem(Ctx->WorkItem);
00419 
00420     // free work item ctx
00421     FreeItem(Ctx, TAG_PORTCLASS);
00422 
00423     if (This->m_Stream)
00424     {
00425         Stream = This->m_Stream;
00426         This->m_Stream = NULL;
00427         DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
00428         Stream->Release();
00429     }
00430 }
00431 
00432 NTSTATUS
00433 NTAPI
00434 CPortPinWaveRT::Close(
00435     IN PDEVICE_OBJECT DeviceObject,
00436     IN PIRP Irp)
00437 {
00438     PCLOSESTREAM_CONTEXT Ctx;
00439 
00440     if (m_Stream)
00441     {
00442         Ctx = (PCLOSESTREAM_CONTEXT)AllocateItem(NonPagedPool, sizeof(CLOSESTREAM_CONTEXT), TAG_PORTCLASS);
00443         if (!Ctx)
00444         {
00445             DPRINT("Failed to allocate stream context\n");
00446             goto cleanup;
00447         }
00448 
00449         Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
00450         if (!Ctx->WorkItem)
00451         {
00452             DPRINT("Failed to allocate work item\n");
00453             goto cleanup;
00454         }
00455 
00456         Ctx->Irp = Irp;
00457         Ctx->Pin = this;
00458 
00459         IoMarkIrpPending(Irp);
00460         Irp->IoStatus.Information = 0;
00461         Irp->IoStatus.Status = STATUS_PENDING;
00462 
00463         // defer work item
00464         IoQueueWorkItem(Ctx->WorkItem, CloseStreamRoutine, DelayedWorkQueue, (PVOID)Ctx);
00465         // Return result
00466         return STATUS_PENDING;
00467     }
00468 
00469     Irp->IoStatus.Information = 0;
00470     Irp->IoStatus.Status = STATUS_SUCCESS;
00471     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00472 
00473     return STATUS_SUCCESS;
00474 
00475 cleanup:
00476 
00477     if (Ctx)
00478         FreeItem(Ctx, TAG_PORTCLASS);
00479 
00480     Irp->IoStatus.Information = 0;
00481     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
00482     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00483     return STATUS_UNSUCCESSFUL;
00484 
00485 }
00486 
00487 NTSTATUS
00488 NTAPI
00489 CPortPinWaveRT::QuerySecurity(
00490     IN PDEVICE_OBJECT DeviceObject,
00491     IN PIRP Irp)
00492 {
00493     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00494 }
00495 
00496 NTSTATUS
00497 NTAPI
00498 CPortPinWaveRT::SetSecurity(
00499     IN PDEVICE_OBJECT DeviceObject,
00500     IN PIRP Irp)
00501 {
00502     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00503 }
00504 
00505 BOOLEAN
00506 NTAPI
00507 CPortPinWaveRT::FastDeviceIoControl(
00508     IN PFILE_OBJECT FileObject,
00509     IN BOOLEAN Wait,
00510     IN PVOID InputBuffer,
00511     IN ULONG InputBufferLength,
00512     OUT PVOID OutputBuffer,
00513     IN ULONG OutputBufferLength,
00514     IN ULONG IoControlCode,
00515     OUT PIO_STATUS_BLOCK StatusBlock,
00516     IN PDEVICE_OBJECT DeviceObject)
00517 {
00518     return FALSE;
00519 }
00520 
00521 BOOLEAN
00522 NTAPI
00523 CPortPinWaveRT::FastRead(
00524     IN PFILE_OBJECT FileObject,
00525     IN PLARGE_INTEGER FileOffset,
00526     IN ULONG Length,
00527     IN BOOLEAN Wait,
00528     IN ULONG LockKey,
00529     IN PVOID Buffer,
00530     OUT PIO_STATUS_BLOCK StatusBlock,
00531     IN PDEVICE_OBJECT DeviceObject)
00532 {
00533     return FALSE;
00534 }
00535 
00536 BOOLEAN
00537 NTAPI
00538 CPortPinWaveRT::FastWrite(
00539     IN PFILE_OBJECT FileObject,
00540     IN PLARGE_INTEGER FileOffset,
00541     IN ULONG Length,
00542     IN BOOLEAN Wait,
00543     IN ULONG LockKey,
00544     IN PVOID Buffer,
00545     OUT PIO_STATUS_BLOCK StatusBlock,
00546     IN PDEVICE_OBJECT DeviceObject)
00547 {
00548     return FALSE;
00549 }
00550 
00551 NTSTATUS
00552 NTAPI
00553 CPortPinWaveRT::Init(
00554     IN PPORTWAVERT Port,
00555     IN PPORTFILTERWAVERT Filter,
00556     IN KSPIN_CONNECT * ConnectDetails,
00557     IN KSPIN_DESCRIPTOR * KsPinDescriptor,
00558     IN PDEVICE_OBJECT DeviceObject)
00559 {
00560     NTSTATUS Status;
00561     PKSDATAFORMAT DataFormat;
00562     BOOLEAN Capture;
00563     KSRTAUDIO_HWLATENCY Latency;
00564 
00565     Port->AddRef();
00566     Filter->AddRef();
00567 
00568     m_Port = Port;
00569     m_Filter = Filter;
00570     m_KsPinDescriptor = KsPinDescriptor;
00571     m_ConnectDetails = ConnectDetails;
00572     m_Miniport = GetWaveRTMiniport(Port);
00573 
00574     DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
00575 
00576     DPRINT("CPortPinWaveRT::Init entered\n");
00577 
00578     m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
00579     if (!m_Format)
00580         return STATUS_INSUFFICIENT_RESOURCES;
00581 
00582     RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
00583 
00584     Status = NewIrpQueue(&m_IrpQueue);
00585     if (!NT_SUCCESS(Status))
00586     {
00587         goto cleanup;
00588     }
00589 
00590     Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, 0, 0, FALSE);
00591     if (!NT_SUCCESS(Status))
00592     {
00593         goto cleanup;
00594     }
00595 
00596     Status = NewPortWaveRTStream(&m_PortStream);
00597     if (!NT_SUCCESS(Status))
00598     {
00599         goto cleanup;
00600     }
00601 
00602     if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
00603     {
00604         Capture = FALSE;
00605     }
00606     else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
00607     {
00608         Capture = TRUE;
00609     }
00610     else
00611     {
00612         DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
00613         KeBugCheck(0);
00614         while(TRUE);
00615     }
00616 
00617     Status = m_Miniport->NewStream(&m_Stream, m_PortStream, ConnectDetails->PinId, Capture, m_Format);
00618     DPRINT("CPortPinWaveRT::Init Status %x\n", Status);
00619 
00620     if (!NT_SUCCESS(Status))
00621         goto cleanup;
00622 
00623     m_Stream->GetHWLatency(&Latency);
00624     // delay of 10 milisec
00625     m_Delay = Int32x32To64(10, -10000);
00626 
00627     Status = m_Stream->AllocateAudioBuffer(16384 * 11, &m_Mdl, &m_CommonBufferSize, &m_CommonBufferOffset, &m_CacheType);
00628     if (!NT_SUCCESS(Status))
00629     {
00630         DPRINT("AllocateAudioBuffer failed with %x\n", Status);
00631         goto cleanup;
00632     }
00633 
00634     m_CommonBuffer = MmGetSystemAddressForMdlSafe(m_Mdl, NormalPagePriority);
00635     if (!NT_SUCCESS(Status))
00636     {
00637         DPRINT("Failed to get system address %x\n", Status);
00638         IoFreeMdl(m_Mdl);
00639         m_Mdl = NULL;
00640         goto cleanup;
00641     }
00642 
00643     DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE));
00644     DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE));
00645     m_State = KSSTATE_PAUSE;
00646     return STATUS_SUCCESS;
00647 
00648 cleanup:
00649     if (m_IrpQueue)
00650     {
00651         m_IrpQueue->Release();
00652         m_IrpQueue = NULL;
00653     }
00654 
00655     if (m_Format)
00656     {
00657         FreeItem(m_Format, TAG_PORTCLASS);
00658         m_Format = NULL;
00659     }
00660 
00661     if (m_Stream)
00662     {
00663         m_Stream->Release();
00664         m_Stream = NULL;
00665     }
00666     else
00667     {
00668         if (m_PortStream)
00669         {
00670             m_PortStream->Release();
00671             m_PortStream = NULL;
00672         }
00673 
00674     }
00675     return Status;
00676 }
00677 
00678 
00679 NTSTATUS
00680 NewPortPinWaveRT(
00681     OUT IPortPinWaveRT ** OutPin)
00682 {
00683     CPortPinWaveRT * This;
00684 
00685     This = new(NonPagedPool, TAG_PORTCLASS) CPortPinWaveRT(NULL);
00686     if (!This)
00687         return STATUS_INSUFFICIENT_RESOURCES;
00688 
00689     This->AddRef();
00690 
00691     // store result
00692     *OutPin = (PPORTPINWAVERT)This;
00693 
00694     return STATUS_SUCCESS;
00695 }

Generated on Fri May 25 2012 04:26:51 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.