mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 09:00:27 +00:00
- Silence a few debug prints
- Add a tag for each queued irp which will be used by the future IPortPinWavePci object - Add support for basic support for capture devices - Implement IPortWavePciStream object svn path=/trunk/; revision=40015
This commit is contained in:
parent
d74173888a
commit
4a74095169
9 changed files with 446 additions and 32 deletions
|
@ -150,9 +150,7 @@ IPortFilterWaveCyclic_fnDeviceIoControl(
|
||||||
ISubdevice *SubDevice = NULL;
|
ISubdevice *SubDevice = NULL;
|
||||||
SUBDEVICE_DESCRIPTOR * Descriptor;
|
SUBDEVICE_DESCRIPTOR * Descriptor;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
#if defined(DBG)
|
|
||||||
IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
|
IPortFilterWaveCyclicImpl * This = (IPortFilterWaveCyclicImpl *)iface;
|
||||||
#endif
|
|
||||||
|
|
||||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
|
ASSERT(IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY);
|
||||||
|
|
|
@ -24,6 +24,7 @@ const GUID IID_IDrmPort = {0x286D3DF8L, 0xCA22, 0x4E2E, {0xB9, 0xBC, 0x20, 0xB4,
|
||||||
const GUID IID_IDrmPort2 = {0x1ACCE59CL, 0x7311, 0x4B6B, {0x9F, 0xBA, 0xCC, 0x3B, 0xA5, 0x9A, 0xCD, 0xCE}};
|
const GUID IID_IDrmPort2 = {0x1ACCE59CL, 0x7311, 0x4B6B, {0x9F, 0xBA, 0xCC, 0x3B, 0xA5, 0x9A, 0xCD, 0xCE}};
|
||||||
const GUID IID_IInterruptSync = {0x22C6AC63L, 0x851B, 0x11D0, {0x9A, 0x7F, 0x00, 0xAA, 0x00, 0x38, 0xAC, 0xFE}};
|
const GUID IID_IInterruptSync = {0x22C6AC63L, 0x851B, 0x11D0, {0x9A, 0x7F, 0x00, 0xAA, 0x00, 0x38, 0xAC, 0xFE}};
|
||||||
const GUID IID_IPortWavePci = {0xb4c90a50L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
const GUID IID_IPortWavePci = {0xb4c90a50L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||||
|
const GUID IID_IPortWavePciStream = {0xb4c90a51L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||||
const GUID IID_IPortMidi = {0xb4c90a40L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
const GUID IID_IPortMidi = {0xb4c90a40L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||||
const GUID IID_IMiniportMidi = {0xb4c90a41L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
const GUID IID_IMiniportMidi = {0xb4c90a41L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||||
const GUID IID_IMiniportWavePci = {0xb4c90a52L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
const GUID IID_IMiniportWavePci = {0xb4c90a52L, 0x5791, 0x11d0, {0x86, 0xf9, 0x00, 0xa0, 0xc9, 0x11, 0xb5, 0x44}};
|
||||||
|
|
|
@ -194,7 +194,8 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
|
||||||
STDMETHOD_(NTSTATUS, Init)(THIS_
|
STDMETHOD_(NTSTATUS, Init)(THIS_
|
||||||
IN KSPIN_CONNECT *ConnectDetails,
|
IN KSPIN_CONNECT *ConnectDetails,
|
||||||
IN PKSDATAFORMAT DataFormat,
|
IN PKSDATAFORMAT DataFormat,
|
||||||
IN PDEVICE_OBJECT DeviceObject);
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG FrameSize);
|
||||||
|
|
||||||
STDMETHOD_(NTSTATUS, AddMapping)(THIS_
|
STDMETHOD_(NTSTATUS, AddMapping)(THIS_
|
||||||
IN PUCHAR Buffer,
|
IN PUCHAR Buffer,
|
||||||
|
@ -219,11 +220,19 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
|
||||||
STDMETHOD_(VOID, UpdateFormat)(THIS_
|
STDMETHOD_(VOID, UpdateFormat)(THIS_
|
||||||
IN PKSDATAFORMAT DataFormat);
|
IN PKSDATAFORMAT DataFormat);
|
||||||
|
|
||||||
|
STDMETHOD_(NTSTATUS, GetMappingWithTag)(THIS_
|
||||||
|
IN PVOID Tag,
|
||||||
|
OUT PPHYSICAL_ADDRESS PhysicalAddress,
|
||||||
|
OUT PVOID *VirtualAddress,
|
||||||
|
OUT PULONG ByteCount,
|
||||||
|
OUT PULONG Flags);
|
||||||
|
|
||||||
|
STDMETHOD_(VOID, ReleaseMappingWithTag)(THIS_
|
||||||
|
IN PVOID Tag);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* IKsWorkSink
|
* IKsWorkSink
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
|
@ -106,7 +106,7 @@ IInterruptSynchronizedRoutine(
|
||||||
IN PVOID ServiceContext)
|
IN PVOID ServiceContext)
|
||||||
{
|
{
|
||||||
IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext;
|
IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext;
|
||||||
DPRINT1("IInterruptSynchronizedRoutine This %p SyncRoutine %p Context %p\n", This, This->SyncRoutine, This->DynamicContext);
|
//DPRINT1("IInterruptSynchronizedRoutine This %p SyncRoutine %p Context %p\n", This, This->SyncRoutine, This->DynamicContext);
|
||||||
return This->SyncRoutine((IInterruptSync*)&This->lpVtbl, This->DynamicContext);
|
return This->SyncRoutine((IInterruptSync*)&This->lpVtbl, This->DynamicContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ IInterruptSync_fnCallSynchronizedRoutine(
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface;
|
IInterruptSyncImpl * This = (IInterruptSyncImpl*)iface;
|
||||||
|
|
||||||
DPRINT1("IInterruptSync_fnCallSynchronizedRoutine This %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", This, Routine, DynamicContext, KeGetCurrentIrql(), This->Interrupt);
|
//DPRINT1("IInterruptSync_fnCallSynchronizedRoutine This %p Routine %p DynamicContext %p Irql %x Interrupt %p\n", This, Routine, DynamicContext, KeGetCurrentIrql(), This->Interrupt);
|
||||||
|
|
||||||
if (!This->Interrupt)
|
if (!This->Interrupt)
|
||||||
{
|
{
|
||||||
|
@ -169,7 +169,7 @@ IInterruptServiceRoutine(
|
||||||
BOOL Success;
|
BOOL Success;
|
||||||
IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext;
|
IInterruptSyncImpl * This = (IInterruptSyncImpl*)ServiceContext;
|
||||||
|
|
||||||
DPRINT("IInterruptServiceRoutine\n");
|
DPRINT("IInterruptServiceRoutine Mode %u\n", This->Mode);
|
||||||
|
|
||||||
if (This->Mode == InterruptSyncModeNormal)
|
if (This->Mode == InterruptSyncModeNormal)
|
||||||
{
|
{
|
||||||
|
@ -249,7 +249,7 @@ IInterruptSync_fnConnect(
|
||||||
Descriptor->u.Interrupt.Vector,
|
Descriptor->u.Interrupt.Vector,
|
||||||
Descriptor->u.Interrupt.Level,
|
Descriptor->u.Interrupt.Level,
|
||||||
Descriptor->u.Interrupt.Level, //FIXME
|
Descriptor->u.Interrupt.Level, //FIXME
|
||||||
LevelSensitive, //FIXME
|
Descriptor->Flags,
|
||||||
TRUE,
|
TRUE,
|
||||||
Descriptor->u.Interrupt.Affinity,
|
Descriptor->u.Interrupt.Affinity,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
|
|
@ -18,6 +18,10 @@ typedef struct _IRP_MAPPING_
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
KDPC Dpc;
|
KDPC Dpc;
|
||||||
|
|
||||||
|
ULONG NumTags;
|
||||||
|
PVOID * Tag;
|
||||||
|
LONG ReferenceCount;
|
||||||
|
|
||||||
}IRP_MAPPING, *PIRP_MAPPING;
|
}IRP_MAPPING, *PIRP_MAPPING;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
@ -38,6 +42,10 @@ typedef struct
|
||||||
KSPIN_LOCK Lock;
|
KSPIN_LOCK Lock;
|
||||||
LIST_ENTRY ListHead;
|
LIST_ENTRY ListHead;
|
||||||
|
|
||||||
|
PVOID LastTag;
|
||||||
|
BOOL OutOfMapping;
|
||||||
|
ULONG MaxFrameSize;
|
||||||
|
|
||||||
}IIrpQueueImpl;
|
}IIrpQueueImpl;
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
@ -119,12 +127,16 @@ IIrpQueue_fnInit(
|
||||||
IN IIrpQueue *iface,
|
IN IIrpQueue *iface,
|
||||||
IN KSPIN_CONNECT *ConnectDetails,
|
IN KSPIN_CONNECT *ConnectDetails,
|
||||||
IN PKSDATAFORMAT DataFormat,
|
IN PKSDATAFORMAT DataFormat,
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG FrameSize)
|
||||||
{
|
{
|
||||||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||||
|
|
||||||
This->ConnectDetails = ConnectDetails;
|
This->ConnectDetails = ConnectDetails;
|
||||||
This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat;
|
This->DataFormat = (PKSDATAFORMAT_WAVEFORMATEX)DataFormat;
|
||||||
|
This->MaxFrameSize = FrameSize;
|
||||||
|
This->LastTag = (PVOID)0x12345678;
|
||||||
|
|
||||||
InitializeListHead(&This->ListHead);
|
InitializeListHead(&This->ListHead);
|
||||||
KeInitializeSpinLock(&This->Lock);
|
KeInitializeSpinLock(&This->Lock);
|
||||||
|
|
||||||
|
@ -142,7 +154,8 @@ IIrpQueue_fnAddMapping(
|
||||||
PIRP_MAPPING Mapping;
|
PIRP_MAPPING Mapping;
|
||||||
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||||
|
|
||||||
Mapping = ExAllocatePool(NonPagedPool, sizeof(IRP_MAPPING));
|
|
||||||
|
Mapping = AllocateItem(NonPagedPool, sizeof(IRP_MAPPING), TAG_PORTCLASS);
|
||||||
if (!Mapping)
|
if (!Mapping)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
@ -150,9 +163,15 @@ IIrpQueue_fnAddMapping(
|
||||||
Mapping->Irp = Irp;
|
Mapping->Irp = Irp;
|
||||||
KeInitializeDpc(&Mapping->Dpc, DpcRoutine, (PVOID)Mapping);
|
KeInitializeDpc(&Mapping->Dpc, DpcRoutine, (PVOID)Mapping);
|
||||||
|
|
||||||
|
if (This->MaxFrameSize)
|
||||||
|
{
|
||||||
|
Mapping->NumTags = max((Mapping->Header->DataUsed / This->MaxFrameSize) + 1, 1);
|
||||||
|
Mapping->Tag = AllocateItem(NonPagedPool, sizeof(PVOID) * This->NumMappings, TAG_PORTCLASS);
|
||||||
|
}
|
||||||
|
|
||||||
This->NumDataAvailable += Mapping->Header->DataUsed;
|
This->NumDataAvailable += Mapping->Header->DataUsed;
|
||||||
|
|
||||||
DPRINT1("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable %lu Irp %p\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Irp);
|
DPRINT("IIrpQueue_fnAddMapping NumMappings %u SizeOfMapping %lu NumDataAvailable %lu Irp %p\n", This->NumMappings, Mapping->Header->DataUsed, This->NumDataAvailable, Irp);
|
||||||
|
|
||||||
/* FIXME use InterlockedCompareExchangePointer */
|
/* FIXME use InterlockedCompareExchangePointer */
|
||||||
if (InterlockedCompareExchange((volatile long *)&This->FirstMap, (LONG)Mapping, (LONG)0) != 0)
|
if (InterlockedCompareExchange((volatile long *)&This->FirstMap, (LONG)Mapping, (LONG)0) != 0)
|
||||||
|
@ -160,6 +179,8 @@ IIrpQueue_fnAddMapping(
|
||||||
|
|
||||||
(void)InterlockedIncrement((volatile long*)&This->NumMappings);
|
(void)InterlockedIncrement((volatile long*)&This->NumMappings);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (Irp)
|
if (Irp)
|
||||||
{
|
{
|
||||||
Irp->IoStatus.Status = STATUS_PENDING;
|
Irp->IoStatus.Status = STATUS_PENDING;
|
||||||
|
@ -200,6 +221,7 @@ IIrpQueue_fnUpdateMapping(
|
||||||
PIRP_MAPPING Mapping;
|
PIRP_MAPPING Mapping;
|
||||||
|
|
||||||
This->CurrentOffset += BytesWritten;
|
This->CurrentOffset += BytesWritten;
|
||||||
|
This->NumDataAvailable -= BytesWritten;
|
||||||
|
|
||||||
if (This->FirstMap->Header->DataUsed <=This->CurrentOffset)
|
if (This->FirstMap->Header->DataUsed <=This->CurrentOffset)
|
||||||
{
|
{
|
||||||
|
@ -207,11 +229,9 @@ IIrpQueue_fnUpdateMapping(
|
||||||
Mapping = (PIRP_MAPPING)ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
|
Mapping = (PIRP_MAPPING)ExInterlockedRemoveHeadList(&This->ListHead, &This->Lock);
|
||||||
|
|
||||||
InterlockedDecrement(&This->NumMappings);
|
InterlockedDecrement(&This->NumMappings);
|
||||||
This->NumDataAvailable -= This->FirstMap->Header->DataUsed;
|
|
||||||
|
|
||||||
KeInsertQueueDpc(&This->FirstMap->Dpc, (PVOID)This->FirstMap, NULL);
|
KeInsertQueueDpc(&This->FirstMap->Dpc, (PVOID)This->FirstMap, NULL);
|
||||||
(void)InterlockedExchangePointer((PVOID volatile*)&This->FirstMap, (PVOID)Mapping);
|
(void)InterlockedExchangePointer((PVOID volatile*)&This->FirstMap, (PVOID)Mapping);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -270,6 +290,137 @@ IIrpQueue_fnUpdateFormat(
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IIrpQueue_fnGetMappingWithTag(
|
||||||
|
IN IIrpQueue *iface,
|
||||||
|
IN PVOID Tag,
|
||||||
|
OUT PPHYSICAL_ADDRESS PhysicalAddress,
|
||||||
|
OUT PVOID *VirtualAddress,
|
||||||
|
OUT PULONG ByteCount,
|
||||||
|
OUT PULONG Flags)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PIRP_MAPPING CurMapping;
|
||||||
|
PIRP_MAPPING Result;
|
||||||
|
PLIST_ENTRY CurEntry;
|
||||||
|
ULONG Index;
|
||||||
|
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||||
|
|
||||||
|
*Flags = 0;
|
||||||
|
Result = NULL;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&This->Lock, &OldIrql);
|
||||||
|
|
||||||
|
CurEntry = This->ListHead.Flink;
|
||||||
|
|
||||||
|
while (CurEntry != &This->ListHead)
|
||||||
|
{
|
||||||
|
CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
|
||||||
|
for(Index = 0; Index < CurMapping->NumTags; Index++)
|
||||||
|
{
|
||||||
|
if (This->LastTag == (PVOID)0x12345678)
|
||||||
|
{
|
||||||
|
CurMapping->Tag[Index] = Tag;
|
||||||
|
CurMapping->ReferenceCount++;
|
||||||
|
Result = CurMapping;
|
||||||
|
if (Index + 1 == CurMapping->NumTags - 1)
|
||||||
|
{
|
||||||
|
/* indicate end of packet */
|
||||||
|
*Flags = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (CurMapping->Tag[Index] == This->LastTag)
|
||||||
|
{
|
||||||
|
if (Index + 1 < CurMapping->NumTags)
|
||||||
|
{
|
||||||
|
CurMapping->Tag[Index+1] = Tag;
|
||||||
|
CurMapping->ReferenceCount++;
|
||||||
|
Result = CurMapping;
|
||||||
|
|
||||||
|
if (Index + 1 == CurMapping->NumTags - 1)
|
||||||
|
{
|
||||||
|
/* indicate end of packet */
|
||||||
|
*Flags = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurEntry = CurEntry->Flink;
|
||||||
|
if (&This->ListHead == CurEntry)
|
||||||
|
{
|
||||||
|
This->OutOfMapping = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Result = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
|
||||||
|
Result->Tag[0] = Tag;
|
||||||
|
Result->ReferenceCount++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CurEntry = CurEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&This->Lock, OldIrql);
|
||||||
|
if (!Result)
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
|
||||||
|
Result->Tag = Tag;
|
||||||
|
*PhysicalAddress = MmGetPhysicalAddress(Result->Header->Data);
|
||||||
|
*VirtualAddress = Result->Header->Data;
|
||||||
|
*ByteCount = Result->Header->DataUsed;
|
||||||
|
This->LastTag = Tag;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
IIrpQueue_fnReleaseMappingWithTag(
|
||||||
|
IN IIrpQueue *iface,
|
||||||
|
IN PVOID Tag)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
PIRP_MAPPING CurMapping;
|
||||||
|
PLIST_ENTRY CurEntry;
|
||||||
|
ULONG Index;
|
||||||
|
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&This->Lock, &OldIrql);
|
||||||
|
CurEntry = This->ListHead.Flink;
|
||||||
|
|
||||||
|
while (CurEntry != &This->ListHead)
|
||||||
|
{
|
||||||
|
CurMapping = CONTAINING_RECORD(CurEntry, IRP_MAPPING, Entry);
|
||||||
|
for(Index = 0; Index < CurMapping->NumTags; Index++)
|
||||||
|
{
|
||||||
|
if (CurMapping->Tag[Index] == Tag)
|
||||||
|
{
|
||||||
|
CurMapping->ReferenceCount--;
|
||||||
|
if (!CurMapping->ReferenceCount)
|
||||||
|
{
|
||||||
|
RemoveEntryList(&CurMapping->Entry);
|
||||||
|
if (CurMapping->Irp)
|
||||||
|
{
|
||||||
|
CurMapping->Irp->IoStatus.Information = CurMapping->Header->FrameExtent;
|
||||||
|
CurMapping->Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
|
IoCompleteRequest(CurMapping->Irp, IO_SOUND_INCREMENT);
|
||||||
|
}
|
||||||
|
ExFreePool(CurMapping->Header->Data);
|
||||||
|
ExFreePool(CurMapping->Header);
|
||||||
|
ExFreePool(CurMapping->Tag);
|
||||||
|
ExFreePool(CurMapping);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CurEntry = CurEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&This->Lock, OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
static IIrpQueueVtbl vt_IIrpQueue =
|
static IIrpQueueVtbl vt_IIrpQueue =
|
||||||
{
|
{
|
||||||
|
@ -284,7 +435,9 @@ static IIrpQueueVtbl vt_IIrpQueue =
|
||||||
IIrpQueue_fnMinMappings,
|
IIrpQueue_fnMinMappings,
|
||||||
IIrpQueue_fnMinimumDataAvailable,
|
IIrpQueue_fnMinimumDataAvailable,
|
||||||
IIrpQueue_fnCancelBuffers,
|
IIrpQueue_fnCancelBuffers,
|
||||||
IIrpQueue_fnUpdateFormat
|
IIrpQueue_fnUpdateFormat,
|
||||||
|
IIrpQueue_fnGetMappingWithTag,
|
||||||
|
IIrpQueue_fnReleaseMappingWithTag
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ typedef struct
|
||||||
ULONG ActiveIrpOffset;
|
ULONG ActiveIrpOffset;
|
||||||
ULONG DelayedRequestInProgress;
|
ULONG DelayedRequestInProgress;
|
||||||
ULONG FrameSize;
|
ULONG FrameSize;
|
||||||
|
BOOL Capture;
|
||||||
|
|
||||||
}IPortPinWaveCyclicImpl;
|
}IPortPinWaveCyclicImpl;
|
||||||
|
|
||||||
|
@ -113,10 +114,22 @@ UpdateCommonBuffer(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BytesToCopy = min(BufferLength, BufferSize);
|
BytesToCopy = min(BufferLength, BufferSize);
|
||||||
|
|
||||||
|
|
||||||
|
if (This->Capture)
|
||||||
|
{
|
||||||
|
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||||
|
Buffer,
|
||||||
|
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||||
|
BytesToCopy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||||
Buffer,
|
Buffer,
|
||||||
BytesToCopy);
|
BytesToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
|
This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
|
||||||
This->CommonBufferOffset += BytesToCopy;
|
This->CommonBufferOffset += BytesToCopy;
|
||||||
|
@ -145,10 +158,21 @@ UpdateCommonBufferOverlap(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BytesToCopy = min(BufferLength, BufferSize);
|
BytesToCopy = min(BufferLength, BufferSize);
|
||||||
|
|
||||||
|
if (This->Capture)
|
||||||
|
{
|
||||||
|
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||||
|
Buffer,
|
||||||
|
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||||
|
BytesToCopy);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
This->DmaChannel->lpVtbl->CopyTo(This->DmaChannel,
|
||||||
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
(PUCHAR)This->CommonBuffer + This->CommonBufferOffset,
|
||||||
Buffer,
|
Buffer,
|
||||||
BytesToCopy);
|
BytesToCopy);
|
||||||
|
}
|
||||||
|
|
||||||
This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
|
This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy);
|
||||||
This->CommonBufferOffset += BytesToCopy;
|
This->CommonBufferOffset += BytesToCopy;
|
||||||
|
@ -197,7 +221,6 @@ IServiceSink_fnRequestService(
|
||||||
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
|
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position);
|
||||||
DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, BufferSize);
|
DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, BufferSize);
|
||||||
|
|
||||||
|
|
||||||
if (Position < This->CommonBufferOffset)
|
if (Position < This->CommonBufferOffset)
|
||||||
{
|
{
|
||||||
UpdateCommonBufferOverlap(This, Position);
|
UpdateCommonBufferOverlap(This, Position);
|
||||||
|
@ -230,7 +253,6 @@ IPortPinWaveCyclic_fnQueryInterface(
|
||||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||||
|
|
||||||
if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
|
if (IsEqualGUIDAligned(refiid, &IID_IIrpTarget) ||
|
||||||
//IsEqualGUIDAligned(refiid, &IID_IPortPinWaveCyclic) ||
|
|
||||||
IsEqualGUIDAligned(refiid, &IID_IUnknown))
|
IsEqualGUIDAligned(refiid, &IID_IUnknown))
|
||||||
{
|
{
|
||||||
*Output = &This->lpVtbl;
|
*Output = &This->lpVtbl;
|
||||||
|
@ -702,7 +724,32 @@ IPortPinWaveCyclic_fnFastRead(
|
||||||
OUT PIO_STATUS_BLOCK StatusBlock,
|
OUT PIO_STATUS_BLOCK StatusBlock,
|
||||||
IN PDEVICE_OBJECT DeviceObject)
|
IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
return STATUS_SUCCESS;
|
NTSTATUS Status;
|
||||||
|
PCONTEXT_WRITE Packet;
|
||||||
|
PIRP Irp;
|
||||||
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||||
|
|
||||||
|
DPRINT1("IPortPinWaveCyclic_fnFastRead entered\n");
|
||||||
|
|
||||||
|
Packet = (PCONTEXT_WRITE)Buffer;
|
||||||
|
|
||||||
|
Irp = Packet->Irp;
|
||||||
|
StatusBlock->Status = STATUS_PENDING;
|
||||||
|
|
||||||
|
Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, Buffer, Length, Irp);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
|
||||||
|
{
|
||||||
|
/* some should initiate a state request but didnt do it */
|
||||||
|
DPRINT1("Starting stream with %lu mappings Offset %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), This->ActiveIrpOffset);
|
||||||
|
|
||||||
|
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
|
||||||
|
This->State = KSSTATE_RUN;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -753,7 +800,7 @@ IPortPinWaveCyclic_fnFastWrite(
|
||||||
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
|
if (This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue) == TRUE && This->State != KSSTATE_RUN)
|
||||||
{
|
{
|
||||||
/* some should initiate a state request but didnt do it */
|
/* some should initiate a state request but didnt do it */
|
||||||
DPRINT1("Starting stream with %lu mappings\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue));
|
DPRINT1("Starting stream with %lu mappings Offset %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), This->ActiveIrpOffset);
|
||||||
|
|
||||||
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
|
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_RUN);
|
||||||
This->State = KSSTATE_RUN;
|
This->State = KSSTATE_RUN;
|
||||||
|
@ -777,6 +824,8 @@ IPortPinWaveCyclic_fnInit(
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PKSDATAFORMAT DataFormat;
|
PKSDATAFORMAT DataFormat;
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
BOOL Capture;
|
||||||
|
|
||||||
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||||
|
|
||||||
Port->lpVtbl->AddRef(Port);
|
Port->lpVtbl->AddRef(Port);
|
||||||
|
@ -804,13 +853,32 @@ IPortPinWaveCyclic_fnInit(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
return Status;
|
return Status;
|
||||||
|
|
||||||
Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DataFormat, DeviceObject);
|
Status = This->IrpQueue->lpVtbl->Init(This->IrpQueue, ConnectDetails, DataFormat, DeviceObject, 0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
This->IrpQueue->lpVtbl->Release(This->IrpQueue);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_IN)
|
||||||
|
{
|
||||||
|
Capture = FALSE;
|
||||||
|
}
|
||||||
|
else if (KsPinDescriptor->Communication == KSPIN_COMMUNICATION_SINK && KsPinDescriptor->DataFlow == KSPIN_DATAFLOW_OUT)
|
||||||
|
{
|
||||||
|
Capture = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DPRINT1("Unexpected Communication %u DataFlow %u\n", KsPinDescriptor->Communication, KsPinDescriptor->DataFlow);
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
Status = This->Miniport->lpVtbl->NewStream(This->Miniport,
|
Status = This->Miniport->lpVtbl->NewStream(This->Miniport,
|
||||||
&This->Stream,
|
&This->Stream,
|
||||||
NULL,
|
NULL,
|
||||||
NonPagedPool,
|
NonPagedPool,
|
||||||
FALSE, //FIXME
|
Capture,
|
||||||
ConnectDetails->PinId,
|
ConnectDetails->PinId,
|
||||||
This->Format,
|
This->Format,
|
||||||
&This->DmaChannel,
|
&This->DmaChannel,
|
||||||
|
@ -834,10 +902,10 @@ IPortPinWaveCyclic_fnInit(
|
||||||
This->CommonBufferOffset = 0;
|
This->CommonBufferOffset = 0;
|
||||||
This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
|
This->CommonBufferSize = This->DmaChannel->lpVtbl->AllocatedBufferSize(This->DmaChannel);
|
||||||
This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel);
|
This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel);
|
||||||
|
This->Capture = Capture;
|
||||||
|
|
||||||
//Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize);
|
//Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize);
|
||||||
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,15 +947,16 @@ IPortPinWaveCyclic_fnGetDeviceBufferSize(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
PVOID
|
PVOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IPortPinWaveCyclic_fnGetIrpStream(
|
IPortPinWaveCyclic_fnGetIrpStream(
|
||||||
IN IPortPinWaveCyclic* iface)
|
IN IPortPinWaveCyclic* iface)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
|
||||||
return NULL;
|
|
||||||
|
return (PVOID)This->IrpQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
167
reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c
Normal file
167
reactos/drivers/wdm/audio/backpln/portcls/port_wavepcistream.c
Normal file
|
@ -0,0 +1,167 @@
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IPortWavePciStreamVtbl * lpVtbl;
|
||||||
|
IIrpQueue *Queue;
|
||||||
|
LONG ref;
|
||||||
|
|
||||||
|
|
||||||
|
}IPortWavePciStreamImpl;
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_fnQueryInterface(
|
||||||
|
IPortWavePciStream* iface,
|
||||||
|
IN REFIID refiid,
|
||||||
|
OUT PVOID* Output)
|
||||||
|
{
|
||||||
|
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||||
|
|
||||||
|
DPRINT("IPortWavePciStream_fnQueryInterface entered\n");
|
||||||
|
|
||||||
|
if (IsEqualGUIDAligned(refiid, &IID_IPortWavePciStream) ||
|
||||||
|
IsEqualGUIDAligned(refiid, &IID_IUnknown))
|
||||||
|
{
|
||||||
|
*Output = &This->lpVtbl;
|
||||||
|
InterlockedIncrement(&This->ref);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_fnAddRef(
|
||||||
|
IPortWavePciStream* iface)
|
||||||
|
{
|
||||||
|
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||||
|
DPRINT("IPortWavePciStream_fnAddRef entered\n");
|
||||||
|
|
||||||
|
return InterlockedIncrement(&This->ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_fnRelease(
|
||||||
|
IPortWavePciStream* iface)
|
||||||
|
{
|
||||||
|
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||||
|
|
||||||
|
InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
DPRINT("IPortWavePciStream_fnRelease entered %u\n", This->ref);
|
||||||
|
|
||||||
|
if (This->ref == 0)
|
||||||
|
{
|
||||||
|
FreeItem(This, TAG_PORTCLASS);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Return new reference count */
|
||||||
|
return This->ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_fnGetMapping(
|
||||||
|
IN IPortWavePciStream *iface,
|
||||||
|
IN PVOID Tag,
|
||||||
|
OUT PPHYSICAL_ADDRESS PhysicalAddress,
|
||||||
|
OUT PVOID *VirtualAddress,
|
||||||
|
OUT PULONG ByteCount,
|
||||||
|
OUT PULONG Flags)
|
||||||
|
{
|
||||||
|
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||||
|
|
||||||
|
return This->Queue->lpVtbl->GetMappingWithTag(This->Queue, Tag, PhysicalAddress, VirtualAddress, ByteCount, Flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_fnReleaseMapping(
|
||||||
|
IN IPortWavePciStream *iface,
|
||||||
|
IN PVOID Tag)
|
||||||
|
{
|
||||||
|
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||||
|
This->Queue->lpVtbl->ReleaseMappingWithTag(This->Queue, Tag);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_fnTerminatePacket(
|
||||||
|
IN IPortWavePciStream *iface)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static IPortWavePciStreamVtbl vt_PortWavePciStream =
|
||||||
|
{
|
||||||
|
IPortWavePciStream_fnQueryInterface,
|
||||||
|
IPortWavePciStream_fnAddRef,
|
||||||
|
IPortWavePciStream_fnRelease,
|
||||||
|
IPortWavePciStream_fnGetMapping,
|
||||||
|
IPortWavePciStream_fnReleaseMapping,
|
||||||
|
IPortWavePciStream_fnTerminatePacket
|
||||||
|
};
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NewIPortWavePciStream(
|
||||||
|
OUT PPORTWAVEPCISTREAM *Stream,
|
||||||
|
IN KSPIN_CONNECT *ConnectDetails,
|
||||||
|
IN PKSDATAFORMAT DataFormat,
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG FrameSize)
|
||||||
|
{
|
||||||
|
IIrpQueue * Queue;
|
||||||
|
IPortWavePciStreamImpl * This;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
Status = NewIrpQueue(&Queue);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
return Status;
|
||||||
|
|
||||||
|
Status = Queue->lpVtbl->Init(Queue, ConnectDetails, DataFormat, DeviceObject, FrameSize);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
Queue->lpVtbl->Release(Queue);
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
This = AllocateItem(NonPagedPool, sizeof(IPortWavePciStreamImpl), TAG_PORTCLASS);
|
||||||
|
if (!This)
|
||||||
|
{
|
||||||
|
Queue->lpVtbl->Release(Queue);
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
This->lpVtbl = &vt_PortWavePciStream;
|
||||||
|
This->ref = 1;
|
||||||
|
This->Queue = Queue;
|
||||||
|
|
||||||
|
*Stream = (PPORTWAVEPCISTREAM)&This->lpVtbl;
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_AddMapping(
|
||||||
|
IN IPortWavePciStream *iface,
|
||||||
|
IN PUCHAR Buffer,
|
||||||
|
IN ULONG BufferSize,
|
||||||
|
IN PIRP Irp)
|
||||||
|
{
|
||||||
|
IPortWavePciStreamImpl * This = (IPortWavePciStreamImpl*)iface;
|
||||||
|
return This->Queue->lpVtbl->AddMapping(This->Queue, Buffer, BufferSize, Irp);
|
||||||
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
<file>port_topology.c</file>
|
<file>port_topology.c</file>
|
||||||
<file>port_wavepci.c</file>
|
<file>port_wavepci.c</file>
|
||||||
<file>port_wavecyclic.c</file>
|
<file>port_wavecyclic.c</file>
|
||||||
|
<file>port_wavepcistream.c</file>
|
||||||
<file>propertyhandler.c</file>
|
<file>propertyhandler.c</file>
|
||||||
<file>miniport.c</file>
|
<file>miniport.c</file>
|
||||||
<file>miniport_dmus.c</file>
|
<file>miniport_dmus.c</file>
|
||||||
|
|
|
@ -241,6 +241,22 @@ PDEVICE_OBJECT
|
||||||
GetDeviceObject(
|
GetDeviceObject(
|
||||||
IPortWaveCyclic* iface);
|
IPortWaveCyclic* iface);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
IPortWavePciStream_AddMapping(
|
||||||
|
IN IPortWavePciStream *iface,
|
||||||
|
IN PUCHAR Buffer,
|
||||||
|
IN ULONG BufferSize,
|
||||||
|
IN PIRP Irp);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
NewIPortWavePciStream(
|
||||||
|
OUT PPORTWAVEPCISTREAM *Stream,
|
||||||
|
IN KSPIN_CONNECT *ConnectDetails,
|
||||||
|
IN PKSDATAFORMAT DataFormat,
|
||||||
|
IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN ULONG FrameSize);
|
||||||
|
|
||||||
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
|
#define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
|
||||||
PropGeneral, PropInstances, PropIntersection)\
|
PropGeneral, PropInstances, PropIntersection)\
|
||||||
|
|
Loading…
Reference in a new issue