- Remove a hack for sysaudio + kmixer
[PORTCLS]
- Disable assert untill stream allocator is in place
- Remove dead code
- Implement IPortPinWaveCyclic_HandleKsStream
[KMIXER]
- Remove unused code
- Implement creating the allocator
- Properly implement openening the device
[STREAM]
- Use GLOBAL as the reference string
- Setup a pin create item
[SYSAUDIO]
- Use reference string GLOBAL to open kmixer
- Use reference string GLOBAL for opening sysaudio. Will be removed once bug 4566 is resolved

svn path=/trunk/; revision=42457
This commit is contained in:
Johannes Anderwald 2009-08-07 09:34:52 +00:00
parent 74733cd9aa
commit 2abccb66e9
11 changed files with 189 additions and 214 deletions

View file

@ -1403,41 +1403,6 @@ KspCreate(
/* get device header */
DeviceHeader = DeviceExtension->DeviceHeader;
if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->ItemListCount == 1)
{
/* hack for bug 4566 */
ASSERT(!IsListEmpty(&DeviceHeader->ItemList));
/* get create item entry */
CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(DeviceHeader->ItemList.Flink, CREATE_ITEM_ENTRY, Entry);
ASSERT(CreateItemEntry->CreateItem);
if (!CreateItemEntry->CreateItem->Create)
{
/* no valid create item */
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* return status */
return STATUS_UNSUCCESSFUL;
}
/* set object create item */
KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
/* call create function */
Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
if (NT_SUCCESS(Status))
{
/* increment create item reference count */
InterlockedIncrement(&CreateItemEntry->ReferenceCount);
}
/* return result */
return Status;
}
/* hack for bug 4566 */
if (IoStack->FileObject->FileName.Buffer == NULL)
{
@ -1449,7 +1414,6 @@ KspCreate(
return STATUS_SUCCESS;
}
if (IoStack->FileObject->RelatedFileObject != NULL)
{
/* request is to instantiate a pin / node / clock / allocator */

View file

@ -124,5 +124,14 @@ KspCreatePin(
IN PKSPIN_CONNECT Connect,
IN KSPIN_DESCRIPTOR_EX* Descriptor);
NTSTATUS
KspAddCreateItemToList(
OUT PLIST_ENTRY ListHead,
IN ULONG ItemsCount,
IN PKSOBJECT_CREATE_ITEM ItemsList);
VOID
KspFreeCreateItems(
IN PLIST_ENTRY ListHead);
#endif

View file

@ -118,20 +118,30 @@ IIrpQueue_fnAddMapping(
IN PIRP Irp)
{
PKSSTREAM_HEADER Header;
//PIO_STACK_LOCATION IoStack;
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
/* FIXME
* irp should contain the stream header...
*/
#if 0
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSSTREAM_HEADER));
/* get stream header */
Header = (KSSTREAM_HEADER*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
#else
/* HACK get stream header */
Header = (KSSTREAM_HEADER*)Buffer;
/* dont exceed max frame size */
ASSERT(This->MaxFrameSize >= Header->DataUsed);
/* hack untill stream probing is ready */
/* HACK untill stream probing is ready */
Irp->Tail.Overlay.DriverContext[2] = (PVOID)Header;
#endif
/* sanity check */
ASSERT(Header);
/* dont exceed max frame size */
//ASSERT(This->MaxFrameSize >= Header->DataUsed);
/* increment num mappings */
InterlockedIncrement(&This->NumMappings);
@ -158,6 +168,7 @@ IIrpQueue_fnGetMapping(
{
PIRP Irp;
ULONG Offset;
//PIO_STACK_LOCATION IoStack;
PKSSTREAM_HEADER StreamHeader;
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
@ -197,8 +208,16 @@ IIrpQueue_fnGetMapping(
return STATUS_SUCCESS;
}
#if 0
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get stream header */
StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
#else
/* HACK get stream header */
StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2];
#endif
/* sanity check */
ASSERT(StreamHeader);
@ -221,6 +240,7 @@ IIrpQueue_fnUpdateMapping(
IN IIrpQueue *iface,
IN ULONG BytesWritten)
{
//PIO_STACK_LOCATION IoStack;
PKSSTREAM_HEADER StreamHeader;
IIrpQueueImpl * This = (IIrpQueueImpl*)iface;
@ -230,8 +250,19 @@ IIrpQueue_fnUpdateMapping(
return;
}
#if 0
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(This->Irp);
/* get stream header */
StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
#else
/* HACK get stream header */
StreamHeader = (PKSSTREAM_HEADER)This->Irp->Tail.Overlay.DriverContext[2];
#endif
/* sanity check */
ASSERT(StreamHeader);
/* add to current offset */
This->CurrentOffset += BytesWritten;

View file

@ -35,8 +35,6 @@ typedef struct
BOOL Capture;
ULONG TotalPackets;
ULONG PreCompleted;
ULONG PostCompleted;
ULONG StopCount;
ULONG Delay;
@ -267,11 +265,11 @@ SetStreamWorkerRoutine(
/* store minimum data threshold */
This->IrpQueue->lpVtbl->SetMinimumDataThreshold(This->IrpQueue, MinimumDataThreshold);
DPRINT1("Stopping PreCompleted %u PostCompleted %u StopCount %u MinimumDataThreshold %u\n", This->PreCompleted, This->PostCompleted, This->StopCount, MinimumDataThreshold);
DPRINT1("Stopping TotalPackets %u StopCount %u\n", This->TotalPackets, This->StopCount);
}
if (This->State == KSSTATE_RUN)
{
DPRINT1("State RUN %x MinAvailable %u\n", State, This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue));
DPRINT1("State RUN %x MinAvailable %u CommonBufferSize %u Offset %u\n", State, This->IrpQueue->lpVtbl->MinimumDataAvailable(This->IrpQueue), This->CommonBufferSize, This->CommonBufferOffset);
}
}
}
@ -339,7 +337,7 @@ IServiceSink_fnRequestService(
Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize);
if (!NT_SUCCESS(Status))
{
SetStreamState(This, KSSTATE_STOP);
//SetStreamState(This, KSSTATE_STOP);
return;
}
@ -633,11 +631,24 @@ IPortPinWaveCyclic_HandleKsStream(
IN IPortPinWaveCyclic * iface,
IN PIRP Irp)
{
NTSTATUS Status;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
DPRINT("IPortPinWaveCyclic_HandleKsStream entered State %u Stream %p\n", This->State, This->Stream);
InterlockedIncrement((PLONG)&This->TotalPackets);
return STATUS_PENDING;
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u Pre %u Post %u State %x MinData %u\n", This->TotalPackets, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue));
Status = This->IrpQueue->lpVtbl->AddMapping(This->IrpQueue, NULL, 0, Irp);
/* check if pin is in run state */
if (This->State != KSSTATE_RUN)
{
/* HACK set pin into run state if caller forgot it */
SetStreamState(This, KSSTATE_RUN);
DPRINT1("Starting stream with %lu mappings Status %x\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), Status);
}
return Status;
}
/*
@ -900,7 +911,6 @@ IPortPinWaveCyclic_fnFastDeviceIoControl(
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
//UNIMPLEMENTED
return FALSE;
}
@ -925,6 +935,8 @@ IPortPinWaveCyclic_fnFastRead(
PIRP Irp;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
/* HACK to be removed */
DPRINT("IPortPinWaveCyclic_fnFastRead entered\n");
Packet = (PCONTEXT_WRITE)Buffer;
@ -967,16 +979,13 @@ IPortPinWaveCyclic_fnFastWrite(
NTSTATUS Status;
PCONTEXT_WRITE Packet;
PIRP Irp;
ULONG PrePostRatio;
ULONG MinData;
IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)iface;
/* HACK to be removed */
InterlockedIncrement((PLONG)&This->TotalPackets);
PrePostRatio = (This->PreCompleted * 100) / This->TotalPackets;
MinData = This->IrpQueue->lpVtbl->NumData(This->IrpQueue);
DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u State %x MinData %u Ratio %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue), PrePostRatio);
DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u State %x MinData %u\n", This->TotalPackets, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue));
Packet = (PCONTEXT_WRITE)Buffer;
Irp = Packet->Irp;
@ -999,7 +1008,7 @@ IPortPinWaveCyclic_fnFastWrite(
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI

View file

@ -26,47 +26,6 @@ Dispatch_fnDeviceIoControl(
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
NTAPI
Dispatch_fnRead(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
NTAPI
Dispatch_fnWrite(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
NTAPI
Dispatch_fnFlush(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
Dispatch_fnClose(
@ -81,102 +40,18 @@ Dispatch_fnClose(
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
Dispatch_fnQuerySecurity(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
NTAPI
Dispatch_fnSetSecurity(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
}
BOOLEAN
NTAPI
Dispatch_fnFastDeviceIoControl(
PFILE_OBJECT FileObject,
BOOLEAN Wait,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
ULONG IoControlCode,
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return FALSE;
}
BOOLEAN
NTAPI
Dispatch_fnFastRead(
PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
ULONG Length,
BOOLEAN Wait,
ULONG LockKey,
PVOID Buffer,
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return FALSE;
}
BOOLEAN
NTAPI
Dispatch_fnFastWrite(
PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
ULONG Length,
BOOLEAN Wait,
ULONG LockKey,
PVOID Buffer,
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
return FALSE;
}
static KSDISPATCH_TABLE DispatchTable =
{
Dispatch_fnDeviceIoControl,
Dispatch_fnRead,
Dispatch_fnWrite,
Dispatch_fnFlush,
KsDispatchInvalidDeviceRequest,
KsDispatchInvalidDeviceRequest,
KsDispatchInvalidDeviceRequest,
Dispatch_fnClose,
Dispatch_fnQuerySecurity,
Dispatch_fnSetSecurity,
Dispatch_fnFastDeviceIoControl,
Dispatch_fnFastRead,
Dispatch_fnFastWrite,
KsDispatchInvalidDeviceRequest,
KsDispatchInvalidDeviceRequest,
KsDispatchFastIoDeviceControlFailure,
KsDispatchFastWriteFailure,
KsDispatchFastWriteFailure,
};
NTSTATUS
@ -192,9 +67,30 @@ DispatchCreateKMixPin(
/* create the pin */
Status = CreatePin(Irp);
Irp->IoStatus.Information = 0;
/* save result */
Irp->IoStatus.Status = Status;
/* complete the request */
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* done */
return Status;
}
NTSTATUS
NTAPI
DispatchCreateKMixAllocator(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
/* create the allocator */
Status = KsCreateDefaultAllocator(Irp);
/* save result */
Irp->IoStatus.Status = Status;
/* complete the request */
IoCompleteRequest(Irp, IO_NO_INCREMENT);
/* done */
return Status;
}
@ -207,15 +103,42 @@ DispatchCreateKMix(
NTSTATUS Status;
KSOBJECT_HEADER ObjectHeader;
PKSOBJECT_CREATE_ITEM CreateItem;
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
PKMIXER_DEVICE_EXT DeviceExtension;
DPRINT("DispatchCreateKMix entered\n");
/* check if the request was from usermode */
if (Irp->RequestorMode == UserMode)
{
/* deny access from usermode */
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
/* get device extension */
DeviceExtension = (PKMIXER_DEVICE_EXT)DeviceObject->DeviceExtension;
#if 0
/* reference the software bus object */
Status = KsReferenceSoftwareBusObject(DeviceExtension->KsDeviceHeader);
if (!NT_SUCCESS(Status))
{
/* failed to reference bus object */
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
#endif
/* allocate create item */
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2);
if (!CreateItem)
{
/* not enough memory */
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
@ -223,15 +146,23 @@ DispatchCreateKMix(
}
/* zero create struct */
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM) * 2);
/* initialize pin create item */
CreateItem->Create = DispatchCreateKMixPin;
RtlInitUnicodeString(&CreateItem->ObjectClass, KS_NAME_PIN);
CreateItem[0].Create = DispatchCreateKMixPin;
RtlInitUnicodeString(&CreateItem[0].ObjectClass, KSSTRING_Pin);
CreateItem[1].Create = DispatchCreateKMixAllocator;
RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Allocator);
/* allocate object header */
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
Status = KsAllocateObjectHeader(&ObjectHeader, 2, CreateItem, Irp, &DispatchTable);
if (!NT_SUCCESS(Status))
{
/* failed to allocate object header */
ExFreePool(CreateItem);
KsDereferenceSoftwareBusObject(DeviceExtension->KsDeviceHeader);
}
DPRINT("KsAllocateObjectHeader result %x\n", Status);
/* complete the irp */
@ -250,18 +181,19 @@ KMixAllocateDeviceHeader(
PKSOBJECT_CREATE_ITEM CreateItem;
/* allocate create item */
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM) * 2);
if (!CreateItem)
return STATUS_INSUFFICIENT_RESOURCES;
/* initialize create item struct */
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
CreateItem->Create = DispatchCreateKMix;
CreateItem->Flags = KSCREATE_ITEM_WILDCARD;
RtlInitUnicodeString(&CreateItem->ObjectClass, L"KMixer");
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM) * 2);
CreateItem[0].Create = DispatchCreateKMix;
RtlInitUnicodeString(&CreateItem[0].ObjectClass, L"GLOBAL");
CreateItem[1].Create = DispatchCreateKMix;
RtlInitUnicodeString(&CreateItem[1].ObjectClass, KSSTRING_Filter);
Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
1,
2,
CreateItem);
return Status;
}

View file

@ -5,6 +5,7 @@
#include <portcls.h>
#include <ks.h>
#include <ksmedia.h>
#include <swenum.h>
#define YDEBUG
#include <debug.h>

View file

@ -56,7 +56,7 @@ StreamClassAddDevice(
/* Zero Create item */
RtlZeroMemory(ItemList, sizeof(KSOBJECT_CREATE_ITEM));
/* Setup object class */
RtlInitUnicodeString(&ItemList->ObjectClass, L"STREAMCLASS");
RtlInitUnicodeString(&ItemList->ObjectClass, L"GLOBAL");
/* Setup CreateDispatch routine */
ItemList->Create = StreamClassCreateFilter;

View file

@ -9,6 +9,22 @@
#include "stream.h"
NTSTATUS
NTAPI
StreamClassCreatePin(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
UNIMPLEMENTED
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_NOT_IMPLEMENTED;
}
NTSTATUS
NTAPI
FilterDispatch_fnDeviceIoControl(
@ -203,10 +219,13 @@ InitializeFilterWithKs(
/* not enough memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Zero create item */
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
/* Set item class */
RtlInitUnicodeString(&CreateItem->ObjectClass, L"STREAMCLASS");
/* Initialize createitem */
RtlInitUnicodeString(&CreateItem->ObjectClass, KSSTRING_Pin);
CreateItem->Create = StreamClassCreatePin;
/* Get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* Create Ks streaming object header */
@ -246,7 +265,6 @@ StreamClassCreateFilter(
NTSTATUS Status;
DPRINT1("StreamClassCreateFilter Called\n");
/* FIXME Support Pins/Clocks */
/* Init filter */
Status = InitializeFilterWithKs(DeviceObject, Irp);

View file

@ -96,7 +96,7 @@ WdmAudOpenSysAudioDevices(
ULONG Length;
HANDLE hSysAudio;
PFILE_OBJECT FileObject;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio");
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\sysaudio\\GLOBAL");
if (DeviceExtension->DeviceInterfaceSupport)
{

View file

@ -255,7 +255,11 @@ SysAudioAllocateDeviceHeader(
/* initialize create item struct */
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
CreateItem->Create = DispatchCreateSysAudio;
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
/* FIXME Sysaudio doesnt need a named create item because it installs itself
* via the device interface
*/
RtlInitUnicodeString(&CreateItem->ObjectClass, L"GLOBAL");
CreateItem->Flags = KSCREATE_ITEM_WILDCARD;
Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
@ -269,14 +273,14 @@ SysAudioOpenKMixer(
IN SYSAUDIODEVEXT *DeviceExtension)
{
NTSTATUS Status;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer");
UNICODE_STRING DeviceInstanceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer\\GLOBAL");
UNICODE_STRING DevicePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\kmixer");
Status = ZwLoadDriver(&DevicePath);
if (NT_SUCCESS(Status))
{
Status = OpenDevice(&DeviceName, &DeviceExtension->KMixerHandle, &DeviceExtension->KMixerFileObject);
Status = OpenDevice(&DeviceInstanceName, &DeviceExtension->KMixerHandle, &DeviceExtension->KMixerFileObject);
if (!NT_SUCCESS(Status))
{
DeviceExtension->KMixerHandle = NULL;

View file

@ -89,6 +89,13 @@ typedef struct
PKSAUDIO_DEVICE_ENTRY DeviceEntry;
}FILTER_WORKER_CONTEXT, *PFILTER_WORKER_CONTEXT;
typedef struct
{
PIRP Irp;
IO_STATUS_BLOCK StatusBlock;
}COMPLETION_CONTEXT, *PCOMPLETION_CONTEXT;
NTSTATUS
SysAudioAllocateDeviceHeader(