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/topolog... ============================================================================== --- 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; +}