NTSTATUS WdmAudControlDeviceState( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { KSPROPERTY Property; KSSTATE State; NTSTATUS Status; ULONG BytesReturned; PFILE_OBJECT FileObject; DPRINT("WdmAudControlDeviceState\n"); Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } Property.Set = KSPROPSETID_Connection; Property.Id = KSPROPERTY_CONNECTION_STATE; Property.Flags = KSPROPERTY_TYPE_SET; State = DeviceInfo->u.State; Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned); ObDereferenceObject(FileObject); DPRINT("WdmAudControlDeviceState Status %x\n", Status); return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); }
NTSTATUS NTAPI WdmAudResetStream( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PWDMAUD_DEVICE_INFO DeviceInfo) { KSRESET ResetStream; NTSTATUS Status; ULONG BytesReturned; PFILE_OBJECT FileObject; DPRINT("WdmAudResetStream\n"); Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType); return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } ResetStream = DeviceInfo->u.ResetStream; ASSERT(ResetStream == KSRESET_BEGIN || ResetStream == KSRESET_END); Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_RESET_STATE, (PVOID)&ResetStream, sizeof(KSRESET), NULL, 0, &BytesReturned); ObDereferenceObject(FileObject); DPRINT("WdmAudResetStream Status %x\n", Status); return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); }
NTSTATUS GetSysAudioDevicePnpName( IN PDEVICE_OBJECT DeviceObject, IN ULONG DeviceIndex, OUT LPWSTR * Device) { ULONG BytesReturned; KSP_PIN Pin; NTSTATUS Status; PWDMAUD_DEVICE_EXTENSION DeviceExtension; /* first check if the device index is within bounds */ if (DeviceIndex >= GetSysAudioDeviceCount(DeviceObject)) return STATUS_INVALID_PARAMETER; /* setup the query request */ Pin.Property.Set = KSPROPSETID_Sysaudio; Pin.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME; Pin.Property.Flags = KSPROPERTY_TYPE_GET; Pin.PinId = DeviceIndex; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; /* query sysaudio for the device path */ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), NULL, 0, &BytesReturned); /* check if the request failed */ if (Status != STATUS_BUFFER_TOO_SMALL || BytesReturned == 0) return STATUS_UNSUCCESSFUL; /* allocate buffer for the device */ *Device = AllocateItem(NonPagedPool, BytesReturned); if (!Device) return STATUS_INSUFFICIENT_RESOURCES; /* query sysaudio again for the device path */ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY) + sizeof(ULONG), (PVOID)*Device, BytesReturned, &BytesReturned); if (!NT_SUCCESS(Status)) { /* failed */ FreeItem(*Device); return Status; } return Status; }
NTSTATUS NTAPI Pin_fnDeviceIoControl( PDEVICE_OBJECT DeviceObject, PIRP Irp) { PDISPATCH_CONTEXT Context; NTSTATUS Status; ULONG BytesReturned; PFILE_OBJECT FileObject = NULL; PIO_STACK_LOCATION IoStack; DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject, Irp); /* Get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); /* The dispatch context is stored in the FsContext member */ Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; /* Sanity check */ ASSERT(Context); /* 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(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; Irp->IoStatus.Status = Status; /* Complete the irp */ IoCompleteRequest(Irp, IO_NO_INCREMENT); /* Done */ return Status; }
NTSTATUS NTAPI AudioPositionPropertyHandler( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { PKSFILTER Filter; PKSPIN Pin, FirstPin; PFILE_OBJECT FileObject; NTSTATUS Status; ULONG BytesReturned; /* first get the pin */ Pin = KsGetPinFromIrp(Irp); /* sanity check */ ASSERT(Pin); /* get parent filter */ Filter = KsPinGetParentFilter(Pin); /* acquire filter control mutex */ KsFilterAcquireControl(Filter); /* get first pin */ FirstPin = KsFilterGetFirstChildPin(Filter, Pin->Id); /* get connected pin of first pin */ FileObject = KsPinGetConnectedPinFileObject(FirstPin); if (!FileObject) { /* no pin connected */ Status = STATUS_INVALID_PARAMETER; } else { /* perform request */ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)Request, sizeof(KSPROPERTY), Data, sizeof(KSAUDIO_POSITION), &BytesReturned); /* store result size */ Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); } /* release control */ KsFilterReleaseControl(Filter); /* done */ return Status; }
NTSTATUS SetMixerInputOutputFormat( IN PFILE_OBJECT FileObject, IN PKSDATAFORMAT InputFormat, IN PKSDATAFORMAT OutputFormat) { KSP_PIN PinRequest; ULONG BytesReturned; NTSTATUS Status; /* re-using pin */ PinRequest.Property.Set = KSPROPSETID_Connection; PinRequest.Property.Flags = KSPROPERTY_TYPE_SET; PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT; /* set the input format */ PinRequest.PinId = 0; DPRINT("InputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", InputFormat, InputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX)); Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)InputFormat, InputFormat->FormatSize, &BytesReturned); if (!NT_SUCCESS(Status)) return Status; /* set the the output format */ PinRequest.PinId = 1; DPRINT("OutputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", OutputFormat, OutputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX)); Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinRequest, sizeof(KSP_PIN), (PVOID)OutputFormat, OutputFormat->FormatSize, &BytesReturned); return Status; }
MIXER_STATUS CreatePinCallback( IN PVOID Ctx, IN ULONG VirtualDeviceId, IN ULONG PinId, IN HANDLE hFilter, IN PKSPIN_CONNECT PinConnect, IN ACCESS_MASK DesiredAccess, OUT PHANDLE PinHandle) { ULONG BytesReturned; SYSAUDIO_INSTANCE_INFO InstanceInfo; NTSTATUS Status; ULONG FreeIndex; PPIN_CREATE_CONTEXT Context = (PPIN_CREATE_CONTEXT)Ctx; /* setup property request */ InstanceInfo.Property.Set = KSPROPSETID_Sysaudio; InstanceInfo.Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO; InstanceInfo.Property.Flags = KSPROPERTY_TYPE_SET; InstanceInfo.Flags = 0; InstanceInfo.DeviceNumber = VirtualDeviceId; /* attach to virtual device */ Status = KsSynchronousIoControlDevice(Context->DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned); if (!NT_SUCCESS(Status)) return MM_STATUS_UNSUCCESSFUL; /* close existing pin */ FreeIndex = ClosePin(Context->ClientInfo, VirtualDeviceId, PinId, Context->DeviceType); /* now create the pin */ Status = KsCreatePin(Context->DeviceExtension->hSysAudio, PinConnect, DesiredAccess, PinHandle); /* check for success */ if (!NT_SUCCESS(Status)) return MM_STATUS_UNSUCCESSFUL; /* store the handle */ Status = InsertPinHandle(Context->ClientInfo, VirtualDeviceId, PinId, Context->DeviceType, *PinHandle, FreeIndex); if (!NT_SUCCESS(Status)) { /* failed to insert handle */ ZwClose(*PinHandle); return MM_STATUS_UNSUCCESSFUL; } return MM_STATUS_SUCCESS; }
MIXER_STATUS Control( IN HANDLE hMixer, IN ULONG dwIoControlCode, IN PVOID lpInBuffer, IN ULONG nInBufferSize, OUT PVOID lpOutBuffer, ULONG nOutBufferSize, PULONG lpBytesReturned) { NTSTATUS Status; PFILE_OBJECT FileObject; /* get file object */ Status = ObReferenceObjectByHandle(hMixer, GENERIC_READ | GENERIC_WRITE, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT("failed to reference %p with %lx\n", hMixer, Status); return MM_STATUS_UNSUCCESSFUL; } /* perform request */ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned); /* release object reference */ ObDereferenceObject(FileObject); if (Status == STATUS_MORE_ENTRIES || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) { /* more data is available */ return MM_STATUS_MORE_ENTRIES; } else if (Status == STATUS_SUCCESS) { /* operation succeeded */ return MM_STATUS_SUCCESS; } else { DPRINT("Failed with %lx\n", Status); return MM_STATUS_UNSUCCESSFUL; } }
NTSTATUS NTAPI WdmAudFrameSize( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PWDMAUD_DEVICE_INFO DeviceInfo, IN PWDMAUD_CLIENT ClientInfo) { PFILE_OBJECT FileObject; KSPROPERTY Property; ULONG BytesReturned; KSALLOCATOR_FRAMING Framing; NTSTATUS Status; /* Get sysaudio pin file object */ Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Invalid buffer handle %p\n", DeviceInfo->hDevice); return SetIrpIoStatus(Irp, Status, 0); } /* Setup get framing request */ Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING; Property.Flags = KSPROPERTY_TYPE_GET; Property.Set = KSPROPSETID_Connection; Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned); /* Did we succeed */ if (NT_SUCCESS(Status)) { /* Store framesize */ DeviceInfo->u.FrameSize = Framing.FrameSize; } /* Release file object */ ObDereferenceObject(FileObject); return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO)); }
ULONG GetSysAudioDeviceCount( IN PDEVICE_OBJECT DeviceObject) { PWDMAUD_DEVICE_EXTENSION DeviceExtension; KSPROPERTY Pin; ULONG Count, BytesReturned; NTSTATUS Status; /* setup the query request */ Pin.Set = KSPROPSETID_Sysaudio; Pin.Id = KSPROPERTY_SYSAUDIO_DEVICE_COUNT; Pin.Flags = KSPROPERTY_TYPE_GET; DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; /* query sysaudio for the device count */ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSPROPERTY), (PVOID)&Count, sizeof(ULONG), &BytesReturned); if (!NT_SUCCESS(Status)) return 0; return Count; }