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
#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);
#define NDEBUG
#include <debug.h>
+#define TAG_KS 'ssKK'
+
VOID
CompleteRequest(
PIRP Irp,
IN POOL_TYPE PoolType,
IN SIZE_T NumberOfBytes)
{
- PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
+ PVOID Item = ExAllocatePoolWithTag(PoolType, NumberOfBytes, TAG_KS);
if (!Item)
return Item;
{
ULONG Result = 0;
NTSTATUS Status = STATUS_SUCCESS;
- //PWDMAUD_DEVICE_EXTENSION DeviceExtension;
-
- //DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
{
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;
/* 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);
Irp->IoStatus.Information = 0;
}
+ /* dereference file object */
+ ObDereferenceObject(Context->FileObject);
+
/* free context */
FreeItem(Context);
/* 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 */
{
DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
Irp->MdlAddress = Mdl;
+ FreeItem(Context);
return SetIrpIoStatus(Irp, Status, 0);
}
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;
}
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))
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);
{
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;
}
/* 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);
IN PVOID Context)
{
PWDMAUD_DEVICE_EXTENSION DeviceExtension;
+ NTSTATUS Status;
/* get device extension */
DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
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");
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,
}
/* register device interfaces */
- Status = WdmAudRegisterDeviceInterface(DeviceObject, DeviceExtension);
+ Status = WdmAudRegisterDeviceInterface(PhysicalDeviceObject, DeviceExtension);
if (!NT_SUCCESS(Status))
{
DPRINT1("WdmRegisterDeviceInterface failed with %x\n", Status);
/* 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);
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);
}
#endif
+ if (DeviceExtension->FileObject == NULL)
+ {
+ /* initialize */
+ WdmAudInitWorkerRoutine(DeviceObject, NULL);
+ }
+
+
Status = WdmAudOpenSysaudio(DeviceObject, &pClient);
if (!NT_SUCCESS(Status))
{
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;
}
#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;
PMDL Mdl;
ULONG Length;
ULONG Function;
+ PFILE_OBJECT FileObject;
}WDMAUD_COMPLETION_CONTEXT, *PWDMAUD_COMPLETION_CONTEXT;
KEVENT InitializationCompletionEvent;
ULONG WorkItemActive;
+ PDEVICE_OBJECT NextDeviceObject;
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
typedef struct
%WDM_WDMAUD.DeviceDesc% = WDM_WDMAUD, SW\{CD171DE3-69E5-11D2-B56D-0000F8754380}\r
;%WDM_DRMKAUD.DeviceDesc% = WDM_DRMKAUD, SW\{EEC12DB6-AD9C-4168-8658-B03DAEF417FE}\r
\r
-%WDMAUDIO_CopyFilesOnlyId.DeviceDesc% = WDMAUDIO.CopyFilesOnly, WDMAUDIO_CopyFilesOnlyId\r
-\r
[WDMAUDIO.CopyFilesOnly]\r
CopyFiles=WDM.CopyFiles, FX.CopyList\r
\r
AddReg = DeviceRegistration\r
CopyFiles = WDM.CopyFiles\r
\r
+;; copied to system32\drivers\r
+[WDM.CopyFiles]\r
+drmk.sys,,,0x0100\r
+portcls.sys,,,0x0100\r
+\r
+\r
[DeviceRegistration]\r
; Kmixer swenum install\r
;HKLM,%RunOnce%,"WDM_KMIXER0",,"rundll32.exe streamci.dll,StreamingDeviceSetup %WDM_KMIXER.DeviceId%,%KSNAME_Filter%,%KSCATEGORY_MIXER%,%17%\WDMAUDIO.inf,WDM_KMIXER.Interface.Install"\r
ErrorControl = 1 ; SERVICE_ERROR_NORMAL\r
ServiceBinary = %10%\system32\drivers\drmkaud.sys\r
\r
-;; copied to system32\drivers\r
-[WDM.CopyFiles]\r
-drmk.sys,,,0x0100\r
-portcls.sys,,,0x0100\r
\r
;; Destination Directory List\r
[DestinationDirs]\r