- convert wdmaud to a software pnp device
- register device interface
[WDMAUD.DRV]
- open wdmaud via device interface

svn path=/trunk/; revision=66709
This commit is contained in:
Johannes Anderwald 2015-03-14 17:50:30 +00:00
parent 249fea034e
commit c7133edff8
9 changed files with 122 additions and 91 deletions

View file

@ -255,25 +255,64 @@ WdmAudOpenSoundDeviceByLegacy(
IN PSOUND_DEVICE SoundDevice,
OUT PVOID *Handle)
{
/* Only open this if it's not already open */
HDEVINFO hDevInfo;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
GUID SWBusGuid = {STATIC_KSCATEGORY_WDMAUD};
PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData;
if ( KernelHandle == INVALID_HANDLE_VALUE )
{
SND_TRACE(L"Opening wdmaud device\n");
KernelHandle = CreateFileW(KERNEL_DEVICE_NAME,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
hDevInfo = SetupDiGetClassDevsW(&SWBusGuid, NULL, NULL, DIGCF_DEVICEINTERFACE| DIGCF_PRESENT);
if (!hDevInfo)
{
// failed
return MMSYSERR_ERROR;
}
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
if (!SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &SWBusGuid, 0, &DeviceInterfaceData))
{
// failed
SetupDiDestroyDeviceInfoList(hDevInfo);
return MMSYSERR_ERROR;
}
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W));
if (!DeviceInterfaceDetailData)
{
// failed
SetupDiDestroyDeviceInfoList(hDevInfo);
return MMSYSERR_ERROR;
}
DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
if (!SetupDiGetDeviceInterfaceDetailW(hDevInfo, &DeviceInterfaceData, DeviceInterfaceDetailData,MAX_PATH * sizeof(WCHAR) + sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W), NULL, NULL))
{
// failed
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(hDevInfo);
return MMSYSERR_ERROR;
}
SND_TRACE(L"Opening wdmaud device '%s'\n",DeviceInterfaceDetailData->DevicePath);
KernelHandle = CreateFileW(DeviceInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(hDevInfo);
}
if ( KernelHandle == INVALID_HANDLE_VALUE )
return MMSYSERR_ERROR;
++ OpenCount;
return MMSYSERR_NOERROR;
return MMSYSERR_NOERROR;
}
MMRESULT

View file

@ -8,12 +8,16 @@
#define COM_NO_WINDOWS_H
#include <windef.h>
#include <winbase.h>
#include <winreg.h>
#include <winuser.h>
#include <mmddk.h>
#include <mmebuddy.h>
#include <ksmedia.h>
#include <interface.h>
#include <devioctl.h>
#include <setupapi.h>
BOOL
WdmAudInitUserModeMixer(VOID);

View file

