- 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

svn path=/trunk/; revision=41497
This commit is contained in:
Johannes Anderwald 2009-06-20 23:37:55 +00:00
parent 9c621c0524
commit eef3e1deca
7 changed files with 316 additions and 130 deletions

View file

@ -710,4 +710,62 @@ typedef IPortFilterTopology *PPORTFILTERTOPOLOGY;
#undef INTERFACE #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 #endif

View file

@ -59,6 +59,85 @@ SetStreamState(
IN IPortPinWaveRTImpl * This, IN IPortPinWaveRTImpl * This,
IN KSSTATE State); 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 static
NTSTATUS NTSTATUS
@ -137,14 +216,16 @@ IServiceSink_fnRequestService(
} }
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position); 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 if (Position.PlayOffset < This->CommonBufferOffset)
// implement writing into cyclic buffer {
// UpdateCommonBufferOverlap(This, Position.PlayOffset);
}
/* reschedule the timer */ else if (Position.PlayOffset >= This->CommonBufferOffset)
This->ServiceGroup->lpVtbl->RequestDelayedService(This->ServiceGroup, This->Delay); {
UpdateCommonBuffer(This, Position.PlayOffset);
}
} }
static IServiceSinkVtbl vt_IServiceSink = static IServiceSinkVtbl vt_IServiceSink =
@ -962,18 +1043,25 @@ IPortPinWaveRT_fnInit(
/* minimum delay of 10 milisec */ /* minimum delay of 10 milisec */
This->Delay = Int32x32To64(min(max(Latency.ChipsetDelay + Latency.CodecDelay + Latency.FifoSize, 10), 10), -10000); 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)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("AllocateAudioBuffer failed with %x\n", Status); DPRINT1("AllocateAudioBuffer failed with %x\n", Status);
goto cleanup; goto cleanup;
} }
This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); This->CommonBuffer = MmGetSystemAddressForMdlSafe(This->Mdl, NormalPagePriority);
This->State = KSSTATE_STOP; if (!NT_SUCCESS(Status))
This->Capture = Capture; {
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; return STATUS_SUCCESS;
cleanup: cleanup:
@ -995,12 +1083,20 @@ cleanup:
This->ServiceGroup = NULL; This->ServiceGroup = NULL;
} }
if (This->Stream)
{
This->Stream->lpVtbl->Release(This->Stream);
This->Stream = NULL;
}
else
{
if (This->PortStream) if (This->PortStream)
{ {
This->PortStream->lpVtbl->Release(This->PortStream); This->PortStream->lpVtbl->Release(This->PortStream);
This->PortStream = NULL; This->PortStream = NULL;
} }
}
return Status; return Status;
} }

View file

