mirror of
https://github.com/reactos/reactos.git
synced 2025-02-23 17:05:46 +00:00
- Fix a bug in the audio_test programm which initialized the deviceinfo before another syscall
- Complete also an unhandeled irp - Implement IOCTL_CLOSE_WDMAUD - Account the number of times pin can be instantiated in sysaudio and apply changes to SYSAUDIO_CLIENT structure - There is still a bug which prevents closing the audio adapter at the 2nd time svn path=/trunk/; revision=39753
This commit is contained in:
parent
a15e6fe4ad
commit
866d5ef497
8 changed files with 188 additions and 87 deletions
|
@ -39,6 +39,7 @@ main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
printf("WDMAUD: opened\n");
|
||||
|
||||
/* clear device info */
|
||||
RtlZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO));
|
||||
|
||||
|
@ -61,20 +62,13 @@ main(int argc, char* argv[])
|
|||
}
|
||||
|
||||
printf("WDMAUD: Num Devices %lu\n", DeviceInfo.DeviceCount);
|
||||
|
||||
if (!DeviceInfo.DeviceCount)
|
||||
{
|
||||
CloseHandle(hWdmAud);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
|
||||
DeviceInfo.u.WaveFormatEx.wFormatTag = 0x1; //WAVE_FORMAT_PCM;
|
||||
DeviceInfo.u.WaveFormatEx.nChannels = 2;
|
||||
DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000;
|
||||
DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
|
||||
DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4;
|
||||
DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
|
||||
|
||||
Status = DeviceIoControl(hWdmAud, IOCTL_GETCAPABILITIES, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
|
||||
|
||||
if (!Status)
|
||||
|
@ -84,6 +78,16 @@ main(int argc, char* argv[])
|
|||
printf("Failed to get iocaps %lx\n", GetLastError());
|
||||
}
|
||||
}
|
||||
printf("WDMAUD: Capabilites NumChannels %x dwFormats %lx\n", DeviceInfo.u.WaveOutCaps.wChannels, DeviceInfo.u.WaveOutCaps.dwFormats);
|
||||
|
||||
DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX);
|
||||
DeviceInfo.u.WaveFormatEx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
DeviceInfo.u.WaveFormatEx.nChannels = 2;
|
||||
DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 48000;
|
||||
DeviceInfo.u.WaveFormatEx.nBlockAlign = 4;
|
||||
DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 48000 * 4;
|
||||
DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16;
|
||||
|
||||
|
||||
|
||||
Status = DeviceIoControl(hWdmAud, IOCTL_OPEN_WDMAUD, (LPVOID)&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), &BytesReturned, &Overlapped);
|
||||
|
@ -97,8 +101,7 @@ main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
printf("WDMAUD: opened device\n");
|
||||
|
||||
//
|
||||
// Allocate a buffer for 1 second
|
||||
|
@ -163,8 +166,8 @@ main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
printf("WDMAUD: STOPPED\n");
|
||||
CloseHandle(hWdmAud);
|
||||
CloseHandle(&Overlapped.hEvent);
|
||||
CloseHandle(hWdmAud);
|
||||
printf("WDMAUD: COMPLETE\n");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -225,6 +225,7 @@ PcPropertyHandler(
|
|||
RtlFreeUnicodeString(&GuidString);
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
|
|
@ -371,13 +371,14 @@ WdmAudCapabilities(
|
|||
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||
IN PWDMAUD_CLIENT ClientInfo)
|
||||
{
|
||||
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
||||
KSP_PIN PinProperty;
|
||||
KSCOMPONENTID ComponentId;
|
||||
KSMULTIPLE_ITEM * MultipleItem;
|
||||
ULONG BytesReturned;
|
||||
PKSDATARANGE_AUDIO DataRangeAudio;
|
||||
PKSDATARANGE DataRange;
|
||||
NTSTATUS Status;
|
||||
|
||||
ULONG Index;
|
||||
ULONG wChannels = 0;
|
||||
ULONG dwFormats = 0;
|
||||
|
@ -420,8 +421,6 @@ WdmAudCapabilities(
|
|||
return SetIrpIoStatus(Irp, Status, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
MultipleItem = ExAllocatePool(NonPagedPool, BytesReturned);
|
||||
if (!MultipleItem)
|
||||
{
|
||||
|
@ -477,6 +476,31 @@ WdmAudCapabilities(
|
|||
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
WdmAudClose(
|
||||
IN PDEVICE_OBJECT DeviceObject,
|
||||
IN PIRP Irp,
|
||||
IN PWDMAUD_DEVICE_INFO DeviceInfo,
|
||||
IN PWDMAUD_CLIENT ClientInfo)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for(Index = 0; Index < ClientInfo->NumPins; Index++)
|
||||
{
|
||||
if (ClientInfo->hPins[Index] == DeviceInfo->hDevice)
|
||||
{
|
||||
DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
|
||||
ZwClose(DeviceInfo->hDevice);
|
||||
ClientInfo->hPins[Index] = NULL;
|
||||
SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
WdmAudDeviceControl(
|
||||
|
@ -530,6 +554,7 @@ WdmAudDeviceControl(
|
|||
case IOCTL_GETCAPABILITIES:
|
||||
return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
||||
case IOCTL_CLOSE_WDMAUD:
|
||||
return WdmAudClose(DeviceObject, Irp, DeviceInfo, ClientInfo);
|
||||
case IOCTL_GETDEVID:
|
||||
case IOCTL_GETVOLUME:
|
||||
case IOCTL_SETVOLUME:
|
||||
|
|
|
@ -203,7 +203,12 @@ WdmAudCleanup(
|
|||
if (pClient)
|
||||
{
|
||||
for (Index = 0; Index < pClient->NumPins; Index++)
|
||||
ZwClose(pClient->hPins[Index]);
|
||||
{
|
||||
if (pClient->hPins[Index])
|
||||
{
|
||||
ZwClose(pClient->hPins[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
if (pClient->hPins)
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define YDEBUG
|
||||
#include <debug.h>
|
||||
#include <ksmedia.h>
|
||||
#include <mmsystem.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
#include "interface.h"
|
||||
|
||||
|
|
|
@ -58,8 +58,7 @@ SysAudioOpenVirtualDevice(
|
|||
IN ULONG DeviceNumber,
|
||||
PSYSAUDIODEVEXT DeviceExtension)
|
||||
{
|
||||
PULONG Index;
|
||||
PHANDLE Handle;
|
||||
PSYSAUDIO_CLIENT_HANDELS Index;
|
||||
ULONG Count;
|
||||
PSYSAUDIO_CLIENT ClientInfo;
|
||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||
|
@ -85,23 +84,17 @@ SysAudioOpenVirtualDevice(
|
|||
if (!ClientInfo->NumDevices)
|
||||
{
|
||||
/* first device to be openend */
|
||||
ClientInfo->Devices = ExAllocatePool(NonPagedPool, sizeof(ULONG));
|
||||
if (!ClientInfo->Devices)
|
||||
{
|
||||
/* no memory */
|
||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||
}
|
||||
|
||||
ClientInfo->Handels = ExAllocatePool(NonPagedPool, sizeof(HANDLE));
|
||||
if (!ClientInfo->Devices)
|
||||
ClientInfo->Devs = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS));
|
||||
if (!ClientInfo->Devs)
|
||||
{
|
||||
/* no memory */
|
||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||
}
|
||||
|
||||
ClientInfo->NumDevices = 1;
|
||||
ClientInfo->Devices[0] = DeviceNumber;
|
||||
ClientInfo->Handels[0] = NULL;
|
||||
ClientInfo->Devs[0].DeviceId = DeviceNumber;
|
||||
ClientInfo->Devs[0].ClientHandles = NULL;
|
||||
ClientInfo->Devs[0].ClientHandlesCount = 0;
|
||||
/* increase usage count */
|
||||
Entry->NumberOfClients++;
|
||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||
|
@ -110,46 +103,37 @@ SysAudioOpenVirtualDevice(
|
|||
/* check if device has already been openend */
|
||||
for(Count = 0; Count < ClientInfo->NumDevices; Count++)
|
||||
{
|
||||
if (ClientInfo->Devices[Count] == DeviceNumber)
|
||||
if (ClientInfo->Devs[Count].DeviceId == DeviceNumber)
|
||||
{
|
||||
/* device has already been opened */
|
||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||
}
|
||||
}
|
||||
/* new device to be openend */
|
||||
Index = ExAllocatePool(NonPagedPool, sizeof(ULONG) * (ClientInfo->NumDevices + 1));
|
||||
Index = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS) * (ClientInfo->NumDevices + 1));
|
||||
if (!Index)
|
||||
{
|
||||
/* no memory */
|
||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||
}
|
||||
|
||||
Handle = ExAllocatePool(NonPagedPool, sizeof(HANDLE) * (ClientInfo->NumDevices + 1));
|
||||
if (!Handle)
|
||||
if (ClientInfo->NumDevices)
|
||||
{
|
||||
/* no memory */
|
||||
ExFreePool(Index);
|
||||
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
|
||||
/* copy device count array */
|
||||
RtlMoveMemory(Index, ClientInfo->Devs, ClientInfo->NumDevices * sizeof(SYSAUDIO_CLIENT_HANDELS));
|
||||
}
|
||||
|
||||
Index[ClientInfo->NumDevices].DeviceId = DeviceNumber;
|
||||
Index[ClientInfo->NumDevices].ClientHandlesCount = 0;
|
||||
Index[ClientInfo->NumDevices].ClientHandles = NULL;
|
||||
|
||||
/* increase usage count */
|
||||
Entry->NumberOfClients++;
|
||||
|
||||
/* copy device count array */
|
||||
if (ClientInfo->NumDevices)
|
||||
{
|
||||
RtlMoveMemory(Index, ClientInfo->Devices, ClientInfo->NumDevices * sizeof(ULONG));
|
||||
RtlMoveMemory(Handle, ClientInfo->Handels, ClientInfo->NumDevices * sizeof(HANDLE));
|
||||
}
|
||||
ExFreePool(ClientInfo->Devs);
|
||||
|
||||
Index[ClientInfo->NumDevices] = DeviceNumber;
|
||||
Handle[ClientInfo->NumDevices] = NULL;
|
||||
ExFreePool(ClientInfo->Handels);
|
||||
ExFreePool(ClientInfo->Devices);
|
||||
ClientInfo->Devs = Index;
|
||||
ClientInfo->NumDevices++;
|
||||
ClientInfo->Devices = Index;
|
||||
ClientInfo->Handels = Handle;
|
||||
|
||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||
}
|
||||
|
||||
|
@ -160,9 +144,12 @@ CreatePinWorkerRoutine(
|
|||
IN PVOID Context)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
HANDLE PinHandle;
|
||||
PSYSAUDIO_CLIENT AudioClient;
|
||||
HANDLE RealPinHandle, VirtualPinHandle;
|
||||
HANDLE Filter;
|
||||
ULONG NumHandels;
|
||||
PFILE_OBJECT FileObject;
|
||||
PSYSAUDIO_PIN_HANDLE ClientPinHandle;
|
||||
PPIN_WORKER_CONTEXT WorkerContext = (PPIN_WORKER_CONTEXT)Context;
|
||||
Filter = WorkerContext->PinConnect->PinToHandle;
|
||||
|
||||
|
@ -172,7 +159,7 @@ CreatePinWorkerRoutine(
|
|||
if (WorkerContext->CreateRealPin)
|
||||
{
|
||||
/* create the real pin */
|
||||
Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
|
||||
Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Failed to create Pin with %x\n", Status);
|
||||
|
@ -182,13 +169,18 @@ CreatePinWorkerRoutine(
|
|||
}
|
||||
|
||||
/* get pin file object */
|
||||
Status = ObReferenceObjectByHandle(PinHandle,
|
||||
Status = ObReferenceObjectByHandle(RealPinHandle,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = PinHandle;
|
||||
if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1)
|
||||
{
|
||||
/* store the pin handle there is the pin can only be instantiated once*/
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle;
|
||||
}
|
||||
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 1;
|
||||
WorkerContext->DispatchContext->Handle = PinHandle;
|
||||
WorkerContext->DispatchContext->Handle = RealPinHandle;
|
||||
WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
|
||||
WorkerContext->DispatchContext->AudioEntry = WorkerContext->Entry;
|
||||
|
||||
|
@ -204,7 +196,7 @@ CreatePinWorkerRoutine(
|
|||
WorkerContext->DispatchContext->PinId = WorkerContext->PinConnect->PinId;
|
||||
|
||||
/* get pin file object */
|
||||
Status = ObReferenceObjectByHandle(PinHandle,
|
||||
Status = ObReferenceObjectByHandle(WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||
|
||||
|
@ -220,7 +212,7 @@ CreatePinWorkerRoutine(
|
|||
|
||||
DPRINT1("creating virtual pin\n");
|
||||
/* now create the virtual audio pin which is exposed to wdmaud */
|
||||
Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
|
||||
Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle);
|
||||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
|
@ -237,7 +229,7 @@ CreatePinWorkerRoutine(
|
|||
}
|
||||
|
||||
/* get pin file object */
|
||||
Status = ObReferenceObjectByHandle(PinHandle,
|
||||
Status = ObReferenceObjectByHandle(VirtualPinHandle,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
|
||||
|
||||
|
@ -250,7 +242,7 @@ CreatePinWorkerRoutine(
|
|||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References = 0;
|
||||
}
|
||||
|
||||
ZwClose(PinHandle);
|
||||
ZwClose(VirtualPinHandle);
|
||||
SetIrpIoStatus(WorkerContext->Irp, STATUS_UNSUCCESSFUL, 0);
|
||||
ExFreePool(WorkerContext);
|
||||
return;
|
||||
|
@ -261,19 +253,59 @@ CreatePinWorkerRoutine(
|
|||
ASSERT(WorkerContext->DispatchContext->FileObject != NULL);
|
||||
ASSERT(WorkerContext->DispatchContext->Handle != NULL);
|
||||
ASSERT(WorkerContext->AudioClient);
|
||||
ASSERT(WorkerContext->AudioClient->Handels);
|
||||
ASSERT(WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices -1] == NULL);
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].bHandle = FALSE;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].hPin = NULL;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandles[NumHandels].PinId = WorkerContext->PinConnect->PinId;
|
||||
}
|
||||
|
||||
/// increase reference count
|
||||
WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].References++;
|
||||
AudioClient->Devs[AudioClient->NumDevices -1].ClientHandlesCount++;
|
||||
}
|
||||
|
||||
|
||||
/* store pin context */
|
||||
FileObject->FsContext2 = (PVOID)WorkerContext->DispatchContext;
|
||||
|
||||
/* store pin handle in client specific struct */
|
||||
WorkerContext->AudioClient->Handels[WorkerContext->AudioClient->NumDevices-1] = PinHandle;
|
||||
|
||||
DPRINT1("Successfully created Pin %p\n", WorkerContext->Irp);
|
||||
*((PHANDLE)WorkerContext->Irp->UserBuffer) = PinHandle;
|
||||
DPRINT1("Successfully created virtual pin %p\n", VirtualPinHandle);
|
||||
*((PHANDLE)WorkerContext->Irp->UserBuffer) = VirtualPinHandle;
|
||||
|
||||
SetIrpIoStatus(WorkerContext->Irp, STATUS_SUCCESS, sizeof(HANDLE));
|
||||
ExFreePool(WorkerContext);
|
||||
}
|
||||
|
||||
|
||||
|
@ -425,7 +457,7 @@ SysAudioHandleProperty(
|
|||
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
|
||||
}
|
||||
/* store last opened device number */
|
||||
*Index = ClientInfo->Devices[ClientInfo->NumDevices-1];
|
||||
*Index = ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId;
|
||||
/* found no device with that device index open */
|
||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG));
|
||||
}
|
||||
|
@ -458,7 +490,7 @@ SysAudioHandleProperty(
|
|||
}
|
||||
for(Count = 0; Count < ClientInfo->NumDevices; Count++)
|
||||
{
|
||||
if (ClientInfo->Devices[Count] == InstanceInfo->DeviceNumber)
|
||||
if (ClientInfo->Devs[Count].DeviceId == InstanceInfo->DeviceNumber)
|
||||
{
|
||||
/* specified device is open */
|
||||
return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0);
|
||||
|
@ -493,8 +525,8 @@ SysAudioHandleProperty(
|
|||
ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context;
|
||||
ASSERT(ClientInfo);
|
||||
ASSERT(ClientInfo->NumDevices >= 1);
|
||||
ASSERT(ClientInfo->Devices != NULL);
|
||||
ASSERT(ClientInfo->Devices[ClientInfo->NumDevices-1] == InstanceInfo->DeviceNumber);
|
||||
ASSERT(ClientInfo->Devs != NULL);
|
||||
ASSERT(ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId == InstanceInfo->DeviceNumber);
|
||||
|
||||
/* get sysaudio entry */
|
||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, InstanceInfo->DeviceNumber);
|
||||
|
@ -541,14 +573,14 @@ SysAudioHandleProperty(
|
|||
PinRequest.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
PinRequest.Property.Id = KSPROPERTY_PIN_CINSTANCES;
|
||||
|
||||
//RtlZeroMemory(&PinInstances, sizeof(KSPIN_CINSTANCES));
|
||||
Status = KsSynchronousIoControlDevice(Entry->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)&PinInstances, sizeof(KSPIN_CINSTANCES), &BytesReturned);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Property Request KSPROPERTY_PIN_GLOBALCINSTANCES failed with %x\n", Status);
|
||||
return SetIrpIoStatus(Irp, Status, 0);
|
||||
}
|
||||
DPRINT1("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount);
|
||||
DPRINT("PinInstances Current %u Max %u\n", PinInstances.CurrentCount, PinInstances.PossibleCount);
|
||||
Entry->Pins[PinConnect->PinId].MaxPinInstanceCount = PinInstances.PossibleCount;
|
||||
|
||||
WorkItem = IoAllocateWorkItem(DeviceObject);
|
||||
if (!WorkItem)
|
||||
|
@ -588,10 +620,10 @@ SysAudioHandleProperty(
|
|||
DbgBreakPoint();
|
||||
ASSERT(Entry->Pins[PinConnect->PinId].PinHandle != NULL);
|
||||
|
||||
if (Entry->Pins[PinConnect->PinId].References != 0)
|
||||
if (Entry->Pins[PinConnect->PinId].References > 1)
|
||||
{
|
||||
/* FIXME need ksmixer */
|
||||
DPRINT1("Device %u Pin %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId);
|
||||
DPRINT1("Device %u Pin %u References %u is already occupied, try later\n", InstanceInfo->DeviceNumber, PinConnect->PinId, Entry->Pins[PinConnect->PinId].References);
|
||||
IoFreeWorkItem(WorkItem);
|
||||
ExFreePool(WorkerContext);
|
||||
ExFreePool(DispatchContext);
|
||||
|
|
|
@ -91,30 +91,48 @@ Dispatch_fnClose(
|
|||
PIRP Irp)
|
||||
{
|
||||
PSYSAUDIO_CLIENT Client;
|
||||
PKSAUDIO_DEVICE_ENTRY Entry;
|
||||
PIO_STACK_LOCATION IoStatus;
|
||||
ULONG Index;
|
||||
|
||||
|
||||
DPRINT1("Dispatch_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
|
||||
ULONG Index, SubIndex;
|
||||
PSYSAUDIODEVEXT DeviceExtension;
|
||||
|
||||
IoStatus = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
Client = (PSYSAUDIO_CLIENT)IoStatus->FileObject->FsContext2;
|
||||
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension;
|
||||
|
||||
|
||||
DPRINT1("Client %p NumDevices %u\n", Client, Client->NumDevices);
|
||||
for(Index = 0; Index < Client->NumDevices; Index++)
|
||||
{
|
||||
if (Client->Handels[Index])
|
||||
if (Client->Devs[Index].ClientHandlesCount)
|
||||
{
|
||||
ZwClose(Client->Handels[Index]);
|
||||
Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, Client->Devs[Index].DeviceId);
|
||||
ASSERT(Entry != NULL);
|
||||
|
||||
for(SubIndex = 0; SubIndex < Client->Devs[Index].ClientHandlesCount; SubIndex++)
|
||||
{
|
||||
ASSERT(Entry->NumberOfPins > Client->Devs[Index].ClientHandles[SubIndex].PinId);
|
||||
if (Client->Devs[Index].ClientHandles[SubIndex].bHandle)
|
||||
{
|
||||
DPRINT1("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 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--;
|
||||
}
|
||||
}
|
||||
ExFreePool(Client->Devs[Index].ClientHandles);
|
||||
}
|
||||
}
|
||||
|
||||
if (Client->Handels)
|
||||
ExFreePool(Client->Handels);
|
||||
|
||||
if (Client->Devices)
|
||||
ExFreePool(Client->Devices);
|
||||
if (Client->Devs)
|
||||
ExFreePool(Client->Devs);
|
||||
|
||||
ExFreePool(Client);
|
||||
|
||||
|
@ -250,7 +268,8 @@ DispatchCreateSysAudio(
|
|||
if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN)))
|
||||
{
|
||||
Status = CreateDispatcher(Irp);
|
||||
DPRINT1("Virtual pin Status %x\n", Status);
|
||||
DPRINT1("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject);
|
||||
DbgBreakPoint();
|
||||
Irp->IoStatus.Information = 0;
|
||||
Irp->IoStatus.Status = Status;
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
|
|
@ -1,16 +1,32 @@
|
|||
#ifndef SYSAUDIO_H__
|
||||
#define SYSAUDIO_H__
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BOOL bHandle;
|
||||
ULONG PinId;
|
||||
HANDLE hPin;
|
||||
}SYSAUDIO_PIN_HANDLE, *PSYSAUDIO_PIN_HANDLE;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG DeviceId;
|
||||
ULONG ClientHandlesCount;
|
||||
PSYSAUDIO_PIN_HANDLE ClientHandles;
|
||||
|
||||
}SYSAUDIO_CLIENT_HANDELS, *PSYSAUDIO_CLIENT_HANDELS;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG NumDevices;
|
||||
PULONG Devices;
|
||||
PHANDLE Handels;
|
||||
PSYSAUDIO_CLIENT_HANDELS Devs;
|
||||
|
||||
}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG MaxPinInstanceCount;
|
||||
HANDLE PinHandle;
|
||||
ULONG References;
|
||||
}PIN_INFO;
|
||||
|
|
Loading…
Reference in a new issue