Author: ekohl
Date: Fri May 28 21:36:57 2010
New Revision: 47384
URL:
http://svn.reactos.org/svn/reactos?rev=47384&view=rev
Log:
[NTOSKRNL]
- Implement SeAppendPrivileges().
Modified:
trunk/reactos/ntoskrnl/se/priv.c
Modified: trunk/reactos/ntoskrnl/se/priv.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/priv.c?rev=473…
==============================================================================
--- trunk/reactos/ntoskrnl/se/priv.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/se/priv.c [iso-8859-1] Fri May 28 21:36:57 2010
@@ -281,15 +281,74 @@
/* PUBLIC FUNCTIONS ***********************************************************/
/*
- * @unimplemented
+ * @implemented
*/
NTSTATUS
NTAPI
-SeAppendPrivileges(PACCESS_STATE AccessState,
- PPRIVILEGE_SET Privileges)
-{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+SeAppendPrivileges(IN OUT PACCESS_STATE AccessState,
+ IN PPRIVILEGE_SET Privileges)
+{
+ PAUX_ACCESS_DATA AuxData;
+ ULONG OldPrivilegeSetSize;
+ ULONG NewPrivilegeSetSize;
+ PPRIVILEGE_SET PrivilegeSet;
+
+ PAGED_CODE();
+
+ /* Get the Auxiliary Data */
+ AuxData = AccessState->AuxData;
+
+ /* Calculate the size of the old privilege set */
+ OldPrivilegeSetSize = sizeof(PRIVILEGE_SET) +
+ (AuxData->PrivilegeSet->PrivilegeCount - 1) *
sizeof(LUID_AND_ATTRIBUTES);
+
+ if (AuxData->PrivilegeSet->PrivilegeCount +
+ Privileges->PrivilegeCount > INITIAL_PRIVILEGE_COUNT)
+ {
+ /* Calculate the size of the new privilege set */
+ NewPrivilegeSetSize = OldPrivilegeSetSize +
+ Privileges->PrivilegeCount *
sizeof(LUID_AND_ATTRIBUTES);
+
+ /* Allocate a new privilege set */
+ PrivilegeSet = ExAllocatePool(PagedPool, NewPrivilegeSetSize);
+ if (PrivilegeSet == NULL)
+ return STATUS_INSUFFICIENT_RESOURCES;
+
+ /* Copy original privileges from the acess state */
+ RtlCopyMemory(PrivilegeSet,
+ AuxData->PrivilegeSet,
+ OldPrivilegeSetSize);
+
+ /* Append privileges from the privilege set*/
+ RtlCopyMemory((PVOID)((ULONG_PTR)PrivilegeSet + OldPrivilegeSetSize),
+ (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) -
sizeof(LUID_AND_ATTRIBUTES)),
+ Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+
+ /* Adjust the number of privileges in the new privilege set */
+ PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount;
+
+ /* Free the old privilege set if it was allocated */
+ if (AccessState->PrivilegesAllocated == TRUE)
+ ExFreePool(AuxData->PrivilegeSet);
+
+ /* Now we are using an allocated privilege set */
+ AccessState->PrivilegesAllocated = TRUE;
+
+ /* Assign the new privileges to the access state */
+ AuxData->PrivilegeSet = PrivilegeSet;
+ }
+ else
+ {
+ /* Append privileges */
+ RtlCopyMemory((PVOID)((ULONG_PTR)AuxData->PrivilegeSet +
OldPrivilegeSetSize),
+ (PVOID)((ULONG_PTR)Privileges + sizeof(PRIVILEGE_SET) -
sizeof(LUID_AND_ATTRIBUTES)),
+ Privileges->PrivilegeCount * sizeof(LUID_AND_ATTRIBUTES));
+
+ /* Adjust the number of privileges in the target privilege set */
+ AuxData->PrivilegeSet->PrivilegeCount += Privileges->PrivilegeCount;
+ }
+
+ return STATUS_SUCCESS;
}
/*