- Fix various bugs such as wrong function definitions, using of uninitialized variables

- Add macros which are not present in the WDK
- Check return type of synchronized interrupt routine
- Use PcHandlePropertyWithTable IPortPinWavePci
- Remove IServiceSink implementation from IPortWaveRt as it is a hack
- Add a small hack to IResource list implementation as prefast doesnt find decl of NumberOfEntries
- Fix build

svn path=/trunk/; revision=43437
This commit is contained in:
Johannes Anderwald 2009-10-13 12:29:41 +00:00
parent 09ef80af6b
commit 89bda0c12e
14 changed files with 446 additions and 315 deletions

View file

@ -238,8 +238,8 @@ NTAPI
PcDmaSlaveDescription(
IN PRESOURCELIST ResourceList OPTIONAL,
IN ULONG DmaIndex,
IN BOOL DemandMode,
IN ULONG AutoInitialize,
IN BOOLEAN DemandMode,
IN BOOLEAN AutoInitialize,
IN DMA_SPEED DmaSpeed,
IN ULONG MaximumLength,
IN ULONG DmaPort,

View file

@ -156,7 +156,7 @@ RegisterConnection(
IN PUNICODE_STRING ToString,
IN ULONG ToPin)
{
PSUBDEVICE_DESCRIPTOR FromSubDeviceDescriptor, ToSubDeviceDescriptor;
PSUBDEVICE_DESCRIPTOR FromSubDeviceDescriptor = NULL, ToSubDeviceDescriptor = NULL;
PSYMBOLICLINK_ENTRY SymEntry;
ISubdevice * FromSubDevice = NULL, *ToSubDevice = NULL;
NTSTATUS Status;
@ -205,35 +205,49 @@ RegisterConnection(
}
FromEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + ToString->MaximumLength, TAG_PORTCLASS);
if (!FromEntry)
if (FromSubDeviceDescriptor)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
FromEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + ToString->MaximumLength, TAG_PORTCLASS);
if (!FromEntry)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
}
ToEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + FromString->MaximumLength, TAG_PORTCLASS);
if (!ToEntry)
if (ToSubDeviceDescriptor)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
ToEntry = (PPHYSICAL_CONNECTION_ENTRY)AllocateItem(NonPagedPool, sizeof(PHYSICAL_CONNECTION_ENTRY) + FromString->MaximumLength, TAG_PORTCLASS);
if (!ToEntry)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto cleanup;
}
}
FromEntry->FromPin = FromPin;
FromEntry->Connection.Pin = ToPin;
FromEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + ToString->MaximumLength;
RtlMoveMemory(&FromEntry->Connection.SymbolicLinkName, ToString->Buffer, ToString->MaximumLength);
FromEntry->Connection.SymbolicLinkName[ToString->Length / sizeof(WCHAR)] = L'\0';
if (FromSubDeviceDescriptor)
{
FromEntry->FromPin = FromPin;
FromEntry->Connection.Pin = ToPin;
FromEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + ToString->MaximumLength;
RtlMoveMemory(&FromEntry->Connection.SymbolicLinkName, ToString->Buffer, ToString->MaximumLength);
FromEntry->Connection.SymbolicLinkName[ToString->Length / sizeof(WCHAR)] = L'\0';
ToEntry->FromPin = ToPin;
ToEntry->Connection.Pin = FromPin;
ToEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + FromString->MaximumLength;
RtlMoveMemory(&ToEntry->Connection.SymbolicLinkName, FromString->Buffer, FromString->MaximumLength);
ToEntry->Connection.SymbolicLinkName[FromString->Length / sizeof(WCHAR)] = L'\0';
InsertTailList(&FromSubDeviceDescriptor->PhysicalConnectionList, &FromEntry->Entry);
}
InsertTailList(&FromSubDeviceDescriptor->PhysicalConnectionList, &FromEntry->Entry);
InsertTailList(&ToSubDeviceDescriptor->PhysicalConnectionList, &ToEntry->Entry);
if (ToSubDeviceDescriptor)
{
ToEntry->FromPin = ToPin;
ToEntry->Connection.Pin = FromPin;
ToEntry->Connection.Size = sizeof(KSPIN_PHYSICALCONNECTION) + FromString->MaximumLength;
RtlMoveMemory(&ToEntry->Connection.SymbolicLinkName, FromString->Buffer, FromString->MaximumLength);
ToEntry->Connection.SymbolicLinkName[FromString->Length / sizeof(WCHAR)] = L'\0';
InsertTailList(&ToSubDeviceDescriptor->PhysicalConnectionList, &ToEntry->Entry);
}
return STATUS_SUCCESS;

