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_wavepci.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_wavepci.cpp
00005  * PURPOSE:         WavePci IRP Audio Pin
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 #include "private.hpp"
00010 
00011 class CPortPinWavePci : public IPortPinWavePci,
00012                         public IServiceSink,
00013                         public IPortWavePciStream
00014 {
00015 public:
00016     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
00017 
00018     STDMETHODIMP_(ULONG) AddRef()
00019     {
00020         InterlockedIncrement(&m_Ref);
00021         return m_Ref;
00022     }
00023     STDMETHODIMP_(ULONG) Release()
00024     {
00025         InterlockedDecrement(&m_Ref);
00026 
00027         if (!m_Ref)
00028         {
00029             delete this;
00030             return 0;
00031         }
00032         return m_Ref;
00033     }
00034     IMP_IPortPinWavePci;
00035     IMP_IServiceSink;
00036     IMP_IPortWavePciStream;
00037     CPortPinWavePci(IUnknown *OuterUnknown) {}
00038     virtual ~CPortPinWavePci(){}
00039 protected:
00040 
00041     friend NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00042     friend NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00043     friend NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00044     friend NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00045 
00046     IPortWavePci * m_Port;
00047     IPortFilterWavePci * m_Filter;
00048     KSPIN_DESCRIPTOR * m_KsPinDescriptor;
00049     PMINIPORTWAVEPCI m_Miniport;
00050     PSERVICEGROUP m_ServiceGroup;
00051     PDMACHANNEL m_DmaChannel;
00052     PMINIPORTWAVEPCISTREAM m_Stream;
00053     KSSTATE m_State;
00054     PKSDATAFORMAT m_Format;
00055     KSPIN_CONNECT * m_ConnectDetails;
00056 
00057     BOOL m_Capture;
00058     PDEVICE_OBJECT m_DeviceObject;
00059     IIrpQueue * m_IrpQueue;
00060 
00061     ULONG m_TotalPackets;
00062     KSAUDIO_POSITION m_Position;
00063     ULONG m_StopCount;
00064 
00065     BOOL m_bUsePrefetch;
00066     ULONG m_PrefetchOffset;
00067     SUBDEVICE_DESCRIPTOR m_Descriptor;
00068 
00069     KSALLOCATOR_FRAMING m_AllocatorFraming;
00070 
00071     LONG m_Ref;
00072 
00073     NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
00074     NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
00075 };
00076 
00077 typedef struct
00078 {
00079     CPortPinWavePci *Pin;
00080     PIO_WORKITEM WorkItem;
00081     KSSTATE State;
00082 }SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
00083 
00084 NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00085 NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00086 NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00087 NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
00088 
00089 DEFINE_KSPROPERTY_CONNECTIONSET(PinWavePciConnectionSet, PinWavePciState, PinWavePciDataFormat, PinWavePciAllocatorFraming);
00090 DEFINE_KSPROPERTY_AUDIOSET(PinWavePciAudioSet, PinWavePciAudioPosition);
00091 
00092 KSPROPERTY_SET PinWavePciPropertySet[] =
00093 {
00094     {
00095         &KSPROPSETID_Connection,
00096         sizeof(PinWavePciConnectionSet) / sizeof(KSPROPERTY_ITEM),
00097         (const KSPROPERTY_ITEM*)&PinWavePciConnectionSet,
00098         0,
00099         NULL
00100     },
00101     {
00102         &KSPROPSETID_Audio,
00103         sizeof(PinWavePciAudioSet) / sizeof(KSPROPERTY_ITEM),
00104         (const KSPROPERTY_ITEM*)&PinWavePciAudioSet,
00105         0,
00106         NULL
00107     }
00108 };
00109 
00110 
00111 NTSTATUS
00112 NTAPI
00113 PinWavePciAllocatorFraming(
00114     IN PIRP Irp,
00115     IN PKSIDENTIFIER Request,
00116     IN OUT PVOID Data)
00117 {
00118     CPortPinWavePci *Pin;
00119     PSUBDEVICE_DESCRIPTOR Descriptor;
00120 
00121     // get sub device descriptor 
00122     Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
00123 
00124     // sanity check 
00125     PC_ASSERT(Descriptor);
00126     PC_ASSERT(Descriptor->PortPin);
00127     PC_ASSERT_IRQL(DISPATCH_LEVEL);
00128 
00129     // cast to pin impl
00130     Pin = (CPortPinWavePci*)Descriptor->PortPin;
00131 
00132 
00133     if (Request->Flags & KSPROPERTY_TYPE_GET)
00134     {
00135         // copy pin framing
00136         RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING));
00137 
00138         Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING);
00139         return STATUS_SUCCESS;
00140     }
00141 
00142     // not supported
00143     return STATUS_NOT_SUPPORTED;
00144 }
00145 
00146 NTSTATUS
00147 NTAPI
00148 PinWavePciAudioPosition(
00149     IN PIRP Irp,
00150     IN PKSIDENTIFIER Request,
00151     IN OUT PVOID Data)
00152 {
00153     CPortPinWavePci *Pin;
00154     PSUBDEVICE_DESCRIPTOR Descriptor;
00155 
00156     // get sub device descriptor 
00157     Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
00158 
00159     // sanity check 
00160     PC_ASSERT(Descriptor);
00161     PC_ASSERT(Descriptor->PortPin);
00162     PC_ASSERT_IRQL(DISPATCH_LEVEL);
00163 
00164     // cast to pin impl
00165     Pin = (CPortPinWavePci*)Descriptor->PortPin;
00166 
00167     //sanity check
00168     PC_ASSERT(Pin->m_Stream);
00169 
00170     if (Request->Flags & KSPROPERTY_TYPE_GET)
00171     {
00172         // FIXME non multithreading-safe
00173         // copy audio position
00174         RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION));
00175 
00176         DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset);
00177         Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION);
00178         return STATUS_SUCCESS;
00179     }
00180 
00181     // not supported
00182     return STATUS_NOT_SUPPORTED;
00183 }
00184 
00185 
00186 NTSTATUS
00187 NTAPI
00188 PinWavePciState(
00189     IN PIRP Irp,
00190     IN PKSIDENTIFIER Request,
00191     IN OUT PVOID Data)
00192 {
00193     NTSTATUS Status = STATUS_UNSUCCESSFUL;
00194     CPortPinWavePci *Pin;
00195     PSUBDEVICE_DESCRIPTOR Descriptor;
00196     PVOID FirstTag, LastTag;
00197     ULONG MappingsRevoked;
00198     PKSSTATE State = (PKSSTATE)Data;
00199 
00200     // get sub device descriptor 
00201     Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
00202 
00203     // sanity check 
00204     PC_ASSERT(Descriptor);
00205     PC_ASSERT(Descriptor->PortPin);
00206     PC_ASSERT_IRQL(DISPATCH_LEVEL);
00207 
00208     // cast to pin impl
00209     Pin = (CPortPinWavePci*)Descriptor->PortPin;
00210 
00211     //sanity check
00212     PC_ASSERT(Pin->m_Stream);
00213 
00214     if (Request->Flags & KSPROPERTY_TYPE_SET)
00215     {
00216         // try set stream
00217         Status = Pin->m_Stream->SetState(*State);
00218 
00219         DPRINT("Setting state %u %x\n", *State, Status);
00220         if (NT_SUCCESS(Status))
00221         {
00222             // store new state
00223             Pin->m_State = *State;
00224             if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP)
00225             {
00226                 // FIXME
00227                 // complete with successful state
00228                 Pin->m_IrpQueue->CancelBuffers();
00229                 while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag))
00230                 {
00231                     Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked);
00232                     DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked);
00233                     KeStallExecutionProcessor(10);
00234                 }
00235                 Pin->m_Position.PlayOffset = 0;
00236                 Pin->m_Position.WriteOffset = 0;
00237             }
00238             else if (Pin->m_State == KSSTATE_STOP)
00239             {
00240                 Pin->m_IrpQueue->CancelBuffers();
00241                 while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag))
00242                 {
00243                     Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked);
00244                     DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked);
00245                     KeStallExecutionProcessor(10);
00246                 }
00247                 Pin->m_Position.PlayOffset = 0;
00248                 Pin->m_Position.WriteOffset = 0;
00249             }
00250             // store result
00251             Irp->IoStatus.Information = sizeof(KSSTATE);
00252 
00253         }
00254         // store result
00255         Irp->IoStatus.Information = sizeof(KSSTATE);
00256         return Status;
00257     }
00258     else if (Request->Flags & KSPROPERTY_TYPE_GET)
00259     {
00260         // get current stream state
00261         *State = Pin->m_State;
00262         // store result
00263         Irp->IoStatus.Information = sizeof(KSSTATE);
00264 
00265         return STATUS_SUCCESS;
00266     }
00267 
00268     // unsupported request
00269     return STATUS_NOT_SUPPORTED;
00270 }
00271 
00272 NTSTATUS
00273 NTAPI
00274 PinWavePciDataFormat(
00275     IN PIRP Irp,
00276     IN PKSIDENTIFIER Request,
00277     IN OUT PVOID Data)
00278 {
00279     NTSTATUS Status = STATUS_UNSUCCESSFUL;
00280     CPortPinWavePci *Pin;
00281     PSUBDEVICE_DESCRIPTOR Descriptor;
00282     PIO_STACK_LOCATION IoStack;
00283 
00284     // get current irp stack location
00285     IoStack = IoGetCurrentIrpStackLocation(Irp);
00286 
00287     // get sub device descriptor 
00288     Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
00289 
00290     // sanity check 
00291     PC_ASSERT(Descriptor);
00292     PC_ASSERT(Descriptor->PortPin);
00293 
00294     // cast to pin impl
00295     Pin = (CPortPinWavePci*)Descriptor->PortPin;
00296 
00297     //sanity check
00298     PC_ASSERT(Pin->m_Stream);
00299     PC_ASSERT(Pin->m_Format);
00300 
00301     if (Request->Flags & KSPROPERTY_TYPE_SET)
00302     {
00303         // try to change data format
00304         PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
00305         ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize);
00306 
00307         if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size)
00308         {
00309             // format is identical
00310             Irp->IoStatus.Information = DataFormat->FormatSize;
00311             return STATUS_SUCCESS;
00312         }
00313 
00314         // new change request
00315         PC_ASSERT(Pin->m_State == KSSTATE_STOP);
00316         // FIXME queue a work item when Irql != PASSIVE_LEVEL
00317         PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
00318 
00319         // allocate new data format
00320         NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
00321         if (!NewDataFormat)
00322         {
00323             // not enough memory
00324             return STATUS_NO_MEMORY;
00325         }
00326 
00327         // copy new data format
00328         RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
00329 
00330         // set new format
00331         Status = Pin->m_Stream->SetFormat(NewDataFormat);
00332         if (NT_SUCCESS(Status))
00333         {
00334             // free old format
00335             FreeItem(Pin->m_Format, TAG_PORTCLASS);
00336 
00337             // store new format
00338             Pin->m_Format = NewDataFormat;
00339             Irp->IoStatus.Information = NewDataFormat->FormatSize;
00340 
00341 #if 0
00342             PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX));
00343             PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO));
00344             PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM));
00345             PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX));
00346 
00347 
00348             DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels,
00349                                                                        ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample,
00350                                                                        ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec);
00351 #endif
00352 
00353         }
00354         else
00355         {
00356             // failed to set format
00357             FreeItem(NewDataFormat, TAG_PORTCLASS);
00358         }
00359 
00360 
00361         // done
00362         return Status;
00363     }
00364     else if (Request->Flags & KSPROPERTY_TYPE_GET)
00365     {
00366         // get current data format
00367         PC_ASSERT(Pin->m_Format);
00368 
00369         if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
00370         {
00371             // buffer too small
00372             Irp->IoStatus.Information = Pin->m_Format->FormatSize;
00373             return STATUS_MORE_ENTRIES;
00374         }
00375         // copy data format
00376         RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize);
00377         // store result size
00378         Irp->IoStatus.Information = Pin->m_Format->FormatSize;
00379 
00380         // done
00381         return STATUS_SUCCESS;
00382     }
00383 
00384     // unsupported request
00385     return STATUS_NOT_SUPPORTED;
00386 }
00387 
00388 
00389 //==================================================================================================================================
00390 NTSTATUS
00391 NTAPI
00392 CPortPinWavePci::QueryInterface(
00393     IN  REFIID refiid,
00394     OUT PVOID* Output)
00395 {
00396     //DPRINT("CPortPinWavePci::QueryInterface entered\n");
00397 
00398     if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) || 
00399         IsEqualGUIDAligned(refiid, IID_IUnknown))
00400     {
00401         *Output = PVOID(PUNKNOWN((IIrpTarget*)this));
00402         PUNKNOWN(*Output)->AddRef();
00403         return STATUS_SUCCESS;
00404     }
00405 
00406     if (IsEqualGUIDAligned(refiid, IID_IServiceSink))
00407     {
00408         *Output = PVOID(PSERVICESINK(this));
00409         PUNKNOWN(*Output)->AddRef();
00410         return STATUS_SUCCESS;
00411     }
00412 
00413 
00414     if (IsEqualGUIDAligned(refiid, IID_IPortWavePciStream))
00415     {
00416         *Output = PVOID(PPORTWAVEPCISTREAM(this));
00417         PUNKNOWN(*Output)->AddRef();
00418         return STATUS_SUCCESS;
00419     }
00420 
00421     return STATUS_UNSUCCESSFUL;
00422 }
00423 
00424 NTSTATUS
00425 NTAPI
00426 CPortPinWavePci::GetMapping(
00427     IN PVOID Tag,
00428     OUT PPHYSICAL_ADDRESS  PhysicalAddress,
00429     OUT PVOID  *VirtualAddress,
00430     OUT PULONG  ByteCount,
00431     OUT PULONG  Flags)
00432 {
00433 
00434     PC_ASSERT_IRQL(DISPATCH_LEVEL);
00435     return m_IrpQueue->GetMappingWithTag(Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags);
00436 }
00437 
00438 NTSTATUS
00439 NTAPI
00440 CPortPinWavePci::ReleaseMapping(
00441     IN PVOID  Tag)
00442 {
00443 
00444     PC_ASSERT_IRQL(DISPATCH_LEVEL);
00445     return m_IrpQueue->ReleaseMappingWithTag(Tag);
00446 }
00447 
00448 NTSTATUS
00449 NTAPI
00450 CPortPinWavePci::TerminatePacket()
00451 {
00452     UNIMPLEMENTED
00453     PC_ASSERT_IRQL(DISPATCH_LEVEL);
00454     return STATUS_SUCCESS;
00455 }
00456 
00457 
00458 VOID
00459 NTAPI
00460 CPortPinWavePci::RequestService()
00461 {
00462     PC_ASSERT_IRQL(DISPATCH_LEVEL);
00463 
00464     if (m_State == KSSTATE_RUN)
00465     {
00466         m_Stream->Service();
00467         //TODO
00468         //generate events
00469     }
00470 }
00471 
00472 //==================================================================================================================================
00473 
00474 NTSTATUS
00475 NTAPI
00476 CPortPinWavePci::NewIrpTarget(
00477     OUT struct IIrpTarget **OutTarget,
00478     IN PCWSTR Name,
00479     IN PUNKNOWN Unknown,
00480     IN POOL_TYPE PoolType,
00481     IN PDEVICE_OBJECT DeviceObject,
00482     IN PIRP Irp,
00483     IN KSOBJECT_CREATE *CreateObject)
00484 {
00485     UNIMPLEMENTED
00486 
00487     Irp->IoStatus.Information = 0;
00488     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
00489     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00490 
00491     return STATUS_UNSUCCESSFUL;
00492 }
00493 
00494 NTSTATUS
00495 NTAPI
00496 CPortPinWavePci::HandleKsProperty(
00497     IN PIRP Irp)
00498 {
00499     //PKSPROPERTY Property;
00500     NTSTATUS Status;
00501     //UNICODE_STRING GuidString;
00502     PIO_STACK_LOCATION IoStack;
00503 
00504     IoStack = IoGetCurrentIrpStackLocation(Irp);
00505 
00506     //DPRINT("IPortPinWave_HandleKsProperty entered\n");
00507 
00508     IoStack = IoGetCurrentIrpStackLocation(Irp);
00509 
00510     if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
00511     {
00512         //DPRINT("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
00513         
00514         Irp->IoStatus.Status = STATUS_SUCCESS;
00515 
00516         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00517         return STATUS_SUCCESS;
00518     }
00519 
00520     Status = PcHandlePropertyWithTable(Irp,  m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor);
00521 
00522     if (Status == STATUS_NOT_FOUND)
00523     {
00524         //Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
00525 #if 0
00526         RtlStringFromGUID(Property->Set, &GuidString);
00527         //DPRINT("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
00528         RtlFreeUnicodeString(&GuidString);
00529 #endif
00530     }
00531 
00532     if (Status != STATUS_PENDING)
00533     {
00534         Irp->IoStatus.Status = Status;
00535         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00536     }
00537 
00538     return Status;
00539 }
00540 
00541 NTSTATUS
00542 NTAPI
00543 CPortPinWavePci::HandleKsStream(
00544     IN PIRP Irp)
00545 {
00546     NTSTATUS Status;
00547     ULONG Data = 0;
00548     BOOLEAN bFailed;
00549     InterlockedIncrement((PLONG)&m_TotalPackets);
00550 
00551     DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
00552 
00553     bFailed = m_IrpQueue->HasLastMappingFailed();
00554 
00555     Status = m_IrpQueue->AddMapping(Irp, &Data);
00556 
00557     if (NT_SUCCESS(Status))
00558     {
00559         if (m_Capture)
00560             m_Position.WriteOffset += Data;
00561         else
00562             m_Position.WriteOffset += Data;
00563 
00564         if (bFailed)
00565         {
00566             // notify stream of new mapping
00567             m_Stream->MappingAvailable();
00568         }
00569 
00570         return STATUS_PENDING;
00571     }
00572 
00573     return Status;
00574 }
00575 
00576 
00577 NTSTATUS
00578 NTAPI
00579 CPortPinWavePci::DeviceIoControl(
00580     IN PDEVICE_OBJECT DeviceObject,
00581     IN PIRP Irp)
00582 {
00583     PIO_STACK_LOCATION IoStack;
00584 
00585     IoStack = IoGetCurrentIrpStackLocation(Irp);
00586 
00587     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
00588     {
00589         return HandleKsProperty(Irp);
00590     }
00591     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
00592     {
00593        return HandleKsStream(Irp);
00594     }
00595 
00596     UNIMPLEMENTED
00597 
00598     Irp->IoStatus.Information = 0;
00599     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
00600     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00601 
00602     return STATUS_UNSUCCESSFUL;
00603 }
00604 
00605 NTSTATUS
00606 NTAPI
00607 CPortPinWavePci::Read(
00608     IN PDEVICE_OBJECT DeviceObject,
00609     IN PIRP Irp)
00610 {
00611     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00612 }
00613 
00614 NTSTATUS
00615 NTAPI
00616 CPortPinWavePci::Write(
00617     IN PDEVICE_OBJECT DeviceObject,
00618     IN PIRP Irp)
00619 {
00620     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00621 }
00622 
00623 NTSTATUS
00624 NTAPI
00625 CPortPinWavePci::Flush(
00626     IN PDEVICE_OBJECT DeviceObject,
00627     IN PIRP Irp)
00628 {
00629     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00630 }
00631 
00632 NTSTATUS
00633 NTAPI
00634 CPortPinWavePci::Close(
00635     IN PDEVICE_OBJECT DeviceObject,
00636     IN PIRP Irp)
00637 {
00638     NTSTATUS Status;
00639 
00640     if (m_Format)
00641     {
00642         // free format
00643         FreeItem(m_Format, TAG_PORTCLASS);
00644 
00645         // format is freed
00646         m_Format = NULL;
00647     }
00648 
00649     if (m_IrpQueue)
00650     {
00651         // cancel remaining irps
00652         m_IrpQueue->CancelBuffers();
00653 
00654         // release irp queue
00655         m_IrpQueue->Release();
00656 
00657         // queue is freed
00658         m_IrpQueue = NULL;
00659     }
00660 
00661 
00662     if (m_ServiceGroup)
00663     {
00664         // remove member from service group
00665         m_ServiceGroup->RemoveMember(PSERVICESINK(this));
00666 
00667         // do not release service group, it is released by the miniport object
00668         m_ServiceGroup = NULL;
00669     }
00670 
00671     if (m_Stream)
00672     {
00673         if (m_State != KSSTATE_STOP)
00674         {
00675             // stop stream
00676             Status = m_Stream->SetState(KSSTATE_STOP);
00677             if (!NT_SUCCESS(Status))
00678             {
00679                 DPRINT("Warning: failed to stop stream with %x\n", Status);
00680                 PC_ASSERT(0);
00681             }
00682         }
00683         // set state to stop
00684         m_State = KSSTATE_STOP;
00685 
00686         DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql());
00687 
00688         // release stream
00689         m_Stream->Release();
00690 
00691         // stream is now freed
00692         m_Stream = NULL;
00693     }
00694 
00695     if (m_Filter)
00696     {
00697         // disconnect pin from filter
00698         m_Filter->FreePin((PPORTPINWAVEPCI)this);
00699 
00700         // release filter reference
00701         m_Filter->Release();
00702 
00703         // pin is done with filter
00704         m_Filter = NULL;
00705     }
00706 
00707     if (m_Port)
00708     {
00709         // release reference to port driver
00710         m_Port->Release();
00711 
00712         // work is done for port
00713         m_Port = NULL;
00714     }
00715 
00716     // successfully complete irp
00717     Irp->IoStatus.Status = STATUS_SUCCESS;
00718     Irp->IoStatus.Information = 0;
00719     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00720 
00721     return STATUS_SUCCESS;
00722 }
00723 
00724 NTSTATUS
00725 NTAPI
00726 CPortPinWavePci::QuerySecurity(
00727     IN PDEVICE_OBJECT DeviceObject,
00728     IN PIRP Irp)
00729 {
00730     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00731 }
00732 
00733 NTSTATUS
00734 NTAPI
00735 CPortPinWavePci::SetSecurity(
00736     IN PDEVICE_OBJECT DeviceObject,
00737     IN PIRP Irp)
00738 {
00739     return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
00740 }
00741 
00742 BOOLEAN
00743 NTAPI
00744 CPortPinWavePci::FastDeviceIoControl(
00745     IN PFILE_OBJECT FileObject,
00746     IN BOOLEAN Wait,
00747     IN PVOID InputBuffer,
00748     IN ULONG InputBufferLength,
00749     OUT PVOID OutputBuffer,
00750     IN ULONG OutputBufferLength,
00751     IN ULONG IoControlCode,
00752     OUT PIO_STATUS_BLOCK StatusBlock,
00753     IN PDEVICE_OBJECT DeviceObject)
00754 {
00755     return FALSE;
00756 }
00757 
00758 BOOLEAN
00759 NTAPI
00760 CPortPinWavePci::FastRead(
00761     IN PFILE_OBJECT FileObject,
00762     IN PLARGE_INTEGER FileOffset,
00763     IN ULONG Length,
00764     IN BOOLEAN Wait,
00765     IN ULONG LockKey,
00766     IN PVOID Buffer,
00767     OUT PIO_STATUS_BLOCK StatusBlock,
00768     IN PDEVICE_OBJECT DeviceObject)
00769 {
00770     return FALSE;
00771 }
00772 
00773 BOOLEAN
00774 NTAPI
00775 CPortPinWavePci::FastWrite(
00776     IN PFILE_OBJECT FileObject,
00777     IN PLARGE_INTEGER FileOffset,
00778     IN ULONG Length,
00779     IN BOOLEAN Wait,
00780     IN ULONG LockKey,
00781     IN PVOID Buffer,
00782     OUT PIO_STATUS_BLOCK StatusBlock,
00783     IN PDEVICE_OBJECT DeviceObject)
00784 {
00785     return FALSE;
00786 }
00787 
00788 
00789 NTSTATUS
00790 NTAPI
00791 CPortPinWavePci::Init(
00792     IN PPORTWAVEPCI Port,
00793     IN PPORTFILTERWAVEPCI Filter,
00794     IN KSPIN_CONNECT * ConnectDetails,
00795     IN KSPIN_DESCRIPTOR * KsPinDescriptor,
00796     IN PDEVICE_OBJECT DeviceObject)
00797 {
00798     NTSTATUS Status;
00799     PKSDATAFORMAT DataFormat;
00800     BOOLEAN Capture;
00801     ISubdevice * Subdevice = NULL;
00802     PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL;
00803 
00804     // check if it is a source / sink pin
00805     if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
00806     {
00807         // sink pin
00808         Capture = FALSE;
00809     }
00810     else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
00811     {
00812         // source pin
00813         Capture = TRUE;
00814     }
00815     else
00816     {
00817         DPRINT("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
00818         DbgBreakPoint();
00819         while(TRUE);
00820     }
00821 
00822     // add port / filter reference
00823     Port->AddRef();
00824     Filter->AddRef();
00825 
00826     // initialize pin
00827     m_Port = Port;
00828     m_Filter = Filter;
00829     m_KsPinDescriptor = KsPinDescriptor;
00830     m_ConnectDetails = ConnectDetails;
00831     m_Miniport = GetWavePciMiniport(Port);
00832     m_DeviceObject = DeviceObject;
00833     m_State = KSSTATE_STOP;
00834     m_Capture = Capture;
00835 
00836     DPRINT("IPortPinWavePci_fnInit entered\n");
00837 
00838     // get dataformat
00839     DataFormat = (PKSDATAFORMAT)(ConnectDetails + 1);
00840 
00841     // allocate data format
00842     m_Format = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
00843     if (!m_Format)
00844     {
00845         // release references
00846         m_Port->Release();
00847         m_Filter->Release();
00848 
00849         // no dangling pointers
00850         Port = NULL;
00851         Filter = NULL;
00852 
00853         // failed to allocate data format
00854         return STATUS_INSUFFICIENT_RESOURCES;
00855     }
00856 
00857     // copy data format
00858     RtlMoveMemory(m_Format, DataFormat, DataFormat->FormatSize);
00859 
00860     // allocate new stream
00861     Status = m_Miniport->NewStream(&m_Stream,
00862                                    NULL,
00863                                    NonPagedPool,
00864                                    PPORTWAVEPCISTREAM(this),
00865                                    ConnectDetails->PinId,
00866                                    Capture,
00867                                    m_Format,
00868                                    &m_DmaChannel,
00869                                    &m_ServiceGroup);
00870 
00871     DPRINT("IPortPinWavePci_fnInit Status %x\n", Status);
00872 
00873     if (!NT_SUCCESS(Status))
00874     {
00875         // free references
00876         Port->Release();
00877         Filter->Release();
00878 
00879         // free data format
00880         FreeItem(m_Format, TAG_PORTCLASS);
00881 
00882         // no dangling pointers
00883         m_Port = NULL;
00884         m_Filter = NULL;
00885         m_Format = NULL;
00886 
00887         // failed to allocate stream
00888         return Status;
00889     }
00890 
00891     // get allocator requirements for pin
00892     Status = m_Stream->GetAllocatorFraming(&m_AllocatorFraming);
00893     if (NT_SUCCESS(Status))
00894     {
00895         DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
00896                m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment);
00897     }
00898 
00899     // allocate new irp queue
00900     Status = NewIrpQueue(&m_IrpQueue);
00901     if (!NT_SUCCESS(Status))
00902     {
00903         // free references
00904         Port->Release();
00905         Filter->Release();
00906         m_Stream->Release();
00907 
00908         // free data format
00909         FreeItem(m_Format, TAG_PORTCLASS);
00910 
00911         // no dangling pointers
00912         m_Port = NULL;
00913         m_Filter = NULL;
00914         m_Format = NULL;
00915         m_Stream = NULL;
00916 
00917         // failed to allocate irp queue
00918         return Status;
00919     }
00920 
00921     // initialize irp queue
00922     Status = m_IrpQueue->Init(ConnectDetails, KsPinDescriptor, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, TRUE);
00923     if (!NT_SUCCESS(Status))
00924     {
00925         // this should never happen
00926         ASSERT(0);
00927     }
00928 
00929     // get subdevice interface
00930     Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice);
00931 
00932     if (!NT_SUCCESS(Status))
00933     {
00934         // this function should never fail
00935         ASSERT(0);
00936     }
00937 
00938     // get subdevice descriptor
00939     Status = Subdevice->GetDescriptor(&SubDeviceDescriptor);
00940     if (!NT_SUCCESS(Status))
00941     {
00942         // this function should never fail
00943         ASSERT(0);
00944     }
00945 
00946     // release subdevice
00947     Subdevice->Release();
00948 
00949     /* set up subdevice descriptor */
00950     RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR));
00951     m_Descriptor.FilterPropertySet = PinWavePciPropertySet;
00952     m_Descriptor.FilterPropertySetCount = sizeof(PinWavePciPropertySet) / sizeof(KSPROPERTY_SET);
00953     m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream;
00954     m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor;
00955     m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport;
00956     m_Descriptor.PortPin = (PVOID)this;
00957 
00958     if (m_ServiceGroup)
00959     {
00960         Status = m_ServiceGroup->AddMember(PSERVICESINK(this));
00961         if (!NT_SUCCESS(Status))
00962         {
00963             // free references
00964             m_Stream->Release();
00965             Port->Release();
00966             Filter->Release();
00967 
00968             // free data format
00969             FreeItem(m_Format, TAG_PORTCLASS);
00970 
00971             // no dangling pointers
00972             m_Stream = NULL;
00973             m_Port = NULL;
00974             m_Filter = NULL;
00975             m_Format = NULL;
00976 
00977             // failed to add to service group
00978             return Status;
00979         }
00980     }
00981 
00982 
00983     return STATUS_SUCCESS;
00984 }
00985 
00986 PVOID
00987 NTAPI
00988 CPortPinWavePci::GetIrpStream()
00989 {
00990     return (PVOID)m_IrpQueue;
00991 }
00992 
00993 
00994 PMINIPORT
00995 NTAPI
00996 CPortPinWavePci::GetMiniport()
00997 {
00998     return (PMINIPORT)m_Miniport;
00999 }
01000 
01001 
01002 NTSTATUS
01003 NewPortPinWavePci(
01004     OUT IPortPinWavePci ** OutPin)
01005 {
01006     CPortPinWavePci * This;
01007 
01008     This = new(NonPagedPool, TAG_PORTCLASS) CPortPinWavePci(NULL);
01009     if (!This)
01010         return STATUS_INSUFFICIENT_RESOURCES;
01011 
01012     This->AddRef();
01013 
01014     // store result
01015     *OutPin = (IPortPinWavePci*)This;
01016 
01017     return STATUS_SUCCESS;
01018 }
01019 

Generated on Sat May 26 2012 04:27:10 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.