mirror of
https://github.com/reactos/reactos.git
synced 2025-07-30 10:02:02 +00:00
- 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:
parent
9c621c0524
commit
eef3e1deca
7 changed files with 316 additions and 130 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 @@ 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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue