diff --git a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h index 77d98c31616..1f6e69ab0ac 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/interfaces.h @@ -710,4 +710,62 @@ typedef IPortFilterTopology *PPORTFILTERTOPOLOGY; #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 diff --git a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c index e878ca47f3a..c6996c86bd8 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/pin_wavert.c @@ -59,6 +59,85 @@ SetStreamState( 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 @@ IServiceSink_fnRequestService( } 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); + DPRINT("PlayOffset %lu WriteOffset %lu Buffer %p BufferSize %u CommonBufferSize %u\n", Position.PlayOffset, Position.WriteOffset, Buffer, BufferSize, This->CommonBufferSize); - //FIXME - // implement writing into cyclic buffer - // - - /* reschedule the timer */ - This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay); + 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 @@ IPortPinWaveRT_fnInit( /* 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->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; + } - This->Stream->lpVtbl->SetFormat(This->Stream, (PKSDATAFORMAT)This->Format); + 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 @@ cleanup: This->ServiceGroup = NULL; } - if (This->PortStream) + if (This->Stream) { - This->PortStream->lpVtbl->Release(This->PortStream); - This->PortStream = NULL; + This->Stream->lpVtbl->Release(This->Stream); + This->Stream = NULL; } + else + { + if (This->PortStream) + { + This->PortStream->lpVtbl->Release(This->PortStream); + This->PortStream = NULL; + } + } return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port.c b/reactos/drivers/wdm/audio/backpln/portcls/port.c index 95f72e3d83a..2fdb7c8b529 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port.c @@ -40,10 +40,8 @@ PcNewPort( 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 { diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c index f041e275ec0..d4b958ce37f 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavepci.c @@ -22,7 +22,6 @@ typedef struct PMINIPORTWAVEPCI Miniport; PDEVICE_OBJECT pDeviceObject; - KDPC Dpc; BOOL bInitialized; PRESOURCELIST pResourceList; PSERVICEGROUP ServiceGroup; @@ -331,26 +330,6 @@ IPortWavePci_fnRelease( 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,16 +364,12 @@ IPortWavePci_fnInit( 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); /* increment reference on resource list */ diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c b/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c index f9ebafba17d..45ee9a7e60b 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_wavertstream.c @@ -10,7 +10,7 @@ typedef struct { - IPortWaveRTStreamVtbl *lpVtbl; + IPortWaveRTStreamInitVtbl *lpVtbl; LONG ref; }IPortWaveRTStreamImpl; @@ -21,8 +21,8 @@ typedef struct static NTSTATUS NTAPI -IPortWaveRTStream_fnQueryInterface( - IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnQueryInterface( + IPortWaveRTStreamInit * iface, IN REFIID refiid, OUT PVOID* Output) { @@ -46,8 +46,8 @@ IPortWaveRTStream_fnQueryInterface( static ULONG NTAPI -IPortWaveRTStream_fnAddRef( - IPortWaveRTStream* iface) +IPortWaveRTStreamInit_fnAddRef( + IPortWaveRTStreamInit * iface) { IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface; DPRINT("IPortWaveRTStream_fnAddRef entered\n"); @@ -61,8 +61,8 @@ IPortWaveRTStream_fnAddRef( static ULONG NTAPI -IPortWaveRTStream_fnRelease( - IPortWaveRTStream* iface) +IPortWaveRTStreamInit_fnRelease( + IPortWaveRTStreamInit * iface) { IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface; @@ -85,8 +85,8 @@ IPortWaveRTStream_fnRelease( 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 @@ IPortWaveRTStream_fnAllocatePagesForMdl( 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 @@ IPortWaveRTStream_fnAllocateContiguousPagesForMdl( 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 @@ IPortWaveRTStream_fnAllocateContiguousPagesForMdl( 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 @@ IPortWaveRTStream_fnMapAllocatedPages( static VOID NTAPI -IPortWaveRTStream_fnUnmapAllocatedPages( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnUnmapAllocatedPages( + IN IPortWaveRTStreamInit * iface, IN PVOID BaseAddress, IN PMDL MemoryDescriptorList) { @@ -171,8 +173,8 @@ IPortWaveRTStream_fnUnmapAllocatedPages( static VOID NTAPI -IPortWaveRTStream_fnFreePagesFromMdl( - IN IPortWaveRTStream* iface, +IPortWaveRTStreamInit_fnFreePagesFromMdl( + IN IPortWaveRTStreamInit * iface, IN PMDL MemoryDescriptorList) { MmFreePagesFromMdl(MemoryDescriptorList); @@ -185,8 +187,8 @@ IPortWaveRTStream_fnFreePagesFromMdl( 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 @@ IPortWaveRTStream_fnGetPhysicalPagesCount( 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 @@ IPortWaveRTStream_fnGetPhysicalPageAddress( } Buffer = UlongToPtr(PtrToUlong(MmGetSystemAddressForMdl(MemoryDescriptorList)) + Index * PAGE_SIZE); - return MmGetPhysicalAddress(Buffer); + + Addr = MmGetPhysicalAddress(Buffer); + Address->QuadPart = Addr.QuadPart; + Result.QuadPart = (PtrToUlong(Address)); + + return Result; } -static IPortWaveRTStreamVtbl vt_PortWaveRTStream = +static IPortWaveRTStreamInitVtbl vt_PortWaveRTStream = { - IPortWaveRTStream_fnQueryInterface, - IPortWaveRTStream_fnAddRef, - IPortWaveRTStream_fnRelease, - IPortWaveRTStream_fnAllocatePagesForMdl, - IPortWaveRTStream_fnAllocateContiguousPagesForMdl, - IPortWaveRTStream_fnMapAllocatedPages, - IPortWaveRTStream_fnUnmapAllocatedPages, - IPortWaveRTStream_fnFreePagesFromMdl, - IPortWaveRTStream_fnGetPhysicalPagesCount, - IPortWaveRTStream_fnGetPhysicalPageAddress + IPortWaveRTStreamInit_fnQueryInterface, + IPortWaveRTStreamInit_fnAddRef, + IPortWaveRTStreamInit_fnRelease, + IPortWaveRTStreamInit_fnAllocatePagesForMdl, + IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl, + IPortWaveRTStreamInit_fnMapAllocatedPages, + IPortWaveRTStreamInit_fnUnmapAllocatedPages, + IPortWaveRTStreamInit_fnFreePagesFromMdl, + IPortWaveRTStreamInit_fnGetPhysicalPagesCount, + IPortWaveRTStreamInit_fnGetPhysicalPageAddress }; NTSTATUS diff --git a/reactos/drivers/wdm/audio/backpln/portcls/private.h b/reactos/drivers/wdm/audio/backpln/portcls/private.h index a0dd108b646..48c1ff154a9 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/private.h +++ b/reactos/drivers/wdm/audio/backpln/portcls/private.h @@ -7,9 +7,11 @@ #ifndef PORTCLS_PRIVATE_H #define PORTCLS_PRIVATE_H +//#define _KS_NO_ANONYMOUS_STRUCTURES_ + #include #include -#define NDEBUG +#define YDEBUG #include #include @@ -182,24 +184,6 @@ NTAPI 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( @@ -214,37 +198,6 @@ PinPropertyHandler( 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 PcDmaMasterDescription( @@ -353,4 +306,52 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\ 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 diff --git a/reactos/drivers/wdm/audio/backpln/portcls/service_group.c b/reactos/drivers/wdm/audio/backpln/portcls/service_group.c index e0f7151d8f0..0003f734937 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/service_group.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/service_group.c @@ -26,6 +26,8 @@ typedef struct BOOL TimerActive; KTIMER Timer; KDPC Dpc; + KEVENT Event; + LONG ThreadActive; }IServiceGroupImpl; @@ -94,6 +96,10 @@ IServiceGroup_fnRelease( 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 @@ IServiceGroupDpc( } } + +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) + if (This->Initialized) + return; + + KeInitializeTimerEx(&This->Timer, NotificationTimer); + + Status = PsCreateSystemThread(&ThreadHandle, THREAD_ALL_ACCESS, NULL, 0, NULL, ServiceGroupThread, (PVOID)This); + if (NT_SUCCESS(Status)) { - KeInitializeTimerEx(&This->Timer, NotificationTimer); + ZwClose(ThreadHandle); This->Initialized = TRUE; } } @@ -290,6 +338,7 @@ PcNewServiceGroup( 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;