- 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
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)
{
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;
/* 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;
/* 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;
}
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;
}
PDEVICE_EXTENSION DeviceExtension;
PKSIDEVICE_HEADER DeviceHeader;
PKSIOBJECT_HEADER ObjectHeader;
- WCHAR ObjectClass[50];
if (!Header)
return STATUS_INVALID_PARAMETER_1;
/* 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)
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 */
{
/* the object header is for a audio filter */
ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
- DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader;
IoStack->FileObject->FsContext = ObjectHeader;
}
*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;
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 */
/* acquire list lock */
KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel);
- /* loop all device items */
- for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
+
+ /* sanity check */
+ ASSERT(IoStack->FileObject);
+
+ if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->MaxItems == 1)
{
- if (DeviceHeader->ItemList[Index].bCreated && DeviceHeader->ItemList[Index].ObjectHeader == NULL)
+ /* hack for bug 4566 */
+ if (!DeviceHeader->ItemList[0].CreateItem || !DeviceHeader->ItemList[0].CreateItem->Create)
{
- 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;
- }
+ /* 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;
}
- 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);
+ /* set object create item */
+ KSCREATE_ITEM_IRP_STORAGE(Irp) = DeviceHeader->ItemList[0].CreateItem;
- Length = wcslen(DeviceHeader->ItemList[Index].ObjectHeader->CreateItem->ObjectClass.Buffer);
+ /* call create function */
+ Status = DeviceHeader->ItemList[0].CreateItem->Create(DeviceObject, Irp);
+ /* release lock */
+ KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
+ /* return result */
+ return Status;
+ }
- /* 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);
- }
+ /* 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++)
+ {
+ /* 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;
- KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem;
- Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp);
- KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
- return Status;
- }
- }
+ 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;
+
+ /* call create function */
+ Status = DeviceHeader->ItemList[Index].CreateItem->Create(DeviceObject, Irp);
+
+ /* release lock */
+ KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
+
+ /* return result */
+ return Status;
+ }
}
/* release lock */
PKSIOBJECT_HEADER ObjectHeader;
PDEVICE_EXTENSION DeviceExtension;
PKSIDEVICE_HEADER DeviceHeader;
- ULONG Index;
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
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;
}
}
{
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)
{
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
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;
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;
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);
-
+ InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE | OBJ_OPENIF, ParentHandle, NULL);
+ /* create the instance */
Status = IoCreateFile(NodeHandle,
DesiredAccess,
&ObjectAttributes,
NULL,
IO_NO_PARAMETER_CHECKING | IO_FORCE_ACCESS_CHECK);
+ /* free request buffer */
ExFreePool(Name.Buffer);
+ /* release parent handle */
+ ObDereferenceObject(FileObject);
return Status;
}
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;
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);
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;
}
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);
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,
}
-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
IN ULONG DeviceNumber,
PSYSAUDIODEVEXT DeviceExtension)
{
- PKSAUDIO_SUBDEVICE_ENTRY Entry;
+ PKSAUDIO_DEVICE_ENTRY Entry;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
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))
{
/* 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))
{
}
/* 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 */
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))
{
{
PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
- PKSAUDIO_SUBDEVICE_ENTRY Entry;
+ PKSAUDIO_DEVICE_ENTRY Entry;
ULONG BytesReturned;
PKSP_PIN Pin;
NTSTATUS
ComputeCompatibleFormat(
- IN PKSAUDIO_SUBDEVICE_ENTRY Entry,
+ IN PKSAUDIO_DEVICE_ENTRY Entry,
IN ULONG PinId,
IN PSYSAUDIODEVEXT DeviceExtension,
IN PKSDATAFORMAT_WAVEFORMATEX ClientFormat,
NTSTATUS
GetPinInstanceCount(
- PKSAUDIO_SUBDEVICE_ENTRY Entry,
+ PKSAUDIO_DEVICE_ENTRY Entry,
PKSPIN_CINSTANCES PinInstances,
PKSPIN_CONNECT PinConnect)
{
PDEVICE_OBJECT DeviceObject)
{
ULONG Length;
- PKSAUDIO_SUBDEVICE_ENTRY Entry;
+ PKSAUDIO_DEVICE_ENTRY Entry;
KSPIN_CONNECT * PinConnect;
PIO_STACK_LOCATION IoStack;
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
PULONG Index;
PKSPROPERTY Property;
PSYSAUDIODEVEXT DeviceExtension;
- PKSAUDIO_SUBDEVICE_ENTRY Entry;
+ PKSAUDIO_DEVICE_ENTRY Entry;
PSYSAUDIO_INSTANCE_INFO InstanceInfo;
ULONG BytesReturned;
PKSOBJECT_CREATE_ITEM CreateItem;
VOID
QueryFilterRoutine(
- IN PKSAUDIO_SUBDEVICE_ENTRY DeviceEntry)
+ IN PKSAUDIO_DEVICE_ENTRY DeviceEntry)
{
KSPROPERTY PropertyRequest;
KSP_PIN PinRequest;
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;
DPRINT("Num Pins %u Num WaveIn Pins %u Name WaveOut Pins %u\n", DeviceEntry->NumberOfPins, NumWaveInPin, NumWaveOutPin);
}
-
-
-
VOID
NTAPI
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);
if (!NT_SUCCESS(Status))
{
- DPRINT("ZwCreateFile failed with %x\n", Status);
+ DPRINT("ZwCreateFile failed with %x %S\n", Status, DeviceName->Buffer);
return Status;
}
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
DeviceInterfaceChangeCallback(
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;
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
+ */
- /* a new device has arrived */
- DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY));
- if (!DeviceEntry)
- {
- /* no memory */
- return STATUS_INSUFFICIENT_RESOURCES;
- }
+ DeviceName.Length = 0;
+ DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR);
- /* 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;
- }
+ DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceName.MaximumLength);
- /* allocate work item */
- WorkItem = IoAllocateWorkItem(DeviceObject);
- if (!WorkItem)
+ if (!DeviceName.Buffer)
{
- /* no memory */
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
+ return STATUS_INSUFFICIENT_RESOURCES;
}
- /* set device name */
- DeviceEntry->DeviceName.Length = 0;
- DeviceEntry->DeviceName.MaximumLength = Event->SymbolicLinkName->Length + 10 * sizeof(WCHAR);
- DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength);
+ RtlAppendUnicodeToString(&DeviceName, L"\\??\\");
+ RtlAppendUnicodeStringToString(&DeviceName, Event->SymbolicLinkName);
- if (!DeviceEntry->DeviceName.Buffer)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
- goto cleanup;
- }
- if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\\??\\")))
+ Status = OpenDevice(&DeviceName, &Handle, &FileObject);
+ if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlAppendUnicodeToString failed with %x\n", Status);
- goto cleanup;
+ ExFreePool(DeviceName.Buffer);
+ return Status;
}
- if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName)))
+ Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_OBJECT_CLASS, NULL, 0, &ReferenceString, sizeof(LPWSTR), &BytesReturned);
+ if (!NT_SUCCESS(Status))
{
- DPRINT1("RtlAppendUnicodeStringToString failed with %x\n", Status);
- goto cleanup;
- }
+ DPRINT1("failed Status %x\n", Status);
- /* 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 */
+ ExFreePool(DeviceName.Buffer);
+ ObDereferenceObject(FileObject);
+ ZwClose(Handle);
+ return Status;
+ }
- InitializeListHead(&DeviceEntry->SubDeviceList);
- do
+ while(*ReferenceString)
{
- 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);
+ Status = InsertAudioDevice(DeviceObject, Event->SymbolicLinkName, ReferenceString);
+ ReferenceString += wcslen(ReferenceString) + 1;
+ }
+ //ExFreePool(ReferenceString);
+ ObDereferenceObject(FileObject);
+ ZwClose(Handle);
+ ExFreePool(DeviceName.Buffer);
return Status;
}
else
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
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);
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
CreateItem->Create = DispatchCreateSysAudio;
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
+ CreateItem->Flags = KSCREATE_ITEM_WILDCARD;
Status = KsAllocateDeviceHeader(&DeviceExtension->KsDeviceHeader,
1,
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");
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");
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);
}
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;
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;
PIRP Irp;
BOOL CreateRealPin;
BOOL CreateMixerPin;
- PKSAUDIO_SUBDEVICE_ENTRY Entry;
+ PKSAUDIO_DEVICE_ENTRY Entry;
KSPIN_CONNECT * PinConnect;
PDISPATCH_CONTEXT DispatchContext;
PSYSAUDIODEVEXT DeviceExtension;
IN PHANDLE HandleOut,
IN PFILE_OBJECT * FileObjectOut);
-PKSAUDIO_SUBDEVICE_ENTRY
+PKSAUDIO_DEVICE_ENTRY
GetListEntry(
IN PLIST_ENTRY Head,
IN ULONG Index);