View file

@ -679,6 +679,10 @@ typedef IPortPinWavePci *PPORTPINWAVEPCI;
#undef INTERFACE
#define INTERFACE IPortFilterWaveRT
#ifndef PPORTWAVERT
typedef IPortWaveRT *PPORTWAVERT;
#endif
DECLARE_INTERFACE_(IPortFilterWaveRT, IIrpTarget)
{
DEFINE_ABSTRACT_UNKNOWN()
@ -966,7 +970,7 @@ DECLARE_INTERFACE_(IDmaChannelInit, IUnknown)
{
DEFINE_ABSTRACT_UNKNOWN()
DEFINE_ABSTRACT_DMACHANNEL_EX()
DEFINE_ABSTRACT_DMACHANNELSLAVE()
//DEFINE_ABSTRACT_DMACHANNELSLAVE()
STDMETHOD_(NTSTATUS, Init)( THIS_
IN PDEVICE_DESCRIPTION DeviceDescription,
@ -1103,4 +1107,15 @@ DECLARE_INTERFACE_(IPortWaveRTStreamInit, IUnknown)
IN ULONG Index \
)
#ifndef IMP_IPortClsVersion
#define IMP_IPortClsVersion \
STDMETHODIMP_(DWORD) GetVersion(void);
#endif
#ifdef IMP_IPortWaveRT
#define IMP_IPortWaveRT IMP_IPort
#endif
#endif

View file

@ -97,8 +97,10 @@ CInterruptSynchronizedRoutine(
IN PVOID ServiceContext)
{
CInterruptSync * This = (CInterruptSync*)ServiceContext;
DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p\n", This, This->m_SyncRoutine, This->m_DynamicContext);
return This->m_SyncRoutine(This, This->m_DynamicContext);
NTSTATUS Status = This->m_SyncRoutine(This, This->m_DynamicContext);
DPRINT("CInterruptSynchronizedRoutine this %p SyncRoutine %p Context %p Status %x\n", This, This->m_SyncRoutine, This->m_DynamicContext, Status);
return NT_SUCCESS(Status);
}
NTSTATUS
@ -155,10 +157,10 @@ IInterruptServiceRoutine(
NTSTATUS Status;
BOOL Success;
//DPRINT("IInterruptServiceRoutine Mode %u\n", m_Mode);
CInterruptSync * This = (CInterruptSync*)ServiceContext;
DPRINT("IInterruptServiceRoutine Mode %u\n", This->m_Mode);
if (This->m_Mode == InterruptSyncModeNormal)
{
CurEntry = This->m_ServiceRoutines.Flink;
@ -234,8 +236,8 @@ CInterruptSync::Connect()
(PVOID)this,
&m_Lock,
Descriptor->u.Interrupt.Vector,
Descriptor->u.Interrupt.Level,
Descriptor->u.Interrupt.Level,
(KIRQL)Descriptor->u.Interrupt.Level,
(KIRQL)Descriptor->u.Interrupt.Level,
(KINTERRUPT_MODE)(Descriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED),
(Descriptor->Flags != CM_RESOURCE_INTERRUPT_LATCHED),
Descriptor->u.Interrupt.Affinity,

View file

@ -358,7 +358,7 @@ CPortPinDMus::TransferMidiDataToDMus()
//set up struct
//Event->Event.usFlags = DMUS_KEF_EVENT_COMPLETE;
Event->Event.cbStruct = sizeof(DMUS_KERNEL_EVENT);
Event->Event.cbEvent = BufferSize;
Event->Event.cbEvent = (USHORT)BufferSize;
Event->Event.uData.pbData = (PBYTE)Buffer;

View file

@ -958,7 +958,7 @@ CPortPinWaveCyclic::Init(
NTSTATUS Status;
PKSDATAFORMAT DataFormat;
PDEVICE_OBJECT DeviceObject;
BOOL Capture;
BOOLEAN Capture;
PVOID SilenceBuffer;
//IDrmAudioStream * DrmAudio = NULL;

View file

@ -41,6 +41,11 @@ public:
VOID NTAPI CloseStream();
protected:
friend NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
friend NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
friend NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
friend NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
IPortWavePci * m_Port;
IPortFilterWavePci * m_Filter;
KSPIN_DESCRIPTOR * m_KsPinDescriptor;
@ -57,20 +62,23 @@ protected:
IIrpQueue * m_IrpQueue;
ULONG m_TotalPackets;
ULONG m_PreCompleted;
ULONG m_PostCompleted;
KSAUDIO_POSITION m_Position;
ULONG m_StopCount;
ULONG m_Delay;
BOOL m_bUsePrefetch;
ULONG m_PrefetchOffset;
SUBDEVICE_DESCRIPTOR m_Descriptor;
KSALLOCATOR_FRAMING m_AllocatorFraming;
LONG m_Ref;
NTSTATUS NTAPI HandleKsProperty(IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN PIO_STATUS_BLOCK IoStatusBlock);
NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
VOID NTAPI SetStreamState( IN KSSTATE State);
};
@ -81,6 +89,259 @@ typedef struct
KSSTATE State;
}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
NTSTATUS NTAPI PinWavePciState(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI PinWavePciDataFormat(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI PinWavePciAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
NTSTATUS NTAPI PinWavePciAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data);
DEFINE_KSPROPERTY_ALLOCATORFRAMING(PinWavePciConnectionSet, PinWavePciState, PinWavePciDataFormat, PinWavePciAllocatorFraming);
DEFINE_KSPROPERTY_AUDIOSET(PinWavePciAudioSet, PinWavePciAudioPosition);
KSPROPERTY_SET PinWavePciPropertySet[] =
{
{
&KSPROPSETID_Connection,
sizeof(PinWavePciConnectionSet) / sizeof(KSPROPERTY_ITEM),
(const KSPROPERTY_ITEM*)&PinWavePciConnectionSet,
0,
NULL
},
{
&KSPROPSETID_Audio,
sizeof(PinWavePciAudioSet) / sizeof(KSPROPERTY_ITEM),
(const KSPROPERTY_ITEM*)&PinWavePciAudioSet,
0,
NULL
}
};
NTSTATUS
NTAPI
PinWavePciAllocatorFraming(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
UNIMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
PinWavePciAudioPosition(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
CPortPinWavePci *Pin;
PSUBDEVICE_DESCRIPTOR Descriptor;
// get sub device descriptor
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
// sanity check
PC_ASSERT(Descriptor);
PC_ASSERT(Descriptor->PortPin);
PC_ASSERT_IRQL(DISPATCH_LEVEL);
// cast to pin impl
Pin = (CPortPinWavePci*)Descriptor->PortPin;
//sanity check
PC_ASSERT(Pin->m_Stream);
if (Request->Flags & KSPROPERTY_TYPE_GET)
{
// FIXME non multithreading-safe
// copy audio position
RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION));
DPRINT1("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset);
Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION);
return STATUS_SUCCESS;
}
// not supported
return STATUS_NOT_SUPPORTED;
}
NTSTATUS
NTAPI
PinWavePciState(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
CPortPinWavePci *Pin;
PSUBDEVICE_DESCRIPTOR Descriptor;
PKSSTATE State = (PKSSTATE)Data;
// get sub device descriptor
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
// sanity check
PC_ASSERT(Descriptor);
PC_ASSERT(Descriptor->PortPin);
PC_ASSERT_IRQL(DISPATCH_LEVEL);
// cast to pin impl
Pin = (CPortPinWavePci*)Descriptor->PortPin;
//sanity check
PC_ASSERT(Pin->m_Stream);
if (Request->Flags & KSPROPERTY_TYPE_SET)
{
// try set stream
Status = Pin->m_Stream->SetState(*State);
DPRINT("Setting state %u %x\n", *State, Status);
if (NT_SUCCESS(Status))
{
// store new state
Pin->m_State = *State;
}
// store result
Irp->IoStatus.Information = sizeof(KSSTATE);
return Status;
}
else if (Request->Flags & KSPROPERTY_TYPE_GET)
{
// get current stream state
*State = Pin->m_State;
// store result
Irp->IoStatus.Information = sizeof(KSSTATE);
return STATUS_SUCCESS;
}
// unsupported request
return STATUS_NOT_SUPPORTED;
}
NTSTATUS
NTAPI
PinWavePciDataFormat(
IN PIRP Irp,
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
CPortPinWavePci *Pin;
PSUBDEVICE_DESCRIPTOR Descriptor;
PIO_STACK_LOCATION IoStack;
// get current irp stack location
IoStack = IoGetCurrentIrpStackLocation(Irp);
// get sub device descriptor
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
// sanity check
PC_ASSERT(Descriptor);
PC_ASSERT(Descriptor->PortPin);
// cast to pin impl
Pin = (CPortPinWavePci*)Descriptor->PortPin;
//sanity check
PC_ASSERT(Pin->m_Stream);
PC_ASSERT(Pin->m_Format);
if (Request->Flags & KSPROPERTY_TYPE_SET)
{
// try to change data format
PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize);
if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size)
{
// format is identical
Irp->IoStatus.Information = DataFormat->FormatSize;
return STATUS_SUCCESS;
}
// new change request
PC_ASSERT(Pin->m_State == KSSTATE_STOP);
// FIXME queue a work item when Irql != PASSIVE_LEVEL
PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
// allocate new data format
NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
if (!NewDataFormat)
{
// not enough memory
return STATUS_NO_MEMORY;
}
// copy new data format
RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
// set new format
Status = Pin->m_Stream->SetFormat(NewDataFormat);
if (NT_SUCCESS(Status))
{
// free old format
FreeItem(Pin->m_Format, TAG_PORTCLASS);
// update irp queue with new format
Pin->m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat);
// store new format
Pin->m_Format = NewDataFormat;
Irp->IoStatus.Information = NewDataFormat->FormatSize;
#if 0
PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX));
PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO));
PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM));
PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX));
DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels,
((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample,
((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec);
#endif
}
else
{
// failed to set format
FreeItem(NewDataFormat, TAG_PORTCLASS);
}
// done
return Status;
}
else if (Request->Flags & KSPROPERTY_TYPE_GET)
{
// get current data format
PC_ASSERT(Pin->m_Format);
if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
{
// buffer too small
Irp->IoStatus.Information = Pin->m_Format->FormatSize;
return STATUS_MORE_ENTRIES;
}
// copy data format
RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize);
// store result size
Irp->IoStatus.Information = Pin->m_Format->FormatSize;
// done
return STATUS_SUCCESS;
}
// unsupported request
return STATUS_NOT_SUPPORTED;
}
//==================================================================================================================================
NTSTATUS
NTAPI
@ -185,7 +446,7 @@ CPortPinWavePci::SetState(KSSTATE State)
// store minimum data threshold
m_IrpQueue->SetMinimumDataThreshold(MinimumDataThreshold);
DPRINT1("Stopping PreCompleted %u PostCompleted %u StopCount %u MinimumDataThreshold %u\n", m_PreCompleted, m_PostCompleted, m_StopCount, MinimumDataThreshold);
DPRINT1("Stopping TotalCompleted %u StopCount %u MinimumDataThreshold %u\n", m_TotalPackets, m_StopCount, MinimumDataThreshold);
}
if (m_State == KSSTATE_RUN)
{
@ -308,144 +569,50 @@ CPortPinWavePci::NewIrpTarget(
NTSTATUS
NTAPI
CPortPinWavePci::HandleKsProperty(
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN PIO_STATUS_BLOCK IoStatusBlock)
IN PIRP Irp)
{
PKSPROPERTY Property;
NTSTATUS Status;
UNICODE_STRING GuidString;
PIO_STACK_LOCATION IoStack;
DPRINT("IPortPinWavePci_HandleKsProperty entered\n");
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (InputBufferLength < sizeof(KSPROPERTY))
DPRINT("IPortPinWave_HandleKsProperty entered\n");
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
{
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
DPRINT1("Unhandled function %lx Length %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
Property = (PKSPROPERTY)InputBuffer;
Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor);
if (IsEqualGUIDAligned(Property->Set, KSPROPSETID_Connection))
if (Status == STATUS_NOT_FOUND)
{
if (Property->Id == KSPROPERTY_CONNECTION_STATE)
{
PKSSTATE State = (PKSSTATE)OutputBuffer;
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
PC_ASSERT_IRQL(DISPATCH_LEVEL);
if (OutputBufferLength < sizeof(KSSTATE))
{
IoStatusBlock->Information = sizeof(KSSTATE);
IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
RtlStringFromGUID(Property->Set, &GuidString);
DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
}
if (Property->Flags & KSPROPERTY_TYPE_SET)
{
Status = STATUS_UNSUCCESSFUL;
IoStatusBlock->Information = 0;
if (Status != STATUS_PENDING)
{
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
if (m_Stream)
{
Status = m_Stream->SetState(*State);
return Status;
}
DPRINT1("Setting state %u %x\n", *State, Status);
if (NT_SUCCESS(Status))
{
m_State = *State;
}
}
IoStatusBlock->Status = Status;
return Status;
}
else if (Property->Flags & KSPROPERTY_TYPE_GET)
{
*State = m_State;
IoStatusBlock->Information = sizeof(KSSTATE);
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT)
{
PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)OutputBuffer;
if (Property->Flags & KSPROPERTY_TYPE_SET)
{
PKSDATAFORMAT NewDataFormat;
if (!RtlCompareMemory(DataFormat, m_Format, DataFormat->FormatSize))
{
IoStatusBlock->Information = DataFormat->FormatSize;
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
if (!NewDataFormat)
{
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_NO_MEMORY;
return STATUS_NO_MEMORY;
}
RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
if (m_Stream)
{
#if 0
ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);
ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX));
ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, &KSDATAFORMAT_TYPE_AUDIO));
ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM));
ASSERT(IsEqualGUIDAligned(&((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX));
ASSERT(This->State == KSSTATE_STOP);
#endif
DPRINT1("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels,
((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample,
((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec);
Status = m_Stream->SetFormat(NewDataFormat);
if (NT_SUCCESS(Status))
{
if (m_Format)
ExFreePoolWithTag(m_Format, TAG_PORTCLASS);
m_IrpQueue->UpdateFormat((PKSDATAFORMAT)NewDataFormat);
m_Format = NewDataFormat;
IoStatusBlock->Information = DataFormat->FormatSize;
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
DPRINT1("Failed to set format\n");
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
else if (Property->Flags & KSPROPERTY_TYPE_GET)
{
if (!m_Format)
{
DPRINT1("No format\n");
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
if (m_Format->FormatSize > OutputBufferLength)
{
IoStatusBlock->Information = m_Format->FormatSize;
IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
RtlMoveMemory(DataFormat, m_Format, m_Format->FormatSize);
IoStatusBlock->Information = DataFormat->FormatSize;
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING)
{
PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)OutputBuffer;
@ -466,16 +633,38 @@ CPortPinWavePci::HandleKsProperty(
return STATUS_SUCCESS;
}
}
#endif
RtlStringFromGUID(Property->Set, &GuidString);
DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
NTSTATUS
NTAPI
CPortPinWavePci::HandleKsStream(
IN PIRP Irp)
{
NTSTATUS Status;
InterlockedIncrement((PLONG)&m_TotalPackets);
IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
IoStatusBlock->Information = 0;
return STATUS_NOT_IMPLEMENTED;
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
Status = m_IrpQueue->AddMapping(NULL, 0, Irp);
if (NT_SUCCESS(Status))
{
PKSSTREAM_HEADER Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
PC_ASSERT(Header);
if (m_Capture)
m_Position.WriteOffset += Header->FrameExtent;
else
m_Position.WriteOffset += Header->DataUsed;
}
return STATUS_PENDING;
}
NTSTATUS
NTAPI
CPortPinWavePci::DeviceIoControl(
@ -483,17 +672,17 @@ CPortPinWavePci::DeviceIoControl(
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
{
Status = HandleKsProperty(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
return HandleKsProperty(Irp);
}
else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_WRITE_STREAM || IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_READ_STREAM)
{
return HandleKsStream(Irp);
}
UNIMPLEMENTED
@ -735,7 +924,7 @@ CPortPinWavePci::Init(
{
NTSTATUS Status;
PKSDATAFORMAT DataFormat;
BOOL Capture;
BOOLEAN Capture;
Port->AddRef();
Filter->AddRef();
@ -810,6 +999,34 @@ CPortPinWavePci::Init(
DPRINT("OptionFlags %x RequirementsFlag %x PoolType %x Frames %lu FrameSize %lu FileAlignment %lu\n",
m_AllocatorFraming.OptionsFlags, m_AllocatorFraming.RequirementsFlags, m_AllocatorFraming.PoolType, m_AllocatorFraming.Frames, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment);
ISubdevice * Subdevice = NULL;
// get subdevice interface
Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&Subdevice);
if (!NT_SUCCESS(Status))
return Status;
PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL;
Status = Subdevice->GetDescriptor(&SubDeviceDescriptor);
if (!NT_SUCCESS(Status))
{
// failed to get descriptor
Subdevice->Release();
return Status;
}
/* set up subdevice descriptor */
RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR));
m_Descriptor.FilterPropertySet = PinWavePciPropertySet;
m_Descriptor.FilterPropertySetCount = sizeof(PinWavePciPropertySet) / sizeof(KSPROPERTY_SET);
m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream;
m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor;
m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport;
m_Descriptor.PortPin = (PVOID)this;
Status = NewIrpQueue(&m_IrpQueue);
if (!NT_SUCCESS(Status))
return Status;

View file

@ -8,8 +8,7 @@
#include "private.hpp"
class CPortPinWaveRT : public IPortPinWaveRT,
public IServiceSink //hack
class CPortPinWaveRT : public IPortPinWaveRT
{
public:
STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
@ -31,7 +30,6 @@ public:
return m_Ref;
}
IMP_IPortPinWaveRT;
IMP_IServiceSink; //HACK
CPortPinWaveRT(IUnknown *OuterUnknown){}
virtual ~CPortPinWaveRT(){}
@ -43,7 +41,6 @@ protected:
PMINIPORTWAVERT m_Miniport;
PMINIPORTWAVERTSTREAM m_Stream;
PPORTWAVERTSTREAM m_PortStream;
PSERVICEGROUP m_ServiceGroup;
KSSTATE m_State;
PKSDATAFORMAT m_Format;
KSPIN_CONNECT * m_ConnectDetails;
@ -70,8 +67,6 @@ protected:
NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
VOID NTAPI SetStreamState(IN KSSTATE State);
VOID UpdateCommonBuffer(ULONG Position);
VOID UpdateCommonBufferOverlap(ULONG Position);
friend VOID NTAPI SetStreamWorkerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context);
friend VOID NTAPI CloseStreamRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context);
@ -86,81 +81,6 @@ typedef struct
}SETSTREAM_CONTEXT, *PSETSTREAM_CONTEXT;
VOID
CPortPinWaveRT::UpdateCommonBuffer(
ULONG Position)
{
ULONG BufferLength;
ULONG BytesToCopy;
ULONG BufferSize;
PUCHAR Buffer;
NTSTATUS Status;
BufferLength = Position - m_CommonBufferOffset;
while(BufferLength)
{
Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize);
if (!NT_SUCCESS(Status))
return;
BytesToCopy = min(BufferLength, BufferSize);
if (m_Capture)
{
RtlMoveMemory(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy);
}
else
{
RtlMoveMemory((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy);
}
m_IrpQueue->UpdateMapping(BytesToCopy);
m_CommonBufferOffset += BytesToCopy;
BufferLength = Position - m_CommonBufferOffset;
}
}
VOID
CPortPinWaveRT::UpdateCommonBufferOverlap(
ULONG Position)
{
ULONG BufferLength;
ULONG BytesToCopy;
ULONG BufferSize;
PUCHAR Buffer;
NTSTATUS Status;
BufferLength = m_CommonBufferSize - m_CommonBufferOffset;
while(BufferLength)
{
Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize);
if (!NT_SUCCESS(Status))
return;
BytesToCopy = min(BufferLength, BufferSize);
if (m_Capture)
{
RtlMoveMemory(Buffer, (PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BytesToCopy);
}
else
{
RtlMoveMemory((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, Buffer, BytesToCopy);
}
m_IrpQueue->UpdateMapping(BytesToCopy);
m_CommonBufferOffset += BytesToCopy;
BufferLength = m_CommonBufferSize - m_CommonBufferOffset;
}
m_CommonBufferOffset = 0;
UpdateCommonBuffer(Position);
}
//==================================================================================================================================
NTSTATUS
NTAPI
@ -170,13 +90,6 @@ CPortPinWaveRT::QueryInterface(
{
DPRINT("IServiceSink_fnQueryInterface entered\n");
if (IsEqualGUIDAligned(refiid, IID_IServiceSink))
{
*Output = PVOID(PSERVICEGROUP(this));
PUNKNOWN(*Output)->AddRef();
return STATUS_SUCCESS;
}
if (IsEqualGUIDAligned(refiid, IID_IIrpTarget) ||
IsEqualGUIDAligned(refiid, IID_IUnknown))
{
@ -187,37 +100,6 @@ CPortPinWaveRT::QueryInterface(
return STATUS_UNSUCCESSFUL;
}
VOID
NTAPI
CPortPinWaveRT::RequestService()
{
KSAUDIO_POSITION Position;
NTSTATUS Status;
PUCHAR Buffer;
ULONG BufferSize;
PC_ASSERT_IRQL(DISPATCH_LEVEL);
Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize);
if (!NT_SUCCESS(Status))
{
SetStreamState(KSSTATE_STOP);
return;
}
Status = m_Stream->GetPosition(&Position);
DPRINT("PlayOffset %lu WriteOffset %lu Buffer %p BufferSize %u CommonBufferSize %u\n", Position.PlayOffset, Position.WriteOffset, Buffer, BufferSize, m_CommonBufferSize);
if (Position.PlayOffset < m_CommonBufferOffset)
{
UpdateCommonBufferOverlap(Position.PlayOffset);
}
else if (Position.PlayOffset >= m_CommonBufferOffset)
{
UpdateCommonBuffer(Position.PlayOffset);
}
}
VOID
NTAPI
SetStreamWorkerRoutine(
@ -248,14 +130,12 @@ SetStreamWorkerRoutine(
{
// reset start stream
This->m_IrpQueue->CancelBuffers(); //FIX function name
This->m_ServiceGroup->CancelDelayedService();
DPRINT1("Stopping PreCompleted %u PostCompleted %u\n", This->m_PreCompleted, This->m_PostCompleted);
}
if (This->m_State == KSSTATE_RUN)
{
// start the notification timer
This->m_ServiceGroup->RequestDelayedService(This->m_Delay);
}
}
}
@ -766,7 +646,7 @@ CPortPinWaveRT::Init(
{
NTSTATUS Status;
PKSDATAFORMAT DataFormat;
BOOL Capture;
BOOLEAN Capture;
KSRTAUDIO_HWLATENCY Latency;
Port->AddRef();
@ -806,15 +686,6 @@ CPortPinWaveRT::Init(
goto cleanup;
}
Status = PcNewServiceGroup(&m_ServiceGroup, NULL);
if (!NT_SUCCESS(Status))
{
goto cleanup;
}
m_ServiceGroup->AddMember(PSERVICESINK(this));
m_ServiceGroup->SupportDelayedService();
if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
{
Capture = FALSE;

View file

@ -355,8 +355,8 @@ CPortWaveCyclic::NewMasterDmaChannel(
IN PUNKNOWN OuterUnknown,
IN PRESOURCELIST ResourceList OPTIONAL,
IN ULONG MaximumLength,
IN BOOL Dma32BitAddresses,
IN BOOL Dma64BitAddresses,
IN BOOLEAN Dma32BitAddresses,
IN BOOLEAN Dma64BitAddresses,
IN DMA_WIDTH DmaWidth,
IN DMA_SPEED DmaSpeed)
{
@ -388,7 +388,7 @@ CPortWaveCyclic::NewSlaveDmaChannel(
IN PRESOURCELIST ResourceList OPTIONAL,
IN ULONG DmaIndex,
IN ULONG MaximumLength,
IN BOOL DemandMode,
IN BOOLEAN DemandMode,
IN DMA_SPEED DmaSpeed)
{
DEVICE_DESCRIPTION DeviceDescription;

View file

@ -161,7 +161,7 @@ CPortWaveRTStreamInit::GetPhysicalPageAddress(
return RtlConvertUlongToLargeInteger(0);
}
Buffer = UlongToPtr(PtrToUlong(MmGetSystemAddressForMdl(MemoryDescriptorList)) + Index * PAGE_SIZE);
Buffer = (PVOID)UlongToPtr(PtrToUlong(MmGetSystemAddressForMdlSafe(MemoryDescriptorList, LowPagePriority)) + Index * PAGE_SIZE);
Addr = MmGetPhysicalAddress(Buffer);
Address->QuadPart = Addr.QuadPart;

View file

@ -2,7 +2,6 @@
<!DOCTYPE module SYSTEM "../../../../../tools/rbuild/project.dtd">
<module name="portcls" type="kernelmodedriver" installbase="system32/drivers" installname="portcls.sys" entrypoint="0">
<importlibrary definition="portcls.spec" />
<define name="PC_NO_IMPORTS" />
<redefine name="_WIN32_WINNT">0x600</redefine>
<include base="portcls">.</include>
<library>ntoskrnl</library>

View file

@ -9,10 +9,12 @@
//#define _KS_NO_ANONYMOUS_STRUCTURES_
#define PC_IMPLEMENTATION
#define COM_STDMETHOD_CAN_THROW
#define PC_NO_IMPORTS
#include <ntddk.h>
#include <portcls.h>
#define NDEBUG
#define YDEBUG
#include <debug.h>
#include <dmusicks.h>
@ -20,7 +22,7 @@
#include "interfaces.hpp"
#include <ks.h>
#include <ksmedia.h>
#include <intrin.h>
//#include <intrin.h>
#define TAG_PORTCLASS 'SLCP'
@ -244,8 +246,8 @@ NTAPI
PcDmaSlaveDescription(
IN PRESOURCELIST ResourceList OPTIONAL,
IN ULONG DmaIndex,
IN BOOL DemandMode,
IN ULONG AutoInitialize,
IN BOOLEAN DemandMode,
IN BOOLEAN AutoInitialize,
IN DMA_SPEED DmaSpeed,
IN ULONG MaximumLength,
IN ULONG DmaPort,
@ -321,6 +323,14 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler)\
}
#define DEFINE_KSPROPERTY_ALLOCATORFRAMING(PinSet,\
PropStateHandler, PropDataFormatHandler, PropAllocatorFraming)\
DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_ITEM_CONNECTION_STATE(PropStateHandler, PropStateHandler),\
DEFINE_KSPROPERTY_ITEM_CONNECTION_DATAFORMAT(PropDataFormatHandler, PropDataFormatHandler),\
DEFINE_KSPROPERTY_ITEM_CONNECTION_ALLOCATORFRAMING(PropAllocatorFraming)\
}
#define DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(GetHandler, SetHandler)\
DEFINE_KSPROPERTY_ITEM(\
KSPROPERTY_AUDIO_POSITION,\
@ -336,9 +346,6 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(PropPositionHandler, PropPositionHandler)\
}
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
PropGeneral, PropInstances, PropIntersection)\
DEFINE_KSPROPERTY_TABLE(PinSet) {\

View file

@ -34,6 +34,9 @@ public:
}
IMP_IResourceList;
#ifdef BUILD_WDK
ULONG NTAPI NumberOfEntries();
#endif
CResourceList(IUnknown * OuterUnknown) : m_OuterUnknown(OuterUnknown), m_PoolType(NonPagedPool), m_TranslatedResourceList(0), m_UntranslatedResourceList(0), m_NumberOfEntries(0) {}
virtual ~CResourceList() {}
@ -72,15 +75,16 @@ CResourceList::QueryInterface(
return STATUS_UNSUCCESSFUL;
}
#if 1
ULONG
NTAPI
CResourceList::NumberOfEntries()
{
// ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
PC_ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
return m_NumberOfEntries;
}
#endif
ULONG
NTAPI

View file

@ -117,6 +117,8 @@ CServiceGroup::RequestService()
{
KIRQL OldIrql;
DPRINT("CServiceGroup::RequestService() Dpc at Level %u\n", KeGetCurrentIrql());
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
{
KeInsertQueueDpc(&m_Dpc, NULL, NULL);