- Rewrite KSCREATE_ITEM handling to support clocks, nodes, allocators. 
- Store create items in list instead of an array. Consequently, the code can be re-used for KSDEVICE_HEADER / KSOBJECT_HEADER functions. 
- Implement KsAddObjectCreateItemToObjectHeader
- Implement now KspCreate and IKsDevice_Create properly
- Implement KsGetDevice by using KSBASIC_HEADER struct which must be positioned before its object specific (PKSFILTER, PKSFILTERFACTOR, PKSPIN)
- Remove a hack from KspCreateObjectType
[PORTCLS]
- Store real dispatched object in FsContext2
- Implement a fast device i/o handler
- Increase minimum data threshold when a stream stops prematurely by 10 audio frames (port driver WaveCyclic)
- Remove the hack of checking wether pin create request is passed. Since create items now work nicely, use a different function and handle pin creation requests seperately.
[KMIXER]
- Remove the hack of checking wether pin create request is passed. Since create items now work nicely, use a different function and handle pin creation requests seperately.
[SYSAUDIO]
- Remove the hack of checking wether pin create request is passed. Since create items now work nicely, use a different function and handle pin creation requests seperately.



svn path=/trunk/; revision=42143
This commit is contained in:
Johannes Anderwald 2009-07-22 14:42:51 +00:00
parent 8497361513
commit 3e489bf3af
26 changed files with 852 additions and 587 deletions

View file