@ -11,6 +11,8 @@
#define NDEBUG
#include <debug.h>
#define TAG_KS 'ssKK'
VOID
CompleteRequest(
PIRP Irp,
@ -29,7 +31,7 @@ AllocateItem(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes)
{
PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
PVOID Item = ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_KS);
if (!Item)
return Item;

View file

@ -49,9 +49,6 @@ WdmAudControlDeviceType(
{
ULONG Result = 0;
NTSTATUS Status = STATUS_SUCCESS;
//PWDMAUD_DEVICE_EXTENSION DeviceExtension;
//DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
@ -231,14 +228,10 @@ WdmAudGetDeviceInterface(
IN PIRP Irp,
IN PWDMAUD_DEVICE_INFO DeviceInfo)
{
//PWDMAUD_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
LPWSTR Device;
ULONG Size, Length;
/* get device extension */
//DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get device interface string input length */
Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
@ -420,19 +413,11 @@ IoCompletion (
/* grab next mdl */
Mdl = NextMdl;
}
//IoFreeMdl(Mdl);
/* clear mdl list */
Irp->MdlAddress = NULL;
Irp->MdlAddress = Context->Mdl;
/* check if mdl is locked */
if (Context->Mdl->MdlFlags & MDL_PAGES_LOCKED)
{
/* unlock pages */
MmUnlockPages(Context->Mdl);
}
/* now free the mdl */
IoFreeMdl(Context->Mdl);
DPRINT("IoCompletion Irp %p IoStatus %lx Information %lx Length %lu\n", Irp, Irp->IoStatus.Status, Irp->IoStatus.Information, Length);
@ -442,6 +427,9 @@ IoCompletion (
Irp->IoStatus.Information = 0;
}
/* dereference file object */
ObDereferenceObject(Context->FileObject);
/* free context */
FreeItem(Context);
@ -502,8 +490,6 @@ WdmAudReadWrite(
/* remove mdladdress as KsProbeStreamIrp will interprete it as an already probed audio buffer */
Irp->MdlAddress = NULL;
/* check for success */
if (IoStack->MajorFunction == IRP_MJ_WRITE)
{
/* probe the write stream irp */
@ -520,6 +506,7 @@ WdmAudReadWrite(
{
DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
Irp->MdlAddress = Mdl;
FreeItem(Context);
return SetIrpIoStatus(Irp, Status, 0);
}
@ -532,39 +519,30 @@ WdmAudReadWrite(
if (!NT_SUCCESS(Status))
{
DPRINT1("Invalid pin handle %p\n", DeviceInfo->hDevice);
Irp->MdlAddress = Mdl;
FreeItem(Context);
return SetIrpIoStatus(Irp, Status, 0);
}
/* store file object whose reference is released in the completion callback */
Context->FileObject = FileObject;
/* skip current irp stack location */
IoSkipCurrentIrpStackLocation(Irp);
/* get next stack location */
IoStack = IoGetNextIrpStackLocation(Irp);
if (Read)
{
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_READ_STREAM;
}
else
{
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM;
}
/* attach file object */
/* prepare stack location */
IoStack->FileObject = FileObject;
IoStack->Parameters.Write.Length = Length;
IoStack->MajorFunction = IRP_MJ_WRITE;
IoStack->Parameters.DeviceIoControl.IoControlCode = (Read ? IOCTL_KS_READ_STREAM : IOCTL_KS_WRITE_STREAM);
IoSetCompletionRoutine(Irp, IoCompletion, (PVOID)Context, TRUE, TRUE, TRUE);
/* mark irp as pending */
// IoMarkIrpPending(Irp);
/* call the driver */
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
/* dereference file object */
ObDereferenceObject(FileObject);
return Status;
}

View file

@ -153,17 +153,19 @@ WdmAudOpenSysAudioDevices(
return Status;
}
InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
DeviceExtension->NumSysAudioDevices++;
DPRINT("Opening device %S\n", Entry->SymbolicLink.Buffer);
Status = WdmAudOpenSysAudioDevice(Entry->SymbolicLink.Buffer, &hSysAudio);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to open sysaudio %x\n", Status);
FreeItem(Entry->SymbolicLink.Buffer);
FreeItem(Entry);
return Status;
}
InsertTailList(&DeviceExtension->SysAudioDeviceList, &Entry->Entry);
DeviceExtension->NumSysAudioDevices++;
/* get the file object */
Status = ObReferenceObjectByHandle(hSysAudio, FILE_READ_DATA | FILE_WRITE_DATA, *IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status))
@ -186,8 +188,6 @@ WdmAudRegisterDeviceInterface(
IN PWDMAUD_DEVICE_EXTENSION DeviceExtension)
{
NTSTATUS Status;
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
UNICODE_STRING SymbolicLinkName;
Status = IoRegisterDeviceInterface(PhysicalDeviceObject, &KSCATEGORY_WDMAUD, NULL, &SymbolicLinkName);
@ -195,20 +195,7 @@ WdmAudRegisterDeviceInterface(
{
IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
RtlFreeUnicodeString(&SymbolicLinkName);
DeviceExtension->DeviceInterfaceSupport = TRUE;
return Status;
}
/* failed to register device interface
* create a symbolic link instead
*/
DeviceExtension->DeviceInterfaceSupport = FALSE;
Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName);
if (!NT_SUCCESS(Status))
{
IoDeleteDevice(PhysicalDeviceObject); //FIXME
DPRINT("Failed to create wdmaud symlink!\n");
//DeviceExtension->DeviceInterfaceSupport = TRUE;
return Status;
}

View file

@ -31,6 +31,19 @@ WdmAudInitWorkerRoutine(
/* get device extension */
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (DeviceExtension->FileObject == NULL)
{
/* find available sysaudio devices */
Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
return;
}
}
/* get device count */
DeviceCount = GetSysAudioDeviceCount(DeviceObject);
@ -61,6 +74,7 @@ WdmAudTimerRoutine(
IN PVOID Context)
{
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
/* get device extension */
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
@ -74,8 +88,9 @@ WdmAudTimerRoutine(
NTSTATUS
NTAPI
WdmAudInstallDevice(
IN PDRIVER_OBJECT DriverObject)
WdmaudAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\wdmaud");
UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\wdmaud");
@ -83,11 +98,11 @@ WdmAudInstallDevice(
NTSTATUS Status;
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
DPRINT("WdmAudInstallDevice called\n");
DPRINT("WdmaudAddDevice called\n");
Status = IoCreateDevice(DriverObject,
sizeof(WDMAUD_DEVICE_EXTENSION),
&DeviceName,
NULL,
FILE_DEVICE_KS,
0,
FALSE,
@ -113,7 +128,7 @@ WdmAudInstallDevice(
}
/* register device interfaces */
Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
Status = WdmAudRegisterDeviceInterface(PhysicalDeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
@ -136,26 +151,20 @@ WdmAudInstallDevice(
/* initialize timer */
IoInitializeTimer(DeviceObject, WdmAudTimerRoutine, (PVOID)WdmAudTimerRoutine);
/* find available sysaudio devices */
Status = WdmAudOpenSysAudioDevices(DeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("WdmAudOpenSysAudioDevices failed with %x\n", Status);
IoDeleteSymbolicLink(&SymlinkName);
IoDeleteDevice(DeviceObject);
return Status;
}
/* allocate ks device header */
Status = KsAllocateDeviceHeader(&DeviceExtension->DeviceHeader, 0, NULL);
if (!NT_SUCCESS(Status))
{
DPRINT1("KsAllocateDeviceHeader failed with %x\n", Status);
IoDeleteSymbolicLink(&SymlinkName);
IoDeleteDevice(DeviceObject);
return Status;
}
/* attach to device stack */
DeviceExtension->NextDeviceObject = IoAttachDeviceToDeviceStack(DeviceObject, PhysicalDeviceObject);
KsSetDevicePnpAndBaseObject(DeviceExtension->DeviceHeader, DeviceExtension->NextDeviceObject, DeviceObject);
/* start the timer */
IoStartTimer(DeviceObject);
@ -203,10 +212,10 @@ WdmAudCreate(
NTSTATUS Status;
PIO_STACK_LOCATION IoStack;
PWDMAUD_CLIENT pClient;
//PWDMAUD_DEVICE_EXTENSION DeviceExtension;
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
/* get device extension */
//DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
#if KS_IMPLEMENTED
Status = KsReferenceSoftwareBusObject((KSDEVICE_HEADER)DeviceObject->DeviceExtension);
@ -217,6 +226,13 @@ WdmAudCreate(
}
#endif
if (DeviceExtension->FileObject == NULL)
{
/* initialize */
WdmAudInitWorkerRoutine(DeviceObject, NULL);
}
Status = WdmAudOpenSysaudio(DeviceObject, &pClient);
if (!NT_SUCCESS(Status))
{
@ -354,6 +370,7 @@ DriverEntry(
Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudReadWrite;
Driver->MajorFunction[IRP_MJ_READ] = WdmAudReadWrite;
Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
Driver->DriverExtension->AddDevice = WdmaudAddDevice;
return WdmAudInstallDevice(Driver);
return STATUS_SUCCESS;
}

View file

@ -14,12 +14,14 @@
#define NDEBUG
#include <debug.h>
#define TAG_WDMAUD 'DMDW'
PVOID
AllocateItem(
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes)
{
PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
PVOID Item = ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_WDMAUD);
if (!Item)
return Item;

View file

@ -11,6 +11,7 @@ typedef struct
PMDL Mdl;
ULONG Length;
ULONG Function;
PFILE_OBJECT FileObject;
}WDMAUD_COMPLETION_CONTEXT, *PWDMAUD_COMPLETION_CONTEXT;
@ -66,6 +67,7 @@ typedef struct
KEVENT InitializationCompletionEvent;
ULONG WorkItemActive;
PDEVICE_OBJECT NextDeviceObject;
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
typedef struct

View file

@ -30,8 +30,6 @@ ExcludeFromSelect = WDMAUDIO_CopyFilesOnlyId
%WDM_WDMAUD.DeviceDesc% = WDM_WDMAUD, SW\{CD171DE3-69E5-11D2-B56D-0000F8754380}
;%WDM_DRMKAUD.DeviceDesc% = WDM_DRMKAUD, SW\{EEC12DB6-AD9C-4168-8658-B03DAEF417FE}
%WDMAUDIO_CopyFilesOnlyId.DeviceDesc% = WDMAUDIO.CopyFilesOnly, WDMAUDIO_CopyFilesOnlyId
[WDMAUDIO.CopyFilesOnly]
CopyFiles=WDM.CopyFiles, FX.CopyList
@ -45,6 +43,12 @@ CopyFiles = WDM.CopyFiles
AddReg = DeviceRegistration
CopyFiles = WDM.CopyFiles
;; copied to system32\drivers
[WDM.CopyFiles]
drmk.sys,,,0x0100
portcls.sys,,,0x0100
[DeviceRegistration]
; Kmixer swenum install
;HKLM,%RunOnce%,"WDM_KMIXER0",,"rundll32.exe streamci.dll,StreamingDeviceSetup %WDM_KMIXER.DeviceId%,%KSNAME_Filter%,%KSCATEGORY_MIXER%,%17%\WDMAUDIO.inf,WDM_KMIXER.Interface.Install"
@ -160,10 +164,6 @@ StartType = 3 ; SERVICE_DEMAND_START
ErrorControl = 1 ; SERVICE_ERROR_NORMAL
ServiceBinary = %10%\system32\drivers\drmkaud.sys
;; copied to system32\drivers
[WDM.CopyFiles]
drmk.sys,,,0x0100
portcls.sys,,,0x0100
;; Destination Directory List
[DestinationDirs]