From b046ce1926e3ddb71003b8f46b2c4ca4283c049f Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 10 Jul 2009 15:14:56 +0000 Subject: [PATCH] [KS] - The pin creation parameters are now placed right after the reference string. Handle this case in KsValidateConnectRequest - Only store the passed create items, no need to copy the passed create items. This is required for enabling dynamic audio devices - Fix copying of the object class in KsAllocateObjectHeader - Check for KSCREATE_ITEM_IRP_STORAGE flag in KsCreate [PORTCLS] - Reduce initial audio buffer to about 1/3 second which greatly improves performance [SYSAUDIO] - Remove concept of audio subdevices - Remove imported KsCreatePin - Replace OpenDevice loop hack svn path=/trunk/; revision=41842 --- reactos/drivers/ksfilter/ks/connectivity.c | 17 +- reactos/drivers/ksfilter/ks/irp.c | 272 +++++++++------- reactos/drivers/ksfilter/ks/kstypes.h | 6 +- reactos/drivers/ksfilter/ks/misc.c | 6 +- reactos/drivers/ksfilter/ks/topology.c | 51 ++- .../wdm/audio/backpln/portcls/irpstream.c | 2 +- .../wdm/audio/backpln/portcls/port_topology.c | 83 +++-- .../drivers/wdm/audio/filters/kmixer/filter.c | 2 +- reactos/drivers/wdm/audio/sysaudio/control.c | 136 +------- reactos/drivers/wdm/audio/sysaudio/deviface.c | 306 ++++++++++-------- .../drivers/wdm/audio/sysaudio/dispatcher.c | 4 +- reactos/drivers/wdm/audio/sysaudio/main.c | 13 +- reactos/drivers/wdm/audio/sysaudio/sysaudio.h | 21 +- 13 files changed, 458 insertions(+), 461 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/connectivity.c b/reactos/drivers/ksfilter/ks/connectivity.c index d2744ff76a8..73921ee2163 100644 --- a/reactos/drivers/ksfilter/ks/connectivity.c +++ b/reactos/drivers/ksfilter/ks/connectivity.c @@ -45,15 +45,23 @@ KsValidateConnectRequest( PKSPIN_CONNECT ConnectDetails; LPWSTR PinName = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}\\"; PKSDATAFORMAT DataFormat; + LPWSTR Offset; IoStack = IoGetCurrentIrpStackLocation(Irp); if (!IoStack->FileObject->FileName.Buffer) return STATUS_INVALID_PARAMETER; - if (wcsncmp(IoStack->FileObject->FileName.Buffer, PinName, wcslen(PinName))) + if (IoStack->FileObject->FileName.Length < wcslen(PinName) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT)) return STATUS_INVALID_PARAMETER; - ConnectDetails = (PKSPIN_CONNECT)(IoStack->FileObject->FileName.Buffer + wcslen(PinName)); + Offset = wcsstr(IoStack->FileObject->FileName.Buffer, PinName); + if (!Offset) + { + /* request is not targeted for a pin */ + return STATUS_INVALID_PARAMETER; + } + + ConnectDetails = (PKSPIN_CONNECT)(Offset + wcslen(PinName)); if (ConnectDetails->PinToHandle != NULL) { @@ -61,11 +69,6 @@ KsValidateConnectRequest( return STATUS_NOT_IMPLEMENTED; } - if (IoStack->FileObject->FileName.Length < wcslen(PinName) + sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT)) - return STATUS_INVALID_PARAMETER; - - ConnectDetails = (PKSPIN_CONNECT)(IoStack->FileObject->FileName.Buffer + wcslen(PinName)); - if (ConnectDetails->PinId >= DescriptorsCount) return STATUS_INVALID_PARAMETER; diff --git a/reactos/drivers/ksfilter/ks/irp.c b/reactos/drivers/ksfilter/ks/irp.c index 5c34c72ec8f..336f8e783dc 100644 --- a/reactos/drivers/ksfilter/ks/irp.c +++ b/reactos/drivers/ksfilter/ks/irp.c @@ -104,14 +104,15 @@ KsAddObjectCreateItemToDeviceHeader( /* now scan the list and check for a free item */ for(Index = 0; Index < Header->MaxItems; Index++) { - if (!Header->ItemList[Index].bCreated) - { - if (FreeIndex == (ULONG)-1) - FreeIndex = Index; + ASSERT(Header->ItemList[Index].CreateItem); - continue; + if (Header->ItemList[Index].CreateItem->Create == NULL) + { + FreeIndex = Index; + break; } - else if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem.ObjectClass.Buffer)) + + if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem->ObjectClass.Buffer)) { /* the same object class already exists */ return STATUS_OBJECT_NAME_COLLISION; @@ -120,26 +121,17 @@ KsAddObjectCreateItemToDeviceHeader( /* found a free index */ if (FreeIndex == (ULONG)-1) { - /* allocate a new device entry */ - PDEVICE_ITEM Item = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * (Header->MaxItems + 1), TAG_DEVICE_HEADER); - if (!Item) - return STATUS_INSUFFICIENT_RESOURCES; - - RtlMoveMemory(Item, Header->ItemList, Header->MaxItems * sizeof(DEVICE_ITEM)); - ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER); - - Header->ItemList = Item; - FreeIndex = Header->MaxItems; - Header->MaxItems++; + /* no empty space found */ + return STATUS_ALLOTTED_SPACE_EXCEEDED; } - /* store the new item */ - Header->ItemList[FreeIndex].bCreated = TRUE; - Header->ItemList[FreeIndex].CreateItem.Create = Create; - Header->ItemList[FreeIndex].CreateItem.Context = Context; - RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem.ObjectClass, ObjectClass); - Header->ItemList[FreeIndex].CreateItem.SecurityDescriptor = SecurityDescriptor; - Header->ItemList[FreeIndex].CreateItem.Flags = 0; + /* initialize create item */ + Header->ItemList[FreeIndex].CreateItem->Create = Create; + Header->ItemList[FreeIndex].CreateItem->Context = Context; + RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem->ObjectClass, ObjectClass); + Header->ItemList[FreeIndex].CreateItem->SecurityDescriptor = SecurityDescriptor; + + return STATUS_SUCCESS; } @@ -187,12 +179,8 @@ KsAllocateDeviceHeader( for(Index = 0; Index < ItemsCount; Index++) { - /* copy provided create items */ - RtlMoveMemory(&Header->ItemList[Index].CreateItem, &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM)); - if (ItemsList[Index].Create!= NULL) - { - Header->ItemList[Index].bCreated = TRUE; - } + /* store provided create items */ + Header->ItemList[Index].CreateItem = &ItemsList[Index]; } Header->MaxItems = ItemsCount; } @@ -294,7 +282,6 @@ KsAllocateObjectHeader( PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_HEADER ObjectHeader; - WCHAR ObjectClass[50]; if (!Header) return STATUS_INVALID_PARAMETER_1; @@ -312,18 +299,10 @@ KsAllocateObjectHeader( /* get device header */ DeviceHeader = DeviceExtension->DeviceHeader; - ObjectClass[0] = L'\0'; + /* sanity check */ + ASSERT(IoStack->FileObject); /* check for an file object */ - if (IoStack->FileObject != NULL) - { - /* validate the file name */ - if (IoStack->FileObject->FileName.Length >= 38) - { - RtlMoveMemory(ObjectClass, IoStack->FileObject->FileName.Buffer, 38 * sizeof(WCHAR)); - ObjectClass[38] = L'\0'; - DPRINT("ObjectClass %S\n", ObjectClass); - } - } + /* allocate the object header */ ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER); if (!ObjectHeader) @@ -333,13 +312,17 @@ KsAllocateObjectHeader( RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER)); /* do we have a name */ - if (ObjectClass[0]) + if (IoStack->FileObject->FileName.Buffer) { - ObjectHeader->ObjectClass = ExAllocatePoolWithTag(NonPagedPool, 40 * sizeof(WCHAR), TAG_DEVICE_HEADER); - if (ObjectHeader->ObjectClass) + /* copy object class */ + ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength; + ObjectHeader->ObjectClass.Buffer = ExAllocatePoolWithTag(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength, TAG_DEVICE_HEADER); + if (!ObjectHeader->ObjectClass.Buffer) { - wcscpy(ObjectHeader->ObjectClass, ObjectClass); + ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER); + return STATUS_INSUFFICIENT_RESOURCES; } + RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName); } /* copy dispatch table */ @@ -362,7 +345,6 @@ KsAllocateObjectHeader( { /* the object header is for a audio filter */ ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems); - DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader; IoStack->FileObject->FsContext = ObjectHeader; } @@ -370,7 +352,7 @@ KsAllocateObjectHeader( *Header = ObjectHeader; - DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectClass, IoStack->FileObject, ObjectHeader); + DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader); return STATUS_SUCCESS; @@ -725,8 +707,9 @@ KsCreate( PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; ULONG Index; - NTSTATUS Status = STATUS_SUCCESS; + NTSTATUS Status; KIRQL OldLevel; + ULONG Length; DPRINT("KS / CREATE\n"); /* get current stack location */ @@ -738,56 +721,85 @@ KsCreate( /* acquire list lock */ KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel); + + /* sanity check */ + ASSERT(IoStack->FileObject); + + if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->MaxItems == 1) + { + /* hack for bug 4566 */ + if (!DeviceHeader->ItemList[0].CreateItem || !DeviceHeader->ItemList[0].CreateItem->Create) + { + /* no valid create item */ + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + /* return status */ + return STATUS_UNSUCCESSFUL; + } + + /* set object create item */ + KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[0].CreateItem; + + /* call create function */ + Status = DeviceHeader->ItemList[0].CreateItem->Create(DeviceObject, Irp); + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + /* return result */ + return Status; + } + + + /* hack for bug 4566 */ + if (IoStack->FileObject->FileName.Buffer == NULL) + { + DPRINT("Using reference string hack\n"); + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + Irp->IoStatus.Information = 0; + /* set return status */ + Irp->IoStatus.Status = STATUS_SUCCESS; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + /* loop all device items */ for(Index = 0; Index < DeviceHeader->MaxItems; Index++) { - if (DeviceHeader->ItemList[Index].bCreated && DeviceHeader->ItemList[Index].ObjectHeader == NULL) + /* is there a create item */ + if (DeviceHeader->ItemList[Index].CreateItem == NULL) + continue; + + /* check if the create item is initialized */ + if (!DeviceHeader->ItemList[Index].CreateItem->Create) + continue; + + ASSERT(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + DPRINT("CreateItem %p Request %S\n", DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, + IoStack->FileObject->FileName.Buffer); + + /* get object class length */ + Length = wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + /* now check if the object class is the same */ + if (!_wcsnicmp(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer, &IoStack->FileObject->FileName.Buffer[1], Length) || + (DeviceHeader->ItemList[Index].CreateItem->Flags & KSCREATE_ITEM_WILDCARD)) { + /* setup create parameters */ DeviceHeader->DeviceIndex = Index; /* set object create item */ - KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem; - Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp); + KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[Index].CreateItem; - /* FIXME IoRegisterDeviceInterface does not support reference strings */ - /* FIXME Check the irp target with the create item's object class */ - if (NT_SUCCESS(Status)) - { - /* release lock */ - KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - return Status; - } + /* call create function */ + Status = DeviceHeader->ItemList[Index].CreateItem->Create(DeviceObject, Irp); + + /* release lock */ + KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); + + /* return result */ + return Status; } - else if (DeviceHeader->ItemList[Index].bCreated && IoStack->FileObject->FileName.Buffer != NULL) - { - ULONG Length; - - ASSERT(DeviceHeader->ItemList[Index].ObjectHeader); - ASSERT(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem); - ASSERT(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer); - - Length = wcslen(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer); - - /* filter for that type has already exists */ - if (!_wcsnicmp(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer, - IoStack->FileObject->FileName.Buffer, - Length)) - { - if (IoStack->FileObject->FileName.Buffer[0] != L'{') - { - RtlMoveMemory(IoStack->FileObject->FileName.Buffer, &IoStack->FileObject->FileName.Buffer[Length+1], - IoStack->FileObject->FileName.Length - (Length + 1) * sizeof(WCHAR)); - - IoStack->FileObject->FileName.Length -= (Length + 1)* sizeof(WCHAR); - } - - - KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem; - Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp); - KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel); - return Status; - } - } - } /* release lock */ @@ -810,7 +822,6 @@ KsClose( PKSIOBJECT_HEADER ObjectHeader; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; - ULONG Index; /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -827,20 +838,20 @@ KsClose( ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext; KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - - for(Index = 0; Index < DeviceHeader->MaxItems; Index++) - { - if (DeviceHeader->ItemList[Index].ObjectHeader == ObjectHeader) - { - DeviceHeader->ItemList[Index].ObjectHeader = NULL; - } - } return ObjectHeader->DispatchTable.Close(DeviceObject, Irp); } else { +#if 0 DPRINT1("Expected Object Header FileObject %p FsContext %p\n", IoStack->FileObject, IoStack->FileObject->FsContext); KeBugCheckEx(0, 0, 0, 0, 0); +#else + DPRINT("Using reference string hack\n"); + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; +#endif return STATUS_SUCCESS; } } @@ -853,10 +864,63 @@ KsDeviceControl( { PIO_STACK_LOCATION IoStack; PKSIOBJECT_HEADER ObjectHeader; + PKSIDEVICE_HEADER DeviceHeader; + PDEVICE_EXTENSION DeviceExtension; + ULONG Length, Index; + LPWSTR Buffer; /* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); + /* hack for bug 4566 */ + if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS) + { + /* get device extension */ + DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; + /* get device header */ + DeviceHeader = DeviceExtension->DeviceHeader; + + /* retrieve all available reference strings registered */ + Length = 0; + + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + continue; + + Length += wcslen(DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + 1; + } + + /* add extra zero */ + Length += 1; + + /* allocate the buffer */ + Buffer = ExAllocatePool(NonPagedPool, Length * sizeof(WCHAR)); + if (!Buffer) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + *((LPWSTR*)Irp->UserBuffer) = Buffer; + Irp->IoStatus.Status = STATUS_SUCCESS; + Irp->IoStatus.Information = sizeof(LPWSTR); + + for(Index = 0; Index < DeviceHeader->MaxItems; Index++) + { + if (!DeviceHeader->ItemList[Index].CreateItem || !DeviceHeader->ItemList[Index].CreateItem->Create || !DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer) + continue; + + wcscpy(Buffer, DeviceHeader->ItemList[Index].CreateItem->ObjectClass.Buffer); + Buffer += wcslen(Buffer) + 1; + } + *Buffer = L'\0'; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_SUCCESS; + } + DPRINT("KS / DeviceControl\n"); if (IoStack->FileObject && IoStack->FileObject->FsContext) { @@ -864,14 +928,6 @@ KsDeviceControl( KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem; - if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS) - { - *((LPWSTR*)Irp->UserBuffer) = ObjectHeader->CreateItem->ObjectClass.Buffer; - Irp->IoStatus.Status = STATUS_SUCCESS; - Irp->IoStatus.Information = sizeof(LPWSTR); - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_SUCCESS; - } return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp); } else diff --git a/reactos/drivers/ksfilter/ks/kstypes.h b/reactos/drivers/ksfilter/ks/kstypes.h index 68a563c7747..89f2cf70a97 100644 --- a/reactos/drivers/ksfilter/ks/kstypes.h +++ b/reactos/drivers/ksfilter/ks/kstypes.h @@ -6,17 +6,15 @@ struct KSIDEVICE_HEADER; typedef struct { KSDISPATCH_TABLE DispatchTable; - LPWSTR ObjectClass; ULONG ItemCount; PKSOBJECT_CREATE_ITEM CreateItem; + UNICODE_STRING ObjectClass; }KSIOBJECT_HEADER, *PKSIOBJECT_HEADER; typedef struct { - BOOL bCreated; - PKSIOBJECT_HEADER ObjectHeader; - KSOBJECT_CREATE_ITEM CreateItem; + PKSOBJECT_CREATE_ITEM CreateItem; }DEVICE_ITEM, *PDEVICE_ITEM; diff --git a/reactos/drivers/ksfilter/ks/misc.c b/reactos/drivers/ksfilter/ks/misc.c index c40226662f2..a20d2dd181f 100644 --- a/reactos/drivers/ksfilter/ks/misc.c +++ b/reactos/drivers/ksfilter/ks/misc.c @@ -282,16 +282,18 @@ KsSynchronousIoControlDevice( if (!DeviceObject) return STATUS_UNSUCCESSFUL; + /* get object header */ ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext; +#if 0 if (!ObjectHeader) { DPRINT("Expected object header\n"); return STATUS_UNSUCCESSFUL; } - +#endif /* check if there is fast device io function */ - if (ObjectHeader->DispatchTable.FastDeviceIoControl) + if (ObjectHeader && ObjectHeader->DispatchTable.FastDeviceIoControl) { IoStatusBlock.Status = STATUS_UNSUCCESSFUL; IoStatusBlock.Information = 0; diff --git a/reactos/drivers/ksfilter/ks/topology.c b/reactos/drivers/ksfilter/ks/topology.c index a887eab8f90..07d7d855855 100644 --- a/reactos/drivers/ksfilter/ks/topology.c +++ b/reactos/drivers/ksfilter/ks/topology.c @@ -17,26 +17,56 @@ KspCreateObjectType( NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; + PFILE_OBJECT FileObject; UNICODE_STRING Name; + PKSIOBJECT_HEADER ObjectHeader; - Name.Length = Name.MaximumLength = (wcslen(ObjectType) + 1) * sizeof(WCHAR) + CreateParametersSize; + /* acquire parent file object */ + Status = ObReferenceObjectByHandle(ParentHandle, + GENERIC_READ | GENERIC_WRITE, + IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); + + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to reference parent %x\n", Status); + return Status; + } + + /* get parent object header */ + ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext; + /* sanity check */ + ASSERT(ObjectHeader); + + /* calculate request length */ + Name.Length = 0; + Name.MaximumLength = wcslen(ObjectType) * sizeof(WCHAR) + CreateParametersSize + ObjectHeader->ObjectClass.MaximumLength + 2 * sizeof(WCHAR); Name.MaximumLength += sizeof(WCHAR); + /* acquire request buffer */ Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength); - + /* check for success */ if (!Name.Buffer) { + /* insufficient resources */ + ObDereferenceObject(FileObject); return STATUS_INSUFFICIENT_RESOURCES; } - wcscpy(Name.Buffer, ObjectType); - Name.Buffer[wcslen(ObjectType)] = '\\'; - - RtlMoveMemory(Name.Buffer + wcslen(ObjectType) +1, CreateParameters, CreateParametersSize); - + /* build a request which looks like \Parent\{ObjectGuid}\CreateParameters + * For pins the parent is the reference string used in registration + * For clocks it is full path for pin\{ClockGuid}\ClockCreateParams + */ + + RtlAppendUnicodeStringToString(&Name, &ObjectHeader->ObjectClass); + RtlAppendUnicodeToString(&Name, L"\\"); + RtlAppendUnicodeToString(&Name, ObjectType); + RtlAppendUnicodeToString(&Name, L"\\"); + /* append create parameters */ + RtlMoveMemory(Name.Buffer + (Name.Length / sizeof(WCHAR)), CreateParameters, CreateParametersSize); + Name.Length += CreateParametersSize; Name.Buffer[Name.Length / 2] = L'\0'; + InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL); - - + /* create the instance */ Status = IoCreateFile(NodeHandle, DesiredAccess, &ObjectAttributes, @@ -52,7 +82,10 @@ KspCreateObjectType( NULL, IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK); + /* free request buffer */ ExFreePool(Name.Buffer); + /* release parent handle */ + ObDereferenceObject(FileObject); return Status; } diff --git a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c index 1fecad8d28f..dd5de4d2ccc 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c @@ -314,7 +314,7 @@ IIrpQueue_fnMinimumDataAvailable( if (This->StartStream) return TRUE; - if (This->DataFormat->WaveFormatEx.nAvgBytesPerSec < This->NumDataAvailable) + if (This->DataFormat->WaveFormatEx.nAvgBytesPerSec/3 < This->NumDataAvailable) { This->StartStream = TRUE; Result = TRUE; diff --git a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c index 4b8b7e34d22..fcacc43ef12 100644 --- a/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c +++ b/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c @@ -542,6 +542,8 @@ PcCreateItemDispatch( IIrpTarget *Filter; PKSOBJECT_CREATE_ITEM CreateItem; PPIN_WORKER_CONTEXT Context; + LPWSTR Buffer; + static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; DPRINT1("PcCreateItemDispatch called DeviceObject %p\n", DeviceObject); @@ -604,60 +606,55 @@ PcCreateItemDispatch( return Status; } - /* is just the filter requested */ - if (IoStack->FileObject->FileName.Buffer == NULL) + /* get the buffer */ + Buffer = IoStack->FileObject->FileName.Buffer; + + /* check if the request contains a pin request */ + if (!wcsstr(Buffer, KS_NAME_PIN)) { - /* create the dispatch object */ + /* creator just wants the filter object */ Status = NewDispatchObject(Irp, Filter, CreateItem->ObjectClass.Buffer); DPRINT1("Filter %p\n", Filter); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = Status; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return Status; } else { - LPWSTR Buffer = IoStack->FileObject->FileName.Buffer; - - static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}"; - - /* is the request for a new pin */ - if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) + /* try to create new pin */ + Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); + if (!Context) { - /* try to create new pin */ - Context = AllocateItem(NonPagedPool, sizeof(PIN_WORKER_CONTEXT), TAG_PORTCLASS); - if (!Context) - { - DPRINT("Failed to allocate worker context\n"); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - /* allocate work item */ - Context->WorkItem = IoAllocateWorkItem(DeviceObject); - if (!Context->WorkItem) - { - DPRINT("Failed to allocate workitem\n"); - FreeItem(Context, TAG_PORTCLASS); - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_INSUFFICIENT_RESOURCES; - } - - Context->Filter = Filter; - Context->Irp = Irp; - - DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql()); + DPRINT("Failed to allocate worker context\n"); Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = STATUS_PENDING; - IoMarkIrpPending(Irp); - IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); - return STATUS_PENDING; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; } + /* allocate work item */ + Context->WorkItem = IoAllocateWorkItem(DeviceObject); + if (!Context->WorkItem) + { + DPRINT("Failed to allocate workitem\n"); + FreeItem(Context, TAG_PORTCLASS); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + + Context->Filter = Filter; + Context->Irp = Irp; + + DPRINT("Queueing IRP %p Irql %u\n", Irp, KeGetCurrentIrql()); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_PENDING; + IoMarkIrpPending(Irp); + IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context); + return STATUS_PENDING; } - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; } diff --git a/reactos/drivers/wdm/audio/filters/kmixer/filter.c b/reactos/drivers/wdm/audio/filters/kmixer/filter.c index 68400372d39..a71e8fceea9 100644 --- a/reactos/drivers/wdm/audio/filters/kmixer/filter.c +++ b/reactos/drivers/wdm/audio/filters/kmixer/filter.c @@ -201,7 +201,7 @@ DispatchCreateKMix( if (Buffer) { /* is the request for a new pin */ - if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) + if (!wcsstr(KS_NAME_PIN, Buffer)) { Status = CreatePin(Irp); diff --git a/reactos/drivers/wdm/audio/sysaudio/control.c b/reactos/drivers/wdm/audio/sysaudio/control.c index 8fca496c99f..1b582d6c9d8 100644 --- a/reactos/drivers/wdm/audio/sysaudio/control.c +++ b/reactos/drivers/wdm/audio/sysaudio/control.c @@ -20,97 +20,13 @@ const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, NTSTATUS ComputeCompatibleFormat( - IN PKSAUDIO_SUBDEVICE_ENTRY Entry, + IN PKSAUDIO_DEVICE_ENTRY Entry, IN ULONG PinId, IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, OUT PKSDATAFORMAT_WAVEFORMATEX MixerFormat); -NTSTATUS -NTAPI -KspCreateObjectType( - IN HANDLE ParentHandle, - IN LPWSTR ObjectType, - PVOID CreateParameters, - UINT CreateParametersSize, - IN ACCESS_MASK DesiredAccess, - OUT PHANDLE NodeHandle) -{ - NTSTATUS Status; - IO_STATUS_BLOCK IoStatusBlock; - OBJECT_ATTRIBUTES ObjectAttributes; - UNICODE_STRING Name; - - Name.Length = Name.MaximumLength = (wcslen(ObjectType) + 1) * sizeof(WCHAR) + CreateParametersSize; - Name.MaximumLength += sizeof(WCHAR); - Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength); - - if (!Name.Buffer) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - - wcscpy(Name.Buffer, ObjectType); - Name.Buffer[wcslen(ObjectType)] = '\\'; - - RtlMoveMemory(Name.Buffer + wcslen(ObjectType) +1, CreateParameters, CreateParametersSize); - - Name.Buffer[Name.Length / 2] = L'\0'; - InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL); - - - Status = IoCreateFile(NodeHandle, - DesiredAccess, - &ObjectAttributes, - &IoStatusBlock, - NULL, - 0, - 0, - FILE_OPEN, - FILE_SYNCHRONOUS_IO_NONALERT, - NULL, - 0, - CreateFileTypeNone, - NULL, - IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK); - - ExFreePool(Name.Buffer); - - return Status; -} - -KSDDKAPI -NTSTATUS -NTAPI -KsoCreatePin( - IN HANDLE FilterHandle, - IN PKSPIN_CONNECT Connect, - IN ACCESS_MASK DesiredAccess, - OUT PHANDLE ConnectionHandle, - IN LPWSTR ObjectClass) -{ - WCHAR szBuffer[100]; - UINT ConnectSize = sizeof(KSPIN_CONNECT); - - PKSDATAFORMAT_WAVEFORMATEX Format = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1); - if (Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) || - Format->DataFormat.FormatSize == sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX)) - { - ConnectSize += Format->DataFormat.FormatSize; - } - - swprintf(szBuffer, L"%s\\{146F1A80-4791-11D0-A5D6-28DB04C10000}", ObjectClass); - - return KspCreateObjectType(FilterHandle, - szBuffer, - (PVOID)Connect, - ConnectSize, - DesiredAccess, - ConnectionHandle); -} - - NTSTATUS SetIrpIoStatus( IN PIRP Irp, @@ -131,38 +47,20 @@ SetIrpIoStatus( } -PKSAUDIO_SUBDEVICE_ENTRY +PKSAUDIO_DEVICE_ENTRY GetListEntry( IN PLIST_ENTRY Head, IN ULONG Index) { - PKSAUDIO_DEVICE_ENTRY DeviceEntry; - PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; - PLIST_ENTRY SubEntry, Entry = Head->Flink; - - while(Entry != Head) - { - DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); - if (Index < DeviceEntry->NumSubDevices) - { - SubEntry = DeviceEntry->SubDeviceList.Flink; - while(SubEntry != &DeviceEntry->SubDeviceList && Index--) - SubEntry = SubEntry->Flink; - - SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); - return SubDeviceEntry; - } - else - { - Index -= DeviceEntry->NumSubDevices; - } + PLIST_ENTRY Entry = Head->Flink; + while(Index-- && Entry != Head) Entry = Entry->Flink; - } - DPRINT1("Not Found index %u\n", Index); + if (Entry == Head) + return NULL; - return NULL; + return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); } NTSTATUS @@ -171,7 +69,7 @@ SysAudioOpenVirtualDevice( IN ULONG DeviceNumber, PSYSAUDIODEVEXT DeviceExtension) { - PKSAUDIO_SUBDEVICE_ENTRY Entry; + PKSAUDIO_DEVICE_ENTRY Entry; PKSOBJECT_CREATE_ITEM CreateItem; /* access the create item */ @@ -243,7 +141,7 @@ CreateMixerPinAndSetFormat( HANDLE PinHandle; PFILE_OBJECT FileObject; - Status = KsoCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle, L"KMixer"); + Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);//, L"KMixer"); if (!NT_SUCCESS(Status)) { @@ -305,7 +203,7 @@ CreatePinWorkerRoutine( /* Let's try to create the audio irp pin */ - Status = KsoCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass); + Status = KsCreatePin(WorkerContext->Entry->Handle, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); if (!NT_SUCCESS(Status)) { @@ -345,7 +243,7 @@ CreatePinWorkerRoutine( } /* Retry with Mixer format */ - Status = KsoCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle, WorkerContext->Entry->ObjectClass); + Status = KsCreatePin(WorkerContext->Entry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle); //, WorkerContext->Entry->ObjectClass); if (!NT_SUCCESS(Status)) { /* This should not fail */ @@ -390,7 +288,7 @@ CreatePinWorkerRoutine( DPRINT1("creating virtual pin\n"); /* now create the virtual audio pin which is exposed to wdmaud */ - Status = KsoCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle, L"SysAudio"); + Status = KsCreatePin(Filter, WorkerContext->PinConnect, GENERIC_READ | GENERIC_WRITE, &VirtualPinHandle); //, L"SysAudio"); if (!NT_SUCCESS(Status)) { @@ -454,7 +352,7 @@ HandleSysAudioFilterPinProperties( { PIO_STACK_LOCATION IoStack; NTSTATUS Status; - PKSAUDIO_SUBDEVICE_ENTRY Entry; + PKSAUDIO_DEVICE_ENTRY Entry; ULONG BytesReturned; PKSP_PIN Pin; @@ -541,7 +439,7 @@ HandleSysAudioFilterPinProperties( NTSTATUS ComputeCompatibleFormat( - IN PKSAUDIO_SUBDEVICE_ENTRY Entry, + IN PKSAUDIO_DEVICE_ENTRY Entry, IN ULONG PinId, IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, @@ -676,7 +574,7 @@ ComputeCompatibleFormat( NTSTATUS GetPinInstanceCount( - PKSAUDIO_SUBDEVICE_ENTRY Entry, + PKSAUDIO_DEVICE_ENTRY Entry, PKSPIN_CINSTANCES PinInstances, PKSPIN_CONNECT PinConnect) { @@ -701,7 +599,7 @@ HandleSysAudioFilterPinCreation( PDEVICE_OBJECT DeviceObject) { ULONG Length; - PKSAUDIO_SUBDEVICE_ENTRY Entry; + PKSAUDIO_DEVICE_ENTRY Entry; KSPIN_CONNECT * PinConnect; PIO_STACK_LOCATION IoStack; PSYSAUDIO_INSTANCE_INFO InstanceInfo; @@ -848,7 +746,7 @@ SysAudioHandleProperty( PULONG Index; PKSPROPERTY Property; PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_SUBDEVICE_ENTRY Entry; + PKSAUDIO_DEVICE_ENTRY Entry; PSYSAUDIO_INSTANCE_INFO InstanceInfo; ULONG BytesReturned; PKSOBJECT_CREATE_ITEM CreateItem; diff --git a/reactos/drivers/wdm/audio/sysaudio/deviface.c b/reactos/drivers/wdm/audio/sysaudio/deviface.c index d76cb5f3e81..d9a85676221 100644 --- a/reactos/drivers/wdm/audio/sysaudio/deviface.c +++ b/reactos/drivers/wdm/audio/sysaudio/deviface.c @@ -18,7 +18,7 @@ const GUID DMOCATEGORY_ACOUSTIC_ECHO_CANCEL = {0xBF963D80L, 0xC559, 0x11D0, { VOID QueryFilterRoutine( - IN PKSAUDIO_SUBDEVICE_ENTRY DeviceEntry) + IN PKSAUDIO_DEVICE_ENTRY DeviceEntry) { KSPROPERTY PropertyRequest; KSP_PIN PinRequest; @@ -32,15 +32,6 @@ QueryFilterRoutine( DPRINT("Querying filter...\n"); - Status = KsSynchronousIoControlDevice(DeviceEntry->FileObject, KernelMode, IOCTL_KS_OBJECT_CLASS, NULL, 0, &DeviceEntry->ObjectClass, sizeof(LPWSTR), &BytesReturned); - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to query object class Status %x\n", Status); - return; - } - - DPRINT("ObjectClass %S\n", DeviceEntry->ObjectClass); - PropertyRequest.Set = KSPROPSETID_Pin; PropertyRequest.Flags = KSPROPERTY_TYPE_GET; PropertyRequest.Id = KSPROPERTY_PIN_CTYPES; @@ -114,9 +105,6 @@ QueryFilterRoutine( DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, NumWaveOutPin); } - - - VOID NTAPI FilterPinWorkerRoutine( @@ -124,21 +112,11 @@ FilterPinWorkerRoutine( IN PVOID Context) { PKSAUDIO_DEVICE_ENTRY DeviceEntry; - PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; - PLIST_ENTRY ListEntry; - PFILTER_WORKER_CONTEXT Ctx = (PFILTER_WORKER_CONTEXT)Context; DeviceEntry = Ctx->DeviceEntry; - ListEntry = DeviceEntry->SubDeviceList.Flink; - while(ListEntry != &DeviceEntry->SubDeviceList) - { - SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(ListEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); - QueryFilterRoutine(SubDeviceEntry); - ListEntry = ListEntry->Flink; - } - + QueryFilterRoutine(DeviceEntry); /* free work item */ IoFreeWorkItem(Ctx->WorkItem); @@ -177,7 +155,7 @@ OpenDevice( if (!NT_SUCCESS(Status)) { - DPRINT("ZwCreateFile failed with %x\n", Status); + DPRINT("ZwCreateFile failed with %x %S\n", Status, DeviceName->Buffer); return Status; } @@ -195,125 +173,92 @@ OpenDevice( } NTSTATUS -NTAPI -DeviceInterfaceChangeCallback( - IN PVOID NotificationStructure, - IN PVOID Context) +InsertAudioDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PUNICODE_STRING DeviceName, + IN LPWSTR ReferenceString) { - DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event; NTSTATUS Status = STATUS_SUCCESS; + PFILTER_WORKER_CONTEXT Ctx = NULL; + PIO_WORKITEM WorkItem = NULL; PSYSAUDIODEVEXT DeviceExtension; PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL; - PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; - PIO_WORKITEM WorkItem = NULL; - PFILTER_WORKER_CONTEXT Ctx = NULL; - PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context; + /* a new device has arrived */ + DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY)); + if (!DeviceEntry) + { + /* no memory */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* initialize audio device entry */ + RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY)); + + /* allocate filter ctx */ + Ctx = ExAllocatePool(NonPagedPool, sizeof(FILTER_WORKER_CONTEXT)); + if (!Ctx) + { + /* no memory */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + + /* allocate work item */ + WorkItem = IoAllocateWorkItem(DeviceObject); + if (!WorkItem) + { + /* no memory */ + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + + /* set device name */ + DeviceEntry->DeviceName.Length = 0; + DeviceEntry->DeviceName.MaximumLength = DeviceName->MaximumLength + 10 * sizeof(WCHAR); + + /* hack for bug 4566 */ + if (ReferenceString) + { + DeviceEntry->DeviceName.MaximumLength += (wcslen(ReferenceString) + 2) * sizeof(WCHAR); + } + + DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength); + + if (!DeviceEntry->DeviceName.Buffer) + { + Status = STATUS_INSUFFICIENT_RESOURCES; + goto cleanup; + } + + RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\"); + RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, DeviceName); + + if (ReferenceString) + { + RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\"); + RtlAppendUnicodeToString(&DeviceEntry->DeviceName, ReferenceString); + } + + Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject); + + if (!NT_SUCCESS(Status)) + { + goto cleanup; + } + + Ctx->DeviceEntry = DeviceEntry; + Ctx->WorkItem = WorkItem; + + /* fetch device extension */ DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; + /* insert new audio device */ + ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock); + InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices); - Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure; - - if (IsEqualGUIDAligned(&Event->Event, - &GUID_DEVICE_INTERFACE_ARRIVAL)) - { - - /* a new device has arrived */ - DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY)); - if (!DeviceEntry) - { - /* no memory */ - return STATUS_INSUFFICIENT_RESOURCES; - } - - /* initialize audio device entry */ - RtlZeroMemory(DeviceEntry, sizeof(KSAUDIO_DEVICE_ENTRY)); - - /* allocate filter ctx */ - Ctx = ExAllocatePool(NonPagedPool, sizeof(FILTER_WORKER_CONTEXT)); - if (!Ctx) - { - /* no memory */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - - /* allocate work item */ - WorkItem = IoAllocateWorkItem(DeviceObject); - if (!WorkItem) - { - /* no memory */ - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - - /* set device name */ - DeviceEntry->DeviceName.Length = 0; - DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR); - DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength); - - if (!DeviceEntry->DeviceName.Buffer) - { - Status = STATUS_INSUFFICIENT_RESOURCES; - goto cleanup; - } - - if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\"))) - { - DPRINT1("RtlAppendUnicodeToString failed with %x\n", Status); - goto cleanup; - } - - if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName))) - { - DPRINT1("RtlAppendUnicodeStringToString failed with %x\n", Status); - goto cleanup; - } - - /* FIXME Ros does not support device interface strings */ - /* Workarround: repeatly call IoCreateFile untill ks wont find a create item which has no object header attached */ - - InitializeListHead(&DeviceEntry->SubDeviceList); - do - { - SubDeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_SUBDEVICE_ENTRY)); - if (SubDeviceEntry) - { - RtlZeroMemory(SubDeviceEntry, sizeof(KSAUDIO_SUBDEVICE_ENTRY)); - Status = OpenDevice(&DeviceEntry->DeviceName, &SubDeviceEntry->Handle, &SubDeviceEntry->FileObject); - if (NT_SUCCESS(Status)) - { - InsertTailList(&DeviceEntry->SubDeviceList, &SubDeviceEntry->Entry); - DeviceEntry->NumSubDevices++; - /* increment audio device count */ - InterlockedIncrement((PLONG)&DeviceExtension->NumberOfKsAudioDevices); - } - else - { - ExFreePool(SubDeviceEntry); - break; - } - } - }while(NT_SUCCESS(Status) && SubDeviceEntry != NULL); - - DPRINT("Successfully opened audio device %u Device %S NumberOfSubDevices %u\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer, DeviceEntry->NumSubDevices); - - Ctx->DeviceEntry = DeviceEntry; - Ctx->WorkItem = WorkItem; - - /* fetch device extension */ - DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; - /* insert new audio device */ - ExInterlockedInsertTailList(&DeviceExtension->KsAudioDeviceList, &DeviceEntry->Entry, &DeviceExtension->Lock); - - IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx); - return Status; - } - else - { - DPRINT("Remove interface to audio device!\n"); - UNIMPLEMENTED - return STATUS_SUCCESS; - } + DPRINT("Successfully opened audio device %u Device %S\n", DeviceExtension->NumberOfKsAudioDevices, DeviceEntry->DeviceName.Buffer); + IoQueueWorkItem(WorkItem, FilterPinWorkerRoutine, DelayedWorkQueue, (PVOID)Ctx); + return Status; cleanup: if (Ctx) @@ -331,6 +276,93 @@ cleanup: } return Status; + +} + + +NTSTATUS +NTAPI +DeviceInterfaceChangeCallback( + IN PVOID NotificationStructure, + IN PVOID Context) +{ + DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event; + NTSTATUS Status = STATUS_SUCCESS; + PSYSAUDIODEVEXT DeviceExtension; + UNICODE_STRING DeviceName; + HANDLE Handle; + PFILE_OBJECT FileObject; + LPWSTR ReferenceString; + ULONG BytesReturned; + + + PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context; + + DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; + + Event = (DEVICE_INTERFACE_CHANGE_NOTIFICATION*)NotificationStructure; + + if (IsEqualGUIDAligned(&Event->Event, + &GUID_DEVICE_INTERFACE_ARRIVAL)) + { + /* + * 1) Open the filter w/o reference string + * 2) Retrieve reference strings with our private IOCTL_KS_OBJECT_CLASS + * 3) Append these reference strings to symbolic link we got + * * see bug 4566 + */ + + DeviceName.Length = 0; + DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR); + + DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName.MaximumLength); + + if (!DeviceName.Buffer) + { + return STATUS_INSUFFICIENT_RESOURCES; + } + + RtlAppendUnicodeToString(&DeviceName, L"\\??\\"); + RtlAppendUnicodeStringToString(&DeviceName, Event->SymbolicLinkName); + + + Status = OpenDevice(&DeviceName, &Handle, &FileObject); + if (!NT_SUCCESS(Status)) + { + ExFreePool(DeviceName.Buffer); + return Status; + } + + Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_OBJECT_CLASS, NULL, 0, &ReferenceString, sizeof(LPWSTR), &BytesReturned); + if (!NT_SUCCESS(Status)) + { + DPRINT1("failed Status %x\n", Status); + + ExFreePool(DeviceName.Buffer); + ObDereferenceObject(FileObject); + ZwClose(Handle); + return Status; + } + + while(*ReferenceString) + { + Status = InsertAudioDevice(DeviceObject, Event->SymbolicLinkName, ReferenceString); + ReferenceString += wcslen(ReferenceString) + 1; + } + //ExFreePool(ReferenceString); + ObDereferenceObject(FileObject); + ZwClose(Handle); + ExFreePool(DeviceName.Buffer); + return Status; + } + else + { + DPRINT("Remove interface to audio device!\n"); + UNIMPLEMENTED + return STATUS_SUCCESS; + } + + } NTSTATUS diff --git a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c index 218772bfffb..078bf418258 100644 --- a/reactos/drivers/wdm/audio/sysaudio/dispatcher.c +++ b/reactos/drivers/wdm/audio/sysaudio/dispatcher.c @@ -201,7 +201,7 @@ DispatchCreateSysAudio( if (Buffer) { /* is the request for a new pin */ - if (!wcsncmp(KS_NAME_PIN, Buffer, wcslen(KS_NAME_PIN))) + if (wcsstr(Buffer, KS_NAME_PIN)) { Status = CreateDispatcher(Irp); DPRINT("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject); @@ -259,6 +259,7 @@ SysAudioAllocateDeviceHeader( RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM)); CreateItem->Create = DispatchCreateSysAudio; RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio"); + CreateItem->Flags = KSCREATE_ITEM_WILDCARD; Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader, 1, @@ -271,7 +272,6 @@ SysAudioOpenKMixer( IN SYSAUDIODEVEXT *DeviceExtension) { NTSTATUS Status; - UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\kmixer"); UNICODE_STRING DevicePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\kmixer"); diff --git a/reactos/drivers/wdm/audio/sysaudio/main.c b/reactos/drivers/wdm/audio/sysaudio/main.c index 628e8d1112b..6cdf2527cf8 100644 --- a/reactos/drivers/wdm/audio/sysaudio/main.c +++ b/reactos/drivers/wdm/audio/sysaudio/main.c @@ -34,9 +34,8 @@ SysAudio_Shutdown( IN PIRP Irp) { PKSAUDIO_DEVICE_ENTRY DeviceEntry; - PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; PSYSAUDIODEVEXT DeviceExtension; - PLIST_ENTRY Entry, SubEntry; + PLIST_ENTRY Entry; DPRINT1("SysAudio_Shutdown called\n"); @@ -50,16 +49,6 @@ SysAudio_Shutdown( DPRINT1("Freeing item %wZ\n", &DeviceEntry->DeviceName); RtlFreeUnicodeString(&DeviceEntry->DeviceName); - while(!IsListEmpty(&DeviceEntry->SubDeviceList)) - { - SubEntry = RemoveHeadList(&DeviceEntry->SubDeviceList); - SubDeviceEntry = (PKSAUDIO_SUBDEVICE_ENTRY)CONTAINING_RECORD(SubEntry, KSAUDIO_SUBDEVICE_ENTRY, Entry); - - ZwClose(SubDeviceEntry->Handle); - ObDereferenceObject(SubDeviceEntry->FileObject); - ExFreePool(SubDeviceEntry->Pins); - ExFreePool(SubDeviceEntry); - } ExFreePool(DeviceEntry); } diff --git a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h index 9673f21729a..8defc5b84c7 100644 --- a/reactos/drivers/wdm/audio/sysaudio/sysaudio.h +++ b/reactos/drivers/wdm/audio/sysaudio/sysaudio.h @@ -22,7 +22,8 @@ typedef struct typedef struct { - LIST_ENTRY Entry; // linked list entry to KSAUDIO_DEVICE_ENTRY + LIST_ENTRY Entry; // device entry for KsAudioDeviceList + UNICODE_STRING DeviceName; // symbolic link of audio device HANDLE Handle; // handle to audio sub device PFILE_OBJECT FileObject; // file objecto to audio sub device @@ -30,18 +31,6 @@ typedef struct ULONG NumberOfPins; // number of pins of audio device PIN_INFO * Pins; // array of PIN_INFO - LPWSTR ObjectClass; // object class of sub device - -}KSAUDIO_SUBDEVICE_ENTRY, *PKSAUDIO_SUBDEVICE_ENTRY; - -typedef struct -{ - LIST_ENTRY Entry; // device entry for KsAudioDeviceList - UNICODE_STRING DeviceName; // symbolic link of audio device - - ULONG NumSubDevices; // number of subdevices - LIST_ENTRY SubDeviceList; // audio sub device list - }KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY; typedef struct @@ -71,7 +60,7 @@ typedef struct { HANDLE Handle; // audio irp pin handle ULONG PinId; // pin id of device - PKSAUDIO_SUBDEVICE_ENTRY AudioEntry; // pointer to audio device entry + PKSAUDIO_DEVICE_ENTRY AudioEntry; // pointer to audio device entry HANDLE hMixerPin; // handle to mixer pin }DISPATCH_CONTEXT, *PDISPATCH_CONTEXT; @@ -86,7 +75,7 @@ typedef struct PIRP Irp; BOOL CreateRealPin; BOOL CreateMixerPin; - PKSAUDIO_SUBDEVICE_ENTRY Entry; + PKSAUDIO_DEVICE_ENTRY Entry; KSPIN_CONNECT * PinConnect; PDISPATCH_CONTEXT DispatchContext; PSYSAUDIODEVEXT DeviceExtension; @@ -129,7 +118,7 @@ OpenDevice( IN PHANDLE HandleOut, IN PFILE_OBJECT * FileObjectOut); -PKSAUDIO_SUBDEVICE_ENTRY +PKSAUDIO_DEVICE_ENTRY GetListEntry( IN PLIST_ENTRY Head, IN ULONG Index);