@ -550,7 +550,6 @@ KsCreateDefaultAllocatorEx(
NTSTATUS Status;
PKSALLOCATOR_FRAMING AllocatorFraming;
PALLOCATOR Allocator;
PKSOBJECT_CREATE_ITEM CreateItem;
PVOID Ctx;
/* first validate connect request */
@ -568,6 +567,7 @@ KsCreateDefaultAllocatorEx(
return STATUS_INSUFFICIENT_RESOURCES;
/* allocate object header */
Status = KsAllocateObjectHeader((KSOBJECT_HEADER*)&Allocator->Header, 0, NULL, Irp, &DispatchTable);
if (!NT_SUCCESS(Status))
{
@ -619,16 +619,6 @@ KsCreateDefaultAllocatorEx(
/* backup allocator framing */
RtlMoveMemory(&Allocator->Status.Framing, AllocatorFraming, sizeof(KSALLOCATOR_FRAMING));
/* get create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
if (CreateItem)
{
/* store create item */
Allocator->Header->CreateItem = CreateItem;
Allocator->Header->ItemCount = 1;
}
return Status;
}

View file

@ -414,6 +414,65 @@ KsQueryObjectCreateItem(
return NULL;
}
NTSTATUS
KspAddCreateItemToList(
OUT PLIST_ENTRY ListHead,
IN ULONG ItemsCount,
IN PKSOBJECT_CREATE_ITEM ItemsList)
{
ULONG Index;
PCREATE_ITEM_ENTRY Entry;
/* add the items */
for(Index = 0; Index < ItemsCount; Index++)
{
/* allocate item */
Entry = AllocateItem(NonPagedPool, sizeof(CREATE_ITEM_ENTRY));
if (!Entry)
{
/* no memory */
return STATUS_INSUFFICIENT_RESOURCES;
}
/* initialize entry */
InitializeListHead(&Entry->ObjectItemList);
Entry->CreateItem = &ItemsList[Index];
Entry->ReferenceCount = 0;
Entry->ItemFreeCallback = NULL;
InsertTailList(ListHead, &Entry->Entry);
}
return STATUS_SUCCESS;
}
VOID
KspFreeCreateItems(
PLIST_ENTRY ListHead)
{
PCREATE_ITEM_ENTRY Entry;
while(!IsListEmpty(ListHead))
{
/* remove create item from list */
Entry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(RemoveHeadList(ListHead), CREATE_ITEM_ENTRY, Entry);
/* caller shouldnt have any references */
ASSERT(Entry->ReferenceCount == 0);
ASSERT(IsListEmpty(&Entry->ObjectItemList));
/* does the creator wish notification */
if (Entry->ItemFreeCallback)
{
/* notify creator */
Entry->ItemFreeCallback(Entry->CreateItem);
}
/* free create item entry */
FreeItem(Entry);
}
}
/*
@implemented
*/
@ -425,7 +484,7 @@ KsAllocateDeviceHeader(
IN ULONG ItemsCount,
IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
{
ULONG Index = 0;
NTSTATUS Status = STATUS_SUCCESS;
PKSIDEVICE_HEADER Header;
if (!OutHeader)
@ -441,9 +500,6 @@ KsAllocateDeviceHeader(
/* clear all memory */
RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER));
/* initialize spin lock */
KeInitializeSpinLock(&Header->ItemListLock); //FIXME
/* initialize device mutex */
KeInitializeMutex(&Header->DeviceMutex, 0);
@ -452,34 +508,34 @@ KsAllocateDeviceHeader(
/* initialize power dispatch list */
InitializeListHead(&Header->PowerDispatchList);
/* initialize create item list */
InitializeListHead(&Header->ItemList);
/* are there any create items provided */
if (ItemsCount && ItemsList)
{
/* allocate space for device item list */
Header->ItemList = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * ItemsCount, TAG_DEVICE_HEADER);
if (!Header->ItemList)
{
ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(Header->ItemList, sizeof(DEVICE_ITEM) * ItemsCount);
Status = KspAddCreateItemToList(&Header->ItemList, ItemsCount, ItemsList);
for(Index = 0; Index < ItemsCount; Index++)
if (NT_SUCCESS(Status))
{
/* store provided create items */
Header->ItemList[Index].CreateItem = &ItemsList[Index];
/* store item count */
Header->ItemListCount = ItemsCount;
}
else
{
/* release create items */
KspFreeCreateItems(&Header->ItemList);
}
Header->MaxItems = ItemsCount;
}
/* store result */
*OutHeader = Header;
return STATUS_SUCCESS;
return Status;
}
/*
@unimplemented
@implemented
*/
KSDDKAPI
VOID
@ -494,7 +550,7 @@ KsFreeDeviceHeader(
if (!DevHeader)
return;
ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER);
KspFreeCreateItems(&Header->ItemList);
ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
}
@ -515,6 +571,8 @@ KsAllocateObjectHeader(
PDEVICE_EXTENSION DeviceExtension;
PKSIDEVICE_HEADER DeviceHeader;
PKSIOBJECT_HEADER ObjectHeader;
PKSOBJECT_CREATE_ITEM CreateItem;
NTSTATUS Status;
if (!Header)
return STATUS_INVALID_PARAMETER_1;
@ -544,6 +602,12 @@ KsAllocateObjectHeader(
/* initialize object header */
RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
/* initialize create item list */
InitializeListHead(&ObjectHeader->ItemList);
/* get create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* do we have a name */
if (IoStack->FileObject->FileName.Buffer)
{
@ -560,28 +624,34 @@ KsAllocateObjectHeader(
/* copy dispatch table */
RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE));
/* store create items */
if (ItemsCount && ItemsList)
{
ObjectHeader->ItemCount = ItemsCount;
ObjectHeader->CreateItem = ItemsList;
}
Status = KspAddCreateItemToList(&ObjectHeader->ItemList, ItemsCount, ItemsList);
if (NT_SUCCESS(Status))
{
/* store item count */
ObjectHeader->ItemListCount = ItemsCount;
}
else
{
/* destroy header*/
KsFreeObjectHeader(ObjectHeader);
return Status;
}
}
/* store the object in the file object */
ASSERT(IoStack->FileObject->FsContext == NULL);
IoStack->FileObject->FsContext = ObjectHeader;
/* the object header is for a audio filter */
ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
/* store parent device */
ObjectHeader->ParentDeviceObject = IoGetRelatedDeviceObject(IoStack->FileObject);
/* store result */
*Header = ObjectHeader;
DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader);
return STATUS_SUCCESS;
@ -611,13 +681,59 @@ KsFreeObjectHeader(
ObjectHeader->Unknown->lpVtbl->Release(ObjectHeader->Unknown);
}
/* FIXME free create items */
/* free create items */
KspFreeCreateItems(&ObjectHeader->ItemList);
/* free object header */
ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER);
}
NTSTATUS
KspAddObjectCreateItemToList(
PLIST_ENTRY ListHead,
IN PDRIVER_DISPATCH Create,
IN PVOID Context,
IN PWCHAR ObjectClass,
IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
PLIST_ENTRY Entry;
PCREATE_ITEM_ENTRY CreateEntry;
/* point to first entry */
Entry = ListHead->Flink;
while(Entry != ListHead)
{
/* get create entry */
CreateEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
/* if the create item has no create routine, then it is free to use */
if (CreateEntry->CreateItem->Create == NULL)
{
/* sanity check */
ASSERT(IsListEmpty(&CreateEntry->ObjectItemList));
ASSERT(CreateEntry->ReferenceCount == 0);
/* use free entry */
CreateEntry->CreateItem->Context = Context;
CreateEntry->CreateItem->Create = Create;
RtlInitUnicodeString(&CreateEntry->CreateItem->ObjectClass, ObjectClass);
CreateEntry->CreateItem->SecurityDescriptor = SecurityDescriptor;
return STATUS_SUCCESS;
}
if (!wcsicmp(ObjectClass, CreateEntry->CreateItem->ObjectClass.Buffer))
{
/* the same object class already exists */
return STATUS_OBJECT_NAME_COLLISION;
}
/* iterate to next entry */
Entry = Entry->Flink;
}
return STATUS_ALLOTTED_SPACE_EXCEEDED;
}
/*
@implemented
*/
@ -632,7 +748,7 @@ KsAddObjectCreateItemToDeviceHeader(
IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
PKSIDEVICE_HEADER Header;
ULONG FreeIndex, Index;
NTSTATUS Status;
Header = (PKSIDEVICE_HEADER)DevHeader;
@ -650,39 +766,16 @@ KsAddObjectCreateItemToDeviceHeader(
if (!ObjectClass)
return STATUS_INVALID_PARAMETER_4;
FreeIndex = (ULONG)-1;
/* now scan the list and check for a free item */
for(Index = 0; Index < Header->MaxItems; Index++)
{
ASSERT(Header->ItemList[Index].CreateItem);
/* let others do the work */
Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor);
if (Header->ItemList[Index].CreateItem->Create == NULL)
{
FreeIndex = Index;
break;
}
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)
if (NT_SUCCESS(Status))
{
/* no empty space found */
return STATUS_ALLOTTED_SPACE_EXCEEDED;
/* increment create item count */
InterlockedIncrement(&Header->ItemListCount);
}
/* 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;
return Status;
}
/*
@ -692,14 +785,41 @@ KSDDKAPI
NTSTATUS
NTAPI
KsAddObjectCreateItemToObjectHeader(
IN KSOBJECT_HEADER Header,
IN KSOBJECT_HEADER ObjectHeader,
IN PDRIVER_DISPATCH Create,
IN PVOID Context,
IN PWCHAR ObjectClass,
IN PSECURITY_DESCRIPTOR SecurityDescriptor)
{
UNIMPLEMENTED;
return STATUS_UNSUCCESSFUL;
PKSIOBJECT_HEADER Header;
NTSTATUS Status;
Header = (PKSIOBJECT_HEADER)ObjectHeader;
DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
/* check if a device header has been provided */
if (!Header)
return STATUS_INVALID_PARAMETER_1;
/* check if a create item has been provided */
if (!Create)
return STATUS_INVALID_PARAMETER_2;
/* check if a object class has been provided */
if (!ObjectClass)
return STATUS_INVALID_PARAMETER_4;
/* let's work */
Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor);
if (NT_SUCCESS(Status))
{
/* increment create item count */
InterlockedIncrement(&Header->ItemListCount);
}
return Status;
}
/*
@ -714,10 +834,9 @@ KsAllocateObjectCreateItem(
IN BOOLEAN AllocateEntry,
IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL)
{
PCREATE_ITEM_ENTRY CreateEntry;
PKSIDEVICE_HEADER Header;
PKSOBJECT_CREATE_ITEM Item;
PDEVICE_ITEM ItemList;
KIRQL OldLevel;
Header = (PKSIDEVICE_HEADER)DevHeader;
@ -727,35 +846,25 @@ KsAllocateObjectCreateItem(
if (!CreateItem)
return STATUS_INVALID_PARAMETER_2;
/* acquire list lock */
KeAcquireSpinLock(&Header->ItemListLock, &OldLevel);
/* first allocate a create entry */
CreateEntry = AllocateItem(NonPagedPool, sizeof(PCREATE_ITEM_ENTRY));
ItemList = ExAllocatePool(NonPagedPool, sizeof(DEVICE_ITEM) * (Header->MaxItems + 1));
if (!ItemList)
/* check for allocation success */
if (!CreateEntry)
{
/* not enough resources */
return STATUS_INSUFFICIENT_RESOURCES;
}
if (AllocateEntry)
{
if (!ItemFreeCallback)
{
/* caller must be notified */
ExFreePool(ItemList);
/* release lock */
KeReleaseSpinLock(&Header->ItemListLock, OldLevel);
return STATUS_INVALID_PARAMETER_4;
}
/* allocate create item */
Item = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
if (!Item)
{
/* no memory */
ExFreePool(ItemList);
/* release lock */
KeReleaseSpinLock(&Header->ItemListLock, OldLevel);
ExFreePool(CreateEntry);
return STATUS_INSUFFICIENT_RESOURCES;
}
@ -772,15 +881,11 @@ KsAllocateObjectCreateItem(
if (!Item->ObjectClass.Buffer)
{
/* release resources */
ExFreePool(Item);
ExFreePool(ItemList);
/* release lock */
KeReleaseSpinLock(&Header->ItemListLock, OldLevel);
FreeItem(Item);
FreeItem(CreateEntry);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlCopyUnicodeString(&Item->ObjectClass, &CreateItem->ObjectClass);
}
else
@ -788,39 +893,25 @@ KsAllocateObjectCreateItem(
if (ItemFreeCallback)
{
/* callback is only accepted when the create item is copied */
ExFreePool(ItemList);
/* release lock */
KeReleaseSpinLock(&Header->ItemListLock, OldLevel);
return STATUS_INVALID_PARAMETER_4;
ItemFreeCallback = NULL;
}
/* use passed create item */
Item = CreateItem;
}
/* initialize create item entry */
InitializeListHead(&CreateEntry->ObjectItemList);
CreateEntry->ItemFreeCallback = ItemFreeCallback;
CreateEntry->CreateItem = Item;
CreateEntry->ReferenceCount = 0;
if (Header->MaxItems)
{
/* copy old create items */
RtlMoveMemory(ItemList, Header->ItemList, sizeof(DEVICE_ITEM) * Header->MaxItems);
}
/* now insert the create item entry */
InsertTailList(&Header->ItemList, &CreateEntry->Entry);
/* initialize item entry */
ItemList[Header->MaxItems].CreateItem = Item;
ItemList[Header->MaxItems].ItemFreeCallback = ItemFreeCallback;
/* free old item list */
ExFreePool(Header->ItemList);
Header->ItemList = ItemList;
Header->MaxItems++;
/* release lock */
KeReleaseSpinLock(&Header->ItemListLock, OldLevel);
/* increment item count */
InterlockedIncrement(&Header->ItemListCount);
return STATUS_SUCCESS;
}
NTSTATUS
@ -990,7 +1081,7 @@ KsSynchronousIoControlDevice(
/* it is send the request */
Status = ObjectHeader->DispatchTable.FastDeviceIoControl(FileObject, TRUE, InBuffer, InSize, OutBuffer, OutSize, IoControl, &IoStatusBlock, DeviceObject);
/* check if the request was handled */
DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information);
//DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information);
if (Status)
{
/* store bytes returned */

View file

@ -159,13 +159,6 @@ KsCreateDefaultClock(
/* get create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
if (CreateItem)
{
/* store create item */
Clock->ObjectHeader->CreateItem = CreateItem;
Clock->ObjectHeader->ItemCount = 1;
}
return Status;
}

View file

@ -532,12 +532,12 @@ IKsDevice_Create(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PCREATE_ITEM_ENTRY CreateItemEntry;
PIO_STACK_LOCATION IoStack;
PDEVICE_EXTENSION DeviceExtension;
PKSIDEVICE_HEADER DeviceHeader;
ULONG Index;
PKSIOBJECT_HEADER ObjectHeader;
NTSTATUS Status;
ULONG Length;
DPRINT("KS / CREATE\n");
/* get current stack location */
@ -553,49 +553,54 @@ IKsDevice_Create(
/* sanity check */
ASSERT(IoStack->FileObject);
/* loop all device items */
for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
/* check if the request is relative */
if (IoStack->FileObject->RelatedFileObject != NULL)
{
/* is there a create item */
if (DeviceHeader->ItemList[Index].CreateItem == NULL)
continue;
/* request is to instantiate a pin / node / clock / allocator */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext;
/* check if the create item is initialized */
if (!DeviceHeader->ItemList[Index].CreateItem->Create)
continue;
/* sanity check */
ASSERT(ObjectHeader);
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 */
IKsDevice_fnRelease((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
/* did we succeed */
if (NT_SUCCESS(Status))
{
/* increment create item reference count */
InterlockedIncrement((PLONG)&DeviceHeader->ItemList[Index].ReferenceCount);
}
/* return result */
return Status;
}
/* find a matching a create item */
Status = FindMatchingCreateItem(&ObjectHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
}
else
{
/* request to create a filter */
Status = FindMatchingCreateItem(&DeviceHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
}
if (NT_SUCCESS(Status))
{
/* set object create item */
KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
/* call create function */
Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
if (NT_SUCCESS(Status))
{
/* increment create item reference count */
InterlockedIncrement(&CreateItemEntry->ReferenceCount);
}
/* acquire list lock */
IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
return Status;
}
/* acquire list lock */
IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
DPRINT1("No item found for Request %p\n", IoStack->FileObject->FileName.Buffer);
Irp->IoStatus.Information = 0;
/* set return status */
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_UNSUCCESSFUL;
/* release lock */
IKsDevice_fnRelease((IKsDevice*)&DeviceHeader->lpVtblIKsDevice);
@ -641,6 +646,7 @@ KsInitializeDevice(
KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject);
/* initialize IKsDevice interface */
Header->lpVtblIKsDevice = &vt_IKsDevice;
Header->Type = KsObjectTypeDevice;
Header->ref = 1;
/* FIXME Power state */

View file

@ -39,6 +39,22 @@ KsGetDeviceForDeviceObject(
return &DeviceExtension->DeviceHeader->KsDevice;
}
/*
@implemented
*/
KSDDKAPI
PKSDEVICE
NTAPI
KsGetDevice(
IN PVOID Object)
{
PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)(ULONG_PTR)Object - sizeof(KSBASIC_HEADER);
ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == BasicHeader->Type);
return BasicHeader->KsDevice;
}
/*
@implemented
*/

View file

@ -11,13 +11,15 @@
typedef struct
{
KSBASIC_HEADER Header;
KSFILTER Filter;
IKsFilterVtbl *lpVtbl;
IKsControlVtbl *lpVtblKsControl;
IKsFilterFactory * FilterFactory;
LONG ref;
PKSIOBJECT_HEADER ObjectHeader;
KSFILTER Filter;
KSTOPOLOGY Topology;
KSPIN_DESCRIPTOR * PinDescriptors;
ULONG PinDescriptorCount;
@ -831,8 +833,11 @@ KspCreateFilter(
IKsFilterImpl * This;
PKSFILTERFACTORY Factory;
PIO_STACK_LOCATION IoStack;
PDEVICE_EXTENSION DeviceExtension;
NTSTATUS Status;
/* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* get the filter factory */
Factory = iface->lpVtbl->GetStruct(iface);
@ -859,6 +864,8 @@ KspCreateFilter(
This->Factory = Factory;
This->FilterFactory = iface;
This->FileObject = IoStack->FileObject;
This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
This->Header.Type = KsObjectTypeFilter;
/* allocate the stream descriptors */
Status = IKsFilter_CreateDescriptors(This, (PKSFILTER_DESCRIPTOR)Factory->FilterDescriptor);
@ -908,6 +915,8 @@ KspCreateFilter(
}
/* initialize object header */
This->Header.Type = KsObjectTypeFilter;
This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
This->ObjectHeader->Type = KsObjectTypeFilter;
This->ObjectHeader->Unknown = (PUNKNOWN)&This->lpVtbl;

View file

@ -11,19 +11,17 @@
typedef struct
{
IKsFilterFactoryVtbl *lpVtbl;
KSBASIC_HEADER Header;
KSFILTERFACTORY FilterFactory;
PKSIDEVICE_HEADER DeviceHeader;
IKsFilterFactoryVtbl *lpVtbl;
LONG ref;
PKSIDEVICE_HEADER DeviceHeader;
PFNKSFILTERFACTORYPOWER SleepCallback;
PFNKSFILTERFACTORYPOWER WakeCallback;
LIST_ENTRY SymbolicLinkList;
LIST_ENTRY FilterInstanceList;
}IKsFilterFactoryImpl;
typedef struct
@ -178,10 +176,17 @@ IKsFilterFactory_fnInitialize(
IKsFilterFactoryImpl * This = (IKsFilterFactoryImpl*)CONTAINING_RECORD(iface, IKsFilterFactoryImpl, lpVtbl);
/* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* initialize filterfactory */
This->SleepCallback = SleepCallback;
This->WakeCallback = WakeCallback;
This->FilterFactory.FilterDescriptor = Descriptor;
This->Header.KsDevice = &DeviceExtension->DeviceHeader->KsDevice;
This->Header.Type = KsObjectTypeFilterFactory;
This->DeviceHeader = DeviceExtension->DeviceHeader;
InitializeListHead(&This->SymbolicLinkList);
InitializeListHead(&This->FilterInstanceList);
@ -206,9 +211,6 @@ IKsFilterFactory_fnInitialize(
FreeString = TRUE;
}
/* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
/* now register the device interface */
Status = KspRegisterDeviceInterfaces(DeviceExtension->DeviceHeader->KsDevice.PhysicalDeviceObject,
Descriptor->CategoriesCount,

View file

@ -269,7 +269,7 @@ KsReadFile(
}
/*
@unimplemented
@implemented
*/
KSDDKAPI
NTSTATUS
@ -903,19 +903,85 @@ KsGetChildCreateParameter(
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
FindMatchingCreateItem(
PLIST_ENTRY ListHead,
ULONG BufferSize,
LPWSTR Buffer,
OUT PCREATE_ITEM_ENTRY *OutCreateItem)
{
PLIST_ENTRY Entry;
PCREATE_ITEM_ENTRY CreateItemEntry;
/* remove '\' slash */
Buffer++;
BufferSize -= sizeof(WCHAR);
/* point to first entry */
Entry = ListHead->Flink;
/* loop all device items */
while(Entry != ListHead)
{
/* get create item entry */
CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
ASSERT(CreateItemEntry->CreateItem);
if(CreateItemEntry->CreateItem->Flags & KSCREATE_ITEM_WILDCARD)
{
/* create item is default */
*OutCreateItem = CreateItemEntry;
return STATUS_SUCCESS;
}
if (!CreateItemEntry->CreateItem->Create)
{
/* skip free create item */
Entry = Entry->Flink;
continue;
}
ASSERT(CreateItemEntry->CreateItem->ObjectClass.Buffer);
DPRINT1("CreateItem %S Length %u Request %S %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
CreateItemEntry->CreateItem->ObjectClass.Length,
Buffer,
BufferSize);
if (CreateItemEntry->CreateItem->ObjectClass.Length > BufferSize)
{
/* create item doesnt match in length */
Entry = Entry->Flink;
continue;
}
/* now check if the object class is the same */
if (RtlCompareMemory(CreateItemEntry->CreateItem->ObjectClass.Buffer, Buffer, CreateItemEntry->CreateItem->ObjectClass.Length) == CreateItemEntry->CreateItem->ObjectClass.Length)
{
/* found matching create item */
*OutCreateItem = CreateItemEntry;
return STATUS_SUCCESS;
}
/* iterate to next */
Entry = Entry->Flink;
}
return STATUS_NOT_FOUND;
}
NTAPI
NTSTATUS
KspCreate(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PCREATE_ITEM_ENTRY CreateItemEntry;
PIO_STACK_LOCATION IoStack;
PDEVICE_EXTENSION DeviceExtension;
PKSIDEVICE_HEADER DeviceHeader;
ULONG Index;
PKSIOBJECT_HEADER ObjectHeader;
NTSTATUS Status;
KIRQL OldLevel;
ULONG Length;
DPRINT("KS / CREATE\n");
/* get current stack location */
@ -925,41 +991,36 @@ KspCreate(
/* get device header */
DeviceHeader = DeviceExtension->DeviceHeader;
/* acquire list lock */
KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel);
/* sanity check */
ASSERT(IoStack->FileObject);
if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->MaxItems == 1)
if (IoStack->FileObject->FileName.Buffer == NULL && DeviceHeader->ItemListCount == 1)
{
/* hack for bug 4566 */
if (!DeviceHeader->ItemList[0].CreateItem || !DeviceHeader->ItemList[0].CreateItem->Create)
ASSERT(!IsListEmpty(&DeviceHeader->ItemList));
/* get create item entry */
CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(DeviceHeader->ItemList.Flink, CREATE_ITEM_ENTRY, Entry);
ASSERT(CreateItemEntry->CreateItem);
if (!CreateItemEntry->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;
KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
/* call create function */
Status = DeviceHeader->ItemList[0].CreateItem->Create(DeviceObject, Irp);
Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
if (NT_SUCCESS(Status))
{
/* increment create item reference count */
InterlockedIncrement((PLONG)&DeviceHeader->ItemList[0].ReferenceCount);
InterlockedIncrement(&CreateItemEntry->ReferenceCount);
}
/* release lock */
KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
/* return result */
return Status;
}
@ -969,8 +1030,6 @@ KspCreate(
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;
@ -978,51 +1037,40 @@ KspCreate(
return STATUS_SUCCESS;
}
/* loop all device items */
for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
if (IoStack->FileObject->RelatedFileObject != NULL)
{
/* is there a create item */
if (DeviceHeader->ItemList[Index].CreateItem == NULL)
continue;
/* request is to instantiate a pin / node / clock / allocator */
ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext;
/* check if the create item is initialized */
if (!DeviceHeader->ItemList[Index].CreateItem->Create)
continue;
/* sanity check */
ASSERT(ObjectHeader);
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);
if (NT_SUCCESS(Status))
{
/* increment create item reference count */
InterlockedIncrement((PLONG)&DeviceHeader->ItemList[Index].ReferenceCount);
}
/* release lock */
KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
/* return result */
return Status;
}
/* find a matching a create item */
Status = FindMatchingCreateItem(&ObjectHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
}
else
{
/* request to create a filter */
Status = FindMatchingCreateItem(&DeviceHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
}
if (NT_SUCCESS(Status))
{
/* set object create item */
KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
/* call create function */
Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
if (NT_SUCCESS(Status))
{
/* increment create item reference count */
InterlockedIncrement(&CreateItemEntry->ReferenceCount);
}
return Status;
}
/* release lock */
KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
Irp->IoStatus.Information = 0;
/* set return status */
@ -1031,6 +1079,81 @@ KspCreate(
return STATUS_UNSUCCESSFUL;
}
NTSTATUS
RosDeviceInterfaceReferenceStringHack(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
PKSIDEVICE_HEADER DeviceHeader;
PDEVICE_EXTENSION DeviceExtension;
PCREATE_ITEM_ENTRY CreateItemEntry;
PLIST_ENTRY Entry;
LPWSTR Buffer;
ULONG Length;
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* get device extension */
DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
/* get device header */
DeviceHeader = DeviceExtension->DeviceHeader;
/* retrieve all available reference strings registered */
Length = 0;
Entry = DeviceHeader->ItemList.Flink;
while(Entry != &DeviceHeader->ItemList)
{
CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
ASSERT(CreateItemEntry->CreateItem);
if (CreateItemEntry->CreateItem->Create && CreateItemEntry->CreateItem->ObjectClass.Buffer)
Length += wcslen(CreateItemEntry->CreateItem->ObjectClass.Buffer) + 1;
Entry = Entry->Flink;
}
/* 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);
Entry = DeviceHeader->ItemList.Flink;
while(Entry != &DeviceHeader->ItemList)
{
CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
ASSERT(CreateItemEntry->CreateItem);
if (CreateItemEntry->CreateItem->Create && CreateItemEntry->CreateItem->ObjectClass.Buffer)
{
wcscpy(Buffer, CreateItemEntry->CreateItem->ObjectClass.Buffer);
Buffer += wcslen(Buffer) + 1;
}
Entry = Entry->Flink;
}
*Buffer = L'\0';
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTAPI
NTSTATUS
KspDeviceControl(
@ -1041,8 +1164,8 @@ KspDeviceControl(
PKSIOBJECT_HEADER ObjectHeader;
PKSIDEVICE_HEADER DeviceHeader;
PDEVICE_EXTENSION DeviceExtension;
ULONG Length, Index;
LPWSTR Buffer;
/* get current stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
@ -1052,65 +1175,18 @@ KspDeviceControl(
/* get device header */
DeviceHeader = DeviceExtension->DeviceHeader;
/* hack for bug 4566 */
if (IoStack->MajorFunction == IRP_MJ_DEVICE_CONTROL && IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_OBJECT_CLASS)
{
/* 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;
/* hack for bug 4566 */
return RosDeviceInterfaceReferenceStringHack(DeviceObject, Irp);
}
DPRINT("KS / DeviceControl\n");
if (IoStack->FileObject && IoStack->FileObject->FsContext)
{
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
ASSERT(ObjectHeader);
//KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
}
else
{
DPRINT1("Expected Object Header\n");
KeBugCheckEx(0, 0, 0, 0, 0);
return STATUS_SUCCESS;
}
return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
}
NTAPI
@ -1150,7 +1226,7 @@ KspDispatchIrp(
/* sanity check */
ASSERT(ObjectHeader);
/* store create item */
KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
//KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
/* retrieve matching dispatch function */
switch(IoStack->MajorFunction)

View file

@ -2,6 +2,7 @@
#define KSFUNC_H__
#include "ksiface.h"
#include "kstypes.h"
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
#define TAG_KSDEVICE TAG('K', 'S', 'E', 'D')
@ -99,4 +100,11 @@ KspPinPropertyHandler(
IN PKSIDENTIFIER Request,
IN OUT PVOID Data);
NTSTATUS
FindMatchingCreateItem(
PLIST_ENTRY ListHead,
ULONG BufferSize,
LPWSTR Buffer,
OUT PCREATE_ITEM_ENTRY *OutCreateItem);
#endif

View file

@ -5,8 +5,9 @@ typedef struct
{
KSDISPATCH_TABLE DispatchTable;
KSOBJECTTYPE Type;
ULONG ItemCount;
PKSOBJECT_CREATE_ITEM CreateItem;
LONG ItemListCount;
LIST_ENTRY ItemList;
UNICODE_STRING ObjectClass;
PUNKNOWN Unknown;
@ -24,32 +25,38 @@ typedef struct
typedef struct
{
LIST_ENTRY Entry;
PKSOBJECT_CREATE_ITEM CreateItem;
PFNKSITEMFREECALLBACK ItemFreeCallback;
LONG ReferenceCount;
}DEVICE_ITEM, *PDEVICE_ITEM;
LIST_ENTRY ObjectItemList;
}CREATE_ITEM_ENTRY, *PCREATE_ITEM_ENTRY;
typedef struct
{
KSOBJECTTYPE Type;
PKSDEVICE KsDevice;
}KSBASIC_HEADER, *PKSBASIC_HEADER;
typedef struct
{
KSOBJECTTYPE Type;
KSDEVICE KsDevice;
IKsDeviceVtbl *lpVtblIKsDevice;
LONG ref;
ERESOURCE SecurityLock;
USHORT MaxItems;
DEVICE_ITEM *ItemList;
LONG ItemListCount;
LIST_ENTRY ItemList;
ULONG DeviceIndex;
KSPIN_LOCK ItemListLock;
PDEVICE_OBJECT PnpDeviceObject;
PDEVICE_OBJECT BaseDevice;
KSTARGET_STATE TargetState;
LIST_ENTRY TargetDeviceList;
KSDEVICE KsDevice;
KMUTEX DeviceMutex;
KSDEVICE_DESCRIPTOR* Descriptor;

View file

@ -23,29 +23,11 @@ KspCreateObjectType(
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
OBJECT_ATTRIBUTES ObjectAttributes;
PFILE_OBJECT FileObject;
UNICODE_STRING Name;
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 = wcslen(ObjectType) * sizeof(WCHAR) + CreateParametersSize + 2 * sizeof(WCHAR);
Name.MaximumLength += sizeof(WCHAR);
/* acquire request buffer */
Name.Buffer = ExAllocatePool(NonPagedPool, Name.MaximumLength);
@ -53,16 +35,13 @@ KspCreateObjectType(
if (!Name.Buffer)
{
/* insufficient resources */
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* build a request which looks like \Parent\{ObjectGuid}\CreateParameters
/* build a request which looks like \{ObjectClass}\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"\\");
@ -81,7 +60,7 @@ KspCreateObjectType(
0,
0,
FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT,
0,
NULL,
0,
CreateFileTypeNone,
@ -90,8 +69,6 @@ KspCreateObjectType(
/* free request buffer */
ExFreePool(Name.Buffer);
/* release parent handle */
ObDereferenceObject(FileObject);
return Status;
}

View file

@ -183,7 +183,7 @@ PcAddAdapterDevice(
if (PrevDeviceObject)
{
/* store the device object in the device header */
//KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, PrevDeviceObject, fdo);
//KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject);
portcls_ext->PrevDeviceObject = PrevDeviceObject;
}
else

View file

@ -15,13 +15,15 @@ Dispatch_fnDeviceIoControl(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* access IrpTarget */
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2;
/* let IrpTarget handle request */
return IrpTarget->lpVtbl->DeviceIoControl(IrpTarget, DeviceObject, Irp);
}
@ -32,13 +34,16 @@ Dispatch_fnRead(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* access IrpTarget */
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2;
/* let IrpTarget handle request */
return IrpTarget->lpVtbl->Read(IrpTarget, DeviceObject, Irp);
}
@ -49,13 +54,16 @@ Dispatch_fnWrite(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* access IrpTarget */
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2;
/* let IrpTarget handle request */
return IrpTarget->lpVtbl->Write(IrpTarget, DeviceObject, Irp);
}
@ -66,13 +74,16 @@ Dispatch_fnFlush(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* access IrpTarget */
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2;
/* let IrpTarget handle request */
return IrpTarget->lpVtbl->Flush(IrpTarget, DeviceObject, Irp);
}
@ -83,13 +94,16 @@ Dispatch_fnClose(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* access IrpTarget */
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2;
/* let IrpTarget handle request */
return IrpTarget->lpVtbl->Close(IrpTarget, DeviceObject, Irp);
}
@ -100,13 +114,16 @@ Dispatch_fnQuerySecurity(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* access IrpTarget */
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2;
/* let IrpTarget handle request */
return IrpTarget->lpVtbl->QuerySecurity(IrpTarget, DeviceObject, Irp);
}
@ -117,13 +134,16 @@ Dispatch_fnSetSecurity(
PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
IIrpTarget * IrpTarget;
PKSOBJECT_CREATE_ITEM CreateItem;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* access IrpTarget */
IrpTarget = (IIrpTarget *)IoStack->FileObject->FsContext2;
/* let IrpTarget handle request */
return IrpTarget->lpVtbl->SetSecurity(IrpTarget, DeviceObject, Irp);
}
@ -212,26 +232,19 @@ NTAPI
NewDispatchObject(
IN PIRP Irp,
IN IIrpTarget * Target,
IN LPWSTR Name)
IN ULONG CreateItemCount,
IN PKSOBJECT_CREATE_ITEM CreateItem)
{
NTSTATUS Status;
KSOBJECT_HEADER ObjectHeader;
PKSOBJECT_CREATE_ITEM CreateItem;
PIO_STACK_LOCATION IoStack;
CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);
if (!CreateItem)
return STATUS_INSUFFICIENT_RESOURCES;
CreateItem->Context = (PVOID)Target;
RtlInitUnicodeString(&CreateItem->ObjectClass, Name);
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IoStack->FileObject);
IoStack->FileObject->FsContext2 = (PVOID)Target;
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);
Status = KsAllocateObjectHeader(&ObjectHeader, CreateItemCount, CreateItem, Irp, &DispatchTable);
DPRINT("KsAllocateObjectHeader result %x\n", Status);
return Status;
}

View file

@ -242,7 +242,43 @@ IPortFilterTopology_fnFastDeviceIoControl(
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
return FALSE;
ULONG Index;
PKSPROPERTY Property;
NTSTATUS Status;
ISubdevice * SubDevice = NULL;
PSUBDEVICE_DESCRIPTOR Descriptor = NULL;
IPortFilterTopologyImpl * This = (IPortFilterTopologyImpl*)iface;
Property = (PKSPROPERTY)InputBuffer;
if (InputBufferLength < sizeof(KSPROPERTY))
return FALSE;
/* get private interface */
Status = This->Port->lpVtbl->QueryInterface(This->Port, &IID_ISubdevice, (PVOID*)&SubDevice);
if (!NT_SUCCESS(Status))
return FALSE;
/* get descriptor */
Status = SubDevice->lpVtbl->GetDescriptor(SubDevice, &Descriptor);
if (!NT_SUCCESS(Status))
{
SubDevice->lpVtbl->Release(SubDevice);
return FALSE;
}
for(Index = 0; Index < Descriptor->FilterPropertySet.FreeKsPropertySetOffset; Index++)
{
if (IsEqualGUIDAligned(&Property->Set, Descriptor->FilterPropertySet.Properties[Index].Set))
{
FastPropertyHandler(FileObject, (PKSPROPERTY)InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock,
1,
&Descriptor->FilterPropertySet.Properties[Index],
Descriptor, SubDevice);
}
}
return TRUE;
}
/*

View file

@ -1015,7 +1015,7 @@ IPortPinDMus_fnFastWrite(
}
/*
* @unimplemented
* @implemented
*/
NTSTATUS
NTAPI

View file

@ -260,7 +260,7 @@ SetStreamWorkerRoutine(
/* get maximum data threshold */
MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec;
/* increase minimum data threshold by a third sec */
MinimumDataThreshold += ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec / 3;
MinimumDataThreshold += This->FrameSize * 10;
/* assure it has not exceeded */
MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold);
@ -970,7 +970,7 @@ IPortPinWaveCyclic_fnFastWrite(
PrePostRatio = (This->PreCompleted * 100) / This->TotalPackets;
MinData = This->IrpQueue->lpVtbl->NumData(This->IrpQueue);
DPRINT1("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u State %x MinData %u Ratio %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue), PrePostRatio);
DPRINT("IPortPinWaveCyclic_fnFastWrite entered Total %u Pre %u Post %u State %x MinData %u Ratio %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted, This->State, This->IrpQueue->lpVtbl->NumData(This->IrpQueue), PrePostRatio);
Packet = (PCONTEXT_WRITE)Buffer;

View file

@ -249,9 +249,9 @@ SetStreamWorkerRoutine(
/* get current data threshold */
MinimumDataThreshold = This->IrpQueue->lpVtbl->GetMinimumDataThreshold(This->IrpQueue);
/* get maximum data threshold */
MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec * 3;
/* increase minimum data threshold by a third sec */
MinimumDataThreshold += ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec / 3;
MaximumDataThreshold = ((PKSDATAFORMAT_WAVEFORMATEX)This->Format)->WaveFormatEx.nAvgBytesPerSec;
/* increase minimum data threshold by 10 frames */
MinimumDataThreshold += This->AllocatorFraming.FrameSize * 10;
/* assure it has not exceeded */
MinimumDataThreshold = min(MinimumDataThreshold, MaximumDataThreshold);
@ -432,48 +432,48 @@ NTSTATUS
NTAPI
IPortPinWavePci_HandleKsProperty(
IN IPortPinWavePci * iface,
IN PIRP Irp)
IN PVOID InputBuffer,
IN ULONG InputBufferLength,
IN PVOID OutputBuffer,
IN ULONG OutputBufferLength,
IN PIO_STATUS_BLOCK IoStatusBlock)
{
PKSPROPERTY Property;
NTSTATUS Status;
UNICODE_STRING GuidString;
PIO_STACK_LOCATION IoStack;
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
IoStack = IoGetCurrentIrpStackLocation(Irp);
DPRINT("IPortPinWavePci_HandleKsProperty entered\n");
if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY))
if (InputBufferLength < sizeof(KSPROPERTY))
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_INVALID_PARAMETER;
return STATUS_INVALID_PARAMETER;
}
Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
Property = (PKSPROPERTY)InputBuffer;
if (IsEqualGUIDAligned(&Property->Set, &KSPROPSETID_Connection))
{
if (Property->Id == KSPROPERTY_CONNECTION_STATE)
{
PKSSTATE State = (PKSSTATE)Irp->UserBuffer;
PKSSTATE State = (PKSSTATE)OutputBuffer;
ASSERT_IRQL(DISPATCH_LEVEL);
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSSTATE))
if (OutputBufferLength < sizeof(KSSTATE))
{
Irp->IoStatus.Information = sizeof(KSSTATE);
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = sizeof(KSSTATE);
IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
if (Property->Flags & KSPROPERTY_TYPE_SET)
{
Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
IoStatusBlock->Information = 0;
if (This->Stream)
{
@ -485,39 +485,35 @@ IPortPinWavePci_HandleKsProperty(
This->State = *State;
}
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Status = Status;
return Status;
}
else if (Property->Flags & KSPROPERTY_TYPE_GET)
{
*State = This->State;
Irp->IoStatus.Information = sizeof(KSSTATE);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = sizeof(KSSTATE);
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
else if (Property->Id == KSPROPERTY_CONNECTION_DATAFORMAT)
{
PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)Irp->UserBuffer;
PKSDATAFORMAT DataFormat = (PKSDATAFORMAT)OutputBuffer;
if (Property->Flags & KSPROPERTY_TYPE_SET)
{
PKSDATAFORMAT NewDataFormat;
if (!RtlCompareMemory(DataFormat, This->Format, DataFormat->FormatSize))
{
Irp->IoStatus.Information = DataFormat->FormatSize;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = DataFormat->FormatSize;
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
NewDataFormat = AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS);
if (!NewDataFormat)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_NO_MEMORY;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_NO_MEMORY;
return STATUS_NO_MEMORY;
}
RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize);
@ -543,16 +539,14 @@ IPortPinWavePci_HandleKsProperty(
This->IrpQueue->lpVtbl->UpdateFormat(This->IrpQueue, (PKSDATAFORMAT)NewDataFormat);
This->Format = NewDataFormat;
Irp->IoStatus.Information = DataFormat->FormatSize;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = DataFormat->FormatSize;
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
DPRINT1("Failed to set format\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
else if (Property->Flags & KSPROPERTY_TYPE_GET)
@ -560,45 +554,40 @@ IPortPinWavePci_HandleKsProperty(
if (!This->Format)
{
DPRINT1("No format\n");
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = 0;
IoStatusBlock->Status = STATUS_UNSUCCESSFUL;
return STATUS_UNSUCCESSFUL;
}
if (This->Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
if (This->Format->FormatSize > OutputBufferLength)
{
Irp->IoStatus.Information = This->Format->FormatSize;
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = This->Format->FormatSize;
IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
RtlMoveMemory(DataFormat, This->Format, This->Format->FormatSize);
Irp->IoStatus.Information = DataFormat->FormatSize;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = DataFormat->FormatSize;
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
else if (Property->Id == KSPROPERTY_CONNECTION_ALLOCATORFRAMING)
{
PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)Irp->UserBuffer;
PKSALLOCATOR_FRAMING Framing = (PKSALLOCATOR_FRAMING)OutputBuffer;
ASSERT_IRQL(DISPATCH_LEVEL);
/* Validate input buffer */
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(KSALLOCATOR_FRAMING))
if (OutputBufferLength < sizeof(KSALLOCATOR_FRAMING))
{
Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING);
Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING);
IoStatusBlock->Status = STATUS_BUFFER_TOO_SMALL;
return STATUS_BUFFER_TOO_SMALL;
}
/* copy frame allocator struct */
RtlMoveMemory(Framing, &This->AllocatorFraming, sizeof(KSALLOCATOR_FRAMING));
Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Information = sizeof(KSALLOCATOR_FRAMING);
IoStatusBlock->Status = STATUS_SUCCESS;
return STATUS_SUCCESS;
}
}
@ -607,9 +596,8 @@ IPortPinWavePci_HandleKsProperty(
DPRINT1("Unhandeled property Set |%S| Id %u Flags %x\n", GuidString.Buffer, Property->Id, Property->Flags);
RtlFreeUnicodeString(&GuidString);
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoStatusBlock->Status = STATUS_NOT_IMPLEMENTED;
IoStatusBlock->Information = 0;
return STATUS_NOT_IMPLEMENTED;
}
@ -624,12 +612,15 @@ IPortPinWavePci_fnDeviceIoControl(
IN PIRP Irp)
{
PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
IoStack = IoGetCurrentIrpStackLocation(Irp);
if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
{
return IPortPinWavePci_HandleKsProperty(iface, Irp);
Status = IPortPinWavePci_HandleKsProperty(iface, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, Irp->UserBuffer, IoStack->Parameters.DeviceIoControl.OutputBufferLength, &Irp->IoStatus);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
@ -850,7 +841,17 @@ IPortPinWavePci_fnFastDeviceIoControl(
OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject)
{
UNIMPLEMENTED
NTSTATUS Status;
if (IoControlCode == IOCTL_KS_PROPERTY)
{
Status = IPortPinWavePci_HandleKsProperty(iface, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, StatusBlock);
if (NT_SUCCESS(Status))
{
return TRUE;
}
}
return FALSE;
}
@ -917,6 +918,7 @@ IPortPinWavePci_fnFastWrite(
NTSTATUS Status;
PCONTEXT_WRITE Packet;
PIRP Irp;
ULONG MinimumDataThreshold;
IPortPinWavePciImpl * This = (IPortPinWavePciImpl*)iface;
DPRINT("IPortPinWavePci_fnFastWrite entered Total %u Pre %u Post %u\n", This->TotalPackets, This->PreCompleted, This->PostCompleted);
@ -955,9 +957,15 @@ IPortPinWavePci_fnFastWrite(
if (This->IrpQueue->lpVtbl->HasLastMappingFailed(This->IrpQueue))
{
/* notify port driver that new mapping is available */
DPRINT("Notifying of new mapping\n");
This->Stream->lpVtbl->MappingAvailable(This->Stream);
/* get minimum data threshold */
MinimumDataThreshold = This->IrpQueue->lpVtbl->GetMinimumDataThreshold(This->IrpQueue);
if (MinimumDataThreshold < This->IrpQueue->lpVtbl->NumData(This->IrpQueue))
{
/* notify port driver that new mapping is available */
DPRINT("Notifying of new mapping\n");
This->Stream->lpVtbl->MappingAvailable(This->Stream);
}
}
return TRUE;

View file

@ -515,12 +515,13 @@ CreatePinWorkerRoutine(
WorkerContext->Irp,
NULL);
DPRINT("CreatePinWorkerRoutine Status %x\n", Status);
DPRINT1("CreatePinWorkerRoutine Status %x\n", Status);
if (NT_SUCCESS(Status))
{
/* create the dispatch object */
Status = NewDispatchObject(WorkerContext->Irp, Pin, NULL);
/* FIXME need create item for clock */
Status = NewDispatchObject(WorkerContext->Irp, Pin, 0, NULL);
DPRINT("Pin %p\n", Pin);
}
@ -536,6 +537,78 @@ CreatePinWorkerRoutine(
FreeItem(WorkerContext, TAG_PORTCLASS);
}
NTSTATUS
NTAPI
PcCreatePinDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
IIrpTarget *Filter;
PKSOBJECT_CREATE_ITEM CreateItem;
PPIN_WORKER_CONTEXT Context;
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* sanity check */
ASSERT(CreateItem);
DPRINT1("PcCreatePinDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer);
Filter = (IIrpTarget*)CreateItem->Context;
/* sanity checks */
ASSERT(Filter != NULL);
#if KS_IMPLEMENTED
Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
{
DPRINT1("PcCreatePinDispatch failed to reference device header\n");
FreeItem(Entry, TAG_PORTCLASS);
goto cleanup;
}
#endif
/* new pins are instantiated at passive level,
* so allocate a work item and context for it
*/
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());
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp);
IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
return STATUS_PENDING;
}
NTSTATUS
NTAPI
@ -543,60 +616,35 @@ PcCreateItemDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status = STATUS_SUCCESS;
PIO_STACK_LOCATION IoStack;
NTSTATUS Status;
ISubdevice * SubDevice;
PPCLASS_DEVICE_EXTENSION DeviceExt;
IIrpTarget *Filter;
PKSOBJECT_CREATE_ITEM CreateItem;
PPIN_WORKER_CONTEXT Context;
LPWSTR Buffer;
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
PKSOBJECT_CREATE_ITEM CreateItem, PinCreateItem;
DPRINT1("PcCreateItemDispatch called DeviceObject %p\n", DeviceObject);
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
/* access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
if (!CreateItem)
{
DPRINT1("PcCreateItemDispatch no CreateItem\n");
return STATUS_UNSUCCESSFUL;
}
DPRINT1("PcCreateItemDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer);
/* get the subdevice */
SubDevice = (ISubdevice*)CreateItem->Context;
DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
if (!SubDevice || !DeviceExt)
{
DPRINT1("PcCreateItemDispatch SubDevice %p DeviceExt %p\n", SubDevice, DeviceExt);
return STATUS_UNSUCCESSFUL;
}
/* sanity checks */
ASSERT(SubDevice != NULL);
#if KS_IMPLEMENTED
Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader);
if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED)
{
DPRINT1("PciCreateItemDispatch failed to reference device header\n");
DPRINT1("PcCreateItemDispatch failed to reference device header\n");
FreeItem(Entry, TAG_PORTCLASS);
goto cleanup;
}
#endif
/* get current io stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* sanity check */
ASSERT(IoStack->FileObject != NULL);
if (IoStack->FileObject->FsContext != NULL)
{
/* nothing to do */
DPRINT1("FsContext already exists\n");
return STATUS_SUCCESS;
}
/* get filter object
* is implemented as a singleton
*/
@ -611,62 +659,37 @@ PcCreateItemDispatch(
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed to get filter object\n");
return Status;
}
/* 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
/* allocate pin create item */
PinCreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);
if (!PinCreateItem)
{
/* 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());
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_PENDING;
IoMarkIrpPending(Irp);
IoQueueWorkItem(Context->WorkItem, CreatePinWorkerRoutine, DelayedWorkQueue, (PVOID)Context);
return STATUS_PENDING;
/* not enough memory */
Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* initialize pin create item */
PinCreateItem->Context = (PVOID)Filter;
PinCreateItem->Create = PcCreatePinDispatch;
RtlInitUnicodeString(&PinCreateItem->ObjectClass, KS_NAME_PIN);
/* FIXME copy security descriptor */
/* now allocate a dispatch object */
Status = NewDispatchObject(Irp, Filter, 1, PinCreateItem);
/* complete request */
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
NewPortTopology(
OUT PPORT* OutPort)

View file

@ -162,7 +162,8 @@ NTAPI
NewDispatchObject(
IN PIRP Irp,
IN IIrpTarget * Target,
IN LPWSTR Name);
IN ULONG ObjectCreateItemCount,
IN PKSOBJECT_CREATE_ITEM ObjectCreateItem);
PMINIPORTWAVECYCLIC
GetWaveCyclicMiniport(

View file

@ -121,9 +121,9 @@ PinPropertyHandler(
IN PKSIDENTIFIER Request,
IN OUT PVOID Data)
{
PKSOBJECT_CREATE_ITEM CreateItem;
PSUBDEVICE_DESCRIPTOR Descriptor;
PIO_STACK_LOCATION IoStack;
//PKSOBJECT_CREATE_ITEM CreateItem;
PSUBDEVICE_DESCRIPTOR Descriptor;
IIrpTarget * IrpTarget;
IPort *Port;
ISubdevice *SubDevice;
@ -134,10 +134,11 @@ PinPropertyHandler(
Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp);
ASSERT(Descriptor);
/* Access the create item */
CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
/* get current irp stack */
IoStack = IoGetCurrentIrpStackLocation(Irp);
/* Get the IrpTarget */
IrpTarget = (IIrpTarget*)CreateItem->Context;
IrpTarget = (IIrpTarget*)IoStack->FileObject->FsContext2;
/* Get the parent */
Status = IrpTarget->lpVtbl->QueryInterface(IrpTarget, &IID_IPort, (PVOID*)&Port);
if (!NT_SUCCESS(Status))

View file

@ -179,6 +179,25 @@ static KSDISPATCH_TABLE DispatchTable =
Dispatch_fnFastWrite,
};
NTSTATUS
NTAPI
DispatchCreateKMixPin(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
DPRINT("DispatchCreateKMix entered\n");
/* create the pin */
Status = CreatePin(Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
DispatchCreateKMix(
@ -187,32 +206,13 @@ DispatchCreateKMix(
{
NTSTATUS Status;
KSOBJECT_HEADER ObjectHeader;
PIO_STACK_LOCATION IoStatus;
LPWSTR Buffer;
PKSOBJECT_CREATE_ITEM CreateItem;
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
IoStatus = IoGetCurrentIrpStackLocation(Irp);
Buffer = IoStatus->FileObject->FileName.Buffer;
DPRINT("DispatchCreateKMix entered\n");
if (Buffer)
{
/* is the request for a new pin */
if (wcsstr(Buffer, KS_NAME_PIN))
{
Status = CreatePin(Irp);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
}
/* allocate create item */
/* allocate create item */
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
if (!CreateItem)
{
@ -225,7 +225,10 @@ DispatchCreateKMix(
/* zero create struct */
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
RtlInitUnicodeString(&CreateItem->ObjectClass, L"KMixer");
/* initialize pin create item */
CreateItem->Create = DispatchCreateKMixPin;
RtlInitUnicodeString(&CreateItem->ObjectClass, KS_NAME_PIN);
/* allocate object header */
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);

View file

@ -5,7 +5,7 @@
#include <portcls.h>
#include <ks.h>
#include <ksmedia.h>
#define NDEBUG
#define YDEBUG
#include <debug.h>
#include <samplerate.h>
@ -18,6 +18,14 @@ typedef struct
}KMIXER_DEVICE_EXT, *PKMIXER_DEVICE_EXT;
typedef struct
{
KSPIN_LOCK Lock;
}SUM_NODE_CONTEXT, *PSUM_NODE_CONTEXT;
NTSTATUS
NTAPI
KMixAllocateDeviceHeader(

View file

@ -141,7 +141,7 @@ CreateMixerPinAndSetFormat(
HANDLE PinHandle;
PFILE_OBJECT FileObject;
Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);//, L"KMixer");
Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
if (!NT_SUCCESS(Status))
{

View file

@ -179,6 +179,25 @@ static KSDISPATCH_TABLE DispatchTable =
Dispatch_fnFastWrite,
};
NTSTATUS
NTAPI
DispatchCreateSysAudioPin(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
DPRINT("DispatchCreateSysAudio entered\n");
/* create the virtual pin */
Status = CreateSysAudioPin(Irp);
/* store result */
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS
NTAPI
DispatchCreateSysAudio(
@ -188,31 +207,11 @@ DispatchCreateSysAudio(
NTSTATUS Status;
KSOBJECT_HEADER ObjectHeader;
PKSOBJECT_CREATE_ITEM CreateItem;
PIO_STACK_LOCATION IoStatus;
LPWSTR Buffer;
PSYSAUDIODEVEXT DeviceExtension;
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
IoStatus = IoGetCurrentIrpStackLocation(Irp);
Buffer = IoStatus->FileObject->FileName.Buffer;
DPRINT("DispatchCreateSysAudio entered\n");
if (Buffer)
{
/* is the request for a new pin */
if (wcsstr(Buffer, KS_NAME_PIN))
{
Status = CreateDispatcher(Irp);
DPRINT("Virtual pin Status %x FileObject %p\n", Status, IoStatus->FileObject);
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
}
/* allocate create item */
CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
if (!CreateItem)
@ -223,14 +222,12 @@ DispatchCreateSysAudio(
return STATUS_INSUFFICIENT_RESOURCES;
}
/* get device extension */
DeviceExtension = (PSYSAUDIODEVEXT) DeviceObject->DeviceExtension;
/* zero create struct */
RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
/* store create context */
RtlInitUnicodeString(&CreateItem->ObjectClass, L"SysAudio");
/* setup create context */
CreateItem->Create = DispatchCreateSysAudioPin;
RtlInitUnicodeString(&CreateItem->ObjectClass, KS_NAME_PIN);
/* allocate object header */
Status = KsAllocateObjectHeader(&ObjectHeader, 1, CreateItem, Irp, &DispatchTable);

View file

@ -419,7 +419,7 @@ static KSDISPATCH_TABLE PinTable =
};
NTSTATUS
CreateDispatcher(
CreateSysAudioPin(
IN PIRP Irp)
{
NTSTATUS Status;

View file

@ -124,7 +124,7 @@ GetListEntry(
IN ULONG Index);
NTSTATUS
CreateDispatcher(
CreateSysAudioPin(
IN PIRP Irp);
ULONG