[NTOSKRNL] Implement IoChangeFileObjectFilterContext()
authorPierre Schweitzer <pierre@reactos.org>
Thu, 4 Oct 2018 17:30:11 +0000 (19:30 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Thu, 4 Oct 2018 17:30:39 +0000 (19:30 +0200)
ntoskrnl/io/iomgr/file.c

index 0a5e0b1..860348a 100644 (file)
@@ -2458,14 +2458,41 @@ IoChangeFileObjectFilterContext(IN PFILE_OBJECT FileObject,
                                 IN PVOID FilterContext,
                                 IN BOOLEAN Define)
 {
+    ULONG_PTR Success;
+    PFILE_OBJECT_EXTENSION FileObjectExtension;
+
     if (!(FileObject->Flags & FO_FILE_OBJECT_HAS_EXTENSION))
     {
         return STATUS_INVALID_PARAMETER;
     }
 
-    UNIMPLEMENTED;
+    FileObjectExtension = FileObject->FileObjectExtension;
+    if (Define)
+    {
+        /* If define, just set the new value if not value is set
+         * Success will only contain old value. It is valid if it is NULL
+         */
+        Success = InterlockedCompareExchange((volatile LONG *)&FileObjectExtension->FilterContext, (ULONG_PTR)FilterContext, 0);
+    }
+    else
+    {
+        /* If not define, we want to reset filter context.
+         * We will remove value (provided by the caller) and set NULL instead.
+         * This will only success if caller provides correct previous value.
+         * To catch whether it worked, we substract previous value to expect value:
+         * If it matches (and thus, we reset), Success will contain 0
+         * Otherwise, it will contain a non-zero value.
+         */
+        Success = InterlockedCompareExchange((volatile LONG *)&FileObjectExtension->FilterContext, 0, (ULONG_PTR)FilterContext) - (ULONG_PTR)FilterContext;
+    }
 
-    return STATUS_NOT_IMPLEMENTED;
+    /* If success isn't 0, it means we failed somewhere (set or unset) */
+    if (Success != 0)
+    {
+        return STATUS_ALREADY_COMMITTED;
+    }
+
+    return STATUS_SUCCESS;
 }
 
 NTSTATUS