mirror of
https://github.com/reactos/reactos.git
synced 2024-08-04 18:40:59 +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
|
@ -165,6 +165,17 @@ WdmAudControlOpen(
|
||||||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
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);
|
Length = sizeof(KSDATAFORMAT_WAVEFORMATEX) + sizeof(KSPIN_CONNECT) + sizeof(SYSAUDIO_INSTANCE_INFO);
|
||||||
InstanceInfo = ExAllocatePool(NonPagedPool, Length);
|
InstanceInfo = ExAllocatePool(NonPagedPool, Length);
|
||||||
if (!InstanceInfo)
|
if (!InstanceInfo)
|
||||||
|
@ -272,6 +283,8 @@ WdmAudControlOpen(
|
||||||
ClientInfo->hPins = Handels;
|
ClientInfo->hPins = Handels;
|
||||||
ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
|
ClientInfo->hPins[ClientInfo->NumPins].Handle = PinHandle;
|
||||||
ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceInfo->DeviceType;
|
ClientInfo->hPins[ClientInfo->NumPins].Type = DeviceInfo->DeviceType;
|
||||||
|
ClientInfo->hPins[ClientInfo->NumPins].FilterId = FilterId;
|
||||||
|
ClientInfo->hPins[ClientInfo->NumPins].PinId = PinId;
|
||||||
ClientInfo->NumPins++;
|
ClientInfo->NumPins++;
|
||||||
}
|
}
|
||||||
DeviceInfo->hDevice = PinHandle;
|
DeviceInfo->hDevice = PinHandle;
|
||||||
|
|
|
@ -16,6 +16,8 @@ typedef struct
|
||||||
{
|
{
|
||||||
HANDLE Handle;
|
HANDLE Handle;
|
||||||
SOUND_DEVICE_TYPE Type;
|
SOUND_DEVICE_TYPE Type;
|
||||||
|
ULONG FilterId;
|
||||||
|
ULONG PinId;
|
||||||
}WDMAUD_HANDLE, *PWDMAUD_HANDLE;
|
}WDMAUD_HANDLE, *PWDMAUD_HANDLE;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,6 @@ SysAudioOpenVirtualDevice(
|
||||||
IN ULONG DeviceNumber,
|
IN ULONG DeviceNumber,
|
||||||
PSYSAUDIODEVEXT DeviceExtension)
|
PSYSAUDIODEVEXT DeviceExtension)
|
||||||
{
|
{
|
||||||
PSYSAUDIO_CLIENT ClientInfo;
|
|
||||||
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
|
|
||||||
|
@ -183,19 +182,6 @@ SysAudioOpenVirtualDevice(
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
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 */
|
/* get device context */
|
||||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber);
|
||||||
ASSERT(Entry != NULL);
|
ASSERT(Entry != NULL);
|
||||||
|
@ -249,8 +235,7 @@ CreateMixerPinAndSetFormat(
|
||||||
IN KSPIN_CONNECT *PinConnect,
|
IN KSPIN_CONNECT *PinConnect,
|
||||||
IN PKSDATAFORMAT InputFormat,
|
IN PKSDATAFORMAT InputFormat,
|
||||||
IN PKSDATAFORMAT OutputFormat,
|
IN PKSDATAFORMAT OutputFormat,
|
||||||
OUT PHANDLE MixerPinHandle,
|
OUT PHANDLE MixerPinHandle)
|
||||||
OUT PFILE_OBJECT *MixerFileObject)
|
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
HANDLE PinHandle;
|
HANDLE PinHandle;
|
||||||
|
@ -281,8 +266,9 @@ CreateMixerPinAndSetFormat(
|
||||||
ZwClose(PinHandle);
|
ZwClose(PinHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
*MixerPinHandle = PinHandle;
|
*MixerPinHandle = PinHandle;
|
||||||
*MixerFileObject = FileObject;
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -294,11 +280,8 @@ CreatePinWorkerRoutine(
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG NumHandels;
|
|
||||||
HANDLE RealPinHandle = NULL, VirtualPinHandle = NULL, Filter;
|
HANDLE RealPinHandle = NULL, VirtualPinHandle = NULL, Filter;
|
||||||
PFILE_OBJECT RealFileObject = NULL, VirtualFileObject = NULL;
|
PFILE_OBJECT VirtualFileObject = NULL;
|
||||||
PSYSAUDIO_CLIENT AudioClient;
|
|
||||||
PSYSAUDIO_PIN_HANDLE ClientPinHandle;
|
|
||||||
PKSDATAFORMAT_WAVEFORMATEX InputFormat;
|
PKSDATAFORMAT_WAVEFORMATEX InputFormat;
|
||||||
PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL;
|
PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL;
|
||||||
PKSPIN_CONNECT MixerPinConnect = NULL;
|
PKSPIN_CONNECT MixerPinConnect = NULL;
|
||||||
|
@ -374,28 +357,12 @@ CreatePinWorkerRoutine(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get pin file object */
|
ASSERT(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
|
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
|
||||||
WorkerContext->DispatchContext->Handle = RealPinHandle;
|
WorkerContext->DispatchContext->Handle = RealPinHandle;
|
||||||
WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
|
WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
|
||||||
WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
|
WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
|
||||||
WorkerContext->DispatchContext->FileObject = RealFileObject;
|
|
||||||
|
|
||||||
/* Do we need to transform the audio stream */
|
/* Do we need to transform the audio stream */
|
||||||
if (OutputFormat != NULL)
|
if (OutputFormat != NULL)
|
||||||
|
@ -405,8 +372,7 @@ CreatePinWorkerRoutine(
|
||||||
MixerPinConnect,
|
MixerPinConnect,
|
||||||
(PKSDATAFORMAT)InputFormat,
|
(PKSDATAFORMAT)InputFormat,
|
||||||
(PKSDATAFORMAT)OutputFormat,
|
(PKSDATAFORMAT)OutputFormat,
|
||||||
&WorkerContext->DispatchContext->hMixerPin,
|
&WorkerContext->DispatchContext->hMixerPin);
|
||||||
&WorkerContext->DispatchContext->MixerFileObject);
|
|
||||||
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -438,61 +404,21 @@ CreatePinWorkerRoutine(
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT(WorkerContext->AudioClient);
|
|
||||||
ASSERT(WorkerContext->AudioClient->NumDevices > 0);
|
|
||||||
ASSERT(WorkerContext->AudioClient->Devs != NULL);
|
|
||||||
ASSERT(WorkerContext->Entry->Pins != NULL);
|
ASSERT(WorkerContext->Entry->Pins != NULL);
|
||||||
|
ASSERT(WorkerContext->Entry->NumberOfPins > WorkerContext->PinConnect->PinId);
|
||||||
|
|
||||||
AudioClient = WorkerContext->AudioClient;
|
/* increment reference count */
|
||||||
NumHandels = AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount;
|
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++;
|
||||||
|
|
||||||
ClientPinHandle = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_PIN_HANDLE) * (NumHandels+1));
|
/* store the pin handle there if the pin can only be instantiated once*/
|
||||||
if (ClientPinHandle)
|
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = VirtualPinHandle;
|
||||||
{
|
|
||||||
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 pin context */
|
/* store pin context */
|
||||||
VirtualFileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
|
VirtualFileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
|
||||||
|
|
||||||
|
/* release virtual file object */
|
||||||
|
ObDereferenceObject(VirtualFileObject);
|
||||||
|
|
||||||
DPRINT("Successfully created virtual pin %p\n", VirtualPinHandle);
|
DPRINT("Successfully created virtual pin %p\n", VirtualPinHandle);
|
||||||
*((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
|
*((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
|
||||||
|
|
||||||
|
@ -502,15 +428,9 @@ CreatePinWorkerRoutine(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
if (RealFileObject)
|
|
||||||
ObDereferenceObject(RealFileObject);
|
|
||||||
|
|
||||||
if (RealPinHandle)
|
if (RealPinHandle)
|
||||||
ZwClose(RealPinHandle);
|
ZwClose(RealPinHandle);
|
||||||
|
|
||||||
if (WorkerContext->DispatchContext->MixerFileObject)
|
|
||||||
ObDereferenceObject(WorkerContext->DispatchContext->MixerFileObject);
|
|
||||||
|
|
||||||
if (WorkerContext->DispatchContext->hMixerPin)
|
if (WorkerContext->DispatchContext->hMixerPin)
|
||||||
ZwClose(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
|
NTSTATUS
|
||||||
HandleSysAudioFilterPinCreation(
|
HandleSysAudioFilterPinCreation(
|
||||||
PIRP Irp,
|
PIRP Irp,
|
||||||
|
@ -824,7 +699,6 @@ HandleSysAudioFilterPinCreation(
|
||||||
KSPIN_CONNECT * PinConnect;
|
KSPIN_CONNECT * PinConnect;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
|
||||||
PSYSAUDIO_CLIENT ClientInfo;
|
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KSPIN_CINSTANCES PinInstances;
|
KSPIN_CINSTANCES PinInstances;
|
||||||
|
@ -853,14 +727,6 @@ HandleSysAudioFilterPinCreation(
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
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 */
|
/* get sysaudio entry */
|
||||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber);
|
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber);
|
||||||
if (!Entry)
|
if (!Entry)
|
||||||
|
@ -884,9 +750,6 @@ HandleSysAudioFilterPinCreation(
|
||||||
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* close existing pin first */
|
|
||||||
CloseExistingPin(ClientInfo, InstanceInfo, PinConnect);
|
|
||||||
|
|
||||||
/* query instance count */
|
/* query instance count */
|
||||||
Status = GetPinInstanceCount(Entry, &PinInstances, PinConnect);
|
Status = GetPinInstanceCount(Entry, &PinInstances, PinConnect);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
@ -905,14 +768,11 @@ HandleSysAudioFilterPinCreation(
|
||||||
{
|
{
|
||||||
/* pin already exists */
|
/* pin already exists */
|
||||||
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
|
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
|
||||||
if (Entry->Pins[PinConnect->PinId].References)
|
ASSERT(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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 */
|
/* create dispatch pin context */
|
||||||
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
|
DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
|
||||||
if (!DispatchContext)
|
if (!DispatchContext)
|
||||||
|
@ -956,7 +816,6 @@ HandleSysAudioFilterPinCreation(
|
||||||
WorkerContext->Entry = Entry;
|
WorkerContext->Entry = Entry;
|
||||||
WorkerContext->Irp = Irp;
|
WorkerContext->Irp = Irp;
|
||||||
WorkerContext->PinConnect = PinConnect;
|
WorkerContext->PinConnect = PinConnect;
|
||||||
WorkerContext->AudioClient = ClientInfo;
|
|
||||||
WorkerContext->DeviceExtension = DeviceExtension;
|
WorkerContext->DeviceExtension = DeviceExtension;
|
||||||
WorkerContext->WorkItem = WorkItem;
|
WorkerContext->WorkItem = WorkItem;
|
||||||
|
|
||||||
|
|
|
@ -73,79 +73,7 @@ Dispatch_fnClose(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
PSYSAUDIO_CLIENT Client;
|
DPRINT("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
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);
|
|
||||||
|
|
||||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
@ -259,13 +187,10 @@ DispatchCreateSysAudio(
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
KSOBJECT_HEADER ObjectHeader;
|
KSOBJECT_HEADER ObjectHeader;
|
||||||
PSYSAUDIO_CLIENT Client;
|
|
||||||
PKSOBJECT_CREATE_ITEM CreateItem;
|
PKSOBJECT_CREATE_ITEM CreateItem;
|
||||||
PIO_STACK_LOCATION IoStatus;
|
PIO_STACK_LOCATION IoStatus;
|
||||||
LPWSTR Buffer;
|
LPWSTR Buffer;
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
ULONG Index;
|
|
||||||
|
|
||||||
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
|
||||||
|
|
||||||
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
||||||
|
@ -298,59 +223,15 @@ DispatchCreateSysAudio(
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
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 */
|
/* get device extension */
|
||||||
DeviceExtension = (PSYSAUDIODEVEXT) DeviceObject->DeviceExtension;
|
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 */
|
/* zero create struct */
|
||||||
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
|
||||||
|
|
||||||
/* store create context */
|
/* store create context */
|
||||||
CreateItem->Context = (PVOID)Client;
|
|
||||||
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
|
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
|
||||||
|
|
||||||
/* store the object in FsContext */
|
|
||||||
IoStatus->FileObject->FsContext2 = (PVOID)Client;
|
|
||||||
|
|
||||||
/* allocate object header */
|
/* allocate object header */
|
||||||
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ Pin_fnDeviceIoControl(
|
||||||
PDISPATCH_CONTEXT Context;
|
PDISPATCH_CONTEXT Context;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
@ -29,15 +30,27 @@ Pin_fnDeviceIoControl(
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
ASSERT(Context);
|
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 */
|
/* 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.Type3InputBuffer,
|
||||||
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
IoStack->Parameters.DeviceIoControl.InputBufferLength,
|
||||||
Irp->UserBuffer,
|
Irp->UserBuffer,
|
||||||
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
|
IoStack->Parameters.DeviceIoControl.OutputBufferLength,
|
||||||
&BytesReturned);
|
&BytesReturned);
|
||||||
|
/* release file object */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
/* Save status and information */
|
/* Save status and information */
|
||||||
Irp->IoStatus.Information = BytesReturned;
|
Irp->IoStatus.Information = BytesReturned;
|
||||||
|
@ -57,6 +70,7 @@ Pin_fnRead(
|
||||||
PDISPATCH_CONTEXT Context;
|
PDISPATCH_CONTEXT Context;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Get current stack location */
|
/* Get current stack location */
|
||||||
|
@ -67,17 +81,30 @@ Pin_fnRead(
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
ASSERT(Context);
|
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 */
|
/* 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),
|
MmGetMdlVirtualAddress(Irp->MdlAddress),
|
||||||
IoStack->Parameters.Read.Length,
|
IoStack->Parameters.Read.Length,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&BytesReturned);
|
&BytesReturned);
|
||||||
|
|
||||||
if (Context->hMixerPin && Context->MixerFileObject)
|
/* release file object */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
|
if (Context->hMixerPin)
|
||||||
{
|
{
|
||||||
// FIXME
|
// FIXME
|
||||||
// call kmixer to convert stream
|
// call kmixer to convert stream
|
||||||
|
@ -102,6 +129,7 @@ Pin_fnWrite(
|
||||||
PDISPATCH_CONTEXT Context;
|
PDISPATCH_CONTEXT Context;
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
ULONG BytesReturned;
|
ULONG BytesReturned;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Get current stack location */
|
/* Get current stack location */
|
||||||
|
@ -112,24 +140,36 @@ Pin_fnWrite(
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
ASSERT(Context);
|
ASSERT(Context);
|
||||||
ASSERT(Context->FileObject != NULL);
|
|
||||||
|
|
||||||
if (Context->hMixerPin && Context->MixerFileObject)
|
if (Context->hMixerPin)
|
||||||
{
|
{
|
||||||
// FIXME
|
// FIXME
|
||||||
// call kmixer to convert stream
|
// call kmixer to convert stream
|
||||||
UNIMPLEMENTED
|
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 */
|
/* 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),
|
MmGetMdlVirtualAddress(Irp->MdlAddress),
|
||||||
IoStack->Parameters.Read.Length,
|
IoStack->Parameters.Read.Length,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
&BytesReturned);
|
&BytesReturned);
|
||||||
|
|
||||||
|
/* release file object */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
/* Save status and information */
|
/* Save status and information */
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
@ -149,6 +189,7 @@ Pin_fnFlush(
|
||||||
PIO_STACK_LOCATION IoStack;
|
PIO_STACK_LOCATION IoStack;
|
||||||
PDEVICE_OBJECT PinDeviceObject;
|
PDEVICE_OBJECT PinDeviceObject;
|
||||||
PIRP PinIrp;
|
PIRP PinIrp;
|
||||||
|
PFILE_OBJECT FileObject;
|
||||||
IO_STATUS_BLOCK IoStatus;
|
IO_STATUS_BLOCK IoStatus;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||||
|
@ -161,10 +202,24 @@ Pin_fnFlush(
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
ASSERT(Context);
|
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 */
|
/* Get Pin's device object */
|
||||||
PinDeviceObject = IoGetRelatedDeviceObject(Context->FileObject);
|
PinDeviceObject = IoGetRelatedDeviceObject(FileObject);
|
||||||
|
|
||||||
|
/* release file object */
|
||||||
|
ObDereferenceObject(FileObject);
|
||||||
|
|
||||||
/* Initialize notification event */
|
/* Initialize notification event */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
@ -177,7 +232,7 @@ Pin_fnFlush(
|
||||||
/* Get the next stack location */
|
/* Get the next stack location */
|
||||||
IoStack = IoGetNextIrpStackLocation(PinIrp);
|
IoStack = IoGetNextIrpStackLocation(PinIrp);
|
||||||
/* The file object must be present in the irp as it contains the KSOBJECT_HEADER */
|
/* 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 */
|
/* call the driver */
|
||||||
Status = IoCallDriver(PinDeviceObject, PinIrp);
|
Status = IoCallDriver(PinDeviceObject, PinIrp);
|
||||||
|
@ -206,8 +261,25 @@ Pin_fnClose(
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PIRP Irp)
|
PIRP Irp)
|
||||||
{
|
{
|
||||||
|
PDISPATCH_CONTEXT Context;
|
||||||
|
PIO_STACK_LOCATION IoStack;
|
||||||
|
|
||||||
DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
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.Status = STATUS_SUCCESS;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||||
|
@ -294,15 +366,22 @@ Pin_fnFastWrite(
|
||||||
PDEVICE_OBJECT DeviceObject)
|
PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
PDISPATCH_CONTEXT Context;
|
PDISPATCH_CONTEXT Context;
|
||||||
|
PFILE_OBJECT RealFileObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
|
||||||
|
|
||||||
Context = (PDISPATCH_CONTEXT)FileObject->FsContext2;
|
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))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("Mixing stream failed with %lx\n", 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)
|
if (Status == STATUS_SUCCESS)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
else
|
else
|
||||||
|
|
|
@ -11,30 +11,6 @@
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <stdio.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
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG MaxPinInstanceCount; // maximum times a audio irp pin can be instantiated
|
ULONG MaxPinInstanceCount; // maximum times a audio irp pin can be instantiated
|
||||||
|
@ -94,12 +70,10 @@ typedef struct
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE Handle; // audio irp pin handle
|
HANDLE Handle; // audio irp pin handle
|
||||||
PFILE_OBJECT FileObject; // audio irp pin file object
|
|
||||||
ULONG PinId; // pin id of device
|
ULONG PinId; // pin id of device
|
||||||
PKSAUDIO_SUBDEVICE_ENTRY AudioEntry; // pointer to audio device entry
|
PKSAUDIO_SUBDEVICE_ENTRY AudioEntry; // pointer to audio device entry
|
||||||
|
|
||||||
HANDLE hMixerPin; // handle to mixer pin
|
HANDLE hMixerPin; // handle to mixer pin
|
||||||
PFILE_OBJECT MixerFileObject; // mixer file object
|
|
||||||
}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
|
}DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
|
||||||
|
|
||||||
// struct PIN_WORKER_CONTEXT
|
// struct PIN_WORKER_CONTEXT
|
||||||
|
@ -115,7 +89,6 @@ typedef struct
|
||||||
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
PKSAUDIO_SUBDEVICE_ENTRY Entry;
|
||||||
KSPIN_CONNECT * PinConnect;
|
KSPIN_CONNECT * PinConnect;
|
||||||
PDISPATCH_CONTEXT DispatchContext;
|
PDISPATCH_CONTEXT DispatchContext;
|
||||||
PSYSAUDIO_CLIENT AudioClient;
|
|
||||||
PSYSAUDIODEVEXT DeviceExtension;
|
PSYSAUDIODEVEXT DeviceExtension;
|
||||||
PKSDATAFORMAT_WAVEFORMATEX MixerFormat;
|
PKSDATAFORMAT_WAVEFORMATEX MixerFormat;
|
||||||
PIO_WORKITEM WorkItem;
|
PIO_WORKITEM WorkItem;
|
||||||
|
|
Loading…
Reference in a new issue