+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Kernel Streaming
+ * FILE: drivers/ksfilter/ks/topoology.c
+ * PURPOSE: KS Allocator functions
+ * PROGRAMMER: Johannes Anderwald
+ */
+
+
#include "priv.h"
-/* ===============================================================
- Topology Functions
-*/
NTSTATUS
NTAPI
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);
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"\\");
0,
0,
FILE_OPEN,
- FILE_SYNCHRONOUS_IO_NONALERT,
+ 0,
NULL,
0,
CreateFileTypeNone,
/* free request buffer */
ExFreePool(Name.Buffer);
- /* release parent handle */
- ObDereferenceObject(FileObject);
return Status;
}
OUT PHANDLE NodeHandle)
{
return KspCreateObjectType(ParentHandle,
- L"{0621061A-EE75-11D0-B915-00A0C9223196}",
+ KSSTRING_TopologyNode,
(PVOID)NodeCreate,
sizeof(KSNODE_CREATE),
DesiredAccess,
}
/*
- @unimplemented
+ @implemented
*/
-KSDDKAPI NTSTATUS NTAPI
+KSDDKAPI
+NTSTATUS
+NTAPI
KsValidateTopologyNodeCreateRequest(
IN PIRP Irp,
IN PKSTOPOLOGY Topology,
- OUT PKSNODE_CREATE* NodeCreate)
+ OUT PKSNODE_CREATE* OutNodeCreate)
{
- UNIMPLEMENTED;
- return STATUS_UNSUCCESSFUL;
+ PKSNODE_CREATE NodeCreate;
+ ULONG Size;
+ NTSTATUS Status;
+
+ /* did the caller miss the topology */
+ if (!Topology)
+ return STATUS_INVALID_PARAMETER;
+
+ /* set create param size */
+ Size = sizeof(KSNODE_CREATE);
+
+ /* fetch create parameters */
+ Status = KspCopyCreateRequest(Irp,
+ KSSTRING_TopologyNode,
+ &Size,
+ (PVOID*)&NodeCreate);
+
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ if (NodeCreate->CreateFlags != 0 || (NodeCreate->Node >= Topology->TopologyNodesCount && NodeCreate->Node != MAXULONG))
+ {
+ /* invalid node create */
+ FreeItem(NodeCreate);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* store result */
+ *OutNodeCreate = NodeCreate;
+
+ return Status;
}
/*
HANDLE hKey;
PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+ DPRINT("KsTopologyPropertyHandler Irp %p Property %p Data %p Topology %p\n", Irp, Property, Data, Topology);
+
if (Property->Flags != KSPROPERTY_TYPE_GET)
{
Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_MORE_ENTRIES;
break;
}
Item->Size = Size;
Item->Count = Topology->CategoriesCount;
- RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->Categories, Topology->CategoriesCount * sizeof(GUID));
+ if (Topology->CategoriesCount)
+ {
+ RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->Categories, Topology->CategoriesCount * sizeof(GUID));
+ }
Irp->IoStatus.Information = Size;
Status = STATUS_SUCCESS;
break;
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_MORE_ENTRIES;
break;
}
Item->Count = Topology->TopologyNodesCount;
RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyNodes, Topology->TopologyNodesCount * sizeof(GUID));
+ if (Topology->TopologyNodesCount)
+ {
+ RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyNodes, Topology->TopologyNodesCount * sizeof(GUID));
+ }
Irp->IoStatus.Information = Size;
Status = STATUS_SUCCESS;
break;
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_MORE_ENTRIES;
break;
}
Item->Size = Size;
Item->Count = Topology->TopologyConnectionsCount;
- RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyConnections, Topology->TopologyConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
+ if (Topology->TopologyConnections)
+ {
+ RtlMoveMemory((PVOID)(Item + 1), (PVOID)Topology->TopologyConnections, Topology->TopologyConnectionsCount * sizeof(KSTOPOLOGY_CONNECTION));
+ }
+
Irp->IoStatus.Information = Size;
Status = STATUS_SUCCESS;
break;
case KSPROPERTY_TOPOLOGY_NAME:
Node = (KSP_NODE*)Property;
+ if (Node->NodeId >= Topology->TopologyNodesCount)
+ {
+ Irp->IoStatus.Information = 0;
+ Status = STATUS_INVALID_PARAMETER;
+ break;
+ }
+
Status = RtlStringFromGUID(&Topology->TopologyNodesNames[Node->NodeId], &GuidString);
if (!NT_SUCCESS(Status))
{
if (!KeyName.Buffer)
{
Irp->IoStatus.Information = 0;
+ Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
{
Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
- Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_MORE_ENTRIES;
ExFreePool(KeyInfo);
break;
}
return Status;
}
+
+NTSTATUS
+NTAPI
+KspTopologyPropertyHandler(
+ IN PIRP Irp,
+ IN PKSIDENTIFIER Request,
+ IN OUT PVOID Data)
+{
+
+ return STATUS_NOT_IMPLEMENTED;
+}