[KS]
[reactos.git] / reactos / drivers / ksfilter / ks / topology.c
index 07d7d85..8d22885 100644 (file)
@@ -1,8 +1,14 @@
+/*
+ * 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
@@ -17,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);
@@ -47,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"\\");
@@ -75,7 +60,7 @@ KspCreateObjectType(
                           0,
                           0,
                           FILE_OPEN,
-                          FILE_SYNCHRONOUS_IO_NONALERT,
+                          0,
                           NULL,
                           0,
                           CreateFileTypeNone,
@@ -84,8 +69,6 @@ KspCreateObjectType(
 
     /* free request buffer */
     ExFreePool(Name.Buffer);
-    /* release parent handle */
-    ObDereferenceObject(FileObject);
     return Status;
 }
 
@@ -101,7 +84,7 @@ KsCreateTopologyNode(
     OUT PHANDLE NodeHandle)
 {
     return KspCreateObjectType(ParentHandle,
-                               L"{0621061A-EE75-11D0-B915-00A0C9223196}",
+                               KSSTRING_TopologyNode,
                                (PVOID)NodeCreate,
                                sizeof(KSNODE_CREATE),
                                DesiredAccess,
@@ -109,16 +92,47 @@ KsCreateTopologyNode(
 }
 
 /*
-    @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;
 }
 
 /*
@@ -146,6 +160,8 @@ KsTopologyPropertyHandler(
     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;
@@ -162,7 +178,7 @@ KsTopologyPropertyHandler(
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
             {
                 Irp->IoStatus.Information = Size;
-                Status = STATUS_BUFFER_TOO_SMALL;
+                Status = STATUS_MORE_ENTRIES;
                 break;
             }
 
@@ -170,7 +186,10 @@ KsTopologyPropertyHandler(
             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;
@@ -180,7 +199,7 @@ KsTopologyPropertyHandler(
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
             {
                 Irp->IoStatus.Information = Size;
-                Status = STATUS_BUFFER_TOO_SMALL;
+                Status = STATUS_MORE_ENTRIES;
                 break;
             }
 
@@ -189,6 +208,10 @@ KsTopologyPropertyHandler(
             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;
@@ -198,7 +221,7 @@ KsTopologyPropertyHandler(
             if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
             {
                 Irp->IoStatus.Information = Size;
-                Status = STATUS_BUFFER_TOO_SMALL;
+                Status = STATUS_MORE_ENTRIES;
                 break;
             }
 
@@ -206,7 +229,11 @@ KsTopologyPropertyHandler(
             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;
@@ -214,6 +241,13 @@ KsTopologyPropertyHandler(
         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))
             {
@@ -227,6 +261,7 @@ KsTopologyPropertyHandler(
             if (!KeyName.Buffer)
             {
                 Irp->IoStatus.Information = 0;
+                Status = STATUS_INSUFFICIENT_RESOURCES;
                 break;
             }
 
@@ -273,7 +308,7 @@ KsTopologyPropertyHandler(
             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;
             }
@@ -291,3 +326,14 @@ KsTopologyPropertyHandler(
 
     return Status;
 }
+
+NTSTATUS
+NTAPI
+KspTopologyPropertyHandler(
+    IN PIRP Irp,
+    IN PKSIDENTIFIER  Request,
+    IN OUT PVOID  Data)
+{
+
+    return STATUS_NOT_IMPLEMENTED;
+}