https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5f0d02eb52c6ebe3caf6a…
commit 5f0d02eb52c6ebe3caf6aa9c6315f5ca06bb89d3
Author: Pierre Schweitzer <pierre(a)reactos.org>
AuthorDate: Thu Oct 4 19:30:11 2018 +0200
Commit: Pierre Schweitzer <pierre(a)reactos.org>
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