Author: janderwald
Date: Mon Feb 16 22:52:11 2009
New Revision: 39640
URL:
http://svn.reactos.org/svn/reactos?rev=39640&view=rev
Log:
- Implement KsTopologyPropertyHandler
Modified:
trunk/reactos/drivers/ksfilter/ks/topology.c
Modified: trunk/reactos/drivers/ksfilter/ks/topology.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/topolo…
==============================================================================
--- trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/ksfilter/ks/topology.c [iso-8859-1] Mon Feb 16 22:52:11 2009
@@ -90,15 +90,172 @@
}
/*
- @unimplemented
-*/
-KSDDKAPI NTSTATUS NTAPI
+ @implemented
+*/
+KSDDKAPI
+NTSTATUS
+NTAPI
KsTopologyPropertyHandler(
IN PIRP Irp,
IN PKSPROPERTY Property,
IN OUT PVOID Data,
IN const KSTOPOLOGY* Topology)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
-}
+ UNICODE_STRING LocalMachine =
RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\MediaCategories\\");
+ UNICODE_STRING Name = RTL_CONSTANT_STRING(L"Name");
+ UNICODE_STRING GuidString;
+ UNICODE_STRING KeyName;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ KSMULTIPLE_ITEM * Item;
+ KSP_NODE * Node;
+ PIO_STACK_LOCATION IoStack;
+ ULONG Size;
+ NTSTATUS Status;
+ HANDLE hKey;
+ PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+
+ if (Property->Flags != KSPROPERTY_TYPE_GET)
+ {
+ Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Irp->IoStatus.Information = 0;
+ return STATUS_NOT_IMPLEMENTED;
+ }
+
+ IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+ switch(Property->Id)
+ {
+ case KSPROPERTY_TOPOLOGY_CATEGORIES:
+ Size = sizeof(KSMULTIPLE_ITEM) + Topology->CategoriesCount *
sizeof(GUID);
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
+ {
+ Irp->IoStatus.Information = Size;
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ Item = (KSMULTIPLE_ITEM*)Irp->UserBuffer;
+ Item->Size = Size;
+ Item->Count = Topology->CategoriesCount;
+
+ RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->Categories,
Topology->CategoriesCount * sizeof(GUID));
+ Irp->IoStatus.Information = Size;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case KSPROPERTY_TOPOLOGY_NODES:
+ Size = sizeof(KSMULTIPLE_ITEM) + Topology->TopologyNodesCount *
sizeof(GUID);
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
+ {
+ Irp->IoStatus.Information = Size;
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ Item = (KSMULTIPLE_ITEM*)Irp->UserBuffer;
+ Item->Size = Size;
+ Item->Count = Topology->TopologyNodesCount;
+
+ RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyNodes,
Topology->TopologyNodesCount * sizeof(GUID));
+ Irp->IoStatus.Information = Size;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case KSPROPERTY_TOPOLOGY_CONNECTIONS:
+ Size = sizeof(KSMULTIPLE_ITEM) + Topology->TopologyConnectionsCount *
sizeof(GUID);
+ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
+ {
+ Irp->IoStatus.Information = Size;
+ Status = STATUS_BUFFER_TOO_SMALL;
+ break;
+ }
+
+ Item = (KSMULTIPLE_ITEM*)Irp->UserBuffer;
+ Item->Size = Size;
+ Item->Count = Topology->TopologyConnectionsCount;
+
+ RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyConnections,
Topology->TopologyConnectionsCount * sizeof(GUID));
+ Irp->IoStatus.Information = Size;
+ Status = STATUS_SUCCESS;
+ break;
+
+ case KSPROPERTY_TOPOLOGY_NAME:
+ Node = (KSP_NODE*)Property;
+
+ Status =
RtlStringFromGUID(&Topology->TopologyNodesNames[Node->NodeId],
&GuidString);
+ if (!NT_SUCCESS(Status))
+ {
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+
+ KeyName.Length = 0;
+ KeyName.MaximumLength = LocalMachine.Length + GuidString.Length +
sizeof(WCHAR);
+ KeyName.Buffer = ExAllocatePool(PagedPool, KeyName.MaximumLength);
+ if (!KeyName.Buffer)
+ {
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+
+ RtlAppendUnicodeStringToString(&KeyName, &LocalMachine);
+ RtlAppendUnicodeStringToString(&KeyName, &GuidString);
+
+
+ InitializeObjectAttributes(&ObjectAttributes, &KeyName,
OBJ_CASE_INSENSITIVE, NULL, NULL);
+ Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
+ ExFreePool(KeyName.Buffer);
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+ ExFreePool(KeyName.Buffer);
+ Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, NULL,
0, &Size);
+ if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ ZwClose(hKey);
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+
+ KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(NonPagedPool,
Size);
+ if (!KeyInfo)
+ {
+ Status = STATUS_NO_MEMORY;
+ break;
+ }
+
+ Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation,
(PVOID)KeyInfo, Size, &Size);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(KeyInfo);
+ ZwClose(hKey);
+ Irp->IoStatus.Information = 0;
+ break;
+ }
+
+ ZwClose(hKey);
+ if (KeyInfo->DataLength + sizeof(WCHAR) >
IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+ {
+ Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
+ Status = STATUS_BUFFER_TOO_SMALL;
+ ExFreePool(KeyInfo);
+ break;
+ }
+
+ RtlMoveMemory(Irp->UserBuffer, &KeyInfo->Data,
KeyInfo->DataLength);
+ ((LPWSTR)Irp->UserBuffer)[KeyInfo->DataLength / sizeof(WCHAR)] =
L'\0';
+ Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
+ ExFreePool(KeyInfo);
+ break;
+ default:
+ Irp->IoStatus.Information = 0;
+ Status = STATUS_NOT_IMPLEMENTED;
+ }
+
+
+ return Status;
+}