mirror of
https://github.com/reactos/reactos.git
synced 2025-04-04 04:26:32 +00:00
[KS]
- 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:
parent
8497361513
commit
3e489bf3af
26 changed files with 852 additions and 587 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -1015,7 +1015,7 @@ IPortPinDMus_fnFastWrite(
|
|||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
* @implemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -419,7 +419,7 @@ static KSDISPATCH_TABLE PinTable =
|
|||
};
|
||||
|
||||
NTSTATUS
|
||||
CreateDispatcher(
|
||||
CreateSysAudioPin(
|
||||
IN PIRP Irp)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
|
|
|
@ -124,7 +124,7 @@ GetListEntry(
|
|||
IN ULONG Index);
|
||||
|
||||
NTSTATUS
|
||||
CreateDispatcher(
|
||||
CreateSysAudioPin(
|
||||
IN PIRP Irp);
|
||||
|
||||
ULONG
|
||||
|
|
Loading…
Reference in a new issue