mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 09:00:27 +00:00
[KS]
- Implement KsEnableEvent, KsEnableEventWithAllocator, KsDiscardEvent [PORTCLS] - Fix signalling the event - DirectSound clients can now use IDirectSoundNotify interface to be notified of a position change svn path=/trunk/; revision=44100
This commit is contained in:
parent
008929cd36
commit
7d088d0725
2 changed files with 365 additions and 27 deletions
|
@ -71,9 +71,312 @@ KspSynchronizedEventRoutine(
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOLEAN
|
||||||
|
NTAPI
|
||||||
|
SyncAddEvent(
|
||||||
|
PKSEVENT_CTX Context)
|
||||||
|
{
|
||||||
|
InsertTailList(Context->List, &Context->EventEntry->ListEntry);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
KspEnableEvent(
|
||||||
|
IN PIRP Irp,
|
||||||
|
IN ULONG EventSetsCount,
|
||||||
|
IN PKSEVENT_SET EventSet,
|
||||||
|
IN OUT PLIST_ENTRY EventsList OPTIONAL,
|
||||||
|
IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL,
|
||||||
|
IN PVOID EventsLock OPTIONAL,
|
||||||
|
IN PFNKSALLOCATOR Allocator OPTIONAL,
|
||||||
|
IN ULONG EventItemSize OPTIONAL)
|
||||||
|
{
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
NTSTATUS Status;
|
||||||
|
KSEVENT Event;
|
||||||
|
PKSEVENT_ITEM EventItem, FoundEventItem;
|
||||||
|
PKSEVENTDATA EventData;
|
||||||
|
PKSEVENT_SET FoundEventSet;
|
||||||
|
PKSEVENT_ENTRY EventEntry;
|
||||||
|
ULONG Index, SubIndex, Size;
|
||||||
|
PVOID Object;
|
||||||
|
KSEVENT_CTX Ctx;
|
||||||
|
LPGUID Guid;
|
||||||
|
|
||||||
|
/* get current stack location */
|
||||||
|
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSEVENT))
|
||||||
|
{
|
||||||
|
/* invalid parameter */
|
||||||
|
return STATUS_NOT_SUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Irp->RequestorMode == UserMode)
|
||||||
|
{
|
||||||
|
_SEH2_TRY
|
||||||
|
{
|
||||||
|
ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT), sizeof(UCHAR));
|
||||||
|
ProbeForRead(Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, sizeof(UCHAR));
|
||||||
|
RtlMoveMemory(&Event, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT));
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
/* Exception, get the error code */
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
/* check for success */
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* failed to probe parameters */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* copy event struct */
|
||||||
|
RtlMoveMemory(&Event, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSEVENT));
|
||||||
|
}
|
||||||
|
|
||||||
|
FoundEventItem = NULL;
|
||||||
|
FoundEventSet = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
if (IsEqualGUIDAligned(&Event.Set, &GUID_NULL) && Event.Id == 0 && Event.Flags == KSEVENT_TYPE_SETSUPPORT)
|
||||||
|
{
|
||||||
|
// store output size
|
||||||
|
Irp->IoStatus.Information = sizeof(GUID) * EventSetsCount;
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(GUID) * EventSetsCount)
|
||||||
|
{
|
||||||
|
// buffer too small
|
||||||
|
return STATUS_MORE_ENTRIES;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get output buffer
|
||||||
|
Guid = (LPGUID)Irp->UserBuffer;
|
||||||
|
|
||||||
|
// copy property guids from property sets
|
||||||
|
for(Index = 0; Index < EventSetsCount; Index++)
|
||||||
|
{
|
||||||
|
RtlMoveMemory(&Guid[Index], EventSet[Index].Set, sizeof(GUID));
|
||||||
|
}
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now try to find event set */
|
||||||
|
for(Index = 0; Index < EventSetsCount; Index++)
|
||||||
|
{
|
||||||
|
if (IsEqualGUIDAligned(&Event.Set, EventSet[Index].Set))
|
||||||
|
{
|
||||||
|
EventItem = (PKSEVENT_ITEM)EventSet[Index].EventItem;
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(EventSet[Index].EventsCount);
|
||||||
|
ASSERT(EventItem);
|
||||||
|
|
||||||
|
/* now find matching event id */
|
||||||
|
for(SubIndex = 0; SubIndex < EventSet[Index].EventsCount; SubIndex++)
|
||||||
|
{
|
||||||
|
if (EventItem[SubIndex].EventId == Event.Id)
|
||||||
|
{
|
||||||
|
/* found event item */
|
||||||
|
FoundEventItem = &EventItem[SubIndex];
|
||||||
|
FoundEventSet = &EventSet[Index];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FoundEventSet)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FoundEventSet)
|
||||||
|
{
|
||||||
|
UNICODE_STRING GuidString;
|
||||||
|
|
||||||
|
RtlStringFromGUID(&Event.Set, &GuidString);
|
||||||
|
|
||||||
|
DPRINT("Guid %S Id %u Flags %x not found\n", GuidString.Buffer, Event.Id, Event.Flags);
|
||||||
|
RtlFreeUnicodeString(&GuidString);
|
||||||
|
return STATUS_PROPSET_NOT_FOUND;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < FoundEventItem->DataInput)
|
||||||
|
{
|
||||||
|
/* buffer too small */
|
||||||
|
DPRINT1("Got %u expected %u\n", IoStack->Parameters.DeviceIoControl.OutputBufferLength, FoundEventItem->DataInput);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FoundEventItem->AddHandler && !EventsList)
|
||||||
|
{
|
||||||
|
/* no add handler and no list to add the new entry to */
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get event data */
|
||||||
|
EventData = Irp->UserBuffer;
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
ASSERT(EventData);
|
||||||
|
|
||||||
|
if (Irp->RequestorMode == UserMode)
|
||||||
|
{
|
||||||
|
if (EventData->NotificationType == KSEVENTF_SEMAPHORE_HANDLE)
|
||||||
|
{
|
||||||
|
/* get semaphore object handle */
|
||||||
|
Status = ObReferenceObjectByHandle(EventData->SemaphoreHandle.Semaphore, SEMAPHORE_MODIFY_STATE, ExSemaphoreObjectType, Irp->RequestorMode, &Object, NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* invalid semaphore handle */
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (EventData->NotificationType == KSEVENTF_EVENT_HANDLE)
|
||||||
|
{
|
||||||
|
/* get event object handle */
|
||||||
|
Status = ObReferenceObjectByHandle(EventData->EventHandle.Event, EVENT_MODIFY_STATE, ExEventObjectType, Irp->RequestorMode, &Object, NULL);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* invalid event handle */
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* user mode client can only pass an event or semaphore handle */
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (EventData->NotificationType != KSEVENTF_EVENT_OBJECT &&
|
||||||
|
EventData->NotificationType != KSEVENTF_SEMAPHORE_OBJECT &&
|
||||||
|
EventData->NotificationType != KSEVENTF_DPC &&
|
||||||
|
EventData->NotificationType != KSEVENTF_WORKITEM &&
|
||||||
|
EventData->NotificationType != KSEVENTF_KSWORKITEM)
|
||||||
|
{
|
||||||
|
/* invalid type requested */
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* calculate request size */
|
||||||
|
Size = sizeof(KSEVENT_ENTRY) + FoundEventItem->ExtraEntryData;
|
||||||
|
|
||||||
|
/* do we have an allocator */
|
||||||
|
if (Allocator)
|
||||||
|
{
|
||||||
|
/* allocate event entry */
|
||||||
|
Status = Allocator(Irp, Size, FALSE);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* failed */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* assume the caller put it there */
|
||||||
|
EventEntry = KSEVENT_ENTRY_IRP_STORAGE(Irp);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* allocate it from nonpaged pool */
|
||||||
|
EventEntry = ExAllocatePool(NonPagedPool, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!EventEntry)
|
||||||
|
{
|
||||||
|
/* not enough memory */
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* zero event entry */
|
||||||
|
RtlZeroMemory(EventEntry, Size);
|
||||||
|
|
||||||
|
/* initialize event entry */
|
||||||
|
EventEntry->EventData = EventData;
|
||||||
|
EventEntry->NotificationType = EventData->NotificationType;
|
||||||
|
EventEntry->EventItem = FoundEventItem;
|
||||||
|
EventEntry->EventSet = FoundEventSet;
|
||||||
|
EventEntry->FileObject = IoStack->FileObject;
|
||||||
|
|
||||||
|
switch(EventEntry->NotificationType)
|
||||||
|
{
|
||||||
|
case KSEVENTF_EVENT_HANDLE:
|
||||||
|
EventEntry->Object = Object;
|
||||||
|
EventEntry->Reserved = 0;
|
||||||
|
break;
|
||||||
|
case KSEVENTF_SEMAPHORE_HANDLE:
|
||||||
|
EventEntry->Object = Object;
|
||||||
|
EventEntry->SemaphoreAdjustment = EventData->SemaphoreHandle.Adjustment;
|
||||||
|
EventEntry->Reserved = 0;
|
||||||
|
break;
|
||||||
|
case KSEVENTF_EVENT_OBJECT:
|
||||||
|
EventEntry->Object = EventData->EventObject.Event;
|
||||||
|
EventEntry->Reserved = EventData->EventObject.Increment;
|
||||||
|
break;
|
||||||
|
case KSEVENTF_SEMAPHORE_OBJECT:
|
||||||
|
EventEntry->Object = EventData->SemaphoreObject.Semaphore;
|
||||||
|
EventEntry->SemaphoreAdjustment = EventData->SemaphoreObject.Adjustment;
|
||||||
|
EventEntry->Reserved = EventData->SemaphoreObject.Increment;
|
||||||
|
break;
|
||||||
|
case KSEVENTF_DPC:
|
||||||
|
EventEntry->Object = EventData->Dpc.Dpc;
|
||||||
|
EventData->Dpc.ReferenceCount = 0;
|
||||||
|
break;
|
||||||
|
case KSEVENTF_WORKITEM:
|
||||||
|
EventEntry->Object = EventData->WorkItem.WorkQueueItem;
|
||||||
|
EventEntry->BufferItem = (PKSBUFFER_ITEM)UlongToPtr(EventData->WorkItem.WorkQueueType);
|
||||||
|
break;
|
||||||
|
case KSEVENTF_KSWORKITEM:
|
||||||
|
EventEntry->Object = EventData->KsWorkItem.KsWorkerObject;
|
||||||
|
EventEntry->DpcItem = (PKSDPC_ITEM)EventData->KsWorkItem.WorkQueueItem;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* should not happen */
|
||||||
|
ASSERT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FoundEventItem->AddHandler)
|
||||||
|
{
|
||||||
|
/* now add the event */
|
||||||
|
Status = FoundEventItem->AddHandler(Irp, EventData, EventEntry);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* discard event entry */
|
||||||
|
KsDiscardEvent(EventEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* setup context */
|
||||||
|
Ctx.List = EventsList;
|
||||||
|
Ctx.EventEntry = EventEntry;
|
||||||
|
|
||||||
|
/* add the event */
|
||||||
|
(void)KspSynchronizedEventRoutine(EventsFlags, EventsLock, SyncAddEvent, &Ctx);
|
||||||
|
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* done */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -86,12 +389,11 @@ KsEnableEvent(
|
||||||
IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL,
|
IN KSEVENTS_LOCKTYPE EventsFlags OPTIONAL,
|
||||||
IN PVOID EventsLock OPTIONAL)
|
IN PVOID EventsLock OPTIONAL)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
return KspEnableEvent(Irp, EventSetsCount, EventSet, EventsList, EventsFlags, EventsLock, NULL, 0);
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -106,8 +408,7 @@ KsEnableEventWithAllocator(
|
||||||
IN PFNKSALLOCATOR Allocator OPTIONAL,
|
IN PFNKSALLOCATOR Allocator OPTIONAL,
|
||||||
IN ULONG EventItemSize OPTIONAL)
|
IN ULONG EventItemSize OPTIONAL)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
return KspEnableEvent(Irp, EventSetsCount, EventSet, EventsList, EventsFlags, EventsLock, Allocator, EventItemSize);
|
||||||
return STATUS_UNSUCCESSFUL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -210,7 +511,7 @@ KsDisableEvent(
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@unimplemented
|
@implemented
|
||||||
*/
|
*/
|
||||||
KSDDKAPI
|
KSDDKAPI
|
||||||
VOID
|
VOID
|
||||||
|
@ -218,7 +519,17 @@ NTAPI
|
||||||
KsDiscardEvent(
|
KsDiscardEvent(
|
||||||
IN PKSEVENT_ENTRY EventEntry)
|
IN PKSEVENT_ENTRY EventEntry)
|
||||||
{
|
{
|
||||||
//UNIMPLEMENTED;
|
/* sanity check */
|
||||||
|
ASSERT(EventEntry->Object);
|
||||||
|
|
||||||
|
if (EventEntry->NotificationType == KSEVENTF_SEMAPHORE_HANDLE || EventEntry->NotificationType == KSEVENTF_EVENT_HANDLE)
|
||||||
|
{
|
||||||
|
/* release object */
|
||||||
|
ObDereferenceObject(EventEntry->Object);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free event entry */
|
||||||
|
ExFreePool(EventEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -295,33 +606,35 @@ KsGenerateEvent(
|
||||||
{
|
{
|
||||||
if (EntryEvent->NotificationType == KSEVENTF_EVENT_HANDLE || EntryEvent->NotificationType == KSEVENTF_EVENT_OBJECT)
|
if (EntryEvent->NotificationType == KSEVENTF_EVENT_HANDLE || EntryEvent->NotificationType == KSEVENTF_EVENT_OBJECT)
|
||||||
{
|
{
|
||||||
// signal event
|
/* signal event */
|
||||||
KeSetEvent(EntryEvent->Object, 0, FALSE);
|
KeSetEvent(EntryEvent->Object, EntryEvent->Reserved, FALSE);
|
||||||
}
|
}
|
||||||
else if (EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_HANDLE || EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_OBJECT)
|
else if (EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_HANDLE || EntryEvent->NotificationType == KSEVENTF_SEMAPHORE_OBJECT)
|
||||||
{
|
{
|
||||||
// release semaphore
|
/* release semaphore */
|
||||||
KeReleaseSemaphore(EntryEvent->Object, 0, EntryEvent->SemaphoreAdjustment, FALSE);
|
KeReleaseSemaphore(EntryEvent->Object, EntryEvent->Reserved, EntryEvent->SemaphoreAdjustment, FALSE);
|
||||||
}
|
}
|
||||||
else if (EntryEvent->NotificationType == KSEVENTF_DPC)
|
else if (EntryEvent->NotificationType == KSEVENTF_DPC)
|
||||||
{
|
{
|
||||||
// queue dpc
|
/* increment reference count to indicate dpc is pending */
|
||||||
|
InterlockedIncrement((PLONG)&EntryEvent->EventData->Dpc.ReferenceCount);
|
||||||
|
/* queue dpc */
|
||||||
KeInsertQueueDpc((PRKDPC)EntryEvent->Object, NULL, NULL);
|
KeInsertQueueDpc((PRKDPC)EntryEvent->Object, NULL, NULL);
|
||||||
}
|
}
|
||||||
else if (EntryEvent->NotificationType == KSEVENTF_WORKITEM)
|
else if (EntryEvent->NotificationType == KSEVENTF_WORKITEM)
|
||||||
{
|
{
|
||||||
// queue work item
|
/* queue work item */
|
||||||
ExQueueWorkItem((PWORK_QUEUE_ITEM)EntryEvent->Object, PtrToUlong(EntryEvent->BufferItem));
|
ExQueueWorkItem((PWORK_QUEUE_ITEM)EntryEvent->Object, PtrToUlong(EntryEvent->BufferItem));
|
||||||
}
|
}
|
||||||
else if (EntryEvent->NotificationType == KSEVENTF_KSWORKITEM)
|
else if (EntryEvent->NotificationType == KSEVENTF_KSWORKITEM)
|
||||||
{
|
{
|
||||||
// queue work item of ks worker
|
/* queue work item of ks worker */
|
||||||
return KsQueueWorkItem((PKSWORKER)EntryEvent->Object, (PWORK_QUEUE_ITEM)EntryEvent->DpcItem);
|
return KsQueueWorkItem((PKSWORKER)EntryEvent->Object, (PWORK_QUEUE_ITEM)EntryEvent->DpcItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
/* unsupported type requested */
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
|
|
|
@ -41,7 +41,7 @@ protected:
|
||||||
|
|
||||||
VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount);
|
VOID UpdateCommonBuffer(ULONG Position, ULONG MaxTransferCount);
|
||||||
VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount);
|
VOID UpdateCommonBufferOverlap(ULONG Position, ULONG MaxTransferCount);
|
||||||
VOID GeneratePositionEvents(IN ULONG OldCommonBufferOffset, IN ULONG NewCommonBufferOffset);
|
VOID GeneratePositionEvents(IN ULONGLONG OldOffset, IN ULONGLONG NewOffset);
|
||||||
NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
|
NTSTATUS NTAPI HandleKsStream(IN PIRP Irp);
|
||||||
NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
|
NTSTATUS NTAPI HandleKsProperty(IN PIRP Irp);
|
||||||
|
|
||||||
|
@ -261,6 +261,8 @@ PinWaveCyclicAddLoopedStreamEvent(
|
||||||
Entry->bLoopedStreaming = TRUE;
|
Entry->bLoopedStreaming = TRUE;
|
||||||
Entry->Position = Data->Position;
|
Entry->Position = Data->Position;
|
||||||
|
|
||||||
|
DPRINT1("Added event\n");
|
||||||
|
|
||||||
// insert item
|
// insert item
|
||||||
(void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock);
|
(void)ExInterlockedInsertTailList(&Pin->m_EventList, &EventEntry->ListEntry, &Pin->m_EventListLock);
|
||||||
|
|
||||||
|
@ -342,7 +344,7 @@ PinWaveCyclicAudioPosition(
|
||||||
}
|
}
|
||||||
else if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
|
else if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
|
||||||
{
|
{
|
||||||
Position->PlayOffset = Pin->m_Position.PlayOffset % Pin->m_Position.WriteOffset;
|
Position->PlayOffset = Pin->m_Position.PlayOffset;
|
||||||
Position->WriteOffset = (ULONGLONG)Pin->m_IrpQueue->GetCurrentIrpOffset();
|
Position->WriteOffset = (ULONGLONG)Pin->m_IrpQueue->GetCurrentIrpOffset();
|
||||||
DPRINT("Play %lu Write %lu\n", Position->PlayOffset, Position->WriteOffset);
|
DPRINT("Play %lu Write %lu\n", Position->PlayOffset, Position->WriteOffset);
|
||||||
}
|
}
|
||||||
|
@ -540,8 +542,8 @@ PinWaveCyclicDataFormat(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
CPortPinWaveCyclic::GeneratePositionEvents(
|
CPortPinWaveCyclic::GeneratePositionEvents(
|
||||||
IN ULONG OldCommonBufferOffset,
|
IN ULONGLONG OldOffset,
|
||||||
IN ULONG NewCommonBufferOffset)
|
IN ULONGLONG NewOffset)
|
||||||
{
|
{
|
||||||
PLIST_ENTRY Entry;
|
PLIST_ENTRY Entry;
|
||||||
PKSEVENT_ENTRY EventEntry;
|
PKSEVENT_ENTRY EventEntry;
|
||||||
|
@ -563,11 +565,15 @@ CPortPinWaveCyclic::GeneratePositionEvents(
|
||||||
|
|
||||||
if (Context->bLoopedStreaming == TRUE)
|
if (Context->bLoopedStreaming == TRUE)
|
||||||
{
|
{
|
||||||
if (NewCommonBufferOffset > OldCommonBufferOffset)
|
if (NewOffset > OldOffset)
|
||||||
{
|
{
|
||||||
/* buffer progress no overlap */
|
/* buffer progress no overlap */
|
||||||
if (OldCommonBufferOffset < Context->Position && Context->Position <= NewCommonBufferOffset)
|
if (OldOffset < Context->Position && Context->Position <= NewOffset)
|
||||||
{
|
{
|
||||||
|
/* when someone eventually fixes sprintf... */
|
||||||
|
DPRINT("Generating event at OldOffset %I64u\n", OldOffset);
|
||||||
|
DPRINT("Context->Position %I64u\n", Context->Position);
|
||||||
|
DPRINT("NewOffset %I64u\n", NewOffset);
|
||||||
/* generate event */
|
/* generate event */
|
||||||
KsGenerateEvent(EventEntry);
|
KsGenerateEvent(EventEntry);
|
||||||
}
|
}
|
||||||
|
@ -575,8 +581,12 @@ CPortPinWaveCyclic::GeneratePositionEvents(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* buffer wrap-arround */
|
/* buffer wrap-arround */
|
||||||
if (OldCommonBufferOffset < Context->Position || NewCommonBufferOffset > Context->Position)
|
if (OldOffset < Context->Position || NewOffset > Context->Position)
|
||||||
{
|
{
|
||||||
|
/* when someone eventually fixes sprintf... */
|
||||||
|
DPRINT("Generating event at OldOffset %I64u\n", OldOffset);
|
||||||
|
DPRINT("Context->Position %I64u\n", Context->Position);
|
||||||
|
DPRINT("NewOffset %I64u\n", NewOffset);
|
||||||
/* generate event */
|
/* generate event */
|
||||||
KsGenerateEvent(EventEntry);
|
KsGenerateEvent(EventEntry);
|
||||||
}
|
}
|
||||||
|
@ -627,6 +637,12 @@ CPortPinWaveCyclic::UpdateCommonBuffer(
|
||||||
|
|
||||||
BufferLength = Position - m_CommonBufferOffset;
|
BufferLength = Position - m_CommonBufferOffset;
|
||||||
m_Position.PlayOffset += BytesToCopy;
|
m_Position.PlayOffset += BytesToCopy;
|
||||||
|
|
||||||
|
if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
|
||||||
|
{
|
||||||
|
// normalize position
|
||||||
|
m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -670,6 +686,13 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap(
|
||||||
m_Position.PlayOffset += BytesToCopy;
|
m_Position.PlayOffset += BytesToCopy;
|
||||||
|
|
||||||
BufferLength = m_CommonBufferSize - m_CommonBufferOffset;
|
BufferLength = m_CommonBufferSize - m_CommonBufferOffset;
|
||||||
|
|
||||||
|
if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
|
||||||
|
{
|
||||||
|
// normalize position
|
||||||
|
m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Gap == Length)
|
if (Gap == Length)
|
||||||
|
@ -693,7 +716,7 @@ CPortPinWaveCyclic::RequestService()
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PUCHAR Buffer;
|
PUCHAR Buffer;
|
||||||
ULONG BufferSize;
|
ULONG BufferSize;
|
||||||
ULONG OldCommonBufferOffset;
|
ULONGLONG OldOffset, NewOffset;
|
||||||
|
|
||||||
PC_ASSERT_IRQL(DISPATCH_LEVEL);
|
PC_ASSERT_IRQL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
@ -706,7 +729,7 @@ CPortPinWaveCyclic::RequestService()
|
||||||
Status = m_Stream->GetPosition(&Position);
|
Status = m_Stream->GetPosition(&Position);
|
||||||
DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture);
|
DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture);
|
||||||
|
|
||||||
OldCommonBufferOffset = m_CommonBufferOffset;
|
OldOffset = m_Position.PlayOffset;
|
||||||
|
|
||||||
if (Position < m_CommonBufferOffset)
|
if (Position < m_CommonBufferOffset)
|
||||||
{
|
{
|
||||||
|
@ -717,7 +740,9 @@ CPortPinWaveCyclic::RequestService()
|
||||||
UpdateCommonBuffer(Position, m_FrameSize);
|
UpdateCommonBuffer(Position, m_FrameSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
GeneratePositionEvents(OldCommonBufferOffset, m_CommonBufferOffset);
|
NewOffset = m_Position.PlayOffset;
|
||||||
|
|
||||||
|
GeneratePositionEvents(OldOffset, NewOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
|
Loading…
Reference in a new issue