- 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
This commit is contained in:
Johannes Anderwald 2009-07-10 15:14:56 +00:00
parent 976cb25f51
commit b046ce1926
13 changed files with 458 additions and 461 deletions

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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))
{
/*<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;
}
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

View file

@ -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");

View file

@ -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);
}

View file

@ -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);