mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 06:15:26 +00:00
- Check in wdmaud if a pin with the specified filter id and pin id has been opened
- Partly rewrite SysAudio as it is no longer required to store client specific information per connection since wdmaud just opens one connection - Verify all audio handles at incoming irp svn path=/trunk/; revision=41371
This commit is contained in:
parent
305a63335d
commit
a0aa8829fc
6 changed files with 134 additions and 320 deletions
|
@ -165,6 +165,17 @@ WdmAudControlOpen(
|
|||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||
}
|
||||
|
||||
/* close pin handle which uses same virtual audio device id and pin id */
|
||||
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
||||
{
|
||||
if (ClientInfo->hPins[Index].FilterId == FilterId && ClientInfo->hPins[Index].PinId == PinId && ClientInfo->hPins[Index].Handle)
|
||||
{
|
||||
ZwClose(ClientInfo->hPins[Index].Handle);
|
||||
ClientInfo->hPins[Index].Handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
|
||||
InstanceInfo = ExAllocatePool(NonPagedPool, Length);
|
||||
if (!InstanceInfo)
|
||||
|
@ -272,6 +283,8 @@ WdmAudControlOpen(
|
|||
ClientInfo->hPins = Handels;
|
||||
ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
|
||||
ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceInfo->DeviceType;
|
||||
ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
|
||||
ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
|
||||
ClientInfo->NumPins++;
|
||||
}
|
||||
DeviceInfo->hDevice = PinHandle;
|
||||
|
|
|
@ -16,6 +16,8 @@ typedef struct
|
|||
{
|
||||
HANDLE Handle;
|
||||
SOUND_DEVICE_TYPE Type;
|
||||
ULONG FilterId;
|
||||
ULONG PinId;
|
||||
}WDMAUD_HANDLE, *PWDMAUD_HANDLE;
|
||||
|
||||
|
||||
|
|
|
@ -169,7 +169,6 @@ SysAudioOpenVirtualDevice(
|
|||
IN ULONG DeviceNumber,
|
||||
PSYSAUDIODEVEXT DeviceExtension)
|
||||
{
|
||||
PSYSAUDIO_CLIENT ClientInfo;
|
||||
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||
|
||||
|
@ -183,19 +182,6 @@ SysAudioOpenVirtualDevice(
|
|||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||
}
|
||||
|
||||
/* get client context */
|
||||
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(ClientInfo);
|
||||
|
||||
/* check for valid device index */
|
||||
if (DeviceNumber >= ClientInfo->NumDevices)
|
||||
{
|
||||
/* invalid device index */
|
||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||
}
|
||||
|
||||
/* get device context */
|
||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
|
||||
ASSERT(Entry != NULL);
|
||||
|
@ -249,8 +235,7 @@ CreateMixerPinAndSetFormat(
|
|||
IN KSPIN_CONNECT *PinConnect,
|
||||
IN PKSDATAFORMAT InputFormat,
|
||||
IN PKSDATAFORMAT OutputFormat,
|
||||
OUT PHANDLE MixerPinHandle,
|
||||
OUT PFILE_OBJECT *MixerFileObject)
|
||||
OUT PHANDLE MixerPinHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE PinHandle;
|
||||
|
@ -281,8 +266,9 @@ CreateMixerPinAndSetFormat(
|
|||
ZwClose(PinHandle);
|
||||
}
|
||||
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
*MixerPinHandle = PinHandle;
|
||||
*MixerFileObject = FileObject;
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -294,11 +280,8 @@ CreatePinWorkerRoutine(
|
|||
IN PVOID Context)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG NumHandels;
|
||||
HANDLE RealPinHandle = NULL, VirtualPinHandle = NULL, Filter;
|
||||
PFILE_OBJECT RealFileObject = NULL, VirtualFileObject = NULL;
|
||||
PSYSAUDIO_CLIENT AudioClient;
|
||||
PSYSAUDIO_PIN_HANDLE ClientPinHandle;
|
||||
PFILE_OBJECT VirtualFileObject = NULL;
|
||||
PKSDATAFORMAT_WAVEFORMATEX InputFormat;
|
||||
PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL;
|
||||
PKSPIN_CONNECT MixerPinConnect = NULL;
|
||||
|
@ -374,28 +357,12 @@ CreatePinWorkerRoutine(
|
|||
}
|
||||
}
|
||||
|
||||
/* get pin file object */
|
||||
Status = ObReferenceObjectByHandle(RealPinHandle,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to get file object with %x\n", Status);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1)
|
||||
{
|
||||
/* store the pin handle there if the pin can only be instantiated once*/
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle;
|
||||
}
|
||||
ASSERT(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount);
|
||||
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
|
||||
WorkerContext->DispatchContext->Handle = RealPinHandle;
|
||||
WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
|
||||
WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
|
||||
WorkerContext->DispatchContext->FileObject = RealFileObject;
|
||||
|
||||
/* Do we need to transform the audio stream */
|
||||
if (OutputFormat != NULL)
|
||||
|
@ -405,8 +372,7 @@ CreatePinWorkerRoutine(
|
|||
MixerPinConnect,
|
||||
(PKSDATAFORMAT)InputFormat,
|
||||
(PKSDATAFORMAT)OutputFormat,
|
||||
&WorkerContext->DispatchContext->hMixerPin,
|
||||
&WorkerContext->DispatchContext->MixerFileObject);
|
||||
&WorkerContext->DispatchContext->hMixerPin);
|
||||
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -438,61 +404,21 @@ CreatePinWorkerRoutine(
|
|||
goto cleanup;
|
||||
}
|
||||
|
||||
ASSERT(WorkerContext->AudioClient);
|
||||
ASSERT(WorkerContext->AudioClient->NumDevices > 0);
|
||||
ASSERT(WorkerContext->AudioClient->Devs != NULL);
|
||||
ASSERT(WorkerContext->Entry->Pins != NULL);
|
||||
ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId);
|
||||
|
||||
AudioClient = WorkerContext->AudioClient;
|
||||
NumHandels = AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount;
|
||||
/* increment reference count */
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++;
|
||||
|
||||
ClientPinHandle = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_PIN_HANDLE) * (NumHandels+1));
|
||||
if (ClientPinHandle)
|
||||
{
|
||||
if (NumHandels)
|
||||
{
|
||||
ASSERT(AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles != NULL);
|
||||
RtlMoveMemory(ClientPinHandle,
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles,
|
||||
sizeof(SYSAUDIO_PIN_HANDLE) * NumHandels);
|
||||
ExFreePool(AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles);
|
||||
}
|
||||
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles = ClientPinHandle;
|
||||
|
||||
/// if the pin can be instantiated more than once
|
||||
/// then store the real pin handle in the client context
|
||||
/// otherwise just the pin id of the available pin
|
||||
if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount > 1)
|
||||
{
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = TRUE;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = RealPinHandle;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = WorkerContext->DispatchContext->hMixerPin;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].DispatchContext = WorkerContext->DispatchContext;
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = FALSE;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = VirtualPinHandle;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hMixer = WorkerContext->DispatchContext->hMixerPin;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].DispatchContext = WorkerContext->DispatchContext;
|
||||
}
|
||||
|
||||
/// increase reference count
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++;
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no memory */
|
||||
goto cleanup;
|
||||
}
|
||||
/* store the pin handle there if the pin can only be instantiated once*/
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = VirtualPinHandle;
|
||||
|
||||
/* store pin context */
|
||||
VirtualFileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
|
||||
|
||||
/* release virtual file object */
|
||||
ObDereferenceObject(VirtualFileObject);
|
||||
|
||||
DPRINT("Successfully created virtual pin %p\n", VirtualPinHandle);
|
||||
*((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
|
||||
|
||||
|
@ -502,15 +428,9 @@ CreatePinWorkerRoutine(
|
|||
return;
|
||||
|
||||
cleanup:
|
||||
if (RealFileObject)
|
||||
ObDereferenceObject(RealFileObject);
|
||||
|
||||
if (RealPinHandle)
|
||||
ZwClose(RealPinHandle);
|
||||
|
||||
if (WorkerContext->DispatchContext->MixerFileObject)
|
||||
ObDereferenceObject(WorkerContext->DispatchContext->MixerFileObject);
|
||||
|
||||
if (WorkerContext->DispatchContext->hMixerPin)
|
||||
ZwClose(WorkerContext->DispatchContext->hMixerPin);
|
||||
|
||||
|
@ -767,51 +687,6 @@ GetPinInstanceCount(
|
|||
|
||||
}
|
||||
|
||||
VOID
|
||||
CloseExistingPin(
|
||||
PSYSAUDIO_CLIENT ClientInfo,
|
||||
PSYSAUDIO_INSTANCE_INFO InstanceInfo,
|
||||
PKSPIN_CONNECT PinConnect)
|
||||
{
|
||||
ULONG Index, SubIndex;
|
||||
PDISPATCH_CONTEXT DispatchContext;
|
||||
|
||||
/* scan the clientinfo if the client has already opened device with the specified pin */
|
||||
for (Index = 0; Index < ClientInfo->NumDevices; Index++)
|
||||
{
|
||||
if (ClientInfo->Devs[Index].DeviceId == InstanceInfo->DeviceNumber)
|
||||
{
|
||||
if (ClientInfo->Devs[Index].ClientHandlesCount)
|
||||
{
|
||||
for(SubIndex = 0; SubIndex < ClientInfo->Devs[Index].ClientHandlesCount; SubIndex++)
|
||||
{
|
||||
if (ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId == PinConnect->PinId)
|
||||
{
|
||||
/* the pin has been already opened by the client, re-use it */
|
||||
ASSERT(ClientInfo->Devs[Index].ClientHandles[SubIndex].bHandle == FALSE);
|
||||
|
||||
DispatchContext = ClientInfo->Devs[Index].ClientHandles[SubIndex].DispatchContext;
|
||||
|
||||
if (DispatchContext->MixerFileObject)
|
||||
ObDereferenceObject(DispatchContext->MixerFileObject);
|
||||
|
||||
if (DispatchContext->hMixerPin)
|
||||
ZwClose(DispatchContext->hMixerPin);
|
||||
|
||||
if (DispatchContext->FileObject)
|
||||
ObDereferenceObject(DispatchContext->FileObject);
|
||||
|
||||
if (DispatchContext->Handle)
|
||||
ZwClose(DispatchContext->Handle);
|
||||
ClientInfo->Devs[Index].ClientHandles[SubIndex].PinId = (ULONG)-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HandleSysAudioFilterPinCreation(
|
||||
PIRP Irp,
|
||||
|
@ -824,7 +699,6 @@ HandleSysAudioFilterPinCreation(
|
|||
KSPIN_CONNECT * PinConnect;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
||||
PSYSAUDIO_CLIENT ClientInfo;
|
||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||
NTSTATUS Status;
|
||||
KSPIN_CINSTANCES PinInstances;
|
||||
|
@ -853,14 +727,6 @@ HandleSysAudioFilterPinCreation(
|
|||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||
}
|
||||
|
||||
/* get client context */
|
||||
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
||||
if (!ClientInfo || !ClientInfo->NumDevices || !ClientInfo->Devs)
|
||||
{
|
||||
/* we have a problem */
|
||||
KeBugCheckEx(0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/* get sysaudio entry */
|
||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber);
|
||||
if (!Entry)
|
||||
|
@ -884,9 +750,6 @@ HandleSysAudioFilterPinCreation(
|
|||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||
}
|
||||
|
||||
/* close existing pin first */
|
||||
CloseExistingPin(ClientInfo, InstanceInfo, PinConnect);
|
||||
|
||||
/* query instance count */
|
||||
Status = GetPinInstanceCount(Entry, &PinInstances, PinConnect);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -905,14 +768,11 @@ HandleSysAudioFilterPinCreation(
|
|||
{
|
||||
/* pin already exists */
|
||||
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
|
||||
if (Entry->Pins[PinConnect->PinId].References)
|
||||
{
|
||||
/* FIXME need ksmixer */
|
||||
DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References);
|
||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||
}
|
||||
}
|
||||
ASSERT(Entry->Pins[PinConnect->PinId].References);
|
||||
|
||||
DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References);
|
||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||
}
|
||||
/* create dispatch pin context */
|
||||
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
|
||||
if (!DispatchContext)
|
||||
|
@ -956,7 +816,6 @@ HandleSysAudioFilterPinCreation(
|
|||
WorkerContext->Entry = Entry;
|
||||
WorkerContext->Irp = Irp;
|
||||
WorkerContext->PinConnect = PinConnect;
|
||||
WorkerContext->AudioClient = ClientInfo;
|
||||
WorkerContext->DeviceExtension = DeviceExtension;
|
||||
WorkerContext->WorkItem = WorkItem;
|
||||
|
||||
|
|
|
@ -73,79 +73,7 @@ Dispatch_fnClose(
|
|||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PSYSAUDIO_CLIENT Client;
|
||||
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||
PIO_STACK_LOCATION IoStatus;
|
||||
ULONG Index, SubIndex;
|
||||
PSYSAUDIODEVEXT DeviceExtension;
|
||||
PDISPATCH_CONTEXT DispatchContext;
|
||||
|
||||
|
||||
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2;
|
||||
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
DPRINT("Client %p NumDevices %u\n", Client, Client->NumDevices);
|
||||
for(Index = 0; Index < Client->NumDevices; Index++)
|
||||
{
|
||||
DPRINT("Index %u Device %u Handels Count %u\n", Index, Client->Devs[Index].DeviceId, Client->Devs[Index].ClientHandlesCount);
|
||||
if (Client->Devs[Index].ClientHandlesCount)
|
||||
{
|
||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Client->Devs[Index].DeviceId);
|
||||
ASSERT(Entry != NULL);
|
||||
|
||||
for(SubIndex = 0; SubIndex < Client->Devs[Index].ClientHandlesCount; SubIndex++)
|
||||
{
|
||||
if (Client->Devs[Index].ClientHandles[SubIndex].PinId == (ULONG)-1)
|
||||
continue;
|
||||
|
||||
if (Client->Devs[Index].ClientHandles[SubIndex].bHandle)
|
||||
{
|
||||
DPRINT("Closing handle %p\n", Client->Devs[Index].ClientHandles[SubIndex].hPin);
|
||||
|
||||
ZwClose(Client->Devs[Index].ClientHandles[SubIndex].hPin);
|
||||
Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* this is a pin which can only be instantiated once
|
||||
* so we just need to release the reference count on that pin
|
||||
*/
|
||||
Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--;
|
||||
|
||||
DispatchContext = (PDISPATCH_CONTEXT)Client->Devs[Index].ClientHandles[SubIndex].DispatchContext;
|
||||
|
||||
if (DispatchContext->MixerFileObject)
|
||||
ObDereferenceObject(DispatchContext->MixerFileObject);
|
||||
|
||||
if (DispatchContext->hMixerPin)
|
||||
ZwClose(DispatchContext->hMixerPin);
|
||||
|
||||
if (DispatchContext->FileObject)
|
||||
ObDereferenceObject(DispatchContext->FileObject);
|
||||
|
||||
ExFreePool(DispatchContext);
|
||||
|
||||
DPRINT("Index %u DeviceIndex %u Pin %u References %u\n", Index, Client->Devs[Index].DeviceId, SubIndex, Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References);
|
||||
if (!Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References)
|
||||
{
|
||||
DPRINT("Closing pin %p\n", Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle);
|
||||
|
||||
ZwClose(Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle);
|
||||
Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].PinHandle = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
ExFreePool(Client->Devs[Index].ClientHandles);
|
||||
}
|
||||
}
|
||||
|
||||
if (Client->Devs)
|
||||
ExFreePool(Client->Devs);
|
||||
|
||||
ExFreePool(Client);
|
||||
DPRINT("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
@ -259,13 +187,10 @@ DispatchCreateSysAudio(
|
|||
{
|
||||
NTSTATUS Status;
|
||||
KSOBJECT_HEADER ObjectHeader;
|
||||
PSYSAUDIO_CLIENT Client;
|
||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||
PIO_STACK_LOCATION IoStatus;
|
||||
LPWSTR Buffer;
|
||||
PSYSAUDIODEVEXT DeviceExtension;
|
||||
ULONG Index;
|
||||
|
||||
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
||||
|
||||
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
@ -298,59 +223,15 @@ DispatchCreateSysAudio(
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Client = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT));
|
||||
if (!Client)
|
||||
{
|
||||
ExFreePool(CreateItem);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/* get device extension */
|
||||
DeviceExtension = (PSYSAUDIODEVEXT) DeviceObject->DeviceExtension;
|
||||
|
||||
Client->NumDevices = DeviceExtension->NumberOfKsAudioDevices;
|
||||
/* has sysaudio found any devices */
|
||||
if (Client->NumDevices)
|
||||
{
|
||||
Client->Devs = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS) * Client->NumDevices);
|
||||
if (!Client->Devs)
|
||||
{
|
||||
ExFreePool(CreateItem);
|
||||
ExFreePool(Client);
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no devices yet available */
|
||||
Client->Devs = NULL;
|
||||
}
|
||||
|
||||
/* Initialize devs array */
|
||||
for(Index = 0; Index < Client->NumDevices; Index++)
|
||||
{
|
||||
Client->Devs[Index].DeviceId = Index;
|
||||
Client->Devs[Index].ClientHandles = NULL;
|
||||
Client->Devs[Index].ClientHandlesCount = 0;
|
||||
}
|
||||
|
||||
/* zero create struct */
|
||||
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
||||
|
||||
/* store create context */
|
||||
CreateItem->Context = (PVOID)Client;
|
||||
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
|
||||
|
||||
/* store the object in FsContext */
|
||||
IoStatus->FileObject->FsContext2 = (PVOID)Client;
|
||||
|
||||
/* allocate object header */
|
||||
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ Pin_fnDeviceIoControl(
|
|||
PDISPATCH_CONTEXT Context;
|
||||
NTSTATUS Status;
|
||||
ULONG BytesReturned;
|
||||
PFILE_OBJECT FileObject;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
||||
|
@ -29,15 +30,27 @@ Pin_fnDeviceIoControl(
|
|||
|
||||
/* Sanity check */
|
||||
ASSERT(Context);
|
||||
ASSERT(Context->FileObject != NULL);
|
||||
|
||||
/* acquire real pin file object */
|
||||
Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
/* Complete the irp */
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Re-dispatch the request to the real target pin */
|
||||
Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
|
||||
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
|
||||
IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
|
||||
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
||||
Irp->UserBuffer,
|
||||
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
|
||||
&BytesReturned);
|
||||
/* release file object */
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
/* Save status and information */
|
||||
Irp->IoStatus.Information = BytesReturned;
|
||||
|
@ -57,6 +70,7 @@ Pin_fnRead(
|
|||
PDISPATCH_CONTEXT Context;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
ULONG BytesReturned;
|
||||
PFILE_OBJECT FileObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Get current stack location */
|
||||
|
@ -67,17 +81,30 @@ Pin_fnRead(
|
|||
|
||||
/* Sanity check */
|
||||
ASSERT(Context);
|
||||
ASSERT(Context->FileObject != NULL);
|
||||
|
||||
/* acquire real pin file object */
|
||||
Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
/* Complete the irp */
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Re-dispatch the request to the real target pin */
|
||||
Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_READ_STREAM,
|
||||
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_READ_STREAM,
|
||||
MmGetMdlVirtualAddress(Irp->MdlAddress),
|
||||
IoStack->Parameters.Read.Length,
|
||||
NULL,
|
||||
0,
|
||||
&BytesReturned);
|
||||
|
||||
if (Context->hMixerPin && Context->MixerFileObject)
|
||||
/* release file object */
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
if (Context->hMixerPin)
|
||||
{
|
||||
// FIXME
|
||||
// call kmixer to convert stream
|
||||
|
@ -102,6 +129,7 @@ Pin_fnWrite(
|
|||
PDISPATCH_CONTEXT Context;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
ULONG BytesReturned;
|
||||
PFILE_OBJECT FileObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* Get current stack location */
|
||||
|
@ -112,24 +140,36 @@ Pin_fnWrite(
|
|||
|
||||
/* Sanity check */
|
||||
ASSERT(Context);
|
||||
ASSERT(Context->FileObject != NULL);
|
||||
|
||||
if (Context->hMixerPin && Context->MixerFileObject)
|
||||
if (Context->hMixerPin)
|
||||
{
|
||||
// FIXME
|
||||
// call kmixer to convert stream
|
||||
UNIMPLEMENTED
|
||||
}
|
||||
|
||||
/* acquire real pin file object */
|
||||
Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
/* Complete the irp */
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Re-dispatch the request to the real target pin */
|
||||
Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
|
||||
Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
|
||||
MmGetMdlVirtualAddress(Irp->MdlAddress),
|
||||
IoStack->Parameters.Read.Length,
|
||||
NULL,
|
||||
0,
|
||||
&BytesReturned);
|
||||
|
||||
/* release file object */
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
/* Save status and information */
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
@ -149,6 +189,7 @@ Pin_fnFlush(
|
|||
PIO_STACK_LOCATION IoStack;
|
||||
PDEVICE_OBJECT PinDeviceObject;
|
||||
PIRP PinIrp;
|
||||
PFILE_OBJECT FileObject;
|
||||
IO_STATUS_BLOCK IoStatus;
|
||||
KEVENT Event;
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
|
@ -161,10 +202,24 @@ Pin_fnFlush(
|
|||
|
||||
/* Sanity check */
|
||||
ASSERT(Context);
|
||||
ASSERT(Context->FileObject != NULL);
|
||||
|
||||
|
||||
/* acquire real pin file object */
|
||||
Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
/* Complete the irp */
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Get Pin's device object */
|
||||
PinDeviceObject = IoGetRelatedDeviceObject(Context->FileObject);
|
||||
PinDeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||
|
||||
/* release file object */
|
||||
ObDereferenceObject(FileObject);
|
||||
|
||||
/* Initialize notification event */
|
||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||
|
@ -177,7 +232,7 @@ Pin_fnFlush(
|
|||
/* Get the next stack location */
|
||||
IoStack = IoGetNextIrpStackLocation(PinIrp);
|
||||
/* The file object must be present in the irp as it contains the KSOBJECT_HEADER */
|
||||
IoStack->FileObject = Context->FileObject;
|
||||
IoStack->FileObject = FileObject;
|
||||
|
||||
/* call the driver */
|
||||
Status = IoCallDriver(PinDeviceObject, PinIrp);
|
||||
|
@ -206,8 +261,25 @@ Pin_fnClose(
|
|||
PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PDISPATCH_CONTEXT Context;
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
|
||||
DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
||||
|
||||
/* Get current stack location */
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
/* The dispatch context is stored in the FsContext2 member */
|
||||
Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
|
||||
|
||||
if (Context->Handle)
|
||||
{
|
||||
ZwClose(Context->Handle);
|
||||
}
|
||||
ZwClose(Context->hMixerPin);
|
||||
|
||||
ExFreePool(Context);
|
||||
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
@ -294,15 +366,22 @@ Pin_fnFastWrite(
|
|||
PDEVICE_OBJECT DeviceObject)
|
||||
{
|
||||
PDISPATCH_CONTEXT Context;
|
||||
PFILE_OBJECT RealFileObject;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
||||
|
||||
Context = (PDISPATCH_CONTEXT)FileObject->FsContext2;
|
||||
|
||||
if (Context->hMixerPin && Context->MixerFileObject)
|
||||
if (Context->hMixerPin)
|
||||
{
|
||||
Status = KsStreamIo(Context->MixerFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode);
|
||||
Status = ObReferenceObjectByHandle(Context->hMixerPin, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
Status = KsStreamIo(RealFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode);
|
||||
ObDereferenceObject(RealFileObject);
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Mixing stream failed with %lx\n", Status);
|
||||
|
@ -310,7 +389,14 @@ Pin_fnFastWrite(
|
|||
}
|
||||
}
|
||||
|
||||
Status = KsStreamIo(Context->FileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode);
|
||||
Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
Status = KsStreamIo(RealFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, KernelMode);
|
||||
|
||||
ObDereferenceObject(RealFileObject);
|
||||
|
||||
if (Status == STATUS_SUCCESS)
|
||||
return TRUE;
|
||||
else
|
||||
|
|
|
@ -11,30 +11,6 @@
|
|||
#include <debug.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL bHandle; // indicates if an audio pin can be instantated more than once
|
||||
ULONG PinId; // specifies the pin id
|
||||
HANDLE hPin; // handle to audio irp pin
|
||||
HANDLE hMixer; // handle to mixer pin
|
||||
PVOID DispatchContext; // pointer to dispatch context
|
||||
}SYSAUDIO_PIN_HANDLE, *PSYSAUDIO_PIN_HANDLE;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG DeviceId; //specifies the device id
|
||||
ULONG ClientHandlesCount; // number of client handles
|
||||
PSYSAUDIO_PIN_HANDLE ClientHandles; // array of client handles
|
||||
}SYSAUDIO_CLIENT_HANDELS, *PSYSAUDIO_CLIENT_HANDELS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG NumDevices; // number of devices in Devs array
|
||||
PSYSAUDIO_CLIENT_HANDELS Devs; // array of client handles
|
||||
|
||||
}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG MaxPinInstanceCount; // maximum times a audio irp pin can be instantiated
|
||||
|
@ -94,12 +70,10 @@ typedef struct
|
|||
typedef struct
|
||||
{
|
||||
HANDLE Handle; // audio irp pin handle
|
||||
PFILE_OBJECT FileObject; // audio irp pin file object
|
||||
ULONG PinId; // pin id of device
|
||||
PKSAUDIO_SUBDEVICE_ENTRY AudioEntry; // pointer to audio device entry
|
||||
|
||||
HANDLE hMixerPin; // handle to mixer pin
|
||||
PFILE_OBJECT MixerFileObject; // mixer file object
|
||||
}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
|
||||
|
||||
// struct PIN_WORKER_CONTEXT
|
||||
|
@ -115,7 +89,6 @@ typedef struct
|
|||
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||
KSPIN_CONNECT * PinConnect;
|
||||
PDISPATCH_CONTEXT DispatchContext;
|
||||
PSYSAUDIO_CLIENT AudioClient;
|
||||
PSYSAUDIODEVEXT DeviceExtension;
|
||||
PKSDATAFORMAT_WAVEFORMATEX MixerFormat;
|
||||
PIO_WORKITEM WorkItem;
|
||||
|
|
Loading…
Reference in a new issue