https://git.reactos.org/?p=reactos.git;a=commitdiff;h=7fb0d13a46e6087e4b1f4…
commit 7fb0d13a46e6087e4b1f45d0fb4b0fbab31b32a4
Author:     George Bișoc <george.bisoc(a)reactos.org>
AuthorDate: Sun Jul 4 18:01:25 2021 +0200
Commit:     George Bișoc <george.bisoc(a)reactos.org>
CommitDate: Mon Jul 5 09:39:06 2021 +0200
    [NTOS:SE] Move SQOS capturing in its own file
    * Quality of service kernel stuff bears nothing with security descriptors in anyway,
so just have a file specifically for it
    * Annotate the function arguments parameters with SAL
    * Document the functions
---
 ntoskrnl/include/internal/se.h |  18 ++--
 ntoskrnl/ntos.cmake            |   1 +
 ntoskrnl/se/sd.c               | 172 -----------------------------
 ntoskrnl/se/sqos.c             | 239 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 249 insertions(+), 181 deletions(-)
diff --git a/ntoskrnl/include/internal/se.h b/ntoskrnl/include/internal/se.h
index 03639470c72..aa01ef58088 100644
--- a/ntoskrnl/include/internal/se.h
+++ b/ntoskrnl/include/internal/se.h
@@ -465,20 +465,20 @@ SepDuplicateToken(
 NTSTATUS
 NTAPI
 SepCaptureSecurityQualityOfService(
-    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
-    IN KPROCESSOR_MODE AccessMode,
-    IN POOL_TYPE PoolType,
-    IN BOOLEAN CaptureIfKernel,
-    OUT PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
-    OUT PBOOLEAN Present
+    _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
+    _In_ KPROCESSOR_MODE AccessMode,
+    _In_ POOL_TYPE PoolType,
+    _In_ BOOLEAN CaptureIfKernel,
+    _Out_ PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
+    _Out_ PBOOLEAN Present
 );
 VOID
 NTAPI
 SepReleaseSecurityQualityOfService(
-    IN PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService OPTIONAL,
-    IN KPROCESSOR_MODE AccessMode,
-    IN BOOLEAN CaptureIfKernel
+    _In_opt_ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService,
+    _In_ KPROCESSOR_MODE AccessMode,
+    _In_ BOOLEAN CaptureIfKernel
 );
 NTSTATUS
diff --git a/ntoskrnl/ntos.cmake b/ntoskrnl/ntos.cmake
index 6e1edf2d944..4b56e74896e 100644
--- a/ntoskrnl/ntos.cmake
+++ b/ntoskrnl/ntos.cmake
@@ -280,6 +280,7 @@ list(APPEND SOURCE
     ${REACTOS_SOURCE_DIR}/ntoskrnl/se/sd.c
     ${REACTOS_SOURCE_DIR}/ntoskrnl/se/semgr.c
     ${REACTOS_SOURCE_DIR}/ntoskrnl/se/sid.c
+    ${REACTOS_SOURCE_DIR}/ntoskrnl/se/sqos.c
     ${REACTOS_SOURCE_DIR}/ntoskrnl/se/srm.c
     ${REACTOS_SOURCE_DIR}/ntoskrnl/se/token.c
     ${REACTOS_SOURCE_DIR}/ntoskrnl/vf/driver.c
diff --git a/ntoskrnl/se/sd.c b/ntoskrnl/se/sd.c
index 7ab6ee9d2bd..72eff599ce5 100644
--- a/ntoskrnl/se/sd.c
+++ b/ntoskrnl/se/sd.c
@@ -215,178 +215,6 @@ SeSetWorldSecurityDescriptor(SECURITY_INFORMATION
SecurityInformation,
     return STATUS_SUCCESS;
 }
-
-NTSTATUS
-NTAPI
-SepCaptureSecurityQualityOfService(IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
-                                   IN KPROCESSOR_MODE AccessMode,
-                                   IN POOL_TYPE PoolType,
-                                   IN BOOLEAN CaptureIfKernel,
-                                   OUT PSECURITY_QUALITY_OF_SERVICE
*CapturedSecurityQualityOfService,
-                                   OUT PBOOLEAN Present)
-{
-    PSECURITY_QUALITY_OF_SERVICE CapturedQos;
-    NTSTATUS Status = STATUS_SUCCESS;
-
-    PAGED_CODE();
-
-    ASSERT(CapturedSecurityQualityOfService);
-    ASSERT(Present);
-
-    if (ObjectAttributes != NULL)
-    {
-        if (AccessMode != KernelMode)
-        {
-            SECURITY_QUALITY_OF_SERVICE SafeQos;
-
-            _SEH2_TRY
-            {
-                ProbeForRead(ObjectAttributes,
-                             sizeof(OBJECT_ATTRIBUTES),
-                             sizeof(ULONG));
-                if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
-                {
-                    if (ObjectAttributes->SecurityQualityOfService != NULL)
-                    {
-                        ProbeForRead(ObjectAttributes->SecurityQualityOfService,
-                                     sizeof(SECURITY_QUALITY_OF_SERVICE),
-                                     sizeof(ULONG));
-
-                        if
(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length
==
-                            sizeof(SECURITY_QUALITY_OF_SERVICE))
-                        {
-                            /*
-                             * Don't allocate memory here because ExAllocate should
bugcheck
-                             * the system if it's buggy, SEH would catch that! So
make a local
-                             * copy of the qos structure.
-                             */
-                            RtlCopyMemory(&SafeQos,
-                                          ObjectAttributes->SecurityQualityOfService,
-                                          sizeof(SECURITY_QUALITY_OF_SERVICE));
-                            *Present = TRUE;
-                        }
-                        else
-                        {
-                            Status = STATUS_INVALID_PARAMETER;
-                        }
-                    }
-                    else
-                    {
-                        *CapturedSecurityQualityOfService = NULL;
-                        *Present = FALSE;
-                    }
-                }
-                else
-                {
-                    Status = STATUS_INVALID_PARAMETER;
-                }
-            }
-            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-            {
-                Status = _SEH2_GetExceptionCode();
-            }
-            _SEH2_END;
-
-            if (NT_SUCCESS(Status))
-            {
-                if (*Present)
-                {
-                    CapturedQos = ExAllocatePoolWithTag(PoolType,
-
sizeof(SECURITY_QUALITY_OF_SERVICE),
-                                                        TAG_QOS);
-                    if (CapturedQos != NULL)
-                    {
-                        RtlCopyMemory(CapturedQos,
-                                      &SafeQos,
-                                      sizeof(SECURITY_QUALITY_OF_SERVICE));
-                        *CapturedSecurityQualityOfService = CapturedQos;
-                    }
-                    else
-                    {
-                        Status = STATUS_INSUFFICIENT_RESOURCES;
-                    }
-                }
-                else
-                {
-                    *CapturedSecurityQualityOfService = NULL;
-                }
-            }
-        }
-        else
-        {
-            if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
-            {
-                if (CaptureIfKernel)
-                {
-                    if (ObjectAttributes->SecurityQualityOfService != NULL)
-                    {
-                        if
(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length
==
-                            sizeof(SECURITY_QUALITY_OF_SERVICE))
-                        {
-                            CapturedQos = ExAllocatePoolWithTag(PoolType,
-
sizeof(SECURITY_QUALITY_OF_SERVICE),
-                                                                TAG_QOS);
-                            if (CapturedQos != NULL)
-                            {
-                                RtlCopyMemory(CapturedQos,
-
ObjectAttributes->SecurityQualityOfService,
-                                              sizeof(SECURITY_QUALITY_OF_SERVICE));
-                                *CapturedSecurityQualityOfService = CapturedQos;
-                                *Present = TRUE;
-                            }
-                            else
-                            {
-                                Status = STATUS_INSUFFICIENT_RESOURCES;
-                            }
-                        }
-                        else
-                        {
-                            Status = STATUS_INVALID_PARAMETER;
-                        }
-                    }
-                    else
-                    {
-                        *CapturedSecurityQualityOfService = NULL;
-                        *Present = FALSE;
-                    }
-                }
-                else
-                {
-                    *CapturedSecurityQualityOfService =
(PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
-                    *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
-                }
-            }
-            else
-            {
-                Status = STATUS_INVALID_PARAMETER;
-            }
-        }
-    }
-    else
-    {
-        *CapturedSecurityQualityOfService = NULL;
-        *Present = FALSE;
-    }
-
-    return Status;
-}
-
-
-VOID
-NTAPI
-SepReleaseSecurityQualityOfService(IN PSECURITY_QUALITY_OF_SERVICE
CapturedSecurityQualityOfService  OPTIONAL,
-                                   IN KPROCESSOR_MODE AccessMode,
-                                   IN BOOLEAN CaptureIfKernel)
-{
-    PAGED_CODE();
-
-    if (CapturedSecurityQualityOfService != NULL &&
-        (AccessMode != KernelMode || CaptureIfKernel))
-    {
-        ExFreePoolWithTag(CapturedSecurityQualityOfService, TAG_QOS);
-    }
-}
-
 /* PUBLIC FUNCTIONS ***********************************************************/
 static
diff --git a/ntoskrnl/se/sqos.c b/ntoskrnl/se/sqos.c
new file mode 100644
index 00000000000..995c19680ba
--- /dev/null
+++ b/ntoskrnl/se/sqos.c
@@ -0,0 +1,239 @@
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:         Security Quality of Service (SQoS) implementation support
+ * COPYRIGHT:       Copyright David Welch <welch(a)cwcom.net>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *******************************************************************/
+
+/**
+ * @brief
+ * Captures the security quality of service data given the object
+ * attributes from an object.
+ *
+ * @param[in] ObjectAttributes
+ * Attributes of an object where SQOS is to be retrieved. If the caller
+ * doesn't fill object attributes to the function, it automatically assumes
+ * SQOS is not present, or if, there's no SQOS present in the object attributes list
+ * of the object itself.
+ *
+ * @param[in] AccessMode
+ * Processor access mode.
+ *
+ * @param[in] PoolType
+ * The pool type for the captured SQOS to be used for allocation.
+ *
+ * @param[in] CaptureIfKernel
+ * Capture access condition. To be set to TRUE if the capture is done within the kernel,
+ * FALSE if the capture is done in a kernel mode driver or user mode otherwise.
+ *
+ * @param[out] CapturedSecurityQualityOfService
+ * The captured SQOS data from the object.
+ *
+ * @param[out] Present
+ * Returns TRUE if SQOS is present in an object, FALSE otherwise. FALSE is also
immediately
+ * returned if no object attributes is given to the call.
+ *
+ * @return
+ * STATUS_SUCCESS if SQOS from the object has been fully and successfully captured.
STATUS_INVALID_PARAMETER
+ * if the caller submits an invalid object attributes list. STATUS_INSUFFICIENT_RESOURCES
if the function has
+ * failed to allocate some resources in the pool for the captured SQOS. A failure
NTSTATUS code is returned
+ * otherwise.
+ */
+NTSTATUS
+NTAPI
+SepCaptureSecurityQualityOfService(
+    _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes,
+    _In_ KPROCESSOR_MODE AccessMode,
+    _In_ POOL_TYPE PoolType,
+    _In_ BOOLEAN CaptureIfKernel,
+    _Out_ PSECURITY_QUALITY_OF_SERVICE *CapturedSecurityQualityOfService,
+    _Out_ PBOOLEAN Present)
+{
+    PSECURITY_QUALITY_OF_SERVICE CapturedQos;
+    NTSTATUS Status = STATUS_SUCCESS;
+
+    PAGED_CODE();
+
+    ASSERT(CapturedSecurityQualityOfService);
+    ASSERT(Present);
+
+    if (ObjectAttributes != NULL)
+    {
+        if (AccessMode != KernelMode)
+        {
+            SECURITY_QUALITY_OF_SERVICE SafeQos;
+
+            _SEH2_TRY
+            {
+                ProbeForRead(ObjectAttributes,
+                             sizeof(OBJECT_ATTRIBUTES),
+                             sizeof(ULONG));
+                if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+                {
+                    if (ObjectAttributes->SecurityQualityOfService != NULL)
+                    {
+                        ProbeForRead(ObjectAttributes->SecurityQualityOfService,
+                                     sizeof(SECURITY_QUALITY_OF_SERVICE),
+                                     sizeof(ULONG));
+
+                        if
(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length
==
+                            sizeof(SECURITY_QUALITY_OF_SERVICE))
+                        {
+                            /*
+                             * Don't allocate memory here because ExAllocate should
bugcheck
+                             * the system if it's buggy, SEH would catch that! So
make a local
+                             * copy of the qos structure.
+                             */
+                            RtlCopyMemory(&SafeQos,
+                                          ObjectAttributes->SecurityQualityOfService,
+                                          sizeof(SECURITY_QUALITY_OF_SERVICE));
+                            *Present = TRUE;
+                        }
+                        else
+                        {
+                            Status = STATUS_INVALID_PARAMETER;
+                        }
+                    }
+                    else
+                    {
+                        *CapturedSecurityQualityOfService = NULL;
+                        *Present = FALSE;
+                    }
+                }
+                else
+                {
+                    Status = STATUS_INVALID_PARAMETER;
+                }
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+                Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END;
+
+            if (NT_SUCCESS(Status))
+            {
+                if (*Present)
+                {
+                    CapturedQos = ExAllocatePoolWithTag(PoolType,
+
sizeof(SECURITY_QUALITY_OF_SERVICE),
+                                                        TAG_QOS);
+                    if (CapturedQos != NULL)
+                    {
+                        RtlCopyMemory(CapturedQos,
+                                      &SafeQos,
+                                      sizeof(SECURITY_QUALITY_OF_SERVICE));
+                        *CapturedSecurityQualityOfService = CapturedQos;
+                    }
+                    else
+                    {
+                        Status = STATUS_INSUFFICIENT_RESOURCES;
+                    }
+                }
+                else
+                {
+                    *CapturedSecurityQualityOfService = NULL;
+                }
+            }
+        }
+        else
+        {
+            if (ObjectAttributes->Length == sizeof(OBJECT_ATTRIBUTES))
+            {
+                if (CaptureIfKernel)
+                {
+                    if (ObjectAttributes->SecurityQualityOfService != NULL)
+                    {
+                        if
(((PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService)->Length
==
+                            sizeof(SECURITY_QUALITY_OF_SERVICE))
+                        {
+                            CapturedQos = ExAllocatePoolWithTag(PoolType,
+
sizeof(SECURITY_QUALITY_OF_SERVICE),
+                                                                TAG_QOS);
+                            if (CapturedQos != NULL)
+                            {
+                                RtlCopyMemory(CapturedQos,
+
ObjectAttributes->SecurityQualityOfService,
+                                              sizeof(SECURITY_QUALITY_OF_SERVICE));
+                                *CapturedSecurityQualityOfService = CapturedQos;
+                                *Present = TRUE;
+                            }
+                            else
+                            {
+                                Status = STATUS_INSUFFICIENT_RESOURCES;
+                            }
+                        }
+                        else
+                        {
+                            Status = STATUS_INVALID_PARAMETER;
+                        }
+                    }
+                    else
+                    {
+                        *CapturedSecurityQualityOfService = NULL;
+                        *Present = FALSE;
+                    }
+                }
+                else
+                {
+                    *CapturedSecurityQualityOfService =
(PSECURITY_QUALITY_OF_SERVICE)ObjectAttributes->SecurityQualityOfService;
+                    *Present = (ObjectAttributes->SecurityQualityOfService != NULL);
+                }
+            }
+            else
+            {
+                Status = STATUS_INVALID_PARAMETER;
+            }
+        }
+    }
+    else
+    {
+        *CapturedSecurityQualityOfService = NULL;
+        *Present = FALSE;
+    }
+
+    return Status;
+}
+
+/**
+ * @brief
+ * Releases (frees) the captured SQOS data from an object in the memory pool.
+ *
+ * @param[in] CapturedSecurityQualityOfService
+ * The captured SQOS data to be released.
+ *
+ * @param[in] AccessMode
+ * Processor access mode.
+ *
+ * @param[in] CaptureIfKernel
+ * Capture access condition. To be set to TRUE if the capture is done within the kernel,
+ * FALSE if the capture is done in a kernel mode driver or user mode otherwise.
+ *
+ * @return
+ * Nothing.
+ */
+VOID
+NTAPI
+SepReleaseSecurityQualityOfService(
+    _In_opt_ PSECURITY_QUALITY_OF_SERVICE CapturedSecurityQualityOfService,
+    _In_ KPROCESSOR_MODE AccessMode,
+    _In_ BOOLEAN CaptureIfKernel)
+{
+    PAGED_CODE();
+
+    if (CapturedSecurityQualityOfService != NULL &&
+        (AccessMode != KernelMode || CaptureIfKernel))
+    {
+        ExFreePoolWithTag(CapturedSecurityQualityOfService, TAG_QOS);
+    }
+}
+
+/* EOF */