Implemented RtlExtendedMagicDivide() and RtlSelfRelativeToAbsoluteSD(). Patch by...
authorEric Kohl <eric.kohl@reactos.org>
Sun, 1 Jun 2003 18:14:24 +0000 (18:14 +0000)
committerEric Kohl <eric.kohl@reactos.org>
Sun, 1 Jun 2003 18:14:24 +0000 (18:14 +0000)
svn path=/trunk/; revision=4815

reactos/lib/ntdll/rtl/largeint.c
reactos/lib/ntdll/rtl/sd.c

index 324a6a9..882649a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: largeint.c,v 1.10 2002/12/08 15:57:39 robd Exp $
+/* $Id: largeint.c,v 1.11 2003/06/01 18:14:24 ekohl Exp $
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
@@ -119,15 +119,78 @@ RtlExtendedLargeIntegerDivide (
        return RC;
 }
 
-LARGE_INTEGER
-STDCALL
-RtlExtendedMagicDivide(LARGE_INTEGER   Dividend,
-       LARGE_INTEGER   MagicDivisor,
-       CCHAR           ShiftCount)
+
+/******************************************************************************
+ * RtlExtendedMagicDivide
+ *
+ * Allows replacing a division by a longlong constant with a multiplication by
+ * the inverse constant.
+ *
+ * RETURNS
+ *  (Dividend * MagicDivisor) >> (64 + ShiftCount)
+ *
+ * NOTES
+ *  If the divisor of a division is constant, the constants MagicDivisor and
+ *  shift must be chosen such that
+ *  MagicDivisor = 2^(64 + ShiftCount) / Divisor.
+ *
+ *  Then we have RtlExtendedMagicDivide(Dividend,MagicDivisor,ShiftCount) ==
+ *  Dividend * MagicDivisor / 2^(64 + ShiftCount) == Dividend / Divisor.
+ *
+ *  The Parameter MagicDivisor although defined as LONGLONG is used as
+ *  ULONGLONG.
+ */
+
+#define LOWER_32(A) ((A) & 0xffffffff)
+#define UPPER_32(A) ((A) >> 32)
+
+LARGE_INTEGER STDCALL
+RtlExtendedMagicDivide (LARGE_INTEGER Dividend,
+                       LARGE_INTEGER MagicDivisor,
+                       CCHAR ShiftCount)
 {
-       UNIMPLEMENTED;
+  ULONGLONG dividend_high;
+  ULONGLONG dividend_low;
+  ULONGLONG inverse_divisor_high;
+  ULONGLONG inverse_divisor_low;
+  ULONGLONG ah_bl;
+  ULONGLONG al_bh;
+  LARGE_INTEGER result;
+  BOOLEAN positive;
+
+  if (Dividend.QuadPart < 0)
+    {
+      dividend_high = UPPER_32((ULONGLONG) -Dividend.QuadPart);
+      dividend_low =  LOWER_32((ULONGLONG) -Dividend.QuadPart);
+      positive = FALSE;
+    }
+  else
+    {
+      dividend_high = UPPER_32((ULONGLONG) Dividend.QuadPart);
+      dividend_low =  LOWER_32((ULONGLONG) Dividend.QuadPart);
+      positive = TRUE;
+    }
+  inverse_divisor_high = UPPER_32((ULONGLONG) MagicDivisor.QuadPart);
+  inverse_divisor_low =  LOWER_32((ULONGLONG) MagicDivisor.QuadPart);
+
+  ah_bl = dividend_high * inverse_divisor_low;
+  al_bh = dividend_low * inverse_divisor_high;
+
+  result.QuadPart =
+    (LONGLONG) ((dividend_high * inverse_divisor_high +
+                UPPER_32(ah_bl) +
+                UPPER_32(al_bh) +
+                UPPER_32(LOWER_32(ah_bl) + LOWER_32(al_bh) +
+                         UPPER_32(dividend_low * inverse_divisor_low))) >> ShiftCount);
+  if (!positive)
+    {
+      result.QuadPart = -result.QuadPart;
+    }
+
+  return result;
 }
 
+
 LARGE_INTEGER
 STDCALL
 RtlLargeIntegerAdd (
index a4b0d65..b8a45c6 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: sd.c,v 1.9 2002/09/08 10:23:06 chorns Exp $
+/* $Id: sd.c,v 1.10 2003/06/01 18:14:24 ekohl Exp $
  *
  * COPYRIGHT:         See COPYING in the top level directory
  * PROJECT:           ReactOS kernel
@@ -641,6 +641,7 @@ RtlSetSaclSecurityDescriptor(PSECURITY_DESCRIPTOR SecurityDescriptor,
    return(STATUS_SUCCESS);
 }
 
+
 NTSTATUS STDCALL
 RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD,
                            PSECURITY_DESCRIPTOR AbsSD,
@@ -654,7 +655,54 @@ RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR RelSD,
                            PSID Group,
                            PDWORD GroupSize)
 {
-   UNIMPLEMENTED;
+  ULONG TotalSize;
+  ULONG OwnerLength;
+  ULONG GroupLength;
+  ULONG DaclLength;
+  ULONG SaclLength;
+  PSID pOwner;
+  PSID pGroup;
+  PACL pDacl;
+  PACL pSacl;
+
+  if (!(RelSD->Control & SE_SELF_RELATIVE))
+    return STATUS_BAD_DESCRIPTOR_FORMAT;
+
+  RtlpQuerySecurityDescriptor (RelSD,
+                              &pOwner,
+                              &OwnerLength,
+                              &pGroup,
+                              &GroupLength,
+                              &pDacl,
+                              &DaclLength,
+                              &pSacl,
+                              &SaclLength);
+
+  if (OwnerLength > *OwnerSize ||
+      GroupLength > *GroupSize ||
+      DaclLength > *DaclSize ||
+      SaclLength > *SaclSize)
+    return STATUS_BUFFER_TOO_SMALL;
+
+  memmove (Owner, pOwner, OwnerLength);
+  memmove (Group, pGroup, GroupLength);
+  memmove (Dacl, pDacl, DaclLength);
+  memmove (Sacl, pSacl, SaclLength);
+
+  memmove (AbsSD, RelSD, sizeof (SECURITY_DESCRIPTOR));
+
+  AbsSD->Control &= ~SE_SELF_RELATIVE;
+  AbsSD->Owner = Owner;
+  AbsSD->Group = Group;
+  AbsSD->Dacl = Dacl;
+  AbsSD->Sacl = Sacl;
+
+  *OwnerSize = OwnerLength;
+  *GroupSize = GroupLength;
+  *DaclSize = DaclLength;
+  *SaclSize = SaclLength;
+
+  return STATUS_SUCCESS;
 }
 
 /* EOF */