Author: janderwald Date: Sun Jun 21 03:37:55 2009 New Revision: 41497
URL: http://svn.reactos.org/svn/reactos?rev=41497&view=rev Log: - Define private interface IPortWaveRTStreamInit in order to deal with PHYSICAL_ADDRESS as return value - Implement reading/writing into cyclic buffer for IPortPinWaveRT - Allocate an audio buffer when the pin is initialized. This needs to be changed once KSPROPERTY_RTAUDIO_BUFFER is implemented - Fix a bug in PcNewPort - Remove obsolete code from IPortWavePci - Return the allocated MDL from IPortWaveRTStream::AllocateContiguousPagesForMdl - Create a system thread when using IServiceGroup::RequestDelayedService - ReactOS now partly supports Vista audio driver model
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h trunk/reactos/drivers/wdm/audio/backpln/portcls/service_group.c
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h [iso-8859-1] Sun Jun 21 03:37:55 2009 @@ -710,4 +710,62 @@
#undef INTERFACE
+/***************************************************************************** + * IPortWaveRTStreamInit + ***************************************************************************** + */ + +#undef INTERFACE +#define INTERFACE IPortWaveRTStreamInit + + +DECLARE_INTERFACE_(IPortWaveRTStreamInit, IUnknown) +{ + DEFINE_ABSTRACT_UNKNOWN() + + STDMETHOD_(PMDL, AllocatePagesForMdl) + ( THIS_ + IN PHYSICAL_ADDRESS HighAddress, + IN SIZE_T TotalBytes + ) PURE; + + STDMETHOD_(PMDL, AllocateContiguousPagesForMdl) + ( THIS_ + IN PHYSICAL_ADDRESS LowAddress, + IN PHYSICAL_ADDRESS HighAddress, + IN SIZE_T TotalBytes + ) PURE; + + STDMETHOD_(PVOID, MapAllocatedPages) + ( THIS_ + IN PMDL MemoryDescriptorList, + IN MEMORY_CACHING_TYPE CacheType + ) PURE; + + STDMETHOD_(VOID, UnmapAllocatedPages) + ( THIS_ + IN PVOID BaseAddress, + IN PMDL MemoryDescriptorList + ) PURE; + + STDMETHOD_(VOID, FreePagesFromMdl) + ( THIS_ + IN PMDL MemoryDescriptorList + ) PURE; + + STDMETHOD_(ULONG, GetPhysicalPagesCount) + ( THIS_ + IN PMDL MemoryDescriptorList + ) PURE; + + STDMETHOD_(PHYSICAL_ADDRESS, GetPhysicalPageAddress) + ( THIS_ + IN PPHYSICAL_ADDRESS Address, + IN PMDL MemoryDescriptorList, + IN ULONG Index + ) PURE; +}; + +#undef INTERFACE + #endif
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c [iso-8859-1] Sun Jun 21 03:37:55 2009 @@ -59,6 +59,85 @@ IN IPortPinWaveRTImpl * This, IN KSSTATE State);
+static +VOID +UpdateCommonBuffer( + IPortPinWaveRTImpl * This, + ULONG Position) +{ + ULONG BufferLength; + ULONG BytesToCopy; + ULONG BufferSize; + PUCHAR Buffer; + NTSTATUS Status; + + BufferLength = Position - This->CommonBufferOffset; + while(BufferLength) + { + Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + return; + + BytesToCopy = min(BufferLength, BufferSize); + + if (This->Capture) + { + RtlMoveMemory(Buffer, (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, BytesToCopy); + } + else + { + RtlMoveMemory((PUCHAR)This->CommonBuffer + This->CommonBufferOffset, Buffer, BytesToCopy); + } + + This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy); + This->CommonBufferOffset += BytesToCopy; + + BufferLength = Position - This->CommonBufferOffset; + } +} + +static +VOID +UpdateCommonBufferOverlap( + IPortPinWaveRTImpl * This, + ULONG Position) +{ + ULONG BufferLength; + ULONG BytesToCopy; + ULONG BufferSize; + PUCHAR Buffer; + NTSTATUS Status; + + + BufferLength = This->CommonBufferSize - This->CommonBufferOffset; + while(BufferLength) + { + Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); + if (!NT_SUCCESS(Status)) + return; + + BytesToCopy = min(BufferLength, BufferSize); + + if (This->Capture) + { + RtlMoveMemory(Buffer, (PUCHAR)This->CommonBuffer + This->CommonBufferOffset, BytesToCopy); + } + else + { + RtlMoveMemory((PUCHAR)This->CommonBuffer + This->CommonBufferOffset, Buffer, BytesToCopy); + } + + This->IrpQueue->lpVtbl->UpdateMapping(This->IrpQueue, BytesToCopy); + This->CommonBufferOffset += BytesToCopy; + + BufferLength = This->CommonBufferSize - This->CommonBufferOffset; + } + This->CommonBufferOffset = 0; + UpdateCommonBuffer(This, Position); +} + + + //================================================================================================================================== static NTSTATUS @@ -137,14 +216,16 @@ }
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position); - DPRINT("PlayOffset %llu WriteOffset %llu %u Buffer %p BufferSize %u\n", Position.PlayOffset, Position.WriteOffset, Buffer, This->CommonBufferSize, BufferSize); - - //FIXME - // implement writing into cyclic buffer - // - - /* reschedule the timer */ - This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay); + DPRINT("PlayOffset %lu WriteOffset %lu Buffer %p BufferSize %u CommonBufferSize %u\n", Position.PlayOffset, Position.WriteOffset, Buffer, BufferSize, This->CommonBufferSize); + + if (Position.PlayOffset < This->CommonBufferOffset) + { + UpdateCommonBufferOverlap(This, Position.PlayOffset); + } + else if (Position.PlayOffset >= This->CommonBufferOffset) + { + UpdateCommonBuffer(This, Position.PlayOffset); + } }
static IServiceSinkVtbl vt_IServiceSink = @@ -962,18 +1043,25 @@ /* minimum delay of 10 milisec */ This->Delay = Int32x32To64(min(max(Latency.ChipsetDelay + Latency.CodecDelay + Latency.FifoSize, 10), 10), -10000);
- Status = This->Stream->lpVtbl->AllocateAudioBuffer(This->Stream, 16384, &This->Mdl, &This->CommonBufferSize, &This->CommonBufferOffset, &This->CacheType); + Status = This->Stream->lpVtbl->AllocateAudioBuffer(This->Stream, 16384 * 11, &This->Mdl, &This->CommonBufferSize, &This->CommonBufferOffset, &This->CacheType); if (!NT_SUCCESS(Status)) { DPRINT1("AllocateAudioBuffer failed with %x\n", Status); goto cleanup; }
- This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); - This->State = KSSTATE_STOP; - This->Capture = Capture; - - This->Stream->lpVtbl->SetFormat(This->Stream, (PKSDATAFORMAT)This->Format); + This->CommonBuffer = MmGetSystemAddressForMdlSafe(This->Mdl, NormalPagePriority); + if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to get system address %x\n", Status); + IoFreeMdl(This->Mdl); + This->Mdl = NULL; + goto cleanup; + } + + DPRINT1("Setting state to acquire %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_ACQUIRE)); + DPRINT1("Setting state to pause %x\n", This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_PAUSE)); + This->State = KSSTATE_PAUSE; return STATUS_SUCCESS;
cleanup: @@ -995,12 +1083,20 @@ This->ServiceGroup = NULL; }
- if (This->PortStream) - { - This->PortStream->lpVtbl->Release(This->PortStream); - This->PortStream = NULL; - } - + if (This->Stream) + { + This->Stream->lpVtbl->Release(This->Stream); + This->Stream = NULL; + } + else + { + if (This->PortStream) + { + This->PortStream->lpVtbl->Release(This->PortStream); + This->PortStream = NULL; + } + + } return Status; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port.c [iso-8859-1] Sun Jun 21 03:37:55 2009 @@ -40,10 +40,8 @@ Status = NewPortWaveCyclic(OutPort); else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWavePci)) Status = NewPortWavePci(OutPort); -#if (NTDDI_VERSION >= NTDDI_VISTA) - else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWavePci)) + else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWaveRT)) Status = NewPortWaveRT(OutPort); -#endif else {
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c [iso-8859-1] Sun Jun 21 03:37:55 2009 @@ -22,7 +22,6 @@
PMINIPORTWAVEPCI Miniport; PDEVICE_OBJECT pDeviceObject; - KDPC Dpc; BOOL bInitialized; PRESOURCELIST pResourceList; PSERVICEGROUP ServiceGroup; @@ -331,26 +330,6 @@ return This->ref; }
-VOID -NTAPI -ServiceNotifyRoutine( - IN struct _KDPC *Dpc, - IN PVOID DeferredContext, - IN PVOID SystemArgument1, - IN PVOID SystemArgument2) -{ - DPRINT("ServiceNotifyRoutine entered %p %p %p\n", DeferredContext, SystemArgument1, SystemArgument2); - - IPortWavePciImpl * This = (IPortWavePciImpl*)DeferredContext; - if (This->ServiceGroup && This->bInitialized) - { - DPRINT("ServiceGroup %p\n", This->ServiceGroup); - This->ServiceGroup->lpVtbl->RequestService(This->ServiceGroup); - } -} - - - NTSTATUS NTAPI IPortWavePci_fnInit( @@ -385,15 +364,11 @@ return STATUS_INVALID_PARAMETER; }
- /* initialize the dpc */ - KeInitializeDpc(&This->Dpc, ServiceNotifyRoutine, (PVOID)This); - /* Initialize port object */ This->Miniport = Miniport; This->pDeviceObject = DeviceObject; This->bInitialized = TRUE; This->pResourceList = ResourceList; -
/* increment reference on miniport adapter */ Miniport->lpVtbl->AddRef(Miniport);
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c [iso-8859-1] Sun Jun 21 03:37:55 2009 @@ -10,7 +10,7 @@
typedef struct { - IPortWaveRTStreamVtbl *lpVtbl; + IPortWaveRTStreamInitVtbl *lpVtbl; LONG ref;
}IPortWaveRTStreamImpl; @@ -21,8 +21,8 @@ static NTSTATUS NTAPI -IPortWaveRTStream_fnQueryInterface( - IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnQueryInterface( + IPortWaveRTStreamInit * iface, IN REFIID refiid, OUT PVOID* Output) { @@ -46,8 +46,8 @@ static ULONG NTAPI -IPortWaveRTStream_fnAddRef( - IPortWaveRTStream* iface) +IPortWaveRTStreamInit_fnAddRef( + IPortWaveRTStreamInit * iface) { IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface; DPRINT("IPortWaveRTStream_fnAddRef entered\n"); @@ -61,8 +61,8 @@ static ULONG NTAPI -IPortWaveRTStream_fnRelease( - IPortWaveRTStream* iface) +IPortWaveRTStreamInit_fnRelease( + IPortWaveRTStreamInit * iface) { IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
@@ -85,8 +85,8 @@ static PMDL NTAPI -IPortWaveRTStream_fnAllocatePagesForMdl( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnAllocatePagesForMdl( + IN IPortWaveRTStreamInit * iface, IN PHYSICAL_ADDRESS HighAddress, IN SIZE_T TotalBytes) { @@ -99,8 +99,8 @@ static PMDL NTAPI -IPortWaveRTStream_fnAllocateContiguousPagesForMdl( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl( + IN IPortWaveRTStreamInit * iface, IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS HighAddress, IN SIZE_T TotalBytes) @@ -129,12 +129,14 @@
if (MmGetMdlByteCount(Mdl) < TotalBytes) { + DPRINT1("ByteCount %u Required %u\n", MmGetMdlByteCount(Mdl), TotalBytes); MmFreePagesFromMdl(Mdl); ExFreePool(Mdl); return NULL; }
- return NULL; + DPRINT("Result %p\n", Mdl); + return Mdl; }
/* @@ -143,8 +145,8 @@ static PVOID NTAPI -IPortWaveRTStream_fnMapAllocatedPages( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnMapAllocatedPages( + IN IPortWaveRTStreamInit * iface, IN PMDL MemoryDescriptorList, IN MEMORY_CACHING_TYPE CacheType) { @@ -157,8 +159,8 @@ static VOID NTAPI -IPortWaveRTStream_fnUnmapAllocatedPages( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnUnmapAllocatedPages( + IN IPortWaveRTStreamInit * iface, IN PVOID BaseAddress, IN PMDL MemoryDescriptorList) { @@ -171,8 +173,8 @@ static VOID NTAPI -IPortWaveRTStream_fnFreePagesFromMdl( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnFreePagesFromMdl( + IN IPortWaveRTStreamInit * iface, IN PMDL MemoryDescriptorList) { MmFreePagesFromMdl(MemoryDescriptorList); @@ -185,8 +187,8 @@ static ULONG NTAPI -IPortWaveRTStream_fnGetPhysicalPagesCount( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnGetPhysicalPagesCount( + IN IPortWaveRTStreamInit * iface, IN PMDL MemoryDescriptorList) { return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList)); @@ -198,13 +200,15 @@ static PHYSICAL_ADDRESS NTAPI -IPortWaveRTStream_fnGetPhysicalPageAddress( - IN IPortWaveRTStream* iface, - IN PMDL MemoryDescriptorList, +IPortWaveRTStreamInit_fnGetPhysicalPageAddress( + IN IPortWaveRTStreamInit * iface, + IN PPHYSICAL_ADDRESS Address, + IN PMDL MemoryDescriptorList, IN ULONG Index) { PVOID Buffer; ULONG Pages; + PHYSICAL_ADDRESS Result, Addr;
Pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList)); if (Pages <= Index) @@ -214,21 +218,26 @@ }
Buffer = UlongToPtr(PtrToUlong(MmGetSystemAddressForMdl(MemoryDescriptorList)) + Index * PAGE_SIZE); - return MmGetPhysicalAddress(Buffer); -} - -static IPortWaveRTStreamVtbl vt_PortWaveRTStream = -{ - IPortWaveRTStream_fnQueryInterface, - IPortWaveRTStream_fnAddRef, - IPortWaveRTStream_fnRelease, - IPortWaveRTStream_fnAllocatePagesForMdl, - IPortWaveRTStream_fnAllocateContiguousPagesForMdl, - IPortWaveRTStream_fnMapAllocatedPages, - IPortWaveRTStream_fnUnmapAllocatedPages, - IPortWaveRTStream_fnFreePagesFromMdl, - IPortWaveRTStream_fnGetPhysicalPagesCount, - IPortWaveRTStream_fnGetPhysicalPageAddress + + Addr = MmGetPhysicalAddress(Buffer); + Address->QuadPart = Addr.QuadPart; + Result.QuadPart = (PtrToUlong(Address)); + + return Result; +} + +static IPortWaveRTStreamInitVtbl vt_PortWaveRTStream = +{ + IPortWaveRTStreamInit_fnQueryInterface, + IPortWaveRTStreamInit_fnAddRef, + IPortWaveRTStreamInit_fnRelease, + IPortWaveRTStreamInit_fnAllocatePagesForMdl, + IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl, + IPortWaveRTStreamInit_fnMapAllocatedPages, + IPortWaveRTStreamInit_fnUnmapAllocatedPages, + IPortWaveRTStreamInit_fnFreePagesFromMdl, + IPortWaveRTStreamInit_fnGetPhysicalPagesCount, + IPortWaveRTStreamInit_fnGetPhysicalPageAddress };
NTSTATUS
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/private.h [iso-8859-1] Sun Jun 21 03:37:55 2009 @@ -7,9 +7,11 @@ #ifndef PORTCLS_PRIVATE_H #define PORTCLS_PRIVATE_H
+//#define _KS_NO_ANONYMOUS_STRUCTURES_ + #include <ntddk.h> #include <portcls.h> -#define NDEBUG +#define YDEBUG #include <debug.h>
#include <dmusicks.h> @@ -182,24 +184,6 @@ NewIrpQueue( IN IIrpQueue **Queue);
- -typedef struct -{ - LIST_ENTRY Entry; - KSOBJECT_HEADER ObjectHeader; -}SUBDEVICE_ENTRY; - -typedef struct -{ - LIST_ENTRY Entry; - ISubdevice * FromSubDevice; - LPWSTR FromUnicodeString; - ULONG FromPin; - ISubdevice * ToSubDevice; - LPWSTR ToUnicodeString; - ULONG ToPin; -}PHYSICAL_CONNECTION; - NTSTATUS NTAPI TopologyPropertyHandler( @@ -213,37 +197,6 @@ IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); - -typedef struct -{ - KSDEVICE_HEADER KsDeviceHeader; - PDEVICE_OBJECT PhysicalDeviceObject; - PDEVICE_OBJECT PrevDeviceObject; - PCPFNSTARTDEVICE StartDevice; - ULONG_PTR Unused[4]; - IAdapterPowerManagement * AdapterPowerManagement; - ULONG MaxSubDevices; - KSOBJECT_CREATE_ITEM * CreateItems; - - IResourceList* resources; - LIST_ENTRY SubDeviceList; - LIST_ENTRY PhysicalConnectionList; - -} PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION; - - -typedef struct -{ - KSSTREAM_HEADER Header; - PIRP Irp; -}CONTEXT_WRITE, *PCONTEXT_WRITE; - -typedef struct -{ - PVOID Pin; - PIO_WORKITEM WorkItem; - PIRP Irp; -}CLOSESTREAM_CONTEXT, *PCLOSESTREAM_CONTEXT;
NTSTATUS NTAPI @@ -353,4 +306,52 @@ DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\ }
+typedef struct +{ + LIST_ENTRY Entry; + KSOBJECT_HEADER ObjectHeader; +}SUBDEVICE_ENTRY; + +typedef struct +{ + LIST_ENTRY Entry; + ISubdevice * FromSubDevice; + LPWSTR FromUnicodeString; + ULONG FromPin; + ISubdevice * ToSubDevice; + LPWSTR ToUnicodeString; + ULONG ToPin; +}PHYSICAL_CONNECTION; + +typedef struct +{ + KSDEVICE_HEADER KsDeviceHeader; + PDEVICE_OBJECT PhysicalDeviceObject; + PDEVICE_OBJECT PrevDeviceObject; + PCPFNSTARTDEVICE StartDevice; + ULONG_PTR Unused[4]; + IAdapterPowerManagement * AdapterPowerManagement; + ULONG MaxSubDevices; + KSOBJECT_CREATE_ITEM * CreateItems; + + IResourceList* resources; + LIST_ENTRY SubDeviceList; + LIST_ENTRY PhysicalConnectionList; + +} PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION; + + +typedef struct +{ + KSSTREAM_HEADER Header; + PIRP Irp; +}CONTEXT_WRITE, *PCONTEXT_WRITE; + +typedef struct +{ + PVOID Pin; + PIO_WORKITEM WorkItem; + PIRP Irp; +}CLOSESTREAM_CONTEXT, *PCLOSESTREAM_CONTEXT; + #endif
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/service_group.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/service_group.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/service_group.c [iso-8859-1] Sun Jun 21 03:37:55 2009 @@ -26,6 +26,8 @@ BOOL TimerActive; KTIMER Timer; KDPC Dpc; + KEVENT Event; + LONG ThreadActive; }IServiceGroupImpl;
@@ -94,6 +96,10 @@ FreeItem(Entry, TAG_PORTCLASS); } KeCancelTimer(&This->Timer); + if (This->ThreadActive) + { + KeSetEvent(&This->Event, 0, TRUE); + } FreeItem(This, TAG_PORTCLASS); return 0; } @@ -203,18 +209,60 @@ } }
+ +VOID +NTAPI +ServiceGroupThread(IN PVOID StartContext) +{ + NTSTATUS Status; + KWAIT_BLOCK WaitBlockArray[2]; + PVOID WaitObjects[2]; + IServiceGroupImpl * This = (IServiceGroupImpl*)StartContext; + + /* Set thread state */ + InterlockedIncrement(&This->ThreadActive); + + /* Setup the wait objects */ + WaitObjects[0] = &This->Timer; + WaitObjects[1] = &This->Event; + + do + { + /* Wait on our objects */ + Status = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, Executive, KernelMode, FALSE, NULL, WaitBlockArray); + + switch(Status) + { + case STATUS_WAIT_0: + IServiceGroupDpc(&This->Dpc, (PVOID)This, NULL, NULL); + break; + case STATUS_WAIT_1: + PsTerminateSystemThread(STATUS_SUCCESS); + break; + } + }while(TRUE); +} + VOID NTAPI IServiceGroup_fnSupportDelayedService( IN IServiceGroup * iface) { + NTSTATUS Status; + HANDLE ThreadHandle; IServiceGroupImpl * This = (IServiceGroupImpl*)iface;
ASSERT_IRQL(DISPATCH_LEVEL);
- if (!This->Initialized) - { - KeInitializeTimerEx(&This->Timer, NotificationTimer); + if (This->Initialized) + return; + + KeInitializeTimerEx(&This->Timer, NotificationTimer); + + Status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, NULL, 0, NULL, ServiceGroupThread, (PVOID)This); + if (NT_SUCCESS(Status)) + { + ZwClose(ThreadHandle); This->Initialized = TRUE; } } @@ -290,6 +338,7 @@ This->ref = 1; KeInitializeDpc(&This->Dpc, IServiceGroupDpc, (PVOID)This); KeSetImportanceDpc(&This->Dpc, HighImportance); + KeInitializeEvent(&This->Event, NotificationEvent, FALSE); InitializeListHead(&This->ServiceSinkHead); *OutServiceGroup = (PSERVICEGROUP)&This->lpVtbl;