https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5f0d02eb52c6ebe3caf6aa9c6315f5ca06bb89d3

commit 5f0d02eb52c6ebe3caf6aa9c6315f5ca06bb89d3
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Thu Oct 4 19:30:11 2018 +0200
Commit:     Pierre Schweitzer <[email protected]>
CommitDate: Thu Oct 4 19:30:39 2018 +0200

    [NTOSKRNL] Implement IoChangeFileObjectFilterContext()
---
 ntoskrnl/io/iomgr/file.c | 31 +++++++++++++++++++++++++++++--
 1 file changed, 29 insertions(+), 2 deletions(-)

diff --git a/ntoskrnl/io/iomgr/file.c b/ntoskrnl/io/iomgr/file.c
index 0a5e0b1d1a..860348a370 100644
--- a/ntoskrnl/io/iomgr/file.c
+++ b/ntoskrnl/io/iomgr/file.c
@@ -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

Reply via email to