Author: janderwald Date: Fri Jul 10 19:14:56 2009 New Revision: 41842
URL: http://svn.reactos.org/svn/reactos?rev=41842&view=rev Log: [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
Modified: trunk/reactos/drivers/ksfilter/ks/connectivity.c trunk/reactos/drivers/ksfilter/ks/irp.c trunk/reactos/drivers/ksfilter/ks/kstypes.h trunk/reactos/drivers/ksfilter/ks/misc.c trunk/reactos/drivers/ksfilter/ks/topology.c trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c trunk/reactos/drivers/wdm/audio/sysaudio/control.c trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c trunk/reactos/drivers/wdm/audio/sysaudio/main.c trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
Modified: trunk/reactos/drivers/ksfilter/ks/connectivity.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/connect... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/connectivity.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/connectivity.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -45,26 +45,29 @@ 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) { UNIMPLEMENTED 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;
Modified: trunk/reactos/drivers/ksfilter/ks/irp.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/irp.c?r... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/irp.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -104,14 +104,15 @@ /* now scan the list and check for a free item */ for(Index = 0; Index < Header->MaxItems; Index++) { - if (!Header->ItemList[Index].bCreated) + ASSERT(Header->ItemList[Index].CreateItem); + + if (Header->ItemList[Index].CreateItem->Create == NULL) { - if (FreeIndex == (ULONG)-1) - FreeIndex = Index; - - continue; + 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 @@ /* 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++; - } - - /* 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; + /* no empty space found */ + return STATUS_ALLOTTED_SPACE_EXCEEDED; + } + + /* 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 @@
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 @@ PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; PKSIOBJECT_HEADER ObjectHeader; - WCHAR ObjectClass[50];
if (!Header) return STATUS_INVALID_PARAMETER_1; @@ -312,18 +299,10 @@ /* 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 @@ RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
/* do we have a name */ - if (ObjectClass[0]) - { - ObjectHeader->ObjectClass = ExAllocatePoolWithTag(NonPagedPool, 40 * sizeof(WCHAR), TAG_DEVICE_HEADER); - if (ObjectHeader->ObjectClass) + if (IoStack->FileObject->FileName.Buffer) + { + /* 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 @@ { /* 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 @@ *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 @@ 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 @@
/* 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); - - /* 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; - } + KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[Index].CreateItem; + + /* 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 @@ PKSIOBJECT_HEADER ObjectHeader; PDEVICE_EXTENSION DeviceExtension; PKSIDEVICE_HEADER DeviceHeader; - ULONG Index;
/* get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp); @@ -827,20 +838,20 @@ 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 @@ { 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 @@
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
Modified: trunk/reactos/drivers/ksfilter/ks/kstypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/kstypes... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/kstypes.h [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -6,17 +6,15 @@ 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;
Modified: trunk/reactos/drivers/ksfilter/ks/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/misc.c?... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/misc.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/misc.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -282,16 +282,18 @@ 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;
Modified: trunk/reactos/drivers/ksfilter/ks/topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/topolog... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -17,26 +17,56 @@ NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; OBJECT_ATTRIBUTES ObjectAttributes; + PFILE_OBJECT FileObject; UNICODE_STRING Name; - - Name.Length = Name.MaximumLength = (wcslen(ObjectType) + 1) * sizeof(WCHAR) + CreateParametersSize; + PKSIOBJECT_HEADER ObjectHeader; + + /* 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 @@ NULL, IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
+ /* free request buffer */ ExFreePool(Name.Buffer); + /* release parent handle */ + ObDereferenceObject(FileObject); return Status; }
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/irpstream.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -314,7 +314,7 @@ 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;
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/port_topology.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -542,6 +542,8 @@ 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 @@ return Status; }
- /* is just the filter requested */ - if (IoStack->FileObject->FileName.Buffer == NULL) - { - /* create the dispatch object */ + /* get the buffer */ + Buffer = IoStack->FileObject->FileName.Buffer; + + /* check if the request contains a pin request */ + if (!wcsstr(Buffer, KS_NAME_PIN)) + { + /* 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; } - } - Irp->IoStatus.Information = 0; - Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return Status; + /* 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; + } }
Modified: trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/filters/k... ============================================================================== --- trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/filters/kmixer/filter.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -201,7 +201,7 @@ 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);
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -20,7 +20,7 @@
NTSTATUS ComputeCompatibleFormat( - IN PKSAUDIO_SUBDEVICE_ENTRY Entry, + IN PKSAUDIO_DEVICE_ENTRY Entry, IN ULONG PinId, IN PSYSAUDIODEVEXT DeviceExtension, IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat, @@ -28,90 +28,6 @@
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, IN NTSTATUS Status, @@ -131,38 +47,20 @@
}
-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); - - return NULL; + if (Entry == Head) + return NULL; + + return (PKSAUDIO_DEVICE_ENTRY)CONTAINING_RECORD(Entry, KSAUDIO_DEVICE_ENTRY, Entry); }
NTSTATUS @@ -171,7 +69,7 @@ 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 @@ 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 @@
/* 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 @@ }
/* 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 @@
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 @@ { PIO_STACK_LOCATION IoStack; NTSTATUS Status; - PKSAUDIO_SUBDEVICE_ENTRY Entry; + PKSAUDIO_DEVICE_ENTRY Entry; ULONG BytesReturned; PKSP_PIN Pin;
@@ -541,7 +439,7 @@
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 @@
NTSTATUS GetPinInstanceCount( - PKSAUDIO_SUBDEVICE_ENTRY Entry, + PKSAUDIO_DEVICE_ENTRY Entry, PKSPIN_CINSTANCES PinInstances, PKSPIN_CONNECT PinConnect) { @@ -701,7 +599,7 @@ 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 @@ PULONG Index; PKSPROPERTY Property; PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_SUBDEVICE_ENTRY Entry; + PKSAUDIO_DEVICE_ENTRY Entry; PSYSAUDIO_INSTANCE_INFO InstanceInfo; ULONG BytesReturned; PKSOBJECT_CREATE_ITEM CreateItem;
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -18,7 +18,7 @@
VOID QueryFilterRoutine( - IN PKSAUDIO_SUBDEVICE_ENTRY DeviceEntry) + IN PKSAUDIO_DEVICE_ENTRY DeviceEntry) { KSPROPERTY PropertyRequest; KSP_PIN PinRequest; @@ -32,15 +32,6 @@
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 @@ DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, NumWaveOutPin); }
- - - VOID NTAPI FilterPinWorkerRoutine( @@ -124,21 +112,11 @@ 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 @@
if (!NT_SUCCESS(Status)) { - DPRINT("ZwCreateFile failed with %x\n", Status); + DPRINT("ZwCreateFile failed with %x %S\n", Status, DeviceName->Buffer); return Status; }
@@ -193,6 +171,114 @@ *FileObjectOut = FileObject; return Status; } + +NTSTATUS +InsertAudioDevice( + IN PDEVICE_OBJECT DeviceObject, + IN PUNICODE_STRING DeviceName, + IN LPWSTR ReferenceString) +{ + NTSTATUS Status = STATUS_SUCCESS; + PFILTER_WORKER_CONTEXT Ctx = NULL; + PIO_WORKITEM WorkItem = NULL; + PSYSAUDIODEVEXT DeviceExtension; + PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL; + + /* 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); + + 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) + ExFreePool(Ctx); + + if (WorkItem) + IoFreeWorkItem(WorkItem); + + if (DeviceEntry) + { + if (DeviceEntry->DeviceName.Buffer) + ExFreePool(DeviceEntry->DeviceName.Buffer); + + ExFreePool(DeviceEntry); + } + + return Status; + +} +
NTSTATUS NTAPI @@ -203,10 +289,13 @@ DEVICE_INTERFACE_CHANGE_NOTIFICATION * Event; NTSTATUS Status = STATUS_SUCCESS; PSYSAUDIODEVEXT DeviceExtension; - PKSAUDIO_DEVICE_ENTRY DeviceEntry = NULL; - PKSAUDIO_SUBDEVICE_ENTRY SubDeviceEntry; - PIO_WORKITEM WorkItem = NULL; - PFILTER_WORKER_CONTEXT Ctx = NULL; + UNICODE_STRING DeviceName; + HANDLE Handle; + PFILE_OBJECT FileObject; + LPWSTR ReferenceString; + ULONG BytesReturned; + + PDEVICE_OBJECT DeviceObject = (PDEVICE_OBJECT)Context;
DeviceExtension = (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension; @@ -216,96 +305,54 @@ if (IsEqualGUIDAligned(&Event->Event, &GUID_DEVICE_INTERFACE_ARRIVAL)) { - - /* a new device has arrived */ - DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY)); - if (!DeviceEntry) - { - /* no memory */ + /*<HACK> + * 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; }
- /* 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); + 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 @@ -315,22 +362,7 @@ return STATUS_SUCCESS; }
-cleanup: - if (Ctx) - ExFreePool(Ctx); - - if (WorkItem) - IoFreeWorkItem(WorkItem); - - if (DeviceEntry) - { - if (DeviceEntry->DeviceName.Buffer) - ExFreePool(DeviceEntry->DeviceName.Buffer); - - ExFreePool(DeviceEntry); - } - - return Status; + }
NTSTATUS
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -201,7 +201,7 @@ 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 @@ 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 @@ 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");
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -34,9 +34,8 @@ 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 @@ 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); }
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Fri Jul 10 19:14:56 2009 @@ -22,25 +22,14 @@
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
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;
@@ -71,7 +60,7 @@ { 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 @@ 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 @@ IN PHANDLE HandleOut, IN PFILE_OBJECT * FileObjectOut);
-PKSAUDIO_SUBDEVICE_ENTRY +PKSAUDIO_DEVICE_ENTRY GetListEntry( IN PLIST_ENTRY Head, IN ULONG Index);