From ace530421a2bc73f2fb69f53f58702d4badf0519 Mon Sep 17 00:00:00 2001 From: Johannes Anderwald Date: Fri, 31 Jul 2009 10:10:26 +0000 Subject: [PATCH] - Partly Implement KsRegisterFilterWithNoKSPins - Implement _KsEdit svn path=/trunk/; revision=42310 --- reactos/drivers/ksfilter/ks/api.c | 75 +++++++++++++++++++------- reactos/drivers/ksfilter/ks/bag.c | 89 +++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+), 18 deletions(-) diff --git a/reactos/drivers/ksfilter/ks/api.c b/reactos/drivers/ksfilter/ks/api.c index 48743f5e734..0cf53f4dcc0 100644 --- a/reactos/drivers/ksfilter/ks/api.c +++ b/reactos/drivers/ksfilter/ks/api.c @@ -1842,23 +1842,6 @@ KsDeviceRegisterAdapterObject( UNIMPLEMENTED } -/* - @unimplemented -*/ -KSDDKAPI -NTSTATUS -NTAPI -_KsEdit( - IN KSOBJECT_BAG ObjectBag, - IN OUT PVOID* PointerToPointerToItem, - IN ULONG NewSize, - IN ULONG OldSize, - IN ULONG Tag) -{ - UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; -} - /* @unimplemented */ @@ -2093,6 +2076,62 @@ KsRegisterFilterWithNoKSPins( IN KSPIN_MEDIUM* MediumList, IN GUID* CategoryList OPTIONAL) { + ULONG Size, Index; + NTSTATUS Status; + PWSTR SymbolicLinkList; + //PUCHAR Buffer; + HANDLE hKey; + UNICODE_STRING InterfaceString; + //UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData"); + + if (!InterfaceClassGUID || !PinCount || !PinDirection || !MediumList) + { + /* all these parameters are required */ + return STATUS_INVALID_PARAMETER; + } + + /* calculate filter data value size */ + Size = PinCount * sizeof(KSPIN_MEDIUM); + if (CategoryList) + { + /* add category list */ + Size += PinCount * sizeof(GUID); + } + + /* FIXME generate filter data blob */ UNIMPLEMENTED - return STATUS_UNSUCCESSFUL; + + /* get symbolic link list */ + Status = IoGetDeviceInterfaces(InterfaceClassGUID, DeviceObject, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &SymbolicLinkList); + if (NT_SUCCESS(Status)) + { + /* initialize first symbolic link */ + RtlInitUnicodeString(&InterfaceString, SymbolicLinkList); + + /* open first device interface registry key */ + Status = IoOpenDeviceInterfaceRegistryKey(&InterfaceString, GENERIC_WRITE, &hKey); + + if (NT_SUCCESS(Status)) + { + /* write filter data */ + //Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Buffer, Size); + + /* close the key */ + ZwClose(hKey); + } + + if (PinCount) + { + /* update medium cache */ + for(Index = 0; Index < PinCount; Index++) + { + KsCacheMedium(&InterfaceString, &MediumList[Index], PinDirection[Index]); + } + } + + /* free the symbolic link list */ + ExFreePool(SymbolicLinkList); + } + + return Status; } diff --git a/reactos/drivers/ksfilter/ks/bag.c b/reactos/drivers/ksfilter/ks/bag.c index fa2486ba117..8c418078777 100644 --- a/reactos/drivers/ksfilter/ks/bag.c +++ b/reactos/drivers/ksfilter/ks/bag.c @@ -298,5 +298,94 @@ KsFreeObjectBag( FreeItem(Bag); } +/* + @implemented +*/ +KSDDKAPI +NTSTATUS +NTAPI +_KsEdit( + IN KSOBJECT_BAG ObjectBag, + IN OUT PVOID* PointerToPointerToItem, + IN ULONG NewSize, + IN ULONG OldSize, + IN ULONG Tag) +{ + PKSIOBJECT_BAG Bag; + PKSIOBJECT_BAG_ENTRY BagEntry; + PVOID Item; + NTSTATUS Status; + + /* get real object bag */ + Bag = (PKSIOBJECT_BAG)ObjectBag; + + /* acquire bag mutex */ + KeWaitForSingleObject(Bag->BagMutex, Executive, KernelMode, FALSE, NULL); + + + if (*PointerToPointerToItem) + { + /* search object bag for this entry */ + BagEntry = KspFindObjectBagItem(&Bag->ObjectList, *PointerToPointerToItem); + } + else + { + /* pointer to null, allocate new entry */ + BagEntry = NULL; + } + + if (!BagEntry || NewSize > OldSize) + { + /* entry does not exist or new entry must be allocated */ + Item = AllocateItem(NonPagedPool, NewSize); + + if (!Item) + { + /* not enough resources */ + KeReleaseMutex(Bag->BagMutex, FALSE); + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* now add the item to the object bag */ + Status = KsAddItemToObjectBag((KSOBJECT_BAG)Bag, Item, NULL); + /* check for success */ + if (!NT_SUCCESS(Status)) + { + /* failed to add item */ + FreeItem(Item); + KeReleaseMutex(Bag->BagMutex, FALSE); + return Status; + } + + if (*PointerToPointerToItem) + { + /* object exists */ + if (OldSize >= NewSize) + { + /* copy old contents */ + RtlMoveMemory(Item, *PointerToPointerToItem, NewSize); + } + else + { + /* copy new contents */ + RtlMoveMemory(Item, *PointerToPointerToItem, OldSize); + } + } + + if (BagEntry) + { + /* remove old entry */ + KsRemoveItemFromObjectBag(ObjectBag, BagEntry->Item, TRUE); + } + + /* store item */ + *PointerToPointerToItem = Item; + } + + /* release bag mutex */ + KeReleaseMutex(Bag->BagMutex, FALSE); + + return STATUS_SUCCESS; +}