@ -40,10 +40,8 @@ PcNewPort(
Status = NewPortWaveCyclic(OutPort); Status = NewPortWaveCyclic(OutPort);
else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWavePci)) else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWavePci))
Status = NewPortWavePci(OutPort); Status = NewPortWavePci(OutPort);
#if (NTDDI_VERSION >= NTDDI_VISTA) else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWaveRT))
else if (IsEqualGUIDAligned(ClassId, &CLSID_PortWavePci))
Status = NewPortWaveRT(OutPort); Status = NewPortWaveRT(OutPort);
#endif
else else
{ {

View file

@ -22,7 +22,6 @@ typedef struct
PMINIPORTWAVEPCI Miniport; PMINIPORTWAVEPCI Miniport;
PDEVICE_OBJECT pDeviceObject; PDEVICE_OBJECT pDeviceObject;
KDPC Dpc;
BOOL bInitialized; BOOL bInitialized;
PRESOURCELIST pResourceList; PRESOURCELIST pResourceList;
PSERVICEGROUP ServiceGroup; PSERVICEGROUP ServiceGroup;
@ -331,26 +330,6 @@ IPortWavePci_fnRelease(
return This->ref; 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 NTSTATUS
NTAPI NTAPI
IPortWavePci_fnInit( IPortWavePci_fnInit(
@ -385,16 +364,12 @@ IPortWavePci_fnInit(
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }
/* initialize the dpc */
KeInitializeDpc(&This->Dpc, ServiceNotifyRoutine, (PVOID)This);
/* Initialize port object */ /* Initialize port object */
This->Miniport = Miniport; This->Miniport = Miniport;
This->pDeviceObject = DeviceObject; This->pDeviceObject = DeviceObject;
This->bInitialized = TRUE; This->bInitialized = TRUE;
This->pResourceList = ResourceList; This->pResourceList = ResourceList;
/* increment reference on miniport adapter */ /* increment reference on miniport adapter */
Miniport->lpVtbl->AddRef(Miniport); Miniport->lpVtbl->AddRef(Miniport);
/* increment reference on resource list */ /* increment reference on resource list */

View file

@ -10,7 +10,7 @@
typedef struct typedef struct
{ {
IPortWaveRTStreamVtbl *lpVtbl; IPortWaveRTStreamInitVtbl *lpVtbl;
LONG ref; LONG ref;
}IPortWaveRTStreamImpl; }IPortWaveRTStreamImpl;
@ -21,8 +21,8 @@ typedef struct
static static
NTSTATUS NTSTATUS
NTAPI NTAPI
IPortWaveRTStream_fnQueryInterface( IPortWaveRTStreamInit_fnQueryInterface(
IPortWaveRTStream* iface, IPortWaveRTStreamInit * iface,
IN REFIID refiid, IN REFIID refiid,
OUT PVOID* Output) OUT PVOID* Output)
{ {
@ -46,8 +46,8 @@ IPortWaveRTStream_fnQueryInterface(
static static
ULONG ULONG
NTAPI NTAPI
IPortWaveRTStream_fnAddRef( IPortWaveRTStreamInit_fnAddRef(
IPortWaveRTStream* iface) IPortWaveRTStreamInit * iface)
{ {
IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface; IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
DPRINT("IPortWaveRTStream_fnAddRef entered\n"); DPRINT("IPortWaveRTStream_fnAddRef entered\n");
@ -61,8 +61,8 @@ IPortWaveRTStream_fnAddRef(
static static
ULONG ULONG
NTAPI NTAPI
IPortWaveRTStream_fnRelease( IPortWaveRTStreamInit_fnRelease(
IPortWaveRTStream* iface) IPortWaveRTStreamInit * iface)
{ {
IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface; IPortWaveRTStreamImpl * This = (IPortWaveRTStreamImpl*)iface;
@ -85,8 +85,8 @@ IPortWaveRTStream_fnRelease(
static static
PMDL PMDL
NTAPI NTAPI
IPortWaveRTStream_fnAllocatePagesForMdl( IPortWaveRTStreamInit_fnAllocatePagesForMdl(
IN IPortWaveRTStream* iface, IN IPortWaveRTStreamInit * iface,
IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS HighAddress,
IN SIZE_T TotalBytes) IN SIZE_T TotalBytes)
{ {
@ -99,8 +99,8 @@ IPortWaveRTStream_fnAllocatePagesForMdl(
static static
PMDL PMDL
NTAPI NTAPI
IPortWaveRTStream_fnAllocateContiguousPagesForMdl( IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl(
IN IPortWaveRTStream* iface, IN IPortWaveRTStreamInit * iface,
IN PHYSICAL_ADDRESS LowAddress, IN PHYSICAL_ADDRESS LowAddress,
IN PHYSICAL_ADDRESS HighAddress, IN PHYSICAL_ADDRESS HighAddress,
IN SIZE_T TotalBytes) IN SIZE_T TotalBytes)
@ -129,12 +129,14 @@ IPortWaveRTStream_fnAllocateContiguousPagesForMdl(
if (MmGetMdlByteCount(Mdl) < TotalBytes) if (MmGetMdlByteCount(Mdl) < TotalBytes)
{ {
DPRINT1("ByteCount %u Required %u\n", MmGetMdlByteCount(Mdl), TotalBytes);
MmFreePagesFromMdl(Mdl); MmFreePagesFromMdl(Mdl);
ExFreePool(Mdl); ExFreePool(Mdl);
return NULL; return NULL;
} }
return NULL; DPRINT("Result %p\n", Mdl);
return Mdl;
} }
/* /*
@ -143,8 +145,8 @@ IPortWaveRTStream_fnAllocateContiguousPagesForMdl(
static static
PVOID PVOID
NTAPI NTAPI
IPortWaveRTStream_fnMapAllocatedPages( IPortWaveRTStreamInit_fnMapAllocatedPages(
IN IPortWaveRTStream* iface, IN IPortWaveRTStreamInit * iface,
IN PMDL MemoryDescriptorList, IN PMDL MemoryDescriptorList,
IN MEMORY_CACHING_TYPE CacheType) IN MEMORY_CACHING_TYPE CacheType)
{ {
@ -157,8 +159,8 @@ IPortWaveRTStream_fnMapAllocatedPages(
static static
VOID VOID
NTAPI NTAPI
IPortWaveRTStream_fnUnmapAllocatedPages( IPortWaveRTStreamInit_fnUnmapAllocatedPages(
IN IPortWaveRTStream* iface, IN IPortWaveRTStreamInit * iface,
IN PVOID BaseAddress, IN PVOID BaseAddress,
IN PMDL MemoryDescriptorList) IN PMDL MemoryDescriptorList)
{ {
@ -171,8 +173,8 @@ IPortWaveRTStream_fnUnmapAllocatedPages(
static static
VOID VOID
NTAPI NTAPI
IPortWaveRTStream_fnFreePagesFromMdl( IPortWaveRTStreamInit_fnFreePagesFromMdl(
IN IPortWaveRTStream* iface, IN IPortWaveRTStreamInit * iface,
IN PMDL MemoryDescriptorList) IN PMDL MemoryDescriptorList)
{ {
MmFreePagesFromMdl(MemoryDescriptorList); MmFreePagesFromMdl(MemoryDescriptorList);
@ -185,8 +187,8 @@ IPortWaveRTStream_fnFreePagesFromMdl(
static static
ULONG ULONG
NTAPI NTAPI
IPortWaveRTStream_fnGetPhysicalPagesCount( IPortWaveRTStreamInit_fnGetPhysicalPagesCount(
IN IPortWaveRTStream* iface, IN IPortWaveRTStreamInit * iface,
IN PMDL MemoryDescriptorList) IN PMDL MemoryDescriptorList)
{ {
return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList)); return ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
@ -198,13 +200,15 @@ IPortWaveRTStream_fnGetPhysicalPagesCount(
static static
PHYSICAL_ADDRESS PHYSICAL_ADDRESS
NTAPI NTAPI
IPortWaveRTStream_fnGetPhysicalPageAddress( IPortWaveRTStreamInit_fnGetPhysicalPageAddress(
IN IPortWaveRTStream* iface, IN IPortWaveRTStreamInit * iface,
IN PPHYSICAL_ADDRESS Address,
IN PMDL MemoryDescriptorList, IN PMDL MemoryDescriptorList,
IN ULONG Index) IN ULONG Index)
{ {
PVOID Buffer; PVOID Buffer;
ULONG Pages; ULONG Pages;
PHYSICAL_ADDRESS Result, Addr;
Pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList)); Pages = ADDRESS_AND_SIZE_TO_SPAN_PAGES(0, MmGetMdlByteCount(MemoryDescriptorList));
if (Pages <= Index) if (Pages <= Index)
@ -214,21 +218,26 @@ IPortWaveRTStream_fnGetPhysicalPageAddress(
} }
Buffer = UlongToPtr(PtrToUlong(MmGetSystemAddressForMdl(MemoryDescriptorList)) + Index * PAGE_SIZE); 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, IPortWaveRTStreamInit_fnQueryInterface,
IPortWaveRTStream_fnAddRef, IPortWaveRTStreamInit_fnAddRef,
IPortWaveRTStream_fnRelease, IPortWaveRTStreamInit_fnRelease,
IPortWaveRTStream_fnAllocatePagesForMdl, IPortWaveRTStreamInit_fnAllocatePagesForMdl,
IPortWaveRTStream_fnAllocateContiguousPagesForMdl, IPortWaveRTStreamInit_fnAllocateContiguousPagesForMdl,
IPortWaveRTStream_fnMapAllocatedPages, IPortWaveRTStreamInit_fnMapAllocatedPages,
IPortWaveRTStream_fnUnmapAllocatedPages, IPortWaveRTStreamInit_fnUnmapAllocatedPages,
IPortWaveRTStream_fnFreePagesFromMdl, IPortWaveRTStreamInit_fnFreePagesFromMdl,
IPortWaveRTStream_fnGetPhysicalPagesCount, IPortWaveRTStreamInit_fnGetPhysicalPagesCount,
IPortWaveRTStream_fnGetPhysicalPageAddress IPortWaveRTStreamInit_fnGetPhysicalPageAddress
}; };
NTSTATUS NTSTATUS

View file

@ -7,9 +7,11 @@
#ifndef PORTCLS_PRIVATE_H #ifndef PORTCLS_PRIVATE_H
#define PORTCLS_PRIVATE_H #define PORTCLS_PRIVATE_H
//#define _KS_NO_ANONYMOUS_STRUCTURES_
#include <ntddk.h> #include <ntddk.h>
#include <portcls.h> #include <portcls.h>
#define NDEBUG #define YDEBUG
#include <debug.h> #include <debug.h>
#include <dmusicks.h> #include <dmusicks.h>
@ -182,24 +184,6 @@ NTAPI
NewIrpQueue( NewIrpQueue(
IN IIrpQueue **Queue); 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 NTSTATUS
NTAPI NTAPI
TopologyPropertyHandler( TopologyPropertyHandler(
@ -214,37 +198,6 @@ PinPropertyHandler(
IN PKSIDENTIFIER Request, IN PKSIDENTIFIER Request,
IN OUT PVOID Data); 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 NTSTATUS
NTAPI NTAPI
PcDmaMasterDescription( PcDmaMasterDescription(
@ -353,4 +306,52 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
DEFINE_KSPROPERTY_ITEM_PIN_PROPOSEDATAFORMAT(PropGeneral)\ 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 #endif

View file

@ -26,6 +26,8 @@ typedef struct
BOOL TimerActive; BOOL TimerActive;
KTIMER Timer; KTIMER Timer;
KDPC Dpc; KDPC Dpc;
KEVENT Event;
LONG ThreadActive;
}IServiceGroupImpl; }IServiceGroupImpl;
@ -94,6 +96,10 @@ IServiceGroup_fnRelease(
FreeItem(Entry, TAG_PORTCLASS); FreeItem(Entry, TAG_PORTCLASS);
} }
KeCancelTimer(&This->Timer); KeCancelTimer(&This->Timer);
if (This->ThreadActive)
{
KeSetEvent(&This->Event, 0, TRUE);
}
FreeItem(This, TAG_PORTCLASS); FreeItem(This, TAG_PORTCLASS);
return 0; 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 VOID
NTAPI NTAPI
IServiceGroup_fnSupportDelayedService( IServiceGroup_fnSupportDelayedService(
IN IServiceGroup * iface) IN IServiceGroup * iface)
{ {
NTSTATUS Status;
HANDLE ThreadHandle;
IServiceGroupImpl * This = (IServiceGroupImpl*)iface; IServiceGroupImpl * This = (IServiceGroupImpl*)iface;
ASSERT_IRQL(DISPATCH_LEVEL); ASSERT_IRQL(DISPATCH_LEVEL);
if (!This->Initialized) if (This->Initialized)
{ return;
KeInitializeTimerEx(&This->Timer, NotificationTimer); 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; This->Initialized = TRUE;
} }
} }
@ -290,6 +338,7 @@ PcNewServiceGroup(
This->ref = 1; This->ref = 1;
KeInitializeDpc(&This->Dpc, IServiceGroupDpc, (PVOID)This); KeInitializeDpc(&This->Dpc, IServiceGroupDpc, (PVOID)This);
KeSetImportanceDpc(&This->Dpc, HighImportance); KeSetImportanceDpc(&This->Dpc, HighImportance);
KeInitializeEvent(&This->Event, NotificationEvent, FALSE);
InitializeListHead(&This->ServiceSinkHead); InitializeListHead(&This->ServiceSinkHead);
*OutServiceGroup = (PSERVICEGROUP)&This->lpVtbl; *OutServiceGroup = (PSERVICEGROUP)&This->lpVtbl;