Synchronize with trunk revision 59636 (just before Alex's CreateProcess revamp).
[reactos.git] / drivers / ksfilter / ks / api.c
index 64c341c..5b50fcf 100644 (file)
@@ -68,18 +68,17 @@ KsAcquireDeviceSecurityLock(
     IN KSDEVICE_HEADER DevHeader,
     IN BOOLEAN Exclusive)
 {
-    NTSTATUS Status;
     PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader;
 
     KeEnterCriticalRegion();
 
     if (Exclusive)
     {
-        Status = ExAcquireResourceExclusiveLite(&Header->SecurityLock, TRUE);
+        ExAcquireResourceExclusiveLite(&Header->SecurityLock, TRUE);
     }
     else
     {
-        Status = ExAcquireResourceSharedLite(&Header->SecurityLock, TRUE);
+        ExAcquireResourceSharedLite(&Header->SecurityLock, TRUE);
     }
 }
 
@@ -169,12 +168,12 @@ KsDefaultDispatchPower(
     PDEVICE_EXTENSION DeviceExtension;
     PKSIDEVICE_HEADER DeviceHeader;
     PKSIOBJECT_HEADER ObjectHeader;
-    PIO_STACK_LOCATION IoStack;
+    //PIO_STACK_LOCATION IoStack;
     PLIST_ENTRY ListEntry;
     NTSTATUS Status;
 
     /* get current irp stack */
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    //IoStack = IoGetCurrentIrpStackLocation(Irp);
 
     /* caller wants to add the target device */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -229,11 +228,11 @@ KsDefaultForwardIrp(
 {
     PDEVICE_EXTENSION DeviceExtension;
     PKSIDEVICE_HEADER DeviceHeader;
-    PIO_STACK_LOCATION IoStack;
+    //PIO_STACK_LOCATION IoStack;
     NTSTATUS Status;
 
     /* get current irp stack */
-    IoStack = IoGetCurrentIrpStackLocation(Irp);
+    //IoStack = IoGetCurrentIrpStackLocation(Irp);
 
     /* caller wants to add the target device */
     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
@@ -614,10 +613,10 @@ KsAllocateObjectHeader(
     IN  KSDISPATCH_TABLE* Table)
 {
     PIO_STACK_LOCATION IoStack;
-    PDEVICE_EXTENSION DeviceExtension;
-    PKSIDEVICE_HEADER DeviceHeader;
+    //PDEVICE_EXTENSION DeviceExtension;
+    //PKSIDEVICE_HEADER DeviceHeader;
     PKSIOBJECT_HEADER ObjectHeader;
-    PKSOBJECT_CREATE_ITEM CreateItem;
+    //PKSOBJECT_CREATE_ITEM CreateItem;
     NTSTATUS Status;
 
     if (!Header)
@@ -632,9 +631,9 @@ KsAllocateObjectHeader(
     /* get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
     /* get device extension */
-    DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
+    //DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
     /* get device header */
-    DeviceHeader = DeviceExtension->DeviceHeader;
+    //DeviceHeader = DeviceExtension->DeviceHeader;
 
     /* sanity check */
     ASSERT(IoStack->FileObject);
@@ -652,7 +651,7 @@ KsAllocateObjectHeader(
     InitializeListHead(&ObjectHeader->ItemList);
 
     /* get create item */
-    CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
+    //CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
 
     /* do we have a name */
     if (IoStack->FileObject->FileName.Buffer)
@@ -1332,7 +1331,7 @@ KopDispatchClose(
 
     /* complete request */
     Irp->IoStatus.Status = STATUS_SUCCESS;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return STATUS_SUCCESS;
 }
@@ -1416,7 +1415,7 @@ KopDispatchCreate(
     IoStack->FileObject->FsContext2 = (PVOID)Header;
 
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
 
     return Status;
 
@@ -1429,7 +1428,7 @@ cleanup:
         FreeItem(Header);
 
     Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
+    CompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }
 
@@ -1703,7 +1702,7 @@ KsCompletePendingRequest(
     if (IoStack->MajorFunction != IRP_MJ_CLOSE)
     {
         /* can be completed immediately */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return;
     }
 
@@ -1711,7 +1710,7 @@ KsCompletePendingRequest(
     if (!NT_SUCCESS(Irp->IoStatus.Status))
     {
         /* closing failed, complete irp */
-        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        CompleteRequest(Irp, IO_NO_INCREMENT);
         return;
     }
 
@@ -1723,136 +1722,8 @@ KsCompletePendingRequest(
 
 }
 
-/*
-    @implemented
-*/
-KSDDKAPI
 NTSTATUS
 NTAPI
-KsCreateBusEnumObject(
-    IN PWCHAR BusIdentifier,
-    IN PDEVICE_OBJECT BusDeviceObject,
-    IN PDEVICE_OBJECT PhysicalDeviceObject,
-    IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL,
-    IN REFGUID InterfaceGuid OPTIONAL,
-    IN PWCHAR ServiceRelativePath OPTIONAL)
-{
-    ULONG Length;
-    NTSTATUS Status = STATUS_SUCCESS;
-    UNICODE_STRING ServiceKeyPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
-    PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension;
-    PDEVICE_EXTENSION DeviceExtension;
-
-    /* calculate sizeof bus enum device extension */
-    Length = wcslen(BusIdentifier) * sizeof(WCHAR);
-    Length += sizeof(BUS_ENUM_DEVICE_EXTENSION);
-
-    BusDeviceExtension = AllocateItem(NonPagedPool, Length);
-    if (!BusDeviceExtension)
-    {
-        /* not enough memory */
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    /* zero device extension */
-    RtlZeroMemory(BusDeviceExtension, sizeof(BUS_ENUM_DEVICE_EXTENSION));
-
-    /* initialize bus device extension */
-    wcscpy(BusDeviceExtension->BusIdentifier, BusIdentifier);
-
-    /* allocate service path string */
-    Length = ServiceKeyPath.MaximumLength;
-    Length += BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName.MaximumLength;
-
-    if (ServiceRelativePath)
-    {
-        /* relative path for devices */
-        Length += wcslen(ServiceRelativePath) + 2 * sizeof(WCHAR);
-    }
-
-    BusDeviceExtension->ServicePath.Length = 0;
-    BusDeviceExtension->ServicePath.MaximumLength = Length;
-    BusDeviceExtension->ServicePath.Buffer = AllocateItem(NonPagedPool, Length);
-
-    if (!BusDeviceExtension->ServicePath.Buffer)
-    {
-        /* not enough memory */
-        FreeItem(BusDeviceExtension);
-        return STATUS_INSUFFICIENT_RESOURCES;
-    }
-
-    RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &ServiceKeyPath);
-    RtlAppendUnicodeStringToString(&BusDeviceExtension->ServicePath, &BusDeviceObject->DriverObject->DriverExtension->ServiceKeyName);
-
-    if (ServiceRelativePath)
-    {
-        RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, L"\\");
-        RtlAppendUnicodeToString(&BusDeviceExtension->ServicePath, ServiceRelativePath);
-    }
-
-    if (InterfaceGuid)
-    {
-        /* register an device interface */
-        Status = IoRegisterDeviceInterface(PhysicalDeviceObject, InterfaceGuid, NULL, &BusDeviceExtension->SymbolicLinkName);
-
-        /* check for success */
-        if (!NT_SUCCESS(Status))
-        {
-            FreeItem(BusDeviceExtension->ServicePath.Buffer);
-            FreeItem(BusDeviceExtension);
-            return Status;
-        }
-
-        /* now enable device interface */
-        Status = IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, TRUE);
-
-        if (!NT_SUCCESS(Status))
-        {
-            FreeItem(BusDeviceExtension->ServicePath.Buffer);
-            FreeItem(BusDeviceExtension);
-            return Status;
-        }
-
-        /* set state enabled */
-        BusDeviceExtension->Enabled = TRUE;
-    }
-
-    /* store device objects */
-    BusDeviceExtension->BusDeviceObject = BusDeviceObject;
-    BusDeviceExtension->PnpDeviceObject = PnpDeviceObject;
-    BusDeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
-
-    if (!PnpDeviceObject)
-    {
-        BusDeviceExtension->PnpDeviceObject = IoAttachDeviceToDeviceStack(BusDeviceObject, PhysicalDeviceObject);
-
-        if (!BusDeviceExtension->PnpDeviceObject)
-        {
-            /* failed to attach device */
-            if (BusDeviceExtension->Enabled)
-            {
-                IoSetDeviceInterfaceState(&BusDeviceExtension->SymbolicLinkName, FALSE);
-                RtlFreeUnicodeString(&BusDeviceExtension->SymbolicLinkName);
-            }
-
-            /* free device extension */
-            FreeItem(BusDeviceExtension->ServicePath.Buffer);
-            FreeItem(BusDeviceExtension);
-
-            return STATUS_DEVICE_REMOVED;
-        }
-    }
-
-    /* attach device extension */
-    DeviceExtension = (PDEVICE_EXTENSION)BusDeviceObject->DeviceExtension;
-    DeviceExtension->DeviceHeader = (PKSIDEVICE_HEADER)BusDeviceExtension;
-
-    /* FIXME scan bus and invalidate device relations */
-    return Status;
-}
-
- NTSTATUS
-NTAPI
 KspSetGetBusDataCompletion(
     IN PDEVICE_OBJECT  DeviceObject,
     IN PIRP  Irp,
@@ -1979,47 +1850,6 @@ KsDeviceRegisterAdapterObject(
 
 }
 
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsGetBusEnumIdentifier(
-    IN PIRP Irp)
-{
-    UNIMPLEMENTED
-
-    return STATUS_UNSUCCESSFUL;
-}
-
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsGetBusEnumParentFDOFromChildPDO(
-    IN PDEVICE_OBJECT DeviceObject,
-    OUT PDEVICE_OBJECT *FunctionalDeviceObject)
-{
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
-
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsGetBusEnumPnpDeviceObject(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN PDEVICE_OBJECT *PnpDeviceObject)
-{
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
 
 /*
     @implemented
@@ -2061,33 +1891,6 @@ KsGetNextSibling(
     return (PVOID)BasicHeader->Next.Pin;
 }
 
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsInstallBusEnumInterface(
-    PIRP Irp)
-{
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
-
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsIsBusEnumChildDevice(
-    IN PDEVICE_OBJECT DeviceObject,
-    OUT PBOOLEAN ChildDevice)
-{
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
-
 ULONG
 KspCountMethodSets(
     IN PKSAUTOMATION_TABLE  AutomationTableA OPTIONAL,
@@ -2257,7 +2060,7 @@ KspCopyMethodSets(
     /* set counter */
     Count = AutomationTableA->MethodSetsCount;
 
-    /* now copy entries which arent available in the dominant table */
+    /* now copy entries which aren't available in the dominant table */
     for(Index = 0; Index < AutomationTableB->MethodSetsCount; Index++)
     {
         /* set found to false */
@@ -2284,15 +2087,100 @@ KspCopyMethodSets(
     return STATUS_SUCCESS;
 }
 
+VOID
+KspAddPropertyItem(
+    OUT PKSPROPERTY_SET OutPropertySet,
+    IN PKSPROPERTY_ITEM PropertyItem,
+    IN ULONG PropertyItemSize)
+{
+    PKSPROPERTY_ITEM CurrentPropertyItem;
+    ULONG Index;
+
+    // check if the property item is already present
+    CurrentPropertyItem = (PKSPROPERTY_ITEM)OutPropertySet->PropertyItem;
+    for(Index = 0; Index < OutPropertySet->PropertiesCount; Index++)
+    {
+        if (CurrentPropertyItem->PropertyId == PropertyItem->PropertyId)
+        {
+            // item already present
+            return;
+        }
+
+        // next item
+        CurrentPropertyItem = (PKSPROPERTY_ITEM)((ULONG_PTR)CurrentPropertyItem + PropertyItemSize);
+    }
+    // add item
+    RtlCopyMemory(CurrentPropertyItem, PropertyItem, PropertyItemSize);
+    OutPropertySet->PropertiesCount++;
+}
+
+NTSTATUS
+KspMergePropertySet(
+    OUT PKSAUTOMATION_TABLE  Table,
+    OUT PKSPROPERTY_SET OutPropertySet,
+    IN PKSPROPERTY_SET PropertySetA,
+    IN PKSPROPERTY_SET PropertySetB,
+    IN KSOBJECT_BAG  Bag OPTIONAL)
+{
+    ULONG PropertyCount, Index;
+    PKSPROPERTY_ITEM PropertyItem, CurrentPropertyItem;
+    NTSTATUS Status;
+
+    // max properties 
+    PropertyCount = PropertySetA->PropertiesCount + PropertySetB->PropertiesCount;
+
+    // allocate items
+    PropertyItem = AllocateItem(NonPagedPool, Table->PropertyItemSize * PropertyCount);
+    if (!PropertyItem)
+        return STATUS_INSUFFICIENT_RESOURCES;
+
+    if (Bag)
+    {
+        /* add table to object bag */
+        Status = KsAddItemToObjectBag(Bag, PropertyItem, NULL);
+        /* check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            /* free table */
+            FreeItem(Table);
+            return Status;
+        }
+    }
+
+    // copy entries from dominant table
+    RtlCopyMemory(PropertyItem, PropertySetA->PropertyItem, Table->PropertyItemSize * PropertySetA->PropertiesCount);
+
+    // init property set
+    OutPropertySet->PropertiesCount = PropertySetA->PropertiesCount;
+    OutPropertySet->PropertyItem = PropertyItem;
+
+    // copy other entries
+    CurrentPropertyItem = (PKSPROPERTY_ITEM)PropertySetB->PropertyItem;
+    for(Index = 0; Index < PropertySetB->PropertiesCount; Index++)
+    {
+
+        // add entries
+        KspAddPropertyItem(OutPropertySet, CurrentPropertyItem, Table->PropertyItemSize);
+
+        // next entry
+        CurrentPropertyItem = (PKSPROPERTY_ITEM)((ULONG_PTR)CurrentPropertyItem + Table->PropertyItemSize);
+    }
+
+    // done
+    return STATUS_SUCCESS;
+}
+
 
 NTSTATUS
 KspCopyPropertySets(
     OUT PKSAUTOMATION_TABLE  Table,
     IN PKSAUTOMATION_TABLE  AutomationTableA OPTIONAL,
-    IN PKSAUTOMATION_TABLE  AutomationTableB OPTIONAL)
+    IN PKSAUTOMATION_TABLE  AutomationTableB OPTIONAL,
+    IN KSOBJECT_BAG  Bag OPTIONAL)
 {
     ULONG Index, SubIndex, Count;
     BOOL bFound;
+    NTSTATUS Status;
 
     if (!AutomationTableA)
     {
@@ -2312,7 +2200,7 @@ KspCopyPropertySets(
     /* set counter */
     Count = AutomationTableA->PropertySetsCount;
 
-    /* now copy entries which arent available in the dominant table */
+    /* now copy entries which aren't available in the dominant table */
     for(Index = 0; Index < AutomationTableB->PropertySetsCount; Index++)
     {
         /* set found to false */
@@ -2334,6 +2222,17 @@ KspCopyPropertySets(
             RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], sizeof(KSPROPERTY_SET));
             Count++;
         }
+        else
+        {
+            // merge property sets
+            Status = KspMergePropertySet(Table, (PKSPROPERTY_SET)&Table->PropertySets[SubIndex], (PKSPROPERTY_SET)&AutomationTableA->PropertySets[SubIndex], (PKSPROPERTY_SET)&AutomationTableB->PropertySets[Index], Bag);
+            if (!NT_SUCCESS(Status))
+            {
+                // failed to merge
+                DPRINT1("[KS] Failed to merge %x\n", Status);
+                return Status;
+            }
+        }
     }
 
     return STATUS_SUCCESS;
@@ -2366,7 +2265,7 @@ KspCopyEventSets(
     /* set counter */
     Count = AutomationTableA->EventSetsCount;
 
-    /* now copy entries which arent available in the dominant table */
+    /* now copy entries which aren't available in the dominant table */
     for(Index = 0; Index < AutomationTableB->EventSetsCount; Index++)
     {
         /* set found to false */
@@ -2448,6 +2347,12 @@ KsMergeAutomationTables(
             Table->PropertyItemSize = AutomationTableB->PropertyItemSize;
         }
 
+        if (AutomationTableA && AutomationTableB)
+        {
+            // FIXME handle different propery item sizes
+            ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize);
+        }
+
         /* now allocate the property sets */
         Table->PropertySets = AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * Table->PropertySetsCount);
 
@@ -2469,7 +2374,7 @@ KsMergeAutomationTables(
             }
         }
         /* now copy the property sets */
-        Status = KspCopyPropertySets(Table, AutomationTableA, AutomationTableB);
+        Status = KspCopyPropertySets(Table, AutomationTableA, AutomationTableB, Bag);
         if(!NT_SUCCESS(Status))
             goto cleanup;
 
@@ -2598,104 +2503,6 @@ cleanup:
     return STATUS_INSUFFICIENT_RESOURCES;
 }
 
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsServiceBusEnumCreateRequest(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN OUT PIRP Irp)
-{
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
-
-
-/*
-    @unimplemented
-*/
-KSDDKAPI
-NTSTATUS
-NTAPI
-KsServiceBusEnumPnpRequest(
-    IN PDEVICE_OBJECT DeviceObject,
-    IN OUT PIRP Irp)
-{
-    UNIMPLEMENTED
-    return STATUS_UNSUCCESSFUL;
-}
-
-VOID
-NTAPI
-KspRemoveBusInterface(
-    PVOID Ctx)
-{
-    PKSREMOVE_BUS_INTERFACE_CTX Context =(PKSREMOVE_BUS_INTERFACE_CTX)Ctx;
-
-    /* TODO
-     * get SWENUM_INSTALL_INTERFACE struct
-     * open device key and delete the keys
-     */
-
-    UNIMPLEMENTED
-
-    /* set status */
-    Context->Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
-
-
-    /* signal completion */
-    KeSetEvent(&Context->Event, IO_NO_INCREMENT, FALSE);
-}
-
-/*
-    @unimplemented
-*/
-KSDDKAPI 
-NTSTATUS
-NTAPI
-KsRemoveBusEnumInterface(
-    IN PIRP Irp)
-{
-    KPROCESSOR_MODE Mode;
-    LUID luid;
-    KSREMOVE_BUS_INTERFACE_CTX Ctx;
-    WORK_QUEUE_ITEM WorkItem;
-
-    /* get previous mode */
-    Mode = ExGetPreviousMode();
-
-    /* convert to luid */
-    luid = RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
-
-    /* perform access check */
-    if (!SeSinglePrivilegeCheck(luid, Mode))
-    {
-        /* insufficient privileges */
-        return STATUS_PRIVILEGE_NOT_HELD;
-    }
-    /* initialize event */
-    KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);
-
-    /* store irp in ctx */
-    Ctx.Irp = Irp;
-
-    /* initialize work item */
-    ExInitializeWorkItem(&WorkItem, KspRemoveBusInterface, (PVOID)&Ctx);
-
-    /* now queue the work item */
-    ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
-
-    /* wait for completion */
-    KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);
-
-    /* return result */
-    return Ctx.Irp->IoStatus.Status;
-
-}
-
-
 /*
     @unimplemented
 */